def test_ImageSet(): raises(ValueError, lambda: ImageSet(x, S.Integers)) assert ImageSet(Lambda(x, 1), S.Integers) == FiniteSet(1) assert ImageSet(Lambda(x, y), S.Integers) == {y} assert ImageSet(Lambda(x, 1), S.EmptySet) == S.EmptySet empty = Intersection(FiniteSet(log(2)/pi), S.Integers) assert unchanged(ImageSet, Lambda(x, 1), empty) # issue #17471 squares = ImageSet(Lambda(x, x**2), S.Naturals) assert 4 in squares assert 5 not in squares assert FiniteSet(*range(10)).intersect(squares) == FiniteSet(1, 4, 9) assert 16 not in squares.intersect(Interval(0, 10)) si = iter(squares) a, b, c, d = next(si), next(si), next(si), next(si) assert (a, b, c, d) == (1, 4, 9, 16) harmonics = ImageSet(Lambda(x, 1/x), S.Naturals) assert Rational(1, 5) in harmonics assert Rational(.25) in harmonics assert 0.25 not in harmonics assert Rational(.3) not in harmonics assert (1, 2) not in harmonics assert harmonics.is_iterable assert imageset(x, -x, Interval(0, 1)) == Interval(-1, 0) assert ImageSet(Lambda(x, x**2), Interval(0, 2)).doit() == Interval(0, 4) assert ImageSet(Lambda((x, y), 2*x), {4}, {3}).doit() == FiniteSet(8) assert (ImageSet(Lambda((x, y), x+y), {1, 2, 3}, {10, 20, 30}).doit() == FiniteSet(11, 12, 13, 21, 22, 23, 31, 32, 33)) c = Interval(1, 3) * Interval(1, 3) assert Tuple(2, 6) in ImageSet(Lambda(((x, y),), (x, 2*y)), c) assert Tuple(2, S.Half) in ImageSet(Lambda(((x, y),), (x, 1/y)), c) assert Tuple(2, -2) not in ImageSet(Lambda(((x, y),), (x, y**2)), c) assert Tuple(2, -2) in ImageSet(Lambda(((x, y),), (x, -2)), c) c3 = ProductSet(Interval(3, 7), Interval(8, 11), Interval(5, 9)) assert Tuple(8, 3, 9) in ImageSet(Lambda(((t, y, x),), (y, t, x)), c3) assert Tuple(Rational(1, 8), 3, 9) in ImageSet(Lambda(((t, y, x),), (1/y, t, x)), c3) assert 2/pi not in ImageSet(Lambda(((x, y),), 2/x), c) assert 2/S(100) not in ImageSet(Lambda(((x, y),), 2/x), c) assert Rational(2, 3) in ImageSet(Lambda(((x, y),), 2/x), c) S1 = imageset(lambda x, y: x + y, S.Integers, S.Naturals) assert S1.base_pset == ProductSet(S.Integers, S.Naturals) assert S1.base_sets == (S.Integers, S.Naturals) # Passing a set instead of a FiniteSet shouldn't raise assert unchanged(ImageSet, Lambda(x, x**2), {1, 2, 3}) S2 = ImageSet(Lambda(((x, y),), x+y), {(1, 2), (3, 4)}) assert 3 in S2.doit() # FIXME: This doesn't yet work: #assert 3 in S2 assert S2._contains(3) is None raises(TypeError, lambda: ImageSet(Lambda(x, x**2), 1))
def test_MultivariateEwens(): n, theta, i = symbols('n theta i', positive=True) # tests for integer dimensions theta_f = symbols('t_f', negative=True) a = symbols('a_1:4', positive=True, integer=True) ed = MultivariateEwens('E', 3, theta) assert density(ed)(a[0], a[1], a[2]) == Piecewise( (6 * 2**(-a[1]) * 3**(-a[2]) * theta**a[0] * theta**a[1] * theta**a[2] / (theta * (theta + 1) * (theta + 2) * factorial(a[0]) * factorial(a[1]) * factorial(a[2])), Eq(a[0] + 2 * a[1] + 3 * a[2], 3)), (0, True)) assert marginal_distribution(ed, ed[1])(a[1]) == Piecewise( (6 * 2**(-a[1]) * theta**a[1] / ((theta + 1) * (theta + 2) * factorial(a[1])), Eq(2 * a[1] + 1, 3)), (0, True)) raises(ValueError, lambda: MultivariateEwens('e1', 5, theta_f)) assert ed.pspace.distribution.set == ProductSet(Range(0, 4, 1), Range(0, 2, 1), Range(0, 2, 1)) # tests for symbolic dimensions eds = MultivariateEwens('E', n, theta) a = IndexedBase('a') j, k = symbols('j, k') den = Piecewise((factorial(n) * Product(theta**a[j] * (j + 1)**(-a[j]) / factorial(a[j]), (j, 0, n - 1)) / RisingFactorial(theta, n), Eq(n, Sum((k + 1) * a[k], (k, 0, n - 1)))), (0, True)) assert density(eds)(a).dummy_eq(den)
class Complexes(with_metaclass(Singleton, CartesianComplexRegion)): """ The Set of all complex numbers Examples ======== >>> from sympy import S, I >>> S.Complexes Complexes >>> 1 + I in S.Complexes True See also ======== Reals ComplexRegion """ is_empty = False is_finite_set = False # Override property from superclass since Complexes has no args sets = ProductSet(S.Reals, S.Reals) def __new__(cls): return Set.__new__(cls) def __str__(self): return "S.Complexes" def __repr__(self): return "S.Complexes"
def test_Normal(): m = Normal('A', [1, 2], [[1, 0], [0, 1]]) A = MultivariateNormal('A', [1, 2], [[1, 0], [0, 1]]) assert m == A assert density(m)(1, 2) == 1/(2*pi) assert m.pspace.distribution.set == ProductSet(S.Reals, S.Reals) raises (ValueError, lambda:m[2]) n = Normal('B', [1, 2, 3], [[1, 0, 0], [0, 1, 0], [0, 0, 1]]) p = Normal('C', Matrix([1, 2]), Matrix([[1, 0], [0, 1]])) assert density(m)(x, y) == density(p)(x, y) assert marginal_distribution(n, 0, 1)(1, 2) == 1/(2*pi) raises(ValueError, lambda: marginal_distribution(m)) assert integrate(density(m)(x, y), (x, -oo, oo), (y, -oo, oo)).evalf() == 1 N = Normal('N', [1, 2], [[x, 0], [0, y]]) assert density(N)(0, 0) == exp(-((4*x + y)/(2*x*y)))/(2*pi*sqrt(x*y)) raises (ValueError, lambda: Normal('M', [1, 2], [[1, 1], [1, -1]])) # symbolic n = symbols('n', integer=True, positive=True) mu = MatrixSymbol('mu', n, 1) sigma = MatrixSymbol('sigma', n, n) X = Normal('X', mu, sigma) assert density(X) == MultivariateNormalDistribution(mu, sigma) raises (NotImplementedError, lambda: median(m)) # Below tests should work after issue #17267 is resolved # assert E(X) == mu # assert variance(X) == sigma # test symbolic multivariate normal densities n = 3 Sg = MatrixSymbol('Sg', n, n) mu = MatrixSymbol('mu', n, 1) obs = MatrixSymbol('obs', n, 1) X = MultivariateNormal('X', mu, Sg) density_X = density(X) eval_a = density_X(obs).subs({Sg: eye(3), mu: Matrix([0, 0, 0]), obs: Matrix([0, 0, 0])}).doit() eval_b = density_X(0, 0, 0).subs({Sg: eye(3), mu: Matrix([0, 0, 0])}).doit() assert eval_a == sqrt(2)/(4*pi**Rational(3/2)) assert eval_b == sqrt(2)/(4*pi**Rational(3/2)) n = symbols('n', integer=True, positive=True) Sg = MatrixSymbol('Sg', n, n) mu = MatrixSymbol('mu', n, 1) obs = MatrixSymbol('obs', n, 1) X = MultivariateNormal('X', mu, Sg) density_X_at_obs = density(X)(obs) expected_density = MatrixElement( exp((S(1)/2) * (mu.T - obs.T) * Sg**(-1) * (-mu + obs)) / \ sqrt((2*pi)**n * Determinant(Sg)), 0, 0) assert density_X_at_obs == expected_density
def base_set(self): # XXX: Maybe deprecate this? It is poorly defined in handling # the multivariate case... sets = self.base_sets if len(sets) == 1: return sets[0] else: return ProductSet(*sets).flatten()
def test_MultivariateTDist(): t1 = MultivariateT('T', [0, 0], [[1, 0], [0, 1]], 2) assert(density(t1))(1, 1) == 1/(8*pi) assert t1.pspace.distribution.set == ProductSet(S.Reals, S.Reals) assert integrate(density(t1)(x, y), (x, -oo, oo), \ (y, -oo, oo)).evalf() == 1 raises(ValueError, lambda: MultivariateT('T', [1, 2], [[1, 1], [1, -1]], 1)) t2 = MultivariateT('t2', [1, 2], [[x, 0], [0, y]], 1) assert density(t2)(1, 2) == 1/(2*pi*sqrt(x*y))
def test_NormalGamma(): ng = NormalGamma('G', 1, 2, 3, 4) assert density(ng)(1, 1) == 32 * exp(-4) / sqrt(pi) assert ng.pspace.distribution.set == ProductSet(S.Reals, Interval(0, oo)) raises(ValueError, lambda: NormalGamma('G', 1, 2, 3, -1)) assert marginal_distribution(ng, 0)(1) == \ 3*sqrt(10)*gamma(Rational(7, 4))/(10*sqrt(pi)*gamma(Rational(5, 4))) assert marginal_distribution(ng, y)(1) == exp(Rational(-1, 4)) / 128 assert marginal_distribution(ng, [0, 1])(x) == x**2 * exp(-x / 4) / 128
def test_multivariate_laplace(): raises(ValueError, lambda: Laplace('T', [1, 2], [[1, 2], [2, 1]])) L = Laplace('L', [1, 0], [[1, 0], [0, 1]]) L2 = MultivariateLaplace('L2', [1, 0], [[1, 0], [0, 1]]) assert density(L)(2, 3) == exp(2) * besselk(0, sqrt(39)) / pi L1 = Laplace('L1', [1, 2], [[x, 0], [0, y]]) assert density(L1)(0, 1) == \ exp(2/y)*besselk(0, sqrt((2 + 4/y + 1/x)/y))/(pi*sqrt(x*y)) assert L.pspace.distribution.set == ProductSet(S.Reals, S.Reals) assert L.pspace.distribution == L2.pspace.distribution
def __new__(cls, sets, polar=False): from sympy import sin, cos x, y, r, theta = symbols('x, y, r, theta', cls=Dummy) I = S.ImaginaryUnit polar = sympify(polar) # Rectangular Form if polar == False: if all(_a.is_FiniteSet for _a in sets.args) and (len(sets.args) == 2): # ** ProductSet of FiniteSets in the Complex Plane. ** # For Cases like ComplexRegion({2, 4}*{3}), It # would return {2 + 3*I, 4 + 3*I} complex_num = [] for x in sets.args[0]: for y in sets.args[1]: complex_num.append(x + I * y) obj = FiniteSet(*complex_num) else: obj = ImageSet.__new__(cls, Lambda((x, y), x + I * y), sets) obj._variables = (x, y) obj._expr = x + I * y # Polar Form elif polar == True: new_sets = [] # sets is Union of ProductSets if not sets.is_ProductSet: for k in sets.args: new_sets.append(k) # sets is ProductSets else: new_sets.append(sets) # Normalize input theta for k, v in enumerate(new_sets): new_sets[k] = ProductSet(v.args[0], normalize_theta_set(v.args[1])) sets = Union(*new_sets) obj = ImageSet.__new__( cls, Lambda((r, theta), r * (cos(theta) + I * sin(theta))), sets) obj._variables = (r, theta) obj._expr = r * (cos(theta) + I * sin(theta)) else: raise ValueError("polar should be either True or False") obj._sets = sets obj._polar = polar return obj
def test_ImageSet(): raises(ValueError, lambda: ImageSet(x, S.Integers)) assert ImageSet(Lambda(x, 1), S.Integers) == FiniteSet(1) assert ImageSet(Lambda(x, y), S.Integers) == {y} assert ImageSet(Lambda(x, 1), S.EmptySet) == S.EmptySet empty = Intersection(FiniteSet(log(2) / pi), S.Integers) assert unchanged(ImageSet, Lambda(x, 1), empty) # issue #17471 squares = ImageSet(Lambda(x, x**2), S.Naturals) assert 4 in squares assert 5 not in squares assert FiniteSet(*range(10)).intersect(squares) == FiniteSet(1, 4, 9) assert 16 not in squares.intersect(Interval(0, 10)) si = iter(squares) a, b, c, d = next(si), next(si), next(si), next(si) assert (a, b, c, d) == (1, 4, 9, 16) harmonics = ImageSet(Lambda(x, 1 / x), S.Naturals) assert Rational(1, 5) in harmonics assert Rational(.25) in harmonics assert 0.25 not in harmonics assert Rational(.3) not in harmonics assert (1, 2) not in harmonics assert harmonics.is_iterable assert imageset(x, -x, Interval(0, 1)) == Interval(-1, 0) assert ImageSet(Lambda(x, x**2), Interval(0, 2)).doit() == Interval(0, 4) c = ComplexRegion(Interval(1, 3) * Interval(1, 3)) assert Tuple(2, 6) in ImageSet(Lambda((x, y), (x, 2 * y)), c) assert Tuple(2, S.Half) in ImageSet(Lambda((x, y), (x, 1 / y)), c) assert Tuple(2, -2) not in ImageSet(Lambda((x, y), (x, y**2)), c) assert Tuple(2, -2) in ImageSet(Lambda((x, y), (x, -2)), c) c3 = Interval(3, 7) * Interval(8, 11) * Interval(5, 9) assert Tuple(8, 3, 9) in ImageSet(Lambda((t, y, x), (y, t, x)), c3) assert Tuple(Rational(1, 8), 3, 9) in ImageSet(Lambda((t, y, x), (1 / y, t, x)), c3) assert 2 / pi not in ImageSet(Lambda((x, y), 2 / x), c) assert 2 / S(100) not in ImageSet(Lambda((x, y), 2 / x), c) assert Rational(2, 3) in ImageSet(Lambda((x, y), 2 / x), c) assert imageset(lambda x, y: x + y, S.Integers, S.Naturals).base_set == ProductSet(S.Integers, S.Naturals) # Passing a set instead of a FiniteSet shouldn't raise assert unchanged(ImageSet, Lambda(x, x**2), {1, 2, 3}) raises(TypeError, lambda: ImageSet(Lambda(x, x**2), 1))
def test_MultivariateBeta(): a1, a2 = symbols('a1, a2', positive=True) a1_f, a2_f = symbols('a1, a2', positive=False, real=True) mb = MultivariateBeta('B', [a1, a2]) mb_c = MultivariateBeta('C', a1, a2) assert density(mb)(1, 2) == S(2)**(a2 - 1)*gamma(a1 + a2)/\ (gamma(a1)*gamma(a2)) assert marginal_distribution(mb_c, 0)(3) == S(3)**(a1 - 1)*gamma(a1 + a2)/\ (a2*gamma(a1)*gamma(a2)) raises(ValueError, lambda: MultivariateBeta('b1', [a1_f, a2])) raises(ValueError, lambda: MultivariateBeta('b2', [a1, a2_f])) raises(ValueError, lambda: MultivariateBeta('b3', [0, 0])) raises(ValueError, lambda: MultivariateBeta('b4', [a1_f, a2_f])) assert mb.pspace.distribution.set == ProductSet(Interval(0, 1), Interval(0, 1))
def __new__(cls, sets): new_sets = [] # sets is Union of ProductSets if not sets.is_ProductSet: for k in sets.args: new_sets.append(k) # sets is ProductSets else: new_sets.append(sets) # Normalize input theta for k, v in enumerate(new_sets): new_sets[k] = ProductSet(v.args[0], normalize_theta_set(v.args[1])) sets = Union(*new_sets) return Set.__new__(cls, sets)
def test_NegativeMultinomial(): k0, x1, x2, x3, x4 = symbols('k0, x1, x2, x3, x4', nonnegative=True, integer=True) p1, p2, p3, p4 = symbols('p1, p2, p3, p4', positive=True) p1_f = symbols('p1_f', negative=True) N = NegativeMultinomial('N', 4, [p1, p2, p3, p4]) C = NegativeMultinomial('C', 4, 0.1, 0.2, 0.3) g = gamma f = factorial assert simplify(density(N)(x1, x2, x3, x4) - p1**x1*p2**x2*p3**x3*p4**x4*(-p1 - p2 - p3 - p4 + 1)**4*g(x1 + x2 + x3 + x4 + 4)/(6*f(x1)*f(x2)*f(x3)*f(x4))) is S.Zero assert comp(marginal_distribution(C, C[0])(1).evalf(), 0.33, .01) raises(ValueError, lambda: NegativeMultinomial('b1', 5, [p1, p2, p3, p1_f])) raises(ValueError, lambda: NegativeMultinomial('b2', k0, 0.5, 0.4, 0.3, 0.4)) assert N.pspace.distribution.set == ProductSet(Range(0, oo, 1), Range(0, oo, 1), Range(0, oo, 1), Range(0, oo, 1))
def test_ImageSet(): raises(ValueError, lambda: ImageSet(x, S.Integers)) assert ImageSet(Lambda(x, 1), S.Integers) == FiniteSet(1) assert ImageSet(Lambda(x, y), S.Integers) == {y} squares = ImageSet(Lambda(x, x**2), S.Naturals) assert 4 in squares assert 5 not in squares assert FiniteSet(*range(10)).intersect(squares) == FiniteSet(1, 4, 9) assert 16 not in squares.intersect(Interval(0, 10)) si = iter(squares) a, b, c, d = next(si), next(si), next(si), next(si) assert (a, b, c, d) == (1, 4, 9, 16) harmonics = ImageSet(Lambda(x, 1 / x), S.Naturals) assert Rational(1, 5) in harmonics assert Rational(.25) in harmonics assert 0.25 not in harmonics assert Rational(.3) not in harmonics assert (1, 2) not in harmonics assert harmonics.is_iterable assert imageset(x, -x, Interval(0, 1)) == Interval(-1, 0) assert ImageSet(Lambda(x, x**2), Interval(0, 2)).doit() == Interval(0, 4) c = ComplexRegion(Interval(1, 3) * Interval(1, 3)) assert Tuple(2, 6) in ImageSet(Lambda((x, y), (x, 2 * y)), c) assert Tuple(2, S.Half) in ImageSet(Lambda((x, y), (x, 1 / y)), c) assert Tuple(2, -2) not in ImageSet(Lambda((x, y), (x, y**2)), c) assert Tuple(2, -2) in ImageSet(Lambda((x, y), (x, -2)), c) c3 = Interval(3, 7) * Interval(8, 11) * Interval(5, 9) assert Tuple(8, 3, 9) in ImageSet(Lambda((t, y, x), (y, t, x)), c3) assert Tuple(S(1) / 8, 3, 9) in ImageSet(Lambda((t, y, x), (1 / y, t, x)), c3) assert 2 / pi not in ImageSet(Lambda((x, y), 2 / x), c) assert 2 / S(100) not in ImageSet(Lambda((x, y), 2 / x), c) assert 2 / S(3) in ImageSet(Lambda((x, y), 2 / x), c) assert imageset(lambda x, y: x + y, S.Integers, S.Naturals).base_set == ProductSet(S.Integers, S.Naturals)
def sets(self): return ProductSet(S.Reals, S.Reals)
def __matmul__(self, other): if other.is_set: return ProductSet(self, other) raise Exception("could not multiply %s, %s" % (self, other))
class ImageSet(Set): """ Image of a set under a mathematical function. The transformation must be given as a Lambda function which has as many arguments as the elements of the set upon which it operates, e.g. 1 argument when acting on the set of integers or 2 arguments when acting on a complex region. This function is not normally called directly, but is called from `imageset`. Examples ======== >>> from sympy import Symbol, S, pi, Dummy, Lambda >>> from sympy.sets.sets import FiniteSet, Interval >>> from sympy.sets.fancysets import ImageSet >>> x = Symbol('x') >>> N = S.Naturals >>> squares = ImageSet(Lambda(x, x**2), N) # {x**2 for x in N} >>> 4 in squares True >>> 5 in squares False >>> FiniteSet(0, 1, 2, 3, 4, 5, 6, 7, 9, 10).intersect(squares) {1, 4, 9} >>> square_iterable = iter(squares) >>> for i in range(4): ... next(square_iterable) 1 4 9 16 If you want to get value for `x` = 2, 1/2 etc. (Please check whether the `x` value is in `base_set` or not before passing it as args) >>> squares.lamda(2) 4 >>> squares.lamda(S(1)/2) 1/4 >>> n = Dummy('n') >>> solutions = ImageSet(Lambda(n, n*pi), S.Integers) # solutions of sin(x) = 0 >>> dom = Interval(-1, 1) >>> dom.intersect(solutions) {0} See Also ======== sympy.sets.sets.imageset """ def __new__(cls, flambda, *sets): if not isinstance(flambda, Lambda): raise ValueError('first argument must be a Lambda') if flambda is S.IdentityFunction and len(sets) == 1: return sets[0] if not flambda.expr.free_symbols or not flambda.expr.args: return FiniteSet(flambda.expr) return Basic.__new__(cls, flambda, *sets) lamda = property(lambda self: self.args[0]) base_set = property(lambda self: ProductSet(self.args[1:])) @property def element_type(self): return self.lamda.expr.dtype def _latex(self, p): from sympy.sets.conditionset import ConditionSet if isinstance(self.base_set, ConditionSet) and self.lamda.variables == self.base_set.variable: return r"\left\{%s \left| %s \right. \right\}" % (p._print(self.lamda.expr), p._print(self.base_set.condition)) from sympy.core.containers import Tuple if isinstance(self.lamda.variables, Tuple): sets = self.args[1:] varsets = [r"%s \in %s" % (p._print(var), p._print(setv)) for var, setv in zip(self.lamda.variables, sets)] # return r"\left\{%s\; |\; %s\right\}" % (self._print(s.lamda.expr), ', '.join(varsets)) return r"\left\{%s \left| %s \right. \right\}" % (p._print(self.lamda.expr), ', '.join(varsets)) var = self.lamda.variables setv = self.base_set varsets = r"%s \in %s" % (p._print(var), p._print(setv)) return r"\left\{%s \left| %s \right. \right\}" % (p._print(self.lamda.expr), varsets) def __iter__(self): already_seen = set() for i in self.base_set: val = self.lamda(i) if val in already_seen: continue else: already_seen.add(val) yield val def _is_multivariate(self): return len(self.lamda.variables) > 1 def _contains(self, other): from sympy.matrices import Matrix from sympy.solvers.solveset import solveset, linsolve from sympy.solvers.solvers import solve from sympy.utilities.iterables import is_sequence, iterable, cartes L = self.lamda if is_sequence(other): if not is_sequence(L.expr): return S.false if len(L.expr) != len(other): raise ValueError(filldedent(''' Dimensions of other and output of Lambda are different.''')) elif iterable(other): raise ValueError(filldedent(''' `other` should be an ordered object like a Tuple.''')) solns = None if self._is_multivariate(): if not is_sequence(L.expr): # exprs -> (numer, denom) and check again # XXX this is a bad idea -- make the user # remap self to desired form return other.as_numer_denom() in self.func( Lambda(L.variables, L.expr.as_numer_denom()), self.base_set) eqs = [expr - val for val, expr in zip(other, L.expr)] variables = L.variables free = set(variables) if all(i.is_number for i in list(Matrix(eqs).jacobian(variables))): solns = list(linsolve([e - val for e, val in zip(L.expr, other)], variables)) else: try: syms = [e.free_symbols & free for e in eqs] solns = {} for i, (e, s, v) in enumerate(zip(eqs, syms, other)): if not s: if e != v: return S.false solns[vars[i]] = [v] continue elif len(s) == 1: sy = s.pop() sol = solveset(e, sy) if sol is S.EmptySet: return S.false elif isinstance(sol, FiniteSet): solns[sy] = list(sol) else: raise NotImplementedError else: # if there is more than 1 symbol from # variables in expr than this is a # coupled system raise NotImplementedError solns = cartes(*[solns[s] for s in variables]) except NotImplementedError: solns = solve([e - val for e, val in zip(L.expr, other)], variables, set=True) if solns: _v, solns = solns # watch for infinite solutions like solving # for x, y and getting (x, 0), (0, y), (0, 0) solns = [i for i in solns if not any( s in i for s in variables)] else: x = L.variables[0] if isinstance(L.expr, Expr): # scalar -> scalar mapping solnsSet = solveset(L.expr - other, x) if solnsSet.is_FiniteSet: solns = list(solnsSet) else: msgset = solnsSet else: # scalar -> vector for e, o in zip(L.expr, other): solns = solveset(e - o, x) if solns is S.EmptySet: return S.false for soln in solns: try: if soln in self.base_set: break # check next pair except TypeError: if self.base_set.contains(soln.evalf()): break else: return S.false # never broke so there was no True return S.true if solns is None: raise NotImplementedError(filldedent(''' Determining whether %s contains %s has not been implemented.''' % (msgset, other))) for soln in solns: try: if soln in self.base_set: return S.true except TypeError: return self.base_set.contains(soln.evalf()) return S.false @property def is_iterable(self): return self.base_set.is_iterable def doit(self, **kwargs): from sympy.sets.setexpr import SetExpr f = self.lamda base_set = self.base_set return SetExpr(base_set)._eval_func(f).set
def base_pset(self): return ProductSet(*self.base_sets)
def _(a, b): if len(b.args) != len(a.args): return S.EmptySet return ProductSet(*(i.intersect(j) for i, j in zip(a.sets, b.sets)))
def base_set(self): sets = self.args[1:] if len(sets) == 1: return sets[0] else: return ProductSet(*self.args[1:]).flatten()
def set(self): return ProductSet(*(domain.set for domain in self.domains))
def __mul__(self, other): if other.is_set: return ProductSet(self, other) if other.is_complex: return S.Complexes raise Exception("could not multiply %s, %s" % (self, other))
def intersection_sets(a, b): # noqa:F811 if len(b.args) != len(a.args): return S.EmptySet return ProductSet(*(i.intersect(j) for i, j in zip(a.sets, b.sets)))
class ImageSet(Set): """ Image of a set under a mathematical function. The transformation must be given as a Lambda function which has as many arguments as the elements of the set upon which it operates, e.g. 1 argument when acting on the set of integers or 2 arguments when acting on a complex region. This function is not normally called directly, but is called from `imageset`. Examples ======== >>> from sympy import Symbol, S, pi, Dummy, Lambda >>> from sympy.sets.sets import FiniteSet, Interval >>> from sympy.sets.fancysets import ImageSet >>> x = Symbol('x') >>> N = S.Naturals >>> squares = ImageSet(Lambda(x, x**2), N) # {x**2 for x in N} >>> 4 in squares True >>> 5 in squares False >>> FiniteSet(0, 1, 2, 3, 4, 5, 6, 7, 9, 10).intersect(squares) {1, 4, 9} >>> square_iterable = iter(squares) >>> for i in range(4): ... next(square_iterable) 1 4 9 16 If you want to get value for `x` = 2, 1/2 etc. (Please check whether the `x` value is in `base_set` or not before passing it as args) >>> squares.lamda(2) 4 >>> squares.lamda(S(1)/2) 1/4 >>> n = Dummy('n') >>> solutions = ImageSet(Lambda(n, n*pi), S.Integers) # solutions of sin(x) = 0 >>> dom = Interval(-1, 1) >>> dom.intersect(solutions) {0} See Also ======== sympy.sets.sets.imageset """ def __new__(cls, flambda, *sets): if not isinstance(flambda, Lambda): raise ValueError('first argument must be a Lambda') if flambda is S.IdentityFunction: if len(sets) != 1: raise ValueError('identify function requires a single set') return sets[0] if not set(flambda.variables) & flambda.expr.free_symbols: return FiniteSet(flambda.expr) return Basic.__new__(cls, flambda, *sets) lamda = property(lambda self: self.args[0]) base_set = property(lambda self: ProductSet(self.args[1:])) def __iter__(self): already_seen = set() for i in self.base_set: val = self.lamda(i) if val in already_seen: continue else: already_seen.add(val) yield val def _is_multivariate(self): return len(self.lamda.variables) > 1 def _contains(self, other): from sympy.matrices import Matrix from sympy.solvers.solveset import solveset, linsolve from sympy.solvers.solvers import solve from sympy.utilities.iterables import is_sequence, iterable, cartes L = self.lamda if is_sequence(other) != is_sequence(L.expr): return False elif is_sequence(other) and len(L.expr) != len(other): return False if self._is_multivariate(): if not is_sequence(L.expr): # exprs -> (numer, denom) and check again # XXX this is a bad idea -- make the user # remap self to desired form return other.as_numer_denom() in self.func( Lambda(L.variables, L.expr.as_numer_denom()), self.base_set) eqs = [expr - val for val, expr in zip(other, L.expr)] variables = L.variables free = set(variables) if all(i.is_number for i in list(Matrix(eqs).jacobian(variables))): solns = list( linsolve([e - val for e, val in zip(L.expr, other)], variables)) else: try: syms = [e.free_symbols & free for e in eqs] solns = {} for i, (e, s, v) in enumerate(zip(eqs, syms, other)): if not s: if e != v: return S.false solns[vars[i]] = [v] continue elif len(s) == 1: sy = s.pop() sol = solveset(e, sy) if sol is S.EmptySet: return S.false elif isinstance(sol, FiniteSet): solns[sy] = list(sol) else: raise NotImplementedError else: # if there is more than 1 symbol from # variables in expr than this is a # coupled system raise NotImplementedError solns = cartes(*[solns[s] for s in variables]) except NotImplementedError: solns = solve([e - val for e, val in zip(L.expr, other)], variables, set=True) if solns: _v, solns = solns # watch for infinite solutions like solving # for x, y and getting (x, 0), (0, y), (0, 0) solns = [ i for i in solns if not any(s in i for s in variables) ] if not solns: return False else: # not sure if [] means no solution or # couldn't find one return else: x = L.variables[0] if isinstance(L.expr, Expr): # scalar -> scalar mapping solnsSet = solveset(L.expr - other, x) if solnsSet.is_FiniteSet: solns = list(solnsSet) else: msgset = solnsSet else: # scalar -> vector # note: it is not necessary for components of other # to be in the corresponding base set unless the # computed component is always in the corresponding # domain. e.g. 1/2 is in imageset(x, x/2, Integers) # while it cannot be in imageset(x, x + 2, Integers). # So when the base set is comprised of integers or reals # perhaps a pre-check could be done to see if the computed # values are still in the set. dom = self.base_set for e, o in zip(L.expr, other): msgset = dom other = e - o dom = dom.intersection(solveset(e - o, x, domain=dom)) if not dom: # there is no solution in common return False return not isinstance(dom, Intersection) for soln in solns: try: if soln in self.base_set: return True except TypeError: return return S.false @property def is_iterable(self): return self.base_set.is_iterable def doit(self, **kwargs): from sympy.sets.setexpr import SetExpr f = self.lamda base_set = self.base_set return SetExpr(base_set)._eval_func(f).set