SymPy : creating a numpy function from diagonal matrix that takes a numpy array
The creation of a numeric 3 by 3 matrix from a numeric vector is not really a SymPy thing, since no symbols are involved. Consider the following, where the argument d is an array holding the diagonal elements.
def mat(d): return np.diag(d-4) + 4
The above function returns a 2d NumPy array. To return a SymPy matrix instead, use
def mat(d): return sp.Matrix(np.diag(d-4) + 4)
When d has extremely small values, the subtraction followed by addition may cause loss of precision: for example, (1e-20 - 4) + 4
evaluates to zero. A safer alternative is
def mat(d): diagmat = np.diag(d) return diagmat + np.fromfunction(lambda i, j: (i != j)*4, diagmat.shape)
you can .subs() float values into the respective symbols:
import sympy as spimport numpy as npx1 = 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)smyMOut[105]: Matrix([[x1, 4, 4],[ 4, x2, 4],[ 4, 4, x3]])fmyMOut[106]: Matrix([[0.1, 4, 4],[ 4, 0.2, 4],[ 4, 4, 0.3]])
seems to be a fine sympy.matrices.dense.MutableDenseMatrix
Matrix after:
fmyM @ myMOut[107]: Matrix([[32.4, 32.4, 32.4],[32.8, 32.8, 32.8],[33.2, 33.2, 33.2]])
may need conversion to a np.array for full use with numpy
below is some of my code showing more of the pattern I used:
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, f1f0, f1 = ysolv(t[0])y0 = [f0(x) for x in xs]y1 = [f1(x) for x in xs]...
from: https://stackoverflow.com/a/41232062/6876009 (yes, my "feeloutXrange" there is a hack so bad it had to be shown)