# jrioux/sympy forked from sympy/sympy

```- adjoint():   Hermite conjugation or conjugate transposition,
- transpose(): Linear map transposition.

>>> A = Symbol('A', hermitian=True)
>>> B = Symbol('B', antihermitian=True)
>>> C = Symbol('C')
>>> M = Matrix(3, 1, [1,I,3])
A
-B
-A*B
B**2
conjugate(transpose(C))
[1, -I, 3]```
1 parent 4c0ac8a commit 04a297fe17802284e394ca6deff8054798e307ae committed Mar 22, 2012
 @@ -662,6 +662,12 @@ def _eval_as_leading_term(self, x): def _eval_conjugate(self): return Add(*[t.conjugate() for t in self.args]) + def _eval_transpose(self): + return Add(*[t.transpose() for t in self.args]) + + def _eval_adjoint(self): + return Add(*[t.adjoint() for t in self.args]) + def _eval_expand_basic(self, deep=True, **hints): sargs, terms = self.args, [] for term in sargs:
 @@ -640,6 +640,35 @@ def conjugate(self): from sympy.functions.elementary.complexes import conjugate as c return c(self) + def _eval_transpose(self): + from sympy.functions.elementary.complexes import conjugate + if self.is_complex: + return self + elif self.is_hermitian: + return conjugate(self) + elif self.is_antihermitian: + return -conjugate(self) + + def transpose(self): + from sympy.functions.elementary.complexes import transpose + return transpose(self) + + def _eval_adjoint(self): + from sympy.functions.elementary.complexes import conjugate, transpose + if self.is_hermitian: + return self + elif self.is_antihermitian: + return -self + obj = self._eval_conjugate() + if obj is not None: + return transpose(obj) + obj = self._eval_transpose() + if obj is not None: + return conjugate(obj) + + def adjoint(self): + from sympy.functions.elementary.complexes import adjoint + return adjoint(self) @classmethod def _parse_order(cls, order):
 @@ -1466,6 +1466,12 @@ def _eval_as_leading_term(self, x): def _eval_conjugate(self): return Mul(*[t.conjugate() for t in self.args]) + def _eval_transpose(self): + return Mul(*[t.transpose() for t in self.args[::-1]]) + + def _eval_adjoint(self): + return Mul(*[t.adjoint() for t in self.args[::-1]]) + def _sage_(self): s = 1 for x in self.args:
 @@ -278,6 +278,30 @@ def _eval_conjugate(self): if expanded != self: return c(expanded) + def _eval_transpose(self): + from sympy.functions.elementary.complexes import transpose + i, p = self.exp.is_integer, self.base.is_complex + if p: + return self.base**self.exp + if i: + return transpose(self.base)**self.exp + if i is False and p is False: + expanded = expand_complex(self) + if expanded != self: + return transpose(expanded) + + def _eval_adjoint(self): + from sympy.functions.elementary.complexes import adjoint + i, p = self.exp.is_integer, self.base.is_positive + if i: + return adjoint(self.base)**self.exp + if p: + return self.base**adjoint(self.exp) + if i is False and p is False: + expanded = expand_complex(self) + if expanded != self: + return adjoint(expanded) + def _eval_expand_basic(self, deep=True, **hints): sargs, terms = self.args, [] for term in sargs:
 @@ -673,6 +673,10 @@ def test_sympy__functions__elementary__complexes__Abs(): from sympy.functions.elementary.complexes import Abs assert _test_args(Abs(x)) +def test_sympy__functions__elementary__complexes__adjoint(): + from sympy.functions.elementary.complexes import adjoint + assert _test_args(adjoint(x)) + def test_sympy__functions__elementary__complexes__arg(): from sympy.functions.elementary.complexes import arg assert _test_args(arg(x)) @@ -705,6 +709,10 @@ def test_sympy__functions__elementary__complexes__principal_branch(): from sympy.functions.elementary.complexes import principal_branch assert _test_args(principal_branch(x, y)) +def test_sympy__functions__elementary__complexes__transpose(): + from sympy.functions.elementary.complexes import transpose + assert _test_args(transpose(x)) + def test_sympy__functions__elementary__exponential__LambertW(): from sympy.functions.elementary.exponential import LambertW assert _test_args(LambertW(2))
 @@ -22,7 +22,7 @@ from elementary.miscellaneous import sqrt, root, Min, Max, Id, real_root from elementary.complexes import (re, im, sign, Abs, conjugate, arg, polar_lift, periodic_argument, unbranched_argument, - principal_branch) + principal_branch, transpose, adjoint) from elementary.trigonometric import acot, cot, tan, cos, sin, asin, acos, atan, atan2 from elementary.exponential import exp_polar, exp, log, LambertW from elementary.hyperbolic import sinh, cosh, tanh, coth, asinh, acosh, atanh, acoth
 @@ -424,12 +424,68 @@ def eval(cls, arg): if obj is not None: return obj + def _eval_adjoint(self): + return transpose(self.args[0]) + def _eval_conjugate(self): return self.args[0] def _eval_derivative(self, x): return conjugate(Derivative(self.args[0], x, **{'evaluate': True})) + def _eval_transpose(self): + return conjugate(transpose(self.args[0])) + +class transpose(Function): + """ + Linear map transposition. + """ + + nargs = 1 + + @classmethod + def eval(cls, arg): + obj = arg._eval_transpose() + if obj is not None: + return obj + + def _eval_adjoint(self): + return conjugate(self.args[0]) + + def _eval_derivative(self, x): + return transpose(Derivative(self.args[0], x, **{'evaluate': True})) + + def _eval_transpose(self): + return self.args[0] + +class adjoint(Function): + """ + Conjugate transpose or Hermite conjugation. + """ + + nargs = 1 + + @classmethod + def eval(cls, arg): + obj = arg._eval_adjoint() + if obj is not None: + return obj + obj = arg._eval_transpose() + if obj is not None: + return conjugate(obj) + + def _eval_adjoint(self): + return self.args[0] + + def _eval_conjugate(self): + return transpose(self.args[0]) + + def _eval_derivative(self, x): + return adjoint(Derivative(self.args[0], x, **{'evaluate': True})) + + def _eval_transpose(self): + return conjugate(self.args[0]) + ############################################################################### ############### HANDLING OF POLAR NUMBERS ##################################### ###############################################################################
 @@ -106,9 +106,21 @@ def eval_transpose(self): def eval_inverse(self): raise NotImplementedError() + def transpose(self): + if isinstance(self, Transpose): + return self.arg + + if self.is_Mul: + return MatMul(*[Transpose(arg) for arg in self.args[::-1]]) + + if self.is_Add: + return MatAdd(*[Transpose(arg) for arg in self.args]) + + return Basic.__new__(Transpose, self) + @property def T(self): - return Transpose(self) + return self.transpose() @property def I(self):
 @@ -21,21 +21,9 @@ class Transpose(MatrixExpr): is_Transpose = True def __new__(cls, mat): - if not mat.is_Matrix: - return mat - - if isinstance(mat, Transpose): - return mat.arg - if hasattr(mat, 'transpose'): return mat.transpose() - if mat.is_Mul: - return MatMul(*[Transpose(arg) for arg in mat.args[::-1]]) - - if mat.is_Add: - return MatAdd(*[Transpose(arg) for arg in mat.args]) - return Basic.__new__(cls, mat) @property
 @@ -36,5 +36,8 @@ def __setitem__(self, *args): as_mutable = MatrixBase.as_mutable + adjoint = MatrixBase.adjoint + conjugate = MatrixBase.conjugate equals = MatrixBase.equals is_Identity = MatrixBase.is_Identity + transpose = MatrixBase.transpose
 @@ -214,6 +214,10 @@ def conjugate(self): C = property(conjugate,None,None,"By-element conjugation.") + def adjoint(self): + """Conjugate transpose or Hermitian conjugation.""" + return self.conjugate().transpose() + @property def H(self): """