Re: piecewise functions from logical relationships (ie. solving with constraints)
- To: mathgroup at smc.vnet.net
- Subject: [mg81313] Re: piecewise functions from logical relationships (ie. solving with constraints)
- From: Chris Chiasson <chris.chiasson at gmail.com>
- Date: Wed, 19 Sep 2007 05:22:33 -0400 (EDT)
- References: <fclb12$fdk$1@smc.vnet.net><fco7m4$3uh$1@smc.vnet.net>
On Sep 18, 5:01 am, Benjamin.R.Le... at gmail.com wrote: > > I dunno how you made Reduce give you that answer (I didn't try very > > long), but, since you have it: > > > In[1]:= (x==2/5+y&&-2/5<y<1/2)||(x==7/5+y&&-1/2<y<-2/5)/.{Or->List,And[Equal[l_,r_],cond_]:>(l/;cond->r)} > > > Out[1]= {x/;-(2/5)<y<1/2->2/5+y,x/;-(1/2)<y<-(2/5)->7/5+y} > > I'm reluctant to try to "parse" the expression myself because (since > my package won't know the equations and constraints in advance) I > don't know what guarantees exist on the form of the output. > > With respect, but as an example of how easily I might overlook some > further possibility: your solution requires a particular ordering of > terms (which appears to be version dependent at best), that the > constraint is non-empty, and that the condition on an individual part > never contains Or. > > I would have thought this would be a fairly common problem; can't > Mathematically automatically re-express these somehow? I assumed you would make the relevant changes to generalize the pattern matching. See below. The auxillary and function below is needed because the built in And function isn't Orderless and also because the built in version holds its arguments. *******************input********* ClearAll@and Default@and := True Attributes@and := {Flat, OneIdentity, Orderless} toCandyMountain[xpr_And] := With[{lxpr = LogicalExpand@xpr}, toCandyMountain@lxpr /; Head@lxpr === Or] toCandyMountain@(List | Or)[args___] := Map[Piecewise, {args} /. And -> and /. and[x == rhs_, other_.] :> {rhs, other} /. and -> And, {0}] toCandyMountain@arg_ := toCandyMountain@{arg} toCandyMountain[(x == 2/5 + y && -2/5 < y < 1/2) || (x == 7/5 + y && -1/2 < y < -2/5)] toCandyMountain[(x == 2/5 + y && -2/5 < y < 1/2) || x == 7/5 + y] toCandyMountain[(x == 2/5 + y && -2/5 < y < 1/2)] toCandyMountain[x == 7/5 + y] *******************output********* \[Piecewise] { {2/5 + y, -(2/5) < y < 1/2}, {7/5 + y, -(1/2) < y < -(2/5)} } \[Piecewise] { {2/5 + y, -(2/5) < y < 1/2}, {7/5 + y, \!\(\* TagBox["True", "PiecewiseDefault", AutoDelete->False, DeletionWarning->True]\)} } \[Piecewise] { {2/5 + y, -(2/5) < y < 1/2} } 7/5 + y *******************other stuff********* (*here are some Mathematica rules for simplifying logical \ expressions (boolean expressions)*) (*some of the rules are from here: http://www.allaboutcircuits.com/vol_4/chpt_7/5.html *) (*these definitions should illustrate pattern matching with defaults*) ClearAll[and, or, not] Default@and := True Default@or := False and[bool_.] := bool(*also handles and[]*) or[bool_.] := bool (Attributes@# = {Flat, OneIdentity, Orderless}) & /@ {and, or}; and[False, _] := False(*definition*) or[True, _] := True and[bool_, True] := bool(*common sense*) or[bool_, False] := bool and[bool_, bool_] := bool or[bool_, and[bool_, _.]] := bool(*derived by factoring*) not[not[bool_]] := bool(*definition*) and[bool1_, or[not@bool1_, bool2_.]] := and[bool1, bool2](*derived by distribution, then factoring*) or[bool1_, and[not@bool1_, bool2_.]] := or[bool1, bool2](*derived by "unfactoring" the first term, then factoring \ other terms*) logicalFactor@or[and[bool1_, bool2_.], and[bool1_, bool3_]] := and[bool1, or[bool2, bool3]] logicalDistribute[xpr_and] := Distribute[xpr, or, and(*this argument is not necessary*)] logicalExpand@and[or[bool1_, bool2_.], or[bool1_, bool3_]] := or[bool1, and[bool2, bool3]](*like distribute, but prefactored for two terms in each or \ -- this makes it less general than logicalDistribute*) (*and[bool1_,or[bool1_,bool2_.]]:=or[bool1,bool2]*)(*less general \ logicalExpand*) {and[True, b, and[True, a]], and[True, and[b, False, a]], or[a, False, or[a, False]], or[b, or[True, a, False]], and@not@not@g, or@not@not@not@d, or[a, d, and[a, c, b]], or[and[a, c, b], and[a, b]]} *******************other stuff output********* {and[a, b], False, a, True, g, not[d], or[a, d], and[a, b]}