switching to high quality piper tts and added label translations
This commit is contained in:
@@ -0,0 +1,653 @@
|
||||
"""Hilbert spaces for quantum mechanics.
|
||||
|
||||
Authors:
|
||||
* Brian Granger
|
||||
* Matt Curry
|
||||
"""
|
||||
|
||||
from functools import reduce
|
||||
|
||||
from sympy.core.basic import Basic
|
||||
from sympy.core.singleton import S
|
||||
from sympy.core.sympify import sympify
|
||||
from sympy.sets.sets import Interval
|
||||
from sympy.printing.pretty.stringpict import prettyForm
|
||||
from sympy.physics.quantum.qexpr import QuantumError
|
||||
|
||||
|
||||
__all__ = [
|
||||
'HilbertSpaceError',
|
||||
'HilbertSpace',
|
||||
'TensorProductHilbertSpace',
|
||||
'TensorPowerHilbertSpace',
|
||||
'DirectSumHilbertSpace',
|
||||
'ComplexSpace',
|
||||
'L2',
|
||||
'FockSpace'
|
||||
]
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Main objects
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
class HilbertSpaceError(QuantumError):
|
||||
pass
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Main objects
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
class HilbertSpace(Basic):
|
||||
"""An abstract Hilbert space for quantum mechanics.
|
||||
|
||||
In short, a Hilbert space is an abstract vector space that is complete
|
||||
with inner products defined [1]_.
|
||||
|
||||
Examples
|
||||
========
|
||||
|
||||
>>> from sympy.physics.quantum.hilbert import HilbertSpace
|
||||
>>> hs = HilbertSpace()
|
||||
>>> hs
|
||||
H
|
||||
|
||||
References
|
||||
==========
|
||||
|
||||
.. [1] https://en.wikipedia.org/wiki/Hilbert_space
|
||||
"""
|
||||
|
||||
def __new__(cls):
|
||||
obj = Basic.__new__(cls)
|
||||
return obj
|
||||
|
||||
@property
|
||||
def dimension(self):
|
||||
"""Return the Hilbert dimension of the space."""
|
||||
raise NotImplementedError('This Hilbert space has no dimension.')
|
||||
|
||||
def __add__(self, other):
|
||||
return DirectSumHilbertSpace(self, other)
|
||||
|
||||
def __radd__(self, other):
|
||||
return DirectSumHilbertSpace(other, self)
|
||||
|
||||
def __mul__(self, other):
|
||||
return TensorProductHilbertSpace(self, other)
|
||||
|
||||
def __rmul__(self, other):
|
||||
return TensorProductHilbertSpace(other, self)
|
||||
|
||||
def __pow__(self, other, mod=None):
|
||||
if mod is not None:
|
||||
raise ValueError('The third argument to __pow__ is not supported \
|
||||
for Hilbert spaces.')
|
||||
return TensorPowerHilbertSpace(self, other)
|
||||
|
||||
def __contains__(self, other):
|
||||
"""Is the operator or state in this Hilbert space.
|
||||
|
||||
This is checked by comparing the classes of the Hilbert spaces, not
|
||||
the instances. This is to allow Hilbert Spaces with symbolic
|
||||
dimensions.
|
||||
"""
|
||||
if other.hilbert_space.__class__ == self.__class__:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def _sympystr(self, printer, *args):
|
||||
return 'H'
|
||||
|
||||
def _pretty(self, printer, *args):
|
||||
ustr = '\N{LATIN CAPITAL LETTER H}'
|
||||
return prettyForm(ustr)
|
||||
|
||||
def _latex(self, printer, *args):
|
||||
return r'\mathcal{H}'
|
||||
|
||||
|
||||
class ComplexSpace(HilbertSpace):
|
||||
"""Finite dimensional Hilbert space of complex vectors.
|
||||
|
||||
The elements of this Hilbert space are n-dimensional complex valued
|
||||
vectors with the usual inner product that takes the complex conjugate
|
||||
of the vector on the right.
|
||||
|
||||
A classic example of this type of Hilbert space is spin-1/2, which is
|
||||
``ComplexSpace(2)``. Generalizing to spin-s, the space is
|
||||
``ComplexSpace(2*s+1)``. Quantum computing with N qubits is done with the
|
||||
direct product space ``ComplexSpace(2)**N``.
|
||||
|
||||
Examples
|
||||
========
|
||||
|
||||
>>> from sympy import symbols
|
||||
>>> from sympy.physics.quantum.hilbert import ComplexSpace
|
||||
>>> c1 = ComplexSpace(2)
|
||||
>>> c1
|
||||
C(2)
|
||||
>>> c1.dimension
|
||||
2
|
||||
|
||||
>>> n = symbols('n')
|
||||
>>> c2 = ComplexSpace(n)
|
||||
>>> c2
|
||||
C(n)
|
||||
>>> c2.dimension
|
||||
n
|
||||
|
||||
"""
|
||||
|
||||
def __new__(cls, dimension):
|
||||
dimension = sympify(dimension)
|
||||
r = cls.eval(dimension)
|
||||
if isinstance(r, Basic):
|
||||
return r
|
||||
obj = Basic.__new__(cls, dimension)
|
||||
return obj
|
||||
|
||||
@classmethod
|
||||
def eval(cls, dimension):
|
||||
if len(dimension.atoms()) == 1:
|
||||
if not (dimension.is_Integer and dimension > 0 or dimension is S.Infinity
|
||||
or dimension.is_Symbol):
|
||||
raise TypeError('The dimension of a ComplexSpace can only'
|
||||
'be a positive integer, oo, or a Symbol: %r'
|
||||
% dimension)
|
||||
else:
|
||||
for dim in dimension.atoms():
|
||||
if not (dim.is_Integer or dim is S.Infinity or dim.is_Symbol):
|
||||
raise TypeError('The dimension of a ComplexSpace can only'
|
||||
' contain integers, oo, or a Symbol: %r'
|
||||
% dim)
|
||||
|
||||
@property
|
||||
def dimension(self):
|
||||
return self.args[0]
|
||||
|
||||
def _sympyrepr(self, printer, *args):
|
||||
return "%s(%s)" % (self.__class__.__name__,
|
||||
printer._print(self.dimension, *args))
|
||||
|
||||
def _sympystr(self, printer, *args):
|
||||
return "C(%s)" % printer._print(self.dimension, *args)
|
||||
|
||||
def _pretty(self, printer, *args):
|
||||
ustr = '\N{LATIN CAPITAL LETTER C}'
|
||||
pform_exp = printer._print(self.dimension, *args)
|
||||
pform_base = prettyForm(ustr)
|
||||
return pform_base**pform_exp
|
||||
|
||||
def _latex(self, printer, *args):
|
||||
return r'\mathcal{C}^{%s}' % printer._print(self.dimension, *args)
|
||||
|
||||
|
||||
class L2(HilbertSpace):
|
||||
"""The Hilbert space of square integrable functions on an interval.
|
||||
|
||||
An L2 object takes in a single SymPy Interval argument which represents
|
||||
the interval its functions (vectors) are defined on.
|
||||
|
||||
Examples
|
||||
========
|
||||
|
||||
>>> from sympy import Interval, oo
|
||||
>>> from sympy.physics.quantum.hilbert import L2
|
||||
>>> hs = L2(Interval(0,oo))
|
||||
>>> hs
|
||||
L2(Interval(0, oo))
|
||||
>>> hs.dimension
|
||||
oo
|
||||
>>> hs.interval
|
||||
Interval(0, oo)
|
||||
|
||||
"""
|
||||
|
||||
def __new__(cls, interval):
|
||||
if not isinstance(interval, Interval):
|
||||
raise TypeError('L2 interval must be an Interval instance: %r'
|
||||
% interval)
|
||||
obj = Basic.__new__(cls, interval)
|
||||
return obj
|
||||
|
||||
@property
|
||||
def dimension(self):
|
||||
return S.Infinity
|
||||
|
||||
@property
|
||||
def interval(self):
|
||||
return self.args[0]
|
||||
|
||||
def _sympyrepr(self, printer, *args):
|
||||
return "L2(%s)" % printer._print(self.interval, *args)
|
||||
|
||||
def _sympystr(self, printer, *args):
|
||||
return "L2(%s)" % printer._print(self.interval, *args)
|
||||
|
||||
def _pretty(self, printer, *args):
|
||||
pform_exp = prettyForm('2')
|
||||
pform_base = prettyForm('L')
|
||||
return pform_base**pform_exp
|
||||
|
||||
def _latex(self, printer, *args):
|
||||
interval = printer._print(self.interval, *args)
|
||||
return r'{\mathcal{L}^2}\left( %s \right)' % interval
|
||||
|
||||
|
||||
class FockSpace(HilbertSpace):
|
||||
"""The Hilbert space for second quantization.
|
||||
|
||||
Technically, this Hilbert space is a infinite direct sum of direct
|
||||
products of single particle Hilbert spaces [1]_. This is a mess, so we have
|
||||
a class to represent it directly.
|
||||
|
||||
Examples
|
||||
========
|
||||
|
||||
>>> from sympy.physics.quantum.hilbert import FockSpace
|
||||
>>> hs = FockSpace()
|
||||
>>> hs
|
||||
F
|
||||
>>> hs.dimension
|
||||
oo
|
||||
|
||||
References
|
||||
==========
|
||||
|
||||
.. [1] https://en.wikipedia.org/wiki/Fock_space
|
||||
"""
|
||||
|
||||
def __new__(cls):
|
||||
obj = Basic.__new__(cls)
|
||||
return obj
|
||||
|
||||
@property
|
||||
def dimension(self):
|
||||
return S.Infinity
|
||||
|
||||
def _sympyrepr(self, printer, *args):
|
||||
return "FockSpace()"
|
||||
|
||||
def _sympystr(self, printer, *args):
|
||||
return "F"
|
||||
|
||||
def _pretty(self, printer, *args):
|
||||
ustr = '\N{LATIN CAPITAL LETTER F}'
|
||||
return prettyForm(ustr)
|
||||
|
||||
def _latex(self, printer, *args):
|
||||
return r'\mathcal{F}'
|
||||
|
||||
|
||||
class TensorProductHilbertSpace(HilbertSpace):
|
||||
"""A tensor product of Hilbert spaces [1]_.
|
||||
|
||||
The tensor product between Hilbert spaces is represented by the
|
||||
operator ``*`` Products of the same Hilbert space will be combined into
|
||||
tensor powers.
|
||||
|
||||
A ``TensorProductHilbertSpace`` object takes in an arbitrary number of
|
||||
``HilbertSpace`` objects as its arguments. In addition, multiplication of
|
||||
``HilbertSpace`` objects will automatically return this tensor product
|
||||
object.
|
||||
|
||||
Examples
|
||||
========
|
||||
|
||||
>>> from sympy.physics.quantum.hilbert import ComplexSpace, FockSpace
|
||||
>>> from sympy import symbols
|
||||
|
||||
>>> c = ComplexSpace(2)
|
||||
>>> f = FockSpace()
|
||||
>>> hs = c*f
|
||||
>>> hs
|
||||
C(2)*F
|
||||
>>> hs.dimension
|
||||
oo
|
||||
>>> hs.spaces
|
||||
(C(2), F)
|
||||
|
||||
>>> c1 = ComplexSpace(2)
|
||||
>>> n = symbols('n')
|
||||
>>> c2 = ComplexSpace(n)
|
||||
>>> hs = c1*c2
|
||||
>>> hs
|
||||
C(2)*C(n)
|
||||
>>> hs.dimension
|
||||
2*n
|
||||
|
||||
References
|
||||
==========
|
||||
|
||||
.. [1] https://en.wikipedia.org/wiki/Hilbert_space#Tensor_products
|
||||
"""
|
||||
|
||||
def __new__(cls, *args):
|
||||
r = cls.eval(args)
|
||||
if isinstance(r, Basic):
|
||||
return r
|
||||
obj = Basic.__new__(cls, *args)
|
||||
return obj
|
||||
|
||||
@classmethod
|
||||
def eval(cls, args):
|
||||
"""Evaluates the direct product."""
|
||||
new_args = []
|
||||
recall = False
|
||||
#flatten arguments
|
||||
for arg in args:
|
||||
if isinstance(arg, TensorProductHilbertSpace):
|
||||
new_args.extend(arg.args)
|
||||
recall = True
|
||||
elif isinstance(arg, (HilbertSpace, TensorPowerHilbertSpace)):
|
||||
new_args.append(arg)
|
||||
else:
|
||||
raise TypeError('Hilbert spaces can only be multiplied by \
|
||||
other Hilbert spaces: %r' % arg)
|
||||
#combine like arguments into direct powers
|
||||
comb_args = []
|
||||
prev_arg = None
|
||||
for new_arg in new_args:
|
||||
if prev_arg is not None:
|
||||
if isinstance(new_arg, TensorPowerHilbertSpace) and \
|
||||
isinstance(prev_arg, TensorPowerHilbertSpace) and \
|
||||
new_arg.base == prev_arg.base:
|
||||
prev_arg = new_arg.base**(new_arg.exp + prev_arg.exp)
|
||||
elif isinstance(new_arg, TensorPowerHilbertSpace) and \
|
||||
new_arg.base == prev_arg:
|
||||
prev_arg = prev_arg**(new_arg.exp + 1)
|
||||
elif isinstance(prev_arg, TensorPowerHilbertSpace) and \
|
||||
new_arg == prev_arg.base:
|
||||
prev_arg = new_arg**(prev_arg.exp + 1)
|
||||
elif new_arg == prev_arg:
|
||||
prev_arg = new_arg**2
|
||||
else:
|
||||
comb_args.append(prev_arg)
|
||||
prev_arg = new_arg
|
||||
elif prev_arg is None:
|
||||
prev_arg = new_arg
|
||||
comb_args.append(prev_arg)
|
||||
if recall:
|
||||
return TensorProductHilbertSpace(*comb_args)
|
||||
elif len(comb_args) == 1:
|
||||
return TensorPowerHilbertSpace(comb_args[0].base, comb_args[0].exp)
|
||||
else:
|
||||
return None
|
||||
|
||||
@property
|
||||
def dimension(self):
|
||||
arg_list = [arg.dimension for arg in self.args]
|
||||
if S.Infinity in arg_list:
|
||||
return S.Infinity
|
||||
else:
|
||||
return reduce(lambda x, y: x*y, arg_list)
|
||||
|
||||
@property
|
||||
def spaces(self):
|
||||
"""A tuple of the Hilbert spaces in this tensor product."""
|
||||
return self.args
|
||||
|
||||
def _spaces_printer(self, printer, *args):
|
||||
spaces_strs = []
|
||||
for arg in self.args:
|
||||
s = printer._print(arg, *args)
|
||||
if isinstance(arg, DirectSumHilbertSpace):
|
||||
s = '(%s)' % s
|
||||
spaces_strs.append(s)
|
||||
return spaces_strs
|
||||
|
||||
def _sympyrepr(self, printer, *args):
|
||||
spaces_reprs = self._spaces_printer(printer, *args)
|
||||
return "TensorProductHilbertSpace(%s)" % ','.join(spaces_reprs)
|
||||
|
||||
def _sympystr(self, printer, *args):
|
||||
spaces_strs = self._spaces_printer(printer, *args)
|
||||
return '*'.join(spaces_strs)
|
||||
|
||||
def _pretty(self, printer, *args):
|
||||
length = len(self.args)
|
||||
pform = printer._print('', *args)
|
||||
for i in range(length):
|
||||
next_pform = printer._print(self.args[i], *args)
|
||||
if isinstance(self.args[i], (DirectSumHilbertSpace,
|
||||
TensorProductHilbertSpace)):
|
||||
next_pform = prettyForm(
|
||||
*next_pform.parens(left='(', right=')')
|
||||
)
|
||||
pform = prettyForm(*pform.right(next_pform))
|
||||
if i != length - 1:
|
||||
if printer._use_unicode:
|
||||
pform = prettyForm(*pform.right(' ' + '\N{N-ARY CIRCLED TIMES OPERATOR}' + ' '))
|
||||
else:
|
||||
pform = prettyForm(*pform.right(' x '))
|
||||
return pform
|
||||
|
||||
def _latex(self, printer, *args):
|
||||
length = len(self.args)
|
||||
s = ''
|
||||
for i in range(length):
|
||||
arg_s = printer._print(self.args[i], *args)
|
||||
if isinstance(self.args[i], (DirectSumHilbertSpace,
|
||||
TensorProductHilbertSpace)):
|
||||
arg_s = r'\left(%s\right)' % arg_s
|
||||
s = s + arg_s
|
||||
if i != length - 1:
|
||||
s = s + r'\otimes '
|
||||
return s
|
||||
|
||||
|
||||
class DirectSumHilbertSpace(HilbertSpace):
|
||||
"""A direct sum of Hilbert spaces [1]_.
|
||||
|
||||
This class uses the ``+`` operator to represent direct sums between
|
||||
different Hilbert spaces.
|
||||
|
||||
A ``DirectSumHilbertSpace`` object takes in an arbitrary number of
|
||||
``HilbertSpace`` objects as its arguments. Also, addition of
|
||||
``HilbertSpace`` objects will automatically return a direct sum object.
|
||||
|
||||
Examples
|
||||
========
|
||||
|
||||
>>> from sympy.physics.quantum.hilbert import ComplexSpace, FockSpace
|
||||
|
||||
>>> c = ComplexSpace(2)
|
||||
>>> f = FockSpace()
|
||||
>>> hs = c+f
|
||||
>>> hs
|
||||
C(2)+F
|
||||
>>> hs.dimension
|
||||
oo
|
||||
>>> list(hs.spaces)
|
||||
[C(2), F]
|
||||
|
||||
References
|
||||
==========
|
||||
|
||||
.. [1] https://en.wikipedia.org/wiki/Hilbert_space#Direct_sums
|
||||
"""
|
||||
def __new__(cls, *args):
|
||||
r = cls.eval(args)
|
||||
if isinstance(r, Basic):
|
||||
return r
|
||||
obj = Basic.__new__(cls, *args)
|
||||
return obj
|
||||
|
||||
@classmethod
|
||||
def eval(cls, args):
|
||||
"""Evaluates the direct product."""
|
||||
new_args = []
|
||||
recall = False
|
||||
#flatten arguments
|
||||
for arg in args:
|
||||
if isinstance(arg, DirectSumHilbertSpace):
|
||||
new_args.extend(arg.args)
|
||||
recall = True
|
||||
elif isinstance(arg, HilbertSpace):
|
||||
new_args.append(arg)
|
||||
else:
|
||||
raise TypeError('Hilbert spaces can only be summed with other \
|
||||
Hilbert spaces: %r' % arg)
|
||||
if recall:
|
||||
return DirectSumHilbertSpace(*new_args)
|
||||
else:
|
||||
return None
|
||||
|
||||
@property
|
||||
def dimension(self):
|
||||
arg_list = [arg.dimension for arg in self.args]
|
||||
if S.Infinity in arg_list:
|
||||
return S.Infinity
|
||||
else:
|
||||
return reduce(lambda x, y: x + y, arg_list)
|
||||
|
||||
@property
|
||||
def spaces(self):
|
||||
"""A tuple of the Hilbert spaces in this direct sum."""
|
||||
return self.args
|
||||
|
||||
def _sympyrepr(self, printer, *args):
|
||||
spaces_reprs = [printer._print(arg, *args) for arg in self.args]
|
||||
return "DirectSumHilbertSpace(%s)" % ','.join(spaces_reprs)
|
||||
|
||||
def _sympystr(self, printer, *args):
|
||||
spaces_strs = [printer._print(arg, *args) for arg in self.args]
|
||||
return '+'.join(spaces_strs)
|
||||
|
||||
def _pretty(self, printer, *args):
|
||||
length = len(self.args)
|
||||
pform = printer._print('', *args)
|
||||
for i in range(length):
|
||||
next_pform = printer._print(self.args[i], *args)
|
||||
if isinstance(self.args[i], (DirectSumHilbertSpace,
|
||||
TensorProductHilbertSpace)):
|
||||
next_pform = prettyForm(
|
||||
*next_pform.parens(left='(', right=')')
|
||||
)
|
||||
pform = prettyForm(*pform.right(next_pform))
|
||||
if i != length - 1:
|
||||
if printer._use_unicode:
|
||||
pform = prettyForm(*pform.right(' \N{CIRCLED PLUS} '))
|
||||
else:
|
||||
pform = prettyForm(*pform.right(' + '))
|
||||
return pform
|
||||
|
||||
def _latex(self, printer, *args):
|
||||
length = len(self.args)
|
||||
s = ''
|
||||
for i in range(length):
|
||||
arg_s = printer._print(self.args[i], *args)
|
||||
if isinstance(self.args[i], (DirectSumHilbertSpace,
|
||||
TensorProductHilbertSpace)):
|
||||
arg_s = r'\left(%s\right)' % arg_s
|
||||
s = s + arg_s
|
||||
if i != length - 1:
|
||||
s = s + r'\oplus '
|
||||
return s
|
||||
|
||||
|
||||
class TensorPowerHilbertSpace(HilbertSpace):
|
||||
"""An exponentiated Hilbert space [1]_.
|
||||
|
||||
Tensor powers (repeated tensor products) are represented by the
|
||||
operator ``**`` Identical Hilbert spaces that are multiplied together
|
||||
will be automatically combined into a single tensor power object.
|
||||
|
||||
Any Hilbert space, product, or sum may be raised to a tensor power. The
|
||||
``TensorPowerHilbertSpace`` takes two arguments: the Hilbert space; and the
|
||||
tensor power (number).
|
||||
|
||||
Examples
|
||||
========
|
||||
|
||||
>>> from sympy.physics.quantum.hilbert import ComplexSpace, FockSpace
|
||||
>>> from sympy import symbols
|
||||
|
||||
>>> n = symbols('n')
|
||||
>>> c = ComplexSpace(2)
|
||||
>>> hs = c**n
|
||||
>>> hs
|
||||
C(2)**n
|
||||
>>> hs.dimension
|
||||
2**n
|
||||
|
||||
>>> c = ComplexSpace(2)
|
||||
>>> c*c
|
||||
C(2)**2
|
||||
>>> f = FockSpace()
|
||||
>>> c*f*f
|
||||
C(2)*F**2
|
||||
|
||||
References
|
||||
==========
|
||||
|
||||
.. [1] https://en.wikipedia.org/wiki/Hilbert_space#Tensor_products
|
||||
"""
|
||||
|
||||
def __new__(cls, *args):
|
||||
r = cls.eval(args)
|
||||
if isinstance(r, Basic):
|
||||
return r
|
||||
return Basic.__new__(cls, *r)
|
||||
|
||||
@classmethod
|
||||
def eval(cls, args):
|
||||
new_args = args[0], sympify(args[1])
|
||||
exp = new_args[1]
|
||||
#simplify hs**1 -> hs
|
||||
if exp is S.One:
|
||||
return args[0]
|
||||
#simplify hs**0 -> 1
|
||||
if exp is S.Zero:
|
||||
return S.One
|
||||
#check (and allow) for hs**(x+42+y...) case
|
||||
if len(exp.atoms()) == 1:
|
||||
if not (exp.is_Integer and exp >= 0 or exp.is_Symbol):
|
||||
raise ValueError('Hilbert spaces can only be raised to \
|
||||
positive integers or Symbols: %r' % exp)
|
||||
else:
|
||||
for power in exp.atoms():
|
||||
if not (power.is_Integer or power.is_Symbol):
|
||||
raise ValueError('Tensor powers can only contain integers \
|
||||
or Symbols: %r' % power)
|
||||
return new_args
|
||||
|
||||
@property
|
||||
def base(self):
|
||||
return self.args[0]
|
||||
|
||||
@property
|
||||
def exp(self):
|
||||
return self.args[1]
|
||||
|
||||
@property
|
||||
def dimension(self):
|
||||
if self.base.dimension is S.Infinity:
|
||||
return S.Infinity
|
||||
else:
|
||||
return self.base.dimension**self.exp
|
||||
|
||||
def _sympyrepr(self, printer, *args):
|
||||
return "TensorPowerHilbertSpace(%s,%s)" % (printer._print(self.base,
|
||||
*args), printer._print(self.exp, *args))
|
||||
|
||||
def _sympystr(self, printer, *args):
|
||||
return "%s**%s" % (printer._print(self.base, *args),
|
||||
printer._print(self.exp, *args))
|
||||
|
||||
def _pretty(self, printer, *args):
|
||||
pform_exp = printer._print(self.exp, *args)
|
||||
if printer._use_unicode:
|
||||
pform_exp = prettyForm(*pform_exp.left(prettyForm('\N{N-ARY CIRCLED TIMES OPERATOR}')))
|
||||
else:
|
||||
pform_exp = prettyForm(*pform_exp.left(prettyForm('x')))
|
||||
pform_base = printer._print(self.base, *args)
|
||||
return pform_base**pform_exp
|
||||
|
||||
def _latex(self, printer, *args):
|
||||
base = printer._print(self.base, *args)
|
||||
exp = printer._print(self.exp, *args)
|
||||
return r'{%s}^{\otimes %s}' % (base, exp)
|
||||
Reference in New Issue
Block a user