def test_derivative_by_array(): from sympy.abc import a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z bexpr = x*y**2*exp(z)*log(t) sexpr = sin(bexpr) cexpr = cos(bexpr) a = Array([sexpr]) assert derive_by_array(sexpr, t) == x*y**2*exp(z)*cos(x*y**2*exp(z)*log(t))/t assert derive_by_array(sexpr, [x, y, z]) == Array([bexpr/x*cexpr, 2*y*bexpr/y**2*cexpr, bexpr*cexpr]) assert derive_by_array(a, [x, y, z]) == Array([[bexpr/x*cexpr], [2*y*bexpr/y**2*cexpr], [bexpr*cexpr]]) assert derive_by_array(sexpr, [[x, y], [z, t]]) == Array([[bexpr/x*cexpr, 2*y*bexpr/y**2*cexpr], [bexpr*cexpr, bexpr/log(t)/t*cexpr]]) assert derive_by_array(a, [[x, y], [z, t]]) == Array([[[bexpr/x*cexpr], [2*y*bexpr/y**2*cexpr]], [[bexpr*cexpr], [bexpr/log(t)/t*cexpr]]]) assert derive_by_array([[x, y], [z, t]], [x, y]) == Array([[[1, 0], [0, 0]], [[0, 1], [0, 0]]]) assert derive_by_array([[x, y], [z, t]], [[x, y], [z, t]]) == Array([[[[1, 0], [0, 0]], [[0, 1], [0, 0]]], [[[0, 0], [1, 0]], [[0, 0], [0, 1]]]]) assert diff(sexpr, t) == x*y**2*exp(z)*cos(x*y**2*exp(z)*log(t))/t assert diff(sexpr, Array([x, y, z])) == Array([bexpr/x*cexpr, 2*y*bexpr/y**2*cexpr, bexpr*cexpr]) assert diff(a, Array([x, y, z])) == Array([[bexpr/x*cexpr], [2*y*bexpr/y**2*cexpr], [bexpr*cexpr]]) assert diff(sexpr, Array([[x, y], [z, t]])) == Array([[bexpr/x*cexpr, 2*y*bexpr/y**2*cexpr], [bexpr*cexpr, bexpr/log(t)/t*cexpr]]) assert diff(a, Array([[x, y], [z, t]])) == Array([[[bexpr/x*cexpr], [2*y*bexpr/y**2*cexpr]], [[bexpr*cexpr], [bexpr/log(t)/t*cexpr]]]) assert diff(Array([[x, y], [z, t]]), Array([x, y])) == Array([[[1, 0], [0, 0]], [[0, 1], [0, 0]]]) assert diff(Array([[x, y], [z, t]]), Array([[x, y], [z, t]])) == Array([[[[1, 0], [0, 0]], [[0, 1], [0, 0]]], [[[0, 0], [1, 0]], [[0, 0], [0, 1]]]]) # test for large scale sparse array for SparseArrayType in [ImmutableSparseNDimArray, MutableSparseNDimArray]: b = MutableSparseNDimArray({0:i, 1:j}, (10000, 20000)) assert derive_by_array(b, i) == ImmutableSparseNDimArray({0: 1}, (10000, 20000)) assert derive_by_array(b, (i, j)) == ImmutableSparseNDimArray({0: 1, 200000001: 1}, (2, 10000, 20000))
def _solve(self, x): # substitute variables with binding positivitiy constraints cpos = self.constraints.tolist(('col', ''), is_positivity_constraint=True) subs_zero = {cstr.expr_0: sp.Integer(0) for col, cstr in cpos if x[cstr.col]} mat = derive_by_array(x.lagrange, x.variabs_multips) mat = sp.Matrix(mat).expand() mat = mat.subs(subs_zero) variabs_multips_slct = list(OrderedSet(x.variabs_multips) - OrderedSet(subs_zero)) A, b = linear_eq_to_matrix(mat, variabs_multips_slct) MP_COUNTER.increment() solution_0 = sp.linsolve((A, b), variabs_multips_slct) if isinstance(solution_0, sp.sets.EmptySet): return None else: # init with zeros solution_dict = dict.fromkeys(x.variabs_multips, sp.Integer(0)) # update with solutions solution_dict.update(dict(zip(variabs_multips_slct, list(solution_0)[0]))) solution = tuple(solution_dict.values()) return solution
def generate_grad(self, symb_fun, vars_, init, poly): args = init + poly return sym.lambdify( (vars_, *args), derive_by_array(symb_fun, vars_+args)[:len(vars_)], self.evaluator )
def test_derivative_by_array(): from sympy.abc import a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z bexpr = x*y**2*exp(z)*log(t) sexpr = sin(bexpr) cexpr = cos(bexpr) a = Array([sexpr]) assert derive_by_array(sexpr, t) == x*y**2*exp(z)*cos(x*y**2*exp(z)*log(t))/t assert derive_by_array(sexpr, [x, y, z]) == Array([bexpr/x*cexpr, 2*y*bexpr/y**2*cexpr, bexpr*cexpr]) assert derive_by_array(a, [x, y, z]) == Array([[bexpr/x*cexpr], [2*y*bexpr/y**2*cexpr], [bexpr*cexpr]]) assert derive_by_array(sexpr, [[x, y], [z, t]]) == Array([[bexpr/x*cexpr, 2*y*bexpr/y**2*cexpr], [bexpr*cexpr, bexpr/log(t)/t*cexpr]]) assert derive_by_array(a, [[x, y], [z, t]]) == Array([[[bexpr/x*cexpr], [2*y*bexpr/y**2*cexpr]], [[bexpr*cexpr], [bexpr/log(t)/t*cexpr]]]) assert derive_by_array([[x, y], [z, t]], [x, y]) == Array([[[1, 0], [0, 0]], [[0, 1], [0, 0]]]) assert derive_by_array([[x, y], [z, t]], [[x, y], [z, t]]) == Array([[[[1, 0], [0, 0]], [[0, 1], [0, 0]]], [[[0, 0], [1, 0]], [[0, 0], [0, 1]]]]) assert diff(sexpr, t) == x*y**2*exp(z)*cos(x*y**2*exp(z)*log(t))/t assert diff(sexpr, Array([x, y, z])) == Array([bexpr/x*cexpr, 2*y*bexpr/y**2*cexpr, bexpr*cexpr]) assert diff(a, Array([x, y, z])) == Array([[bexpr/x*cexpr], [2*y*bexpr/y**2*cexpr], [bexpr*cexpr]]) assert diff(sexpr, Array([[x, y], [z, t]])) == Array([[bexpr/x*cexpr, 2*y*bexpr/y**2*cexpr], [bexpr*cexpr, bexpr/log(t)/t*cexpr]]) assert diff(a, Array([[x, y], [z, t]])) == Array([[[bexpr/x*cexpr], [2*y*bexpr/y**2*cexpr]], [[bexpr*cexpr], [bexpr/log(t)/t*cexpr]]]) assert diff(Array([[x, y], [z, t]]), Array([x, y])) == Array([[[1, 0], [0, 0]], [[0, 1], [0, 0]]]) assert diff(Array([[x, y], [z, t]]), Array([[x, y], [z, t]])) == Array([[[[1, 0], [0, 0]], [[0, 1], [0, 0]]], [[[0, 0], [1, 0]], [[0, 0], [0, 1]]]])
def test_issue_22726(): if not numpy: skip("numpy not installed") x1, x2 = symbols('x1 x2') f = Max(S.Zero, Min(x1, x2)) g = derive_by_array(f, (x1, x2)) G = lambdify((x1, x2), g, modules='numpy') point = {x1: 1, x2: 2} assert (abs(g.subs(point) - G(*point.values())) <= 1e-10).all()
def model(self, u, var, returnlatex=False): from sympy.tensor.array import derive_by_array, tensorproduct m = len(var) gradient = Matrix(derive_by_array(u, var)) length = sqrt(trace(Matrix(tensorproduct(gradient, gradient)).reshape(m, m))) n = gradient/length div = Matrix(derive_by_array(n, var)).reshape(m, m) div_n = trace(div) # div_n = sym.simplify(div_n) hessian = Matrix(derive_by_array(gradient, var)).reshape(m, m) laplace = trace(hessian) laplace = sym.simplify(laplace) val = {'grad': gradient, 'Hessian': hessian, 'Laplace': laplace, 'unit_normal':n, 'div_unit_normal':div_n} if returnlatex is False: return val else: print('grad:\n', printing.latex(val['grad'])) print('Hessian:\n', printing.latex(val['Hessian'])) print('Laplace:\n', printing.latex(val['Laplace'])) print('unit_normal:\n', printing.latex(val['unit_normal'])) print('div_unit_normal:\n', printing.latex(val['div_unit_normal']))
def show_pde(self): u = self.u phi = self.phi gu = derive_by_array(u, (x, y, z)) hu = derive_by_array(gu, (x, y, z)).tomatrix() lu = tensorcontraction(hu, (0, 1)) n = derive_by_array(phi, (x, y, z)) n /= sqrt(n[0]**2 + n[1]**2 + n[2]**2) hn = derive_by_array(n, (x, y, z)).tomatrix() dn = tensorcontraction(hn, (0, 1)) gu = Matrix(gu) n = Matrix(n) t0 = lu - (gu.transpose() * n)[0, 0] * dn t1 = n.transpose() * hu * n f = -t0 + t1[0, 0] gu -= (gu.T * n)[0, 0] * n return u, gu, f.simplify()
def _eval_derivative(self, wrt): from sympy.tensor.array.ndim_array import NDimArray if isinstance(wrt, Indexed) and wrt.base == self.base: if len(self.indices) != len(wrt.indices): msg = "Different # of indices: d({!s})/d({!s})".format(self, wrt) raise IndexException(msg) result = S.One for index1, index2 in zip(self.indices, wrt.indices): result *= KroneckerDelta(index1, index2) return result elif isinstance(self.base, NDimArray): from sympy.tensor.array import derive_by_array return Indexed(derive_by_array(self.base, wrt), *self.args[1:]) else: return S.Zero
def bond_hessian(j, z1, z2, z3, tau=3.0): # f1 = spot_rate(j,z1, z2, z3) bond_price = 1 / (1 + allfunctions.spot_rate(j, z1, z2, z3, tau))**j hessian = derive_by_array(derive_by_array(bond_price, (z1, z2, z3)), (z1, z2, z3)) return hessian
def bond_grad(j, z1, z2, z3, tau=3.0): bond_price = 1 / (1 + allfunctions.spot_rate(j, z1, z2, z3, tau))**j grad = derive_by_array(bond_price, (z1, z2, z3)) return grad
def gradient(self): """ returns the gradient of phi as a sympy Matrix (col vector) """ phi = Array([self.phi]) gradphi = derive_by_array(phi, self.basis) return gradphi.tomatrix()
from sympy import MatrixSymbol, Matrix, symbols, exp, pprint, log, hessian from sympy.tensor.array import derive_by_array import numpy as np x = symbols('x') y = symbols('y') THETA = MatrixSymbol('THETA', 2, 1) f = x**4 + 3 * y**4 + x**2 + x**2 * y**2 + x + 2 + y**2 + y**3 + y gradP = Matrix(derive_by_array(f, [x, y])) pprint(gradP) hessenP = Matrix(hessian(f, [x, y])) pprint(hessenP) thetaResult = Matrix([[1], [1]]) xyMap = {x: 1, y: 1} while True: xOld = xyMap[x] yOld = xyMap[y] gradPTemp = gradP.subs(xyMap).evalf() hessenPTemp = hessenP.subs(xyMap).evalf() diff = hessenPTemp.inv() * gradPTemp xyMap[x] = xyMap[x] - Matrix(diff).tolist()[0][0] xyMap[y] = xyMap[y] - Matrix(diff).tolist()[1][0] xDelta = xOld - xyMap[x] yDelta = yOld - xyMap[y] temp = xDelta * xDelta + yDelta * yDelta print(temp) if (temp < 0.00000000001): break
# https://stackoverflow.com/questions/39558515/how-to-get-the-gradient-and-hessian-sympy from sympy import Function, Matrix, Symbol, simplify, symbols from sympy.tensor.array import derive_by_array eta, xi, sigma = symbols("eta xi sigma") x = Matrix([[xi], [eta]]) h = [Function("h_" + str(i + 1))(x[0], x[1]) for i in range(3)] z = [Symbol("z_" + str(i + 1)) for i in range(3)] lamb = 0 for i in range(3): lamb += 1 / (2 * sigma**2) * (z[i] - h[i])**2 lamb = simplify(lamb) gradient = derive_by_array(lamb, (eta, xi)) print(type(gradient)) print(gradient) hessian = derive_by_array(gradient, (eta, xi)) print(type(hessian)) print(hessian)
def show_surface(self): phi = self.phi n0 = derive_by_array(phi, (x, y, z)) n /= sqrt(n[0]**2 + n[1]**2 + n[2]**2) hn = derive_by_array(n, (x, y, z)).tomatrix() dn = tensorcontraction(hn, (0, 1))
def grad(f, *args): gradient = Matrix(derive_by_array(f, args)) return gradient
def hessian(f, *args): n = len(args) gradient = Matrix(derive_by_array(f, args)) hessian = Matrix(derive_by_array(gradient, args)).reshape(n, n) return hessian
def main(): """Run main.""" print('Starting program...') # Definition of variables Csa = Symbol('Csa') Csv = Symbol('Csv') Cpa = Symbol('Cpa') Cpv = Symbol('Cpv') # Definition of equations Tsa = Csa/Kr + Csa*Rs Tsv = Csv/Kr Tpa = Cpa/Kl + Cpa*Rp Tpv = Cpv/Kl Tsum = Tsa+Tsv+Tpa+Tpv # Volumes Vsa = Tsa*V/Tsum Vsv = Tsv*V/Tsum Vpa = Tpa*V/Tsum Vpv = Tpv*V/Tsum Vsum = Vsa + Vsv + Vpa + Vpv Vtot = lambdify((Csa, Csv, Cpa, Cpv), Vsum) # Pressures Psa = Tsa*V/(Csa*Tsum) Psv = Tsv*V/(Csv*Tsum) Ppa = Tpa*V/(Cpa*Tsum) Ppv = Tpv*V/(Cpv*Tsum) # Objective Function f_obj = V/(Tsum) f = lambdify((Csa, Csv, Cpa, Cpv), f_obj) # Partial derivatives of objective function partial = derive_by_array(f_obj, (Csa, Csv, Cpa, Cpv)) grad = lambdify((Csa, Csv, Cpa, Cpv), partial) # Tolerance - num iterations # tol = 0.001 n = 10000 # Start seed for the random function # np.random.seed(1) # Generate random values for init Cpa, Cpv, Csa, Csv x = np.random.rand(4) min_val = 5000000 min_x = x while(n > 0): # Check all x are positive for val in x: if val < 0: val = abs(val) # Check the volume restriction act_v = Vtot(x[0], x[1], x[2], x[3]) if act_v != V: y = V*np.ones(4) diff = np.abs(np.subtract(x, y)) val, idx = min((val, idx) for (idx, val) in enumerate(diff)) x[idx] = val # Calculate gradient given the points g = grad(x[0], x[1], x[2], x[3]) # Calculate the value of the objective function act = f(x[0], x[1], x[2], x[3]) if(act < min_val): min_val = act min_x = x # Modify the actual value depending the gradient val, idx = max((val, idx) for (idx, val) in enumerate(g)) x[idx] = abs(x[idx] + val) n = n - 1 print(' Csa: {} \n Csv: {} \n Cpa: {} \n Cpv: {} \n'.format( min_x[0], min_x[1], min_x[2], min_x[3]))
def gradient(self): """ returns a sympy matrix containing Dij = dvj/dxi (vj by col, d/dxi by row) """ v = Array(self.v) gradv = derive_by_array(v, self.basis) return gradv.tomatrix()