def test_AccumBounds_pow(): assert B(0, 2)**2 == B(0, 4) assert B(-1, 1)**2 == B(0, 1) assert B(1, 2)**2 == B(1, 4) assert B(-1, 2)**3 == B(-1, 8) assert B(-1, 1)**0 == 1 assert B(1, 2)**Rational(5, 2) == B(1, 4 * sqrt(2)) assert B(0, 2)**S.Half == B(0, sqrt(2)) neg = Symbol('neg', negative=True) assert unchanged(Pow, B(neg, 1), S.Half) nn = Symbol('nn', nonnegative=True) assert B(nn, nn + 1)**S.Half == B(sqrt(nn), sqrt(nn + 1)) assert B(nn, nn + 1)**nn == B(nn**nn, (nn + 1)**nn) assert unchanged(Pow, B(nn, nn + 1), x) i = Symbol('i', integer=True) assert B(1, 2)**i == B(Min(1, 2**i), Max(1, 2**i)) i = Symbol('i', integer=True, nonnegative=True) assert B(1, 2)**i == B(1, 2**i) assert B(0, 1)**i == B(0**i, 1) assert B(1, 5)**(-2) == B(Rational(1, 25), 1) assert B(-1, 3)**(-2) == B(0, oo) assert B(0, 2)**(-3) == B(Rational(1, 8), oo) assert B(-2, 0)**(-3) == B(-oo, -Rational(1, 8)) assert B(0, 2)**(-2) == B(Rational(1, 4), oo) assert B(-1, 2)**(-3) == B(-oo, oo) assert B(-3, -2)**(-3) == B(Rational(-1, 8), Rational(-1, 27)) assert B(-3, -2)**(-2) == B(Rational(1, 9), Rational(1, 4)) assert B(0, oo)**S.Half == B(0, oo) assert B(-oo, 0)**(-2) == B(0, oo) assert B(-2, 0)**(-2) == B(Rational(1, 4), oo) assert B(Rational(1, 3), S.Half)**oo is S.Zero assert B(0, S.Half)**oo is S.Zero assert B(S.Half, 1)**oo == B(0, oo) assert B(0, 1)**oo == B(0, oo) assert B(2, 3)**oo is oo assert B(1, 2)**oo == B(0, oo) assert B(S.Half, 3)**oo == B(0, oo) assert B(Rational(-1, 3), Rational(-1, 4))**oo is S.Zero assert B(-1, Rational(-1, 2))**oo is S.NaN assert B(-3, -2)**oo is zoo assert B(-2, -1)**oo is S.NaN assert B(-2, Rational(-1, 2))**oo is S.NaN assert B(Rational(-1, 2), S.Half)**oo is S.Zero assert B(Rational(-1, 2), 1)**oo == B(0, oo) assert B(Rational(-2, 3), 2)**oo == B(0, oo) assert B(-1, 1)**oo == B(-oo, oo) assert B(-1, S.Half)**oo == B(-oo, oo) assert B(-1, 2)**oo == B(-oo, oo) assert B(-2, S.Half)**oo == B(-oo, oo) assert B(1, 2)**x == Pow(B(1, 2), x, evaluate=False) assert B(2, 3)**(-oo) is S.Zero assert B(0, 2)**(-oo) == B(0, oo) assert B(-1, 2)**(-oo) == B(-oo, oo) assert (tan(x)**sin(2*x)).subs(x, B(0, pi/2)) == \ Pow(B(-oo, oo), B(0, 1))
def test_issue_11045(): assert integrate(1 / (x * sqrt(x**2 - 1)), (x, 1, 2)) == pi / 3 # handle And with Or arguments assert Piecewise((1, And(Or(x < 1, x > 3), x < 2)), (0, True)).integrate( (x, 0, 3)) == 1 # hidden false assert Piecewise((1, x > 1), (2, x > x + 1), (3, True)).integrate( (x, 0, 3)) == 5 # targetcond is Eq assert Piecewise((1, x > 1), (2, Eq(1, x)), (3, True)).integrate( (x, 0, 4)) == 6 # And has Relational needing to be solved assert Piecewise((1, And(2 * x > x + 1, x < 2)), (0, True)).integrate( (x, 0, 3)) == 1 # Or has Relational needing to be solved assert Piecewise((1, Or(2 * x > x + 2, x < 1)), (0, True)).integrate( (x, 0, 3)) == 2 # ignore hidden false (handled in canonicalization) assert Piecewise((1, x > 1), (2, x > x + 1), (3, True)).integrate( (x, 0, 3)) == 5 # watch for hidden True Piecewise assert Piecewise((2, Eq(1 - x, x * (1 / x - 1))), (0, True)).integrate( (x, 0, 3)) == 6 # overlapping conditions of targetcond are recognized and ignored; # the condition x > 3 will be pre-empted by the first condition assert Piecewise((1, Or(x < 1, x > 2)), (2, x > 3), (3, True)).integrate( (x, 0, 4)) == 6 # convert Ne to Or assert Piecewise((1, Ne(x, 0)), (2, True)).integrate((x, -1, 1)) == 2 # no default but well defined assert Piecewise((x, (x > 1) & (x < 3)), (1, (x < 4))).integrate( (x, 1, 4)) == 5 p = Piecewise((x, (x > 1) & (x < 3)), (1, (x < 4))) nan = Undefined i = p.integrate((x, 1, y)) assert i == Piecewise( (y - 1, y < 1), (Min(3, y)**2 / 2 - Min(3, y) + Min(4, y) - S(1) / 2, y <= Min(4, y)), (nan, True)) assert p.integrate((x, 1, -1)) == i.subs(y, -1) assert p.integrate((x, 1, 4)) == 5 assert p.integrate((x, 1, 5)) == nan # handle Not p = Piecewise((1, x > 1), (2, Not(And(x > 1, x < 3))), (3, True)) assert p.integrate((x, 0, 3)) == 4 # handle updating of int_expr when there is overlap p = Piecewise((1, And(5 > x, x > 1)), (2, Or(x < 3, x > 7)), (4, x < 8)) assert p.integrate((x, 0, 10)) == 20 # And with Eq arg handling assert Piecewise((1, x < 1), (2, And(Eq(x, 3), x > 1))).integrate( (x, 0, 3)) == S.NaN assert Piecewise((1, x < 1), (2, And(Eq(x, 3), x > 1)), (3, True)).integrate((x, 0, 3)) == 7 assert Piecewise((1, x < 0), (2, And(Eq(x, 3), x < 1)), (3, True)).integrate((x, -1, 1)) == 4 # middle condition doesn't matter: it's a zero width interval assert Piecewise((1, x < 1), (2, Eq(x, 3) & (y < x)), (3, True)).integrate( (x, 0, 3)) == 7
cost_function=lambda expr: expr.count( lambda e: ( # division & eval of transcendentals are expensive floating point operations... (isinstance(e, Pow) and e.exp.is_negative) # division or (isinstance(e, (log, log2)) and not e.args[0].is_number) ) # transcendental )) log2const_opt = ReplaceOptim(log(2) * log2(_w), log(_w)) logsumexp_2terms_opt = ReplaceOptim( lambda l: (isinstance(l, log) and isinstance(l.args[0], Add) and len(l.args[0].args) == 2 and all(isinstance(t, exp) for t in l.args[0].args)), lambda l: (Max(*[e.args[0] for e in l.args[0].args]) + log1p( exp(Min(*[e.args[0] for e in l.args[0].args]))))) def _try_expm1(expr): protected, old_new = expr.replace(exp, lambda arg: Dummy(), map=True) factored = protected.factor() new_old = {v: k for k, v in old_new.items()} return factored.replace( _d - 1, lambda d: expm1(new_old[d].args[0])).xreplace(new_old) def _expm1_value(e): numbers, non_num = sift(e.args, lambda arg: arg.is_number, binary=True) non_num_exp, non_num_other = sift(non_num, lambda arg: arg.has(exp), binary=True)
def test_image_Intersection(): x = Symbol('x', real=True) y = Symbol('y', real=True) assert imageset(x, x**2, Interval(-2, 0).intersect(Interval(x, y))) == \ Interval(0, 4).intersect(Interval(Min(x**2, y**2), Max(x**2, y**2)))
def min(self, a, b): return Min(a, b)
def test_inverse_mellin_transform(): from sympy import simplify, Max, Min, expand, powsimp, cot IMT = inverse_mellin_transform assert IMT(gamma(s), s, x, (0, oo)) == exp(-x) assert IMT(gamma(-s), s, x, (-oo, 0)) == exp(-1 / x) assert simplify(IMT(s/(2*s**2 - 2), s, x, (2, oo))) == \ (x**2 + 1)*Heaviside(1 - x)/(4*x) # test passing "None" assert IMT(1/(s**2 - 1), s, x, (-1, None)) == \ -x*Heaviside(-x + 1)/2 - Heaviside(x - 1)/(2*x) assert IMT(1/(s**2 - 1), s, x, (None, 1)) == \ -x*Heaviside(-x + 1)/2 - Heaviside(x - 1)/(2*x) # test expansion of sums assert IMT(gamma(s) + gamma(s - 1), s, x, (1, oo)) == (x + 1) * exp(-x) / x # test factorisation of polys r = symbols('r', real=True) assert IMT(1/(s**2 + 1), s, exp(-x), (None, oo) ).subs(x, r).rewrite(sin).simplify() \ == sin(r)*Heaviside(1 - exp(-r)) # test multiplicative substitution _a, _b = symbols('a b', positive=True) assert IMT(_b**(-s / _a) * factorial(s / _a) / s, s, x, (0, oo)) == exp(-_b * x**_a) assert IMT(factorial(_a / _b + s / _b) / (_a + s), s, x, (-_a, oo)) == x**_a * exp(-x**_b) def simp_pows(expr): return simplify(powsimp(expand_mul(expr, deep=False), force=True)).replace(exp_polar, exp) # Now test the inverses of all direct transforms tested above # Section 8.4.2 nu = symbols('nu', real=True) assert IMT(-1 / (nu + s), s, x, (-oo, None)) == x**nu * Heaviside(x - 1) assert IMT(1 / (nu + s), s, x, (None, oo)) == x**nu * Heaviside(1 - x) assert simp_pows(IMT(gamma(beta)*gamma(s)/gamma(s + beta), s, x, (0, oo))) \ == (1 - x)**(beta - 1)*Heaviside(1 - x) assert simp_pows(IMT(gamma(beta)*gamma(1 - beta - s)/gamma(1 - s), s, x, (-oo, None))) \ == (x - 1)**(beta - 1)*Heaviside(x - 1) assert simp_pows(IMT(gamma(s)*gamma(rho - s)/gamma(rho), s, x, (0, None))) \ == (1/(x + 1))**rho assert simp_pows(IMT(d**c*d**(s - 1)*sin(pi*c) *gamma(s)*gamma(s + c)*gamma(1 - s)*gamma(1 - s - c)/pi, s, x, (Max(-re(c), 0), Min(1 - re(c), 1)))) \ == (x**c - d**c)/(x - d) assert simplify(IMT(1/sqrt(pi)*(-c/2)*gamma(s)*gamma((1 - c)/2 - s) *gamma(-c/2 - s)/gamma(1 - c - s), s, x, (0, -re(c)/2))) == \ (1 + sqrt(x + 1))**c assert simplify(IMT(2**(a + 2*s)*b**(a + 2*s - 1)*gamma(s)*gamma(1 - a - 2*s) /gamma(1 - a - s), s, x, (0, (-re(a) + 1)/2))) == \ b**(a - 1)*(sqrt(1 + x/b**2) + 1)**(a - 1)*(b**2*sqrt(1 + x/b**2) + b**2 + x)/(b**2 + x) assert simplify(IMT(-2**(c + 2*s)*c*b**(c + 2*s)*gamma(s)*gamma(-c - 2*s) / gamma(-c - s + 1), s, x, (0, -re(c)/2))) == \ b**c*(sqrt(1 + x/b**2) + 1)**c # Section 8.4.5 assert IMT(24 / s**5, s, x, (0, oo)) == log(x)**4 * Heaviside(1 - x) assert expand(IMT(6/s**4, s, x, (-oo, 0)), force=True) == \ log(x)**3*Heaviside(x - 1) assert IMT(pi / (s * sin(pi * s)), s, x, (-1, 0)) == log(x + 1) assert IMT(pi / (s * sin(pi * s / 2)), s, x, (-2, 0)) == log(x**2 + 1) assert IMT(pi / (s * sin(2 * pi * s)), s, x, (Rational(-1, 2), 0)) == log(sqrt(x) + 1) assert IMT(pi / (s * sin(pi * s)), s, x, (0, 1)) == log(1 + 1 / x) # TODO def mysimp(expr): from sympy import expand, logcombine, powsimp return expand(powsimp(logcombine(expr, force=True), force=True, deep=True), force=True).replace(exp_polar, exp) assert mysimp(mysimp(IMT(pi / (s * tan(pi * s)), s, x, (-1, 0)))) in [ log(1 - x) * Heaviside(1 - x) + log(x - 1) * Heaviside(x - 1), log(x) * Heaviside(x - 1) + log(1 - 1 / x) * Heaviside(x - 1) + log(-x + 1) * Heaviside(-x + 1) ] # test passing cot assert mysimp(IMT(pi * cot(pi * s) / s, s, x, (0, 1))) in [ log(1 / x - 1) * Heaviside(1 - x) + log(1 - 1 / x) * Heaviside(x - 1), -log(x) * Heaviside(-x + 1) + log(1 - 1 / x) * Heaviside(x - 1) + log(-x + 1) * Heaviside(-x + 1), ] # 8.4.14 assert IMT(-gamma(s + S.Half)/(sqrt(pi)*s), s, x, (Rational(-1, 2), 0)) == \ erf(sqrt(x)) # 8.4.19 assert simplify(IMT(gamma(a/2 + s)/gamma(a/2 - s + 1), s, x, (-re(a)/2, Rational(3, 4)))) \ == besselj(a, 2*sqrt(x)) assert simplify(IMT(2**a*gamma(S.Half - 2*s)*gamma(s + (a + 1)/2) / (gamma(1 - s - a/2)*gamma(1 - 2*s + a)), s, x, (-(re(a) + 1)/2, Rational(1, 4)))) == \ sin(sqrt(x))*besselj(a, sqrt(x)) assert simplify(IMT(2**a*gamma(a/2 + s)*gamma(S.Half - 2*s) / (gamma(S.Half - s - a/2)*gamma(1 - 2*s + a)), s, x, (-re(a)/2, Rational(1, 4)))) == \ cos(sqrt(x))*besselj(a, sqrt(x)) # TODO this comes out as an amazing mess, but simplifies nicely assert simplify(IMT(gamma(a + s)*gamma(S.Half - s) / (sqrt(pi)*gamma(1 - s)*gamma(1 + a - s)), s, x, (-re(a), S.Half))) == \ besselj(a, sqrt(x))**2 assert simplify(IMT(gamma(s)*gamma(S.Half - s) / (sqrt(pi)*gamma(1 - s - a)*gamma(1 + a - s)), s, x, (0, S.Half))) == \ besselj(-a, sqrt(x))*besselj(a, sqrt(x)) assert simplify(IMT(4**s*gamma(-2*s + 1)*gamma(a/2 + b/2 + s) / (gamma(-a/2 + b/2 - s + 1)*gamma(a/2 - b/2 - s + 1) *gamma(a/2 + b/2 - s + 1)), s, x, (-(re(a) + re(b))/2, S.Half))) == \ besselj(a, sqrt(x))*besselj(b, sqrt(x)) # Section 8.4.20 # TODO this can be further simplified! assert simplify(IMT(-2**(2*s)*cos(pi*a/2 - pi*b/2 + pi*s)*gamma(-2*s + 1) * gamma(a/2 - b/2 + s)*gamma(a/2 + b/2 + s) / (pi*gamma(a/2 - b/2 - s + 1)*gamma(a/2 + b/2 - s + 1)), s, x, (Max(-re(a)/2 - re(b)/2, -re(a)/2 + re(b)/2), S.Half))) == \ besselj(a, sqrt(x))*-(besselj(-b, sqrt(x)) - besselj(b, sqrt(x))*cos(pi*b))/sin(pi*b) # TODO more # for coverage assert IMT(pi / cos(pi * s), s, x, (0, S.Half)) == sqrt(x) / (x + 1)
'f_fastsom2slowsom': 'Transfer coefficient from Fast to Slow SOM', 'f_fastsom2passsom': 'Transfer coefficient from Fast to Passive SOM', 'f_slowsom2fastsom': 'Transfer coefficient from Slow to Fast SOM', 'f_slowsom2passsom': 'Transfer coefficient from Slow to Passive SOM', 'f_passsom2fastsom': 'Transfer coefficient from Passive to Fast SOM' } for name in sym_dict.keys(): var(name) R = 8.314 Arrhenius = exp((E_p * (T_k - 298)) / (R * T_k * 298)) I = I_0 * exp(-k * L) J_e = 1 #((alpha_q * I * J_m)/(sqrt((J_m)^2 * (alpha_q)^2 * I^2))) * ((C_i - Gamma)/(4*(C_i + 2 * Gamma))) #Fixme: had to set J_e to 1 because problem with sqrt AttributeError: 'Not' object has no attribute '_eval_power' J_c = (V_m * (C_i - Gamma)) / (C_i + K_c * (1 + (O_x / K_o))) A = Min(J_c, J_e) - R_d g_l * A / ((C_i - Gamma) * (1 + (D / D_0))) A_n = G_s * (C_a - C_i) A_c = A_n * (1 - exp(-k * L)) / k GPP = A_c * 3600 * 12 / 1000000 # Scaling expression from TECO fortran code, line 667.' # gC*day^{-1} f_W = Min((0.5 * W), 1) f_T = Q_10 * ((T - 10) / 10) xi = f_W * f_T t = TimeSymbol("t") # unit: "day" #x = StateVariableTuple((C_foliage, C_roots, C_wood, C_metlit, C_stlit, C_fastsom, C_slowsom, C_passsom)) x = StateVariableTuple((C_foliage, C_wood, C_roots, C_metlit, C_stlit, C_fastsom, C_slowsom, C_passsom)) u = GPP b = (b_foliage, b_roots, b_wood, 0, 0, 0, 0, 0) Input = InputTuple(u * ImmutableMatrix(b)) B = CompartmentalMatrix(
def test_fcode_functions(): x, y = symbols('x,y') assert fcode(sin(x)**cos(y)) == " sin(x)**cos(y)" assert fcode(Max(x, y) + Min(x, y)) == " max(x, y) + min(x, y)"
def test_transform_Intersection(): x = Symbol('x', real=True) y = Symbol('y', real=True) assert Interval(-2, 0).intersect(Interval(x, y)).transform(x, x**2) == \ Interval(0, 4).intersect(Interval(Min(x**2, y**2), Max(x**2, y**2)))
def T_(self, consider_limits=False, tolerance=1e-10): """ Description ----------- Returns the transformation matrix from the parent link to the child link in homogeneous coordinates. This matrix is computed symbolically The degrees of freedom names are formatted like this : prefix_name where name is the joint name (self.joint_name) and prefix is : - 'd' for 1 DOF translation - 'dx' / 'dy' for 2 DOF translations - 'dx' / 'dy' / 'dz' for 3 DOF translations - 'theta' for 1 DOF rotations - 'roll' / 'pitch' / 'yaw' for 3 DOF rotations Parameters ---------- consider_limits : bool If True, the transition matrices ensure it's not possible to go beyond self.limit_lower and self.limit_upper. This results adding max and min functions in the transition matrix. For example, if the degree of freedom is d and consider_limits is True, every d value will become : min(max(d, self.limit_lower), self.limit_upper) (if the limits are not None). This can cause derivation problems so you can disable this option turning consider_limits to False. Note that some types of joints NEED limits (revolute & prismatic) and some just ignore them. Be careful with this option, as the default limit values are 0. So, if your URDF file doesn't specify limits, this option will allow the DOF to move between 0 and 0. This will consequently "remove" the degree of freedom from the transition matrix. Defaults to False tolerance : float Tolerance for simplification of the expression. Defaults to 1e-10 Returns ------- sympy.matrices.immutable.ImmutableDenseMatrix Transformation matrix from the parent link to the child link in homogeneous coordinates. The shape is (4, 4) """ # Initialisation T = Matrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) # Translation ........................................................ T[0:3, 3] = self.origin_xyz # Rotation ........................................................... # Yaw around Z axis . . . . . . . . . . . . . . . . . . . . . . . . . angle = self.origin_rpy[2, 0] yaw = Matrix([[cos(angle), -sin(angle), 0], [sin(angle), cos(angle), 0], [0, 0, 1]]) # Pitch around Y axis . . . . . . . . . . . . . . . . . . . . . . . . angle = self.origin_rpy[1, 0] pitch = Matrix([[cos(angle), 0, sin(angle)], [0, 1, 0], [-sin(angle), 0, cos(angle)]]) # Roll around X axis . . . . . . . . . . . . . . . . . . . . . . . . . angle = self.origin_rpy[0, 0] roll = Matrix([[1, 0, 0], [0, cos(angle), -sin(angle)], [0, sin(angle), cos(angle)]]) # Yaw * Pitch * Roll T[0:3, 0:3] = (yaw * pitch * roll).evalf() # Rodrigues formula .................................................. def rodrigues(axis, angle_): """ Description ----------- Computes the Rodrigues rotation matrix from a rotation around the axis 'axis' with the rotation 'angle' https://en.wikipedia.org/wiki/Rodrigues%27_rotation_formula Parameters ---------- axis : numpy.ndarray Axis around the one the rotation is made. Has to be normalized and shape = (3, 1) angle_ : sympy.core.symbol.Symbol Symbol for angle rotation (in radians) Returns ------- sympy.matrices.dense.MutableDenseMatrix Rotation matrix of the angle 'angle' around the axis 'axis'. Shape is 3x3 """ # Cross Product Matrix k = Matrix([[0, -axis[2, 0], axis[1, 0]], [axis[2, 0], 0, -axis[0, 0]], [-axis[1, 0], axis[0, 0], 0]]) identity = Matrix([[1, 0, 0], [0, 1, 0], [0, 0, 1]]) return identity + sin(angle_) * k + (1 - cos(angle_)) * k**2 # Adding degree(s) of freedom of the joint ........................... # Revolute Joints . . . . . . . . . . . . . . . . . . . . . . . . . . if self.joint_type == 'revolute': # 1 degree of freedom around the axis # Degree of freedom theta = Symbol('theta_' + self.name) if consider_limits: theta_limit = Min(Max(theta, self.limit_lower), self.limit_upper) T[0:3, 0:3] *= rodrigues(self.axis, theta_limit) else: T[0:3, 0:3] *= rodrigues(self.axis, theta) # Continuous Joints . . . . . . . . . . . . . . . . . . . . . . . . . elif self.joint_type == 'continuous': # 1 degree of freedom around the axis # Degree of freedom theta = Symbol('theta_' + self.name) T[0:3, 0:3] *= rodrigues(self.axis, theta) # Prismatic Joints . . . . . . . . . . . . . . . . . . . . . . . . . . elif self.joint_type == 'prismatic': # 1 degree of freedom along the axis # Since axis is normalized, the translation value is multiplied by # the axis to get its XYZ value d = Symbol('d_' + self.name) if consider_limits: d_limit = Min(Max(d, self.limit_lower), self.limit_upper) T[0:3, 3] += d_limit * self.axis else: T[0:3, 3] += d * self.axis # Fixed Joints . . . . . . . . . . . . . . . . . . . . . . . . . . . . elif self.joint_type == 'fixed': # Nothing to do here (no degrees of freedom) pass # Floating Joints . . . . . . . . . . . . . . . . . . . . . . . . . . elif self.joint_type == 'floating': # 6 degrees of freedom (3 translations, 3 rotations) # Translation Symbols dx = Symbol('dx_' + self.name) dy = Symbol('dy_' + self.name) dz = Symbol('dz_' + self.name) # Translation transformations T[0, 3] += dx T[1, 3] += dy T[2, 3] += dz # Rotation Symbols droll = Symbol('roll_' + self.name) dpitch = Symbol('pitch_' + self.name) dyaw = Symbol('yaw_' + self.name) # Rotation transformations roll_rot = Matrix([[1, 0, 0], [0, cos(droll), -sin(droll)], [0, sin(droll), cos(droll)]]) pitch_rot = Matrix([[cos(dpitch), 0, sin(dpitch)], [0, 1, 0], [-sin(dpitch), 0, cos(dpitch)]]) yaw_rot = Matrix([[cos(dyaw), -sin(dyaw), 0], [sin(dyaw), cos(dyaw), 0], [0, 0, 1]]) T[0:3, 0:3] *= (yaw_rot * pitch_rot * roll_rot) # Planar Joints . . . . . . . . . . . . . . . . . . . . . . . . . . . elif self.joint_type == 'planar': # 2 degrees of freedom (translation in the normal plan) # Degrees of freedom # dx = Symbol('dx_' + self.name) # dy = Symbol('dy_' + self.name) print('Planar Joints not Supported yet') # A bug in SymPy is not rounding float values if they are not # multiplied by a Symbol. To fix this, we multiply T by a random # Symbol, optimize and then divide by this Symbol. debug_sym = Symbol('debug_symbol') return nsimplify(T * debug_sym, tolerance=tolerance).evalf() / debug_sym
def _print_Min(self, expr): from sympy import Min if len(expr.args) == 1: return self._print(expr.args[0]) return "%smin(%s, %s)" % (self._ns, expr.args[0], self._print(Min(*expr.args[1:])))
def T_(self, consider_limits=False, tolerance=1e-10): """ Transition matrix of the joint. Computed from the Denavit-Hartenberg parameters. For more details, see : https://en.wikipedia.org/wiki/Denavit%E2%80%93Hartenberg_parameters Parameters ---------- consider_limits : bool If True, the transition matrices ensure it's not possible to go beyond self.pmin and self.pmax. This results adding max and min functions in the transition matrix. For example, if the degree of freedom is d and consider_limits is True, every d value will become : min(max(d, self.pmin), self.pmax) (if the limits are not None). This can cause derivation problems so you can disable this option turning consider_limits to False. Defaults to False tolerance : float Tolerance for simplification of the expression. Defaults to 1e-10 Returns ------- sympy.matrices.immutable.ImmutableDenseMatrix Transformation matrix from the parent link to the child link in homogeneous coordinates. The shape is (4, 4) """ T = Matrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) # Finding the degree of freedom ...................................... subs = { "d": self.__d, "theta": self.__theta, "r": self.__r, "alpha": self.__alpha } # Considering limits if asked for sym in subs: if type(subs[sym]) != float: if consider_limits and self.pmin is not None: subs[sym] = Max(subs[sym], self.pmin) if consider_limits and self.pmax is not None: subs[sym] = Min(subs[sym], self.pmax) break val = Symbol("__k__") c = cos(val) s = sin(val) matrices = { "TransX": Matrix([[1, 0, 0, val], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]), "TransZ": Matrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, val], [0, 0, 0, 1]]), "RotX": Matrix([[1, 0, 0, 0], [0, c, -s, 0], [0, s, c, 0], [0, 0, 0, 1]]), "RotZ": Matrix([[c, -s, 0, 0], [s, c, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) } for transformation in self.__rot_trans: trans, param = transformation.split("..") T *= matrices[trans].subs(val, subs[param]) # A bug in SymPy is not rounding float values if they are not # multiplied by a Symbol. To fix this, we multiply T by a random # Symbol, optimize and then divide by this Symbol. debug_sym = Symbol('debug_symbol') return nsimplify(T * debug_sym, tolerance=tolerance).evalf() / debug_sym
def _apply_kernel_equations(o): """ Generate parameters for Convolution kernels References: * SKA-TEL-SDP-0000040 01D section 3.6.12 - Gridding Kernel Update * SKA-TEL-SDP-0000040 01D section E - Re-use of Convolution Kernels """ b = Symbol('b') o.dfonF_backward = BLDep(b, o.epsilon_f_approx / (o.Qkernel * sqrt(o.Nkernel2_backward(b)))) o.dfonF_predict = BLDep(b, o.epsilon_f_approx / (o.Qkernel * sqrt(o.Nkernel2_predict(b)))) # allow uv positional errors up to o.epsilon_f_approx * # 1/Qkernel of a cell from frequency smearing.(But not more # than Nf_max channels...) o.Nf_gcf_backward_nosmear = BLDep(b, Min(log(o.wl_max / o.wl_min) / log(o.dfonF_backward(b) + 1.), o.Nf_max)) o.Nf_gcf_predict_nosmear = BLDep(b, Min(log(o.wl_max / o.wl_min) / log(o.dfonF_predict(b) + 1.), o.Nf_max)) # Number of times kernel convolution needs to be repeated to # generate all oversampling values used in gridding. o.Ngcf_used_backward = BLDep(b, 1) o.Ngcf_used_predict = BLDep(b, 1) if o.on_the_fly: o.Nf_gcf_backward = o.Nf_vis_backward o.Nf_gcf_predict = o.Nf_vis_predict o.Tkernel_backward = o.Tcoal_backward o.Tkernel_predict = o.Tcoal_predict elif not isinstance(o.image_gridding, Symbol) and o.image_gridding > 0: # For image-domain gridding, we multiply kernels that get # applied closely together by the visibilities in image # space, apply phase ramps to account for their shift # relative to each other, FFT the result once, then add to # the grid. So w need larger kernels, gridding is more # expensive, but we need less "kernels" (which are now # "sub-grids"). Note that sub-grid convolution now happens # *after* gridding! o.Nf_gcf_backward = BLDep(b, o.Theta_fov * b / o.wl_sb_min / o.image_gridding * (1 - 1 / o.Qsubband)) o.Nf_gcf_predict = BLDep(b, o.Theta_fov_predict * b / o.wl_sb_min / o.image_gridding * (1 - 1 / o.Qsubband)) o.Tkernel_backward = BLDep(b, Max(o.Tcoal_backward(b), Min(o.Tsnap, 24 * 3600 * o.image_gridding / 2 / pi / o.Theta_fov / b * o.wl_sb_min))) o.Tkernel_predict = BLDep(b, Max(o.Tcoal_backward(b), Min(o.Tsnap, 24 * 3600 * o.image_gridding / 2 / pi / o.Theta_fov_predict / b * o.wl_sb_min))) else: # For both of the following, maintain distributability; # need at least Nf_min kernels. o.Nf_gcf_backward = BLDep(b, Max(o.Nf_gcf_backward_nosmear(b), o.Nf_min)) o.Nf_gcf_predict = BLDep(b, Max(o.Nf_gcf_predict_nosmear(b), o.Nf_min)) o.Tkernel_backward = BLDep(b, o.Tion) o.Tkernel_predict = BLDep(b, o.Tion) # Determine number of visibilities per kernel, approximate # number of oversampling values used. o.Nvis_gcf_backward = BLDep(b, o.Nf_vis_backward(b) / o.Nf_gcf_backward(b) * o.Tkernel_backward(b) / o.Tcoal_backward(b)) o.Nvis_gcf_predict = BLDep(b, o.Nf_vis_predict(b) / o.Nf_gcf_predict(b) * o.Tkernel_predict(b) / o.Tcoal_predict(b)) o.Ngcf_used_backward = BLDep(b, o.Qgcf**2 * (1 - (1 - 1 / o.Qgcf**2)**o.Nvis_gcf_backward(b))) o.Ngcf_used_predict = BLDep(b, o.Qgcf**2 * (1 - (1 - 1 / o.Qgcf**2)**o.Nvis_gcf_predict(b)))
def _apply_coalesce_equations(o, symbolify): """ Determines amount of coalescing of visibilities in time. References: * SKA-TEL-SDP-0000040 01D section A - Covering the Time Axis * SKA-TEL-SDP-0000040 01D section D - Visibility Averaging and Coalescing """ # Time averaging scaled for max baseline. Note that we have # two averaging steps to consider - one in ingest and then one # after phase rotation. We assume that "global" averaging must # retain enough information to prevent smearing for a # hypothetical imaging process using the full field of view, # but reduce that requirement to the actual facet field of # view later. We also assume that we can chose these two # averaging degrees independently without any ill effects. b = Symbol('b') combine_samples = lambda theta: BLDep(b, Max(Min(floor(o.epsilon_f_approx * o.wl / (theta * o.Omega_E * b * o.Tint_used)), o.Tsnap / o.Tint_used), 1.)) o.combine_time_samples = combine_samples(o.Theta_fov_total) o.combine_time_samples_facet = combine_samples(o.Theta_fov) # coalesce visibilities in time. o.Tcoal_skipper = BLDep(b, o.Tint_used * o.combine_time_samples(b)) if symbolify == 'helper': o.Tcoal_skipper = Symbol(o.make_symbol_name("Tcoal_skipper")) if o.blcoal: # For backward step at gridding only, allow coalescance of # visibility points at Facet FoV smearing limit only for # bl-dep averaging case. o.Tcoal_backward = BLDep(b, Min(o.Tint_used * o.combine_time_samples_facet(b), o.Tion)) if o.scale_predict_by_facet: o.Tcoal_predict = BLDep(b, o.Tcoal_backward(b)) else: # Don't let any bl-dependent time averaging be for # longer than either 1.2s or Tion. ?Why 1.2s? o.Tcoal_predict = BLDep(b, Min(o.Tcoal_skipper(b), 1.2, o.Tion)) else: o.Tcoal_predict = BLDep(b, o.Tint_used) o.Tcoal_backward = BLDep(b, o.Tint_used) # Visibility rate (visibilities per second) on ingest, including autocorrelations (per beam, per polarisation) o.Rvis_ingest = (o.Nbl + o.Na) * o.Nf_max / o.Tint_used # Total visibility rate (visibilities per second per beam, per # polarisation) after frequency channels have been combined where # possible. We focus on imaging pipelines here, so we remove # auto-correlations. If they are required by science pipelines, we # assume that they are tracked separately as a data product not # covered by the parametric model. if o.global_blcoal: o.Rvis = blsum(b, o.Nf_vis(b) / Min(o.Tcoal_skipper(b), 1.2, o.Tion)) else: o.Rvis = blsum(b, o.Nf_vis(b) / o.Tint_used) # Visibility rate for backward step, allow coalescing # in time and freq prior to gridding o.Rvis_backward = blsum(b, o.Nf_vis_backward(b) / o.Tcoal_backward(b)) # Visibility rate for predict step o.Rvis_predict = blsum(b, o.Nf_vis_predict(b) / o.Tcoal_predict(b))
def test_piecewise_integrate_symbolic_conditions(): a = Symbol('a', real=True, finite=True) b = Symbol('b', real=True, finite=True) x = Symbol('x', real=True, finite=True) y = Symbol('y', real=True, finite=True) p0 = Piecewise((0, Or(x < a, x > b)), (1, True)) p1 = Piecewise((0, x < a), (0, x > b), (1, True)) p2 = Piecewise((0, x > b), (0, x < a), (1, True)) p3 = Piecewise((0, x < a), (1, x < b), (0, True)) p4 = Piecewise((0, x > b), (1, x > a), (0, True)) p5 = Piecewise((1, And(a < x, x < b)), (0, True)) assert integrate(p0, (x, -oo, y)) == Min(b, y) - Min(a, b, y) assert integrate(p1, (x, -oo, y)) == Min(b, y) - Min(a, b, y) assert integrate(p2, (x, -oo, y)) == Min(b, y) - Min(a, b, y) assert integrate(p3, (x, -oo, y)) == Min(b, y) - Min(a, b, y) assert integrate(p4, (x, -oo, y)) == Min(b, y) - Min(a, b, y) assert integrate(p5, (x, -oo, y)) == Min(b, y) - Min(a, b, y) assert integrate(p0, (x, y, oo)) == Max(a, b, y) - Max(a, y) assert integrate(p1, (x, y, oo)) == Max(a, b, y) - Max(a, y) assert integrate(p2, (x, y, oo)) == Max(a, b, y) - Max(a, y) assert integrate(p3, (x, y, oo)) == Max(a, b, y) - Max(a, y) assert integrate(p4, (x, y, oo)) == Max(a, b, y) - Max(a, y) assert integrate(p5, (x, y, oo)) == Max(a, b, y) - Max(a, y) assert integrate(p0, x) == Piecewise((0, Or(x < a, x > b)), (x, True)) assert integrate(p1, x) == Piecewise((0, Or(x < a, x > b)), (x, True)) assert integrate(p2, x) == Piecewise((0, Or(x < a, x > b)), (x, True)) p1 = Piecewise((0, x < a), (0.5, x > b), (1, True)) p2 = Piecewise((0.5, x > b), (0, x < a), (1, True)) p3 = Piecewise((0, x < a), (1, x < b), (0.5, True)) p4 = Piecewise((0.5, x > b), (1, x > a), (0, True)) p5 = Piecewise((1, And(a < x, x < b)), (0.5, x > b), (0, True)) assert integrate(p1, (x, -oo, y)) == 0.5 * y + 0.5 * Min(b, y) - Min(a, b, y) assert integrate(p2, (x, -oo, y)) == 0.5 * y + 0.5 * Min(b, y) - Min(a, b, y) assert integrate(p3, (x, -oo, y)) == 0.5 * y + 0.5 * Min(b, y) - Min(a, b, y) assert integrate(p4, (x, -oo, y)) == 0.5 * y + 0.5 * Min(b, y) - Min(a, b, y) assert integrate(p5, (x, -oo, y)) == 0.5 * y + 0.5 * Min(b, y) - Min(a, b, y)
def test_piecewise_integrate4_symbolic_conditions(): a = Symbol('a', real=True, finite=True) b = Symbol('b', real=True, finite=True) x = Symbol('x', real=True, finite=True) y = Symbol('y', real=True, finite=True) p0 = Piecewise((0, Or(x < a, x > b)), (1, True)) p1 = Piecewise((0, x < a), (0, x > b), (1, True)) p2 = Piecewise((0, x > b), (0, x < a), (1, True)) p3 = Piecewise((0, x < a), (1, x < b), (0, True)) p4 = Piecewise((0, x > b), (1, x > a), (0, True)) p5 = Piecewise((1, And(a < x, x < b)), (0, True)) # check values of a=1, b=3 (and reversed) with values # of y of 0, 1, 2, 3, 4 lim = Tuple(x, -oo, y) for p in (p0, p1, p2, p3, p4, p5): ans = p.integrate(lim) for i in range(5): reps = {a:1, b:3, y:i} assert ans.subs(reps) == p.subs(reps).integrate(lim.subs(reps)) reps = {a: 3, b:1, y:i} assert ans.subs(reps) == p.subs(reps).integrate(lim.subs(reps)) lim = Tuple(x, y, oo) for p in (p0, p1, p2, p3, p4, p5): ans = p.integrate(lim) for i in range(5): reps = {a:1, b:3, y:i} assert ans.subs(reps) == p.subs(reps).integrate(lim.subs(reps)) reps = {a:3, b:1, y:i} assert ans.subs(reps) == p.subs(reps).integrate(lim.subs(reps)) ans = Piecewise( (0, x <= Min(a, b)), (x - Min(a, b), x <= b), (b - Min(a, b), True)) for i in (p0, p1, p2, p4): assert i.integrate(x) == ans assert p3.integrate(x) == Piecewise( (0, x < a), (-a + x, x <= Max(a, b)), (-a + Max(a, b), True)) assert p5.integrate(x) == Piecewise( (0, x <= a), (-a + x, x <= Max(a, b)), (-a + Max(a, b), True)) p1 = Piecewise((0, x < a), (0.5, x > b), (1, True)) p2 = Piecewise((0.5, x > b), (0, x < a), (1, True)) p3 = Piecewise((0, x < a), (1, x < b), (0.5, True)) p4 = Piecewise((0.5, x > b), (1, x > a), (0, True)) p5 = Piecewise((1, And(a < x, x < b)), (0.5, x > b), (0, True)) # check values of a=1, b=3 (and reversed) with values # of y of 0, 1, 2, 3, 4 lim = Tuple(x, -oo, y) for p in (p1, p2, p3, p4, p5): ans = p.integrate(lim) for i in range(5): reps = {a:1, b:3, y:i} assert ans.subs(reps) == p.subs(reps).integrate(lim.subs(reps)) reps = {a: 3, b:1, y:i} assert ans.subs(reps) == p.subs(reps).integrate(lim.subs(reps))
def test_mellin_transform(): from sympy import Max, Min, Ne MT = mellin_transform bpos = symbols('b', positive=True) # 8.4.2 assert MT(x**nu*Heaviside(x - 1), x, s) == \ (-1/(nu + s), (-oo, -re(nu)), True) assert MT(x**nu*Heaviside(1 - x), x, s) == \ (1/(nu + s), (-re(nu), oo), True) assert MT((1 - x)**(beta - 1)*Heaviside(1 - x), x, s) == \ (gamma(beta)*gamma(s)/gamma(beta + s), (0, oo), re(-beta) < 0) assert MT((x - 1)**(beta - 1)*Heaviside(x - 1), x, s) == \ (gamma(beta)*gamma(1 - beta - s)/gamma(1 - s), (-oo, -re(beta) + 1), re(-beta) < 0) assert MT((1 + x)**(-rho), x, s) == \ (gamma(s)*gamma(rho - s)/gamma(rho), (0, re(rho)), True) # TODO also the conditions should be simplified assert MT(abs(1 - x)**(-rho), x, s) == (cos(pi * (rho / 2 - s)) * gamma(s) * gamma(rho - s) / (cos(pi * rho / 2) * gamma(rho)), (0, re(rho)), And(re(rho) - 1 < 0, re(rho) < 1)) mt = MT((1 - x)**(beta - 1) * Heaviside(1 - x) + a * (x - 1)**(beta - 1) * Heaviside(x - 1), x, s) assert mt[1], mt[2] == ((0, -re(beta) + 1), True) assert MT((x**a - b**a)/(x - b), x, s)[0] == \ pi*b**(a + s - 1)*sin(pi*a)/(sin(pi*s)*sin(pi*(a + s))) assert MT((x**a - bpos**a)/(x - bpos), x, s) == \ (pi*bpos**(a + s - 1)*sin(pi*a)/(sin(pi*s)*sin(pi*(a + s))), (Max(-re(a), 0), Min(1 - re(a), 1)), True) expr = (sqrt(x + b**2) + b)**a assert MT(expr.subs(b, bpos), x, s) == \ (-a*(2*bpos)**(a + 2*s)*gamma(s)*gamma(-a - 2*s)/gamma(-a - s + 1), (0, -re(a)/2), True) expr = (sqrt(x + b**2) + b)**a / sqrt(x + b**2) assert MT(expr.subs(b, bpos), x, s) == \ (2**(a + 2*s)*bpos**(a + 2*s - 1)*gamma(s) *gamma(1 - a - 2*s)/gamma(1 - a - s), (0, -re(a)/2 + S(1)/2), True) # 8.4.2 assert MT(exp(-x), x, s) == (gamma(s), (0, oo), True) assert MT(exp(-1 / x), x, s) == (gamma(-s), (-oo, 0), True) # 8.4.5 assert MT(log(x)**4 * Heaviside(1 - x), x, s) == (24 / s**5, (0, oo), True) assert MT(log(x)**3 * Heaviside(x - 1), x, s) == (6 / s**4, (-oo, 0), True) assert MT(log(x + 1), x, s) == (pi / (s * sin(pi * s)), (-1, 0), True) assert MT(log(1 / x + 1), x, s) == (pi / (s * sin(pi * s)), (0, 1), True) assert MT(log(abs(1 - x)), x, s) == (pi / (s * tan(pi * s)), (-1, 0), True) assert MT(log(abs(1 - 1 / x)), x, s) == (pi / (s * tan(pi * s)), (0, 1), True) # TODO we cannot currently do these (needs summation of 3F2(-1)) # this also implies that they cannot be written as a single g-function # (although this is possible) mt = MT(log(x) / (x + 1), x, s) assert mt[1:] == ((0, 1), True) assert not hyperexpand(mt[0], allow_hyper=True).has(meijerg) mt = MT(log(x)**2 / (x + 1), x, s) assert mt[1:] == ((0, 1), True) assert not hyperexpand(mt[0], allow_hyper=True).has(meijerg) mt = MT(log(x) / (x + 1)**2, x, s) assert mt[1:] == ((0, 2), True) assert not hyperexpand(mt[0], allow_hyper=True).has(meijerg) # 8.4.14 assert MT(erf(sqrt(x)), x, s) == \ (-gamma(s + S(1)/2)/(sqrt(pi)*s), (-S(1)/2, 0), True)
,'c22': 'Fraction of slow soil coming from structural litter' ,'c23': 'Fraction of slow soil coming from cwd litter' ,'c33': 'Fraction of passive soil coming from cwd litter' ,'d12': 'Fraction of microbial soil coming from slow soil' ,'d13': 'Fraction of microbial soil coming from passive soil' ,'d21': 'Fraction of slow soil coming from microbial soil' ,'d23': 'Fraction of slow soil coming from passive soil' ,'d31': 'Fraction of passive soil coming from microbial soil' ,'d32': 'Fraction of passive soil coming from slow soil' } for name in sym_dict.keys(): var(name) #a_leaf + a_root + a_wood = 1 #b1l + b2l = 1 #b1r + b2r = 1 x_nup = Min(1,(N_min/(F_nupmin*Delta_t))) x_pup = Min(1,(P_lab/(F_pupmin*Delta_t))) x_npup = Min(x_nup,x_pup) x_nleaf = (n_leaf/(n_leaf+k_n)) x_pleaf = (p_leaf/(p_leaf+k_p)) x_npleaf = Min(x_nleaf,x_pleaf) F_c = x_npleaf*x_npup*F_cmax #unit: "gC*m^{-2}*d^{-1}" u = F_c x = StateVariableTuple((C_leaf, C_root, C_wood, C_j1, C_j2, C_j3, C_k1, C_k2, C_k3)) b = ImmutableMatrix((a_leaf, a_root, a_wood)) Input = InputTuple(tuple(u*b)+(0,0,0,0,0,0)) A = CompartmentalMatrix([ [-mu_leaf*(b1l+b2l), 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ] ,[ 0 ,-mu_root*(b1r+b2r), 0 , 0 , 0 , 0 , 0 , 0 , 0 ] ,[ 0 , 0 ,-mu_wood*b3w, 0 , 0 , 0 , 0 , 0 , 0 ] ,[ mu_leaf*b1l , mu_root*b1r , 0 ,-mu_j1*m_n*(c11+c21), 0 , 0 , 0 , 0 , 0 ]
def test_mellin_transform(): from sympy import Max, Min MT = mellin_transform bpos = symbols('b', positive=True) # 8.4.2 assert MT(x**nu*Heaviside(x - 1), x, s) == \ (-1/(nu + s), (-oo, -re(nu)), True) assert MT(x**nu*Heaviside(1 - x), x, s) == \ (1/(nu + s), (-re(nu), oo), True) assert MT((1 - x)**(beta - 1)*Heaviside(1 - x), x, s) == \ (gamma(beta)*gamma(s)/gamma(beta + s), (0, oo), re(beta) > 0) assert MT((x - 1)**(beta - 1)*Heaviside(x - 1), x, s) == \ (gamma(beta)*gamma(1 - beta - s)/gamma(1 - s), (-oo, -re(beta) + 1), re(beta) > 0) assert MT((1 + x)**(-rho), x, s) == \ (gamma(s)*gamma(rho - s)/gamma(rho), (0, re(rho)), True) # TODO also the conditions should be simplified, e.g. # And(re(rho) - 1 < 0, re(rho) < 1) should just be # re(rho) < 1 assert MT(abs(1 - x)**(-rho), x, s) == (2 * sin(pi * rho / 2) * gamma(1 - rho) * cos(pi * (rho / 2 - s)) * gamma(s) * gamma(rho - s) / pi, (0, re(rho)), And(re(rho) - 1 < 0, re(rho) < 1)) mt = MT((1 - x)**(beta - 1) * Heaviside(1 - x) + a * (x - 1)**(beta - 1) * Heaviside(x - 1), x, s) assert mt[1], mt[2] == ((0, -re(beta) + 1), re(beta) > 0) assert MT((x**a - b**a)/(x - b), x, s)[0] == \ pi*b**(a + s - 1)*sin(pi*a)/(sin(pi*s)*sin(pi*(a + s))) assert MT((x**a - bpos**a)/(x - bpos), x, s) == \ (pi*bpos**(a + s - 1)*sin(pi*a)/(sin(pi*s)*sin(pi*(a + s))), (Max(-re(a), 0), Min(1 - re(a), 1)), True) expr = (sqrt(x + b**2) + b)**a assert MT(expr.subs(b, bpos), x, s) == \ (-a*(2*bpos)**(a + 2*s)*gamma(s)*gamma(-a - 2*s)/gamma(-a - s + 1), (0, -re(a)/2), True) expr = (sqrt(x + b**2) + b)**a / sqrt(x + b**2) assert MT(expr.subs(b, bpos), x, s) == \ (2**(a + 2*s)*bpos**(a + 2*s - 1)*gamma(s) *gamma(1 - a - 2*s)/gamma(1 - a - s), (0, -re(a)/2 + S.Half), True) # 8.4.2 assert MT(exp(-x), x, s) == (gamma(s), (0, oo), True) assert MT(exp(-1 / x), x, s) == (gamma(-s), (-oo, 0), True) # 8.4.5 assert MT(log(x)**4 * Heaviside(1 - x), x, s) == (24 / s**5, (0, oo), True) assert MT(log(x)**3 * Heaviside(x - 1), x, s) == (6 / s**4, (-oo, 0), True) assert MT(log(x + 1), x, s) == (pi / (s * sin(pi * s)), (-1, 0), True) assert MT(log(1 / x + 1), x, s) == (pi / (s * sin(pi * s)), (0, 1), True) assert MT(log(abs(1 - x)), x, s) == (pi / (s * tan(pi * s)), (-1, 0), True) assert MT(log(abs(1 - 1 / x)), x, s) == (pi / (s * tan(pi * s)), (0, 1), True) # 8.4.14 assert MT(erf(sqrt(x)), x, s) == \ (-gamma(s + S.Half)/(sqrt(pi)*s), (Rational(-1, 2), 0), True)
def test_latex_functions(): assert latex(exp(x)) == "e^{x}" assert latex(exp(1) + exp(2)) == "e + e^{2}" f = Function('f') assert latex(f(x)) == '\\operatorname{f}{\\left (x \\right )}' beta = Function('beta') assert latex(beta(x)) == r"\beta{\left (x \right )}" assert latex(sin(x)) == r"\sin{\left (x \right )}" assert latex(sin(x), fold_func_brackets=True) == r"\sin {x}" assert latex(sin(2*x**2), fold_func_brackets=True) == \ r"\sin {2 x^{2}}" assert latex(sin(x**2), fold_func_brackets=True) == \ r"\sin {x^{2}}" assert latex(asin(x)**2) == r"\operatorname{asin}^{2}{\left (x \right )}" assert latex(asin(x)**2, inv_trig_style="full") == \ r"\arcsin^{2}{\left (x \right )}" assert latex(asin(x)**2, inv_trig_style="power") == \ r"\sin^{-1}{\left (x \right )}^{2}" assert latex(asin(x**2), inv_trig_style="power", fold_func_brackets=True) == \ r"\sin^{-1} {x^{2}}" assert latex(factorial(k)) == r"k!" assert latex(factorial(-k)) == r"\left(- k\right)!" assert latex(factorial2(k)) == r"k!!" assert latex(factorial2(-k)) == r"\left(- k\right)!!" assert latex(binomial(2, k)) == r"{\binom{2}{k}}" assert latex(FallingFactorial(3, k)) == r"{\left(3\right)}_{\left(k\right)}" assert latex(RisingFactorial(3, k)) == r"{\left(3\right)}^{\left(k\right)}" assert latex(floor(x)) == r"\lfloor{x}\rfloor" assert latex(ceiling(x)) == r"\lceil{x}\rceil" assert latex(Min(x, 2, x**3)) == r"\min\left(2, x, x^{3}\right)" assert latex(Max(x, 2, x**3)) == r"\max\left(2, x, x^{3}\right)" assert latex(Abs(x)) == r"\lvert{x}\rvert" assert latex(re(x)) == r"\Re{x}" assert latex(re(x + y)) == r"\Re{x} + \Re{y}" assert latex(im(x)) == r"\Im{x}" assert latex(conjugate(x)) == r"\overline{x}" assert latex(gamma(x)) == r"\Gamma\left(x\right)" assert latex(Order(x)) == r"\mathcal{O}\left(x\right)" assert latex(lowergamma(x, y)) == r'\gamma\left(x, y\right)' assert latex(uppergamma(x, y)) == r'\Gamma\left(x, y\right)' assert latex(cot(x)) == r'\cot{\left (x \right )}' assert latex(coth(x)) == r'\coth{\left (x \right )}' assert latex(re(x)) == r'\Re{x}' assert latex(im(x)) == r'\Im{x}' assert latex(root(x, y)) == r'x^{\frac{1}{y}}' assert latex(arg(x)) == r'\arg{\left (x \right )}' assert latex(zeta(x)) == r'\zeta\left(x\right)' assert latex(zeta(x)) == r"\zeta\left(x\right)" assert latex(zeta(x)**2) == r"\zeta^{2}\left(x\right)" assert latex(zeta(x, y)) == r"\zeta\left(x, y\right)" assert latex(zeta(x, y)**2) == r"\zeta^{2}\left(x, y\right)" assert latex(dirichlet_eta(x)) == r"\eta\left(x\right)" assert latex(dirichlet_eta(x)**2) == r"\eta^{2}\left(x\right)" assert latex(polylog(x, y)) == r"\operatorname{Li}_{x}\left(y\right)" assert latex(polylog(x, y)**2) == r"\operatorname{Li}_{x}^{2}\left(y\right)" assert latex(lerchphi(x, y, n)) == r"\Phi\left(x, y, n\right)" assert latex(lerchphi(x, y, n)**2) == r"\Phi^{2}\left(x, y, n\right)" assert latex(Ei(x)) == r'\operatorname{Ei}{\left (x \right )}' assert latex(Ei(x)**2) == r'\operatorname{Ei}^{2}{\left (x \right )}' assert latex(expint(x, y)**2) == r'\operatorname{E}_{x}^{2}\left(y\right)' assert latex(Shi(x)**2) == r'\operatorname{Shi}^{2}{\left (x \right )}' assert latex(Si(x)**2) == r'\operatorname{Si}^{2}{\left (x \right )}' assert latex(Ci(x)**2) == r'\operatorname{Ci}^{2}{\left (x \right )}' assert latex(Chi(x)**2) == r'\operatorname{Chi}^{2}{\left (x \right )}' # Test latex printing of function names with "_" assert latex( polar_lift(0)) == r"\operatorname{polar\_lift}{\left (0 \right )}" assert latex(polar_lift(0)** 3) == r"\operatorname{polar\_lift}^{3}{\left (0 \right )}"
't': 'TimeSymbol("t")' #Fixme: Needed to include it here so that the equation for GPP would work } for name in sym_dict.keys(): var(name) Gamma = (O_2 / (2 * tau)) J_e = (alpha_3 * Q_p * ((C_i - Gamma) / (C_i + (2 * Gamma)))) J_e4 = V_m J_c = ((V_m * (C_i - Gamma)) / (C_i + (K_c * (1 + (O_2 / K_o))))) J_c4 = k * C_i # the compensation point is taken to be 0 for C4 plants T = V_m / 8.2 J_s = ((3 * T * (1 - (Gamma / C_i))) + (J_p * Gamma / C_i)) J_i = alpha_4 * Q_p A_g = Min(J_e, J_c, J_s) # A_g = Min(J_i,J_e,J_c) #C4 fT_stem = exp(E_0 * ((1 / (15 - T_0)) - (1 / (T_stem - T_0)))) R_leaf = gamma * V_m fT_soil = exp(E_0 * ((1 / (15 - T_0)) - (1 / (T_soil - T_0)))) R_stem = Beta_stem * lambda_sapwood * C_is * fT_stem R_root = Beta_root * C_ir * fT_soil A_n = A_g - R_leaf GPP_i = integrate(A_g, t) NPP_i = ((1 - eta) * (integrate(A_g - R_leaf - R_stem - R_root, t))) x = StateVariableTuple((C_il, C_is, C_ir)) u = NPP_i b = (a_il, a_is, a_ir) Input = InputTuple(u * ImmutableMatrix(b)) A = CompartmentalMatrix(diag(-1 / tau_il, -1 / tau_is, -1 / tau_ir))
def test_piecewise_integrate_symbolic_conditions(): from sympy.abc import a, b, x, y p0 = Piecewise((0, Or(x < a, x > b)), (1, True)) p1 = Piecewise((0, x < a), (0, x > b), (1, True)) p2 = Piecewise((0, x > b), (0, x < a), (1, True)) p3 = Piecewise((0, x < a), (1, x < b), (0, True)) p4 = Piecewise((0, x > b), (1, x > a), (0, True)) p5 = Piecewise((1, And(a < x, x < b)), (0, True)) assert integrate(p0, (x, -oo, y)) == Min(b, y) - Min(a, b, y) assert integrate(p1, (x, -oo, y)) == Min(b, y) - Min(a, b, y) assert integrate(p2, (x, -oo, y)) == Min(b, y) - Min(a, b, y) assert integrate(p3, (x, -oo, y)) == Min(b, y) - Min(a, b, y) assert integrate(p4, (x, -oo, y)) == Min(b, y) - Min(a, b, y) assert integrate(p5, (x, -oo, y)) == Min(b, y) - Min(a, b, y) assert integrate(p0, (x, y, oo)) == Max(a, b, y) - Max(a, y) assert integrate(p1, (x, y, oo)) == Max(a, b, y) - Max(a, y) assert integrate(p2, (x, y, oo)) == Max(a, b, y) - Max(a, y) assert integrate(p3, (x, y, oo)) == Max(a, b, y) - Max(a, y) assert integrate(p4, (x, y, oo)) == Max(a, b, y) - Max(a, y) assert integrate(p5, (x, y, oo)) == Max(a, b, y) - Max(a, y) assert integrate(p0, x) == Piecewise((0, Or(x < a, x > b)), (x, True)) assert integrate(p1, x) == Piecewise((0, Or(x < a, x > b)), (x, True)) assert integrate(p2, x) == Piecewise((0, Or(x < a, x > b)), (x, True)) p1 = Piecewise((0, x < a), (0.5, x > b), (1, True)) p2 = Piecewise((0.5, x > b), (0, x < a), (1, True)) p3 = Piecewise((0, x < a), (1, x < b), (0.5, True)) p4 = Piecewise((0.5, x > b), (1, x > a), (0, True)) p5 = Piecewise((1, And(a < x, x < b)), (0.5, x > b), (0, True)) assert integrate(p1, (x, -oo, y)) == 0.5 * y + 0.5 * Min(b, y) - Min(a, b, y) assert integrate(p2, (x, -oo, y)) == 0.5 * y + 0.5 * Min(b, y) - Min(a, b, y) assert integrate(p3, (x, -oo, y)) == 0.5 * y + 0.5 * Min(b, y) - Min(a, b, y) assert integrate(p4, (x, -oo, y)) == 0.5 * y + 0.5 * Min(b, y) - Min(a, b, y) assert integrate(p5, (x, -oo, y)) == 0.5 * y + 0.5 * Min(b, y) - Min(a, b, y)
def clamp(self, x, minValue, maxValue): # Find a way to create a Sympy "clamp" function return Max(Min(x, maxValue), minValue)
'transfer coefficients from pool j to pool i', 'f_68': 'transfer coefficients from pool j to pool i', 'A': 'Carbon transfer coefficients between plant, litter, and soil pools', 'B': 'Vector of partitioning coefficients of the photosynthetically fixed carbon (b_1, b_2, b_3)', 'C': 'Diagonal matrix with exit rates of carbon from the eight carbon pools (c_)', 'xi': 'Environmental scalar representing effects of temperature and moisture on the carbon transfer among pools' # xi_(t) } for name in sym_dict.keys(): var(name) f_W = Min((0.5 * W), 1) f_T = Q_10**((T - 10) / 10) xi = f_W * f_T x = StateVariableTuple((x_1, x_2, x_3, x_4, x_5, x_6, x_7, x_8)) B = (b_1, b_2, b_3, 0, 0, 0, 0, 0) Input = InputTuple(U * ImmutableMatrix(B)) A = ImmutableMatrix([[-1, 0, 0, 0, 0, 0, 0, 0], [0, -1, 0, 0, 0, 0, 0, 0], [0, 0, -1, 0, 0, 0, 0, 0], [f_41, 0, f_43, -1, 0, 0, 0, 0], [f_51, f_52, f_53, 0, -1, 0, 0, 0], [0, 0, 0, f_64, f_65, -1, f_67, f_68], [0, 0, 0, 0, f_75, f_76, -1, 0], [0, 0, 0, 0, 0, f_86, f_87, -1]]) C = ImmutableMatrix(diag(c_1, c_2, c_3, c_4, c_5, c_6, c_7, c_8)) CM = CompartmentalMatrix(xi * A * C) t = TimeSymbol("t")
def omapper(self): """ Logical decomposition of the DOMAIN region into OWNED and CORE sub-regions. This is "cumulative" over all DiscreteFunctions in the HaloScheme; it also takes into account IterationSpace offsets induced by SubDomains/SubDimensions. Examples -------- Consider a HaloScheme comprising two one-dimensional Functions, ``u`` and ``v``. ``u``'s halo, on the LEFT and RIGHT DataSides respectively, is (2, 2), while ``v``'s is (4, 4). The situation is depicted below. ^^oo----------------oo^^ u ^^^^oooo------------oooo^^^^ v Where '^' represents a HALO point, 'o' a OWNED point, and '-' a CORE point. Together, the 'o' and '-' points constitute the DOMAIN region. In this example, the "cumulative" OWNED size is (left=4, right=4), that is the max on each DataSide across all Functions, namely ``u`` and ``v``. The ``omapper`` will contain the following entries: [(((d, CORE, CENTER),), {d: (d_m + 4, d_M - 4)}), (((d, OWNED, LEFT),), {d: (d_m, min(d_m + 3, d_M))}), (((d, OWNED, RIGHT),), {d: (max(d_M - 3, d_m), d_M)})] In presence of SubDomains (or, more generally, iteration over SubDimensions), the "true" DOMAIN is actually smaller. For example, consider again the example above, but now with a SubDomain that excludes the first ``nl`` and the last ``nr`` DOMAIN points, where ``nl >= 0`` and ``nr >= 0``. Often, ``nl`` and ``nr`` are referred to as the "thickness" of the SubDimension (see also SubDimension.__doc__). For example, the situation could be as below ^^ooXXX----------XXXoo^^ u ^^^^ooooX----------Xoooo^^^^ v Where 'X' is a CORE point excluded by the computation due to the SubDomain. Here, the 'o' points are outside of the SubDomain, but in general they could also be inside. The ``omapper`` is constructed taking into account that SubDomains are iterated over with min point ``d_m + nl`` and max point ``d_M - nr``. Here, the ``omapper`` is: [(((d, CORE, CENTER),), {d: (d_m + 4, d_M - 4), nl: (max(nl - 4, 0),), nr: (max(nr - 4, 0),)}), (((d, OWNED, LEFT),), {d: (d_m, min(d_m + 3, d_M - nr)), nl: (nl,), nr: (0,)}), (((d, OWNED, RIGHT),), {d: (max(d_M - 3, d_m + nl), d_M), nl: (0,), nr: (nr,)})] To convince ourselves that this makes sense, we consider a number of cases. For now, we assume ``|d_M - d_m| > HALO``, that is the left-HALO and right-HALO regions do not overlap. 1. The SubDomain thickness is 0, which is like there were no SubDomains. By instantiating the template above with ``nl = 0`` and ``nr = 0``, it is trivial to see that we fall back to the non-SubDomain case. 2. The SubDomain thickness is as big as the HALO region size, that is ``nl = 4`` and ``nr = 4``. The ``omapper`` is such that no iterations will be performed in the OWNED regions (i.e., "everything is CORE"). 3. The SubDomain left-thickness is smaller than the left-HALO region size, while the SubDomain right-thickness is larger than the right-Halo region size. This means that some left-OWNED points are within the SubDomain, while the RIGHT-OWNED are outside. For example, take ``nl = 1`` and ``nr = 5``; the iteration regions will then be: - (CORE, CENTER): {d: (d_m + 4, d_M - 4), nl: (0,), nr: (1,)}, so the min point is ``d_m + 4``, while the max point is ``d_M - 5``. - (OWNED, LEFT): {d: (d_m, d_m + 3), nl: (1,), nr: (0,)}, so the min point is ``d_m + 1``, while the max point is ``dm + 3``. - (OWNED, RIGHT): {d: (d_M - 3, d_M), nl: (0,), nr: (5,)}, so the min point is ``d_M - 3``, while the max point is ``d_M - 5``, which implies zero iterations in this region. Let's now assume that the left-HALO and right-HALO regions overlap. For example, ``d_m = 0`` and ``d_M = 1`` (i.e., the DOMAIN only has two points), with the HALO size that is still (4, 4). 4. Let's take ``nl = 1`` and ``nr = 0``. That is, only one point is in the SubDomain and should be updated. We again instantiate the iteration regions and obtain: - (CORE, CENTER): {d: (d_m + 4, d_M - 4), nl: (0,), nr: (0,)}, so the min point is ``d_m + 4 = 4``, while the max point is ``d_M - 4 = -3``, which implies zero iterations in this region. - (OWNED, LEFT): {d: (d_m, min(d_m + 3, d_M - nr)), nl: (1,), nr: (0,)}, so the min point is ``d_m + 1 = 1``, while the max point is ``min(d_m + 3, d_M - nr) = min(3, 1) = 1``, which implies that there is exactly one point in this region. - (OWNED, RIGHT): {d: (max(d_M - 3, d_m + nl), d_M), nl: (0,), nr: (0,)}, so the min point is ``max(d_M - 3, d_m + nl) = max(-2, 1) = 1``, while the max point is ``d_M = 1``, which implies that there is exactly one point in this region, and this point is redundantly computed as it's logically the same as that in the (OWNED, LEFT) region. Notes ----- For each Function, the '^' and 'o' are exactly the same on *all MPI ranks*, so the output of this method is guaranteed to be consistent across *all MPI ranks*. """ items = [((d, CENTER), (d, LEFT), (d, RIGHT)) for d in self.dimensions] processed = [] for item in product(*items): where = [] mapper = {} for d, s in item: osl, osr = self.owned_size[d] # Handle SubDomain/SubDimensions to-honor offsets nl = Max(0, *[i for i, _ in self.honored.get(d, [])]) nr = Max(0, *[i for _, i in self.honored.get(d, [])]) if s is CENTER: where.append((d, CORE, s)) mapper[d] = (d.symbolic_min + osl, d.symbolic_max - osr) if nl != 0: mapper[nl] = (Max(nl - osl, 0), ) if nr != 0: mapper[nr] = (Max(nr - osr, 0), ) else: where.append((d, OWNED, s)) if s is LEFT: mapper[d] = (d.symbolic_min, Min(d.symbolic_min + osl - 1, d.symbolic_max - nr)) if nl != 0: mapper[nl] = (nl, ) mapper[nr] = (0, ) else: mapper[d] = (Max(d.symbolic_max - osr + 1, d.symbolic_min + nl), d.symbolic_max) if nr != 0: mapper[nl] = (0, ) mapper[nr] = (nr, ) processed.append((tuple(where), frozendict(mapper))) _, core = processed.pop(0) owned = processed return OMapper(core, owned)
def _set_function(f, x): from sympy.functions.elementary.miscellaneous import Min, Max from sympy.solvers.solveset import solveset from sympy.core.function import diff, Lambda from sympy.series import limit from sympy.calculus.singularities import singularities from sympy.sets import Complement # TODO: handle functions with infinitely many solutions (eg, sin, tan) # TODO: handle multivariate functions expr = f.expr if len(expr.free_symbols) > 1 or len(f.variables) != 1: return var = f.variables[0] if expr.is_Piecewise: result = S.EmptySet domain_set = x for (p_expr, p_cond) in expr.args: if p_cond is true: intrvl = domain_set else: intrvl = p_cond.as_set() intrvl = Intersection(domain_set, intrvl) if p_expr.is_Number: image = FiniteSet(p_expr) else: image = imageset(Lambda(var, p_expr), intrvl) result = Union(result, image) # remove the part which has been `imaged` domain_set = Complement(domain_set, intrvl) if domain_set.is_EmptySet: break return result if not x.start.is_comparable or not x.end.is_comparable: return try: sing = [i for i in singularities(expr, var) if i.is_real and i in x] except NotImplementedError: return if x.left_open: _start = limit(expr, var, x.start, dir="+") elif x.start not in sing: _start = f(x.start) if x.right_open: _end = limit(expr, var, x.end, dir="-") elif x.end not in sing: _end = f(x.end) if len(sing) == 0: solns = list(solveset(diff(expr, var), var)) extr = [_start, _end] + [f(i) for i in solns if i.is_real and i in x] start, end = Min(*extr), Max(*extr) left_open, right_open = False, False if _start <= _end: # the minimum or maximum value can occur simultaneously # on both the edge of the interval and in some interior # point if start == _start and start not in solns: left_open = x.left_open if end == _end and end not in solns: right_open = x.right_open else: if start == _end and start not in solns: left_open = x.right_open if end == _start and end not in solns: right_open = x.left_open return Interval(start, end, left_open, right_open) else: return imageset(f, Interval(x.start, sing[0], x.left_open, True)) + \ Union(*[imageset(f, Interval(sing[i], sing[i + 1], True, True)) for i in range(0, len(sing) - 1)]) + \ imageset(f, Interval(sing[-1], x.end, True, x.right_open))
def test_Min_Max(): # see gh-10375 assert lambdify((x, y, z), Min(x, y, z))(1, 2, 3) == 1 assert lambdify((x, y, z), Max(x, y, z))(1, 2, 3) == 3
def test_piecewise_integrate(): x, y = symbols('x y', real=True, finite=True) # XXX Use '<=' here! '>=' is not yet implemented .. f = Piecewise(((x - 2)**2, 0 <= x), (1, True)) assert integrate(f, (x, -2, 2)) == Rational(14, 3) g = Piecewise(((x - 5)**5, 4 <= x), (f, True)) assert integrate(g, (x, -2, 2)) == Rational(14, 3) assert integrate(g, (x, -2, 5)) == Rational(43, 6) g = Piecewise(((x - 5)**5, 4 <= x), (f, x < 4)) assert integrate(g, (x, -2, 2)) == Rational(14, 3) assert integrate(g, (x, -2, 5)) == Rational(43, 6) g = Piecewise(((x - 5)**5, 2 <= x), (f, x < 2)) assert integrate(g, (x, -2, 2)) == Rational(14, 3) assert integrate(g, (x, -2, 5)) == -Rational(701, 6) g = Piecewise(((x - 5)**5, 2 <= x), (f, True)) assert integrate(g, (x, -2, 2)) == Rational(14, 3) assert integrate(g, (x, -2, 5)) == -Rational(701, 6) g = Piecewise(((x - 5)**5, 2 <= x), (2 * f, True)) assert integrate(g, (x, -2, 2)) == 2 * Rational(14, 3) assert integrate(g, (x, -2, 5)) == -Rational(673, 6) g = Piecewise((1, x > 0), (0, Eq(x, 0)), (-1, x < 0)) assert integrate(g, (x, -1, 1)) == 0 g = Piecewise((1, x - y < 0), (0, True)) assert integrate(g, (y, -oo, 0)) == -Min(0, x) assert integrate(g, (y, 0, oo)) == oo - Max(0, x) assert integrate(g, (y, -oo, oo)) == oo - x g = Piecewise((0, x < 0), (x, x <= 1), (1, True)) assert integrate(g, (x, -5, 1)) == Rational(1, 2) assert integrate(g, (x, -5, y)).subs(y, 1) == Rational(1, 2) assert integrate(g, (x, y, 1)).subs(y, -5) == Rational(1, 2) assert integrate(g, (x, 1, -5)) == -Rational(1, 2) assert integrate(g, (x, 1, y)).subs(y, -5) == -Rational(1, 2) assert integrate(g, (x, y, -5)).subs(y, 1) == -Rational(1, 2) assert integrate(g, (x, -5, y)) == Piecewise( (0, y < 0), (y**2 / 2, y <= 1), (y - 0.5, True)) assert integrate(g, (x, y, 1)) == Piecewise( (0.5, y < 0), (0.5 - y**2 / 2, y <= 1), (1 - y, True)) g = Piecewise((1 - x, Interval(0, 1).contains(x)), (1 + x, Interval(-1, 0).contains(x)), (0, True)) assert integrate(g, (x, -5, 1)) == 1 assert integrate(g, (x, -5, y)).subs(y, 1) == 1 assert integrate(g, (x, y, 1)).subs(y, -5) == 1 assert integrate(g, (x, 1, -5)) == -1 assert integrate(g, (x, 1, y)).subs(y, -5) == -1 assert integrate(g, (x, y, -5)).subs(y, 1) == -1 assert integrate(g, (x, -5, y)) == Piecewise( (-y**2 / 2 + y + 0.5, Interval(0, 1).contains(y)), (y**2 / 2 + y + 0.5, Interval(-1, 0).contains(y)), (0, y <= -1), (1, True)) assert integrate(g, (x, y, 1)) == Piecewise( (y**2 / 2 - y + 0.5, Interval(0, 1).contains(y)), (-y**2 / 2 - y + 0.5, Interval(-1, 0).contains(y)), (1, y <= -1), (0, True)) g = Piecewise((0, Or(x <= -1, x >= 1)), (1 - x, x > 0), (1 + x, True)) assert integrate(g, (x, -5, 1)) == 1 assert integrate(g, (x, -5, y)).subs(y, 1) == 1 assert integrate(g, (x, y, 1)).subs(y, -5) == 1 assert integrate(g, (x, 1, -5)) == -1 assert integrate(g, (x, 1, y)).subs(y, -5) == -1 assert integrate(g, (x, y, -5)).subs(y, 1) == -1 assert integrate(g, (x, -5, y)) == Piecewise((0, y <= -1), (1, y >= 1), (-y**2 / 2 + y + 0.5, y > 0), (y**2 / 2 + y + 0.5, True)) assert integrate(g, (x, y, 1)) == Piecewise((1, y <= -1), (0, y >= 1), (y**2 / 2 - y + 0.5, y > 0), (-y**2 / 2 - y + 0.5, True))
def test_latex_functions(): assert latex(exp(x)) == "e^{x}" assert latex(exp(1) + exp(2)) == "e + e^{2}" f = Function('f') assert latex(f(x)) == '\\operatorname{f}{\\left (x \\right )}' beta = Function('beta') assert latex(beta(x)) == r"\beta{\left (x \right )}" assert latex(sin(x)) == r"\sin{\left (x \right )}" assert latex(sin(x), fold_func_brackets=True) == r"\sin {x}" assert latex(sin(2*x**2), fold_func_brackets=True) == \ r"\sin {2 x^{2}}" assert latex(sin(x**2), fold_func_brackets=True) == \ r"\sin {x^{2}}" assert latex(asin(x)**2) == r"\operatorname{asin}^{2}{\left (x \right )}" assert latex(asin(x)**2, inv_trig_style="full") == \ r"\arcsin^{2}{\left (x \right )}" assert latex(asin(x)**2, inv_trig_style="power") == \ r"\sin^{-1}{\left (x \right )}^{2}" assert latex(asin(x**2), inv_trig_style="power", fold_func_brackets=True) == \ r"\sin^{-1} {x^{2}}" assert latex(factorial(k)) == r"k!" assert latex(factorial(-k)) == r"\left(- k\right)!" assert latex(subfactorial(k)) == r"!k" assert latex(subfactorial(-k)) == r"!\left(- k\right)" assert latex(factorial2(k)) == r"k!!" assert latex(factorial2(-k)) == r"\left(- k\right)!!" assert latex(binomial(2, k)) == r"{\binom{2}{k}}" assert latex( FallingFactorial(3, k)) == r"{\left(3\right)}_{\left(k\right)}" assert latex(RisingFactorial(3, k)) == r"{\left(3\right)}^{\left(k\right)}" assert latex(floor(x)) == r"\lfloor{x}\rfloor" assert latex(ceiling(x)) == r"\lceil{x}\rceil" assert latex(Min(x, 2, x**3)) == r"\min\left(2, x, x^{3}\right)" assert latex(Min(x, y)**2) == r"\min\left(x, y\right)^{2}" assert latex(Max(x, 2, x**3)) == r"\max\left(2, x, x^{3}\right)" assert latex(Max(x, y)**2) == r"\max\left(x, y\right)^{2}" assert latex(Abs(x)) == r"\left\lvert{x}\right\rvert" assert latex(re(x)) == r"\Re{x}" assert latex(re(x + y)) == r"\Re{x} + \Re{y}" assert latex(im(x)) == r"\Im{x}" assert latex(conjugate(x)) == r"\overline{x}" assert latex(gamma(x)) == r"\Gamma\left(x\right)" assert latex(Order(x)) == r"\mathcal{O}\left(x\right)" assert latex(lowergamma(x, y)) == r'\gamma\left(x, y\right)' assert latex(uppergamma(x, y)) == r'\Gamma\left(x, y\right)' assert latex(cot(x)) == r'\cot{\left (x \right )}' assert latex(coth(x)) == r'\coth{\left (x \right )}' assert latex(re(x)) == r'\Re{x}' assert latex(im(x)) == r'\Im{x}' assert latex(root(x, y)) == r'x^{\frac{1}{y}}' assert latex(arg(x)) == r'\arg{\left (x \right )}' assert latex(zeta(x)) == r'\zeta\left(x\right)' assert latex(zeta(x)) == r"\zeta\left(x\right)" assert latex(zeta(x)**2) == r"\zeta^{2}\left(x\right)" assert latex(zeta(x, y)) == r"\zeta\left(x, y\right)" assert latex(zeta(x, y)**2) == r"\zeta^{2}\left(x, y\right)" assert latex(dirichlet_eta(x)) == r"\eta\left(x\right)" assert latex(dirichlet_eta(x)**2) == r"\eta^{2}\left(x\right)" assert latex(polylog(x, y)) == r"\operatorname{Li}_{x}\left(y\right)" assert latex( polylog(x, y)**2) == r"\operatorname{Li}_{x}^{2}\left(y\right)" assert latex(lerchphi(x, y, n)) == r"\Phi\left(x, y, n\right)" assert latex(lerchphi(x, y, n)**2) == r"\Phi^{2}\left(x, y, n\right)" assert latex(elliptic_k(z)) == r"K\left(z\right)" assert latex(elliptic_k(z)**2) == r"K^{2}\left(z\right)" assert latex(elliptic_f(x, y)) == r"F\left(x\middle| y\right)" assert latex(elliptic_f(x, y)**2) == r"F^{2}\left(x\middle| y\right)" assert latex(elliptic_e(x, y)) == r"E\left(x\middle| y\right)" assert latex(elliptic_e(x, y)**2) == r"E^{2}\left(x\middle| y\right)" assert latex(elliptic_e(z)) == r"E\left(z\right)" assert latex(elliptic_e(z)**2) == r"E^{2}\left(z\right)" assert latex(elliptic_pi(x, y, z)) == r"\Pi\left(x; y\middle| z\right)" assert latex(elliptic_pi(x, y, z)**2) == \ r"\Pi^{2}\left(x; y\middle| z\right)" assert latex(elliptic_pi(x, y)) == r"\Pi\left(x\middle| y\right)" assert latex(elliptic_pi(x, y)**2) == r"\Pi^{2}\left(x\middle| y\right)" assert latex(Ei(x)) == r'\operatorname{Ei}{\left (x \right )}' assert latex(Ei(x)**2) == r'\operatorname{Ei}^{2}{\left (x \right )}' assert latex(expint(x, y)**2) == r'\operatorname{E}_{x}^{2}\left(y\right)' assert latex(Shi(x)**2) == r'\operatorname{Shi}^{2}{\left (x \right )}' assert latex(Si(x)**2) == r'\operatorname{Si}^{2}{\left (x \right )}' assert latex(Ci(x)**2) == r'\operatorname{Ci}^{2}{\left (x \right )}' assert latex(Chi(x)**2) == r'\operatorname{Chi}^{2}{\left (x \right )}' assert latex( jacobi(n, a, b, x)) == r'P_{n}^{\left(a,b\right)}\left(x\right)' assert latex(jacobi(n, a, b, x)**2) == r'\left(P_{n}^{\left(a,b\right)}\left(x\right)\right)^{2}' assert latex( gegenbauer(n, a, x)) == r'C_{n}^{\left(a\right)}\left(x\right)' assert latex(gegenbauer(n, a, x)**2) == r'\left(C_{n}^{\left(a\right)}\left(x\right)\right)^{2}' assert latex(chebyshevt(n, x)) == r'T_{n}\left(x\right)' assert latex( chebyshevt(n, x)**2) == r'\left(T_{n}\left(x\right)\right)^{2}' assert latex(chebyshevu(n, x)) == r'U_{n}\left(x\right)' assert latex( chebyshevu(n, x)**2) == r'\left(U_{n}\left(x\right)\right)^{2}' assert latex(legendre(n, x)) == r'P_{n}\left(x\right)' assert latex(legendre(n, x)**2) == r'\left(P_{n}\left(x\right)\right)^{2}' assert latex( assoc_legendre(n, a, x)) == r'P_{n}^{\left(a\right)}\left(x\right)' assert latex(assoc_legendre(n, a, x)**2) == r'\left(P_{n}^{\left(a\right)}\left(x\right)\right)^{2}' assert latex(laguerre(n, x)) == r'L_{n}\left(x\right)' assert latex(laguerre(n, x)**2) == r'\left(L_{n}\left(x\right)\right)^{2}' assert latex( assoc_laguerre(n, a, x)) == r'L_{n}^{\left(a\right)}\left(x\right)' assert latex(assoc_laguerre(n, a, x)**2) == r'\left(L_{n}^{\left(a\right)}\left(x\right)\right)^{2}' assert latex(hermite(n, x)) == r'H_{n}\left(x\right)' assert latex(hermite(n, x)**2) == r'\left(H_{n}\left(x\right)\right)^{2}' # Test latex printing of function names with "_" assert latex( polar_lift(0)) == r"\operatorname{polar\_lift}{\left (0 \right )}" assert latex(polar_lift( 0)**3) == r"\operatorname{polar\_lift}^{3}{\left (0 \right )}" assert latex(totient(n)) == r'\phi\left( n \right)'
class TestAllGood(object): # These latex strings should parse to the corresponding SymPy expression GOOD_PAIRS = [ ("0", 0), ("1", 1), ("-3.14", -3.14), ("5-3", _Add(5, -3)), ("(-7.13)(1.5)", _Mul(Rational('-7.13'), Rational('1.5'))), ("\\left(-7.13\\right)\\left(1.5\\right)", _Mul(Rational('-7.13'), Rational('1.5'))), ("x", x), ("2x", 2 * x), ("x^2", x**2), ("x^{3 + 1}", x**_Add(3, 1)), ("x^{\\left\\{3 + 1\\right\\}}", x**_Add(3, 1)), ("-3y + 2x", _Add(_Mul(2, x), Mul(-1, 3, y, evaluate=False))), ("-c", -c), ("a \\cdot b", a * b), ("a / b", a / b), ("a \\div b", a / b), ("a + b", a + b), ("a + b - a", Add(a, b, _Mul(-1, a), evaluate=False)), ("a^2 + b^2 = c^2", Eq(a**2 + b**2, c**2)), ("a^2 + b^2 != 2c^2", Ne(a**2 + b**2, 2 * c**2)), ("a\\mod b", Mod(a, b)), ("\\sin \\theta", sin(theta)), ("\\sin(\\theta)", sin(theta)), ("\\sin\\left(\\theta\\right)", sin(theta)), ("\\sin^{-1} a", asin(a)), ("\\sin a \\cos b", _Mul(sin(a), cos(b))), ("\\sin \\cos \\theta", sin(cos(theta))), ("\\sin(\\cos \\theta)", sin(cos(theta))), ("\\arcsin(a)", asin(a)), ("\\arccos(a)", acos(a)), ("\\arctan(a)", atan(a)), ("\\sinh(a)", sinh(a)), ("\\cosh(a)", cosh(a)), ("\\tanh(a)", tanh(a)), ("\\sinh^{-1}(a)", asinh(a)), ("\\cosh^{-1}(a)", acosh(a)), ("\\tanh^{-1}(a)", atanh(a)), ("\\arcsinh(a)", asinh(a)), ("\\arccosh(a)", acosh(a)), ("\\arctanh(a)", atanh(a)), ("\\arsinh(a)", asinh(a)), ("\\arcosh(a)", acosh(a)), ("\\artanh(a)", atanh(a)), ("\\operatorname{arcsinh}(a)", asinh(a)), ("\\operatorname{arccosh}(a)", acosh(a)), ("\\operatorname{arctanh}(a)", atanh(a)), ("\\operatorname{arsinh}(a)", asinh(a)), ("\\operatorname{arcosh}(a)", acosh(a)), ("\\operatorname{artanh}(a)", atanh(a)), ("\\operatorname{gcd}(a, b)", UnevaluatedExpr(gcd(a, b))), ("\\operatorname{lcm}(a, b)", UnevaluatedExpr(lcm(a, b))), ("\\operatorname{gcd}(a,b)", UnevaluatedExpr(gcd(a, b))), ("\\operatorname{lcm}(a,b)", UnevaluatedExpr(lcm(a, b))), ("\\operatorname{floor}(a)", floor(a)), ("\\operatorname{ceil}(b)", ceiling(b)), ("\\cos^2(x)", cos(x)**2), ("\\cos(x)^2", cos(x)**2), ("\\gcd(a, b)", UnevaluatedExpr(gcd(a, b))), ("\\lcm(a, b)", UnevaluatedExpr(lcm(a, b))), ("\\gcd(a,b)", UnevaluatedExpr(gcd(a, b))), ("\\lcm(a,b)", UnevaluatedExpr(lcm(a, b))), ("\\floor(a)", floor(a)), ("\\ceil(b)", ceiling(b)), ("\\max(a, b)", Max(a, b)), ("\\min(a, b)", Min(a, b)), ("\\frac{a}{b}", a / b), ("\\frac{a + b}{c}", _Mul(a + b, _Pow(c, -1))), ("\\frac{7}{3}", _Mul(7, _Pow(3, -1))), ("(\\csc x)(\\sec y)", csc(x) * sec(y)), ("\\lim_{x \\to 3} a", Limit(a, x, 3)), ("\\lim_{x \\rightarrow 3} a", Limit(a, x, 3)), ("\\lim_{x \\Rightarrow 3} a", Limit(a, x, 3)), ("\\lim_{x \\longrightarrow 3} a", Limit(a, x, 3)), ("\\lim_{x \\Longrightarrow 3} a", Limit(a, x, 3)), ("\\lim_{x \\to 3^{+}} a", Limit(a, x, 3, dir='+')), ("\\lim_{x \\to 3^{-}} a", Limit(a, x, 3, dir='-')), ("\\infty", oo), ("\\infty\\%", oo), ("\\$\\infty", oo), ("-\\infty", -oo), ("-\\infty\\%", -oo), ("-\\$\\infty", -oo), ("\\lim_{x \\to \\infty} \\frac{1}{x}", Limit(_Mul(1, _Pow(x, -1)), x, oo)), ("\\frac{d}{dx} x", Derivative(x, x)), ("\\frac{d}{dt} x", Derivative(x, t)), # ("f(x)", f(x)), # ("f(x, y)", f(x, y)), # ("f(x, y, z)", f(x, y, z)), # ("\\frac{d f(x)}{dx}", Derivative(f(x), x)), # ("\\frac{d\\theta(x)}{dx}", Derivative(theta(x), x)), ("|x|", _Abs(x)), ("\\left|x\\right|", _Abs(x)), ("||x||", _Abs(Abs(x))), ("|x||y|", _Abs(x) * _Abs(y)), ("||x||y||", _Abs(_Abs(x) * _Abs(y))), ("\\lfloor x\\rfloor", floor(x)), ("\\lceil y\\rceil", ceiling(y)), ("\\pi^{|xy|}", pi**_Abs(x * y)), ("\\frac{\\pi}{3}", _Mul(pi, _Pow(3, -1))), ("\\sin{\\frac{\\pi}{2}}", sin(_Mul(pi, _Pow(2, -1)), evaluate=False)), ("a+bI", a + I * b), ("e^{I\\pi}", -1), ("\\int x dx", Integral(x, x)), ("\\int x d\\theta", Integral(x, theta)), ("\\int (x^2 - y)dx", Integral(x**2 - y, x)), ("\\int x + a dx", Integral(_Add(x, a), x)), ("\\int da", Integral(1, a)), ("\\int_0^7 dx", Integral(1, (x, 0, 7))), ("\\int_a^b x dx", Integral(x, (x, a, b))), ("\\int^b_a x dx", Integral(x, (x, a, b))), ("\\int_{a}^b x dx", Integral(x, (x, a, b))), ("\\int^{b}_a x dx", Integral(x, (x, a, b))), ("\\int_{a}^{b} x dx", Integral(x, (x, a, b))), ("\\int_{ }^{}x dx", Integral(x, x)), ("\\int^{ }_{ }x dx", Integral(x, x)), ("\\int^{b}_{a} x dx", Integral(x, (x, a, b))), # ("\\int_{f(a)}^{f(b)} f(z) dz", Integral(f(z), (z, f(a), f(b)))), ("\\int (x+a)", Integral(_Add(x, a), x)), ("\\int a + b + c dx", Integral(Add(a, b, c, evaluate=False), x)), ("\\int \\frac{dz}{z}", Integral(Pow(z, -1), z)), ("\\int \\frac{3 dz}{z}", Integral(3 * Pow(z, -1), z)), ("\\int \\frac{1}{x} dx", Integral(Pow(x, -1), x)), ("\\int \\frac{1}{a} + \\frac{1}{b} dx", Integral(_Add(_Pow(a, -1), Pow(b, -1)), x)), ("\\int \\frac{3 \\cdot d\\theta}{\\theta}", Integral(3 * _Pow(theta, -1), theta)), ("\\int \\frac{1}{x} + 1 dx", Integral(_Add(_Pow(x, -1), 1), x)), ("x_0", Symbol('x_0', real=True)), ("x_{1}", Symbol('x_1', real=True)), ("x_a", Symbol('x_a', real=True)), ("x_{b}", Symbol('x_b', real=True)), ("h_\\theta", Symbol('h_{\\theta}', real=True)), ("h_\\theta ", Symbol('h_{\\theta}', real=True)), ("h_{\\theta}", Symbol('h_{\\theta}', real=True)), # ("h_{\\theta}(x_0, x_1)", Symbol('h_{theta}', real=True)(Symbol('x_{0}', real=True), Symbol('x_{1}', real=True))), ("x!", _factorial(x)), ("100!", _factorial(100)), ("\\theta!", _factorial(theta)), ("(x + 1)!", _factorial(_Add(x, 1))), ("\\left(x + 1\\right)!", _factorial(_Add(x, 1))), ("(x!)!", _factorial(_factorial(x))), ("x!!!", _factorial(_factorial(_factorial(x)))), ("5!7!", _Mul(_factorial(5), _factorial(7))), ("\\sqrt{x}", sqrt(x)), ("\\sqrt{x + b}", sqrt(_Add(x, b))), ("\\sqrt[3]{\\sin x}", root(sin(x), 3)), ("\\sqrt[y]{\\sin x}", root(sin(x), y)), ("\\sqrt[\\theta]{\\sin x}", root(sin(x), theta)), ("x < y", StrictLessThan(x, y)), ("x \\leq y", LessThan(x, y)), ("x > y", StrictGreaterThan(x, y)), ("x \\geq y", GreaterThan(x, y)), ("\\sum_{k = 1}^{3} c", Sum(c, (k, 1, 3))), ("\\sum_{k = 1}^3 c", Sum(c, (k, 1, 3))), ("\\sum^{3}_{k = 1} c", Sum(c, (k, 1, 3))), ("\\sum^3_{k = 1} c", Sum(c, (k, 1, 3))), ("\\sum_{k = 1}^{10} k^2", Sum(k**2, (k, 1, 10))), ("\\sum_{n = 0}^{\\infty} \\frac{1}{n!}", Sum(_Pow(_factorial(n), -1), (n, 0, oo))), ("\\prod_{a = b}^{c} x", Product(x, (a, b, c))), ("\\prod_{a = b}^c x", Product(x, (a, b, c))), ("\\prod^{c}_{a = b} x", Product(x, (a, b, c))), ("\\prod^c_{a = b} x", Product(x, (a, b, c))), ("\\ln x", _log(x, E)), ("\\ln xy", _log(x * y, E)), ("\\log x", _log(x, 10)), ("\\log xy", _log(x * y, 10)), # ("\\log_2 x", _log(x, 2)), ("\\log_{2} x", _log(x, 2)), # ("\\log_a x", _log(x, a)), ("\\log_{a} x", _log(x, a)), ("\\log_{11} x", _log(x, 11)), ("\\log_{a^2} x", _log(x, _Pow(a, 2))), ("[x]", x), ("[a + b]", _Add(a, b)), ("\\frac{d}{dx} [ \\tan x ]", Derivative(tan(x), x)), ("2\\overline{x}", 2 * Symbol('xbar', real=True)), ("2\\overline{x}_n", 2 * Symbol('xbar_n', real=True)), ("\\frac{x}{\\overline{x}_n}", x / Symbol('xbar_n', real=True)), ("\\frac{\\sin(x)}{\\overline{x}_n}", sin(Symbol('x', real=True)) / Symbol('xbar_n', real=True)), ("2\\bar{x}", 2 * Symbol('xbar', real=True)), ("2\\bar{x}_n", 2 * Symbol('xbar_n', real=True)), ("\\sin\\left(\\theta\\right) \\cdot4", sin(theta) * 4), ("\\ln\\left(\\theta\\right)", _log(theta, E)), ("\\ln\\left(x-\\theta\\right)", _log(x - theta, E)), ("\\ln\\left(\\left(x-\\theta\\right)\\right)", _log(x - theta, E)), ("\\ln\\left(\\left[x-\\theta\\right]\\right)", _log(x - theta, E)), ("\\ln\\left(\\left\\{x-\\theta\\right\\}\\right)", _log(x - theta, E)), ("\\ln\\left(\\left|x-\\theta\\right|\\right)", _log(_Abs(x - theta), E)), ("\\frac{1}{2}xy(x+y)", Mul(_Pow(2, -1), x, y, (x + y), evaluate=False)), ("\\frac{1}{2}\\theta(x+y)", Mul(_Pow(2, -1), theta, (x + y), evaluate=False)), ("1-f(x)", 1 - f * x), ("\\begin{matrix}1&2\\\\3&4\\end{matrix}", Matrix([[1, 2], [3, 4]])), ("\\begin{matrix}x&x^2\\\\\\sqrt{x}&x\\end{matrix}", Matrix([[x, x**2], [_Pow(x, S.Half), x]])), ("\\begin{matrix}\\sqrt{x}\\\\\\sin(\\theta)\\end{matrix}", Matrix([_Pow(x, S.Half), sin(theta)])), ("\\begin{pmatrix}1&2\\\\3&4\\end{pmatrix}", Matrix([[1, 2], [3, 4]])), ("\\begin{bmatrix}1&2\\\\3&4\\end{bmatrix}", Matrix([[1, 2], [3, 4]])), # scientific notation ("2.5\\times 10^2", 250), ("1,500\\times 10^{-1}", 150), # e notation ("2.5E2", 250), ("1,500E-1", 150), # multiplication without cmd ("2x2y", Mul(2, x, 2, y, evaluate=False)), ("2x2", Mul(2, x, 2, evaluate=False)), ("x2", x * 2), # lin alg processing ("\\theta\\begin{matrix}1&2\\\\3&4\\end{matrix}", MatMul(theta, Matrix([[1, 2], [3, 4]]), evaluate=False)), ("\\theta\\begin{matrix}1\\\\3\\end{matrix} - \\begin{matrix}-1\\\\2\\end{matrix}", MatAdd(MatMul(theta, Matrix([[1], [3]]), evaluate=False), MatMul(-1, Matrix([[-1], [2]]), evaluate=False), evaluate=False)), ("\\theta\\begin{matrix}1&0\\\\0&1\\end{matrix}*\\begin{matrix}3\\\\-2\\end{matrix}", MatMul(theta, Matrix([[1, 0], [0, 1]]), Matrix([3, -2]), evaluate=False)), ("\\frac{1}{9}\\theta\\begin{matrix}1&2\\\\3&4\\end{matrix}", MatMul(Pow(9, -1, evaluate=False), theta, Matrix([[1, 2], [3, 4]]), evaluate=False)), ("\\begin{pmatrix}1\\\\2\\\\3\\end{pmatrix},\\begin{pmatrix}4\\\\3\\\\1\\end{pmatrix}", [Matrix([1, 2, 3]), Matrix([4, 3, 1])]), ("\\begin{pmatrix}1\\\\2\\\\3\\end{pmatrix};\\begin{pmatrix}4\\\\3\\\\1\\end{pmatrix}", [Matrix([1, 2, 3]), Matrix([4, 3, 1])]), ("\\left\\{\\begin{pmatrix}1\\\\2\\\\3\\end{pmatrix},\\begin{pmatrix}4\\\\3\\\\1\\end{pmatrix}\\right\\}", [Matrix([1, 2, 3]), Matrix([4, 3, 1])]), ("\\left\\{\\begin{pmatrix}1\\\\2\\\\3\\end{pmatrix},\\begin{pmatrix}4\\\\3\\\\1\\end{pmatrix},\\begin{pmatrix}1\\\\1\\\\1\\end{pmatrix}\\right\\}", [Matrix([1, 2, 3]), Matrix([4, 3, 1]), Matrix([1, 1, 1])]), ("\\left\\{\\begin{pmatrix}1\\\\2\\\\3\\end{pmatrix}\\right\\}", Matrix([1, 2, 3])), ("\\left{\\begin{pmatrix}1\\\\2\\\\3\\end{pmatrix}\\right}", Matrix([1, 2, 3])), ("{\\begin{pmatrix}1\\\\2\\\\3\\end{pmatrix}}", Matrix([1, 2, 3])), # us dollars ("\\$1,000.00", 1000), ("\\$543.21", 543.21), ("\\$0.009", 0.009), # percentages ("100\\%", 1), ("1.5\\%", 0.015), ("0.05\\%", 0.0005), # empty set ("\\emptyset", S.EmptySet) ] def test_good_pair(self, s, eq): assert_equal(s, eq)