# Is there a way to symbolically invert a piecewise function

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.

-

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]


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]


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

-

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.

-
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