def marginal_distribution(self, *indices): count = self.component_count orig = [Indexed(self.symbol, i) for i in range(count)] all_syms = [Symbol(str(i)) for i in orig] replace_dict = dict(zip(all_syms, orig)) sym = [Symbol(str(Indexed(self.symbol, i))) for i in indices] limits = list([i,] for i in all_syms if i not in sym) index = 0 for i in range(count): if i not in indices: limits[index].append(self.distribution.set.args[i]) limits[index] = tuple(limits[index]) index += 1 if self.distribution.is_Continuous: f = Lambda(sym, integrate(self.distribution(*all_syms), *limits)) elif self.distribution.is_Discrete: f = Lambda(sym, summation(self.distribution(*all_syms), *limits)) return f.xreplace(replace_dict)
def test_Roots(): f = Poly(x**17 + x - 1, x) assert str(RootsOf(f)) == "RootsOf(x**17 + x - 1, x)" assert str(RootOf(f, 0)) == "RootOf(x**17 + x - 1, x, index=0)" assert str(RootSum(Lambda(z, z**2), f)) == "RootSum(Lambda(_z, _z**2), x**17 + x - 1, x)"
def compute_moment_generating_function(self, expr): d = self.compute_density(expr) t = Dummy('t', real=True) return Lambda(t, sum(exp(k * t) * v for k, v in d.items()))
def test_sym_integral(): f = Lambda(x, exp(-x**2)) l = lambdify(x, Integral(f(x), (x, -oo, oo)), modules="sympy") assert l(y).doit() == sqrt(pi)
'R2', 'R2_origin', 'relations_2d', 'R2_r', 'R2_p', 'R3', 'R3_origin', 'relations_3d', 'R3_r', 'R3_c', 'R3_s' ] ############################################################################### # R2 ############################################################################### R2 = Manifold('R^2', 2) # type: Any R2_origin = Patch('origin', R2) # type: Any x, y = symbols('x y', real=True) r, theta = symbols('rho theta', nonnegative=True) relations_2d = { ('rectangular', 'polar'): Lambda((x, y), Matrix([sqrt(x**2 + y**2), atan2(y, x)])), ('polar', 'rectangular'): Lambda((r, theta), Matrix([r*cos(theta), r*sin(theta)])), } R2_r = CoordSystem('rectangular', R2_origin, [x, y], relations_2d) # type: Any R2_p = CoordSystem('polar', R2_origin, [r, theta], relations_2d) # type: Any # support deprecated feature with warnings.catch_warnings(): warnings.simplefilter("ignore") x, y, r, theta = symbols('x y r theta', cls=Dummy) R2_r.connect_to(R2_p, [x, y], [sqrt(x**2 + y**2), atan2(y, x)], inverse=False, fill_in_gaps=False) R2_p.connect_to(R2_r, [r, theta], [r*cos(theta), r*sin(theta)],
def test_Lambda_arguments(): raises(TypeError, lambda: Lambda(x, 2*x)(x, y)) raises(TypeError, lambda: Lambda((x, y), x + y)(x)) raises(TypeError, lambda: Lambda((), 42)(x))
def test_IdentityFunction(): assert Lambda(x, x) is Lambda(y, y) is S.IdentityFunction assert Lambda(x, 2*x) is not S.IdentityFunction assert Lambda((x, y), x) is not S.IdentityFunction
def main(): print __doc__ # arrays are represented with IndexedBase, indices with Idx m = Symbol('m', integer=True) i = Idx('i', m) A = IndexedBase('A') B = IndexedBase('B') x = Symbol('x') print "Compiling ufuncs for radial harmonic oscillator solutions" # setup a basis of ho-solutions (for l=0) basis_ho = {} for n in range(basis_dimension): # Setup the radial ho solution for this n expr = R_nl(n, orbital_momentum_l, omega2, x) # Reduce the number of operations in the expression by eval to float expr = expr.evalf(15) print "The h.o. wave function with l = %i and n = %i is" % ( orbital_momentum_l, n) pprint(expr) # implement, compile and wrap it as a ufunc basis_ho[n] = ufuncify(x, expr) # now let's see if we can express a hydrogen radial wave in terms of # the ho basis. Here's the solution we will approximate: H_ufunc = ufuncify(x, hydro_nl(hydrogen_n, orbital_momentum_l, 1, x)) # The transformation to a different basis can be written like this, # # psi(r) = sum_i c(i) phi_i(r) # # where psi(r) is the hydrogen solution, phi_i(r) are the H.O. solutions # and c(i) are scalar coefficients. # # So in order to express a hydrogen solution in terms of the H.O. basis, we # need to determine the coefficients c(i). In position space, it means # that we need to evaluate an integral: # # psi(r) = sum_i Integral(R**2*conj(phi(R))*psi(R), (R, 0, oo)) phi_i(r) # # To calculate the integral with autowrap, we notice that it contains an # element-wise sum over all vectors. Using the Indexed class, it is # possible to generate autowrapped functions that perform summations in # the low-level code. (In fact, summations are very easy to create, and as # we will see it is often necessary to take extra steps in order to avoid # them.) # we need one integration ufunc for each wave function in the h.o. basis binary_integrator = {} for n in range(basis_dimension): # # setup basis wave functions # # To get inline expressions in the low level code, we attach the # wave function expressions to a regular Sympy function using the # implemented_function utility. This is an extra step needed to avoid # erronous summations in the wave function expressions. # # Such function objects carry around the expression they represent, # but the expression is not exposed unless explicit measures are taken. # The benefit is that the routines that searches for repeated indices # in order to make contractions will not search through the wave # function expression. psi_ho = implemented_function( 'psi_ho', Lambda(x, R_nl(n, orbital_momentum_l, omega2, x))) # We represent the hydrogen function by an array which will be an input # argument to the binary routine. This will let the integrators find # h.o. basis coefficients for any wave function we throw at them. psi = IndexedBase('psi') # # setup expression for the integration # step = Symbol('step') # use symbolic stepsize for flexibility # let i represent an index of the grid array, and let A represent the # grid array. Then we can approximate the integral by a sum over the # following expression (simplified rectangular rule, ignoring end point # corrections): expr = A[i]**2 * psi_ho(A[i]) * psi[i] * step if n == 0: print "Setting up binary integrators for the integral:" pprint(Integral(x**2 * psi_ho(x) * Function('psi')(x), (x, 0, oo))) # But it needs to be an operation on indexed objects, so that the code # generators will recognize it correctly as an array. # expr = expr.subs(x, A[i]) # Autowrap it. For functions that take more than one argument, it is # a good idea to use the 'args' keyword so that you know the signature # of the wrapped function. (The dimension m will be an optional # argument, but it must be present in the args list.) binary_integrator[n] = autowrap(expr, args=[A.label, psi.label, step, m]) # Lets see how it converges with the grid dimension print "Checking convergence of integrator for n = %i" % n for g in range(3, 8): grid, step = np.linspace(0, rmax, 2**g, retstep=True) print "grid dimension %5i, integral = %e" % ( 2**g, binary_integrator[n](grid, H_ufunc(grid), step)) print "A binary integrator has been set up for each basis state" print "We will now use them to reconstruct a hydrogen solution." # Note: We didn't need to specify grid or use gridsize before now grid, stepsize = np.linspace(0, rmax, gridsize, retstep=True) print "Calculating coefficients with gridsize = %i and stepsize %f" % ( len(grid), stepsize) coeffs = {} for n in range(basis_dimension): coeffs[n] = binary_integrator[n](grid, H_ufunc(grid), stepsize) print "c(%i) = %e" % (n, coeffs[n]) print "Constructing the approximate hydrogen wave" hydro_approx = 0 all_steps = {} for n in range(basis_dimension): hydro_approx += basis_ho[n](grid) * coeffs[n] all_steps[n] = hydro_approx.copy() if pylab: line = pylab.plot(grid, all_steps[n], ':', label='max n = %i' % n) # check error numerically diff = np.max(np.abs(hydro_approx - H_ufunc(grid))) print "Error estimate: the element with largest deviation misses by %f" % diff if diff > 0.01: print "This is much, try to increase the basis size or adjust omega" else: print "Ah, that's a pretty good approximation!" # Check visually if pylab: print "Here's a plot showing the contribution for each n" line[0].set_linestyle('-') pylab.plot(grid, H_ufunc(grid), 'r-', label='exact') pylab.legend() pylab.show() print """Note:
def pdf(self): x = Symbol('x') return Lambda( x, Piecewise(*([(v, Eq(k, x)) for k, v in self.dict.items()] + [(0, True)])))
latex) from sympy.sets.sets import FiniteSet, Interval from sympy.sets.fancysets import ImageSet t = Symbol('t') T = Symbol(r'\mathbb{T}') # Iterables print(latex(T)) TS0 = tsc(S.EmptySet, latex(T) + '=' + latex(S.EmptySet)) TS1 = tsc(Range(-2, 1), latex(T) + '=' + latex(Range(-2, 1))) TS2 = tsc(Range(-oo, 5, 5), latex(T) + '=' + latex(Range(-oo, 5, 5))) TS3 = tsc(Range(0, oo, 7), latex(T) + '=' + latex(Range(0, oo, 7))) TS4 = tsc(S.Naturals, latex(T) + '=' + latex(S.Naturals)) TS5 = tsc(S.Naturals0, latex(T) + '=' + latex(S.Naturals0)) TS6 = tsc(S.Integers, latex(T) + '=' + latex(S.Integers)) TS7 = tsc(ImageSet(Lambda(t, -t), S.Naturals), latex(T) + '=' + latex(ImageSet(Lambda(t, -t), S.Naturals))) # TODO: Create an instance of rational numbers in some subset like Interval(0,1s). # TODO: Recorrer las fracciones de la siguiente manera: # https://mathoverflow.net/questions/200656/is-there-a-natural-bijection-from-mathbbn-to-mathbbq # Non-interables TS9 = tsc(S.Reals, latex(T) + '=' + latex(S.Reals)) # Means Interval(-oo,+oo). TS10 = tsc(S.UniversalSet, latex(T) + '=' + latex(S.UniversalSet)) # print(list(TS1.ts)) # TODO: Implementar raise try: iterator = iter(TS9.ts) except TypeError:
def level_spacing_distribution(self): s = Dummy('s') f = ((S(2)**18) / ((S(3)**6) * (pi**3))) * (s**4) * exp( (-64 / (9 * pi)) * s**2) return Lambda(s, f)
def density(self, expr): n, ZGSE = self.dimension, self.normalization_constant h_pspace = RandomMatrixPSpace('P', model=self) H = RandomMatrixSymbol('H', n, n, pspace=h_pspace) return Lambda(H, exp(-S(n) * Trace(H**2)) / ZGSE)
def level_spacing_distribution(self): s = Dummy('s') f = (pi / 2) * s * exp((-pi / 4) * s**2) return Lambda(s, f)
def level_spacing_distribution(self): s = Dummy('s') f = (32 / pi**2) * (s**2) * exp((-4 / pi) * s**2) return Lambda(s, f)
def test_re(): x, y = symbols('x,y') a, b = symbols('a,b', real=True) r = Symbol('r', real=True) i = Symbol('i', imaginary=True) assert re(nan) == nan assert re(oo) == oo assert re(-oo) == -oo assert re(0) == 0 assert re(1) == 1 assert re(-1) == -1 assert re(E) == E assert re(-E) == -E assert re(x) == re(x) assert re(x * I) == -im(x) assert re(r * I) == 0 assert re(r) == r assert re(i * I) == I * i assert re(i) == 0 assert re(x + y) == re(x + y) assert re(x + r) == re(x) + r assert re(re(x)) == re(x) assert re(2 + I) == 2 assert re(x + I) == re(x) assert re(x + y * I) == re(x) - im(y) assert re(x + r * I) == re(x) assert re(log(2 * I)) == log(2) assert re((2 + I)**2).expand(complex=True) == 3 assert re(conjugate(x)) == re(x) assert conjugate(re(x)) == re(x) assert re(x).as_real_imag() == (re(x), 0) assert re(i * r * x).diff(r) == re(i * x) assert re(i * r * x).diff(i) == I * r * im(x) assert re( sqrt(a + b * I)) == (a**2 + b**2)**Rational(1, 4) * cos(atan2(b, a) / 2) assert re(a * (2 + b * I)) == 2 * a assert re((1 + sqrt(a + b*I))/2) == \ (a**2 + b**2)**Rational(1, 4)*cos(atan2(b, a)/2)/2 + Rational(1, 2) assert re(x).rewrite(im) == x - S.ImaginaryUnit * im(x) assert (x + re(y)).rewrite(re, im) == x + y - S.ImaginaryUnit * im(y) a = Symbol('a', algebraic=True) t = Symbol('t', transcendental=True) x = Symbol('x') assert re(a).is_algebraic assert re(x).is_algebraic is None assert re(t).is_algebraic is False assert re(S.ComplexInfinity) == S.NaN n, m, l = symbols('n m l') A = MatrixSymbol('A', n, m) assert re(A) == (S(1) / 2) * (A + conjugate(A)) A = Matrix([[1 + 4 * I, 2], [0, -3 * I]]) assert re(A) == Matrix([[1, 2], [0, 0]]) A = ImmutableMatrix([[1 + 3 * I, 3 - 2 * I], [0, 2 * I]]) assert re(A) == ImmutableMatrix([[1, 3], [0, 0]]) X = SparseMatrix([[2 * j + i * I for i in range(5)] for j in range(5)]) assert re(X) - Matrix([[0, 0, 0, 0, 0], [2, 2, 2, 2, 2], [4, 4, 4, 4, 4], [6, 6, 6, 6, 6], [8, 8, 8, 8, 8] ]) == Matrix.zeros(5) assert im(X) - Matrix([[0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4] ]) == Matrix.zeros(5) X = FunctionMatrix(3, 3, Lambda((n, m), n + m * I)) assert re(X) == Matrix([[0, 0, 0], [1, 1, 1], [2, 2, 2]])
def test_lambda(): x = Symbol('x') assert sympify('lambda: 1') == Lambda((), 1) assert sympify('lambda x: x') == Lambda(x, x) assert sympify('lambda x: 2*x') == Lambda(x, 2*x) assert sympify('lambda x, y: 2*x+y') == Lambda([x, y], 2*x + y)
def characteristic_function(self): t = Dummy('t', real=True) return Lambda(t, sum(exp(I * k * t) * v for k, v in self.dict.items()))
def test_Lambda(): e = Lambda(x, x**2) assert e(4) == 16 assert e(x) == x**2 assert e(y) == y**2 assert Lambda((), 42)() == 42 assert unchanged(Lambda, (), 42) assert Lambda((), 42) != Lambda((), 43) assert Lambda((), f(x))() == f(x) assert Lambda((), 42).nargs == FiniteSet(0) assert unchanged(Lambda, (x,), x**2) assert Lambda(x, x**2) == Lambda((x,), x**2) assert Lambda(x, x**2) == Lambda(y, y**2) assert Lambda(x, x**2) != Lambda(y, y**2 + 1) assert Lambda((x, y), x**y) == Lambda((y, x), y**x) assert Lambda((x, y), x**y) != Lambda((x, y), y**x) assert Lambda((x, y), x**y)(x, y) == x**y assert Lambda((x, y), x**y)(3, 3) == 3**3 assert Lambda((x, y), x**y)(x, 3) == x**3 assert Lambda((x, y), x**y)(3, y) == 3**y assert Lambda(x, f(x))(x) == f(x) assert Lambda(x, x**2)(e(x)) == x**4 assert e(e(x)) == x**4 x1, x2 = (Indexed('x', i) for i in (1, 2)) assert Lambda((x1, x2), x1 + x2)(x, y) == x + y assert Lambda((x, y), x + y).nargs == FiniteSet(2) p = x, y, z, t assert Lambda(p, t*(x + y + z))(*p) == t * (x + y + z) assert Lambda(x, 2*x) + Lambda(y, 2*y) == 2*Lambda(x, 2*x) assert Lambda(x, 2*x) not in [ Lambda(x, x) ] raises(BadSignatureError, lambda: Lambda(1, x)) assert Lambda(x, 1)(1) is S.One raises(BadSignatureError, lambda: Lambda((x, x), x + 2)) raises(BadSignatureError, lambda: Lambda(((x, x), y), x)) raises(BadSignatureError, lambda: Lambda(((y, x), x), x)) raises(BadSignatureError, lambda: Lambda(((y, 1), 2), x)) with warns_deprecated_sympy(): assert Lambda([x, y], x+y) == Lambda((x, y), x+y) flam = Lambda( ((x, y),) , x + y) assert flam((2, 3)) == 5 flam = Lambda( ((x, y), z) , x + y + z) assert flam((2, 3), 1) == 6 flam = Lambda( (((x,y),z),) , x+y+z) assert flam( ((2,3),1) ) == 6 raises(BadArgumentsError, lambda: flam(1, 2, 3)) flam = Lambda( (x,), (x, x)) assert flam(1,) == (1, 1) assert flam((1,)) == ((1,), (1,)) flam = Lambda( ((x,),) , (x, x)) raises(BadArgumentsError, lambda: flam(1)) assert flam((1,)) == (1, 1) # Previously TypeError was raised so this is potentially needed for # backwards compatibility. assert issubclass(BadSignatureError, TypeError) assert issubclass(BadArgumentsError, TypeError) # These are tested to see they don't raise: hash(Lambda(x, 2*x)) hash(Lambda(x, x)) # IdentityFunction subclass
def test_Lambda_symbols(): assert Lambda(x, 2 * x).free_symbols == set() assert Lambda(x, x * y).free_symbols == set([y])
def test_Lambda_symbols(): assert Lambda(x, 2*x).free_symbols == set() assert Lambda(x, x*y).free_symbols == {y} assert Lambda((), 42).free_symbols == set() assert Lambda((), x*y).free_symbols == {x,y}
def test_Lambda(): e = Lambda(x, x**2) assert e(4) == 16 assert e(x) == x**2 assert e(y) == y**2 assert Lambda(x, x**2) == Lambda(x, x**2) assert Lambda(x, x**2) == Lambda(y, y**2) assert Lambda(x, x**2) != Lambda(y, y**2 + 1) assert Lambda((x, y), x**y) == Lambda((y, x), y**x) assert Lambda((x, y), x**y) != Lambda((x, y), y**x) assert Lambda((x, y), x**y)(x, y) == x**y assert Lambda((x, y), x**y)(3, 3) == 3**3 assert Lambda((x, y), x**y)(x, 3) == x**3 assert Lambda((x, y), x**y)(3, y) == 3**y assert Lambda(x, f(x))(x) == f(x) assert Lambda(x, x**2)(e(x)) == x**4 assert e(e(x)) == x**4 assert Lambda((x, y), x + y).nargs == 2 p = x, y, z, t assert Lambda(p, t * (x + y + z))(*p) == t * (x + y + z) assert Lambda(x, 2 * x) + Lambda(y, 2 * y) == 2 * Lambda(x, 2 * x) assert Lambda(x, 2 * x) not in [Lambda(x, x)]
def test_diff_wrt_func_subs(): assert f(g(x)).diff(x).subs(g, Lambda(x, 2*x)).doit() == f(2*x).diff(x)
def test_RootSum___new__(): f = x**3 + x + 3 g = Lambda(r, log(r * x)) s = RootSum(f, g) assert isinstance(s, RootSum) == True assert RootSum(f**2, g) == 2 * RootSum(f, g) assert RootSum((x - 7) * f**3, g) == log(7 * x) + 3 * RootSum(f, g) # Issue 2472 assert hash(RootSum((x - 7) * f**3, g)) == hash(log(7 * x) + 3 * RootSum(f, g)) raises(MultivariatePolynomialError, "RootSum(x**3 + x + y)") raises(ValueError, "RootSum(x**2 + 3, lambda x: x)") assert RootSum(f, exp) == RootSum(f, Lambda(x, exp(x))) assert RootSum(f, log) == RootSum(f, Lambda(x, log(x))) assert isinstance(RootSum(f, auto=False), RootSum) == True assert RootSum(f) == 0 assert RootSum(f, Lambda(x, x)) == 0 assert RootSum(f, Lambda(x, x**2)) == -2 assert RootSum(f, Lambda(x, 1)) == 3 assert RootSum(f, Lambda(x, 2)) == 6 assert RootSum(f, auto=False).is_commutative == True assert RootSum(f, Lambda(x, 1 / (x + x**2))) == S(11) / 3 assert RootSum(f, Lambda(x, y / (x + x**2))) == S(11) / 3 * y assert RootSum(x**2 - 1, Lambda(x, 3 * x**2), x) == 6 assert RootSum(x**2 - y, Lambda(x, 3 * x**2), x) == 6 * y assert RootSum(x**2 - 1, Lambda(x, z * x**2), x) == 2 * z assert RootSum(x**2 - y, Lambda(x, z * x**2), x) == 2 * z * y assert RootSum(x**2 - 1, Lambda(x, exp(x)), quadratic=True) == exp(-1) + exp(1) assert RootSum(x**3 + a * x + a**3, tan, x) == RootSum(x**3 + x + 1, Lambda(x, tan(a * x))) assert RootSum(a**3 * x**3 + a * x + 1, tan, x) == RootSum(x**3 + x + 1, Lambda(x, tan(x / a)))
def test_integral(): f = Lambda(x, exp(-x**2)) l = lambdify(x, Integral(f(x), (x, -oo, oo)), modules="sympy") assert l(x) == Integral(exp(-x**2), (x, -oo, oo))
def test_RootSum_free_symbols(): assert RootSum(x**3 + x + 3, Lambda(r, exp(r))).free_symbols == set() assert RootSum(x**3 + x + 3, Lambda(r, exp(a * r))).free_symbols == set([a]) assert RootSum(x**3 + x + y, Lambda(r, exp(a * r)), x).free_symbols == set([a, y])
def compute_characteristic_function(self, expr): d = self.compute_density(expr) t = Dummy('t', real=True) return Lambda(t, sum(exp(I * k * t) * v for k, v in d.items()))
def test_applyfunc_matrix(): x = Dummy("x") double = Lambda(x, x ** 2) expr = ElementwiseApplyFunction(double, Xd) assert isinstance(expr, ElementwiseApplyFunction) assert expr.doit() == Xd.applyfunc(lambda x: x ** 2) assert expr.shape == (3, 3) assert expr.func(*expr.args) == expr assert simplify(expr) == expr assert expr[0, 0] == double(Xd[0, 0]) expr = ElementwiseApplyFunction(double, X) assert isinstance(expr, ElementwiseApplyFunction) assert isinstance(expr.doit(), ElementwiseApplyFunction) assert expr == X.applyfunc(double) assert expr.func(*expr.args) == expr expr = ElementwiseApplyFunction(exp, X * Y) assert expr.expr == X * Y assert expr.function == Lambda(x, exp(x)) assert expr == (X * Y).applyfunc(exp) assert expr.func(*expr.args) == expr assert isinstance(X * expr, MatMul) assert (X * expr).shape == (3, 3) Z = MatrixSymbol("Z", 2, 3) assert (Z * expr).shape == (2, 3) expr = ElementwiseApplyFunction(exp, Z.T) * ElementwiseApplyFunction(exp, Z) assert expr.shape == (3, 3) expr = ElementwiseApplyFunction(exp, Z) * ElementwiseApplyFunction(exp, Z.T) assert expr.shape == (2, 2) raises( ShapeError, lambda: ElementwiseApplyFunction(exp, Z) * ElementwiseApplyFunction(exp, Z), ) M = Matrix([[x, y], [z, t]]) expr = ElementwiseApplyFunction(sin, M) assert isinstance(expr, ElementwiseApplyFunction) assert expr.function == Lambda(x, sin(x)) assert expr.expr == M assert expr.doit() == M.applyfunc(sin) assert expr.doit() == Matrix([[sin(x), sin(y)], [sin(z), sin(t)]]) assert expr.func(*expr.args) == expr expr = ElementwiseApplyFunction(double, Xk) assert expr.doit() == expr assert expr.subs(k, 2).shape == (2, 2) assert (expr * expr).shape == (k, k) M = MatrixSymbol("M", k, t) expr2 = M.T * expr * M assert isinstance(expr2, MatMul) assert expr2.args[1] == expr assert expr2.shape == (t, t) expr3 = expr * M assert expr3.shape == (k, t) raises(ShapeError, lambda: M * expr) expr1 = ElementwiseApplyFunction(lambda x: x + 1, Xk) expr2 = ElementwiseApplyFunction(lambda x: x, Xk) assert expr1 != expr2
def test_Lambda(): assert str(Lambda(d, d**2)) == "Lambda(_d, _d**2)"
def intersection_sets(self, other): # noqa:F811 from sympy.solvers.diophantine import diophantine # Only handle the straight-forward univariate case if (len(self.lamda.variables) > 1 or self.lamda.signature != self.lamda.variables): return None base_set = self.base_sets[0] # Intersection between ImageSets with Integers as base set # For {f(n) : n in Integers} & {g(m) : m in Integers} we solve the # diophantine equations f(n)=g(m). # If the solutions for n are {h(t) : t in Integers} then we return # {f(h(t)) : t in integers}. # If the solutions for n are {n_1, n_2, ..., n_k} then we return # {f(n_i) : 1 <= i <= k}. if base_set is S.Integers: gm = None if isinstance(other, ImageSet) and other.base_sets == (S.Integers, ): gm = other.lamda.expr var = other.lamda.variables[0] # Symbol of second ImageSet lambda must be distinct from first m = Dummy('m') gm = gm.subs(var, m) elif other is S.Integers: m = gm = Dummy('m') if gm is not None: fn = self.lamda.expr n = self.lamda.variables[0] try: solns = list(diophantine(fn - gm, syms=(n, m), permute=True)) except (TypeError, NotImplementedError): # TypeError if equation not polynomial with rational coeff. # NotImplementedError if correct format but no solver. return # 3 cases are possible for solns: # - empty set, # - one or more parametric (infinite) solutions, # - a finite number of (non-parametric) solution couples. # Among those, there is one type of solution set that is # not helpful here: multiple parametric solutions. if len(solns) == 0: return EmptySet elif any(s.free_symbols for tupl in solns for s in tupl): if len(solns) == 1: soln, solm = solns[0] (t, ) = soln.free_symbols expr = fn.subs(n, soln.subs(t, n)).expand() return imageset(Lambda(n, expr), S.Integers) else: return else: return FiniteSet(*(fn.subs(n, s[0]) for s in solns)) if other == S.Reals: from sympy.core.function import expand_complex from sympy.solvers.solvers import denoms, solve_linear from sympy.core.relational import Eq def _solution_union(exprs, sym): # return a union of linear solutions to i in expr; # if i cannot be solved, use a ConditionSet for solution sols = [] for i in exprs: x, xis = solve_linear(i, 0, [sym]) if x == sym: sols.append(FiniteSet(xis)) else: sols.append(ConditionSet(sym, Eq(i, 0))) return Union(*sols) f = self.lamda.expr n = self.lamda.variables[0] n_ = Dummy(n.name, real=True) f_ = f.subs(n, n_) re, im = f_.as_real_imag() im = expand_complex(im) re = re.subs(n_, n) im = im.subs(n_, n) ifree = im.free_symbols lam = Lambda(n, re) if im.is_zero: # allow re-evaluation # of self in this case to make # the result canonical pass elif im.is_zero is False: return S.EmptySet elif ifree != {n}: return None else: # univarite imaginary part in same variable; # use numer instead of as_numer_denom to keep # this as fast as possible while still handling # simple cases base_set &= _solution_union(Mul.make_args(numer(im)), n) # exclude values that make denominators 0 base_set -= _solution_union(denoms(f), n) return imageset(lam, base_set) elif isinstance(other, Interval): from sympy.solvers.solveset import (invert_real, invert_complex, solveset) f = self.lamda.expr n = self.lamda.variables[0] new_inf, new_sup = None, None new_lopen, new_ropen = other.left_open, other.right_open if f.is_real: inverter = invert_real else: inverter = invert_complex g1, h1 = inverter(f, other.inf, n) g2, h2 = inverter(f, other.sup, n) if all(isinstance(i, FiniteSet) for i in (h1, h2)): if g1 == n: if len(h1) == 1: new_inf = h1.args[0] if g2 == n: if len(h2) == 1: new_sup = h2.args[0] # TODO: Design a technique to handle multiple-inverse # functions # Any of the new boundary values cannot be determined if any(i is None for i in (new_sup, new_inf)): return range_set = S.EmptySet if all(i.is_real for i in (new_sup, new_inf)): # this assumes continuity of underlying function # however fixes the case when it is decreasing if new_inf > new_sup: new_inf, new_sup = new_sup, new_inf new_interval = Interval(new_inf, new_sup, new_lopen, new_ropen) range_set = base_set.intersect(new_interval) else: if other.is_subset(S.Reals): solutions = solveset(f, n, S.Reals) if not isinstance(range_set, (ImageSet, ConditionSet)): range_set = solutions.intersect(other) else: return if range_set is S.EmptySet: return S.EmptySet elif isinstance(range_set, Range) and range_set.size is not S.Infinity: range_set = FiniteSet(*list(range_set)) if range_set is not None: return imageset(Lambda(n, f), range_set) return else: return
def _visit_Lambda(self, stmt): expr = self._visit(stmt.body) args = self._visit(stmt.args) return Lambda(tuple(args), expr)
def test_im(): x, y = symbols('x,y') a, b = symbols('a,b', real=True) r = Symbol('r', real=True) i = Symbol('i', imaginary=True) assert im(nan) == nan assert im(oo * I) == oo assert im(-oo * I) == -oo assert im(0) == 0 assert im(1) == 0 assert im(-1) == 0 assert im(E * I) == E assert im(-E * I) == -E assert im(x) == im(x) assert im(x * I) == re(x) assert im(r * I) == r assert im(r) == 0 assert im(i * I) == 0 assert im(i) == -I * i assert im(x + y) == im(x + y) assert im(x + r) == im(x) assert im(x + r * I) == im(x) + r assert im(im(x) * I) == im(x) assert im(2 + I) == 1 assert im(x + I) == im(x) + 1 assert im(x + y * I) == im(x) + re(y) assert im(x + r * I) == im(x) + r assert im(log(2 * I)) == pi / 2 assert im((2 + I)**2).expand(complex=True) == 4 assert im(conjugate(x)) == -im(x) assert conjugate(im(x)) == im(x) assert im(x).as_real_imag() == (im(x), 0) assert im(i * r * x).diff(r) == im(i * x) assert im(i * r * x).diff(i) == -I * re(r * x) assert im( sqrt(a + b * I)) == (a**2 + b**2)**Rational(1, 4) * sin(atan2(b, a) / 2) assert im(a * (2 + b * I)) == a * b assert im((1 + sqrt(a + b*I))/2) == \ (a**2 + b**2)**Rational(1, 4)*sin(atan2(b, a)/2)/2 assert im(x).rewrite(re) == -S.ImaginaryUnit * (x - re(x)) assert (x + im(y)).rewrite(im, re) == x - S.ImaginaryUnit * (y - re(y)) a = Symbol('a', algebraic=True) t = Symbol('t', transcendental=True) x = Symbol('x') assert re(a).is_algebraic assert re(x).is_algebraic is None assert re(t).is_algebraic is False assert im(S.ComplexInfinity) == S.NaN n, m, l = symbols('n m l') A = MatrixSymbol('A', n, m) assert im(A) == (S(1) / (2 * I)) * (A - conjugate(A)) A = Matrix([[1 + 4 * I, 2], [0, -3 * I]]) assert im(A) == Matrix([[4, 0], [0, -3]]) A = ImmutableMatrix([[1 + 3 * I, 3 - 2 * I], [0, 2 * I]]) assert im(A) == ImmutableMatrix([[3, -2], [0, 2]]) X = ImmutableSparseMatrix([[i * I + i for i in range(5)] for i in range(5)]) Y = SparseMatrix([[i for i in range(5)] for i in range(5)]) assert im(X).as_immutable() == Y X = FunctionMatrix(3, 3, Lambda((n, m), n + m * I)) assert im(X) == Matrix([[0, 1, 2], [0, 1, 2], [0, 1, 2]])