//This file is part of Bertini 2. // //b2/test/endgames/interpolation.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. // //b2/test/endgames/interpolation.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 b2/test/endgames/interpolation.cpp. If not, see . // // Copyright(C) 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 // Tim Hodges, Colorado State University // this file in intended to be included into other test files, with blanks filled in above. using namespace bertini; using namespace bertini::endgame; using bertini::DefaultPrecision; template using Vec = Eigen::Matrix; template using Mat = Eigen::Matrix; using BCT = BaseComplexType; using BRT = Eigen::NumTraits::Real; template BCT ComplexFromString(T... s) {return bertini::NumTraits::FromString(s...);} template BRT RealFromString(T... s) {return bertini::NumTraits::FromString(s...);} BOOST_AUTO_TEST_CASE( constant_four_variate ) { int num_samples = 3; DefaultPrecision(ambient_precision); TimeCont times; SampCont samples, derivatives; times.emplace_back(ComplexFromString("1.890235648907826359017283461724")); times.emplace_back(ComplexFromString("2.6751239470926520645293652")); times.emplace_back(ComplexFromString("3.566754186725389412876498127534875")); Vec sample(4); sample << ComplexFromString("6.4789162736409137056734534678679"), ComplexFromString("-1.5877816237549123614917624"), ComplexFromString("5.947461892534781890236417801"),ComplexFromString("-3.87746985236816238746178293"); for (int ii=0; ii<3; ++ii) samples.push_back(sample); Vec derivative(4); derivative << ComplexFromString("0"), ComplexFromString("0"), ComplexFromString("0"),ComplexFromString("0"); for (int ii=0; ii<3; ++ii) derivatives.push_back(derivative); BCT target_time = ComplexFromString("0.9471925368945182312341234123"); auto result = HermiteInterpolateAndSolve(target_time,num_samples,times,samples,derivatives); BOOST_CHECK( (result - sample).norm() < pow(RealFromString("10"),ambient_precision-2)); } /** This test case illustrates the convergent nature of the HemiteInterpolateAndSolve function. The test case will construct 3 samples with derivative,time, and space values for the function x^8 + 1. After the three samples have been constructed there will be a hermite interpolation. We check this against the tracking tolerance for the endgame. */ BOOST_AUTO_TEST_CASE( eight_degree_univariate ) { DefaultPrecision(ambient_precision); BCT target_time(0,0); //our target time is the origin. unsigned int num_samples = 3; TimeCont times; SampCont samples, derivatives; BCT time; Vec sample(1), derivative(1); time = ComplexFromString(".1"); // x = .1 times.push_back(time); sample << ComplexFromString("1.00000001"); // f(.1) = 1.00000001 samples.push_back(sample); derivative << ComplexFromString("8e-7"); //f'(.1) = 8e-7 derivatives.push_back(derivative); time = ComplexFromString(".05"); // x = .1/2 = .05 times.push_back(time); sample << ComplexFromString("1.0000000000390625"); //f(.05) = 1.0000000000390625 samples.push_back(sample); derivative << ComplexFromString("6.25e-9"); //f'(.05) = 6.25e-9 derivatives.push_back(derivative); time = ComplexFromString(".025"); // x = .05/2 = .025 times.push_back(time); sample << ComplexFromString("1.000000000000152587890625"); // f(.025) = 1.000000000000152587890625 samples.push_back(sample); derivative << ComplexFromString("4.8828125e-11"); //f'(.025) = 4.8828125e-11 derivatives.push_back(derivative); Vec< BCT > first_approx = HermiteInterpolateAndSolve(target_time,num_samples,times,samples,derivatives); BOOST_CHECK( norm(first_approx(0) - ComplexFromString("0.9999999767578209232082898114211261253459","0")) < 1e-7); // answer was found using matlab for a check. difference is diff is 2.32422e-08 }//end basic hermite test case mp against matlab /** This test case illustrates the convergent nature of the HemiteInterpolateAndSolve function. The test case will construct 3 samples with derivative,time, and space values for the function x^8 + 1. After the three samples have been constructed there will be a hermite interpolation. Next, a new sample is constructed and the earliest sample is discarded. Leaving us three samples that are "nearer" to the target at the origin. A new approximation is made, with the a new sample and approximation done afterwards. We then check to make sure our approximations are getting better by checking the distance from the correct answer and the various approximations made. */ BOOST_AUTO_TEST_CASE(eight_degree_univariate_advanced_gets_better) { DefaultPrecision(ambient_precision); BCT target_time(0,0); unsigned int num_samples = 3; TimeCont times; SampCont samples, derivatives; BCT time; Vec sample(1), derivative(1); time = ComplexFromString(".1"); // x = .1 times.push_back(time); sample << ComplexFromString("1.00000001"); // f(.1) = 1.00000001 samples.push_back(sample); derivative << ComplexFromString("8e-7"); //f'(.1) = 8e-7 derivatives.push_back(derivative); time = ComplexFromString(".05"); // x = .1/2 = .05 times.push_back(time); sample << ComplexFromString("1.0000000000390625"); //f(.05) = 1.0000000000390625 samples.push_back(sample); derivative << ComplexFromString("6.25e-9"); //f'(.05) = 6.25e-9 derivatives.push_back(derivative); time = ComplexFromString(".025"); // x = .05/2 = .025 times.push_back(time); sample << ComplexFromString("1.000000000000152587890625"); // f(.025) = 1.000000000000152587890625 samples.push_back(sample); derivative << ComplexFromString("4.8828125e-11"); //f'(.025) = 4.8828125e-11 derivatives.push_back(derivative); Vec< BCT > first_approx = HermiteInterpolateAndSolve(target_time,num_samples,times,samples,derivatives); Vec< BCT > correct(1); correct << ComplexFromString("1"); //Setting up a new sample for approximation. time = ComplexFromString(".0125"); //.025/2 = .0125 times.push_back(time); sample << ComplexFromString("1.00000000000000059604644775390625"); // f(.0125) = 1.00000000000000059604644775390625 samples.push_back(sample); derivative << ComplexFromString("3.814697265625e-13"); //f'(.0125) = 3.814697265625e-13 derivatives.push_back(derivative); //Get rid of earliest sample. times.pop_front(); samples.pop_front(); derivatives.pop_front(); //Compute the second approximation. Vec< BCT > second_approx = HermiteInterpolateAndSolve(target_time,num_samples,times,samples,derivatives); // //Check to make sure we are doing better. BOOST_CHECK(abs(second_approx(0)-correct(0)) < abs(first_approx(0)-correct(0))); //Setting up new sample for use in approximation. time = ComplexFromString("0.00625"); //.0125/2 = 0.00625 times.push_back(time); sample << ComplexFromString("1.0000000000000000023283064365386962890625"); // f(.00625) = 1.0000000000000000023283064365386962890625 samples.push_back(sample); derivative << ComplexFromString("2.98023223876953125000000000000000e-15"); //f'(.00625) = 2.98023223876953125000000000000000×e-15 derivatives.push_back(derivative); times.pop_front(); samples.pop_front(); derivatives.pop_front(); Vec< BCT > third_approx = HermiteInterpolateAndSolve(target_time,num_samples,times,samples,derivatives); BOOST_CHECK((first_approx - correct).norm() < 1e-10); BOOST_CHECK((second_approx - correct).norm() < 1e-10); BOOST_CHECK((third_approx - correct).norm() < 1e-10); }//end hermite test case