как получить все основания (a, b) выражения, такого как (a [0] * b [0])? - PullRequest
1 голос
/ 25 апреля 2019

Недавно я переустанавливал анаконду и sympy.Затем я запускаю тот же код, например, как следующий, что дает мне ошибки.(У меня нет такой ошибки раньше)

import sympy as sp
a, b= sp.symbols('a b', cls=sp.IndexedBase)
l= sp.symbols('l', cls=sp.Wild)

def Bfunc(expr,p1,p2):
    if expr.base==p1:return expr.replace(p1[l],0.2*(p2[l]+p1[-l]),map=False, simultaneous=True, exact=True)
    else: return expr.replace(p2[l],0.2*(p1[l]+p2[-l]),map=False, simultaneous=True, exact=True)      

inputstate=a[0]*b[0]
psi0=inputstate.replace(lambda expr: expr.base in [a,b], lambda expr: Bfunc(expr,a,b))

Это дает мне ошибку:

enter image description here

Проблема expr.base , который не может дать базу a или b .

Давайте рассмотрим очень простой пример:

import sympy as sp
a, b= sp.symbols('a b', cls=sp.IndexedBase)
l= sp.symbols('l', cls=sp.Wild)    

inputstate=a[0]*b[0]
inputstate.base

ошибка:

Traceback (most recent call last):

  File "<ipython-input-59-7cc51ba4a4cd>", line 6, in <module>
    inputstate.base

AttributeError: 'Mul' object has no attribute 'base'

Если inputtate = a [0] , то inputtate.base дает вам a .

Поэтому мне интересно, почему такая ошибка происходит после того, как я переустановил sympy и anaconda.Или есть какой-нибудь способ дать весь базовый список и исправить ошибку?

Если у кого-то есть подобные случаи, было бы очень здорово, если бы вы могли дать мне несколько советов.Заранее спасибо!

Ответы [ 3 ]

2 голосов
/ 07 мая 2019

Ваша функция foo возвращает None, когда обнаруживает ошибку атрибута, и это сигнализирует replace, что на этом узле ничего не следует делать. Когда вы используете лямбду, нечего ловить ошибку, поэтому процесс обращает ваше внимание на ошибку. Один из вариантов - изменить replace, чтобы он игнорировал ошибки и просто пропускал узел. Хорошая вещь о том, что не делает это, однако, заключается в том, что он предупреждает вас о том, что вы делаете что-то таким образом, что пропустите объекты, которые вы хотели обработать. Поэтому, чтобы использовать лямбду, вы должны помочь ей в определении условий интересов.

>>> L1 = lambda x: x.is_Pow and x.base in [a, b]
>>> inputstate.replace(L1, lambda expr: Bfunc(expr,a,b))
a[0]*b[0]
>>> L2 = lambda x: x.as_base_exp()[0] in [a, b]
>>> inputstate.replace(L1, lambda expr: Bfunc(expr,a,b))
a[0]*b[0]

(Я предпочитаю L1, потому что он использует быстрый тест is_Pow, чтобы узнать, имеет ли он дело с силой или нет. Ваш Bfunc предполагает, что он имеет дело с силой, поэтому L2 не будет работать во всех случаях, если вы не измените его). это , чтобы иметь дело с делом не-Пау.)

Один вопрос, на который нужно ответить, заключается в том, хотите ли вы нацелить действительные полномочия или также «полномочия» с показателем степени 1. Например, если вы хотите поднять показатели всех способностей на 1, вы бы хотели x*y**2 -> x**2*y**3 или просто x*y**3? L1 был бы хорош для первого случая и L2 для второго.

0 голосов
/ 07 мая 2019

допустим следующие коды:

import sympy as sp
a, b= sp.symbols('a b', cls=sp.IndexedBase)
l= sp.symbols('l', cls=sp.Wild)

def Bfunctest(expr,p1,p2):
    if expr.base==p1:return expr.replace(p1[l],0.2*p1[-l],map=False, simultaneous=True, exact=False)
    else: return expr.replace(p2[l],0.2*p2[-l],map=False, simultaneous=True, exact=False)

L1 = lambda expr: expr.is_Pow and expr.base in [a, b]
inputstate=a[1]*b[1]
out=inputstate.replace(L1, lambda expr: Bfunctest(expr,a,b))

Выходное значение равно a[1]*b[1], а не 0.04*a[-1]*b[-1], что означает, что Bfunctest() не исключено.

потому что inputstate.is_Pow and inputstate.base in [a, b] дает вам Ложь . Это происходит в том случае, когда вы используете inputstate.as_base_exp()[0] in [a, b], что дает False . Таким образом, Bfunctest() не будет исключен.

0 голосов
/ 25 апреля 2019

a является IndexedBase, а a[0] является Indexed объектом, чей base is a`:

In [21]: type(a)                                                                
Out[21]: sympy.tensor.indexed.IndexedBase
In [22]: type(a[0])                                                             
Out[22]: sympy.tensor.indexed.Indexed
In [23]: a[0].base                                                              
Out[23]: a

In [25]: inputstate=a[0]*b[0]                                                   
In [26]: inputstate                                                             
Out[26]: a[0]*b[0]
In [27]: type(inputstate)                                                       
Out[27]: sympy.core.mul.Mul

inputstate является Mul expr объектом,Это не Indexed, поэтому у него нет базы.

У вас есть запись о «правильном» поведении в более ранних версиях sympy или свидетельство каких-либо изменений в документации.В какой версии он работал?

Ваши Bfunc и replace, кажется, работают для меня:

In [51]: ab = inputstate.replace(lambda expr: expr.base in [a,b], lambda expr: Bfunc(expr,a,b))                                                        
In [52]: ab                                                                     
Out[52]: a[0]*b[0]
In [53]: type(ab)                                                               
Out[53]: sympy.core.mul.Mul

Какие изменения я должен увидеть?

In [55]: sp.__version__                                                         
Out[55]: '1.3'

Если я заменим лямбду replace небольшой функцией:

In [71]: def foo(expr): 
    ...:     try: 
    ...:         print(expr, expr.base) 
    ...:         return expr.base in [a,b] 
    ...:     except AttributeError: 
    ...:         print(expr) 
    ...:          
    ...:                                                                        
In [72]: ab = inputstate.replace(foo, lambda expr: Bfunc(expr,a,b))             
a
a
0
a[0] a
b
b
0
b[0] b
a[0]*b[0]

Похоже, что replace передает различные элементы expr в эту функцию.Такие ошибки, как AttributeError, игнорируются.

В примечаниях к выпуску 1.4 содержится информация о replace и его параметре exact.Интересно, что использование exact=False исправит ситуацию в 1.4 (я не могу проверить это без оценки).

https://docs.sympy.org/latest/modules/core.html#sympy.core.basic.Basic.replace

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...