Group Abstract Group Abstract

Message Boards Message Boards

0
|
9.3K Views
|
5 Replies
|
6 Total Likes
View groups...
Share
Share this post:

Generalize a function that finds distance between 2 pairs of coordinates?

Posted 9 years ago
POSTED BY: Brandon Davis
5 Replies

One comment though,

A recursive solution is "not so nice" only because Mathematica is not a true functional language (in spite of the fact that it supports functional programming style). In functional languages (e.g., Erlang, Clojure, F# etc.) recursion is the only way to implement iterations (well, almost the only way, there is list comprehension) . This is especially true if that language supports pattern matching (e.g., Erlang, but certainly far from the level of Mathematica) and tail recursion optimization. However, in Mathematica this is not the case. I have tackled many cases were the adoption of tail recursion is unsuccessful or very inefficient, and Sander'c comments are certainly right for large problems.

yehuda

Though the solution of both are working, there are also other methods. The method of Yehuda is recursive which is not that nice, and can therefore not be parallelised easily. I see wo other ways of doing it:

ClearAll[distance];
distance[{{x1_,y1_},{x2_,y2_}}]:=Abs[(x2-x1)]+Abs[(y2-y1)];
totaldistance[x:{{_,_}..}]:=Total[distance/@Partition[x,2,1,{-1,1},{{0,0}}]]

similar to the above 2 replies. But one can also do it like this:

ClearAll[distance];
ClearAll[distance];
distance[{\[CapitalDelta]x_,\[CapitalDelta]y_}]:=Abs[\[CapitalDelta]x]+Abs[\[CapitalDelta]y];
totaldistance[x:{{_,_}..}]:=Total[distance/@Differences[Join[{{0,0}},x,{{0,0}}]]]

or even:

ClearAll[totaldistance];
totaldistance[x:{{_,_}..}]:=Total[Abs[Differences[Join[{{0.0,0.0}},x,{{0.0,0.0}}]]],\[Infinity]]

Note that prepending/appending 0.0 instead of 0 can make a big difference depending on the input data. Especially if it is a packed array of a certain type. The last one will be the fastest as it does not use Map, and everything is vectorized (assuming real numbers, not symbolic calculation, and 'large' number of points).

POSTED BY: Sander Huisman

This does not implement the distance from the origin {0,0} as the OP asked for... You need {0,0} and {0,0} at the beginning and the end of the list before partitioning it. So, use

Partition[{pts__List},2,1,{-1,1},{{0,0}}]

yehuda

You can use Partition to divide your path into couples of successive points, and then map distance on the couples:

Clear[distance];
distance[{{x1_, y1_}, {x2_, y2_}}] := Abs[x2 - x1] + Abs[y2 - y1];
distance[{pts__List}] := 
 Total[Map[distance, Partition[{pts}, 2, 1, 1]]]

The parameters 2, 1, 1 given to Partition mean that the sublists will be of length 2, with overhang 1, and the last point will appear as the first element in the last couple, with the second element taken from the beginning of the path. It's complicated. I hope I didn't mix it up.

POSTED BY: Gianluca Gorni
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard