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\}}\)
symengine_number_types.h
Go to the documentation of this file.
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2019 - 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 #ifndef dealii_differentiation_sd_symengine_number_types_h
17 #define dealii_differentiation_sd_symengine_number_types_h
18 
19 #include <deal.II/base/config.h>
20 
21 #ifdef DEAL_II_WITH_SYMENGINE
22 
23 // Low level
24 # include <symengine/basic.h>
25 # include <symengine/dict.h>
26 # include <symengine/symengine_exception.h>
27 # include <symengine/symengine_rcp.h>
28 
29 // Number types
30 # include <symengine/expression.h>
31 # include <symengine/integer.h>
32 # include <symengine/logic.h>
33 # include <symengine/number.h>
34 # include <symengine/rational.h>
35 
36 // Number operations
37 # include <symengine/add.h>
38 # include <symengine/functions.h>
39 # include <symengine/mul.h>
40 # include <symengine/pow.h>
41 
42 // Evaluation
43 # include <symengine/eval.h>
44 # include <symengine/eval_arb.h>
45 # include <symengine/eval_double.h>
46 
47 // Differentiation
48 # include <deal.II/base/exceptions.h>
49 # include <deal.II/base/numbers.h>
50 
53 
54 # include <boost/serialization/split_member.hpp>
55 
56 # include <symengine/derivative.h>
57 
58 # include <algorithm>
59 # include <memory>
60 # include <sstream>
61 # include <type_traits>
62 # include <utility>
63 # include <vector>
64 
66 
67 namespace Differentiation
68 {
69  namespace SD
70  {
82  std::string,
83  << "The string '" << arg1
84  << "' could not be parsed successfully. Are you sure that (1) it "
85  << "consists of legitimate operations and syntax, and (2) you've "
86  << "previously declared all symbolic variables that are present "
87  << "in the expression?");
88 
90 
180  {
181  public:
186 
190  Expression();
191 
199  explicit Expression(const bool value);
200 
208  template <typename NumberType,
209  typename = typename std::enable_if<
211  explicit Expression(const NumberType &value);
212 
220  template <typename NumberType,
221  typename = typename std::enable_if<
223  explicit Expression(const std::complex<NumberType> &value);
224 
228  Expression(const SymEngine::integer_class &value);
229 
236  template <typename NumberType,
237  typename = typename std::enable_if<
239  Expression(const NumberType &numerator, const NumberType &denominator);
240 
244  Expression(const SymEngine::rational_class &value);
245 
282  Expression(const Expression &condition,
283  const Expression &expression_if_true,
284  const Expression &expression_if_false);
285 
307  Expression(const std::vector<std::pair<Expression, Expression>>
308  & condition_expression,
309  const Expression &expression_otherwise);
310 
330  Expression(const std::vector<std::pair<Expression, Expression>>
331  &condition_expression);
332 
333 
340  Expression(const char *symbol);
341 
354  Expression(const std::string &symb_expr,
355  const bool parse_as_expression = false);
356 
363  Expression(const std::string & symbol_func,
364  const types::symbol_vector &arguments);
365 
369  Expression(const Expression &rhs) = default;
370 
378  explicit Expression(const SymEngine::Expression &rhs);
379 
388  Expression(const SymEngine::RCP<const SymEngine::Basic> &rhs);
389 
393  Expression(Expression &&rhs) = default;
394 
403  Expression(SymEngine::RCP<const SymEngine::Basic> &&rhs);
404 
408  virtual ~Expression() = default;
409 
411 
416 
422  Expression &
423  parse(const std::string &expression);
424 
431  std::ostream &
432  print(std::ostream &stream) const;
433 
439  void
440  save(std::ostream &stream) const;
441 
452  void
453  load(std::istream &stream);
454 
462  template <class Archive>
463  void
464  save(Archive &archive, const unsigned int version) const;
465 
478  template <class Archive>
479  void
480  load(Archive &archive, const unsigned int version);
481 
482 # ifdef DOXYGEN
483 
496  template <class Archive>
497  void
498  serialize(Archive &archive, const unsigned int version);
499 # else
500  // This macro defines the serialize() method that is compatible with
501  // the templated save() and load() method that have been implemented.
502  BOOST_SERIALIZATION_SPLIT_MEMBER()
503 # endif
504 
506 
511 
515  const SymEngine::Expression &
516  get_expression() const;
517 
522  const SymEngine::Basic &
523  get_value() const;
524 
529  const SymEngine::RCP<const SymEngine::Basic> &
530  get_RCP() const;
531 
533 
538 
545  Expression &
546  operator=(const Expression &rhs);
547 
554  Expression &
555  operator=(Expression &&rhs) noexcept;
556 
563  Expression &
564  operator+=(const Expression &rhs);
565 
572  Expression &
573  operator-=(const Expression &rhs);
574 
581  Expression &
582  operator*=(const Expression &rhs);
583 
590  Expression &
591  operator/=(const Expression &rhs);
592 
594 
599 
606  template <typename NumberType>
607  Expression &
608  operator=(const NumberType &rhs);
609 
618  Expression
619  operator-() const;
620 
627  template <typename NumberType>
628  Expression &
629  operator+=(const NumberType &rhs);
630 
637  template <typename NumberType>
638  Expression &
639  operator-=(const NumberType &rhs);
640 
647  template <typename NumberType>
648  Expression &
649  operator*=(const NumberType &rhs);
650 
657  template <typename NumberType>
658  Expression &
659  operator/=(const NumberType &rhs);
660 
662 
667 
672  Expression
673  differentiate(const Expression &symbol) const;
674 
679  Expression
681  const SymEngine::RCP<const SymEngine::Symbol> &symbol) const;
682 
687  Expression
688  differentiate(const SymEngine::RCP<const SymEngine::Basic> &symbol) const;
689 
691 
696 
709  Expression
710  substitute(const types::substitution_map &substitution_values) const;
711 
728  Expression
729  substitute(const SymEngine::map_basic_basic &substitution_values) const;
730 
740  Expression
741  substitute(const Expression &symbol, const Expression &value) const;
742 
752  template <typename NumberType>
753  Expression
754  substitute(const Expression &symbol, const NumberType &value) const;
755 
763  template <typename ReturnType>
764  ReturnType
766  const types::substitution_map &substitution_values) const;
767 
779  template <typename ReturnType>
780  ReturnType
782  const SymEngine::map_basic_basic &substitution_values) const;
783 
785 
790 
841  template <typename ResultType>
842  explicit operator ResultType() const;
843 
848  explicit operator const SymEngine::Expression &() const;
849 
854  operator const SymEngine::RCP<const SymEngine::Basic> &() const;
855 
857 
858  protected:
862  SymEngine::Expression &
863  get_expression();
864 
865  private:
870  SymEngine::Expression expression;
871  };
872 
877 
885  template <>
886  struct is_symengine_number<Expression> : std::true_type
887  {};
888 
889 
897  template <>
898  struct is_sd_number<Expression> : std::true_type
899  {};
900 
902 
907 
913  std::ostream &
914  operator<<(std::ostream &stream, const Expression &expression);
915 
921  std::istream &
922  operator>>(std::istream &stream, Expression &expression);
923 
925 
930 
936  Expression
937  operator==(const Expression &lhs, const Expression &rhs);
938 
944  Expression
945  operator!=(const Expression &lhs, const Expression &rhs);
946 
952  Expression
953  operator<(const Expression &lhs, const Expression &rhs);
954 
960  Expression
961  operator>(const Expression &lhs, const Expression &rhs);
962 
968  Expression
969  operator<=(const Expression &lhs, const Expression &rhs);
970 
976  Expression
977  operator>=(const Expression &lhs, const Expression &rhs);
978 
980 
985 
992  Expression operator!(const Expression &expression);
993 
1000  Expression operator&(const Expression &lhs, const Expression &rhs);
1001 
1008  Expression
1009  operator|(const Expression &lhs, const Expression &rhs);
1010 
1017  Expression
1018  operator^(const Expression &lhs, const Expression &rhs);
1019 
1027  Expression
1028  operator&&(const Expression &lhs, const Expression &rhs);
1029 
1037  Expression
1038  operator||(const Expression &lhs, const Expression &rhs);
1039 
1041 
1046 
1052  Expression
1053  operator+(Expression lhs, const Expression &rhs);
1054 
1060  Expression
1061  operator-(Expression lhs, const Expression &rhs);
1062 
1068  Expression operator*(Expression lhs, const Expression &rhs);
1069 
1075  Expression
1076  operator/(Expression lhs, const Expression &rhs);
1077 
1086  template <typename NumberType,
1087  typename = typename std::enable_if<
1089  inline Expression
1090  operator+(const NumberType &lhs, const Expression &rhs)
1091  {
1092  return Expression(lhs) + rhs;
1093  }
1094 
1103  template <typename NumberType,
1104  typename = typename std::enable_if<
1106  inline Expression
1107  operator+(const Expression &lhs, const NumberType &rhs)
1108  {
1109  return lhs + Expression(rhs);
1110  }
1111 
1120  template <typename NumberType,
1121  typename = typename std::enable_if<
1123  inline Expression
1124  operator-(const NumberType &lhs, const Expression &rhs)
1125  {
1126  return Expression(lhs) - rhs;
1127  }
1128 
1137  template <typename NumberType,
1138  typename = typename std::enable_if<
1140  inline Expression
1141  operator-(const Expression &lhs, const NumberType &rhs)
1142  {
1143  return lhs - Expression(rhs);
1144  }
1145 
1154  template <typename NumberType,
1155  typename = typename std::enable_if<
1157  inline Expression operator*(const NumberType &lhs, const Expression &rhs)
1158  {
1159  return Expression(lhs) * rhs;
1160  }
1161 
1170  template <typename NumberType,
1171  typename = typename std::enable_if<
1173  inline Expression operator*(const Expression &lhs, const NumberType &rhs)
1174  {
1175  return lhs * Expression(rhs);
1176  }
1177 
1186  template <typename NumberType,
1187  typename = typename std::enable_if<
1189  inline Expression
1190  operator/(const NumberType &lhs, const Expression &rhs)
1191  {
1192  return Expression(lhs) / rhs;
1193  }
1194 
1203  template <typename NumberType,
1204  typename = typename std::enable_if<
1206  inline Expression
1207  operator/(const Expression &lhs, const NumberType &rhs)
1208  {
1209  return lhs / Expression(rhs);
1210  }
1211 
1213 
1214  } // namespace SD
1215 } // namespace Differentiation
1216 
1217 
1218 /* ---------------------- inline and template functions -------------------- */
1219 
1220 
1221 # ifndef DOXYGEN
1222 
1223 
1224 namespace Differentiation
1225 {
1226  namespace SD
1227  {
1228  template <typename NumberType, typename>
1229  Expression::Expression(const NumberType &value)
1230  : expression(value)
1231  {}
1232 
1233 
1234  template <typename NumberType, typename>
1235  Expression::Expression(const std::complex<NumberType> &value)
1236  : expression(value)
1237  {}
1238 
1239 
1240  template <typename NumberType, typename>
1241  Expression::Expression(const NumberType &numerator,
1242  const NumberType &denominator)
1243  : expression(
1244  SymEngine::Rational::from_two_ints(*SymEngine::integer(numerator),
1245  *SymEngine::integer(denominator)))
1246  {}
1247 
1248 
1249  template <class Archive>
1250  void
1251  Expression::save(Archive &ar, const unsigned int /*version*/) const
1252  {
1253  std::stringstream sstream;
1254  sstream << *this;
1255  const std::string expr = sstream.str();
1256  ar & expr;
1257  }
1258 
1259 
1260  template <class Archive>
1261  void
1262  Expression::load(Archive &ar, const unsigned int /*version*/)
1263  {
1264  std::string expr;
1265  ar & expr;
1266  parse(expr);
1267  }
1268 
1269 
1270  template <typename NumberType>
1271  Expression
1272  Expression::substitute(const Expression &symbol,
1273  const NumberType &value) const
1274  {
1275  Assert(SymEngine::is_a<SymEngine::Symbol>(symbol.get_value()),
1276  ExcMessage(
1277  "Substitution with a number that does not represent a symbol."));
1278 
1279  types::substitution_map sub_vals;
1280  sub_vals[symbol] = Expression(value);
1281  return substitute(sub_vals);
1282  }
1283 
1284 
1285  template <typename ReturnType>
1286  ReturnType
1288  const types::substitution_map &substitution_values) const
1289  {
1290  return static_cast<ReturnType>(substitute(substitution_values));
1291  }
1292 
1293 
1294  template <typename ReturnType>
1295  ReturnType
1297  const SymEngine::map_basic_basic &substitution_values) const
1298  {
1299  return static_cast<ReturnType>(substitute(substitution_values));
1300  }
1301 
1302 
1303  template <typename NumberType>
1304  Expression &
1305  Expression::operator=(const NumberType &rhs)
1306  {
1307  *this = Expression(rhs);
1308  return *this;
1309  }
1310 
1311 
1312  template <typename NumberType>
1313  Expression &
1314  Expression::operator+=(const NumberType &rhs)
1315  {
1316  *this = Expression(SymEngine::add(get_RCP(), Expression(rhs).get_RCP()));
1317  return *this;
1318  }
1319 
1320 
1321  template <typename NumberType>
1322  Expression &
1323  Expression::operator-=(const NumberType &rhs)
1324  {
1325  *this = Expression(SymEngine::sub(get_RCP(), Expression(rhs).get_RCP()));
1326  return *this;
1327  }
1328 
1329 
1330  template <typename NumberType>
1331  Expression &
1332  Expression::operator*=(const NumberType &rhs)
1333  {
1334  *this = Expression(SymEngine::mul(get_RCP(), Expression(rhs).get_RCP()));
1335  return *this;
1336  }
1337 
1338 
1339  template <typename NumberType>
1340  Expression &
1341  Expression::operator/=(const NumberType &rhs)
1342  {
1343  *this = Expression(SymEngine::div(get_RCP(), Expression(rhs).get_RCP()));
1344  return *this;
1345  }
1346 
1347 
1348  template <typename ResultType>
1349  Expression::operator ResultType() const
1350  {
1351  return static_cast<ResultType>(get_expression());
1352  }
1353 
1354  } // namespace SD
1355 } // namespace Differentiation
1356 
1357 
1358 // Specializations from numbers.h
1359 // These are required in order to make the SD::Expression class a compatible
1360 // number for the Tensor and SymmetricTensor classes
1361 
1362 // Forward declarations:
1363 template <int rank_, int dim, typename Number>
1364 class Tensor;
1365 
1366 namespace internal
1367 {
1368  template <>
1369  struct NumberType<Differentiation::SD::Expression>
1370  {
1371  static const Differentiation::SD::Expression &
1373  {
1374  return t;
1375  }
1376 
1377  template <
1378  typename T,
1379  typename = typename std::enable_if<std::is_arithmetic<T>::value>::type>
1381  value(const T &t)
1382  {
1384  }
1385 
1386  template <
1387  typename T,
1388  typename = typename std::enable_if<std::is_arithmetic<T>::value>::type>
1390  value(T &&t)
1391  {
1393  }
1394 
1395  template <
1396  typename T,
1397  typename = typename std::enable_if<std::is_arithmetic<T>::value>::type>
1399  value(const std::complex<T> &t)
1400  {
1402  }
1403 
1404  template <typename T, int dim>
1406  value(const Tensor<0, dim, T> &t)
1407  {
1408  return Differentiation::SD::Expression(static_cast<T>(t));
1409  }
1410 
1411  template <typename T, int dim>
1413  value(const Tensor<0, dim, std::complex<T>> &t)
1414  {
1415  return Differentiation::SD::Expression(static_cast<std::complex<T>>(t));
1416  }
1417  };
1418 } // namespace internal
1419 
1420 
1421 namespace numbers
1422 {
1423  template <>
1424  inline bool
1426  {
1427  if (SymEngine::is_a_Number(value.get_value()))
1428  {
1429  const SymEngine::RCP<const SymEngine::Number> number_rcp =
1430  SymEngine::rcp_static_cast<const SymEngine::Number>(value.get_RCP());
1431  return number_rcp->is_zero();
1432  }
1433 
1434  return false;
1435  }
1436 
1437  template <>
1438  inline bool
1440  const Differentiation::SD::Expression &value_2)
1441  {
1442  return (value_1.get_value().__cmp__(value_2.get_value()) == 0);
1443  }
1444 
1445  template <>
1446  inline bool
1448  const Differentiation::SD::Expression &value_2)
1449  {
1450  return (value_1.get_value().__cmp__(value_2.get_value()) == -1);
1451  }
1452 } // namespace numbers
1453 
1454 
1455 # endif // DOXYGEN
1456 
1458 
1459 #endif // DEAL_II_WITH_SYMENGINE
1460 
1461 #endif // dealii_differentiation_sd_symengine_number_types_h
Differentiation::SD::operator&&
Expression operator&&(const Expression &lhs, const Expression &rhs)
Definition: symengine_number_types.cc:501
Differentiation::SD::operator!
Expression operator!(const Expression &expression)
Definition: symengine_number_types.cc:438
Differentiation::SD::Expression::save
void save(std::ostream &stream) const
Definition: symengine_number_types.cc:188
Differentiation::SD::Expression::parse
Expression & parse(const std::string &expression)
Definition: symengine_number_types.cc:172
Differentiation::SD::Expression::operator/=
Expression & operator/=(const Expression &rhs)
Definition: symengine_number_types.cc:371
Differentiation::SD::operator==
Expression operator==(const Expression &lhs, const Expression &rhs)
Definition: symengine_number_types.cc:397
Differentiation::SD::is_symengine_number
Definition: symengine_number_traits.h:57
Differentiation::SD::operator>>
std::istream & operator>>(std::istream &stream, Expression &expression)
Definition: symengine_number_types.cc:387
Differentiation::SD::Expression::get_expression
const SymEngine::Expression & get_expression() const
Definition: symengine_number_types.cc:213
symengine_number_traits.h
Differentiation::SD::Expression::print
std::ostream & print(std::ostream &stream) const
Definition: symengine_number_types.cc:180
internal::NumberType::value
static constexpr const T & value(const T &t)
Definition: numbers.h:703
Differentiation::SD::operator|
Expression operator|(const Expression &lhs, const Expression &rhs)
Definition: symengine_number_types.cc:467
Differentiation::SD::operator+
Expression operator+(Expression lhs, const Expression &rhs)
Definition: symengine_number_types.cc:515
Differentiation::SD::Expression::substitute
Expression substitute(const types::substitution_map &substitution_values) const
Definition: symengine_number_types.cc:294
Differentiation::SD::types::symbol_vector
std::vector< SD::Expression > symbol_vector
Definition: symengine_types.h:71
Differentiation::SD::operator<<
std::ostream & operator<<(std::ostream &stream, const Expression &expression)
Definition: symengine_number_types.cc:379
Differentiation::SD::Expression::operator*=
Expression & operator*=(const Expression &rhs)
Definition: symengine_number_types.cc:363
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::ExcSymEngineParserError
static ::ExceptionBase & ExcSymEngineParserError(std::string arg1)
Differentiation::SD::Expression::get_value
const SymEngine::Basic & get_value() const
Definition: symengine_number_types.cc:227
symengine_types.h
Differentiation::SD::Expression::expression
SymEngine::Expression expression
Definition: symengine_number_types.h:870
Differentiation::SD::Expression::load
void load(std::istream &stream)
Definition: symengine_number_types.cc:198
Differentiation::SD::operator>
Expression operator>(const Expression &lhs, const Expression &rhs)
Definition: symengine_number_types.cc:418
Differentiation::SD::Expression::get_RCP
const SymEngine::RCP< const SymEngine::Basic > & get_RCP() const
Definition: symengine_number_types.cc:234
Differentiation::SD::Expression::Expression
Expression()
Definition: symengine_number_types.cc:48
LAPACKSupport::T
static const char T
Definition: lapack_support.h:163
Differentiation::SD::Expression::serialize
void serialize(Archive &archive, const unsigned int version)
Differentiation::SD::operator/
Expression operator/(Expression lhs, const Expression &rhs)
Definition: symengine_number_types.cc:538
StandardExceptions::ExcMessage
static ::ExceptionBase & ExcMessage(std::string arg1)
Differentiation::SD::operator<
Expression operator<(const Expression &lhs, const Expression &rhs)
Definition: symengine_number_types.cc:411
Differentiation::SD::operator||
Expression operator||(const Expression &lhs, const Expression &rhs)
Definition: symengine_number_types.cc:508
Tensor
Definition: tensor.h:450
DEAL_II_NAMESPACE_OPEN
#define DEAL_II_NAMESPACE_OPEN
Definition: config.h:358
Differentiation::SD::Expression::operator+=
Expression & operator+=(const Expression &rhs)
Definition: symengine_number_types.cc:347
Differentiation
Definition: numbers.h:645
Differentiation::SD::operator!=
Expression operator!=(const Expression &lhs, const Expression &rhs)
Definition: symengine_number_types.cc:404
DeclException1
#define DeclException1(Exception1, type1, outsequence)
Definition: exceptions.h:518
Differentiation::SD::operator<=
Expression operator<=(const Expression &lhs, const Expression &rhs)
Definition: symengine_number_types.cc:425
Differentiation::SD::Expression::operator=
Expression & operator=(const Expression &rhs)
Definition: symengine_number_types.cc:320
Differentiation::SD::substitute
Expression substitute(const Expression &expression, const types::substitution_map &substitution_map)
Differentiation::SD::Expression::operator-=
Expression & operator-=(const Expression &rhs)
Definition: symengine_number_types.cc:355
numbers
Definition: numbers.h:207
Differentiation::SD::is_sd_number
Definition: symengine_number_traits.h:44
exceptions.h
Differentiation::SD::Expression
Definition: symengine_number_types.h:179
Differentiation::SD::operator^
Expression operator^(const Expression &lhs, const Expression &rhs)
Definition: symengine_number_types.cc:484
Differentiation::SD::Expression::operator-
Expression operator-() const
Definition: symengine_number_types.cc:340
value
static const bool value
Definition: dof_tools_constraints.cc:433
Differentiation::SD::operator>=
Expression operator>=(const Expression &lhs, const Expression &rhs)
Definition: symengine_number_types.cc:432
Assert
#define Assert(cond, exc)
Definition: exceptions.h:1419
Differentiation::SD::Expression::substitute_and_evaluate
ReturnType substitute_and_evaluate(const types::substitution_map &substitution_values) const
Differentiation::SD::operator-
Expression operator-(Expression lhs, const Expression &rhs)
Definition: symengine_number_types.cc:523
Differentiation::SD::Expression::~Expression
virtual ~Expression()=default
Differentiation::SD::operator&
Expression operator&(const Expression &lhs, const Expression &rhs)
Definition: symengine_number_types.cc:450
config.h
Differentiation::SD::Expression::differentiate
Expression differentiate(const Expression &symbol) const
Definition: symengine_number_types.cc:261
internal
Definition: aligned_vector.h:369
DEAL_II_NAMESPACE_CLOSE
#define DEAL_II_NAMESPACE_CLOSE
Definition: config.h:359
Differentiation::SD::substitute_and_evaluate
ValueType substitute_and_evaluate(const Expression &expression, const types::substitution_map &substitution_map)
numbers.h
numbers::value_is_zero
constexpr bool value_is_zero(const Number &value)
Definition: numbers.h:941
numbers::value_is_less_than
bool value_is_less_than(const Number1 &value_1, const Number2 &value_2)
Definition: numbers.h:949
Differentiation::SD::operator*
Expression operator*(Expression lhs, const Expression &rhs)
Definition: symengine_number_types.cc:530