1

Here is an example function which returns True if a point p is on an (open) line segment (A, B) assuming that Orientation[A, p, B] returns 0 if the three points are collinear:

PointIsOnSegment[p_, A_, B_] := 
    If[Orientation[A, p, B] != 0 || SquaredEuclideanDistance[A, p] > SquaredEuclideanDistance[A, B] || SquaredEuclideanDistance[B, p] > SquaredEuclideanDistance[A, B], False, True];

So, if the point is on the line segment, this function evaluates SquaredEuclideanDistance[A, B] twice. So if we wanted to compute it only once, we could either use a Module or Block, like:

PointIsOnSegment[p_, A_, B_] := Block[{sqDistAB = SquaredEuclideanDistance[A, B]},
    If[Orientation[A, p, B] != 0 || SquaredEuclideanDistance[A, p] > sqDistAB || SquaredEuclideanDistance[B, p] > sqDistAB, False, True]];

Or we could use an anonymous function:

PointIsOnSegment[p_, A_, B_] := 
    If[Orientation[A, p, B] != 0 || SquaredEuclideanDistance[A, p] > # || SquaredEuclideanDistance[B, p] > #, False, True] &[SquaredEuclideanDistance[A, B]];

What I want to know is which method should be preferred in terms of efficiency? Keep in mind that this is a very simple example, but I have in mind slightly more complex functions where several intermediate values (like distSqAB above) need to be computed once and then used in the final return value.

Part of this stems from my coming from an imperative background and trying to learn to program mathematica in a functional style (so I am tending more towards the third option above), but I wanted to know if I'm create unnecessary work for myself (since excessive use of anonymous functions quickly becomes unreadable).

John
  • 165
  • 5
  • In this specific case, With is more idiomatic than Block. However, I don't think you'd see a performance difference here (or in general) that should require your attention... more often than not, the bottleneck in your code will be elsewhere. – rm -rf May 24 '13 at 14:05
  • As rm said, this is a typical use for With, not Block or Module. Block/Module create mutable local variables, With/Function only allow using constants. Function is also a closer analog of With because both can inject expressions into a held expression. Personally I find With more readable than Function but I know that some people would use Function... Regarding performance, why don't you just measure? My hunch is that With will be marginally faster than Module/Block because it spares some evaluation steps, but I might be wrong. – Szabolcs May 24 '13 at 14:31

0 Answers0