numerical-collection-cpp 0.10.0
A collection of algorithms in numerical analysis implemented in C++
Loading...
Searching...
No Matches
differentiate.h
Go to the documentation of this file.
1/*
2 * Copyright 2021 MusicScience37 (Kenta Kabashima)
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
20#pragma once
21
22#include <cstddef>
23#include <memory>
24#include <utility> // IWYU pragma: keep
25#include <vector>
26
27#include <Eigen/Core>
28
36
38
47template <typename Scalar>
48[[nodiscard]] inline auto differentiate(
49 const variable<Scalar>& func_value, const variable<Scalar>& arg) -> Scalar {
51 diff.compute(func_value.node());
52 return diff.coeff(arg.node());
53}
54
55namespace impl {
56
64template <typename ArgType>
66public:
68 using variable_type = typename ArgType::Scalar;
69
71 using scalar_type = typename variable_type::scalar_type;
72
74 using result_type = Eigen::Matrix<scalar_type, ArgType::RowsAtCompileTime,
75 ArgType::ColsAtCompileTime, Eigen::ColMajor,
76 ArgType::MaxRowsAtCompileTime, ArgType::MaxColsAtCompileTime>;
77
85 std::shared_ptr<const graph::node_differentiator<scalar_type>> diff)
86 : arg_(arg), diff_(std::move(diff)) {}
87
95 auto operator()(index_type row, index_type col) const -> scalar_type {
96 return diff_->coeff(arg_(row, col).node());
97 }
98
99private:
101 const ArgType& arg_;
102
104 std::shared_ptr<const graph::node_differentiator<scalar_type>> diff_;
105};
106
107} // namespace impl
108
118template <typename Scalar, typename ArgDerived>
119[[nodiscard]] inline auto differentiate(const variable<Scalar>& func_value,
120 const Eigen::MatrixBase<ArgDerived>& arg)
121 -> Eigen::CwiseNullaryOp<
124 ArgDerived>::result_type> {
125 static_assert(
126 std::is_same_v<typename ArgDerived::Scalar, variable<Scalar>>);
127
128 auto diff = std::make_shared<graph::node_differentiator<Scalar>>();
129 diff->compute(func_value.node());
130
131 using result_type = typename impl::differentiate_scalar_with_matrix_functor<
132 ArgDerived>::result_type;
133 return result_type::NullaryExpr(arg.rows(), arg.cols(),
135 arg.derived(), std::move(diff)));
136}
137
138namespace impl {
139
148template <typename FuncValType, typename ArgType>
150public:
152 using variable_type = typename FuncValType::Scalar;
153
154 static_assert(std::is_same_v<typename ArgType::Scalar, variable_type>);
155
157 using scalar_type = typename variable_type::scalar_type;
158
161 Eigen::Matrix<scalar_type, FuncValType::RowsAtCompileTime,
162 ArgType::RowsAtCompileTime, Eigen::ColMajor,
163 FuncValType::MaxRowsAtCompileTime, ArgType::MaxRowsAtCompileTime>;
164
172 std::shared_ptr<std::vector<graph::node_differentiator<scalar_type>>>
173 diff)
174 : arg_(arg), diff_(std::move(diff)) {}
175
183 auto operator()(index_type row, index_type col) const -> scalar_type {
184 return diff_->at(util::safe_cast<std::size_t>(row))
185 .coeff(arg_(col, 0).node());
186 }
187
188private:
190 const ArgType& arg_;
191
193 std::shared_ptr<std::vector<graph::node_differentiator<scalar_type>>> diff_;
194};
195
196} // namespace impl
197
207template <typename FuncValType, typename ArgType>
208[[nodiscard]] inline auto differentiate(
209 const Eigen::MatrixBase<FuncValType>& func_value,
210 const Eigen::MatrixBase<ArgType>& arg)
211 -> Eigen::CwiseNullaryOp<
214 ArgType>::result_type> {
215 using variable_type = typename FuncValType::Scalar;
216 using scalar_type = typename variable_type::scalar_type;
217
218 NUM_COLLECT_PRECONDITION(func_value.cols() == 1 && arg.cols() == 1,
219 "differentiate function requires vectors as arguments.");
220
221 auto diff = std::make_shared<
222 std::vector<graph::node_differentiator<scalar_type>>>();
223 diff->resize(util::safe_cast<std::size_t>(func_value.size()));
224 for (index_type i = 0; i < func_value.size(); ++i) {
225 diff->operator[](util::safe_cast<std::size_t>(i))
226 .compute(func_value(i, 0).node());
227 }
228
229 using result_type =
231 ArgType>::result_type;
232 return result_type::NullaryExpr(func_value.size(), arg.size(),
234 arg.derived(), std::move(diff)));
235}
236
237} // namespace num_collect::auto_diff::backward
Definition of node class.
Class to compute differential coefficients for nodes in backward-mode automatic differentiation kubot...
void compute(const node_ptr< scalar_type > &top_node)
Compute differential coefficients.
auto coeff(const node_ptr< scalar_type > &node) const -> scalar_type
Get the differential coefficient of a node.
Class of functor to assign differential coefficients to matrices on the condition that a scalar-value...
typename variable_type::scalar_type scalar_type
Type of scalars.
Eigen::Matrix< scalar_type, ArgType::RowsAtCompileTime, ArgType::ColsAtCompileTime, Eigen::ColMajor, ArgType::MaxRowsAtCompileTime, ArgType::MaxColsAtCompileTime > result_type
Type of resulting differential coefficients.
differentiate_scalar_with_matrix_functor(const ArgType &arg, std::shared_ptr< const graph::node_differentiator< scalar_type > > diff)
Constructor.
auto operator()(index_type row, index_type col) const -> scalar_type
Get an element of differential coefficients.
std::shared_ptr< const graph::node_differentiator< scalar_type > > diff_
Differentiator.
Class of functor to assign differential coefficients to matrices on the condition that a vector-value...
Eigen::Matrix< scalar_type, FuncValType::RowsAtCompileTime, ArgType::RowsAtCompileTime, Eigen::ColMajor, FuncValType::MaxRowsAtCompileTime, ArgType::MaxRowsAtCompileTime > result_type
Type of resulting differential coefficients.
differentiate_vector_with_vector_functor(const ArgType &arg, std::shared_ptr< std::vector< graph::node_differentiator< scalar_type > > > diff)
Constructor.
std::shared_ptr< std::vector< graph::node_differentiator< scalar_type > > > diff_
Differentiators.
auto operator()(index_type row, index_type col) const -> scalar_type
Get an element of differential coefficients.
Class of variables in backward-mode automatic differentiation kubota1998.
Definition variable.h:48
Definition of exceptions.
Definition of index_type type.
Definition of macros for logging.
Namespace of backward-mode automatic differentiation.
auto differentiate(const variable< Scalar > &func_value, const variable< Scalar > &arg) -> Scalar
Compute a differential coefficient.
Namespace of internal implementations.
Definition exception.h:33
std::ptrdiff_t index_type
Type of indices in this library.
Definition index_type.h:33
auto safe_cast(const From &value) -> To
Cast safely.
Definition safe_cast.h:54
STL namespace.
Definition of node class.
Definition of NUM_COLLECT_PRECONDITION macro.
#define NUM_COLLECT_PRECONDITION(CONDITION,...)
Check whether a precondition is satisfied and throw an exception if not.
Definition of safe_cast function.