wolfram-mathematica - titulos - valor absoluto en wolfram mathematica
Matrices simbólicas en matemática con dimensiones desconocidas. (5)
Aquí está el código [enlace muerto eliminado] que desperdició mi mañana ... No está completo, pero básicamente funciona. Puede obtener el cuaderno del enlace anterior [muerto] o copiar el código a continuación.
Tenga en cuenta que una pregunta similar apareció en ask.sagemath no hace mucho tiempo.
Casi como la solución de Sasha, define una matriz simbólica usando
A = SymbolicMatrix["A", {n, k}]
para alguna cadena "A"
que no tiene que ser el mismo que el símbolo A
Ok, aquí está el código:
ClearAll[SymbolicMatrix]
Options[SymbolicMatrix] = {Transpose -> False, Conjugate -> False, MatrixPower -> 1};
Mano corta para introducir matrices cuadradas (podría hacer que funcione para diferentes cabezas ...)
SymbolicMatrix[name_String, n:_Symbol|_Integer, opts : OptionsPattern[]] := SymbolicMatrix[name, {n, n}, opts]
Comportamiento bajo transposición, conjugado, conjugado, transposición e inverso
SymbolicMatrix/:Transpose[SymbolicMatrix[name_String,{m_,n_},opts:OptionsPattern[]]]:=SymbolicMatrix[name,{n,m},
Transpose->!OptionValue[SymbolicMatrix,Transpose],Sequence@@FilterRules[{opts},Except[Transpose]]]
SymbolicMatrix/:Conjugate[SymbolicMatrix[name_String,{m_,n_},opts:OptionsPattern[]]]:=SymbolicMatrix[name,{m,n},
Conjugate->!OptionValue[SymbolicMatrix,Conjugate],Sequence@@FilterRules[{opts},Except[Conjugate]]]
SymbolicMatrix/:ConjugateTranspose[A:SymbolicMatrix[name_String,{m_,n_},opts:OptionsPattern[]]]:=Conjugate[Transpose[A]]
SymbolicMatrix/:Inverse[SymbolicMatrix[name_String,{n_,n_},opts:OptionsPattern[]]]:=SymbolicMatrix[name,{n,n},
MatrixPower->-OptionValue[SymbolicMatrix,MatrixPower],Sequence@@FilterRules[{opts},Except[MatrixPower]]]
SymbolicMatrix/:(Transpose|Conjugate|ConjugateTranspose|Inverse)[eye:SymbolicMatrix[IdentityMatrix,{n_,n_}]]:=eye
Combinando poderes de matriz (incluyendo la matriz de identidad)
SymbolicMatrix/:SymbolicMatrix[a_String,{n_,n_},opt1:OptionsPattern[]].SymbolicMatrix[a_,{n_,n_},opt2:OptionsPattern[]]:=SymbolicMatrix[a,{n,n},Sequence@@FilterRules[{opt1},Except[MatrixPower]],MatrixPower->Total[OptionValue[SymbolicMatrix,#,MatrixPower]&/@{{opt1},{opt2}}]]/;FilterRules[{opt1},Except[MatrixPower]]==FilterRules[{opt2},Except[MatrixPower]]
SymbolicMatrix[a_String,{n_,n_},opts:OptionsPattern[]]:=SymbolicMatrix[IdentityMatrix,{n,n}]/;OptionValue[SymbolicMatrix,{opts},MatrixPower]===0
SymbolicMatrix/:(A:SymbolicMatrix[a_String,{n_,m_},OptionsPattern[]]).SymbolicMatrix[IdentityMatrix,{m_,m_}]:=A
SymbolicMatrix/:SymbolicMatrix[IdentityMatrix,{n_,n_}].(A:SymbolicMatrix[a_String,{n_,m_},OptionsPattern[]]):=A
Bonita impresión con la dimensión como información sobre herramientas.
Format[SymbolicMatrix[name_String,{m_,n_},opts:OptionsPattern[]]]:=With[{
base=If[OptionValue[SymbolicMatrix,MatrixPower]===1,
StyleBox[name,FontWeight->Bold,FontColor->Darker@Brown],
SuperscriptBox[StyleBox[name,FontWeight->Bold,FontColor->Darker@Brown],OptionValue[SymbolicMatrix,MatrixPower]]],
c=Which[
OptionValue[SymbolicMatrix,Transpose]&&OptionValue[SymbolicMatrix,Conjugate],"/[ConjugateTranspose]",
OptionValue[SymbolicMatrix,Transpose],"/[Transpose]",
OptionValue[SymbolicMatrix,Conjugate],"/[Conjugate]",
True,Null]},
Interpretation[Tooltip[DisplayForm@RowBox[{base,c}/.Null->Sequence[]],{m,n}],SymbolicMatrix[name,{m,n},opts]]]
Format[SymbolicMatrix[IdentityMatrix,{n_,n_}]]:=Interpretation[Tooltip[Style[/[ScriptCapitalI],Bold,Darker@Brown],n],SymbolicMatrix[IdentityMatrix,{n,n}]]
Definir algunas reglas para Dot. Debe extenderse entonces para que pueda manejar cantidades escalares, etc ... También para que se puedan tomar inversos de AB si AB es cuadrado, incluso si ni A ni B son cuadrados.
SymbolicMatrix::dotdims = "The dimensions of `1` and `2` are not compatible";
Unprotect[Dot]; (*Clear[Dot];*)
Dot/:(a:SymbolicMatrix[_,{_,n_},___]).(b:SymbolicMatrix[_,{m_,_},___]):=(Message[SymbolicMatrix::dotdims,HoldForm[a],HoldForm[b]];Hold[a.b])/;Not[m===n]
Dot/:Conjugate[d:Dot[A_SymbolicMatrix,B__SymbolicMatrix]]:=Map[Conjugate,d]
Dot/:(t:Transpose|ConjugateTranspose)[d:Dot[A_SymbolicMatrix,B__SymbolicMatrix]]:=Dot@@Map[t,Reverse[List@@d]]
Dot/:Inverse[HoldPattern[d:Dot[SymbolicMatrix[_,{n_,n_},___]...]]]:=Reverse@Map[Inverse,d]
A_ .(B_+C__):=A.B+A.Plus[C]
(B_+C__).A_:=B.A+Plus[C].A
Protect[Dot];
Hacer que Transpose, Conjugate y ConjugateTranspose se distribuyan sobre Plus.
Unprotect[Transpose, Conjugate, ConjugateTranspose];
Clear[Transpose, Conjugate, ConjugateTranspose];
Do[With[{c = c}, c[p : Plus[a_, b__]] := c /@ p], {c, {Transpose, Conjugate, ConjugateTranspose}}]
Protect[Transpose, Conjugate, ConjugateTranspose];
Aquí hay algunas pruebas / ejemplos simples
Ahora para el código que se ocupa de la expansión de componentes. Al igual que la solución de Sasha, sobrecargo la Parte.
Clear[SymbolicMatrixComponent]
Options[SymbolicMatrixComponent]={Conjugate->False,MatrixPower->1};
Alguna notación
Format[SymbolicMatrixComponent[A_String,{i_,j_},opts:OptionsPattern[]]]:=Interpretation[DisplayForm[SubsuperscriptBox[StyleBox[A,Darker@Brown],RowBox[{i,",",j}],
RowBox[{If[OptionValue[SymbolicMatrixComponent,{opts},MatrixPower]===1,Null,OptionValue[SymbolicMatrixComponent,{opts},MatrixPower]],If[OptionValue[SymbolicMatrixComponent,{opts},Conjugate],"*",Null]}/.Null->Sequence[]]]],
SymbolicMatrixComponent[A,{i,j},opts]]
Código para extraer partes de matrices y Dot
productos de matrices Es necesario agregar controles para garantizar que todos los rangos de suma explícitos sean adecuados.
SymbolicMatrix/:SymbolicMatrix[A_String,{m_,n_},opts:OptionsPattern[]][[i_,j_]]:=SymbolicMatrixComponent[A,If[OptionValue[SymbolicMatrix,{opts},Transpose],Reverse,Identity]@{i,j},Sequence@@FilterRules[{opts},Options[SymbolicMatrixComponent]]]
SymbolicMatrix/:SymbolicMatrix[IdentityMatrix,{m_,n_}][[i_,j_]]:=KroneckerDelta[i,j]
Unprotect[Part]; (*Clear[Part]*)
Part/:((c___.b:SymbolicMatrix[_,{o_,n_},OptionsPattern[]]).SymbolicMatrix[A_String,{n_,m_},opts:OptionsPattern[]])[[i_,j_]]:=With[{s=Unique["i",Temporary]},Sum[(c.b)[[i,s]]SymbolicMatrixComponent[A,If[OptionValue[SymbolicMatrix,{opts},Transpose],Reverse,Identity]@{s,j},Sequence @@ FilterRules[{opts}, Options[SymbolicMatrixComponent]]],{s,n}]]
Part/:(a_+b_)[[i_,j_]]:=a[[i,j]]+b[[i,j]]/;!And@@(FreeQ[#,SymbolicMatrix]&/@{a,b})
Part/:Hold[a_][[i_,j_]]:=Hold[a[[i,j]]]/;!FreeQ[a,SymbolicMatrix]
Protect[Part];
Algunos ejemplos:
¿Hay una manera de hacer un álgebra matricial simbólica en Matemática para matrices donde las dimensiones son desconocidas? Por ejemplo, si tengo una matriz MxL A y una matriz LxN B, me gustaría poder ingresar
A.B
Y haz que me de una matriz cuyo elemento ab[i,j]
esté dado por
Sum[a[i,l]*b[l,j],{l,1,L}]
El problema en el que estoy trabajando es como este, pero involucra el producto de 12 matrices, incluida la misma matriz (y su transposición) repetida varias veces. Probablemente será posible simplificar los valores de la matriz resultante, pero no es obvio si esto es posible hasta después de hacer el álgebra. Este puede ser un problema que tengo que resolver a mano, pero sería mucho más fácil si Mathematica pudiera proporcionar alguna ayuda para simplificar el álgebra.
No estoy seguro de si esto es realmente muy útil, pero podría ser un comienzo:
ClearAll[SymbolicMatrix]
SymbolicMatrix /: Transpose[SymbolicMatrix[a_, {m_, n_}]] :=
SymbolicMatrix[Evaluate[a[#2, #1]] & , {n, m}]
SymbolicMatrix /:
SymbolicMatrix[a_, {m_, n_}] . SymbolicMatrix[b_, {n_, p_}] :=
With[{s = Unique[/[FormalI], Temporary]},
SymbolicMatrix[Function[{/[FormalN], /[FormalM]},
Evaluate[Sum[a[/[FormalN], s]*b[s, /[FormalM]], {s, 1, n}]]], {m,
p}]]
SymbolicMatrix /: SymbolicMatrix[a_, {m_, n_}][[i_, j_]] := a[i, j]
Ahora, define algunas matrices simbólicas y haz un producto de puntos:
In[109]:= amat = SymbolicMatrix[a, {n, k}];
bmat = SymbolicMatrix[b, {k, k}];
Evaluar elementos de la matriz:
In[111]:= (amat . bmat . Transpose[amat])[[i, j]]
Out[111]= Sum[
a[j, /[FormalI]$1485]*
Sum[a[i, /[FormalI]$1464]*
b[/[FormalI]$1464, /[FormalI]$1485], {/[FormalI]$1464, 1, k}],
{/[FormalI]$1485, 1, k}]
Puedes usar NCAlgebra para eso. Por ejemplo:
MM = 3
LL = 2
NN = 3
AA = Table[Subscript[a, i, j], {i, 1, MM}, {j, 1, LL}]
BB = Table[Subscript[b, i, j], {i, 1, LL}, {j, 1, NN}]
definirá matrices simbólicas AA
y BB
con entradas no conmutativas $ a_ {i, j} $ y $ b_ {i, j} $. Estos pueden ser manipulados y producir los resultados que buscas. Por ejemplo:
NCDot[AA, BB]
multiplicará las dos matrices usando **
,
AA ** BB // NCMatrixExpand
hará lo mismo, y
tp[AA ** BB] // NCMatrixExpand
Se transpondrá utilizando tp
.
Si está dispuesto a cambiar de Mathematica a Python, la funcionalidad que necesita está en la rama de desarrollo de SymPy. Debería estar en la versión 0.72.
In [1]: from sympy import *
In [2]: X = MatrixSymbol(''X'', 2,3)
In [3]: Y = MatrixSymbol(''Y'', 3,3)
In [4]: X*Y*X.T
Out[4]: X⋅Y⋅X''
In [5]: (X*Y*X.T)[0,1]
Out[5]:
X₀₀⋅(X₁₀⋅Y₀₀ + X₁₁⋅Y₀₁ + X₁₂⋅Y₀₂) + X₀₁⋅(X₁₀⋅Y₁₀ + X₁₁⋅Y₁₁ + X₁₂⋅Y₁₂) + X₀₂⋅(X₁₀⋅Y₂₀ + X₁₁⋅Y₂₁ + X₁₂⋅Y₂₂)
Estos objetos puramente simbólicos también pueden hacer uso de todos los algoritmos de matriz estándar para matrices explícitamente definidas
In [14]: X = MatrixSymbol(''X'', 2,2)
In [14]: X.as_explicit().det()
Out[14]: X₀₀⋅X₁₁ - X₀₁⋅X₁₀
Matrices de forma simbólica son factibles también
In [7]: n,m,k = symbols(''n,m,k'')
In [8]: X = MatrixSymbol(''X'', n,m)
In [9]: Y = MatrixSymbol(''Y'', m,k)
In [10]: (X*Y)[3,4]
Out[10]:
m - 1
___
╲
╲ X(3, k)⋅Y(k, 4)
╱
╱
‾‾‾
k = 0
Yo uso este enfoque:
SymbolicMatrix[symbol_String, m_Integer, n_Integer] := Table[
ToExpression[symbol <> ToString[i] <> ToString[j]],
{i, 1, m}, {j, 1, n}
];
SymbolicMatrix[symbol_Symbol, m_Integer, n_Integer] := SymbolicMatrix[ToString[symbol], m, n];
SymbolicMatrix[symbol_, m_Integer] := SymbolicMatrix[symbol, m, 1];
Cuando se invoca como A = SymbolicMatrix["a", 2, 3];
o A = SymbolicMatrix[a, 2, 3];
, crea una matriz
{{a11, a12, a13}, {a21, a22, a23}}
Por lo tanto, crea m
x n
símbolos, pero los encuentro descriptivos y todo es fácil de usar (al menos para mis propósitos).