Я предполагаю, что это похоже на Mathematica
Replace
метод .Также этот ответ на подобный вопрос может быть полезен.
По сути, он заменяет символ t
значением 0
.В вашем примере это не очень важно:
print(s.evalf().subs({t: 0}))
print(s.subs({t: 0}).evalf())
Оба оператора приводят к одному и тому же конечному значению.Однако при вычислении, например, производных, порядок имеет значение.Например,
In [76]: x=sympy.Symbol('x')
In [77]: sympy.diff(x**2, x)
Out[77]: 2*x
In [78]: sympy.diff((x**2).subs({'x':5}), x)
Out[78]: 0
In [79]: sympy.diff(x**2, x).subs({'x':5})
Out[79]: 10
В первом примере x
заменяется на 5 до дифференцирования (а производная от 25 по x равна 0), а во втором примересначала вычисляется производная (2*x
), а затем в этом производном выражении символ x
заменяется на 5, так что ответом является 2*5=10
.
РЕДАКТИРОВАТЬ после комментария @abarnet:
In [85]: import sympy
...:
...: omega, t = sympy.symbols("omega, t")
...: s = sympy.pi * sympy.cos(omega*t)
...:
...: # both result in 3.14159265358979
...: print(s.evalf().subs({t: 0}))
...: print(s.subs({t: 0}).evalf())
...: # results in 3.14159265358979*cos(omega*t)
...: print(s.evalf(subs={t: 0, omega: 1}))
...:
...:
3.14159265358979
3.14159265358979
3.14159265358979
Итак, предоставления просто t
недостаточно для sympy
- он не может оценить, что такое omega*0
, не зная, что такое omega
.
РЕДАКТИРОВАТЬ 2:
Второй пример работает, потому что оценка выполняется после замены, в то время как третий пример пытается выполнить числовую оценку с данными заменами и не может вычислить выражение численно (без omega
), и поэтому оставляет выражение в символической форме.Первый пример также работает, потому что он просто заменяет t
на 0 и упрощает выражение.Однако
In [86]: s.evalf()
Out[86]: 3.14159265358979*cos(omega*t)
РЕДАКТИРОВАТЬ 3:
Изучая код, становится ясно, что код evalf
(фактически одна из функций evalf_*
) пытается оценить каждый аргумент в args
независимо с заданными параметрами (т. Е. subs
), прежде чем приступить к оценке выражения.Так, в первом случае s.evalf().subs({t: 0})
, первый eval()
ничего не делает (ну, почти ... - он оценивает pi
в 3.1415...
), а subs({t: 0})
заменяет t
на 0, а затемвыражение переоценивается / упрощается до 3.14...
.Во втором случае сначала выполняется замена, а затем pi
оценивается как 3.1415...
.В третьем случае каждый аргумент в s.args
оценивается.Код здесь не выполняется (поскольку он не может оценить omega
с учетом предоставленной опции subs
) и возвращает входное выражение без изменений.
То есть третий параметр s.eval(subs={t: 0})
требует всех аргументовs
подлежит определению.Проверка этого выполняется здесь для mul
функции (очевидно, sympy
master опережает мою установленную версию).
Чтобы увидеть это, попробуйте простое выражение:
In [1]: import sympy
...: from sympy.core import evalf
...: t, x = sympy.symbols("t, x")
...:
...:
In [2]: (t*x).evalf(subs={t:0})
Out[2]: t*x
In [3]: evalf.evalf(t*x, 10, {t: 0})
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
~/.../lib/python3.5/site-packages/sympy/core/evalf.py in evalf(x, prec, options)
1285 rf = evalf_table[x.func]
-> 1286 r = rf(x, prec, options)
1287 except KeyError:
~/.../lib/python3.5/site-packages/sympy/core/evalf.py in evalf_symbol(x, prec, options)
1203 def evalf_symbol(x, prec, options):
-> 1204 val = options['subs'][x]
1205 if isinstance(val, mpf):
KeyError: 'subs'
During handling of the above exception, another exception occurred:
AttributeError Traceback (most recent call last)
~/.../lib/python3.5/site-packages/sympy/core/evalf.py in evalf(x, prec, options)
1292 xe = x._eval_evalf(prec)
-> 1293 re, im = xe.as_real_imag()
1294 if re.has(re_) or im.has(im_):
AttributeError: 'NoneType' object has no attribute 'as_real_imag'
During handling of the above exception, another exception occurred:
NotImplementedError Traceback (most recent call last)
<ipython-input-3-e075388b139d> in <module>()
----> 1 evalf.evalf(t*x, 10, {t: 0})
~/.../lib/python3.5/site-packages/sympy/core/evalf.py in evalf(x, prec, options)
1284 try:
1285 rf = evalf_table[x.func]
-> 1286 r = rf(x, prec, options)
1287 except KeyError:
1288 try:
~/.../lib/python3.5/site-packages/sympy/core/evalf.py in evalf_mul(v, prec, options)
536 from sympy.core.numbers import Float
537 for arg in args:
--> 538 arg = evalf(arg, prec, options)
539 if arg[0] is None:
540 continue
~/.../lib/python3.5/site-packages/sympy/core/evalf.py in evalf(x, prec, options)
1308 r = re, im, reprec, imprec
1309 except AttributeError:
-> 1310 raise NotImplementedError
1311 if options.get("verbose"):
1312 print("### input", x)
NotImplementedError:
In [4]: