Cantera  4.0.0a1
Loading...
Searching...
No Matches
polyfit.cpp
Go to the documentation of this file.
1//! @file polyfit.cpp
2
3// This file is part of Cantera. See License.txt in the top-level directory or
4// at https://cantera.org/license.txt for license and copyright information.
5
7#include "cantera/numerics/eigen_dense.h"
10
11namespace Cantera
12{
13
14double polyfit(size_t deg, span<const double> x, span<const double> y,
15 span<const double> w, span<double> p)
16{
17 size_t n = x.size();
18 checkArraySize("polyfit", y.size(), n);
19 checkArraySize("polyfit", p.size(), deg + 1);
20 if (!w.empty()) {
21 checkArraySize("polyfit", w.size(), n);
22 }
23
24 if (deg >= n) {
25 throw CanteraError("polyfit", "Polynomial degree ({}) must be less "
26 "than number of input data points ({})", deg, n);
27 }
28
29 ConstMappedVector xx(x.data(), n);
30 Eigen::VectorXd yy = ConstMappedVector(y.data(), n);
31 MappedVector pp(p.data(), deg + 1);
32
33 // Construct A such that each row i of A has the elements
34 // 1, x[i], x[i]^2, x[i]^3 ... + x[i]^deg
35 Eigen::MatrixXd A(n, deg+1);
36 A.col(0).setConstant(1.0);
37
38 if (deg > 0) {
39 A.col(1) = xx;
40 }
41 for (size_t i = 1; i < deg; i++) {
42 A.col(i+1) = A.col(i).array() * xx.array();
43 }
44
45 if (!w.empty() && w[0] > 0) {
46 // For compatibility with old Fortran dpolft, input weights are the
47 // squares of the weight vector used in this algorithm
48 Eigen::VectorXd ww = ConstMappedVector(w.data(), n).cwiseSqrt().eval();
49
50 // Multiply by the weights on both sides
51 A = ww.asDiagonal() * A;
52 yy.array() *= ww.array();
53 }
54
55 // Solve W*A*p = W*y to find the polynomial coefficients
56 pp = A.colPivHouseholderQr().solve(yy);
57
58 // Evaluate the computed polynomial at the input x coordinates to compute
59 // the RMS error as the return value
60 return (A * pp - yy).eval().norm() / sqrt(n);
61}
62
63}
Base class for exceptions thrown by Cantera classes.
Definitions for the classes that are thrown when Cantera experiences an error condition (also contain...
This file contains definitions for utility functions and text for modules, inputfiles and logging,...
double polyfit(size_t deg, span< const double > x, span< const double > y, span< const double > w, span< double > p)
Fits a polynomial function to a set of data points.
Definition polyfit.cpp:14
Namespace for the Cantera kernel.
Definition AnyMap.cpp:595
void checkArraySize(const char *procedure, size_t available, size_t required)
Wrapper for throwing ArraySizeError.