Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I have a piecewise function that is continuous and strictly monotonic, like this:

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

Now, I would like to get the inverse of that function. I would like an expression like this:

fInverse[x_] = Piecewise[{{4*x, x < 0}, {2*x, x < 1.5}, {5/2 + x/3, True}}]

(I later want to convert that expression or something derived from it of it to C code that will run on a microprocessor. So I need symbolic result, not a numerical one.)

I have tried InverseFunction[f], but I think it the result is a numerical inverse. I also tried Solve[f[t] == x, t], but it returns no result at all.

Simplify[Reduce[f[t] == x, t]] with proper assumptions ($Assumptions = {t ∈ Reals, x ∈ Reals}) is promising:

(t == 2 x && 0 <= x < 3/2) || (t == 4 x && x < 0) || (6 t == 15 + 2 x && 2 x >= 3)

but it's not a piecewise expression.

My next step would be to write a function piecewiseInvert that iterates through the alternatives in the Piecewise expression, solves each one for t, changes the conditions appropriately, and creates a new Piecewise, but I'm hoping that there's a simpler way to do this.

share|improve this question

2 Answers 2

up vote 2 down vote accepted

I think you're on the right track with Reduce. If the domain Reals is specified, Reduce will return results that can be converted to a Piecewise expression straightforwardly.

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

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

fInverse = invPW[f]
fInverse[x]

Mathematica graphics

One can remove the extraneous True case by replacing the last condition by True:

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

fInverse = invPWC[f]
fInverse[x]

Mathematica graphics


Note: Solve almost does it, also yielding a result that can be converted to Piecewise easily. But it does not include the end points of the intervals when appropriate.

Solve[x == f[t], t, Reals]

(* {{t -> ConditionalExpression[2 x, 0 < x < 3/2]},
    {t -> ConditionalExpression[4 x, x < 0]}, 
    {t -> ConditionalExpression[1/6 (15 + 2 x), x > 3/2]}}  *)
share|improve this answer

One approach would be to use ConditionalExpression instead of Piecewise. For example:

InverseFunction /@ {ConditionalExpression[#/4, # <= 0] &, 
                    ConditionalExpression[#/2, 0 <= # <= 3] &, 
                    ConditionalExpression[3/2 + 3 (# - 3), 3 <= #] &}

returns

{ConditionalExpression[4 #1, #1 <= 0] &, ConditionalExpression[2 #1, 0 <= #1 <= 3/2] &, 
 ConditionalExpression[1/6 (15 + 2 #1), #1 > 3/2] &}

which is indeed the inverse, also expressed as a ConditionalExpression.

share|improve this answer
    
The expression in question is the result of an integral containing piecewise functions. And I don't think I can calculate that integral using ConditionalExpressions. Is there a way to automatically convert a piecewise expression to a set of ConditionalExpressions? –  nikie Nov 4 '13 at 16:51
    
I'm not sure. I guess there must be, but I've never tried to convert. –  bill s Nov 4 '13 at 16:54

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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