BELFEM 0.9.0
Berkeley Lab Finite Element Framework
Loading...
Searching...
No Matches
fn_BZ_polyfit.hpp
Go to the documentation of this file.
1/*
2 * BELFEM -- The Berkeley Lab Finite Element Framework
3 * Copyright (c) 2026, The Regents of the University of California,
4 * through Lawrence Berkeley National Laboratory (subject to receipt of any required
5 * approvals from the U.S. Dept. of Energy). All rights reserved.
6 *
7 * Developers: Christian Messe, Gregory Giard
8 *
9 * See the top-level LICENSE file for the complete license and disclaimer.
10 */
11
12#ifndef BELFEM_FN_BZ_POLYFIT_HPP
13#define BELFEM_FN_BZ_POLYFIT_HPP
14#include "typedefs.hpp"
15#include "cl_Vector.hpp"
16#include "cl_Matrix.hpp"
17#include "assert.hpp"
18#include "fn_gels.hpp"
19
20namespace belfem
21{
22//------------------------------------------------------------------------------
23
24 template< typename T >
25 void
26 polyfit( const Vector< T > & aX, const Vector< T > & aY, const uint & aN, Vector< T > & aCoeffs )
27 {
28 BELFEM_ASSERT( aX.length() == aY.length(),
29 "Legnths of X and Y vectors do not match ( %lu and %lu )",
30 ( long unsigned int ) aX.length(),
31 ( long unsigned int ) aY.length() );
32
33 BELFEM_ASSERT( aX.length() > aN, "not enough samples in vector to create a polynomial of degree %u",
34 ( unsigned int ) aN );
35
36 // number of entries
37 int tN = aN + 1;
38
39 // get the number of samples
40 index_t tNumSamples = aX.length();
41
42 // the vandermonde matrix is solved directly rather than through the
43 // normal equations, which would square the condition number
44 Matrix< T > tVandermonde( tNumSamples, tN );
45
46 // right hand side, also receives the coefficients
47 Vector< T > tRHS( tNumSamples );
48
49 // get a reference value to scale the polynomial
50 T tXref = ( tNumSamples - 1 ) / ( aX( tNumSamples - 1 ) - aX( 0 ) );
51
52 // loop over all samples
53 for( index_t k=0; k<tNumSamples; ++k )
54 {
55 // scaled value of X to improve condition of matrix
56 T tX = aX( k ) * tXref;
57
58 // create polynomial, the highest power sits in the first column
59 tVandermonde( k, aN ) = 1.0;
60
61 for( int i=aN-1; i>=0; --i )
62 {
63 tVandermonde( k, i ) = tVandermonde( k, i+1 ) * tX ;
64 }
65
66 tRHS( k ) = aY( k );
67 }
68
69 // solve the least squares problem, this destroys the vandermonde
70 // matrix and writes the coefficients into the first tN entries of tRHS
71 Vector< T > tWork;
72
73 gels( tVandermonde, tRHS, tWork );
74
75 // copy data into coefficient vector
76 aCoeffs.set_size( tN );
77
78 T tScale = 1.0;
79
80 for( int i=aN; i>=0; --i )
81 {
82 aCoeffs( i ) = tRHS( i ) * tScale;
83 tScale *= tXref;
84 }
85 }
86
87//------------------------------------------------------------------------------
88}
89#endif //BELFEM_FN_BZ_POLYFIT_HPP
#define BELFEM_ASSERT(aCheck,...)
Definition assert.hpp:244
Dense column-major matrix.
Definition cl_BZ_Matrix.hpp:28
Column vector.
Definition cl_BZ_Vector.hpp:41
Least-squares or minimum-norm solution of a full-rank system (LAPACK ?gels).
USER GUIDES:
Definition cl_Capacitor.cpp:16
int_t gels(Matrix< T > &A, Vector< T > &B, Vector< T > &Work, const bool AbortOnError=true)
solve the least squares problem min || A * x - b || via LAPACK ?gels ( QR or LQ factorization,...
Definition fn_gels.hpp:278
@ T
Definition cl_Material.hpp:122
unsigned int uint
Definition typedefs.hpp:30
void polyfit(const Vector< T > &aX, const Vector< T > &aY, const uint &aN, Vector< T > &aCoeffs)
Definition fn_AR_polyfit.hpp:25
uint32_t index_t
Definition typedefs.hpp:52
i
Definition main.py:48