def test_posify(): from sympy import posify, Symbol, log from sympy.abc import x assert str(posify(x + Symbol("p", positive=True) + Symbol("n", negative=True))) == "(_x + n + p, {_x: x})" # log(1/x).expand() should be log(1/x) but it comes back as -log(x) # when it is corrected, posify will allow the change to be made: eq, rep = posify(1 / x) assert log(eq).expand().subs(rep) == -log(x) assert str(posify([x, 1 + x])) == "([_x, _x + 1], {_x: x})"
def test_posify(): from sympy import posify, Symbol, log from sympy.abc import x assert str( posify(x + Symbol('p', positive=True) + Symbol('n', negative=True))) == '(n + p + _x, {_x: x})' # log(1/x).expand() should be log(1/x) but it comes back as -log(x) # when it is corrected, posify will allow the change to be made: eq, rep = posify(1 / x) assert log(eq).expand().subs(rep) == -log(x) assert str(posify([x, 1 + x])) == '([_x, 1 + _x], {_x: x})'
def symbolic_equality(test_expr, target_expr): """Test if two expressions are symbolically equivalent. Use the sympy 'simplify' function to test if the difference between two expressions is symbolically zero. This is known to be impossible in the general case, but should work well enough for most cases likely to be used on Isaac. A return value of 'False' thus does not necessarily mean the two expressions are not equal (sympy assumes complex number variables; so some simlifications may not occur). Returns True if sympy can determine that the two expressions are equal, and returns False if this cannot be determined OR if the two expressions are definitely not equal. - 'test_expr' should be the untrusted sympy expression to check. - 'target_expr' should be the trusted sympy expression to match against. """ print "[SYMBOLIC TEST]" # Here we make the assumption that all variables are real and positive to # aid the simplification process. Since we do this for numeric checking anyway, # it doesn't seem like much of an issue. Removing 'sympy.posify()' below will # stop this. try: if sympy.simplify(sympy.posify(test_expr - target_expr)[0]) == 0: print "Symbolic match." print "INFO: Adding known pair (%s, %s)" % (target_expr, test_expr) KNOWN_PAIRS[(target_expr, test_expr)] = "symbolic" return True else: return False except NotImplementedError, e: print "%s: %s - Can't check symbolic equality!" % (type(e).__name__, e.message.capitalize()) return False
def test_posify(): from sympy.abc import x assert str(posify( x + Symbol('p', positive=True) + Symbol('n', negative=True))) == '(_x + n + p, {_x: x})' eq, rep = posify(1/x) assert log(eq).expand().subs(rep) == -log(x) assert str(posify([x, 1 + x])) == '([_x, _x + 1], {_x: x})' x = symbols('x') p = symbols('p', positive=True) n = symbols('n', negative=True) orig = [x, n, p] modified, reps = posify(orig) assert str(modified) == '[_x, n, p]' assert [w.subs(reps) for w in modified] == orig assert str(Integral(posify(1/x + y)[0], (y, 1, 3)).expand()) == \ 'Integral(1/_x, (y, 1, 3)) + Integral(_y, (y, 1, 3))' assert str(Sum(posify(1/x**n)[0], (n,1,3)).expand()) == \ 'Sum(_x**(-n), (n, 1, 3))' # issue 16438 k = Symbol('k', finite=True) eq, rep = posify(k) assert eq.assumptions0 == {'positive': True, 'zero': False, 'imaginary': False, 'nonpositive': False, 'commutative': True, 'hermitian': True, 'real': True, 'nonzero': True, 'nonnegative': True, 'negative': False, 'complex': True, 'finite': True, 'infinite': False}
def test_posify(): from sympy.abc import x assert str(posify( x + Symbol('p', positive=True) + Symbol('n', negative=True))) == '(_x + n + p, {_x: x})' eq, rep = posify(1/x) assert log(eq).expand().subs(rep) == -log(x) assert str(posify([x, 1 + x])) == '([_x, _x + 1], {_x: x})' x = symbols('x') p = symbols('p', positive=True) n = symbols('n', negative=True) orig = [x, n, p] modified, reps = posify(orig) assert str(modified) == '[_x, n, p]' assert [w.subs(reps) for w in modified] == orig assert str(Integral(posify(1/x + y)[0], (y, 1, 3)).expand()) == \ 'Integral(1/_x, (y, 1, 3)) + Integral(_y, (y, 1, 3))' assert str(Sum(posify(1/x**n)[0], (n,1,3)).expand()) == \ 'Sum(_x**(-n), (n, 1, 3))' # issue 16438 k = Symbol('k', finite=True) eq, rep = posify(k) assert eq.assumptions0 == {'positive': True, 'zero': False, 'imaginary': False, 'nonpositive': False, 'commutative': True, 'hermitian': True, 'real': True, 'nonzero': True, 'nonnegative': True, 'negative': False, 'complex': True, 'finite': True, 'infinite': False, 'extended_real':True, 'extended_negative': False, 'extended_nonnegative': True, 'extended_nonpositive': False, 'extended_nonzero': True, 'extended_positive': True}
def test_posify(): from sympy.abc import x assert str(posify(x + Symbol("p", positive=True) + Symbol("n", negative=True))) == "(_x + n + p, {_x: x})" # log(1/x).expand() should be log(1/x) but it comes back as -log(x) # when it is corrected, posify will allow the change to be made. The # force=True option can do so as well when it is implemented. eq, rep = posify(1 / x) assert log(eq).expand().subs(rep) == -log(x) assert str(posify([x, 1 + x])) == "([_x, _x + 1], {_x: x})" x = symbols("x") p = symbols("p", positive=True) n = symbols("n", negative=True) orig = [x, n, p] modified, reps = posify(orig) assert str(modified) == "[_x, n, p]" assert [w.subs(reps) for w in modified] == orig
def test_posify(): from sympy.abc import x assert str( posify(x + Symbol('p', positive=True) + Symbol('n', negative=True))) == '(_x + n + p, {_x: x})' # log(1/x).expand() should be log(1/x) but it comes back as -log(x) # when it is corrected, posify will allow the change to be made. The # force=True option can do so as well when it is implemented. eq, rep = posify(1 / x) assert log(eq).expand().subs(rep) == -log(x) assert str(posify([x, 1 + x])) == '([_x, _x + 1], {_x: x})' x = symbols('x') p = symbols('p', positive=True) n = symbols('n', negative=True) orig = [x, n, p] modified, reps = posify(orig) assert str(modified) == '[_x, n, p]' assert [w.subs(reps) for w in modified] == orig
def test_posify(): from sympy.abc import x assert str(posify( x + Symbol('p', positive=True) + Symbol('n', negative=True))) == '(_x + n + p, {_x: x})' # log(1/x).expand() should be log(1/x) but it comes back as -log(x) # when it is corrected, posify will allow the change to be made. The # force=True option can do so as well when it is implemented. eq, rep = posify(1/x) assert log(eq).expand().subs(rep) == -log(x) assert str(posify([x, 1 + x])) == '([_x, _x + 1], {_x: x})' x = symbols('x') p = symbols('p', positive=True) n = symbols('n', negative=True) orig = [x, n, p] modified, reps = posify(orig) assert str(modified) == '[_x, n, p]' assert [w.subs(reps) for w in modified] == orig assert str(Integral(posify(1/x + y)[0], (y, 1, 3)).expand()) == \ 'Integral(1/_x, (y, 1, 3)) + Integral(_y, (y, 1, 3))' assert str(Sum(posify(1/x**n)[0], (n,1,3)).expand()) == \ 'Sum(_x**(-n), (n, 1, 3))'
def test_posify(): from sympy.abc import x assert (str( posify(x + Symbol("p", positive=True) + Symbol("n", negative=True))) == "(_x + n + p, {_x: x})") eq, rep = posify(1 / x) assert log(eq).expand().subs(rep) == -log(x) assert str(posify([x, 1 + x])) == "([_x, _x + 1], {_x: x})" x = symbols("x") p = symbols("p", positive=True) n = symbols("n", negative=True) orig = [x, n, p] modified, reps = posify(orig) assert str(modified) == "[_x, n, p]" assert [w.subs(reps) for w in modified] == orig assert (str(Integral(posify(1 / x + y)[0], ( y, 1, 3)).expand()) == "Integral(1/_x, (y, 1, 3)) + Integral(_y, (y, 1, 3))") assert (str(Sum(posify(1 / x**n)[0], (n, 1, 3)).expand()) == "Sum(_x**(-n), (n, 1, 3))") # issue 16438 k = Symbol("k", finite=True) eq, rep = posify(k) assert eq.assumptions0 == { "positive": True, "zero": False, "imaginary": False, "nonpositive": False, "commutative": True, "hermitian": True, "real": True, "nonzero": True, "nonnegative": True, "negative": False, "complex": True, "finite": True, "infinite": False, "extended_real": True, "extended_negative": False, "extended_nonnegative": True, "extended_nonpositive": False, "extended_nonzero": True, "extended_positive": True, }
def symbolic_equality(test_expr, target_expr): """Test if two expressions are symbolically equivalent. Use the sympy 'simplify' function to test if the difference between two expressions is symbolically zero. This is known to be impossible in the general case, but should work well enough for most cases likely to be used on Isaac. A return value of 'False' thus does not necessarily mean the two expressions are not equal (sympy assumes complex number variables; so some simlifications may not occur). Returns True if sympy can determine that the two expressions are equal, and returns False if this cannot be determined OR if the two expressions are definitely not equal. - 'test_expr' should be the untrusted sympy expression to check. - 'target_expr' should be the trusted sympy expression to match against. """ print("[SYMBOLIC TEST]") # Here we make the assumption that all variables are real and positive to # aid the simplification process. Since we do this for numeric checking anyway, # it doesn't seem like much of an issue. Removing 'sympy.posify()' below will # stop this. try: if sympy.simplify(sympy.posify(test_expr - target_expr)[0]) == 0: print("Symbolic match.") print("INFO: Adding known pair ({0}, {1})".format( target_expr, test_expr)) KNOWN_PAIRS[(target_expr, test_expr)] = EqualityType.SYMBOLIC return True else: return False except NotImplementedError as e: print("{0}: {1} - Can't check symbolic equality!".format( type(e).__name__, str(e).capitalize())) return False
def test_posify(): from sympy.abc import x assert str(posify(x + Symbol("p", positive=True) + Symbol("n", negative=True))) == "(_x + n + p, {_x: x})" eq, rep = posify(1 / x) assert log(eq).expand().subs(rep) == -log(x) assert str(posify([x, 1 + x])) == "([_x, _x + 1], {_x: x})" x = symbols("x") p = symbols("p", positive=True) n = symbols("n", negative=True) orig = [x, n, p] modified, reps = posify(orig) assert str(modified) == "[_x, n, p]" assert [w.subs(reps) for w in modified] == orig assert ( str(Integral(posify(1 / x + y)[0], (y, 1, 3)).expand()) == "Integral(1/_x, (y, 1, 3)) + Integral(_y, (y, 1, 3))" ) assert str(Sum(posify(1 / x ** n)[0], (n, 1, 3)).expand()) == "Sum(_x**(-n), (n, 1, 3))"
def test_posify(): from sympy.abc import x assert str( posify(x + Symbol('p', positive=True) + Symbol('n', negative=True))) == '(_x + n + p, {_x: x})' eq, rep = posify(1 / x) assert log(eq).expand().subs(rep) == -log(x) assert str(posify([x, 1 + x])) == '([_x, _x + 1], {_x: x})' x = symbols('x') p = symbols('p', positive=True) n = symbols('n', negative=True) orig = [x, n, p] modified, reps = posify(orig) assert str(modified) == '[_x, n, p]' assert [w.subs(reps) for w in modified] == orig assert str(Integral(posify(1/x + y)[0], (y, 1, 3)).expand()) == \ 'Integral(1/_x, (y, 1, 3)) + Integral(_y, (y, 1, 3))' assert str(Sum(posify(1/x**n)[0], (n,1,3)).expand()) == \ 'Sum(_x**(-n), (n, 1, 3))'
def test_posify(): from sympy.abc import x assert str(posify( x + Symbol('p', positive=True) + Symbol('n', negative=True))) == '(_x + n + p, {_x: x})' eq, rep = posify(1/x) assert log(eq).expand().subs(rep) == -log(x) assert str(posify([x, 1 + x])) == '([_x, _x + 1], {_x: x})' x = symbols('x') p = symbols('p', positive=True) n = symbols('n', negative=True) orig = [x, n, p] modified, reps = posify(orig) assert str(modified) == '[_x, n, p]' assert [w.subs(reps) for w in modified] == orig assert str(Integral(posify(1/x + y)[0], (y, 1, 3)).expand()) == \ 'Integral(1/_x, (y, 1, 3)) + Integral(_y, (y, 1, 3))' assert str(Sum(posify(1/x**n)[0], (n,1,3)).expand()) == \ 'Sum(_x**(-n), (n, 1, 3))'
def test_random(): from sympy import posify assert posify(x)[0]._random() is not None
def test_random(): from sympy import posify, lucas assert posify(x)[0]._random() is not None assert lucas(n)._random(2, -2, 0, -1, 1) is None
def test_posify(): assert posify(A)[0].is_commutative == False for q in (A*B/A, (A*B/A)**2, (A*B)**2, A*B - B*A): p = posify(q) assert p[0].subs(p[1]) == q
def test_random(): from sympy import posify assert posify(x)[0]._random() is not None assert S('-pi*Abs(1/log(n!)) + 1')._random(2, -2, 0, -1, 0) is None
def __new__(cls, unit_expr=None, cgs_value=None, dimensions=None, **assumptions): """ Build a new unit. May be an atomic unit (like a gram) or a combination of other units (like g / cm**3). Either way, you can make the unit symbol anything. Parameters ---------- unit_expr : string or sympy.core.expr.Expr The symbolic expression. Symbol("g") for gram. cgs_value : float This unit's value in cgs. 1.0 for gram. dimensions : sympy.core.expr.Expr A sympy expression representing the dimensionality of this unit. Should just be a sympy.core.mul.Mul object of mass, length, time, and temperature objects to various powers. mass for gram. """ # Check for no args if not unit_expr: unit_expr = sympify(1) # if we have a string, parse into an expression if isinstance(unit_expr, str): unit_expr = parse_expr(unit_expr) if not isinstance(unit_expr, Expr): raise Exception("Unit representation must be a string or sympy Expr. %s is a %s" % (unit_expr, type(unit_expr))) # done with argument checking... # sympify, posify, and nsimplify the expr unit_expr = sympify(unit_expr) p, r = posify(unit_expr) unit_expr = p.subs(r) unit_expr = nsimplify(unit_expr) # see if the unit is atomic. is_atomic = False if isinstance(unit_expr, Symbol): is_atomic = True # did they supply cgs_value and dimensions? if cgs_value and not dimensions or dimensions and not cgs_value: raise Exception("If you provide cgs_vale or dimensions, you must provide both! cgs_value is %s, dimensions is %s." % (cgs_value, dimensions)) if cgs_value and dimensions: # check that cgs_vale is a float or can be converted to one try: cgs_value = float(cgs_value) except ValueError: raise ValueError("Please provide a float for the cgs_value kwarg. I got a '%s'." % cgs_value) # check that dimensions is valid dimensions = verify_dimensions(sympify(dimensions)) # save the values this_cgs_value, this_dimensions = cgs_value, dimensions else: # lookup the unit symbols this_cgs_value, this_dimensions = \ get_unit_data_from_expr(unit_expr) # cool trick to get dimensions powers as Rationals this_dimensions = nsimplify(this_dimensions) # init obj with superclass construct obj = Expr.__new__(cls, **assumptions) # attach attributes to obj obj.expr = unit_expr obj.is_atomic = is_atomic obj.cgs_value = this_cgs_value obj.dimensions = this_dimensions # return `obj` so __init__ can handle it. return obj