33#ifndef BERTINI_SLP_HPP
34#define BERTINI_SLP_HPP
48#include <boost/serialization/utility.hpp>
163 const int BinaryOperations = Add|Subtract | Multiply|Divide | Power | IntPower;
164 const int TrigOperations = Sin|Cos|Tan | Asin|Acos|Atan;
165 const int UnaryOperations = Exp|Log | Negate | Assign | TrigOperations | Sqrt;
167 constexpr bool IsUnary(Operation op)
169 return op & UnaryOperations;
172 constexpr bool IsBinary(Operation op)
174 return op & BinaryOperations;
177 std::string OpcodeToString(Operation op);
201 using Nd = std::shared_ptr<const node::Node>;
215 friend class boost::serialization::access;
217 template <
typename Archive>
218 void serialize(Archive& ar,
const unsigned version) {
235 friend class boost::serialization::access;
237 template <
typename Archive>
238 void serialize(Archive& ar,
const unsigned version) {
255 friend class boost::serialization::access;
257 template <
typename Archive>
258 void serialize(Archive& ar,
const unsigned version) {
273 template<
typename Derived>
274 void Eval(Eigen::MatrixBase<Derived>
const& variable_values)
const
277 using NumT =
typename Derived::Scalar;
297 template<
typename Derived,
typename ComplexT>
298 void Eval(Eigen::MatrixBase<Derived>
const& variable_values, ComplexT
const& time)
const
300 using NumT =
typename Derived::Scalar;
301 static_assert(std::is_same<NumT, ComplexT>::value,
"scalar types must be the same");
319 template<
typename NumT>
325 template <
typename T>
326 void EvalFunctions()
const{
333 template <
typename T>
334 void EvalJacobian()
const{
340 template <
typename T>
341 void EvalTimeDeriv()
const{
356 template<
typename NumT>
359 this->EvalFunctions<NumT>();
361 auto& memory = std::get<std::vector<NumT>>(memory_);
364 for (
int ii = 0; ii < number_of_.Functions; ++ii) {
365 result(ii) = memory[ii + output_locations_.Functions];
380 template<
typename NumT>
383 this->EvalJacobian<NumT>();
385 auto& memory = std::get<std::vector<NumT>>(memory_);
388 for (
int jj =0; jj < number_of_.Variables; ++jj) {
389 for (
int ii = 0; ii < number_of_.Functions; ++ii) {
390 result(ii, jj) = memory[ii+jj*number_of_.Functions + output_locations_.Jacobian];
406 template<
typename NumT>
409 this->EvalTimeDeriv<NumT>();
411 auto& memory = std::get<std::vector<NumT>>(memory_);
414 for (
int ii = 0; ii < number_of_.Functions; ++ii) {
415 result(ii) = memory[ii + output_locations_.TimeDeriv];
425 template<
typename NumT>
427 Vec<NumT> return_me(this->NumFunctions());
437 template<
typename NumT>
439 Mat<NumT> return_me(this->NumFunctions(), this->NumVariables());
449 template<
typename NumT>
451 Vec<NumT> return_me(this->NumFunctions());
457 inline unsigned NumFunctions()
const{
return number_of_.Functions;}
459 inline unsigned NumVariables()
const{
return number_of_.Variables;}
480 void precision(
unsigned new_precision)
const;
488 return this->has_path_variable_;
504 template<
typename Derived>
506 using NumT =
typename Derived::Scalar;
508#ifndef BERTINI_DISABLE_PRECISION_CHECKS
509 if (!std::is_same<NumT,dbl_complex>::value &&
Precision(variable_values)!=this->precision_){
510 std::stringstream err_msg;
511 err_msg <<
"variable_values and SLP must be of same precision. respective precisions: " <<
Precision(variable_values) <<
" " << this->precision_ << std::endl;
512 throw std::runtime_error(err_msg.str());
516 using NumT =
typename Derived::Scalar;
517 auto& memory = std::get<std::vector<NumT>>(memory_);
519 for (
int ii = 0; ii < number_of_.Variables; ++ii) {
521 memory[ii + input_locations_.Variables] = variable_values(ii);
523 is_evaluated_ =
false;
534 template<
typename ComplexT>
537#ifndef BERTINI_DISABLE_PRECISION_CHECKS
539 std::stringstream err_msg;
540 err_msg <<
"time value and SLP must be of same precision. respective precisions: " <<
Precision(time) <<
" " << this->precision_ << std::endl;
541 throw std::runtime_error(err_msg.str());
546 throw std::runtime_error(
"calling Eval with path variable, but this StraightLineProgram doesn't have one.");
549 auto& memory = std::get<std::vector<ComplexT>>(memory_);
551 memory[input_locations_.Time] = time;
552 is_evaluated_ =
false;
572 void AddInstruction(Operation binary_op,
size_t in_loc1,
size_t in_loc2,
size_t out_loc);
581 void AddInstruction(Operation unary_op,
size_t in_loc,
size_t out_loc);
587 void AddNumber(Nd
const num,
size_t loc);
589 template<
typename NumT>
590 auto& GetMemory()
const{
591 return std::get<std::vector<NumT>>(this->memory_);
595 template<
typename NumT>
596 void CopyNumbersIntoMemory()
const;
599 mutable unsigned precision_ = 16;
600 bool has_path_variable_ =
false;
603 OutputLocations output_locations_;
604 InputLocations input_locations_;
606 mutable std::tuple< std::vector<dbl_complex>, std::vector<mpfr_complex> > memory_;
607 std::vector<IntT> integers_;
609 std::vector<size_t> instructions_;
610 std::vector< std::pair<Nd,size_t> > true_values_of_numbers_;
612 mutable bool is_evaluated_ =
false;
616 friend class boost::serialization::access;
618 template <
typename Archive>
619 void serialize(Archive& ar,
const unsigned version) {
622 ar & has_path_variable_;
625 ar & output_locations_;
626 ar & input_locations_;
628 ar & std::get<std::vector<dbl_complex>>(memory_);
629 ar & std::get<std::vector<mpfr_complex>>(memory_);
633 ar & true_values_of_numbers_;
647 public Visitor<node::Variable>,
650 public Visitor<node::Rational>,
651 public Visitor<node::Function>,
652 public Visitor<node::Jacobian>,
653 public Visitor<node::Differential>,
656 public Visitor<node::SumOperator>,
657 public Visitor<node::MultOperator>,
658 public Visitor<node::IntegerPowerOperator>,
659 public Visitor<node::PowerOperator>,
660 public Visitor<node::ExpOperator>,
661 public Visitor<node::LogOperator>,
662 public Visitor<node::NegateOperator>,
663 public Visitor<node::SqrtOperator>,
666 public Visitor<node::SinOperator>,
667 public Visitor<node::ArcSinOperator>,
668 public Visitor<node::CosOperator>,
669 public Visitor<node::ArcCosOperator>,
670 public Visitor<node::TanOperator>,
671 public Visitor<node::ArcTanOperator>,
673 public Visitor<node::special_number::Pi>,
674 public Visitor<node::special_number::E>
687 using Nd = std::shared_ptr<const node::Node>;
688 using SLP = StraightLineProgram;
692 SLP Compile(System
const& sys);
698 virtual void Visit(node::Variable
const& n);
699 virtual void Visit(node::Integer
const& n);
700 virtual void Visit(node::Float
const& n);
701 virtual void Visit(node::Rational
const& n);
702 virtual void Visit(node::Function
const& n);
703 virtual void Visit(node::Jacobian
const& n);
704 virtual void Visit(node::Differential
const& n);
707 virtual void Visit(node::SumOperator
const& n);
708 virtual void Visit(node::MultOperator
const& n);
709 virtual void Visit(node::IntegerPowerOperator
const& n);
710 virtual void Visit(node::PowerOperator
const& n);
711 virtual void Visit(node::ExpOperator
const& n);
712 virtual void Visit(node::LogOperator
const& n);
713 virtual void Visit(node::NegateOperator
const& n);
714 virtual void Visit(node::SqrtOperator
const& n);
718 virtual void Visit(node::SinOperator
const& n);
719 virtual void Visit(node::ArcSinOperator
const& n);
720 virtual void Visit(node::CosOperator
const& n);
721 virtual void Visit(node::ArcCosOperator
const& n);
722 virtual void Visit(node::TanOperator
const& n);
723 virtual void Visit(node::ArcTanOperator
const& n);
725 virtual void Visit(node::special_number::Pi
const& n);
726 virtual void Visit(node::special_number::E
const& n);
734 template<
typename NodeT>
735 void DealWithNumber(NodeT
const& n){
736 auto nd=n.shared_from_this();
737 this->slp_under_construction_.AddNumber(nd, next_available_complex_);
738 this->locations_encountered_nodes_[nd] = next_available_complex_++;
746 size_t next_available_complex_ = 0;
747 size_t next_available_int_ = 0;
751 std::map<Nd, size_t> locations_encountered_nodes_;
752 std::map<IntT, size_t> locations_integers_;
753 std::map<Nd, size_t> locations_top_level_functions_and_derivatives_;
755 SLP slp_under_construction_;
Definition straight_line_program.hpp:197
StraightLineProgram(System const &sys)
Definition straight_line_program.cpp:62
void Eval() const
loops through the instructions in memory and evaluates each operation
Definition straight_line_program.cpp:207
friend std::ostream & operator<<(std::ostream &out, const StraightLineProgram &s)
Overloaded operator for printing to an arbirtary out stream.
Definition straight_line_program.cpp:118
Vec< NumT > GetTimeDeriv() const
creates the Vec<NumT> to be used in the overloaded function
Definition straight_line_program.hpp:450
void SetVariableValues(Eigen::MatrixBase< Derived > const &variable_values) const
Copy the values of the variables from the passed in vector to memory.
Definition straight_line_program.hpp:505
unsigned precision() const
Get the current precision of the SLP.
Definition straight_line_program.hpp:468
void GetFuncValsInPlace(Vec< NumT > &result) const
assignts the computed values of functions into the given vector
Definition straight_line_program.hpp:357
bool HavePathVariable() const
Does this SLP have a path variable?
Definition straight_line_program.hpp:487
void SetPathVariable(ComplexT const &time) const
Copy the current time value to memory.
Definition straight_line_program.hpp:535
Mat< NumT > GetJacobian() const
creates the Vec<NumT> to be used in the overloaded function
Definition straight_line_program.hpp:438
void Eval(Eigen::MatrixBase< Derived > const &variable_values, ComplexT const &time) const
copies the variable values into the Matrix base and the path variables into the complex type time
Definition straight_line_program.hpp:298
void GetJacobianInPlace(Mat< NumT > &result) const
retrieves the computed values of jacobians
Definition straight_line_program.hpp:381
Vec< NumT > GetFuncVals() const
creates the Vec<NumT> to be used in the overloaded function
Definition straight_line_program.hpp:426
void GetTimeDerivInPlace(Vec< NumT > &result) const
copies the values of the time derivatives into your given vector
Definition straight_line_program.hpp:407
The fundamental polynomial system class for Bertini2.
Definition system/system.hpp:99
A strawman class for implementing the visitor pattern.
Definition visitor.hpp:46
The first non-trivial visitor class.
Definition visitor.hpp:62
Bertini extensions of the Eigen linear algebra library.
unsigned Precision(Eigen::MatrixBase< Derived > const &v)
Get the precision of an Eigen object. If the object is empty, it's the precision of a default-constru...
Definition eigen_extensions.hpp:292
Forward declarations for types in the node:: namespace.
The main multiprecision complex number type. This is essentially boost::multiprecision' complex.
Extensions to the Boost.Multiprecision library.
Definition straight_line_program.hpp:249
Definition straight_line_program.hpp:210
Contains the visitor base types.