16#ifndef dealii_differentiation_sd_symengine_number_visitor_internal_h
17#define dealii_differentiation_sd_symengine_number_visitor_internal_h
21#ifdef DEAL_II_WITH_SYMENGINE
25# include <symengine/basic.h>
26# include <symengine/dict.h>
27# include <symengine/symengine_exception.h>
28# include <symengine/symengine_rcp.h>
31# include <symengine/visitor.h>
41# include <boost/serialization/split_member.hpp>
60 template <
typename ReturnType,
typename ExpressionType>
64 std::vector<std::pair<SD::Expression, SD::Expression>>;
130 call(ReturnType * output_values,
132 const ReturnType * substitution_values);
139 template <
class Archive>
141 save(Archive &archive,
const unsigned int version)
const;
148 template <
class Archive>
150 load(Archive &archive,
const unsigned int version);
158 template <
class Archive>
160 serialize(Archive &archive,
const unsigned int version);
164 BOOST_SERIALIZATION_SPLIT_MEMBER()
172 template <
typename StreamType>
208 init(
const SymEngine::vec_basic &dependent_functions);
235 call(ReturnType * output_values,
236 const SymEngine::vec_basic &independent_symbols,
237 const ReturnType * substitution_values);
268 template <
typename ReturnType,
typename ExpressionType>
270 :
public SymEngine::BaseVisitor<
271 DictionarySubstitutionVisitor<ReturnType, ExpressionType>>
310 const bool use_cse =
false);
337 const SymEngine::Basic & dependent_function,
338 const bool use_cse =
false);
363 const bool use_cse =
false);
391 const bool use_cse =
false);
426 call(ReturnType *output_values,
const ReturnType *substitution_values);
446 call(
const std::vector<ReturnType> &substitution_values);
453 template <
class Archive>
455 save(Archive &archive,
const unsigned int version)
const;
462 template <
class Archive>
464 load(Archive &archive,
const unsigned int version);
472 template <
class Archive>
474 serialize(Archive &archive,
const unsigned int version);
478 BOOST_SERIALIZATION_SPLIT_MEMBER()
494 template <
typename StreamType>
497 const bool print_independent_symbols =
false,
498 const bool print_dependent_functions =
false,
499 const bool print_cse_reductions =
false)
const;
507# define IMPLEMENT_DSV_BVISIT(Argument) \
508 void bvisit(const Argument &) \
510 AssertThrow(false, ExcNotImplemented()); \
513 IMPLEMENT_DSV_BVISIT(SymEngine::Basic)
514 IMPLEMENT_DSV_BVISIT(SymEngine::Symbol)
515 IMPLEMENT_DSV_BVISIT(SymEngine::Constant)
516 IMPLEMENT_DSV_BVISIT(SymEngine::Integer)
517 IMPLEMENT_DSV_BVISIT(SymEngine::Rational)
518 IMPLEMENT_DSV_BVISIT(SymEngine::RealDouble)
519 IMPLEMENT_DSV_BVISIT(SymEngine::ComplexDouble)
520 IMPLEMENT_DSV_BVISIT(SymEngine::Add)
521 IMPLEMENT_DSV_BVISIT(SymEngine::Mul)
522 IMPLEMENT_DSV_BVISIT(SymEngine::Pow)
523 IMPLEMENT_DSV_BVISIT(SymEngine::Log)
524 IMPLEMENT_DSV_BVISIT(SymEngine::Sin)
525 IMPLEMENT_DSV_BVISIT(SymEngine::Cos)
526 IMPLEMENT_DSV_BVISIT(SymEngine::Tan)
527 IMPLEMENT_DSV_BVISIT(SymEngine::Csc)
528 IMPLEMENT_DSV_BVISIT(SymEngine::Sec)
529 IMPLEMENT_DSV_BVISIT(SymEngine::Cot)
530 IMPLEMENT_DSV_BVISIT(SymEngine::ASin)
531 IMPLEMENT_DSV_BVISIT(SymEngine::ACos)
532 IMPLEMENT_DSV_BVISIT(SymEngine::ATan)
533 IMPLEMENT_DSV_BVISIT(SymEngine::ATan2)
534 IMPLEMENT_DSV_BVISIT(SymEngine::ACsc)
535 IMPLEMENT_DSV_BVISIT(SymEngine::ASec)
536 IMPLEMENT_DSV_BVISIT(SymEngine::ACot)
537 IMPLEMENT_DSV_BVISIT(SymEngine::Sinh)
538 IMPLEMENT_DSV_BVISIT(SymEngine::Cosh)
539 IMPLEMENT_DSV_BVISIT(SymEngine::Tanh)
540 IMPLEMENT_DSV_BVISIT(SymEngine::Csch)
541 IMPLEMENT_DSV_BVISIT(SymEngine::Sech)
542 IMPLEMENT_DSV_BVISIT(SymEngine::Coth)
543 IMPLEMENT_DSV_BVISIT(SymEngine::ASinh)
544 IMPLEMENT_DSV_BVISIT(SymEngine::ACosh)
545 IMPLEMENT_DSV_BVISIT(SymEngine::ATanh)
546 IMPLEMENT_DSV_BVISIT(SymEngine::ACsch)
547 IMPLEMENT_DSV_BVISIT(SymEngine::ACoth)
548 IMPLEMENT_DSV_BVISIT(SymEngine::ASech)
549 IMPLEMENT_DSV_BVISIT(SymEngine::Abs)
550 IMPLEMENT_DSV_BVISIT(SymEngine::Gamma)
551 IMPLEMENT_DSV_BVISIT(SymEngine::LogGamma)
552 IMPLEMENT_DSV_BVISIT(SymEngine::Erf)
553 IMPLEMENT_DSV_BVISIT(SymEngine::Erfc)
554 IMPLEMENT_DSV_BVISIT(SymEngine::Max)
555 IMPLEMENT_DSV_BVISIT(SymEngine::Min)
557# undef IMPLEMENT_DSV_BVISIT
595 template <
typename ReturnType,
typename ExpressionType>
601 dependent_functions));
606 template <
typename ReturnType,
typename ExpressionType>
609 const SymEngine::vec_basic &dependent_functions)
627 SymEngine::vec_pair se_replacements;
628 SymEngine::vec_basic se_reduced_exprs;
629 SymEngine::cse(se_replacements, se_reduced_exprs, dependent_functions);
631 intermediate_symbols_exprs =
640 template <
typename ReturnType,
typename ExpressionType>
643 ReturnType * output_values,
645 const ReturnType * substitution_values)
649 independent_symbols),
650 substitution_values);
655 template <
typename ReturnType,
typename ExpressionType>
658 ReturnType * output_values,
659 const SymEngine::vec_basic &independent_symbols,
660 const ReturnType * substitution_values)
665 SymEngine::map_basic_basic substitution_value_map;
666 for (
unsigned i = 0; i < independent_symbols.size(); ++i)
667 substitution_value_map[independent_symbols[i]] =
668 static_cast<const SymEngine::RCP<const SymEngine::Basic> &
>(
669 ExpressionType(substitution_values[i]));
673 for (
unsigned i = 0; i < intermediate_symbols_exprs.size(); ++i)
675 const SymEngine::RCP<const SymEngine::Basic> &cse_symbol =
676 intermediate_symbols_exprs[i].first;
677 const SymEngine::RCP<const SymEngine::Basic> &cse_expr =
678 intermediate_symbols_exprs[i].second;
679 Assert(substitution_value_map.find(cse_symbol) ==
680 substitution_value_map.end(),
682 "Reduced symbol already appears in substitution map. "
683 "Is there a clash between the reduced symbol name and "
684 "the symbol used for an independent variable?"));
685 substitution_value_map[cse_symbol] =
686 static_cast<const SymEngine::RCP<const SymEngine::Basic> &
>(
687 ExpressionType(ExpressionType(cse_expr)
688 .
template substitute_and_evaluate<ReturnType>(
689 substitution_value_map)));
693 for (
unsigned i = 0; i < reduced_exprs.size(); ++i)
694 output_values[i] = ExpressionType(reduced_exprs[i])
695 .template substitute_and_evaluate<ReturnType>(
696 substitution_value_map);
701 template <
typename ReturnType,
typename ExpressionType>
702 template <
class Archive>
706 const unsigned int )
const
710 ar &intermediate_symbols_exprs;
716 template <
typename ReturnType,
typename ExpressionType>
717 template <
class Archive>
728 ar &intermediate_symbols_exprs;
734 template <
typename ReturnType,
typename ExpressionType>
735 template <
typename StreamType>
738 StreamType &stream)
const
740 stream <<
"Common subexpression elimination: \n";
741 stream <<
" Intermediate reduced expressions: \n";
742 for (
unsigned i = 0; i < intermediate_symbols_exprs.size(); ++i)
744 const SymEngine::RCP<const SymEngine::Basic> &cse_symbol =
745 intermediate_symbols_exprs[i].first;
746 const SymEngine::RCP<const SymEngine::Basic> &cse_expr =
747 intermediate_symbols_exprs[i].second;
748 stream <<
" " << i <<
": " << cse_symbol <<
" = " << cse_expr
752 stream <<
" Final reduced expressions for dependent variables: \n";
753 for (
unsigned i = 0; i < reduced_exprs.size(); ++i)
754 stream <<
" " << i <<
": " << reduced_exprs[i] <<
'\n';
756 stream << std::flush;
761 template <
typename ReturnType,
typename ExpressionType>
769 return (n_reduced_expressions() > 0) ||
770 (n_intermediate_expressions() > 0);
775 template <
typename ReturnType,
typename ExpressionType>
777 CSEDictionaryVisitor<ReturnType,
778 ExpressionType>::n_intermediate_expressions()
const
780 return intermediate_symbols_exprs.size();
785 template <
typename ReturnType,
typename ExpressionType>
790 return reduced_exprs.size();
798 template <
typename ReturnType,
typename ExpressionType>
802 const SD::Expression & output,
810 template <
typename ReturnType,
typename ExpressionType>
813 const SymEngine::vec_basic &inputs,
814 const SymEngine::Basic & output,
818 SD::Expression(output.rcp_from_this()),
824 template <
typename ReturnType,
typename ExpressionType>
827 const SymEngine::vec_basic &inputs,
828 const SymEngine::vec_basic &outputs,
838 template <
typename ReturnType,
typename ExpressionType>
845 independent_symbols.clear();
846 dependent_functions.clear();
848 independent_symbols = inputs;
855 if (use_cse ==
false)
856 dependent_functions = outputs;
865 template <
typename ReturnType,
typename ExpressionType>
868 const std::vector<ReturnType> &substitution_values)
871 dependent_functions.size() == 1,
873 "Cannot use this call function when more than one symbolic expression is to be evaluated."));
875 substitution_values.size() == independent_symbols.size(),
877 "Input substitution vector does not match size of symbol vector."));
880 call(&out, substitution_values.data());
886 template <
typename ReturnType,
typename ExpressionType>
889 ReturnType * output_values,
890 const ReturnType *substitution_values)
895 cse.call(output_values, independent_symbols, substitution_values);
900 SymEngine::map_basic_basic substitution_value_map;
901 for (
unsigned i = 0; i < independent_symbols.size(); ++i)
902 substitution_value_map[independent_symbols[i]] =
903 static_cast<const SymEngine::RCP<const SymEngine::Basic> &
>(
904 ExpressionType(substitution_values[i]));
911 for (
unsigned i = 0; i < dependent_functions.size(); ++i)
913 ExpressionType(dependent_functions[i])
914 .template substitute_and_evaluate<ReturnType>(
915 substitution_value_map);
921 template <
typename ReturnType,
typename ExpressionType>
922 template <
class Archive>
926 const unsigned int version)
const
937 ar &independent_symbols;
938 cse.save(ar, version);
939 ar &dependent_functions;
944 template <
typename ReturnType,
typename ExpressionType>
945 template <
class Archive>
949 const unsigned int version)
959 ar &independent_symbols;
960 cse.load(ar, version);
961 ar &dependent_functions;
966 template <
typename ReturnType,
typename ExpressionType>
967 template <
typename StreamType>
971 const bool print_independent_symbols,
972 const bool print_dependent_functions,
973 const bool print_cse_reductions)
const
975 if (print_independent_symbols)
977 stream <<
"Independent variables: \n";
978 for (
unsigned i = 0; i < independent_symbols.size(); ++i)
979 stream <<
" " << i <<
": " << independent_symbols[i] <<
'\n';
981 stream << std::flush;
985 if (print_cse_reductions && cse.executed())
993 if (print_dependent_functions)
995 stream <<
"Dependent variables: \n";
996 for (
unsigned i = 0; i < dependent_functions.size(); ++i)
997 stream <<
" " << i << dependent_functions[i] <<
'\n';
999 stream << std::flush;
CSEDictionaryVisitor()=default
void serialize(Archive &archive, const unsigned int version)
unsigned int n_intermediate_expressions() const
void call(ReturnType *output_values, const SymEngine::vec_basic &independent_symbols, const ReturnType *substitution_values)
symbol_vector_pair intermediate_symbols_exprs
void call(ReturnType *output_values, const types::symbol_vector &independent_symbols, const ReturnType *substitution_values)
types::symbol_vector reduced_exprs
void save(Archive &archive, const unsigned int version) const
void print(StreamType &stream) const
void init(const SymEngine::vec_basic &dependent_functions)
virtual ~CSEDictionaryVisitor()=default
void init(const types::symbol_vector &dependent_functions)
void load(Archive &archive, const unsigned int version)
unsigned int n_reduced_expressions() const
std::vector< std::pair< SD::Expression, SD::Expression > > symbol_vector_pair
ReturnType call(const std::vector< ReturnType > &substitution_values)
void init(const types::symbol_vector &independent_symbols, const Expression &dependent_function, const bool use_cse=false)
void init(const SymEngine::vec_basic &independent_symbols, const SymEngine::Basic &dependent_function, const bool use_cse=false)
SD::types::symbol_vector dependent_functions
void init(const types::symbol_vector &independent_symbols, const types::symbol_vector &dependent_functions, const bool use_cse=false)
void call(ReturnType *output_values, const ReturnType *substitution_values)
DictionarySubstitutionVisitor()=default
void print(StreamType &stream, const bool print_independent_symbols=false, const bool print_dependent_functions=false, const bool print_cse_reductions=false) const
CSEDictionaryVisitor< ReturnType, ExpressionType > cse
virtual ~DictionarySubstitutionVisitor() override=default
void save(Archive &archive, const unsigned int version) const
void serialize(Archive &archive, const unsigned int version)
void init(const SymEngine::vec_basic &independent_symbols, const SymEngine::vec_basic &dependent_functions, const bool use_cse=false)
SD::types::symbol_vector independent_symbols
void load(Archive &archive, const unsigned int version)
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_DISABLE_EXTRA_DIAGNOSTICS
#define DEAL_II_NAMESPACE_CLOSE
#define DEAL_II_ENABLE_EXTRA_DIAGNOSTICS
#define Assert(cond, exc)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcMessage(std::string arg1)
std::vector< std::pair< Expression, Expression > > convert_basic_pair_vector_to_expression_pair_vector(const SymEngine::vec_pair &symbol_value_vector)
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)
std::vector< SD::Expression > symbol_vector
void call(const std::function< RT()> &function, internal::return_value< RT > &ret_val)
static constexpr const T & value(const T &t)