16#ifndef dealii_differentiation_sd_symengine_optimizer_h
17#define dealii_differentiation_sd_symengine_optimizer_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/lambda_double.h>
32# include <symengine/visitor.h>
33# ifdef HAVE_SYMENGINE_LLVM
34# include <symengine/llvm_double.h>
48# include <boost/serialization/split_member.hpp>
49# include <boost/type_traits.hpp>
54# include <type_traits>
76 "SymEngine has not been built with LLVM support.");
83 "The SymEngine LLVM optimizer does not (yet) support the "
84 "selected return type.");
90 template <
typename ReturnType>
121 template <
class StreamType>
183 static_cast<unsigned int>(f2));
215 static_cast<unsigned int>(f2));
261 const bool use_agg_opt =
263 const int opt_level = (use_agg_opt ? 3 : 2);
273 template <
class StreamType>
277 s <<
" OptimizationFlags|";
302 template <
typename ReturnType,
typename T =
void>
315 template <
typename ReturnType,
typename T =
void>
319# ifdef HAVE_SYMENGINE_LLVM
329 template <
typename ReturnType,
typename T =
void>
330 struct LLVMOptimizer;
349 template <
typename ReturnType,
typename Optimizer,
typename T =
void>
361 template <
typename ReturnType_,
typename T =
void>
362 struct SupportedOptimizerTypeTraits
364 static const bool is_supported =
false;
366 using ReturnType = void;
372 template <
typename ReturnType_>
373 struct SupportedOptimizerTypeTraits<
375 typename
std::enable_if<std::is_arithmetic<ReturnType_>::value>::type>
377 static const bool is_supported =
true;
380 typename std::conditional<std::is_same<ReturnType_, float>::value,
388 template <
typename ReturnType_>
389 struct SupportedOptimizerTypeTraits<
391 typename
std::enable_if<
392 boost::is_complex<ReturnType_>::value &&
393 std::is_arithmetic<typename ReturnType_::value_type>::value>::type>
395 static const bool is_supported =
true;
397 using ReturnType =
typename std::conditional<
398 std::is_same<ReturnType_, std::complex<float>>::value,
400 std::complex<double>>::type;
405 template <
typename ReturnType_>
406 struct DictionaryOptimizer<
408 typename
std::enable_if<
409 SupportedOptimizerTypeTraits<ReturnType_>::is_supported>::type>
412 typename SupportedOptimizerTypeTraits<ReturnType_>::ReturnType;
414 internal::DictionarySubstitutionVisitor<ReturnType, SD::Expression>;
427 const SymEngine::vec_basic & independent_symbols,
428 const SymEngine::vec_basic & dependent_functions,
432 optimizer.init(independent_symbols,
443 template <
class Archive>
445 save(Archive & archive,
446 const unsigned int version,
449 optimizer.save(archive, version);
458 template <
class Archive>
460 load(Archive & archive,
461 const unsigned int version,
463 const SymEngine::vec_basic & ,
464 const SymEngine::vec_basic & ,
467 optimizer.load(archive, version);
487 template <
typename Stream>
489 print(Stream & stream,
491 const bool print_independent_symbols =
false,
492 const bool print_dependent_functions =
false,
493 const bool print_cse_reductions =
true)
495 optimizer.print(stream,
496 print_independent_symbols,
497 print_dependent_functions,
498 print_cse_reductions);
504 template <
typename ReturnType_>
505 struct LambdaOptimizer<
507 typename
std::enable_if<
508 SupportedOptimizerTypeTraits<ReturnType_>::is_supported>::type>
511 typename std::conditional<!boost::is_complex<ReturnType_>::value,
513 std::complex<double>>::type;
515 !boost::is_complex<ReturnType_>::value,
516 SymEngine::LambdaRealDoubleVisitor,
517 SymEngine::LambdaComplexDoubleVisitor>::type;
530 const SymEngine::vec_basic & independent_symbols,
531 const SymEngine::vec_basic & dependent_functions,
535 optimizer.init(independent_symbols,
546 template <
class Archive>
558 template <
class Archive>
563 const SymEngine::vec_basic & independent_symbols,
564 const SymEngine::vec_basic & dependent_functions,
567 initialize(optimizer,
590 template <
typename StreamType>
604# ifdef HAVE_SYMENGINE_LLVM
605 template <
typename ReturnType_>
606 struct LLVMOptimizer<
608 typename
std::enable_if<std::is_arithmetic<ReturnType_>::value>::type>
611 typename std::conditional<std::is_same<ReturnType_, float>::value,
615 typename std::conditional<std::is_same<ReturnType_, float>::value,
616 SymEngine::LLVMFloatVisitor,
617 SymEngine::LLVMDoubleVisitor>::type;
623 static const bool supported_by_LLVM =
true;
635 initialize(OptimizerType & optimizer,
636 const SymEngine::vec_basic & independent_symbols,
637 const SymEngine::vec_basic & dependent_functions,
638 const enum OptimizationFlags &optimization_flags)
642 optimizer.init(independent_symbols,
654 template <
class Archive>
656 save(Archive &archive,
658 OptimizerType &optimizer)
660 const std::string llvm_compiled_function = optimizer.dumps();
661 archive & llvm_compiled_function;
670 template <
class Archive>
672 load(Archive &archive,
674 OptimizerType &optimizer,
675 const SymEngine::vec_basic & ,
676 const SymEngine::vec_basic & ,
677 const enum OptimizationFlags & )
679 std::string llvm_compiled_function;
680 archive & llvm_compiled_function;
681 optimizer.loads(llvm_compiled_function);
701 template <
typename StreamType>
704 const OptimizerType & ,
719 template <
typename ReturnType_>
720 struct LLVMOptimizer<
722 typename
std::enable_if<
723 boost::is_complex<ReturnType_>::value &&
724 std::is_arithmetic<typename ReturnType_::value_type>::value>::type>
728 using ReturnType =
typename LambdaOptimizer<ReturnType_>::ReturnType;
730 typename LambdaOptimizer<ReturnType_>::OptimizerType;
736 static const bool supported_by_LLVM =
false;
748 initialize(OptimizerType & ,
749 const SymEngine::vec_basic & ,
750 const SymEngine::vec_basic & ,
751 const enum OptimizationFlags & )
762 template <
class Archive>
777 template <
class Archive>
782 const SymEngine::vec_basic & ,
783 const SymEngine::vec_basic & ,
784 const enum OptimizationFlags & )
806 template <
typename StreamType>
809 const OptimizerType & ,
823 template <
typename ReturnType,
typename Optimizer>
824 struct OptimizerHelper<ReturnType,
826 typename
std::enable_if<std::is_same<
828 typename Optimizer::ReturnType>::value>::type>
839 initialize(
typename Optimizer::OptimizerType *optimizer,
840 const SymEngine::vec_basic & independent_symbols,
841 const SymEngine::vec_basic & dependent_functions,
849 Optimizer::initialize(*optimizer,
871 substitute(
typename Optimizer::OptimizerType *optimizer,
872 std::vector<ReturnType> & output_values,
873 const std::vector<ReturnType> & substitution_values)
876 optimizer->call(output_values.data(), substitution_values.data());
885 template <
class Archive>
887 save(Archive & archive,
888 const unsigned int version,
889 typename Optimizer::OptimizerType *optimizer)
896 Optimizer::save(archive, version, *optimizer);
905 template <
class Archive>
907 load(Archive & archive,
908 const unsigned int version,
909 typename Optimizer::OptimizerType *optimizer,
910 const SymEngine::vec_basic & independent_symbols,
911 const SymEngine::vec_basic & dependent_functions,
919 Optimizer::load(archive,
944 template <
typename Stream>
946 print(Stream & stream,
947 typename Optimizer::OptimizerType *optimizer,
948 const bool print_independent_symbols =
false,
949 const bool print_dependent_functions =
false,
950 const bool print_cse_reductions =
true)
957 Optimizer::print(stream,
959 print_independent_symbols,
960 print_dependent_functions,
961 print_cse_reductions);
965 template <
typename ReturnType,
typename Optimizer>
966 struct OptimizerHelper<ReturnType,
968 typename
std::enable_if<!std::is_same<
970 typename Optimizer::ReturnType>::value>::type>
981 initialize(
typename Optimizer::OptimizerType *optimizer,
982 const SymEngine::vec_basic & independent_symbols,
983 const SymEngine::vec_basic & dependent_functions,
989 optimizer->init(independent_symbols,
1010 substitute(
typename Optimizer::OptimizerType *optimizer,
1011 std::vector<ReturnType> & output_values,
1012 const std::vector<ReturnType> & substitution_values)
1018 std::vector<typename Optimizer::ReturnType> int_outputs(
1019 output_values.size());
1020 std::vector<typename Optimizer::ReturnType> int_inputs(
1021 substitution_values.size());
1023 std::copy(substitution_values.begin(),
1024 substitution_values.end(),
1025 int_inputs.begin());
1026 optimizer->call(int_outputs.data(), int_inputs.data());
1027 std::copy(int_outputs.begin(),
1029 output_values.begin());
1038 template <
class Archive>
1040 save(Archive & archive,
1041 const unsigned int version,
1042 typename Optimizer::OptimizerType *optimizer)
1045 Optimizer::save(archive, version, *optimizer);
1054 template <
class Archive>
1056 load(Archive & archive,
1057 const unsigned int version,
1058 typename Optimizer::OptimizerType *optimizer,
1059 const SymEngine::vec_basic & independent_symbols,
1060 const SymEngine::vec_basic & dependent_functions,
1068 Optimizer::load(archive,
1071 independent_symbols,
1072 dependent_functions,
1073 optimization_flags);
1093 template <
typename Stream>
1095 print(Stream & stream,
1096 typename Optimizer::OptimizerType *optimizer,
1097 const bool print_cse_reductions =
true,
1098 const bool print_independent_symbols =
false,
1099 const bool print_dependent_functions =
false)
1103 optimizer->print(stream,
1104 print_independent_symbols,
1105 print_dependent_functions,
1106 print_cse_reductions);
1137 template <
typename NumberType,
1140 template <
int,
int,
typename>
1142 TensorType<rank, dim, NumberType>
1144 const TensorType<rank, dim, Expression> &symbol_tensor,
1145 const std::vector<NumberType> & cached_evaluation,
1148 TensorType<rank, dim, NumberType> out;
1149 for (
unsigned int i = 0; i < out.n_independent_components; ++i)
1152 out.unrolled_to_component_indices(i));
1154 optimizer.
extract(symbol_tensor[indices], cached_evaluation);
1182 template <
typename NumberType,
int dim>
1186 const std::vector<NumberType> & cached_evaluation,
1190 for (
unsigned int i = 0;
1191 i < SymmetricTensor<2, dim>::n_independent_components;
1193 for (
unsigned int j = 0;
1194 j < SymmetricTensor<2, dim>::n_independent_components;
1198 make_rank_4_tensor_indices<dim>(i, j);
1200 optimizer.
extract(symbol_tensor[indices], cached_evaluation);
1223 template <
typename NumberType,
typename T>
1249 template <
typename NumberType,
typename T>
1252 const std::vector<T> & functions)
1254 for (
const auto &function : functions)
1278 template <
typename NumberType,
typename T,
typename... Args>
1282 const Args &...other_functions)
1302 template <
int,
int,
typename>
1306 const TensorType<rank, dim, Expression> &symbol_tensor)
1309 out.reserve(symbol_tensor.n_independent_components);
1310 for (
unsigned int i = 0; i < symbol_tensor.n_independent_components;
1314 symbol_tensor.unrolled_to_component_indices(i));
1315 out.push_back(symbol_tensor[indices].get_RCP());
1337 for (
unsigned int i = 0;
1338 i < SymmetricTensor<2, dim>::n_independent_components;
1340 for (
unsigned int j = 0;
1341 j < SymmetricTensor<2, dim>::n_independent_components;
1345 make_rank_4_tensor_indices<dim>(i, j);
1346 out.push_back(symbol_tensor[indices].get_RCP());
1445 template <
typename ReturnType>
1522 template <
typename Stream>
1524 print(Stream &stream,
const bool print_cse =
false)
const;
1534 template <
class Archive>
1536 save(Archive &archive,
const unsigned int version)
const;
1551 template <
class Archive>
1553 load(Archive &archive,
const unsigned int version);
1577 template <
class Archive>
1583 BOOST_SERIALIZATION_SPLIT_MEMBER()
1666 template <
int rank,
int dim>
1674 template <
int rank,
int dim>
1702 template <
typename T>
1719 template <
typename T,
typename... Args>
1838 substitute(
const SymEngine::map_basic_basic &substitution_map)
const;
1852 const std::vector<ReturnType> &values)
const;
1865 substitute(
const SymEngine::vec_basic & symbols,
1866 const std::vector<ReturnType> &values)
const;
1905 const std::vector<ReturnType> &
1926 std::vector<ReturnType>
1927 evaluate(
const std::vector<Expression> &funcs)
const;
1937 template <
int rank,
int dim>
1950 template <
int rank,
int dim>
1964 const std::vector<ReturnType> &cached_evaluation)
const;
1974 std::vector<ReturnType>
1975 extract(
const std::vector<Expression> &funcs,
1976 const std::vector<ReturnType> &cached_evaluation)
const;
1986 template <
int rank,
int dim>
1989 const std::vector<ReturnType> & cached_evaluation)
const;
1999 template <
int rank,
int dim>
2002 const std::vector<ReturnType> &cached_evaluation)
const;
2050 const SymEngine::RCP<const SymEngine::Basic> &function)
const;
2147 substitute(
const std::vector<ReturnType> &substitution_values)
const;
2158 template <
typename ReturnType>
2159 template <
typename Stream>
2165 stream <<
"Method? " << optimization_method() <<
'\n';
2166 stream <<
"Flags: " << optimization_flags() <<
'\n';
2167 stream <<
"Optimized? " << (optimized() ?
"Yes" :
"No") <<
'\n';
2168 stream <<
"Values substituted? " << values_substituted() <<
"\n\n";
2171 stream <<
"Symbols (" << n_independent_variables()
2172 <<
" independent variables):" <<
'\n';
2174 for (SD::types::substitution_map::const_iterator it =
2175 independent_variables_symbols.begin();
2176 it != independent_variables_symbols.end();
2179 stream << cntr <<
": " << it->first <<
'\n';
2181 stream <<
'\n' << std::flush;
2184 stream <<
"Functions (" << n_dependent_variables()
2185 <<
" dependent variables):" <<
'\n';
2187 for (
typename SD::types::symbol_vector::const_iterator it =
2188 dependent_variables_functions.begin();
2189 it != dependent_variables_functions.end();
2192 stream << cntr <<
": " << (*it) <<
'\n';
2194 stream <<
'\n' << std::flush;
2197 if (optimized() ==
true && use_symbolic_CSE() ==
true)
2200 const bool print_cse_reductions =
true;
2201 const bool print_independent_symbols =
false;
2202 const bool print_dependent_functions =
false;
2206 Assert(
dynamic_cast<typename internal::DictionaryOptimizer<
2208 ExcMessage(
"Cannot cast optimizer to Dictionary type."));
2210 internal::OptimizerHelper<
2212 internal::DictionaryOptimizer<ReturnType>>::
2214 dynamic_cast<typename internal::DictionaryOptimizer<
2216 print_independent_symbols,
2217 print_dependent_functions,
2218 print_cse_reductions);
2220 stream <<
'\n' << std::flush;
2224 Assert(
dynamic_cast<typename internal::LambdaOptimizer<
2226 ExcMessage(
"Cannot cast optimizer to Lambda type."));
2228 internal::OptimizerHelper<ReturnType,
2229 internal::LambdaOptimizer<ReturnType>>::
2231 dynamic_cast<typename internal::LambdaOptimizer<
2233 print_independent_symbols,
2234 print_dependent_functions,
2235 print_cse_reductions);
2237# ifdef HAVE_SYMENGINE_LLVM
2240 Assert(
dynamic_cast<typename internal::LLVMOptimizer<
2242 ExcMessage(
"Cannot cast optimizer to LLVM type."));
2244 internal::OptimizerHelper<ReturnType,
2245 internal::LLVMOptimizer<ReturnType>>::
2247 dynamic_cast<typename internal::LLVMOptimizer<
2249 print_independent_symbols,
2250 print_dependent_functions,
2251 print_cse_reductions);
2260 if (values_substituted())
2262 stream <<
"Evaluated functions:" <<
'\n';
2263 stream << std::flush;
2265 for (
typename std::vector<ReturnType>::const_iterator it =
2266 dependent_variables_output.begin();
2267 it != dependent_variables_output.end();
2270 stream << cntr <<
": " << (*it) <<
'\n';
2272 stream <<
'\n' << std::flush;
2278 template <
typename ReturnType>
2279 template <
class Archive>
2282 const unsigned int version)
const
2287 static_cast<typename std::underlying_type<OptimizerType>::type
>(
2293 static_cast<typename std::underlying_type<OptimizationFlags>::type
>(
2300 ar &independent_variables_symbols;
2301 ar &dependent_variables_functions;
2303 ar &dependent_variables_output;
2304 ar &map_dep_expr_vec_entry;
2305 ar &ready_for_value_extraction;
2308 has_been_serialized =
true;
2309 ar &has_been_serialized;
2317 if (
typename internal::DictionaryOptimizer<ReturnType>::OptimizerType
2318 *opt =
dynamic_cast<typename internal::DictionaryOptimizer<
2323 internal::OptimizerHelper<
2325 internal::DictionaryOptimizer<ReturnType>>::save(ar, version, opt);
2327 else if (
typename internal::LambdaOptimizer<ReturnType>::OptimizerType
2328 *opt =
dynamic_cast<typename internal::LambdaOptimizer<
2333 internal::OptimizerHelper<
2335 internal::LambdaOptimizer<ReturnType>>::save(ar, version, opt);
2337# ifdef HAVE_SYMENGINE_LLVM
2338 else if (
typename internal::LLVMOptimizer<ReturnType>::OptimizerType
2339 *opt =
dynamic_cast<typename internal::LLVMOptimizer<
2344 internal::OptimizerHelper<
2346 internal::LLVMOptimizer<ReturnType>>::save(ar, version, opt);
2357 template <
typename ReturnType>
2358 template <
class Archive>
2370 typename std::underlying_type<OptimizerType>::type m;
2375 typename std::underlying_type<OptimizationFlags>::type f;
2382 ar &independent_variables_symbols;
2383 ar &dependent_variables_functions;
2385 ar &dependent_variables_output;
2386 ar &map_dep_expr_vec_entry;
2387 ar &ready_for_value_extraction;
2389 ar &has_been_serialized;
2396 create_optimizer(optimizer);
2405 if (
typename internal::DictionaryOptimizer<ReturnType>::OptimizerType
2406 *opt =
dynamic_cast<typename internal::DictionaryOptimizer<
2411 internal::OptimizerHelper<ReturnType,
2412 internal::DictionaryOptimizer<ReturnType>>::
2419 dependent_variables_functions),
2420 optimization_flags());
2422 else if (
typename internal::LambdaOptimizer<ReturnType>::OptimizerType
2423 *opt =
dynamic_cast<typename internal::LambdaOptimizer<
2428 internal::OptimizerHelper<ReturnType,
2429 internal::LambdaOptimizer<ReturnType>>::
2436 dependent_variables_functions),
2437 optimization_flags());
2439# ifdef HAVE_SYMENGINE_LLVM
2440 else if (
typename internal::LLVMOptimizer<ReturnType>::OptimizerType
2441 *opt =
dynamic_cast<typename internal::LLVMOptimizer<
2446 internal::OptimizerHelper<ReturnType,
2447 internal::LLVMOptimizer<ReturnType>>::
2454 dependent_variables_functions),
2455 optimization_flags());
2466 template <
typename ReturnType>
2467 template <
int rank,
int dim>
2472 Assert(optimized() ==
false,
2474 "Cannot register functions once the optimizer is finalised."));
2476 register_vector_functions(
2482 template <
typename ReturnType>
2483 template <
int rank,
int dim>
2488 Assert(optimized() ==
false,
2490 "Cannot register functions once the optimizer is finalised."));
2492 register_vector_functions(
2498 template <
typename ReturnType>
2499 template <
typename T,
typename... Args>
2503 const Args &...other_functions)
2511 template <
typename ReturnType>
2512 template <
typename T>
2515 const std::vector<T> &functions)
2522 template <
typename ReturnType>
2523 template <
int rank,
int dim>
2527 const std::vector<ReturnType> & cached_evaluation)
const
2536 template <
typename ReturnType>
2537 template <
int rank,
int dim>
2543 values_substituted() ==
true,
2545 "The optimizer is not configured to perform evaluation. "
2546 "This action can only performed after substitute() has been called."));
2548 return extract(funcs, dependent_variables_output);
2553 template <
typename ReturnType>
2554 template <
int rank,
int dim>
2558 const std::vector<ReturnType> & cached_evaluation)
const
2567 template <
typename ReturnType>
2568 template <
int rank,
int dim>
2574 values_substituted() ==
true,
2576 "The optimizer is not configured to perform evaluation. "
2577 "This action can only performed after substitute() has been called."));
2579 return extract(funcs, dependent_variables_output);
static constexpr unsigned int n_independent_components
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_DISABLE_EXTRA_DIAGNOSTICS
#define DEAL_II_NAMESPACE_CLOSE
#define DEAL_II_ENABLE_EXTRA_DIAGNOSTICS
SymmetricTensor< rank, dim, ReturnType > extract(const SymmetricTensor< rank, dim, Expression > &funcs, const std::vector< ReturnType > &cached_evaluation) const
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_functions(const T &functions, const Args &...other_functions)
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
void print(Stream &stream, const bool print_cse=false) const
TensorType< rank, dim, NumberType > tensor_evaluate_optimized(const TensorType< rank, dim, Expression > &symbol_tensor, const std::vector< NumberType > &cached_evaluation, const BatchOptimizer< NumberType > &optimizer)
enum OptimizerType optimization_method() const
void copy_from(const BatchOptimizer &other)
void register_function(const Tensor< rank, dim, Expression > &function_tensor)
static ::ExceptionBase & ExcNotImplemented()
void set_optimization_method(const enum OptimizerType &optimization_method, const enum OptimizationFlags &optimization_flags=OptimizationFlags::optimize_all)
SymmetricTensor< rank, dim, ReturnType > evaluate(const SymmetricTensor< rank, dim, Expression > &funcs) const
OptimizationFlags & operator|=(OptimizationFlags &f1, const OptimizationFlags f2)
void save(Archive &archive, const unsigned int version) const
bool use_symbolic_CSE(const enum OptimizationFlags &flags)
enum OptimizationFlags optimization_flags() const
types::symbol_vector unroll_to_expression_vector(const TensorType< rank, dim, Expression > &symbol_tensor)
#define Assert(cond, exc)
void register_functions(const types::symbol_vector &functions)
BatchOptimizer(BatchOptimizer &&)=default
std::vector< ReturnType > dependent_variables_output
static ::ExceptionBase & ExcSymEngineLLVMReturnTypeNotSupported()
~BatchOptimizer()=default
Expression operator|(const Expression &lhs, const Expression &rhs)
enum OptimizerType method
int get_LLVM_optimization_level(const enum OptimizationFlags &flags)
Tensor< rank, dim, ReturnType > extract(const Tensor< rank, dim, Expression > &funcs, const std::vector< ReturnType > &cached_evaluation) const
std::size_t n_dependent_variables() const
void serialize(Archive &archive, const unsigned int version)
#define DeclExceptionMsg(Exception, defaulttext)
void register_symbols(const types::substitution_map &substitution_map)
const std::vector< ReturnType > & evaluate() const
static ::ExceptionBase & ExcSymEngineLLVMNotAvailable()
static ::ExceptionBase & ExcInternalError()
std::map< SD::Expression, std::size_t, SD::types::internal::ExpressionKeyLess > map_dependent_expression_to_vector_entry_t
Expression operator&(const Expression &lhs, const Expression &rhs)
void register_function(const Expression &function)
Tensor< rank, dim, ReturnType > evaluate(const Tensor< rank, dim, Expression > &funcs) const
std::unique_ptr< SymEngine::Visitor > optimizer
ReturnType extract(const Expression &func, const std::vector< ReturnType > &cached_evaluation) const
static ::ExceptionBase & ExcNotInitialized()
void load(Archive &archive, const unsigned int version)
void register_functions(const std::vector< T > &functions)
bool is_valid_nonunique_dependent_variable(const SD::Expression &function) const
void register_vector_functions(const types::symbol_vector &functions)
void register_functions(BatchOptimizer< NumberType > &optimizer, const T &function)
std::ostream & operator<<(std::ostream &stream, const Expression &expression)
static ::ExceptionBase & ExcMessage(std::string arg1)
std::size_t n_independent_variables() const
types::symbol_vector get_independent_symbols() const
void register_function(const SymmetricTensor< rank, dim, Expression > &function_tensor)
map_dependent_expression_to_vector_entry_t map_dep_expr_vec_entry
OptimizationFlags & operator&=(OptimizationFlags &f1, const OptimizationFlags f2)
#define AssertThrow(cond, exc)
bool values_substituted() const
SD::types::symbol_vector extract_symbols(const SD::types::substitution_map &substitution_values)
SymEngine::vec_basic convert_expression_vector_to_basic_vector(const SD::types::symbol_vector &symbol_vector)
std::vector< SD::Expression > symbol_vector
std::map< SD::Expression, SD::Expression, internal::ExpressionKeyLess > substitution_map
Expression substitute(const Expression &expression, const types::substitution_map &substitution_map)
constexpr ReturnType< rank, T >::value_type & extract(T &t, const ArrayType &indices)
std::string to_string(const number value, const unsigned int digits=numbers::invalid_unsigned_int)