2
$\begingroup$

I have some function definitions that ultimately define an equality through Solve and Replace:

Curve[p_] := w1*x^p + w2*y^p; (* some function with parameters *)
ComputeWeights[p1_, p2_, p_] := (* compute w1 and w2 through Solve *)
  Solve[w1 == 1 - w2 && 
     w1*p1[[1]]^p + w2*p1[[2]]^p == w1*p2[[1]]^p + w2*p2[[2]]^p, {w1, 
     w2}][[1]];
MyCurve[p1_, p2_, p_] := Curve[p] /. ComputeWeights[p1, p2, p];
MyConstant[p1_, p2_, p_] := 
  MyCurve[p1, p2, p] /. {x -> p1[[1]], y -> p1[[2]]};
MyEquality[p1_, p2_, p_] := 
  MyCurve[p1, p2, p] == MyConstant[p1, p2, p];

Now, I can use the defined equality:

t1 = {0.2, 0.5}; t2 = {0.6, 0.3}; MyEquality[t1, t2, 10]

which correctly outputs

0.138326 x^10 + 0.861674 y^10 == 0.000841493

If I try to graph this with a ContourPlot, it works fine:

(* ok *) ContourPlot[0.138326 x^10 + 0.861674 y^10 == 0.000841493, {x, 0, 1}, {y, 0, 1}]

However, if I embed the MyEquality function in ContourPlot (which is the reason why I defined it in the first place) it no longer works (I see an empty square, but no curve):

(* ko *) ContourPlot[MyEquality[t1, t2, 10], {x, 0, 1}, {y, 0, 1}]

Strangely enough, it works if I use a function for the lhs of the equality:

(* ok *) ContourPlot[MyCurve[t1, t2, 10] == 0.000841493, {x, 0, 1}, {y, 0, 1}]

but not if I use a function for the rhs:

(* ko *) ContourPlot[0.138326 x^10 + 0.861674 y^10 == MyConstant[t1, t2, 10], {x, 0, 1}, {y, 0, 1}]

There must be something profound I don't understand about replacements and equalities (and possibly function definitions) in Mathematica. What is the problem here?

$\endgroup$
2
$\begingroup$

Wrap the first argument of ContourPlot with Evaluate:

ContourPlot[Evaluate@MyEquality[t1, t2, 10], {x, 0, 1}, {y, 0, 1}]

enter image description here

Notes:

ContourPlot (and all *Plot functions) have the Attribute HoldAll, that is, all arguments are maintained in an unevaluated form.

So, in a simpler example,

eqn = Cos[x] == Cos[y]; 
ContourPlot[eqn, {x, 0, 4 Pi}, {y, 0, 4 Pi}] 

does not produce anything because ContourPlot sees eqn not Cos[x] == Cos[y]. Forcing evaluation of eqn by wrapping it with Evaluate,

 ContourPlot[Evaluate@eqn, {x, 0, 4 Pi}, {y, 0, 4 Pi}]

works as if we used

 ContourPlot[Cos[x] == Cos[y], {x, 0, 4 Pi}, {y, 0, 4 Pi}]
$\endgroup$
  • $\begingroup$ Great, thanks! But what is it that prevents the resulting expression to be evaluated, i.e., why do I have to force evaluation? $\endgroup$ – Maiaux Nov 29 '18 at 17:43
  • 1
    $\begingroup$ @Maiaux, ContourPlot (and all *Plot functions) have the Attribute HoldAll ( that is, all arguments to a function are maintained in an unevaluated form.) So, in a simpler example, eqn = Cos[x] == Cos[y]; ContourPlot[eqn, {x, 0, 4 Pi}, {y, 0, 4 Pi}] does not produce anything because ContourPlot sees eqn not Cos[x] == Cos[y]. Forcing evaluation of eqn by wrapping it with Evaluate, (ContourPlot[Evaluate@eqn, {x, 0, 4 Pi}, {y, 0, 4 Pi}]) works as if we used ContourPlot[Cos[x] == Cos[y], {x, 0, 4 Pi}, {y, 0, 4 Pi}]. Hope this helps. $\endgroup$ – kglr Nov 29 '18 at 18:23
  • $\begingroup$ ... See also Evaluate in the docs. $\endgroup$ – kglr Nov 29 '18 at 18:23
  • $\begingroup$ Thanks @kglr. However I now wonder why my third example works (and the last one doesn’t), even without forcing evaluation. After all, they both have some parts that need to be evaluated... $\endgroup$ – Maiaux Nov 29 '18 at 22:28
  • $\begingroup$ @Maiaux, it is puzzling. I don't know the answer otomh. Maybe, if you have patience, Trace[ContourPlot[...]] with the two inputs might reveal something about the difference. $\endgroup$ – kglr Nov 29 '18 at 23:06

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.