Add files
This commit is contained in:
1
core/example/.gitignore
vendored
Normal file
1
core/example/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
CMakeFiles/
|
||||
1
core/example/parameter_homotopy/.gitignore
vendored
Normal file
1
core/example/parameter_homotopy/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
build/
|
||||
68
core/example/parameter_homotopy/CMakeLists.txt
Normal file
68
core/example/parameter_homotopy/CMakeLists.txt
Normal 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")
|
||||
14
core/example/parameter_homotopy/README.md
Normal file
14
core/example/parameter_homotopy/README.md
Normal 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/`
|
||||
108
core/example/parameter_homotopy/include/my_system.hpp
Normal file
108
core/example/parameter_homotopy/include/my_system.hpp
Normal 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
|
||||
|
||||
@@ -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
|
||||
|
||||
46
core/example/parameter_homotopy/include/random.hpp
Normal file
46
core/example/parameter_homotopy/include/random.hpp
Normal 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);
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
72
core/example/parameter_homotopy/src/main.cpp
Normal file
72
core/example/parameter_homotopy/src/main.cpp
Normal 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;
|
||||
}
|
||||
1
core/example/performance_numbers/.gitignore
vendored
Normal file
1
core/example/performance_numbers/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
build/
|
||||
68
core/example/performance_numbers/CMakeLists.txt
Normal file
68
core/example/performance_numbers/CMakeLists.txt
Normal file
@@ -0,0 +1,68 @@
|
||||
cmake_minimum_required (VERSION 3.4)
|
||||
|
||||
project (performance_numbers)
|
||||
|
||||
|
||||
IF( NOT CMAKE_BUILD_TYPE )
|
||||
SET( CMAKE_BUILD_TYPE release)
|
||||
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/construct_system.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(performance_numbers ${MY_SOURCES})
|
||||
|
||||
|
||||
target_link_libraries (performance_numbers ${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")
|
||||
14
core/example/performance_numbers/README.md
Normal file
14
core/example/performance_numbers/README.md
Normal 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/`
|
||||
120
core/example/performance_numbers/include/construct_system.hpp
Normal file
120
core/example/performance_numbers/include/construct_system.hpp
Normal file
@@ -0,0 +1,120 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <bertini2/system.hpp>
|
||||
|
||||
template<typename NumType> using Vec = Eigen::Matrix<NumType, Eigen::Dynamic, 1>;
|
||||
template<typename NumType> using Mat = Eigen::Matrix<NumType, Eigen::Dynamic, Eigen::Dynamic>;
|
||||
using dbl = bertini::dbl;
|
||||
using mpfr = bertini::mpfr;
|
||||
|
||||
namespace demo{
|
||||
|
||||
|
||||
using Node = std::shared_ptr<bertini::node::Node>;
|
||||
using Variable = std::shared_ptr<bertini::node::Variable>;
|
||||
|
||||
|
||||
|
||||
|
||||
auto ConstructSystem1()
|
||||
{
|
||||
using bertini::Variable::Make;
|
||||
using bertini::Integer::Make;
|
||||
using bertini::MakeFloat;
|
||||
|
||||
auto x1 = Variable::Make("x1");
|
||||
auto x2 = Variable::Make("x2");
|
||||
auto x3 = Variable::Make("x3");
|
||||
auto x4 = Variable::Make("x4");
|
||||
|
||||
auto p1 = MakeFloat("3.2");
|
||||
auto p2 = MakeFloat("-2.8");
|
||||
auto p3 = bertini::MakeFloat("3.5");
|
||||
auto p4 = MakeFloat("-3.6");
|
||||
|
||||
std::vector<Node> params{p1, p2, p3, p4};
|
||||
|
||||
auto f1 = pow(x1,3)*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*pow(x3,2)*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*pow(x4,2)*params[0] + x3*params[1] + 2;
|
||||
|
||||
auto f4 = pow(x1,2)*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);
|
||||
|
||||
Sys.Differentiate();
|
||||
|
||||
return Sys;
|
||||
}
|
||||
|
||||
|
||||
template<typename CType>
|
||||
auto GenerateSystemInput(bertini::System S, unsigned int prec=16)
|
||||
{
|
||||
int num_variables = S.NumVariables();
|
||||
|
||||
Vec<CType> v(num_variables);
|
||||
|
||||
bertini::DefaultPrecision(prec);
|
||||
for(int ii = 0; ii < num_variables; ++ii)
|
||||
{
|
||||
v(ii) = CType(3)*bertini::RandomUnit<CType>();
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
template<typename CType>
|
||||
auto GenerateRHS(bertini::System S, unsigned int prec=16)
|
||||
{
|
||||
auto num_functions = S.NumFunctions();
|
||||
|
||||
Vec<CType> b(num_functions);
|
||||
|
||||
bertini::DefaultPrecision(prec);
|
||||
for(int ii = 0; ii < num_functions; ++ii)
|
||||
{
|
||||
b(ii) = CType(3)*bertini::RandomUnit<CType>();
|
||||
}
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
|
||||
template<typename CType>
|
||||
auto GenerateMatrix(int N, unsigned int prec=16)
|
||||
{
|
||||
Mat<CType> A(N,N);
|
||||
|
||||
bertini::DefaultPrecision(prec);
|
||||
for(int ii = 0; ii < N; ++ii)
|
||||
{
|
||||
for(int jj = 0; jj < N; ++jj)
|
||||
{
|
||||
A(ii,jj) = CType(3)*bertini::RandomUnit<CType>();
|
||||
}
|
||||
}
|
||||
|
||||
return A;
|
||||
}
|
||||
|
||||
|
||||
} // namespace demo
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
//
|
||||
// performance_tests.hpp
|
||||
// Xcode_b2
|
||||
//
|
||||
// Created by Jeb Collins University of Mary Washington. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef performance_tests_h
|
||||
#define performance_tests_h
|
||||
#include "construct_system.hpp"
|
||||
|
||||
template<typename CType>
|
||||
void EvalAndLUTests(const bertini::System& S, const bertini::Vec<CType>& v,
|
||||
const bertini::Vec<CType>& b, int num_times)
|
||||
{
|
||||
auto J = S.Jacobian(v);
|
||||
for(int ii = 0; ii < num_times; ++ii)
|
||||
{
|
||||
S.Reset();
|
||||
J = S.Jacobian(v);
|
||||
J.lu().solve(b);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename CType>
|
||||
void MatrixMultTests(const Mat<CType>& A, int num_times)
|
||||
{
|
||||
for(int ii = 0; ii < num_times; ++ii)
|
||||
{
|
||||
A*A;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* performance_tests_h */
|
||||
110
core/example/performance_numbers/src/main.cpp
Normal file
110
core/example/performance_numbers/src/main.cpp
Normal file
@@ -0,0 +1,110 @@
|
||||
#include "performance_tests.hpp"
|
||||
#include <ctime>
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
|
||||
int num_evaluations = 1; ///> Number of times to evaluate the Jacobian in each run
|
||||
int num_test_runs = 5000; ///> number of times to run the test for average
|
||||
int num_precisions = 20 ; ///> number of different precisions to use
|
||||
int max_precision = 308; ///> maximum precision used for testing
|
||||
int matrix_N = 500; ///> size of matrix for matrix multiplication
|
||||
|
||||
std::vector<int> precisions(num_precisions-1);
|
||||
for(int P = 0; P < num_precisions-1; ++P)
|
||||
{
|
||||
precisions[P] = std::floor(16 + ((max_precision)-16.0)/num_precisions*(P));
|
||||
}
|
||||
precisions.push_back(max_precision);
|
||||
|
||||
|
||||
// Compute the time using CPU clock time, not wall clock time.
|
||||
auto start = std::clock();
|
||||
auto end = std::clock();
|
||||
|
||||
auto sys1 = demo::ConstructSystem1();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
auto v_d = demo::GenerateSystemInput<dbl>(sys1);
|
||||
auto b_d = demo::GenerateRHS<dbl>(sys1);
|
||||
auto A_d = demo::GenerateMatrix<dbl>(matrix_N);
|
||||
auto v_mp = demo::GenerateSystemInput<mpfr>(sys1);
|
||||
auto b_mp = demo::GenerateRHS<mpfr>(sys1);
|
||||
auto A_mp = demo::GenerateMatrix<mpfr>(matrix_N);
|
||||
|
||||
|
||||
//Get base number for double precision
|
||||
std::cout << "\n\n\nTesting Jacobian evaluation, matrix multiplication, and LU decomposition in double precision:\n\n";
|
||||
double time_delta_d = 0;
|
||||
for(int ii = 0; ii < num_test_runs; ++ii)
|
||||
{
|
||||
start = std::clock();
|
||||
EvalAndLUTests(sys1, v_d, b_d, num_evaluations);
|
||||
MatrixMultTests(A_d, 100*num_evaluations);
|
||||
end = std::clock();
|
||||
time_delta_d += (double)(end-start)/(double)(CLOCKS_PER_SEC);
|
||||
}
|
||||
time_delta_d = time_delta_d/num_test_runs;
|
||||
|
||||
|
||||
std::cout << "Average time taken:\n";
|
||||
std::cout << time_delta_d << std::endl << std::endl;
|
||||
|
||||
|
||||
// Now work with various precisions for mpfr
|
||||
std::cout << "Testing Jacobian evaluation, matrix multiplication, and LU decomposition in multiple precision:\n\n";
|
||||
Vec<double> time_delta_mp(num_precisions);
|
||||
for(int PP = 0; PP < num_precisions; ++PP)
|
||||
{
|
||||
std::cout << "Evaluating with precision " << precisions[PP] << "...\n";
|
||||
time_delta_mp(PP) = 0;
|
||||
v_mp = demo::GenerateSystemInput<mpfr>(sys1, precisions[PP]);
|
||||
b_mp = demo::GenerateRHS<mpfr>(sys1, Precision(v_mp));
|
||||
sys1.precision(Precision(v_mp));
|
||||
for(int ii = 0; ii < num_test_runs; ++ii)
|
||||
{
|
||||
start = std::clock();
|
||||
EvalAndLUTests(sys1, v_mp, b_mp, num_evaluations);
|
||||
MatrixMultTests(A_mp, 100*num_evaluations);
|
||||
end = std::clock();
|
||||
time_delta_mp(PP) += (double)(end-start)/(double)(CLOCKS_PER_SEC);
|
||||
}
|
||||
time_delta_mp(PP) = time_delta_mp(PP)/num_test_runs;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// std::cout << time_delta_mp << std::endl;
|
||||
|
||||
auto time_factors = time_delta_mp/time_delta_d;
|
||||
|
||||
|
||||
// Compute coefficient for linear fit
|
||||
Mat<double> M(2,2);
|
||||
Vec<double> b(2);
|
||||
|
||||
M(0,0) = num_precisions;
|
||||
M(0,1) = 0;
|
||||
M(1,1) = 0;
|
||||
b(0) = 0; b(1) = 0;
|
||||
for(int ii = 0; ii < num_precisions; ++ii)
|
||||
{
|
||||
M(0,1) += precisions[ii];
|
||||
M(1,1) += pow(precisions[ii],2);
|
||||
b(0) += time_factors(ii);
|
||||
b(1) += precisions[ii]*time_factors(ii);
|
||||
}
|
||||
M(1,0) = M(0,1);
|
||||
|
||||
Vec<double> x = M.lu().solve(b);
|
||||
|
||||
// std::cout << x(0) << std::endl;
|
||||
std::cout << "y(P) = "<< x(1)<<"*P + "<< x(0) << std::endl;
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user