def test_ccode_exceptions(): assert ccode(gamma(x), standard='C99') == "tgamma(x)" assert 'not supported in c' in ccode(gamma(x), standard='C89').lower() assert ccode(ceiling(x)) == "ceil(x)" assert ccode(Abs(x)) == "fabs(x)" assert ccode(gamma(x)) == "tgamma(x)" r, s = symbols('r,s', real=True) assert ccode(Mod(ceiling(r), ceiling(s))) == "((ceil(r)) % (ceil(s)))" assert ccode(Mod(r, s)) == "fmod(r, s)"
def test_ccode_exceptions(): assert ccode(gamma(x), standard='C99') == "tgamma(x)" gamma_c89 = ccode(gamma(x), standard='C89') assert 'not supported in c' in gamma_c89.lower() gamma_c89 = ccode(gamma(x), standard='C89', allow_unknown_functions=False) assert 'not supported in c' in gamma_c89.lower() gamma_c89 = ccode(gamma(x), standard='C89', allow_unknown_functions=True) assert not 'not supported in c' in gamma_c89.lower() assert ccode(ceiling(x)) == "ceil(x)" assert ccode(Abs(x)) == "fabs(x)" assert ccode(gamma(x)) == "tgamma(x)" r, s = symbols('r,s', real=True) assert ccode(Mod(ceiling(r), ceiling(s))) == "((ceil(r)) % (ceil(s)))" assert ccode(Mod(r, s)) == "fmod(r, s)"
def test_Matrices(): assert maple_code(Matrix(1, 1, [10])) == \ 'Matrix([[10]], storage = rectangular)' A = Matrix([[1, sin(x / 2), abs(x)], [0, 1, pi], [0, exp(1), ceiling(x)]]) expected = \ 'Matrix(' \ '[[1, sin((1/2)*x), abs(x)],' \ ' [0, 1, Pi],' \ ' [0, exp(1), ceil(x)]], ' \ 'storage = rectangular)' assert maple_code(A) == expected # row and columns assert maple_code(A[:, 0]) == \ 'Matrix([[1], [0], [0]], storage = rectangular)' assert maple_code(A[0, :]) == \ 'Matrix([[1, sin((1/2)*x), abs(x)]], storage = rectangular)' assert maple_code(Matrix([[x, x - y, -y]])) == \ 'Matrix([[x, x - y, -y]], storage = rectangular)' # empty matrices assert maple_code(Matrix(0, 0, [])) == \ 'Matrix([], storage = rectangular)' assert maple_code(Matrix(0, 3, [])) == \ 'Matrix([], storage = rectangular)'
def test_Function(): assert mcode(sin(x)**cos(x)) == "sin(x).^cos(x)" assert mcode(abs(x)) == "abs(x)" assert mcode(ceiling(x)) == "ceil(x)" assert mcode(Max(x, y) + Min(x, y)) == "max(x, y) + min(x, y)" assert mcode(Max(x, y, z)) == "max(x, max(y, z))" assert mcode(Min(x, y, z)) == "min(x, min(y, z))"
def _eval_evalf(self, prec): # The default code is insufficient for polar arguments. # mpmath provides an optional argument "r", which evaluates # G(z**(1/r)). I am not sure what its intended use is, but we hijack it # here in the following way: to evaluate at a number z of |argument| # less than (say) n*pi, we put r=1/n, compute z' = root(z, n) # (carefully so as not to loose the branch information), and evaluate # G(z'**(1/r)) = G(z'**n) = G(z). from sympy.functions import exp_polar, ceiling from sympy import Expr import mpmath z = self.argument znum = self.argument._eval_evalf(prec) if znum.has(exp_polar): znum, branch = znum.as_coeff_mul(exp_polar) if len(branch) != 1: return branch = branch[0].args[0]/I else: branch = S(0) n = ceiling(abs(branch/S.Pi)) + 1 znum = znum**(S(1)/n)*exp(I*branch / n) # Convert all args to mpf or mpc try: [z, r, ap, bq] = [arg._to_mpmath(prec) for arg in [znum, 1/n, self.args[0], self.args[1]]] except ValueError: return with mpmath.workprec(prec): v = mpmath.meijerg(ap, bq, z, r) return Expr._from_mpmath(v, prec)
def _eval_evalf(self, prec): # The default code is insufficient for polar arguments. # mpmath provides an optional argument "r", which evaluates # G(z**(1/r)). I am not sure what its intended use is, but we hijack it # here in the following way: to evaluate at a number z of |argument| # less than (say) n*pi, we put r=1/n, compute z' = root(z, n) # (carefully so as not to loose the branch information), and evaluate # G(z'**(1/r)) = G(z'**n) = G(z). from sympy.functions import exp_polar, ceiling from sympy import Expr import mpmath znum = self.argument._eval_evalf(prec) if znum.has(exp_polar): znum, branch = znum.as_coeff_mul(exp_polar) if len(branch) != 1: return branch = branch[0].args[0] / I else: branch = S.Zero n = ceiling(abs(branch / S.Pi)) + 1 znum = znum**(S.One / n) * exp(I * branch / n) # Convert all args to mpf or mpc try: [z, r, ap, bq] = [ arg._to_mpmath(prec) for arg in [znum, 1 / n, self.args[0], self.args[1]] ] except ValueError: return with mpmath.workprec(prec): v = mpmath.meijerg(ap, bq, z, r) return Expr._from_mpmath(v, prec)
def test_Functions(): assert rust_code(sin(x) ** cos(x)) == "x.sin().powf(x.cos())" assert rust_code(abs(x)) == "x.abs()" assert rust_code(ceiling(x)) == "x.ceil()" assert rust_code(floor(x)) == "x.floor()" # Automatic rewrite assert rust_code(Mod(x, 3)) == 'x - 3*((1_f64/3.0)*x).floor()'
def test_ccode_functions2(): assert ccode(ceiling(x)) == "ceil(x)" assert ccode(Abs(x)) == "fabs(x)" assert ccode(gamma(x)) == "tgamma(x)" r, s = symbols('r,s', real=True) assert ccode(Mod(ceiling(r), ceiling(s))) == '((ceil(r) % ceil(s)) + '\ 'ceil(s)) % ceil(s)' assert ccode(Mod(r, s)) == "fmod(r, s)" p1, p2 = symbols('p1 p2', integer=True, positive=True) assert ccode(Mod(p1, p2)) == 'p1 % p2' assert ccode(Mod(p1, p2 + 3)) == 'p1 % (p2 + 3)' assert ccode(Mod(-3, -7, evaluate=False)) == '(-3) % (-7)' assert ccode(-Mod(3, 7, evaluate=False)) == '-(3 % 7)' assert ccode(r * Mod(p1, p2)) == 'r*(p1 % p2)' assert ccode(Mod(p1, p2)**s) == 'pow(p1 % p2, s)' n = symbols('n', integer=True, negative=True) assert ccode(Mod(-n, p2)) == '(-n) % p2'
def crack_when_pq_close(n): t = ceiling(sqrt(n)) while True: k = t**2 - n if k > 0: s = round(int(sqrt(t**2 - n))) if s**2 + n == t**2: return t + s, t - s t += 1
def test_C99CodePrinter__precision(): n = symbols('n', integer=True) f32_printer = C99CodePrinter(dict(type_aliases={real: float32})) f64_printer = C99CodePrinter(dict(type_aliases={real: float64})) f80_printer = C99CodePrinter(dict(type_aliases={real: float80})) assert f32_printer.doprint(sin(x+2.1)) == 'sinf(x + 2.1F)' assert f64_printer.doprint(sin(x+2.1)) == 'sin(x + 2.1000000000000001)' assert f80_printer.doprint(sin(x+Float('2.0'))) == 'sinl(x + 2.0L)' for printer, suffix in zip([f32_printer, f64_printer, f80_printer], ['f', '', 'l']): def check(expr, ref): assert printer.doprint(expr) == ref.format(s=suffix, S=suffix.upper()) check(Abs(n), 'abs(n)') check(Abs(x + 2.0), 'fabs{s}(x + 2.0{S})') check(sin(x + 4.0)**cos(x - 2.0), 'pow{s}(sin{s}(x + 4.0{S}), cos{s}(x - 2.0{S}))') check(exp(x*8.0), 'exp{s}(8.0{S}*x)') check(exp2(x), 'exp2{s}(x)') check(expm1(x*4.0), 'expm1{s}(4.0{S}*x)') check(Mod(n, 2), '((n) % (2))') check(Mod(2*n + 3, 3*n + 5), '((2*n + 3) % (3*n + 5))') check(Mod(x + 2.0, 3.0), 'fmod{s}(1.0{S}*x + 2.0{S}, 3.0{S})') check(Mod(x, 2.0*x + 3.0), 'fmod{s}(1.0{S}*x, 2.0{S}*x + 3.0{S})') check(log(x/2), 'log{s}((1.0{S}/2.0{S})*x)') check(log10(3*x/2), 'log10{s}((3.0{S}/2.0{S})*x)') check(log2(x*8.0), 'log2{s}(8.0{S}*x)') check(log1p(x), 'log1p{s}(x)') check(2**x, 'pow{s}(2, x)') check(2.0**x, 'pow{s}(2.0{S}, x)') check(x**3, 'pow{s}(x, 3)') check(x**4.0, 'pow{s}(x, 4.0{S})') check(sqrt(3+x), 'sqrt{s}(x + 3)') check(Cbrt(x-2.0), 'cbrt{s}(x - 2.0{S})') check(hypot(x, y), 'hypot{s}(x, y)') check(sin(3.*x + 2.), 'sin{s}(3.0{S}*x + 2.0{S})') check(cos(3.*x - 1.), 'cos{s}(3.0{S}*x - 1.0{S})') check(tan(4.*y + 2.), 'tan{s}(4.0{S}*y + 2.0{S})') check(asin(3.*x + 2.), 'asin{s}(3.0{S}*x + 2.0{S})') check(acos(3.*x + 2.), 'acos{s}(3.0{S}*x + 2.0{S})') check(atan(3.*x + 2.), 'atan{s}(3.0{S}*x + 2.0{S})') check(atan2(3.*x, 2.*y), 'atan2{s}(3.0{S}*x, 2.0{S}*y)') check(sinh(3.*x + 2.), 'sinh{s}(3.0{S}*x + 2.0{S})') check(cosh(3.*x - 1.), 'cosh{s}(3.0{S}*x - 1.0{S})') check(tanh(4.0*y + 2.), 'tanh{s}(4.0{S}*y + 2.0{S})') check(asinh(3.*x + 2.), 'asinh{s}(3.0{S}*x + 2.0{S})') check(acosh(3.*x + 2.), 'acosh{s}(3.0{S}*x + 2.0{S})') check(atanh(3.*x + 2.), 'atanh{s}(3.0{S}*x + 2.0{S})') check(erf(42.*x), 'erf{s}(42.0{S}*x)') check(erfc(42.*x), 'erfc{s}(42.0{S}*x)') check(gamma(x), 'tgamma{s}(x)') check(loggamma(x), 'lgamma{s}(x)') check(ceiling(x + 2.), "ceil{s}(x + 2.0{S})") check(floor(x + 2.), "floor{s}(x + 2.0{S})") check(fma(x, y, -z), 'fma{s}(x, y, -z)') check(Max(x, 8.0, x**4.0), 'fmax{s}(8.0{S}, fmax{s}(x, pow{s}(x, 4.0{S})))') check(Min(x, 2.0), 'fmin{s}(2.0{S}, x)')
def decimal_dig(self): """ Number of digits needed to store & load without loss. Number of decimal digits needed to guarantee that two consecutive conversions (float -> text -> float) to be idempotent. This is useful when one do not want to loose precision due to rounding errors when storing a floating point value as text. """ from sympy.functions import ceiling, log return ceiling((self.nmant + 1) * log(2)/log(10) + 1)
def decimal_dig(self): """ Number of digits needed to store & load without loss. Number of decimal digits needed to guarantee that two consecutive conversions (float -> text -> float) to be idempotent. This is useful when one do not want to loose precision due to rounding errors when storing a floating point value as text. """ from sympy.functions import ceiling, log return ceiling((self.nmant + 1) * log(2) / log(10) + 1)
def test_Function(): assert mcode(sin(x) ** cos(x)) == "sin(x).^cos(x)" assert mcode(abs(x)) == "abs(x)" assert mcode(ceiling(x)) == "ceil(x)" assert mcode(arg(x)) == "angle(x)" assert mcode(im(x)) == "imag(x)" assert mcode(re(x)) == "real(x)" assert mcode(Max(x, y) + Min(x, y)) == "max(x, y) + min(x, y)" assert mcode(Max(x, y, z)) == "max(x, max(y, z))" assert mcode(Min(x, y, z)) == "min(x, min(y, z))"
def test_user_functions(): x = symbols('x', integer=False) n = symbols('n', integer=True) custom_functions = { "ceiling": "ceil", "Abs": [(lambda x: not x.is_integer, "fabs", 4), (lambda x: x.is_integer, "abs", 4)], } assert rust_code(ceiling(x), user_functions=custom_functions) == "x.ceil()" assert rust_code(Abs(x), user_functions=custom_functions) == "fabs(x)" assert rust_code(Abs(n), user_functions=custom_functions) == "abs(n)"
def test_ccode_user_functions(): x = symbols("x", integer=False) n = symbols("n", integer=True) custom_functions = { "ceiling": "ceil", "Abs": [(lambda x: not x.is_integer, "fabs"), (lambda x: x.is_integer, "abs")], } assert ccode(ceiling(x), user_functions=custom_functions) == "ceil(x)" assert ccode(Abs(x), user_functions=custom_functions) == "fabs(x)" assert ccode(Abs(n), user_functions=custom_functions) == "abs(n)"
def test_Matrices(): assert julia_code(Matrix(1, 1, [10])) == "[10]" A = Matrix([[1, sin(x / 2), abs(x)], [0, 1, pi], [0, exp(1), ceiling(x)]]) expected = "[1 sin(x/2) abs(x);\n" "0 1 pi;\n" "0 e ceil(x)]" assert julia_code(A) == expected # row and columns assert julia_code(A[:, 0]) == "[1, 0, 0]" assert julia_code(A[0, :]) == "[1 sin(x/2) abs(x)]" # empty matrices assert julia_code(Matrix(0, 0, [])) == "zeros(0, 0)" assert julia_code(Matrix(0, 3, [])) == "zeros(0, 3)" # annoying to read but correct assert julia_code(Matrix([[x, x - y, -y]])) == "[x x - y -y]"
def test_Matrices(): assert mcode(Matrix(1, 1, [10])) == "10" A = Matrix([[1, sin(x / 2), abs(x)], [0, 1, pi], [0, exp(1), ceiling(x)]]) expected = "[1 sin(x/2) abs(x); 0 1 pi; 0 exp(1) ceil(x)]" assert mcode(A) == expected # row and columns assert mcode(A[:, 0]) == "[1; 0; 0]" assert mcode(A[0, :]) == "[1 sin(x/2) abs(x)]" # empty matrices assert mcode(Matrix(0, 0, [])) == '[]' assert mcode(Matrix(0, 3, [])) == 'zeros(0, 3)' # annoying to read but correct assert mcode(Matrix([[x, x - y, -y]])) == "[x x - y -y]"
def test_Matrices(): assert mcode(Matrix(1, 1, [10])) == "10" A = Matrix([[1, sin(x/2), abs(x)], [0, 1, pi], [0, exp(1), ceiling(x)]]); expected = "[1 sin(x/2) abs(x); 0 1 pi; 0 exp(1) ceil(x)]" assert mcode(A) == expected # row and columns assert mcode(A[:,0]) == "[1; 0; 0]" assert mcode(A[0,:]) == "[1 sin(x/2) abs(x)]" # empty matrices assert mcode(Matrix(0, 0, [])) == '[]' assert mcode(Matrix(0, 3, [])) == 'zeros(0, 3)' # annoying to read but correct assert mcode(Matrix([[x, x - y, -y]])) == "[x x - y -y]"
def test_Function_change_name(): assert mcode(abs(x)) == "abs(x)" assert mcode(ceiling(x)) == "ceil(x)" assert mcode(arg(x)) == "angle(x)" assert mcode(im(x)) == "imag(x)" assert mcode(re(x)) == "real(x)" assert mcode(conjugate(x)) == "conj(x)" assert mcode(chebyshevt(y, x)) == "chebyshevT(y, x)" assert mcode(chebyshevu(y, x)) == "chebyshevU(y, x)" assert mcode(laguerre(x, y)) == "laguerreL(x, y)" assert mcode(Chi(x)) == "coshint(x)" assert mcode(Shi(x)) == "sinhint(x)" assert mcode(Ci(x)) == "cosint(x)" assert mcode(Si(x)) == "sinint(x)" assert mcode(li(x)) == "logint(x)" assert mcode(loggamma(x)) == "gammaln(x)" assert mcode(polygamma(x, y)) == "psi(x, y)" assert mcode(RisingFactorial(x, y)) == "pochhammer(x, y)" assert mcode(DiracDelta(x)) == "dirac(x)" assert mcode(DiracDelta(x, 3)) == "dirac(3, x)" assert mcode(Heaviside(x)) == "heaviside(x)" assert mcode(Heaviside(x, y)) == "heaviside(x, y)"
def test_ccode_exceptions(): assert ccode(gamma(x), standard='C99') == "tgamma(x)" assert 'not supported in c' in ccode(gamma(x), standard='C89').lower() assert ccode(ceiling(x)) == "ceil(x)" assert ccode(Abs(x)) == "fabs(x)" assert ccode(gamma(x)) == "tgamma(x)"
def test_Functions(): assert rust_code(sin(x) ** cos(x)) == "x.sin().powf(x.cos())" assert rust_code(abs(x)) == "x.abs()" assert rust_code(ceiling(x)) == "x.ceil()"
def test_ccode_exceptions(): assert ccode(ceiling(x)) == "ceil(x)" assert ccode(Abs(x)) == "fabs(x)"
def test_jscode_exceptions(): assert jscode(ceiling(x)) == "Math.ceil(x)" assert jscode(Abs(x)) == "Math.abs(x)"
def test_glsl_code_exceptions(): assert glsl_code(ceiling(x)) == "ceil(x)" assert glsl_code(Abs(x)) == "abs(x)"
def test_Function(): assert maple_code(sin(x)**cos(x)) == "sin(x)^cos(x)" assert maple_code(abs(x)) == "abs(x)" assert maple_code(ceiling(x)) == "ceil(x)"
def test_Function(): assert julia_code(sin(x) ** cos(x)) == "sin(x).^cos(x)" assert julia_code(abs(x)) == "abs(x)" assert julia_code(ceiling(x)) == "ceil(x)"
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 _eval_nseries(self, x, x0, n): from sympy import powsimp, collect def geto(e): "Returns the O(..) symbol, or None if there is none." if e.is_Order: return e if e.is_Add: for x in e.args: if x.is_Order: return x def getn(e): """ Returns the order of the expression "e". The order is determined either from the O(...) term. If there is no O(...) term, it returns None. Example: >>> getn(1+x+O(x**2)) 2 >>> getn(1+x) >>> """ o = geto(e) if o is None: return None else: o = o.expr if o.is_Symbol: return Integer(1) if o.is_Pow: return o.args[1] n, d = o.as_numer_denom() if d.func is log: # i.e. o = x**2/log(x) if n.is_Symbol: return Integer(1) if n.is_Pow: return n.args[1] raise NotImplementedError() base, exp = self.args if exp.is_Integer: if exp > 0: # positive integer powers are easy to expand, e.g.: # sin(x)**4 = (x-x**3/3+...)**4 = ... return (base.nseries(x, x0, n) ** exp)._eval_expand_multinomial(deep = False) elif exp == -1: # this is also easy to expand using the formula: # 1/(1 + x) = 1 + x + x**2 + x**3 ... # so we need to rewrite base to the form "1+x" from sympy import log if base.has(log(x)): # we need to handle the log(x) singularity: assert x0 == 0 y = Symbol("y", dummy=True) p = self.subs(log(x), -1/y) if not p.has(x): p = p.nseries(y, x0, n) p = p.subs(y, -1/log(x)) return p base = base.nseries(x, x0, n) if base.has(log(x)): # we need to handle the log(x) singularity: assert x0 == 0 y = Symbol("y", dummy=True) self0 = 1/base p = self0.subs(log(x), -1/y) if not p.has(x): p = p.nseries(y, x0, n) p = p.subs(y, -1/log(x)) return p prefactor = base.as_leading_term(x) # express "rest" as: rest = 1 + k*x**l + ... + O(x**n) rest = ((base-prefactor)/prefactor)._eval_expand_mul() if rest == 0: # if prefactor == w**4 + x**2*w**4 + 2*x*w**4, we need to # factor the w**4 out using collect: return 1/collect(prefactor, x) if rest.is_Order: return (1+rest)/prefactor n2 = getn(rest) if n2 is not None: n = n2 term2 = collect(rest.as_leading_term(x), x) k, l = Wild("k"), Wild("l") r = term2.match(k*x**l) k, l = r[k], r[l] if l.is_Rational and l>0: pass elif l.is_number and l>0: l = l.evalf() else: raise NotImplementedError() from sympy.functions import ceiling terms = [1/prefactor] for m in xrange(1,ceiling(n/l)): new_term = terms[-1]*(-rest) if new_term.is_Pow: new_term = new_term._eval_expand_multinomial(deep = False) else: new_term = new_term._eval_expand_mul(deep = False) terms.append(new_term) r = Add(*terms) if n2 is None: # Append O(...) because it is not included in "r" from sympy import O r += O(x**n) return powsimp(r, deep=True, combine='exp') else: # negative powers are rewritten to the cases above, for example: # sin(x)**(-4) = 1/( sin(x)**4) = ... # and expand the denominator: denominator = (base**(-exp)).nseries(x, x0, n) if 1/denominator == self: return self # now we have a type 1/f(x), that we know how to expand return (1/denominator).nseries(x, x0, n) if exp.has(x): import sympy return sympy.exp(exp*sympy.log(base)).nseries(x, x0, n) if base == x: return powsimp(self, deep=True, combine='exp') order = C.Order(x**n, x) x = order.symbols[0] e = self.exp b = self.base ln = C.log exp = C.exp if e.has(x): return exp(e * ln(b)).nseries(x, x0, n) if b==x: return self b0 = b.limit(x,0) if b0 is S.Zero or b0.is_unbounded: lt = b.as_leading_term(x) o = order * lt**(1-e) bs = b.nseries(x, x0, n-e) if bs.is_Add: bs = bs.removeO() if bs.is_Add: # bs -> lt + rest -> lt * (1 + (bs/lt - 1)) return (lt**e * ((bs/lt).expand()**e).nseries(x, x0, n-e)).expand() + order return bs**e+order o2 = order * (b0**-e) # b -> b0 + (b-b0) -> b0 * (1 + (b/b0-1)) z = (b/b0-1) #r = self._compute_oseries3(z, o2, self.taylor_term) x = o2.symbols[0] ln = C.log o = C.Order(z, x) if o is S.Zero: r = (1+z) else: if o.expr.is_number: e2 = ln(o2.expr*x)/ln(x) else: e2 = ln(o2.expr)/ln(o.expr) n = e2.limit(x,0) + 1 if n.is_unbounded: # requested accuracy gives infinite series, # order is probably nonpolynomial e.g. O(exp(-1/x), x). r = (1+z) else: try: n = int(n) except TypeError: #well, the n is something more complicated (like 1+log(2)) n = int(n.evalf()) + 1 assert n>=0,`n` l = [] g = None for i in xrange(n+2): g = self.taylor_term(i, z, g) g = g.nseries(x, x0, n) l.append(g) r = Add(*l) return r * b0**e + order
def test_Function(): assert julia_code(sin(x)**cos(x)) == "sin(x).^cos(x)" assert julia_code(abs(x)) == "abs(x)" assert julia_code(ceiling(x)) == "ceil(x)"
def _eval_nseries(self, x, x0, n): from sympy import powsimp, collect def geto(e): "Returns the O(..) symbol, or None if there is none." if e.is_Order: return e if e.is_Add: for x in e.args: if x.is_Order: return x def getn(e): """ Returns the order of the expression "e". The order is determined either from the O(...) term. If there is no O(...) term, it returns None. Example: >>> getn(1+x+O(x**2)) 2 >>> getn(1+x) >>> """ o = geto(e) if o is None: return None else: o = o.expr if o.is_Symbol: return Integer(1) if o.is_Pow: return o.args[1] n, d = o.as_numer_denom() if isinstance(d, log): # i.e. o = x**2/log(x) if n.is_Symbol: return Integer(1) if n.is_Pow: return n.args[1] raise NotImplementedError() base, exp = self.args if exp.is_Integer: if exp > 0: # positive integer powers are easy to expand, e.g.: # sin(x)**4 = (x-x**3/3+...)**4 = ... return (base.nseries(x, x0, n) ** exp)._eval_expand_multinomial(deep=False) elif exp == -1: # this is also easy to expand using the formula: # 1/(1 + x) = 1 + x + x**2 + x**3 ... # so we need to rewrite base to the form "1+x" from sympy import log if base.has(log(x)): # we need to handle the log(x) singularity: assert x0 == 0 y = Symbol("y", dummy=True) p = self.subs(log(x), -1 / y) if not p.has(x): p = p.nseries(y, x0, n) p = p.subs(y, -1 / log(x)) return p base = base.nseries(x, x0, n) if base.has(log(x)): # we need to handle the log(x) singularity: assert x0 == 0 y = Symbol("y", dummy=True) self0 = 1 / base p = self0.subs(log(x), -1 / y) if not p.has(x): p = p.nseries(y, x0, n) p = p.subs(y, -1 / log(x)) return p prefactor = base.as_leading_term(x) # express "rest" as: rest = 1 + k*x**l + ... + O(x**n) rest = ((base - prefactor) / prefactor)._eval_expand_mul() if rest == 0: # if prefactor == w**4 + x**2*w**4 + 2*x*w**4, we need to # factor the w**4 out using collect: return 1 / collect(prefactor, x) if rest.is_Order: return (1 + rest) / prefactor n2 = getn(rest) if n2 is not None: n = n2 term2 = collect(rest.as_leading_term(x), x) k, l = Wild("k"), Wild("l") r = term2.match(k * x ** l) k, l = r[k], r[l] if l.is_Rational and l > 0: pass elif l.is_number and l > 0: l = l.evalf() else: raise NotImplementedError() from sympy.functions import ceiling terms = [1 / prefactor] for m in xrange(1, ceiling(n / l)): new_term = terms[-1] * (-rest) if new_term.is_Pow: new_term = new_term._eval_expand_multinomial(deep=False) else: new_term = new_term._eval_expand_mul(deep=False) terms.append(new_term) r = Add(*terms) if n2 is None: # Append O(...) because it is not included in "r" from sympy import O r += O(x ** n) return powsimp(r, deep=True, combine="exp") else: # negative powers are rewritten to the cases above, for example: # sin(x)**(-4) = 1/( sin(x)**4) = ... # and expand the denominator: denominator = (base ** (-exp)).nseries(x, x0, n) if 1 / denominator == self: return self # now we have a type 1/f(x), that we know how to expand return (1 / denominator).nseries(x, x0, n) if exp.has(x): import sympy return sympy.exp(exp * sympy.log(base)).nseries(x, x0, n) if base == x: return powsimp(self, deep=True, combine="exp") order = C.Order(x ** n, x) x = order.symbols[0] e = self.exp b = self.base ln = C.log exp = C.exp if e.has(x): return exp(e * ln(b)).nseries(x, x0, n) if b == x: return self b0 = b.limit(x, 0) if b0 is S.Zero or b0.is_unbounded: lt = b.as_leading_term(x) o = order * lt ** (1 - e) bs = b.nseries(x, x0, n - e) if bs.is_Add: bs = bs.removeO() if bs.is_Add: # bs -> lt + rest -> lt * (1 + (bs/lt - 1)) return (lt ** e * ((bs / lt).expand() ** e).nseries(x, x0, n - e)).expand() + order return bs ** e + order o2 = order * (b0 ** -e) # b -> b0 + (b-b0) -> b0 * (1 + (b/b0-1)) z = b / b0 - 1 # r = self._compute_oseries3(z, o2, self.taylor_term) x = o2.symbols[0] ln = C.log o = C.Order(z, x) if o is S.Zero: r = 1 + z else: if o.expr.is_number: e2 = ln(o2.expr * x) / ln(x) else: e2 = ln(o2.expr) / ln(o.expr) n = e2.limit(x, 0) + 1 if n.is_unbounded: # requested accuracy gives infinite series, # order is probably nonpolynomial e.g. O(exp(-1/x), x). r = 1 + z else: try: n = int(n) except TypeError: # well, the n is something more complicated (like 1+log(2)) n = int(n.evalf()) + 1 assert n >= 0, ` n ` l = [] g = None for i in xrange(n + 2): g = self.taylor_term(i, z, g) g = g.nseries(x, x0, n) l.append(g) r = Add(*l) return r * b0 ** e + order
def test_rcode_exceptions(): assert rcode(ceiling(x)) == "ceiling(x)" assert rcode(Abs(x)) == "abs(x)" assert rcode(gamma(x)) == "gamma(x)"
def test_ccode_functions(): assert ccode(sin(x) ** cos(x)) == "pow(sin(x), cos(x))" assert ccode(ceiling(x)) == "ceil(x)" assert ccode(Abs(x)) == "fabs(x)" assert ccode(gamma(x)) == "tgamma(x)"
def test_ccode_exceptions(): assert ccode(ceiling(x)) == "ceil(x)" assert ccode(Abs(x)) == "fabs(x)" assert ccode(gamma(x)) == "tgamma(x)"
def test_C99CodePrinter__precision(): n = symbols("n", integer=True) f32_printer = C99CodePrinter(dict(type_aliases={real: float32})) f64_printer = C99CodePrinter(dict(type_aliases={real: float64})) f80_printer = C99CodePrinter(dict(type_aliases={real: float80})) assert f32_printer.doprint(sin(x + 2.1)) == "sinf(x + 2.1F)" assert f64_printer.doprint(sin(x + 2.1)) == "sin(x + 2.1000000000000001)" assert f80_printer.doprint(sin(x + Float("2.0"))) == "sinl(x + 2.0L)" for printer, suffix in zip([f32_printer, f64_printer, f80_printer], ["f", "", "l"]): def check(expr, ref): assert printer.doprint(expr) == ref.format(s=suffix, S=suffix.upper()) check(Abs(n), "abs(n)") check(Abs(x + 2.0), "fabs{s}(x + 2.0{S})") check( sin(x + 4.0) ** cos(x - 2.0), "pow{s}(sin{s}(x + 4.0{S}), cos{s}(x - 2.0{S}))", ) check(exp(x * 8.0), "exp{s}(8.0{S}*x)") check(exp2(x), "exp2{s}(x)") check(expm1(x * 4.0), "expm1{s}(4.0{S}*x)") check(Mod(n, 2), "((n) % (2))") check(Mod(2 * n + 3, 3 * n + 5), "((2*n + 3) % (3*n + 5))") check(Mod(x + 2.0, 3.0), "fmod{s}(1.0{S}*x + 2.0{S}, 3.0{S})") check(Mod(x, 2.0 * x + 3.0), "fmod{s}(1.0{S}*x, 2.0{S}*x + 3.0{S})") check(log(x / 2), "log{s}((1.0{S}/2.0{S})*x)") check(log10(3 * x / 2), "log10{s}((3.0{S}/2.0{S})*x)") check(log2(x * 8.0), "log2{s}(8.0{S}*x)") check(log1p(x), "log1p{s}(x)") check(2 ** x, "pow{s}(2, x)") check(2.0 ** x, "pow{s}(2.0{S}, x)") check(x ** 3, "pow{s}(x, 3)") check(x ** 4.0, "pow{s}(x, 4.0{S})") check(sqrt(3 + x), "sqrt{s}(x + 3)") check(Cbrt(x - 2.0), "cbrt{s}(x - 2.0{S})") check(hypot(x, y), "hypot{s}(x, y)") check(sin(3.0 * x + 2.0), "sin{s}(3.0{S}*x + 2.0{S})") check(cos(3.0 * x - 1.0), "cos{s}(3.0{S}*x - 1.0{S})") check(tan(4.0 * y + 2.0), "tan{s}(4.0{S}*y + 2.0{S})") check(asin(3.0 * x + 2.0), "asin{s}(3.0{S}*x + 2.0{S})") check(acos(3.0 * x + 2.0), "acos{s}(3.0{S}*x + 2.0{S})") check(atan(3.0 * x + 2.0), "atan{s}(3.0{S}*x + 2.0{S})") check(atan2(3.0 * x, 2.0 * y), "atan2{s}(3.0{S}*x, 2.0{S}*y)") check(sinh(3.0 * x + 2.0), "sinh{s}(3.0{S}*x + 2.0{S})") check(cosh(3.0 * x - 1.0), "cosh{s}(3.0{S}*x - 1.0{S})") check(tanh(4.0 * y + 2.0), "tanh{s}(4.0{S}*y + 2.0{S})") check(asinh(3.0 * x + 2.0), "asinh{s}(3.0{S}*x + 2.0{S})") check(acosh(3.0 * x + 2.0), "acosh{s}(3.0{S}*x + 2.0{S})") check(atanh(3.0 * x + 2.0), "atanh{s}(3.0{S}*x + 2.0{S})") check(erf(42.0 * x), "erf{s}(42.0{S}*x)") check(erfc(42.0 * x), "erfc{s}(42.0{S}*x)") check(gamma(x), "tgamma{s}(x)") check(loggamma(x), "lgamma{s}(x)") check(ceiling(x + 2.0), "ceil{s}(x + 2.0{S})") check(floor(x + 2.0), "floor{s}(x + 2.0{S})") check(fma(x, y, -z), "fma{s}(x, y, -z)") check(Max(x, 8.0, x ** 4.0), "fmax{s}(8.0{S}, fmax{s}(x, pow{s}(x, 4.0{S})))") check(Min(x, 2.0), "fmin{s}(2.0{S}, x)")
def test_torch_math(): if not torch: skip("Torch not installed") ma = torch.tensor([[1, 2, -3, -4]]) expr = Abs(x) assert torch_code(expr) == "torch.abs(x)" f = lambdify(x, expr, 'torch') y = f(ma) c = torch.abs(ma) assert (y == c).all() expr = sign(x) assert torch_code(expr) == "torch.sign(x)" _compare_torch_scalar((x, ), expr, rng=lambda: random.randint(0, 10)) expr = ceiling(x) assert torch_code(expr) == "torch.ceil(x)" _compare_torch_scalar((x, ), expr, rng=lambda: random.random()) expr = floor(x) assert torch_code(expr) == "torch.floor(x)" _compare_torch_scalar((x, ), expr, rng=lambda: random.random()) expr = exp(x) assert torch_code(expr) == "torch.exp(x)" _compare_torch_scalar((x, ), expr, rng=lambda: random.random()) # expr = sqrt(x) # assert torch_code(expr) == "torch.sqrt(x)" # _compare_torch_scalar((x,), expr, rng=lambda: random.random()) # expr = x ** 4 # assert torch_code(expr) == "torch.pow(x, 4)" # _compare_torch_scalar((x,), expr, rng=lambda: random.random()) expr = cos(x) assert torch_code(expr) == "torch.cos(x)" _compare_torch_scalar((x, ), expr, rng=lambda: random.random()) expr = acos(x) assert torch_code(expr) == "torch.acos(x)" _compare_torch_scalar((x, ), expr, rng=lambda: random.uniform(0, 0.95)) expr = sin(x) assert torch_code(expr) == "torch.sin(x)" _compare_torch_scalar((x, ), expr, rng=lambda: random.random()) expr = asin(x) assert torch_code(expr) == "torch.asin(x)" _compare_torch_scalar((x, ), expr, rng=lambda: random.random()) expr = tan(x) assert torch_code(expr) == "torch.tan(x)" _compare_torch_scalar((x, ), expr, rng=lambda: random.random()) expr = atan(x) assert torch_code(expr) == "torch.atan(x)" _compare_torch_scalar((x, ), expr, rng=lambda: random.random()) # expr = atan2(y, x) # assert torch_code(expr) == "torch.atan2(y, x)" # _compare_torch_scalar((y, x), expr, rng=lambda: random.random()) expr = cosh(x) assert torch_code(expr) == "torch.cosh(x)" _compare_torch_scalar((x, ), expr, rng=lambda: random.random()) expr = acosh(x) assert torch_code(expr) == "torch.acosh(x)" _compare_torch_scalar((x, ), expr, rng=lambda: random.uniform(1, 2)) expr = sinh(x) assert torch_code(expr) == "torch.sinh(x)" _compare_torch_scalar((x, ), expr, rng=lambda: random.uniform(1, 2)) expr = asinh(x) assert torch_code(expr) == "torch.asinh(x)" _compare_torch_scalar((x, ), expr, rng=lambda: random.uniform(1, 2)) expr = tanh(x) assert torch_code(expr) == "torch.tanh(x)" _compare_torch_scalar((x, ), expr, rng=lambda: random.uniform(1, 2)) expr = atanh(x) assert torch_code(expr) == "torch.atanh(x)" _compare_torch_scalar((x, ), expr, rng=lambda: random.uniform(-.5, .5)) expr = erf(x) assert torch_code(expr) == "torch.erf(x)" _compare_torch_scalar((x, ), expr, rng=lambda: random.random()) expr = loggamma(x) assert torch_code(expr) == "torch.lgamma(x)" _compare_torch_scalar((x, ), expr, rng=lambda: random.random())
def test_ccode_functions(): assert ccode(sin(x)**cos(x)) == "pow(sin(x), cos(x))" assert ccode(ceiling(x)) == "ceil(x)" assert ccode(Abs(x)) == "fabs(x)" assert ccode(gamma(x)) == "tgamma(x)"