# Building intervals

I'm facing the right know the problem of building intervals to an arbitrary number. The special thing is that the first and the last intervals should have fixed length, while the "middle" ones should be of a fixed number. I think an example will make things more clear;-)

We take the number 111, the first and the last 3 intervals should have the length 10, in between there should be 5 intervals.

The solution would be: {{0,10},{10,20},{20,30},{30,40.2},{40.2,50.4},{50.4,60.6},{60.6,70.8},{70.8,81},{81,91},{91,101},{101,111}}

I hope I made the problem understandable.

Thank you! rainer

Something like :

makeIntervals[start_, end_] := Module[{front, middle, rear, len},
front = NestList[# + 10 &, {start, start + 10}, 2];
rear = NestList[# + 10 &, {end - 30, end - 20}, 2];
len = (rear[[1, 1]] - front[[-1, -1]])/5;
middle = NestList[# + len &, {front[[-1, -1]], front[[-1, -1]] + len}, 4];
Join[front, middle, rear]
]

makeIntervals[0, 111] // N

(* {{0., 10.}, {10., 20.}, {20., 30.}, {30., 40.2}, {40.2, 50.4}, {50.4, 60.6},{60.6, 70.8}, {70.8, 81.}, {81., 91.}, {91., 101.}, {101., 111.}} *)

• works perfect, thx – RMMA Aug 16 '12 at 9:30

The simplest method I think would be to simply build each range seperatly and join them:

divideIntoIntervals[n_, l_, m_, middle_] :=
Partition[Join[
Range[0, l (m-1), l],
Range[l m, n - l m, (n - 2 l m)/(middle)],
Range[n - l (m-1), n, l]
],2, 1]


For the example this is called using:

divideIntoIntervals[111, 10, 3, 5]


{{0, 10}, {10, 20}, {20, 30}, {30, 201/5}, {201/5, 252/ 5}, {252/5, 303/5}, {303/5, 354/5}, {354/5, 81}, {81, 91}, {91, 101}, {101, 111}}

You could add checks to see if the range is only increasing, since this will give negative ranges if you ask for something like divideIntoIntervals[111, 50, 3, 5], but this could be the intended usage in some cases.

Updated to incorporate suggestion by J. M.

• a very clear solution, tahnk you! Only the intervals overlap a bit ({30,30},{81,81}) – RMMA Aug 16 '12 at 10:14
• @rainer Thx, didn't notice that. It's fixed now. – jVincent Aug 16 '12 at 10:36
• Alternatively, avoiding the use of Union[]: divideIntoIntervals[n_, l_, m_, middle_] := Partition[Join[l Range[0, m - 1], Range[l m, n - l m, (n - 2 l m)/middle], Range[n - l m + l, n, l]], 2, 1] – J. M. will be back soon Aug 16 '12 at 10:51

Define

• n - upper bound number, like your 111
• i - how many intervals at the edges, like your 3
• j - length of intervals at the edges, like your 10
• k - length of internal intervals, like your 5

The Function

h[n_, i_, j_, k_] :=Join[#, Table[{s, s + #}, {s, j i, n - j i - #, #}] &@((n - 2 j i)/k),
Reverse /@ Reverse[n - #]] &@({#, # + j} & /@ Range[0, (i - 1) j, j])


N@h[111, 3, 10, 5]


{{0, 10}, {10, 20}, {20, 30}, {30., 40.2}, {40.2, 50.4}, {50.4, 60.6}, {60.6, 70.8}, {70.8, 81.}, {81, 91}, {91, 101}, {101, 111}}

• thx that's really appealing! – RMMA Aug 16 '12 at 9:30
• @rainer update - I simplified it a bit – Vitaliy Kaurov Aug 16 '12 at 9:33
f[x_] := If[ x > 60,
Join[ Table[ Interval[{10 k, 10 (k + 1)}], {k, 0, 2}],
Table[ Interval[{k, k + (x - 60)/5} ], {k, Most@Range[30, x - 30, (x - 60)/5]}],
Table[ Interval[{10 k + x - 30, 10 (k + 1) + x - 30}], {k, 0, 2}]]]


If you prefer real numbers in between you can replace x with N @ x where you'd like.

f[111]

{Interval[{0, 10}], Interval[{10, 20}], Interval[{20, 30}],
Interval[{30, 201/5}], Interval[{201/5, 252/5}], Interval[{252/5, 303/5}],
Interval[{303/5, 354/5}], Interval[{354/5, 81}],
Interval[{81, 91}], Interval[{91, 101}],  Interval[{101, 111}]}