13 std::vector<double> w_in,
14 std::vector<double>& z)
16 const int n = (int)
y.size();
19 if (
n==1){ z[0]=
y[0];
return; }
21 double ymin =
y[0],
ymax =
y[0];
22 for (
int i=1;i<
n;++i){ ymin = std::min(ymin,
y[i]);
ymax = std::max(
ymax,
y[i]); }
23 const double range_y = std::max(1.0,
ymax - ymin);
24 const double abs_tol = 1e-12 * range_y;
25 const double rel_tol = 1e-12;
26 const double eps_w = 1e-15;
28 struct Block{
int L, R;
double sw, sy; };
29 std::vector<Block> S; S.reserve(
n);
31 for (
int i=0;i<
n;++i){
33 double wi = std::isfinite(w_in[i]) ? w_in[i] : 1.0;
34 if (!std::isfinite(yi)) {
35 yi = (i>0 ? z[i-1] : 0.0);
37 wi = std::max(wi, 0.0);
38 if (wi==0.0) wi = eps_w;
40 S.push_back({i,i,wi,wi*yi});
44 auto &B1 = S[S.size()-2];
45 double m1 = B1.sy / B1.sw;
46 double m2 = B2.sy / B2.sw;
48 double eps_pav = abs_tol + rel_tol*std::max(std::abs(m1), std::abs(m2));
49 if (m1 <= m2 + eps_pav)
break;
59 for (
const auto& B : S){
60 double m = B.sy / B.sw;
61 for (
int j=B.L; j<=B.R; ++j) z[j] = m;
67 const std::vector<double>& y_in,
68 std::vector<double>& z,
70 int maxit = 500,
double tol = 1e-9)
72 const int n = (int)
x.size();
73 std::vector<double> w(
n,1.0);
76 int i0 = -1;
for (
int i=0;i<
n;++i)
if (std::abs(
x[i])<1e-15) { i0=i;
break; }
79 const double eta = 1.0 / (1.0 + 4.0*mu);
80 std::vector<double> g(
n), zprev(
n);
82 auto add_Lap1D = [&](
const std::vector<double>& v, std::vector<double>& out){
83 out[0] += mu * ( v[0] - v[1] );
84 for (
int i=1;i<
n-1;++i) out[i] += mu * (2*v[i] - v[i-1] - v[i+1]);
85 out[
n-1] += mu * ( v[
n-1] - v[
n-2] );
88 for (
int it=0; it<maxit; ++it){
91 for (
int i=0;i<
n;++i) g[i] = (z[i]-y_in[i]);
94 for (
int i=0;i<
n;++i) z[i] -= eta * g[i];
96 if (i0>=0) z[i0] = 0.0;
101 for (
int i=0;i<
n;++i){
double d=z[i]-zprev[i]; diff+=d*d; }
102 if (diff < tol)
break;
108 const std::vector<double>& z,
109 std::vector<double>& m)
111 const int n = (int)
x.size();
113 if (
n==1){ m[0]=0.0;
return; }
114 std::vector<double> h(
n-1), d(
n-1);
115 for (
int i=0;i<
n-1;++i){
117 d[i] = (z[i+1]-z[i])/h[i];
121 for (
int i=1;i<
n-1;++i){
122 if ( (d[i-1]*d[i]) <= 0.0 ) { m[i]=0.0; }
124 double w1 = 2.0*h[i] + h[i-1];
125 double w2 = h[i] + 2.0*h[i-1];
126 m[i] = (w1 + w2) / ( (w1/d[i-1]) + (w2/d[i]) );
133 const std::vector<double>& z,
134 const std::vector<double>& m,
137 const int n = (int)
x.size();
138 if (xi <=
x.front())
return z.front();
139 if (xi >=
x.back())
return z.back();
140 int k = (int)(std::upper_bound(
x.begin(),
x.end(), xi) -
x.begin()) - 1;
141 double h =
x[k+1]-
x[k];
142 double t = (xi -
x[k]) / h;
143 double t2 = t*t, t3 = t2*t;
145 double h00 = ( 2*t3 - 3*t2 + 1);
146 double h10 = ( t3 - 2*t2 + t)*h;
147 double h01 = (-2*t3 + 3*t2 );
148 double h11 = ( t3 - t2 )*h;
150 return h00*z[k] + h10*m[k] + h01*z[k+1] + h11*m[k+1];
159 double* y_out,
double lambda) {
161 std::vector<double> x_raw(s_inp), y_raw(s_inp);
162 for (
int i=0;i<s_inp;++i){ x_raw[i]=x_inp[i]; y_raw[i]=y_inp[i]; }
164 const int n = (int)x_raw.size();
166 x_out[0]=0.0; y_out[0]=0.0;
return;
169 for (
int i=0;i<nout;++i){ x_out[i]=x_raw[0]; y_out[i]=y_raw[0]; }
173 std::vector<double> z;
176 std::vector<double> m;
179 double xmin = x_raw.front(), xmax = x_raw.back();
182 for (
int i=0;i<nout;++i){
183 double xi = xmin + (xmax - xmin) * (
double)i / (double)(nout-1);
void pchip_slopes(const std::vector< double > &x, const std::vector< double > &z, std::vector< double > &m)
double pchip_eval(const std::vector< double > &x, const std::vector< double > &z, const std::vector< double > &m, double xi)
void cpp_table_mat_spline_fit(int s_inp, double *x_inp, double *y_inp, int nout, double *x_out, double *y_out, double lambda)
void isotone_project_pav(std::vector< double > y, std::vector< double > w_in, std::vector< double > &z)
void smooth_isotone(const std::vector< double > &x, const std::vector< double > &y_in, std::vector< double > &z, double mu=1e-2, int maxit=500, double tol=1e-9)
subroutine ymax(idn, fac, npc, pld, stiffmin, stiffmax, stiffini, stiffavg)