3
$\begingroup$

I am trying to visualize polynomials of complex variables inside a "manipulate" environment. I adapted the solution suggested by Michael to one of my previous questions to use a polynomial a user enters in an input field, but I don't get the syntax right. Instead of the usual representation using colors, I try to only plot the real part of the graph, where the imaginary part is close to 0. I use the following code, but I get an error message, where Mathematica tries to interpret my region function.

Manipulate[
With[{f = ReleaseHold[xx /. HoldPattern[tt_ /; MatchQ[tt, Symbol["z"]]] :> x + I*y]},
With[{fReal = Re@f, fIm = Im@f},
Plot3D[fReal, {x, -xmax, xmax}, {y, -xmax, xmax}, 
 RegionFunction -> Function[{x, y, z}, -0.1 < fIm < 0.1], 
 PerformanceGoal -> "Quality"]
]],
{xmax, 1, 10},
{{xx, Unevaluated[z^2], "w(z)="}, InputField[#, Hold[Expression]] &},
{{z, Unevaluated[z]}, ControlType -> None}, 
Initialization :> (MakeBoxes[z, form_] := FormBox["z", form]) ]

Can someone please explain me how to properly define the RegionFunction?

$\endgroup$
3
$\begingroup$

In terms of your RegionFunction you have this expression:

Function[{x, y, z}, -0.1 < fIm < 0.1]

But Mathematica renames the variables so that, for example, the original x and the Function x do not collide. But this means you can't do something like fIm/.{x->x, y->y}, obviously.

Thus you will want to use a different set of variable names as your function argument. For example try:

Function[{x$, y$, z}, -0.1 < fIm/.{x->x$, y->y$} < 0.1]

As for the replacement of z, it wasn't occurring for me. What you can do instead is look for any appropriate z symbol and simply replace that.

Knowing that Manipulate turns f into FE`f$$nn where nn is the front-end equivalent of $ModuleNumber we can just use this:

xx /.
 s_Symbol?(StringMatchQ[ToString@#, "FE*z*" | "z"] &) :> (x + 
    I*y)

Then combining all of this:

Manipulate[
 With[{f =
    ReleaseHold@xx /.
     s_Symbol?(StringMatchQ[ToString@#, "FE*z*" | "z"] &) :> (x + I*y)},
  With[{fReal = Re@f, fIm = Im@f},
   Plot3D[fIm, {x, -xmax, xmax}, {y, -xmax, xmax}, 
    RegionFunction -> 
     Function[{x$, y$, z}, -0.1 < (fIm /. {x -> x$, y -> y$}) < 0.1], 
    PerformanceGoal -> "Quality"]]],
 {xmax, 1, 10}, {{xx, Unevaluated[z^2], "w(z)="}, 
  InputField[#, Hold[Expression]] &}, {{z, Unevaluated[z]}, 
  ControlType -> None}, 
 Initialization :> (MakeBoxes[z, form_] := FormBox["z", form])
 ]
$\endgroup$
  • $\begingroup$ Thank you very much, this is very helpful. In my original code, the z-replacement does not work when I first run the code, but it does work if I redefine the function in the input box. I could not figure out the reason for this, but since this was not a major issue, I did not want to ask two questions at the same time. Your solution fixed this problem, too, thanks. $\endgroup$ – Ferenc Beleznay Jan 7 '17 at 21:04
4
$\begingroup$

Here's a variation on how to keep z localized when InputField returns an expression in terms of Global`z: We'll use Slot to avoid having to localize x and y. We'll also alter the replacement pattern little to avoid an evaluation leak that was causing a problem in code in the OP. Well, the problem is that the z in the initialization of xx gets mapped to the Manipulate local FE`z$$ instead of Global`z. One possibility is to use Alternatives to catch both cases. Below we'll just reinitialize xx in terms of Global`z.

x = y = z = 0;  (* to check independence of `Manipulate` symbols *)

Manipulate[
 With[{f = ReleaseHold[
     xx /. HoldPattern[tt_ /; MatchQ[Hold@tt, ToExpression@"Hold[z]"]] :> #1 + I*#2]},
  With[{fReal = Re@f, fIm = Im@f},                  (* see Note below *)
   Plot3D[fReal &[x, y],
    {x, -xmax, xmax}, {y, -xmax, xmax},
    RegionFunction -> Function[{x, y, z}, -0.1 < (fIm &[x, y]) < 0.1],
    PerformanceGoal -> "Quality", PlotLabel -> z]
   ]],
 {xmax, 1, 10},
 {{xx, Hold[z^2], "w(z)="}, InputField[#, Hold[Expression]] &},
 {{z, Unevaluated[z]}, ControlType -> None},
 Initialization :>
  (z /: MakeBoxes[z, form_] := FormBox["z", form];  (* format FE`z$$ as z in output *)
   xx = ToExpression@"Hold[z^2]";)                  (* put xx in terms of Global`z *)
 ]

Mathematica graphics

Manual check of output (recommended, when Manipulate is rewriting code hidden behind the scenes):

Plot3D[Re[(x + I y)^2], {x, -1, 1}, {y, -1, 1}, 
 RegionFunction -> Function[{x, y, z}, -0.1 < Im[(x + I y)^2] < 0.1], 
 PerformanceGoal -> "Quality"]

Mathematica graphics

Note: Some might find this a more comfortable coding style:

With[{fReal = Evaluate@Re@f &, fIm = Evaluate@Im@f &},...
  ...fReal[x, y],...
    ... < fIm[x, y] < ...
$\endgroup$
  • $\begingroup$ I would like to ask one more question. I saved the output as a CDF file (I would like to show it to people without access to Mathematica), but in the CDF file the content of the input box does not change the graph. I always see the the grapf of z^2 no matter I write in the input box. Is this a bug in the CDF player (I use version 10) or do I need to change something in the code? $\endgroup$ – Ferenc Beleznay Jan 8 '17 at 0:26
  • $\begingroup$ @FerencBeleznay I believe that unfortunately, the CDF format does not support the full range of functionality of Mathematica. In particular, InputField is restricted to numbers as input only. I think the "Enterprise" CDF player will allow more types of input, but I don't have it to check. $\endgroup$ – Michael E2 Jan 8 '17 at 0:29
  • $\begingroup$ This is indeed unfortunate. This makes it pointless for me to use the input box this way. I need to rework everything to input coefficients instead of the full function. It would have been nice to be able to visualize more general functions, though. $\endgroup$ – Ferenc Beleznay Jan 8 '17 at 7:26
0
$\begingroup$

The OP mentioned CDFs in a comment, which suggested this alternative, which seems an easier way to localize symbols to be used in function expressions than my other answer. The idea is to localize the context with the option CellContext -> Cell. This simplifies the programming quite a bit. Of course with the free CDF player, one still cannot enter expressions into the InputField (see http://www.wolfram.com/cdf/adopting-cdf/cdf-and-mathematica-comparison.en.html).

xmax = xx = x = y = z = -1;  (* to check code independence *)

Block[{z},                   (* to block the value of  z  being used to initialize  w *)
 CellPrint@ExpressionCell[

    Manipulate[
     With[{f = w /. z -> x + I y},
      With[{fReal = Re@f, fIm = Im@f},
       Plot3D[fReal, {x, -xmax, xmax}, {y, -xmax, xmax},
        RegionFunction -> (-0.1 < fIm < 0.1 /. {x -> #1, y -> #2} &),
        PerformanceGoal -> "Quality",
        PlotLabel -> HoldForm[Evaluate@Symbol["f"]][z] == f]  (* to check expressions *)
       ]],
     {xmax, 1, 10},
     {{w, z^2, "w(z)="}, InputField[#, Expression] &}
     ],

    "Output",
    CellContext -> Cell];
 ]

As a variation, instead of using Block[{z},..], which highlights all the z in red, one can use $CellContext`. Instances of z in the body, which are evaluated only in the front-end DynamicModule at run-time, will be assigned the correct context; however, one can use $CellContext`z and it will still work.

CellPrint@ExpressionCell[

   Manipulate[
    With[{f = w /. z -> x + I y},       (* $CellContext`z works here too *)
     With[{fReal = Re@f, fIm = Im@f},
      Plot3D[fReal, {x, -xmax, xmax}, {y, -xmax, xmax},
       RegionFunction -> (-0.1 < fIm < 0.1 /. {x -> #1, y -> #2} &),
       PerformanceGoal -> "Quality",
       PlotLabel -> HoldForm[Evaluate@Symbol["f"]][z] == f]
      ]],
    {xmax, 1, 10},
    {{w, $CellContext`z^2, "w(z)="}, InputField[#, Expression] &}  (* N.B. *)
    ],

   "Output",
   CellContext -> Cell];

Further note: Strangely, the CDF works in Mathematica but not in CDF player. In particular, the contexts of the symbols z are treated differently in CDF player. In CDF player, at least one symbol z is given the Global` context (because it is printed in the label of the plot). However, the substitution z -> x + I y is not performed, suggesting that z has a different context. One can get around this with the circumlocution

f = w /. zz_Symbol /; SymbolName[zz] === "z" -> x + I y

(but one still cannot use the InputField in CDF anyway, without the Enterprise edition of the CDF player).

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.