Group Abstract Group Abstract

Message Boards Message Boards

0
|
10.2K Views
|
10 Replies
|
1 Total Like
View groups...
Share
Share this post:

Evaluation within If or Which

Posted 10 years ago

For these pieces of code how can I "r" evaluated. When I use If "r" remains unevaluated. When I use Which "r" is only evaluated when the first case is True. Can I get some help? Thanks

Clear[aa, bb, fIf, r];
fIf[u_, v_] := Block[{aa = u + v + w, bb = 2 u - v - w},
  If[bb > aa, r = BB];
  If[aa > bb, r = AA];
  If[aa == bb, r = AB];
  {aa, bb, r}
  ]
{fIf[2, 2], fIf[2, 1], fIf[2, 0]} //. w -> -1
{fIf[2, 2], fIf[2, 1], fIf[2, 0]} //. w -> 0
{fIf[2, 2], fIf[2, 1], fIf[2, 0]} //. w -> 1

Clear[aa, bb, r1, r2, r3];
fWhich[u_, v_] = Block[{aa = u + v + w, bb = 2 u - v - w},
   r1 = Which[aa == bb, AB, aa > bb, AA, bb > aa, BB];
   r2 = Which[aa > bb, AA, aa == bb, AB, bb > aa, BB];
   r3 = Which[bb > aa, BB, aa > bb, AA, aa == bb, AB];
   {aa, bb, r1, r2, r3}
   ];
{{"aa", "bb", "r1", "r2", "r3"}, fWhich[2, 1], fWhich[2, 2],    fWhich[2, 0]} //. w -> -1 // MatrixForm
{{"aa", "bb", "r1", "r2", "r3"}, fWhich[2, 1], fWhich[2, 2],    fWhich[2, 0]} //. w ->  0 // MatrixForm
{{"aa", "bb", "r1", "r2", "r3"}, fWhich[2, 1], fWhich[2, 2],    fWhich[2, 0]} //. w ->  1 // MatrixForm
POSTED BY: Alain RIWAN
10 Replies
Posted 9 years ago

I'm interpreting your question to be: "Does Mathematica use 'which' where other languages use 'then', and does Mathematica use 'switch' where other languages use 'else'?"

The answer is "no".

Mathematica has an If[...] form, and it is analogous to the if {...} else {...} branching structure of procedural languages like Java.

Mathematica has a Swich[...] form, and it is analogous to the switch {case ...} branching structure of procedural languages like Java.

Mathematica has a Which[...] form, and I think most procedural languages like Java have no analog to it. It is basically the same as cond from Lisp.

POSTED BY: Eric Rimbey

Is which used in place of then and switch used in place of else? Or am I working with these ideas incorrectly. I am new to programming.

POSTED BY: Leighton Cooper
Posted 10 years ago

Thanks. I'm pretty sure I tried it at first and it didn't work!!!

POSTED BY: Alain RIWAN
Posted 10 years ago

Well, I'm not sure where you're going with this, and how it relates to the original post, but the easy way to get "a>b" to evaluate in your example is to replace

Dynamic[a] > Dynamic[b]

with

Dynamic[a > b]
POSTED BY: Eric Rimbey
Posted 10 years ago

In fact I think the core of the problem is how to get the expression "a>b" dynamically evaluated in this example

{Slider[Dynamic[a]], Dynamic[a]} {Slider[Dynamic[b]], Dynamic[b]} Dynamic[a]> Dynamic[b]

POSTED BY: Alain RIWAN
Posted 10 years ago

Thanks for your answer.

POSTED BY: Alain RIWAN
Posted 10 years ago

Alain,

Let's walk through the case of fWhich[2,1] (this isn't valid Mathematica syntax, I'm just trying to step through what happens conceptually):

fWhich[2,1]
--> aa = 3 + w  &&  bb = 3 - w
--> r1 = Which[aa == bb, AB, aa > bb, AA, bb > aa, BB]
--> r1 = Which[3 + w == 3 - w, AB, aa > bb, AA, bb > aa, BB]

This Which expression cannot be resolved, because Which expects all of the "test" expressions to evaluate to True or False. Since 3 + w == 3 - w cannot be resolved to True of False, the Which expression gets assigned to r1 with no further evaluation of its arguments. Same thing happens with r2 and r3. So, we end up with

fWhich[2,1] being equal to
{3 + w, 3 - w, Which[3 + w == 3 - w, AB, aa > bb, AA, bb > aa, BB], 
 Which[3 + w > 3 - w, AA, aa == bb, AB, bb > aa, BB], 
 Which[3 - w > 3 + w, BB, aa > bb, AA, aa == bb, AB]}

That whole expression is what you get when you evaluate fWhich[2,1]. Then you replace the w with, say -1. Let's look at the first Which expression (the one assigned to r1).

Which[3 + w == 3 - w, AB, aa > bb, AA, bb > aa, BB]
--> Which[3 + -1 == 3 - -1, AB, aa > bb, AA, bb > aa, BB]
--> Which[2 == 4, AB, aa > bb, AA, bb > aa, BB]
--> Which[False, AB, aa > bb, AA, bb > aa, BB]
--> Which[aa > bb, AA, bb > aa, BB]

And at that point, no further evaluation of Which can be completed. This is exactly what you now see in your output, that partially simplified Which expression. Compare this to fWhich[2,0]. In that case, the first expression, after substituting for the w, evaluates to True, and so it can resolve to BB, which is, again, exactly what you see in your output.

You seem to be expecting that all of the parts of Which would be partially expanded into expressions using the values of u and v instead of just the aa and bb, but Which has the HoldAll attribute, so it keeps those unevaluated until it needs them. Since it didn't need any of them beyond the first one, you're seeing the aa and bb "leak" out. They were only defined within the scope of the Block, so now they are just raw symbols with no definition.

Unless you can provide a better reason than w being a "mere parameter", what you really want to do here add is w to the input arguments for fWhich. You can "curry" your function if that makes it clearer for you:

fWhich[u_,v_,w_]:=...

or

fWhich[u_, v_][w_]:=...

The situation with your fIf function is slightly different, because If will still evaluate if the conditional is not True or False. In fact, you can provide a fourth input to be returned in the case that the conditional is neither True or False. Maybe this behavior is more of what you are expecting. I can work through that approach if you wish.

POSTED BY: Eric Rimbey

Take a look at "HoldRest" and "HoldAll"

?? If

If[condition,t,f] gives t if condition evaluates to True, and f if it evaluates to False. 
If[condition,t,f,u] gives u if condition evaluates to neither True nor False.  >>

Attributes[If]={HoldRest,Protected}

?? Which

Which[Subscript[test, 1],Subscript[value, 1],Subscript[test, 2],Subscript[value, 2],\[Ellipsis]] evaluates each of the Subscript[test, i] in turn, returning the value of the Subscript[value, i] corresponding to the first one that yields True.  >>

Attributes[Which]={HoldAll,Protected}
POSTED BY: Frank Kampas
Posted 10 years ago

Thanks for your kind answer. but you can easily imagine this is a very simple example and the many "w" are mere parameters I would use only at the moment of evaluation. and I still don't understand why the expression in Which is resolved only when the first case is true, something like the //. only works on the first part of the expression.

POSTED BY: Alain RIWAN
Posted 10 years ago

Alain,

Your variables aa & bb don't resolve to a number until you do the final replacements of w. Consider one of your If expressions:

If[bb > aa, r = BB]

Assuming u=2 and v=1, this is effectively trying to determine 3+w > 3-w, which cannot be determined, because w is still unknown. Since your assignment to r was inside the If, it never gets evaluated.

In your second example, you are setting r to the Which expression itself, which, upon application of the replacement rules for w, sometimes resolves to one of the values. The same thing would have happened if you used r=If[...] in your first example.

What I would suggest, is that you simply make w an input variable to fIf and fWhich. Like this:

fIf[u_, v_, w_] :=
 Block[
  {aa = u + v + w, bb = 2 u - v - w},
  If[bb > aa, r = BB];
  If[aa > bb, r = AA];
  If[aa == bb, r = AB];
  {aa, bb, r}
  ]
POSTED BY: Eric Rimbey
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard