]> https://gitweb.dealii.org/ - dealii.git/commitdiff
Implement substitution and evaluation for SD scalar types
authorJean-Paul Pelteret <jppelteret@gmail.com>
Tue, 7 May 2019 16:34:01 +0000 (18:34 +0200)
committerJean-Paul Pelteret <jppelteret@gmail.com>
Sun, 12 May 2019 19:24:02 +0000 (21:24 +0200)
include/deal.II/differentiation/sd/symengine_scalar_operations.h
source/differentiation/sd/symengine_scalar_operations.cc

index 257adb0005f235188a51bc2eba10a53dba9e9d7b..ce712bd3eb396f60d5249a92af8ab000ef2aecc3 100644 (file)
@@ -1246,6 +1246,155 @@ namespace Differentiation
       const std::vector<std::pair<ExpressionType, ValueType>> &symbol_values,
       const bool force_cyclic_dependency_resolution = false);
 
+    /**
+     * Perform a single substitution sweep of a set of symbols into the given
+     * symbolic expression.
+     * The symbols in the @p expression that correspond to the entry keys
+     * of the @p substitution_map are substituted with the map entry's associated
+     * value.
+     * This substitution function may be used to give a set of symbolic
+     * variables either a numeric interpretation or some symbolic definition.
+     *
+     * @note It is not required that all symbolic expressions be fully resolved
+     * when using this function. In other words, partial substitutions are
+     * valid.
+     *
+     * @note This function call is typically expensive, as by default it performs a
+     * dictionary substitution for the symbols in the symbolic expression.
+     * Should the numerical values of some symbolic expression be derired, then
+     * this performance deficit may be mitigated through the use of the
+     * BatchOptimizer class.
+     * Situation dependent, the overhead of using a typical dictionary based
+     * substitution may be on par with that of the a substitution performed
+     * using a BatchOptimizer. This is because there is an overhead to setting
+     * up the optimizer, so this should be taken into consideration if
+     * substitution is to occur for the given symbolic
+     * expression only a few times.
+     *
+     * @note If the symbols stored in the map are explicitly dependent on one another,
+     * then the returned result depends on order in which the map is traversed.
+     * It is recommended to first resolve all inter-dependencies in the map
+     * using the resolve_explicit_dependencies() function.
+     * Examples:
+     *   1. If <tt>map["a"] == 1</tt> and <tt>map["b"] == "a"+ 2</tt> then
+     *     then the function $f(a,b(a)) = a+b$ will be evaluated and the result
+     *     $f\vert_{a=1,b=a+2} = 3+a$ is returned. This return is because the
+     *     symbol "a" is substituted throughout the function first, and only
+     * then is the symbol "b(a)" substituted, by which time its explicit
+     * dependency on "a" cannot be resolved.
+     *  2. If <tt>map["a"] == "b"+2</tt> and <tt>map["b"] == 1</tt> then
+     *     then the function $f(a(b),a) = a+b$ will be evaluated and the result
+     *     $f\vert_{a=b+2, b} = [b+2+b]_{b=1} = 4$ is returned. This is because
+     * the explicitly dependent symbol "a(b)" is substituted first followed by
+     * the symbol "b".
+     */
+    Expression
+    substitute(const Expression &             expression,
+               const types::substitution_map &substitution_map);
+
+    /**
+     * Perform a substitution of the @p symbol into the given
+     * @p expression, with the result that all matches are assigned
+     * the corresponding @p value.
+     * This substitution function may be used to give a set of symbolic
+     * variables either a numeric interpretation or some symbolic definition.
+     *
+     * For more information regarding the performance of symbolic substitution,
+     * see the other @ref substitute(const Expression &,
+     * const types::substitution_map &) function.
+     *
+     * @note It is not required that all symbolic expressions be fully resolved
+     * when using this function. In other words, partial substitutions are
+     * valid.
+     */
+    template <typename ValueType>
+    Expression
+    substitute(const Expression &expression,
+               const Expression &symbol,
+               const ValueType & value);
+
+    /**
+     * Perform a single substitution sweep of a set of symbols into the given
+     * symbolic expression.
+     * The symbols in the @p expression that correspond to a matching entry key
+     * of the @p symbol_values vector entry are substituted by the entry's associated
+     * value.
+     * This substitution function may be used to give a set of symbolic
+     * variables either a numeric interpretation or some symbolic definition.
+     *
+     * For more information regarding the performance of symbolic substitution,
+     * see the other @ref substitute(const Expression &,
+     * const types::substitution_map &) function.
+     *
+     * @note It is not required that all symbolic expressions be fully resolved
+     * when using this function. In other words, partial substitutions are
+     * valid.
+     *
+     * @tparam Args Any symbolic type and value combination that is understood
+     *         by the make_substitution_map() functions. This includes
+     *         arguments involving individual Expressions,
+     *         std::vector<Expression>, as well as Tensors and SymmetricTensors
+     *         of Expressions.
+     */
+    template <typename ExpressionType = SD::Expression, typename... Args>
+    ExpressionType
+    substitute(const ExpressionType &expression, const Args &... symbol_values);
+
+    /**
+     * Perform a single substitution sweep of a set of symbols into the given
+     * symbolic function, and immediately evaluate the result.
+     * The symbols in the @p expression that correspond to the entry keys
+     * of the @p substitution_map are substituted with the map entry's associated
+     * value.
+     * This substitution function is used to give a set of symbolic variables
+     * a numeric interpretation, with the returned result being of the type
+     * specified by the @p ValueType template argument.
+     *
+     * For more information regarding the performance of symbolic substitution,
+     * and the outcome of evaluation using a substitution map with cyclic
+     * dependencies, see the @ref substitute(const Expression &,
+     * const types::substitution_map &) function.
+     *
+     * @note It is required that all symbols in the @p expression be
+     * successfully resolved by the @p substitution_map.
+     * If only partial substitution is performed, then an error is thrown.
+     */
+    template <typename ValueType>
+    ValueType
+    substitute_and_evaluate(const Expression &             expression,
+                            const types::substitution_map &substitution_map);
+
+    /**
+     * Perform a single substitution sweep of a set of symbols into the given
+     * symbolic function, and immediately evaluate the result.
+     * The symbols in the @p expression that correspond to the entry keys
+     * of the @p substitution_map are substituted with the map entry's associated
+     * value.
+     * This substitution function is used to give a set of symbolic variables
+     * a numeric interpretation, with the returned result being of the type
+     * specified by the @p ValueType template argument.
+     *
+     * For more information regarding the performance of symbolic substitution,
+     * and the outcome of evaluation using a substitution map with cyclic
+     * dependencies, see the @ref substitute(const Expression &,
+     * const types::substitution_map &) function.
+     *
+     * @note It is required that all symbols in the @p expression be
+     * successfully resolved by the substitution map that is generated with the
+     * input collection of @p symbol_values.
+     * If only partial substitution is performed, then an error is thrown.
+     *
+     * @tparam Args Any symbolic type and value combination that is understood
+     *         by the make_substitution_map() functions. This includes
+     *         arguments involving individual Expressions,
+     *         std::vector<Expression>, as well as Tensors and SymmetricTensors
+     *         of Expressions.
+     */
+    template <typename ValueType, typename... Args>
+    ValueType
+    substitute_and_evaluate(const Expression &expression,
+                            const Args &... symbol_values);
+
     //@}
 
   } // namespace SD
@@ -1705,6 +1854,45 @@ namespace Differentiation
                                            force_cyclic_dependency_resolution);
     }
 
+
+    template <typename ValueType>
+    Expression
+    substitute(const Expression &expression,
+               const Expression &symbol,
+               const ValueType & value)
+    {
+      return expression.substitute(symbol, value);
+    }
+
+
+    template <typename ExpressionType, typename... Args>
+    ExpressionType
+    substitute(const ExpressionType &expression, const Args &... symbol_values)
+    {
+      // Call other function
+      return substitute(expression, make_substitution_map(symbol_values...));
+    }
+
+
+    template <typename ValueType>
+    ValueType
+    substitute_and_evaluate(const Expression &             expression,
+                            const types::substitution_map &substitution_map)
+    {
+      return expression.substitute_and_evaluate<ValueType>(substitution_map);
+    }
+
+
+    template <typename ValueType, typename... Args>
+    ValueType
+    substitute_and_evaluate(const Expression &expression,
+                            const Args &... symbol_values)
+    {
+      // Call other function
+      return substitute_and_evaluate<ValueType>(
+        expression, make_substitution_map(symbol_values...));
+    }
+
   } // namespace SD
 } // namespace Differentiation
 
index 438b80425710ee6d6d5ad85155c1b3cc14bd235d..6366677ba178630cbae0989a87cc90cd880487c8 100644 (file)
@@ -253,6 +253,14 @@ namespace Differentiation
       return symbol_values_resolved;
     }
 
+
+    Expression
+    substitute(const Expression &             expression,
+               const types::substitution_map &substitution_map)
+    {
+      return expression.substitute(substitution_map);
+    }
+
   } // namespace SD
 } // namespace Differentiation
 

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.