2016-07-03 23 views
6

Ciao Sto cercando di ottenere i termini comuni di un elenco per semplificare per esempio se la lista che ho è:Python: Lista algebrica semplificazione

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']]  

v'è alcuna funzione che mi potrebbe dare come risultato :

Quello che sostanzialmente voglio fare è la riduzione algebrica.

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]]

L'unico requisito per la semplificazione è che tutti i termini semplificati devono dipendere da una somma o resto di K. In altre parole, tutto deve essere una funzione di una combinazione lineare di K; [-KcKa + KDKa]; [KcKaKF] = [[ '- 1', 'Kc', 'Ka'], [ '+ 1', 'asciutto', 'Ka']]; ['+1', 'Kc', 'Ka', 'KF']

Provo ad usare Sympy ma il problema che ho è che i termini da ridurre provengono da un'apparecchiatura quindi non so mai quali sarebbero i simboli essere e usare sympy è necessario dichiarare i simboli. Qualche idea su come posso affrontare questo problema?

+0

Una domanda molto interessante. Avete qualche esigenza che la soluzione sia ottimale in qualche modo o funzionerà una buona semplificazione? –

+0

Il tuo problema non ha una soluzione unica: le sottoespressioni possono essere prese in considerazione in più di un modo equivalente. –

+0

L'unico requisito è che tutte le semplificazioni debbano dipendere da una somma o resto di K. In altre parole, tutto deve essere una funzione di una combinazione lineare di K – user3671704

risposta

0

Prima di tutto, trasformare il vostro elenco per un'espressione SymPy:

In [1]: 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']] 

In [2]: list_add_mul = sympify(List) 

In [4]: expr = Add(*map(lambda x: Mul(*x), list_add_mul)) 

In [5]: expr 
Out[5]: 
A₁⋅B₁⋅D₁⋅KD⋅Ka - A₁⋅B₁⋅D₁⋅Ka⋅Kc + A₁⋅B₁⋅D₂⋅Ka⋅Kc + A₁⋅B₁⋅Ka⋅Kc - B₁⋅C₁⋅D₁⋅KF⋅K 
a⋅Kc + B₁⋅D₁⋅F₁⋅Kc⋅Kl⋅Kz 

Ora espr è l'espressione SymPy si desidera lavorare. Se si vuole semplicemente sostituire alcuni valori, utilizzare .subs:

Ricordatevi prima di definire i simboli che si vuole utilizzare:

>>> var("Ka, Kc, Kz") 

Poi si può sostituire:

In [6]: expr.subs({Ka: 25.0, Kc: 7.0, Kz: 3.5}) 
Out[6]: 
25.0⋅A₁⋅B₁⋅D₁⋅KD - 175.0⋅A₁⋅B₁⋅D₁ + 175.0⋅A₁⋅B₁⋅D₂ + 175.0⋅A₁⋅B₁ - 175.0⋅B₁⋅C₁ 
⋅D₁⋅KF + 24.5⋅B₁⋅D₁⋅F₁⋅Kl 

Altrimenti, potresti provare a definire una regola di sostituzione per le tue variabili. Ad esempio, metterli in una dict:

{ 
    Ka: ... , 
    Kc: ... , 
    KD: ... , 
    KF: ... , 
} 

è necessario sostituire i puntini con un'espressione adatta contenente nuove variabili. Queste nuove variabili dovrebbero rappresentare le combinazioni delle costanti K.

Ad esempio: c1 = -Kc * Ka + KD * Ka, _c2 = ... _ quindi si invertono queste equazioni.

Nel tuo caso, sembra che le espressioni non possono essere adeguatamente invertiti:

>>> solve([Eq(-Kc*Ka + KD*Ka, c1), Eq(Kc*Ka*KF, c2), Eq(-Kc*Ka + KD*Ka, c3), Eq(Kc*Ka*KF, c4)], Ka, Kc, KD, KF) 
[] 
+0

Ho fatto tutti i passaggi ma quando provo i expr.subs ({Ka: 25.0, Kc: 7.0, Kz: 3.5}) comando che ho ottenuto: il nome 'Ka' non è definito – user3671704

+0

È necessario definire tutte le variabili che si intendono utilizzare. Ho aggiornato la risposta. –

0

Credo di sapere che cosa manipolazioni algebriche che si vuole fare, ma si sono appesi su come ottenere i simboli "K" fuori di sympy? Sympy è piuttosto bravo a indovinare i nomi delle variabili.Si può solo costruire l'espressione:

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 

e quindi ottenere l'elenco dei simboli:

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] 

Una volta che avete l'elenco dei simboli, è banale per afferrare quelle che iniziano con una 'K' , o non:

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))