1
/***************************************************************************
2
File : Interpolation.cpp
4
--------------------------------------------------------------------
5
Copyright : (C) 2007 by Ion Vasilief
6
Email (use @ for *) : ion_vasilief*yahoo.fr
7
Description : Numerical interpolation 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 "Interpolation.h"
31
#include <QMessageBox>
33
#include <gsl/gsl_sort.h>
34
#include <gsl/gsl_spline.h>
35
#include <gsl/gsl_interp.h>
37
Interpolation::Interpolation(ApplicationWindow *parent, Graph *g, const QString& curveTitle, int m)
41
setDataFromCurve(curveTitle);
44
Interpolation::Interpolation(ApplicationWindow *parent, Graph *g, const QString& curveTitle,
45
double start, double end, int m)
49
setDataFromCurve(curveTitle, start, end);
52
void Interpolation::init(int m)
56
QMessageBox::critical((ApplicationWindow *)parent(), tr("SciDAVis") + " - " + tr("Error"),
57
tr("Unknown interpolation method. Valid values are: 0 - Linear, 1 - Cubic, 2 - Akima."));
65
setName(tr("Linear") + tr("Int"));
66
d_explanation = tr("Linear") + " " + tr("Interpolation");
69
setName(tr("Cubic") + tr("Int"));
70
d_explanation = tr("Cubic") + " " + tr("Interpolation");
73
setName(tr("Akima") + tr("Int"));
74
d_explanation = tr("Akima") + " " + tr("Interpolation");
78
d_min_points = d_method + 3;
82
void Interpolation::setMethod(int m)
86
QMessageBox::critical((ApplicationWindow *)parent(), tr("Error"),
87
tr("Unknown interpolation method, valid values are: 0 - Linear, 1 - Cubic, 2 - Akima."));
91
int min_points = m + 3;
94
QMessageBox::critical((ApplicationWindow *)parent(), tr("SciDAVis") + " - " + tr("Error"),
95
tr("You need at least %1 points in order to perform this operation!").arg(min_points));
100
d_min_points = min_points;
103
void Interpolation::calculateOutputData(double *x, double *y)
105
gsl_interp_accel *acc = gsl_interp_accel_alloc ();
106
const gsl_interp_type *method;
110
method = gsl_interp_linear;
113
method = gsl_interp_cspline;
116
method = gsl_interp_akima;
120
gsl_spline *interp = gsl_spline_alloc (method, d_n);
121
gsl_spline_init (interp, d_x, d_y, d_n);
123
double step = (d_to - d_from)/(double)(d_points - 1);
124
for (int j = 0; j < d_points; j++)
126
x[j] = d_from + j*step;
127
y[j] = gsl_spline_eval (interp, x[j], acc);
130
gsl_spline_free (interp);
131
gsl_interp_accel_free (acc);
134
int Interpolation::sortedCurveData(QwtPlotCurve *c, double start, double end, double **x, double **y)
136
if (!c || c->rtti() != QwtPlotItem::Rtti_PlotCurve)
139
int i_start = 0, i_end = c->dataSize();
140
for (int i = 0; i < i_end; i++)
141
if (c->x(i) > start && i)
146
for (int i = i_end-1; i >= 0; i--)
147
if (c->x(i) < end && i < c->dataSize())
152
int n = i_end - i_start + 1;
153
(*x) = new double[n];
154
(*y) = new double[n];
155
double *xtemp = new double[n];
156
double *ytemp = new double[n];
160
for (int i = i_start; i <= i_end; i++)
163
if (xtemp[j] == pr_x)
167
return -1;//this kind of data causes division by zero in GSL interpolation routines
170
ytemp[j++] = c->y(i);
172
size_t *p = new size_t[n];
173
gsl_sort_index(p, xtemp, 1, n);
174
for (int i=0; i<n; i++)
176
(*x)[i] = xtemp[p[i]];
177
(*y)[i] = ytemp[p[i]];