Max operations in sympy without using Piecewise

45 Views Asked by At

I tried to use Piecewise operation in sympy to solve a equation where a part cannot be less then zero, but it's computationaly expansive.

from sympy import symbols, solveset, Max, Piecewise, simplify

S, T1, T2, T3, T4, A, B, C, D = symbols('S T1 T2 T3 T4 A B C D')
soma = Piecewise((S - T1, S-T1 > 0), (0, S- T1 < 0)) + Piecewise((T2 - S, T2 - S > 0), (0, T2 - S < 0)) + \
       -  Piecewise((S - T3, S-T3 > 0), (0, S - T3 < 0)) - Piecewise((T4 - S, T4 - S > 0), (0, T4 - S < 0)) - A - B + C + D

soma = simplify(soma)

solve(soma,S)

The whole equation when I simulate using pure python can be defined as:

soma = max(S-T1,0) + max(T2-S,0) - max(S-T3,0) - max(T4-S,0) - A - B + C + D

then I find S when soma = 0

Note some proprieties:

  1. S, T1, T2, T3, T4 are always greater than 0 ( > 0)
  2. A, B, C, D are always greater than 0 too ( > 0)

I tried to write the whole equation (S - T1) - (S - T3) + (T2 - S) - (T4 - S) and define the inequalities but is obvious that S get cancellated.

Note that I'm not defining the variables because it's symbolic math

*edit - I need to solve the equation for S when soma == 0

1

There are 1 best solutions below

2
Oscar Benjamin On

It is not clear what you want as output. This is what I get solving case by case:

In [19]: p = piecewise_exclusive(soma) # slow but expands all conditions fully

In [20]: p
Out[20]: 
⎧          -A - B + C + D            for S ≥ T₂ ∧ S ≥ T₄ ∧ S ≤ T₁ ∧ S ≤ T₃
⎪                                                                         
⎪     -A - B + C + D + S - T₁        for S ≥ T₂ ∧ S ≥ T₄ ∧ S ≤ T₃ ∧ S > T₁
⎪                                                                         
⎪     -A - B + C + D - S + T₂        for S ≥ T₄ ∧ S ≤ T₁ ∧ S ≤ T₃ ∧ S < T₂
⎪                                                                         
⎪     -A - B + C + D - T₁ + T₂       for S ≥ T₄ ∧ S ≤ T₃ ∧ S > T₁ ∧ S < T₂
⎪                                                                         
⎪     -A - B + C + D - S + T₃        for S ≥ T₂ ∧ S ≥ T₄ ∧ S ≤ T₁ ∧ S > T₃
⎪                                                                         
⎪     -A - B + C + D - T₁ + T₃       for S ≥ T₂ ∧ S ≥ T₄ ∧ S > T₁ ∧ S > T₃
⎪                                                                         
⎪  -A - B + C + D - 2⋅S + T₂ + T₃    for S ≥ T₄ ∧ S ≤ T₁ ∧ S > T₃ ∧ S < T₂
⎪                                                                         
⎪-A - B + C + D - S - T₁ + T₂ + T₃   for S ≥ T₄ ∧ S > T₁ ∧ S > T₃ ∧ S < T₂
⎨                                                                         
⎪     -A - B + C + D + S - T₄        for S ≥ T₂ ∧ S ≤ T₁ ∧ S ≤ T₃ ∧ S < T₄
⎪                                                                         
⎪  -A - B + C + D + 2⋅S - T₁ - T₄    for S ≥ T₂ ∧ S ≤ T₃ ∧ S > T₁ ∧ S < T₄
⎪                                                                         
⎪     -A - B + C + D + T₂ - T₄       for S ≤ T₁ ∧ S ≤ T₃ ∧ S < T₂ ∧ S < T₄
⎪                                                                         
⎪-A - B + C + D + S - T₁ + T₂ - T₄   for S ≤ T₃ ∧ S > T₁ ∧ S < T₂ ∧ S < T₄
⎪                                                                         
⎪     -A - B + C + D + T₃ - T₄       for S ≥ T₂ ∧ S ≤ T₁ ∧ S > T₃ ∧ S < T₄
⎪                                                                         
⎪-A - B + C + D + S - T₁ + T₃ - T₄   for S ≥ T₂ ∧ S > T₁ ∧ S > T₃ ∧ S < T₄
⎪                                                                         
⎪-A - B + C + D - S + T₂ + T₃ - T₄   for S ≤ T₁ ∧ S > T₃ ∧ S < T₂ ∧ S < T₄
⎪                                                                         
⎩-A - B + C + D - T₁ + T₂ + T₃ - T₄  for S > T₁ ∧ S > T₃ ∧ S < T₂ ∧ S < T₄

Now solve case by case:

In [21]: for expr, condition in p.args:
    ...:     if expr.has(S):
    ...:         [sol] = solve(expr, S)
    ...:         print(f'If {condition} then S = {sol}')
    ...:     else:
    ...:         print(f'If {condition} then S is not unique and {expr} = 0')
    ...: 
If (S >= T2) & (S >= T4) & (S <= T1) & (S <= T3) then S is not unique and -A - B + C + D = 0
If (S >= T2) & (S >= T4) & (S <= T3) & (S > T1) then S = A + B - C - D + T1
If (S >= T4) & (S <= T1) & (S <= T3) & (S < T2) then S = -A - B + C + D + T2
If (S >= T4) & (S <= T3) & (S > T1) & (S < T2) then S is not unique and -A - B + C + D - T1 + T2 = 0
If (S >= T2) & (S >= T4) & (S <= T1) & (S > T3) then S = -A - B + C + D + T3
If (S >= T2) & (S >= T4) & (S > T1) & (S > T3) then S is not unique and -A - B + C + D - T1 + T3 = 0
If (S >= T4) & (S <= T1) & (S > T3) & (S < T2) then S = -A/2 - B/2 + C/2 + D/2 + T2/2 + T3/2
If (S >= T4) & (S > T1) & (S > T3) & (S < T2) then S = -A - B + C + D - T1 + T2 + T3
If (S >= T2) & (S <= T1) & (S <= T3) & (S < T4) then S = A + B - C - D + T4
If (S >= T2) & (S <= T3) & (S > T1) & (S < T4) then S = A/2 + B/2 - C/2 - D/2 + T1/2 + T4/2
If (S <= T1) & (S <= T3) & (S < T2) & (S < T4) then S is not unique and -A - B + C + D + T2 - T4 = 0
If (S <= T3) & (S > T1) & (S < T2) & (S < T4) then S = A + B - C - D + T1 - T2 + T4
If (S >= T2) & (S <= T1) & (S > T3) & (S < T4) then S is not unique and -A - B + C + D + T3 - T4 = 0
If (S >= T2) & (S > T1) & (S > T3) & (S < T4) then S = A + B - C - D + T1 - T3 + T4
If (S <= T1) & (S > T3) & (S < T2) & (S < T4) then S = -A - B + C + D + T2 + T3 - T4
If (S > T1) & (S > T3) & (S < T2) & (S < T4) then S is not unique and -A - B + C + D - T1 + T2 + T3 - T4 = 0