Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I am using operations over Interval and the result of an intersection (or union) contains some singletons. Would it be possible to remove them ?

Example:

Interval[
  {2894486400, 2894486400},
  {2894659200, 2894832000},
  {2895004800, 2895004800},
  {2895177600, 2895350400}
]

Transformed in :

Interval[{2894659200, 2894832000}, {2895177600, 2895350400}]
share|improve this question
3  
Try DeleteCases: DeleteCases[%, {$x_, $x_}] –  kale Aug 5 at 13:22
    
Works well ! Is the variable $x_ a pattern ? I should learn that type of syntax :) –  Mammouth Aug 5 at 13:26
1  
Not necessarily. When matching patterns I just specified a variable x so that the first and last elements in the lists had to be the same. I usually add a $ so I don't get confused if another x has already been defined in my current context. –  kale Aug 5 at 13:31
    
Thank you for the precision. I have not seen this very often, do you have any reference (book, article, etc.) that explains this ? –  Mammouth Aug 5 at 13:59
    
Nope. Just a personal preference. I do the same thing for functions like FindRoot: $x /. FindRoot[Exp[$x]==5, {$x,1}]. Like I said, complete personal preference. –  kale Aug 5 at 14:24

2 Answers 2

up vote 4 down vote accepted

For version 10 you might use:

interval ~Select~ DuplicateFreeQ
Interval[{2894659200, 2894832000}, {2895177600, 2895350400}]

For other versions alternatives to DeleteCases include:

Select[interval, UnsameQ @@ # &]

Pick[#, UnsameQ @@@ #] & @ interval

Benchmarks

As requested:

generate[n_] := 
  Sort @ RandomInteger[n, ⌊.7n⌋] ~Partition~ 2 // Apply[Interval];

f1 = DeleteCases[{x_, x_}];
f2 = Select[DuplicateFreeQ];
f3 = Select[UnsameQ @@ # &];
f4 = Pick[#, UnsameQ @@@ #] &;
f5 = # /. {x_, x_} :> Sequence[] &;

Needs["GeneralUtilities`"]

BenchmarkPlot[{f1, f2, f3, f4, f5}, generate, 2^Range[7, 16], "IncludeFits" -> True]

enter image description here

The lines are hard to see here but:

  • f1 and f4 are the winners with nearly identical timings
  • f3 and f5 are the slowest
  • f2 is in the middle
  • All methods have the same complexity, unsurprisingly

If speed is the goal f5 can be improved by using Replace:

f6 = Replace[#, {x_, x_} :> Sequence[], {1}] &; 

BenchmarkPlot[{f1, f5, f6}, generate, 2^Range[7, 16], "IncludeFits" -> True]

enter image description here

This shows that DeleteCases has only the slightest performance margin over {x_, x_} :> Sequence[] when the latter is used with a targeted levelspec, which I find somewhat surprising as I assumed the latter would incur additional evaluation.

share|improve this answer
    
Any advantage (speed, etc) of using one versus the others? I'm too lazy to test them lol. –  seismatica Aug 5 at 21:46
    
@seismatica Let's find out. :-) –  Mr.Wizard Aug 5 at 22:05
    
Very nice! +1.. –  seismatica Aug 5 at 22:21
    
Could you add # /. {x_, x_} :> Sequence[] &? It's bound to be slower, but I'm curious :). –  Teake Nutma Aug 6 at 8:26
    
@TeakeNutma Done. –  Mr.Wizard Aug 6 at 16:07

Yes, this is perfectly possible. In fact, there are multiple ways to do this. The most straightforward is to use DeleteCases, as @kale points out in the comments:

interval = Interval[
 {2894486400, 2894486400}, 
 {2894659200, 2894832000}, 
 {2895004800, 2895004800}, 
 {2895177600, 2895350400}
];

DeleteCases[interval, {x_, x_}]
Interval[{2894659200, 2894832000}, {2895177600, 2895350400}]

Here x_ is a named pattern. Because it occurs as {x_, x_}, it only matches those intervals that are singletons.

Another method, my favorite (but probably not as efficient as DeleteCases), is to replace the singletons with Sequence, which get automatically spliced out:

interval /. {x_, x_} -> Sequence[]
Interval[{2894659200, 2894832000}, {2895177600, 2895350400}]
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.