/**
\addtogroup arrayfire_func
@{

\defgroup lapack_factor_func_svd svd

Perform singular value decomposition.

This function factorizes a matrix \f$A\f$ into two unitary matrices, \f$U\f$
and \f$V^T\f$, and a diagonal matrix \f$S\f$, such that \f$A = USV^T\f$. If
\f$A\f$ has \f$M\f$ rows and \f$N\f$ columns (\f$M \times N\f$), then \f$U\f$
will be \f$M \times M\f$, \f$V\f$ will be \f$N \times N\f$, and \f$S\f$ will be
\f$M \times N\f$. However, for \f$S\f$, this function only returns the non-zero
diagonal elements as a sorted (in descending order) 1D array.

To reconstruct the original matrix \f$A\f$ from the individual factors, the
following code snippet can be used:

\snippet test/svd_dense.cpp ex_svd_reg

When memory is a concern, and \f$A\f$ is dispensable, \ref af::svdInPlace() can
be used. However, this in-place version is currently limited to input arrays
where \f$M \geq N\f$.

\ingroup lapack_factor_mat

===============================================================================

\defgroup lapack_factor_func_lu lu

Perform LU decomposition.

This function decomposes input matrix \f$A\f$ into a lower triangle \f$L\f$, an
upper triangle \f$U\f$ such that \f$A = L * U\f$.

For stability, a permutation array \f$P\f$ is also used to modify the formula
in the following manner, \f$A(P, span) = L * U\f$.

This operation can be performed in ArrayFire, using the following code snippet.

\snippet test/lu_dense.cpp ex_lu_unpacked

The permuted version of the original matrix can be reconstructed, using the
following snippet.

\snippet test/lu_dense.cpp ex_lu_recon

The sample output for these operations can be seen below.

\code
a_orig [3 3 1 1]
    0.0000     3.0000     6.0000
    1.0000     4.0000     7.0000
    2.0000     5.0000     8.0000

l [3 3 1 1]
    1.0000     0.0000     0.0000
    0.0000     1.0000     0.0000
    0.5000     0.5000     1.0000

u [3 3 1 1]
    2.0000     5.0000     8.0000
    0.0000     3.0000     6.0000
    0.0000     0.0000     0.0000

pivot [3 1 1 1]
         2
         0
         1

a_recon [3 3 1 1]
    2.0000     5.0000     8.0000
    0.0000     3.0000     6.0000
    1.0000     4.0000     7.0000

a_perm [3 3 1 1]
    2.0000     5.0000     8.0000
    0.0000     3.0000     6.0000
    1.0000     4.0000     7.0000
\endcode

When memory is a concern, users can perform the LU decomposition in place as
shown below.

\snippet test/lu_dense.cpp ex_lu_packed

The lower and upper triangle matrices can be obtained if necessary in the
following manner.

\snippet test/lu_dense.cpp ex_lu_extract

LU decompositions have many applications including
<a href="http://en.wikipedia.org/wiki/LU_decomposition#Solving_linear_equations">
solving a system of linear equations</a>. Check \ref af::solveLU for more
information.

\ingroup lapack_factor_mat

===============================================================================

\defgroup lapack_factor_func_qr qr

Perform QR decomposition.

This function decomposes input matrix \f$A\f$ into an orthogonal matrix \f$Q\f$
and an upper triangular matrix \f$R\f$ such that, \f$A = Q * R\f$ and
\f$Q * Q^T = I\f$, where \f$I\f$ is an identity matrix. The matrix \f$Q\f$ is a
square matrix of size \f$max(M, N)\f$ where \f$M\f$ and \f$N\f$ are rows and
columns of \f$A\f$ respectively. The matrix \f$R\f$ is the same size as
\f$A\f$.

This operation can be performed in ArrayFire using the following code snippet.

\snippet test/qr_dense.cpp ex_qr_unpacked

The additional parameter `tau` can be used to speed up solving over- and
under-determined systems of equations.

The original matrix can be reconstructed using the following code snippet.

\snippet test/qr_dense.cpp ex_qr_recon

When memory is a concern, users can perform QR decomposition in place as shown
below.

\snippet test/qr_dense.cpp ex_qr_packed

\ingroup lapack_factor_mat

===============================================================================

\defgroup lapack_factor_func_cholesky cholesky

Perform Cholesky decomposition.

This function decomposes a
<a href="http://en.wikipedia.org/wiki/Positive-definite_matrix">positive
definite</a> matrix \f$A\f$ into two triangular matrices such that,
\f$A = L * U\f$ and \f$L = U^T\f$.

Only one of \f$L\f$ and \f$U\f$ is stored to conserve space when solving linear
equations.

This operation can be performed in ArrayFire using the following code snippet.

\snippet test/cholesky_dense.cpp ex_chol_reg

When memory is a concern, users can perform Cholesky decomposition in place as
shown below.

\snippet test/cholesky_dense.cpp ex_chol_inplace

\ingroup lapack_factor_mat

===============================================================================

\defgroup lapack_solve_func_gen solve

Solve a system of equations.

This function takes a co-efficient matrix \f$A\f$ and an output matrix \f$B\f$
as inputs to solve the following equation for \f$X\f$, \f$A * X = B\f$.

This operation can be done in ArrayFire using the following code snippet.

\snippet test/solve_common.hpp ex_solve

The results can be verified by reconstructing the output matrix using \ref
af::matmul in the following manner,

\snippet test/solve_common.hpp ex_solve_recon

The sample output can be seen below.

\code
A [3 3 1 1]
    0.1000     3.1000     6.1000
    1.1000     4.1000     7.0000
    2.0000     5.0000     8.0000

B0 [3 1 1 1]
   21.9000
   30.7000
   39.0000

X1 [3 1 1 1]
    4.0000
    3.0000
    2.0000

B1 [3 1 1 1]
   21.9000
   30.7000
   39.0000
\endcode

If the coefficient matrix is known to be a triangular matrix, \ref AF_MAT_LOWER
or \ref AF_MAT_UPPER can be passed to make solve faster.

The sample code snippets for solving a lower triangular matrix can be seen
below.

\snippet test/solve_common.hpp ex_solve_lower

Similarily, the code snippet for solving an upper triangular matrix can be seen
below.

\snippet test/solve_common.hpp ex_solve_upper

See also: \ref af::solveLU

\ingroup lapack_solve_mat

===============================================================================

\defgroup lapack_solve_lu_func_gen solveLU

Solve a system of equations.

This function takes a co-efficient matrix \f$A\f$ and an output matrix \f$B\f$
as inputs to solve the following equation for \f$X\f$, \f$A * X = B\f$.

This operation can be done in ArrayFire using the following code snippet.

\snippet test/solve_common.hpp ex_solve_lu

This function, along with \ref af::lu, split up the task af::solve performs for
square matrices.

This function is beneficial over \ref af::solve only in long running
application where the coefficient matrix \f$A\f$ stays the same, but the
observed variables keep changing.

\ingroup lapack_solve_mat

===============================================================================

\defgroup lapack_ops_func_inv inverse

Invert a matrix.

This function inverts a square matrix \f$A\f$. The code snippet to demonstrate
this can be seen below.

\snippet test/inverse_dense.cpp ex_inverse

The sample output can be seen below.

\code
A [3 3 1 1]
    0.0100     3.0100     6.0100
    1.0100     4.0100     7.0000
    2.0000     5.0000     8.0000

IA [3 3 1 1]
   48.9076   -99.9927    50.7518
  -99.1552   199.9852  -100.4968
   49.7451   -99.9926    50.2475

I [3 3 1 1]
    1.0000     0.0001    -0.0000
    0.0000     1.0000     0.0000
    0.0000     0.0000     1.0000

\endcode

\ingroup lapack_ops_mat

===============================================================================

\defgroup lapack_ops_func_pinv pinverse

Pseudo-invert (Moore-Penrose) a matrix.

This function calculates the Moore-Penrose pseudoinverse of a matrix \f$A\f$,
using \ref af::svd at its core. If \f$A\f$ is of size \f$M \times N\f$, then
its pseudoinverse \f$A^+\f$ will be of size \f$N \times M\f$.

This calculation can be batched if the input array is three or four-dimensional
\f$(M \times N \times P \times Q\f$, with \f$Q=1\f$ for only three dimensions
\f$)\f$. Each \f$M \times N\f$ slice along the third dimension will have its
own pseudoinverse, for a total of \f$P \times Q\f$ pseudoinverses in the output
array \f$(N \times M \times P \times Q)\f$.

Below is an example snippet of its usage. In this example, we have a matrix
\f$A\f$ and compute its pseudoinverse \f$A^+\f$. This condition must hold:
\f$AA^+A=A\f$, given that the two matrices are pseudoinverses of each other (in
fact, this is one of the Moore-Penrose conditions):

\snippet test/pinverse.cpp ex_pinverse

\ingroup lapack_ops_mat

===============================================================================

\defgroup lapack_ops_func_rank rank

Find the rank of a matrix.

This function uses \ref af::qr to find the rank of the input matrix within the
given tolerance.

\ingroup lapack_ops_mat

===============================================================================

\defgroup lapack_ops_func_det det

Find the determinant of a matrix.

This function requires scratch space equal to the input array.

\ingroup lapack_ops_mat

===============================================================================

\defgroup lapack_ops_func_norm norm

Find the norm of a matrix

This function can return the norm using various metrics based on the `type`
parameter.

\ref AF_NORM_MATRIX_2 is currently not supported.

\ingroup lapack_ops_mat

===============================================================================

\defgroup lapack_helper_func_available isLAPACKAvailable

\brief Returns true if ArrayFire is compiled with LAPACK support

\ingroup lapack_helper

===============================================================================

@}
*/
