Commit 1a4f8fc5 authored by Stefan Gerlach's avatar Stefan Gerlach

Merge branch 'master' into frameworks

parents 4bae7f78 6310a217
......@@ -62,7 +62,20 @@ int nsl_diff_deriv_first_equal(const double *x, double *y, const size_t n) {
return 0;
}
int nsl_diff_deriv_first(const double *x, double *y, const size_t n) {
int nsl_diff_first_deriv(const double *x, double *y, const size_t n, int order) {
switch (order) {
case 2:
return nsl_diff_first_deriv_second_order(x, y, n);
/*TODO: higher order */
default:
printf("nsl_diff_first_deriv() unknown order %d\n", order);
return -1;
}
return 0;
}
int nsl_diff_first_deriv_second_order(const double *x, double *y, const size_t n) {
if (n < 3)
return -1;
......@@ -92,7 +105,7 @@ int nsl_diff_deriv_first(const double *x, double *y, const size_t n) {
return 0;
}
int nsl_diff_deriv_first_avg(const double *x, double *y, const size_t n) {
int nsl_diff_first_deriv_avg(const double *x, double *y, const size_t n) {
if (n < 1)
return -1;
......@@ -116,38 +129,100 @@ int nsl_diff_deriv_first_avg(const double *x, double *y, const size_t n) {
return 0;
}
int nsl_diff_deriv_second(const double *x, double *y, const size_t n) {
int nsl_diff_second_deriv(const double *x, double *y, const size_t n, int order) {
switch (order) {
case 1:
return nsl_diff_second_deriv_first_order(x, y, n);
case 2:
return nsl_diff_second_deriv_second_order(x, y, n);
/*TODO: higher order */
default:
printf("nsl_diff_second_deriv() unknown order %d\n", order);
return -1;
}
return 0;
}
int nsl_diff_second_deriv_first_order(const double *x, double *y, const size_t n) {
if (n < 3)
return -1;
double h1, h2, h12, dy=0., oldy=0., oldy2=0.;
size_t i;
for (i=0; i<n; i++) {
if (i == 0) {
h1 = x[1]-x[0];
h2 = x[2]-x[1];
h12 = h1 + h2;
/*first order */
dy = 2.*(h1*y[2] - h12*y[1] + h2*y[0])/(h1*h2*h12);
}
else if (i == n-1) {
h1 = x[i-1]-x[i-2];
h2 = x[i]-x[i-1];
h12 = h1 + h2;
/*first order */
y[i] = 2.*(h1*y[i] - h12*y[i-1] + h2*y[i-2])/(h1*h2*h12);
y[i-1] = oldy;
}
else {
h1 = x[i]-x[i-1];
h2 = x[i+1]-x[i];
h12 = h1 + h2;
/*second order */
dy = 2.*(h1*y[i+1] - h12*y[i] + h2*y[i-1])/(h1*h2*h12);
}
if (i > 1)
y[i-2] = oldy2;
if (i > 0 && i < n-1)
oldy2 = oldy;
oldy = dy;
}
return 0;
}
int nsl_diff_second_deriv_second_order(const double *x, double *y, const size_t n) {
if (n < 3)
return -1;
/* TODO: same order for all points */
double h1, h2, dy=0., oldy=0., oldoldy=0.;
double h1, h2, h12, dy=0., oldy=0., oldy2=0., oldy3=0.;
size_t i;
for (i=0; i<n; i++) {
if (i == 0) {
h1 = x[1]-x[0];
h2 = x[2]-x[1];
dy = 2.*(h1*y[2] - (h1+h2)*y[1] + h2*y[0])/(h1*h2*(h1+h2));
h12 = h1 + h2;
/*first order */
dy = 2.*(h1*y[2] - h12*y[1] + h2*y[0])/(h1*h2*h12);
}
else if (i == n-1) {
h1 = x[i-1]-x[i-2];
h2 = x[i]-x[i-1];
y[i] = 2.*(h1*y[i] - (h1+h2)*y[i-1] + h2*y[i-2])/(h1*h2*(h1+h2));
h12 = h1 + h2;
/*first order */
y[i] = 2.*(h1*y[i] - h12*y[i-1] + h2*y[i-2])/(h1*h2*h12);
y[i-1] = oldy;
}
else {
h1 = x[i]-x[i-1];
h2 = x[i+1]-x[i];
dy = 2.*(h1*y[i+1] - (h1+h2)*y[i] + h2*y[i-1])/(h1*h2*(h1+h2));
h12 = h1 + h2;
/*second order */
dy = 2.*(h1*y[i+1] - h12*y[i] + h2*y[i-1])/(h1*h2*h12);
}
if (i > 1)
y[i-2] = oldoldy;
y[i-2] = oldy2;
if (i > 0 && i < n-1)
oldoldy = oldy;
oldy2 = oldy;
oldy = dy;
}
return 0;
}
......@@ -42,10 +42,11 @@ double nsl_diff_first_central(double xm, double fm, double xp, double fp);
for equal/unequal spaced data.
result in y
*/
int nsl_diff_deriv_first_equal(const double *x, double *y, const size_t n);
int nsl_diff_deriv_first(const double *x, double *y, const size_t n);
int nsl_diff_first_deriv_equal(const double *x, double *y, const size_t n);
int nsl_diff_first_deriv(const double *x, double *y, const size_t n, int order);
int nsl_diff_first_deriv_second_order(const double *x, double *y, const size_t n);
/* using average between left and right diff (like in other programs) */
int nsl_diff_deriv_first_avg(const double *x, double *y, const size_t n);
int nsl_diff_first_deriv_avg(const double *x, double *y, const size_t n);
/************ second derivatives *********/
......@@ -53,6 +54,8 @@ int nsl_diff_deriv_first_avg(const double *x, double *y, const size_t n);
for unequal spaced data.
result in y
*/
int nsl_diff_deriv_second(const double *x, double *y, const size_t n);
int nsl_diff_second_deriv(const double *x, double *y, const size_t n, int order);
int nsl_diff_second_deriv_first_order(const double *x, double *y, const size_t n);
int nsl_diff_second_deriv_second_order(const double *x, double *y, const size_t n);
#endif /* NSL_DIFF_H */
......@@ -42,7 +42,7 @@ int main() {
printf("expecting 2*x as derivative:\n");
/*int status = nsl_diff_deriv_first_equal(xdata, ydata, n);*/
int status = nsl_diff_deriv_first(xdata, ydata, n);
int status = nsl_diff_first_deriv(xdata, ydata, n, 2);
for (i=0; i < n; i++)
printf("%g %g\n", xdata[i], ydata[i]);
......@@ -50,7 +50,7 @@ int main() {
printf("avg derivative:\n");
double ydata2[]={1,4,16,64,256,1024,4096};
status = nsl_diff_deriv_first_avg(xdata, ydata2, n);
status = nsl_diff_first_deriv_avg(xdata, ydata2, n);
for (i=0; i < n; i++)
printf("%g %g\n", xdata[i], ydata2[i]);
......@@ -58,7 +58,7 @@ int main() {
printf("expecting 2 as second derivative:\n");
double ydata3[]={1,4,16,64,256,1024,4096};
status = nsl_diff_deriv_second(xdata, ydata3, n);
status = nsl_diff_second_deriv(xdata, ydata3, n, 2);
for (i=0; i < n; i++)
printf("%g %g\n", xdata[i], ydata3[i]);
......
......@@ -102,3 +102,66 @@ double complex nsl_sf_poly_reversed_bessel_theta(int n, double complex x) {
return (2*n - 1)*nsl_sf_poly_reversed_bessel_theta(n - 1, x) + x*x*nsl_sf_poly_reversed_bessel_theta(n - 2, x);
}
/***************** interpolating polynomials *************/
double nsl_sf_poly_interp_lagrange_1(double v, double *x, double *y) {
return (y[0]*(x[1]-v) + y[1]*(v-x[0]))/(x[1]-x[0]);
}
double nsl_sf_poly_interp_lagrange_1_deriv(double *x, double *y) {
return (y[0]-y[1])/(x[1]-x[0]);
}
double nsl_sf_poly_interp_lagrange_2(double v, double *x, double *y) {
double h1 = x[1]-x[0], h2 = x[2]-x[1];
double h12 = h1+h2;
return y[0]*(v-x[1])*(v-x[2])/(h1*h12) + y[1]*(x[0]-v)*(v-x[2])/(h1*h2) + y[2]*(x[0]-v)*(x[1]-v)/(h12*h2);
}
double nsl_sf_poly_interp_lagrange_2_deriv(double v, double *x, double *y) {
double h1 = x[1]-x[0], h2 = x[2]-x[1];
double h12 = h1+h2;
return y[0]*(2.*v-x[1]-x[2])/(h1*h12) + y[1]*(x[0]-2.*v+x[2])/(h1*h2) + y[2]*(2.*v-x[0]-x[1])/(h12*h2);
}
double nsl_sf_poly_interp_lagrange_2_deriv2(double *x, double *y) {
double h1 = x[1]-x[0], h2 = x[2]-x[1];
double h12 = h1+h2;
return 2.*( y[0]/(h1*h12) - y[1]/(h1*h2) + y[2]/(h12*h2) );
}
double nsl_sf_poly_interp_lagrange_3(double v, double *x, double *y) {
double h1 = x[1]-x[0], h2 = x[2]-x[1], h3 = x[3]-x[2];
double h12 = h1+h2, h23 = h2+h3, h13=h12+h3;
return y[0]*(v-x[1])*(v-x[2])*(v-x[3])/(h1*h12*h13) + y[1]*(v-x[0])*(v-x[2])*(v-x[3])/(h1*h2*h23)
- y[2]*(v-x[0])*(v-x[1])*(v-x[3])/(h12*h2*h3) + y[3]*(v-x[0])*(v-x[1])*(v-x[2])/(h13*h23*h3);
}
double nsl_sf_poly_interp_lagrange_3_deriv(double v, double *x, double *y) {
double h1 = x[1]-x[0], h2 = x[2]-x[1], h3 = x[3]-x[2], S=x[1]+x[2]+x[3]+x[4];
double h12 = h1+h2, h23 = h2+h3, h13=h12+h3;
return -y[0]*(3*v*v-2.*v*(S-x[0])+x[1]*x[2]+(S-x[0]-x[3])*x[3])/(h1*h12*h13)
+ y[1]*(3*v*v-2.*v*(S-x[1])+(x[0]+x[2])*x[3])/(h1*h2*h23)
+ y[2]*(3*v*v+x[0]*x[1]-2.*v*(S-x[2])+(x[0]+x[1])*x[3])/(h12*h2*h3)
+ y[3]*(3*v*v+x[0]*x[1]+(x[0]+x[1])*x[2]-2.*v*(S-x[3]))/(h13*h23*h3);
}
double nsl_sf_poly_interp_lagrange_3_deriv2(double v, double *x, double *y) {
double h1 = x[1]-x[0], h2 = x[2]-x[1], h3 = x[3]-x[2], S=x[1]+x[2]+x[3]+x[4];
double h12 = h1+h2, h23 = h2+h3, h13=h12+h3;
return 2.*( y[0]*(S-3.*v-x[0])/(h1*h12*h13) + y[1]*(3.*v-S+x[1])/(h1*h2*h23)
+ y[2]*(S-3.*v-x[2])/(h12*h2*h3) +y[3]*(3.*v-S+x[3])/(h13*h23*h3) );
}
double nsl_sf_poly_interp_lagrange_3_deriv3(double *x, double *y) {
double h1 = x[1]-x[0], h2 = x[2]-x[1], h3 = x[3]-x[2];
double h12 = h1+h2, h23 = h2+h3, h13=h12+h3;
return 6.*( -y[0]/(h1*h12*h13) + y[1]/(h1*h2*h23) - y[2]/(h12*h2*h3) +y[3]/(h13*h23*h3) );
}
......@@ -50,4 +50,20 @@ double complex nsl_sf_poly_bessel_y(int n, double complex x);
/* reversed Bessel polynomials \theta_n(x) */
double complex nsl_sf_poly_reversed_bessel_theta(int n, double complex x);
/* interpolating polynomial (Lagrange)
1 - first order (2-point) and derivative
2 - second order (3-point) and derivatives
3 - third order (4-point) and derivatives
TODO: barycentric form (https://en.wikipedia.org/wiki/Lagrange_polynomial)
*/
double nsl_sf_poly_interp_lagrange_1(double v, double *x, double *y);
double nsl_sf_poly_interp_lagrange_1_deriv(double *x, double *y);
double nsl_sf_poly_interp_lagrange_2(double v, double *x, double *y);
double nsl_sf_poly_interp_lagrange_2_deriv(double v, double *x, double *y);
double nsl_sf_poly_interp_lagrange_2_deriv2(double *x, double *y);
double nsl_sf_poly_interp_lagrange_3(double v, double *x, double *y);
double nsl_sf_poly_interp_lagrange_3_deriv(double v, double *x, double *y);
double nsl_sf_poly_interp_lagrange_3_deriv2(double v, double *x, double *y);
double nsl_sf_poly_interp_lagrange_3_deriv3(double *x, double *y);
#endif /* NSL_SF_POLY_H */
......@@ -254,10 +254,6 @@ void SpreadsheetModel::handleAspectAdded(const AbstractAspect * aspect) {
updateVerticalHeader();
updateHorizontalHeader();
emit headerDataChanged(Qt::Horizontal, 0, m_spreadsheet->columnCount()-1);
//emit headerDataChanged(Qt::Vertical, old_rows, m_spreadsheet->rowCount()-1);
emit headerDataChanged(Qt::Vertical, 0, m_spreadsheet->rowCount()-1);
connect(col, SIGNAL(plotDesignationChanged(const AbstractColumn*)), this,
SLOT(handlePlotDesignationChange(const AbstractColumn*)));
connect(col, SIGNAL(modeChanged(const AbstractColumn*)), this,
......@@ -299,14 +295,9 @@ void SpreadsheetModel::handleAspectRemoved(const AbstractAspect* parent, const A
if (!col || parent != static_cast<AbstractAspect*>(m_spreadsheet))
return;
int old_rows = m_vertical_header_data.size();
updateVerticalHeader();
updateHorizontalHeader();
emit headerDataChanged(Qt::Horizontal, 0, m_spreadsheet->columnCount()-1);
emit headerDataChanged(Qt::Vertical, old_rows, m_spreadsheet->rowCount()-1);
beginResetModel();
endRemoveColumns();
endResetModel();
......
......@@ -1326,7 +1326,6 @@ void CartesianPlotPrivate::retransform() {
void CartesianPlotPrivate::retransformScales() {
CartesianPlot* plot = dynamic_cast<CartesianPlot*>(q);
QList<CartesianScale*> scales;
double sceneStart, sceneEnd, logicalStart, logicalEnd;
//perform the mapping from the scene coordinates to the plot's coordinates here.
QRectF itemRect = mapRectFromScene(rect);
......@@ -1335,40 +1334,56 @@ void CartesianPlotPrivate::retransformScales() {
if (xScale != CartesianPlot::ScaleLinear)
checkXRange();
//check where we have x-range breaks
bool hasValidBreak = false;
if (xRangeBreakingEnabled && !xRangeBreaks.list.isEmpty()) {
foreach(const CartesianPlot::RangeBreak& b, xRangeBreaks.list)
hasValidBreak = (!std::isnan(b.start) && !std::isnan(b.end));
}
//check whether we have x-range breaks - the first break, if available, should be valid
bool hasValidBreak = (xRangeBreakingEnabled && !xRangeBreaks.list.isEmpty() && xRangeBreaks.list.first().isValid());
static const int breakGap = 20;
double sceneStart, sceneEnd, logicalStart, logicalEnd;
//create x-scales
int plotSceneStart = itemRect.x()+horizontalPadding;
int plotSceneEnd = itemRect.x()+itemRect.width()-horizontalPadding;
if (!hasValidBreak) {
sceneStart = itemRect.x()+horizontalPadding;
sceneEnd = itemRect.x()+itemRect.width()-horizontalPadding;
//no breaks available -> range goes from the plot beginning to the end of the plot
sceneStart = plotSceneStart;
sceneEnd = plotSceneEnd;
logicalStart = xMin;
logicalEnd = xMax;
//TODO: how should we handle the case sceneStart=sceneEnd
//(to reproduce, create plots and adjust the spacing/pading to get zero size for the plots)
if (sceneStart!=sceneEnd) {
if (sceneStart!=sceneEnd)
scales << this->createScale(xScale, sceneStart, sceneEnd, logicalStart, logicalEnd);
}
} else {
foreach(const CartesianPlot::RangeBreak& b, xRangeBreaks.list) {
sceneStart = itemRect.x()+horizontalPadding;
sceneEnd = itemRect.x()+itemRect.width()-horizontalPadding;
sceneEnd = sceneStart+(sceneEnd-sceneStart)*b.position;
logicalStart = xMin;
logicalEnd = b.start;
scales << this->createScale(xScale, sceneStart, sceneEnd, logicalStart, logicalEnd);
int sceneEndLast = plotSceneStart;
int logicalEndLast = xMin;
for (int i=0; i<xRangeBreaks.list.size(); ++i) {
const CartesianPlot::RangeBreak& curBreak = xRangeBreaks.list.at(i);
if (!curBreak.isValid())
break;
//current range goes from the end of the previous one (or from the plot beginning) to curBreak.start
sceneStart = sceneEndLast;
if (i!=0) sceneStart+=breakGap;
sceneEnd = plotSceneStart+(plotSceneEnd-plotSceneStart)*curBreak.position;
logicalStart = logicalEndLast;
logicalEnd = curBreak.start;
if (sceneStart!=sceneEnd)
scales << this->createScale(xScale, sceneStart, sceneEnd, logicalStart, logicalEnd);
sceneEndLast = sceneEnd;
logicalEndLast = curBreak.end;
}
//add the remaining range going from the last available range break to the end of the plot (=end of the x-data range)
sceneStart = sceneEndLast+breakGap;
sceneEnd = plotSceneEnd;
logicalStart = logicalEndLast;
logicalEnd = xMax;
sceneStart = sceneEnd+50;
sceneEnd = itemRect.x()+itemRect.width()-horizontalPadding;
logicalStart = b.end;
logicalEnd = xMax;
if (sceneStart!=sceneEnd)
scales << this->createScale(xScale, sceneStart, sceneEnd, logicalStart, logicalEnd);
}
}
cSystem ->setXScales(scales);
......@@ -1377,36 +1392,52 @@ void CartesianPlotPrivate::retransformScales() {
if (yScale != CartesianPlot::ScaleLinear)
checkYRange();
//check where we have y-range breaks
hasValidBreak = false;
if (yRangeBreakingEnabled && !yRangeBreaks.list.isEmpty()) {
foreach(const CartesianPlot::RangeBreak& b, yRangeBreaks.list)
hasValidBreak = (!std::isnan(b.start) && !std::isnan(b.end));
}
//check whether we have y-range breaks - the first break, if available, should be valid
hasValidBreak = (yRangeBreakingEnabled && !yRangeBreaks.list.isEmpty() && yRangeBreaks.list.first().isValid());
//create y-scales
scales.clear();
plotSceneStart = itemRect.y()+itemRect.height()-verticalPadding;
plotSceneEnd = itemRect.y()+verticalPadding;
if (!hasValidBreak) {
sceneStart = itemRect.y()+itemRect.height()-verticalPadding;
sceneEnd = itemRect.y()+verticalPadding;
//no breaks available -> range goes from the plot beginning to the end of the plot
sceneStart = plotSceneStart;
sceneEnd = plotSceneEnd;
logicalStart = yMin;
logicalEnd = yMax;
scales << this->createScale(yScale, sceneStart, sceneEnd, logicalStart, logicalEnd);
} else {
foreach(const CartesianPlot::RangeBreak& b, yRangeBreaks.list) {
sceneStart = itemRect.y()+itemRect.height()-verticalPadding;
sceneEnd = itemRect.y()+verticalPadding;
sceneEnd = sceneStart+(sceneEnd-sceneStart)*b.position;
logicalStart = yMin;
logicalEnd = b.start;
scales << this->createScale(yScale, sceneStart, sceneEnd, logicalStart, logicalEnd);
sceneStart = sceneEnd+50;
sceneEnd = itemRect.y()+verticalPadding;
logicalStart = b.end;
logicalEnd = yMax;
if (sceneStart!=sceneEnd)
scales << this->createScale(yScale, sceneStart, sceneEnd, logicalStart, logicalEnd);
} else {
int sceneEndLast = plotSceneStart;
int logicalEndLast = yMin;
for (int i=0; i<yRangeBreaks.list.size(); ++i) {
const CartesianPlot::RangeBreak& curBreak = yRangeBreaks.list.at(i);
if (!curBreak.isValid())
break;
//current range goes from the end of the previous one (or from the plot beginning) to curBreak.start
sceneStart = sceneEndLast;
if (i!=0) sceneStart-=breakGap;
sceneEnd = plotSceneStart+(plotSceneEnd-plotSceneStart)*curBreak.position;
logicalStart = logicalEndLast;
logicalEnd = curBreak.start;
if (sceneStart!=sceneEnd)
scales << this->createScale(yScale, sceneStart, sceneEnd, logicalStart, logicalEnd);
sceneEndLast = sceneEnd;
logicalEndLast = curBreak.end;
}
//add the remaining range going from the last available range break to the end of the plot (=end of the y-data range)
sceneStart = sceneEndLast-breakGap;
sceneEnd = plotSceneEnd;
logicalStart = logicalEndLast;
logicalEnd = yMax;
if (sceneStart!=sceneEnd)
scales << this->createScale(yScale, sceneStart, sceneEnd, logicalStart, logicalEnd);
}
cSystem ->setYScales(scales);
......@@ -1517,7 +1548,8 @@ void CartesianPlotPrivate::checkYRange() {
}
CartesianScale* CartesianPlotPrivate::createScale(CartesianPlot::Scale type, double sceneStart, double sceneEnd, double logicalStart, double logicalEnd) {
Interval<double> interval (logicalStart-0.01, logicalEnd+0.01); //TODO: move this to CartesianScale
// Interval<double> interval (logicalStart-0.01, logicalEnd+0.01); //TODO: move this to CartesianScale
Interval<double> interval (-1E15, 1E15);
if (type == CartesianPlot::ScaleLinear) {
return CartesianScale::createLinearScale(interval, sceneStart, sceneEnd, logicalStart, logicalEnd);
} else {
......
......@@ -62,7 +62,8 @@ class CartesianPlot:public AbstractPlot{
ZoomInY, ZoomOutY, ShiftLeftX, ShiftRightX, ShiftUpY, ShiftDownY};
struct RangeBreak {
RangeBreak() : start(NAN), end(NAN), position(0.5), style(RangeBreakSloped) {};
RangeBreak() : start(NAN), end(NAN), position(0.5), style(RangeBreakSloped) {}
bool isValid() const {return (!std::isnan(start) && !std::isnan(end)); }
float start;
float end;
float position;
......
......@@ -245,19 +245,22 @@ void XYDifferentiationCurvePrivate::recalculate() {
double* ydata = ydataVector.data();
// differentiation settings
const int order = differentiationData.order;
const int derivOrder = differentiationData.derivOrder;
const int accOrder = differentiationData.accOrder;
#ifndef NDEBUG
qDebug()<<"order:"<<order;
qDebug()<<"derivation order:"<<derivOrder;
qDebug()<<"accuracy order:"<<accOrder;
#endif
///////////////////////////////////////////////////////////
int status=0;
switch (order) {
// TODO: use accOrder
switch (derivOrder) {
case 1:
status = nsl_diff_deriv_first(xdata, ydata, n);
status = nsl_diff_first_deriv_second_order(xdata, ydata, n);
break;
case 2:
status = nsl_diff_deriv_second(xdata, ydata, n);
status = nsl_diff_second_deriv_second_order(xdata, ydata, n);
break;
}
......@@ -295,7 +298,8 @@ void XYDifferentiationCurve::save(QXmlStreamWriter* writer) const{
writer->writeStartElement("differentiationData");
WRITE_COLUMN(d->xDataColumn, xDataColumn);
WRITE_COLUMN(d->yDataColumn, yDataColumn);
writer->writeAttribute( "order", QString::number(d->differentiationData.order) );
writer->writeAttribute( "derivOrder", QString::number(d->differentiationData.derivOrder) );
writer->writeAttribute( "accOrder", QString::number(d->differentiationData.accOrder) );
writer->writeEndElement();// differentiationData
// differentiation results (generated columns)
......@@ -345,11 +349,17 @@ bool XYDifferentiationCurve::load(XmlStreamReader* reader) {
READ_COLUMN(xDataColumn);
READ_COLUMN(yDataColumn);
str = attribs.value("order").toString();
str = attribs.value("derivOrder").toString();
if (str.isEmpty())
reader->raiseWarning(attributeWarning.arg("'order'"));
reader->raiseWarning(attributeWarning.arg("'derivOrder'"));
else
d->differentiationData.order = str.toInt();
d->differentiationData.derivOrder = str.toInt();
str = attribs.value("accOrder").toString();
if (str.isEmpty())
reader->raiseWarning(attributeWarning.arg("'accOrder'"));
else
d->differentiationData.accOrder = str.toInt();
} else if (reader->name() == "differentiationResult") {
......
......@@ -37,9 +37,10 @@ class XYDifferentiationCurve: public XYCurve {
public:
struct DifferentiationData {
DifferentiationData() : order(1) {};
DifferentiationData() : derivOrder(1), accOrder(2) {};
int order; // order of differentiation
int derivOrder; // order of differentiation
int accOrder; // order ofaccuracy
};
struct DifferentiationResult {
DifferentiationResult() : available(false), valid(false), elapsedTime(0) {};
......
......@@ -445,10 +445,10 @@ void XYInterpolationCurvePrivate::recalculate() {
case nsl_interp_evaluate_function:
break;
case nsl_interp_evaluate_derivative:
nsl_diff_deriv_first(xVector->data(), yVector->data(), npoints);
nsl_diff_first_deriv_second_order(xVector->data(), yVector->data(), npoints);
break;
case nsl_interp_evaluate_second_derivative:
nsl_diff_deriv_second(xVector->data(), yVector->data(), npoints);
nsl_diff_second_deriv_second_order(xVector->data(), yVector->data(), npoints);
break;
case nsl_interp_evaluate_integral:
nsl_interp_integral(xVector->data(), yVector->data(), npoints);
......
......@@ -92,7 +92,8 @@ void XYDifferentiationCurveDock::setupGeneral() {
connect( uiGeneralTab.leComment, SIGNAL(returnPressed()), this, SLOT(commentChanged()) );
connect( uiGeneralTab.chkVisible, SIGNAL(clicked(bool)), this, SLOT(visibilityChanged(bool)) );
connect( uiGeneralTab.sbOrder, SIGNAL(valueChanged(int)), this, SLOT(orderChanged()) );
connect( uiGeneralTab.sbDerivOrder, SIGNAL(valueChanged(int)), this, SLOT(derivOrderChanged()) );
connect( uiGeneralTab.sbAccOrder, SIGNAL(valueChanged(int)), this, SLOT(accOrderChanged()) );
connect( uiGeneralTab.pbRecalculate, SIGNAL(clicked()), this, SLOT(recalculateClicked()) );
}
......@@ -125,8 +126,10 @@ void XYDifferentiationCurveDock::initGeneralTab() {
// update list of selectable types
xDataColumnChanged(cbXDataColumn->currentModelIndex());
uiGeneralTab.sbOrder->setValue(m_differentiationData.order);
this->orderChanged();