/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2005 Klaus Spanderen This file is part of QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ QuantLib is free software: you can redistribute it and/or modify it under the terms of the QuantLib license. You should have received a copy of the license along with this program; if not, please email . The license is also available online at . This program 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 license for more details. */ #include "tqreigendecomposition.hpp" #include "utilities.hpp" #include using namespace QuantLib; using namespace boost::unit_test_framework; QL_BEGIN_TEST_LOCALS(TqrEigenDecompositionTest) Real tolerance = 1.0e-10; QL_END_TEST_LOCALS(TqrEigenDecompositionTest) void TqrEigenDecompositionTest::testEigenValueDecomposition() { BOOST_MESSAGE("Testing TQR eigenvalue decomposition..."); Array diag(5); Array sub(4,1); diag[0]=11; diag[1]=7; diag[2]=6; diag[3]=2; diag[4]=0; Real ev[5] = {11.2467832217139119, 7.4854967362908535, 5.5251516080277518, 2.1811760273123308, -0.4386075933448487}; TqrEigenDecomposition tqre(diag, sub, TqrEigenDecomposition::WithoutEigenVector); for (Size i=0; i < diag.size(); ++i) { const Real expected(ev[i]); const Real calculated(tqre.eigenvalues()[i]); if (std::fabs(expected-calculated) > tolerance) { BOOST_FAIL(std::string("wrong eigenvalue \n") << "calculated: " << calculated <<" expected : " << expected); } } } void TqrEigenDecompositionTest::testZeroOffDiagEigenValues() { BOOST_MESSAGE("Testing TQR zero-off-diagonal eigenvalues..."); Array diag(5); Array sub(4,1); sub[0] =sub[2]=0; diag[0]=12; diag[1]=9; diag[2]=6; diag[3]=3; diag[4]=0; TqrEigenDecomposition tqre1(diag, sub); sub[0]=sub[2]=1e-14; TqrEigenDecomposition tqre2(diag, sub); for (Size i=0; i < diag.size(); ++i) { const Real expected(tqre2.eigenvalues()[i]); const Real calculated(tqre1.eigenvalues()[i]); if (std::fabs(expected-calculated) > tolerance) { BOOST_FAIL(std::string("wrong eigenvalue \n") << "calculated: " << calculated << " expected : " << expected); } } } void TqrEigenDecompositionTest::testEigenVectorDecomposition() { BOOST_MESSAGE("Testing TQR eigenvector decomposition..."); Array diag(2,1); Array sub(1,1); TqrEigenDecomposition tqre(diag, sub); if (std::fabs(0.25 + tqre.eigenvectors()[0][0] * tqre.eigenvectors()[0][1] * tqre.eigenvectors()[1][0] * tqre.eigenvectors()[1][1]) > tolerance) { BOOST_FAIL("wrong eigenvector"); } } test_suite* TqrEigenDecompositionTest::suite() { test_suite* suite = BOOST_TEST_SUITE("TQR eigendecomposition tests"); suite->add(BOOST_TEST_CASE( &TqrEigenDecompositionTest::testEigenValueDecomposition)); suite->add(BOOST_TEST_CASE( &TqrEigenDecompositionTest::testZeroOffDiagEigenValues)); suite->add(BOOST_TEST_CASE( &TqrEigenDecompositionTest::testEigenVectorDecomposition)); return suite; }