Message Boards Message Boards

0
|
2298 Views
|
2 Replies
|
2 Total Likes
View groups...
Share
Share this post:

An attempt to make an exprssion shorter and neater

Posted 1 year ago

I have the following expression:

Show[
 ParametricPlot[
  Table[
   {u[j]},
   {j, Min[Im@z1, Im@z2], Max[Im@z1, Im@z2]}]
  , {t, 0, 1}]
 ,
 ParametricPlot[
  Table[
   v[j],
   {j, Min[Re@z1, Re@z2], Max[Re@z1, Re@z2]}]
  , {t, 0, 1}]
 ]

I am not showing the explicit meaning of u and v to de-clutter the idea of the question.

As you can see the limits for the iterator j of the two Tables make use of Min and Max in a very similar way, once with the Im and once with the Re of z1 and z2.

My question is if I can make this expression look neater and more concise, together with the fact that the limits for ParametricPlot is {t,0,1} in both of them.

Any idea or suggestion would be very welcome.

POSTED BY: Ehud Behar
2 Replies

It is somewhat tricky to unify the similar constructs, because Table must be kept from evaluating too soon. Here is an attempt, probably not so readable:

With[{z = {1 + I, -1 - 2 I},
  u = {t + #, #} &, v = {t - #, t^2 #} &},
 Flatten[
  tbl[f[j], {j, Splice[MinMax[g /@ z]]}] /.
    {{f -> u, g -> Im},
     {f -> v, g -> Re}} /.
   tbl -> Table,
  1];
 ParametricPlot[%, {t, 0, 1}]]
POSTED BY: Gianluca Gorni

Sometimes shorter is clearer but at some point shorter is less clear.

First you can combine the two plots into one. Normally Show[plot1, plot2] takes some characteristics from plot1 and ignores any differences in plot2, most notably PlotRange. If the plot range of plot1 does not contain the range of plot2, then plot2 will be cut off. The workaround is to add an explicit PlotRange option to Show. With a single combine ParametricPlot[..], the plot range will be computed for all the functions. Normally that means asymptotes and large spike are truncated, which in many cases is seen as a benefit of PlotRange -> Automatic over PlotRange -> All.

ParametricPlot[
 Join[
  Table[u[j],
   {j, Min[Im@z1, Im@z2], Max[Im@z1, Im@z2]}],
  Table[v[j],
   {j, Min[Re@z1, Re@z2], Max[Re@z1, Re@z2]}]],
 {t, 0, 1}, Evaluated -> True]

From here it's not clear whether there are any significant improvements. The Min, Max, Re, Im can be restructured, but it's not clear to me that everyone would agree it's so much better that it's worth. I'll show them anyway, since they might be interesting. A standard change, the preference for which depends one's programming style, is to replace Table with Map. Another thing that seems an improvement is CoordinateBoundingBox, which simplifies all the Min, Max, Re, Im stuff; but using its result is more complicated. Perhaps some will like it and others will think it's at best a wash.

Each of the following is to replace the first argument of ParametricPlot:

(* Map (/@) instead of Table *)
Join[
 u /@ Range[Min[Im@z1, Im@z2], Max[Im@z1, Im@z2]],
 v /@ Range[Min[Re@z1, Re@z2], Max[Re@z1, Re@z2]]
 ]

(* CoordinateBoundingBox *)
Join @@ MapThread[#1 /@ Range @@ #2 &,
  {{u, v},
   Transpose@CoordinateBoundingBox[ReIm@{z1, z2}]}
  ]

(* The height of obfuscation *)
Join @@ MapThread[Map,
  {{u, v},
   Range @@@ Transpose@CoordinateBoundingBox[ReIm@{z1, z2}]}
  ]

If u and v are Listable, then we can do better (or worse):

Join @@ {u@#1, v@#2} & @@ 
 Range @@@ Transpose@CoordinateBoundingBox@ReIm@{z1, z2}

Numerical example:

Block[{z1 = 1 + 2 I, z2 = 5 - 3 I},
 Join @@ MapThread[Map,
   {{u, v},
    foo = Range @@@ Transpose@CoordinateBoundingBox[ReIm@{z1, z2}]}
   ]
 ]
(*  {u[1], u[2], u[3], u[4], u[5], v[-3], v[-2], v[-1], v[0], v[1], v[2]}  *)

foo
(*  {{1, 2, 3, 4, 5}, {-3, -2, -1, 0, 1, 2}}  *)

We saved the intermediate result of Range @@@... in foo just to show what that piece of code does.

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

Group Abstract Group Abstract