1c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// This file is part of Eigen, a lightweight C++ template library
2c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// for linear algebra.
3c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//
4c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// Copyright (C) 2008-2011 Gael Guennebaud <gael.guennebaud@inria.fr>
5c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//
6c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// This Source Code Form is subject to the terms of the Mozilla
7c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// Public License v. 2.0. If a copy of the MPL was not distributed
8c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
9c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
10c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#ifndef EIGEN_UMFPACKSUPPORT_H
11c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#define EIGEN_UMFPACKSUPPORT_H
12c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
13c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathnamespace Eigen {
14c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
15c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/* TODO extract L, extract U, compute det, etc... */
16c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
17c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// generic double/complex<double> wrapper functions:
18c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
19c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathinline void umfpack_free_numeric(void **Numeric, double)
20c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ umfpack_di_free_numeric(Numeric); *Numeric = 0; }
21c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
22c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathinline void umfpack_free_numeric(void **Numeric, std::complex<double>)
23c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ umfpack_zi_free_numeric(Numeric); *Numeric = 0; }
24c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
25c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathinline void umfpack_free_symbolic(void **Symbolic, double)
26c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ umfpack_di_free_symbolic(Symbolic); *Symbolic = 0; }
27c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
28c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathinline void umfpack_free_symbolic(void **Symbolic, std::complex<double>)
29c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ umfpack_zi_free_symbolic(Symbolic); *Symbolic = 0; }
30c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
31c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathinline int umfpack_symbolic(int n_row,int n_col,
32c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                            const int Ap[], const int Ai[], const double Ax[], void **Symbolic,
33c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                            const double Control [UMFPACK_CONTROL], double Info [UMFPACK_INFO])
34c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
35c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  return umfpack_di_symbolic(n_row,n_col,Ap,Ai,Ax,Symbolic,Control,Info);
36c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
37c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
38c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathinline int umfpack_symbolic(int n_row,int n_col,
39c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                            const int Ap[], const int Ai[], const std::complex<double> Ax[], void **Symbolic,
40c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                            const double Control [UMFPACK_CONTROL], double Info [UMFPACK_INFO])
41c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
42c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  return umfpack_zi_symbolic(n_row,n_col,Ap,Ai,&internal::real_ref(Ax[0]),0,Symbolic,Control,Info);
43c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
44c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
45c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathinline int umfpack_numeric( const int Ap[], const int Ai[], const double Ax[],
46c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                            void *Symbolic, void **Numeric,
47c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                            const double Control[UMFPACK_CONTROL],double Info [UMFPACK_INFO])
48c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
49c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  return umfpack_di_numeric(Ap,Ai,Ax,Symbolic,Numeric,Control,Info);
50c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
51c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
52c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathinline int umfpack_numeric( const int Ap[], const int Ai[], const std::complex<double> Ax[],
53c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                            void *Symbolic, void **Numeric,
54c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                            const double Control[UMFPACK_CONTROL],double Info [UMFPACK_INFO])
55c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
56c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  return umfpack_zi_numeric(Ap,Ai,&internal::real_ref(Ax[0]),0,Symbolic,Numeric,Control,Info);
57c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
58c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
59c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathinline int umfpack_solve( int sys, const int Ap[], const int Ai[], const double Ax[],
60c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                          double X[], const double B[], void *Numeric,
61c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                          const double Control[UMFPACK_CONTROL], double Info[UMFPACK_INFO])
62c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
63c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  return umfpack_di_solve(sys,Ap,Ai,Ax,X,B,Numeric,Control,Info);
64c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
65c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
66c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathinline int umfpack_solve( int sys, const int Ap[], const int Ai[], const std::complex<double> Ax[],
67c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                          std::complex<double> X[], const std::complex<double> B[], void *Numeric,
68c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                          const double Control[UMFPACK_CONTROL], double Info[UMFPACK_INFO])
69c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
70c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  return umfpack_zi_solve(sys,Ap,Ai,&internal::real_ref(Ax[0]),0,&internal::real_ref(X[0]),0,&internal::real_ref(B[0]),0,Numeric,Control,Info);
71c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
72c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
73c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathinline int umfpack_get_lunz(int *lnz, int *unz, int *n_row, int *n_col, int *nz_udiag, void *Numeric, double)
74c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
75c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  return umfpack_di_get_lunz(lnz,unz,n_row,n_col,nz_udiag,Numeric);
76c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
77c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
78c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathinline int umfpack_get_lunz(int *lnz, int *unz, int *n_row, int *n_col, int *nz_udiag, void *Numeric, std::complex<double>)
79c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
80c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  return umfpack_zi_get_lunz(lnz,unz,n_row,n_col,nz_udiag,Numeric);
81c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
82c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
83c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathinline int umfpack_get_numeric(int Lp[], int Lj[], double Lx[], int Up[], int Ui[], double Ux[],
84c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                               int P[], int Q[], double Dx[], int *do_recip, double Rs[], void *Numeric)
85c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
86c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  return umfpack_di_get_numeric(Lp,Lj,Lx,Up,Ui,Ux,P,Q,Dx,do_recip,Rs,Numeric);
87c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
88c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
89c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathinline int umfpack_get_numeric(int Lp[], int Lj[], std::complex<double> Lx[], int Up[], int Ui[], std::complex<double> Ux[],
90c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                               int P[], int Q[], std::complex<double> Dx[], int *do_recip, double Rs[], void *Numeric)
91c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
92c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  double& lx0_real = internal::real_ref(Lx[0]);
93c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  double& ux0_real = internal::real_ref(Ux[0]);
94c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  double& dx0_real = internal::real_ref(Dx[0]);
95c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  return umfpack_zi_get_numeric(Lp,Lj,Lx?&lx0_real:0,0,Up,Ui,Ux?&ux0_real:0,0,P,Q,
96c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                                Dx?&dx0_real:0,0,do_recip,Rs,Numeric);
97c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
98c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
99c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathinline int umfpack_get_determinant(double *Mx, double *Ex, void *NumericHandle, double User_Info [UMFPACK_INFO])
100c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
101c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  return umfpack_di_get_determinant(Mx,Ex,NumericHandle,User_Info);
102c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
103c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
104c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathinline int umfpack_get_determinant(std::complex<double> *Mx, double *Ex, void *NumericHandle, double User_Info [UMFPACK_INFO])
105c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
106c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  double& mx_real = internal::real_ref(*Mx);
107c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  return umfpack_zi_get_determinant(&mx_real,0,Ex,NumericHandle,User_Info);
108c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
109c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
110c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/** \ingroup UmfPackSupport_Module
111c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * \brief A sparse LU factorization and solver based on UmfPack
112c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  *
113c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * This class allows to solve for A.X = B sparse linear problems via a LU factorization
114c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * using the UmfPack library. The sparse matrix A must be squared and full rank.
115c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * The vectors or matrices X and B can be either dense or sparse.
116c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  *
117c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * \WARNING The input matrix A should be in a \b compressed and \b column-major form.
118c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * Otherwise an expensive copy will be made. You can call the inexpensive makeCompressed() to get a compressed matrix.
119c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * \tparam _MatrixType the type of the sparse matrix A, it must be a SparseMatrix<>
120c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  *
121c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * \sa \ref TutorialSparseDirectSolvers
122c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  */
123c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename _MatrixType>
124c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathclass UmfPackLU : internal::noncopyable
125c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
126c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  public:
127c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef _MatrixType MatrixType;
128c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename MatrixType::Scalar Scalar;
129c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename MatrixType::RealScalar RealScalar;
130c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename MatrixType::Index Index;
131c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef Matrix<Scalar,Dynamic,1> Vector;
132c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef Matrix<int, 1, MatrixType::ColsAtCompileTime> IntRowVectorType;
133c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef Matrix<int, MatrixType::RowsAtCompileTime, 1> IntColVectorType;
134c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef SparseMatrix<Scalar> LUMatrixType;
135c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef SparseMatrix<Scalar,ColMajor,int> UmfpackMatrixType;
136c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
137c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  public:
138c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
139c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    UmfPackLU() { init(); }
140c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
141c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    UmfPackLU(const MatrixType& matrix)
142c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
143c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      init();
144c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      compute(matrix);
145c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
146c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
147c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    ~UmfPackLU()
148c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
149c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      if(m_symbolic) umfpack_free_symbolic(&m_symbolic,Scalar());
150c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      if(m_numeric)  umfpack_free_numeric(&m_numeric,Scalar());
151c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
152c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
153c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    inline Index rows() const { return m_copyMatrix.rows(); }
154c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    inline Index cols() const { return m_copyMatrix.cols(); }
155c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
156c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    /** \brief Reports whether previous computation was successful.
157c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      *
158c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * \returns \c Success if computation was succesful,
159c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      *          \c NumericalIssue if the matrix.appears to be negative.
160c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      */
161c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    ComputationInfo info() const
162c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
163c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      eigen_assert(m_isInitialized && "Decomposition is not initialized.");
164c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      return m_info;
165c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
166c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
167c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    inline const LUMatrixType& matrixL() const
168c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
169c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      if (m_extractedDataAreDirty) extractData();
170c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      return m_l;
171c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
172c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
173c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    inline const LUMatrixType& matrixU() const
174c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
175c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      if (m_extractedDataAreDirty) extractData();
176c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      return m_u;
177c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
178c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
179c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    inline const IntColVectorType& permutationP() const
180c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
181c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      if (m_extractedDataAreDirty) extractData();
182c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      return m_p;
183c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
184c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
185c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    inline const IntRowVectorType& permutationQ() const
186c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
187c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      if (m_extractedDataAreDirty) extractData();
188c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      return m_q;
189c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
190c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
191c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    /** Computes the sparse Cholesky decomposition of \a matrix
192c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath     *  Note that the matrix should be column-major, and in compressed format for best performance.
193c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath     *  \sa SparseMatrix::makeCompressed().
194c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath     */
195c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    void compute(const MatrixType& matrix)
196c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
197c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      analyzePattern(matrix);
198c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      factorize(matrix);
199c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
200c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
201c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    /** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A.
202c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      *
203c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * \sa compute()
204c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      */
205c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    template<typename Rhs>
206c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    inline const internal::solve_retval<UmfPackLU, Rhs> solve(const MatrixBase<Rhs>& b) const
207c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
208c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      eigen_assert(m_isInitialized && "UmfPackLU is not initialized.");
209c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      eigen_assert(rows()==b.rows()
210c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                && "UmfPackLU::solve(): invalid number of rows of the right hand side matrix b");
211c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      return internal::solve_retval<UmfPackLU, Rhs>(*this, b.derived());
212c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
213c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
214c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    /** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A.
215c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      *
216c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * \sa compute()
217c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      */
218c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//     template<typename Rhs>
219c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//     inline const internal::sparse_solve_retval<UmfPAckLU, Rhs> solve(const SparseMatrixBase<Rhs>& b) const
220c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//     {
221c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//       eigen_assert(m_isInitialized && "UmfPAckLU is not initialized.");
222c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//       eigen_assert(rows()==b.rows()
223c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//                 && "UmfPAckLU::solve(): invalid number of rows of the right hand side matrix b");
224c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//       return internal::sparse_solve_retval<UmfPAckLU, Rhs>(*this, b.derived());
225c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//     }
226c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
227c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    /** Performs a symbolic decomposition on the sparcity of \a matrix.
228c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      *
229c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * This function is particularly useful when solving for several problems having the same structure.
230c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      *
231c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * \sa factorize(), compute()
232c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      */
233c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    void analyzePattern(const MatrixType& matrix)
234c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
235c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      if(m_symbolic)
236c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        umfpack_free_symbolic(&m_symbolic,Scalar());
237c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      if(m_numeric)
238c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        umfpack_free_numeric(&m_numeric,Scalar());
239c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
240c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      grapInput(matrix);
241c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
242c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      int errorCode = 0;
243c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      errorCode = umfpack_symbolic(matrix.rows(), matrix.cols(), m_outerIndexPtr, m_innerIndexPtr, m_valuePtr,
244c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                                   &m_symbolic, 0, 0);
245c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
246c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      m_isInitialized = true;
247c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      m_info = errorCode ? InvalidInput : Success;
248c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      m_analysisIsOk = true;
249c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      m_factorizationIsOk = false;
250c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
251c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
252c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    /** Performs a numeric decomposition of \a matrix
253c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      *
254c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * The given matrix must has the same sparcity than the matrix on which the pattern anylysis has been performed.
255c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      *
256c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * \sa analyzePattern(), compute()
257c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      */
258c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    void factorize(const MatrixType& matrix)
259c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
260c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      eigen_assert(m_analysisIsOk && "UmfPackLU: you must first call analyzePattern()");
261c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      if(m_numeric)
262c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        umfpack_free_numeric(&m_numeric,Scalar());
263c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
264c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      grapInput(matrix);
265c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
266c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      int errorCode;
267c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      errorCode = umfpack_numeric(m_outerIndexPtr, m_innerIndexPtr, m_valuePtr,
268c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                                  m_symbolic, &m_numeric, 0, 0);
269c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
270c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      m_info = errorCode ? NumericalIssue : Success;
271c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      m_factorizationIsOk = true;
272c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
273c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
274c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    #ifndef EIGEN_PARSED_BY_DOXYGEN
275c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    /** \internal */
276c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    template<typename BDerived,typename XDerived>
277c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    bool _solve(const MatrixBase<BDerived> &b, MatrixBase<XDerived> &x) const;
278c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    #endif
279c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
280c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    Scalar determinant() const;
281c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
282c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    void extractData() const;
283c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
284c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  protected:
285c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
286c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
287c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    void init()
288c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
289c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      m_info = InvalidInput;
290c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      m_isInitialized = false;
291c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      m_numeric = 0;
292c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      m_symbolic = 0;
293c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      m_outerIndexPtr = 0;
294c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      m_innerIndexPtr = 0;
295c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      m_valuePtr      = 0;
296c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
297c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
298c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    void grapInput(const MatrixType& mat)
299c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
300c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      m_copyMatrix.resize(mat.rows(), mat.cols());
301c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      if( ((MatrixType::Flags&RowMajorBit)==RowMajorBit) || sizeof(typename MatrixType::Index)!=sizeof(int) || !mat.isCompressed() )
302c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      {
303c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        // non supported input -> copy
304c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        m_copyMatrix = mat;
305c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        m_outerIndexPtr = m_copyMatrix.outerIndexPtr();
306c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        m_innerIndexPtr = m_copyMatrix.innerIndexPtr();
307c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        m_valuePtr      = m_copyMatrix.valuePtr();
308c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      }
309c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      else
310c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      {
311c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        m_outerIndexPtr = mat.outerIndexPtr();
312c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        m_innerIndexPtr = mat.innerIndexPtr();
313c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        m_valuePtr      = mat.valuePtr();
314c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      }
315c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
316c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
317c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    // cached data to reduce reallocation, etc.
318c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    mutable LUMatrixType m_l;
319c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    mutable LUMatrixType m_u;
320c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    mutable IntColVectorType m_p;
321c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    mutable IntRowVectorType m_q;
322c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
323c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    UmfpackMatrixType m_copyMatrix;
324c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    const Scalar* m_valuePtr;
325c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    const int* m_outerIndexPtr;
326c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    const int* m_innerIndexPtr;
327c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    void* m_numeric;
328c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    void* m_symbolic;
329c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
330c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    mutable ComputationInfo m_info;
331c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    bool m_isInitialized;
332c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    int m_factorizationIsOk;
333c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    int m_analysisIsOk;
334c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    mutable bool m_extractedDataAreDirty;
335c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
336c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  private:
337c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    UmfPackLU(UmfPackLU& ) { }
338c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
339c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
340c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
341c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename MatrixType>
342c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathvoid UmfPackLU<MatrixType>::extractData() const
343c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
344c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  if (m_extractedDataAreDirty)
345c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
346c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    // get size of the data
347c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    int lnz, unz, rows, cols, nz_udiag;
348c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    umfpack_get_lunz(&lnz, &unz, &rows, &cols, &nz_udiag, m_numeric, Scalar());
349c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
350c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    // allocate data
351c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    m_l.resize(rows,(std::min)(rows,cols));
352c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    m_l.resizeNonZeros(lnz);
353c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
354c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    m_u.resize((std::min)(rows,cols),cols);
355c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    m_u.resizeNonZeros(unz);
356c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
357c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    m_p.resize(rows);
358c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    m_q.resize(cols);
359c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
360c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    // extract
361c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    umfpack_get_numeric(m_l.outerIndexPtr(), m_l.innerIndexPtr(), m_l.valuePtr(),
362c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                        m_u.outerIndexPtr(), m_u.innerIndexPtr(), m_u.valuePtr(),
363c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                        m_p.data(), m_q.data(), 0, 0, 0, m_numeric);
364c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
365c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    m_extractedDataAreDirty = false;
366c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
367c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
368c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
369c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename MatrixType>
370c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtypename UmfPackLU<MatrixType>::Scalar UmfPackLU<MatrixType>::determinant() const
371c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
372c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  Scalar det;
373c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  umfpack_get_determinant(&det, 0, m_numeric, 0);
374c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  return det;
375c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
376c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
377c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename MatrixType>
378c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename BDerived,typename XDerived>
379c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathbool UmfPackLU<MatrixType>::_solve(const MatrixBase<BDerived> &b, MatrixBase<XDerived> &x) const
380c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
381c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  const int rhsCols = b.cols();
382c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  eigen_assert((BDerived::Flags&RowMajorBit)==0 && "UmfPackLU backend does not support non col-major rhs yet");
383c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  eigen_assert((XDerived::Flags&RowMajorBit)==0 && "UmfPackLU backend does not support non col-major result yet");
384c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
385c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  int errorCode;
386c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  for (int j=0; j<rhsCols; ++j)
387c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
388c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    errorCode = umfpack_solve(UMFPACK_A,
389c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        m_outerIndexPtr, m_innerIndexPtr, m_valuePtr,
390c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        &x.col(j).coeffRef(0), &b.const_cast_derived().col(j).coeffRef(0), m_numeric, 0, 0);
391c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    if (errorCode!=0)
392c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      return false;
393c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
394c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
395c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  return true;
396c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
397c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
398c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
399c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathnamespace internal {
400c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
401c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename _MatrixType, typename Rhs>
402c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct solve_retval<UmfPackLU<_MatrixType>, Rhs>
403c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  : solve_retval_base<UmfPackLU<_MatrixType>, Rhs>
404c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
405c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef UmfPackLU<_MatrixType> Dec;
406c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  EIGEN_MAKE_SOLVE_HELPERS(Dec,Rhs)
407c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
408c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  template<typename Dest> void evalTo(Dest& dst) const
409c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
410c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    dec()._solve(rhs(),dst);
411c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
412c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
413c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
414c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename _MatrixType, typename Rhs>
415c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct sparse_solve_retval<UmfPackLU<_MatrixType>, Rhs>
416c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  : sparse_solve_retval_base<UmfPackLU<_MatrixType>, Rhs>
417c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
418c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef UmfPackLU<_MatrixType> Dec;
419c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  EIGEN_MAKE_SPARSE_SOLVE_HELPERS(Dec,Rhs)
420c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
421c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  template<typename Dest> void evalTo(Dest& dst) const
422c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
423c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    dec()._solve(rhs(),dst);
424c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
425c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
426c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
427c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} // end namespace internal
428c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
429c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} // end namespace Eigen
430c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
431c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#endif // EIGEN_UMFPACKSUPPORT_H
432