Exemplo n.º 1
0
void
TestMatrix::runSubTest8(double& res, double& expected, std::string& subTestName)
{
    expected = 1;
    subTestName = "simple_invert";

#ifdef COSMO_LAPACK
    Math::Matrix<double> mat(2, 2);
    mat(0, 0) = 1;
    mat(0, 1) = 2;
    mat(1, 0) = 3;
    mat(1, 1) = 4;

    mat.writeIntoTextFile("test_files/matrix_test_8_original.txt");

    Math::Matrix<double> invMat;
    mat.getInverse(&invMat);

    invMat.writeIntoTextFile("test_files/matrix_test_8_inverse.txt");

    Math::Matrix<double> prod = invMat * mat;
    prod.writeIntoTextFile("test_files/matrix_test_8_product.txt");

    res = 1;
    for(int i = 0; i < prod.rows(); ++i)
    {
        for(int j = 0; j < prod.cols(); ++j)
        {
            if(i == j)
            {
                if(!Math::areEqual(prod(i, j), 1.0, 1e-5))
                {
                    output_screen("FAIL! Diagonal element " << i << " must be 1 but it is " << prod(i, j) << std::endl);
                    res = 0;
                }
            }
            else
            {
                if(!Math::areEqual(prod(i, j), 0.0, 1e-5))
                {
                    output_screen("FAIL! Non-diagonal element " << i << " " << j << " must be 0 but it is " << prod(i, j) << std::endl);
                    res = 0;
                }
            }
        }
    }
#else
    output_screen_clean("This test (below) is skipped because Cosmo++ has not been linked to lapack" << std::endl);
    res = 1;
#endif
}
Exemplo n.º 2
0
void
TestMatrix::runSubTestEigen(double& res, double& expected, std::string& subTestName, bool pd)
{
    subTestName = "simple_symmetric_eigen";
    if(pd)
        subTestName = "simple_symmetric_positive_eigen";

#ifdef COSMO_LAPACK
    Math::SymmetricMatrix<double> mat(3, 3);
    mat(0, 0) = 3;
    mat(1, 1) = 10;
    mat(2, 2) = 4;
    mat(0, 2) = 2;

    std::vector<double> eigenvals;
    Math::Matrix<double> eigenvecs;

    const int info = mat.getEigen(&eigenvals, &eigenvecs, pd);
    if(info)
    {
        output_screen_clean("FAIL! Eigenvalue/eigenvector decomposition failed. Info = " << info << std::endl);
        res = 0;
        return;
    }

    //output_screen_clean("Eigenvalues: " << eigenvals[0] << ", " << eigenvals[1] << ", " << eigenvals[2] << std::endl);

    if(pd)
        eigenvecs.writeIntoTextFile("test_files/matrix_test_eigenvecs.txt");
    else
        eigenvecs.writeIntoTextFile("test_files/matrix_test_eigenvecs_pos.txt");

    res = 1;
    expected = 1;

    Math::Matrix<double> m = mat;

    for(int i = 0; i < 3; ++i)
    {
        Math::Matrix<double> v = eigenvecs.getCol(i);
        Math::Matrix<double> prod = m * v;
        for(int j = 0; j < 3; ++j)
        {
            if(!Math::areEqual(prod(j, 0), eigenvals[i] * v(j, 0), 1e-5))
            {
                output_screen_clean("FAIL! The eigenvalue " << i << " times the eigenvector doesn't match the matrix times the eigenvector." << std::endl);
                output_screen_clean("\tLooking at index " << j << ", expected " << eigenvals[i] * v(j, 0) << " obtained " << prod(j, 0) << std::endl);
                res = 0;
            }
        }
    }

    Math::Matrix<double> diag = eigenvecs.getTranspose() * mat * eigenvecs;

    for(int i = 0; i < 3; ++i)
    {
        for(int j = 0; j < 3; ++j)
        {
            if(i == j)
            {
                if(!Math::areEqual(diag(i, i), eigenvals[i], 1e-5))
                {
                    output_screen_clean("FAIL! The diagonalized matrix has " << diag(i, i) << " on the diagonal at index " << i << " but the corresponding eigenvalue is " << eigenvals[i] << std::endl);
                    res = 0;
                }
            }
            else
            {
                if(!Math::areEqual(diag(i, j), 0.0, 1e-5))
                {
                    output_screen_clean("FAIL! The diagonalized matrix has " << diag(i, j) << " as the off-diagonal element (" << i << ", " << j << "). Must be 0." << std::endl);
                    res = 0;
                }
            }
        }
    }

#else
    output_screen_clean("This test (below) is skipped because Cosmo++ has not been linked to lapack" << std::endl);
    res = 1;
    expected = 1;
#endif
}