如何使用命令eval与矩阵

时间:2022-02-27 21:35:37

I have any Symbols:

我有任何符号:

In [1]: from sympy import *

In [2]: import numpy as np

In [3]: x=Symbol('x')

And I created any matrix:

我创建了任何矩阵:

In [4]: a=Matrix([[2*x**2,3+x],[4*x**3,-5*x]])

In [5]: a
Out[5]:
  Matrix([
          [2*x**2, x + 3],
          [4*x**3,  -5*x]])

if x=1 I want to evaluate the matrix a. I use the command eval:

如果x = 1我想评估矩阵a。我使用命令eval:

In [6]: x=1

In [7]: eval('a')

Out[7]:
  Matrix([
          [2*x**2, x + 3],
          [4*x**3,  -5*x]]) 

I want to obtain this ouput:

我想获得这个输出:

Out[7]:
  Matrix([
          [2, 4],
          [4, -5]]) 

What's wrong with what I am doing?

我在做什么有什么问题?

1 个解决方案

#1


0  

Use the subs method:

使用subs方法:

import sympy as sy

x = sy.Symbol('x')
a = sy.Matrix([[2*x**2,3+x],[4*x**3,-5*x]])

print(a.subs(dict(x=1)))
# [2,  4]
# [4, -5]

or the evalf method:

或者evalf方法:

print(a.evalf(subs=dict(x=1)))
# [2.0,  4.0]
# [4.0, -5.0]

If you have more than one Symbol to substitute, just add them to the substitution dict. For example,

如果要替换多个Symbol,只需将它们添加到替换词典中即可。例如,

a.subs(dict(x=1, y=exp(5)))

Note that if you define

请注意,如果您定义

x = sy.Symbol('x')

then you are binding the name x to the object sy.Symbol('x'). If later on you assign

然后你将名称x绑定到对象sy.Symbol('x')。如果你以后再分配

x = 1

then you are rebinding the name x to a different object, the int 1. The old Symbol object still exists, its just the name x no longer references it. (In Python names (aka variables) simply map to objects).

然后你将名称x重新绑定到另一个对象,int 1.旧的Symbol对象仍然存在,只是名称x不再引用它。 (在Python名称(又名变量)中只是映射到对象)。

Meanwhile if you bind a to a Matrix:

同时,如果你绑定到矩阵:

a = sy.Matrix([[2*x**2,3+x],[4*x**3,-5*x]])

that Matrix object may use the the Symbol whose repr is x. Note carefully that this x is not the Python variable, rather it is the Symbol object itself.

Matrix对象可以使用其repr为x的Symbol。请注意,此x不是Python变量,而是Symbol对象本身。

So reassigning x to 1 has no impact on a. That is why eval('a') does not substitute the new binding for x. Instead eval('a') simply looks up the bare name a in the global namespace, finds that it maps to the Matrix object and returns that Matrix.

所以将x重新分配为1对a没有影响。这就是eval('a')不能用x替换新绑定的原因。相反,eval('a')只是在全局命名空间中查找裸名称a,发现它映射到Matrix对象并返回该Matrix。


If you want the Matrix to automatically update when x is changed, one possible solution would be to subclass Matrix and define a new property that performs the subs call for you. For example,

如果希望Matrix在x更改时自动更新,一种可能的解决方案是子类化Matrix并定义一个为您执行子调用的新属性。例如,

import sympy as sy
import math

class UpdatingMatrix(sy.Matrix):
    def __init__(self, *args):
        super(UpdatingMatrix, self).__init__(*args)
        self._names = set([symbol.name for expr in self.mat
                           for symbol in expr.free_symbols])
    @property
    def val(self):
        return self.subs({name:eval(name) for name in self._names})

x = sy.Symbol('x')
y = sy.Symbol('y')
a = UpdatingMatrix([[2*x**2,3+x*y],[4*x**3,-5*x]])
x = 100
y = 1
print(a.val)

yields

产量

[  20000,  103]
[4000000, -500]

Note that you have to use a.val to see the updated value; I don't see a way to automatically change a itself when performing an assignment like x = 1. That might not be desirable anyway, since if that were possible, then a could not update itself a second time in you were to later assign x = 2 (since a would no longer depend on x.) With the solution above, each time you access a.val, the substitutions are re-applied, so a.val would return the value of a with respect to the current values of x and y.

请注意,您必须使用a.val来查看更新的值;在执行像x = 1这样的赋值时,我没有看到自动更改自身的方法。无论如何,这可能是不可取的,因为如果可能的话,那么第二次无法更新自己以后再分配x = 2(因为a不再依赖于x。)使用上面的解决方案,每次访问a.val时,都会重新应用替换,因此a.val将返回相对于当前值的a的值。 x和y。

#1


0  

Use the subs method:

使用subs方法:

import sympy as sy

x = sy.Symbol('x')
a = sy.Matrix([[2*x**2,3+x],[4*x**3,-5*x]])

print(a.subs(dict(x=1)))
# [2,  4]
# [4, -5]

or the evalf method:

或者evalf方法:

print(a.evalf(subs=dict(x=1)))
# [2.0,  4.0]
# [4.0, -5.0]

If you have more than one Symbol to substitute, just add them to the substitution dict. For example,

如果要替换多个Symbol,只需将它们添加到替换词典中即可。例如,

a.subs(dict(x=1, y=exp(5)))

Note that if you define

请注意,如果您定义

x = sy.Symbol('x')

then you are binding the name x to the object sy.Symbol('x'). If later on you assign

然后你将名称x绑定到对象sy.Symbol('x')。如果你以后再分配

x = 1

then you are rebinding the name x to a different object, the int 1. The old Symbol object still exists, its just the name x no longer references it. (In Python names (aka variables) simply map to objects).

然后你将名称x重新绑定到另一个对象,int 1.旧的Symbol对象仍然存在,只是名称x不再引用它。 (在Python名称(又名变量)中只是映射到对象)。

Meanwhile if you bind a to a Matrix:

同时,如果你绑定到矩阵:

a = sy.Matrix([[2*x**2,3+x],[4*x**3,-5*x]])

that Matrix object may use the the Symbol whose repr is x. Note carefully that this x is not the Python variable, rather it is the Symbol object itself.

Matrix对象可以使用其repr为x的Symbol。请注意,此x不是Python变量,而是Symbol对象本身。

So reassigning x to 1 has no impact on a. That is why eval('a') does not substitute the new binding for x. Instead eval('a') simply looks up the bare name a in the global namespace, finds that it maps to the Matrix object and returns that Matrix.

所以将x重新分配为1对a没有影响。这就是eval('a')不能用x替换新绑定的原因。相反,eval('a')只是在全局命名空间中查找裸名称a,发现它映射到Matrix对象并返回该Matrix。


If you want the Matrix to automatically update when x is changed, one possible solution would be to subclass Matrix and define a new property that performs the subs call for you. For example,

如果希望Matrix在x更改时自动更新,一种可能的解决方案是子类化Matrix并定义一个为您执行子调用的新属性。例如,

import sympy as sy
import math

class UpdatingMatrix(sy.Matrix):
    def __init__(self, *args):
        super(UpdatingMatrix, self).__init__(*args)
        self._names = set([symbol.name for expr in self.mat
                           for symbol in expr.free_symbols])
    @property
    def val(self):
        return self.subs({name:eval(name) for name in self._names})

x = sy.Symbol('x')
y = sy.Symbol('y')
a = UpdatingMatrix([[2*x**2,3+x*y],[4*x**3,-5*x]])
x = 100
y = 1
print(a.val)

yields

产量

[  20000,  103]
[4000000, -500]

Note that you have to use a.val to see the updated value; I don't see a way to automatically change a itself when performing an assignment like x = 1. That might not be desirable anyway, since if that were possible, then a could not update itself a second time in you were to later assign x = 2 (since a would no longer depend on x.) With the solution above, each time you access a.val, the substitutions are re-applied, so a.val would return the value of a with respect to the current values of x and y.

请注意,您必须使用a.val来查看更新的值;在执行像x = 1这样的赋值时,我没有看到自动更改自身的方法。无论如何,这可能是不可取的,因为如果可能的话,那么第二次无法更新自己以后再分配x = 2(因为a不再依赖于x。)使用上面的解决方案,每次访问a.val时,都会重新应用替换,因此a.val将返回相对于当前值的a的值。 x和y。