//This file is part of Bertini 2.
//
//eigen_test.cpp is free software: 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 3 of the License, or
//(at your option) any later version.
//
//eigen_test.cpp 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 General Public License for more details.
//
//You should have received a copy of the GNU General Public License
//along with eigen_test.cpp. If not, see .
//
// Copyright(C) 2015 - 2021 by Bertini2 Development Team
//
// See for a copy of the license,
// as well as COPYING. Bertini2 is provided with permitted
// additional terms in the b2/licenses/ directory.
// individual authors of this file include:
// silviana amethyst, university of wisconsin eau claire
#include
#include "bertini2/eigen_extensions.hpp"
#include
#include
#include "externs.hpp"
BOOST_AUTO_TEST_SUITE(num_traits_checking)
using mpfr_float = bertini::mpfr_float;
// this test assures that the Eigen::NumTraits defined in eigen_extensions.hpp is correctly found during template instantiation, and that the Real type it defines is actually mpfr_float. If it were not, then we would be unable to make an expression of ::Real type in variable q, because it would be an expression, not a populatable number of type mpfr_float.
BOOST_AUTO_TEST_CASE(expressions_of_mpfr_floats)
{
using NumT = bertini::mpfr_float;
NumT a {1}, b{2}, c{3};
Eigen::NumTraits::Real q{0};
}
BOOST_AUTO_TEST_CASE(size_object_sensible_vec)
{
bertini::Vec v(3);
BOOST_CHECK_EQUAL(v.rows(),3);
BOOST_CHECK_EQUAL(v.cols(),1);
BOOST_CHECK(!bertini::IsEmpty(v));
}
BOOST_AUTO_TEST_CASE(size_object_sensible_mat)
{
bertini::Mat v(3,4);
BOOST_CHECK_EQUAL(v.rows(),3);
BOOST_CHECK_EQUAL(v.cols(),4);
BOOST_CHECK(!bertini::IsEmpty(v));
}
BOOST_AUTO_TEST_SUITE_END()
BOOST_AUTO_TEST_SUITE(kahan_matrix_solving_LU)
using mpfr_float = bertini::mpfr_float;
using bertini::KahanMatrix;
BOOST_AUTO_TEST_CASE(solve_100x100_kahan_matrix_double) {
unsigned int size = 10;
srand(2); rand();
Eigen::Matrix A = KahanMatrix(size, 0.285), B(size,size), C;
for (int ii=0; ii A =
KahanMatrix(size, bertini::mpfr_float(0.285)), B(size,size), C;
for (int ii=0; ii;
bertini::DefaultPrecision(100);
mpfr_matrix A = KahanMatrix(size, mpfr(0.285)), B(size,size), C;
for (int ii=0; ii, Eigen::Dynamic, Eigen::Dynamic> A =
KahanMatrix(size, std::complex(0.285)), B(size,size), C;
for (int ii=0; ii A =
KahanMatrix(size, bertini::mpfr_complex("0.285","0.0")), B(size,size), C;
for (int ii=0; ii::highest() << std::endl;
// std::cout << Eigen::NumTraits::lowest() << std::endl;
// std::cout << Eigen::NumTraits::dummy_precision() << std::endl;
// std::cout << Eigen::NumTraits::epsilon() << std::endl;
//
// }
BOOST_AUTO_TEST_CASE(eigen_partial_pivot_solve_singular_matrix)
{
Eigen::Matrix A(2,2), B(2,1);
A << 1, 1, 0, 0;
B << 0.5, 1;
auto LU = A.lu();
auto C = LU.solve(B);
}
BOOST_AUTO_TEST_CASE(eigen_partial_pivot_solve_near_singular_matrix_double)
{
Eigen::Matrix A(2,2), B(2,1);
A << 1, 1, 1e-20, 0;
B << 0.5, 1;
auto LU = A.lu();
auto C = LU.solve(B);
BOOST_CHECK(bertini::LUPartialPivotDecompositionSuccessful(LU.matrixLU())!=bertini::MatrixSuccessCode::Success);
}
BOOST_AUTO_TEST_CASE(small_value_double)
{
BOOST_CHECK( bertini::IsSmallValue(std::complex(1e-15,0)));
BOOST_CHECK( bertini::IsSmallValue(std::complex(1e-14,0)));
BOOST_CHECK( bertini::IsSmallValue(std::complex(-1e-15,0)));
BOOST_CHECK( bertini::IsSmallValue(std::complex(-1e-14,0)));
BOOST_CHECK(!bertini::IsSmallValue(std::complex(1e-10,0)));
BOOST_CHECK(!bertini::IsSmallValue(std::complex(1e2,0)));
BOOST_CHECK(!bertini::IsSmallValue(std::complex(-1e-10,0)));
BOOST_CHECK(!bertini::IsSmallValue(std::complex(-1e2,0)));
}
BOOST_AUTO_TEST_CASE(large_change_double)
{
BOOST_CHECK(bertini::IsLargeChange(1.0,1e-12));
BOOST_CHECK(bertini::IsLargeChange(1e5,1e-7));
BOOST_CHECK(!bertini::IsLargeChange(1e3,1e-4));
BOOST_CHECK(!bertini::IsLargeChange(1e-15,1e-18));
}
BOOST_AUTO_TEST_CASE(small_value_multiprecision)
{
bertini::DefaultPrecision(30);
bertini::mpfr_float p = pow(mpfr_float(10),-mpfr_float(30));
BOOST_CHECK( bertini::IsSmallValue(bertini::mpfr_complex(p,mpfr_float(0))));
BOOST_CHECK( bertini::IsSmallValue(bertini::mpfr_complex(-p,mpfr_float(0))));
BOOST_CHECK(!bertini::IsSmallValue(bertini::mpfr_complex(1e-15,0.0)));
BOOST_CHECK(!bertini::IsSmallValue(bertini::mpfr_complex(1e-14,0.0)));
BOOST_CHECK(!bertini::IsSmallValue(bertini::mpfr_complex(1e-10,0.0)));
BOOST_CHECK(!bertini::IsSmallValue(bertini::mpfr_complex(1e2,0.0)));
BOOST_CHECK(!bertini::IsSmallValue(bertini::mpfr_complex(-1e-15,0.0)));
BOOST_CHECK(!bertini::IsSmallValue(bertini::mpfr_complex(-1e-14,0.0)));
BOOST_CHECK(!bertini::IsSmallValue(bertini::mpfr_complex(-1e-10,0.0)));
BOOST_CHECK(!bertini::IsSmallValue(bertini::mpfr_complex(-1e2,0.0)));
}
BOOST_AUTO_TEST_CASE(large_change_multiprecision)
{
bertini::DefaultPrecision(30);
bertini::mpfr_float p = pow(mpfr_float(10),-mpfr_float(30));
BOOST_CHECK( bertini::IsLargeChange(mpfr_float(1.0),p));
BOOST_CHECK( bertini::IsLargeChange(mpfr_float(1e16),mpfr_float(p*mpfr_float(1e16))));
BOOST_CHECK( bertini::IsLargeChange(mpfr_float(-1e16),mpfr_float(p*mpfr_float(1e16))));
BOOST_CHECK( bertini::IsLargeChange(mpfr_float(1e16),mpfr_float(-p*mpfr_float(1e16))));
BOOST_CHECK(!bertini::IsLargeChange(mpfr_float(1.0),mpfr_float(1e-12)));
BOOST_CHECK(!bertini::IsLargeChange(mpfr_float(-1.0),mpfr_float(1e-12)));
BOOST_CHECK(!bertini::IsLargeChange(mpfr_float(1e5),mpfr_float(1e-7)));
BOOST_CHECK(!bertini::IsLargeChange(mpfr_float(1e3),mpfr_float(1e-4)));
BOOST_CHECK(!bertini::IsLargeChange(mpfr_float(1e-15),mpfr_float(1e-18)));
}
BOOST_AUTO_TEST_CASE(eigen_LU_partial_pivot_3x3)
{
Eigen::Matrix A(3,3);
A << 0.000000010000000, 1.000000000000000, 1.000000000000000,
0 , 1.000000000000000 , 1.000000000000000,
1.000000000000000 ,1.000000000000000 , 0;
auto LU = A.lu();
BOOST_CHECK(bertini::LUPartialPivotDecompositionSuccessful(LU.matrixLU())==bertini::MatrixSuccessCode::Success);
}
BOOST_AUTO_TEST_CASE(eigen_norm_of_vector)
{
Eigen::Matrix A(1,3);
A << 1, 2, 3;
double n = A.norm();
}
BOOST_AUTO_TEST_CASE(dot_product_with_mpfr_type)
{
bertini::DefaultPrecision(CLASS_TEST_MPFR_DEFAULT_DIGITS);
using data_type = bertini::mpfr_complex;
Eigen::Matrix v(data_type(2),data_type(4),data_type(3));
Eigen::Matrix w(data_type(1),data_type(2),data_type(-1));
data_type result = v.dot(w);
data_type exact(7);
BOOST_CHECK_EQUAL(result, exact);
}
BOOST_AUTO_TEST_CASE(svd_with_mpfr_type)
{
bertini::DefaultPrecision(CLASS_TEST_MPFR_DEFAULT_DIGITS);
using data_type = bertini::mpfr_complex;
Eigen::Matrix A(2,2);
A << data_type(2), data_type(1), data_type(1), data_type(2);
// this breaks with boost multiprecision et_on with eigen 3.2.7.
Eigen::JacobiSVD> svd(A, Eigen::ComputeThinU | Eigen::ComputeThinV);
}
// scalar multiplication with various types
BOOST_AUTO_TEST_CASE(scalar_multiplication_mpfr_mpfr)
{
bertini::DefaultPrecision(CLASS_TEST_MPFR_DEFAULT_DIGITS);
using data_type = bertini::mpfr_complex;
Eigen::Matrix A(2,2);
A << data_type(2), data_type(1), data_type(1), data_type(2);
data_type a(1);
// this breaks with boost multiprecision et_on with eigen 3.2.7.
Eigen::Matrix B = a*A;
B = A*a;
}
BOOST_AUTO_TEST_CASE(scalar_multiplication_mpfr_int)
{
bertini::DefaultPrecision(CLASS_TEST_MPFR_DEFAULT_DIGITS);
using data_type = bertini::mpfr_complex;
data_type q(1);
int a(1);
auto b = a*q;
Eigen::Matrix A(2,2);
A << data_type(2), data_type(1), data_type(1), data_type(2);
Eigen::Matrix B = a*A;
B = A*a;
}
BOOST_AUTO_TEST_CASE(scalar_multiplication_mpfr_long)
{
bertini::DefaultPrecision(CLASS_TEST_MPFR_DEFAULT_DIGITS);
using data_type = bertini::mpfr_complex;
data_type q(1);
long a(1);
auto b = a*q;
Eigen::Matrix A(2,2);
A << data_type(2), data_type(1), data_type(1), data_type(2);
Eigen::Matrix B = a*A;
B = A*a;
}
BOOST_AUTO_TEST_CASE(scalar_multiplication_mpfr_mpz_int)
{
bertini::DefaultPrecision(CLASS_TEST_MPFR_DEFAULT_DIGITS);
using data_type = bertini::mpfr_complex;
data_type q(1);
bertini::mpz_int a(1);
auto b = a*q;
Eigen::Matrix A(2,2);
A << data_type(2), data_type(1), data_type(1), data_type(2);
Eigen::Matrix B = a*A;
B = A*a;
}
// self multiplication
BOOST_AUTO_TEST_CASE(self_multiplication_dbl_int)
{
using data_type = bertini::dbl;
Eigen::Matrix A(2,2);
A << data_type(2), data_type(1), data_type(1), data_type(2);
int a(1);
A*=a;
}
BOOST_AUTO_TEST_CASE(self_multiplication_mpfr_mpfr)
{
bertini::DefaultPrecision(CLASS_TEST_MPFR_DEFAULT_DIGITS);
using data_type = bertini::mpfr_complex;
Eigen::Matrix A(2,2);
A << data_type(2), data_type(1), data_type(1), data_type(2);
data_type a(1);
A*=a;
}
BOOST_AUTO_TEST_CASE(self_multiplication_mpfr_int)
{
bertini::DefaultPrecision(CLASS_TEST_MPFR_DEFAULT_DIGITS);
using data_type = bertini::mpfr_complex;
data_type q(1);
int a(1);
auto b = a*q;
Eigen::Matrix A(2,2);
A << data_type(2), data_type(1), data_type(1), data_type(2);
A*=a;
}
BOOST_AUTO_TEST_CASE(self_multiplication_mpfr_long)
{
bertini::DefaultPrecision(CLASS_TEST_MPFR_DEFAULT_DIGITS);
using data_type = bertini::mpfr_complex;
data_type q(1);
long a(1);
Eigen::Matrix A(2,2);
A << data_type(2), data_type(1), data_type(1), data_type(2);
A*=a;
}
BOOST_AUTO_TEST_CASE(self_multiplication_mpfr_mpz_int)
{
bertini::DefaultPrecision(CLASS_TEST_MPFR_DEFAULT_DIGITS);
using data_type = bertini::mpfr_complex;
data_type q(1);
bertini::mpz_int a(1);
Eigen::Matrix A(2,2);
A << data_type(2), data_type(1), data_type(1), data_type(2);
A*=a;
}
BOOST_AUTO_TEST_CASE(change_precision_mpfr_float)
{
bertini::DefaultPrecision(CLASS_TEST_MPFR_DEFAULT_DIGITS);
using bertini::Precision;
using data_type = bertini::mpfr_float;
Eigen::Matrix A(2,2);
A << data_type(2), data_type(1), data_type(1), data_type(2);
Precision(A,100);
BOOST_CHECK_EQUAL(A(0,0).precision(),100);
}
BOOST_AUTO_TEST_CASE(change_precision_mpfr_complex)
{
bertini::DefaultPrecision(CLASS_TEST_MPFR_DEFAULT_DIGITS);
using bertini::Precision;
using data_type = bertini::mpfr_complex;
Eigen::Matrix A(2,2);
A << data_type(2), data_type(1), data_type(1), data_type(2);
Precision(A,100);
BOOST_CHECK_EQUAL(A(0,0).precision(),100);
}
BOOST_AUTO_TEST_CASE(change_precision_mpfr_complex2)
{
bertini::DefaultPrecision(50);
using bertini::Precision;
using data_type = bertini::mpfr_complex;
Eigen::Matrix A(2,2);
A << data_type(2), data_type(1), data_type(1), data_type(2);
Precision(A,100);
BOOST_CHECK_EQUAL(A(0,0).precision(),100);
auto new_prec = 50-10;
bertini::DefaultPrecision(new_prec);
Eigen::Matrix B(2,2);
B = A; // assignment preserves precision of source
BOOST_CHECK((A-B).norm() < 1e-38);
BOOST_CHECK_EQUAL(Precision(B),100);
}
BOOST_AUTO_TEST_CASE(copy_matrix)
{
bertini::DefaultPrecision(50);
using bertini::Precision;
using data_type = bertini::mpfr_complex;
Eigen::Matrix A(4);
A << data_type(2), data_type(1), data_type(1), data_type(2);
Precision(A,100);
BOOST_CHECK_EQUAL(A(0).precision(),100);
auto new_prec = 50-10;
bertini::DefaultPrecision(new_prec);
Eigen::Matrix B(4);
B = A;
BOOST_CHECK((A-B).norm() < 1e-38);
BOOST_CHECK_EQUAL(Precision(B),100);
}
BOOST_AUTO_TEST_SUITE_END()