Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

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?

share|improve this question
2  
Evaluate overrides only Hold-attributes of heads immediately enclosing it, but you have another layer here (MatchQ). This discussion might help. –  Leonid Shifrin May 6 '12 at 11:49
    
thanks for the link: yes, a useful and comprehensive discussion on lexical vs dynamic scoping. –  NCM May 7 '12 at 2:02
add comment

2 Answers

up vote 7 down vote accepted

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}]]
share|improve this answer
    
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 6 '12 at 14:57
    
@NCM: Thank you for the accept. –  celtschk May 6 '12 at 16:01
add comment

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}]
share|improve this answer
    
RegionPlot[Im[Sqrt[1 - (x^2 + y^2)]] == 0, ...] works as well. –  Heike May 6 '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 7 '12 at 2:08
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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