Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python: List algebraic simplification

Hi I am trying to get the common terms of a list to simplify it for example if the list I have is:

List=[['1','A1','B1','Kc','Ka'],['1','A1','B1','D2','Kc','Ka'],
['-1','A1','B1','D1','Kc','Ka'],['1','A1','B1','D1','KD','Ka'],
['-1','B1','D1','C1','Kc','Ka','KF'],['1','B1','D1','F1','Kc','Kz','Kl']]    

is there any function that could give me as a result:

List_output=[['A1', 'B1', [['D1', [['KD', 'Ka'],
['-1', 'Ka', 'Kc']]], ['Ka', 'Kc'], ['D2', 'Ka', 'Kc']]],
['B1', 'D1', [['F1', 'Kc', 'Kl', 'Kz'], ['-1', 'C1', 'KF', 'Ka', 'Kc']]]]

What I basically want to do is an algebraic reduction.

(A1 B1 Kc Ka + A1 B1 D2 Kc Ka - A1 B1 D1 Kc Ka + A1 B1 D1 KD Ka -
B1 D1 C1 Kc Ka KF + B1 D1 F1 Kc Kz Kl ) ->
A1B1[D1[-KcKa + KDKa] + D2KcKa +KcKa] + B1D1[-C1[KcKaKF] + F1[KcKzKl]]  

The only requirement for the simplification is that all terms simplified need to depend on a sum or rest of K's. In other words, everything needs to be a function of a linear combination of K's: [-KcKa + KDKa]; [KcKaKF]; [['-1','Kc','Ka'],['+1','KD','Ka']].

I am trying to use SymPy but the problem I have is that the terms to reduce come from elsewhere so I never know what the symbols will be. To use SymPy you need to declare the symbols, right? Any idea of how I can tackle this problem?

like image 213
user3671704 Avatar asked Jul 03 '16 10:07

user3671704


1 Answers

I think you know what algebraic manipulations you want to do, but you are hung up on getting the "K" symbols out of sympy? Sympy is pretty good about guessing variable names. You can just construct the expression:

In [1]: import sympy

In [2]: List=[['1','A1','B1','Kc','Ka'],['1','A1','B1','D2','Kc','Ka'],['-1','A
   ...: 1','B1','D1','Kc','Ka'],['1','A1','B1','D1','KD','Ka'],['-1','B1','D1',
   ...: 'C1','Kc','Ka','KF'],['1','B1','D1','F1','Kc','Kz','Kl']]    

In [3]: expression = sympy.Add(*[sympy.Mul(*[sympy.S(y) for y in x]) for x in L
   ...: ist] )

In [4]: expression
Out[4]: A1*B1*D1*KD*Ka - A1*B1*D1*Ka*Kc + A1*B1*D2*Ka*Kc + A1*B1*Ka*Kc - B1*C1*D1*KF*Ka*Kc + B1*D1*F1*Kc*Kl*Kz

And then get the list of symbols:

In [5]: all_symbols = [x for x in expression.atoms() if type(x)==sympy.Symbol]

In [6]: all_symbols
Out[6]: [Kc, B1, KF, A1, Kz, Ka, D1, C1, F1, D2, KD, Kl]

Once you have the list of symbols, it is trivial to grab those which start with a 'K', or don't:

In [7]: solvefor = [x for x in all_symbols if str(x)[0]!="K"]

In [8]: solvefor
Out[8]: [B1, A1, D1, C1, F1, D2]

In [9]: sympy.horner(expression, wrt=solvefor)
Out[9]: B1*(A1*(D1*(KD*Ka - Ka*Kc) + D2*Ka*Kc + Ka*Kc) + D1*(-C1*KF*Ka*Kc + F1*Kc*Kl*Kz))
like image 170
RLC Avatar answered Sep 28 '22 17:09

RLC