({{, (RefLink[MatrixFunction, paclet:ref/MatrixFunction])[f,m]
gives the matrix generated by the scalar function f at the matrix argument m.}})

OpenersNotesSection(Spacer1)Details and Options

A matrix function transforms a matrix to another matrix. For convergent power series, (RefLink[MatrixFunction, paclet:ref/MatrixFunction])[f,m] effectively evaluates the power series for the function f with ordinary powers replaced by matrix powers.

The function f should be a unary differentiable or symbolic function.

(RefLink[MatrixFunction, paclet:ref/MatrixFunction]) works only on square matrices. It applies the Schur–Parlett method for inexact matrices and Jordan decomposition for exact or symbolic matrices.

(RefLink[MatrixFunction, paclet:ref/MatrixFunction]) can be used on (RefLink[SparseArray, paclet:ref/SparseArray]) objects.

A (RefLink[Method, paclet:ref/Method]) option can be given, with possible explicit settings:

The "Schur" method can be specified with method options mopts by (RefLink[Method, paclet:ref/Method])->{"Schur",mopts}. The following method options can be given:

OpenersPrimaryExamplesSection(Spacer1)Examples  (31)

OpenersExampleSection0(Spacer1)Basic Examples  (2)

Compute the matrix sine and cosine of a 3×3 matrix m:

m={{1.,1.,0.},{0.,1.,0.},{0.,0.,2.}};

cosm=MatrixFunction[Cos,m]

sinm=MatrixFunction[Sin,m]

Test the matrix identity (sin^2)(m)+(cos^2)(m)==1:

sinm.sinm+cosm.cosm==IdentityMatrix[3]

Compute a matrix polynomial, specifying the polynomial as a pure function:

MatrixFunction[((#)^5)+2((#)^2)+1&,{{a,1},{0,b}}]

OpenersExampleSection1(Spacer1)Scope  (8)

Use exact arithmetic to compute the matrix function of a logarithm of a polynomial:

m = {{1,1/2,1/3,1/4},{0,1,1/3,1/4},{0,0,1,1/4},{0,0,0,1}};

MatrixFunction[Log[1+2#+3((#)^2)]&,m]//Simplify

Use machine arithmetic:

MatrixFunction[Log[1+2 #+3((#)^2)]&,N[m]]

Use 20-digit-precision arithmetic:

MatrixFunction[Log[1+2#+3((#)^2)]&,N[m,20]]

Compute the square root of a matrix:

MatrixFunction[Sqrt,{{((5 π)/18),((2 π)/9)},{((4 π)/9),(π/18)}}]//Simplify

Compute the matrix sine for a complex matrix:

MatrixFunction[Sin[# π]&,{{1, 2+I}, {3+I, 1}}]//Simplify

Compute the matrix function using the composition of sine and cosine functions:

MatrixFunction[Sin[Cos[π#/4] π/8]&, {{4,-1},{6,-1}}]

Compute the logarithm of an approximate matrix:

m={{2.,2.,1.},{4.,6.,4.},{3.,6.,8.}};MatrixFunction[Log,m]

Verify that the exponential of the result is the original matrix:

MatrixExp[%]==m

Find the second inverse matrix power applied to a particular vector:

m = RandomReal[{1,2}, {10, 10}];
b = ConstantArray[1., 10];

MatrixFunction[((#)^(-2))&,m].b

This is a more efficient way of computing (m^(-1)).(m^(-1)).b:

minv=LinearSolve[m];
Nest[minv,b,2]

Compute a matrix function applied to a vector for a sparse matrix:

m = SparseArray[{{i_,i_}->-2., {i_, j_}/;Abs[i-j]==1->1.}, {10,10}];

MatrixFunction[Exp[-((#)^2)]&,m].Range[10]//Chop

Compute a matrix polynomial of a sparse tridiagonal matrix:

MatrixFunction[((#)^(3/2))+ 2 ((#)^(1/2))+ 3 ((#)^(-1/2))&,SparseArray[{{i_,i_}->2.,{i_,j_}/;Abs[i-j]==1->-1.},{6,6}]]//Chop

OpenersExampleSection2(Spacer1)Generalizations & Extensions  (3)

Compute a matrix function with a symbolic scalar function:

MatrixFunction[f,{{1,2},{0,1}}]//Simplify

Use a symbolic matrix with a symbolic scalar function:

MatrixFunction[f,{{0,a},{b,0}}]//Simplify

Compute the matrix sine of a symbolic diagonal matrix:

MatrixFunction[Sin,{{a,0},{0,b}}]

Compute the matrix tangent of a symbolic non-diagonal matrix:

MatrixFunction[Tan,{{a,0},{1,b}}]

Use a symbolic scalar function with a numeric matrix:

MatrixFunction[f, {{5,-1},{9,-1}}]

OpenersExampleSection3(Spacer1)Options  (2)

OpenersExampleSubsection0(Spacer1)Method  (2)

If many eigenvalues are very close, they are put in a diagonal block submatrix, which may become large; computations are then more expensive and convergence may be slow:

m=(({{0.0003, 100., 1.}, {0, 0.0002, 100.}, {0, 0, 0.0001}}));
f = (1-#)/(Sqrt[1-((#)^2)])&;

AbsoluteTiming[m1=MatrixFunction[f,m]]

A smaller value for "BlockSeparationDelta" reduces the diagonal block size and also speeds convergence:

AbsoluteTiming[m2=MatrixFunction[f,m,Method->{"Schur","BlockSeparationDelta"->(10^(-6))}]]

But the result may be much less accurate:

mfinv =Function[Module[{id = IdentityMatrix[Length[#]]},Inverse[id+ #.#].(id-#.#)]];
{Norm[mfinv[m1]-m],Norm[mfinv[m2]-m]}

When an input matrix is poorly balanced (containing terms of very different magnitudes), balancing may improve the result:

m={{1000.,0,0,0,0.3,0,-1000},{0,0.1,0,0.2,0.4,-1000,3000},{0,0,2000.,0,0.3,0.2,-1000},{0,0,0,1.,0,-1000,0},{0,1000,0,0,0.3,0.1,0},{0,0,0,0,0,0.2,-0.3},{100,0,0,0,0,0,1.}};
m0=MatrixFunction[Sqrt,m,Method->{"Schur","Balanced"->True}];
m1=MatrixFunction[Sqrt,m,Method->"Schur"];
{Norm[MatrixPower[m0,2]-m],Norm[MatrixPower[m1,2]-m]}

OpenersExampleSection4(Spacer1)Applications  (3)

The solution of (((∂^2)y(t))/(∂(t^2)))+A y(t)==0, y(0)==y0, y'(0)=(y0)'(0) for a scalar symbol A is given with:

DSolve[{D[y[t],{t,2}]+A y[t]==0,y[0]==y0[0],y'[0]==y0'[0]},y,t]

If A is a matrix, the solution can be computed using matrix functions in the scalar solution:

A=-{{0,1,0},{1/3,1,0},{1,0,1}}//N;
y0[t_]:={t,(Sqrt[1+t]),1+t}

sqA=MatrixFunction[Sqrt,A];
y[t_?NumericQ]:=MatrixFunction[Cos,t sqA].y0[0]+Inverse[sqA].MatrixFunction[Sin,t sqA].y0'[0];

Plot[y[t],{t,0,1}]

Find the matrix that satisfies X+sin(X)==A:

m=RandomReal[{0,1},{6,6}];

f[x_?MatrixQ]:=MatrixFunction[#+Sin[#]&,x];

sol=FindRoot[f[x]==m,{x,IdentityMatrix[Length[m]]}];
MatrixForm[x/.sol]

f[x/.sol]-m//Chop

Evaluate a characteristic polynomial:

m = Reverse[IdentityMatrix[5]];

p = CharacteristicPolynomial[m,#]

MatrixFunction[Evaluate[p]&,  m]

OpenersExampleSection5(Spacer1)Properties & Relations  (6)

Applying (RefLink[ArcSin, paclet:ref/ArcSin]) after (RefLink[Sin, paclet:ref/Sin]) gives the original matrix:

MatrixFunction[Sin,{{((5 π)/18),((2 π)/9)},{((4 π)/9),(π/18)}}]

MatrixFunction[ArcSin,%]

Compute the matrix logarithm and then the matrix exponent:

MatrixExp[MatrixFunction[Log,{{0,0,1},{0,2,0},{-1,0,0}}]]

Using the function 1/#& is the same as using (RefLink[Inverse, paclet:ref/Inverse]):

MatrixFunction[1/#&,{{1,1},{1,2}}]==Inverse[{{1,1},{1,2}}]

Using a function that is a power is equivalent to using (RefLink[MatrixPower, paclet:ref/MatrixPower]):

MatrixFunction[((#)^n)&,{{0,0,1},{0,2,0},{-1,0,0}}]==MatrixPower[{{0,0,1},{0,2,0},{-1,0,0}}, n]

If m is diagonalizable with m==v.d.(v^(-1)) and the eigenvectors are well conditioned, then f(m)==v.f(d).(v^(-1)):

m=RandomReal[1,{3,3}];

{d, vt} = Eigensystem[m]

v = Transpose[vt];
v.DiagonalMatrix[Sin[Cos[d]]].Inverse[v] - MatrixFunction[Sin[Cos[#]]&,m]//Chop

A matrix is a root of its characteristic polynomial:

m = RandomInteger[2, {3,3}]

polyf = Function[Evaluate[CharacteristicPolynomial[m,#]]]

MatrixFunction[polyf, m]//Simplify

OpenersExampleSection6(Spacer1)Possible Issues  (6)

The scalar function can have symbolic derivatives for exact or symbolic matrices:

F[x_?NumericQ]:=(Sqrt[x]);
MatrixFunction[F,{{1,1,0},{0,1,1},{0,0,1}}]

MatrixFunction[F,{{1,1,0},{0,1,1},{0,0,1}}//N]

Compare with this example:

F[x_]:=(Sqrt[x]); 
MatrixFunction[F,{{1,1,0},{0,1,1},{0,0,1}}]

(RefLink[MatrixFunction, paclet:ref/MatrixFunction]) does not work with non-differentiable functions such as (RefLink[Abs, paclet:ref/Abs]):

MatrixFunction[Abs,{{1.,1.,0.},{0.,1.,1.},{0.,0.,1.}}]

It will return a matrix function for an exact input matrix, but the result is meaningless because (RefLink[Abs, paclet:ref/Abs]) does not have a first or second derivative:

MatrixFunction[Abs,{{1,1,0},{0,1,1},{0,0,1}}]

(RefLink[MatrixFunction, paclet:ref/MatrixFunction]) does not return a result when the scalar function or any of its initial derivatives are not defined at matrix eigenvalues:

MatrixFunction[Sqrt[1-#]&,{{1,1,0},{0,1,1},{0,0,1}}]

MatrixFunction[Sqrt[1-#]&,{{1.,1.,0.},{0.,1.,1.},{0.,0.,1.}}]

The scalar function f has poles (singularities) at 1, 2, and 3:

f=1/Apply[Times,(#-Range[3])]&;

If a scalar function is not analytic and a matrix eigenvalue is close to a function pole, the resulting matrix is usually incorrect:

m={{-2.131558166676987,-2.937833681080357,-0.995639204939471},{4.991469442950794,5.743899123162778,1.4428901292047926},{1.621158931412957,1.1503162105039664,2.387659043514208}};
Eigenvalues[m]

mf=MatrixFunction[Evaluate[f],m]

The method "Jordan" can work with exact and inexact matrices:

MatrixFunction[Sin[# π]&,{{1/2,1/3},{1/3,1/4}},Method->"Jordan"]//Simplify

MatrixFunction[Sin[# π]&,{{1./2.,1./3.},{1./3.,1./4.}},Method->"Jordan"]

The method "Schur" works only with inexact (machine- and arbitrary-precision) matrices:

MatrixFunction[Sin[# π]&,{{1/2,1/3},{1/3,1/4}},Method->"Schur"]

MatrixFunction[Sin[# π]&,{{1./2.,1./3.},{1./3.,1./4.}},Method->"Schur"]

OpenersExampleSection7(Spacer1)Neat Examples  (1)

A=IdentityMatrix[20]+(Reverse/@IdentityMatrix[20])+1/20RandomReal[{0,1},{20,20}];
ListAnimate[MatrixPlot[MatrixFunction[Sin,#]]&/@Table[i A,{i,1,20}]]

({{DocumentationFooterIconsRelatedFunction.png, ({{See Also}, {(RefLink[MatrixExp, paclet:ref/MatrixExp])  ▪  (RefLink[MatrixLog, paclet:ref/MatrixLog])  ▪  (RefLink[MatrixPower, paclet:ref/MatrixPower])  ▪  (RefLink[Inverse, paclet:ref/Inverse])  ▪  (RefLink[JordanDecomposition, paclet:ref/JordanDecomposition])  ▪  (RefLink[Eigensystem, paclet:ref/Eigensystem])  ▪  (RefLink[SchurDecomposition, paclet:ref/SchurDecomposition])}})}})

({{DocumentationFooterIconsRelatedTutorial.png, ({{Tutorials}, {▪(RefLinkPlain[Basic Matrix Operations, paclet:tutorial/BasicMatrixOperations])}, {▪(RefLinkPlain[Vectors and Matrices, paclet:tutorial/VectorsAndMatrices])}})}})

({{DocumentationFooterIconsRelatedGuide.png, ({{Related Guides}, {▪(RefLinkPlain[Matrix Operations, paclet:guide/MatrixOperations])}})}})