基于我在这里找到的一个例子,我试图从使用的对角矩阵创建一个函数sumpy.diag
myM = Matrix([ [x1, 4, 4], [4, x2, 4], [4, 4, x3]])
这是使用此例程创建的,例如:
import sympy as sp import numpy as np x1 = sp.Symbol('x1') x2 = sp.Symbol('x2') x3 = sp.Symbol('x3') X = sp.Matrix([x1, x2, x3]) myM = 4 * sp.ones(3, 3) sp.diag(*X) + myM - sp.diag(*np.diag(myM))
现在我将要创建一个函数,使用lambdify
的ufuncify
,采用一个numpy.array
或长度3(像np.array([0.1,0.2,0.3])
)作为输入,并给出输出作为根据矩阵myM
myM = Matrix([ [0.1, 4, 4], [4, 0.2, 4], [4, 4, 0.3]])
最终我需要使用这种方法象征性地创建雅可比矩阵: 并且由于函数形式可能在计算过程中发生变化,因此以符号方式计算雅可比矩阵将非常有用.
从数字向量创建数字3乘3矩阵实际上不是SymPy事物,因为不涉及符号.请考虑以下内容,其中参数d是包含对角元素的数组.
def mat(d): return np.diag(d-4) + 4
上面的函数返回一个2d NumPy数组.要改为返回SymPy矩阵,请使用
def mat(d): return sp.Matrix(np.diag(d-4) + 4)
当d具有极小的值时,减法后加法可能会导致精度损失:例如,(1e-20 - 4) + 4
求值为零.更安全的选择是
def mat(d): diagmat = np.diag(d) return diagmat + np.fromfunction(lambda i, j: (i != j)*4, diagmat.shape)
你可以.subs()将值浮动到相应的符号中:
import sympy as sp import numpy as np x1 = sp.Symbol('x1') x2 = sp.Symbol('x2') x3 = sp.Symbol('x3') X = sp.Matrix([x1, x2, x3]) myM = 4 * sp.ones(3, 3) smyM=sp.diag(*X) + myM - sp.diag(*np.diag(myM)) fcoefs = [(a, f) for a, f in (zip([x1, x2, x3], np.array([0.1,0.2,0.3])))] fmyM = smyM.subs(fcoefs) smyM Out[105]: Matrix([ [x1, 4, 4], [ 4, x2, 4], [ 4, 4, x3]]) fmyM Out[106]: Matrix([ [0.1, 4, 4], [ 4, 0.2, 4], [ 4, 4, 0.3]])
似乎是一个很好的sympy.matrices.dense.MutableDenseMatrix
矩阵之后:
fmyM @ myM Out[107]: Matrix([ [32.4, 32.4, 32.4], [32.8, 32.8, 32.8], [33.2, 33.2, 33.2]])
可能需要转换为np.array以便与numpy一起使用
下面是我的一些代码,显示了我使用的更多模式:
def ysolv(coeffs): x,y,a,b,c,d,e = symbols('x y a b c d e') ellipse = a*y**2 + b*x*y + c*x + d*y + e - x**2 y_sols = solve(ellipse, y) print(*y_sols, sep='\n') num_coefs = [(a, f) for a, f in (zip([a,b,c,d,e], coeffs))] y_solsf0 = y_sols[0].subs(num_coefs) y_solsf1 = y_sols[1].subs(num_coefs) f0 = lambdify([x], y_solsf0) f1 = lambdify([x], y_solsf1) return f0, f1 f0, f1 = ysolv(t[0]) y0 = [f0(x) for x in xs] y1 = [f1(x) for x in xs] ...
来自:https://stackoverflow.com/a/41232062/6876009(是的,我的"feeloutXrange"有一个黑客那么糟糕,它必须显示)