EDWhyte
EDWhyte

Reputation: 351

Prevent replacing of single variable expressions in sympy.cse

I want extract and replace common expressions in a set of equations using sympy.cse

When I run sympy.cse(eqs) I get the results below. How can I prevent sympy.cse to extract single variables eg. replacing S2_comp3 with -x0. (I have noticed that all these single variables are their negative)

result

  ([(x0, -S2_comp3),
  (x1, -S_source_comp3),
  (x2, S_source_total/S1_total),
  (x3, -S_source_comp1),
  (x4, -S_source_comp2),
  (x5, -S_source_comp4),
  (x6, -S2_comp1),
  (x7, -S2_comp2)],
 [S2_comp3*eff_c3 - S6_comp3,
  S6_comp3 + S9_comp3 + x0,
  S1_comp3 + S2_comp3 + S3_comp3 + S4_comp3 + x1,
  S1_comp3*x2 + x1,
  S1_comp1*x2 + x3,
  S1_comp2*x2 + x4,
  S1_comp4*x2 + x5,
  -S1_comp1 - S1_comp2 - S1_comp3 - S1_comp4 - S1_comp5 + S1_total,
  S1_comp1 + S2_comp1 + S3_comp1 + S4_comp1 + x3,
  S2_comp1*eff_c1 - S6_comp1,
  S6_comp1 + S9_comp1 + x6,
  S1_comp2 + S2_comp2 + S3_comp2 + S4_comp2 + x4,
  S2_comp2*eff_c2 - S6_comp2,
  S6_comp2 + S9_comp2 + x7,
  S1_comp4 + S2_comp4 + S3_comp4 + S4_comp4 + x5,
  -S2_comp4 - S2_comp5 + S2_total + x0 + x6 + x7,
  S1_comp5 + S2_comp5 + S3_comp5 + S4_comp5 - S_source_comp5])

With

eqs = [S2_comp3*eff_c3 - S6_comp3,
      -S2_comp3 + S6_comp3 + S9_comp3,
       S1_comp3 + S2_comp3 + S3_comp3 + S4_comp3 - S_source_comp3,
       S1_comp3*S_source_total/S1_total - S_source_comp3,
       S1_comp1*S_source_total/S1_total - S_source_comp1,
       S1_comp2*S_source_total/S1_total - S_source_comp2,
       S1_comp4*S_source_total/S1_total - S_source_comp4,
       -S1_comp1 - S1_comp2 - S1_comp3 - S1_comp4 - S1_comp5 + S1_total,
       S1_comp1 + S2_comp1 + S3_comp1 + S4_comp1 - S_source_comp1,
       S2_comp1*eff_c1 - S6_comp1,
       -S2_comp1 + S6_comp1 + S9_comp1,
       S1_comp2 + S2_comp2 + S3_comp2 + S4_comp2 - S_source_comp2,
       S2_comp2*eff_c2 - S6_comp2,
       -S2_comp2 + S6_comp2 + S9_comp2,
       S1_comp4 + S2_comp4 + S3_comp4 + S4_comp4 - S_source_comp4,
       -S2_comp1 - S2_comp2 - S2_comp3 - S2_comp4 - S2_comp5 + S2_total,
       S1_comp5 + S2_comp5 + S3_comp5 + S4_comp5 - S_source_comp5]

With

 var = [S6_comp3,
       S2_comp3,
       S9_comp1,
       S2_comp1,
       S2_comp5,
       S1_comp1,
       S2_comp4,
       S1_comp4,
       S1_comp2,
       S9_comp2,
       S6_comp1,
       S1_comp3,
       S1_comp5,
       S9_comp3,
       S2_comp2,
       S6_comp2,
       S1_total]

Upvotes: 3

Views: 192

Answers (1)

smichr
smichr

Reputation: 19115

For situations like this where the return value is not as you like it, the postprocess option can be used. For example,

def noneg(r,e):
    rv = []
    negs = []
    for i in range(len(r)):
        o, n = r[i]
        if (-n).is_Symbol:
            for j in range(i + 1, len(r)):
                oj, nj = r[j]
                r[j] = oj, nj.subs(o, n)
            negs.append((o, n))
        else:
            rv.append((o, n))
    for o, n in reversed(negs):
        e = [ei.subs(o, n) for ei in e]
    return rv, e

>>> print filldedent(cse(your_eqs, postprocess=noneg))

([(x2, 1/S1_total)], [S2_comp3*eff_c3 - S6_comp3, -S2_comp3 + S6_comp3
+ S9_comp3, S1_comp3 + S2_comp3 + S3_comp3 + S4_comp3 -
S_source_comp3, S1_comp3*S_source_total*x2 - S_source_comp3,
S1_comp1*S_source_total*x2 - S_source_comp1,
S1_comp2*S_source_total*x2 - S_source_comp2,
S1_comp4*S_source_total*x2 - S_source_comp4, -S1_comp1 - S1_comp2 -
S1_comp3 - S1_comp4 - S1_comp5 + S1_total, S1_comp1 + S2_comp1 +
S3_comp1 + S4_comp1 - S_source_comp1, S2_comp1*eff_c1 - S6_comp1,
-S2_comp1 + S6_comp1 + S9_comp1, S1_comp2 + S2_comp2 + S3_comp2 +
S4_comp2 - S_source_comp2, S2_comp2*eff_c2 - S6_comp2, -S2_comp2 +
S6_comp2 + S9_comp2, S1_comp4 + S2_comp4 + S3_comp4 + S4_comp4 -
S_source_comp4, -S2_comp1 - S2_comp2 - S2_comp3 - S2_comp4 - S2_comp5
+ S2_total, S1_comp5 + S2_comp5 + S3_comp5 + S4_comp5 -
S_source_comp5])

Upvotes: 3

Related Questions