def test_sympify3(): assert sympify("x**3") == x**3 assert sympify("x^3") == x**3 assert sympify("1/2") == Integer(1)/2 raises(SympifyError, lambda: _sympify('x**3')) raises(SympifyError, lambda: _sympify('1/2'))
def __new__(cls, label, shape=None, **kw_args): from sympy import MatrixBase, NDimArray if isinstance(label, string_types): label = Symbol(label) elif isinstance(label, Symbol): pass elif isinstance(label, (MatrixBase, NDimArray)): return label elif isinstance(label, Iterable): return _sympify(label) else: label = _sympify(label) if is_sequence(shape): shape = Tuple(*shape) elif shape is not None: shape = Tuple(shape) offset = kw_args.pop('offset', S.Zero) strides = kw_args.pop('strides', None) if shape is not None: obj = Expr.__new__(cls, label, shape) else: obj = Expr.__new__(cls, label) obj._shape = shape obj._offset = offset obj._strides = strides obj._name = str(label) return obj
def __getitem__(self, key): if not isinstance(key, tuple) and isinstance(key, slice): from sympy.matrices.expressions.slice import MatrixSlice return MatrixSlice(self, key, (0, None, 1)) if isinstance(key, tuple) and len(key) == 2: i, j = key if isinstance(i, slice) or isinstance(j, slice): from sympy.matrices.expressions.slice import MatrixSlice return MatrixSlice(self, i, j) i, j = _sympify(i), _sympify(j) if self.valid_index(i, j) != False: return self._entry(i, j) else: raise IndexError("Invalid indices (%s, %s)" % (i, j)) elif isinstance(key, (SYMPY_INTS, Integer)): # row-wise decomposition of matrix rows, cols = self.shape # allow single indexing if number of columns is known if not isinstance(cols, Integer): raise IndexError(filldedent(''' Single indexing is only supported when the number of columns is known.''')) key = _sympify(key) i = key // cols j = key % cols if self.valid_index(i, j) != False: return self._entry(i, j) else: raise IndexError("Invalid index %s" % key) elif isinstance(key, (Symbol, Expr)): raise IndexError(filldedent(''' Only integers may be used when addressing the matrix with a single index.''')) raise IndexError("Invalid index, wanted %s[i,j]" % self)
def __new__(cls, start, end, left_open=False, right_open=False): start = _sympify(start) end = _sympify(end) left_open = _sympify(left_open) right_open = _sympify(right_open) if not all(isinstance(a, (type(true), type(false))) for a in [left_open, right_open]): raise NotImplementedError( "left_open and right_open can have only true/false values, " "got %s and %s" % (left_open, right_open)) inftys = [S.Infinity, S.NegativeInfinity] # Only allow real intervals (use symbols with 'is_real=True'). if not (start.is_real or start in inftys) or not (end.is_real or end in inftys): raise ValueError("Only real intervals are supported") # Make sure that the created interval will be valid. if end.is_comparable and start.is_comparable: if end < start: return S.EmptySet if end == start and (left_open or right_open): return S.EmptySet if end == start and not (left_open or right_open): return FiniteSet(end) # Make sure infinite interval end points are open. if start == S.NegativeInfinity: left_open = true if end == S.Infinity: right_open = true return Basic.__new__(cls, start, end, left_open, right_open)
def __new__(cls, name, index, system, pretty_str, latex_str): from sympy.vector.coordsysrect import CoordSys3D if isinstance(name, Symbol): name = name.name if isinstance(pretty_str, Symbol): pretty_str = pretty_str.name if isinstance(latex_str, Symbol): latex_str = latex_str.name index = _sympify(index) system = _sympify(system) obj = super(BaseScalar, cls).__new__(cls, Symbol(name), index, system, Symbol(pretty_str), Symbol(latex_str)) if not isinstance(system, CoordSys3D): raise TypeError("system should be a CoordSys3D") if index not in range(0, 3): raise ValueError("Invalid index specified.") # The _id is used for equating purposes, and for hashing obj._id = (index, system) obj._name = obj.name = name obj._pretty_form = u'' + pretty_str obj._latex_form = latex_str obj._system = system return obj
def __new__(cls, lhs, op, rhs): lhs = _sympify(lhs) rhs = _sympify(rhs) # Tuple of things that can be on the lhs of an assignment assignable = (Symbol, MatrixSymbol, MatrixElement, Indexed) if not isinstance(lhs, assignable): raise TypeError("Cannot assign to lhs of type %s." % type(lhs)) # Indexed types implement shape, but don't define it until later. This # causes issues in assignment validation. For now, matrices are defined # as anything with a shape that is not an Indexed lhs_is_mat = hasattr(lhs, 'shape') and not isinstance(lhs, Indexed) rhs_is_mat = hasattr(rhs, 'shape') and not isinstance(rhs, Indexed) # If lhs and rhs have same structure, then this assignment is ok if lhs_is_mat: if not rhs_is_mat: raise ValueError("Cannot assign a scalar to a matrix.") elif lhs.shape != rhs.shape: raise ValueError("Dimensions of lhs and rhs don't align.") elif rhs_is_mat and not lhs_is_mat: raise ValueError("Cannot assign a matrix to a scalar.") if isinstance(op, str): op = operator(op) elif op not in op_registry.values(): raise TypeError("Unrecognized Operator") return Basic.__new__(cls, lhs, op, rhs)
def __new__(cls, start, end, left_open=False, right_open=False): start = _sympify(start) end = _sympify(end) # Only allow real intervals (use symbols with 'is_real=True'). if not start.is_real or not end.is_real: raise ValueError("Only real intervals are supported") # Make sure that the created interval will be valid. if end.is_comparable and start.is_comparable: if end < start: return S.EmptySet if end == start and (left_open or right_open): return S.EmptySet if end == start and not (left_open or right_open): return FiniteSet(end) # Make sure infinite interval end points are open. if start == S.NegativeInfinity: left_open = True if end == S.Infinity: right_open = True return Basic.__new__(cls, start, end, left_open, right_open)
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, b, e, evaluate=True): b = _sympify(b) e = _sympify(e) obj = sympy.Expr.__new__(cls, b, e) obj.is_commutative = b.is_commutative and e.is_commutative return obj
def __new__(cls, index, system, pretty_str=None, latex_str=None): from sympy.vector.coordsysrect import CoordSys3D if pretty_str is None: pretty_str = "x{0}".format(index) elif isinstance(pretty_str, Symbol): pretty_str = pretty_str.name if latex_str is None: latex_str = "x_{0}".format(index) elif isinstance(latex_str, Symbol): latex_str = latex_str.name index = _sympify(index) system = _sympify(system) obj = super(BaseScalar, cls).__new__(cls, index, system) if not isinstance(system, CoordSys3D): raise TypeError("system should be a CoordSys3D") if index not in range(0, 3): raise ValueError("Invalid index specified.") # The _id is used for equating purposes, and for hashing obj._id = (index, system) obj._name = obj.name = system._name + '.' + system._variable_names[index] obj._pretty_form = u'' + pretty_str obj._latex_form = latex_str obj._system = system 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 compare_pretty(a, b): """ Is a > b in the sense of ordering in printing? THIS FUNCTION IS DEPRECATED. Use ``default_sort_key`` instead. :: yes ..... return 1 no ...... return -1 equal ... return 0 Strategy: It uses Basic.compare as a fallback, but improves it in many cases, like ``x**3``, ``x**4``, ``O(x**3)`` etc. In those simple cases, it just parses the expression and returns the "sane" ordering such as:: 1 < x < x**2 < x**3 < O(x**4) etc. Examples ======== >>> from sympy.abc import x >>> from sympy import Basic, Number >>> Basic._compare_pretty(x, x**2) -1 >>> Basic._compare_pretty(x**2, x**2) 0 >>> Basic._compare_pretty(x**3, x**2) 1 >>> Basic._compare_pretty(Number(1, 2), Number(1, 3)) 1 >>> Basic._compare_pretty(Number(0), Number(-1)) 1 """ try: a = _sympify(a) except SympifyError: pass try: b = _sympify(b) except SympifyError: pass # both objects are non-SymPy if (not isinstance(a, Basic)) and (not isinstance(b, Basic)): return cmp(a, b) if not isinstance(a, Basic): return -1 # other < sympy if not isinstance(b, Basic): return +1 # sympy > other # now both objects are from SymPy, so we can proceed to usual comparison return cmp(a.sort_key(), b.sort_key())
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, 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, target, iter, body): target = _sympify(target) if not iterable(iter): raise TypeError("iter must be an iterable") iter = _sympify(iter) if not iterable(body): raise TypeError("body must be an iterable") body = Tuple(*(_sympify(i) for i in body)) return Basic.__new__(cls, target, iter, body)
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, arg, condition=None, **kwargs): arg = _sympify(arg) if not kwargs.pop('evaluate', global_evaluate[0]): if condition is None: obj = Expr.__new__(cls, arg) else: condition = _sympify(condition) obj = Expr.__new__(cls, arg, condition) obj._condition = condition return obj if not arg.has(RandomSymbol): return S.Zero if condition is not None: condition = _sympify(condition) if isinstance(arg, RandomSymbol): if condition is None: obj = Expr.__new__(cls, arg) else: obj = Expr.__new__(cls, arg, condition) obj._condition = condition return obj elif isinstance(arg, Add): rv = [] for a in arg.args: if a.has(RandomSymbol): rv.append(a) variances = Add(*map(lambda xv: Variance(xv, condition), rv)) map_to_covar = lambda x: 2*Covariance(*x, condition=condition) covariances = Add(*map(map_to_covar, itertools.combinations(rv, 2))) return variances + covariances elif isinstance(arg, Mul): nonrv = [] rv = [] for a in arg.args: if a.has(RandomSymbol): rv.append(a) else: nonrv.append(a**2) if len(rv) == 0: return S.Zero if condition is None: obj = Expr.__new__(cls, Mul(*rv)) else: obj = Expr.__new__(cls, Mul(*rv), condition) obj._condition = condition return Mul(*nonrv)*obj else: # this expression contains a RandomSymbol somehow: return Variance(arg, condition, evaluate=False)
def __new__(cls, target, iter, body): target = _sympify(target) if not iterable(iter): raise TypeError("iter must be an iterable") if isinstance(iter, list): # _sympify errors on lists because they are mutable iter = tuple(iter) iter = _sympify(iter) if not isinstance(body, CodeBlock): if not iterable(body): raise TypeError("body must be an iterable or CodeBlock") body = CodeBlock(*(_sympify(i) for i in body)) return Basic.__new__(cls, target, iter, body)
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, symbol, attrs=FiniteSet(), type_=None): args = (_sympify(symbol), attrs if isinstance(attrs, FiniteSet) else FiniteSet(*attrs)) if type_ is not None: if not isinstance(type_, Type): raise TypeError("type_ argument should be an instance of Type") args += (type_,) return Basic.__new__(cls, *args)
def __eq__(self, other): """a == b -> Compare two symbolic trees and see whether they are equal this is the same as: a.compare(b) == 0 but faster """ if type(self) is not type(other): # issue 3001 a**1.0 == a like a**2.0 == a**2 while isinstance(self, C.Pow) and self.exp == 1: self = self.base while isinstance(other, C.Pow) and other.exp == 1: other = other.base try: other = _sympify(other) except SympifyError: return False # sympy != other if type(self) is not type(other): return False return self._hashable_content() == other._hashable_content()
def __new__(cls, arg, expr): if not isinstance(arg, Argument): raise TypeError("arg must be of type `Argument`") expr = _sympify(expr) if not isinstance(expr, (Expr, MatrixExpr)): raise TypeError("Unsupported expression type %s." % type(expr)) return Basic.__new__(cls, arg, expr)
def __setitem__(self, index, value): """Allows to set items to MutableDenseNDimArray. Examples ======== >>> from sympy import MutableSparseNDimArray >>> a = MutableSparseNDimArray.zeros(2, 2) >>> a[0, 0] = 1 >>> a[1, 1] = 1 >>> a [[1, 0], [0, 1]] """ index = self._parse_index(index) if not isinstance(value, MutableNDimArray): value = _sympify(value) if isinstance(value, NDimArray): return NotImplementedError if value == 0 and index in self._sparse_array: self._sparse_array.pop(index) else: self._sparse_array[index] = value
def __new__(cls, iterable=None, shape=None, **kwargs): from sympy.utilities.iterables import flatten shape, flat_list = cls._handle_ndarray_creation_inputs(iterable, shape, **kwargs) shape = Tuple(*map(_sympify, shape)) loop_size = functools.reduce(lambda x,y: x*y, shape) if shape else 0 # Sparse array: if isinstance(flat_list, (dict, Dict)): sparse_array = Dict(flat_list) else: sparse_array = {} for i, el in enumerate(flatten(flat_list)): if el != 0: sparse_array[i] = _sympify(el) sparse_array = Dict(sparse_array) self = Basic.__new__(cls, sparse_array, shape, **kwargs) self._shape = shape self._rank = len(shape) self._loop_size = loop_size self._sparse_array = sparse_array return self
def __contains__(self, other): """ Returns True if other is contained in self, where other belongs to extended real numbers, False if not contained, otherwise TypeError is raised. Examples ======== >>> from sympy import AccumBounds, oo >>> 1 in AccumBounds(-1, 3) True -oo and oo go together as limits (in AccumulationBounds). >>> -oo in AccumBounds(1, oo) True >>> oo in AccumBounds(-oo, 0) True """ other = _sympify(other) if other is S.Infinity or other is S.NegativeInfinity: if self.min is S.NegativeInfinity or self.max is S.Infinity: return True return False rv = And(self.min <= other, self.max >= other) if rv not in (True, False): raise TypeError("input failed to evaluate") return rv
def __new__(cls, *args, **options): args = [_sympify(arg) for arg in args] argset = multiset(args) # dictionary args_final=[] # xor is commutative and is false if count of x is even and x # if count of x is odd. Here x can be True, False or any Symbols for x, freq in argset.items(): if freq % 2 == 0: argset[x] = false else: argset[x] = x for _, z in argset.items(): args_final.append(z) argset = set(args_final) truecount = 0 for x in args: if isinstance(x, Number) or x in [True, False]: # Includes 0, 1 argset.discard(x) if x: truecount += 1 if len(argset) < 1: return true if truecount % 2 != 0 else false if truecount % 2 != 0: return Not(Xor(*argset)) _args = frozenset(argset) obj = super(Xor, cls).__new__(cls, *_args, **options) if isinstance(obj, Xor): obj._argset = _args return obj
def __contains__(self, other): """ Returns True if other is contained in self, where other belongs to extended real numbers, False if not contained, otherwise TypeError is raised. Examples ======== >>> from sympy import AccumBounds, oo >>> 1 in AccumBounds(-1, 3) True -oo and oo go together as limits (in AccumulationBounds). >>> -oo in AccumBounds(1, oo) True >>> oo in AccumBounds(-oo, 0) True """ other = _sympify(other) if not (other.is_Symbol or other.is_number): raise TypeError("Input of type real symbol or Number expected") if other is S.Infinity or other is S.NegativeInfinity: if self.min is S.NegativeInfinity or self.max is S.Infinity: return True return False return And(self.min <= other and self.max >= other)
def __new__(cls, routine_call, idx): if not isinstance(routine_call, RoutineCall): raise TypeError("routine_call must be of type RoutineCall") idx = _sympify(idx) if isinstance(idx, Integer): if not -1 <= idx < len(routine_call.routine.returns): raise ValueError("idx out of bounds") elif isinstance(idx, Symbol): names = [a.name.name for a in routine_call.routine.inplace] if idx not in names: raise KeyError("unknown inplace result %s" % idx) # Get the name of the symbol if idx == -1: expr = routine_call.routine.returns[0].expr elif isinstance(idx, Integer): expr = routine_call.routine.returns[idx].expr else: inp = routine_call.routine.inplace expr = [i.expr for i in inp if idx == i.name.name][0] # Sub in values to expression args = [i.name for i in routine_call.routine.arguments] values = [i for i in routine_call.arguments] expr = expr.subs(dict(zip(args, values))) # Create the object s = cls._alias_type.__new__(cls, routine_call, idx) s._expr = expr cls._alias_assumptions(s, expr) return s
def _contains(self, other): if (((self.start - other)/self.step).is_integer or ((self.stop - other)/self.step).is_integer): return _sympify(other >= self.inf and other <= self.sup) elif (((self.start - other)/self.step).is_integer is False and ((self.stop - other)/self.step).is_integer is False): return S.false
def __setitem__(self, index, value): """Allows to set items to MutableDenseNDimArray. Examples ======== >>> from sympy import MutableSparseNDimArray >>> a = MutableSparseNDimArray.zeros(2, 2) >>> a[0, 0] = 1 >>> a[1, 1] = 1 >>> a [[1, 0], [0, 1]] """ if isinstance(index, tuple) and any([isinstance(i, slice) for i in index]): value, eindices, slice_offsets = self._get_slice_data_for_array_assignment(index, value) for i in eindices: other_i = [ind - j for ind, j in zip(i, slice_offsets) if j is not None] other_value = value[other_i] complete_index = self._parse_index(i) if other_value != 0: self._sparse_array[complete_index] = other_value elif complete_index in self._sparse_array: self._sparse_array.pop(complete_index) else: index = self._parse_index(index) value = _sympify(value) if value == 0 and index in self._sparse_array: self._sparse_array.pop(index) else: self._sparse_array[index] = value
def __eq__(self, other): """Return a boolean indicating whether a == b on the basis of their symbolic trees. This is the same as a.compare(b) == 0 but faster. Notes ===== If a class that overrides __eq__() needs to retain the implementation of __hash__() from a parent class, the interpreter must be told this explicitly by setting __hash__ = <ParentClass>.__hash__. Otherwise the inheritance of __hash__() will be blocked, just as if __hash__ had been explicitly set to None. References ========== from http://docs.python.org/dev/reference/datamodel.html#object.__hash__ """ if type(self) is not type(other): # issue 3001 a**1.0 == a like a**2.0 == a**2 while isinstance(self, C.Pow) and self.exp == 1: self = self.base while isinstance(other, C.Pow) and other.exp == 1: other = other.base try: other = _sympify(other) except SympifyError: return False # sympy != other if type(self) is not type(other): return False return self._hashable_content() == other._hashable_content()
def lineseg_integrate(polygon, index, line_seg, expr, degree): """Helper function to compute the line integral of `expr` over `line_seg` Parameters =========== polygon : Face of a 3-Polytope index : index of line_seg in polygon line_seg : Line Segment Examples ======== >>> from sympy.integrals.intpoly import lineseg_integrate >>> polygon = [(0, 5, 0), (5, 5, 0), (5, 5, 5), (0, 5, 5)] >>> line_seg = [(0, 5, 0), (5, 5, 0)] >>> lineseg_integrate(polygon, 0, line_seg, 1, 0) 5 """ expr = _sympify(expr) if expr.is_zero: return S.Zero result = S.Zero x0 = line_seg[0] distance = norm(tuple([line_seg[1][i] - line_seg[0][i] for i in range(3)])) if isinstance(expr, Expr): expr_dict = {x: line_seg[1][0], y: line_seg[1][1], z: line_seg[1][2]} result += distance * expr.subs(expr_dict) else: result += distance * expr expr = diff(expr, x) * x0[0] + diff(expr, y) * x0[1] +\ diff(expr, z) * x0[2] result += lineseg_integrate(polygon, index, line_seg, expr, degree - 1) result /= (degree + 1) return result
def __lt__(self, other): """ Returns True if range of values attained by `self` AccumulationBounds object is less than the range of values attained by `other`, where other may be any value of type AccumulationBounds object or extended real number value, False if `other` satisfies the same property, else an unevaluated Relational Examples ======== >>> from sympy import AccumBounds, oo >>> AccumBounds(1, 3) < AccumBounds(4, oo) True >>> AccumBounds(1, 4) < AccumBounds(3, 4) AccumBounds(1, 4) < AccumBounds(3, 4) >>> AccumBounds(1, oo) < -1 False """ other = _sympify(other) if isinstance(other, AccumBounds): if self.max < other.min: return True if self.min >= other.max: return False elif not(other.is_real or other is S.Infinity or other is S.NegativeInfinity): raise TypeError( "Invalid comparison of %s %s" % (type(other), other)) elif other.is_comparable: if self.max < other: return True if self.min >= other: return False return super(AccumulationBounds, self).__lt__(other)
def __ge__(self, other): """ Returns True if range of values attained by `self` AccumulationBounds object is less that the range of values attained by `other`, where other may be any value of type AccumulationBounds object or extended real number value, False is returned if `other` satisfies the same property, None if the values attained by AccumulationBounds object intersect. Examples ======== >>> from sympy import AccumBounds, oo >>> AccumBounds(1, 3) >= AccumBounds(4, oo) False >>> AccumBounds(1, 4) >= AccumBounds(3, 4) >>> AccumBounds(1, oo) >= 1 True """ other = _sympify(other) if isinstance(other, AccumBounds): if self.min >= other.max: return True if self.max < other.min: return False return None if not (other.is_real or other is S.Infinity or other is S.NegativeInfinity): raise TypeError("Invalid comparison of %s %s" % (type(other), other)) if other.is_comparable: if self.min >= other: return True if self.max < other: return False return None
def _unify_element_sympy(cls, rep, element): domain = rep.domain element = _sympify(element) if domain != EXRAW: # The domain can only be ZZ, QQ or EXRAW if element.is_Integer: new_domain = domain elif element.is_Rational: new_domain = QQ else: new_domain = EXRAW # XXX: This converts the domain for all elements in the matrix # which can be slow. This happens e.g. if __setitem__ changes one # element to something that does not fit in the domain if new_domain != domain: rep = rep.convert_to(new_domain) domain = new_domain if domain != EXRAW: element = new_domain.from_sympy(element) if domain == EXRAW and not isinstance(element, Expr): sympy_deprecation_warning( """ non-Expr objects in a Matrix is deprecated. Matrix represents a mathematical matrix. To represent a container of non-numeric entities, Use a list of lists, TableForm, NumPy array, or some other data structure instead. """, deprecated_since_version="1.9", active_deprecations_target="deprecated-non-expr-in-matrix", stacklevel=4, ) return rep, element
def CircularSymplecticEnsemble(sym, dim): """ Represents Cicular Symplectic Ensembles. Examples ======== >>> from sympy.stats import CircularSymplecticEnsemble as CSE >>> from sympy.stats import joint_eigen_distribution >>> C = CSE('S', 1) >>> joint_eigen_distribution(C) Lambda(t[1], Product(Abs(exp(I*t[_j]) - exp(I*t[_k]))**4, (_j, _k + 1, 1), (_k, 1, 0))/(2*pi)) Note ==== As can be seen above in the example, density of CiruclarSymplecticEnsemble is not evaluated becuase the exact definition is based on haar measure of unitary group which is not unique. """ sym, dim = _symbol_converter(sym), _sympify(dim) model = CircularSymplecticEnsembleModel(sym, dim) rmp = RandomMatrixPSpace(sym, model=model) return RandomMatrixSymbol(sym, dim, dim, pspace=rmp)
def __setitem__(self, index, value): """Allows to set items to MutableDenseNDimArray. Examples ======== >>> from sympy import MutableDenseNDimArray >>> a = MutableDenseNDimArray.zeros(2, 2) >>> a[0,0] = 1 >>> a[1,1] = 1 >>> a [[1, 0], [0, 1]] """ if isinstance(index, tuple) and any([isinstance(i, slice) for i in index]): value, eindices, slice_offsets = self._get_slice_data_for_array_assignment(index, value) for i in eindices: other_i = [ind - j for ind, j in zip(i, slice_offsets) if j is not None] self._array[self._parse_index(i)] = value[other_i] else: index = self._parse_index(index) self._setter_iterable_check(value) value = _sympify(value) self._array[index] = value
def __new__(cls, iterable=None, shape=None, **kwargs): shape, flat_list = cls._handle_ndarray_creation_inputs(iterable, shape, **kwargs) shape = Tuple(*map(_sympify, shape)) cls._check_special_bounds(flat_list, shape) loop_size = functools.reduce(lambda x,y: x*y, shape) if shape else len(flat_list) # Sparse array: if isinstance(flat_list, (dict, Dict)): sparse_array = Dict(flat_list) else: sparse_array = {} for i, el in enumerate(flatten(flat_list)): if el != 0: sparse_array[i] = _sympify(el) sparse_array = Dict(sparse_array) self = Basic.__new__(cls, sparse_array, shape, **kwargs) self._shape = shape self._rank = len(shape) self._loop_size = loop_size self._sparse_array = sparse_array return self
def __new__(cls, flambda, *sets): if not isinstance(flambda, Lambda): raise ValueError('First argument must be a Lambda') sets = [_sympify(s) for s in sets] if flambda is S.IdentityFunction: if len(sets) != 1: raise ValueError('Identity function requires a single set') return sets[0] if not all(isinstance(s, Set) for s in sets): raise TypeError("Set arguments to ImageSet should of type Set") sets = [s.flatten() if s.is_ProductSet else s for s in sets] if not set(flambda.variables) & flambda.expr.free_symbols: emptyprod = fuzzy_or(s.is_empty for s in sets) if emptyprod == True: return S.EmptySet elif emptyprod == False: return FiniteSet(flambda.expr) return Basic.__new__(cls, flambda, *sets)
def __new__(cls, *args): args = [_sympify(arg) for arg in args] args = cls._flatten(args) ranks = [get_rank(arg) for arg in args] if len(args) == 1: return args[0] # If there are contraction objects inside, transform the whole # expression into `CodegenArrayContraction`: contractions = { i: arg for i, arg in enumerate(args) if isinstance(arg, CodegenArrayContraction) } if contractions: cumulative_ranks = list(accumulate([0] + ranks))[:-1] tp = cls(*[ arg.expr if isinstance(arg, CodegenArrayContraction) else arg for arg in args ]) contraction_indices = [ tuple(cumulative_ranks[i] + k for k in j) for i, arg in contractions.items() for j in arg.contraction_indices ] return CodegenArrayContraction(tp, *contraction_indices) obj = Basic.__new__(cls, *args) obj._subranks = ranks shapes = [i.shape for i in args] if any(i is None for i in shapes): obj._shape = None else: obj._shape = tuple(j for i in shapes for j in i) return obj
def test__sympify(): x = Symbol('x') f = Function('f') # positive _sympify assert _sympify(x) is x assert _sympify(f) is f assert _sympify(1) == Integer(1) assert _sympify(0.5) == Real("0.5") assert _sympify(1+1j) == 1 + I class A: def _sympy_(self): return Integer(5) a = A() assert _sympify(a) == Integer(5) # negative _sympify raises(SympifyError, "_sympify('1')") raises(SympifyError, "_sympify([1,2,3])")
def __new__(cls, base, exp): return Basic.__new__(cls, _sympify(base), _sympify(exp))
def __new__(cls, mat): mat = _sympify(mat) assert mat.is_Matrix if not mat.is_square: raise ShapeError("Inverse of non-square matrix %s" % mat) return Basic.__new__(cls, mat)
def test_int_float(): class F1_1(object): def __float__(self): return 1.1 class F1_1b(object): """ This class is still a float, even though it also implements __int__(). """ def __float__(self): return 1.1 def __int__(self): return 1 class F1_1c(object): """ This class is still a float, because it implements _sympy_() """ def __float__(self): return 1.1 def __int__(self): return 1 def _sympy_(self): return Real(1.1) class I5(object): def __int__(self): return 5 class I5b(object): """ This class implements both __int__() and __float__(), so it will be treated as Real in SymPy. One could change this behavior, by using float(a) == int(a), but deciding that integer-valued floats represent exact numbers is arbitrary and often not correct, so we do not do it. If, in the future, we decide to do it anyway, the tests for I5b need to be changed. """ def __float__(self): return 5.0 def __int__(self): return 5 class I5c(object): """ This class implements both __int__() and __float__(), but also a _sympy_() method, so it will be Integer. """ def __float__(self): return 5.0 def __int__(self): return 5 def _sympy_(self): return Integer(5) i5 = I5() i5b = I5b() i5c = I5c() f1_1 = F1_1() f1_1b = F1_1b() f1_1c = F1_1c() assert sympify(i5) == 5 assert isinstance(sympify(i5), Integer) assert sympify(i5b) == 5 assert isinstance(sympify(i5b), Real) assert sympify(i5c) == 5 assert isinstance(sympify(i5c), Integer) assert abs(sympify(f1_1) - 1.1) < 1e-5 assert abs(sympify(f1_1b) - 1.1) < 1e-5 assert abs(sympify(f1_1c) - 1.1) < 1e-5 assert _sympify(i5) == 5 assert isinstance(_sympify(i5), Integer) assert _sympify(i5b) == 5 assert isinstance(_sympify(i5b), Real) assert _sympify(i5c) == 5 assert isinstance(_sympify(i5c), Integer) assert abs(_sympify(f1_1) - 1.1) < 1e-5 assert abs(_sympify(f1_1b) - 1.1) < 1e-5 assert abs(_sympify(f1_1c) - 1.1) < 1e-5
def __new__(cls, sym, condition, base_set=S.UniversalSet): # nonlinsolve uses ConditionSet to return an unsolved system # of equations (see _return_conditionset in solveset) so until # that is changed we do minimal checking of the args sym = _sympify(sym) base_set = _sympify(base_set) condition = _sympify(condition) if isinstance(condition, FiniteSet): condition_orig = condition temp = (Eq(lhs, 0) for lhs in condition) condition = And(*temp) SymPyDeprecationWarning( feature="Using {} for condition".format(condition_orig), issue=17651, deprecated_since_version="1.5", useinstead="{} for condition".format(condition), ).warn() condition = as_Boolean(condition) if isinstance(sym, Tuple): # unsolved eqns syntax return Basic.__new__(cls, sym, condition, base_set) if not isinstance(base_set, Set): raise TypeError("expecting set for base_set") if condition is S.false: return S.EmptySet elif condition is S.true: return base_set if isinstance(base_set, EmptySet): return base_set know = None if isinstance(base_set, FiniteSet): sifted = sift(base_set, lambda _: fuzzy_bool(condition.subs(sym, _))) if sifted[None]: know = FiniteSet(*sifted[True]) base_set = FiniteSet(*sifted[None]) else: return FiniteSet(*sifted[True]) if isinstance(base_set, cls): s, c, base_set = base_set.args if sym == s: condition = And(condition, c) elif sym not in c.free_symbols: condition = And(condition, c.xreplace({s: sym})) elif s not in condition.free_symbols: condition = And(condition.xreplace({sym: s}), c) sym = s else: # user will have to use cls.sym to get symbol dum = Symbol("lambda") if dum in condition.free_symbols or dum in c.free_symbols: dum = Dummy(str(dum)) condition = And(condition.xreplace({sym: dum}), c.xreplace({s: dum})) sym = dum if not isinstance(sym, Symbol): s = Dummy("lambda") if s not in condition.xreplace({sym: s}).free_symbols: raise ValueError( "non-symbol dummy not recognized in condition") rv = Basic.__new__(cls, sym, condition, base_set) return rv if know is None else Union(know, rv)
def __new__(cls, n): if n < 2: raise ValueError("Min dimension for type 'D' is 2") return super().__new__(cls, "D", _sympify(n))
def __new__(cls, *mats): return Basic.__new__(BlockDiagMatrix, *[_sympify(m) for m in mats])
def __new__(cls, n): return super(Identity, cls).__new__(cls, _sympify(n))
def test_Range(): # Only works in Python 3 where range returns a range type assert sympify(range(10)) == Range(10) assert _sympify(range(10)) == Range(10)
def __getitem__(self, key): from sympy.functions.elementary.piecewise import Piecewise if isinstance(key, slice): start, stop = key.start, key.stop if start is None: start = 0 if stop is None: stop = self.shape[0] if start == 0 and stop == self.shape[0]: return self rows = 0 args = [] len_self_shape = len(self.shape) for arg in self.args: if start >= stop: break index = rows if len(arg.shape) < len_self_shape: rows += 1 else: rows += arg.shape[0] if start < rows: if len(arg.shape) < len_self_shape: args.append(arg) start += 1 elif rows <= stop: if rows - start < arg.shape[0]: args.append(arg[start:]) else: args.append(arg) start = rows else: args.append(arg[start - index:stop - index]) start = stop if len(args) == 1: return args[0] if len(args) == 0: return ZeroMatrix(*self.shape) return self.func(*args) if isinstance(key, tuple): if len(key) == 1: key = key[0] elif len(key) == 2: i, j = key if isinstance(i, slice): if isinstance(j, slice): raise Exception('unimplemented method') else: assert i.step is None, 'unimplemented slice object %s' % i start, stop = i.start, i.stop if start is None: if stop is None: # v have the same columns args = [] for v in self.args: if len(v.shape) > 1: indexed = v[:, j] else: indexed = v[j] args.append(indexed) return self.func(*args) raise Exception('unimplemented slice object %s' % i) elif isinstance(j, slice): raise Exception('unimplemented method') from sympy.core.sympify import _sympify i, j = _sympify(i), _sympify(j) if self.valid_index(i, j) != False: args = [] length = 0 for arg in self.args: _length = length shape = arg.shape length += shape[0] cond = i < length if len(arg.shape) == 1: args.append([arg[j], cond]) else: if cond.is_BooleanFalse: continue args.append([arg[i - _length, j], cond]) args[-1][-1] = True return Piecewise(*args) else: raise IndexError("Invalid indices (%s, %s)" % (i, j)) if isinstance(key, int) or key.is_Integer or key.is_Symbol or key.is_Expr: if self.axis == 0: from sympy import S rows = S.Zero args = [] for arg in self.args: index = rows if len(arg.shape) < len(self.shape): rows += S.One else: rows += arg.shape[0] cond = key < rows if cond.is_BooleanFalse: continue if len(arg.shape) < len(self.shape): args.append([arg, cond]) else: args.append([arg[key - index], cond]) args[-1][-1] = True return Piecewise(*args) else: return self.func(*(a[key] for a in self.args), axis=self.axis - 1) raise IndexError("Invalid index, wanted %s[i,j]" % self)
def __new__(cls, name, n, m): n, m = _sympify(n), _sympify(m) if isinstance(name, string_types): name = Symbol(name) obj = Basic.__new__(cls, name, n, m) return obj
def primitive_element(extension, x=None, *, ex=False, polys=False): r""" Find a single generator for a number field given by several generators. Explanation =========== The basic problem is this: Given several algebraic numbers $\alpha_1, \alpha_2, \ldots, \alpha_n$, find a single algebraic number $\theta$ such that $\mathbb{Q}(\alpha_1, \alpha_2, \ldots, \alpha_n) = \mathbb{Q}(\theta)$. This function actually guarantees that $\theta$ will be a linear combination of the $\alpha_i$, with non-negative integer coefficients. Furthermore, if desired, this function will tell you how to express each $\alpha_i$ as a $\mathbb{Q}$-linear combination of the powers of $\theta$. Examples ======== >>> from sympy import primitive_element, sqrt, S, minpoly, simplify >>> from sympy.abc import x >>> f, lincomb, reps = primitive_element([sqrt(2), sqrt(3)], x, ex=True) Then ``lincomb`` tells us the primitive element as a linear combination of the given generators ``sqrt(2)`` and ``sqrt(3)``. >>> print(lincomb) [1, 1] This means the primtiive element is $\sqrt{2} + \sqrt{3}$. Meanwhile ``f`` is the minimal polynomial for this primitive element. >>> print(f) x**4 - 10*x**2 + 1 >>> print(minpoly(sqrt(2) + sqrt(3), x)) x**4 - 10*x**2 + 1 Finally, ``reps`` (which was returned only because we set keyword arg ``ex=True``) tells us how to recover each of the generators $\sqrt{2}$ and $\sqrt{3}$ as $\mathbb{Q}$-linear combinations of the powers of the primitive element $\sqrt{2} + \sqrt{3}$. >>> print([S(r) for r in reps[0]]) [1/2, 0, -9/2, 0] >>> theta = sqrt(2) + sqrt(3) >>> print(simplify(theta**3/2 - 9*theta/2)) sqrt(2) >>> print([S(r) for r in reps[1]]) [-1/2, 0, 11/2, 0] >>> print(simplify(-theta**3/2 + 11*theta/2)) sqrt(3) Parameters ========== extension : list of :py:class:`~.Expr` Each expression must represent an algebraic number $\alpha_i$. x : :py:class:`~.Symbol`, optional (default=None) The desired symbol to appear in the computed minimal polynomial for the primitive element $\theta$. If ``None``, we use a dummy symbol. ex : boolean, optional (default=False) If and only if ``True``, compute the representation of each $\alpha_i$ as a $\mathbb{Q}$-linear combination over the powers of $\theta$. polys : boolean, optional (default=False) If ``True``, return the minimal polynomial as a :py:class:`~.Poly`. Otherwise return it as an :py:class:`~.Expr`. Returns ======= Pair (f, coeffs) or triple (f, coeffs, reps), where: ``f`` is the minimal polynomial for the primitive element. ``coeffs`` gives the primitive element as a linear combination of the given generators. ``reps`` is present if and only if argument ``ex=True`` was passed, and is a list of lists of rational numbers. Each list gives the coefficients of falling powers of the primitive element, to recover one of the original, given generators. """ if not extension: raise ValueError("Cannot compute primitive element for empty extension") extension = [_sympify(ext) for ext in extension] if x is not None: x, cls = sympify(x), Poly else: x, cls = Dummy('x'), PurePoly if not ex: gen, coeffs = extension[0], [1] g = minimal_polynomial(gen, x, polys=True) for ext in extension[1:]: if ext.is_Rational: coeffs.append(0) continue _, factors = factor_list(g, extension=ext) g = _choose_factor(factors, x, gen) s, _, g = g.sqf_norm() gen += s*ext coeffs.append(s) if not polys: return g.as_expr(), coeffs else: return cls(g), coeffs gen, coeffs = extension[0], [1] f = minimal_polynomial(gen, x, polys=True) K = QQ.algebraic_field((f, gen)) # incrementally constructed field reps = [K.unit] # representations of extension elements in K for ext in extension[1:]: if ext.is_Rational: coeffs.append(0) # rational ext is not included in the expression of a primitive element reps.append(K.convert(ext)) # but it is included in reps continue p = minimal_polynomial(ext, x, polys=True) L = QQ.algebraic_field((p, ext)) _, factors = factor_list(f, domain=L) f = _choose_factor(factors, x, gen) s, g, f = f.sqf_norm() gen += s*ext coeffs.append(s) K = QQ.algebraic_field((f, gen)) h = _switch_domain(g, K) erep = _linsolve(h.gcd(p)) # ext as element of K ogen = K.unit - s*erep # old gen as element of K reps = [dup_eval(_.rep, ogen, K) for _ in reps] + [erep] if K.ext.root.is_Rational: # all extensions are rational H = [K.convert(_).rep for _ in extension] coeffs = [0]*len(extension) f = cls(x, domain=QQ) else: H = [_.rep for _ in reps] if not polys: return f.as_expr(), coeffs, H else: return f, coeffs, H
def test_lambda_raises(): with raises(SympifyError): _sympify('lambda: 1')
def __new__(cls, symbol, set): symbol, set = _symbol_converter(symbol), _sympify(set) return Basic.__new__(cls, symbol, set)
def continued_fraction(a): """Return the continued fraction representation of a Rational or quadratic irrational. Examples ======== >>> from sympy.ntheory.continued_fraction import continued_fraction >>> from sympy import sqrt >>> continued_fraction((1 + 2*sqrt(3))/5) [0, 1, [8, 3, 34, 3]] See Also ======== continued_fraction_periodic, continued_fraction_reduce, continued_fraction_convergents """ e = _sympify(a) if all(i.is_Rational for i in e.atoms()): if e.is_Integer: return continued_fraction_periodic(e, 1, 0) elif e.is_Rational: return continued_fraction_periodic(e.p, e.q, 0) elif e.is_Pow and e.exp is S.Half and e.base.is_Integer: return continued_fraction_periodic(0, 1, e.base) elif e.is_Mul and len( e.args) == 2 and (e.args[0].is_Rational and e.args[1].is_Pow and e.args[1].base.is_Integer and e.args[1].exp is S.Half): a, b = e.args return continued_fraction_periodic(0, a.q, b.base, a.p) else: # this should not have to work very hard- no # simplification, cancel, etc... which should be # done by the user. e.g. This is a fancy 1 but # the user should simplify it first: # sqrt(2)*(1 + sqrt(2))/(sqrt(2) + 2) p, d = e.expand().as_numer_denom() if d.is_Integer: if p.is_Rational: return continued_fraction_periodic(p, d) # look for a + b*c # with c = sqrt(s) if p.is_Add and len(p.args) == 2: a, bc = p.args else: a = S.Zero bc = p if a.is_Integer: b = S.NaN if bc.is_Mul and len(bc.args) == 2: b, c = bc.args elif bc.is_Pow: b = Integer(1) c = bc if b.is_Integer and (c.is_Pow and c.exp is S.Half and c.base.is_Integer): # (a + b*sqrt(c))/d c = c.base return continued_fraction_periodic(a, d, c, b) raise ValueError('expecting a rational or quadratic irrational, not %s' % e)
def __new__(cls, n): return super().__new__(cls, "B", _sympify(n))
def __sympifyit_wrapper(a, b): try: b = _sympify(b) return func(a, b) except SympifyError: return retval
def size(self): try: return _sympify(len(self)) except ValueError: return S.Infinity
def test_sympify_poly(): p = Poly(x**2+x+1, x) assert _sympify(p) is p assert sympify(p) is p
def __new__(cls, sym, distribution, dim_n, dim_m): sym = _symbol_converter(sym) dim_n, dim_m = _sympify(dim_n), _sympify(dim_m) if not (dim_n.is_integer and dim_m.is_integer): raise ValueError("Dimensions should be integers") return Basic.__new__(cls, sym, distribution, dim_n, dim_m)