def test_solve_poly_system(): assert solve_poly_system([x - 1], x) == [(S.One, )] assert solve_poly_system([y - x, y - x - 1], x, y) == None assert solve_poly_system([y - x**2, y + x**2], x, y) == [(S.Zero, S.Zero)] assert solve_poly_system([2*x - 3, 3*y/2 - 2*x, z - 5*y], x, y, z) == \ [(Rational(3, 2), Integer(2), Integer(10))] assert solve_poly_system([x*y - 2*y, 2*y**2 - x**2], x, y) == \ [(0, 0), (2, -2**S.Half), (2, 2**S.Half)] assert solve_poly_system([y - x**2, y + x**2 + 1], x, y) == \ [(I*S.Half**S.Half, -S.Half), (-I*S.Half**S.Half, -S.Half)] a, b = -1 - 2**S.Half, -1 + 2**S.Half assert solve_poly_system([x**2+y+z-1, x+y**2+z-1, x+y+z**2-1], x, y, z) == \ [(a, a, a), (0, 0, 1), (0, 1, 0), (b, b, b), (1, 0, 0)] solution = [(1, -1), (1, 1)] assert solve_poly_system([Poly(x**2 - y**2), Poly(x - 1)]) == solution assert solve_poly_system([x**2 - y**2, x - 1], x, y) == solution assert solve_poly_system([x**2 - y**2, x - 1]) == solution raises(ValueError, "solve_poly_system([x**3-y**3], x, y)")
def test_solve_poly_system(): assert solve_poly_system([x-1], x) == [(S.One,)] assert solve_poly_system([y - x, y - x - 1], x, y) == None assert solve_poly_system([y - x**2, y + x**2], x, y) == [(S.Zero, S.Zero)] assert solve_poly_system([2*x - 3, 3*y/2 - 2*x, z - 5*y], x, y, z) == \ [(Rational(3, 2), Integer(2), Integer(10))] assert solve_poly_system([x*y - 2*y, 2*y**2 - x**2], x, y) == \ [(0, 0), (2, -2**S.Half), (2, 2**S.Half)] assert solve_poly_system([y - x**2, y + x**2 + 1], x, y) == \ [(I*S.Half**S.Half, -S.Half), (-I*S.Half**S.Half, -S.Half)] a, b = -1 - 2**S.Half, -1 + 2**S.Half assert solve_poly_system([x**2+y+z-1, x+y**2+z-1, x+y+z**2-1], x, y, z) == \ [(a, a, a), (0, 0, 1), (0, 1, 0), (b, b, b), (1, 0, 0)] solution = [(1, -1), (1, 1)] assert solve_poly_system([Poly(x**2 - y**2), Poly(x - 1)]) == solution assert solve_poly_system([x**2 - y**2, x - 1], x, y) == solution assert solve_poly_system([x**2 - y**2, x - 1]) == solution raises(ValueError, "solve_poly_system([x**3-y**3], x, y)")
def __init__(self, A, B, C, D, E, F): self.A, self.B, self.C, self.D, self.E, self.F = A, B, C, D, E, F print("{}*x^2 + {}*x*y + {}*y^2 + {}*x + {}*y + {} = 0".format( A, 2 * B, C, 2 * D, 2 * E, F)) inv1 = self.A + self.C inv2 = numpy.linalg.det([[self.A, self.B], [self.B, self.C]]) inv3 = numpy.linalg.det([[self.A, self.B, self.D], [self.B, self.C, self.E], [self.D, self.E, self.F]]) ans = sympy.solve_poly_system([ symx + symy - inv1, symx * symy - inv2, symx * symy * symz - inv3 ], symx, symy, symz) coeffs = list(filter(lambda x: x[1] * x[2] >= 0, ans)) if coeffs is None: raise HyperbolaException("not a hyp") coeffs = coeffs[0] if coeffs[0] < 0 and coeffs[1] > 0 and coeffs[2] > 0: coeffs = [-x for x in coeffs] A1 = coeffs[0] C1 = coeffs[1] F1 = -coeffs[2] a_can_big = F1 / A1 b_can_big = F1 / -C1 a_can = sqrt(a_can_big) b_can = sqrt(b_can_big) c_can = sqrt(a_can_big + b_can_big) rotate_angle = pi / 4 if A != C: # я проверка угла rotate_angle = atan(2 * B / (A - C)) / 2 # начало ск new_point = sympy.solve_poly_system( [A * symx + B * symy + D, B * symx + C * symy + E], symx, symy)[0] self.delta = 2 * a_can sys_coord = [ geom.SysCoord(rotate_angle, [(-a_can, 0), (a_can, 0)], [(-c_can, 0), (c_can, 0)], new_point), geom.SysCoord(rotate_angle + pi / 2, [(-a_can, 0), (a_can, 0)], [(-c_can, 0), (c_can, 0)], new_point), geom.SysCoord(rotate_angle - pi / 2, [(-a_can, 0), (a_can, 0)], [(-c_can, 0), (c_can, 0)], new_point) ] self.starting_points, self.focuses, self.rotate_angle = self.take_syscoord( sys_coord) line = (tan(self.rotate_angle), -1, 0) print(self.starting_points) self.left_points, self.right_points = geom.get_left_right_points(line)
def ψ(H, Φ, Θ): L = Symbol('L') syms = [] for i in range(H, -1, -1): syms.append(Symbol('ψ_{}'.format(i))) Z = Poly(syms, L) AR = Poly([-1*φ for φ in reversed(Φ)]+[1], L) MA = Poly([-1*θ for θ in reversed(Θ)]+[1], L) S = (AR*Z-MA).all_coeffs() if len(Θ) == 0 and len(Φ) == 1: ψ_ = [Φ[0]**k for k in range(H)] elif len(Θ) == 1 and len(Φ) == 1: ψ_ = [1]+np.round([Φ[0]**k*(Φ[0]-Θ[0]) for k in range(H-1)], 5).tolist() else: ψ_ = solve_poly_system(S[len(S)-H-1:])[0] M = np.empty((H, H)) for i in range(H): for j in range(H): M[i, j] = -1*ψ_[i-j] if i > j-1 else 0 return np.array(M, dtype=np.double)
def findCoefficients(): A, B, C, D, E, F = (a, -1 / 2, 0, (b + a * d) / 2, -d / 2, b * d + c) #A, B, C, D, E, F = [-3, -1 / 2, 0, -4 / 2, 5 / 2, -1] print((A, B, C, D, E, F)) g = numpy.linalg.det([[A, B, D], [B, C, E], [D, E, F]]) h = numpy.linalg.det([[A, B], [B, C]]) s = A + C all = sympy.solve_poly_system( [symx + symy - s, symx * symy - h, symx * symy * symz - g], symx, symy, symz) k = -all[0][2] nA = all[0][0] / k mB = all[0][1] / k if nA < 0: nA = all[1][0] / k mB = all[1][1] / k if mB < 0: mB *= -1 nA2 = 1 / nA #a^2 mB2 = 1 / mB #b^2 cF = math.sqrt(mB2 + nA2) #x f aX = math.sqrt(nA2) al = math.atan(2 * B / (A - C)) / 2 #true findStart(A, B, C, D, E, cF, al, aX)
def solveSimultaneousEqs(eq): ''' Solve Simultaneous Equations Finite solutions only. No expression based answers. Usage: eq = list() eq.append("-x/10-x/5-6-(x-y)/2") eq.append("y/4-3-6-(x-y)/2") solveSimultaneousEqs(eq) ''' eq = [sympify(expr) for expr in eq] freesym = [expr.free_symbols for expr in eq] freevar = list() for freeset in freesym: for sym in freeset: freevar.append(sym) freevar = list(set(freevar)) for sym in freevar: exec(f"{sym.name}=symbols('{sym.name}')") solutions = solve_poly_system(eq, freevar) solutionList = list() freevar = [str(var) for var in freevar] for possibility in solutions: possibility = [float(num) for num in possibility] solutionList.append(dict(zip(freevar, possibility))) return solutionList
def x_intersections(function, *args): "Finds all x for which function(x) = 0" # solve_poly_system seems more efficient than solve for larger expressions return [ var for var in chain.from_iterable(solve_poly_system([function], *args)) if (var.is_real) ]
def ivalStarts(A, B, C, D, E, cF, al, aX): x0y0 = sympy.solve_poly_system( [A * symx + B * symy + D, B * symx + C * symy + E], symx, symy) x0 = x0y0[0][0] y0 = x0y0[0][1] global fX1, fY1, fX2, fY2 fX1, fY1 = rotatePoint(cF, al, x0, y0) fX2, fY2 = rotatePoint(-cF, al, x0, y0) return (rotatePoint(aX, al, x0, y0), rotatePoint(-aX, al, x0, y0))
def resolve(self): expressions = [] for i in range(0, len(self._left_operands)): lo = Poly(self._left_operands[i], self._symbols) ro = Poly(self._right_operands[i], self._symbols) expressions.append(lo - ro) solutions = solve_poly_system(expressions, self._symbols) return [list(x) for x in zip(*solutions)]
def intersect(self, other): """Calculates points of intersection with the algebraic curve. Parameters ---------- other : :obj:`Line` or :obj:`AlgebraicCurve` The object to intersect this curve with. Returns ------- :obj:`list` of :obj:`Point` The points of intersection. """ sol = set() if isinstance(other, Line): for z in [0, 1]: polys = [self.polynomial.subs(self.symbols[-1], z)] for f in other.polynomials(self.symbols): polys.append(f.subs(self.symbols[-1], z)) try: x = sympy.solve_poly_system(polys, *self.symbols[:-1]) sol.update(tuple(float(x) for x in cor) + (z,) for cor in x) except NotImplementedError: continue if isinstance(other, AlgebraicCurve): for z in [0, 1]: f = self.polynomial.subs(self.symbols[-1], z) g = other.polynomial.subs(self.symbols[-1], z) try: x = sympy.solve_poly_system([f, g], *self.symbols[:-1]) sol.update(tuple(float(x) for x in cor) + (z,) for cor in x) except NotImplementedError: continue if (0, 0, 0) in sol: sol.remove((0, 0, 0)) return [Point(p) for p in sol]
def find_coords(cd, a_b, b_a): x1, y1 = 0, 0 x2, y2 = 0, cd equations = [(y - y1)**2 + (x - x1)**2 - b_a**2, (y - y2)**2 + (x - x2)**2 - a_b**2] solutions = solve_poly_system(equations, x, y) #TODO точка C может лежать чуть ниже точки B, # тогда solutions везде будут отрицательными for item in solutions: if item[0] >= 0 and item[1] >= 0: first = float(item[0]) second = float(item[1]) return [first, second] raise ValueError('solution to equations is negative')
def test2_12_2_2(self): """ Consider R4 with basis {e_1, e_2, e_3, e_4}. Show that the 2-vector B = (e_1 ^ e_2) + (e_3 ^ e_4) is not a 2-blade (i.e., it cannot be written as the outer product of two vectors). """ (_g4d, e_1, e_2, e_3, e_4) = Ga.build('e*1|2|3|4') # B B = (e_1 ^ e_2) + (e_3 ^ e_4) # C is the product of a and b vectors a_1 = Symbol('a_1') a_2 = Symbol('a_2') a_3 = Symbol('a_3') a_4 = Symbol('a_4') a = a_1 * e_1 + a_2 * e_2 + a_3 * e_3 + a_4 * e_4 b_1 = Symbol('b_1') b_2 = Symbol('b_2') b_3 = Symbol('b_3') b_4 = Symbol('b_4') b = b_1 * e_1 + b_2 * e_2 + b_3 * e_3 + b_4 * e_4 C = a ^ b # other coefficients are null blades = [ e_1 ^ e_2, e_1 ^ e_3, e_1 ^ e_4, e_2 ^ e_3, e_2 ^ e_4, e_3 ^ e_4, ] C_coefs = C.blade_coefs(blades) B_coefs = B.blade_coefs(blades) # try to solve the system and show there is no solution system = [ (C_coef) - (B_coef) for C_coef, B_coef in zip(C_coefs, B_coefs) ] unknowns = [ a_1, a_2, a_3, a_4, b_1, b_2, b_3, b_4 ] # TODO: use solve if sympy fix it result = solve_poly_system(system, unknowns) self.assertTrue(result is None)
def fudge_kostansek(name, hc): rc = 2*R_particle + hc * nm kos = get_force_field("kostansek-shift") U_tot = kos.potential_expr U_k = U_tot dU_k = U_k.diff(r) A,B,C,U,dU,R = map(S.Symbol, 'A B C U dU R'.split()) diam = 2*R sol = S.solve_poly_system([ A*diam**2 + B*diam + C, A*r**2 + B*r + C - U, 2*A*r + B - dU], A, B, C) sol, = sol A,B,C = [S.simplify(expr.subs(U,U_k).subs(dU, dU_k).subs(r,rc).subs(R,R_particle)) for expr in sol] para = A*r**2 + B*r + C para = S.simplify(para) para = AnalyticPotential(name + '-para', para) return PieceWisePotential(name, [[ds[-oo:rc], para], [ds[Boundary(rc, inclusive=False):oo], kos]])
def intersect(self, other): """Calculates points of intersection with the algebraic curve. Parameters ---------- other : :obj:`Line` or :obj:`AlgebraicCurve` The object to intersect this curve with. Returns ------- :obj:`list` of :obj:`Point` The points of intersection. """ sol = set() if isinstance(other, Line): polys = [self.polynomial] + other.polynomials(self.symbols) elif isinstance(other, AlgebraicCurve): polys = [self.polynomial, other.polynomial] else: raise NotImplementedError("Intersection for objects of type %s not supported." % str(type(other))) for z in [0, 1]: p = [f.subs(self.symbols[-1], z) for f in polys] try: x = sympy.solve_poly_system(p, *self.symbols[:-1]) sol.update(tuple(complex(x) for x in cor) + (z,) for cor in x) except NotImplementedError: continue if (0, 0, 0) in sol: sol.remove((0, 0, 0)) return [Point(np.real_if_close(p)) for p in sol]
{'position':[ 47.5, -37.2, 43.6], 'contribution': 0.1870}] # P8 (9) electrode_data = [{'position':[-56.3, 22.3, 7.1], 'contribution': 0.8374}, # F7 (2) {'position':[ 32.1, 39.5, 21.8], 'contribution': 0.0135}, # AF4 (14) {'position':[-47.5, -37.2, 43.6], 'contribution': 0.0525}, # P7 (6) {'position':[ 47.5, -37.2, 43.6], 'contribution': 0.0829}] # P8 (9 #electrode_data = sorted(electrode_data, key=lambda k: k['contribution'], reverse=False) #electrode_data = electrode_data[0:4] # Equations equations = [] for electrode in electrode_data: equations.append('(x - (%d))^2 + (y - (%d))^2 + (z - (%d))^2 - (%d) * k' % (sympify(electrode['position'][0]), sympify(electrode['position'][1]), sympify(electrode['position'][2]), sympify(electrode['contribution']))) solutions = solve_poly_system(equations, x, y, z, k) #for solution in solutions: # print [float(x) for x in solution] best_solution = [99999999999.0] for solution in solutions: solution = [complex(x) for x in solution] #if solution[-1] < best_solution[-1]: best_solution = solution print best_solution
f = x + 2*y + 3*z g1 = x**2 + y**2 + z**2 c1 = 3 g2 = x c2 = 1 df_dx = sp.diff(f, 'x') df_dy = sp.diff(f, 'y') df_dz = sp.diff(f, 'z') dg1_dx = sp.diff(g1, 'x') dg1_dy = sp.diff(g1, 'y') dg1_dz = sp.diff(g1, 'z') dg2_dx = sp.diff(g2, 'x') dg2_dy = sp.diff(g2, 'y') dg2_dz = sp.diff(g2, 'z') sols = sp.solve_poly_system([ df_dx - l1*dg1_dx + l2*dg2_dx, df_dy - l1*dg1_dy + l2*dg2_dy, df_dz - l1*dg1_dz + l2*dg2_dz, g1 - c1, g2 - c2 ], x, y, z, l1, l2) for i in range(0, len(sols)): print(i, sols[i][0:3], f.evalf(subs={x:sols[i][0], y:sols[i][1], z:sols[i][3]}))
}, # P7 (6) { 'position': [47.5, -37.2, 43.6], 'contribution': 0.0829 } ] # P8 (9 #electrode_data = sorted(electrode_data, key=lambda k: k['contribution'], reverse=False) #electrode_data = electrode_data[0:4] # Equations equations = [] for electrode in electrode_data: equations.append( '(x - (%d))^2 + (y - (%d))^2 + (z - (%d))^2 - (%d) * k' % (sympify(electrode['position'][0]), sympify( electrode['position'][1]), sympify( electrode['position'][2]), sympify(electrode['contribution']))) solutions = solve_poly_system(equations, x, y, z, k) #for solution in solutions: # print [float(x) for x in solution] best_solution = [99999999999.0] for solution in solutions: solution = [complex(x) for x in solution] #if solution[-1] < best_solution[-1]: best_solution = solution print best_solution
def solve(*equalities): if len(equalities) == 1: return sympy.solve(equalities[0]) return sympy.solve_poly_system(equalities)
def points(self): """ Finds all points which satisfy eqautions of A """ return sp.solve_poly_system(self.polynomials, self.field)
def integral_basis(f,x,y): """ Compute the integral basis {b1, ..., bg} of the algebraic function field C[x,y] / (f). """ # If the curve is not monic then map y |-> y/lc(x) where lc(x) # is the leading coefficient of f T = sympy.Dummy('T') d = sympy.degree(f,y) lc = sympy.LC(f,y) if x in lc: f = sympy.ratsimp( f.subs(y,y/lc)*lc**(d-1) ) else: f = f/lc lc = 1 # # Compute df # p = sympy.Poly(f,[x,y]) n = p.degree(y) res = sympy.resultant(p,p.diff(y),y) factors = sympy.factor_list(res)[1] df = [k for k,deg in factors if (deg > 1) and (sympy.LC(k) == 1)] # # Compute series truncations at appropriate x points # alpha = [] r = [] for l in range(len(df)): k = df[l] alphak = sympy.roots(k).keys()[0] rk = compute_series_truncations(f,x,y,alphak,T) alpha.append(alphak) r.append(rk) # # Main Loop # a = [sympy.Dummy('a%d'%k) for k in xrange(n)] b = [1] for d in range(1,n): bd = y*b[-1] for l in range(len(df)): k = df[l] alphak = alpha[l] rk = r[l] found_something = True while found_something: # construct system of equations consisting of the coefficients # of negative powers of (x-alphak) in the substitutions # A(r_{k,1}),...,A(r_{k,n}) A = (sum(ak*bk for ak,bk in zip(a,b)) + bd) / (x - alphak) coeffs = [] for rki in rk: # substitute and extract coefficients A_rki = A.subs(y,rki) coeffs.extend(_negative_power_coeffs(A_rki, x, alphak)) # solve the coefficient equations for a0,...,a_{d-1} coeffs = [coeff.as_numer_denom()[0] for coeff in coeffs] sols = sympy.solve_poly_system(coeffs, a[:d]) if sols is None or sols == []: found_something = False else: sol = sols[0] bdm1 = sum( sol[i]*bk for i,bk in zip(range(d),b) ) bd = (bdm1 + bd) / k # bd found. Append to list of basis elements b.append( bd ) # finally, convert back to singularized curve if necessary for i in xrange(1,len(b)): b[i] = b[i].subs(y,y*lc).ratsimp() return b
# stackoverflow.com/questions/10457240 from sympy import * x, y = symbols('x y') from sympy import roots, solve_poly_system ans = solve_poly_system([y**2 - x**3 + 1, y * x], x, y) print(ans)
def GetField(self): # see the documentation on how the field is calculated (Magnetisch veld cirkelvormige geleider) from Lib.Functions import UpdateDictionary, ConvertAnglesToVector, ConvertVectorToAngles from sympy import solve_poly_system Theta = math.radians(self.Theta) Phi = math.radians(self.Phi) M = self.CoordinatesCenter pi = math.pi mu = 4 * pi * 10 ** (-7) h = 0.25 * (self.Heigth / self.Windings) L = CoordSys3D('L') n = ConvertAnglesToVector(Theta, Phi) M = M[0] * L.i + M[1] * L.j + M[2] * L.k M = M + h * n Mcomponents = M.components UpdateDictionary(Mcomponents) M = [Mcomponents[L.i], Mcomponents[L.j], Mcomponents[L.k]] tan_alpha = h / self.CurvatureRadius alpha = math.atan(tan_alpha) R = self.CurvatureRadius / math.cos(alpha) ncomponents = n.components UpdateDictionary(ncomponents) nx = ncomponents[L.i] ny = ncomponents[L.j] nz = ncomponents[L.k] kx, ky = sy.symbols('kx ky') if nx != 0 and ny != 0: k = solve_poly_system([kx * nx + ky * ny, kx ** 2 + ky ** 2 - 1], kx, ky) kx = k[0][0] ky = k[0][1] else: kx = 0 ky = 1 dnx, dny, dnz = sy.symbols('dnx, dny, dnz') dn = solve_poly_system([nx * dnx + ny * dny + nz * dnz, dnx ** 2 + dny ** 2 + dnz ** 2 - tan_alpha ** 2,(kx / tan_alpha) * dnx + (ky / tan_alpha) * dny - math.cos(self.BeginAngle)], dnx, dny, dnz) if len(dn) >= 2: dnx = dn[1][0] dny = dn[1][1] dnz = dn[1][2] else: dnx = dn[0][0] dny = dn[0][1] dnz = dn[0][2] dn = dnx * L.i + dny * L.j + dnz * L.k r = n + dn r = r.normalize() Phi, Theta = ConvertVectorToAngles(r) B = Vector.zero windings = 0 begin = self.BeginAngle while windings < self.Windings: bentconductor = BentConductor("name", M, R, Theta, Phi, [begin, begin + 180], self.Current, self.Radius) B += bentconductor.GetField() M = M[0] * L.i + M[1] * L.j + M[2] * L.k M = M + 2 * h * n Mcomponents = M.components UpdateDictionary(Mcomponents) M = [Mcomponents[L.i], Mcomponents[L.j], Mcomponents[L.k]] dn = -dn r = n + dn r = r.normalize() Theta, Phi = ConvertVectorToAngles(r) begin = begin + 180 windings += 0.5 return B
from sympy import Symbol from sympy import solve, roots, solve_poly_system from sympy import sqrt from sympy import init_printing init_printing() ''' x = Symbol('x') s = solve(x**3 + 2*x + 3, x) print s ''' x1 = Symbol('x1') x2 = Symbol('x2') y1 = Symbol('y1') y2 = Symbol('y2') x = Symbol('x') y = Symbol('y') f = (x2-x1)**2 + (y2-y1)**2 - ((x-x1)**2 + (y-y1)**2)*2 g = (x2-x1)**2 + (y2-y1)**2 - ((x-x2)**2 + (y-y2)**2)*2 s = solve_poly_system([f,g],x,y) print 'x:', s[0][0] print 'x:', s[1][0] print '' print 'y:', s[0][1] print 'y:', s[1][1]
ylabel('Amount of LR') show() # Run a stochastic simulation using BNG bng_stoch_data = bng.run_ssa(model, t_end=tmax, n_steps=numpoints) figure() plot(bng_stoch_data['time'], bng_stoch_data['LR']) xlim([0, 40]) ylim([0, 100]) title('BNG Stochastic Simulation') xlabel('Time') ylabel('Amount of LR') show() # Show contact and influence maps #kappa.show_influence_map(model) #kappa.show_contact_map(model) """ # Solve the model for steady state activated Bax using SymPy #cons_eqns = parse_expr('s0 + s2 - tBid_0, bng.generate_equations(model) var('s0, s1, s2, L_0, R_0') conservation_eqns = [s0 + s2 - L_0, s1 + s2 - R_0] solution = solve_poly_system(model.odes + conservation_eqns, s0, s1, s2) s2_soln = solution[0][2].subs({S('kf'): S('k_f'), S('kr'): S('k_r')}) latex_output = latex(s2_soln) print latex_output
ax.set_ylabel('y') ax.set_zlabel('z') # plt.show() # Q1-2 # define function using symbol x and y x, y = symbols('x y') z = (x + y) * (x * y + x * y**2) z_gradient = [z.diff(x), z.diff(y)] # gradient of z # print(z_gradient) # print('({}, {})'.format(z_gradient[0].subs([(x, 0), (y, 0)]), z_gradient[1].subs([(x, 0), (y, 0)]))) # Q1-3 # find critical points critical_points = solve_poly_system(z_gradient, [x, y]) print(critical_points) # [(0, -1), (0, 0), (3/8, -3/4), (1, -1)] # hessian matrix hessian = [[z.diff(x).diff(x), z.diff(x).diff(y)], [z.diff(y).diff(x), z.diff(y).diff(y)]] # print(hessian) # second partial derivative test for critical_x, critical_y in critical_points: f_xx = hessian[0][0].subs([(x, critical_x), (y, critical_y)]) f_xy = hessian[0][1].subs([(x, critical_x), (y, critical_y)]) f_yx = hessian[1][0].subs([(x, critical_x), (y, critical_y)]) f_yy = hessian[1][1].subs([(x, critical_x), (y, critical_y)]) assert f_xy == f_yx, 'f_xy and f_yx must be same!'