Subexpressie vervangen door een symbool?

Ik heb een matrix van 3x3, waarvan ik de inverse bereken. De inverse kan alleen leesbaar worden geschreven wanneer sommige subuitdrukkingen worden vervangen door nieuwe symbolen, omdat ze meerdere keren voorkomen. Kan ik sympy hard proberen om die subuitdrukkingen te vinden en ze te vervangen? Ik probeerde het volgende, zonder succes:

from sympy import *

Ex, Ez, nuxy, nuxz = symbols('E_x E_z nu_xy nu_xz')

# compliance matrix for cross-anisotropic material
compl = Matrix([[1/Ex, -nuxy/Ex, -nuxz/Ez],
                [-nuxy/Ex, 1/Ex, -nuxz/Ez],
                [-nuxz/Ex, -nuxz/Ex, 1/Ez]])

# stiffness matrix
stiff = compl.inv()

# symbols I want to introduce 
m, e = symbols('m e')  

meSubs = {Ex/Ez: e, (1 - nuxy - 2*e*nuxz**2): m}  # instead of these subexpressions

# stiff.simplify() returns None, is that a bug? that's why I apply simplify together with subs here:
stiff.applyfunc(lambda x: simplify(x.subs(meSubs)))
print stiff

Met behulp van sympy 0.6.7 (ik zou kunnen upgraden, indien nodig).

EDIT:

Ik heb een upgrade naar 0.7.1-git (cf9c01f8f9b4b749a7f59891f546646e4b38e580 om precies te zijn) uitgevoerd (dankzij @PreludeAndFugue voor suggestie):

from sympy import *
Ex,Ez,nuxy,nuxz,m=symbols('E_x E_z nu_xy nu_xz m')
compl=Matrix([[1/Ex,-nuxy/Ex,-nuxz/Ez],[-nuxy/Ex,1/Ex,-nuxz/Ez],[-nuxz/Ex,-nuxz/Ex,1/Ez]])
stiff=compl.inv()
stiff.simplify()
stiff.subs({-nuxy-2*nuxz**2+1:m})    # tried other rearrangements of the equality, as well, same result.
stiff.applyfunc(lambda x: together(expand(x)))
pprint(stiff)

het verkrijgen van

⎡              ⎛    2    ⎞                         ⎛            2⎞                              ⎤
⎢           Eₓ⋅⎝ν_xz  - 1⎠                     -Eₓ⋅⎝-ν_xy - ν_xz ⎠                 Eₓ⋅ν_xz      ⎥
⎢ ──────────────────────────────────   ────────────────────────────────────  ───────────────────⎥
⎢     2              2         2             2              2         2                    2    ⎥
⎢ ν_xy  + 2⋅ν_xy⋅ν_xz  + 2⋅ν_xz  - 1   - ν_xy  - 2⋅ν_xy⋅ν_xz  - 2⋅ν_xz  + 1  -ν_xy - 2⋅ν_xz  + 1⎥
⎢                                                                                               ⎥
⎢            ⎛            2⎞                         ⎛    2    ⎞                                ⎥
⎢        -Eₓ⋅⎝-ν_xy - ν_xz ⎠                      Eₓ⋅⎝ν_xz  - 1⎠                   Eₓ⋅ν_xz      ⎥
⎢────────────────────────────────────   ──────────────────────────────────   ───────────────────⎥
⎢      2              2         2           2              2         2                     2    ⎥
⎢- ν_xy  - 2⋅ν_xy⋅ν_xz  - 2⋅ν_xz  + 1   ν_xy  + 2⋅ν_xy⋅ν_xz  + 2⋅ν_xz  - 1   -ν_xy - 2⋅ν_xz  + 1⎥
⎢                                                                                               ⎥
⎢              E_z⋅ν_xz                              E_z⋅ν_xz                  E_z⋅(ν_xy - 1)   ⎥
⎢        ───────────────────                   ───────────────────           ────────────────── ⎥
⎢                      2                                     2                            2     ⎥
⎣        -ν_xy - 2⋅ν_xz  + 1                   -ν_xy - 2⋅ν_xz  + 1           ν_xy + 2⋅ν_xz  - 1 ⎦

Hm, dus waarom wordt "-ν_xy - 2⋅ν_xz² + 1" niet vervangen door m?

5
@PreludeAndFugue: bedankt voor het simplify() ding ... had kunnen controleren.
toegevoegd de auteur eudoxos, de bron
Merk op dat stiff.simplify() stijf inplace vereenvoudigt, dus retourneert None . Vergelijk met bijvoorbeeld list.sort() .
toegevoegd de auteur Gary Kerr, de bron
De functie pprint van Sympy kan worden gebruikt om een ​​prettified-versie af te drukken.
toegevoegd de auteur Gary Kerr, de bron
Alle hoofdontwikkelaars zijn hier: groups.google.com/group/sympy/topics . Je zou goede antwoorden van hen moeten krijgen.
toegevoegd de auteur Gary Kerr, de bron

2 antwoord

Het wordt wel vervangen, maar subs werkt niet mutably op Matrices. applyfunc werkt helaas ook niet mutably. ik krijg

In [10]: pprint(stiff.subs({-nuxy-2*nuxz**2+1:m}))
⎡               ⎛     2    ⎞                            ⎛              2⎞                            ⎤
⎢            Eₓ⋅⎝nu_xz  - 1⎠                        -Eₓ⋅⎝-nu_xy - nu_xz ⎠                Eₓ⋅nu_xz    ⎥
⎢ ──────────────────────────────────────   ────────────────────────────────────────      ────────    ⎥
⎢      2                2          2              2                2          2             m        ⎥
⎢ nu_xy  + 2⋅nu_xy⋅nu_xz  + 2⋅nu_xz  - 1   - nu_xy  - 2⋅nu_xy⋅nu_xz  - 2⋅nu_xz  + 1                  ⎥
⎢                                                                                                    ⎥
⎢             ⎛              2⎞                           ⎛     2    ⎞                               ⎥
⎢         -Eₓ⋅⎝-nu_xy - nu_xz ⎠                        Eₓ⋅⎝nu_xz  - 1⎠                   Eₓ⋅nu_xz    ⎥
⎢────────────────────────────────────────   ──────────────────────────────────────       ────────    ⎥
⎢       2                2          2            2                2          2              m        ⎥
⎢- nu_xy  - 2⋅nu_xy⋅nu_xz  - 2⋅nu_xz  + 1   nu_xy  + 2⋅nu_xy⋅nu_xz  + 2⋅nu_xz  - 1                   ⎥
⎢                                                                                                    ⎥
⎢               E_z⋅nu_xz                                 E_z⋅nu_xz                  -E_z⋅(nu_xy - 1)⎥
⎢               ─────────                                 ─────────                  ────────────────⎥
⎣                   m                                         m                             m        ⎦

Er zijn plannen om Matrix standaard onveranderbaar te maken en vervolgens MutableMatrix volledig op zijn plaats te laten werken op alle operaties. Zie https://code.google.com/p/sympy/issues/ detail? id = 3410 . Maar het is nog niet gebeurd.

0
toegevoegd

Ik weet niet zeker of het gebruik van 0.6.7 een probleem is, maar een update naar 0.7.1 wordt aanbevolen.

Als ik naar stijf kijk, zie ik niet dat de subsituties in meSubs nuttig zijn. Nadat ik stijf heb gemaakt, heb ik het volgende gedaan:

stiff.simplify()
stiff = stiff.subs({2*nuxz**2: 1 - nuxy - m})
stiff = stiff.applyfunc(lambda x: together(expand(x)))
pprint(stiff)

De output is niet slecht:

[     /    2    \       /            2\                  ]
[  E_x*\nu_xz  - 1/    E_x*\nu_xy + nu_xz/    E_x*nu_xz    ]
[  ----------------    --------------------     ---------    ]
[   m*(-nu_xy - 1)        m*(nu_xy + 1)             m        ]
[                                                            ]
[   /            2\       /    2    \                    ]
[E_x*\nu_xy + nu_xz/   E_x*\nu_xz  - 1/       E_x*nu_xz    ]
[--------------------    ----------------       ---------    ]
[   m*(nu_xy + 1)         m*(-nu_xy - 1)            m        ]
[                                                            ]
[     E_z*nu_xz             E_z*nu_xz        E_z*(-nu_xy + 1)]
[     ---------             ---------        ----------------]
[         m                     m                   m        ]

expand: http://docs.sympy.org/0.7.1/modules/core.html?highlight=expand#sympy.core.function.expand

together: http://docs.sympy.org/0.7.1/modules/polys/reference.html?highlight=together#sympy.polys.rationaltools.together

0
toegevoegd
Ik heb geprobeerd met de nieuwste git-versie, en zet het als bewerking van de vraag. Misschien is mijn machine vervloekt?
toegevoegd de auteur eudoxos, de bron
Ja, de subs dingen hierboven werken niet op die manier in 0.6.7 (tenminste voor mij, waarschijnlijk omdat het de nu in .subs() niet herkent maar wel wanneer het symbool in de eerste plaats wordt gemaakt). Een upgrade naar 0.7.1 is een goed idee, ongeacht.
toegevoegd de auteur VPeric, de bron