15#ifdef DEAL_II_WITH_SYMENGINE
20# include <boost/archive/text_iarchive.hpp>
21# include <boost/archive/text_oarchive.hpp>
30#ifdef DEAL_II_WITH_SYMENGINE
37 template <
typename ReturnType>
47 template <
typename ReturnType>
58 template <
typename ReturnType>
73 template <
typename ReturnType>
90 template <
typename ReturnType>
99 "Cannot call set_optimization_method() once the optimizer is finalized."));
101# ifndef HAVE_SYMENGINE_LLVM
113 template <
typename ReturnType>
122 template <
typename ReturnType>
131 template <
typename ReturnType>
140 template <
typename ReturnType>
157 template <
typename ReturnType>
166 template <
typename ReturnType>
173 "Cannot register symbols once the optimizer is finalized."));
179 for (
const auto &entry : substitution_map)
182 Assert(SymEngine::is_a<SymEngine::Symbol>(*(symbol.
get_RCP())),
183 ExcMessage(
"Key entry in map is not a symbol."));
189 substitution_map.end());
194 template <
typename ReturnType>
197 const SymEngine::map_basic_basic &substitution_map)
205 template <
typename ReturnType>
212 "Cannot register symbols once the optimizer is finalized."));
214 for (
const auto &symbol : symbols)
226 template <
typename ReturnType>
229 const SymEngine::vec_basic &symbols)
237 template <
typename ReturnType>
246 template <
typename ReturnType>
255 template <
typename ReturnType>
261 "Cannot register functions once the optimizer is finalized."));
268 template <
typename ReturnType>
275 "Cannot register functions once the optimizer is finalized."));
282 template <
typename ReturnType>
285 const SymEngine::vec_basic &functions)
293 template <
typename ReturnType>
302 template <
typename ReturnType>
319 template <
typename ReturnType>
324 ExcMessage(
"Cannot call optimize() more than once."));
362# ifdef HAVE_SYMENGINE_LLVM
363 else if (
typename internal::LLVMOptimizer<ReturnType>::OptimizerType
364 *opt =
dynamic_cast<typename internal::LLVMOptimizer<
370 internal::LLVMOptimizer<ReturnType>>::
396 template <
typename ReturnType>
404 "The optimizer is not configured to perform substitution. "
405 "This action can only performed after optimize() has been called."));
416 Assert(symbol_sub_vec.size() == symbol_vec.size(),
419 for (
unsigned int i = 0; i < symbol_sub_vec.size(); ++i)
424 "The input substitution map is either incomplete, or does "
425 "not match that used in the register_symbols() call."));
431 const std::vector<ReturnType> values =
438 template <
typename ReturnType>
441 const SymEngine::map_basic_basic &substitution_map)
const
449 template <
typename ReturnType>
453 const std::vector<ReturnType> &values)
const
463 template <
typename ReturnType>
466 const SymEngine::vec_basic &symbols,
467 const std::vector<ReturnType> &values)
const
476 template <
typename ReturnType>
479 const std::vector<ReturnType> &substitution_values)
const
484 "The optimizer is not configured to perform substitution. "
485 "This action can only performed after optimize() has been called."));
511# ifdef HAVE_SYMENGINE_LLVM
512 else if (
typename internal::LLVMOptimizer<ReturnType>::OptimizerType
513 *opt =
dynamic_cast<typename internal::LLVMOptimizer<
519 internal::LLVMOptimizer<ReturnType>>
::
533 template <
typename ReturnType>
534 const std::vector<ReturnType> &
540 "The optimizer is not configured to perform evaluation. "
541 "This action can only performed after substitute() has been called."));
548 template <
typename ReturnType>
552 const std::vector<ReturnType> &cached_evaluation)
const
561 const typename map_dependent_expression_to_vector_entry_t::const_iterator
580 auto serialize_and_deserialize_expression =
582 std::ostringstream oss;
584 boost::archive::text_oarchive oa(oss,
585 boost::archive::no_header);
591 std::istringstream iss(oss.str());
592 boost::archive::text_iarchive ia(iss,
593 boost::archive::no_header);
602 serialize_and_deserialize_expression(func);
612 serialize_and_deserialize_expression(e.first);
622 return extract(func, cached_evaluation);
629 "Still cannot find map entry, and there's no hope to recover from this situation."));
633 ExcMessage(
"Function has not been registered."));
636 return cached_evaluation[it->second];
641 template <
typename ReturnType>
648 "The optimizer is not configured to perform evaluation. "
649 "This action can only performed after substitute() has been called."));
656 template <
typename ReturnType>
657 std::vector<ReturnType>
659 const std::vector<Expression> &funcs,
660 const std::vector<ReturnType> &cached_evaluation)
const
662 std::vector<ReturnType> out;
663 out.reserve(funcs.size());
665 for (
const auto &func : funcs)
666 out.emplace_back(
extract(func, cached_evaluation));
673 template <
typename ReturnType>
674 std::vector<ReturnType>
676 const std::vector<Expression> &funcs)
const
681 "The optimizer is not configured to perform evaluation. "
682 "This action can only performed after substitute() has been called."));
688 template <
typename ReturnType>
698 template <
typename ReturnType>
701 const SymEngine::RCP<const SymEngine::Basic> &func)
const
707 if (SymEngine::is_a<SymEngine::Constant>(*func))
709 if (&*func == &*SymEngine::zero)
711 if (&*func == &*SymEngine::one)
713 if (&*func == &*SymEngine::minus_one)
715 if (&*func == &*SymEngine::I)
717 if (&*func == &*SymEngine::Inf)
719 if (&*func == &*SymEngine::NegInf)
721 if (&*func == &*SymEngine::ComplexInf)
723 if (&*func == &*SymEngine::Nan)
731 template <
typename ReturnType>
739 "Cannot register function as the optimizer has already been finalized."));
741 const bool entry_registered =
745 if (entry_registered ==
true &&
748 ExcMessage(
"Function has already been registered."));
750 if (entry_registered ==
false)
760 template <
typename ReturnType>
768 "Cannot register function as the optimizer has already been finalized."));
773 for (
const auto &func : funcs)
775 const bool entry_registered =
779 if (entry_registered ==
true &&
782 ExcMessage(
"Function has already been registered."));
784 if (entry_registered ==
false)
795 template <
typename ReturnType>
798 std::unique_ptr<SymEngine::Visitor> &
optimizer)
817# ifdef HAVE_SYMENGINE_LLVM
818 if (internal::LLVMOptimizer<ReturnType>::supported_by_LLVM)
821 typename internal::LLVMOptimizer<ReturnType>::OptimizerType;
843# include "differentiation/sd/symengine_optimizer.inst"
bool use_symbolic_CSE() const
types::substitution_map independent_variables_symbols
types::symbol_vector dependent_variables_functions
void substitute(const types::substitution_map &substitution_map) const
enum OptimizationFlags flags
void register_scalar_function(const SD::Expression &function)
const types::symbol_vector & get_dependent_functions() const
void create_optimizer(std::unique_ptr< SymEngine::Visitor > &optimizer)
bool ready_for_value_extraction
enum OptimizerType optimization_method() const
void copy_from(const BatchOptimizer &other)
void set_optimization_method(const enum OptimizerType &optimization_method, const enum OptimizationFlags &optimization_flags=OptimizationFlags::optimize_all)
enum OptimizationFlags optimization_flags() const
void register_functions(const types::symbol_vector &functions)
std::vector< ReturnType > dependent_variables_output
enum OptimizerType method
std::size_t n_dependent_variables() const
void register_symbols(const types::substitution_map &substitution_map)
const std::vector< ReturnType > & evaluate() const
void register_function(const Expression &function)
std::unique_ptr< SymEngine::Visitor > optimizer
ReturnType extract(const Expression &func, const std::vector< ReturnType > &cached_evaluation) const
bool is_valid_nonunique_dependent_variable(const SD::Expression &function) const
void register_vector_functions(const types::symbol_vector &functions)
std::size_t n_independent_variables() const
types::symbol_vector get_independent_symbols() const
map_dependent_expression_to_vector_entry_t map_dep_expr_vec_entry
bool values_substituted() const
const SymEngine::RCP< const SymEngine::Basic > & get_RCP() const
const SymEngine::Basic & get_value() const
#define DEAL_II_NAMESPACE_OPEN
constexpr bool running_in_debug_mode()
#define DEAL_II_NAMESPACE_CLOSE
static ::ExceptionBase & ExcNotImplemented()
#define Assert(cond, exc)
static ::ExceptionBase & ExcSymEngineLLVMReturnTypeNotSupported()
static ::ExceptionBase & ExcSymEngineLLVMNotAvailable()
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
static ::ExceptionBase & ExcNotInitialized()
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)
std::vector< NumberType > extract_values(const SD::types::substitution_map &substitution_values)
SD::types::symbol_vector extract_symbols(const SD::types::substitution_map &substitution_values)
SD::types::substitution_map convert_basic_map_to_expression_map(const SymEngine::map_basic_basic &substitution_map)
SD::types::symbol_vector convert_basic_vector_to_expression_vector(const SymEngine::vec_basic &symbol_vector)
SymEngine::vec_basic convert_expression_vector_to_basic_vector(const SD::types::symbol_vector &symbol_vector)
bool use_symbolic_CSE(const enum OptimizationFlags &flags)
std::map< SD::Expression, SD::Expression, internal::ExpressionKeyLess > substitution_map
std::vector< SD::Expression > symbol_vector
Expression substitute(const Expression &expression, const types::substitution_map &substitution_map)
types::substitution_map make_substitution_map(const Expression &symbol, const Expression &value)
constexpr bool values_are_equal(const Number1 &value_1, const Number2 &value_2)