def _eval_(self, a, z): """ EXAMPLES:: sage: struve_L(-2,0) struve_L(-2, 0) sage: struve_L(-1,0) 0 sage: struve_L(pi,0) 0 sage: struve_L(-1/2,x) sqrt(2)*sqrt(1/(pi*x))*sinh(x) sage: struve_L(1/2,1) sqrt(2)*(cosh(1) - 1)/sqrt(pi) sage: struve_L(2,x) struve_L(2, x) sage: struve_L(-3/2,x) -bessel_I(3/2, x) """ from sage.symbolic.ring import SR if z.is_zero() \ and (SR(a).is_numeric() or SR(a).is_constant()) \ and a.real() >= -1: return ZZ(0) if a == -Integer(1)/2: from sage.functions.hyperbolic import sinh return sqrt(2/(pi*z)) * sinh(z) if a == Integer(1)/2: from sage.functions.hyperbolic import cosh return sqrt(2/(pi*z)) * (cosh(z)-1) if a < 0 and not SR(a).is_integer() and SR(2*a).is_integer(): from sage.rings.rational_field import QQ n = (a*(-2) - 1)/2 return Integer(-1)**n * bessel_I(n+QQ(1)/2, z)
def _eval_(self, a, z): """ EXAMPLES:: sage: struve_H(0,0) 0 sage: struve_H(pi,0) 0 sage: struve_H(-1/2,x) sqrt(2)*sqrt(1/(pi*x))*sin(x) sage: struve_H(1/2,-1) -sqrt(2)*sqrt(-1/pi)*(cos(1) - 1) sage: struve_H(1/2,pi) 2*sqrt(2)/pi sage: struve_H(2,x) struve_H(2, x) sage: struve_H(-3/2,x) -bessel_J(3/2, x) """ from sage.symbolic.ring import SR if z.is_zero() \ and (SR(a).is_numeric() or SR(a).is_constant()) \ and a.real() >= -1: return ZZ(0) if a == -Integer(1)/2: from sage.functions.trig import sin return sqrt(2/(pi*z)) * sin(z) if a == Integer(1)/2: from sage.functions.trig import cos return sqrt(2/(pi*z)) * (1-cos(z)) if a < 0 and not SR(a).is_integer() and SR(2*a).is_integer(): from sage.rings.rational_field import QQ n = (a*(-2) - 1)/2 return Integer(-1)**n * bessel_J(n+QQ(1)/2, z)
def _step_upper_bound_low_mem(r, m, q, generating_function): r""" Low memory implementation of :func:`_step_upper_bound_internal`. Significantly slower, but the memory footprint does not significantly increase even if the series coefficients need to be computed to very high degree terms. """ L = LieAlgebra(ZZ, ['X_%d' % k for k in range(r)]).Lyndon() dim_fm = L.graded_dimension(m) PR = PolynomialRing(ZZ, 't') t = PR.gen() a = (1 - dim_fm * (1 - t**q)) * t**m b = PR.one() for k in range(1, m): b *= (1 - t**k)**L.graded_dimension(k) # extract initial coefficients from a symbolic series expansion bd = b.degree() id = max(a.degree() + 1, bd) offset = id - bd quot = SR(a / b) sym_t = SR(t) qs = quot.series(sym_t, id) # check if partial sum is positive already within series expansion # store the last offset...id terms to start the linear recurrence coeffs = deque() cumul = ZZ.zero() for s in range(id): c = ZZ(qs.coefficient(sym_t, s)) cumul += c if s >= offset: coeffs.append(c) if cumul > 0: if generating_function: return s, quot return s # the rest of the coefficients are defined by a recurrence relation multipliers = [-b.monomial_coefficient(t**(bd - k)) for k in range(bd)] while cumul <= 0: c_next = sum(c * m for c, m in zip(coeffs, multipliers)) cumul += c_next s += 1 coeffs.append(c_next) coeffs.popleft() if generating_function: return s, quot return s
def max_to_sr(expr): r""" Convert a Maxima object into a symbolic expression. INPUT: - ``expr`` - ECL object OUTPUT: symbolic expression EXAMPLES:: sage: from sage.interfaces.maxima_lib import maxima_lib, max_to_sr sage: f = maxima_lib('f(x)') sage: f.ecl() <ECL: (($F SIMP) $X)> sage: max_to_sr(f.ecl()) f(x) TESTS:: sage: from sage.interfaces.maxima_lib import sr_to_max, max_to_sr sage: f = function('f',x).diff() sage: bool(max_to_sr(sr_to_max(f)) == f) True """ if expr.consp(): op_max=caar(expr) if op_max in special_max_to_sage: return special_max_to_sage[op_max](expr) if not(op_max in max_op_dict): # This could be unsafe if the conversion to SR # changes the structure of expr sage_expr=SR(maxima(expr)) max_op_dict[op_max]=sage_expr.operator() sage_op_dict[sage_expr.operator()]=op_max op=max_op_dict[op_max] max_args=cdr(expr) args=[max_to_sr(a) for a in max_args] return op(*args) elif expr.symbolp(): if not(expr in max_sym_dict): sage_symbol=SR(maxima(expr)) sage_sym_dict[sage_symbol]=expr max_sym_dict[expr]=sage_symbol return max_sym_dict[expr] else: e=expr.python() if isinstance(e,float): return sage.rings.real_double.RealDoubleElement(e) return e
def simplify_abs_trig(expr): r""" Simplify abs(sin(...)) in symbolic expressions """ from sage.symbolic.ring import SR from sage.symbolic.constants import pi sexpr = str(expr) if 'abs(sin(' not in sexpr: # nothing to simplify return expr tp = [] val = [] for pos in range(len(sexpr)): if sexpr[pos:pos + 8] == 'abs(sin(': # finding the end of abs argument: scan = pos + 4 # start of abs parenth = 1 while parenth != 0: if sexpr[scan] == '(': parenth += 1 if sexpr[scan] == ')': parenth -= 1 scan += 1 pos_abs_end = scan # finding the end of sin argument: scan = pos + 8 # start of sin parenth = 1 while parenth != 0: if sexpr[scan] == '(': parenth += 1 if sexpr[scan] == ')': parenth -= 1 scan += 1 pos_sin_end = scan # if the abs contains only the sinus, the simplification can be tried: if pos_sin_end == pos_abs_end - 1: tp.append(pos) val.append(sexpr[pos:pos_abs_end]) simp = [] for v in val: # argument of the sinus: sx = v[8:-2] x = SR(sx) if x >= 0 and x <= pi: simp.append('sin(' + sx + ')') elif x >= -pi and x <= 0: simp.append('(-sin(' + sx + '))') else: simp.append(v) # no simplification is applicable nexpr = "" pos0 = 0 for i, pos in enumerate(tp): nexpr += sexpr[pos0:pos] + simp[i] pos0 = pos + len(val[i]) nexpr += sexpr[pos0:] return SR(nexpr)
def simplify_sqrt_real(expr): r""" Simplify sqrt in symbolic expressions in the real domain. EXAMPLES: Simplifications of basic expressions:: sage: assume(x<0) sage: simplify_sqrt_real( sqrt(x^2) ) -x sage: simplify_sqrt_real( sqrt(x^2-2*x+1) ) -x + 1 sage: simplify_sqrt_real( sqrt(x^2) + sqrt(x^2-2*x+1) ) -2*x + 1 """ from sage.symbolic.ring import SR from sage.calculus.calculus import maxima # 1/ Search for the sqrt's in expr sexpr = str(expr) if 'sqrt(' not in sexpr: # no sqrt to simplify return expr pos_sqrts = [] # positions of the sqrt's in sexpr the_sqrts = [] # the sqrt sub-expressions in sexpr for pos in range(len(sexpr)): if sexpr[pos:pos + 5] == 'sqrt(': pos_sqrts.append(pos) parenth = 1 scan = pos + 5 while parenth != 0: if sexpr[scan] == '(': parenth += 1 if sexpr[scan] == ')': parenth -= 1 scan += 1 the_sqrts.append(sexpr[pos:scan]) # 2/ Simplifications of the sqrt's new_expr = "" # will contain the result pos0 = 0 for i, pos in enumerate(pos_sqrts): # radcan is called on each sqrt: x = SR(the_sqrts[i]) simpl = SR(x._maxima_().radcan()) # the absolute value of radcan's output is taken, the call to simplify() # taking into account possible assumptions regarding the sign of simpl: new_expr += sexpr[pos0:pos] + '(' + str(abs(simpl).simplify()) + ')' pos0 = pos + len(the_sqrts[i]) new_expr += sexpr[pos0:] return SR(new_expr)
def fourier_series_sine_coefficient(cls, self, parameters, variable, n, L): r""" Returns the n-th Fourier series coefficient of `\sin(n\pi x/L)`, `b_n`. INPUT: - ``self`` - the function f(x), defined over -L x L - ``n`` - an integer n0 - ``L`` - (the period)/2 OUTPUT: `b_n = \frac{1}{L}\int_{-L}^L f(x)\sin(n\pi x/L)dx` EXAMPLES:: sage: f(x) = x^2 sage: f = piecewise([[(-1,1),f]]) sage: f.fourier_series_sine_coefficient(2,1) # L=1, n=2 0 """ from sage.all import sin, pi x = SR.var('x') result = 0 for domain, f in parameters: for interval in domain: a = interval.lower() b = interval.upper() result += (f * sin(pi * x * n / L) / L).integrate(x, a, b) return SR(result).simplify_trig()
def _element_constructor_(self, fun): """ Coerce a given function (element of the symbolic ring) into a differential form of degree zero. EXAMPLES:: sage: x, y, z = var('x, y, z') sage: U = CoordinatePatch((x, y, z)) doctest:...: DeprecationWarning: Use Manifold instead. See http://trac.sagemath.org/24444 for details. sage: F = DifferentialForms(U); F doctest:...: DeprecationWarning: For the set of differential forms of degree p, use U.diff_form_module(p), where U is the base manifold (type U.diff_form_module? for details). See http://trac.sagemath.org/24444 for details. Algebra of differential forms in the variables x, y, z sage: F(sin(x*y)) # indirect doctest doctest:...: DeprecationWarning: Use U.diff_form(degree) instead, where U is the base manifold (type U.diff_form? for details). See http://trac.sagemath.org/24444 for details. sin(x*y) """ fun = SR(fun) if fun not in self: raise ValueError("Function not an element of this algebra of differential forms.") return DifferentialForm(self, 0, fun)
def mma_free_integrator(expression, v, a=None, b=None): """ sage: from sage.symbolic.integration.external import mma_free_integrator sage: mma_free_integrator(sin(x), x) # optional - internet -cos(x) """ import urllib, re # We need to integrate against x vars = [str(x) for x in expression.variables()] if any(len(x) > 1 for x in vars): raise NotImplementedError, "Mathematica online integrator can only handle single letter variables." x = SR.var('x') if repr(v) != 'x': for i in range(ord('a'), ord('z') + 1): if chr(i) not in vars: shadow_x = SR.var(chr(i)) break expression = expression.subs({x: shadow_x}).subs({dvar: x}) params = urllib.urlencode({ 'expr': expression._mathematica_init_(), 'random': 'false' }) page = urllib.urlopen("http://integrals.wolfram.com/index.jsp", params).read() page = page[page.index('"inputForm"'):page.index('"outputForm"')] page = re.sub("\s", "", page) mexpr = re.match(r".*Integrate.*==</em><br/>(.*)</p>", page).groups()[0] try: ans = SR(mexpr.lower().replace('[', '(').replace(']', ')')) if repr(v) != 'x': ans = ans.subs({x: v}).subs({shadow_x: x}) return ans except TypeError: raise ValueError, "Unable to parse: %s" % mexpr
def bilinear_form(self, R=None): """ Return the bilinear form over ``R`` associated to ``self``. INPUT: - ``R`` -- (default: universal cyclotomic field) a ring used to compute the bilinear form EXAMPLES:: sage: CoxeterType(['A', 2, 1]).bilinear_form() [ 1 -1/2 -1/2] [-1/2 1 -1/2] [-1/2 -1/2 1] sage: CoxeterType(['H', 3]).bilinear_form() [ 1 -1/2 0] [ -1/2 1 1/2*E(5)^2 + 1/2*E(5)^3] [ 0 1/2*E(5)^2 + 1/2*E(5)^3 1] sage: C = CoxeterMatrix([[1,-1,-1],[-1,1,-1],[-1,-1,1]]) sage: C.bilinear_form() [ 1 -1 -1] [-1 1 -1] [-1 -1 1] """ n = self.rank() mat = self.coxeter_matrix()._matrix base_ring = mat.base_ring() from sage.rings.universal_cyclotomic_field import UniversalCyclotomicField UCF = UniversalCyclotomicField() if R is None: R = UCF # if UCF.has_coerce_map_from(base_ring): # R = UCF # else: # R = base_ring # Compute the matrix with entries `- \cos( \pi / m_{ij} )`. if R is UCF: val = lambda x: (R.gen(2 * x) + ~R.gen(2 * x)) / R( -2) if x > -1 else R.one() * x else: from sage.functions.trig import cos from sage.symbolic.constants import pi val = lambda x: -R(cos(pi / SR(x))) if x > -1 else x MS = MatrixSpace(R, n, sparse=True) MC = MS._get_matrix_class() bilinear = MC(MS, entries={(i, j): val(mat[i, j]) for i in range(n) for j in range(n) if mat[i, j] != 2}, coerce=True, copy=True) bilinear.set_immutable() return bilinear
def check_splittingField(self): """ Verify that the splitting field of a Q-polynomial scheme with principal multiplicity more than 2 is at most a degree 2 extension of the field of rational numbers. """ if checkNonneg(2 - self._.m[1]): return if self._has("Q"): M = self._.Q elif self._has("P"): M = self._.P else: M = self.dualEigenmatrix() t = None for r in M[1:, 1:]: for v in r: if len(SR(v).variables()) > 0: continue mp = v.minpoly() if mp.degree() == 1: continue elif mp.degree() == 2: if t is None: t = QQ.extension(mp, 'a')['t'].gen() continue elif not mp(t).is_irreducible(): continue raise InfeasibleError("splitting field of Q-polynomial scheme" " with m[1] > 2 is more than degree 2" " extension of rationals", ["CerzoSuzuki09", "MartinWilliford09"])
def fourier_series_partial_sum(cls, self, parameters, variable, N, L): r""" Returns the partial sum .. math:: f(x) \sim \frac{a_0}{2} + \sum_{n=1}^N [a_n\cos(\frac{n\pi x}{L}) + b_n\sin(\frac{n\pi x}{L})], as a string. EXAMPLE:: sage: f(x) = x^2 sage: f = piecewise([[(-1,1),f]]) sage: f.fourier_series_partial_sum(3,1) cos(2*pi*x)/pi^2 - 4*cos(pi*x)/pi^2 + 1/3 sage: f1(x) = -1 sage: f2(x) = 2 sage: f = piecewise([[(-pi,pi/2),f1],[(pi/2,pi),f2]]) sage: f.fourier_series_partial_sum(3,pi) -3*cos(x)/pi - 3*sin(2*x)/pi + 3*sin(x)/pi - 1/4 """ from sage.all import pi, sin, cos, srange x = self.default_variable() a0 = self.fourier_series_cosine_coefficient(0, L) result = a0 / 2 + sum( [(self.fourier_series_cosine_coefficient(n, L) * cos(n * pi * x / L) + self.fourier_series_sine_coefficient( n, L) * sin(n * pi * x / L)) for n in srange(1, N)]) return SR(result).expand()
def __setitem__(self, subscript, fun): r""" Modify a given component of the differential form. INPUT: - ``subscript``: subscript of the component. Must be an integer or a list of integers. EXAMPLES:: sage: F = DifferentialForms(); F Algebra of differential forms in the variables x, y, z sage: f = DifferentialForm(F, 2) sage: f[1, 2] = x; f x*dy/\dz """ if isinstance(subscript, (Integer, int)): subscript = (subscript, ) else: subscript = tuple(subscript) dim = self.parent().base_space().dim() if any([s >= dim for s in subscript]): raise ValueError("Index out of bounds.") if len(subscript) != self._degree: raise TypeError("%s is not a subscript of degree %s" %\ (subscript, self._degree)) sign, subscript = sort_subscript(subscript) self._components[subscript] = sign * SR(fun)
def max_at_to_sage(expr): r""" Special conversion rule for AT expressions. INPUT: - ``expr`` - ECL object; a Maxima AT expression OUTPUT: symbolic expression EXAMPLES:: sage: from sage.interfaces.maxima_lib import maxima_lib, max_at_to_sage sage: a=maxima_lib("'at(f(x,y,z),[x=1,y=2,z=3])") sage: a 'at(f(x,y,z),[x=1,y=2,z=3]) sage: max_at_to_sage(a.ecl()) f(1, 2, 3) sage: a=maxima_lib("'at(f(x,y,z),x=1)") sage: a 'at(f(x,y,z),x=1) sage: max_at_to_sage(a.ecl()) f(1, y, z) """ arg=max_to_sr(expr.cadr()) subsarg=caddr(expr) if caar(subsarg)==mlist: subsvalues=dict( (v.lhs(),v.rhs()) for v in max_to_sr(subsarg)) else: v=max_to_sr(subsarg) subsvalues=dict([(v.lhs(),v.rhs())]) return SR(arg).subs(subsvalues)
def maxima_integrator(expression, v, a=None, b=None): """ Integration using Maxima EXAMPLES:: sage: from sage.symbolic.integration.external import maxima_integrator sage: maxima_integrator(sin(x), x) -cos(x) sage: maxima_integrator(cos(x), x) sin(x) sage: f(x) = function('f')(x) sage: maxima_integrator(f(x), x) integrate(f(x), x) TESTS: Check that :trac:`25817` is fixed:: sage: maxima_integrator(log(e^x*log(x)*sin(x))/x^2, x) 1/2*(x*(Ei(-log(x)) + conjugate(Ei(-log(x)))) - 2*x*integrate(sin(x)/(x*cos(x)^2 + x*sin(x)^2 + 2*x*cos(x) + x), x) + 2*x*integrate(sin(x)/(x*cos(x)^2 + x*sin(x)^2 - 2*x*cos(x) + x), x) + 2*x*log(x) + 2*log(2) - log(cos(x)^2 + sin(x)^2 + 2*cos(x) + 1) - log(cos(x)^2 + sin(x)^2 - 2*cos(x) + 1) - 2*log(log(x)))/x """ from sage.calculus.calculus import maxima if not isinstance(expression, Expression): expression = SR(expression) if a is None: result = maxima.sr_integral(expression, v) else: result = maxima.sr_integral(expression, v, a, b) return result._sage_()
def populate_polyhedra(self): from sage.geometry.polyhedron.constructor import Polyhedron from sage.symbolic.ring import SR def get_vector(inequality, vars): coefficients = list(inequality.coefficient(var) for var in vars) constant = inequality - sum(c*v for c, v in zip(coefficients, vars)) return [constant] + coefficients d = self.dimension() prefix = self.trees[0].PREFIX vars = list(SR(prefix + "{}".format(j)) for j in range(d+1)) for tree in self.trees: others = list(self.trees) others.remove(tree) ineqs = [other.partition_cost() - tree.partition_cost() for other in others] + vars ineq_matrix = [get_vector(ineq, vars) for ineq in ineqs] P = Polyhedron(ieqs=ineq_matrix) if self.is_disjoint(): P = polyhedron_break_tie(P) tree.polyhedron = P nonnegative_orthant = Polyhedron(ieqs=[dd*(0,) + (1,) + (d+1-dd)*(0,) for dd in range(1, d+1+1)]) assert all(A.polyhedron & nonnegative_orthant == A.polyhedron for A in self.trees) if self.is_disjoint(): assert all((A.polyhedron & B.polyhedron).is_empty() for A in self.trees for B in self.trees if A != B)
def __init__(self, ambient_manifold, n, coordinates, chart_name, embedding_functions, name=None, latex_name=None, ambient_chart=None, start_index=0): from sage.symbolic.ring import SR Manifold.__init__(self, n, name, latex_name, start_index) if not isinstance(ambient_manifold, Manifold): raise TypeError( "The argument ambient_manifold must be a manifold.") self.ambient_manifold = ambient_manifold Chart(self, coordinates, chart_name) if ambient_chart is None: ambient_chart = ambient_manifold.def_chart.name n_amb = ambient_manifold.dim if len(embedding_functions) != n_amb: raise ValueError( str(n_amb) + " coordinate functions must be provided.") embedding_expressions = [ SR(embedding_functions[i]) for i in range(n_amb) ] self.embedding = DiffMapping(self, ambient_manifold, embedding_expressions, chart_name, ambient_chart)
def EllipticCurve_from_cubic(F, P): r""" Construct an elliptic curve from a ternary cubic with a rational point. INPUT: - ``F`` -- a homogeneous cubic in three variables with rational coefficients (either as a polynomial ring element or as a string) defining a smooth plane cubic curve. - ``P`` -- a 3-tuple `(x,y,z)` defining a projective point on the curve `F=0`. OUTPUT: (elliptic curve) An elliptic curve (in minimal Weierstrass form) isomorphic to the curve `F=0`. .. note:: USES MAGMA - This function will not work on computers that do not have magma installed. TO DO: implement this without using MAGMA. For a more general version, see the function ``EllipticCurve_from_plane_curve()``. EXAMPLES: First we find that the Fermat cubic is isomorphic to the curve with Cremona label 27a1:: sage: E = EllipticCurve_from_cubic('x^3 + y^3 + z^3', [1,-1,0]) # optional - magma sage: E # optional - magma Elliptic Curve defined by y^2 + y = x^3 - 7 over Rational Field sage: E.cremona_label() # optional - magma '27a1' Next we find the minimal model and conductor of the Jacobian of the Selmer curve. :: sage: E = EllipticCurve_from_cubic('u^3 + v^3 + 60*w^3', [1,-1,0]) # optional - magma sage: E # optional - magma Elliptic Curve defined by y^2 = x^3 - 24300 over Rational Field sage: E.conductor() # optional - magma 24300 """ from sage.interfaces.all import magma cmd = "P<%s,%s,%s> := ProjectivePlane(RationalField());" % SR( F).variables() magma.eval(cmd) cmd = 'aInvariants(MinimalModel(EllipticCurve(Curve(Scheme(P, %s)),P!%s)));' % ( F, P) s = magma.eval(cmd) return EllipticCurve(rings.RationalField(), eval(s))
def test_issue_4023(): from sage.symbolic.ring import SR from sage.functions.all import log from sympy import integrate, simplify a, x = SR.var("a x") i = integrate(log(x) / a, (x, a, a + 1)) i2 = simplify(i) s = SR(i2) assert s == (a * log(1 + a) - a * log(a) + log(1 + a) - 1) / a
def integral(x, *args, **kwds): """ Returns an indefinite or definite integral of an object x. First call x.integrate() and if that fails make an object and integrate it using Maxima, maple, etc, as specified by algorithm. For symbolic expression calls ``sage.calculus.calculus.integral`` - see this function for available options. EXAMPLES:: sage: f = cyclotomic_polynomial(10) sage: integral(f) 1/5*x^5 - 1/4*x^4 + 1/3*x^3 - 1/2*x^2 + x :: sage: integral(sin(x),x) -cos(x) :: sage: y = var('y') sage: integral(sin(x),y) y*sin(x) :: sage: integral(sin(x), x, 0, pi/2) 1 sage: sin(x).integral(x, 0,pi/2) 1 sage: integral(exp(-x), (x, 1, oo)) e^(-1) Numerical approximation:: sage: h = integral(tan(x)/x, (x, 1, pi/3)); h integrate(tan(x)/x, x, 1, 1/3*pi) sage: h.n() 0.07571599101... Specific algorithm can be used for integration:: sage: integral(sin(x)^2, x, algorithm='maxima') 1/2*x - 1/4*sin(2*x) sage: integral(sin(x)^2, x, algorithm='sympy') -1/2*sin(x)*cos(x) + 1/2*x """ if hasattr(x, 'integral'): return x.integral(*args, **kwds) else: from sage.symbolic.ring import SR return SR(x).integral(*args, **kwds)
def fricas_integrator(expression, v, a=None, b=None, noPole=True): """ Integration using FriCAS EXAMPLES:: sage: from sage.symbolic.integration.external import fricas_integrator # optional - fricas sage: fricas_integrator(sin(x), x) # optional - fricas -cos(x) sage: fricas_integrator(cos(x), x) # optional - fricas sin(x) sage: fricas_integrator(1/(x^2-2), x, 0, 1) # optional - fricas 1/4*sqrt(2)*(log(3*sqrt(2) - 4) - log(sqrt(2))) sage: fricas_integrator(1/(x^2+6), x, -oo, oo) # optional - fricas 1/6*sqrt(6)*pi TESTS: Check that :trac:`25220` is fixed:: sage: integral(sqrt(1-cos(x)), x, 0, 2*pi, algorithm="fricas") # optional - fricas 4*sqrt(2) Check that in case of failure one gets unevaluated integral:: sage: integral(cos(ln(cos(x))), x, 0, pi/8, algorithm='fricas') # optional - fricas integrate(cos(log(cos(x))), x, 0, 1/8*pi) sage: integral(cos(ln(cos(x))), x, algorithm='fricas') # optional - fricas integral(cos(log(cos(x))), x) """ if not isinstance(expression, Expression): expression = SR(expression) from sage.interfaces.fricas import fricas ex = fricas(expression) if a is None: result = ex.integrate(v) else: seg = fricas.equation(v, fricas.segment(a, b)) if noPole: result = ex.integrate(seg, '"noPole"') else: result = ex.integrate(seg) result = result.sage() if result == "failed": return expression.integrate(v, a, b, hold=True) if result == "potentialPole": raise ValueError("The integrand has a potential pole" " in the integration interval") return result
def _sympysage_true(self): """ EXAMPLES:: sage: from sympy.logic.boolalg import BooleanTrue sage: assert SR(True)._sympy_() == BooleanTrue() # known bug sage: assert SR(True) == BooleanTrue()._sage_() """ from sage.symbolic.ring import SR return SR(True)
def is_algebraic_integer(x): """ Determine whether a number is an algebraic integer, or whether the given minimal polynomial defines one. """ if x is None: return None if not isinstance(x, Polynomial): x = SR(x).minpoly() return NumberField(x, names=('a', )).gen().is_integral()
def check_expression(expr, var_symbols, only_from_sympy=False): """ Does ``eval(expr)`` both in Sage and SymPy and does other checks. EXAMPLES:: sage: from sage.interfaces.sympy import check_expression sage: check_expression("1.123*x", "x") """ from sage import __dict__ as sagedict from sage.symbolic.ring import SR from sympy import (__dict__ as sympydict, Basic, S, var as svar) # evaluate the expression in the context of Sage: if var_symbols: SR.var(var_symbols) is_different = False try: e_sage = SR(expr) assert not isinstance(e_sage, Basic) except (NameError, TypeError): is_different = True pass # evaluate the expression in the context of SymPy: if var_symbols: sympy_vars = svar(var_symbols) b = globals().copy() b.update(sympydict) assert "sin" in b b.update(sympydict) e_sympy = eval(expr, b) assert isinstance(e_sympy, Basic) # Sympy func may have specific _sage_ method if is_different: _sage_method = getattr(e_sympy.func, "_sage_") e_sage = _sage_method(S(e_sympy)) # Do the actual checks: if not only_from_sympy: assert S(e_sage) == e_sympy assert e_sage == SR(e_sympy)
def symbolic_prod(expression, *args, **kwds): r""" Return the symbolic product `\prod_{v = a}^b expression` with respect to the variable `v` with endpoints `a` and `b`. INPUT: - ``expression`` - a symbolic expression - ``v`` - a variable or variable name - ``a`` - lower endpoint of the product - ``b`` - upper endpoint of the prduct - ``algorithm`` - (default: ``'maxima'``) one of - ``'maxima'`` - use Maxima (the default) - ``'giac'`` - (optional) use Giac - ``'sympy'`` - use SymPy - ``hold`` - (default: ``False``) if ``True`` don't evaluate EXAMPLES:: sage: i, k, n = var('i,k,n') sage: product(k,k,1,n) factorial(n) sage: product(x + i*(i+1)/2, i, 1, 4) x^4 + 20*x^3 + 127*x^2 + 288*x + 180 sage: product(i^2, i, 1, 7) 25401600 sage: f = function('f') sage: product(f(i), i, 1, 7) f(7)*f(6)*f(5)*f(4)*f(3)*f(2)*f(1) sage: product(f(i), i, 1, n) product(f(i), i, 1, n) sage: assume(k>0) sage: product(integrate (x^k, x, 0, 1), k, 1, n) 1/factorial(n + 1) sage: product(f(i), i, 1, n).log().log_expand() sum(log(f(i)), i, 1, n) """ from .misc_c import prod as c_prod if hasattr(expression, 'prod'): return expression.prod(*args, **kwds) elif len(args) <= 1: return c_prod(expression, *args) else: from sage.symbolic.ring import SR return SR(expression).prod(*args, **kwds)
def repr_pretty(coefficients, type, prefix='x', indices=None, latex=False): r""" Return a pretty representation of equation/inequality represented by the coefficients. INPUT: - ``coefficients`` -- a tuple or other iterable - ``type`` -- either ``0`` (``PolyhedronRepresentation.INEQUALITY``) or ``1`` (``PolyhedronRepresentation.EQUATION``) - ``prefix`` -- a string - ``indices`` -- a tuple or other iterable - ``latex`` -- a boolean OUTPUT: A string. EXAMPLES:: sage: from sage.geometry.polyhedron.representation import repr_pretty sage: from sage.geometry.polyhedron.representation import PolyhedronRepresentation sage: print(repr_pretty((0, 1, 0, 0), PolyhedronRepresentation.INEQUALITY)) x0 >= 0 sage: print(repr_pretty((1, 2, 1, 0), PolyhedronRepresentation.INEQUALITY)) 2*x0 + x1 + 1 >= 0 sage: print(repr_pretty((1, -1, -1, 1), PolyhedronRepresentation.EQUATION)) x2 + 1 == x0 + x1 """ from sage.misc.latex import latex as latex_function from sage.modules.free_module_element import vector from sage.symbolic.ring import SR coeffs = vector(coefficients) if indices is None: indices = range(len(coeffs) - 1) vars = vector([1] + list(SR(prefix + '{}'.format(i)) for i in indices)) positive_part = vector([max(c, 0) for c in coeffs]) negative_part = -(coeffs - positive_part) assert coeffs == positive_part - negative_part if type == PolyhedronRepresentation.EQUATION: rel = '=' if latex else '==' elif type == PolyhedronRepresentation.INEQUALITY: rel = r'\geq' if latex else '>=' else: raise NotImplementedError( 'no pretty printing available: wrong type {}'.format(type)) f = latex_function if latex else repr return '{} {} {}'.format(f(positive_part * vars), rel, f(negative_part * vars))
def laplace(cls, self, parameters, variable, x='x', s='t'): r""" Returns the Laplace transform of self with respect to the variable var. INPUT: - ``x`` - variable of self - ``s`` - variable of Laplace transform. We assume that a piecewise function is 0 outside of its domain and that the left-most endpoint of the domain is 0. EXAMPLES:: sage: x, s, w = var('x, s, w') sage: f = piecewise([[(0,1),1],[[1,2], 1-x]]) sage: f.laplace(x, s) -e^(-s)/s + (s + 1)*e^(-2*s)/s^2 + 1/s - e^(-s)/s^2 sage: f.laplace(x, w) -e^(-w)/w + (w + 1)*e^(-2*w)/w^2 + 1/w - e^(-w)/w^2 :: sage: y, t = var('y, t') sage: f = piecewise([[[1,2], 1-y]]) sage: f.laplace(y, t) (t + 1)*e^(-2*t)/t^2 - e^(-t)/t^2 :: sage: s = var('s') sage: t = var('t') sage: f1(t) = -t sage: f2(t) = 2 sage: f = piecewise([[[0,1],f1],[(1,infinity),f2]]) sage: f.laplace(t,s) (s + 1)*e^(-s)/s^2 + 2*e^(-s)/s - 1/s^2 """ from sage.all import assume, exp, forget x = SR.var(x) s = SR.var(s) assume(s > 0) result = 0 for domain, f in parameters: for interval in domain: a = interval.lower() b = interval.upper() result += (SR(f) * exp(-s * x)).integral(x, a, b) forget(s > 0) return result
def sr_sum(self, *args): """ Helper function to wrap calculus use of Maxima's summation. TESTS:: sage: x, y, k, n = var('x, y, k, n') sage: sum(binomial(n,k) * x^k * y^(n-k), k, 0, n) (x + y)^n sage: q, a = var('q, a') sage: sum(a*q^k, k, 0, oo) Traceback (most recent call last): ... ValueError: Computation failed since Maxima requested additional constraints; using the 'assume' command before summation *may* help (example of legal syntax is 'assume(abs(q)-1>0)', see `assume?` for more details) Is abs(q)-1 positive, negative, or zero? sage: assume(q > 1) sage: sum(a*q^k, k, 0, oo) Traceback (most recent call last): ... ValueError: Sum is divergent. sage: forget() sage: assume(abs(q) < 1) sage: sum(a*q^k, k, 0, oo) -a/(q - 1) sage: forget() sage: assumptions() # check the assumptions were really forgotten [] """ try: return max_to_sr( maxima_eval([[max_ratsimp], [[max_simplify_sum], ([max_sum], [sr_to_max(SR(a)) for a in args])]])) except RuntimeError, error: s = str(error) if "divergent" in s: # in pexpect interface, one looks for this; # could not find an example where 'Pole encountered' occurred, though # if "divergent" in s or 'Pole encountered' in s: raise ValueError, "Sum is divergent." elif "Is" in s: # Maxima asked for a condition j = s.find('Is ') s = s[j:] k = s.find(' ', 4) raise ValueError, "Computation failed since Maxima requested additional constraints; using the 'assume' command before summation *may* help (example of legal syntax is 'assume(" + s[ 4:k] + ">0)', see `assume?` for more details)\n" + s else: raise error
def weight_integrand(self, simplify_factor=True): """ Weight integrand as a rational function. The Jacobian determinant of some coordinate transformation. """ def arg(x, y): return arctan(y / x) # up to a constant, but it doesn't matter def phi(x, y, a, b): z = (a + I * b - x - I * y) * (a - I * b - x - I * y) w = z.real() q = z.imag() return arg(w, q).full_simplify() n = len(self.internal_vertices()) coordinates = lambda v: SR.var(chr(97+2*(v-1)) + ',' + chr(97+2*(v-1)+1)) \ if v in self.internal_vertices() else \ [(0,0), (1,0)][self.ground_vertices().index(v)] internal_coordinates = sum( (list(coordinates(v)) for v in sorted(self.internal_vertices())), []) U = CoordinatePatch(internal_coordinates) F = DifferentialForms(U) psi = 0 two_forms = [] for v in self.internal_vertices(): x, y = coordinates(v) outgoing_edges = self.outgoing_edges([v]) left_target = filter(lambda (x, y, z): z == 'L', outgoing_edges)[0][1] right_target = filter(lambda (x, y, z): z == 'R', outgoing_edges)[0][1] one_forms = [] for target in [left_target, right_target]: a, b = coordinates(target) one_form = DifferentialForm(F, 1) for v in internal_coordinates: index = internal_coordinates.index(v) one_form[index] = phi(x, y, a, b).diff(v) if simplify_factor: one_form[index] = SR(one_form[index]).full_simplify() one_forms.append(one_form) two_form = one_forms[0] * one_forms[1] two_forms.append(two_form) import operator two_n_form = reduce(operator.mul, two_forms, 1) return two_n_form[range(0, 2 * n)]
def sr_tlimit(self,expr,v,a,dir=None): """ Helper function to wrap calculus use of Maxima's Taylor series limits. TESTS:: sage: f = (1+1/x)^x sage: limit(f, x = I, taylor=True) (-I + 1)^I """ L=[sr_to_max(SR(a)) for a in [expr,v,a]] if dir == "plus": L.append(max_plus) elif dir == "minus": L.append(max_minus) return max_to_sr(maxima_eval(([max_tlimit],L)))