Mathematica Mathematica - sorting NSolve solutions

AI Thread Summary
The discussion focuses on a Mathematica code that processes multiple files containing coordinates representing points of circles, using NSolve to generate outputs for each point. The user encounters issues with the outputs not being sorted, which complicates the subsequent analysis for calculating surface areas of the shapes formed. Suggestions include using a custom sorting function or clustering to group the outputs into distinct arrays for each shape. The conversation highlights the need for clarity in the desired output format and the importance of understanding the structure of the data being processed. Ultimately, the user seeks effective methods to organize and visualize the results from their computations.
MartinV
Messages
68
Reaction score
0
Hello, everyone.

I have a code written in Mathematica that loads a single file in turn. Each file contains a 200×2 array of numbers which are x,y coordinates of points. I feed each line of each file in a loop that contains a NSolve equation system. The equation system returns 5 outputs for every input. The problem is that those solutions are not sorted.

The input points represent positions of a circle, each file a different position of that circle. The five outputs sometimes give me a whole circle (or whatever shape the input circle turns into), sometimes two or three files contain fractions of those shapes. Sometimes the outputs are even complex. If I plot everything and make an animation with all the different circle positions, I only get real solutions and all the shapes are complete. But now I want to use those output arrays into another program, one that would calculate the surface of those shapes. If I want to do this, I need to put those fractions of shapes together so that each file contains points that mark a single shape.

Here is the code I use for doing the NSolve bit:

SetDirectory["C:\Documents and Settings..."];

p = 1.0; q = 0; eps = 0.5; M = 187;

For[j = 1, j <= M, j++,
P = Import["P" <> ToString[j] <> ".txt", "Table"]; b = {}; c = {};
d = {}; e = {}; f = {};
For[i = 1, i <= 200, i++,
a = NSolve[{x - (1 - eps)*x/(x^2 + y^2) -
eps*(x - p)/((x - p)^2 + (y - q)^2) == P[[i, 1]],
y - (1 - eps)*y/(x^2 + y^2) -
eps*(y - q)/((x - p)^2 + (y - q)^2) == P[[i, 2]]}, {x, y}];
aa = Sort[a];
b = Append[b, {aa[[1, 1, 2]], aa[[1, 2, 2]]}];
c = Append[c, {aa[[2, 1, 2]], aa[[2, 2, 2]]}];
d = Append[d, {aa[[3, 1, 2]], aa[[3, 2, 2]]}];
e = Append[e, {aa[[4, 1, 2]], aa[[4, 2, 2]]}];
f = Append[f, {aa[[5, 1, 2]], aa[[5, 2, 2]]}];
]
Export["Q" <> ToString[j] <> ".txt", b];
Export["R" <> ToString[j] <> ".txt", c];
Export["S" <> ToString[j] <> ".txt", d];
Export["T" <> ToString[j] <> ".txt", e];
Export["U" <> ToString[j] <> ".txt", f];
]

This particular code exports the outputs into .txt files just like the input files are. I have a similar code, only this one plots all the solutions, making an animation. I tried using Sort[] but it didn't do anything. Up until now I tried using Matlab to import the newly made files but that is also giving me problems. Now I realize I need to have both the animations and the surface graphs on one screen so I need to make this work in Mathematica now.

Any help would be greatly appreciated.
 
Physics news on Phys.org
MartinV said:
The problem is that those solutions are not sorted. ... I tried using Sort[] but it didn't do anything.
Have you tried using something other than the default ordering function:
Sort[{a,b,c},f]
where f is some function that takes two elements of your list and returns True if they are in the correct order and False if they are not.
 
I thought of doing a Sort rule but I just can't figure out what to use. I'm quite new with Mathematica and don't know how to use it properly. Do you have any ideas?
 
How can you tell if two elements of the list are in order or out of order?
 
I plot them. I want each of the output arrays to represent a single object. If the input is 200 points that represent a circle, outputs are usually something ellipse-like. Sometimes that ellipse is drawn by two or more colours, meaning the points belong to several arrays. I could sort them by x and y-axis or by absolute value which would mean distance from zero.
 
So then you would make a function like:
f[a_,b_]:=OrderedQ[{Abs[a],Abs}]

and then call
Sort[{a,b,c},f]
 
I would never think of that myself. Thanks. I'll try it and report tomorrow how it worked.
 
Been sick for a few days.

Anyway, that sorting thing didn't work unless I'm missing something.
 
Are the elements of the list in ascending order of absolute value? Some more detail would help. I can't tell if the problem is that the Sort itself didn't work or if it worked but the result wasn't what you really needed.
 
  • #10
No.

The five files I need to sort through are outputs of NSolve. The input file contains points of a circle, starting at the right (if the circle would have the center at 0,0, then I start at R,0). So the x values first go down and y goes up, then y goes down while x still goes down, then x starts to climb while y descends and then climbs back up to the starting point.
 
  • #11
It is somewhat difficult to tell what it is you want to do because we can't see your input data files of hundreds of data points or your hundreds of solutions or what it is you want sorted into what order.

Would it be possible for you to temporarily scale this back to say 12 points and show exactly the input you want to sort and exactly what you want the output from sort to be on those 12 points? With the actual Mathematica form of the input and your manually created result then it would probably be feasible for someone to write a line or two of code that will sort these into the order you desire.
 
  • #12
Yes, Bill Simpson has a good idea. Note that we are just talking about the inputs and desired outputs of the Sort, not your overall procedure and the files.
 
  • #13
That's a good idea.

This is the input file.
5.4045085e-001 2.2938926e-001
5.1545085e-001 2.4755283e-001
4.8454915e-001 2.4755283e-001
4.5954915e-001 2.2938926e-001
4.5000000e-001 2.0000000e-001
4.5954915e-001 1.7061074e-001
4.8454915e-001 1.5244717e-001
5.1545085e-001 1.5244717e-001
5.4045085e-001 1.7061074e-001
5.5000000e-001 2.0000000e-001

Left column x coordinates, right line y coordinates. Points roughly represent the circle. I put these points in the code above. Result for one point looks like this:

{{x -> 1.4768, y -> -0.402992}, {x -> 0.595122,
y -> -0.733527}, {x -> 0.596497, y -> 0.999175}, {x -> 0.51045,
y -> -0.0682166}, {x -> -0.50395, y -> -0.298782}}

Strangely this particular calculation didn't spawn complex values but I'm not interested in the complex ones anyway.

This is how unsorted numbers look like when plotted:

slika1.png

slika2.png


I need each elipse to be in a separate array.

I hope it's now clear what I'm trying to achieve.
 
  • #14
MartinV said:
5.4045085e-001 2.2938926e-001
5.1545085e-001 2.4755283e-001
4.8454915e-001 2.4755283e-001
4.5954915e-001 2.2938926e-001
4.5000000e-001 2.0000000e-001
4.5954915e-001 1.7061074e-001
4.8454915e-001 1.5244717e-001
5.1545085e-001 1.5244717e-001
5.4045085e-001 1.7061074e-001
5.5000000e-001 2.0000000e-001

...

{{x -> 1.4768, y -> -0.402992}, {x -> 0.595122,
y -> -0.733527}, {x -> 0.596497, y -> 0.999175}, {x -> 0.51045,
y -> -0.0682166}, {x -> -0.50395, y -> -0.298782}}
This doesn't make sense as input and output for the Sort function. The input and the output for the Sort will be the same list elements, just in a different order. That is what sorting does.

Btw, are you sure that you really want the list of points sorted. Wouldn't you rather have it grouped into separate ellipses?
 
  • #15
The first array is the input of the entire code. The bracketted numbers are what I need to have sorted.

Grouped into separate ellipses is good but they need to be in proper order because I will be calculating the surface area of the ellipses.

BTW, the sorting is suppose to group the points into the right ellipses. Hence for each input point I get five outputs, each a part of its own ellipse.
 
  • #16
I asked for unsorted points so I could show how to sort them. You responded with a list of 5 points. Excellent. Exactly what I asked for. So the first thing I do is plot them to see what I am facing, how they are out of order and what I am going to need to do to get them to plot as a nice ellipse..

ListPlot[Map[{x, y} /.#&, {{x->1.4768, y-> -0.402992}, {x->0.595122, y-> -0.733527}, {x->0.596497, y->0.999175}, {x->0.51045, y-> -0.0682166}, {x-> -0.50395, y-> -0.298782}}], PlotJoined->True]

Try that. See what I'm seeing here now. Then suppose you have nothing else to go on and you need to decide how to sort that so those points will plot as a nice ellipse. I'm perplexed.

Now two steps backward. When I look at your two ellipse plots you showed above I see two different colored arcs in each one. I also see the "end points" of the arcs are "off the chart." But I don't think I see any hint of 200 points on an ellipse that the order of the points has been scrambled so that the plot is zig zagging back and forth across the ellipse and if I just sorted them into order all the zigging would disappear and I would have a nice ellipse.

Item 1: I'll guess that the two different colored arcs in your plots mean that if you look at your data really carefully you will see your points are in two different lists. Early versions of ListPlot could only plot a single list of points. Later versions of ListPlot when given a list of two or more lists of points will plot each list separately and will do each in a separate color. I realize in a forest of points you could easily overlook that you have multiple lists being given to ListPlot. But go carefully look and see if this is the case. If so try to figure out why and see if you can fix that.

Item 2: I don't believe your problem has anything to do with sorting. I believe somehow your "endpoints" of your arcs are just wrong. I can't even begin to imagine why. But I would go look very carefully at the data and the equations and see whether a couple of your equations result in wild values for solutions.
 
  • #17
Bill Simpson said:
Item 1: I'll guess that the two different colored arcs in your plots mean that if you look at your data really carefully you will see your points are in two different lists. Early versions of ListPlot could only plot a single list of points. Later versions of ListPlot when given a list of two or more lists of points will plot each list separately and will do each in a separate color. I realize in a forest of points you could easily overlook that you have multiple lists being given to ListPlot. But go carefully look and see if this is the case. If so try to figure out why and see if you can fix that.

This is what I was talking about the whole time. I find one set of solutions in two or possibly more arrays. I want to sort them so I have one solution in one array, second solution in another array.
 
  • #18
That is not sorting, that is grouping or clustering. There is a built in function for clustering.
 
  • #19
I did not know clustering exists. I am rather new in using Mathematica.

I'm not sure how to use the FindCluster method. Do I use it everytime a loop does the NSolve for a new point? Because that's only five pairs of numbers and clustering them seems a bit bizzare. I can use the cluster thing when I have all 1000 pairs of points (5 outputs × 200 points) but the points are already separated in the five arrays. Should I throw all five groups together and then use FindCluster?

I know I look like a complete "#$ by now but I just can't seem to get a clear picture of Mathematica.
 
Last edited:
  • #20
If you had 0.01% of the trouble with a toaster that you WILL have with Mathematica you would have thrown the toaster down the stairs and got one that was easier to get along with.

Now, back to your real problem. Can you plot all those ellipses at once, forget trying to think about Mathematica syntax, look at the plot and say something like "well the first ellipse is always going to have y values between .5 and .7, the second ellipse is always going to have y values between .9 and 1.2, etc"?

Write down five lines of english, one for each ellipse, that you could tell a mindless assistant to use to divide all the points up into five different bins. Then get ALL your {x->1.,y->.8} into a single large list, not nested lists of nested lists. Call that say gobsofpoints. Note: If they are not in a single list you can get rid of the nesting using something like gobsofpoints = Partition[Flatten[mynestedgobofpoints], 2]

Now to extract the points for one of the ellipses. Suppose the first ellipse has .5<=y<=.7. Use this to extract only those points.

firstellipse = Select[gobsofpoints, .5 <= Last[{x, y} /. #] <= .7 &]

Change the .5 and .7 to capture your secondellipse, thirdellipse, etc.

If your ellipses are perhaps overlapping and you cannot divide them up this way then it is going to get more interesting.
 
  • #21
MartinV said:
the points are already separated in the five arrays.
What does this mean?
 
  • #22
It means that if you look at the code in the first post, you will see that the equation system gives five outputs for each input and every solution of NSolve goes into its own array.

slika3.png

Here I have plotted each solution in different color. You can see that sometimes the color jumps from up high to way down. My goal is to make every ellipse whole, not jumping up and down.

slika4.png

Here is the whole plot. The red circles are the input files, the rest (yellow, black, blue, magenta, green) are the five outputs.
 
  • #23
So each solution from NSolve gives you exactly one point from each of 5 ellipses. The first point is from one of the yellow ellipses, the second point is from one of the black ellipses, the third from blue, fourth from magenta, and fifth from green? And the problem is that sometimes the first point, the yellow one, is actually in a region that should be blue or magenta, and vice versa. So you want to look at the solution, determine if the yellow one is out of place, and if so, swap the yellow, blue, and magenta solutions so that they are each in the right region. Is that correct?

Is there actually any significance to the color of the ellipses? I.e. do you really need to see the transition between the yellow and black ellipses, or is this just a way to avoid the big streaks and otherwise you don't care about the colors?
 
  • #24
Yes, that is what I want.

I used colors so all five series are distinguishable.
The thing is when two ellipses come close, they start to form a combined shape. The number of points is always the same (5 × 200) but some have complex value. I don't include complex points in the plot. Here's an example:
Slika5.png
 
Last edited:
  • #25
I tried doing it like this;

(looped as before)
a = NSolve[...]; % my function as before
b = Append[b, a]; % new solutions are added to the previous for each of the 200 input points
c = Partition[Flatten, 2]; % to create 1000 lines of {x -> 111, y -> 222}

Now I try to do FindClusters[c,5] and I get:

FindClusters::amtd:
FindClusters is unable to automatically select an appropriate dissimilarity function for the input data

What am I doing wrong (again)?
 
  • #26
Try this:
sortCoords[{yel_, bla_, blu_, mag_, gre_}] := Join[Sort[{yel, blu, mag}, OrderedQ[{#1[[2, 2]], #2[[2, 2]]}] &], {bla, gre}]

and replace Sort[a] by sortCoords[a]
 
  • #27
I did the sortCoords thing. The coloring of the plot is different, so some numbers have shifted from one group to another. It's still mixed, unfortunately.
 
  • #29
LensingLoopAnimate.png
 
  • #30
It looks fine and unmixed to me.
 
  • #31
The blue color is in two ellipses as is the red and the green. All shapes are composed of multiple colors.
 
  • #32
Oh, I can't see that. Can you re-do the second plot from 22 with the new sort function?

But try this first:
sortCoords[{yel_, bla_, blu_, mag_, gre_}] := Join[Sort[{bla, blu, mag}, OrderedQ[{#1[[2, 2]], #2[[2, 2]]}] &], {yel, gre}]
 
Last edited:
  • #33
Watching this exchange reminds me of something I read ten or twenty years ago. The AI researchers had spent vast amounts of time and effort trying to get a vision system and robot machine to pick odd shaped parts of of a pile of parts in a bin. Then one afternoon someone asked the question:

Why are you tossing the parts in the bin and then asking the robot to do the hard work of recognizing them and taking them back out, why don't you just not throw the parts in the bin in the first place?

Could your code perhaps be organized in a slightly different way so that the process of identifying the individual ellipses would already be done for you?
 
  • #34
This is done with the last sortCoords:

sortCoords[{yel_, bla_, blu_, mag_, gre_}] := Join[Sort[{bla, blu, mag}, OrderedQ[{#1[[2, 2]], #2[[2, 2]]}] &], {yel, gre}]

Slika6.png


It's an improvement from before but it's not exactly what it's suppose to be.
 
  • #35
Bill Simpson said:
Could your code perhaps be organized in a slightly different way so that the process of identifying the individual ellipses would already be done for you?

I'm willing to try every aspect. Do you have anything specific in mind?
 
  • #36
At the points where it jumps, why is it jumping? Also, is there any rule about the regions where the roots come from, i.e. I know that the order changes but can you say that there is always exactly one root with y>.2, exactly one with -.2<y<0 and 0<x<1, ...
 
  • #37
If you post the 5-6 data files and your latest notebook that did the six color plot above along with some directions on how to use your notebook and what you really want as output then I'll look at it and see if I can get something to work.
 
  • #38
At the points where it jumps, why is it jumping?

If I'd known that, I would be done with my bachelor's degree by now. It's got something to do with the fact that the lower, apple-shapped formation, is moving in the opposite direction as the upper one (hat-like).

The inputs are traveling from left to right. The 'hat formation' series (cyan first, then magenta, then black, magenta again, cyan in the end) also goes from left to right. The lower series starts at (1,0) (magenta), then shifts to blue and cyan. At the bottom another picture forms (green), cyan elipses disappear, then the green turns into blue and black.
The top of the "apple" is a separate picture.

Bill Simpson, I usually run the code at the beginning of this thread with input files. I can zip those files and send them to you. Then all you need to do is run the program (it runs approx 15 minutes with 187 input files.)
 
  • #39
In post 13 you gave 10 inputs. I was able to use your code to replicate one group of 5 ellipses, all neatly separated. As an intermediate to zipping up the whole input, perhaps you could find one spot where it "jumps" and give the 10 inputs before and the 10 inputs after. Then maybe I could figure out why it is jumping. You could do that either with the original jumps without my sorting function or with the new jumps with my sorting function. Either way is fine, just let me know.
 
  • #40
I have 41 files ready. How do I send them?
 
  • #41
Ok, I managed to separate the ellipses using FindClusters[]. The code now looks like this:

SetDirectory["C:\..."];

p = 1.0; q = 0; eps = 0.5; M = 101;

For[j = 1, j <= M, j += 1,
P = Import["P" <> ToString[j] <> ".txt", "Table"]; b = {}; c = {}; d = {};
For[i = 1, i <= 200, i++,
a = NSolve[{x - (1 - eps)*x/(x^2 + y^2) - eps*(x - p)/((x - p)^2 + (y - q)^2) == P[[i, 1]],
y - (1 - eps)*y/(x^2 + y^2) - eps*(y - q)/((x - p)^2 + (y - q)^2) == P[[i, 2]]}, {x, y}]; b = Append[b, a];
] ; c = {x, y} /. Partition[Flatten, 2]; d = Select[c, FreeQ[#, Complex] &];
{e[j],f[j], g[j]} = FindClusters[d, 3, Method -> "Agglomerate"];
]

Now I have one more thing left to do. I have to calculate the surface area of those ellipses.

This is what I have so far:

surf[x_] :=
Do[k =
x[[i, 1]]*(x[[i + 1, 2]] - x[[i, 2]]) -
x[[i, 2]]*(x[[i + 1, 1]] - x[[i, 2]]), {i, 1, Length[x]}]

I was planning to use surf[] on every array I get out of FindClusters[] like this:

surf[e[55]] (55 is the number of a random source. Input file P55.txt gives me solutions e[55],f[55],g[55])

Somehow it's not working. Index i begins at 200 instead of 1, probably because I used i as index before. I thought by doing {i,1,Length[x]} it would reset it.

Anway, I'm trying to do the integral over those points. I need to calculate a cross product between coordinates of points and the distance between them. If anyone knows a faster way to do this, let me know.
 
  • #42
This is what I have now:

surf[x_] :=
k = Table[x[[i, 1]]*(x[[i + 1, 2]] - x[[i, 2]]) - x[[i, 2]]*(x[[i + 1, 1]] - x[[i, 2]]), {i, Length[x]}]

It still doesn't work and I don't know why. I really need help here.
 
  • #43
MartinV said:
It still doesn't work and I don't know why. I really need help here.

Restart the kernel.
Evaluate the whole notebook in order up to but just before where you are going to evaluate surf[].
Create two lines:

mydata=WhatEverItIs;
surf[mydata]

Delete everything else, evaluate those two lines and past the result here.
You want to guarantee that I can evaluate this and get exactly the same thing you get, without needing hundreds of files or thousands of data points or perhaps hundreds of lines of Mathematica that nobody but you has or knows what they do. Simplify it down to those two lines (actually WhatEverItIs just needs to be big enough to allow someone to discover what the problem really is, no more and no less).

I really need to see exactly what the details of your WhatEverItIs so I can try to tell you why it isn't working and what to try to do to hopefully fix it.
 
Last edited:
  • #44
My WhatEverItIs (the data I need to feed into surf) is 200 pairs of numbers. Part of it:

{{-1.00704, 0.433162}, {-1.00634, 0.436155}, {-1.00568,
0.43911}, {-1.00506, 0.442026}, {-1.00448, 0.444898}, {-1.00395,
0.447725}, {-1.00346, 0.450502}, {-1.00301, 0.453228}, {-1.00261,
0.455899}, {-1.00226, 0.458513}, {-1.00195, 0.461068}, {-1.00169,
0.463561}, {-1.00149, 0.465989}, {-1.00133, 0.468352}, {-1.00122,
0.470646}, {-1.00116, 0.472869}, {-1.00115, 0.47502}, {-1.00119,
0.477097}, {-1.00128, 0.479098}, {-1.00142, 0.481022}, {-1.00161,
0.482866}, {-1.00185, 0.484631}, {-1.00215, 0.486314}}

The output of surf[mydata] is:

0.496875, 0.501302, 0.50583, 0.510457, 0.515175, 0.519982, 0.524871, \
0.529837, 0.534875, 0.53998, 0.545145, 0.550365, 0.555634, 0.560946, \
0.566296, 0.571677, 0.577084, 0.58251, 0.587949, 0.593396, 0.598843, \
0.604286, 0.609718, -0.430136 (-0.430136 + {{-1.00704,
0.433162}, {-1.00634, 0.436155}, {-1.00568, 0.43911}, {-1.00506,
0.442026}, {-1.00448, 0.444898}, {-1.00395, 0.447725}, {-1.00346,
0.450502}, {-1.00301, 0.453228}, {-1.00261,
0.455899}, {-1.00226, 0.458513},

then in the middle I get this:

{-1.00779, 0.430136}}[[201, 1]]) - 1.00779 (-0.430136 + {{-1.00704, 0.433162}, {-1.00634, 0.436155},

Those intial numbers are probably what I'm looking for but I want a plain array of numbers. 200 lines in input, 200 lines in output. In truth I need the sum of those 200 output numbers but for now I would be happy if I just get those 200.
 
  • #45
Ah, good, we are finally making some progress.

You have a vector of 200 {x,y}.
Your surf has Table[x[[i, 1]]*(x[[i + 1, 2]] - x[[i, 2]]) - x[[i, 2]]*(x[[i + 1, 1]] - x[[i, 2]]), {i, Length[x]}].

Notice that i ranges over the length of your vector BUT your Table has x[[i+1,2]] and x[[i+1,1]] in it. Those are going to "subscript off the end" of your vector. Unless you have turned it off (you didn't actually show everything I asked for, input, output, error messages, etc, all the real raw stuff to help diagnose your problem) you should have gotten some error, perhaps like
Part::partw: "Part 201 of {YourHugeXList} does not exist.

So I don't know if this is really going to fix it, but you can have {i,Length[x]-1} so your Table doesn't try to reach beyond the end of your list. Or maybe you need to carefully think about your subscripting so you really use all the points and nothing beyond either end.

Does this help? See if you can fix your surf[] from this and if that doesn't fix everything then post another message with all the input and output and errors and what is wrong so we can track this down. And manually check that output data to make sure it is right or helps you track down what is wrong.
 
  • #46
MartinV said:
200 lines in input, 200 lines in output.

Since you appear to be doing something that you might think of as a "moving average" on pairs of points with 200 input points you are only going to get 199 output points.

Or is what you really want for the 200th output the "moving average" of point #200 and point #1? If so then perhaps an appropriately placed If[i<200,stuff,otherstuff] might be of interest.
 
Last edited:
  • #47
Ah, calling for a 201th line of array. No wonder it didn't work. I wrote it like this instead:

surf[x_] :=
Do[k = Append[k,
x[[i, 1]]*(x[[i + 1, 2]] - x[[i, 2]]) -
x[[i, 2]]*(x[[i + 1, 1]] - x[[i, 1]])], {i,1,Length[x] - 1},1]; k =
Append[k,
x[[Length[x], 1]]*(x[[1, 2]] - x[[Length[x], 2]]) -
x[[Length[x], 2]]*(x[[1, 1]] - x[[Length[x], 1]])];

I am attempting to create an array "k" that would store all the partial results one after the other. I used Append 199 times (if Length[x] is 200). Then I wrote another line that complets the circle by calculating the 200th and the 1st line and add it at the end of the array "k".

When I evaluate this definition, I get:

Part::partd: Part specification x[[0,1]] is longer than depth of object. >>

Part::partd: Part specification x[[1,2]] is longer than depth of object. >>

Part::partd: Part specification x[[0,2]] is longer than depth of object. >>

General::stop: Further output of Part::partd will be suppressed during this calculation. >>

I guess I'm still doing something wrong.
 
  • #48
First, your
Do[blahblahblah, {i,1,Length[x] - 1},1];
I cannot understand what that final ,1 is doing there and I suspect Mathematica cannot either. I assume that is just a typo and you need to remove that ,1. But it excellent that you appear to have posted all the actual code you are using along with the error messages, otherwise this would have been impossible to catch. But you didn't show any error message that would have resulted from that ,1 and I suspect that is again not showing enough to really tell what is going on.

Next, the precedence of ; and function definition I believe is making what you wrote something very different from what you might think. I do not believe both your Do and your final k=blahblahblah; are both part of your surf[x_] function. I believe your surf[x_] function ends at that ; I believe you are going to need () to override the precedence and get these to group the way I think you want. You can, for example, put a Print["oops"]; between those and see if it prints only when you use surf[yourdata] or if it prints the moment you define surf[x_]. If it does the latter that confirms it is not really a part of your surf[x_] definition.

Next, you haven't shown that k needs to be initialized, perhaps to {} or you will get, at least I get, more errors.

If all my guesswork about what I can't see that you have is correct then killing the kernel and restarting the calculation with my own dummy data I see the following:

In[1]:= yy=Table[{j,j+1},{j,1,200}];
surf[x_]:=
(k={};
Do[k=Append[k,x[[i,1]]*(x[[i+1,2]]-x[[i,2]])-x[[i,2]]*(x[[i+1,1]]-x[[i,1]])],{i,1,Length[x]-1}];
k=Append[k,x[[Length[x],1]]*(x[[1,2]]-x[[Length[x],2]])-x[[Length[x],2]]*(x[[1,1]]-x[[Length[x],1]])]
);
surf[yy]

Out[3]= {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,199}

Now my dummy data is completely meaningless, but I include it to show everything that went into and came out of the calculation.

You might also find Reap and Sow interesting tools to master.

yy=Table[{j,j+1},{j,1,200}];
surf[x_]:=
Reap[
Do[Sow[x[[i,1]]*(x[[i+1,2]]-x[[i,2]])-x[[i,2]]*(x[[i+1,1]]-x[[i,1]])],{i,1,Length[x]-1}];
Sow[x[[Length[x],1]]*(x[[1,2]]-x[[Length[x],2]])-x[[Length[x],2]]*(x[[1,1]]-x[[Length[x],1]])]
][[2,1]];
surf[yy]

This will give identical output but without needing your k to accumulate results and the quadratic slowdown associated with Append when you do this lots of times and in this case it would have accidentally avoided your precedence error in your function definition too.

Another technique you might consider when doing things like your "rolling average"

yy = Table[{j, j + 1}, {j, 1, 200}];
surf[x_] :=
Reap[
Do[Sow[x[[i, 1]]*(x[[Mod[i+1,Length[x],1], 2]] - x[[i, 2]]) - x[[i, 2]]*(x[[Mod[i+1,Length[x],1], 1]] - x[[i, 1]])], {i, 1, Length[x]}];
][[2, 1]];
surf[yy]

which you need to study to see all the small changes and test carefully to ensure it always gives exactly the same result.

You could also consider appending the first element of x to the end of x and then doing your "moving average" 200 times. But you will need to watch out when you do this and understand how function arguments really behave in Mathematica, they are not really "variables" that you can then assign new values to inside a function definition, but that a much deeper swimming pool than I want to try to explain at the moment.

All these are opportunities for you to consider how best to use data structures and algorithms to get your result correctly.
 
Last edited:
  • #49
I cannot understand what that final ,1 is doing there and I suspect Mathematica cannot either.

It's the unit of the count for i. I looked into Mathematica documentation and I thought I should add it to make sure it goes the way it was suppose to. Not necessary though.

I used the () and I think it's working now. Thanks for the help and your continuous patience. I keep mixing syntax from Matlab because I spent the most time using that.
 
  • #50
No.

In[1]:= Do[Print,{i,1,3},1]
From In[1]:= Do::itform : Argument 1 at position 3 does not have the correct form for an iterator.
Out[1]= Do[Print,{i,1,3},1]

That is not going to work, not unless you are not really showing what you actually have, which is a very very bad thing.

But either of these will work.

In[2]:= Do[Print,{i,1,3,1}]
From In[2]:= 1
From In[2]:= 2
From In[2]:= 3

In[3]:= Do[Print,{i,1,3}]
From In[3]:= 1
From In[3]:= 2
From In[3]:= 3

Stepsize is always optional and if not present defaults to 1
 

Similar threads

Replies
2
Views
1K
Replies
6
Views
4K
Replies
1
Views
2K
Replies
1
Views
2K
Replies
1
Views
2K
Replies
1
Views
2K
Replies
5
Views
2K
Replies
4
Views
1K
Back
Top