STK++ 0.9.13
STK_Algo.h
Go to the documentation of this file.
1/*--------------------------------------------------------------------*/
2/* Copyright (C) 2004-2016 Serge Iovleff, Université Lille 1, Inria
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License as
6 published by the Free Software Foundation; either version 2 of the
7 License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public
15 License along with this program; if not, write to the
16 Free Software Foundation, Inc.,
17 59 Temple Place,
18 Suite 330,
19 Boston, MA 02111-1307
20 USA
21
22 Contact : S..._Dot_I..._At_stkpp_Dot_org (see copyright for ...)
23*/
24
25/*
26 * Project: stkpp::STatistiK
27 * Purpose: Method implementing Algorithms.
28 * Author: Serge Iovleff, S..._Dot_I..._At_stkpp_Dot_org (see copyright for ...)
29 **/
30
35#ifndef STK_ALGO_H
36#define STK_ALGO_H
37
38#include "STK_Const_Math.h"
39#include "STK_ISerie.h"
40#include "STK_IFunction.h"
41
42namespace STK
43{
44
64template <class Serie>
65Real sumAlternateSerie(const ISerie<Serie>& f, int const& n = 0)
66{
67 // Compute the rate of convergence
68 Real rate = 3.0 + 2.0 * Const::_SQRT2_;
69 // compute the number of iterations if needed
70 int niter = n;
71 if (niter==0)
72 {
73 niter = (int )( std::log(Arithmetic<Real>::epsilon())
74 / (Const::_LN2_-std::log(rate))
75 ) + 1;
76 }
77 // initialization
78 rate = pow(rate, niter);
79 Real b = -2.0/(rate+1.0/rate), c = -1.0, sum = 0.0;
80 // first iteration (k = 0)
81 sum += (c = b-c) * f.first();
82 b *= (- 2.*niter*niter);
83 // iterations
84 for (int k = 1; k<niter; k++)
85 {
86 sum += (c = b-c) * f.next();
87 Real aux = k+1.;
88 b *= ((k + niter)/(k + aux)) * ((k - niter)/aux) * 2.;
89 }
90 return sum;
91}
92
109template <class Serie>
110Real sumSerie(const ISerie<Serie>& f, int const& iter_max = 10)
111{
112 Real e0[7]; // original serie
113 Real e1[6];
114 Real e2[5];
115 Real e3[4];
116 Real e4[3];
117 Real e5[2];
118 Real delta, sum; // e6
119
120 e0[0] = f.first(); //f[0];
121 e0[1] = e0[0] + f.next();
122 e0[2] = e0[1] + f.next();
123 e0[3] = e0[2] + f.next();
124 e0[4] = e0[3] + f.next();
125 e0[5] = e0[4] + f.next();
126 e0[6] = e0[5] + f.next();
127
128 // first epsilon e_{-1}[n] = 0
129 e1[0] = 1/(e0[1] - e0[0]);
130 e1[1] = 1/(e0[2] - e0[1]);
131 e1[2] = 1/(e0[3] - e0[2]);
132 e1[3] = 1/(e0[4] - e0[3]);
133 e1[4] = 1/(e0[5] - e0[4]);
134 e1[5] = 1/(e0[6] - e0[5]);
135
136 // second epsilon
137 e2[0] = e0[0] + 1/(e1[1] - e1[0]);
138 e2[1] = e0[1] + 1/(e1[2] - e1[1]);
139 e2[2] = e0[2] + 1/(e1[3] - e1[2]);
140 e2[3] = e0[3] + 1/(e1[4] - e1[3]);
141 e2[4] = e0[4] + 1/(e1[5] - e1[4]);
142
143 // third epsilon
144 e3[0] = e1[0] + 1/(e2[1] - e2[0]);
145 e3[1] = e1[1] + 1/(e2[2] - e2[1]);
146 e3[2] = e1[2] + 1/(e2[3] - e2[2]);
147 e3[3] = e1[3] + 1/(e2[4] - e2[3]);
148
149 // fourth epsilon
150 e4[0] = e2[0] + 1/(e3[1] - e3[0]);
151 e4[1] = e2[1] + 1/(e3[2] - e3[1]);
152 e4[2] = e2[2] + 1/(e3[3] - e3[2]);
153
154 // fifth epsilon
155 e5[0] = e3[0] + 1/(e4[1] - e4[0]);
156 e5[1] = e3[1] + 1/(e4[2] - e4[1]);
157
158 // sum e6[0]
159 sum = e4[0] + (delta = 1/(e5[1] - e5[0]));
160
161 // main loop
162 for (int n=1; n<=iter_max; n++)
163 { // roll s0
164 e0[4] = e0[5];
165 e0[5] = e0[6];
166 e0[6] += f.next();
167
168 // roll first epsilon
169 e1[3] = e1[4];
170 e1[4] = e1[5];
171 if ( (delta = (e0[6] - e0[5])) == 0) break;
172 e1[5] = 1./delta;
173
174 // roll second epsilon
175 e2[2] = e2[3];
176 e2[3] = e2[4];
177 if ( (delta = (e1[5] - e1[4])) == 0) break;
178 e2[4] = e0[4] + 1./delta;
179
180 // roll third epsilon
181 e3[1] = e3[2];
182 e3[2] = e3[3];
183 if ( (delta = (e2[4] - e2[3])) == 0) break;
184 e3[3] = e1[3] + 1./delta;
185
186 // roll fourth epsilon
187 e4[0] = e4[1];
188 e4[1] = e4[2];
189 if ( (delta = (e3[3] - e3[2])) == 0) break;
190 e4[2] = e2[2] + 1./delta;
191
192 // roll fifth epsilon
193 e5[0] = e5[1];
194 if ( (delta = (e4[2] - e4[1])) == 0) break;
195 e5[1] = e3[1] + 1./delta;
196
197 // roll sixth epsilon and compute sum
198 if ( (delta = (e5[1] - e5[0])) == 0) break;
199 if (!Arithmetic<Real>::isFinite(delta = 1./delta)) break;
200 // sum
201 Real sum1 = e4[0] + delta;
202 if (sum1 == sum) break;
203 sum = sum1;
204 }
205
206 return sum;
207}
222template <class Seriea, class Serieb>
224 , const ISerie<Serieb>& b
225 , int const& iter_max = 100
226 )
227{
228 // initialize a_n
229 Real an = a.first(); // a_1
230 // note a_1 =0 => cf = 0
231 if (an == 0.) return 0.;
232 // initialize b_n
233 Real bn = b.first(); // b_1
234 // initialize numerator
235 Real Nold = 0, Ncur = an; // = a_1
236 // initialize denominator
237 Real Dold = 1, Dcur = bn; // = b_1
238 // result
239 Real cf = 0.;
240 // iterations
241 for (int n=1; n<=iter_max; n++)
242 {
243 // compute a_n
244 an = a.next();
245 // check trivial case
246 // (a_n =0) and (D_n = 0) => cf = +\infty
247 if (an == 0.) return Ncur/Dcur;
248 // update b_n
249 bn = b.next();
250 // compute numerator and denominator
251 Real Nnew = bn * Ncur + an * Nold;
252 Real Dnew = bn * Dcur + an * Dold;
253 // update old numerator and denominator
254 Nold = Ncur;
255 Dold = Dcur;
256 // update current numerator and denominator
257 Ncur = Nnew;
258 Dcur = Dnew;
259 // normalize if necessary with 2^32
260 if (std::abs(Dcur) > 4294967296.0)
261 {
262 Ncur /= Dcur;
263 Nold /= Dcur;
264 Dold /= Dcur;
265 Dcur = 1.;
266 }
267 // normalize if necessary with 2^32
268 if (std::abs(Ncur) > 4294967296.0)
269 {
270 Ncur /= 4294967296.0;
271 Nold /= 4294967296.0;
272 Dold /= 4294967296.0;
273 Dcur /= 4294967296.0;
274 }
275 // if D_n not to small check cv
276 if (std::abs(Dcur) != 0)
277 {
279 // check cv
280 if (std::abs(cf - cfnew) < std::abs(cfnew)*Arithmetic<Real>::epsilon())
281 return cfnew;
282 else
283 cf = cfnew;
284 }
285 }
286 // avoid warning at compilation
287 return cf;
288}
289
290} // namespace STK
291
292#endif /*STK_ALGO_H*/
In this file we give the main mathematical constants.
In this file we define Interface base class for Real functions.
In this file we define Interface base class for Real Series.
The MultidimRegression class allows to regress a multidimensional output variable among a multivariat...
Real sumAlternateSerie(const ISerie< Serie > &f, int const &n=0)
Sum an alternating series using the Chebichev polynomials.
Definition STK_Algo.h:65
Real sumSerie(const ISerie< Serie > &f, int const &iter_max=10)
Sum a serie using the epsilon acceleration process.
Definition STK_Algo.h:110
Real continuedFraction(const ISerie< Seriea > &a, const ISerie< Serieb > &b, int const &iter_max=100)
Evaluate a continued fraction.
Definition STK_Algo.h:223
Arrays::SumOp< Lhs, Rhs >::result_type sum(Lhs const &lhs, Rhs const &rhs)
convenience function for summing two arrays
double Real
STK fundamental type of Real values.
The namespace STK is the main domain space of the Statistical ToolKit project.
Arithmetic properties of STK fundamental types.