7#include <initializer_list>
8#include <source_location>
13#include <gch/small_vector.hpp>
15#include "sleipnir/autodiff/expression.hpp"
16#include "sleipnir/autodiff/expression_graph.hpp"
17#include "sleipnir/autodiff/sleipnir_base.hpp"
18#include "sleipnir/util/assert.hpp"
19#include "sleipnir/util/concepts.hpp"
21#ifndef SLEIPNIR_DISABLE_DIAGNOSTICS
22#include "sleipnir/util/print.hpp"
31template <
typename Scalar>
32class AdjointExpressionGraph;
36template <
typename Scalar,
int UpLo = Eigen::Lower | Eigen::Upper>
37 requires(UpLo == Eigen::Lower) || (UpLo == (Eigen::Lower | Eigen::Upper))
40template <
typename Scalar>
48template <
typename Scalar_>
74 : expr{detail::make_expression_ptr<detail::ConstExpression<
Scalar>>(
84 slp_assert(
value.rows() == 1 &&
value.cols() == 1);
94 : expr{detail::make_expression_ptr<detail::ConstExpression<
Scalar>>(
104 : expr{detail::make_expression_ptr<detail::ConstExpression<
Scalar>>(
129 expr = detail::make_expression_ptr<detail::ConstExpression<Scalar>>(
value);
130 m_graph_initialized =
false;
141#ifndef SLEIPNIR_DISABLE_DIAGNOSTICS
144 if (expr->args[0] !=
nullptr) {
145 auto location = std::source_location::current();
148 "WARNING: {}:{}: {}: Modified the value of a dependent variable",
161 if (!m_graph_initialized) {
162 m_graph = detail::topological_sort(expr);
163 m_graph_initialized =
true;
165 detail::update_values(m_graph);
176 ExpressionType
type()
const {
return expr->type(); }
185 template <ScalarLike LHS, SleipnirScalarLike<Scalar> RHS>
197 template <SleipnirScalarLike<Scalar> LHS, ScalarLike RHS>
315 detail::make_expression_ptr<detail::DecisionVariableExpression<Scalar>>();
319 gch::small_vector<detail::Expression<Scalar>*> m_graph;
322 bool m_graph_initialized =
false;
324 template <
typename Scalar>
326 template <
typename Scalar>
328 template <
typename Scalar>
330 template <
typename Scalar>
332 template <
typename Scalar>
335 template <
typename Scalar>
338 template <
typename Scalar>
341 template <
typename Scalar>
343 template <
typename Scalar>
345 template <
typename Scalar>
347 template <
typename Scalar>
349 template <
typename Scalar>
351 template <
typename Scalar>
354 template <
typename Scalar>
357 template <
typename Scalar>
360 template <
typename Scalar>
362 template <
typename Scalar>
364 template <
typename Scalar>
367 template <
typename Scalar>
370 template <
typename Scalar>
373 template <
typename Scalar>
375 template <
typename Scalar>
377 template <
typename Scalar>
379 template <
typename Scalar>
381 template <
typename Scalar>
383 template <
typename Scalar>
385 template <
typename Scalar>
391 template <
typename Scalar,
int UpLo>
392 requires(
UpLo == Eigen::Lower) || (
UpLo == (Eigen::Lower | Eigen::Upper))
394 template <
typename Scalar>
398template <
template <
typename>
typename T,
typename Scalar>
399 requires SleipnirMatrixLike<T<Scalar>, Scalar>
400Variable(T<Scalar>) -> Variable<Scalar>;
402template <std::
floating_po
int T>
403Variable(T) -> Variable<T>;
405template <std::
integral T>
406Variable(T) -> Variable<T>;
414template <
typename Scalar>
415Variable<Scalar> abs(
const Variable<Scalar>& x) {
416 return Variable{detail::abs(x.expr)};
425template <
typename Scalar>
426Variable<Scalar> acos(
const Variable<Scalar>& x) {
427 return Variable{detail::acos(x.expr)};
436template <
typename Scalar>
437Variable<Scalar> asin(
const Variable<Scalar>& x) {
438 return Variable{detail::asin(x.expr)};
447template <
typename Scalar>
448Variable<Scalar> atan(
const Variable<Scalar>& x) {
449 return Variable{detail::atan(x.expr)};
459template <
typename Scalar>
460Variable<Scalar> atan2(
const ScalarLike
auto& y,
const Variable<Scalar>& x) {
461 return Variable{detail::atan2(Variable<Scalar>(y).expr, x.expr)};
471template <
typename Scalar>
472Variable<Scalar> atan2(
const Variable<Scalar>& y,
const ScalarLike
auto& x) {
473 return Variable{detail::atan2(y.expr, Variable<Scalar>(x).expr)};
483template <
typename Scalar>
484Variable<Scalar> atan2(
const Variable<Scalar>& y,
const Variable<Scalar>& x) {
485 return Variable{detail::atan2(y.expr, x.expr)};
494template <
typename Scalar>
495Variable<Scalar> cbrt(
const Variable<Scalar>& x) {
496 return Variable{detail::cbrt(x.expr)};
505template <
typename Scalar>
506Variable<Scalar> cos(
const Variable<Scalar>& x) {
507 return Variable{detail::cos(x.expr)};
516template <
typename Scalar>
517Variable<Scalar> cosh(
const Variable<Scalar>& x) {
518 return Variable{detail::cosh(x.expr)};
527template <
typename Scalar>
528Variable<Scalar> erf(
const Variable<Scalar>& x) {
529 return Variable{detail::erf(x.expr)};
538template <
typename Scalar>
539Variable<Scalar> exp(
const Variable<Scalar>& x) {
540 return Variable{detail::exp(x.expr)};
550template <
typename Scalar>
551Variable<Scalar> hypot(
const ScalarLike
auto& x,
const Variable<Scalar>& y) {
552 return Variable{detail::hypot(Variable<Scalar>(x).expr, y.expr)};
562template <
typename Scalar>
563Variable<Scalar> hypot(
const Variable<Scalar>& x,
const ScalarLike
auto& y) {
564 return Variable{detail::hypot(x.expr, Variable<Scalar>(y).expr)};
574template <
typename Scalar>
575Variable<Scalar> hypot(
const Variable<Scalar>& x,
const Variable<Scalar>& y) {
576 return Variable{detail::hypot(x.expr, y.expr)};
585template <
typename Scalar>
586Variable<Scalar> log(
const Variable<Scalar>& x) {
587 return Variable{detail::log(x.expr)};
596template <
typename Scalar>
597Variable<Scalar> log10(
const Variable<Scalar>& x) {
598 return Variable{detail::log10(x.expr)};
608template <
typename Scalar>
609Variable<Scalar> pow(
const ScalarLike
auto& base,
610 const Variable<Scalar>& power) {
611 return Variable{detail::pow(Variable<Scalar>(base).expr, power.expr)};
621template <
typename Scalar>
622Variable<Scalar> pow(
const Variable<Scalar>& base,
623 const ScalarLike
auto& power) {
624 return Variable{detail::pow(base.expr, Variable<Scalar>(power).expr)};
634template <
typename Scalar>
635Variable<Scalar> pow(
const Variable<Scalar>& base,
636 const Variable<Scalar>& power) {
637 return Variable{detail::pow(base.expr, power.expr)};
646template <
typename Scalar>
647Variable<Scalar> sign(
const Variable<Scalar>& x) {
648 return Variable{detail::sign(x.expr)};
657template <
typename Scalar>
658Variable<Scalar> sin(
const Variable<Scalar>& x) {
659 return Variable{detail::sin(x.expr)};
668template <
typename Scalar>
669Variable<Scalar> sinh(
const Variable<Scalar>& x) {
670 return Variable{detail::sinh(x.expr)};
679template <
typename Scalar>
680Variable<Scalar> sqrt(
const Variable<Scalar>& x) {
681 return Variable{detail::sqrt(x.expr)};
690template <
typename Scalar>
691Variable<Scalar> tan(
const Variable<Scalar>& x) {
692 return Variable{detail::tan(x.expr)};
701template <
typename Scalar>
702Variable<Scalar> tanh(
const Variable<Scalar>& x) {
703 return Variable{detail::tanh(x.expr)};
714template <
typename Scalar>
715Variable<Scalar> hypot(
const Variable<Scalar>& x,
const Variable<Scalar>& y,
716 const Variable<Scalar>& z) {
717 return Variable{sqrt(pow(x, 2) + pow(y, 2) + pow(z, 2))};
725template <
typename Scalar, ScalarLike LHS, ScalarLike RHS>
726 requires SleipnirScalarLike<LHS, Scalar> || SleipnirScalarLike<RHS, Scalar>
727auto make_constraints(LHS&& lhs, RHS&& rhs) {
728 gch::small_vector<Variable<Scalar>> constraints;
729 constraints.emplace_back(lhs - rhs);
734template <
typename Scalar, ScalarLike LHS, MatrixLike RHS>
735 requires SleipnirScalarLike<LHS, Scalar> || SleipnirMatrixLike<RHS, Scalar>
736auto make_constraints(LHS&& lhs, RHS&& rhs) {
737 gch::small_vector<Variable<Scalar>> constraints;
738 constraints.reserve(rhs.rows() * rhs.cols());
740 for (
int row = 0; row < rhs.rows(); ++row) {
741 for (
int col = 0; col < rhs.cols(); ++col) {
743 constraints.emplace_back(lhs - rhs[row, col]);
750template <
typename Scalar, MatrixLike LHS, ScalarLike RHS>
751 requires SleipnirMatrixLike<LHS, Scalar> || SleipnirScalarLike<RHS, Scalar>
752auto make_constraints(LHS&& lhs, RHS&& rhs) {
753 gch::small_vector<Variable<Scalar>> constraints;
754 constraints.reserve(lhs.rows() * lhs.cols());
756 for (
int row = 0; row < lhs.rows(); ++row) {
757 for (
int col = 0; col < lhs.cols(); ++col) {
759 constraints.emplace_back(lhs[row, col] - rhs);
766template <
typename Scalar, MatrixLike LHS, MatrixLike RHS>
767 requires SleipnirMatrixLike<LHS, Scalar> || SleipnirMatrixLike<RHS, Scalar>
768auto make_constraints(LHS&& lhs, RHS&& rhs) {
769 slp_assert(lhs.rows() == rhs.rows() && lhs.cols() == rhs.cols());
771 gch::small_vector<Variable<Scalar>> constraints;
772 constraints.reserve(lhs.rows() * lhs.cols());
774 for (
int row = 0; row < lhs.rows(); ++row) {
775 for (
int col = 0; col < lhs.cols(); ++col) {
777 constraints.emplace_back(lhs[row, col] - rhs[row, col]);
789template <
typename Scalar>
803 elem.constraints.end());
818 elem.constraints.end());
831 template <
typename LHS,
typename RHS>
854template <
typename Scalar>
869 elem.constraints.end());
885 elem.constraints.end());
898 template <
typename LHS,
typename RHS>
922template <
typename LHS,
typename RHS>
923 requires(ScalarLike<LHS> || MatrixLike<LHS>) && SleipnirType<LHS> &&
924 (ScalarLike<RHS> || MatrixLike<RHS>) && (!SleipnirType<RHS>)
925auto operator==(LHS&& lhs, RHS&& rhs) {
926 return EqualityConstraints<typename std::decay_t<LHS>::Scalar>{lhs, rhs};
935template <
typename LHS,
typename RHS>
936 requires(ScalarLike<LHS> || MatrixLike<LHS>) && (!SleipnirType<LHS>) &&
937 (ScalarLike<RHS> || MatrixLike<RHS>) && SleipnirType<RHS>
938auto operator==(LHS&& lhs, RHS&& rhs) {
939 return EqualityConstraints<typename std::decay_t<RHS>::Scalar>{lhs, rhs};
948template <
typename LHS,
typename RHS>
949 requires(ScalarLike<LHS> || MatrixLike<LHS>) && SleipnirType<LHS> &&
950 (ScalarLike<RHS> || MatrixLike<RHS>) && SleipnirType<RHS>
951auto operator==(LHS&& lhs, RHS&& rhs) {
952 return EqualityConstraints<typename std::decay_t<LHS>::Scalar>{lhs, rhs};
962template <
typename LHS,
typename RHS>
963 requires(ScalarLike<LHS> || MatrixLike<LHS>) &&
964 (ScalarLike<RHS> || MatrixLike<RHS>) &&
965 (SleipnirType<LHS> || SleipnirType<RHS>)
966auto operator<(LHS&& lhs, RHS&& rhs) {
977template <
typename LHS,
typename RHS>
978 requires(ScalarLike<LHS> || MatrixLike<LHS>) &&
979 (ScalarLike<RHS> || MatrixLike<RHS>) &&
980 (SleipnirType<LHS> || SleipnirType<RHS>)
981auto operator<=(LHS&& lhs, RHS&& rhs) {
992template <
typename LHS,
typename RHS>
993 requires(ScalarLike<LHS> || MatrixLike<LHS>) &&
994 (ScalarLike<RHS> || MatrixLike<RHS>) &&
995 (SleipnirType<LHS> || SleipnirType<RHS>)
996auto operator>(LHS&& lhs, RHS&& rhs) {
1007template <
typename LHS,
typename RHS>
1008 requires(ScalarLike<LHS> || MatrixLike<LHS>) && SleipnirType<LHS> &&
1009 (ScalarLike<RHS> || MatrixLike<RHS>) && (!SleipnirType<RHS>)
1010auto operator>=(LHS&& lhs, RHS&& rhs) {
1011 return InequalityConstraints<typename std::decay_t<LHS>::Scalar>{lhs, rhs};
1021template <
typename LHS,
typename RHS>
1022 requires(ScalarLike<LHS> || MatrixLike<LHS>) && (!SleipnirType<LHS>) &&
1023 (ScalarLike<RHS> || MatrixLike<RHS>) && SleipnirType<RHS>
1024auto operator>=(LHS&& lhs, RHS&& rhs) {
1025 return InequalityConstraints<typename std::decay_t<RHS>::Scalar>{lhs, rhs};
1035template <
typename LHS,
typename RHS>
1036 requires(ScalarLike<LHS> || MatrixLike<LHS>) && SleipnirType<LHS> &&
1037 (ScalarLike<RHS> || MatrixLike<RHS>) && SleipnirType<RHS>
1038auto operator>=(LHS&& lhs, RHS&& rhs) {
1039 return InequalityConstraints<typename std::decay_t<LHS>::Scalar>{lhs, rhs};
1051template <
typename Scalar>
1052struct NumTraits<slp::Variable<Scalar>> : NumTraits<Scalar> {
1061 static constexpr int IsComplex = 0;
1063 static constexpr int IsInteger = 0;
1065 static constexpr int IsSigned = 1;
1067 static constexpr int RequireInitialization = 1;
1069 static constexpr int ReadCost = 1;
1071 static constexpr int AddCost = 3;
1073 static constexpr int MulCost = 3;
Definition hessian.hpp:30
Definition intrusive_shared_ptr.hpp:29
Definition jacobian.hpp:30
Definition sleipnir_base.hpp:11
Definition variable.hpp:49
ExpressionType type() const
Definition variable.hpp:176
friend Variable< Scalar > operator*(const LHS &lhs, const RHS &rhs)
Definition variable.hpp:186
Variable(const detail::ExpressionPtr< Scalar > &expr)
Definition variable.hpp:112
Variable< Scalar > & operator/=(const Variable< Scalar > &rhs)
Definition variable.hpp:243
Variable< Scalar > & operator*=(const Variable< Scalar > &rhs)
Definition variable.hpp:220
friend Variable< Scalar > operator+(const Variable< Scalar > &lhs, const Variable< Scalar > &rhs)
Definition variable.hpp:255
void set_value(Scalar value)
Definition variable.hpp:140
friend Variable< Scalar > operator/(const Variable< Scalar > &lhs, const Variable< Scalar > &rhs)
Definition variable.hpp:232
Variable(std::floating_point auto value)
Definition variable.hpp:93
constexpr Variable(detail::ExpressionPtr< Scalar > &&expr)
Definition variable.hpp:119
friend Variable< Scalar > operator+(const Variable< Scalar > &lhs)
Definition variable.hpp:308
Variable(Scalar value)
Definition variable.hpp:72
constexpr Variable(std::nullptr_t)
Definition variable.hpp:64
Variable< Scalar > & operator=(ScalarLike auto value)
Definition variable.hpp:128
friend Variable< Scalar > operator-(const Variable< Scalar > &lhs)
Definition variable.hpp:299
friend Variable< Scalar > operator*(const Variable< Scalar > &lhs, const Variable< Scalar > &rhs)
Definition variable.hpp:209
Variable(std::integral auto value)
Definition variable.hpp:103
Variable(SleipnirMatrixLike< Scalar > auto value)
Definition variable.hpp:83
Variable< Scalar > & operator+=(const Variable< Scalar > &rhs)
Definition variable.hpp:266
Scalar_ Scalar
Definition variable.hpp:54
Scalar value()
Definition variable.hpp:160
Variable< Scalar > & operator-=(const Variable< Scalar > &rhs)
Definition variable.hpp:289
friend Variable< Scalar > operator-(const Variable< Scalar > &lhs, const Variable< Scalar > &rhs)
Definition variable.hpp:278
Definition adjoint_expression_graph.hpp:26
Definition concepts.hpp:18
Definition concepts.hpp:24
Definition concepts.hpp:33
Definition concepts.hpp:15
Definition variable.hpp:790
EqualityConstraints(LHS &&lhs, RHS &&rhs)
Definition variable.hpp:835
EqualityConstraints(std::initializer_list< EqualityConstraints > equality_constraints)
Definition variable.hpp:799
gch::small_vector< Variable< Scalar > > constraints
A vector of scalar equality constraints.
Definition variable.hpp:792
EqualityConstraints(const std::vector< EqualityConstraints > &equality_constraints)
Definition variable.hpp:814
Definition variable.hpp:855
gch::small_vector< Variable< Scalar > > constraints
A vector of scalar inequality constraints.
Definition variable.hpp:857
InequalityConstraints(LHS &&lhs, RHS &&rhs)
Definition variable.hpp:902
InequalityConstraints(const std::vector< InequalityConstraints > &inequality_constraints)
Definition variable.hpp:881
InequalityConstraints(std::initializer_list< InequalityConstraints > inequality_constraints)
Definition variable.hpp:865