Loading [MathJax]/extensions/TeX/AMSsymbols.js
 Reference documentation for deal.II version 9.2.0
\(\newcommand{\dealvcentcolon}{\mathrel{\mathop{:}}}\) \(\newcommand{\dealcoloneq}{\dealvcentcolon\mathrel{\mkern-1.2mu}=}\) \(\newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]}\) \(\newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}\)
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
symengine_optimizer.cc
Go to the documentation of this file.
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2020 by the deal.II authors
4 //
5 // This file is part of the deal.II library.
6 //
7 // The deal.II library is free software; you can use it, redistribute
8 // it, and/or modify it under the terms of the GNU Lesser General
9 // Public License as published by the Free Software Foundation; either
10 // version 2.1 of the License, or (at your option) any later version.
11 // The full text of the license can be found in the file LICENSE at
12 // the top level of the deal.II distribution.
13 //
14 // ---------------------------------------------------------------------
15 
16 #include <deal.II/base/config.h>
17 
18 #ifdef DEAL_II_WITH_SYMENGINE
19 
22 
23 # include <boost/archive/text_iarchive.hpp>
24 # include <boost/archive/text_oarchive.hpp>
25 
26 # include <utility>
27 
29 
30 
31 namespace Differentiation
32 {
33  namespace SD
34  {
35  template <typename ReturnType>
37  : method(OptimizerType::dictionary)
39  , ready_for_value_extraction(false)
40  , has_been_serialized(false)
41  {}
42 
43 
44 
45  template <typename ReturnType>
47  const enum OptimizerType & optimization_method,
48  const enum OptimizationFlags &optimization_flags)
49  : BatchOptimizer()
50  {
52  }
53 
54 
55 
56  template <typename ReturnType>
58  const BatchOptimizer<ReturnType> &other)
59  : method(other.method)
60  , flags(other.flags)
61  , independent_variables_symbols(other.independent_variables_symbols)
62  , dependent_variables_functions(other.dependent_variables_functions)
63  , dependent_variables_output(0)
64  , map_dep_expr_vec_entry(other.map_dep_expr_vec_entry)
65  , ready_for_value_extraction(false)
66  {}
67 
68 
69 
70  template <typename ReturnType>
71  void
73  const enum OptimizerType & optimization_method,
74  const enum OptimizationFlags &optimization_flags)
75  {
76  Assert(
77  optimized() == false,
78  ExcMessage(
79  "Cannot call set_optimization_method() once the optimizer is finalized."));
80 
81 # ifndef HAVE_SYMENGINE_LLVM
82  if (optimization_method == OptimizerType::llvm)
83  {
85  }
86 # endif
87  method = optimization_method;
88  flags = optimization_flags;
89  }
90 
91 
92 
93  template <typename ReturnType>
94  enum OptimizerType
96  {
97  return method;
98  }
99 
100 
101 
102  template <typename ReturnType>
103  enum OptimizationFlags
105  {
106  return flags;
107  }
108 
109 
110 
111  template <typename ReturnType>
112  bool
114  {
115  return internal::use_symbolic_CSE(flags);
116  }
117 
118 
119 
120  template <typename ReturnType>
121  bool
123  {
124  if (dependent_variables_output.size() > 0)
125  {
126  Assert(dependent_variables_output.size() ==
127  dependent_variables_functions.size(),
128  ExcInternalError());
129  return true;
130  }
131 
132  return false;
133  }
134 
135 
136 
137  template <typename ReturnType>
138  bool
140  {
141  return ready_for_value_extraction;
142  }
143 
144 
145 
146  template <typename ReturnType>
147  void
150  {
151  Assert(optimized() == false,
152  ExcMessage(
153  "Cannot register symbols once the optimizer is finalized."));
154 
155 # ifdef DEBUG
156  // Ensure that all of the keys in the map are actually symbolic
157  // in nature
158  for (const auto &entry : substitution_map)
159  {
160  const SD::Expression &symbol = entry.first;
161  Assert(SymEngine::is_a<SymEngine::Symbol>(*(symbol.get_RCP())),
162  ExcMessage("Key entry in map is not a symbol."));
163  }
164 # endif
165  // Merge the two maps, in the process ensuring that there is no
166  // duplication of symbols
167  independent_variables_symbols.insert(substitution_map.begin(),
168  substitution_map.end());
169  }
170 
171 
172 
173  template <typename ReturnType>
174  void
176  const SymEngine::map_basic_basic &substitution_map)
177  {
178  register_symbols(
180  }
181 
182 
183 
184  template <typename ReturnType>
185  void
187  const SD::types::symbol_vector &symbols)
188  {
189  Assert(optimized() == false,
190  ExcMessage(
191  "Cannot register symbols once the optimizer is finalized."));
192 
193  for (const auto &symbol : symbols)
194  {
195  Assert(independent_variables_symbols.find(symbol) ==
196  independent_variables_symbols.end(),
197  ExcMessage("Symbol is already in the map."));
198  independent_variables_symbols.insert(
199  std::make_pair(symbol, SD::Expression(0.0)));
200  }
201  }
202 
203 
204 
205  template <typename ReturnType>
206  void
208  const SymEngine::vec_basic &symbols)
209  {
210  register_symbols(
212  }
213 
214 
215 
216  template <typename ReturnType>
219  {
220  return Utilities::extract_symbols(independent_variables_symbols);
221  }
222 
223 
224 
225  template <typename ReturnType>
226  std::size_t
228  {
229  return independent_variables_symbols.size();
230  }
231 
232 
233 
234  template <typename ReturnType>
235  void
237  {
238  Assert(optimized() == false,
239  ExcMessage(
240  "Cannot register functions once the optimizer is finalized."));
241 
242  register_scalar_function(function);
243  }
244 
245 
246 
247  template <typename ReturnType>
248  void
251  {
252  Assert(optimized() == false,
253  ExcMessage(
254  "Cannot register functions once the optimizer is finalized."));
255 
256  register_vector_functions(functions);
257  }
258 
259 
260 
261  template <typename ReturnType>
262  void
264  const SymEngine::vec_basic &functions)
265  {
268  }
269 
270 
271 
272  template <typename ReturnType>
275  {
276  return dependent_variables_functions;
277  }
278 
279 
280 
281  template <typename ReturnType>
282  std::size_t
284  {
285  if (has_been_serialized == false)
286  {
287  // If we've had to augment our map after serialization, then
288  // this check, unfortunately, cannot be performed.
289  Assert(map_dep_expr_vec_entry.size() ==
290  dependent_variables_functions.size(),
291  ExcInternalError());
292  }
293  return dependent_variables_functions.size();
294  }
295 
296 
297 
298  template <typename ReturnType>
299  void
301  {
302  Assert(optimized() == false,
303  ExcMessage("Cannot call optimize() more than once."));
304 
305  // Create and configure the optimizer
306  create_optimizer(optimizer);
307  Assert(optimizer, ExcNotInitialized());
308 
309  const SD::types::symbol_vector symbol_vec =
310  Utilities::extract_symbols(independent_variables_symbols);
312  *opt = dynamic_cast<typename internal::DictionaryOptimizer<
313  ReturnType>::OptimizerType *>(optimizer.get()))
314  {
315  Assert(optimization_method() == OptimizerType::dictionary,
316  ExcInternalError());
317  internal::OptimizerHelper<ReturnType,
319  initialize(opt,
321  symbol_vec),
323  dependent_variables_functions),
324  optimization_flags());
325  }
327  *opt = dynamic_cast<typename internal::LambdaOptimizer<
328  ReturnType>::OptimizerType *>(optimizer.get()))
329  {
330  Assert(optimization_method() == OptimizerType::lambda,
331  ExcInternalError());
332  internal::OptimizerHelper<ReturnType,
334  initialize(opt,
336  symbol_vec),
338  dependent_variables_functions),
339  optimization_flags());
340  }
341 # ifdef HAVE_SYMENGINE_LLVM
343  *opt = dynamic_cast<typename internal::LLVMOptimizer<
344  ReturnType>::OptimizerType *>(optimizer.get()))
345  {
346  Assert(optimization_method() == OptimizerType::llvm,
347  ExcInternalError());
348  internal::OptimizerHelper<ReturnType,
349  internal::LLVMOptimizer<ReturnType>>::
350  initialize(opt,
352  symbol_vec),
354  dependent_variables_functions),
355  optimization_flags());
356  }
357 # endif
358  else
359  {
360  AssertThrow(false, ExcMessage("Unknown optimizer type."));
361  }
362 
363  // The size of the outputs is now fixed, as is the number and
364  // order of the symbols to be substituted.
365  // Note: When no optimisation is actually used (i.e. optimization_method()
366  // == off and use_symbolic_CSE() == false), we could conceptually go
367  // without this data structure. However, since the user expects to perform
368  // substitution of all dependent variables in one go, we still require it
369  // for intermediate storage of results.
370  dependent_variables_output.resize(n_dependent_variables());
371  }
372 
373 
374 
375  template <typename ReturnType>
376  void
379  {
380  Assert(
381  optimized() == true,
382  ExcMessage(
383  "The optimizer is not configured to perform substitution. "
384  "This action can only performed after optimize() has been called."));
385  Assert(optimizer, ExcNotInitialized());
386 
387  // Check that the registered symbol map and the input map are compatible
388  // with one another
389 # ifdef DEBUG
390  const SD::types::symbol_vector symbol_sub_vec =
392  const SD::types::symbol_vector symbol_vec =
393  Utilities::extract_symbols(independent_variables_symbols);
394  Assert(symbol_sub_vec.size() == symbol_vec.size(),
395  ExcDimensionMismatch(symbol_sub_vec.size(), symbol_vec.size()));
396  for (unsigned int i = 0; i < symbol_sub_vec.size(); ++i)
397  {
398  Assert(numbers::values_are_equal(symbol_sub_vec[i], symbol_vec[i]),
399  ExcMessage(
400  "The input substitution map is either incomplete, or does "
401  "not match that used in the register_symbols() call."));
402  }
403 # endif
404 
405  // Extract the values from the substitution map, and use the other
406  // function
407  const std::vector<ReturnType> values =
408  Utilities::extract_values<ReturnType>(substitution_map);
409  substitute(values);
410  }
411 
412 
413 
414  template <typename ReturnType>
415  void
417  const SymEngine::map_basic_basic &substitution_map) const
418  {
419  substitute(
421  }
422 
423 
424 
425  template <typename ReturnType>
426  void
428  const SD::types::symbol_vector &symbols,
429  const std::vector<ReturnType> & values) const
430  {
431  // Zip the two vectors and use the other function call
432  // This ensures the ordering of the input vectors matches that of the
433  // stored map.
434  substitute(make_substitution_map(symbols, values));
435  }
436 
437 
438 
439  template <typename ReturnType>
440  void
442  const SymEngine::vec_basic & symbols,
443  const std::vector<ReturnType> &values) const
444  {
446  symbols),
447  values);
448  }
449 
450 
451 
452  template <typename ReturnType>
453  void
455  const std::vector<ReturnType> &substitution_values) const
456  {
457  Assert(
458  optimized() == true,
459  ExcMessage(
460  "The optimizer is not configured to perform substitution. "
461  "This action can only performed after optimize() has been called."));
462  Assert(optimizer, ExcNotInitialized());
463  Assert(substitution_values.size() == independent_variables_symbols.size(),
464  ExcDimensionMismatch(substitution_values.size(),
465  independent_variables_symbols.size()));
466 
468  *opt = dynamic_cast<typename internal::DictionaryOptimizer<
469  ReturnType>::OptimizerType *>(optimizer.get()))
470  {
471  Assert(optimization_method() == OptimizerType::dictionary,
472  ExcInternalError());
473  internal::OptimizerHelper<ReturnType,
475  substitute(opt, dependent_variables_output, substitution_values);
476  }
478  *opt = dynamic_cast<typename internal::LambdaOptimizer<
479  ReturnType>::OptimizerType *>(optimizer.get()))
480  {
481  Assert(optimization_method() == OptimizerType::lambda,
482  ExcInternalError());
483  internal::OptimizerHelper<ReturnType,
485  substitute(opt, dependent_variables_output, substitution_values);
486  }
487 # ifdef HAVE_SYMENGINE_LLVM
489  *opt = dynamic_cast<typename internal::LLVMOptimizer<
490  ReturnType>::OptimizerType *>(optimizer.get()))
491  {
492  Assert(optimization_method() == OptimizerType::llvm,
493  ExcInternalError());
494  internal::OptimizerHelper<ReturnType,
495  internal::LLVMOptimizer<ReturnType>>::
496  substitute(opt, dependent_variables_output, substitution_values);
497  }
498 # endif
499  else
500  {
501  AssertThrow(false, ExcNotImplemented());
502  }
503 
504  ready_for_value_extraction = true;
505  }
506 
507 
508 
509  template <typename ReturnType>
510  const std::vector<ReturnType> &
512  {
513  Assert(
514  values_substituted() == true,
515  ExcMessage(
516  "The optimizer is not configured to perform evaluation. "
517  "This action can only performed after substitute() has been called."));
518 
519  return dependent_variables_output;
520  }
521 
522 
523 
524  template <typename ReturnType>
525  ReturnType
527  {
528  Assert(
529  values_substituted() == true,
530  ExcMessage(
531  "The optimizer is not configured to perform evaluation. "
532  "This action can only performed after substitute() has been called."));
533 
534  // TODO[JPP]: Find a way to fix this bug that crops up in serialization
535  // cases, e.g. symengine/batch_optimizer_05. Even though the entry is
536  // in the map, it can only be found by an exhaustive search and string
537  // comparison. Why? Because the leading zero coefficient may seemingly
538  // be dropped (or added) at any time.
539  //
540  // Just this should theoretically work:
541  const typename map_dependent_expression_to_vector_entry_t::const_iterator
542  it = map_dep_expr_vec_entry.find(func);
543 
544  // But instead we are forced to live with this abomination, and its
545  // knock-on effects:
546  if (has_been_serialized && it == map_dep_expr_vec_entry.end())
547  {
548  // Some SymEngine operations might return results with a zero leading
549  // coefficient. Upon serialization, this might be dropped, meaning
550  // that when we reload the expressions they now look somewhat
551  // different to as before. If all data that the user uses is
552  // guaranteed to either have been serialized or never serialized, then
553  // there would be no problem. However, users might rebuild their
554  // dependent expression and just reload the optimizer. This is
555  // completely legitimate. But in this scenario we might be out of sync
556  // with the expressions. This is not great. So we take the nuclear
557  // approach, and run everything through a serialization operation to
558  // see if we can homogenize all of the expressions such that they look
559  // the same in string form.
560  auto serialize_and_deserialize_expression =
561  [](const Expression &old_expr) {
562  std::ostringstream oss;
563  {
564  boost::archive::text_oarchive oa(oss,
565  boost::archive::no_header);
566  oa << old_expr;
567  }
568 
569  Expression new_expr;
570  {
571  std::istringstream iss(oss.str());
572  boost::archive::text_iarchive ia(iss,
573  boost::archive::no_header);
574 
575  ia >> new_expr;
576  }
577 
578  return new_expr;
579  };
580 
581  const Expression new_func =
582  serialize_and_deserialize_expression(func);
583 
584  // Find this in the map, while also making sure to compactify all map
585  // entries. If we find the entry that we're looking for, then we
586  // (re-)add the input expression into the map, and do the proper
587  // search again. We should only need to do this once per invalid
588  // entry, as the corrected entry is then cached in the map.
589  for (const auto &e : map_dep_expr_vec_entry)
590  {
591  const Expression new_map_expr =
592  serialize_and_deserialize_expression(e.first);
593 
594  // Add a new map entry and re-search. This is guaranteed to
595  // return a valid entry. Note that we must do a string comparison,
596  // because the data structures that form the expressions might
597  // still be different.
598  if (new_func.get_value().__str__() ==
599  new_map_expr.get_value().__str__())
600  {
601  map_dep_expr_vec_entry[func] = e.second;
602  return evaluate(func);
603  }
604  }
605 
606  AssertThrow(
607  false,
608  ExcMessage(
609  "Still cannot find map entry, and there's no hope to recover from this situation."));
610  }
611 
612  Assert(it != map_dep_expr_vec_entry.end(),
613  ExcMessage("Function has not been registered."));
614  Assert(it->second < n_dependent_variables(), ExcInternalError());
615 
616  return dependent_variables_output[it->second];
617  }
618 
619 
620 
621  template <typename ReturnType>
622  std::vector<ReturnType>
624  const std::vector<Expression> &funcs) const
625  {
626  std::vector<ReturnType> out;
627  out.reserve(funcs.size());
628 
629  for (const auto &func : funcs)
630  out.emplace_back(evaluate(func));
631 
632  return out;
633  }
634 
635 
636 
637  template <typename ReturnType>
638  bool
640  const SD::Expression &func) const
641  {
642  return is_valid_nonunique_dependent_variable(func.get_RCP());
643  }
644 
645 
646 
647  template <typename ReturnType>
648  bool
650  const SymEngine::RCP<const SymEngine::Basic> &func) const
651  {
652  // SymEngine's internal constants are the valid
653  // reusable return types for various derivative operations
654  // See
655  // https://github.com/symengine/symengine/blob/master/symengine/constants.h
656  if (SymEngine::is_a<SymEngine::Constant>(*func))
657  return true;
658  if (&*func == &*SymEngine::zero)
659  return true;
660  if (&*func == &*SymEngine::one)
661  return true;
662  if (&*func == &*SymEngine::minus_one)
663  return true;
664  if (&*func == &*SymEngine::I)
665  return true;
666  if (&*func == &*SymEngine::Inf)
667  return true;
668  if (&*func == &*SymEngine::NegInf)
669  return true;
670  if (&*func == &*SymEngine::ComplexInf)
671  return true;
672  if (&*func == &*SymEngine::Nan)
673  return true;
674 
675  return false;
676  }
677 
678 
679 
680  template <typename ReturnType>
681  void
683  const SD::Expression &func)
684  {
685  Assert(
686  dependent_variables_output.size() == 0,
687  ExcMessage(
688  "Cannot register function as the optimizer has already been finalized."));
689  dependent_variables_output.reserve(n_dependent_variables() + 1);
690  const bool entry_registered =
691  (map_dep_expr_vec_entry.find(func) != map_dep_expr_vec_entry.end());
692 # ifdef DEBUG
693  if (entry_registered == true &&
694  is_valid_nonunique_dependent_variable(func) == false)
695  Assert(entry_registered,
696  ExcMessage("Function has already been registered."));
697 # endif
698  if (entry_registered == false)
699  {
700  dependent_variables_functions.push_back(func);
701  map_dep_expr_vec_entry[func] =
702  dependent_variables_functions.size() - 1;
703  }
704  }
705 
706 
707 
708  template <typename ReturnType>
709  void
711  const SD::types::symbol_vector &funcs)
712  {
713  Assert(
714  dependent_variables_output.size() == 0,
715  ExcMessage(
716  "Cannot register function as the optimizer has already been finalized."));
717  const std::size_t n_dependents_old = n_dependent_variables();
718  dependent_variables_output.reserve(n_dependents_old + funcs.size());
719  dependent_variables_functions.reserve(n_dependents_old + funcs.size());
720 
721  for (const auto &func : funcs)
722  {
723  const bool entry_registered =
724  (map_dep_expr_vec_entry.find(func) != map_dep_expr_vec_entry.end());
725 # ifdef DEBUG
726  if (entry_registered == true &&
727  is_valid_nonunique_dependent_variable(func) == false)
728  Assert(entry_registered,
729  ExcMessage("Function has already been registered."));
730 # endif
731  if (entry_registered == false)
732  {
733  dependent_variables_functions.push_back(func);
734  map_dep_expr_vec_entry[func] =
735  dependent_variables_functions.size() - 1;
736  }
737  }
738  }
739 
740 
741 
742  template <typename ReturnType>
743  void
745  std::unique_ptr<SymEngine::Visitor> &optimizer)
746  {
747  Assert(!optimizer, ExcMessage("Optimizer has already been created."));
748 
749  if (optimization_method() == OptimizerType::dictionary ||
750  optimization_method() == OptimizerType::dictionary)
751  {
752  using Optimizer_t =
754  optimizer.reset(new Optimizer_t());
755  }
756  else if (optimization_method() == OptimizerType::lambda)
757  {
758  using Optimizer_t =
760  optimizer.reset(new Optimizer_t());
761  }
762  else if (optimization_method() == OptimizerType::llvm)
763  {
764 # ifdef HAVE_SYMENGINE_LLVM
765  if (internal::LLVMOptimizer<ReturnType>::supported_by_LLVM)
766  {
767  using Optimizer_t =
769  optimizer.reset(new Optimizer_t());
770  }
771  else
772  {
774  }
775 # else
777 # endif
778  }
779  else
780  {
781  AssertThrow(false, ExcMessage("Unknown optimizer selected."));
782  }
783  }
784 
785  } // namespace SD
786 } // namespace Differentiation
787 
788 
789 /* --- Explicit instantiations --- */
790 # include "symengine_optimizer.inst"
791 
792 
794 
795 #endif // DEAL_II_WITH_SYMENGINE
Differentiation::SD::BatchOptimizer::register_symbols
void register_symbols(const types::substitution_map &substitution_map)
Definition: symengine_optimizer.cc:148
Differentiation::SD::BatchOptimizer::register_functions
void register_functions(const types::symbol_vector &functions)
Differentiation::SD::Utilities::extract_symbols
SD::types::symbol_vector extract_symbols(const SD::types::substitution_map &substitution_values)
Differentiation::SD::BatchOptimizer::evaluate
const std::vector< ReturnType > & evaluate() const
Definition: symengine_optimizer.cc:511
Differentiation::SD::OptimizationFlags::optimize_default
@ optimize_default
Differentiation::SD::internal::register_functions
void register_functions(BatchOptimizer< NumberType > &optimizer, const T &function)
Definition: symengine_optimizer.h:1210
Differentiation::SD::Utilities::convert_expression_vector_to_basic_vector
SymEngine::vec_basic convert_expression_vector_to_basic_vector(const SD::types::symbol_vector &symbol_vector)
Differentiation::SD::OptimizerType::lambda
@ lambda
StandardExceptions::ExcNotImplemented
static ::ExceptionBase & ExcNotImplemented()
Differentiation::SD::ExcSymEngineLLVMReturnTypeNotSupported
static ::ExceptionBase & ExcSymEngineLLVMReturnTypeNotSupported()
Differentiation::SD::internal::use_symbolic_CSE
bool use_symbolic_CSE(const enum OptimizationFlags &flags)
Definition: symengine_optimizer.h:238
Differentiation::SD::BatchOptimizer::set_optimization_method
void set_optimization_method(const enum OptimizerType &optimization_method, const enum OptimizationFlags &optimization_flags=OptimizationFlags::optimize_all)
Definition: symengine_optimizer.cc:72
Differentiation::SD::BatchOptimizer::use_symbolic_CSE
bool use_symbolic_CSE() const
Definition: symengine_optimizer.cc:113
Differentiation::SD::BatchOptimizer::substitute
void substitute(const types::substitution_map &substitution_map) const
Definition: symengine_optimizer.cc:377
Differentiation::SD::BatchOptimizer::get_independent_symbols
types::symbol_vector get_independent_symbols() const
Definition: symengine_optimizer.cc:218
Physics::Elasticity::Kinematics::e
SymmetricTensor< 2, dim, Number > e(const Tensor< 2, dim, Number > &F)
Differentiation::SD::types::symbol_vector
std::vector< SD::Expression > symbol_vector
Definition: symengine_types.h:71
Differentiation::SD::BatchOptimizer::optimization_flags
enum OptimizationFlags optimization_flags() const
Definition: symengine_optimizer.cc:104
Differentiation::SD::internal::DictionaryOptimizer
Definition: symengine_optimizer.h:303
Differentiation::SD::types::substitution_map
std::map< SD::Expression, SD::Expression, internal::ExpressionKeyLess > substitution_map
Definition: symengine_types.h:62
numbers::values_are_equal
constexpr bool values_are_equal(const Number1 &value_1, const Number2 &value_2)
Definition: numbers.h:925
Differentiation::SD::BatchOptimizer::values_substituted
bool values_substituted() const
Definition: symengine_optimizer.cc:139
internal::p4est::functions
int(&) functions(const void *v1, const void *v2)
Definition: p4est_wrappers.cc:339
Differentiation::SD::BatchOptimizer::create_optimizer
void create_optimizer(std::unique_ptr< SymEngine::Visitor > &optimizer)
Definition: symengine_optimizer.cc:744
Differentiation::SD::BatchOptimizer::get_dependent_functions
const types::symbol_vector & get_dependent_functions() const
Definition: symengine_optimizer.cc:274
Differentiation::SD::BatchOptimizer::n_independent_variables
std::size_t n_independent_variables() const
Definition: symengine_optimizer.cc:227
Differentiation::SD::BatchOptimizer::n_dependent_variables
std::size_t n_dependent_variables() const
Definition: symengine_optimizer.cc:283
Differentiation::SD::BatchOptimizer::register_vector_functions
void register_vector_functions(const types::symbol_vector &functions)
Definition: symengine_optimizer.cc:710
Differentiation::SD::Expression::get_value
const SymEngine::Basic & get_value() const
Definition: symengine_number_types.cc:227
Differentiation::SD::OptimizerType
OptimizerType
Definition: symengine_optimizer.h:99
LAPACKSupport::one
static const types::blas_int one
Definition: lapack_support.h:183
symengine_optimizer.h
Differentiation::SD::Expression::get_RCP
const SymEngine::RCP< const SymEngine::Basic > & get_RCP() const
Definition: symengine_number_types.cc:234
Differentiation::SD::BatchOptimizer::is_valid_nonunique_dependent_variable
bool is_valid_nonunique_dependent_variable(const SD::Expression &function) const
Definition: symengine_optimizer.cc:639
StandardExceptions::ExcMessage
static ::ExceptionBase & ExcMessage(std::string arg1)
Differentiation::SD::internal::OptimizerHelper
Definition: symengine_optimizer.h:350
DEAL_II_NAMESPACE_OPEN
#define DEAL_II_NAMESPACE_OPEN
Definition: config.h:358
Differentiation::SD::BatchOptimizer::optimize
void optimize()
Definition: symengine_optimizer.cc:300
Differentiation
Definition: numbers.h:645
StandardExceptions::ExcNotInitialized
static ::ExceptionBase & ExcNotInitialized()
Differentiation::SD::substitute
Expression substitute(const Expression &expression, const types::substitution_map &substitution_map)
Differentiation::SD::ExcSymEngineLLVMNotAvailable
static ::ExceptionBase & ExcSymEngineLLVMNotAvailable()
Differentiation::SD::Utilities::convert_basic_map_to_expression_map
SD::types::substitution_map convert_basic_map_to_expression_map(const SymEngine::map_basic_basic &substitution_map)
Differentiation::SD::OptimizerType::dictionary
@ dictionary
Differentiation::SD::BatchOptimizer::optimization_method
enum OptimizerType optimization_method() const
Definition: symengine_optimizer.cc:95
Differentiation::SD::Expression
Definition: symengine_number_types.h:179
Differentiation::SD::make_substitution_map
types::substitution_map make_substitution_map(const Expression &symbol, const Expression &value)
Definition: symengine_scalar_operations.cc:172
StandardExceptions::ExcInternalError
static ::ExceptionBase & ExcInternalError()
Assert
#define Assert(cond, exc)
Definition: exceptions.h:1419
Differentiation::SD::Utilities::convert_basic_vector_to_expression_vector
SD::types::symbol_vector convert_basic_vector_to_expression_vector(const SymEngine::vec_basic &symbol_vector)
Differentiation::SD::BatchOptimizer::register_scalar_function
void register_scalar_function(const SD::Expression &function)
Definition: symengine_optimizer.cc:682
LAPACKSupport::zero
static const types::blas_int zero
Definition: lapack_support.h:179
StandardExceptions::ExcDimensionMismatch
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
config.h
Differentiation::SD::BatchOptimizer::register_function
void register_function(const Expression &function)
Definition: symengine_optimizer.cc:236
DEAL_II_NAMESPACE_CLOSE
#define DEAL_II_NAMESPACE_CLOSE
Definition: config.h:359
Differentiation::SD::OptimizerType::llvm
@ llvm
Differentiation::SD::OptimizationFlags
OptimizationFlags
Definition: symengine_optimizer.h:145
AssertThrow
#define AssertThrow(cond, exc)
Definition: exceptions.h:1531
symengine_utilities.h
Differentiation::SD::internal::LambdaOptimizer
Definition: symengine_optimizer.h:316
Differentiation::SD::BatchOptimizer::BatchOptimizer
BatchOptimizer()
Definition: symengine_optimizer.cc:36
Differentiation::SD::BatchOptimizer::optimized
bool optimized() const
Definition: symengine_optimizer.cc:122
Differentiation::SD::BatchOptimizer
Definition: symengine_optimizer.h:91