switching to high quality piper tts and added label translations
This commit is contained in:
@@ -0,0 +1,220 @@
|
||||
from sympy.core.sympify import _sympify
|
||||
|
||||
from sympy.matrices.expressions import MatrixExpr
|
||||
from sympy.core import S, Eq, Ge
|
||||
from sympy.core.mul import Mul
|
||||
from sympy.functions.special.tensor_functions import KroneckerDelta
|
||||
|
||||
|
||||
class DiagonalMatrix(MatrixExpr):
|
||||
"""DiagonalMatrix(M) will create a matrix expression that
|
||||
behaves as though all off-diagonal elements,
|
||||
`M[i, j]` where `i != j`, are zero.
|
||||
|
||||
Examples
|
||||
========
|
||||
|
||||
>>> from sympy import MatrixSymbol, DiagonalMatrix, Symbol
|
||||
>>> n = Symbol('n', integer=True)
|
||||
>>> m = Symbol('m', integer=True)
|
||||
>>> D = DiagonalMatrix(MatrixSymbol('x', 2, 3))
|
||||
>>> D[1, 2]
|
||||
0
|
||||
>>> D[1, 1]
|
||||
x[1, 1]
|
||||
|
||||
The length of the diagonal -- the lesser of the two dimensions of `M` --
|
||||
is accessed through the `diagonal_length` property:
|
||||
|
||||
>>> D.diagonal_length
|
||||
2
|
||||
>>> DiagonalMatrix(MatrixSymbol('x', n + 1, n)).diagonal_length
|
||||
n
|
||||
|
||||
When one of the dimensions is symbolic the other will be treated as
|
||||
though it is smaller:
|
||||
|
||||
>>> tall = DiagonalMatrix(MatrixSymbol('x', n, 3))
|
||||
>>> tall.diagonal_length
|
||||
3
|
||||
>>> tall[10, 1]
|
||||
0
|
||||
|
||||
When the size of the diagonal is not known, a value of None will
|
||||
be returned:
|
||||
|
||||
>>> DiagonalMatrix(MatrixSymbol('x', n, m)).diagonal_length is None
|
||||
True
|
||||
|
||||
"""
|
||||
arg = property(lambda self: self.args[0])
|
||||
|
||||
shape = property(lambda self: self.arg.shape) # type:ignore
|
||||
|
||||
@property
|
||||
def diagonal_length(self):
|
||||
r, c = self.shape
|
||||
if r.is_Integer and c.is_Integer:
|
||||
m = min(r, c)
|
||||
elif r.is_Integer and not c.is_Integer:
|
||||
m = r
|
||||
elif c.is_Integer and not r.is_Integer:
|
||||
m = c
|
||||
elif r == c:
|
||||
m = r
|
||||
else:
|
||||
try:
|
||||
m = min(r, c)
|
||||
except TypeError:
|
||||
m = None
|
||||
return m
|
||||
|
||||
def _entry(self, i, j, **kwargs):
|
||||
if self.diagonal_length is not None:
|
||||
if Ge(i, self.diagonal_length) is S.true:
|
||||
return S.Zero
|
||||
elif Ge(j, self.diagonal_length) is S.true:
|
||||
return S.Zero
|
||||
eq = Eq(i, j)
|
||||
if eq is S.true:
|
||||
return self.arg[i, i]
|
||||
elif eq is S.false:
|
||||
return S.Zero
|
||||
return self.arg[i, j]*KroneckerDelta(i, j)
|
||||
|
||||
|
||||
class DiagonalOf(MatrixExpr):
|
||||
"""DiagonalOf(M) will create a matrix expression that
|
||||
is equivalent to the diagonal of `M`, represented as
|
||||
a single column matrix.
|
||||
|
||||
Examples
|
||||
========
|
||||
|
||||
>>> from sympy import MatrixSymbol, DiagonalOf, Symbol
|
||||
>>> n = Symbol('n', integer=True)
|
||||
>>> m = Symbol('m', integer=True)
|
||||
>>> x = MatrixSymbol('x', 2, 3)
|
||||
>>> diag = DiagonalOf(x)
|
||||
>>> diag.shape
|
||||
(2, 1)
|
||||
|
||||
The diagonal can be addressed like a matrix or vector and will
|
||||
return the corresponding element of the original matrix:
|
||||
|
||||
>>> diag[1, 0] == diag[1] == x[1, 1]
|
||||
True
|
||||
|
||||
The length of the diagonal -- the lesser of the two dimensions of `M` --
|
||||
is accessed through the `diagonal_length` property:
|
||||
|
||||
>>> diag.diagonal_length
|
||||
2
|
||||
>>> DiagonalOf(MatrixSymbol('x', n + 1, n)).diagonal_length
|
||||
n
|
||||
|
||||
When only one of the dimensions is symbolic the other will be
|
||||
treated as though it is smaller:
|
||||
|
||||
>>> dtall = DiagonalOf(MatrixSymbol('x', n, 3))
|
||||
>>> dtall.diagonal_length
|
||||
3
|
||||
|
||||
When the size of the diagonal is not known, a value of None will
|
||||
be returned:
|
||||
|
||||
>>> DiagonalOf(MatrixSymbol('x', n, m)).diagonal_length is None
|
||||
True
|
||||
|
||||
"""
|
||||
arg = property(lambda self: self.args[0])
|
||||
@property
|
||||
def shape(self):
|
||||
r, c = self.arg.shape
|
||||
if r.is_Integer and c.is_Integer:
|
||||
m = min(r, c)
|
||||
elif r.is_Integer and not c.is_Integer:
|
||||
m = r
|
||||
elif c.is_Integer and not r.is_Integer:
|
||||
m = c
|
||||
elif r == c:
|
||||
m = r
|
||||
else:
|
||||
try:
|
||||
m = min(r, c)
|
||||
except TypeError:
|
||||
m = None
|
||||
return m, S.One
|
||||
|
||||
@property
|
||||
def diagonal_length(self):
|
||||
return self.shape[0]
|
||||
|
||||
def _entry(self, i, j, **kwargs):
|
||||
return self.arg._entry(i, i, **kwargs)
|
||||
|
||||
|
||||
class DiagMatrix(MatrixExpr):
|
||||
"""
|
||||
Turn a vector into a diagonal matrix.
|
||||
"""
|
||||
def __new__(cls, vector):
|
||||
vector = _sympify(vector)
|
||||
obj = MatrixExpr.__new__(cls, vector)
|
||||
shape = vector.shape
|
||||
dim = shape[1] if shape[0] == 1 else shape[0]
|
||||
if vector.shape[0] != 1:
|
||||
obj._iscolumn = True
|
||||
else:
|
||||
obj._iscolumn = False
|
||||
obj._shape = (dim, dim)
|
||||
obj._vector = vector
|
||||
return obj
|
||||
|
||||
@property
|
||||
def shape(self):
|
||||
return self._shape
|
||||
|
||||
def _entry(self, i, j, **kwargs):
|
||||
if self._iscolumn:
|
||||
result = self._vector._entry(i, 0, **kwargs)
|
||||
else:
|
||||
result = self._vector._entry(0, j, **kwargs)
|
||||
if i != j:
|
||||
result *= KroneckerDelta(i, j)
|
||||
return result
|
||||
|
||||
def _eval_transpose(self):
|
||||
return self
|
||||
|
||||
def as_explicit(self):
|
||||
from sympy.matrices.dense import diag
|
||||
return diag(*list(self._vector.as_explicit()))
|
||||
|
||||
def doit(self, **hints):
|
||||
from sympy.assumptions import ask, Q
|
||||
from sympy.matrices.expressions.matmul import MatMul
|
||||
from sympy.matrices.expressions.transpose import Transpose
|
||||
from sympy.matrices.dense import eye
|
||||
from sympy.matrices.matrixbase import MatrixBase
|
||||
vector = self._vector
|
||||
# This accounts for shape (1, 1) and identity matrices, among others:
|
||||
if ask(Q.diagonal(vector)):
|
||||
return vector
|
||||
if isinstance(vector, MatrixBase):
|
||||
ret = eye(max(vector.shape))
|
||||
for i in range(ret.shape[0]):
|
||||
ret[i, i] = vector[i]
|
||||
return type(vector)(ret)
|
||||
if vector.is_MatMul:
|
||||
matrices = [arg for arg in vector.args if arg.is_Matrix]
|
||||
scalars = [arg for arg in vector.args if arg not in matrices]
|
||||
if scalars:
|
||||
return Mul.fromiter(scalars)*DiagMatrix(MatMul.fromiter(matrices).doit()).doit()
|
||||
if isinstance(vector, Transpose):
|
||||
vector = vector.arg
|
||||
return DiagMatrix(vector)
|
||||
|
||||
|
||||
def diagonalize_vector(vector):
|
||||
return DiagMatrix(vector).doit()
|
||||
Reference in New Issue
Block a user