Eigendecomposition of a matrix

From Infogalactic: the planetary knowledge core
Jump to: navigation, search

In the mathematical discipline of linear algebra, eigendecomposition or sometimes spectral decomposition is the factorization of a matrix into a canonical form, whereby the matrix is represented in terms of its eigenvalues and eigenvectors. Only diagonalizable matrices can be factorized in this way.

Fundamental theory of matrix eigenvectors and eigenvalues

<templatestyles src="Module:Hatnote/styles.css"></templatestyles>

A (non-zero) vector v of dimension N is an eigenvector of a square (N×N) matrix A if and only if it satisfies the linear equation

 \mathbf{A} \mathbf{v} = \lambda \mathbf{v}

where λ is a scalar, termed the eigenvalue corresponding to v. That is, the eigenvectors are the vectors that the linear transformation A merely elongates or shrinks, and the amount that they elongate/shrink by is the eigenvalue. The above equation is called the eigenvalue equation or the eigenvalue problem.

This yields an equation for the eigenvalues

 p\left(\lambda\right) := \det\left(\mathbf{A} - \lambda \mathbf{I}\right)= 0. \!\

We call p(λ) the characteristic polynomial, and the equation, called the characteristic equation, is an Nth order polynomial equation in the unknown λ. This equation will have Nλ distinct solutions, where 1 ≤ NλN . The set of solutions, that is, the eigenvalues, is called the spectrum of A.[1][2][3]

We can factor p as

p\left(\lambda\right)= (\lambda-\lambda_1)^{n_1}(\lambda-\lambda_2)^{n_2}\cdots(\lambda-\lambda_k)^{n_k} = 0. \!\

The integer ni is termed the algebraic multiplicity of eigenvalue λi. The algebraic multiplicities sum to N:

\sum\limits_{i=1}^{N_{\lambda}}{n_i} =N.

For each eigenvalue, λi, we have a specific eigenvalue equation

 \left(\mathbf{A} - \lambda_i \mathbf{I}\right)\mathbf{v}  = 0. \!\

There will be 1 ≤ mini linearly independent solutions to each eigenvalue equation. The mi solutions are the eigenvectors associated with the eigenvalue λi. The integer mi is termed the geometric multiplicity of λi. It is important to keep in mind that the algebraic multiplicity ni and geometric multiplicity mi may or may not be equal, but we always have mini. The simplest case is of course when mi = ni = 1. The total number of linearly independent eigenvectors, Nv, can be calculated by summing the geometric multiplicities

\sum\limits_{i=1}^{N_{\lambda}}{m_i} =N_{\mathbf{v}}.

The eigenvectors can be indexed by eigenvalues, i.e. using a double index, with vi,j being the jth eigenvector for the ith eigenvalue. The eigenvectors can also be indexed using the simpler notation of a single index vk, with k = 1, 2, ..., Nv.

Eigendecomposition of a matrix

Let A be a square (N×N) matrix with N linearly independent eigenvectors, q_i \,\, (i = 1, \dots, N). Then A can be factorized as

\mathbf{A}=\mathbf{Q}\mathbf{\Lambda}\mathbf{Q}^{-1}

where Q is the square (N×N) matrix whose ith column is the eigenvector q_i of A and Λ is the diagonal matrix whose diagonal elements are the corresponding eigenvalues, i.e., \Lambda_{ii}=\lambda_i. Note that only diagonalizable matrices can be factorized in this way. For example, the defective matrix \begin{pmatrix}
1 & 1 \\
0 & 1 \\
\end{pmatrix} cannot be diagonalized.

The eigenvectors q_i \,\, (i = 1, \dots, N) are usually normalized, but they need not be. A non-normalized set of eigenvectors, v_i \,\, (i = 1, \dots, N), can also be used as the columns of Q. That can be understood by noting that the magnitude of the eigenvectors in Q gets canceled in the decomposition by the presence of Q−1.

Example

Taking a 2 × 2 real matrix \mathbf{A} = \begin{bmatrix} 1 & 0 \\ 1 & 3 \\ \end{bmatrix} as an example to be decomposed into a diagonal matrix through multiplication of a non-singular matrix \mathbf{B} = \begin{bmatrix}
a & b \\
c & d \\
\end{bmatrix} \in \mathbb{R}^{2\times2} .

Then

\begin{bmatrix}
a & b \\ c & d \\ \end{bmatrix}^{-1} \begin{bmatrix} 1 & 0 \\ 1 & 3 \\ \end{bmatrix} \begin{bmatrix} a & b \\ c & d \\ \end{bmatrix} = \begin{bmatrix} x & 0 \\ 0 & y \\ \end{bmatrix}, for some real diagonal matrix \begin{bmatrix} x & 0 \\ 0 & y \\ \end{bmatrix}.

Shifting \mathbf{B} to the right hand side:

\begin{bmatrix} 1 & 0 \\ 1 & 3 \\ \end{bmatrix} \begin{bmatrix} a & b \\ c & d \\ \end{bmatrix} = \begin{bmatrix} a & b \\ c & d \\ \end{bmatrix} \begin{bmatrix} x & 0 \\ 0 & y \\ \end{bmatrix}

The above equation can be decomposed into 2 simultaneous equations:

 \begin{cases} \begin{bmatrix} 1 & 0\\ 1 & 3 \end{bmatrix} \begin{bmatrix} a \\ c \end{bmatrix} = \begin{bmatrix} ax \\ cx \end{bmatrix} \\ \begin{bmatrix} 1 & 0\\ 1 & 3 \end{bmatrix} \begin{bmatrix} b \\ d \end{bmatrix} = \begin{bmatrix} by \\ dy \end{bmatrix} \end{cases}

Factoring out the eigenvalues x and y:

 \begin{cases} \begin{bmatrix} 1 & 0\\ 1 & 3 \end{bmatrix} \begin{bmatrix} a \\ c \end{bmatrix} = x\begin{bmatrix} a \\ c \end{bmatrix} \\ \begin{bmatrix} 1 & 0\\ 1 & 3 \end{bmatrix} \begin{bmatrix} b \\ d \end{bmatrix} = y\begin{bmatrix} b \\ d \end{bmatrix} \end{cases}

Letting \overrightarrow{a} = \begin{bmatrix} a \\ c \end{bmatrix}, \overrightarrow{b} = \begin{bmatrix} b \\ d \end{bmatrix}, this gives us two vector equations:

 \begin{cases} A \overrightarrow{a} = x \overrightarrow{a} \\ A \overrightarrow{b} = y \overrightarrow{b} \end{cases}

And can be represented by a single vector equation involving 2 solutions as eigenvalues:

\mathbf{A} \mathbf{u} = \lambda \mathbf{u}

where  \lambda represents the two eigenvalues x and y,  \mathbf{u} represents the vectors \overrightarrow{a} and \overrightarrow{b}.

Shifting \lambda \mathbf{u} to the left hand side and factorizing  \mathbf{u} out

 (\mathbf{A}-\lambda \mathbf{I}) \mathbf{u} = 0

Since \mathbf{B} is non-singular, it is essential that \mathbf{u} is non-zero. Therefore,

 (\mathbf{A}-\lambda \mathbf{I}) = \mathbf{0}

Considering the determinant of (\mathbf{A}-\lambda \mathbf{I}),

 \begin{bmatrix} 1- \lambda & 0\\ 1 & 3- \lambda \end{bmatrix} =0

Thus

(1- \lambda)(3- \lambda)=0

Giving us the solutions of the eigenvalues for the matrix \mathbf{A} as  \lambda=1 or  \lambda=3 , and the resulting diagonal matrix from the eigendecomposition of \mathbf{A} is thus \begin{bmatrix} 1 & 0 \\ 0 & 3 \end{bmatrix}.

Putting the solutions back into the above simultaneous equations

 \begin{cases} \begin{bmatrix} 1 & 0 \\ 1 & 3 \end{bmatrix} \begin{bmatrix} a \\ c \end{bmatrix} = 1\begin{bmatrix} a \\ c \end{bmatrix} \\ \begin{bmatrix} 1 & 0\\ 1 & 3 \end{bmatrix} \begin{bmatrix} b \\ d \end{bmatrix} = 3\begin{bmatrix} b \\ d \end{bmatrix} \end{cases}

Solving the equations, we have a= -2c, a\in \mathbb{R} and b=0, d\in \mathbb{R}

Thus the matrix \mathbf{B} required for the eigendecomposition of \mathbf{A} is \begin{bmatrix} -2c & 0 \\ c & d \end{bmatrix}, [c, d]\in \mathbb{R} . i.e. :

\begin{bmatrix}
-2c & 0 \\ c & d \\ \end{bmatrix}^{-1} \begin{bmatrix} 1 & 0 \\ 1 & 3 \\ \end{bmatrix} \begin{bmatrix} -2c & 0 \\ c & d \\ \end{bmatrix} = \begin{bmatrix} 1 & 0 \\ 0 & 3 \\ \end{bmatrix}, [c, d]\in \mathbb{R}

Matrix inverse via eigendecomposition

<templatestyles src="Module:Hatnote/styles.css"></templatestyles>

If matrix A can be eigendecomposed and if none of its eigenvalues are zero, then A is nonsingular and its inverse is given by

\mathbf{A}^{-1}=\mathbf{Q}\mathbf{\Lambda}^{-1}\mathbf{Q}^{-1}

Furthermore, because Λ is a diagonal matrix, its inverse is easy to calculate:

\left[\Lambda^{-1}\right]_{ii}=\frac{1}{\lambda_i}

Practical implications[4]

When eigendecomposition is used on a matrix of measured, real data, the inverse may be less valid when all eigenvalues are used unmodified in the form above. This is because as eigenvalues become relatively small, their contribution to the inversion is large. Those near zero or at the "noise" of the measurement system will have undue influence and could hamper solutions (detection) using the inverse.

Two mitigations have been proposed: 1) truncating small/zero eigenvalues, 2) extending the lowest reliable eigenvalue to those below it.

The first mitigation method is similar to a sparse sample of the original matrix, removing components that are not considered valuable. However, if the solution or detection process is near the noise level, truncating may remove components that influence the desired solution.

The second mitigation extends the eigenvalue so that lower values have much less influence over inversion, but do still contribute, such that solutions near the noise will still be found.

The reliable eigenvalue can be found by assuming that eigenvalues of extremely similar and low value are a good representation of measurement noise (which is assumed low for most systems).

If the eigenvalues are rank-sorted by value, then the reliable eigenvalue can be found by minimization of the Laplacian of the sorted eigenvalues:[5]

\min|\nabla^2 \lambda_s |

where the eigenvalues are subscripted with an 's' to denote being sorted. The position of the minimization is the lowest reliable eigenvalue. In measurement systems, the square root of this reliable eigenvalue is the average noise over the components of the system.

Functional calculus

The eigendecomposition allows for much easier computation of power series of matrices. If f(x) is given by

f(x)=a_0+a_1 x+a_2 x^2+\cdots

then we know that

f\left(\mathbf{A}\right)=\mathbf{Q}f\left(\mathbf{\Lambda}\right)\mathbf{Q}^{-1}

Because Λ is a diagonal matrix, functions of Λ are very easy to calculate:

\left[f\left(\mathbf{\Lambda}\right)\right]_{ii}=f\left(\lambda_i\right)

The off-diagonal elements of f(Λ) are zero; that is, f(Λ) is also a diagonal matrix. Therefore, calculating f(A) reduces to just calculating the function on each of the eigenvalues .

A similar technique works more generally with the holomorphic functional calculus, using

\mathbf{A}^{-1}=\mathbf{Q}\mathbf{\Lambda}^{-1}\mathbf{Q}^{-1}

from above. Once again, we find that

\left[f\left(\mathbf{\Lambda}\right)\right]_{ii}=f\left(\lambda_i\right)

Examples

\mathbf{A}^{2}=(\mathbf{Q}\mathbf{\Lambda}\mathbf{Q}^{-1})(\mathbf{Q}\mathbf{\Lambda}\mathbf{Q}^{-1}) = \mathbf{Q}\mathbf{\Lambda}(\mathbf{Q}^{-1}\mathbf{Q})\mathbf{\Lambda}\mathbf{Q}^{-1}=\mathbf{Q}\mathbf{\Lambda}^{2}\mathbf{Q}^{-1}
\mathbf{A}^{n}=\mathbf{Q}\mathbf{\Lambda}^{n}\mathbf{Q}^{-1}

Decomposition for special matrices

Lua error in package.lua at line 80: module 'strict' not found.

Normal matrices

A complex normal matrix (A^* A = A A^*) has an orthogonal eigenvector basis, so a normal matrix can be decomposed as

\mathbf{A}=\mathbf{U}\mathbf{\Lambda}\mathbf{U}^{*}

where U is a unitary matrix. Further, if A is Hermitian (A=A^*), which implies that it is also complex normal, the diagonal matrix Λ has only real values, and if A is unitary, Λ takes all its values on the complex unit circle.

Real symmetric matrices

As a special case, for every N×N real symmetric matrix, the eigenvalues are real and the eigenvectors can be chosen such that they orthogonal to each other. Thus a real symmetric matrix A can be decomposed as

\mathbf{A}=\mathbf{Q}\mathbf{\Lambda}\mathbf{Q}^{T}

where Q is an orthogonal matrix, and Λ is a diagonal matrix whose entries are the eigenvalues of A.

Useful facts

Lua error in package.lua at line 80: module 'strict' not found.

Useful facts regarding eigenvalues

  • The product of the eigenvalues is equal to the determinant of A
\det\left(\mathbf{A}\right) = \prod\limits_{i=1}^{N_{\lambda}}{\lambda_i^{n_i}} \!\

Note that each eigenvalue is raised to the power ni, the algebraic multiplicity.

  • The sum of the eigenvalues is equal to the trace of A
\operatorname{tr}\left(\mathbf{A}\right) = \sum\limits_{i=1}^{N_{\lambda}}{{n_i}\lambda_i} \!\

Note that each eigenvalue is multiplied by ni, the algebraic multiplicity.

  • If the eigenvalues of A are λi, and A is invertible, then the eigenvalues of A−1 are simply λi−1.
  • If the eigenvalues of A are λi, then the eigenvalues of f(A) are simply fi), for any holomorphic function f.

Useful facts regarding eigenvectors

  • If A is Hermitian and full-rank, the basis of eigenvectors may be chosen to be mutually orthogonal. The eigenvalues are real.
  • The eigenvectors of A−1 are the same as the eigenvectors of A.
  • Eigenvectors are defined up to a phase, i.e. if Av=\lambda v then e^{i\theta}v is also an eigenvector, and specifically so is -v.
  • In the case of degenerate eigenvalues (an eigenvalue appearing more than once), the eigenvectors have an additional freedom of rotation, i.e. any linear (orthonormal) combination of eigenvectors sharing an eigenvalue (i.e. in the degenerate sub-space), are themselves eigenvectors (i.e. in the subspace).

Useful facts regarding eigendecomposition

  • A can be eigendecomposed if and only if
N_{\mathbf{v}}=N \,
  • If p(λ) has no repeated roots, i.e. Nλ = N, then A can be eigendecomposed.
  • The statement "A can be eigendecomposed" does not imply that A has an inverse.
  • The statement "A has an inverse" does not imply that A can be eigendecomposed.

Useful facts regarding matrix inverse

  • \mathbf{A} can be inverted if and only if
\lambda_i \ne 0 \; \forall \,i
  • If \lambda_i \ne 0 \; \forall \,i and N_{\mathbf{v}}=N, the inverse is given by
\mathbf{A}^{-1}=\mathbf{Q}\mathbf{\Lambda}^{-1}\mathbf{Q}^{-1}

Numerical computations

Lua error in Module:Details at line 30: attempt to call field '_formatLink' (a nil value).

Numerical computation of eigenvalues

Suppose that we want to compute the eigenvalues of a given matrix. If the matrix is small, we can compute them symbolically using the characteristic polynomial. However, this is often impossible for larger matrices, in which case we must use a numerical method.

In practice, eigenvalues of large matrices are not computed using the characteristic polynomial. Computing the polynomial becomes expensive in itself, and exact (symbolic) roots of a high-degree polynomial can be difficult to compute and express: the Abel–Ruffini theorem implies that the roots of high-degree (5 or above) polynomials cannot in general be expressed simply using nth roots. Therefore, general algorithms to find eigenvectors and eigenvalues are iterative.

Iterative numerical algorithms for approximating roots of polynomials exist, such as Newton's method, but in general it is impractical to compute the characteristic polynomial and then apply these methods. One reason is that small round-off errors in the coefficients of the characteristic polynomial can lead to large errors in the eigenvalues and eigenvectors: the roots are an extremely ill-conditioned function of the coefficients.[6]

A simple and accurate iterative method is the power method: a random vector v is chosen and a sequence of unit vectors is computed as

\frac{Av}{\|Av\|}, \frac{A^2v}{\|A^2v\|}, \frac{A^3v}{\|A^3v\|}, \dots

This sequence will almost always converge to an eigenvector corresponding to the eigenvalue of greatest magnitude, provided that v has a nonzero component of this eigenvector in the eigenvector basis (and also provided that there is only one eigenvalue of greatest magnitude). This simple algorithm is useful in some practical applications; for example, Google uses it to calculate the page rank of documents in their search engine.[7] Also, the power method is the starting point for many more sophisticated algorithms. For instance, by keeping not just the last vector in the sequence, but instead looking at the span of all the vectors in the sequence, one can get a better (faster converging) approximation for the eigenvector, and this idea is the basis of Arnoldi iteration.[6] Alternatively, the important QR algorithm is also based on a subtle transformation of a power method.[6]

Numerical computation of eigenvectors

Once the eigenvalues are computed, the eigenvectors could be calculated by solving the equation

 \left(\mathbf{A} - \lambda_i \mathbf{I}\right)\mathbf{v}_{i,j}  = 0 \!\

using Gaussian elimination or any other method for solving matrix equations.

However, in practical large-scale eigenvalue methods, the eigenvectors are usually computed in other ways, as a byproduct of the eigenvalue computation. In power iteration, for example, the eigenvector is actually computed before the eigenvalue (which is typically computed by the Rayleigh quotient of the eigenvector).[6] In the QR algorithm for a Hermitian matrix (or any normal matrix), the orthonormal eigenvectors are obtained as a product of the Q matrices from the steps in the algorithm.[6] (For more general matrices, the QR algorithm yields the Schur decomposition first, from which the eigenvectors can be obtained by a backsubstitution procedure.[8]) For Hermitian matrices, the Divide-and-conquer eigenvalue algorithm is more efficient than the QR algorithm if both eigenvectors and eigenvalues are desired.[6]

Additional topics

Generalized eigenspaces

Recall that the geometric multiplicity of an eigenvalue can be described as the dimension of the associated eigenspace, the nullspace of λI − A. The algebraic multiplicity can also be thought of as a dimension: it is the dimension of the associated generalized eigenspace (1st sense), which is the nullspace of the matrix (λI − A)k for any sufficiently large k. That is, it is the space of generalized eigenvectors (1st sense), where a generalized eigenvector is any vector which eventually becomes 0 if λI − A is applied to it enough times successively. Any eigenvector is a generalized eigenvector, and so each eigenspace is contained in the associated generalized eigenspace. This provides an easy proof that the geometric multiplicity is always less than or equal to the algebraic multiplicity.

This usage should not be confused with the generalized eigenvalue problem described below.

Conjugate eigenvector

A conjugate eigenvector or coneigenvector is a vector sent after transformation to a scalar multiple of its conjugate, where the scalar is called the conjugate eigenvalue or coneigenvalue of the linear transformation. The coneigenvectors and coneigenvalues represent essentially the same information and meaning as the regular eigenvectors and eigenvalues, but arise when an alternative coordinate system is used. The corresponding equation is

Av = \lambda v^*.\,

For example, in coherent electromagnetic scattering theory, the linear transformation A represents the action performed by the scattering object, and the eigenvectors represent polarization states of the electromagnetic wave. In optics, the coordinate system is defined from the wave's viewpoint, known as the Forward Scattering Alignment (FSA), and gives rise to a regular eigenvalue equation, whereas in radar, the coordinate system is defined from the radar's viewpoint, known as the Back Scattering Alignment (BSA), and gives rise to a coneigenvalue equation.

Generalized eigenvalue problem

A generalized eigenvalue problem (2nd sense) is the problem of finding a vector v that obeys

 A\mathbf{v} = \lambda B \mathbf{v} \quad \quad

where A and B are matrices. If v obeys this equation, with some λ, then we call v the generalized eigenvector of A and B (in the 2nd sense), and λ is called the generalized eigenvalue of A and B (in the 2nd sense) which corresponds to the generalized eigenvector v. The possible values of λ must obey the following equation

\det(A - \lambda B)=0.\,

In the case we can find n\in\mathbb{N} linearly independent vectors  \{\mathbf{v}_1\ ,\dots, \mathbf{v}_n\} so that for every i\in\{1,\dots,n\},  A\mathbf{v}_i = \lambda_i B \mathbf{v}_i  \quad, where \lambda_i\in\mathbb{F} then we define the matrices P and D such that

P= \begin{pmatrix} | & & | \\ \mathbf{v}_1 & \cdots & \mathbf{v}_n   \\ | &  & | \\  \end{pmatrix} \equiv 
\begin{pmatrix} (\mathbf{v}_1)_1 & \cdots & (\mathbf{v}_n)_1 \\ \vdots &  & \vdots   \\ (\mathbf{v}_1)_n & \cdots & (\mathbf{v}_n)_n \\ \end{pmatrix}
 (D)_{ij} = \begin{cases}  \lambda_i,  & \text{if }i = j\\ 0, & \text{else} \end{cases}

Then the following equality holds

\mathbf{A}=\mathbf{B}\mathbf{P}\mathbf{D}\mathbf{P}^{-1}

And the proof is

 \mathbf{A}\mathbf{P}= \mathbf{A} \begin{pmatrix} | & & | \\
  \mathbf{v}_1 & \cdots & \mathbf{v}_n   \\
  | &  & | \\ 
\end{pmatrix}
= \begin{pmatrix}
  | & & | \\
  A\mathbf{v}_1 & \cdots & A\mathbf{v}_n   \\
  | &  & | \\ 
\end{pmatrix}
= \begin{pmatrix}
  | & & | \\
  \lambda_1B\mathbf{v}_1 & \cdots & \lambda_nB\mathbf{v}_n   \\
  | &  & | \\ 
\end{pmatrix}
=
\begin{pmatrix}
  | & & | \\
  B\mathbf{v}_1 & \cdots & B\mathbf{v}_n   \\
  | &  & | \\ 
\end{pmatrix}
\mathbf{D}
= \mathbf{B}\mathbf{P}\mathbf{D}

And since P is invertible, we multiply the equation from the right by its inverse, finishing the proof.

The set of matrices of the form AλB, where λ is a complex number, is called a pencil; the term matrix pencil can also refer to the pair (A,B) of matrices.[9] If B is invertible, then the original problem can be written in the form

 B^{-1}A\mathbf{v} = \lambda \mathbf{v} \quad \quad

which is a standard eigenvalue problem. However, in most situations it is preferable not to perform the inversion, but rather to solve the generalized eigenvalue problem as stated originally. This is especially important if A and B are Hermitian matrices, since in this case B^{-1}A is not generally Hermitian and important properties of the solution are no longer apparent.

If A and B are Hermitian and B is a positive-definite matrix, the eigenvalues λ are real and eigenvectors v1 and v2 with distinct eigenvalues are B-orthogonal (\mathbf{v}_1^* B \mathbf{v}_2 = 0).[10] Also, in this case it is guaranteed that there exists a basis of generalized eigenvectors (it is not a defective problem).[9] This case is sometimes called a Hermitian definite pencil or definite pencil.[9]

See also

Notes

  1. Golub & Van Loan (1996, p. 310)
  2. Kreyszig (1972, p. 273)
  3. Nering (1970, p. 270)
  4. Lua error in package.lua at line 80: module 'strict' not found.
  5. Lua error in package.lua at line 80: module 'strict' not found.
  6. 6.0 6.1 6.2 6.3 6.4 6.5 Lua error in package.lua at line 80: module 'strict' not found.
  7. Ipsen, Ilse, and Rebecca M. Wills, Analysis and Computation of Google's PageRank, 7th IMACS International Symposium on Iterative Methods in Scientific Computing, Fields Institute, Toronto, Canada, 5–8 May 2005.
  8. Lua error in package.lua at line 80: module 'strict' not found.
  9. 9.0 9.1 9.2 Lua error in package.lua at line 80: module 'strict' not found.
  10. Lua error in package.lua at line 80: module 'strict' not found.

References

  • Lua error in package.lua at line 80: module 'strict' not found.
  • Lua error in package.lua at line 80: module 'strict' not found.
  • Lua error in package.lua at line 80: module 'strict' not found.
  • Lua error in package.lua at line 80: module 'strict' not found.
  • Lua error in package.lua at line 80: module 'strict' not found.
  • Lua error in package.lua at line 80: module 'strict' not found.
  • Lua error in package.lua at line 80: module 'strict' not found.

External links