sparse_solvers.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 <gael.guennebaud@inria.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 
00027 template<typename Scalar> void
00028 initSPD(double density,
00029         Matrix<Scalar,Dynamic,Dynamic>& refMat,
00030         SparseMatrix<Scalar>& sparseMat)
00031 {
00032   Matrix<Scalar,Dynamic,Dynamic> aux(refMat.rows(),refMat.cols());
00033   initSparse(density,refMat,sparseMat);
00034   refMat = refMat * refMat.adjoint();
00035   for (int k=0; k<2; ++k)
00036   {
00037     initSparse(density,aux,sparseMat,ForceNonZeroDiag);
00038     refMat += aux * aux.adjoint();
00039   }
00040   sparseMat.setZero();
00041   for (int j=0 ; j<sparseMat.cols(); ++j)
00042     for (int i=j ; i<sparseMat.rows(); ++i)
00043       if (refMat(i,j)!=Scalar(0))
00044         sparseMat.insert(i,j) = refMat(i,j);
00045   sparseMat.finalize();
00046 }
00047 
00048 template<typename Scalar> void sparse_solvers(int rows, int cols)
00049 {
00050   double density = std::max(8./(rows*cols), 0.01);
00051   typedef Matrix<Scalar,Dynamic,Dynamic> DenseMatrix;
00052   typedef Matrix<Scalar,Dynamic,1> DenseVector;
00053   // Scalar eps = 1e-6;
00054 
00055   DenseVector vec1 = DenseVector::Random(rows);
00056 
00057   std::vector<Vector2i> zeroCoords;
00058   std::vector<Vector2i> nonzeroCoords;
00059 
00060   // test triangular solver
00061   {
00062     DenseVector vec2 = vec1, vec3 = vec1;
00063     SparseMatrix<Scalar> m2(rows, cols);
00064     DenseMatrix refMat2 = DenseMatrix::Zero(rows, cols);
00065 
00066     // lower - dense
00067     initSparse<Scalar>(density, refMat2, m2, ForceNonZeroDiag|MakeLowerTriangular, &zeroCoords, &nonzeroCoords);
00068     VERIFY_IS_APPROX(refMat2.template triangularView<Lower>().solve(vec2),
00069                      m2.template triangularView<Lower>().solve(vec3));
00070 
00071     // upper - dense
00072     initSparse<Scalar>(density, refMat2, m2, ForceNonZeroDiag|MakeUpperTriangular, &zeroCoords, &nonzeroCoords);
00073     VERIFY_IS_APPROX(refMat2.template triangularView<Upper>().solve(vec2),
00074                      m2.template triangularView<Upper>().solve(vec3));
00075 
00076     // lower - transpose
00077     initSparse<Scalar>(density, refMat2, m2, ForceNonZeroDiag|MakeLowerTriangular, &zeroCoords, &nonzeroCoords);
00078     VERIFY_IS_APPROX(refMat2.transpose().template triangularView<Upper>().solve(vec2),
00079                      m2.transpose().template triangularView<Upper>().solve(vec3));
00080 
00081     // upper - transpose
00082     initSparse<Scalar>(density, refMat2, m2, ForceNonZeroDiag|MakeUpperTriangular, &zeroCoords, &nonzeroCoords);
00083     VERIFY_IS_APPROX(refMat2.transpose().template triangularView<Lower>().solve(vec2),
00084                      m2.transpose().template triangularView<Lower>().solve(vec3));
00085 
00086     SparseMatrix<Scalar> matB(rows, rows);
00087     DenseMatrix refMatB = DenseMatrix::Zero(rows, rows);
00088 
00089     // lower - sparse
00090     initSparse<Scalar>(density, refMat2, m2, ForceNonZeroDiag|MakeLowerTriangular);
00091     initSparse<Scalar>(density, refMatB, matB);
00092     refMat2.template triangularView<Lower>().solveInPlace(refMatB);
00093     m2.template triangularView<Lower>().solveInPlace(matB);
00094     VERIFY_IS_APPROX(matB.toDense(), refMatB);
00095 
00096     // upper - sparse
00097     initSparse<Scalar>(density, refMat2, m2, ForceNonZeroDiag|MakeUpperTriangular);
00098     initSparse<Scalar>(density, refMatB, matB);
00099     refMat2.template triangularView<Upper>().solveInPlace(refMatB);
00100     m2.template triangularView<Upper>().solveInPlace(matB);
00101     VERIFY_IS_APPROX(matB, refMatB);
00102 
00103     // test deprecated API
00104     initSparse<Scalar>(density, refMat2, m2, ForceNonZeroDiag|MakeLowerTriangular, &zeroCoords, &nonzeroCoords);
00105     VERIFY_IS_APPROX(refMat2.template triangularView<Lower>().solve(vec2),
00106                      m2.template triangularView<Lower>().solve(vec3));
00107   }
00108 }
00109 
00110 void test_sparse_solvers()
00111 {
00112   for(int i = 0; i < g_repeat; i++) {
00113     CALL_SUBTEST_1(sparse_solvers<double>(8, 8) );
00114     int s = internal::random<int>(1,300);
00115     CALL_SUBTEST_2(sparse_solvers<std::complex<double> >(s,s) );
00116     CALL_SUBTEST_1(sparse_solvers<double>(s,s) );
00117   }
00118 }


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