1
/***************************************************************************
4
--------------------------------------------------------------------
5
Copyright : (C) 2007 by Ion Vasilief
6
Email (use @ for *) : ion_vasilief*yahoo.fr
7
Description : Numerical integration of data sets
9
***************************************************************************/
11
/***************************************************************************
13
* This program is free software; you can redistribute it and/or modify *
14
* it under the terms of the GNU General Public License as published by *
15
* the Free Software Foundation; either version 2 of the License, or *
16
* (at your option) any later version. *
18
* This program is distributed in the hope that it will be useful, *
19
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
20
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
21
* GNU General Public License for more details. *
23
* You should have received a copy of the GNU General Public License *
24
* along with this program; if not, write to the Free Software *
25
* Foundation, Inc., 51 Franklin Street, Fifth Floor, *
26
* Boston, MA 02110-1301 USA *
28
***************************************************************************/
29
#include "Integration.h"
31
#include "MultiLayer.h"
34
#include <QMessageBox>
38
#include <gsl/gsl_spline.h>
39
#include <gsl/gsl_interp.h>
40
#include <gsl/gsl_vector.h>
42
Integration::Integration(ApplicationWindow *parent, Graph *g)
48
Integration::Integration(ApplicationWindow *parent, Graph *g, const QString& curveTitle)
52
setDataFromCurve(curveTitle);
55
Integration::Integration(ApplicationWindow *parent, Graph *g, const QString& curveTitle, double start, double end)
59
setDataFromCurve(curveTitle, start, end);
62
void Integration::init()
64
setName(tr("Integration"));
66
d_max_iterations = 40;
70
QString Integration::logInfo()
72
// Do the interpolation, use GSL libraries for that
73
gsl_interp_accel *acc = gsl_interp_accel_alloc();
74
const gsl_interp_type *method;
75
// The method for interpolation is chosen based on the number of points
77
method=gsl_interp_linear;
79
method=gsl_interp_cspline;
81
method=gsl_interp_akima;
83
// If we have enough points use GSL libraries for interpolation, else use the polint algorithm
87
interp = gsl_spline_alloc (method, d_n);
88
gsl_spline_init (interp, d_x, d_y, d_n);
91
// Using Numerical Recipes
92
// This is Romberg Integration method
93
// This method uses the Nevilles' algorithm for interpollation;
95
double xx,tnm,sum,del,ss,dss,error,tsum;
98
yup = gsl_spline_eval (interp, d_to, acc);
99
ylow = gsl_spline_eval (interp, d_from, acc);
103
polint(d_x,d_y,d_n,d_to,&yup,&dss);
104
polint(d_x,d_y,d_n,d_from,&ylow,&dss);
107
double *S = new double[d_max_iterations];
108
double *h = new double[d_max_iterations];
110
bool success = false;
112
for(j=0; j < d_max_iterations; j++)
115
S[0]=0.5*(d_to-d_from)*(ylow+yup);
120
for(it=1,l=1;l<j-1;l++)it<<=1;
122
del=(d_to-d_from)/tnm;
124
for(sum=0.0,l=1;l<=it;l++)
127
sum+=gsl_spline_eval (interp,xx, acc);
130
polint(d_x,d_y,d_n,xx,&tsum,&dss);
135
S[j]=0.5*(S[j-1]+(d_to-d_from)*sum/tnm);
140
polint(&h[j-d_method],&S[j-d_method],d_method,0,&ss,&dss);
143
error=fabs(S[j]-S[j-1]);
144
if(error<=d_tolerance) success = true;
148
QString logInfo = "[" + QDateTime::currentDateTime().toString(Qt::LocalDate) + "\t" + tr("Plot")+ ": ''" + d_graph->parentPlotName() + "'']\n";
149
logInfo += "\n" + tr("Numerical integration of") + ": " + d_curve->title().text() + " " + tr("using a %1 order method").arg(d_method)+"\n";
151
logInfo += tr("Iterations") + ": " + QString::number(j)+"\n";
153
logInfo += tr("Iterations") + ": " + QString::number(j-1)+"\n";
155
ApplicationWindow *app = (ApplicationWindow *)parent();
156
int prec = app->d_decimal_digits;
157
logInfo += tr("Tolerance") + "(" + tr("max") + " = " + QLocale().toString(d_tolerance, 'g', prec)+"): " + QString::number(error)+ "\n";
158
logInfo += tr("Points") + ": "+QString::number(d_n) + " " + tr("from") + " x = " +QLocale().toString(d_from, 'g', prec) + " ";
159
logInfo += tr("to") + " x = " + QLocale().toString(d_to, 'g', prec) + "\n";
161
// using GSL to find maximum value of data set
162
gsl_vector *aux = gsl_vector_alloc(d_n);
163
for(int i=0; i < d_n; i++)
164
gsl_vector_set (aux, i, fabs(d_y[i]));
165
int maxID=gsl_vector_max_index (aux);
166
gsl_vector_free (aux);
168
logInfo += tr("Peak at") + " x = " + QLocale().toString(d_x[maxID], 'g', prec)+"\t";
169
logInfo += "y = " + QLocale().toString(d_y[maxID], 'g', prec)+"\n";
171
logInfo += tr("Area") + "=";
173
logInfo += QLocale().toString(S[j], 'g', prec);
175
logInfo += QLocale().toString(S[j-1], 'g', prec);
176
logInfo += "\n-------------------------------------------------------------\n";
179
gsl_spline_free (interp);
181
gsl_interp_accel_free (acc);
187
void Integration::setMethodOrder(int n)
191
QMessageBox::critical((ApplicationWindow *)parent(), tr("Error"),
192
tr("Unknown integration method. Valid values must be in the range: 1 (Trapezoidal Method) to 5."));