def __new__(cls, *args): """ Construct a Trace object. """ expr = args[0] indices = args[1] if len(args) == 2 else -1 # -1 indicates full trace if isinstance(expr, Matrix): return expr.trace() elif hasattr(expr, "trace") and callable(t.x): # for any objects that have trace() defined e.g numpy return expr.trace() elif isinstance(expr, Add): return Add(*[Tr(arg, indices) for arg in expr.args]) elif isinstance(expr, Mul): c_part, nc_part = expr.args_cnc() if len(nc_part) == 0: return Mul(*c_part) else: # cyclic permute nc_part for canonical ordering nc_part_ordered = _cycle_permute(nc_part) return Mul(*c_part) * Expr.__new__(cls, Mul(*nc_part_ordered), indices) elif isinstance(expr, Pow): if _is_scalar(expr.args[0]) and _is_scalar(expr.args[1]): return expr else: return Expr.__new__(cls, expr, indices) else: if _is_scalar(expr): return expr return Expr.__new__(cls, expr, indices)
def __new__(cls, *args, **hints): if not len(args) == 6: raise ValueError('6 parameters expected, got %s' % args) evaluate = hints.get('evaluate', False) if evaluate: return Expr.__new__(cls, *args)._eval_wignerd() return Expr.__new__(cls, *args, **{'evaluate': False})
def _call_super_constructor(cls, arg1, arg2, condition): if condition is not None: obj = Expr.__new__(cls, arg1, arg2, condition) else: obj = Expr.__new__(cls, arg1, arg2) obj._condition = condition return obj
def _eval_adjoint(self): obj = Expr._eval_adjoint(self) if obj is None: obj = Expr.__new__(Dagger, self) if isinstance(obj, QExpr): obj.hilbert_space = self.hilbert_space return obj
def __new__(cls, expr, condition=None, **kwargs): expr = _sympify(expr) if not kwargs.pop('evaluate', global_evaluate[0]): if condition is None: obj = Expr.__new__(cls, expr) else: condition = _sympify(condition) obj = Expr.__new__(cls, expr, condition) obj._condition = condition return obj if not expr.has(RandomSymbol): return expr if condition is not None: condition = _sympify(condition) if isinstance(expr, Add): return Add(*[Expectation(a, condition=condition) for a in expr.args]) elif isinstance(expr, Mul): rv = [] nonrv = [] for a in expr.args: if isinstance(a, RandomSymbol) or a.has(RandomSymbol): rv.append(a) else: nonrv.append(a) return Mul(*nonrv)*Expectation(Mul(*rv), condition=condition, evaluate=False) else: if condition is None: obj = Expr.__new__(cls, expr) else: obj = Expr.__new__(cls, expr, condition) obj._condition = condition return obj
def __new__(cls, arg1, arg2, condition=None, **kwargs): arg1 = _sympify(arg1) arg2 = _sympify(arg2) if not kwargs.pop('evaluate', global_evaluate[0]): if condition is None: obj = Expr.__new__(cls, arg1, arg2) else: condition = _sympify(condition) obj = Expr.__new__(cls, arg1, arg2, condition) obj._condition = condition return obj if condition is not None: condition = _sympify(condition) if arg1 == arg2: return Variance(arg1, condition) if not arg1.has(RandomSymbol): return S.Zero if not arg2.has(RandomSymbol): return S.Zero arg1, arg2 = sorted([arg1, arg2], key=default_sort_key) if isinstance(arg1, RandomSymbol) and isinstance(arg2, RandomSymbol): return Expr.__new__(cls, arg1, arg2) coeff_rv_list1 = cls._expand_single_argument(arg1.expand()) coeff_rv_list2 = cls._expand_single_argument(arg2.expand()) addends = [a*b*Covariance(*sorted([r1, r2], key=default_sort_key), evaluate=False) for (a, r1) in coeff_rv_list1 for (b, r2) in coeff_rv_list2] return Add(*addends)
def __new__(cls, *args): """ Construct a Trace object. Parameters ========== args = sympy expression """ expr = args[0] indices = Tuple(*args[1]) if len(args) == 2 else Tuple() if isinstance(expr, Matrix): return expr.trace() elif hasattr(expr, 'trace') and callable(t.x): #for any objects that have trace() defined e.g numpy return expr.trace() elif isinstance(expr, Add): return Add(*[Tr(arg, indices) for arg in expr.args]) elif isinstance(expr, Mul): c_part, nc_part = expr.args_cnc() if len(nc_part) == 0: return Mul(*c_part) else: nc_part_ordered = _cycle_permute(_rearrange_args(nc_part)) return Mul(*c_part) * Expr.__new__(cls, Mul(*nc_part_ordered), indices ) elif isinstance(expr, Pow): if (_is_scalar(expr.args[0]) and _is_scalar(expr.args[1])): return expr else: return Expr.__new__(cls, expr, indices) else: if (_is_scalar(expr)): return expr return Expr.__new__(cls, expr, indices)
def __new__(cls, *args, **kwargs): from sympy.tensor.array import NDimArray, tensorproduct, Array from sympy import MatrixBase, MatrixExpr from sympy.strategies import flatten args = [sympify(arg) for arg in args] evaluate = kwargs.get("evaluate", global_evaluate[0]) if not evaluate: obj = Expr.__new__(cls, *args) return obj arrays = [] other = [] scalar = S.One for arg in args: if isinstance(arg, (Iterable, MatrixBase, NDimArray)): arrays.append(Array(arg)) elif isinstance(arg, (MatrixExpr,)): other.append(arg) else: scalar *= arg coeff = scalar*tensorproduct(*arrays) if len(other) == 0: return coeff if coeff != 1: newargs = [coeff] + other else: newargs = other obj = Expr.__new__(cls, *newargs, **kwargs) return flatten(obj)
def __new__(cls, *args, **hints): if not len(args) == 6: raise ValueError("6 parameters expected, got %s" % args) args = sympify(args) evaluate = hints.get("evaluate", False) if evaluate: return Expr.__new__(cls, *args)._eval_wignerd() return Expr.__new__(cls, *args, **{"evaluate": False})
def __new__(cls, arg, condition=None, **kwargs): arg = _sympify(arg) if condition is None: obj = Expr.__new__(cls, arg) else: condition = _sympify(condition) obj = Expr.__new__(cls, arg, condition) obj._condition = condition return obj
def __new__(cls, prob, condition=None, **kwargs): prob = _sympify(prob) if condition is None: obj = Expr.__new__(cls, prob) else: condition = _sympify(condition) obj = Expr.__new__(cls, prob, condition) obj._condition = condition return obj
def __new__(cls, expr, condition=None, **kwargs): expr = _sympify(expr) if condition is None: if not expr.has(RandomSymbol): return expr obj = Expr.__new__(cls, expr) else: condition = _sympify(condition) obj = Expr.__new__(cls, expr, condition) obj._condition = condition return obj
def __new__(cls, *args): """ Construct a Trace object. Parameters ========== args = sympy expression indices = tuple/list if indices, optional """ # expect no indices,int or a tuple/list/Tuple if (len(args) == 2): if not isinstance(args[1], (list, Tuple, tuple)): indices = Tuple(args[1]) else: indices = Tuple(*args[1]) expr = args[0] elif (len(args) == 1): indices = Tuple() expr = args[0] else: raise ValueError("Arguments to Tr should be of form" "(expr[, [indices]])") if isinstance(expr, Matrix): return expr.trace() elif hasattr(expr, 'trace') and callable(expr.trace): #for any objects that have trace() defined e.g numpy return expr.trace() elif isinstance(expr, Add): return Add(*[Tr(arg, indices) for arg in expr.args]) elif isinstance(expr, Mul): c_part, nc_part = expr.args_cnc() if len(nc_part) == 0: return Mul(*c_part) else: obj = Expr.__new__(cls, Mul(*nc_part), indices ) #this check is needed to prevent cached instances #being returned even if len(c_part)==0 return Mul(*c_part)*obj if len(c_part)>0 else obj elif isinstance(expr, Pow): if (_is_scalar(expr.args[0]) and _is_scalar(expr.args[1])): return expr else: return Expr.__new__(cls, expr, indices) else: if (_is_scalar(expr)): return expr return Expr.__new__(cls, expr, indices)
def __new__(cls, arg1, arg2, condition=None, **kwargs): arg1 = _sympify(arg1) arg2 = _sympify(arg2) if kwargs.pop('evaluate', global_evaluate[0]): arg1, arg2 = sorted([arg1, arg2], key=default_sort_key) if condition is None: obj = Expr.__new__(cls, arg1, arg2) else: condition = _sympify(condition) obj = Expr.__new__(cls, arg1, arg2, condition) obj._condition = condition return obj
def __new__(cls, arg, **old_assumptions): # Return the dagger of a sympy Matrix immediately. if isinstance(arg, (Matrix, numpy_ndarray, scipy_sparse_matrix)): return matrix_dagger(arg) arg = sympify(arg) r = cls.eval(arg) if isinstance(r, Expr): return r #make unevaluated dagger commutative or non-commutative depending on arg if arg.is_commutative: obj = Expr.__new__(cls, arg, **{'commutative':True}) else: obj = Expr.__new__(cls, arg, **{'commutative':False}) if isinstance(obj, QExpr): obj.hilbert_space = arg.hilbert_space return obj
def __rmul__(self, other): """other*BraBase""" from sympy.physics.quantum.operator import OuterProduct if isinstance(other, KetBase): return OuterProduct(other, self) else: return Expr.__rmul__(self, other)
def __mul__(self, other): """BraBase*other""" from sympy.physics.quantum.innerproduct import InnerProduct if isinstance(other, KetBase): return InnerProduct(self, other) else: return Expr.__mul__(self, other)
def __mul__(self, other): """KetBase*other""" from sympsi.operator import OuterProduct if isinstance(other, BraBase): return OuterProduct(self, other) else: return Expr.__mul__(self, other)
def _eval_evalf(self, prec): from sympy.mpmath import mp, workprec from sympy import Expr z = self.args[0]._to_mpmath(prec) with workprec(prec): res = mp.airybi(z, derivative=1) return Expr._from_mpmath(res, prec)
def __new__(cls, bra, ket): if not isinstance(ket, KetBase): raise TypeError('KetBase subclass expected, got: %r' % ket) if not isinstance(bra, BraBase): raise TypeError('BraBase subclass expected, got: %r' % ket) obj = Expr.__new__(cls, bra, ket) return obj
def __new__(cls, bra, ket, **old_assumptions): if not isinstance(ket, KetBase): raise TypeError('KetBase subclass expected, got: %r' % ket) if not isinstance(bra, BraBase): raise TypeError('BraBase subclass expected, got: %r' % ket) obj = Expr.__new__(cls, *(bra, ket), **{'commutative':True}) return obj
def __new__(cls, *args, **old_assumptions): """Construct a new quantum object. Parameters ========== args : tuple The list of numbers or parameters that uniquely specify the quantum object. For a state, this will be its symbol or its set of quantum numbers. Examples ======== >>> from sympy.physics.quantum.qexpr import QExpr >>> q = QExpr(0) >>> q 0 >>> q.label (0,) >>> q.hilbert_space H >>> q.args (0,) >>> q.is_commutative False """ # First compute args and call Expr.__new__ to create the instance args = cls._eval_args(args) inst = Expr.__new__(cls, *args, **{'commutative':False}) # Now set the slots on the instance inst.hilbert_space = cls._eval_hilbert_space(args) return inst
def jn_zeros(n, k, method="sympy", dps=15): """ Zeros of the spherical Bessel function of the first kind. This returns an array of zeros of jn up to the k-th zero. * method = "sympy": uses mpmath besseljzero * method = "scipy": uses the SciPy's sph_jn and newton to find all roots, which is faster than computing the zeros using a general numerical solver, but it requires SciPy and only works with low precision floating point numbers. [the function used with method="sympy" is a recent addition to mpmath, before that a general solver was used] Examples ======== >>> from sympy import jn_zeros >>> jn_zeros(2, 4, dps=5) [5.7635, 9.095, 12.323, 15.515] See Also ======== jn, yn, besselj, besselk, bessely """ from math import pi if method == "sympy": from sympy.mpmath import besseljzero from sympy.mpmath.libmp.libmpf import dps_to_prec from sympy import Expr prec = dps_to_prec(dps) return [Expr._from_mpmath(besseljzero(S(n + 0.5)._to_mpmath(prec), int(k)), prec) for k in xrange(1, k + 1)] elif method == "scipy": from scipy.special import sph_jn from scipy.optimize import newton f = lambda x: sph_jn(n, x)[0][-1] else: raise NotImplementedError("Unknown method.") def solver(f, x): if method == "scipy": root = newton(f, x) else: raise NotImplementedError("Unknown method.") return root # we need to approximate the position of the first root: root = n + pi # determine the first root exactly: root = solver(f, root) roots = [root] for i in range(k - 1): # estimate the position of the next root using the last root + pi: root = solver(f, root + pi) roots.append(root) return roots
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 __new__(cls, factor=1, unit=None, abbrev='', **assumptions): if not isinstance(factor, str): factor = sympify(factor) # if the given unit is a number (because of some operations) and # the factor is represented as a number, then return a number if ((unit is None or isinstance(unit, (Number, numbers.Real))) and isinstance(factor, (Number, numbers.Real))): return factor * (unit or 1) #TODO: if factor is of the form "1 m", parse the factor and the unit if isinstance(factor, (Number, numbers.Real)): unit = cls.qsimplify(unit) if isinstance(unit, Quantity): unit = unit.as_unit if not isinstance(unit, Unit): raise TypeError("'unit' should be a Unit instance; %s found" % type(unit)) else: raise NotImplementedError obj = Expr.__new__(cls, factor, unit, **assumptions) obj.factor, obj.unit = factor, unit obj._abbrev = abbrev return obj
def __rmul__(self, other): """other*KetBase""" from sympy.physics.quantum.innerproduct import InnerProduct if isinstance(other, BraBase): return InnerProduct(other, self) else: return Expr.__rmul__(self, other)
def __new__(cls, *args): if not len(args) in [1, 2]: raise ValueError('1 or 2 parameters expected, got %s' % str(args)) if len(args) == 1: args = (args[0], Integer(0)) if len(args) == 2: args = (args[0], Integer(args[1])) return Expr.__new__(cls, *args)
def _eval_evalf(self, prec): from mpmath import mp, workprec from sympy import Expr a = self.args[0]._to_mpmath(prec) z = self.args[1]._to_mpmath(prec) with workprec(prec): res = mp.gammainc(a, z, mp.inf) return Expr._from_mpmath(res, prec)
def __new__(cls, p, q=None, prec=15): rat = Rational.__new__(cls, p, q) if isinstance(rat, (Integer, Infinity)): return rat obj = Expr.__new__(cls) obj.p = rat.p obj.q = rat.q obj.prec = prec return obj
def _eval_evalf(self, prec): from sympy.mpmath import mp from sympy import Expr z = self.args[0]._to_mpmath(prec) oprec = mp.prec mp.prec = prec res = mp.airybi(z, derivative=1) mp.prec = oprec return Expr._from_mpmath(res, prec)
def __new__(cls, base, indices, **options): return Expr.__new__(cls, base, indices)
def __new__(cls, l, r): l = sp.sympify(l) r = sp.sympify(r) obj = Expr.__new__(cls, l, r) obj.is_commutative = False return obj
def __new__(cls, *args, **options): assert len(args) == 1 if isinstance(args[0], Inverse): return args[0].arg return Expr.__new__(cls, *args)
def __new__(cls, A, B, **old_assumptions): r = cls.eval(A, B) if r is not None: return r obj = Expr.__new__(cls, *(A, B), **{'commutative': False}) return obj
def __new__(cls, X, n, condition=None, **kwargs): X = _sympify(X) n = _sympify(n) if condition is not None: condition = _sympify(condition) return Expr.__new__(cls, X, n, condition)
def common_denominator(expr: sp.Expr) -> sp.Expr: """Finds least common multiple of all denominators occurring in an expression""" denominators = [r.q for r in expr.atoms(sp.Rational)] return sp.lcm(denominators)
def extract_coefficients(equation: sympy.Expr, local_map: dict, global_coords: list) -> tuple: """ Args: equation: The equation in local coordinates. local_map: The mapping from local coordinates to the index of a global coordinate. global_coords: The list of global co-ordinates. Returns: The linear and nonlinear parts of the equation in the global co-ordinate system. Extracts the coordinates from the given equation and maps them into the global coordinate space. Equations are assumed to come in as sympy expressions of the form :math:`\Phi(x) = 0`. local_map is a dictionary mappings .. math:: M: \\rightarrow i where :math:`x` are the local co-ordinates and the keys of local_map, and the values are the indices :math:`i` such that `global_coord[i]` is the corresponding global coordinate. The result is :math:`L,N` such that: .. math:: Ly + N(y) = 0 """ coeff_dict = {} nonlinear_terms = sympy.S(0) subs = [(k, global_coords[v]) for k, v in local_map.items()] subs.sort(key=lambda x: str(x[1])[-1], reverse=True) logger.debug("Extracting coefficients from %s", repr(equation)) logger.debug("Using local-to-global substitutions %s", repr(subs)) terms = equation.expand().args if not terms: if equation in local_map: coeff_dict[local_map[equation]] = sympy.S(1) else: nonlinear_terms = equation else: for term in terms: factors = list(flatten(term.as_coeff_mul())) coeff = sympy.S(1) base = [] while factors: factor = factors.pop() if factor.is_number: coeff *= factor elif factor.is_symbol and factor not in local_map: coeff *= factor else: base.append(factor) if len(base) == 1 and base[0] in local_map: coeff_dict[local_map[base[0]]] = coeff else: new_term = term new_term = new_term.subs(subs) nonlinear_terms = sympy.Add(new_term, nonlinear_terms) logger.debug("Linear terms: %s", repr(coeff_dict)) logger.debug("Nonlinear terms: %s", repr(nonlinear_terms)) return coeff_dict, nonlinear_terms
def _apply_substitutions(self, expr: sp.Expr) -> sp.Expr: for left, right in map(lambda eq: eq.args, self._substitution_equations): expr = expr.subs(right, left) return expr
def test_issue_5486_bug(): from sympy import I, Expr assert abs(Expr._from_mpmath(I._to_mpmath(15), 15) - I) < 1.0e-15
def replace_second_order_products( expr: sp.Expr, search_symbols: Iterable[sp.Symbol], positive: Optional[bool] = None, replace_mixed: Optional[List[Assignment]] = None) -> sp.Expr: """Replaces second order mixed terms like x*y by 2*( (x+y)**2 - x**2 - y**2 ). This makes the term longer - simplify usually is undoing these - however this transformation can be done to find more common sub-expressions Args: expr: input expression search_symbols: symbols that are searched for for example, given [x,y,z] terms like x*y, x*z, z*y are replaced positive: there are two ways to do this substitution, either with term (x+y)**2 or (x-y)**2 . if positive=True the first version is done, if positive=False the second version is done, if positive=None the sign is determined by the sign of the mixed term that is replaced replace_mixed: if a list is passed here, the expr x+y or x-y is replaced by a special new symbol and the replacement equation is added to the list """ mixed_symbols_replaced = set([e.lhs for e in replace_mixed ]) if replace_mixed is not None else set() if expr.is_Mul: distinct_search_symbols = set() nr_of_search_terms = 0 other_factors = 1 for t in expr.args: if t in search_symbols: nr_of_search_terms += 1 distinct_search_symbols.add(t) else: other_factors *= t if len(distinct_search_symbols) == 2 and nr_of_search_terms == 2: u, v = sorted(list(distinct_search_symbols), key=lambda symbol: symbol.name) if positive is None: other_factors_without_symbols = other_factors for s in other_factors.atoms(sp.Symbol): other_factors_without_symbols = other_factors_without_symbols.subs( s, 1) positive = other_factors_without_symbols.is_positive assert positive is not None sign = 1 if positive else -1 if replace_mixed is not None: new_symbol_str = 'P' if positive else 'M' mixed_symbol_name = u.name + new_symbol_str + v.name mixed_symbol = sp.Symbol(mixed_symbol_name.replace("_", "")) if mixed_symbol not in mixed_symbols_replaced: mixed_symbols_replaced.add(mixed_symbol) replace_mixed.append(Assignment(mixed_symbol, u + sign * v)) else: mixed_symbol = u + sign * v return sp.Rational( 1, 2) * sign * other_factors * (mixed_symbol**2 - u**2 - v**2) param_list = [ replace_second_order_products(a, search_symbols, positive, replace_mixed) for a in expr.args ] result = expr.func(*param_list, evaluate=False) if param_list else expr return result
def jn_zeros(n, k, method="sympy", dps=15): """ Zeros of the spherical Bessel function of the first kind. This returns an array of zeros of jn up to the k-th zero. * method = "sympy": uses :func:`mpmath.besseljzero` * method = "scipy": uses the `SciPy's sph_jn <http://docs.scipy.org/doc/scipy/reference/generated/scipy.special.jn.html>`_ and `newton <http://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.newton.html>`_ to find all roots, which is faster than computing the zeros using a general numerical solver, but it requires SciPy and only works with low precision floating point numbers. [The function used with method="sympy" is a recent addition to mpmath, before that a general solver was used.] Examples ======== >>> from sympy import jn_zeros >>> jn_zeros(2, 4, dps=5) [5.7635, 9.095, 12.323, 15.515] See Also ======== jn, yn, besselj, besselk, bessely """ from math import pi if method == "sympy": from sympy.mpmath import besseljzero from sympy.mpmath.libmp.libmpf import dps_to_prec from sympy import Expr prec = dps_to_prec(dps) return [ Expr._from_mpmath(besseljzero(S(n + 0.5)._to_mpmath(prec), int(k)), prec) for k in xrange(1, k + 1) ] elif method == "scipy": from scipy.special import sph_jn from scipy.optimize import newton f = lambda x: sph_jn(n, x)[0][-1] else: raise NotImplementedError("Unknown method.") def solver(f, x): if method == "scipy": root = newton(f, x) else: raise NotImplementedError("Unknown method.") return root # we need to approximate the position of the first root: root = n + pi # determine the first root exactly: root = solver(f, root) roots = [root] for i in range(k - 1): # estimate the position of the next root using the last root + pi: root = solver(f, root + pi) roots.append(root) return roots
def __new__(cls, x): return Expr.__new__(cls, x)
def substitute(self, expression: sympy.Expr, substitutions: dict): for key, value in substitutions.items(): if not isinstance(value, sympy.Expr): substitutions[key] = sympy.sympify(value) return expression.subs(substitutions, simultaneous=True).doit()
def __new__(cls, j1, j2, j12, j3, j, j23): args = map(sympify, (j1, j2, j12, j3, j, j23)) return Expr.__new__(cls, *args)
def __new__(cls, j1, j2, j12, j3, j4, j34, j13, j24, j): args = map(sympify, (j1, j2, j12, j3, j4, j34, j13, j24, j)) return Expr.__new__(cls, *args)
def __new__(cls, *args, **kwargs): """ Create a new dimension. Possibilities are (examples given with list/tuple work also with tuple/list): >>> from sympy.physics.unitsystems.dimensions import Dimension >>> Dimension(length=1) {'length': 1} >>> Dimension({"length": 1}) {'length': 1} >>> Dimension([("length", 1), ("time", -1)]) #doctest: +SKIP {'length': 1, 'time': -1} """ # before setting the dict, check if a name and/or a symbol are defined # if so, remove them from the dict name = kwargs.pop('name', None) symbol = kwargs.pop('symbol', None) # pairs of (dimension, power) pairs = [] # add first items from args to the pairs for arg in args: # construction with {"length": 1} if isinstance(arg, dict): arg = copy(arg) pairs.extend(arg.items()) elif isinstance(arg, (Tuple, tuple, list)): #TODO: add construction with ("length", 1); not trivial because # e.g. [("length", 1), ("time", -1)] has also length = 2 for p in arg: #TODO: check that p is a tuple if len(p) != 2: raise ValueError("Length of iterable has to be 2; " "'%d' found" % len(p)) # construction with [("length", 1), ...] pairs.extend(arg) else: # error if the arg is not of previous types raise TypeError("Positional arguments can only be: " "dict, tuple, list; '%s' found" % type(arg)) pairs.extend(kwargs.items()) # check validity of dimension key and power for pair in pairs: #if not isinstance(p[0], str): # raise TypeError("key %s is not a string." % p[0]) if not isinstance(pair[1], (numbers.Real, Number)): raise TypeError("Power corresponding to '%s' is not a number" % pair[0]) # filter dimensions set to zero; this avoid the following odd result: # Dimension(length=1) == Dimension(length=1, mass=0) => False # also simplify to avoid powers such as 2.00000 pairs = [(pair[0], nsimplify(pair[1])) for pair in pairs if pair[1] != 0] pairs.sort(key=str) new = Expr.__new__(cls, Dict(*pairs)) new.name = name new.symbol = symbol new._dict = dict(pairs) return new
def __new__(cls, *args): return Expr.__new__(cls, *args)
def __new__(cls, *args, **options): return Expr.__new__(cls, *args)
def _sub_symbols_in_expression( parameter: sympy.Expr, symbols_map: Dict[sympy.Symbol, Parameter]) -> sympy.Expr: return parameter.subs(symbols_map)
def __new__(cls, A, B): r = cls.eval(A, B) if r is not None: return r obj = Expr.__new__(cls, A, B) return obj
def domain_defined(self, x): domain = Expr.domain_defined(self, x) for arg in self.args: domain &= arg.domain_defined(x) return domain
def amp_and_shift(expr: Expr, x: Symbol) -> Tuple[Expr, Expr]: amp = simplify(cancel(sqrt(expr**2 + expr.diff(x)**2).subs(x, 0))) shift = arg(expr.subs(x, 0) + I * expr.diff(x).subs(x, 0)) return amp, shift
def extract_coefficients(equation: sympy.Expr, local_map: dict, global_coords: list) -> tuple: """ Args: equation: The equation in local coordinates. local_map: The mapping from local coordinates to the index of a global coordinate. global_coords: The list of global co-ordinates. Returns: The linear and nonlinear parts of the equation in the global co-ordinate system. Extracts the coordinates from the given equation and maps them into the global coordinate space. Equations are assumed to come in as sympy expressions of the form :math:`\\Phi(x) = 0`. local_map is a dictionary mappings .. math:: M: \\rightarrow i where :math:`x` are the local co-ordinates and the keys of local_map, and the values are the indices :math:`i` such that `global_coord[i]` is the corresponding global coordinate. The result is :math:`L,N` such that: .. math:: Ly + N(y) = 0 """ coefficients = {} nonlinear_terms = sympy.S(0) subs = [(k, global_coords[v]) for k, v in local_map.items()] local_variables = set(local_map.keys()) subs.sort(key=lambda x: str(x[1])[-1], reverse=True) logger.debug("Extracting coefficients from %s", repr(equation)) logger.debug("Using local-to-global substitutions %s", repr(subs)) remainder = equation mappings = list(local_map.items()) while mappings and remainder: variable, index = mappings.pop() coefficient = equation.coeff(variable) if not coefficient: continue remainder -= coefficient * variable if coefficient.atoms() & local_variables: nonlinear_terms += (coefficient * variable).subs(subs) else: coefficients[index] = coefficient nonlinear_terms = sympy.expand(nonlinear_terms + remainder.subs(subs)) logger.debug("Linear terms: %s", repr(coefficients)) logger.debug("Nonlinear terms: %s", repr(nonlinear_terms)) return coefficients, nonlinear_terms
def __new__(cls, arg0, arg1=LiteralFloat(0)): return Expr.__new__(cls, arg0, arg1)
def __new__(cls, unit_expr=sympy_one, cgs_value=None, cgs_offset=0.0, dimensions=None, registry=None, **assumptions): """ Create a new unit. May be an atomic unit (like a gram) or combinations of atomic units (like g / cm**3). Parameters ---------- unit_expr : Unit object, sympy.core.expr.Expr object, or str The symbolic unit expression. cgs_value : float The unit's value in cgs. dimensions : sympy.core.expr.Expr A sympy expression representing the dimensionality of this unit. It must contain only mass, length, time, temperature and angle symbols. offset : float The offset necessary to normalize temperature units to a common zero point. registry : UnitRegistry object The unit registry we use to interpret unit symbols. """ # Simplest case. If user passes a Unit object, just use the expr. unit_key = None if isinstance(unit_expr, basestring): if registry and unit_expr in registry.unit_objs: return registry.unit_objs[unit_expr] else: unit_key = unit_expr if not unit_expr: # Bug catch... # if unit_expr is an empty string, parse_expr fails hard... unit_expr = "1" unit_expr = parse_expr(unit_expr, global_dict=global_dict, transformations=unit_text_transform) elif isinstance(unit_expr, Unit): # grab the unit object's sympy expression. unit_expr = unit_expr.expr # Make sure we have an Expr at this point. if not isinstance(unit_expr, Expr): raise UnitParseError("Unit representation must be a string or " \ "sympy Expr. %s has type %s." \ % (unit_expr, type(unit_expr))) if registry is None: # Caller did not set the registry, so use the default. registry = default_unit_registry # done with argument checking... # see if the unit is atomic. is_atomic = False if isinstance(unit_expr, Symbol): is_atomic = True # # check cgs_value and dimensions # if cgs_value is not None and dimensions is not None: # check that cgs_value is a float or can be converted to one try: cgs_value = float(cgs_value) except ValueError: raise UnitParseError("Could not use cgs_value as a float. " \ "cgs_value is '%s' (type %s)." \ % (cgs_value, type(cgs_value)) ) # check that dimensions is valid validate_dimensions(dimensions) else: # lookup the unit symbols try: cgs_value, dimensions = \ _get_unit_data_from_expr(unit_expr, registry.lut) except ValueError: cgs_value, dimensions, cgs_offset = \ _get_unit_data_from_expr(unit_expr, registry.lut) # Create obj with superclass construct. obj = Expr.__new__(cls, **assumptions) # Attach attributes to obj. obj.expr = unit_expr obj.is_atomic = is_atomic obj.cgs_value = cgs_value obj.cgs_offset = cgs_offset obj.dimensions = dimensions obj.registry = registry if unit_key: registry.unit_objs[unit_key] = obj # Return `obj` so __init__ can handle it. return obj
def __new__(cls, arg): return Expr.__new__(cls, arg)
def __new__(cls, j1, m1, j2, m2, j3, m3): args = map(sympify, (j1, m1, j2, m2, j3, m3)) return Expr.__new__(cls, *args)
def __new__(cls, unit_expr=sympy_one, base_value=None, base_offset=0.0, dimensions=None, registry=None, latex_repr=None, **assumptions): """ Create a new unit. May be an atomic unit (like a gram) or combinations of atomic units (like g / cm**3). Parameters ---------- unit_expr : Unit object, sympy.core.expr.Expr object, or str The symbolic unit expression. base_value : float The unit's value in yt's base units. base_offset : float The offset necessary to normalize temperature units to a common zero point. dimensions : sympy.core.expr.Expr A sympy expression representing the dimensionality of this unit. It must contain only mass, length, time, temperature and angle symbols. registry : UnitRegistry object The unit registry we use to interpret unit symbols. latex_repr : string A string to render the unit as LaTeX Additional keyword arguments are passed as assumptions to the Sympy Expr initializer """ # Simplest case. If user passes a Unit object, just use the expr. unit_key = None if isinstance(unit_expr, (str, bytes, text_type)): if isinstance(unit_expr, bytes): unit_expr = unit_expr.decode("utf-8") if registry and unit_expr in registry.unit_objs: return registry.unit_objs[unit_expr] else: unit_key = unit_expr if not unit_expr: # Bug catch... # if unit_expr is an empty string, parse_expr fails hard... unit_expr = "1" try: unit_expr = parse_expr(unit_expr, global_dict=global_dict, transformations=unit_text_transform) except SyntaxError as e: msg = ("Unit expression %s raised an error " "during parsing:\n%s" % (unit_expr, repr(e))) raise UnitParseError(msg) elif isinstance(unit_expr, Unit): # grab the unit object's sympy expression. unit_expr = unit_expr.expr elif hasattr(unit_expr, 'units') and hasattr(unit_expr, 'value'): # something that looks like a YTArray, grab the unit and value if unit_expr.shape != (): raise UnitParseError( 'Cannot create a unit from a non-scalar YTArray, received: ' '%s' % (unit_expr, )) value = unit_expr.value if value == 1: unit_expr = unit_expr.units.expr else: unit_expr = unit_expr.value * unit_expr.units.expr # Make sure we have an Expr at this point. if not isinstance(unit_expr, Expr): raise UnitParseError("Unit representation must be a string or " \ "sympy Expr. %s has type %s." \ % (unit_expr, type(unit_expr))) if unit_expr == sympy_one and dimensions is None: dimensions = dimensionless if registry is None: # Caller did not set the registry, so use the default. registry = default_unit_registry # done with argument checking... # see if the unit is atomic. is_atomic = False if isinstance(unit_expr, Symbol): is_atomic = True # # check base_value and dimensions # if base_value is not None: # check that base_value is a float or can be converted to one try: base_value = float(base_value) except ValueError: raise UnitParseError("Could not use base_value as a float. " \ "base_value is '%s' (type %s)." \ % (base_value, type(base_value)) ) # check that dimensions is valid if dimensions is not None: validate_dimensions(dimensions) else: # lookup the unit symbols unit_data = _get_unit_data_from_expr(unit_expr, registry.lut) base_value = unit_data[0] dimensions = unit_data[1] if len(unit_data) > 2: base_offset = unit_data[2] latex_repr = unit_data[3] else: base_offset = 0.0 # Create obj with superclass construct. obj = Expr.__new__(cls, **assumptions) # Attach attributes to obj. obj.expr = unit_expr obj.is_atomic = is_atomic obj.base_value = base_value obj.base_offset = base_offset obj.dimensions = dimensions obj._latex_repr = latex_repr obj.registry = registry if unit_key is not None: registry.unit_objs[unit_key] = obj # Return `obj` so __init__ can handle it. return obj
def test_diff_wrt_value(): assert Expr()._diff_wrt is False assert x._diff_wrt is True assert f(x)._diff_wrt is True assert Derivative(f(x), x)._diff_wrt is True assert Derivative(x**2, x)._diff_wrt is False
def __new__(cls, *shape): if len(shape) == 0: return S.One shape = map(_sympify, shape) obj = Expr.__new__(cls, *shape) return obj