sparse_lu.cpp
Go to the documentation of this file.
00001 // This file is part of Eigen, a lightweight C++ template library
00002 // for linear algebra.
00003 //
00004 // Copyright (C) 2008-2010 Gael Guennebaud <g.gael@free.fr>
00005 //
00006 // Eigen is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 3 of the License, or (at your option) any later version.
00010 //
00011 // Alternatively, you can redistribute it and/or
00012 // modify it under the terms of the GNU General Public License as
00013 // published by the Free Software Foundation; either version 2 of
00014 // the License, or (at your option) any later version.
00015 //
00016 // Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
00017 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00018 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
00019 // GNU General Public License for more details.
00020 //
00021 // You should have received a copy of the GNU Lesser General Public
00022 // License and a copy of the GNU General Public License along with
00023 // Eigen. If not, see <http://www.gnu.org/licenses/>.
00024 
00025 #include "sparse.h"
00026 #include <Eigen/SparseExtra>
00027 
00028 #ifdef EIGEN_UMFPACK_SUPPORT
00029 #include <Eigen/UmfPackSupport>
00030 #endif
00031 
00032 #ifdef EIGEN_SUPERLU_SUPPORT
00033 #include <Eigen/SuperLUSupport>
00034 #endif
00035 
00036 template<typename Scalar> void sparse_lu(int rows, int cols)
00037 {
00038   double density = std::max(8./(rows*cols), 0.01);
00039   typedef Matrix<Scalar,Dynamic,Dynamic> DenseMatrix;
00040   typedef Matrix<Scalar,Dynamic,1> DenseVector;
00041 
00042   DenseVector vec1 = DenseVector::Random(rows);
00043 
00044   std::vector<Vector2i> zeroCoords;
00045   std::vector<Vector2i> nonzeroCoords;
00046 
00047     SparseMatrix<Scalar> m2(rows, cols);
00048     DenseMatrix refMat2(rows, cols);
00049 
00050     DenseVector b = DenseVector::Random(cols);
00051     DenseVector refX(cols), x(cols);
00052 
00053     initSparse<Scalar>(density, refMat2, m2, ForceNonZeroDiag, &zeroCoords, &nonzeroCoords);
00054 
00055     FullPivLU<DenseMatrix> refLu(refMat2);
00056     refX = refLu.solve(b);
00057     #if defined(EIGEN_SUPERLU_SUPPORT) || defined(EIGEN_UMFPACK_SUPPORT)
00058     Scalar refDet = refLu.determinant();
00059     #endif
00060     x.setZero();
00061     // // SparseLU<SparseMatrix<Scalar> > (m2).solve(b,&x);
00062     // // VERIFY(refX.isApprox(x,test_precision<Scalar>()) && "LU: default");
00063     
00064     #ifdef EIGEN_UMFPACK_SUPPORT
00065     {
00066       // check solve
00067       x.setZero();
00068       SparseLU<SparseMatrix<Scalar>,UmfPack> lu(m2);
00069       VERIFY(lu.succeeded() && "umfpack LU decomposition failed");
00070       VERIFY(lu.solve(b,&x) && "umfpack LU solving failed");
00071       VERIFY(refX.isApprox(x,test_precision<Scalar>()) && "LU: umfpack");
00072       VERIFY_IS_APPROX(refDet,lu.determinant());
00073         // TODO check the extracted data
00074         //std::cerr << slu.matrixL() << "\n";
00075     }
00076     #endif
00077     
00078     #ifdef EIGEN_SUPERLU_SUPPORT
00079     {
00080       x.setZero();
00081       SparseLU<SparseMatrix<Scalar>,SuperLU> slu(m2);
00082       if (slu.succeeded())
00083       {
00084         if (slu.solve(b,&x)) {
00085           VERIFY(refX.isApprox(x,test_precision<Scalar>()) && "LU: SuperLU");
00086         }
00087         // std::cerr << refDet << " == " << slu.determinant() << "\n";
00088         if (slu.solve(b, &x, SvTranspose)) {
00089           VERIFY(b.isApprox(m2.transpose() * x, test_precision<Scalar>()));
00090         }
00091 
00092         if (slu.solve(b, &x, SvAdjoint)) {
00093          VERIFY(b.isApprox(m2.adjoint() * x, test_precision<Scalar>()));
00094         }
00095 
00096         if (!NumTraits<Scalar>::IsComplex) {
00097           VERIFY_IS_APPROX(refDet,slu.determinant()); // FIXME det is not very stable for complex
00098         }
00099       }
00100     }
00101     #endif
00102     
00103 }
00104 
00105 void test_sparse_lu()
00106 {
00107   for(int i = 0; i < g_repeat; i++) {
00108     CALL_SUBTEST_1(sparse_lu<double>(8, 8) );
00109     int s = internal::random<int>(1,300);
00110     CALL_SUBTEST_2(sparse_lu<std::complex<double> >(s,s) );
00111     CALL_SUBTEST_1(sparse_lu<double>(s,s) );
00112   }
00113 }


re_vision
Author(s): Dorian Galvez-Lopez
autogenerated on Sun Jan 5 2014 11:32:45