|
| 1 | +#pragma once |
| 2 | + |
| 3 | +#include "drake/common/autodiff/auto_diff_derivatives_xpr.h" |
| 4 | +#include "drake/common/autodiff/internal/partials.h" |
| 5 | +#include "drake/common/drake_copyable.h" |
| 6 | +#include "drake/common/eigen_types.h" |
| 7 | + |
| 8 | +namespace drake { |
| 9 | +namespace autodiff { |
| 10 | + |
| 11 | +/** A scalar type that performs automatic differentiation, similar to |
| 12 | +Eigen::AutoDiffScalar<Eigen::VectorXd>. Unlike Eigen::AutoDiffScalar, |
| 13 | +Drake's AutoDiff is not templated; it only supports dynamically-sized |
| 14 | +derivatives using floating-point doubles. |
| 15 | +
|
| 16 | +However, using modern C++ implementation tricks (reference-counted, |
| 17 | +copy-on-write derivatives storage) and a more careful representation |
| 18 | +(maintaining the derivatives scale separately, and using inline storage |
| 19 | +in case only one partial is non-zero) it runs much faster than |
| 20 | +Eigen::AutoDiffScalar<Eigen::VectorXd>. */ |
| 21 | +class AutoDiff { |
| 22 | + public: |
| 23 | + DRAKE_DEFAULT_COPY_AND_MOVE_AND_ASSIGN(AutoDiff); |
| 24 | + |
| 25 | + /** Compatibility alias to mimic Eigen::AutoDiffScalar. */ |
| 26 | + using DerType = Eigen::VectorXd; |
| 27 | + |
| 28 | + /** Compatibility alias to mimic Eigen::AutoDiffScalar. */ |
| 29 | + using Scalar = double; |
| 30 | + |
| 31 | + /** Constructs zero. */ |
| 32 | + AutoDiff() = default; |
| 33 | + |
| 34 | + /** Constructs a value with empty derivatives. */ |
| 35 | + // NOLINTNEXTLINE(runtime/explicit): This conversion is desirable. |
| 36 | + AutoDiff(double value) : value_{value} {} |
| 37 | + |
| 38 | + /** Constructs a value with a single partial derivative of 1.0 at the given |
| 39 | + `offset` in a vector of `size` otherwise-zero derivatives. */ |
| 40 | + AutoDiff(double value, Eigen::Index size, Eigen::Index offset) |
| 41 | + : value_{value}, |
| 42 | + partials_{size, offset} {} |
| 43 | + |
| 44 | + /** Constructs a value with the given derivatives. */ |
| 45 | + AutoDiff( |
| 46 | + double value, |
| 47 | + const Eigen::Ref<const Eigen::VectorXd>& derivatives) |
| 48 | + : value_{value}, |
| 49 | + partials_{derivatives} {} |
| 50 | + |
| 51 | + /** Assigns a value and clears the derivatives. */ |
| 52 | + AutoDiff& operator=(double value) { |
| 53 | + value_ = value; |
| 54 | + partials_.SetZero(); |
| 55 | + return *this; |
| 56 | + } |
| 57 | + |
| 58 | + ~AutoDiff() = default; |
| 59 | + |
| 60 | + /** Returns the value part of this AutoDiff (readonly). */ |
| 61 | + double value() const { return value_; } |
| 62 | + |
| 63 | + /** (Advanced) Returns the value part of this AutoDiff (mutable). |
| 64 | + Operations on this value will NOT alter the dervatives. */ |
| 65 | + double& value() { return value_; } |
| 66 | + |
| 67 | + /** Returns a view of the dervatives part of this AutoDiff (readonly). */ |
| 68 | + AutoDiffDerivativesConstXpr derivatives() const { |
| 69 | + return partials_.make_const_xpr(); |
| 70 | + } |
| 71 | + |
| 72 | + /** (Advanced) Returns a mutable view of the dervatives part of this AutoDiff. |
| 73 | +
|
| 74 | + Instead of mutating the derivatives after construction, it's generally |
| 75 | + preferable to set them directly in the constructor if possible. |
| 76 | +
|
| 77 | + @note this function name is kept for compatibility with Eigen::AutoDiffScalar |
| 78 | + but it does NOT run in constant-time even though its name is lowercase. |
| 79 | + Calling this function often needs to copy the derivatives prior to returning |
| 80 | + the reference, so is O(N) in the size() of the derivatives. */ |
| 81 | + AutoDiffDerivativesMutableXpr derivatives() { |
| 82 | + return partials_.MakeMutableXpr(); |
| 83 | + } |
| 84 | + |
| 85 | + /** (Internal use only) |
| 86 | + Users should call derivatives() instead. */ |
| 87 | + const internal::Partials& partials() const { return partials_; } |
| 88 | + |
| 89 | + /** (Internal use only) |
| 90 | + Users should call derivatives() instead. */ |
| 91 | + internal::Partials& partials() { return partials_; } |
| 92 | + |
| 93 | + private: |
| 94 | + double value_{0.0}; |
| 95 | + internal::Partials partials_; |
| 96 | +}; |
| 97 | + |
| 98 | +} // namespace autodiff |
| 99 | +} // namespace drake |
| 100 | + |
| 101 | +/* clang-format off to disable clang-format-includes */ |
| 102 | +// These futher refine our AutoDiff type and must appear in exactly this order. |
| 103 | +#include "drake/common/autodiff/internal/standard_operations.h" |
| 104 | +#include "drake/common/autodiff/internal/eigen_specializations.h" |
0 commit comments