Add files

This commit is contained in:
2025-01-14 01:15:48 +01:00
commit 2f9fcec55b
406 changed files with 87154 additions and 0 deletions

View File

@@ -0,0 +1 @@
build/

View File

@@ -0,0 +1,68 @@
cmake_minimum_required (VERSION 3.4)
project (parameter_homotopy_example)
IF( NOT CMAKE_BUILD_TYPE )
SET( CMAKE_BUILD_TYPE debug)
ENDIF()
message("CMAKE_BUILD_TYPE = ${CMAKE_BUILD_TYPE}")
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wall -g -O0")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O2")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -O2 -g")
include_directories (include)
set(MY_HEADERS
include/parameter_homotopy.hpp
)
set(MY_SOURCES
src/main.cpp
)
include(GenerateExportHeader)
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin)
find_library(B2_LIBRARIES
NAMES "bertini2"
)
find_library(GMP_LIBRARIES
NAMES "gmp"
)
find_library(MPFR_LIBRARIES
NAMES "mpfr"
)
#Prep for compiling against boost
find_package(Boost REQUIRED
COMPONENTS system log)
INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIR})
LINK_DIRECTORIES(${Boost_LIBRARY_DIRS})
find_package (Eigen3 3.3 REQUIRED NO_MODULE)
include_directories(${B2_INCLUDE_DIRS})
add_executable(parameter_homotopy_example ${MY_SOURCES})
target_link_libraries (parameter_homotopy_example ${B2_LIBRARIES} ${MPFR_LIBRARIES} ${GMP_LIBRARIES} Eigen3::Eigen ${Boost_LIBRARIES})
#set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -ltcmalloc")
#set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lprofiler")

View File

@@ -0,0 +1,14 @@
This example illustrates a way to use Bertini2 as an engine to run parameter homotopies.
--
### Compiling
Uses CMake.
1. `cd b2/core/example/parameter_homotopy`
2. `mkdir build && cd build`
3. `cmake ..`
4. `make`
Resulting product `parameter_homotopy` is in `build/bin/`

View File

@@ -0,0 +1,108 @@
#pragma once
#include <bertini2/system.hpp>
namespace demo{
using Node = std::shared_ptr<bertini::node::Node>;
using Variable = std::shared_ptr<bertini::node::Variable>;
using dbl = bertini::dbl;
using mpfr = bertini::mpfr;
auto MakeStep1Parameters()
{
using bertini::Variable::Make;
// make symbolic objects for the parameters
auto param_A = MakeFloat(bertini::RandomComplex(30));
auto param_B = MakeFloat(bertini::RandomComplex(30));
auto param_C = MakeFloat(bertini::RandomComplex(30));
auto param_D = MakeFloat(bertini::RandomComplex(30));
return std::vector<Node>{param_A, param_B, param_C, param_D};
}
template<typename ParamContT>
auto MakeStep2Parameters(ParamContT const& step1_params, Node const& time)
{
using bertini::Variable::Make;
std::vector<Node> steptwo_param_funcs;
std::vector<Variable> steptwo_params;
std::string suffix = "A";
for (const auto& p: step1_params)
{
auto new_param = Variable::Make("param_"+suffix);
steptwo_params.push_back(new_param);
steptwo_param_funcs.push_back((1-time)*new_param + time*p);
++suffix[0];
}
return std::make_tuple(steptwo_param_funcs, steptwo_params);
}
template <typename ParamContT>
auto ConstructSystem(ParamContT const& params)
{
using bertini::Variable::Make;
auto x1 = Variable::Make("x1");
auto x2 = Variable::Make("x2");
auto x3 = Variable::Make("x3");
auto x4 = Variable::Make("x4");
auto f1 = x1*x1*x1*params[0] + x1*x1*x2*params[1] + x1*x2*x2*params[2] + x1*x3*x3*params[3] + x1*x4*x4*params[0]
+ x1*params[1]+ x2*x2*x2*params[2] + x2*x3*x3*params[3] + x2*x4*x4*params[0] + x2*params[1] + 1;
auto f2 = x1*x1*x1*params[2] + x1*x1*x2*params[3] + x1*x2*x2*params[0] + x1*x3*x3*params[1] + x1*x4*x4*params[2]
+ x1*params[3] + x2*x2*x2*params[0] + x2*x3*x3*params[1] + x2*x4*x4*params[2] + x2*params[3] - 1;
auto f3 = x1*x1*x3*params[0] + x1*x2*x3*params[1] + x2*x2*x3*params[2] + x3*x3*x3*params[3] + x3*x4*x4*params[0] + x3*params[1] + 2;
auto f4 = x1*x1*x4*params[2] + x1*x2*x4*params[3] + x2*x2*x4*params[0] + x3*x3*x4*params[1] + x4*x4*x4*params[2] + x4*params[3] - 3;
// make an empty system
bertini::System Sys;
// add the functions. we could elide the `auto` construction above and construct directly into the system if we wanted
Sys.AddFunction(f1);
Sys.AddFunction(f2);
Sys.AddFunction(f3);
Sys.AddFunction(f4);
// make an affine variable group
bertini::VariableGroup vg{x1, x2, x3, x4};
Sys.AddVariableGroup(vg);
return Sys;
}
auto ConstructStart(bertini::System const& sys)
{
return bertini::start_system::TotalDegree(sys);
}
template <typename StartT>
auto ConstructHomotopy(bertini::System const& target_sys, StartT const& start_sys)
{
using bertini::Variable::Make;
auto t = Variable::Make("t");
auto gamma = bertini::Rational::Make(bertini::node::Rational::Rand());
return (1-t)*target_sys + gamma*t*start_sys;
}
} // namespace demo

View File

@@ -0,0 +1,82 @@
#pragma once
#include <bertini2/nag_algorithms/zero_dim_solve.hpp>
#include <bertini2/nag_algorithms/output.hpp>
#include <bertini2/endgames.hpp>
#include <bertini2/system.hpp>
namespace demo{
using TrackerT = bertini::tracking::AMPTracker;
using Tolerances = bertini::algorithm::TolerancesConfig;
using EndgameConfT = bertini::endgame::EndgameConfig;
auto StepOne(bertini::System const& sys)
{
using namespace bertini;
using namespace algorithm;
using EndgameT = typename endgame::EndgameSelector<TrackerT>::Cauchy;
auto zd = bertini::algorithm::ZeroDim<TrackerT, EndgameT, bertini::System, bertini::start_system::TotalDegree>(sys);
zd.DefaultSetup();
auto tols = zd.Get<Tolerances>();
tols.newton_before_endgame = 1e-5;
tols.newton_during_endgame = 1e-6;
zd.Set(tols);
auto& tr = zd.GetTracker();
tr.SetPredictor(bertini::tracking::Predictor::HeunEuler);
tracking::GoryDetailLogger<TrackerT> tr_logger;
// tr.AddObserver(&tr_logger);
endgame::GoryDetailLogger<EndgameT> eg_logger;
zd.GetEndgame().AddObserver(&eg_logger);
auto eg = zd.GetFromEndgame<EndgameConfT>();
eg.final_tolerance = 1e-11;
zd.SetToEndgame(eg);
zd.Solve();
return output::NonsingularSolutions::Extract(zd);
}
template <typename SolnContT>
auto StepTwo(bertini::System const& target_sys, bertini::System const& start_sys, bertini::System const& homotopy, SolnContT const& solns)
{
using namespace bertini;
using namespace tracking;
using namespace algorithm;
auto userss = bertini::start_system::User(start_sys, solns);
auto zd = bertini::algorithm::ZeroDim<TrackerT, typename bertini::endgame::EndgameSelector<TrackerT>::Cauchy, bertini::System, bertini::start_system::User, bertini::policy::RefToGiven>(target_sys, userss, homotopy);
zd.DefaultSetup();
zd.GetTracker().SetPredictor(bertini::tracking::Predictor::HeunEuler);
auto tols = zd.Get<Tolerances>();
tols.newton_before_endgame = 1e-6;
tols.newton_during_endgame = 1e-7;
zd.Set(tols);
auto eg = zd.GetFromEndgame<EndgameConfT>();
eg.final_tolerance = 1e-12;
zd.SetToEndgame(eg);
zd.Solve();
return output::AllSolutions::Extract(zd);
}
} // namespace demo

View File

@@ -0,0 +1,46 @@
// a little bit of code to generate random real numbers, either integral or floating point.
#include <random>
#include <iostream>
#pragma once
namespace demo{
template<typename T>
struct Random
{
static
T Generate()
{
static_assert(std::is_arithmetic<T>::value, "must use an arithmetic type");
return Generate(std::is_integral<T>());
}
private:
static
T Generate(std::true_type)
{
static std::random_device rd;
static std::default_random_engine gen(rd());
static std::uniform_int_distribution<T> dist(std::numeric_limits<T>::min(),std::numeric_limits<T>::max());
return dist(gen);
}
static
T Generate(std::false_type)
{
static std::random_device rd;
static std::default_random_engine gen(rd());
static std::uniform_real_distribution<T> dist(T{-1},T{1});
return dist(gen);
}
};
}

View File

@@ -0,0 +1,72 @@
#include "parameter_homotopy.hpp"
#include "random.hpp"
#include "my_system.hpp"
#include <chrono>
int main()
{
bertini::LoggingInit();
auto step1_params = demo::MakeStep1Parameters();
auto target_sys_step1 = demo::ConstructSystem(step1_params);
std::cout << "your target_system for step 1:\n\n";
std::cout << target_sys_step1 << '\n';
std::cout << "\n\nwith parameter values:\n\n";
for (const auto& p : step1_params)
std::cout << p << " ";
std::cout << '\n';
// now to solve the start system.
auto stepone_solutions = demo::StepOne(target_sys_step1);
std::cout << "done computing the " << stepone_solutions.size() << " step1 solutions, and here they are: \n";
for (auto& iter : stepone_solutions)
std::cout << iter << '\n' << '\n';
auto t = bertini::Variable::Make("t");
auto step2_stuff = demo::MakeStep2Parameters(step1_params, t);
auto homotopy_sys_step2 = demo::ConstructSystem(std::get<0>(step2_stuff));
homotopy_sys_step2.AddPathVariable(t);
auto target_sys_step2 = demo::ConstructSystem(std::get<1>(step2_stuff));
int num_to_step2s = 100;
auto start_allstep2 = std::chrono::high_resolution_clock::now();
for (int ii=0; ii<num_to_step2s; ii++)
{
auto start_iteration = std::chrono::high_resolution_clock::now();
bertini::DefaultPrecision(30);
// iterate over the parameter values. set the
for (auto& p : std::get<1>(step2_stuff))
{
bertini::mpfr v;
bertini::RandomReal(v, 30);
p->precision(30);
p->set_current_value(bertini::dbl(v));
p->set_current_value(v);
}
bertini::DefaultPrecision(16);
// std::cout << "your target system for step2:\n" << target_sys_step2 << '\n';
// for (auto& p : std::get<1>(step2_stuff))
// std::cout << "solving for parameter values " << *p << " " << p->Eval<bertini::dbl>() << '\n';
auto steptwo_solutions = demo::StepTwo(target_sys_step2, target_sys_step1, homotopy_sys_step2, stepone_solutions);
// std::cout << "done computing the " << steptwo_solutions.size() << " step2 solutions, and here they are: \n";
// for (auto& iter : steptwo_solutions)
// std::cout << iter << '\n' << '\n';
std::cout << (std::chrono::high_resolution_clock::now() - start_iteration).count() << '\n';
}
std::cout << "solving " << num_to_step2s << " " << (std::chrono::high_resolution_clock::now() - start_allstep2).count() << '\n';
return 0;
}