b2/python/src/zero_dim_export.cpp
2025-01-14 01:15:53 +01:00

251 lines
9.4 KiB
C++

//This file is part of Bertini 2.
//
//python/zero_dim_export.cpp is free software: you can redistribute it and/or modify
//it under the terms of the GNU General Public License as published by
//the Free Software Foundation, either version 3 of the License, or
//(at your option) any later version.
//
//python/zero_dim_export.cpp is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//GNU General Public License for more details.
//
//You should have received a copy of the GNU General Public License
//along with python/zero_dim_export.cpp. If not, see <http://www.gnu.org/licenses/>.
//
// Copyright(C) 2023 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
// 2023
//
//
// python/zero_dim_export.cpp: source file for exposing the zero dim algorithm to python.
#include "zero_dim_export.hpp"
namespace bertini{
namespace python{
template<typename AlgoT>
template<class PyClass>
void ZDVisitor<AlgoT>::visit(PyClass& cl) const
{
cl
.def("solve", &AlgoT::Solve, "run the zero dim algorithm with currently stored settings")
.def("get_tracker", GetTrackerMutable(), return_internal_reference<>(), "get a mutable reference to the Tracker being used")
.def("get_endgame", GetEndgameMutable(), return_internal_reference<>(), "get a mutable reference to the Endgame being used")
.def("solutions", &AlgoT::FinalSolutions, return_internal_reference<>(), "get the solutions at the target time")
.def("solution_metadata", &AlgoT::FinalSolutionMetadata, return_internal_reference<>(), "get the metadata for the solutions at the target time")
.def("endgame_boundary_data", &AlgoT::EndgameBoundaryData, return_internal_reference<>(), "get the data for the state at the endgame boundary (when we switch from regular tracking to endgame tracking")
;
}
void ExportZeroDim(){
scope current_scope;
std::string new_submodule_name(extract<const char*>(current_scope.attr("__name__")));
new_submodule_name.append(".nag_algorithms");
object new_submodule(borrowed(PyImport_AddModule(new_submodule_name.c_str())));
current_scope.attr("nag_algorithms") = new_submodule;
scope new_submodule_scope = new_submodule;
new_submodule_scope.attr("__doc__") = "Algorithms for computing things, like point solutions to square systems (zerodim algorithm).";
ExportZDConfigs();
ExportZDAlgorithms();
}
// a helper function used immediately below. There is no declaration in the header file...
template<typename TrackerT, typename EndgameT, typename SystemT, typename StartSystemT>
void ExportZeroDimSpecific(std::string const& class_name){
using ZeroDimT = algorithm::ZeroDim<TrackerT, EndgameT, SystemT, StartSystemT>;
class_<ZeroDimT, std::shared_ptr<ZeroDimT> >(class_name.c_str(), init<SystemT>())
.def(ZDVisitor<ZeroDimT>())
;
}
void ExportZDAlgorithms(){
{
using TrackerT = bertini::tracking::DoublePrecisionTracker;
ExportZeroDimSpecific<TrackerT, bertini::endgame::EndgameSelector<TrackerT>::PSEG, bertini::System, bertini::start_system::TotalDegree>("ZeroDimPowerSeriesDoublePrecisionTotalDegree");
ExportZeroDimSpecific<TrackerT, bertini::endgame::EndgameSelector<TrackerT>::Cauchy, bertini::System, bertini::start_system::TotalDegree>("ZeroDimCauchyDoublePrecisionTotalDegree");
}
{
using TrackerT = bertini::tracking::MultiplePrecisionTracker;
ExportZeroDimSpecific<TrackerT, bertini::endgame::EndgameSelector<TrackerT>::PSEG, bertini::System, bertini::start_system::TotalDegree>("ZeroDimPowerSeriesFixedMultiplePrecisionTotalDegree");
ExportZeroDimSpecific<TrackerT, bertini::endgame::EndgameSelector<TrackerT>::Cauchy, bertini::System, bertini::start_system::TotalDegree>("ZeroDimCauchyFixedMultiplePrecisionTotalDegree");
}
{
using TrackerT = bertini::tracking::AMPTracker;
ExportZeroDimSpecific<TrackerT, bertini::endgame::EndgameSelector<TrackerT>::PSEG, bertini::System, bertini::start_system::TotalDegree>("ZeroDimPowerSeriesAdaptivePrecisionTotalDegree");
ExportZeroDimSpecific<TrackerT, bertini::endgame::EndgameSelector<TrackerT>::Cauchy, bertini::System, bertini::start_system::TotalDegree>("ZeroDimCauchyAdaptivePrecisionTotalDegree");
}
}
void ExportZDConfigs()
{
using namespace bertini::algorithm;
class_<TolerancesConfig>("TolerancesConfig", init<>())
.def_readwrite("newton_before_endgame", &TolerancesConfig::newton_before_endgame)
.def_readwrite("newton_during_endgame", &TolerancesConfig::newton_during_endgame)
.def_readwrite("final_tolerance", &TolerancesConfig::final_tolerance)
.def_readwrite("path_truncation_threshold", &TolerancesConfig::path_truncation_threshold)
;
class_<MidPathConfig>("MidPathConfig", init<>())
.def_readwrite("same_point_tolerance", &MidPathConfig::same_point_tolerance)
;
class_<AutoRetrackConfig>("AutoRetrackConfig", init<>())
.def_readwrite("midpath_decrease_tolerance_factor", &AutoRetrackConfig::midpath_decrease_tolerance_factor)
;
class_<SharpeningConfig>("SharpeningConfig", init<>())
.def_readwrite("sharpendigits", &SharpeningConfig::sharpendigits)
.def_readwrite("function_residual_tolerance", &SharpeningConfig::function_residual_tolerance)
.def_readwrite("ratio_tolerance", &SharpeningConfig::ratio_tolerance)
;
class_<RegenerationConfig>("RegenerationConfig", init<>())
.def_readwrite("remove_infinite_endpoints", &RegenerationConfig::remove_infinite_endpoints)
.def_readwrite("higher_dimension_check", &RegenerationConfig::higher_dimension_check)
.def_readwrite("start_level", &RegenerationConfig::start_level)
.def_readwrite("newton_before_endgame", &RegenerationConfig::newton_before_endgame)
.def_readwrite("newton_during_endgame", &RegenerationConfig::newton_during_endgame)
.def_readwrite("final_tolerance", &RegenerationConfig::final_tolerance)
;
class_<PostProcessingConfig>("PostProcessingConfig", init<>())
.def_readwrite("real_threshold", &PostProcessingConfig::real_threshold)
.def_readwrite("endpoint_finite_threshold", &PostProcessingConfig::endpoint_finite_threshold)
.def_readwrite("same_point_tolerance", &PostProcessingConfig::same_point_tolerance)
;
class_<ZeroDimConfig<dbl_complex>>("ZeroDimConfigDoublePrec", init<>())
.def_readwrite("start_time", &ZeroDimConfig<dbl_complex>::start_time)
.def_readwrite("target_time", &ZeroDimConfig<dbl_complex>::target_time)
.def_readwrite("endgame_boundary", &ZeroDimConfig<dbl_complex>::endgame_boundary)
;
class_<ZeroDimConfig<mpfr_complex>>("ZeroDimConfigMultiprec", init<>())
.def_readwrite("start_time", &ZeroDimConfig<mpfr_complex>::start_time)
.def_readwrite("target_time", &ZeroDimConfig<mpfr_complex>::target_time)
.def_readwrite("endgame_boundary", &ZeroDimConfig<mpfr_complex>::endgame_boundary)
;
}
template<typename NumT>
void ExposeSolutionMetaData(std::string const& class_name){
using namespace bertini::algorithm;
using MDT = SolutionMetaData<NumT>;
class_<MDT>(class_name.c_str(),init<>())
.def_readwrite("path_index",&MDT::path_index)
.def_readwrite("solution_index",&MDT::solution_index)
.def_readwrite("precision_changed",&MDT::precision_changed)
.def_readwrite("time_of_first_prec_increase",&MDT::time_of_first_prec_increase)
.def_readwrite("max_precision_used",&MDT::max_precision_used)
.def_readwrite("pre_endgame_success",&MDT::pre_endgame_success)
.def_readwrite("condition_number",&MDT::condition_number)
.def_readwrite("newton_residual",&MDT::newton_residual)
.def_readwrite("final_time_used",&MDT::final_time_used)
.def_readwrite("accuracy_estimate",&MDT::accuracy_estimate)
.def_readwrite("accuracy_estimate_user_coords",&MDT::accuracy_estimate_user_coords)
.def_readwrite("cycle_num",&MDT::cycle_num)
.def_readwrite("endgame_success",&MDT::endgame_success, "this is a SuccessCode. 0 means Success. Anything other than 0 means something happened.")
.def_readwrite("function_residual",&MDT::function_residual)
.def_readwrite("multiplicity",&MDT::multiplicity)
.def_readwrite("is_real",&MDT::is_real)
.def_readwrite("is_finite",&MDT::is_finite)
.def_readwrite("is_singular",&MDT::is_singular)
;
}
template<typename NumT>
void ExposeEndgameBoundaryMetaData(std::string const& class_name){
using namespace bertini::algorithm;
using MDT = EGBoundaryMetaData<NumT>;
class_<MDT>(class_name.c_str(),init<>())
.def_readwrite("path_point",&MDT::path_point)
.def_readwrite("success_code",&MDT::success_code)
.def_readwrite("last_used_stepsize",&MDT::last_used_stepsize)
;
}
void ExposeZDMetaData(){
using namespace bertini::algorithm;
class_<AlgorithmMetaData>("AlgorithmMetaData",init<>())
.def_readwrite("number_path_failures",&AlgorithmMetaData::number_path_failures)
.def_readwrite("number_path_successes",&AlgorithmMetaData::number_path_successes)
.def_readwrite("number_paths_tracked",&AlgorithmMetaData::number_paths_tracked)
.def_readwrite("start_time",&AlgorithmMetaData::start_time)
.def_readwrite("elapsed_time",&AlgorithmMetaData::elapsed_time)
;
ExposeSolutionMetaData<mpfr_complex>("SolutionMetaDataMultiPrec");
ExposeSolutionMetaData<dbl_complex>("SolutionMetaDataDoublePrec");
ExposeEndgameBoundaryMetaData<mpfr_complex>("EndgameBoundaryMetaDataMultiPrec");
ExposeEndgameBoundaryMetaData<dbl_complex>("EndgameBoundaryMetaDataDoublePrec");
}
}} // namespaces