28 float newton_rhaphson(std::function<T(T)> &&f, std::function<T(T)> &&df, T epsilon_c, T x_0) {
30 auto iterate_newton = [](T f, T df, T xk) -> T {
37 while (epsilon > epsilon_c) {
38 T xkp1 = iterate_newton(f(xk), df(xk), xk);
40 epsilon = std::fabs(xk - xkp1);
69 template<
class T,
class Lambda>
72 const std::vector<T> &X,
73 const std::vector<T> &Y,
74 const std::vector<T> &p0,
81 const int params_nb = p0.size();
82 const int data_size = X.size();
84 std::vector<T> p = p0;
89 auto evaluate_sse = [&](
const std::vector<T> ¶ms) -> T {
91 for (
int k = 0; k < data_size; k++) {
92 T r = Y[k] - f(params, X[k]);
97 T sse = evaluate_sse(p);
98 T sse_trial = sse + 2 * tolerance;
99 while (it < maxits and sham::abs(sse_trial - sse) > tolerance) {
100 sse = evaluate_sse(p);
104 std::vector<T> f_at_p(data_size);
105 for (
int i = 0; i < data_size; i++) {
106 f_at_p[i] = f(p, X[i]);
110 T original_p_j = p[j];
111 const T MIN_STEP_SCALE_EPSILON = 1e-6;
112 T step_scale = (std::abs(original_p_j) < MIN_STEP_SCALE_EPSILON)
113 ? MIN_STEP_SCALE_EPSILON
115 const T FINITE_DIFF_STEP_FACTOR = 0.001;
116 T dpj = step_scale * FINITE_DIFF_STEP_FACTOR;
119 T f_perturbed = f(p, X[i]);
122 return (f_perturbed - f_at_p[i]) / dpj;
127 return Y[i] - f(p, X[i]);
143 std::vector<T> p_trial = p;
144 for (
int i = 0; i < params_nb; i++) {
145 p_trial[i] += delta.
data[i];
149 for (
int k = 0; k < data_size; k++) {
150 T residual = Y[k] - f(p_trial, X[k]);
151 sse_trial += residual * residual;
153 if (sse_trial > sse) {
162 T total_sum_squares = 0.0;
164 for (
int k = 0; k < data_size; k++) {
168 for (
int k = 0; k < data_size; k++) {
169 total_sum_squares += (Y[k] - mean_Y) * (Y[k] - mean_Y);
171 T R2 = 1 - sse / total_sum_squares;
174 "least_squares",
"Least squares stopped after", it,
"iterations with R^2=", R2);
#define SHAM_ASSERT(x)
Shorthand for SHAM_ASSERT_NAMED without a message.
Matrix class with runtime size based on std::vector storage and mdspan.
constexpr auto get_mdspan()
Get the matrix data as a mdspan.
Vector class with runtime size based on std::vector storage and mdspan.
constexpr auto get_mdspan()
Get the vector data as a mdspan.
std::vector< T > data
The vector data.
namespace for math utility
void vec_set_vals(const std::mdspan< T, Extents, Layout, Accessor > &input, Func &&func)
Set the elements of a vector according to a user-provided function.
void mat_transpose(const std::mdspan< T, Extents1, Layout1, Accessor1 > &input, const std::mdspan< T, Extents2, Layout2, Accessor2 > &output)
This function transposes a matrix.
std::pair< std::vector< T >, T > least_squares(const Lambda &f, const std::vector< T > &X, const std::vector< T > &Y, const std::vector< T > &p0, int maxits=1000, T tolerance=1e-9)
This function determines the best fit parameters for a given function with least squares.
void mat_set_vals(const std::mdspan< T, Extents, Layout, Accessor > &input, Func &&func)
Set the elements of a matrix according to a user-provided function.
void Cholesky_solve(const std::mdspan< T, Extents1, Layout1, Accessor1 > &M, const std::mdspan< T, Extents2, Layout2, Accessor2 > &y, const std::mdspan< T, Extents3, Layout3, Accessor3 > &x)
This function solves a system of linear equations with Cholesky decomposition. The system must have t...
void mat_plus_equal_scalar_id(const std::mdspan< T, Extents1, Layout1, Accessor1 > &inout, const U beta)
This function compute addition of a matrix with mutiple of identity matrix A +=beta * I,...
void mat_prod(const std::mdspan< Ta, Extents1, Layout1, Accessor1 > &input1, const std::mdspan< Ta, Extents2, Layout2, Accessor2 > &input2, const std::mdspan< Tb, Extents3, Layout3, Accessor3 > &output)
Compute the product of two matrices.
void mat_gemv(const U alpha, const std::mdspan< T, Extents1, Layout1, Accessor1 > &M, const std::mdspan< T, Extents2, Layout2, Accessor2 > &x, const U beta, const std::mdspan< T, Extents3, Layout3, Accessor3 > &y)
This function performs matrix-vector multiplication as y = a*Mx + b*y.