# How to split Abs functions into two?

I have a list of functions like this:

    myfuncions ={ConditionalExpression[(1/2)*Abs[1 - 3*x], x >= 1 || x <= 0],
ConditionalExpression[Abs[1 - 2*x], x >= 1 || x <= 0],
ConditionalExpression[Abs[-1 + x], x >= 2 || x <= 0],
ConditionalExpression[1+x, x <= 0]};


For each function with Abs I want to split it into 2 funcions as follows (I take the first function as an example):

The expected output for all functions is as follows (if I don't make mistake):

{{ConditionalExpression[1/2 (-1 + 3 x), x >= 1],
ConditionalExpression[1/2 (1 - 3 x),
x <= 0]}, {ConditionalExpression[-1 + 2 x, x >= 1],
ConditionalExpression[1 - 2 x, x <= 0]}, {ConditionalExpression[
Abs[-1 + x], x <= 0],
ConditionalExpression[-1 + x, x >= 2]}, {ConditionalExpression[
1 + x, x <= 0]}}


Any idea to do that? I don't have problem with math but still struggle to express that into mathematica code.

• Have a look at PiecewiseExpand. Apr 7, 2022 at 8:23
• @Roman can you explain more? I used that function before but don't know how it work here.
– hana
Apr 7, 2022 at 9:36
• In second to last row of the expected output, is ConditionalExpression[Abs[-1 + x], x <= 0] correct? And shouldn't ConditionalExpression[Abs[-1 + x], x >= 2 || x <= 0] yield a list with the x>= 2 condition first, then the x<=0 condition? Apr 7, 2022 at 17:54

Here is a function that expands the Abs function and simplifies the conditional expression

Clear[absExpand]
absExpand[e_] := With[{arg = FirstCase[e, Abs[y_] :> y, Null, ∞]},
Simplify[e, #] & /@ {arg < 0, arg >= 0}]

expr = ConditionalExpression[(1/2)*Abs[1 - 3*x], x >= 1 || x <= 0];
absExpand[expr]

(*   {ConditionalExpression[1/2 (-1 + 3 x), x >= 1],
ConditionalExpression[1/2 (1 - 3 x), x <= 0]}   *)


You may have to use absExpand[expr]//InputForm to see exactly the output shown above.

• Thanks, would it be okay to use e here instead of expr? It tried and it worked but I'm not sure if there is some hidden problems. FirstCase[e, Abs[y_] :> y, Null, \[Infinity]]
– hana
Apr 7, 2022 at 13:31
• @hana Good catch! That's definitely a mistake that I must have introduced in a last-minute edit. I'll fix it now. Apr 7, 2022 at 20:56

The following deals with an expression that has one or more Abs functions, being treated as RealAbs. It's probably more robust to replace Abs -> RealAbs, but in the OP's examples, the inequalities imply to PiecewiseExpand that Abs may be treated as the real absolute value (or more precisely, the complex absolute value restricted to a real argument).

(* ConditionalExpression to Piecewise *)
ceToPWRule = ConditionalExpression[e_, c_] :>
PiecewiseExpand[Piecewise[{{e, c}}, Inactive@Undefined]];
(* Split Piecewise cases into list of ConditionExpressions *)
splitPiecewiseRule = Verbatim[Piecewise][ff_, def_] :>
(Piecewise[{#}, Undefined] & /@ ff);


First example (output shown both in StandardForm and InputForm):

Replace[First@myfuncions,
f_ :> (PiecewiseExpand[f /. ceToPWRule] /. splitPiecewiseRule)]


All the OP's function (the last has only one case):

Activate[
Replace[myfuncions,
f_ :> (PiecewiseExpand[f /. ceToPWRule] /. splitPiecewiseRule), 1],
Undefined]


Example with two Abs[]:

Activate[
Replace[
ConditionalExpression[Abs[x - 7], x (10 - x) >= 0] + myfuncions,
f_ :> (PiecewiseExpand[f /. ceToPWRule] /. splitPiecewiseRule),
1],
Undefined] // Simplify

• This is great too. I didn't know RealAbs and Activate exist.
– hana
Apr 7, 2022 at 16:34
myfuncions = {ConditionalExpression[(1/2)*Abs[1 - 3*x], x >= 1 || x <= 0],
ConditionalExpression[Abs[1 - 2*x], x >= 1 || x <= 0],
ConditionalExpression[Abs[-1 + x], x >= 2 || x <= 0],
ConditionalExpression[1 + x, x <= 0]};

PiecewiseExpand /@ myfuncions


$$\left\{\fbox{ \begin{array}{cc} \{ & \begin{array}{cc} \frac{1}{2} (1-3 x) & x\leq \frac{1}{3} \\ \frac{1}{2} (3 x-1) & \text{True} \\ \end{array} \\ \end{array} \text{ if }x\geq 1\lor x\leq 0},\fbox{ \begin{array}{cc} \{ & \begin{array}{cc} 1-2 x & x\leq \frac{1}{2} \\ 2 x-1 & \text{True} \\ \end{array} \\ \end{array} \text{ if }x\geq 1\lor x\leq 0},\fbox{ \begin{array}{cc} \{ & \begin{array}{cc} 1-x & x<1 \\ x-1 & \text{True} \\ \end{array} \\ \end{array} \text{ if }x\geq 2\lor x\leq 0},\fbox{x+1\text{ if }x\leq 0}\right\}$$

I don't know how to go further with ConditionalExpression. However, with Piecewise we can go all the way. I've used Indeterminate to mark values outside of the condition; but you can use anything else like Missing[], \$Failed, etc.:

myfunctions = {Piecewise[{{(1/2)*Abs[1 - 3*x], x >= 1 || x <= 0}}, Indeterminate],
Piecewise[{{Abs[1 - 2*x], x >= 1 || x <= 0}}, Indeterminate],
Piecewise[{{Abs[-1 + x], x >= 2 || x <= 0}}, Indeterminate],
Piecewise[{{1 + x, x <= 0}}, Indeterminate]};

PiecewiseExpand /@ myfunctions


$$\{ \left\{ \begin{array}{cc} \frac{1}{2} (1-3 x) & x\leq 0 \\ \frac{1}{2} (3 x-1) & x\geq 1 \\ \text{Indeterminate} & \text{True} \end{array} \right. ,\\ \left\{ \begin{array}{cc} 1-2 x & x\leq 0 \\ 2 x-1 & x\geq 1 \\ \text{Indeterminate} & \text{True} \end{array} \right. ,\\ \left\{ \begin{array}{cc} 1-x & x\leq 0 \\ x-1 & x\geq 2 \\ \text{Indeterminate} & \text{True} \end{array} \right. ,\\ \left\{ \begin{array}{cc} x+1 & x\leq 0 \\ \text{Indeterminate} & \text{True} \end{array} \right. \}$$

• I see, I think you misunderstood my question. The output is not of the expected output as I mentioned above.
– hana
Apr 7, 2022 at 13:32
• Please see update Apr 7, 2022 at 14:49
• I admit it's hard to understand what is being sought. I didn't get it until I saw LouisB's answer. The OP gives four functions and an output of only two, and a mysterious combining that include the disjunction of a boolean inequality and a scalar-value conditional expression -- hard to understand. I think what the OP wants is another step: To split each of the Piecewise functions you obtained into a ConditionalExpression for each case (except Indeterminate). Apr 7, 2022 at 15:10
• @MichaelE2 I think my comment on how to obtain the result in human way was confusing. I picked one function as an example and showed the process of obtaning the result as a human.
– hana
Apr 7, 2022 at 16:10
• @hana It seems better now. The combining of the inequality and ConditionalExpression was confusing to me. Further, it might be nicer, since you give four input functions, to also give the four outputs. It would let me confirm my understanding of the description of the human way. Apr 7, 2022 at 16:50
Clear["Global*"]

myfuncions = {ConditionalExpression[(1/2)*Abs[1 - 3*x],
x >= 1 || x <= 0],
ConditionalExpression[Abs[1 - 2*x], x >= 1 || x <= 0],
ConditionalExpression[Abs[-1 + x], x >= 2 || x <= 0],
ConditionalExpression[1 + x, x <= 0]};

myfuncions /.
ConditionalExpression[expr_,
Or[a_,
b_]] :>
(ConditionalExpression[Simplify[expr, #], #] & /@ {a, b})

(* {{ConditionalExpression[1/2 (-1 + 3 x), x >= 1],
ConditionalExpression[1/2 (1 - 3 x),
x <= 0]}, {ConditionalExpression[-1 + 2 x, x >= 1],
ConditionalExpression[1 - 2 x,
x <= 0]}, {ConditionalExpression[-1 + x, x >= 2],
ConditionalExpression[Abs[-1 + x], x <= 0]},
ConditionalExpression[1 + x, x <= 0]} *)


Using Refine, and fixing the expected output to not have an Abs and be in an order consistent with the rest of the output.

condAbsExpand[expr_?(StringContainsQ["Abs"]@*ToString)] := ConditionalExpression[Refine[expr[[1]], #], #] & /@ List @@ expr[[2]]
condAbsExpand[expr_] := Identity@expr

condAbsExpand@ConditionalExpression[(1/2)*Abs[1 - 3*x], x >= 1 || x <= 0]
condAbsExpand/@ myfuncions - expected // Simplify


{ConditionalExpression[1/2 (-1 + 3 x), x >= 1], ConditionalExpression[1/2 (1 - 3 x), x <= 0]}

{{ConditionalExpression[0, x >= 1], ConditionalExpression[0, x <= 0]}, {ConditionalExpression[0, x >= 1], ConditionalExpression[0, x <= 0]}, {ConditionalExpression[0, x >= 2], ConditionalExpression[0, x <= 0]}, ConditionalExpression[0, x <= 0]}}