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$ 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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.