Message Boards Message Boards

0
|
7166 Views
|
6 Replies
|
3 Total Likes
View groups...
Share
Share this post:

Evaluate a variable inside an If clause?

Posted 7 years ago

This function

fn[x_]=Module[{ww},
 ww=ArcTan[x];
 If[x<ww,  ww,(*else*)  x ]
]

evaluates to

If[x < ArcTan[x], ww$375, x]

Why does the second occurrence of the local variable ww remain as a variable name instead of being evaluated like the first occurrence?

POSTED BY: Mark Alford
6 Replies

Do I understand it right that you want fn[z] to work even if z is a symbol (and thus the If function will not be evaluated)?

If so, use With:

Clear[fn]
fn[x_] := With[{ww = ArcTan[x]}, If[x < ww, ww, x]]

fn[z]
(* If[z < ArcTan[z], ArcTan[z], z] *)

See here: https://mathematica.stackexchange.com/questions/559/what-are-the-use-cases-for-different-scoping-constructs

One of the uses of With is injecting evaluated values.

Or perhaps what you want is fn to evaluate only with numbers:

Clear[fn]
fn[x_?NumericQ] := With[{ww = ArcTan[x]}, If[x < ww, ww, x]]
POSTED BY: Szabolcs Horvát
Posted 7 years ago

Thank you. You are right about wanting it to work with symbols. Using "With" is a good idea. Also I realized that "Piecewise" is appropriate:

fn[x_]=Module[{ww},                                                      
                 ww=ArcTan[x];                                                  
        Piecewise[{{ww,x<ww}},x]                                                
        ] 

evaluates to

Piecewise[{{ArcTan[x], x < ArcTan[x]}}, x]

which does what I wanted.

POSTED BY: Mark Alford

Yes, Piecewise is more suitable here because it is explicitly designed for symbolic computations. If is primarily for flow control when programming, but it tends to work with many symbolic math functions too.

POSTED BY: Szabolcs Horvát
Posted 7 years ago

If you look at the help page for If and you click on Details then you find

If[condition,t,f] is left unevaluated if condition evaluates to neither True nor False.

Mathematica recognized your If and then evaluated your condition to try to determine whether it was True or False. To do that it evaluated x and the local variable ww, to do that it determined that ww had been assigned the value ArcTan[x]. You have not assigned a value to x and so the value of x<ArcTan[x] is just x<ArcTan[x]. That is neither True nor False and thus it evaluates nothing further and the result is If[x<ArcTan[x], ww, x]

POSTED BY: Bill Simpson
Posted 7 years ago

If[condition,t,f] is left unevaluated if condition evaluates to neither True nor False.

I see, that's the reason. So I need to explicitly tell mathematica to evaluate it, e.g.

fn[x_]=Module[{vv,ww},
 ww=ArcTan[x];
 If[x<ww, Evaluate[ww], Evaluate[ (x+ww)/2 ]
]

which yields the desired result

If[x < ArcTan[x], ArcTan[x], (x + ArcTan[x])/2]

Similarly, with a Which statement I need to sprinkle Evaluate in the right places:

fn[x_]=Module[{ww,yy},
 ww=ArcTan[x];
 yy=Exp[x];
 Which[
  x<0, Evaluate[ww],
  Evaluate[x<ww], Evaluate[yy],
  True, Evaluate[2*yy]
 ]
]

which yields the desired result

Which[x < 0, ArcTan[x], x < ArcTan[x], E^x, True, 2*E^x]

Thank you.

POSTED BY: Mark Alford

You need := in your definition because the = tries to evaluate everything in the assign immediately (which it can't). You need the delayed assignment.

To be clear: do fn[x_]:= ...

POSTED BY: Neil Singer
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract