Loading...
Searching...
No Matches
quasi_newton_update.h
Go to the documentation of this file.
1// SPDX-License-Identifier: AGPL-3.0-only
2// Copyright (C) 2026 Artificial Intelligence Techniques, S.L. and Roberto López González
3
4#pragma once
5
7
8namespace opennn::detail
9{
10
11// Internal CPU kernel. Matrices are symmetric n-by-n, vectors have length n,
12// and output/work storage must not overlap the inputs or each other.
13// Nocedal (1980), "Updating Quasi-Newton Matrices With Limited Storage",
14// equations (1) and (3): H+ = (I-rho*s*yT) H (I-rho*y*sT) + rho*s*sT.
15inline bool bfgs_inverse_update(const Eigen::Ref<const MatrixR>& previous,
16 const Eigen::Ref<const VectorR>& step,
17 const Eigen::Ref<const VectorR>& gradient_change,
18 Eigen::Ref<MatrixR> updated,
19 Eigen::Ref<VectorR> work)
20{
21 updated = previous;
22
23 const float curvature = step.dot(gradient_change);
24 if (!(curvature > EPSILON) || !std::isfinite(curvature)) return false;
25
26 work.noalias() = previous * gradient_change;
27 const float quadratic = gradient_change.dot(work);
28 if (!(quadratic > EPSILON) || !std::isfinite(quadratic)) return false;
29
30 const double rho = 1.0 / double(curvature);
31 const double coefficient = 0.5 * rho * (1.0 + rho * double(quadratic));
32 if (coefficient > double(std::numeric_limits<float>::max())) return false;
33
34 // H+ = H + s*qT + q*sT, q = rho*((1+rho*yT*H*y)*s/2 - H*y).
35 work = float(coefficient) * step - float(rho) * work;
36 if (!work.allFinite()) return false;
37
38 updated.selfadjointView<Eigen::Lower>().rankUpdate(step, work);
39 updated.triangularView<Eigen::Upper>() = updated.triangularView<Eigen::Lower>().transpose();
40
41 if (!updated.allFinite())
42 {
43 updated = previous;
44 return false;
45 }
46 return true;
47}
48
49}
Definition opennn_types.h:204
bool bfgs_inverse_update(const Eigen::Ref< const MatrixR > &previous, const Eigen::Ref< const VectorR > &step, const Eigen::Ref< const VectorR > &gradient_change, Eigen::Ref< MatrixR > updated, Eigen::Ref< VectorR > work)
Definition quasi_newton_update.h:15
constexpr float EPSILON
Definition opennn_types.h:308