Expressions#

#include <heyoka/expression.hpp>

The expression class#

class expression#

Class to represent symbolic expressions.

This is the main class used to represent mathematical expressions in heyoka. It is a union of several types:

Because expressions are essentially trees, we refer to these types as the node types of an expression.

Expressions can be created in a variety of ways. After creation, expressions can be combined via arithmetic operators and mathematical functions to form new expressions of arbitrary complexity.

Expressions which consist of a single variable or a single constant/parameter are referred to as elementary expressions.

Expressions provide an immutable API: after creation, an expression cannot be changed in-place (except via assignment or swapping).

using value_type = std::variant<number, variable, func, param>#

The union of node types.

expression() noexcept#

Default constructor.

This constructor initialises the expression to a double-precision number with a value of zero.

explicit expression(float x) noexcept#
explicit expression(double x) noexcept#
explicit expression(long double x) noexcept#
explicit expression(mppp::real128 x) noexcept#
explicit expression(mppp::real x)#

Constructors from floating-point objects.

These constructors initialise the expression to a floating-point number with the input value x. Expressions can be constructed from objects of any floating-point type supported by number.

Parameters:

x – the construction argument.

Exception:

any exception raised by the copy constructor of mppp::real.

explicit expression(std::string s)#

Constructor from variable name.

This constructor initialises the expression to a variable constructed from the input string s.

Parameters:

s – the variable name.

Exception:

any exception thrown by the copy constructor of std::string.

explicit expression(number x)#
explicit expression(variable x)#
explicit expression(func x) noexcept#
explicit expression(param x) noexcept#

Constructors from objects of the node types.

These constructors will initialise the internal union with the input argument x.

Parameters:

x – the construction argument.

Exception:

any exception raised by the copy constructor of number or variable.

expression(const expression&)#
expression(expression&&) noexcept#
expression &operator=(const expression&)#
expression &operator=(expression&&) noexcept#
~expression()#

Expressions are copy/move constructible/assignable and destructible.

Note that because func employs reference semantics, copying/assigning a non-elementary expression is a constant-time operation.

Exception:

any exception thrown by the copy constructor/copy assignment operators of the active node types.

[[nodiscard]] const value_type &value() const noexcept#

Const accessor to the internal union.

Returns:

a const reference to the internal value_type instance.

Functions#

template<typename Arg0, typename ...Args>
auto make_vars(const Arg0 &str, const Args&... strs)#

Create variable expressions from strings.

This function will return one or more expression instances containing variables constructed from the input arguments. If a single argument is supplied, a single expression is returned. Otherwise, a std::array of expressions (one for each argument) is returned.

This function is enabled only if all input arguments are convertible to std::string.

Parameters:
  • str – the first string argument.

  • strs – the remaining string arguments.

Returns:

one or more expressions constructed from str and strs.

Exception:

any exception thrown by constructing std::string objects.

Example#

auto x = make_vars("x");
auto [y, z] = make_vars("y", "z");

Operators#

Arithmetic operators#

The expression class provides overloaded arithmetic binary operators and their in-place variants.

The overloaded binary operators require at least one argument to be an expression, while the other argument can be either another expression or any floating-point value supported by number.

The overloaded in-place operators require the first argument to be an expression, while the second argument can be either another expression or any floating-point value supported by number.

Comparison operators#

bool operator==(const expression &e1, const expression &e2) noexcept#
bool operator!=(const expression &e1, const expression &e2) noexcept#

Expression (in)equality.

These operators compare e1 and e2 for structural equality. That is, two expressions are considered equal if the underlying symbolic trees are identical. It is important to emphasise that while structural equality implies mathematical equivalence, the opposite is not true: it is possible to define structurally-different expressions which are mathematically equivalent, such as \(\sin^2\left(x\right)+\cos^2\left(x\right)\) and \(1\).

Parameters:
  • e1 – the first operand.

  • e2 – the second operand.

Returns:

the result of the comparison.

User-defined literals#

expression literals::operator""_flt(long double)#
expression literals::operator""_flt(unsigned long long)#
expression literals::operator""_dbl(long double)#
expression literals::operator""_dbl(unsigned long long)#
expression literals::operator""_ldbl(long double)#
expression literals::operator""_ldbl(unsigned long long)#
template<char... Chars>
expression literals::operator""_f128()#