Message Boards Message Boards

5 Replies
3 Total Likes
View groups...
Share this post:

Problem with PiecewiseExpand??

Posted 11 years ago
In the following code, it seems that f2 evaluates incorrectly, but f1 & f3 evaluate correctly - even though f3 is generated from f2. It might not be handling the strings correctly (e.g., "Yes")?

Maybe there is something subtle here I'm missing. I know how to work around this problem, but it doesn't seem I should need a workaround and it makes me wary of PiecewiseExpand.
f1=Piecewise[{{Piecewise[{{a1, x == "Yes"}, {a2, x == "No"}}, 0], y == "Yes"}, {b, y == "No"}}]

Thanks for any comments.
POSTED BY: David Barrows
5 Replies
Turns out there is a reason for this odd behavior.

A Kernel developer told me,
Symbolic computation functions treat expressions with head Equal
as numeric equations and consider non-numeric expressions that
appear in equations as symbolic parameters, even if those
expressions are strings, pictures, Boolean constants, etc.
In[5]:= Solve[x=="Yes" && x+y==Graphics[Circle[]] && x z==True, {x, y, z}]

Out[5]= {{x -> Yes, y -> -Yes + -Graphics-, z -> ----}}

Making PiecewiseExpand, Solve, etc, look inside expressions with "==" for non-numerical items
opens up a large box of special cases and potential conflicts.

In your example, using (Full)Simplify on the PiecewiseExpand output is probably the easiest workaround.
There are things one could do with Hold or HoldForm. There isn't a StringEquals function, but StringMatchQ
could be used if keeping strings from being treated as parameters is critical.
 In[1]:= $Version
 Out[1]= 9.0 for Mac OS X x86 (64-bit) (January 24, 2013)
 In[2]:= f1=Piecewise[{{Piecewise[{{a1,StringMatchQ[x,"Yes"]}, {a2, StringMatchQ[x,"No"]}},0],
 StringMatchQ::strse: String or list of strings expected at position 1 in StringMatchQ[y,Yes]. >> 
 StringMatchQ::strse: String or list of strings expected at position 1 in StringMatchQ[x,Yes]. >>
 StringMatchQ::strse: String or list of strings expected at position 1 in StringMatchQ[x,No]. >>
General::stop: Further output of StringMatchQ::strse will be suppressed during this calculation. >>

Out[2]= \[Piecewise]    \[Piecewise]    a1    StringMatchQ[x,Yes]
                                        a2    StringMatchQ[x,No]    StringMatchQ[y,Yes]
                                        0    True
                    b      StringMatchQ[y,No]
                    0      True

In[3]:= f2= PiecewiseExpand[f1]
Out[3]= \[Piecewise]    a1    StringMatchQ[y,Yes]&&StringMatchQ[x,Yes]
                        a2    StringMatchQ[y,Yes]&&StringMatchQ[x,No]
                        0    !StringMatchQ[y,No]||StringMatchQ[y,Yes]
                        b    True

In[4]:= f2 /. {x->"No", y->"Yes"}
Out[4]= a2

The warning messages after In[2] can be prevented by evaluating
POSTED BY: Bruce Miller
Posted 11 years ago
Thanks for the research Bruce.

I see that StringMatchQ makes things work. I'm using a structure like this in a derivative calculation of an ODE being solved using DSolve in a Dynamic environment with sliders, SetterBars, etc. So far I've only gotten NDSolve to give correct numerical results. DSolve doesn't seem to like nested Piecewise equations. I'm ok with the NDSolve version & will work on the more esthetically pleasing version in my spare time.

Thanks again for the help.
POSTED BY: David Barrows
You are right.  Since Equals cannot figure out   -"No" + "Yes" ==0, this Piecewise is stuck.
In[4]:= f2 /. {x->"No", y->"Yes"}

Out[4]= \[Piecewise] a1 -No+Yes==0
                     a2 True

I sent a problem report on this to developers. 
If it is expected behavior, then the documentation needs clarification.
POSTED BY: Bruce Miller
Posted 11 years ago
Thanks for the comments Bruce. Yes, the expansion does appear to try to do arithmetic with a string & that might be a problem with PiecewiseExpand. My real concern is that the results for f2 are actually wrong (execute the "Table" line of code,) - on my computer anyway. Maybe it is because the logic is expanded incorrectly (assumes only Reals maybe??). Curiously, once simplification is applied, these errors seem to be corrected.

Makes me hesitant to use PiecewiseExpand.
POSTED BY: David Barrows
To save 100 people having to fire up their Mathematicas, in f2, the conditions
are re-ordered to look like it is doing arithmetic with character strings.

In[2]:= f2=f1//PiecewiseExpand
Out[2]= Piecewise[{
      {a1, Yes - y == 0 && Yes - x == 0},
      {a2, Yes - y == 0 && No - x == 0},
       {0, No - y != 0 || Yes - y == 0}}, b]

FullSimplify or Simplify changes them back to looking like tests,  "{a1, Yes == y && Yes == x}" . 

Worthy of a suggestion tomorrow.
POSTED BY: Bruce Miller
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
or Discard

Group Abstract Group Abstract