6
$\begingroup$

Suppose I make the following function to plot contour lines for a complex function:

ContourRe[Func_, xrange_, yrange_, Nlines_: 30, size_: 400] := ContourPlot[Re[Func[x + I*y]],
{x, xrange[[1]], xrange[[2]]}, {y, yrange[[1]], yrange[[2]]}, 
ContourShading -> False, Contours -> Nlines, ContourStyle -> Red, ImageSize -> size]

How can I generalize it so that the input function Func can have additional parameters? For example I have:

F1[z_]:=Exp[z]+3*I
F2[z_,a_:-2]:=a*Exp[z]

How should I modify ContourRe so that it can take both F1 and F2 as arguments and plot them?

It is like in python in which many of the built-in scipy functions have args={} for us to specify any parameters associated with the input function. In mathematica there are things like OptionsPattern and OptionValue, but after looking at the documentations I don't really know how to use them in this specific example.

$\endgroup$

2 Answers 2

6
$\begingroup$

I would use SubValues: define your functions with more than one []. This both makes it easier to write the plotting function, and it keeps the conceptually two different things, parameters and variables, separate.

f2[a_:-2, b_:0][z_] := a*Exp[z] + b

contourRe[fu : (func_[args__] | func_), xrange_, yrange_, nLines_: 30, size_: 400] := ContourPlot[Re[fu[x + I*y]],
{x, xrange[[1]], xrange[[2]]}, {y, yrange[[1]], yrange[[2]]}, 
ContourShading -> False, Contours -> nLines, ContourStyle -> Red, ImageSize -> size]

I changed the variable names to start with lower-case, both to avoid clashes with built-ins, and to make autocompletion more useful :) Now both

contourRe[f2[], {-2, 2}, {-3, 3}]

and

contourRe[f2[3,4], {-2, 2}, {-3, 3}]

work. Functions without parameters also work, e.g.

contourRe[Sin, {-2, 2}, {-3, 3}]
$\endgroup$
7
  • $\begingroup$ ,Wouldn't a_:1 make more sense? $\endgroup$
    – Feyre
    Commented Aug 10, 2016 at 9:59
  • $\begingroup$ @Feyre, I just copied the a parameter from OP's F2 :p $\endgroup$ Commented Aug 10, 2016 at 10:27
  • $\begingroup$ Thanks. This is what I am looking for. But even if the input function has no parameters, I still need to define it as func[]this method requires all the function to be defined as func[][z_]:=Log[z]? Are there any possible ways to handle cases like func[z_]:=Log[z] instead? $\endgroup$
    – Physicist
    Commented Aug 10, 2016 at 10:30
  • $\begingroup$ Sure, just copy-paste the definition I made, remove [args___] from both the LHS and RHS, and evaluate it. This does not overwrite the definition I made, it will just add another use-case. Since Mathematica tries more specific rules first, it will work. $\endgroup$ Commented Aug 10, 2016 at 10:42
  • $\begingroup$ I've made an update to my answer that I think is even better. $\endgroup$ Commented Aug 10, 2016 at 10:53
3
$\begingroup$

I would refashion the plotting procedure to accept pure functions. Note that the range values (like x1) can be captured within parameter definition.

plot[f_Function, {x1_, x2_}, {y1_, y2_}, nLines_: 30, size_: 150] :=
 ContourPlot[Re[f[x + I y]], {x, x1, x2}, {y, y1, y2},
  ContourShading -> False,
  Contours -> nLines,
  ContourStyle -> Red,
  ImageSize -> size]

Then:

(* f1 = Exp[#] + 3 I &; *)
f1 = Function[z, Exp[z] + 3 I];

f2[a_: - 2] := Function[z, a Exp[z] + Sin[a z]]

plot[f1, {-5, 5}, {-5, 5}]

enter image description here

(* f2[] is the call with default a, not just f2 *)
plot[f2[.2], {-5, 5}, {-5, 5}]

enter image description here

plot[10 Log[#] &, {-5, 5}, {-5, 5}]

enter image description here

$\endgroup$

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.