2031 lines
55 KiB
C++
2031 lines
55 KiB
C++
//This file is part of Bertini 2.
|
|
//
|
|
//generic_cauchy_test.hpp 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.
|
|
//
|
|
//generic_cauchy_test.hpp 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 generic_cauchy_test.hpp. If not, see <http://www.gnu.org/licenses/>.
|
|
//
|
|
// Copyright(C) 2015 - 2021 by Bertini2 Development Team
|
|
//
|
|
// See <http://www.gnu.org/licenses/> 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
|
|
|
|
/**
|
|
\file generic_cauchy_test.hpp Defines tests that all cauchy endgames's, combined with all tracker types, must pass.
|
|
|
|
This file in intended for inclusion into another test file, which declares TrackerType and TestedEGType
|
|
*/
|
|
|
|
|
|
|
|
// there is deliberately a missing #pragma once here, because want to allow inclusion in multiple suites in same file.
|
|
|
|
|
|
using System = bertini::System;
|
|
using Variable = bertini::node::Variable;
|
|
|
|
|
|
using Var = std::shared_ptr<Variable>;
|
|
|
|
using VariableGroup = bertini::VariableGroup;
|
|
|
|
|
|
|
|
using dbl = bertini::dbl;
|
|
using mpfr = bertini::mpfr_complex;
|
|
using mpfr_float = bertini::mpfr_float;
|
|
using mpq_rational = bertini::mpq_rational;
|
|
|
|
using bertini::Precision;
|
|
|
|
template<typename NumType> using Vec = Eigen::Matrix<NumType, Eigen::Dynamic, 1>;
|
|
template<typename NumType> using Mat = Eigen::Matrix<NumType, Eigen::Dynamic, Eigen::Dynamic>;
|
|
|
|
|
|
using PrecisionConfig = bertini::tracking::TrackerTraits<TrackerType>::PrecisionConfig;
|
|
|
|
using BRT = bertini::tracking::TrackerTraits<TrackerType>::BaseRealType;
|
|
using BCT = bertini::tracking::TrackerTraits<TrackerType>::BaseComplexType;
|
|
|
|
using SuccessCode = bertini::SuccessCode;
|
|
|
|
template<typename ...T>
|
|
BCT ComplexFromString(T... s)
|
|
{return bertini::NumTraits<BCT>::FromString(s...);}
|
|
|
|
template<typename ...T>
|
|
BRT RealFromString(T... s)
|
|
{return bertini::NumTraits<BRT>::FromString(s...);}
|
|
|
|
|
|
using bertini::DefaultPrecision;
|
|
|
|
|
|
|
|
using namespace bertini::endgame;
|
|
|
|
/**
|
|
In this test we take a univariate polynomial with one solution and ensure that our CircleTrack function returns to the same position.
|
|
This is tested by checking that our cauchy_samples has the front and end with the same value roughly.
|
|
*/
|
|
BOOST_AUTO_TEST_CASE(circle_track_cycle_num_1)
|
|
{
|
|
|
|
DefaultPrecision(ambient_precision);
|
|
|
|
System sys;
|
|
Var x = Variable::Make("x");
|
|
Var t = Variable::Make("t");
|
|
|
|
sys.AddFunction((x-1)*(1-t) + (x+1)*t);
|
|
|
|
VariableGroup vars{x};
|
|
sys.AddVariableGroup(vars);
|
|
sys.AddPathVariable(t);
|
|
|
|
|
|
auto precision_config = PrecisionConfig(sys);
|
|
|
|
TrackerType tracker(sys);
|
|
|
|
bertini::tracking::SteppingConfig stepping_preferences;
|
|
bertini::tracking::NewtonConfig newton_preferences;
|
|
|
|
tracker.Setup(TestedPredictor,
|
|
1e-5,
|
|
1e5,
|
|
stepping_preferences,
|
|
newton_preferences);
|
|
|
|
tracker.PrecisionSetup(precision_config);
|
|
|
|
auto origin = BCT(0,0);
|
|
|
|
|
|
TestedEGType my_endgame(tracker);
|
|
|
|
bertini::SampCont<BCT>& cauchy_samples = my_endgame.GetCauchySamples<BCT>();
|
|
bertini::TimeCont<BCT>& cauchy_times = my_endgame.GetCauchyTimes<BCT>();
|
|
|
|
|
|
|
|
cauchy_times.push_back(ComplexFromString("0.1"));
|
|
cauchy_samples.push_back(Vec<BCT>(1));
|
|
cauchy_samples.back() << ComplexFromString("7.999999999999999e-01", "2.168404344971009e-19"); //
|
|
|
|
|
|
auto first_track_success = my_endgame.CircleTrack(origin);
|
|
|
|
BOOST_CHECK((my_endgame.GetCauchySamples<BCT>().back() - cauchy_samples.front()).template lpNorm<Eigen::Infinity>() < 1e-5);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
In this test we take a univariate polynomial with one solution of multiplicity 2. We need to ensure that our CircleTrack function
|
|
returns to the same position after two calls. The first call should land us on the second path, and the second call should land us back
|
|
where we started. This is tested by checking that cauchy_samples has the front and end with the same value roughly.
|
|
*/
|
|
BOOST_AUTO_TEST_CASE(circle_track_cycle_num_greater_than_1)
|
|
{
|
|
|
|
DefaultPrecision(ambient_precision);
|
|
|
|
System sys;
|
|
Var x = Variable::Make("x");
|
|
Var t = Variable::Make("t");
|
|
|
|
sys.AddFunction( pow(x-1,2)*(1-t) + (pow(x,2) + 1)*t);
|
|
|
|
VariableGroup vars{x};
|
|
sys.AddVariableGroup(vars);
|
|
sys.AddPathVariable(t);
|
|
|
|
|
|
auto precision_config = PrecisionConfig(sys);
|
|
|
|
TrackerType tracker(sys);
|
|
|
|
bertini::tracking::SteppingConfig stepping_preferences;
|
|
bertini::tracking::NewtonConfig newton_preferences;
|
|
|
|
tracker.Setup(TestedPredictor,
|
|
1e-5,
|
|
1e5,
|
|
stepping_preferences,
|
|
newton_preferences);
|
|
|
|
tracker.PrecisionSetup(precision_config);
|
|
|
|
bertini::TimeCont<BCT> cauchy_times;
|
|
bertini::SampCont<BCT> cauchy_samples;
|
|
|
|
|
|
|
|
Vec<BCT> sample(1);
|
|
auto origin = BCT(0,0);
|
|
|
|
|
|
BCT time = ComplexFromString("0.1");
|
|
cauchy_times.push_back(time);
|
|
sample << ComplexFromString("9.000000000000001e-01", "4.358898943540673e-01"); //
|
|
cauchy_samples.push_back(sample);
|
|
|
|
TestedEGType my_endgame(tracker);
|
|
|
|
my_endgame.SetCauchySamples(cauchy_samples);
|
|
my_endgame.SetCauchyTimes(cauchy_times);
|
|
|
|
auto tracking_success = my_endgame.CircleTrack(origin);
|
|
|
|
const auto& first_track_sample = my_endgame.GetCauchySamples<BCT>().back();
|
|
|
|
BOOST_CHECK((first_track_sample - sample).template lpNorm<Eigen::Infinity>() > 1e-5);
|
|
|
|
tracking_success = my_endgame.CircleTrack(origin);
|
|
|
|
const auto& second_track_sample = my_endgame.GetCauchySamples<BCT>().back();
|
|
|
|
BOOST_CHECK((second_track_sample - sample).template lpNorm<Eigen::Infinity>() < 1e-5);
|
|
|
|
} // end circle_track_mp_cycle_num_greater_than_1
|
|
|
|
|
|
/**
|
|
We are going to track around a nonzero target time. For a random nonzero time value we expect to not encircle any branch points.
|
|
Making the cycle number 1.
|
|
*/
|
|
BOOST_AUTO_TEST_CASE(circle_track__nonzero_target_time)
|
|
{
|
|
|
|
DefaultPrecision(ambient_precision);
|
|
|
|
System sys;
|
|
Var x = Variable::Make("x");
|
|
Var t = Variable::Make("t");
|
|
|
|
sys.AddFunction( pow(x-1,3)*(1-t) + (pow(x,3) + 1)*t);
|
|
|
|
VariableGroup vars{x};
|
|
sys.AddVariableGroup(vars);
|
|
sys.AddPathVariable(t);
|
|
|
|
|
|
auto precision_config = PrecisionConfig(sys);
|
|
|
|
TrackerType tracker(sys);
|
|
|
|
bertini::tracking::SteppingConfig stepping_preferences;
|
|
bertini::tracking::NewtonConfig newton_preferences;
|
|
|
|
tracker.Setup(TestedPredictor,
|
|
1e-5,
|
|
1e5,
|
|
stepping_preferences,
|
|
newton_preferences);
|
|
|
|
tracker.PrecisionSetup(precision_config);
|
|
|
|
bertini::TimeCont<BCT> cauchy_times;
|
|
bertini::SampCont<BCT> cauchy_samples;
|
|
|
|
|
|
|
|
BCT time(1);
|
|
Vec<BCT> sample(1);
|
|
auto center = ComplexFromString(".19","-.01");
|
|
|
|
|
|
time = ComplexFromString("0.2");
|
|
cauchy_times.push_back(time);
|
|
sample << ComplexFromString("3.603621541081173e-01", "2.859583229930518e-18"); //
|
|
cauchy_samples.push_back(sample);
|
|
|
|
TestedEGType my_endgame(tracker);
|
|
|
|
my_endgame.SetCauchySamples(cauchy_samples);
|
|
my_endgame.SetCauchyTimes(cauchy_times);
|
|
|
|
auto tracking_success = my_endgame.CircleTrack(center);
|
|
|
|
|
|
const auto& first_track_sample = my_endgame.GetCauchySamples<BCT>().back();
|
|
|
|
BOOST_CHECK((first_track_sample - sample).template lpNorm<Eigen::Infinity>() < 1e-5);
|
|
|
|
} // end circle_track_nonzero_target_time
|
|
|
|
|
|
|
|
/**
|
|
In this test we take a univariate polynomial with one solution of multiplicity. For our first power series approximation we need to
|
|
make sure that we have a stablization of the cycle number. This is achieved by computing an approximation for C over K which is described
|
|
on page 53 of the Berini Book, Numerically Solving Polynomials Systems with Bertini \cite bertinibook.
|
|
|
|
This test case is ensuring no calculations are greatly altered, so our test condition is to check against a computed value that has been already known.
|
|
*/
|
|
BOOST_AUTO_TEST_CASE(compute_c_over_k_for_cauchy_class)
|
|
{
|
|
DefaultPrecision(ambient_precision);
|
|
|
|
bertini::System sys;
|
|
Var x = Variable::Make("x");
|
|
sys.AddFunction(pow(x-1,3)); //f(x) = (x-1)^3
|
|
|
|
VariableGroup vars{x};
|
|
sys.AddVariableGroup(vars);
|
|
|
|
auto precision_config = PrecisionConfig(sys);
|
|
|
|
TrackerType tracker(sys);
|
|
|
|
bertini::tracking::SteppingConfig stepping_preferences;
|
|
bertini::tracking::NewtonConfig newton_preferences;
|
|
|
|
tracker.Setup(TestedPredictor,
|
|
1e-5,
|
|
1e5,
|
|
stepping_preferences,
|
|
newton_preferences);
|
|
|
|
tracker.PrecisionSetup(precision_config);
|
|
|
|
bertini::TimeCont<BCT> pseg_times;
|
|
bertini::SampCont<BCT> pseg_samples;
|
|
|
|
|
|
BCT time(1);
|
|
Vec<BCT> sample(1);
|
|
|
|
time = ComplexFromString(".1"); // x = .1
|
|
pseg_times.push_back(time);
|
|
sample << ComplexFromString("-0.729"); // f(.1) = -0.729
|
|
pseg_samples.push_back(sample);
|
|
|
|
|
|
time = ComplexFromString(".05"); // x = .1/2 = .05
|
|
pseg_times.push_back(time);
|
|
sample << ComplexFromString("-0.857375"); //f(.05) = -0.857375
|
|
pseg_samples.push_back(sample);
|
|
|
|
|
|
time = ComplexFromString(".025"); // x = .05/2 = .025
|
|
pseg_times.push_back(time);
|
|
sample << ComplexFromString("-0.926859375"); // f(.025) = -0.926859375
|
|
pseg_samples.push_back(sample);
|
|
|
|
|
|
SecurityConfig security_settings;
|
|
|
|
TestedEGType my_endgame(tracker,security_settings);
|
|
my_endgame.SetPSEGTimes(pseg_times);
|
|
my_endgame.SetPSEGSamples(pseg_samples);
|
|
|
|
auto first_c_over_k = my_endgame.ComputeCOverK<BCT>();
|
|
|
|
using std::abs;
|
|
BOOST_CHECK( abs(first_c_over_k - RealFromString("1.12917")) < 1e-5 );
|
|
|
|
//Setting up a new sample for approximation.
|
|
time = ComplexFromString(".0125"); //.025/2 = .0125
|
|
pseg_times.push_back(time);
|
|
sample << ComplexFromString("-0.962966796875"); // f(.0125) = -0.962966796875
|
|
pseg_samples.push_back(sample);
|
|
|
|
//Get rid of earliest sample.
|
|
pseg_times.pop_front();
|
|
pseg_samples.pop_front();
|
|
|
|
my_endgame.SetPSEGTimes(pseg_times);
|
|
my_endgame.SetPSEGSamples(pseg_samples);
|
|
|
|
auto second_c_over_k = my_endgame.ComputeCOverK<BCT>();
|
|
|
|
BOOST_CHECK( abs(second_c_over_k - RealFromString("1.05888")) < 1e-5);
|
|
|
|
} // end compute c over k for cauchy class
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
After we have computed C over K approximations we have to make sure that we lie within some agreed terms. This means our agreements need
|
|
to be with some ratio of each other. (Minimum is usually .75), and we need to agree so many times (usually 3). This test case checks for this.
|
|
|
|
*/
|
|
BOOST_AUTO_TEST_CASE(stabilization_of_C_over_K)
|
|
{
|
|
DefaultPrecision(ambient_precision);
|
|
|
|
bertini::System sys;
|
|
Var x = Variable::Make("x");
|
|
Var t = Variable::Make("t");
|
|
sys.AddFunction( pow(x-1,3)*(1-t) + (pow(x,3) + 1)*t);
|
|
|
|
VariableGroup vars{x};
|
|
sys.AddVariableGroup(vars);
|
|
|
|
auto precision_config = PrecisionConfig(sys);
|
|
|
|
TrackerType tracker(sys);
|
|
|
|
bertini::tracking::SteppingConfig stepping_preferences;
|
|
bertini::tracking::NewtonConfig newton_preferences;
|
|
|
|
tracker.Setup(TestedPredictor,
|
|
1e-5,
|
|
1e5,
|
|
stepping_preferences,
|
|
newton_preferences);
|
|
|
|
tracker.PrecisionSetup(precision_config);
|
|
|
|
bertini::TimeCont<BCT> pseg_times;
|
|
bertini::SampCont<BCT> pseg_samples;
|
|
bertini::TimeCont<BRT> c_over_k_array;
|
|
|
|
BCT time;
|
|
Vec<BCT> sample(1);
|
|
|
|
time = ComplexFromString(".1"); // x = .1
|
|
pseg_times.push_back(time);
|
|
sample << ComplexFromString("1.100000000000000e+00", "6.244997998398396e-01"); // f(.1) = 1.100000000000000e+00 6.244997998398396e-01
|
|
pseg_samples.push_back(sample);
|
|
|
|
|
|
time = ComplexFromString(".05"); // x = .1/2 = .05
|
|
pseg_times.push_back(time);
|
|
sample << ComplexFromString("1.125000000000000e+00", "4.841229182759271e-01"); //f(.05) = 1.125000000000000e+00 4.841229182759271e-01
|
|
pseg_samples.push_back(sample);
|
|
|
|
|
|
time = ComplexFromString(".025"); // x = .05/2 = .025
|
|
pseg_times.push_back(time);
|
|
sample << ComplexFromString("1.123854702920065e+00", "3.736283818773165e-01"); // f(.025) = 1.123854702920065e+00 3.736283818773165e-01
|
|
pseg_samples.push_back(sample);
|
|
|
|
|
|
SecurityConfig security_settings;
|
|
|
|
TestedEGType my_endgame(tracker,security_settings);
|
|
my_endgame.SetPSEGTimes(pseg_times);
|
|
my_endgame.SetPSEGSamples(pseg_samples);
|
|
|
|
auto first_c_over_k = my_endgame.ComputeCOverK<BCT>();
|
|
|
|
c_over_k_array.push_back(first_c_over_k);
|
|
|
|
//Setting up a new sample for approximation.
|
|
time = ComplexFromString(".0125"); //.025/2 = .0125
|
|
pseg_times.push_back(time);
|
|
sample << ComplexFromString("1.111721780135302e+00", "2.886596646224579e-01"); // f(.0125) = 1.111721780135302e+00 2.886596646224579e-01
|
|
pseg_samples.push_back(sample);
|
|
|
|
//Get rid of earliest sample.
|
|
pseg_times.pop_front();
|
|
pseg_samples.pop_front();
|
|
|
|
my_endgame.SetPSEGTimes(pseg_times);
|
|
my_endgame.SetPSEGSamples(pseg_samples);
|
|
|
|
auto second_c_over_k = my_endgame.ComputeCOverK<BCT>();
|
|
|
|
c_over_k_array.push_back(second_c_over_k);
|
|
|
|
|
|
|
|
//Setting up a new sample for approximation.
|
|
time = ComplexFromString(".00625"); //.025/2 = .0125
|
|
pseg_times.push_back(time);
|
|
sample << ComplexFromString("1.096071609421043e+00", "2.237005761359081e-01"); // f(.00625) = 1.096071609421043e+00 2.237005761359081e-01
|
|
pseg_samples.push_back(sample);
|
|
|
|
//Get rid of earliest sample.
|
|
pseg_times.pop_front();
|
|
pseg_samples.pop_front();
|
|
|
|
my_endgame.SetPSEGTimes(pseg_times);
|
|
my_endgame.SetPSEGSamples(pseg_samples);
|
|
|
|
auto third_c_over_k = my_endgame.ComputeCOverK<BCT>();
|
|
|
|
c_over_k_array.push_back(third_c_over_k);
|
|
|
|
BOOST_CHECK(my_endgame.CheckForCOverKStabilization(c_over_k_array) == true);
|
|
|
|
} // end check agreement function mp for cauchy
|
|
|
|
|
|
|
|
|
|
/**
|
|
In this test case we have a solution we are trying to find with multiplicity 1. If we call CircleTrack we should have a closed loop.
|
|
This test case is checking to make sure our CheckClosedLoop function returns that we have actually closed.
|
|
*/
|
|
BOOST_AUTO_TEST_CASE(check_closed_loop_for_cycle_num_1)
|
|
{
|
|
DefaultPrecision(ambient_precision);
|
|
|
|
System sys;
|
|
Var x = Variable::Make("x");
|
|
Var t = Variable::Make("t");
|
|
|
|
sys.AddFunction((x-1)*(1-t) + (x+1)*t);
|
|
|
|
VariableGroup vars{x};
|
|
sys.AddVariableGroup(vars);
|
|
sys.AddPathVariable(t);
|
|
|
|
|
|
auto precision_config = PrecisionConfig(sys);
|
|
|
|
TrackerType tracker(sys);
|
|
|
|
bertini::tracking::SteppingConfig stepping_preferences;
|
|
bertini::tracking::NewtonConfig newton_preferences;
|
|
|
|
tracker.Setup(TestedPredictor,
|
|
1e-5,
|
|
1e5,
|
|
stepping_preferences,
|
|
newton_preferences);
|
|
|
|
tracker.PrecisionSetup(precision_config);
|
|
|
|
bertini::TimeCont<BCT> cauchy_times;
|
|
bertini::SampCont<BCT> cauchy_samples;
|
|
|
|
|
|
BCT time(1);
|
|
Vec<BCT> sample(1);
|
|
auto origin = BCT(0,0);
|
|
|
|
|
|
time = ComplexFromString(".1");
|
|
cauchy_times.push_back(time);
|
|
sample << ComplexFromString("7.999999999999999e-01", "2.168404344971009e-19"); //
|
|
cauchy_samples.push_back(sample);
|
|
|
|
|
|
TestedEGType my_endgame(tracker);
|
|
|
|
my_endgame.SetCauchySamples(cauchy_samples);
|
|
my_endgame.SetCauchyTimes(cauchy_times);
|
|
|
|
|
|
auto tracking_success = my_endgame.CircleTrack(origin);
|
|
BOOST_CHECK(my_endgame.CheckClosedLoop<BCT>() == true);
|
|
|
|
} // end check closed loop if cycle num is 1 for cauchy class test
|
|
|
|
|
|
|
|
/**
|
|
In this test case we have a solution we are trying to find with multiplicity 2. If we call CircleTrack we should not have a closed loop.
|
|
|
|
This test case is checking to make sure our CheckClosedLoop function returns that we have not closed.
|
|
*/
|
|
BOOST_AUTO_TEST_CASE(check_closed_loop_for_cycle_num_greater_than_1)
|
|
{
|
|
DefaultPrecision(ambient_precision);
|
|
|
|
System sys;
|
|
Var x = Variable::Make("x");
|
|
Var t = Variable::Make("t");
|
|
|
|
sys.AddFunction( pow(x-1,2)*(1-t) + (pow(x,2) + 1)*t);
|
|
|
|
|
|
VariableGroup vars{x};
|
|
sys.AddVariableGroup(vars);
|
|
sys.AddPathVariable(t);
|
|
|
|
|
|
auto precision_config = PrecisionConfig(sys);
|
|
|
|
TrackerType tracker(sys);
|
|
|
|
bertini::tracking::SteppingConfig stepping_preferences;
|
|
bertini::tracking::NewtonConfig newton_preferences;
|
|
|
|
tracker.Setup(TestedPredictor,
|
|
1e-5,
|
|
1e5,
|
|
stepping_preferences,
|
|
newton_preferences);
|
|
|
|
tracker.PrecisionSetup(precision_config);
|
|
|
|
bertini::TimeCont<BCT> cauchy_times;
|
|
bertini::SampCont<BCT> cauchy_samples;
|
|
auto origin = BCT(0,0);
|
|
|
|
|
|
|
|
auto time = ComplexFromString("0.1");
|
|
cauchy_times.push_back(time);
|
|
|
|
Vec<BCT> sample(1);
|
|
sample << ComplexFromString("9.000000000000001e-01", "4.358898943540673e-01"); //
|
|
cauchy_samples.push_back(sample);
|
|
|
|
|
|
TestedEGType my_endgame(tracker);
|
|
|
|
my_endgame.SetCauchySamples(cauchy_samples);
|
|
my_endgame.SetCauchyTimes(cauchy_times);
|
|
|
|
auto tracking_success = my_endgame.CircleTrack(origin);
|
|
BOOST_CHECK(my_endgame.CheckClosedLoop<BCT>() == false);
|
|
|
|
tracking_success = my_endgame.CircleTrack(origin);
|
|
BOOST_CHECK(my_endgame.CheckClosedLoop<BCT>() == true);
|
|
|
|
} // end check closed loop if cycle num is greater than 1 for cauchy class test
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
After we have stabilized our estimation of c over k, we can start to perform cauchy loops to see if the minimum and maximum norms
|
|
of sample points are within a tolerance. If so, we can start actually using the Cauchy Integral Formula to extrapolate approximations
|
|
at the origin.
|
|
|
|
In this example, since the cycle number is 1, we should see that our RatioEGOperatingZoneTest function says that we are good to proceed
|
|
in using the Cauchy Integral Formula.
|
|
*/
|
|
BOOST_AUTO_TEST_CASE(compare_cauchy_ratios)
|
|
{
|
|
DefaultPrecision(ambient_precision);
|
|
|
|
System sys;
|
|
Var x = Variable::Make("x");
|
|
Var t = Variable::Make("t");
|
|
|
|
sys.AddFunction((x-1)*(1-t) + (x+1)*t);
|
|
|
|
VariableGroup vars{x};
|
|
sys.AddVariableGroup(vars);
|
|
sys.AddPathVariable(t);
|
|
|
|
|
|
auto precision_config = PrecisionConfig(sys);
|
|
|
|
TrackerType tracker(sys);
|
|
|
|
|
|
|
|
bertini::tracking::SteppingConfig stepping_preferences;
|
|
bertini::tracking::NewtonConfig newton_preferences;
|
|
|
|
tracker.Setup(TestedPredictor,
|
|
1e-5,
|
|
1e5,
|
|
stepping_preferences,
|
|
newton_preferences);
|
|
|
|
tracker.PrecisionSetup(precision_config);
|
|
|
|
bertini::TimeCont<BCT> cauchy_times;
|
|
bertini::SampCont<BCT> cauchy_samples;
|
|
|
|
|
|
auto time = ComplexFromString(".1");
|
|
Vec<BCT> sample(1);
|
|
auto origin = BCT(0,0);
|
|
|
|
cauchy_times.push_back(time);
|
|
sample << ComplexFromString("7.999999999999999e-01", "2.168404344971009e-19"); //
|
|
cauchy_samples.push_back(sample);
|
|
|
|
TestedEGType my_endgame(tracker);
|
|
my_endgame.SetCauchyTimes(cauchy_times);
|
|
my_endgame.SetCauchySamples(cauchy_samples);
|
|
|
|
auto tracking_success = my_endgame.CircleTrack(origin);
|
|
BOOST_CHECK(my_endgame.RatioEGOperatingZoneTest<BCT>(origin) == true);
|
|
|
|
} // end compare cauchy ratios for cauchy class test
|
|
|
|
|
|
|
|
|
|
/**
|
|
After we have stabilized our estimation of c over k, we can start to perform cauchy loops to see if the minimum and maximum norms
|
|
of sample points are within a tolerance. If so, we can start actually using the Cauchy Integral Formula to extrapolate approximations
|
|
at the origin.
|
|
*/
|
|
BOOST_AUTO_TEST_CASE(compare_cauchy_ratios_cycle_num_greater_than_1)
|
|
{
|
|
|
|
DefaultPrecision(ambient_precision);
|
|
|
|
System sys;
|
|
Var x = Variable::Make("x");
|
|
Var t = Variable::Make("t");
|
|
|
|
sys.AddFunction( pow(x-1,2)*(1-t) + (pow(x,2) + 1)*t);
|
|
|
|
VariableGroup vars{x};
|
|
sys.AddVariableGroup(vars);
|
|
sys.AddPathVariable(t);
|
|
|
|
|
|
auto precision_config = PrecisionConfig(sys);
|
|
|
|
TrackerType tracker(sys);
|
|
|
|
bertini::tracking::SteppingConfig stepping_preferences;
|
|
bertini::tracking::NewtonConfig newton_preferences;
|
|
|
|
tracker.Setup(TestedPredictor,
|
|
1e-5,
|
|
1e5,
|
|
stepping_preferences,
|
|
newton_preferences);
|
|
|
|
tracker.PrecisionSetup(precision_config);
|
|
|
|
bertini::TimeCont<BCT> cauchy_times;
|
|
bertini::SampCont<BCT> cauchy_samples;
|
|
auto origin = BCT(0,0);
|
|
|
|
|
|
|
|
auto time = ComplexFromString("0.1");
|
|
Vec<BCT> sample(1);
|
|
|
|
cauchy_times.push_back(time);
|
|
sample << ComplexFromString("9.000000000000001e-01", "4.358898943540673e-01"); //
|
|
cauchy_samples.push_back(sample);
|
|
|
|
TestedEGType my_endgame(tracker);
|
|
|
|
my_endgame.SetCauchyTimes(cauchy_times);
|
|
my_endgame.SetCauchySamples(cauchy_samples);
|
|
|
|
auto tracking_success = my_endgame.CircleTrack(origin);
|
|
BOOST_CHECK(my_endgame.RatioEGOperatingZoneTest<BCT>(origin) == true);
|
|
|
|
} // end compare cauchy ratios for cycle num greater than 1 cauchy class test
|
|
|
|
|
|
/**
|
|
In the cauchy endgame we want to compute cauchy loops and make sure that we have that the max and min norms of the samples around the
|
|
origin are within some heuristic value. The function InitialCauchyLoops does this while holding onto the cycle number.
|
|
This test case is making sure we succeed and get the correct cycle number.
|
|
*/
|
|
BOOST_AUTO_TEST_CASE(initial_cauchy_loops)
|
|
{
|
|
|
|
DefaultPrecision(ambient_precision);
|
|
|
|
System sys;
|
|
Var x = Variable::Make("x");
|
|
Var t = Variable::Make("t");
|
|
|
|
sys.AddFunction((x-1)*(1-t) + (x+1)*t);
|
|
|
|
VariableGroup vars{x};
|
|
sys.AddVariableGroup(vars);
|
|
sys.AddPathVariable(t);
|
|
|
|
|
|
auto precision_config = PrecisionConfig(sys);
|
|
|
|
TrackerType tracker(sys);
|
|
|
|
bertini::tracking::SteppingConfig stepping_preferences;
|
|
bertini::tracking::NewtonConfig newton_preferences;
|
|
|
|
tracker.Setup(TestedPredictor,
|
|
1e-5,
|
|
1e5,
|
|
stepping_preferences,
|
|
newton_preferences);
|
|
|
|
tracker.PrecisionSetup(precision_config);
|
|
|
|
bertini::TimeCont<BCT> pseg_times;
|
|
bertini::SampCont<BCT> pseg_samples;
|
|
|
|
auto time = ComplexFromString("0.1");
|
|
Vec<BCT> sample(1);
|
|
auto origin = BCT(0,0);
|
|
|
|
pseg_times.push_back(time);
|
|
sample << ComplexFromString("7.999999999999999e-01", "2.168404344971009e-19"); //
|
|
pseg_samples.push_back(sample);
|
|
|
|
TestedEGType my_endgame(tracker);
|
|
|
|
my_endgame.SetPSEGSamples(pseg_samples);
|
|
my_endgame.SetPSEGTimes(pseg_times);
|
|
|
|
auto success_of_initial_cauchy_loops = my_endgame.InitialCauchyLoops<BCT>(origin);
|
|
|
|
BOOST_CHECK(success_of_initial_cauchy_loops == SuccessCode::Success);
|
|
BOOST_CHECK(my_endgame.CycleNumber() == 1);
|
|
|
|
}//end initial_cauchy_loops
|
|
|
|
/*
|
|
This test case is to compute pre cauchy loops around a nonzero target time. Need to ensure we will succeed at closing the loops,
|
|
and ensure that our ratios around the target time are small enough.
|
|
*/
|
|
BOOST_AUTO_TEST_CASE(initial_cauchy_loops_nonzero_target_time)
|
|
{
|
|
|
|
DefaultPrecision(ambient_precision);
|
|
|
|
System sys;
|
|
Var x = Variable::Make("x");
|
|
Var t = Variable::Make("t");
|
|
|
|
sys.AddFunction(pow(x-1,3)*(1-t) + (pow(x,3)+1)*t);
|
|
|
|
VariableGroup vars{x};
|
|
sys.AddVariableGroup(vars);
|
|
sys.AddPathVariable(t);
|
|
|
|
|
|
auto precision_config = PrecisionConfig(sys);
|
|
|
|
TrackerType tracker(sys);
|
|
|
|
bertini::tracking::SteppingConfig stepping_preferences;
|
|
bertini::tracking::NewtonConfig newton_preferences;
|
|
|
|
tracker.Setup(TestedPredictor,
|
|
1e-5,
|
|
1e5,
|
|
stepping_preferences,
|
|
newton_preferences);
|
|
|
|
tracker.PrecisionSetup(precision_config);
|
|
|
|
bertini::TimeCont<BCT> pseg_times;
|
|
bertini::SampCont<BCT> pseg_samples;
|
|
|
|
auto start_time = ComplexFromString("0.2");
|
|
Vec<BCT> start_sample(1);
|
|
auto center_for_loops = ComplexFromString(".15","-.01");
|
|
|
|
pseg_times.push_back(start_time);
|
|
start_sample << ComplexFromString("3.603621541081173e-01", "2.859583229930518e-18"); //
|
|
pseg_samples.push_back(start_sample);
|
|
|
|
TestedEGType my_endgame(tracker);
|
|
|
|
my_endgame.SetPSEGSamples(pseg_samples);
|
|
my_endgame.SetPSEGTimes(pseg_times);
|
|
|
|
auto success_of_initial_cauchy_loops = my_endgame.InitialCauchyLoops<BCT>(center_for_loops);
|
|
|
|
BOOST_CHECK(success_of_initial_cauchy_loops == SuccessCode::Success);
|
|
|
|
|
|
}//end inital_cauchy_loops nonzero target time.
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
In the cauchy endgame we want to compute cauchy loops and make sure that we have that the max and min norms of the samples around the
|
|
origin are within some heuristic value. The function InitialCauchyLoops does this while holding onto the cycle number.
|
|
This test case is making sure we succeed and get the correct cycle number.
|
|
*/
|
|
BOOST_AUTO_TEST_CASE(initial_cauchy_loops_cycle_num_greater_than_1)
|
|
{
|
|
DefaultPrecision(ambient_precision);
|
|
|
|
System sys;
|
|
Var x = Variable::Make("x");
|
|
Var t = Variable::Make("t");
|
|
|
|
sys.AddFunction( pow(x-1,2)*(1-t) + (pow(x,2) + 1)*t);
|
|
|
|
VariableGroup vars{x};
|
|
sys.AddVariableGroup(vars);
|
|
sys.AddPathVariable(t);
|
|
|
|
|
|
auto precision_config = PrecisionConfig(sys);
|
|
|
|
TrackerType tracker(sys);
|
|
|
|
bertini::tracking::SteppingConfig stepping_preferences;
|
|
bertini::tracking::NewtonConfig newton_preferences;
|
|
|
|
tracker.Setup(TestedPredictor,
|
|
1e-5,
|
|
1e5,
|
|
stepping_preferences,
|
|
newton_preferences);
|
|
|
|
tracker.PrecisionSetup(precision_config);
|
|
|
|
bertini::TimeCont<BCT> pseg_times;
|
|
bertini::SampCont<BCT> pseg_samples;
|
|
|
|
|
|
|
|
BCT time(1);
|
|
Vec<BCT> sample(1);
|
|
auto origin = BCT(0,0);
|
|
|
|
|
|
time = ComplexFromString("0.1");
|
|
pseg_times.push_back(time);
|
|
sample << ComplexFromString("9.000000000000001e-01", "4.358898943540673e-01"); //
|
|
pseg_samples.push_back(sample);
|
|
|
|
|
|
TestedEGType my_endgame(tracker);
|
|
|
|
my_endgame.SetPSEGSamples(pseg_samples);
|
|
my_endgame.SetPSEGTimes(pseg_times);
|
|
|
|
BOOST_CHECK(my_endgame.InitialCauchyLoops<BCT>(origin) == SuccessCode::Success);
|
|
BOOST_CHECK(my_endgame.CycleNumber() == 2);
|
|
|
|
}// end initial_cauchy_loops_cycle_num_greater_than_1
|
|
|
|
|
|
|
|
/**
|
|
The function tested is ComputeFirstApproximation. This function is the culmination of tracking samples until our estimation of
|
|
c over k is stabilized and we have our Cauchy loop ratios within a tolerance. After this we will use the cauchy integral formula to compute all further extrapolants.
|
|
*/
|
|
BOOST_AUTO_TEST_CASE(first_approximation)
|
|
{
|
|
DefaultPrecision(ambient_precision);
|
|
|
|
|
|
bertini::System sys;
|
|
Var x = Variable::Make("x"), t = Variable::Make("t");
|
|
VariableGroup vars{x};
|
|
sys.AddVariableGroup(vars);
|
|
sys.AddPathVariable(t);
|
|
// Define homotopy system
|
|
sys.AddFunction( pow(x-1,3)*(1-t) + (pow(x,3) + 1)*t);
|
|
|
|
auto precision_config = PrecisionConfig(sys);
|
|
|
|
TrackerType tracker(sys);
|
|
|
|
bertini::tracking::SteppingConfig stepping_preferences;
|
|
bertini::tracking::NewtonConfig newton_preferences;
|
|
|
|
tracker.Setup(TestedPredictor,
|
|
1e-5,
|
|
1e5,
|
|
stepping_preferences,
|
|
newton_preferences);
|
|
|
|
tracker.PrecisionSetup(precision_config);
|
|
|
|
auto origin = BCT(0,0);
|
|
Vec<BCT> x_origin(1);
|
|
x_origin << BCT(1,0);
|
|
|
|
Vec<BCT> first_approx(1);
|
|
auto time = ComplexFromString("0.1");
|
|
Vec<BCT> sample(1);
|
|
sample << ComplexFromString("0.5","0"); // f(.1) = 5.000000000000001e-01 9.084258952712920e-17 from bertini classic
|
|
|
|
#ifdef B2_OBSERVE_TRACKERS
|
|
bertini::tracking::GoryDetailLogger<TrackerType> tons_of_detail;
|
|
tracker.AddObserver(tons_of_detail);
|
|
#endif
|
|
|
|
TestedEGType my_endgame(tracker);
|
|
|
|
|
|
|
|
auto first_approx_success = my_endgame.InitialApproximation(time,sample,origin,first_approx);
|
|
BOOST_CHECK(first_approx_success == SuccessCode::Success);
|
|
BOOST_CHECK((first_approx - x_origin).template lpNorm<Eigen::Infinity>() < 1e-2);
|
|
BOOST_CHECK(my_endgame.CycleNumber() == 3);
|
|
|
|
}
|
|
|
|
/**
|
|
The function tested is ComputeFirstApproximation. This function is the culmination of tracking samples until our estimation of
|
|
c over k is stabilized and we have our Cauchy loop ratios within a tolerance. After this we will use the cauchy integral formula to compute all further extrapolants.
|
|
|
|
Specifically this test case will be attempting to do this with a target time that is not the origin.
|
|
*/
|
|
BOOST_AUTO_TEST_CASE(first_approximation_nonzero_target_time)
|
|
{
|
|
DefaultPrecision(ambient_precision);
|
|
|
|
System sys;
|
|
Var x = Variable::Make("x");
|
|
Var t = Variable::Make("t");
|
|
|
|
sys.AddFunction(pow(x-1,3)*(1-t) + (pow(x,3)+1)*t);
|
|
|
|
VariableGroup vars{x};
|
|
sys.AddVariableGroup(vars);
|
|
sys.AddPathVariable(t);
|
|
|
|
|
|
auto precision_config = PrecisionConfig(sys);
|
|
|
|
TrackerType tracker(sys);
|
|
|
|
bertini::tracking::SteppingConfig stepping_preferences;
|
|
bertini::tracking::NewtonConfig newton_preferences;
|
|
|
|
tracker.Setup(TestedPredictor,
|
|
1e-5,
|
|
1e5,
|
|
stepping_preferences,
|
|
newton_preferences);
|
|
|
|
tracker.PrecisionSetup(precision_config);
|
|
|
|
bertini::TimeCont<BCT> pseg_times;
|
|
bertini::SampCont<BCT> pseg_samples;
|
|
|
|
auto start_time = ComplexFromString("0.2");
|
|
Vec<BCT> start_sample(1);
|
|
auto target_time = ComplexFromString(".15","-.01");
|
|
Vec<BCT> first_approx(1);
|
|
Vec<BCT> x_to_check_against(1);
|
|
x_to_check_against << ComplexFromString("0.424892","0.0136983");
|
|
|
|
pseg_times.push_back(start_time);
|
|
start_sample << ComplexFromString("3.603621541081173e-01", "2.859583229930518e-18"); //
|
|
pseg_samples.push_back(start_sample);
|
|
|
|
TestedEGType my_endgame(tracker);
|
|
|
|
my_endgame.SetPSEGSamples(pseg_samples);
|
|
my_endgame.SetPSEGTimes(pseg_times);
|
|
|
|
#ifdef B2_OBSERVE_TRACKERS
|
|
bertini::tracking::GoryDetailLogger<TrackerType> tons_of_detail;
|
|
tracker.AddObserver(tons_of_detail);
|
|
#endif
|
|
|
|
|
|
auto first_approx_success = my_endgame.InitialApproximation(start_time,start_sample,target_time,first_approx);
|
|
|
|
BOOST_CHECK((first_approx - x_to_check_against).template lpNorm<Eigen::Infinity>() < 1e-2);
|
|
BOOST_CHECK(my_endgame.CycleNumber() == 1);
|
|
|
|
}// end first_approximation_using_pseg_nonzero_target_time
|
|
|
|
|
|
/**
|
|
This test case uses all the sample points collected by CircleTrack around a non-singular point to compute an extrapolant using the
|
|
trapezoidal rule for integration.
|
|
*/
|
|
BOOST_AUTO_TEST_CASE(compute_cauchy_approximation_cycle_num_1)
|
|
{
|
|
DefaultPrecision(ambient_precision);
|
|
|
|
System sys;
|
|
Var x = Variable::Make("x");
|
|
Var t = Variable::Make("t");
|
|
|
|
sys.AddFunction((x-1)*(1-t) + (x+1)*t);
|
|
|
|
VariableGroup vars{x};
|
|
sys.AddVariableGroup(vars);
|
|
sys.AddPathVariable(t);
|
|
|
|
|
|
auto precision_config = PrecisionConfig(sys);
|
|
|
|
TrackerType tracker(sys);
|
|
|
|
bertini::tracking::SteppingConfig stepping_preferences;
|
|
bertini::tracking::NewtonConfig newton_preferences;
|
|
|
|
tracker.Setup(TestedPredictor,
|
|
1e-5,
|
|
1e5,
|
|
stepping_preferences,
|
|
newton_preferences);
|
|
|
|
tracker.PrecisionSetup(precision_config);
|
|
|
|
bertini::TimeCont<BCT> cauchy_times;
|
|
bertini::SampCont<BCT> cauchy_samples;
|
|
|
|
|
|
auto time = ComplexFromString("0.1");
|
|
Vec<BCT> sample(1);
|
|
auto origin = BCT(0,0);
|
|
Vec<BCT> x_origin(1);
|
|
|
|
cauchy_times.push_back(time);
|
|
sample << ComplexFromString("7.999999999999999e-01", "2.168404344971009e-19"); //
|
|
cauchy_samples.push_back(sample);
|
|
x_origin << BCT(1,0);
|
|
|
|
#ifdef B2_OBSERVE_TRACKERS
|
|
bertini::tracking::GoryDetailLogger<TrackerType> tons_of_detail;
|
|
tracker.AddObserver(tons_of_detail);
|
|
#endif
|
|
|
|
TestedEGType my_endgame(tracker);
|
|
|
|
my_endgame.SetCauchyTimes(cauchy_times);
|
|
my_endgame.SetCauchySamples(cauchy_samples);
|
|
|
|
auto first_track_success = my_endgame.CircleTrack(origin);
|
|
|
|
my_endgame.CycleNumber(1); // manually set cycle number to 1 for this test
|
|
|
|
Vec<BCT> first_cauchy_approx;
|
|
auto code = my_endgame.ComputeCauchyApproximationOfXAtT0<BCT>(first_cauchy_approx);
|
|
|
|
BOOST_CHECK((first_cauchy_approx - x_origin).template lpNorm<Eigen::Infinity>() < 1e-5);
|
|
|
|
}// end compute_cauchy_approximation_cycle_num_1
|
|
|
|
|
|
|
|
/**
|
|
This test case uses all the sample points collected by CircleTrack around a non-singular point to compute an extrapolant using the
|
|
trapezoidal rule for integration. CircleTrack is called twice to close up the loop.
|
|
*/
|
|
BOOST_AUTO_TEST_CASE(compute_cauchy_approximation_cycle_num_greater_than_1)
|
|
{
|
|
DefaultPrecision(ambient_precision);
|
|
|
|
System sys;
|
|
Var x = Variable::Make("x");
|
|
Var t = Variable::Make("t");
|
|
|
|
sys.AddFunction( pow(x-1,2)*(1-t) + (pow(x,2) + 1)*t);
|
|
|
|
VariableGroup vars{x};
|
|
sys.AddVariableGroup(vars);
|
|
sys.AddPathVariable(t);
|
|
|
|
|
|
auto precision_config = PrecisionConfig(sys);
|
|
|
|
TrackerType tracker(sys);
|
|
|
|
bertini::tracking::SteppingConfig stepping_preferences;
|
|
bertini::tracking::NewtonConfig newton_preferences;
|
|
|
|
tracker.Setup(TestedPredictor,
|
|
1e-5,
|
|
1e5,
|
|
stepping_preferences,
|
|
newton_preferences);
|
|
|
|
tracker.PrecisionSetup(precision_config);
|
|
|
|
bertini::TimeCont<BCT> cauchy_times;
|
|
bertini::SampCont<BCT> cauchy_samples;
|
|
|
|
|
|
|
|
BCT time(1);
|
|
Vec<BCT> sample(1);
|
|
auto origin = BCT(0,0);
|
|
Vec<BCT> x_origin(1);
|
|
|
|
time = ComplexFromString("0.1");
|
|
cauchy_times.push_back(time);
|
|
sample << ComplexFromString("9.000000000000001e-01", "4.358898943540673e-01"); //
|
|
cauchy_samples.push_back(sample);
|
|
x_origin << BCT(1,0);
|
|
|
|
#ifdef B2_OBSERVE_TRACKERS
|
|
bertini::tracking::GoryDetailLogger<TrackerType> tons_of_detail;
|
|
tracker.AddObserver(tons_of_detail);
|
|
#endif
|
|
|
|
TestedEGType my_endgame(tracker);
|
|
|
|
my_endgame.SetCauchyTimes(cauchy_times);
|
|
my_endgame.SetCauchySamples(cauchy_samples);
|
|
|
|
auto first_track_success = my_endgame.CircleTrack(origin);
|
|
auto second_track_success = my_endgame.CircleTrack(origin);
|
|
|
|
my_endgame.CycleNumber(2);
|
|
|
|
Vec<BCT> first_cauchy_approx;
|
|
auto code = my_endgame.ComputeCauchyApproximationOfXAtT0<BCT>(first_cauchy_approx);
|
|
|
|
BOOST_CHECK((first_cauchy_approx - x_origin).template lpNorm<Eigen::Infinity>() < 1e-5);
|
|
}// end compute_cauchy_approximation_cycle_num_greater_than_1
|
|
|
|
|
|
/**
|
|
To actually use the Cauchy integral formula we must track around the origin and collect samples. This is done by ComputeCauchySamples.
|
|
*/
|
|
BOOST_AUTO_TEST_CASE(cauchy_samples_cycle_num_1)
|
|
{
|
|
DefaultPrecision(ambient_precision);
|
|
|
|
System sys;
|
|
Var x = Variable::Make("x");
|
|
Var t = Variable::Make("t");
|
|
|
|
sys.AddFunction((x-1)*(1-t) + (x+1)*t);
|
|
|
|
VariableGroup vars{x};
|
|
sys.AddVariableGroup(vars);
|
|
sys.AddPathVariable(t);
|
|
|
|
|
|
auto precision_config = PrecisionConfig(sys);
|
|
|
|
TrackerType tracker(sys);
|
|
|
|
bertini::tracking::SteppingConfig stepping_preferences;
|
|
bertini::tracking::NewtonConfig newton_preferences;
|
|
|
|
tracker.Setup(TestedPredictor,
|
|
1e-5,
|
|
1e5,
|
|
stepping_preferences,
|
|
newton_preferences);
|
|
|
|
tracker.PrecisionSetup(precision_config);
|
|
|
|
|
|
|
|
Vec<BCT> sample(1);
|
|
auto origin = BCT(0,0);
|
|
|
|
|
|
BCT time = ComplexFromString(".1");
|
|
|
|
sample << ComplexFromString("7.999999999999999e-01", "2.168404344971009e-19"); //
|
|
|
|
#ifdef B2_OBSERVE_TRACKERS
|
|
bertini::tracking::GoryDetailLogger<TrackerType> tons_of_detail;
|
|
tracker.AddObserver(tons_of_detail);
|
|
#endif
|
|
|
|
TestedEGType my_endgame(tracker);
|
|
my_endgame.AddToPSData(time, sample);
|
|
|
|
auto finding_cauchy_samples_success = my_endgame.ComputeCauchySamples(origin);
|
|
|
|
BOOST_CHECK((my_endgame.GetCauchySamples<BCT>().back() - my_endgame.GetCauchySamples<BCT>().front()).template lpNorm<Eigen::Infinity>() < 1e-5);
|
|
BOOST_CHECK(my_endgame.GetCauchySamples<BCT>().size() == 4);
|
|
BOOST_CHECK(my_endgame.CycleNumber() == 1);
|
|
|
|
}// end find_cauchy_samples_cycle_num_1
|
|
|
|
|
|
|
|
|
|
/**
|
|
To actually use the Cauchy integral formula we must track around the origin and collect samples. This is done by ComputeCauchySamples.
|
|
*/
|
|
BOOST_AUTO_TEST_CASE(find_cauchy_samples_cycle_num_greater_than_1)
|
|
{
|
|
DefaultPrecision(ambient_precision);
|
|
|
|
System sys;
|
|
Var x = Variable::Make("x");
|
|
Var t = Variable::Make("t");
|
|
|
|
sys.AddFunction( pow(x-1,2)*(1-t) + (pow(x,2) + 1)*t);
|
|
|
|
VariableGroup vars{x};
|
|
sys.AddVariableGroup(vars);
|
|
sys.AddPathVariable(t);
|
|
|
|
|
|
auto precision_config = PrecisionConfig(sys);
|
|
|
|
TrackerType tracker(sys);
|
|
|
|
bertini::tracking::SteppingConfig stepping_preferences;
|
|
bertini::tracking::NewtonConfig newton_preferences;
|
|
|
|
tracker.Setup(TestedPredictor,
|
|
1e-6,
|
|
1e5,
|
|
stepping_preferences,
|
|
newton_preferences);
|
|
|
|
tracker.PrecisionSetup(precision_config);
|
|
|
|
|
|
auto time = ComplexFromString("0.1");
|
|
|
|
Vec<BCT> sample(1);
|
|
auto origin = BCT(0,0);
|
|
sample << ComplexFromString("9.000000000000001e-01", "4.358898943540673e-01"); //
|
|
|
|
#ifdef B2_OBSERVE_TRACKERS
|
|
bertini::tracking::GoryDetailLogger<TrackerType> tons_of_detail;
|
|
tracker.AddObserver(tons_of_detail);
|
|
#endif
|
|
|
|
TestedEGType my_endgame(tracker);
|
|
|
|
my_endgame.AddToPSData(time, sample);
|
|
auto finding_cauchy_samples_success = my_endgame.ComputeCauchySamples(origin);
|
|
|
|
BOOST_CHECK((my_endgame.GetCauchySamples<BCT>().back() - my_endgame.GetCauchySamples<BCT>().front()).template lpNorm<Eigen::Infinity>() < 1e-6);
|
|
BOOST_CHECK_EQUAL(my_endgame.GetCauchySamples<BCT>().size(), 7);
|
|
BOOST_CHECK_EQUAL(my_endgame.CycleNumber(), 2);
|
|
|
|
}// end find_cauchy_samples_cycle_num_greater_than_1
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
Full blown test to see if we can actually find the non singular point at the origin.
|
|
*/
|
|
BOOST_AUTO_TEST_CASE(full_test_cycle_num_1)
|
|
{
|
|
DefaultPrecision(ambient_precision);
|
|
|
|
System sys;
|
|
Var x = Variable::Make("x");
|
|
Var t = Variable::Make("t");
|
|
|
|
sys.AddFunction((x-1)*(1-t) + (x+1)*t);
|
|
|
|
VariableGroup vars{x};
|
|
sys.AddVariableGroup(vars);
|
|
sys.AddPathVariable(t);
|
|
|
|
|
|
auto precision_config = PrecisionConfig(sys);
|
|
|
|
TrackerType tracker(sys);
|
|
|
|
bertini::tracking::SteppingConfig stepping_preferences;
|
|
bertini::tracking::NewtonConfig newton_preferences;
|
|
|
|
tracker.Setup(TestedPredictor,
|
|
1e-5,
|
|
1e5,
|
|
stepping_preferences,
|
|
newton_preferences);
|
|
|
|
tracker.PrecisionSetup(precision_config);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
auto time = ComplexFromString(".1");
|
|
|
|
Vec<BCT> sample(1);
|
|
sample << ComplexFromString("7.999999999999999e-01", "2.168404344971009e-19"); //
|
|
|
|
Vec<BCT> solution(1);
|
|
solution << BCT(1,0);
|
|
|
|
TestedEGType my_endgame(tracker);
|
|
|
|
#ifdef B2_OBSERVE_TRACKERS
|
|
bertini::tracking::GoryDetailLogger<TrackerType> tons_of_detail;
|
|
tracker.AddObserver(tons_of_detail);
|
|
#endif
|
|
|
|
auto cauchy_endgame_success = my_endgame.Run(time,sample);
|
|
|
|
BOOST_CHECK((my_endgame.FinalApproximation<BCT>() - solution).template lpNorm<Eigen::Infinity>() < 1e-5);
|
|
BOOST_CHECK_EQUAL(my_endgame.CycleNumber(), 1);
|
|
|
|
}// end full_test_cycle_num_1
|
|
|
|
|
|
|
|
|
|
/**
|
|
Full blown test to see if we can actually find the singular point at the origin.
|
|
*/
|
|
BOOST_AUTO_TEST_CASE(full_test_cycle_num_greater_than_1)
|
|
{
|
|
DefaultPrecision(ambient_precision);
|
|
|
|
System sys;
|
|
Var x = Variable::Make("x");
|
|
Var t = Variable::Make("t");
|
|
|
|
sys.AddFunction( pow(x-1,2)*(1-t) + (pow(x,2) + 1)*t);
|
|
|
|
VariableGroup vars{x};
|
|
sys.AddVariableGroup(vars);
|
|
sys.AddPathVariable(t);
|
|
|
|
|
|
auto precision_config = PrecisionConfig(sys);
|
|
|
|
TrackerType tracker(sys);
|
|
|
|
bertini::tracking::SteppingConfig stepping_preferences;
|
|
bertini::tracking::NewtonConfig newton_preferences;
|
|
newton_preferences.max_num_newton_iterations = 2;
|
|
newton_preferences.min_num_newton_iterations = 1;
|
|
|
|
tracker.Setup(TestedPredictor,
|
|
1e-5,
|
|
1e5,
|
|
stepping_preferences,
|
|
newton_preferences);
|
|
|
|
tracker.PrecisionSetup(precision_config);
|
|
|
|
auto time = ComplexFromString("0.1");
|
|
|
|
Vec<BCT> sample(1);
|
|
sample << ComplexFromString("9.000000000000001e-01", "4.358898943540673e-01");
|
|
|
|
Vec<BCT> x_origin(1);
|
|
x_origin << BCT(1,0);
|
|
|
|
|
|
TestedEGType my_endgame(tracker);
|
|
|
|
auto cauchy_endgame_success = my_endgame.Run(time,sample);
|
|
|
|
#ifdef B2_OBSERVE_TRACKERS
|
|
bertini::tracking::GoryDetailLogger<TrackerType> tons_of_detail;
|
|
tracker.AddObserver(tons_of_detail);
|
|
#endif
|
|
|
|
BOOST_CHECK(cauchy_endgame_success==SuccessCode::Success);
|
|
BOOST_CHECK((my_endgame.FinalApproximation<BCT>() - x_origin).template lpNorm<Eigen::Infinity>() < 1e-5);
|
|
BOOST_CHECK_EQUAL(my_endgame.CycleNumber(), 2);
|
|
}// end full_test_cycle_num_greater_than_1
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
Full blown test to see if we can actually find the singular point at the origin.
|
|
*/
|
|
BOOST_AUTO_TEST_CASE(cauchy_endgame_test_cycle_num_greater_than_1_base)
|
|
{
|
|
DefaultPrecision(ambient_precision);
|
|
|
|
System sys;
|
|
Var x = Variable::Make("x");
|
|
Var t = Variable::Make("t");
|
|
|
|
sys.AddFunction( pow(x-1,2)*(1-t) + (pow(x,2) + 1)*t);
|
|
|
|
VariableGroup vars{x};
|
|
sys.AddVariableGroup(vars);
|
|
sys.AddPathVariable(t);
|
|
|
|
|
|
auto precision_config = PrecisionConfig(sys);
|
|
|
|
TrackerType tracker(sys);
|
|
|
|
bertini::tracking::SteppingConfig stepping_preferences;
|
|
bertini::tracking::NewtonConfig newton_preferences;
|
|
newton_preferences.max_num_newton_iterations = 2;
|
|
newton_preferences.min_num_newton_iterations = 1;
|
|
|
|
tracker.Setup(TestedPredictor,
|
|
1e-5,
|
|
1e5,
|
|
stepping_preferences,
|
|
newton_preferences);
|
|
|
|
tracker.PrecisionSetup(precision_config);
|
|
|
|
tracker.ReinitializeInitialStepSize(false);
|
|
|
|
|
|
BCT time(1);
|
|
Vec<BCT> sample(1);
|
|
Vec<BCT> x_origin(1);
|
|
|
|
|
|
time = ComplexFromString("0.1");
|
|
|
|
sample << ComplexFromString("9.000000000000001e-01", "4.358898943540673e-01"); //
|
|
x_origin << BCT(1,0);
|
|
|
|
|
|
TestedEGType my_endgame(tracker);
|
|
auto cauchy_endgame_success = my_endgame.Run(time,sample);
|
|
|
|
#ifdef B2_OBSERVE_TRACKERS
|
|
bertini::tracking::GoryDetailLogger<TrackerType> tons_of_detail;
|
|
tracker.AddObserver(tons_of_detail);
|
|
#endif
|
|
|
|
BOOST_CHECK(cauchy_endgame_success==SuccessCode::Success);
|
|
BOOST_CHECK((my_endgame.FinalApproximation<BCT>() - x_origin).template lpNorm<Eigen::Infinity>() < 1e-5);
|
|
BOOST_CHECK_EQUAL(my_endgame.CycleNumber(), 2);
|
|
}// end cauchy_endgame_test_cycle_num_greater_than_1
|
|
|
|
|
|
|
|
|
|
/**
|
|
Full blown test to see if we can actually find the non singular point at the origin. This example has multiple variables.
|
|
*/
|
|
BOOST_AUTO_TEST_CASE(cauchy_multiple_variables)
|
|
{
|
|
DefaultPrecision(ambient_precision);
|
|
|
|
bertini::System sys;
|
|
Var x = Variable::Make("x"), t = Variable::Make("t"), y = Variable::Make("y");
|
|
VariableGroup vars{x,y};
|
|
sys.AddVariableGroup(vars);
|
|
sys.AddPathVariable(t);
|
|
|
|
sys.AddFunction((pow(x-1,3))*(1-t) + (pow(x,3) + 1)*t);
|
|
sys.AddFunction((pow(y-1,2))*(1-t) + (pow(y,2) + 1)*t);
|
|
|
|
auto precision_config = PrecisionConfig(sys);
|
|
|
|
TrackerType tracker(sys);
|
|
|
|
bertini::tracking::SteppingConfig stepping_preferences;
|
|
bertini::tracking::NewtonConfig newton_preferences;
|
|
|
|
tracker.Setup(TestedPredictor,
|
|
1e-5,
|
|
1e5,
|
|
stepping_preferences,
|
|
newton_preferences);
|
|
|
|
tracker.PrecisionSetup(precision_config);
|
|
|
|
|
|
BCT current_time(1);
|
|
Vec<BCT> current_space(2);
|
|
current_time = ComplexFromString(".1");
|
|
current_space << ComplexFromString("5.000000000000001e-01", "9.084258952712920e-17") ,ComplexFromString("9.000000000000001e-01","4.358898943540673e-01");
|
|
|
|
Vec<BCT> correct(2);
|
|
correct << BCT(1,0),BCT(1,0);
|
|
|
|
EndgameConfig endgame_settings;
|
|
CauchyConfig cauchy_settings;
|
|
SecurityConfig security_settings;
|
|
|
|
TestedEGType my_endgame(tracker,cauchy_settings,endgame_settings,security_settings);
|
|
|
|
#ifdef B2_OBSERVE_TRACKERS
|
|
bertini::tracking::GoryDetailLogger<TrackerType> tons_of_detail;
|
|
tracker.AddObserver(tons_of_detail);
|
|
#endif
|
|
|
|
auto code = my_endgame.Run(current_time,current_space);
|
|
BOOST_CHECK(code == SuccessCode::Success);
|
|
|
|
BOOST_CHECK((my_endgame.FinalApproximation<BCT>() - correct).template lpNorm<Eigen::Infinity>() < 1e-11);
|
|
|
|
}// end cauchy_multiple_variables
|
|
|
|
|
|
|
|
/**
|
|
Test to see if we can compute Cauchy samples around a nonzero target time.
|
|
*/
|
|
BOOST_AUTO_TEST_CASE(compute_cauchy_samples_nonzero_target_time)
|
|
{
|
|
|
|
DefaultPrecision(ambient_precision);
|
|
|
|
System sys;
|
|
Var x = Variable::Make("x");
|
|
Var t = Variable::Make("t");
|
|
|
|
sys.AddFunction(pow(x-1,3)*(1-t) + (pow(x,3)+1)*t);
|
|
|
|
VariableGroup vars{x};
|
|
sys.AddVariableGroup(vars);
|
|
sys.AddPathVariable(t);
|
|
|
|
|
|
auto precision_config = PrecisionConfig(sys);
|
|
|
|
TrackerType tracker(sys);
|
|
|
|
bertini::tracking::SteppingConfig stepping_preferences;
|
|
bertini::tracking::NewtonConfig newton_preferences;
|
|
|
|
tracker.Setup(TestedPredictor,
|
|
1e-5,
|
|
1e5,
|
|
stepping_preferences,
|
|
newton_preferences);
|
|
|
|
tracker.PrecisionSetup(precision_config);
|
|
|
|
bertini::TimeCont<BCT> pseg_times;
|
|
bertini::SampCont<BCT> pseg_samples;
|
|
|
|
auto start_time = ComplexFromString("0.2");
|
|
Vec<BCT> start_sample(1);
|
|
auto target_time = ComplexFromString(".15","-.01");
|
|
Vec<BCT> first_approx(1);
|
|
|
|
start_sample << ComplexFromString("3.603621541081173e-01", "2.859583229930518e-18"); //
|
|
|
|
|
|
|
|
#ifdef B2_OBSERVE_TRACKERS
|
|
bertini::tracking::GoryDetailLogger<TrackerType> tons_of_detail;
|
|
tracker.AddObserver(tons_of_detail);
|
|
#endif
|
|
|
|
EndgameConfig endgame_settings;
|
|
CauchyConfig cauchy_settings;
|
|
SecurityConfig security_settings;
|
|
TestedEGType my_endgame(tracker,cauchy_settings,endgame_settings,security_settings);
|
|
|
|
my_endgame.AddToPSData(start_time, start_sample);
|
|
|
|
auto cauchy_samples_success = my_endgame.ComputeCauchySamples(target_time);
|
|
|
|
|
|
BOOST_CHECK(cauchy_samples_success == SuccessCode::Success);
|
|
}// end compute_cauchy_samples_nonzero_target_time
|
|
|
|
|
|
/**
|
|
Full blown test to see if we can actually track using an endgame to a nonzero target time.
|
|
*/
|
|
BOOST_AUTO_TEST_CASE(cauchy_full_run_nonzero_target_time)
|
|
{
|
|
|
|
DefaultPrecision(ambient_precision);
|
|
|
|
System sys;
|
|
Var x = Variable::Make("x");
|
|
Var t = Variable::Make("t");
|
|
|
|
sys.AddFunction(pow(x-1,3)*(1-t) + (pow(x,3)+1)*t);
|
|
|
|
VariableGroup vars{x};
|
|
sys.AddVariableGroup(vars);
|
|
sys.AddPathVariable(t);
|
|
|
|
|
|
auto precision_config = PrecisionConfig(sys);
|
|
|
|
TrackerType tracker(sys);
|
|
|
|
bertini::tracking::SteppingConfig stepping_preferences;
|
|
bertini::tracking::NewtonConfig newton_preferences;
|
|
|
|
tracker.Setup(TestedPredictor,
|
|
1e-5,
|
|
1e5,
|
|
stepping_preferences,
|
|
newton_preferences);
|
|
|
|
tracker.PrecisionSetup(precision_config);
|
|
|
|
bertini::TimeCont<BCT> pseg_times;
|
|
bertini::SampCont<BCT> pseg_samples;
|
|
|
|
auto start_time = ComplexFromString("0.2");
|
|
Vec<BCT> start_sample(1);
|
|
auto target_time = ComplexFromString(".15","-.01");
|
|
Vec<BCT> first_approx(1);
|
|
Vec<BCT> x_to_check_against(1);
|
|
|
|
start_sample << ComplexFromString("3.603621541081173e-01", "2.859583229930518e-18");
|
|
x_to_check_against << ComplexFromString("4.248924277564006e-01", "1.369835558109531e-02");
|
|
|
|
|
|
|
|
|
|
|
|
bertini::tracking::GoryDetailLogger<TrackerType> tons_of_detail;
|
|
tracker.AddObserver(tons_of_detail);
|
|
|
|
EndgameConfig endgame_settings;
|
|
CauchyConfig cauchy_settings;
|
|
SecurityConfig security_settings;
|
|
TestedEGType my_endgame(tracker,cauchy_settings,endgame_settings,security_settings);
|
|
|
|
auto endgame_success = my_endgame.Run(start_time,start_sample,target_time);
|
|
BOOST_CHECK(endgame_success == SuccessCode::Success);
|
|
|
|
BOOST_CHECK((my_endgame.FinalApproximation<BCT>() - x_to_check_against).template lpNorm<Eigen::Infinity>() < 1e-10);
|
|
|
|
}// end cauchy_full_run_nonzero_target_time
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
Griewank Osborne is a classic example. Here we allow x and y to mix. There are six paths to be tracked and we know there values
|
|
at t = 0.1.
|
|
|
|
Three of these paths will converge to origin and three will diverge to infinity triggering a SecurityMaxNorm issue.
|
|
|
|
This test will check to see if the answer that we converge on compared to the correct answer are withing the track tolerance during
|
|
the endgame.
|
|
*/
|
|
BOOST_AUTO_TEST_CASE(griewank_osborne)
|
|
{
|
|
|
|
|
|
|
|
DefaultPrecision(ambient_precision);
|
|
|
|
bertini::System griewank_osborn_sys;
|
|
Var x = Variable::Make("x"), t = Variable::Make("t"), y = Variable::Make("y");
|
|
VariableGroup vars{x,y};
|
|
griewank_osborn_sys.AddVariableGroup(vars);
|
|
|
|
griewank_osborn_sys.AddFunction((mpq_rational(29,16))*pow(x,3)-2*x*y);
|
|
griewank_osborn_sys.AddFunction((y - pow(x,2)));
|
|
griewank_osborn_sys.Homogenize();
|
|
griewank_osborn_sys.AutoPatch();
|
|
|
|
BOOST_CHECK(griewank_osborn_sys.IsHomogeneous());
|
|
BOOST_CHECK(griewank_osborn_sys.IsPatched());
|
|
|
|
auto griewank_TD = bertini::start_system::TotalDegree(griewank_osborn_sys);
|
|
griewank_TD.Homogenize();
|
|
BOOST_CHECK(griewank_TD.IsHomogeneous());
|
|
BOOST_CHECK(griewank_TD.IsPatched());
|
|
|
|
auto final_griewank_osborn_system = (1-t)*griewank_osborn_sys + t*griewank_TD;
|
|
final_griewank_osborn_system.AddPathVariable(t);
|
|
|
|
|
|
auto precision_config = PrecisionConfig(final_griewank_osborn_system);
|
|
|
|
TrackerType tracker(final_griewank_osborn_system);
|
|
|
|
bertini::tracking::SteppingConfig stepping_preferences;
|
|
bertini::tracking::NewtonConfig newton_preferences;
|
|
|
|
tracker.Setup(TestedPredictor,
|
|
1e-6,
|
|
1e5,
|
|
stepping_preferences,
|
|
newton_preferences);
|
|
|
|
tracker.PrecisionSetup(precision_config);
|
|
|
|
|
|
BCT t_start(1), t_endgame_boundary(0.1);
|
|
std::vector<Vec<BCT> > griewank_solutions;
|
|
std::vector<Vec<BCT> > griewank_homogenized_solutions;
|
|
for (unsigned ii = 0; ii < griewank_TD.NumStartPoints(); ++ii)
|
|
{
|
|
DefaultPrecision(ambient_precision);
|
|
final_griewank_osborn_system.precision(ambient_precision);
|
|
auto start_point = griewank_TD.StartPoint<BCT>(ii);
|
|
|
|
Vec<BCT> result;
|
|
SuccessCode tracking_success;
|
|
|
|
tracking_success = tracker.TrackPath(result,t_start,t_endgame_boundary,start_point);
|
|
BOOST_CHECK(tracking_success==SuccessCode::Success);
|
|
|
|
griewank_homogenized_solutions.push_back(result);
|
|
griewank_solutions.push_back(final_griewank_osborn_system.DehomogenizePoint(result));
|
|
}
|
|
|
|
Vec<BCT> correct(2);
|
|
correct << BCT(0,0),BCT(0,0);
|
|
|
|
EndgameConfig endgame_settings;
|
|
CauchyConfig cauchy_settings;
|
|
SecurityConfig security_settings;
|
|
|
|
TestedEGType my_endgame(tracker,cauchy_settings,endgame_settings,security_settings);
|
|
|
|
#ifdef B2_OBSERVE_TRACKERS
|
|
bertini::tracking::GoryDetailLogger<TrackerType> tons_of_detail;
|
|
tracker.AddObserver(tons_of_detail);
|
|
#endif
|
|
|
|
unsigned num_paths_diverging = 0;
|
|
unsigned num_paths_converging = 0;
|
|
unsigned num_fails = 0;
|
|
|
|
unsigned num_infinite_solutions = 0;
|
|
for (auto& s : griewank_homogenized_solutions) //current_space_values)
|
|
{
|
|
auto init_prec = Precision(s(0));
|
|
DefaultPrecision(init_prec);
|
|
final_griewank_osborn_system.precision(init_prec);
|
|
BCT time_at_correct_prec = t_endgame_boundary;
|
|
Precision(time_at_correct_prec,init_prec);
|
|
|
|
SuccessCode endgame_success = my_endgame.Run(time_at_correct_prec,s);
|
|
|
|
// i took this check out jan 27, 2018. the tracker's precision literally cannot be adjusted as currently written. hence, there's no way to correct a failing test like this. i do hope there isn't something nasty lurking about causing it to fail, but causing other problems as well. i guess it would be nice if the tracker came back in the same precision as the endgame result, but ... do i really care? if i did, i would have to add a ChangePrecision(p) method to all flavors of trackers, but that's not really what they do... they're a tool, and adjust precision according to the input they receive, just like the endgames, and other things.
|
|
// BOOST_CHECK_EQUAL(Precision(my_endgame.FinalApproximation<BCT>()), tracker.CurrentPrecision());
|
|
|
|
if(endgame_success == SuccessCode::Success)
|
|
{
|
|
num_paths_converging++;
|
|
}
|
|
else if(endgame_success == SuccessCode::SecurityMaxNormReached || endgame_success == SuccessCode::GoingToInfinity)
|
|
{
|
|
num_paths_diverging++;
|
|
}
|
|
else
|
|
++num_fails;
|
|
|
|
if (griewank_osborn_sys.DehomogenizePoint(my_endgame.FinalApproximation<BCT>()).template lpNorm<Eigen::Infinity>() > security_settings.max_norm)
|
|
++num_infinite_solutions;
|
|
|
|
}
|
|
BOOST_CHECK(num_paths_converging>=3);
|
|
BOOST_CHECK(num_paths_diverging<=3);
|
|
}//end compute griewank osborne
|
|
|
|
|
|
/**
|
|
In this example we take a decoupled system, homogenize and patch it. Track to endgame boundary and then run our endgame on the space
|
|
values we have.
|
|
|
|
|
|
has six solutions at t = .1:
|
|
0
|
|
0.687592791426802019127961784761 0.0567041721787413764699348206477
|
|
1.11076734170908975052327605226 0.207914822575706710605647487
|
|
|
|
1
|
|
1.02264960658155701356264444257 0.520917033127216794197167359926
|
|
1.11076734170909913190783413484 0.207914822575691493611316218448
|
|
|
|
2
|
|
0.989757601991555768794484038153 -0.57762120530600610801563732366
|
|
1.11076734170909918741898536609 0.20791482257569138952790765984
|
|
|
|
3
|
|
0.687592791426887395278555459299 0.0567041721787893780032385748768
|
|
0.689232658290901023523389312686 -0.207914822575691576878043065335
|
|
|
|
4
|
|
1.02264960658081959931948637747 0.520917033127118696605766956908
|
|
0.689232658292013194430512839668 -0.207914822576518617066069857076
|
|
|
|
5
|
|
0.989757601991599268196007422024 -0.577621205306094375358982164819
|
|
0.689232658290901310861758919599 -0.207914822575714712814276165999
|
|
*/
|
|
BOOST_AUTO_TEST_CASE(total_degree_start_system)
|
|
{
|
|
DefaultPrecision(ambient_precision);
|
|
|
|
Var x = Variable::Make("x");
|
|
Var y = Variable::Make("y");
|
|
Var t = Variable::Make("t");
|
|
|
|
System sys;
|
|
|
|
VariableGroup v{x,y};
|
|
|
|
sys.AddVariableGroup(v);
|
|
|
|
sys.AddFunction(pow(x-1,3));
|
|
sys.AddFunction(pow(y-1,2));
|
|
sys.Homogenize();
|
|
sys.AutoPatch();
|
|
|
|
|
|
BOOST_CHECK(sys.IsHomogeneous());
|
|
BOOST_CHECK(sys.IsPatched());
|
|
|
|
|
|
|
|
auto TD = bertini::start_system::TotalDegree(sys);
|
|
TD.Homogenize();
|
|
BOOST_CHECK(TD.IsHomogeneous());
|
|
BOOST_CHECK(TD.IsPatched());
|
|
|
|
|
|
auto final_system = (1-t)*sys + t*TD;
|
|
final_system.AddPathVariable(t);
|
|
|
|
auto precision_config = PrecisionConfig(final_system);
|
|
|
|
auto tracker = TrackerType(final_system);
|
|
bertini::tracking::SteppingConfig stepping_preferences;
|
|
bertini::tracking::NewtonConfig newton_preferences;
|
|
tracker.Setup(TestedPredictor,
|
|
1e-5, 1e5,
|
|
stepping_preferences, newton_preferences);
|
|
|
|
tracker.PrecisionSetup(precision_config);
|
|
|
|
auto num_paths_to_track{TD.NumStartPoints()};
|
|
BCT t_start(1);
|
|
std::vector<Vec<BCT> > solutions;
|
|
std::vector<Vec<BCT> > homogenized_solutions;
|
|
for (unsigned ii = 0; ii < num_paths_to_track; ++ii)
|
|
{
|
|
DefaultPrecision(ambient_precision);
|
|
BCT t_endgame_boundary{0.1};
|
|
final_system.precision(ambient_precision);
|
|
auto start_point = TD.StartPoint<BCT>(ii);
|
|
|
|
Vec<BCT> result;
|
|
SuccessCode tracking_success;
|
|
|
|
tracking_success = tracker.TrackPath(result,t_start,t_endgame_boundary,start_point);
|
|
BOOST_CHECK(tracking_success==SuccessCode::Success);
|
|
|
|
homogenized_solutions.push_back(result);
|
|
solutions.push_back(final_system.DehomogenizePoint(result));
|
|
|
|
BOOST_CHECK_EQUAL(Precision(result), tracker.CurrentPrecision());
|
|
}
|
|
|
|
Vec<BCT> correct(2);
|
|
correct << BCT(1,0),BCT(1,0);
|
|
|
|
TestedEGType my_endgame(tracker);
|
|
|
|
tracker.Setup(TestedPredictor,
|
|
1e-6, 1e5,
|
|
stepping_preferences, newton_preferences);
|
|
|
|
#ifdef B2_OBSERVE_TRACKERS
|
|
bertini::tracking::GoryDetailLogger<TrackerType> tons_of_detail;
|
|
tracker.AddObserver(tons_of_detail);
|
|
#endif
|
|
|
|
std::vector<Vec<BCT> > endgame_solutions;
|
|
|
|
unsigned num_successful_occurences = 0;
|
|
unsigned num_fails = 0;
|
|
unsigned num_correct = 0;
|
|
for (const auto& s : homogenized_solutions)
|
|
{
|
|
auto eg_prec = Precision(s);
|
|
DefaultPrecision(eg_prec);
|
|
BCT t_endgame_boundary{0.1};
|
|
final_system.precision(eg_prec);
|
|
SuccessCode endgame_success = my_endgame.Run(t_endgame_boundary,s);
|
|
if(endgame_success == SuccessCode::Success)
|
|
{
|
|
++num_successful_occurences;
|
|
|
|
BOOST_CHECK_EQUAL(Precision(my_endgame.FinalApproximation<BCT>()), tracker.CurrentPrecision());
|
|
if((tracker.GetSystem().DehomogenizePoint(my_endgame.FinalApproximation<BCT>())-correct).template lpNorm<Eigen::Infinity>() < 1e-11)
|
|
{
|
|
++num_correct;
|
|
}
|
|
}
|
|
else
|
|
++num_fails;
|
|
}
|
|
BOOST_CHECK_EQUAL(num_successful_occurences,num_paths_to_track);
|
|
BOOST_CHECK_EQUAL(num_fails,0);
|
|
BOOST_CHECK_EQUAL(num_correct,num_paths_to_track);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
Checks that we can do logging of an endgame while running.
|
|
*/
|
|
BOOST_AUTO_TEST_CASE(gory_detail_logging)
|
|
{
|
|
DefaultPrecision(ambient_precision);
|
|
|
|
System sys;
|
|
Var x = Variable::Make("x");
|
|
Var t = Variable::Make("t");
|
|
|
|
sys.AddFunction( pow(x-1,2)*(1-t) + (pow(x,2) + 1)*t);
|
|
|
|
VariableGroup vars{x};
|
|
sys.AddVariableGroup(vars);
|
|
sys.AddPathVariable(t);
|
|
|
|
|
|
auto precision_config = PrecisionConfig(sys);
|
|
|
|
TrackerType tracker(sys);
|
|
|
|
bertini::tracking::SteppingConfig stepping_preferences;
|
|
bertini::tracking::NewtonConfig newton_preferences;
|
|
newton_preferences.max_num_newton_iterations = 2;
|
|
newton_preferences.min_num_newton_iterations = 1;
|
|
|
|
tracker.Setup(TestedPredictor,
|
|
1e-5,
|
|
1e5,
|
|
stepping_preferences,
|
|
newton_preferences);
|
|
|
|
tracker.PrecisionSetup(precision_config);
|
|
|
|
tracker.ReinitializeInitialStepSize(false);
|
|
|
|
|
|
BCT time(1);
|
|
Vec<BCT> sample(1);
|
|
Vec<BCT> x_origin(1);
|
|
|
|
|
|
time = ComplexFromString("0.1");
|
|
|
|
sample << ComplexFromString("9.000000000000001e-01", "4.358898943540673e-01"); //
|
|
x_origin << BCT(1,0);
|
|
|
|
|
|
TestedEGType my_endgame(tracker);
|
|
|
|
|
|
bertini::endgame::GoryDetailLogger<TestedEGType> eg_logger;
|
|
my_endgame.AddObserver(eg_logger);
|
|
|
|
auto cauchy_endgame_success = my_endgame.Run(time,sample);
|
|
|
|
|
|
BOOST_CHECK(cauchy_endgame_success==SuccessCode::Success);
|
|
BOOST_CHECK((my_endgame.FinalApproximation<BCT>() - x_origin).template lpNorm<Eigen::Infinity>() < 1e-5);
|
|
BOOST_CHECK_EQUAL(my_endgame.CycleNumber(), 2);
|
|
}// end cauchy_endgame_test_cycle_num_greater_than_1
|
|
|
|
|