From d65c8cb60acd34a0eb898194713ff45e604de0fe Mon Sep 17 00:00:00 2001 From: Gael Guennebaud Date: Wed, 23 Dec 2009 11:48:53 +0100 Subject: fix #69 and extend unit tests or triangular solvers --- test/product_trsolve.cpp | 89 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 test/product_trsolve.cpp (limited to 'test/product_trsolve.cpp') diff --git a/test/product_trsolve.cpp b/test/product_trsolve.cpp new file mode 100644 index 000000000..449240f7c --- /dev/null +++ b/test/product_trsolve.cpp @@ -0,0 +1,89 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2008-2009 Gael Guennebaud +// +// Eigen is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 3 of the License, or (at your option) any later version. +// +// Alternatively, you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of +// the License, or (at your option) any later version. +// +// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License and a copy of the GNU General Public License along with +// Eigen. If not, see . + +#include "main.h" + +#define VERIFY_TRSM(TRI,XB) { \ + (XB).setRandom(); ref = (XB); \ + (TRI).solveInPlace(XB); \ + VERIFY_IS_APPROX((TRI).toDenseMatrix() * (XB), ref); \ + } + +#define VERIFY_TRSM_ONTHERIGHT(TRI,XB) { \ + (XB).setRandom(); ref = (XB); \ + (TRI).transpose().template solveInPlace(XB.transpose()); \ + VERIFY_IS_APPROX((XB).transpose() * (TRI).transpose().toDenseMatrix(), ref.transpose()); \ + } + +template void trsolve(int size=Size,int cols=Cols) +{ + typedef typename NumTraits::Real RealScalar; + + Matrix cmLhs(size,size); + Matrix rmLhs(size,size); + + Matrix cmRhs(size,cols), ref(size,cols); + Matrix rmRhs(size,cols); + + cmLhs.setRandom(); cmLhs *= static_cast(0.1); cmLhs.diagonal().cwise() += static_cast(1); + rmLhs.setRandom(); rmLhs *= static_cast(0.1); rmLhs.diagonal().cwise() += static_cast(1); + + VERIFY_TRSM(cmLhs.conjugate().template triangularView(), cmRhs); + VERIFY_TRSM(cmLhs .template triangularView(), cmRhs); + VERIFY_TRSM(cmLhs .template triangularView(), rmRhs); + VERIFY_TRSM(cmLhs.conjugate().template triangularView(), rmRhs); + + VERIFY_TRSM(cmLhs.conjugate().template triangularView(), cmRhs); + VERIFY_TRSM(cmLhs .template triangularView(), rmRhs); + + VERIFY_TRSM(rmLhs .template triangularView(), cmRhs); + VERIFY_TRSM(rmLhs.conjugate().template triangularView(), rmRhs); + + + VERIFY_TRSM_ONTHERIGHT(cmLhs.conjugate().template triangularView(), cmRhs); + VERIFY_TRSM_ONTHERIGHT(cmLhs .template triangularView(), cmRhs); + VERIFY_TRSM_ONTHERIGHT(cmLhs .template triangularView(), rmRhs); + VERIFY_TRSM_ONTHERIGHT(cmLhs.conjugate().template triangularView(), rmRhs); + + VERIFY_TRSM_ONTHERIGHT(cmLhs.conjugate().template triangularView(), cmRhs); + VERIFY_TRSM_ONTHERIGHT(cmLhs .template triangularView(), rmRhs); + + VERIFY_TRSM_ONTHERIGHT(rmLhs .template triangularView(), cmRhs); + VERIFY_TRSM_ONTHERIGHT(rmLhs.conjugate().template triangularView(), rmRhs); +} + +void test_product_trsolve() +{ + for(int i = 0; i < g_repeat ; i++) + { + // matrices + CALL_SUBTEST_1((trsolve(ei_random(1,320),ei_random(1,320)))); + CALL_SUBTEST_2((trsolve,Dynamic,Dynamic>(ei_random(1,320),ei_random(1,320)))); + + // vectors + CALL_SUBTEST_3((trsolve,Dynamic,1>(ei_random(1,320)))); + CALL_SUBTEST_4((trsolve())); + CALL_SUBTEST_5((trsolve,4,1>())); + } +} -- cgit v1.2.3 From 826bff58c68273d1d0088898c1f54a01c9a94b04 Mon Sep 17 00:00:00 2001 From: Gael Guennebaud Date: Mon, 4 Jan 2010 17:36:26 +0100 Subject: Fix #69 for the second time, and add the respective regression test --- Eigen/src/Core/SolveTriangular.h | 22 ++++++++++++++++++---- test/product_trsolve.cpp | 3 ++- 2 files changed, 20 insertions(+), 5 deletions(-) (limited to 'test/product_trsolve.cpp') diff --git a/Eigen/src/Core/SolveTriangular.h b/Eigen/src/Core/SolveTriangular.h index 15717a120..9c4a49c3c 100644 --- a/Eigen/src/Core/SolveTriangular.h +++ b/Eigen/src/Core/SolveTriangular.h @@ -25,13 +25,27 @@ #ifndef EIGEN_SOLVETRIANGULAR_H #define EIGEN_SOLVETRIANGULAR_H +template +class ei_trsolve_traits +{ + private: + enum { + RhsIsVectorAtCompileTime = (Side==OnTheLeft ? Rhs::ColsAtCompileTime : Rhs::RowsAtCompileTime)==1 + }; + public: + enum { + Unrolling = (RhsIsVectorAtCompileTime && Rhs::SizeAtCompileTime <= 8) + ? CompleteUnrolling : NoUnrolling, + RhsVectors = RhsIsVectorAtCompileTime ? 1 : Dynamic + }; +}; + template::Unrolling, int StorageOrder = (int(Lhs::Flags) & RowMajorBit) ? RowMajor : ColMajor, - int RhsVectors = Rhs::IsVectorAtCompileTime ? 1 : Dynamic + int RhsVectors = ei_trsolve_traits::RhsVectors > struct ei_triangular_solver_selector; diff --git a/test/product_trsolve.cpp b/test/product_trsolve.cpp index 449240f7c..66e263862 100644 --- a/test/product_trsolve.cpp +++ b/test/product_trsolve.cpp @@ -84,6 +84,7 @@ void test_product_trsolve() // vectors CALL_SUBTEST_3((trsolve,Dynamic,1>(ei_random(1,320)))); CALL_SUBTEST_4((trsolve())); - CALL_SUBTEST_5((trsolve,4,1>())); + CALL_SUBTEST_5((trsolve())); + CALL_SUBTEST_6((trsolve,4,1>())); } } -- cgit v1.2.3