def rep_innerproduct(expr, **options): """ Returns an innerproduct like representation (e.g. ``<x'|x>``) for the given state. Attempts to calculate inner product with a bra from the specified basis. Should only be passed an instance of KetBase or BraBase Parameters ========== expr : KetBase or BraBase The expression to be represented Examples ======== >>> from sympy.physics.quantum.represent import rep_innerproduct >>> from sympy.physics.quantum.cartesian import XOp, XKet, PxOp, PxKet >>> rep_innerproduct(XKet()) DiracDelta(x - x_1) >>> rep_innerproduct(XKet(), basis=PxOp()) sqrt(2)*exp(-I*px_1*x/hbar)/(2*sqrt(hbar)*sqrt(pi)) >>> rep_innerproduct(PxKet(), basis=XOp()) sqrt(2)*exp(I*px*x_1/hbar)/(2*sqrt(hbar)*sqrt(pi)) """ if not isinstance(expr, (KetBase, BraBase)): raise TypeError("expr passed is not a Bra or Ket") basis = get_basis(expr, **options) if not isinstance(basis, StateBase): raise NotImplementedError("Can't form this representation!") if "index" not in options: options["index"] = 1 basis_kets = enumerate_states(basis, options["index"], 2) if isinstance(expr, BraBase): bra = expr ket = (basis_kets[1] if basis_kets[0].dual == expr else basis_kets[0]) else: bra = (basis_kets[1].dual if basis_kets[0] == expr else basis_kets[0].dual) ket = expr prod = InnerProduct(bra, ket) result = prod.doit() format = options.get('format', 'sympy') return expr._format_represent(result, format)
def rep_innerproduct(expr, **options): """ Returns an innerproduct like representation (e.g. ``<x'|x>``) for the given state. Attempts to calculate inner product with a bra from the specified basis. Should only be passed an instance of KetBase or BraBase Parameters ========== expr : KetBase or BraBase The expression to be represented Examples ======== >>> from sympy.physics.quantum.represent import rep_innerproduct >>> from sympy.physics.quantum.cartesian import XOp, XKet, PxOp, PxKet >>> rep_innerproduct(XKet()) DiracDelta(x - x_1) >>> rep_innerproduct(XKet(), basis=PxOp()) sqrt(2)*exp(-I*px_1*x/hbar)/(2*sqrt(hbar)*sqrt(pi)) >>> rep_innerproduct(PxKet(), basis=XOp()) sqrt(2)*exp(I*px*x_1/hbar)/(2*sqrt(hbar)*sqrt(pi)) """ if not isinstance(expr, (KetBase, BraBase)): raise TypeError("expr passed is not a Bra or Ket") basis = get_basis(expr, **options) if not isinstance(basis, StateBase): raise NotImplementedError("Can't form this representation!") if not "index" in options: options["index"] = 1 basis_kets = enumerate_states(basis, options["index"], 2) if isinstance(expr, BraBase): bra = expr ket = (basis_kets[1] if basis_kets[0].dual == expr else basis_kets[0]) else: bra = (basis_kets[1].dual if basis_kets[0] == expr else basis_kets[0].dual) ket = expr prod = InnerProduct(bra, ket) result = prod.doit() format = options.get('format', 'sympy') return expr._format_represent(result, format)
def __mul__(self, other): """BraBase*other""" from sympy.physics.quantum.innerproduct import InnerProduct if isinstance(other, KetBase): return InnerProduct(self, other) else: return Expr.__mul__(self, other)
def __rmul__(self, other): """other*KetBase""" from sympy.physics.quantum.innerproduct import InnerProduct if isinstance(other, BraBase): return InnerProduct(other, self) else: return Expr.__rmul__(self, other)
def test_SHOKet(): assert SHOKet('k').dual_class() == SHOBra assert SHOBra('b').dual_class() == SHOKet assert InnerProduct(b, k).doit() == KroneckerDelta(k.n, b.n) assert k.hilbert_space == ComplexSpace(S.Infinity) assert k3_rep[k3.n, 0] == Integer(1) assert b3_rep[0, b3.n] == Integer(1)
def qapply_Mul(e, **options): ip_doit = options.get('ip_doit', True) args = list(e.args) # If we only have 0 or 1 args, we have nothing to do and return. if len(args) <= 1 or not isinstance(e, Mul): return e rhs = args.pop() lhs = args.pop() # Make sure we have two non-commutative objects before proceeding. if (sympify(rhs).is_commutative and not isinstance(rhs, Wavefunction)) or \ (sympify(lhs).is_commutative and not isinstance(lhs, Wavefunction)): return e # For a Pow with an integer exponent, apply one of them and reduce the # exponent by one. if isinstance(lhs, Pow) and lhs.exp.is_Integer: args.append(lhs.base**(lhs.exp - 1)) lhs = lhs.base # Pull OuterProduct apart if isinstance(lhs, OuterProduct): args.append(lhs.ket) lhs = lhs.bra # Call .doit() on Commutator/AntiCommutator. if isinstance(lhs, (Commutator, AntiCommutator)): comm = lhs.doit() if isinstance(comm, Add): return qapply( e.func(*(args + [comm.args[0], rhs])) + e.func(*(args + [comm.args[1], rhs])), **options ) else: return qapply(e.func(*args)*comm*rhs, **options) # Apply tensor products of operators to states if isinstance(lhs, TensorProduct) and all(isinstance(arg, (Operator, State, Mul, Pow)) or arg == 1 for arg in lhs.args) and \ isinstance(rhs, TensorProduct) and all(isinstance(arg, (Operator, State, Mul, Pow)) or arg == 1 for arg in rhs.args) and \ len(lhs.args) == len(rhs.args): result = TensorProduct(*[qapply(lhs.args[n]*rhs.args[n], **options) for n in range(len(lhs.args))]).expand(tensorproduct=True) return qapply_Mul(e.func(*args), **options)*result # Now try to actually apply the operator and build an inner product. try: result = lhs._apply_operator(rhs, **options) except (NotImplementedError, AttributeError): try: result = rhs._apply_operator(lhs, **options) except (NotImplementedError, AttributeError): if isinstance(lhs, BraBase) and isinstance(rhs, KetBase): result = InnerProduct(lhs, rhs) if ip_doit: result = result.doit() else: result = None # TODO: I may need to expand before returning the final result. if result == 0: return S.Zero elif result is None: if len(args) == 0: # We had two args to begin with so args=[]. return e else: return qapply_Mul(e.func(*(args + [lhs])), **options)*rhs elif isinstance(result, InnerProduct): return result*qapply_Mul(e.func(*args), **options) else: # result is a scalar times a Mul, Add or TensorProduct return qapply(e.func(*args)*result, **options)
def test_doit(): f = FooKet('foo') b = BarBra('bar') assert InnerProduct(b, f).doit() == I assert InnerProduct(Dagger(f), Dagger(b)).doit() == -I assert InnerProduct(Dagger(f), f).doit() == Integer(1)
def test_innerproduct(): x = symbols('x') ip1 = InnerProduct(Bra(), Ket()) ip2 = InnerProduct(TimeDepBra(), TimeDepKet()) ip3 = InnerProduct(JzBra(1, 1), JzKet(1, 1)) ip4 = InnerProduct(JzBraCoupled(1, 1, (1, 1)), JzKetCoupled(1, 1, (1, 1))) ip_tall1 = InnerProduct(Bra(x / 2), Ket(x / 2)) ip_tall2 = InnerProduct(Bra(x), Ket(x / 2)) ip_tall3 = InnerProduct(Bra(x / 2), Ket(x)) assert str(ip1) == '<psi|psi>' assert pretty(ip1) == '<psi|psi>' assert upretty(ip1) == u'⟨ψ❘ψ⟩' assert latex( ip1) == r'\left\langle \psi \right. {\left|\psi\right\rangle }' sT(ip1, "InnerProduct(Bra(Symbol('psi')),Ket(Symbol('psi')))") assert str(ip2) == '<psi;t|psi;t>' assert pretty(ip2) == '<psi;t|psi;t>' assert upretty(ip2) == u'⟨ψ;t❘ψ;t⟩' assert latex(ip2) == \ r'\left\langle \psi;t \right. {\left|\psi;t\right\rangle }' sT( ip2, "InnerProduct(TimeDepBra(Symbol('psi'),Symbol('t')),TimeDepKet(Symbol('psi'),Symbol('t')))" ) assert str(ip3) == "<1,1|1,1>" assert pretty(ip3) == '<1,1|1,1>' assert upretty(ip3) == u'⟨1,1❘1,1⟩' assert latex(ip3) == r'\left\langle 1,1 \right. {\left|1,1\right\rangle }' sT( ip3, "InnerProduct(JzBra(Integer(1),Integer(1)),JzKet(Integer(1),Integer(1)))" ) assert str(ip4) == "<1,1,j1=1,j2=1|1,1,j1=1,j2=1>" assert pretty(ip4) == '<1,1,j1=1,j2=1|1,1,j1=1,j2=1>' assert upretty(ip4) == u'⟨1,1,j₁=1,j₂=1❘1,1,j₁=1,j₂=1⟩' assert latex(ip4) == \ r'\left\langle 1,1,j_{1}=1,j_{2}=1 \right. {\left|1,1,j_{1}=1,j_{2}=1\right\rangle }' sT( ip4, "InnerProduct(JzBraCoupled(Integer(1),Integer(1),Tuple(Integer(1), Integer(1)),Tuple(Tuple(Integer(1), Integer(2), Integer(1)))),JzKetCoupled(Integer(1),Integer(1),Tuple(Integer(1), Integer(1)),Tuple(Tuple(Integer(1), Integer(2), Integer(1)))))" ) assert str(ip_tall1) == '<x/2|x/2>' ascii_str = \ """\ / | \\ \n\ / x|x \\\n\ \\ -|- /\n\ \\2|2/ \ """ ucode_str = \ u"""\ ╱ │ ╲ \n\ ╱ x│x ╲\n\ ╲ ─│─ ╱\n\ ╲2│2╱ \ """ assert pretty(ip_tall1) == ascii_str assert upretty(ip_tall1) == ucode_str assert latex(ip_tall1) == \ r'\left\langle \frac{1}{2} x \right. {\left|\frac{1}{2} x\right\rangle }' sT( ip_tall1, "InnerProduct(Bra(Mul(Rational(1, 2), Symbol('x'))),Ket(Mul(Rational(1, 2), Symbol('x'))))" ) assert str(ip_tall2) == '<x|x/2>' ascii_str = \ """\ / | \\ \n\ / |x \\\n\ \\ x|- /\n\ \\ |2/ \ """ ucode_str = \ u"""\ ╱ │ ╲ \n\ ╱ │x ╲\n\ ╲ x│─ ╱\n\ ╲ │2╱ \ """ assert pretty(ip_tall2) == ascii_str assert upretty(ip_tall2) == ucode_str assert latex(ip_tall2) == \ r'\left\langle x \right. {\left|\frac{1}{2} x\right\rangle }' sT(ip_tall2, "InnerProduct(Bra(Symbol('x')),Ket(Mul(Rational(1, 2), Symbol('x'))))") assert str(ip_tall3) == '<x/2|x>' ascii_str = \ """\ / | \\ \n\ / x| \\\n\ \\ -|x /\n\ \\2| / \ """ ucode_str = \ u"""\ ╱ │ ╲ \n\ ╱ x│ ╲\n\ ╲ ─│x ╱\n\ ╲2│ ╱ \ """ assert pretty(ip_tall3) == ascii_str assert upretty(ip_tall3) == ucode_str assert latex(ip_tall3) == \ r'\left\langle \frac{1}{2} x \right. {\left|x\right\rangle }' sT(ip_tall3, "InnerProduct(Bra(Mul(Rational(1, 2), Symbol('x'))),Ket(Symbol('x')))")
(A, Amat), (Dagger(A), Dagger(Amat)), # OuterProduct (OuterProduct(k, b), Avec * Avec.H), # TensorProduct (TensorProduct(A, B), matrix_tensor_product(Amat, Bmat)), # Pow (A**2, Amat**2), # Add/Mul (A * B + 2 * A, Amat * Bmat + 2 * Amat), # Commutator (Commutator(A, B), Amat * Bmat - Bmat * Amat), # AntiCommutator (AntiCommutator(A, B), Amat * Bmat + Bmat * Amat), # InnerProduct (InnerProduct(b, k), (Avec.H * Avec)[0]) ] def test_format_sympy(): for test in _tests: lhs = represent(test[0], basis=A, format='sympy') rhs = to_sympy(test[1]) assert lhs == rhs def test_scalar_sympy(): assert represent(Integer(1)) == Integer(1) assert represent(Float(1.0)) == Float(1.0) assert represent(1.0 + I) == 1.0 + I
def qapply_Mul(e, **options): ip_doit = options.get('ip_doit', True) args = list(e.args) # If we only have 0 or 1 args, we have nothing to do and return. if len(args) <= 1: return e rhs = args.pop() lhs = args.pop() # Make sure we have two non-commutative objects before proceeding. if rhs.is_commutative or lhs.is_commutative: return e # For a Pow with an integer exponent, apply one of them and reduce the # exponent by one. if isinstance(lhs, Pow) and lhs.exp.is_Integer: args.append(lhs.base**(lhs.exp-1)) lhs = lhs.base # Pull OuterProduct apart if isinstance(lhs, OuterProduct): args.append(lhs.ket) lhs = lhs.bra # Call .doit() on Commutator/AntiCommutator. if isinstance(lhs, (Commutator, AntiCommutator)): comm = lhs.doit() if isinstance(comm, Add): return qapply( e._new_rawargs(*(args + [comm.args[0], rhs])) +\ e._new_rawargs(*(args + [comm.args[1], rhs])), **options ) else: return qapply(e._new_rawargs(*args)*comm*rhs, **options) # Now try to actually apply the operator and build an inner product. try: result = lhs._apply_operator(rhs, **options) except (NotImplementedError, AttributeError): try: result = rhs._apply_operator(lhs, **options) except (NotImplementedError, AttributeError): if isinstance(lhs, BraBase) and isinstance(rhs, KetBase): result = InnerProduct(lhs, rhs) if ip_doit: result = result.doit() else: result = None # TODO: I may need to expand before returning the final result. if result == 0: return 0 elif result is None: return qapply_Mul(e._new_rawargs(*(args+[lhs])), **options)*rhs elif isinstance(result, InnerProduct): return result*qapply_Mul(e._new_rawargs(*args), **options) else: # result is a scalar times a Mul, Add or TensorProduct return qapply(e._new_rawargs(*args)*result, **options)
def qapply_Mul(e, **options): ip_doit = options.get('ip_doit', True) args = list(e.args) # If we only have 0 or 1 args, we have nothing to do and return. if len(args) <= 1: return e rhs = args.pop() lhs = args.pop() # Make sure we have two non-commutative objects before proceeding. if rhs.is_commutative or lhs.is_commutative: return e # For a Pow with an integer exponent, apply one of them and reduce the # exponent by one. if isinstance(lhs, Pow) and lhs.exp.is_Integer: args.append(lhs.base**(lhs.exp - 1)) lhs = lhs.base # Pull OuterProduct apart if isinstance(lhs, OuterProduct): args.append(lhs.ket) lhs = lhs.bra # Call .doit() on Commutator/AntiCommutator. if isinstance(lhs, (Commutator, AntiCommutator)): comm = lhs.doit() if isinstance(comm, Add): return qapply( e._new_rawargs(*(args + [comm.args[0], rhs])) +\ e._new_rawargs(*(args + [comm.args[1], rhs])), **options ) else: return qapply(e._new_rawargs(*args) * comm * rhs, **options) # Now try to actually apply the operator and build an inner product. try: result = lhs._apply_operator(rhs, **options) except (NotImplementedError, AttributeError): try: result = rhs._apply_operator(lhs, **options) except (NotImplementedError, AttributeError): if isinstance(lhs, BraBase) and isinstance(rhs, KetBase): result = InnerProduct(lhs, rhs) if ip_doit: result = result.doit() else: result = None # TODO: I may need to expand before returning the final result. if result == 0: return 0 elif result is None: return qapply_Mul(e._new_rawargs(*(args + [lhs])), **options) * rhs elif isinstance(result, InnerProduct): return result * qapply_Mul(e._new_rawargs(*args), **options) else: # result is a scalar times a Mul, Add or TensorProduct return qapply(e._new_rawargs(*args) * result, **options)
def test_SHOKet(): assert SHOKet('k').dual_class() == SHOBra assert SHOBra('b').dual_class() == SHOKet assert InnerProduct(b, k).doit() == KroneckerDelta(k.n, b.n) assert k.hilbert_space == ComplexSpace(S.Infinity)
def test_doit(): f = FooKet("foo") b = BarBra("bar") assert InnerProduct(b, f).doit() == I assert InnerProduct(Dagger(f), Dagger(b)).doit() == -I assert InnerProduct(Dagger(f), f).doit() == Integer(1)