6

I am trying to plot the region over which a function of two (real) parameters a and b is real-valued, using RegionPlot and MatchQ. In general this will be a complicated function with real and complex parts, but to illustrate the query I will use a simple function, a^2 + b^2:

RegionPlot[MatchQ[(a^2 + b^2), _Real],{a,-2,2},{b,-2,2}]

As expected, RegionPlot colors the whole region. This is because RegionPlot presumably evaluates its predicate - here MatchQ - on the a,b mesh before plotting, so that the expression a^2+b^2 in MatchQ is manifestly real, i.e. the Head of the resulting expression is Real and MatchQ evaluates to True. On its own however, with no contextual information on a or b,

MatchQ[(a^2 + b^2), _Real]

evaluates to

False

as expected. Now if I replace a^2+b^2 with

Evaluate[Expand[(a + I b) (a - I b)]]

i.e.

RegionPlot[MatchQ[Evaluate[Expand[(a + I b) (a - I b)]], _Real],{a,-2,2},{b,-2,2}]

RegionPlot displays a completely blank region (also the case for ComplexExpand). Since Evaluate should have presumably overridden the HoldAll attribute of RegionPlot, I would have expected the expression to evaluate to Real and therefore for the MatchQ to evaluate to True, so why doesn't RegionPlot display the region in this case?

rm -rf
  • 88,781
  • 21
  • 293
  • 472
NCM
  • 63
  • 2

2 Answers2

7

As it turns out, the Evaluate is only evaluated immediately if it is top level in the argument, as the following code shows:

ClearAll[test];SetAttributes[test,HoldAll];test[x_]:=Hold[x]
test[Evaluate[1+1]]
(*
==> Hold[2]
*)
test[f[Evaluate[1+1]]]
(*
==> Hold[f[Evaluate[1+1]]]
*)

Since in your code it is not top level, it is passed on together with the rest of the expression to RegionPlot. It is evaluated at a point where the variables already have numerical values. And this gives a complex result with imaginary part numerically zero, as the following proves:

ClearAll[f];SetAttributes[f,HoldAll];f[x_]:=Block[{a=1.,b=1.},x]
f[Head[Evaluate[(a+I b)(a-I b)]]]
(*
==> Complex
*)
f[(a+I b)(a-I b)]
(*
==> 2.+0. I
*)

You can get rid of the numerically zero imaginary part by using Chop:

RegionPlot[MatchQ[Chop@Evaluate[Expand[(a+I b) (a-I b)]],_Real],{a,-2,2},{b,-2,2}]

More generally, to evaluate just part of an expression passed to a function with HoldAll attribute, you can use With:

With[{expr=Expand[(a+I b)(a-I b)]},
     RegionPlot[MatchQ[expr,_Real],{a,-2,2},{b,-2,2}]]
celtschk
  • 19,133
  • 1
  • 51
  • 106
  • Many thanks: I suspect Chopping will likely be required with the actual function concerned so appreciate the pointer. Useful tip on the evaluation sequence. – NCM May 06 '12 at 14:57
  • @NCM: Thank you for the accept. – celtschk May 06 '12 at 16:01
2

I haven't tried to fix your code, but I suppose I would try to plot the region like so

RegionPlot[Sqrt[1 - (x^2 + y^2)] == 
  Re[Sqrt[1 - (x^2 + y^2)]], {x, -2, 2}, {y, -2, 2}]

Or even using DensityPlot, which only plots spots where the function is real.

DensityPlot[Sqrt[1 - (x^2 + y^2)], {x, -2, 2}, {y, -2, 2}]
Mark McClure
  • 32,469
  • 3
  • 103
  • 161
  • RegionPlot[Im[Sqrt[1 - (x^2 + y^2)]] == 0, ...] works as well. – Heike May 06 '12 at 12:48
  • thanks - the function in my example wasn't so important really and in practice will be much more complicated anyway; I wanted to understand the evaluation mechanism which (I think) I now do. – NCM May 07 '12 at 02:08