//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()