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$

2 Answers 2

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$
1
  • $\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$ Commented Jan 7, 2017 at 21:04
5
$\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$
3
  • $\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$ Commented Jan 8, 2017 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
    Commented Jan 8, 2017 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$ Commented Jan 8, 2017 at 7:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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