15#ifndef dealii_differentiation_sd_symengine_number_visitor_internal_h
16#define dealii_differentiation_sd_symengine_number_visitor_internal_h
20#ifdef DEAL_II_WITH_SYMENGINE
28# include <boost/serialization/split_member.hpp>
30# include <symengine/basic.h>
31# include <symengine/dict.h>
32# include <symengine/symengine_exception.h>
33# include <symengine/symengine_rcp.h>
34# include <symengine/visitor.h>
53 template <
typename ReturnType,
typename ExpressionType>
57 std::vector<std::pair<SD::Expression, SD::Expression>>;
123 call(ReturnType *output_values,
125 const ReturnType *substitution_values);
132 template <
class Archive>
134 save(Archive &archive,
const unsigned int version)
const;
141 template <
class Archive>
143 load(Archive &archive,
const unsigned int version);
151 template <
class Archive>
153 serialize(Archive &archive,
const unsigned int version);
157 BOOST_SERIALIZATION_SPLIT_MEMBER()
165 template <
typename StreamType>
201 init(
const SymEngine::vec_basic &dependent_functions);
228 call(ReturnType *output_values,
229 const SymEngine::vec_basic &independent_symbols,
230 const ReturnType *substitution_values);
261 template <
typename ReturnType,
typename ExpressionType>
263 :
public SymEngine::BaseVisitor<
264 DictionarySubstitutionVisitor<ReturnType, ExpressionType>>
303 const bool use_cse =
false);
330 const SymEngine::Basic &dependent_function,
331 const bool use_cse =
false);
356 const bool use_cse =
false);
384 const bool use_cse =
false);
419 call(ReturnType *output_values,
const ReturnType *substitution_values);
439 call(
const std::vector<ReturnType> &substitution_values);
446 template <
class Archive>
448 save(Archive &archive,
const unsigned int version)
const;
455 template <
class Archive>
457 load(Archive &archive,
const unsigned int version);
465 template <
class Archive>
467 serialize(Archive &archive,
const unsigned int version);
471 BOOST_SERIALIZATION_SPLIT_MEMBER()
487 template <
typename StreamType>
490 const bool print_independent_symbols =
false,
491 const bool print_dependent_functions =
false,
492 const bool print_cse_reductions =
false)
const;
500# define IMPLEMENT_DSV_BVISIT(Argument) \
501 void bvisit(const Argument &) \
503 AssertThrow(false, ExcNotImplemented()); \
506 IMPLEMENT_DSV_BVISIT(SymEngine::Basic)
507 IMPLEMENT_DSV_BVISIT(SymEngine::Symbol)
508 IMPLEMENT_DSV_BVISIT(SymEngine::Constant)
509 IMPLEMENT_DSV_BVISIT(SymEngine::Integer)
510 IMPLEMENT_DSV_BVISIT(SymEngine::Rational)
511 IMPLEMENT_DSV_BVISIT(SymEngine::RealDouble)
512 IMPLEMENT_DSV_BVISIT(SymEngine::ComplexDouble)
513 IMPLEMENT_DSV_BVISIT(SymEngine::Add)
514 IMPLEMENT_DSV_BVISIT(SymEngine::Mul)
515 IMPLEMENT_DSV_BVISIT(SymEngine::Pow)
516 IMPLEMENT_DSV_BVISIT(SymEngine::Log)
517 IMPLEMENT_DSV_BVISIT(SymEngine::Sin)
518 IMPLEMENT_DSV_BVISIT(SymEngine::Cos)
519 IMPLEMENT_DSV_BVISIT(SymEngine::Tan)
520 IMPLEMENT_DSV_BVISIT(SymEngine::Csc)
521 IMPLEMENT_DSV_BVISIT(SymEngine::Sec)
522 IMPLEMENT_DSV_BVISIT(SymEngine::Cot)
523 IMPLEMENT_DSV_BVISIT(SymEngine::ASin)
524 IMPLEMENT_DSV_BVISIT(SymEngine::ACos)
525 IMPLEMENT_DSV_BVISIT(SymEngine::ATan)
526 IMPLEMENT_DSV_BVISIT(SymEngine::ATan2)
527 IMPLEMENT_DSV_BVISIT(SymEngine::ACsc)
528 IMPLEMENT_DSV_BVISIT(SymEngine::ASec)
529 IMPLEMENT_DSV_BVISIT(SymEngine::ACot)
530 IMPLEMENT_DSV_BVISIT(SymEngine::Sinh)
531 IMPLEMENT_DSV_BVISIT(SymEngine::Cosh)
532 IMPLEMENT_DSV_BVISIT(SymEngine::Tanh)
533 IMPLEMENT_DSV_BVISIT(SymEngine::Csch)
534 IMPLEMENT_DSV_BVISIT(SymEngine::Sech)
535 IMPLEMENT_DSV_BVISIT(SymEngine::Coth)
536 IMPLEMENT_DSV_BVISIT(SymEngine::ASinh)
537 IMPLEMENT_DSV_BVISIT(SymEngine::ACosh)
538 IMPLEMENT_DSV_BVISIT(SymEngine::ATanh)
539 IMPLEMENT_DSV_BVISIT(SymEngine::ACsch)
540 IMPLEMENT_DSV_BVISIT(SymEngine::ACoth)
541 IMPLEMENT_DSV_BVISIT(SymEngine::ASech)
542 IMPLEMENT_DSV_BVISIT(SymEngine::Abs)
543 IMPLEMENT_DSV_BVISIT(SymEngine::Gamma)
544 IMPLEMENT_DSV_BVISIT(SymEngine::LogGamma)
545 IMPLEMENT_DSV_BVISIT(SymEngine::Erf)
546 IMPLEMENT_DSV_BVISIT(SymEngine::Erfc)
547 IMPLEMENT_DSV_BVISIT(SymEngine::Max)
548 IMPLEMENT_DSV_BVISIT(SymEngine::Min)
550# undef IMPLEMENT_DSV_BVISIT
588 template <
typename ReturnType,
typename ExpressionType>
594 dependent_functions));
599 template <
typename ReturnType,
typename ExpressionType>
602 const SymEngine::vec_basic &dependent_functions)
620 SymEngine::vec_pair se_replacements;
621 SymEngine::vec_basic se_reduced_exprs;
622 SymEngine::cse(se_replacements, se_reduced_exprs, dependent_functions);
624 intermediate_symbols_exprs =
633 template <
typename ReturnType,
typename ExpressionType>
636 ReturnType *output_values,
638 const ReturnType *substitution_values)
642 independent_symbols),
643 substitution_values);
648 template <
typename ReturnType,
typename ExpressionType>
651 ReturnType *output_values,
652 const SymEngine::vec_basic &independent_symbols,
653 const ReturnType *substitution_values)
658 SymEngine::map_basic_basic substitution_value_map;
659 for (
unsigned i = 0; i < independent_symbols.size(); ++i)
660 substitution_value_map[independent_symbols[i]] =
661 static_cast<const SymEngine::RCP<const SymEngine::Basic> &
>(
662 ExpressionType(substitution_values[i]));
666 for (
const auto &expression : intermediate_symbols_exprs)
668 const SymEngine::RCP<const SymEngine::Basic> &cse_symbol =
670 const SymEngine::RCP<const SymEngine::Basic> &cse_expr =
672 Assert(substitution_value_map.find(cse_symbol) ==
673 substitution_value_map.end(),
675 "Reduced symbol already appears in substitution map. "
676 "Is there a clash between the reduced symbol name and "
677 "the symbol used for an independent variable?"));
678 substitution_value_map[cse_symbol] =
679 static_cast<const SymEngine::RCP<const SymEngine::Basic> &
>(
680 ExpressionType(ExpressionType(cse_expr)
681 .
template substitute_and_evaluate<ReturnType>(
682 substitution_value_map)));
686 for (
unsigned i = 0; i < reduced_exprs.size(); ++i)
687 output_values[i] = ExpressionType(reduced_exprs[i])
688 .template substitute_and_evaluate<ReturnType>(
689 substitution_value_map);
694 template <
typename ReturnType,
typename ExpressionType>
695 template <
class Archive>
699 const unsigned int )
const
703 ar &intermediate_symbols_exprs;
709 template <
typename ReturnType,
typename ExpressionType>
710 template <
class Archive>
721 ar &intermediate_symbols_exprs;
727 template <
typename ReturnType,
typename ExpressionType>
728 template <
typename StreamType>
731 StreamType &stream)
const
733 stream <<
"Common subexpression elimination: \n";
734 stream <<
" Intermediate reduced expressions: \n";
735 for (
unsigned i = 0; i < intermediate_symbols_exprs.size(); ++i)
737 const SymEngine::RCP<const SymEngine::Basic> &cse_symbol =
738 intermediate_symbols_exprs[i].first;
739 const SymEngine::RCP<const SymEngine::Basic> &cse_expr =
740 intermediate_symbols_exprs[i].second;
741 stream <<
" " << i <<
": " << cse_symbol <<
" = " << cse_expr
745 stream <<
" Final reduced expressions for dependent variables: \n";
746 for (
unsigned i = 0; i < reduced_exprs.size(); ++i)
747 stream <<
" " << i <<
": " << reduced_exprs[i] <<
'\n';
749 stream << std::flush;
754 template <
typename ReturnType,
typename ExpressionType>
762 return (n_reduced_expressions() > 0) ||
763 (n_intermediate_expressions() > 0);
768 template <
typename ReturnType,
typename ExpressionType>
770 CSEDictionaryVisitor<ReturnType,
771 ExpressionType>::n_intermediate_expressions()
const
773 return intermediate_symbols_exprs.size();
778 template <
typename ReturnType,
typename ExpressionType>
783 return reduced_exprs.size();
791 template <
typename ReturnType,
typename ExpressionType>
795 const SD::Expression &output,
803 template <
typename ReturnType,
typename ExpressionType>
806 const SymEngine::vec_basic &inputs,
807 const SymEngine::Basic &output,
811 SD::Expression(output.rcp_from_this()),
817 template <
typename ReturnType,
typename ExpressionType>
820 const SymEngine::vec_basic &inputs,
821 const SymEngine::vec_basic &outputs,
831 template <
typename ReturnType,
typename ExpressionType>
838 independent_symbols.clear();
839 dependent_functions.clear();
841 independent_symbols = inputs;
848 if (use_cse ==
false)
849 dependent_functions = outputs;
858 template <
typename ReturnType,
typename ExpressionType>
861 const std::vector<ReturnType> &substitution_values)
864 dependent_functions.size() == 1,
866 "Cannot use this call function when more than one symbolic expression is to be evaluated."));
868 substitution_values.size() == independent_symbols.size(),
870 "Input substitution vector does not match size of symbol vector."));
873 call(&out, substitution_values.data());
879 template <
typename ReturnType,
typename ExpressionType>
882 ReturnType *output_values,
883 const ReturnType *substitution_values)
888 cse.call(output_values, independent_symbols, substitution_values);
893 SymEngine::map_basic_basic substitution_value_map;
894 for (
unsigned i = 0; i < independent_symbols.size(); ++i)
895 substitution_value_map[independent_symbols[i]] =
896 static_cast<const SymEngine::RCP<const SymEngine::Basic> &
>(
897 ExpressionType(substitution_values[i]));
904 for (
unsigned i = 0; i < dependent_functions.size(); ++i)
906 ExpressionType(dependent_functions[i])
907 .template substitute_and_evaluate<ReturnType>(
908 substitution_value_map);
914 template <
typename ReturnType,
typename ExpressionType>
915 template <
class Archive>
919 const unsigned int version)
const
930 ar &independent_symbols;
931 cse.save(ar, version);
932 ar &dependent_functions;
937 template <
typename ReturnType,
typename ExpressionType>
938 template <
class Archive>
942 const unsigned int version)
952 ar &independent_symbols;
953 cse.load(ar, version);
954 ar &dependent_functions;
959 template <
typename ReturnType,
typename ExpressionType>
960 template <
typename StreamType>
964 const bool print_independent_symbols,
965 const bool print_dependent_functions,
966 const bool print_cse_reductions)
const
968 if (print_independent_symbols)
970 stream <<
"Independent variables: \n";
971 for (
unsigned i = 0; i < independent_symbols.size(); ++i)
972 stream <<
" " << i <<
": " << independent_symbols[i] <<
'\n';
974 stream << std::flush;
978 if (print_cse_reductions && cse.executed())
986 if (print_dependent_functions)
988 stream <<
"Dependent variables: \n";
989 for (
unsigned i = 0; i < dependent_functions.size(); ++i)
990 stream <<
" " << i << dependent_functions[i] <<
'\n';
992 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
static constexpr DEAL_II_HOST_DEVICE_ALWAYS_INLINE const T & value(const T &t)