Suppose a matrix is given where both rows and columns are keyed, for example this correlation matrix:
ds = <|"ERE"-><|"ERE"->1.`,"MDE"->0.5`,"PTB"->0.5`,"MDP12"->0.6`|>,"MDE"-><|"ERE"->0.5`,"MDE"->1.`,"PTB"->0.1`,"MDP12"->0.8`|>,"PTB"-><|"ERE"->0.5`,"MDE"->0.1`,"PTB"->1.`,"MDP12"->0.1`|>,"MDP12"-><|"ERE"->0.6`,"MDE"->0.8`,"PTB"->0.1`,"MDP12"->1.`|>|>
What is the minimal amount of work to get matrix functions such as Eigensystem
to be output in keyed form?
If keys are projected out, then Eigensystem
can be called on the underlying value matrix:
ds // Query[Values, Values] // Eigensystem
{{2.38557,1.096,0.34121,0.177218},{{-0.545044,-0.546841,-0.277419,-0.571779},{0.296227,-0.364221,0.81849,-0.33116},{0.724656,-0.497105,-0.476972,0.0160709},{-0.300084,-0.566741,0.160034,0.750429}}}
The desired keyed format would have an association for the eigenvalues and a nested Association for the Eigenvector matrix:
ds // keyedEigensystem
{<|ERE->2.38557,MDE->1.096,PTB->0.34121,MDP12->0.177218|>,<|ERE-><|ERE->-0.545044,MDE->-0.546841,PTB->-0.277419,MDP12->-0.571779|>,MDE-><|ERE->0.296227,MDE->-0.364221,PTB->0.81849,MDP12->-0.33116|>,PTB-><|ERE->0.724656,MDE->-0.497105,PTB->-0.476972,MDP12->0.0160709|>,MDP12-><|ERE->-0.300084,MDE->-0.566741,PTB->0.160034,MDP12->0.750429|>|>}
Current solution is cumbersome, and would likely need mod for rectangular matrices and functions like SingularValueDecomposition
. Is there a simpler, more flexible method?
keyedEgensystem[as_Association]:=Query[{{Keys,Query[Transpose/*Keys]},Query[Values,Values]/*Eigensystem}]/*Replace[{{rowKeys_,colKeys_},{l_,M_}}:>{AssociationThread[rowKeys,l],Query[AssociationThread[rowKeys,\[Bullet]],AssociationThread[colKeys,\[Bullet]]][M]}][as]
PS using the shorthand pseudo-op form
\[Bullet] /: h_[pre___, \[Bullet], post___] :=
Function[expr, h[pre, expr, post]];