SymPy中evalf方法subs参数的作用及运行差异疑问
evalf(subs={...}) Behavior Let me break down what's happening with the subs parameter in SymPy's evalf method, using your example to clarify the differences between the three approaches you tried.
Key Difference: How evalf(subs) Works vs. Separate subs + evalf
The subs parameter in evalf is not a shortcut for either s.evalf().subs(...) or s.subs(...).evalf(). Instead, it only applies substitutions to symbols that are directly evaluated during the numerical computation process—meaning it won't touch subexpressions that can't be fully evaluated to a number (because they still contain unassigned free symbols).
Let's Walk Through Your Example
Your code:
import sympy omega, t = sympy.symbols("omega, t") s = sympy.pi * sympy.cos(omega*t)
s.subs({t: 0}).evalf()- First, this performs a global substitution of
t=0across the entire expression, turningsintosympy.pi * sympy.cos(0)(which simplifies tosympy.pi * 1). - Then
evalf()converts the symbolicpito its numerical approximation. Result:3.14159265358979.
- First, this performs a global substitution of
s.evalf().subs({t: 0})- First,
evalf()converts the symbolicpito its numerical value, leaving the rest of the expression (which has unassignedomegaandt) as-is:3.14159265358979 * cos(omega*t). - Then
subs({t:0})performs a global substitution, turningcos(omega*t)intocos(0) = 1. Result:3.14159265358979.
- First,
s.evalf(subs={t: 0})- Here's where the behavior changes:
evalfstarts evaluating parts of the expression that can be turned into numbers. First, it convertssympy.pito its numerical value. - Next, it looks at
cos(omega*t). Sinceomegais a free, unassigned symbol, SymPy can't compute a numerical value for this cosine term—so it leaves the entire subexpressioncos(omega*t)in symbolic form. - Crucially: the
subs={t:0}parameter is only used for symbols that are being actively evaluated to a number. Since thecos(omega*t)subexpression isn't being numerically evaluated (because ofomega), SymPy doesn't apply thet=0substitution to it. - The final result is the numerical
pimultiplied by the untouched symboliccos(omega*t):3.14159265358979*cos(omega*t).
- Here's where the behavior changes:
When to Use evalf(subs)?
This parameter is useful when you have an expression with multiple symbols, some of which you want to assign values for numerical evaluation, while leaving others as symbols. For example:
s = sympy.pi * sympy.cos(omega*t) # If we assign both omega and t, evalf(subs) works as expected print(s.evalf(subs={omega: 1, t: 0})) # Output: 3.14159265358979
Here, since both symbols are assigned, SymPy can fully evaluate the cosine term numerically, so the substitutions are applied, and the whole expression becomes a single number.
内容的提问来源于stack exchange,提问作者finefoot

