1
$\begingroup$

This Answer provides the following code

invPWC[f_] := Evaluate @ Module[{t}, 
 Piecewise[
  ReplacePart[
   List @@ Reduce[# == f[t], t, Reals] /. {cond_ && t == expr_ :> {expr, cond}},
   {-1, -1} -> True]]] &;

I get that the {-1,-1} -> True replaces the last condition with "True", and I think I get that # is being used so that the function doesn't need to define another variable.

What I am most confused about though is the following

  • What is {cond_ && t == expr_ :> {expr, cond}} doing?

  • List @@ is reducing the head of the Reduce output with "list", but what is the head of the Reduce output?

With regards to my first question, I figure cond_ and express_ are defined by Reduce, and here we are just accessing them (and replacing them with something?) but I have no idea what they do

With regards to my second question, I tried using FullForm on some Reduce examples, but sometimes the head seems to be And, other times Or...

$\endgroup$
1
$\begingroup$

It's useful to have a test input on hand when taking apart code like the one in the OP.

ff = Function[t, Piecewise[{{t/4, t < 0}, {t/2, t < 3}, {3/2 + (t - 3)*3, True}}]];

First (with a slight change of variables to help clarify the operations),

Reduce[x == ff[y], y, Reals]
   (x <= 0 && y == 4 x) || (0 < x <= 3/2 && y == 2 x) || (x > 3/2 && y == 1/6 (15 + 2 x))

This generates a bunch of conditions in disjunctive normal form (DNF), corresponding to the pieces of the function to be inverted.

List @@ %
   {x <= 0 && y == 4 x, 0 < x <= 3/2 && y == 2 x, x > 3/2 && y == 1/6 (15 + 2 x)}

Here, Apply[] (@@) converts the disjunction (Or[]) into a list of conditions.

% /. {cond_ && y == expr_ :> {expr, cond}}
   {{4 x, x <= 0}, {2 x, 0 < x <= 3/2}, {1/6 (15 + 2 x), x > 3/2}}

We match each conjunction (And[], &&), and extract the pieces required to build a Piecewise[] function out of them. Taking the first piece x <= 0 && y == 4 x as an example, and using the pattern cond_ && y == expr_ :> {expr, cond}, cond_ corresponds to x <= 0, and expr_ corresponds to 4 x.

ReplacePart[%, {-1, -1} -> True]
   {{4 x, x <= 0}, {2 x, 0 < x <= 3/2}, {1/6 (15 + 2 x), True}}

As you mentioned, this just converts the last condition to True (corresponding to the "default" case of the Piecewise[] function). Finally, this can be fed to Piecewise[] directly:

Piecewise[%]
   Piecewise[{{4 x, x <= 0}, {2 x, 0 < x <= 3/2}}, (15 + 2 x)/6]

The rest of the function with its (Evaluate[(* stuff *)] & is just one way to produce a pure function instead of a function with an explicit variable.


With regards to my second question, I tried using FullForm on some Reduce examples, but sometimes the head seems to be And, other times Or...

That's actually a weakness of the current approach. The function as currently implemented assumes the output of Reduce[] is always DNF. One way to ensure that this is always the case is to use BooleanConvert[], e.g. BooleanConvert[Reduce[x == ff[y], y, Reals], "DNF"].

| improve this answer | |
$\endgroup$
  • $\begingroup$ I'm still confused on one thing: Why do we need y=expr_ as opposed to just expr_ -- for example, we don't have a y=cond_.. Also, This is a really good answer, thanks. $\endgroup$ – majmun Jan 29 at 19:52
  • 1
    $\begingroup$ Look carefully at the structure of e.g. x <= 0 && y == 4 x. y == cond_ does not match x <= 0 (i.e. MatchQ[x <= 0, y == cond_] returns False). However, y == 4 x does match y == expr_ (i.e. MatchQ[y == 4 x, y == expr_] returns True), but you don't need the y == portion, so you peel out the required piece in the replacement rule. $\endgroup$ – J. M.'s discontentment Jan 29 at 22:58
  • $\begingroup$ That makes sense. Thanks $\endgroup$ – majmun Jan 29 at 23:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.