# How to unite intervals?

Posted 8 years ago
5210 Views
|
8 Replies
|
4 Total Likes
|
 Help me please to unite resulted intervals!The line "For..." outputs the intervals where the roots exist (roots: 2.94 and 5,52). I have to consider a remark: If in the intervals {x~[i],x[i+1]} and {x[i+1],x~~[i+1]} can be the roots of the equation, the range {x~[i],x~~[i+1]} must have at least one of its root. X = {-2, 6} spx = {-2, -1.90577, -1.81153, -1.59327, -1.375, -1.35785, -1.3407, -1.24655, -1.22941, -1.11811, -0.934054, -0.80167, -0.75, -0.625,-0.5, -0.25, -0.0981238, 0.303752, 0.651876, 0.94833, 1, 1.5, 1.75,2.11731, 2.5, 2.5625, 2.625, 3.3125, 3.75, 4, 4.00964, 4.01928,4.25964, 4.36731, 4.5, 4.75, 5, 5.25, 5.5, 5.75, 6} spfw = {33.3632, 43.263, 51.6709, 55.5421, 57.1266, 57.2511, 57.3756,58.059, 58.0778, 58.1995,56.846,55.1903,54.5739,53.0828,51.1542,48.9959,48.0325,42.2533, 36.408,30.7952,30.1551,28.6446,23.138,19.4168,6.47053,5.90328,5.32951,-0.513959, -0.750527, -6.38895, -6.39157, -6.39418,-6.36456, -6.09357, -6.28599, -5.25369, -4.19539, -2.18625, -0.133803,2.90414, 6.171} spfn = {33.3632, 40.2933, 46.5882, 51.9781, 55.5583, 55.5708, 55.5762, 55.4604, 55.4393, 55.0045, 530116, 51.1309, 50.4546, 48.1226, 45.6012, 43.402, 42.066, 37.5522, 32.6864, 28.1979, 28.0685,25.7067, 17.5943,13.5547, -2.97428, -3.21054, -3.36422, -5.05466, -5.1301, -6.4392,-6.76879, -6.48231, -7.20196, -7.00719, -7.53373, -6.00246, -4.41058,-2.8187, -1.16621, 2.35765, 6.04694} For[i = 1, i < Length@spfn, i++, If[! (((0 < spfn[[i]]) && (0 < spfn[[i + 1]])) || ((spfw[[i]] < 0) && (spfw[[i + 1]] < 0))), Print["1) exists root on: {", spx[[i]], ";", spx[[i + 1]], "}"]]] So the result include 5 intervals: 1) exists root on: {2.11731;2.5} 1) exists root on: {2.5;2.5625} 1) exists root on: {2.5625;2.625} 1) exists root on: {2.625;3.3125} 1) exists root on: {5.5;5.75} And as the first root is 2.94 it has to enter into 4 first intervals, and 5.52 in the last. So after considering the remark, that line should outputs two intervals.I tried to use IntervalUnion but it doesn't work:( Please help me to code this remark in this line.
8 Replies
Sort By:
Posted 8 years ago
 Hi Julia,My 2 cents: IntervalUnion @@ (Reap[ For[i = 1, i < Length@spfn, i++, If[! (((0 < spfn[[i]]) && (0 < spfn[[i + 1]])) || ((spfw[[i]] < 0) && (spfw[[i + 1]] < 0))), Sow[Interval[{spx[[i]], spx[[i + 1]]}]]]]] // Flatten // Rest) IntervalUnion only works on a "data type" Interval so to use IntervalUnion you must wrap the list containing the lower and upper bound of an interval, say, {a, b} becomes Interval[{a,b}]. I replaced the Print in your code with an expression that builds a list of such an interval data types by "sowing" it to the upper level of the expression. With Reap the sowed intervals are captured. (The postfix application of Flatten and Rest are just a lazy way to get to the list of sowed intervals, I can recommend to try to evaluate the Reap expression, its result is then self-explaining)Then you use @@ to apply IntervalUnion to the list of intervals to get your answer: Interval[{2.11731, 3.3125}, {5.5, 5.75}] No need for an iterative solution for which you need to maintain a separate state variable./Twan
Posted 8 years ago
 Oops, didn't read the first response well enough.
Posted 8 years ago
 Ah, let's try this, In[1]:= X = {-2, 6}; spx = {-2, -1.90577, -1.81153, -1.59327, -1.375, -1.35785, -1.3407, -1.24655, -1.22941, -1.11811, -0.934054, -0.80167, -0.75, -0.625, -0.5, -0.25, -0.0981238, 0.303752, 0.651876, 0.94833, 1, 1.5, 1.75, 2.11731, 2.5, 2.5625, 2.625, 3.3125, 3.75, 4, 4.00964, 4.01928, 4.25964, 4.36731, 4.5, 4.75, 5, 5.25, 5.5, 5.75, 6}; spfw = {33.3632, 43.263, 51.6709, 55.5421, 57.1266, 57.2511, 57.3756, 58.059, 58.0778, 58.1995, 56.846, 55.1903, 54.5739, 53.0828, 51.1542, 48.9959, 48.0325, 42.2533, 36.408, 30.7952, 30.1551, 28.6446, 23.138, 19.4168, 6.47053, 5.90328, 5.32951, -0.513959, -0.750527, -6.38895, -6.39157, -6.39418, -6.36456, -6.09357, -6.28599, -5.25369, -4.19539, -2.18625, -0.133803, 2.90414, 6.171}; spfn = {33.3632, 40.2933, 46.5882, 51.9781, 55.5583, 55.5708, 55.5762, 55.4604, 55.4393, 55.0045, 530116, 51.1309, 50.4546, 48.1226, 45.6012, 43.402, 42.066, 37.5522, 32.6864, 28.1979, 28.0685, 25.7067, 17.5943, 13.5547, -2.97428, -3.21054, -3.36422, -5.05466, -5.1301, -6.4392, -6.76879, -6.48231, -7.20196, -7.00719, -7.53373, -6.00246, -4.41058, -2.8187, -1.16621, 2.35765, 6.04694}; myintervals = Reap[ For[i = 1, i < Length@spfn, i++, If[(((0 < spfn[[i]]) && (0 < spfn[[i + 1]])) || ((spfw[[i]] < 0) && (spfw[[i + 1]] < 0))), Sow[Interval[{spx[[i]], spx[[i + 1]]}]]] ] ][[2, 1]] Out[5]= {Interval[{-2, -1.90577}], Interval[{-1.90577, -1.81153}], Interval[{-1.81153, -1.59327}], Interval[{-1.59327, -1.375}], Interval[{-1.375, -1.35785}], Interval[{-1.35785, -1.3407}], Interval[{-1.3407, -1.24655}], Interval[{-1.24655, -1.22941}], Interval[{-1.22941, -1.11811}], Interval[{-1.11811, -0.934054}], Interval[{-0.934054, -0.80167}], Interval[{-0.80167, -0.75}], Interval[{-0.75, -0.625}], Interval[{-0.625, -0.5}], Interval[{-0.5, -0.25}], Interval[{-0.25, -0.0981238}], Interval[{-0.0981238, 0.303752}], Interval[{0.303752, 0.651876}], Interval[{0.651876, 0.94833}], Interval[{0.94833, 1}], Interval[{1, 1.5}], Interval[{1.5, 1.75}], Interval[{1.75, 2.11731}], Interval[{3.3125, 3.75}], Interval[{3.75, 4}], Interval[{4, 4.00964}], Interval[{4.00964, 4.01928}], Interval[{4.01928, 4.25964}], Interval[{4.25964, 4.36731}], Interval[{4.36731, 4.5}], Interval[{4.5, 4.75}], Interval[{4.75, 5}], Interval[{5, 5.25}], Interval[{5.25, 5.5}], Interval[{5.75, 6}]} In[6]:= IntervalUnion @@ myintervals Out[6]= Interval[{-2, 2.11731}, {3.3125, 5.5}, {5.75, 6}] I'll explain a little, starting with your first post. Print[] turns expressions into text that you can read, but the result of that isn't something Mathematica can calculate with. So instead I am just going to have your If make Intervals for Mathematica to calculate with.Now sometimes your If may find an Interval and sometimes not. So I suppose I would like a sort of bag that it could put each interval it finds into the bag. Once the For is finished I would like to do an IntervalUnion on the contents of the bag. Reap creates a "bag" where Sow can put things and after the Reap is finished it gives you the contents of the bag. You can read the examples in the help system.Now the help shows IntervalUnion[Interval[..],Interval[..]] but what we got from Reap was {Interva[..],Interval[..]} and that is wrapped in {} to make it a list. We want to strip off those {} outside the Interval and put that inside IntervalUnion. @@ will do that. You can look up @@ in the help system and try to understand how it works.So this has introduced some new ideas for you to try to understand.See if this works for you.
Posted 8 years ago
 Thank you very much!!! You absolutely helped me:)
Posted 8 years ago
 I'm sorry for bothering..... It was the 1-st step of my algorithm. Tell me please, how on the 2-nd step of algorithm to find intervals roots separately in the 1-st found interval {2.11731,3.3125} and in the second {5.5,5.75}, using myintervals1 ???? I tried this, but I can't correctly use it ;(( X = {-2, 6} spx = {-2, -1.90577, -1.81153, -1.59327, -1.375, -1.35785, -1.3407, -1.24655, -1.22941, -1.11811, -0.934054, -0.80167, -0.75, -0.625, -0.5, -0.25, -0.0981238, 0.303752, 0.651876, 0.94833, 1, 1.5, 1.75, 2.11731, 2.5, 2.5625, 2.625, 3.3125, 3.75, 4, 4.00964, 4.01928, 4.25964, 4.36731, 4.5, 4.75, 5, 5.25, 5.5, 5.75, 6} spkw = {105.056, 89.2249, 17.7361, 7.25929, 7.25929, 7.25929, 7.25929, 1.09386, 1.09386, -7.35382, -12.5073, -11.929, -11.929, -15.429, -8.63312, -6.34314, -14.3807, -16.7907, -18.933, -12.3896, -3.021, -22.0262, -25.7865, -18.8033, -9.07591, -9.18036, -8.49959, -9.24378, -7.32337, -0.271835, -0.270096, 0.123206, 0.156523, 0.465142, 4.12922, 4.23318, 8.03654, 8.20981, 12.1518, 12.3944} spkn = {73.5426, 66.8007, 24.6942, 16.4029, 0.726929, 0.314512, -1.23002, -1.23002, -3.90668, -10.8276, -14.2065, -13.0895, -18.656, -20.1709, -8.79676, -8.79676, -11.2319, -13.9771, -15.1407, -2.50312, -4.72374, -32.4496, -34.2958, -21.0455, -2.45882, -2.45882, -2.45882, -2.45882, -2.45882, -2.45882, -2.45882, -1.70357, -1.70357, -1.11799, 6.1251, 6.36752, 6.36752, 6.60995, 14.0955, 14.5803} spmw = {243.475, 213.305, 83.8004, 67.1081, 67.1081, 67.1081, 67.1081, 59.4226, 59.4226, 49.9772, 45.1635, 45.6272, 45.6272, 43.4397, 46.8376, 47.4101, 46.6214, 47.3535, 48.75, 42.5447, 33.1761, 61.6839, 68.2644, 53.4787, 29.1603, 29.4279, 27.6409, 30.1061, 22.9045, -5.30161, -5.30859, -6.88938, -7.0313, -8.37913, -24.8675, -25.3613, -44.3781, -45.2877, -66.9686, -68.3634} spmn = {180.448, 167.6, 91.3225, 78.1123, 56.5579, 55.9978, 53.9271, 53.9271, 50.6364, 42.898, 39.742, 40.6374, 36.4626, 35.5158, 41.2028, 41.2028, 40.9639, 41.7978, 42.5563, 30.5716, 32.7923, 74.3811, 77.6119, 49.5569, 3.09017, 3.09017, 3.09017, 3.09017, 3.09017, 3.09017, 3.09017, 0.0546329, 0.0546329, -2.5028, -35.0967, -36.2482, -36.2482, -37.5209, -78.6912, -81.4791} spfw = {33.3632, 43.263, 51.6709, 55.5421, 57.1266, 57.2511, 57.3756, 58.059, 58.0778, 58.1995, 56.846, 55.1903, 54.5739, 53.0828, 51.1542, 48.9959, 48.0325, 42.2533, 36.408, 30.7952, 30.1551, 28.6446, 23.138, 19.4168, 6.47053, 5.90328, 5.32951, -0.513959, -0.750527, -6.38895, -6.39157, -6.39418, -6.36456, -6.09357, -6.28599, -5.25369, -4.19539, -2.18625,-0.133803, 2.90414, 6.171} spfn = {33.3632, 40.2933, 46.5882, 51.9781, 55.5583, 55.5708, 55.5762, 55.4604, 55.4393, 55.0045, 530116, 51.1309, 50.4546, 48.1226, 45.6012, 43.402, 42.066, 37.5522, 32.6864, 28.1979, 28.0685, 25.7067, 17.5943, 13.5547, -2.97428, -3.21054, -3.36422, -5.05466, -5.1301, -6.4392, -6.76879, -6.48231, -7.20196, -7.00719, -7.53373, -6.00246, -4.41058, -2.8187, -1.16621, 2.35765, 6.04694} (*1 STEP*) myintervals1 = Reap[For[i = 1, i < Length@spfn, i++, If[! (((0 < spfn[[i]]) && (0 < spfn[[i + 1]])) || ((spfw[[i]] < 0) && (spfw[[i + 1]] < 0))), Sow[Interval[{spx[[i]], spx[[i + 1]]}]]]]][[2, 1]] Print["1)", IntervalUnion @@ myintervals1] (*2 STEP*) myintervals2 = Reap[For[i = 1, i < Length@spfn, i++, If[spfn[[i]]*spfn[[i + 1]] < 0 && spfw[[i]]*spfw[[i + 1]] < 0, Sow[Interval[{Min[xnz[i] = -spmn[[i]]/spkn[[i]], xwz[[i]] = -spmw[[i]]/spkw[[i]]], Max[xnz[[i]] = -spmn[[i]]/spkn[[i]], xwz[[i]] = -spmw[[i]]/spkw[[i]]]}]] ] ] ][[2, 1]] Print["2)", myintervals2] 
Posted 8 years ago
 Can you show the exact code and input you used with IntervalUnion that did not work? Did your code look exactly like the examples shown on the help page for IntervalUnion?
Posted 8 years ago
 Yes, but it outputs 5 intervals and union nothing:(  For[i = 1, i < Length@spfn, i++, If[! (((0 < spfn[[i]]) && (0 < spfn[[i + 1]])) || ((spfw[[i]] < 0) && (spfw[[i + 1]] < 0))), Print[IntervalUnion[Interval[{spx[[i]], spx[[i + 1]]}], Interval[{spx[[i]], spx[[i + 1]]}]]] ] ] 
Posted 8 years ago