def test_ccode_sign(): expr1, ref1 = sign(x) * y, 'y*(((x) > 0) - ((x) < 0))' expr2, ref2 = sign(cos(x)), '(((cos(x)) > 0) - ((cos(x)) < 0))' expr3, ref3 = sign(2 * x + x**2) * x + x**2, 'pow(x, 2) + x*(((pow(x, 2) + 2*x) > 0) - ((pow(x, 2) + 2*x) < 0))' assert ccode(expr1) == ref1 assert ccode(expr1, 'z') == 'z = %s;' % ref1 assert ccode(expr2) == ref2 assert ccode(expr3) == ref3
def test_sign(): expr = sign(x) * y assert rust_code(expr) == "y*x.signum()" assert rust_code(expr, assign_to='r') == "r = y*x.signum();" expr = sign(x + y) + 42 assert rust_code(expr) == "(x + y).signum() + 42" assert rust_code(expr, assign_to='r') == "r = (x + y).signum() + 42;" expr = sign(cos(x)) assert rust_code(expr) == "x.cos().signum()"
def test_ccode_sign(): expr = sign(x) * y assert ccode(expr) == 'y*(((x) > 0) - ((x) < 0))' assert ccode(expr, 'z') == 'z = y*(((x) > 0) - ((x) < 0));' assert ccode(sign(2 * x + x**2) * x + x**2) == \ 'pow(x, 2) + x*(((pow(x, 2) + 2*x) > 0) - ((pow(x, 2) + 2*x) < 0))' expr = sign(cos(x)) assert ccode(expr) == '(((cos(x)) > 0) - ((cos(x)) < 0))'
def test_ccode_sign(): expr1, ref1 = sign(x) * y, "y*(((x) > 0) - ((x) < 0))" expr2, ref2 = sign(cos(x)), "(((cos(x)) > 0) - ((cos(x)) < 0))" expr3, ref3 = ( sign(2 * x + x ** 2) * x + x ** 2, "pow(x, 2) + x*(((pow(x, 2) + 2*x) > 0) - ((pow(x, 2) + 2*x) < 0))", ) assert ccode(expr1) == ref1 assert ccode(expr1, "z") == "z = %s;" % ref1 assert ccode(expr2) == ref2 assert ccode(expr3) == ref3
def test_rcode_sgn(): expr = sign(x) * y assert rcode(expr) == "y*sign(x)" p = rcode(expr, "z") assert p == "z = y*sign(x);" p = rcode(sign(2 * x + x**2) * x + x**2) assert p == "x^2 + x*sign(x^2 + 2*x)" expr = sign(cos(x)) p = rcode(expr) assert p == "sign(cos(x))"
def test_rcode_sgn(): expr = sign(x) * y assert rcode(expr) == 'y*sign(x)' p = rcode(expr, 'z') assert p == 'z = y*sign(x);' p = rcode(sign(2 * x + x**2) * x + x**2) assert p == "x^2 + x*sign(x^2 + 2*x)" expr = sign(cos(x)) p = rcode(expr) assert p == 'sign(cos(x))'
def test_bounded(): x, y = symbols('xy') assert ask(x, Q.bounded) == False assert ask(x, Q.bounded, Assume(x, Q.bounded)) == True assert ask(x, Q.bounded, Assume(y, Q.bounded)) == False assert ask(x, Q.bounded, Assume(x, Q.complex)) == False assert ask(x+1, Q.bounded) == False assert ask(x+1, Q.bounded, Assume(x, Q.bounded)) == True assert ask(x+y, Q.bounded) == None assert ask(x+y, Q.bounded, Assume(x, Q.bounded)) == False assert ask(x+1, Q.bounded, Assume(x, Q.bounded) & \ Assume(y, Q.bounded)) == True assert ask(2*x, Q.bounded) == False assert ask(2*x, Q.bounded, Assume(x, Q.bounded)) == True assert ask(x*y, Q.bounded) == None assert ask(x*y, Q.bounded, Assume(x, Q.bounded)) == False assert ask(x*y, Q.bounded, Assume(x, Q.bounded) & \ Assume(y, Q.bounded)) == True assert ask(x**2, Q.bounded) == False assert ask(2**x, Q.bounded) == False assert ask(2**x, Q.bounded, Assume(x, Q.bounded)) == True assert ask(x**x, Q.bounded) == False assert ask(Rational(1,2) ** x, Q.bounded) == True assert ask(x ** Rational(1,2), Q.bounded) == False # sign function assert ask(sign(x), Q.bounded) == True assert ask(sign(x), Q.bounded, Assume(x, Q.bounded, False)) == True # exponential functions assert ask(log(x), Q.bounded) == False assert ask(log(x), Q.bounded, Assume(x, Q.bounded)) == True assert ask(exp(x), Q.bounded) == False assert ask(exp(x), Q.bounded, Assume(x, Q.bounded)) == True assert ask(exp(2), Q.bounded) == True # trigonometric functions assert ask(sin(x), Q.bounded) == True assert ask(sin(x), Q.bounded, Assume(x, Q.bounded, False)) == True assert ask(cos(x), Q.bounded) == True assert ask(cos(x), Q.bounded, Assume(x, Q.bounded, False)) == True assert ask(2*sin(x), Q.bounded) == True assert ask(sin(x)**2, Q.bounded) == True assert ask(cos(x)**2, Q.bounded) == True assert ask(cos(x) + sin(x), Q.bounded) == True
def test_bounded(): x, y = symbols('x,y') assert ask(Q.bounded(x)) == False assert ask(Q.bounded(x), Q.bounded(x)) == True assert ask(Q.bounded(x), Q.bounded(y)) == False assert ask(Q.bounded(x), Q.complex(x)) == False assert ask(Q.bounded(x + 1)) == False assert ask(Q.bounded(x + 1), Q.bounded(x)) == True assert ask(Q.bounded(x + y)) == None assert ask(Q.bounded(x + y), Q.bounded(x)) == False assert ask(Q.bounded(x + 1), Q.bounded(x) & Q.bounded(y)) == True assert ask(Q.bounded(2 * x)) == False assert ask(Q.bounded(2 * x), Q.bounded(x)) == True assert ask(Q.bounded(x * y)) == None assert ask(Q.bounded(x * y), Q.bounded(x)) == False assert ask(Q.bounded(x * y), Q.bounded(x) & Q.bounded(y)) == True assert ask(Q.bounded(x**2)) == False assert ask(Q.bounded(2**x)) == False assert ask(Q.bounded(2**x), Q.bounded(x)) == True assert ask(Q.bounded(x**x)) == False assert ask(Q.bounded(Rational(1, 2)**x)) == None assert ask(Q.bounded(Rational(1, 2)**x), Q.positive(x)) == True assert ask(Q.bounded(Rational(1, 2)**x), Q.negative(x)) == False assert ask(Q.bounded(sqrt(x))) == False # sign function assert ask(Q.bounded(sign(x))) == True assert ask(Q.bounded(sign(x)), ~Q.bounded(x)) == True # exponential functions assert ask(Q.bounded(log(x))) == False assert ask(Q.bounded(log(x)), Q.bounded(x)) == True assert ask(Q.bounded(exp(x))) == False assert ask(Q.bounded(exp(x)), Q.bounded(x)) == True assert ask(Q.bounded(exp(2))) == True # trigonometric functions assert ask(Q.bounded(sin(x))) == True assert ask(Q.bounded(sin(x)), ~Q.bounded(x)) == True assert ask(Q.bounded(cos(x))) == True assert ask(Q.bounded(cos(x)), ~Q.bounded(x)) == True assert ask(Q.bounded(2 * sin(x))) == True assert ask(Q.bounded(sin(x)**2)) == True assert ask(Q.bounded(cos(x)**2)) == True assert ask(Q.bounded(cos(x) + sin(x))) == True
def test_bounded(): x, y = symbols('x,y') assert ask(Q.bounded(x)) == False assert ask(Q.bounded(x), Q.bounded(x)) == True assert ask(Q.bounded(x), Q.bounded(y)) == False assert ask(Q.bounded(x), Q.complex(x)) == False assert ask(Q.bounded(x+1)) == False assert ask(Q.bounded(x+1), Q.bounded(x)) == True assert ask(Q.bounded(x+y)) == None assert ask(Q.bounded(x+y), Q.bounded(x)) == False assert ask(Q.bounded(x+1), Q.bounded(x) & Q.bounded(y)) == True assert ask(Q.bounded(2*x)) == False assert ask(Q.bounded(2*x), Q.bounded(x)) == True assert ask(Q.bounded(x*y)) == None assert ask(Q.bounded(x*y), Q.bounded(x)) == False assert ask(Q.bounded(x*y), Q.bounded(x) & Q.bounded(y)) == True assert ask(Q.bounded(x**2)) == False assert ask(Q.bounded(2**x)) == False assert ask(Q.bounded(2**x), Q.bounded(x)) == True assert ask(Q.bounded(x**x)) == False assert ask(Q.bounded(Rational(1,2) ** x)) == None assert ask(Q.bounded(Rational(1,2) ** x), Q.positive(x)) == True assert ask(Q.bounded(Rational(1,2) ** x), Q.negative(x)) == False assert ask(Q.bounded(sqrt(x))) == False # sign function assert ask(Q.bounded(sign(x))) == True assert ask(Q.bounded(sign(x)), ~Q.bounded(x)) == True # exponential functions assert ask(Q.bounded(log(x))) == False assert ask(Q.bounded(log(x)), Q.bounded(x)) == True assert ask(Q.bounded(exp(x))) == False assert ask(Q.bounded(exp(x)), Q.bounded(x)) == True assert ask(Q.bounded(exp(2))) == True # trigonometric functions assert ask(Q.bounded(sin(x))) == True assert ask(Q.bounded(sin(x)), ~Q.bounded(x)) == True assert ask(Q.bounded(cos(x))) == True assert ask(Q.bounded(cos(x)), ~Q.bounded(x)) == True assert ask(Q.bounded(2*sin(x))) == True assert ask(Q.bounded(sin(x)**2)) == True assert ask(Q.bounded(cos(x)**2)) == True assert ask(Q.bounded(cos(x) + sin(x))) == True
def calc_limit(a, b): """replace x with a, using subs if possible, otherwise limit where sign of b is considered""" wok = inverse_mapping.subs(x, a) if wok is S.NaN or wok.is_bounded is False and a.is_bounded: return limit(sign(b)*inverse_mapping, x, a) return wok
def refine_Pow(expr, assumptions): """ Handler for instances of Pow. >>> from sympy import Symbol, Assume, Q >>> from sympy.assumptions.refine import refine_Pow >>> from sympy.abc import x >>> refine_Pow((-1)**x, Assume(x, Q.real)) >>> refine_Pow((-1)**x, Assume(x, Q.even)) 1 >>> refine_Pow((-1)**x, Assume(x, Q.odd)) -1 """ from sympy.core import Pow, Rational from sympy.functions import sign if ask(expr.base, Q.real, assumptions): if expr.base.is_number: if ask(expr.exp, Q.even, assumptions): return abs(expr.base) ** expr.exp if ask(expr.exp, Q.odd, assumptions): return sign(expr.base) * abs(expr.base) ** expr.exp if isinstance(expr.exp, Rational): if type(expr.base) is Pow: return abs(expr.base.base) ** (expr.base.exp * expr.exp)
def test_MpmathPrinter(): p = MpmathPrinter() assert p.doprint(sign(x)) == 'mpmath.sign(x)' assert p.doprint(Rational(1, 2)) == 'mpmath.mpf(1)/mpmath.mpf(2)' assert p.doprint(loggamma(x)) == 'mpmath.loggamma(x)' assert p.doprint(fresnels(x)) == 'mpmath.fresnels(x)' assert p.doprint(fresnelc(x)) == 'mpmath.fresnelc(x)'
def test_PythonCodePrinter(): prntr = PythonCodePrinter() assert not prntr.module_imports assert prntr.doprint(x**y) == 'x**y' assert prntr.doprint(Mod(x, 2)) == 'x % 2' assert prntr.doprint(And(x, y)) == 'x and y' assert prntr.doprint(Or(x, y)) == 'x or y' assert not prntr.module_imports assert prntr.doprint(pi) == 'math.pi' assert prntr.module_imports == {'math': {'pi'}} assert prntr.doprint(x**Rational(1, 2)) == 'math.sqrt(x)' assert prntr.doprint(sqrt(x)) == 'math.sqrt(x)' assert prntr.module_imports == {'math': {'pi', 'sqrt'}} assert prntr.doprint(acos(x)) == 'math.acos(x)' assert prntr.doprint(Assignment(x, 2)) == 'x = 2' assert prntr.doprint(Piecewise( (1, Eq(x, 0)), (2, x > 6))) == '((1) if (x == 0) else (2) if (x > 6) else None)' assert prntr.doprint(Piecewise((2, Le(x, 0)), (3, Gt(x, 0)), evaluate=False)) == '((2) if (x <= 0) else'\ ' (3) if (x > 0) else None)' assert prntr.doprint(sign(x)) == '(0.0 if x == 0 else math.copysign(1, x))' assert prntr.doprint(p[0, 1]) == 'p[0, 1]'
def test_PythonCodePrinter(): prntr = PythonCodePrinter() assert not prntr.module_imports assert prntr.doprint(x**y) == "x**y" assert prntr.doprint(Mod(x, 2)) == "x % 2" assert prntr.doprint(And(x, y)) == "x and y" assert prntr.doprint(Or(x, y)) == "x or y" assert not prntr.module_imports assert prntr.doprint(pi) == "math.pi" assert prntr.module_imports == {"math": {"pi"}} assert prntr.doprint(x**Rational(1, 2)) == "math.sqrt(x)" assert prntr.doprint(sqrt(x)) == "math.sqrt(x)" assert prntr.module_imports == {"math": {"pi", "sqrt"}} assert prntr.doprint(acos(x)) == "math.acos(x)" assert prntr.doprint(Assignment(x, 2)) == "x = 2" assert (prntr.doprint(Piecewise( (1, Eq(x, 0)), (2, x > 6))) == "((1) if (x == 0) else (2) if (x > 6) else None)") assert (prntr.doprint( Piecewise((2, Le(x, 0)), (3, Gt(x, 0)), evaluate=False)) == "((2) if (x <= 0) else" " (3) if (x > 0) else None)") assert prntr.doprint(sign(x)) == "(0.0 if x == 0 else math.copysign(1, x))" assert prntr.doprint(p[0, 1]) == "p[0, 1]"
def calc_limit(a, b): """replace x with a, using subs if possible, otherwise limit where sign of b is considered""" wok = inverse_mapping.subs(x, a) if not wok is S.NaN: return wok return limit(sign(b)*inverse_mapping, x, a)
def denester(nested): """ Denests a list of expressions that contain nested square roots. This method should not be called directly - use 'sqrtdenest' instead. This algorithm is based on <http://www.almaden.ibm.com/cs/people/fagin/symb85.pdf>. It is assumed that all of the elements of 'nested' share the same bottom-level radicand. (This is stated in the paper, on page 177, in the paragraph immediately preceding the algorithm.) When evaluating all of the arguments in parallel, the bottom-level radicand only needs to be denested once. This means that calling denester with x arguments results in a recursive invocation with x+1 arguments; hence denester has polynomial complexity. However, if the arguments were evaluated separately, each call would result in two recursive invocations, and the algorithm would have exponential complexity. This is discussed in the paper in the middle paragraph of page 179. """ if all((n**2).is_Number for n in nested): #If none of the arguments are nested for f in subsets(len(nested)): #Test subset 'f' of nested p = prod(nested[i]**2 for i in range(len(f)) if f[i]).expand() if 1 in f and f.count(1) > 1 and f[-1]: p = -p if sqrt(p).is_Number: return sqrt(p), f #If we got a perfect square, return its square root. return nested[-1], [0]*len(nested) #Otherwise, return the radicand from the previous invocation. else: a, b, r, R = Wild('a'), Wild('b'), Wild('r'), None values = [expr.match(sqrt(a + b * sqrt(r))) for expr in nested] if any(v is None for v in values): # this pattern is not recognized return nested[-1], [0]*len(nested) #Otherwise, return the radicand from the previous invocation. for v in values: if r in v: #Since if b=0, r is not defined if R is not None: assert R == v[r] #All the 'r's should be the same. else: R = v[r] if R is None: return nested[-1], [0]*len(nested) #return the radicand from the previous invocation. d, f = denester([sqrt((v[a]**2).expand()-(R*v[b]**2).expand()) for v in values] + [sqrt(R)]) if all(fi == 0 for fi in f): v = values[-1] return sqrt(v[a] + v[b]*d), f else: v = prod(nested[i]**2 for i in range(len(nested)) if f[i]).expand().match(a+b*sqrt(r)) if 1 in f and f.index(1) < len(nested) - 1 and f[len(nested)-1]: v[a] = -1 * v[a] v[b] = -1 * v[b] if not f[len(nested)]: #Solution denests with square roots vad = (v[a] + d).expand() if not vad: return nested[-1], [0]*len(nested) #Otherwise, return the radicand from the previous invocation. return (sqrt(vad/2) + sign(v[b])*sqrt((v[b]**2*R/(2*vad)).expand())).expand(), f else: #Solution requires a fourth root FR, s = (R.expand()**Rational(1,4)), sqrt((v[b]*R).expand()+d) return (s/(sqrt(2)*FR) + v[a]*FR/(sqrt(2)*s)).expand(), f
def _sqrt_numeric_denest(a, b, r, d2): r"""Helper that denest $\sqrt{a + b \sqrt{r}}, d^2 = a^2 - b^2 r > 0$ If it cannot be denested, it returns ``None``. """ d = sqrt(d2) s = a + d # sqrt_depth(res) <= sqrt_depth(s) + 1 # sqrt_depth(expr) = sqrt_depth(r) + 2 # there is denesting if sqrt_depth(s) + 1 < sqrt_depth(r) + 2 # if s**2 is Number there is a fourth root if sqrt_depth(s) < sqrt_depth(r) + 1 or (s**2).is_Rational: s1, s2 = sign(s), sign(b) if s1 == s2 == -1: s1 = s2 = 1 res = (s1 * sqrt(a + d) + s2 * sqrt(a - d)) * sqrt(2) / 2 return res.expand()
def _calc_limit_1(F, a, b): """ replace d with a, using subs if possible, otherwise limit where sign of b is considered """ wok = F.subs(d, a) if wok is S.NaN or wok.is_bounded is False and a.is_bounded: return limit(sign(b) * F, d, a) return wok
def _calc_limit_1(F, a, b): """ replace d with a, using subs if possible, otherwise limit where sign of b is considered """ wok = F.subs(d, a) if wok is S.NaN or wok.is_bounded is False and a.is_bounded: return limit(sign(b)*F, d, a) return wok
def p_parameter(self): """P is a parameter of parabola. Returns ======= p : number or symbolic expression Notes ===== The absolute value of p is the focal length. The sign on p tells which way the parabola faces. Vertical parabolas that open up and horizontal that open right, give a positive value for p. Vertical parabolas that open down and horizontal that open left, give a negative value for p. See Also ======== http://www.sparknotes.com/math/precalc/conicsections/section2.rhtml Examples ======== >>> from sympy import Parabola, Point, Line >>> p1 = Parabola(Point(0, 0), Line(Point(5, 8), Point(7, 8))) >>> p1.p_parameter -4 """ m = self.directrix.slope if m is S.Infinity: x = self.directrix.coefficients[2] p = sign(self.focus.args[0] + x) elif m == 0: y = self.directrix.coefficients[2] p = sign(self.focus.args[1] + y) else: d = self.directrix.projection(self.focus) p = sign(self.focus.x - d.x) return p * self.focal_length
def test_MpmathPrinter(): p = MpmathPrinter() assert p.doprint(sign(x)) == 'mpmath.sign(x)' assert p.doprint(Rational(1, 2)) == 'mpmath.mpf(1)/mpmath.mpf(2)' assert p.doprint(S.Exp1) == 'mpmath.e' assert p.doprint(S.Pi) == 'mpmath.pi' assert p.doprint(S.GoldenRatio) == 'mpmath.phi' assert p.doprint(S.EulerGamma) == 'mpmath.euler' assert p.doprint(S.NaN) == 'mpmath.nan' assert p.doprint(S.Infinity) == 'mpmath.inf' assert p.doprint(S.NegativeInfinity) == 'mpmath.ninf'
def p_parameter(self): """P is a parameter of parabola. Returns ======= p : number or symbolic expression Notes ===== The absolute value of p is the focal length. The sign on p tells which way the parabola faces. Vertical parabolas that open up and horizontal that open right, give a positive value for p. Vertical parabolas that open down and horizontal that open left, give a negative value for p. See Also ======== http://www.sparknotes.com/math/precalc/conicsections/section2.rhtml Examples ======== >>> from sympy import Parabola, Point, Line >>> p1 = Parabola(Point(0, 0), Line(Point(5, 8), Point(7, 8))) >>> p1.p_parameter -4 """ if self.axis_of_symmetry.slope == 0: x = self.directrix.coefficients[2] p = sign(self.focus.args[0] + x) else: y = self.directrix.coefficients[2] p = sign(self.focus.args[1] + y) return p * self.focal_length
def test_Function(): assert mcode(sin(x)**cos(x)) == "sin(x).^cos(x)" assert mcode(sign(x)) == "sign(x)" assert mcode(exp(x)) == "exp(x)" assert mcode(log(x)) == "log(x)" assert mcode(factorial(x)) == "factorial(x)" assert mcode(floor(x)) == "floor(x)" assert mcode(atan2(y, x)) == "atan2(y, x)" assert mcode(beta(x, y)) == 'beta(x, y)' assert mcode(polylog(x, y)) == 'polylog(x, y)' assert mcode(harmonic(x)) == 'harmonic(x)' assert mcode(bernoulli(x)) == "bernoulli(x)" assert mcode(bernoulli(x, y)) == "bernoulli(x, y)"
def test_Function(): assert mcode(sin(x) ** cos(x)) == "sin(x).^cos(x)" assert mcode(sign(x)) == "sign(x)" assert mcode(exp(x)) == "exp(x)" assert mcode(log(x)) == "log(x)" assert mcode(factorial(x)) == "factorial(x)" assert mcode(floor(x)) == "floor(x)" assert mcode(atan2(y, x)) == "atan2(y, x)" assert mcode(beta(x, y)) == 'beta(x, y)' assert mcode(polylog(x, y)) == 'polylog(x, y)' assert mcode(harmonic(x)) == 'harmonic(x)' assert mcode(bernoulli(x)) == "bernoulli(x)" assert mcode(bernoulli(x, y)) == "bernoulli(x, y)"
def test_NumPyPrinter(): from sympy import ( Lambda, ZeroMatrix, OneMatrix, FunctionMatrix, HadamardProduct, KroneckerProduct, Adjoint, DiagonalOf, DiagMatrix, DiagonalMatrix, ) from sympy.abc import a, b p = NumPyPrinter() assert p.doprint(sign(x)) == "numpy.sign(x)" A = MatrixSymbol("A", 2, 2) B = MatrixSymbol("B", 2, 2) C = MatrixSymbol("C", 1, 5) D = MatrixSymbol("D", 3, 4) assert p.doprint(A**(-1)) == "numpy.linalg.inv(A)" assert p.doprint(A**5) == "numpy.linalg.matrix_power(A, 5)" assert p.doprint(Identity(3)) == "numpy.eye(3)" u = MatrixSymbol("x", 2, 1) v = MatrixSymbol("y", 2, 1) assert p.doprint(MatrixSolve(A, u)) == "numpy.linalg.solve(A, x)" assert p.doprint(MatrixSolve(A, u) + v) == "numpy.linalg.solve(A, x) + y" assert p.doprint(ZeroMatrix(2, 3)) == "numpy.zeros((2, 3))" assert p.doprint(OneMatrix(2, 3)) == "numpy.ones((2, 3))" assert (p.doprint(FunctionMatrix(4, 5, Lambda( (a, b), a + b))) == "numpy.fromfunction(lambda a, b: a + b, (4, 5))") assert p.doprint(HadamardProduct(A, B)) == "numpy.multiply(A, B)" assert p.doprint(KroneckerProduct(A, B)) == "numpy.kron(A, B)" assert p.doprint(Adjoint(A)) == "numpy.conjugate(numpy.transpose(A))" assert p.doprint(DiagonalOf(A)) == "numpy.reshape(numpy.diag(A), (-1, 1))" assert p.doprint(DiagMatrix(C)) == "numpy.diagflat(C)" assert p.doprint(DiagonalMatrix(D)) == "numpy.multiply(D, numpy.eye(3, 4))" # Workaround for numpy negative integer power errors assert p.doprint(x**-1) == "x**(-1.0)" assert p.doprint(x**-2) == "x**(-2.0)" assert p.doprint(S.Exp1) == "numpy.e" assert p.doprint(S.Pi) == "numpy.pi" assert p.doprint(S.EulerGamma) == "numpy.euler_gamma" assert p.doprint(S.NaN) == "numpy.nan" assert p.doprint(S.Infinity) == "numpy.PINF" assert p.doprint(S.NegativeInfinity) == "numpy.NINF"
def test_NumPyPrinter(): p = NumPyPrinter() assert p.doprint(sign(x)) == 'numpy.sign(x)' A = MatrixSymbol("A", 2, 2) assert p.doprint(A**(-1)) == "numpy.linalg.inv(A)" assert p.doprint(A**5) == "numpy.linalg.matrix_power(A, 5)" u = MatrixSymbol('x', 2, 1) v = MatrixSymbol('y', 2, 1) assert p.doprint(MatrixSolve(A, u)) == 'numpy.linalg.solve(A, x)' assert p.doprint(MatrixSolve(A, u) + v) == 'numpy.linalg.solve(A, x) + y' # Workaround for numpy negative integer power errors assert p.doprint(x**-1) == 'x**(-1.0)' assert p.doprint(x**-2) == 'x**(-2.0)'
def test_NumPyPrinter(): from sympy.core.function import Lambda from sympy.matrices.expressions.adjoint import Adjoint from sympy.matrices.expressions.diagonal import (DiagMatrix, DiagonalMatrix, DiagonalOf) from sympy.matrices.expressions.funcmatrix import FunctionMatrix from sympy.matrices.expressions.hadamard import HadamardProduct from sympy.matrices.expressions.kronecker import KroneckerProduct from sympy.matrices.expressions.special import (OneMatrix, ZeroMatrix) from sympy.abc import a, b p = NumPyPrinter() assert p.doprint(sign(x)) == 'numpy.sign(x)' A = MatrixSymbol("A", 2, 2) B = MatrixSymbol("B", 2, 2) C = MatrixSymbol("C", 1, 5) D = MatrixSymbol("D", 3, 4) assert p.doprint(A**(-1)) == "numpy.linalg.inv(A)" assert p.doprint(A**5) == "numpy.linalg.matrix_power(A, 5)" assert p.doprint(Identity(3)) == "numpy.eye(3)" u = MatrixSymbol('x', 2, 1) v = MatrixSymbol('y', 2, 1) assert p.doprint(MatrixSolve(A, u)) == 'numpy.linalg.solve(A, x)' assert p.doprint(MatrixSolve(A, u) + v) == 'numpy.linalg.solve(A, x) + y' assert p.doprint(ZeroMatrix(2, 3)) == "numpy.zeros((2, 3))" assert p.doprint(OneMatrix(2, 3)) == "numpy.ones((2, 3))" assert p.doprint(FunctionMatrix(4, 5, Lambda((a, b), a + b))) == \ "numpy.fromfunction(lambda a, b: a + b, (4, 5))" assert p.doprint(HadamardProduct(A, B)) == "numpy.multiply(A, B)" assert p.doprint(KroneckerProduct(A, B)) == "numpy.kron(A, B)" assert p.doprint(Adjoint(A)) == "numpy.conjugate(numpy.transpose(A))" assert p.doprint(DiagonalOf(A)) == "numpy.reshape(numpy.diag(A), (-1, 1))" assert p.doprint(DiagMatrix(C)) == "numpy.diagflat(C)" assert p.doprint(DiagonalMatrix(D)) == "numpy.multiply(D, numpy.eye(3, 4))" # Workaround for numpy negative integer power errors assert p.doprint(x**-1) == 'x**(-1.0)' assert p.doprint(x**-2) == 'x**(-2.0)' expr = Pow(2, -1, evaluate=False) assert p.doprint(expr) == "2**(-1.0)" assert p.doprint(S.Exp1) == 'numpy.e' assert p.doprint(S.Pi) == 'numpy.pi' assert p.doprint(S.EulerGamma) == 'numpy.euler_gamma' assert p.doprint(S.NaN) == 'numpy.nan' assert p.doprint(S.Infinity) == 'numpy.PINF' assert p.doprint(S.NegativeInfinity) == 'numpy.NINF'
def fits_in(unit, dimension, reciprocal): """ Checks if unit fits in given dimension (just for use inside this module) Args: - unit - dimension - reciprocal: 1 or -1 to show if unit is supposed to be fitted in as reciprocal or not """ assert isinstance(unit, Unit) assert isinstance(dimension, Dimension) assert reciprocal is S.One or reciprocal is S.NegativeOne for lookAtThis, unitExp in unit.dim.items(): dimExp = dimension.get(lookAtThis, 0) if not unitExp == 0: if not sign(unitExp) == sign(dimExp * reciprocal): return False if not abs(unitExp) <= abs(dimExp): return False return True
def _sqrt_numeric_denest(a, b, r, d2): """Helper that denest expr = a + b*sqrt(r), with d2 = a**2 - b**2*r > 0 or returns None if not denested. """ from sympy.simplify.simplify import radsimp depthr = sqrt_depth(r) d = sqrt(d2) vad = a + d # sqrt_depth(res) <= sqrt_depth(vad) + 1 # sqrt_depth(expr) = depthr + 2 # there is denesting if sqrt_depth(vad)+1 < depthr + 2 # if vad**2 is Number there is a fourth root if sqrt_depth(vad) < depthr + 1 or (vad**2).is_Rational: vad1 = radsimp(1/vad) return (sqrt(vad/2) + sign(b)*sqrt((b**2*r*vad1/2).expand())).expand()
def test_PythonCodePrinter(): prntr = PythonCodePrinter() assert not prntr.module_imports assert prntr.doprint(x**y) == 'x**y' assert prntr.doprint(Mod(x, 2)) == 'x % 2' assert prntr.doprint(And(x, y)) == 'x and y' assert prntr.doprint(Or(x, y)) == 'x or y' assert not prntr.module_imports assert prntr.doprint(pi) == 'math.pi' assert prntr.module_imports == {'math': {'pi'}} assert prntr.doprint(acos(x)) == 'math.acos(x)' assert prntr.doprint(Assignment(x, 2)) == 'x = 2' assert prntr.doprint(Piecewise((1, Eq(x, 0)), (2, x>6))) == '((1) if (x == 0) else (2) if (x > 6) else None)' assert prntr.doprint(Piecewise((2, Le(x, 0)), (3, Gt(x, 0)), evaluate=False)) == '((2) if (x <= 0) else'\ ' (3) if (x > 0) else None)' assert prntr.doprint(sign(x)) == '(0.0 if x == 0 else math.copysign(1, x))'
def test_NumPyPrinter(): p = NumPyPrinter() assert p.doprint(sign(x)) == 'numpy.sign(x)' A = MatrixSymbol("A", 2, 2) assert p.doprint(A**(-1)) == "numpy.linalg.inv(A)" assert p.doprint(A**5) == "numpy.linalg.matrix_power(A, 5)" assert p.doprint(Identity(3)) == "numpy.eye(3)" u = MatrixSymbol('x', 2, 1) v = MatrixSymbol('y', 2, 1) assert p.doprint(MatrixSolve(A, u)) == 'numpy.linalg.solve(A, x)' assert p.doprint(MatrixSolve(A, u) + v) == 'numpy.linalg.solve(A, x) + y' # Workaround for numpy negative integer power errors assert p.doprint(x**-1) == 'x**(-1.0)' assert p.doprint(x**-2) == 'x**(-2.0)' assert p.doprint(S.Exp1) == 'numpy.e' assert p.doprint(S.Pi) == 'numpy.pi' assert p.doprint(S.EulerGamma) == 'numpy.euler_gamma' assert p.doprint(S.NaN) == 'numpy.nan' assert p.doprint(S.Infinity) == 'numpy.PINF' assert p.doprint(S.NegativeInfinity) == 'numpy.NINF'
def refine_Pow(expr, assumptions): """ Handler for instances of Pow. >>> from sympy import Symbol, Q >>> from sympy.assumptions.refine import refine_Pow >>> from sympy.abc import x,y,z >>> refine_Pow((-1)**x, Q.real(x)) >>> refine_Pow((-1)**x, Q.even(x)) 1 >>> refine_Pow((-1)**x, Q.odd(x)) -1 For powers of -1, even parts of the exponent can be simplified: >>> refine_Pow((-1)**(x+y), Q.even(x)) (-1)**y >>> refine_Pow((-1)**(x+y+z), Q.odd(x) & Q.odd(z)) (-1)**y >>> refine_Pow((-1)**(x+y+2), Q.odd(x)) (-1)**(y + 1) >>> refine_Pow((-1)**(x+3), True) (-1)**(x + 1) """ from sympy.core import Pow, Rational from sympy.functions.elementary.complexes import Abs from sympy.functions import sign if isinstance(expr.base, Abs): if ask(Q.real(expr.base.args[0]), assumptions) and \ ask(Q.even(expr.exp), assumptions): return expr.base.args[0]**expr.exp if ask(Q.real(expr.base), assumptions): if expr.base.is_number: if ask(Q.even(expr.exp), assumptions): return abs(expr.base)**expr.exp if ask(Q.odd(expr.exp), assumptions): return sign(expr.base) * abs(expr.base)**expr.exp if isinstance(expr.exp, Rational): if type(expr.base) is Pow: return abs(expr.base.base)**(expr.base.exp * expr.exp) if expr.base is S.NegativeOne: if expr.exp.is_Add: old = expr # For powers of (-1) we can remove # - even terms # - pairs of odd terms # - a single odd term + 1 # - A numerical constant N can be replaced with mod(N,2) coeff, terms = expr.exp.as_coeff_add() terms = set(terms) even_terms = set([]) odd_terms = set([]) initial_number_of_terms = len(terms) for t in terms: if ask(Q.even(t), assumptions): even_terms.add(t) elif ask(Q.odd(t), assumptions): odd_terms.add(t) terms -= even_terms if len(odd_terms) % 2: terms -= odd_terms new_coeff = (coeff + S.One) % 2 else: terms -= odd_terms new_coeff = coeff % 2 if new_coeff != coeff or len(terms) < initial_number_of_terms: terms.add(new_coeff) expr = expr.base**(Add(*terms)) # Handle (-1)**((-1)**n/2 + m/2) e2 = 2 * expr.exp if ask(Q.even(e2), assumptions): if e2.could_extract_minus_sign(): e2 *= expr.base if e2.is_Add: i, p = e2.as_two_terms() if p.is_Pow and p.base is S.NegativeOne: if ask(Q.integer(p.exp), assumptions): i = (i + 1) / 2 if ask(Q.even(i), assumptions): return expr.base**p.exp elif ask(Q.odd(i), assumptions): return expr.base**(p.exp + 1) else: return expr.base**(p.exp + i) if old != expr: return expr
def test_NumPyPrinter(): p = NumPyPrinter() assert p.doprint(sign(x)) == 'numpy.sign(x)' A = MatrixSymbol("A", 2, 2) assert p.doprint(A**(-1)) == "numpy.linalg.inv(A)" assert p.doprint(A**5) == "numpy.linalg.matrix_power(A, 5)"
def sqrtofsqrtsimp_(a=0, b=0, c=0): # 1/sqrt(a + b*sqrt(c)) q = sqrt(a**2 - b**2*c) if not q.is_Rational: return None return 1/(sqrt((a+q)/2) + sign(b)*sqrt((a-q)/2))
def refine_Pow(expr, assumptions): """ Handler for instances of Pow. >>> from sympy import Symbol, Q >>> from sympy.assumptions.refine import refine_Pow >>> from sympy.abc import x,y,z >>> refine_Pow((-1)**x, Q.real(x)) >>> refine_Pow((-1)**x, Q.even(x)) 1 >>> refine_Pow((-1)**x, Q.odd(x)) -1 For powers of -1, even parts of the exponent can be simplified: >>> refine_Pow((-1)**(x+y), Q.even(x)) (-1)**y >>> refine_Pow((-1)**(x+y+z), Q.odd(x) & Q.odd(z)) (-1)**y >>> refine_Pow((-1)**(x+y+2), Q.odd(x)) (-1)**(y + 1) >>> refine_Pow((-1)**(x+3), True) (-1)**(x + 1) """ from sympy.core import Pow, Rational from sympy.functions import sign if ask(Q.real(expr.base), assumptions): if expr.base.is_number: if ask(Q.even(expr.exp), assumptions): return abs(expr.base) ** expr.exp if ask(Q.odd(expr.exp), assumptions): return sign(expr.base) * abs(expr.base) ** expr.exp if isinstance(expr.exp, Rational): if type(expr.base) is Pow: return abs(expr.base.base) ** (expr.base.exp * expr.exp) if expr.base is S.NegativeOne: if expr.exp.is_Add: # For powers of (-1) we can remove # - even terms # - pairs of odd terms # - a single odd term + 1 # - A numerical constant N can be replaced with mod(N,2) coeff, terms = expr.exp.as_coeff_add() terms = set(terms) even_terms = set([]) odd_terms = set([]) initial_number_of_terms = len(terms) for t in terms: if ask(Q.even(t), assumptions): even_terms.add(t) elif ask(Q.odd(t), assumptions): odd_terms.add(t) terms -= even_terms if len(odd_terms)%2: terms -= odd_terms new_coeff = (coeff + S.One) % 2 else: terms -= odd_terms new_coeff = coeff % 2 if new_coeff != coeff or len(terms) < initial_number_of_terms: terms.add(new_coeff) return expr.base**(Add(*terms))
def _denester(nested, av0, h, max_depth_level): """Denests a list of expressions that contain nested square roots. Algorithm based on <http://www.almaden.ibm.com/cs/people/fagin/symb85.pdf>. It is assumed that all of the elements of 'nested' share the same bottom-level radicand. (This is stated in the paper, on page 177, in the paragraph immediately preceding the algorithm.) When evaluating all of the arguments in parallel, the bottom-level radicand only needs to be denested once. This means that calling _denester with x arguments results in a recursive invocation with x+1 arguments; hence _denester has polynomial complexity. However, if the arguments were evaluated separately, each call would result in two recursive invocations, and the algorithm would have exponential complexity. This is discussed in the paper in the middle paragraph of page 179. """ from sympy.simplify.simplify import radsimp if h > max_depth_level: return None, None if av0[1] is None: return None, None if (av0[0] is None and all(n.is_Number for n in nested)): # no arguments are nested for f in subsets(len(nested)): # test subset 'f' of nested p = _mexpand(Mul(*[nested[i] for i in range(len(f)) if f[i]])) if f.count(1) > 1 and f[-1]: p = -p sqp = sqrt(p) if sqp.is_Rational: return sqp, f # got a perfect square so return its square root. # Otherwise, return the radicand from the previous invocation. return sqrt(nested[-1]), [0]*len(nested) else: R = None if av0[0] is not None: values = [av0[:2]] R = av0[2] nested2 = [av0[3], R] av0[0] = None else: values = filter(None, [_sqrt_match(expr) for expr in nested]) for v in values: if v[2]: #Since if b=0, r is not defined if R is not None: if R != v[2]: av0[1] = None return None, None else: R = v[2] if R is None: # return the radicand from the previous invocation return sqrt(nested[-1]), [0]*len(nested) nested2 = [_mexpand(v[0]**2) - _mexpand(R*v[1]**2) for v in values] + [R] d, f = _denester(nested2, av0, h + 1, max_depth_level) if not f: return None, None if not any(f[i] for i in range(len(nested))): v = values[-1] return sqrt(v[0] + v[1]*d), f else: p = Mul(*[nested[i] for i in range(len(nested)) if f[i]]) v = _sqrt_match(p) if 1 in f and f.index(1) < len(nested) - 1 and f[len(nested) - 1]: v[0] = -v[0] v[1] = -v[1] if not f[len(nested)]: #Solution denests with square roots vad = _mexpand(v[0] + d) if vad <= 0: # return the radicand from the previous invocation. return sqrt(nested[-1]), [0]*len(nested) if not(sqrt_depth(vad) < sqrt_depth(R) + 1 or (vad**2).is_Number): av0[1] = None return None, None vad1 = radsimp(1/vad) return _mexpand(sqrt(vad/2) + sign(v[1])*sqrt(_mexpand(v[1]**2*R*vad1/2))), f else: #Solution requires a fourth root s2 = _mexpand(v[1]*R) + d if s2 <= 0: return sqrt(nested[-1]), [0]*len(nested) FR, s = root(_mexpand(R), 4), sqrt(s2) return _mexpand(s/(sqrt(2)*FR) + v[0]*FR/(sqrt(2)*s)), f
def trpzs2aff(tvec=zeros3, rquat=Mat([1,0,0,0]), parity=1, zfac=ones3, stri=zeros3): mat = rquat2rmat(rquat) * sign(parity) * zfac2zmat(zfac) * stri2smat(stri) return augment(mat, tvec)
def __new__(cls, tvec=zeros3, rquat=Mat([1,0,0,0]), parity=1): tvec = Mat(tvec) rquat = Mat(rquat) parity = sign(parity) return Functor.__new__(cls, tvec, rquat, parity)
def refine_Pow(expr, assumptions): """ Handler for instances of Pow. >>> from sympy import Symbol, Q >>> from sympy.assumptions.refine import refine_Pow >>> from sympy.abc import x,y,z >>> refine_Pow((-1)**x, Q.real(x)) >>> refine_Pow((-1)**x, Q.even(x)) 1 >>> refine_Pow((-1)**x, Q.odd(x)) -1 For powers of -1, even parts of the exponent can be simplified: >>> refine_Pow((-1)**(x+y), Q.even(x)) (-1)**y >>> refine_Pow((-1)**(x+y+z), Q.odd(x) & Q.odd(z)) (-1)**y >>> refine_Pow((-1)**(x+y+2), Q.odd(x)) (-1)**(y + 1) >>> refine_Pow((-1)**(x+3), True) (-1)**(x + 1) """ from sympy.core import Pow, Rational from sympy.functions.elementary.complexes import Abs from sympy.functions import sign if isinstance(expr.base, Abs): if ask(Q.real(expr.base.args[0]), assumptions) and \ ask(Q.even(expr.exp), assumptions): return expr.base.args[0] ** expr.exp if ask(Q.real(expr.base), assumptions): if expr.base.is_number: if ask(Q.even(expr.exp), assumptions): return abs(expr.base) ** expr.exp if ask(Q.odd(expr.exp), assumptions): return sign(expr.base) * abs(expr.base) ** expr.exp if isinstance(expr.exp, Rational): if type(expr.base) is Pow: return abs(expr.base.base) ** (expr.base.exp * expr.exp) if expr.base is S.NegativeOne: if expr.exp.is_Add: old = expr # For powers of (-1) we can remove # - even terms # - pairs of odd terms # - a single odd term + 1 # - A numerical constant N can be replaced with mod(N,2) coeff, terms = expr.exp.as_coeff_add() terms = set(terms) even_terms = set([]) odd_terms = set([]) initial_number_of_terms = len(terms) for t in terms: if ask(Q.even(t), assumptions): even_terms.add(t) elif ask(Q.odd(t), assumptions): odd_terms.add(t) terms -= even_terms if len(odd_terms) % 2: terms -= odd_terms new_coeff = (coeff + S.One) % 2 else: terms -= odd_terms new_coeff = coeff % 2 if new_coeff != coeff or len(terms) < initial_number_of_terms: terms.add(new_coeff) expr = expr.base**(Add(*terms)) # Handle (-1)**((-1)**n/2 + m/2) e2 = 2*expr.exp if ask(Q.even(e2), assumptions): if e2.could_extract_minus_sign(): e2 *= expr.base if e2.is_Add: i, p = e2.as_two_terms() if p.is_Pow and p.base is S.NegativeOne: if ask(Q.integer(p.exp), assumptions): i = (i + 1)/2 if ask(Q.even(i), assumptions): return expr.base**p.exp elif ask(Q.odd(i), assumptions): return expr.base**(p.exp + 1) else: return expr.base**(p.exp + i) if old != expr: return expr
def test_MpmathPrinter(): p = MpmathPrinter() assert p.doprint(sign(x)) == 'mpmath.sign(x)'
def test_MpmathPrinter(): p = MpmathPrinter() assert p.doprint(sign(x)) == 'mpmath.sign(x)' assert p.doprint(Rational(1, 2)) == 'mpmath.mpf(1)/mpmath.mpf(2)'
def SuperellipseYZ(n, a, b): x = (Abs(cos(v)) ** (2/n)) * a * sign(cos(v)) y = (Abs(sin(v)) ** (2/n)) * b * sign(sin(v)) return VVF(0, -x, y)
def test_NumPyPrinter(): p = NumPyPrinter() assert p.doprint(sign(x)) == 'numpy.sign(x)'
N = 15 # número de términos en la suma #step_approx=lambdify(x,Sum(A(m).doit()*sp.legendre(2*m+1,x),(m,0,N)).doit(),"numpy") step_approx = lambdify( x, Sum(A(m).evalf() * sp.legendre(2 * m + 1, x), (m, 0, N)).doit(), "numpy") #Sum es una función de sympy. Recordar que m es un símbolo que también importamos desde simpy. #Un ejemplo para entender la expresión de arriba es from sympy.abc import p #notar que ya importamos m antes Sum(p, (p, 0, 3)) print(Sum(p, (p, 0, 3))) ## Graficamos la aproximación y comparamos con la solución exacta. Note que si ponemos muchos términos la solución no converge. fig = mpl.figure(figsize=(10, 10)) step = lambdify(x, sp.sign(x), "numpy") f_vals = step(x_vals) mpl.plot(x_vals, f_vals, color="k", label="Exact") for N in [5, 15, 25]: x_vals = np.linspace(-1, 1, 200) step_approx = lambdify( x, Sum(A(m).evalf() * sp.legendre(2 * m + 1, x), (m, 0, N)).doit(), "numpy") z_vals = step_approx(x_vals) mpl.plot(x_vals, z_vals, label=f"N = {N:d}") mpl.ylabel("step") mpl.ylim(-2, 2) #seteamos los límites del ploteo mpl.legend() #para ver los labels # mpl.show()
def Jump(x,x_i,Xi): return 1./2.*(sign(x-Xi)-sign(x_i-Xi))
def test_tensorflow_math(): if not tf: skip("TensorFlow not installed") expr = Abs(x) assert tensorflow_code(expr) == "tensorflow.math.abs(x)" _compare_tensorflow_scalar((x, ), expr) expr = sign(x) assert tensorflow_code(expr) == "tensorflow.math.sign(x)" _compare_tensorflow_scalar((x, ), expr) expr = ceiling(x) assert tensorflow_code(expr) == "tensorflow.math.ceil(x)" _compare_tensorflow_scalar((x, ), expr, rng=lambda: random.random()) expr = floor(x) assert tensorflow_code(expr) == "tensorflow.math.floor(x)" _compare_tensorflow_scalar((x, ), expr, rng=lambda: random.random()) expr = exp(x) assert tensorflow_code(expr) == "tensorflow.math.exp(x)" _compare_tensorflow_scalar((x, ), expr, rng=lambda: random.random()) expr = sqrt(x) assert tensorflow_code(expr) == "tensorflow.math.sqrt(x)" _compare_tensorflow_scalar((x, ), expr, rng=lambda: random.random()) expr = x**4 assert tensorflow_code(expr) == "tensorflow.math.pow(x, 4)" _compare_tensorflow_scalar((x, ), expr, rng=lambda: random.random()) expr = cos(x) assert tensorflow_code(expr) == "tensorflow.math.cos(x)" _compare_tensorflow_scalar((x, ), expr, rng=lambda: random.random()) expr = acos(x) assert tensorflow_code(expr) == "tensorflow.math.acos(x)" _compare_tensorflow_scalar((x, ), expr, rng=lambda: random.uniform(0, 0.95)) expr = sin(x) assert tensorflow_code(expr) == "tensorflow.math.sin(x)" _compare_tensorflow_scalar((x, ), expr, rng=lambda: random.random()) expr = asin(x) assert tensorflow_code(expr) == "tensorflow.math.asin(x)" _compare_tensorflow_scalar((x, ), expr, rng=lambda: random.random()) expr = tan(x) assert tensorflow_code(expr) == "tensorflow.math.tan(x)" _compare_tensorflow_scalar((x, ), expr, rng=lambda: random.random()) expr = atan(x) assert tensorflow_code(expr) == "tensorflow.math.atan(x)" _compare_tensorflow_scalar((x, ), expr, rng=lambda: random.random()) expr = atan2(y, x) assert tensorflow_code(expr) == "tensorflow.math.atan2(y, x)" _compare_tensorflow_scalar((y, x), expr, rng=lambda: random.random()) expr = cosh(x) assert tensorflow_code(expr) == "tensorflow.math.cosh(x)" _compare_tensorflow_scalar((x, ), expr, rng=lambda: random.random()) expr = acosh(x) assert tensorflow_code(expr) == "tensorflow.math.acosh(x)" _compare_tensorflow_scalar((x, ), expr, rng=lambda: random.uniform(1, 2)) expr = sinh(x) assert tensorflow_code(expr) == "tensorflow.math.sinh(x)" _compare_tensorflow_scalar((x, ), expr, rng=lambda: random.uniform(1, 2)) expr = asinh(x) assert tensorflow_code(expr) == "tensorflow.math.asinh(x)" _compare_tensorflow_scalar((x, ), expr, rng=lambda: random.uniform(1, 2)) expr = tanh(x) assert tensorflow_code(expr) == "tensorflow.math.tanh(x)" _compare_tensorflow_scalar((x, ), expr, rng=lambda: random.uniform(1, 2)) expr = atanh(x) assert tensorflow_code(expr) == "tensorflow.math.atanh(x)" _compare_tensorflow_scalar((x, ), expr, rng=lambda: random.uniform(-.5, .5)) expr = erf(x) assert tensorflow_code(expr) == "tensorflow.math.erf(x)" _compare_tensorflow_scalar((x, ), expr, rng=lambda: random.random()) expr = loggamma(x) assert tensorflow_code(expr) == "tensorflow.math.lgamma(x)" _compare_tensorflow_scalar((x, ), expr, rng=lambda: random.random())
def _denester(nested, av0, h, max_depth_level): """Denests a list of expressions that contain nested square roots. Algorithm based on <http://www.almaden.ibm.com/cs/people/fagin/symb85.pdf>. It is assumed that all of the elements of 'nested' share the same bottom-level radicand. (This is stated in the paper, on page 177, in the paragraph immediately preceding the algorithm.) When evaluating all of the arguments in parallel, the bottom-level radicand only needs to be denested once. This means that calling _denester with x arguments results in a recursive invocation with x+1 arguments; hence _denester has polynomial complexity. However, if the arguments were evaluated separately, each call would result in two recursive invocations, and the algorithm would have exponential complexity. This is discussed in the paper in the middle paragraph of page 179. """ from sympy.simplify.simplify import radsimp if h > max_depth_level: return None, None if av0[1] is None: return None, None if (av0[0] is None and all(n.is_Number for n in nested)): # no arguments are nested for f in subsets(len(nested)): # test subset 'f' of nested p = _mexpand(Mul(*[nested[i] for i in range(len(f)) if f[i]])) if f.count(1) > 1 and f[-1]: p = -p sqp = sqrt(p) if sqp.is_Rational: return sqp, f # got a perfect square so return its square root. # Otherwise, return the radicand from the previous invocation. return sqrt(nested[-1]), [0] * len(nested) else: R = None if av0[0] is not None: values = [av0[:2]] R = av0[2] nested2 = [av0[3], R] av0[0] = None else: values = filter(None, [_sqrt_match(expr) for expr in nested]) for v in values: if v[2]: #Since if b=0, r is not defined if R is not None: if R != v[2]: av0[1] = None return None, None else: R = v[2] if R is None: # return the radicand from the previous invocation return sqrt(nested[-1]), [0] * len(nested) nested2 = [ _mexpand(v[0]**2) - _mexpand(R * v[1]**2) for v in values ] + [R] d, f = _denester(nested2, av0, h + 1, max_depth_level) if not f: return None, None if not any(f[i] for i in range(len(nested))): v = values[-1] return sqrt(v[0] + v[1] * d), f else: p = Mul(*[nested[i] for i in range(len(nested)) if f[i]]) v = _sqrt_match(p) if 1 in f and f.index(1) < len(nested) - 1 and f[len(nested) - 1]: v[0] = -v[0] v[1] = -v[1] if not f[len(nested)]: #Solution denests with square roots vad = _mexpand(v[0] + d) if vad <= 0: # return the radicand from the previous invocation. return sqrt(nested[-1]), [0] * len(nested) if not (sqrt_depth(vad) < sqrt_depth(R) + 1 or (vad**2).is_Number): av0[1] = None return None, None vad1 = radsimp(1 / vad) return _mexpand( sqrt(vad / 2) + sign(v[1]) * sqrt(_mexpand(v[1]**2 * R * vad1 / 2))), f else: #Solution requires a fourth root s2 = _mexpand(v[1] * R) + d if s2 <= 0: return sqrt(nested[-1]), [0] * len(nested) FR, s = root(_mexpand(R), 4), sqrt(s2) return _mexpand(s / (sqrt(2) * FR) + v[0] * FR / (sqrt(2) * s)), f