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
29# include <boost/serialization/split_member.hpp>
31# include <symengine/basic.h>
32# include <symengine/dict.h>
33# include <symengine/symengine_exception.h>
34# include <symengine/symengine_rcp.h>
35# include <symengine/visitor.h>
54 template <
typename ReturnType,
typename ExpressionType>
58 std::vector<std::pair<SD::Expression, SD::Expression>>;
124 call(ReturnType * output_values,
126 const ReturnType * substitution_values);
133 template <
class Archive>
135 save(Archive &archive,
const unsigned int version)
const;
142 template <
class Archive>
144 load(Archive &archive,
const unsigned int version);
152 template <
class Archive>
154 serialize(Archive &archive,
const unsigned int version);
158 BOOST_SERIALIZATION_SPLIT_MEMBER()
166 template <
typename StreamType>
202 init(
const SymEngine::vec_basic &dependent_functions);
229 call(ReturnType * output_values,
230 const SymEngine::vec_basic &independent_symbols,
231 const ReturnType * substitution_values);
262 template <
typename ReturnType,
typename ExpressionType>
264 :
public SymEngine::BaseVisitor<
265 DictionarySubstitutionVisitor<ReturnType, ExpressionType>>
304 const bool use_cse =
false);
331 const SymEngine::Basic & dependent_function,
332 const bool use_cse =
false);
357 const bool use_cse =
false);
385 const bool use_cse =
false);
420 call(ReturnType *output_values,
const ReturnType *substitution_values);
440 call(
const std::vector<ReturnType> &substitution_values);
447 template <
class Archive>
449 save(Archive &archive,
const unsigned int version)
const;
456 template <
class Archive>
458 load(Archive &archive,
const unsigned int version);
466 template <
class Archive>
468 serialize(Archive &archive,
const unsigned int version);
472 BOOST_SERIALIZATION_SPLIT_MEMBER()
488 template <
typename StreamType>
491 const bool print_independent_symbols =
false,
492 const bool print_dependent_functions =
false,
493 const bool print_cse_reductions =
false)
const;
501# define IMPLEMENT_DSV_BVISIT(Argument) \
502 void bvisit(const Argument &) \
504 AssertThrow(false, ExcNotImplemented()); \
507 IMPLEMENT_DSV_BVISIT(SymEngine::Basic)
508 IMPLEMENT_DSV_BVISIT(SymEngine::Symbol)
509 IMPLEMENT_DSV_BVISIT(SymEngine::Constant)
510 IMPLEMENT_DSV_BVISIT(SymEngine::Integer)
511 IMPLEMENT_DSV_BVISIT(SymEngine::Rational)
512 IMPLEMENT_DSV_BVISIT(SymEngine::RealDouble)
513 IMPLEMENT_DSV_BVISIT(SymEngine::ComplexDouble)
514 IMPLEMENT_DSV_BVISIT(SymEngine::Add)
515 IMPLEMENT_DSV_BVISIT(SymEngine::Mul)
516 IMPLEMENT_DSV_BVISIT(SymEngine::Pow)
517 IMPLEMENT_DSV_BVISIT(SymEngine::Log)
518 IMPLEMENT_DSV_BVISIT(SymEngine::Sin)
519 IMPLEMENT_DSV_BVISIT(SymEngine::Cos)
520 IMPLEMENT_DSV_BVISIT(SymEngine::Tan)
521 IMPLEMENT_DSV_BVISIT(SymEngine::Csc)
522 IMPLEMENT_DSV_BVISIT(SymEngine::Sec)
523 IMPLEMENT_DSV_BVISIT(SymEngine::Cot)
524 IMPLEMENT_DSV_BVISIT(SymEngine::ASin)
525 IMPLEMENT_DSV_BVISIT(SymEngine::ACos)
526 IMPLEMENT_DSV_BVISIT(SymEngine::ATan)
527 IMPLEMENT_DSV_BVISIT(SymEngine::ATan2)
528 IMPLEMENT_DSV_BVISIT(SymEngine::ACsc)
529 IMPLEMENT_DSV_BVISIT(SymEngine::ASec)
530 IMPLEMENT_DSV_BVISIT(SymEngine::ACot)
531 IMPLEMENT_DSV_BVISIT(SymEngine::Sinh)
532 IMPLEMENT_DSV_BVISIT(SymEngine::Cosh)
533 IMPLEMENT_DSV_BVISIT(SymEngine::Tanh)
534 IMPLEMENT_DSV_BVISIT(SymEngine::Csch)
535 IMPLEMENT_DSV_BVISIT(SymEngine::Sech)
536 IMPLEMENT_DSV_BVISIT(SymEngine::Coth)
537 IMPLEMENT_DSV_BVISIT(SymEngine::ASinh)
538 IMPLEMENT_DSV_BVISIT(SymEngine::ACosh)
539 IMPLEMENT_DSV_BVISIT(SymEngine::ATanh)
540 IMPLEMENT_DSV_BVISIT(SymEngine::ACsch)
541 IMPLEMENT_DSV_BVISIT(SymEngine::ACoth)
542 IMPLEMENT_DSV_BVISIT(SymEngine::ASech)
543 IMPLEMENT_DSV_BVISIT(SymEngine::Abs)
544 IMPLEMENT_DSV_BVISIT(SymEngine::Gamma)
545 IMPLEMENT_DSV_BVISIT(SymEngine::LogGamma)
546 IMPLEMENT_DSV_BVISIT(SymEngine::Erf)
547 IMPLEMENT_DSV_BVISIT(SymEngine::Erfc)
548 IMPLEMENT_DSV_BVISIT(SymEngine::Max)
549 IMPLEMENT_DSV_BVISIT(SymEngine::Min)
551# undef IMPLEMENT_DSV_BVISIT
589 template <
typename ReturnType,
typename ExpressionType>
595 dependent_functions));
600 template <
typename ReturnType,
typename ExpressionType>
603 const SymEngine::vec_basic &dependent_functions)
621 SymEngine::vec_pair se_replacements;
622 SymEngine::vec_basic se_reduced_exprs;
623 SymEngine::cse(se_replacements, se_reduced_exprs, dependent_functions);
625 intermediate_symbols_exprs =
634 template <
typename ReturnType,
typename ExpressionType>
637 ReturnType * output_values,
639 const ReturnType * substitution_values)
643 independent_symbols),
644 substitution_values);
649 template <
typename ReturnType,
typename ExpressionType>
652 ReturnType * output_values,
653 const SymEngine::vec_basic &independent_symbols,
654 const ReturnType * substitution_values)
659 SymEngine::map_basic_basic substitution_value_map;
660 for (
unsigned i = 0; i < independent_symbols.size(); ++i)
661 substitution_value_map[independent_symbols[i]] =
662 static_cast<const SymEngine::RCP<const SymEngine::Basic> &
>(
663 ExpressionType(substitution_values[i]));
667 for (
const auto &expression : intermediate_symbols_exprs)
669 const SymEngine::RCP<const SymEngine::Basic> &cse_symbol =
671 const SymEngine::RCP<const SymEngine::Basic> &cse_expr =
673 Assert(substitution_value_map.find(cse_symbol) ==
674 substitution_value_map.end(),
676 "Reduced symbol already appears in substitution map. "
677 "Is there a clash between the reduced symbol name and "
678 "the symbol used for an independent variable?"));
679 substitution_value_map[cse_symbol] =
680 static_cast<const SymEngine::RCP<const SymEngine::Basic> &
>(
681 ExpressionType(ExpressionType(cse_expr)
682 .
template substitute_and_evaluate<ReturnType>(
683 substitution_value_map)));
687 for (
unsigned i = 0; i < reduced_exprs.size(); ++i)
688 output_values[i] = ExpressionType(reduced_exprs[i])
689 .template substitute_and_evaluate<ReturnType>(
690 substitution_value_map);
695 template <
typename ReturnType,
typename ExpressionType>
696 template <
class Archive>
700 const unsigned int )
const
704 ar &intermediate_symbols_exprs;
710 template <
typename ReturnType,
typename ExpressionType>
711 template <
class Archive>
722 ar &intermediate_symbols_exprs;
728 template <
typename ReturnType,
typename ExpressionType>
729 template <
typename StreamType>
732 StreamType &stream)
const
734 stream <<
"Common subexpression elimination: \n";
735 stream <<
" Intermediate reduced expressions: \n";
736 for (
unsigned i = 0; i < intermediate_symbols_exprs.size(); ++i)
738 const SymEngine::RCP<const SymEngine::Basic> &cse_symbol =
739 intermediate_symbols_exprs[i].first;
740 const SymEngine::RCP<const SymEngine::Basic> &cse_expr =
741 intermediate_symbols_exprs[i].second;
742 stream <<
" " << i <<
": " << cse_symbol <<
" = " << cse_expr
746 stream <<
" Final reduced expressions for dependent variables: \n";
747 for (
unsigned i = 0; i < reduced_exprs.size(); ++i)
748 stream <<
" " << i <<
": " << reduced_exprs[i] <<
'\n';
750 stream << std::flush;
755 template <
typename ReturnType,
typename ExpressionType>
763 return (n_reduced_expressions() > 0) ||
764 (n_intermediate_expressions() > 0);
769 template <
typename ReturnType,
typename ExpressionType>
771 CSEDictionaryVisitor<ReturnType,
772 ExpressionType>::n_intermediate_expressions()
const
774 return intermediate_symbols_exprs.size();
779 template <
typename ReturnType,
typename ExpressionType>
784 return reduced_exprs.size();
792 template <
typename ReturnType,
typename ExpressionType>
796 const SD::Expression & output,
804 template <
typename ReturnType,
typename ExpressionType>
807 const SymEngine::vec_basic &inputs,
808 const SymEngine::Basic & output,
812 SD::Expression(output.rcp_from_this()),
818 template <
typename ReturnType,
typename ExpressionType>
821 const SymEngine::vec_basic &inputs,
822 const SymEngine::vec_basic &outputs,
832 template <
typename ReturnType,
typename ExpressionType>
839 independent_symbols.clear();
840 dependent_functions.clear();
842 independent_symbols = inputs;
849 if (use_cse ==
false)
850 dependent_functions = outputs;
859 template <
typename ReturnType,
typename ExpressionType>
862 const std::vector<ReturnType> &substitution_values)
865 dependent_functions.size() == 1,
867 "Cannot use this call function when more than one symbolic expression is to be evaluated."));
869 substitution_values.size() == independent_symbols.size(),
871 "Input substitution vector does not match size of symbol vector."));
874 call(&out, substitution_values.data());
880 template <
typename ReturnType,
typename ExpressionType>
883 ReturnType * output_values,
884 const ReturnType *substitution_values)
889 cse.call(output_values, independent_symbols, substitution_values);
894 SymEngine::map_basic_basic substitution_value_map;
895 for (
unsigned i = 0; i < independent_symbols.size(); ++i)
896 substitution_value_map[independent_symbols[i]] =
897 static_cast<const SymEngine::RCP<const SymEngine::Basic> &
>(
898 ExpressionType(substitution_values[i]));
905 for (
unsigned i = 0; i < dependent_functions.size(); ++i)
907 ExpressionType(dependent_functions[i])
908 .template substitute_and_evaluate<ReturnType>(
909 substitution_value_map);
915 template <
typename ReturnType,
typename ExpressionType>
916 template <
class Archive>
920 const unsigned int version)
const
931 ar &independent_symbols;
932 cse.save(ar, version);
933 ar &dependent_functions;
938 template <
typename ReturnType,
typename ExpressionType>
939 template <
class Archive>
943 const unsigned int version)
953 ar &independent_symbols;
954 cse.load(ar, version);
955 ar &dependent_functions;
960 template <
typename ReturnType,
typename ExpressionType>
961 template <
typename StreamType>
965 const bool print_independent_symbols,
966 const bool print_dependent_functions,
967 const bool print_cse_reductions)
const
969 if (print_independent_symbols)
971 stream <<
"Independent variables: \n";
972 for (
unsigned i = 0; i < independent_symbols.size(); ++i)
973 stream <<
" " << i <<
": " << independent_symbols[i] <<
'\n';
975 stream << std::flush;
979 if (print_cse_reductions && cse.executed())
987 if (print_dependent_functions)
989 stream <<
"Dependent variables: \n";
990 for (
unsigned i = 0; i < dependent_functions.size(); ++i)
991 stream <<
" " << i << dependent_functions[i] <<
'\n';
993 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_NAMESPACE_CLOSE
#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 DEAL_II_HOST_DEVICE_ALWAYS_INLINE const T & value(const T &t)