Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

piecewise functions from logical relationships (ie. solving with constraints)

0 views
Skip to first unread message

Ben Lewis

unread,
Sep 17, 2007, 3:40:18 AM9/17/07
to
G'day all,

Say I have an equation that defines some arbitrary relationship between
two variables x and y (or N equations and 2N variables), and furthermore
that I know a specific region for which the relationship is one-to-one
and onto. In other words, some function f (such that y=f[x]) and it's
inverse g (x=g[y]) are mathematically well-defined in that region by my
equation. Is there then any way to obtain both functions using Mathematica?

I want the specific functions (f and g) so that, for particular points
in the region, I can change (coordinate) variables in either direction,
and also to compute various derivatives of these functions (particularly
the Jacobian matrix).

For example:

eq := y+1/2==Mod[x+0.1,1]
constr := -1/2<y<1/2 && 0<x<1 && y!=-0.4 && x!=0.9

Reduce produced output in a different form:
(x==2/5+y && -2/5<y<1/2) || (x==7/5+y && -1/2<y<-2/5)

Something in a form like "g->Mod[#+2/5,1]&" would be ideal, or
similarly: "x->Piecewise[{{2/5+y,-2/5<y<1/2},{7/5+y,-1/2<y<-2/5}}]".


-Ben


Chris Chiasson

unread,
Sep 18, 2007, 12:28:55 AM9/18/07
to

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}


Benjamin...@gmail.com

unread,
Sep 18, 2007, 6:01:40 AM9/18/07
to
> 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?


Chris Chiasson

unread,
Sep 19, 2007, 5:26:51 AM9/19/07
to

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]}


0 new messages