/** Checks to see if this axis has valid parameters * */ bool AxisDetails::valid() { if (m_cmbAxisType->currentIndex() == ScaleDraw::Numeric) { if (m_chkShowFormula->isChecked()) { QString formula = m_txtFormula->text().lower(); try { double value = 1.0; MyParser parser; if (formula.contains("x")) { parser.DefineVar("x", &value); } else if (formula.contains("y")) { parser.DefineVar("y", &value); } parser.SetExpr(formula.ascii()); parser.Eval(); } catch(mu::ParserError &e) { QMessageBox::critical(this, tr("MantidPlot - Formula input error"), QString::fromStdString(e.GetMsg())+"\n"+tr("Valid variables are 'x' for Top/Bottom axes and 'y' for Left/Right axes!")); return false; } } } Table *w = m_app->table(m_cmbColName->currentText()); return m_initialised && m_graph && !((m_cmbAxisType->currentIndex() == ScaleDraw::Text || m_cmbAxisType->currentIndex() == ScaleDraw::ColHeader) && !w); }
double ScaleDraw::transformValue(double value) const { if (!formula_string.isEmpty()) { double lbl=0.0; try { MyParser parser; if (formula_string.contains("x")) parser.DefineVar("x", &value); else if (formula_string.contains("y")) parser.DefineVar("y", &value); parser.SetExpr(formula_string.ascii()); lbl=parser.Eval(); } catch(mu::ParserError &) { return 0; } return lbl; } else return value; }
void NonLinearFit::removeDataSingularities() { MyParser parser; for (int i = 0; i < d_p; i++){ double param = gsl_vector_get(d_param_init, i); parser.DefineVar(d_param_names[i].ascii(), ¶m); } QMapIterator<QString, double> it(d_constants); while (it.hasNext()) { it.next(); parser.DefineConst(it.key().ascii(), it.value()); } double xvar; parser.DefineVar("x", &xvar); parser.SetExpr(d_formula.ascii()); for (int i = 0; i < d_n; i++){ xvar = d_x[i]; try { parser.EvalRemoveSingularity(&xvar); } catch(MyParser::Pole){ QApplication::restoreOverrideCursor(); QMessageBox::critical((ApplicationWindow *)parent(), QObject::tr("QtiPlot"), QObject::tr("Ignored data point at x = %1.").arg(xvar)); removePole(i); } } }
void NonLinearFit::calculateFitCurveData(double *X, double *Y) { MyParser parser; for (int i=0; i<d_p; i++) parser.DefineVar(d_param_names[i].ascii(), &d_results[i]); QMapIterator<QString, double> i(d_constants); while (i.hasNext()) { i.next(); parser.DefineConst(i.key().ascii(), i.value()); } double x; parser.DefineVar("x", &x); parser.SetExpr(d_formula.ascii()); if (d_gen_function){ double X0 = d_x[0]; double step = (d_x[d_n - 1] - X0)/(d_points - 1); for (int i=0; i<d_points; i++){ x = X0 + i*step; X[i] = x; Y[i] = parser.EvalRemoveSingularity(&x, false); } } else { for (int i=0; i<d_points; i++) { x = d_x[i]; X[i] = x; Y[i] = parser.EvalRemoveSingularity(&x, false); } } }
bool NonLinearFit::setFormula(const QString& s, bool guess) { if (s.isEmpty()){ QMessageBox::critical((ApplicationWindow *)parent(), tr("QtiPlot - Input function error"), tr("Please enter a valid non-empty expression! Operation aborted!")); d_init_err = true; return false; } if (d_formula == s) return true; if (guess) setParametersList(guessParameters(s)); if (!d_p){ QMessageBox::critical((ApplicationWindow *)parent(), tr("QtiPlot - Fit Error"), tr("There are no parameters specified for this fit operation. Please define a list of parameters first!")); d_init_err = true; return false; } try { double *param = new double[d_p]; MyParser parser; double xvar; parser.DefineVar("x", &xvar); for (int k = 0; k < (int)d_p; k++){ param[k] = gsl_vector_get(d_param_init, k); parser.DefineVar(d_param_names[k].ascii(), ¶m[k]); } QMapIterator<QString, double> i(d_constants); while (i.hasNext()) { i.next(); parser.DefineConst(i.key().ascii(), i.value()); } parser.SetExpr(s.ascii()); parser.Eval() ; delete[] param; } catch(mu::ParserError &e){ QMessageBox::critical((ApplicationWindow *)parent(), tr("QtiPlot - Input function error"), QString::fromStdString(e.GetMsg())); d_init_err = true; return false; } d_init_err = false; d_formula = s; return true; }
Integration::Integration(const QString& formula, const QString& var, ApplicationWindow *parent, Graph *g, double start, double end) : Filter(parent, g), d_formula(formula), d_variable(var) { d_init_err = false; d_n = 0; d_from = start; d_to = end; if (d_to == d_from) d_init_err = true; MyParser parser; double x = 0.0; parser.DefineVar(d_variable.ascii(), &x); parser.SetExpr(d_formula.ascii()); try { parser.Eval(); } catch(mu::ParserError &e) { QMessageBox::critical(parent, tr("QtiPlot - Input error"), QString::fromStdString(e.GetMsg())); d_init_err = true; } setObjectName(tr("Integration")); d_integrand = AnalyticalFunction; d_method = 1; d_max_iterations = 20; d_sort_data = false; }
double Integration::trapezf(int n) { MyParser parser; double x = d_from; parser.DefineVar(d_variable.ascii(), &x); parser.SetExpr(d_formula.ascii()); static double s; if (n == 1){ x = d_from; double aux = parser.Eval(); x = d_to; return (s = 0.5*(d_to - d_from)*(aux + parser.Eval())); } else { int it = 1; for(int j=1; j < n-1; j++) it<<=1; double tnm = it; double del = (d_to - d_from)/tnm; x = d_from + 0.5*del; double sum = 0.0; for(int j=1; j <= it; j++, x += del) sum += parser.Eval(); s = 0.5*(s + (d_to - d_from)*sum/tnm); return s; } }
double NonLinearFit::eval(double *par, double x) { MyParser parser; for (int i=0; i<d_p; i++) parser.DefineVar(d_param_names[i].ascii(), &par[i]); QMapIterator<QString, double> i(d_constants); while (i.hasNext()) { i.next(); parser.DefineConst(i.key().ascii(), i.value()); } parser.DefineVar("x", &x); parser.SetExpr(d_formula.ascii()); return parser.EvalRemoveSingularity(&x, false); }
double user_d(const gsl_vector * x, void *params) { int n = ((struct FitData *)params)->n; int p = ((struct FitData *)params)->p; double *X = ((struct FitData *)params)->X; double *Y = ((struct FitData *)params)->Y; double *sigma = ((struct FitData *)params)->sigma; NonLinearFit *fitter = (NonLinearFit *)((struct FitData *) params)->fitter; const char *function = fitter->formula().ascii(); QStringList parNames = fitter->parameterNames(); double val=0; MyParser parser; try { double *parameters = new double[p]; double xvar; parser.DefineVar("x", &xvar); for (int i=0; i < p; i++) { parameters[i]=gsl_vector_get(x,i); parser.DefineVar(parNames[i].ascii(), ¶meters[i]); } QMapIterator<QString, double> i(fitter->constants()); while (i.hasNext()){ i.next(); parser.DefineConst(i.key().ascii(), i.value()); } parser.SetExpr(function); for (int j = 0; j < n; j++) { xvar = X[j]; double s = 1.0/sqrt(sigma[j]); try { double t = (parser.EvalRemoveSingularity(&xvar) - Y[j])/s; val += t*t; } catch (MyParser::Pole) { return GSL_POSINF; //weird, I know. blame gsl. } } delete[] parameters; } catch (mu::ParserError &e) { QMessageBox::critical(0,"QtiPlot - Input function error",QString::fromStdString(e.GetMsg())); return GSL_EINVAL; } return val; }
int user_df(const gsl_vector *x, void *params, gsl_matrix *J) { int n = ((struct FitData *)params)->n; int p = ((struct FitData *)params)->p; double *X = ((struct FitData *)params)->X; double *sigma = ((struct FitData *)params)->sigma; NonLinearFit *fitter = (NonLinearFit *)((struct FitData *) params)->fitter; const char *function = fitter->formula().ascii(); QStringList parNames = fitter->parameterNames(); try { double *param = new double[p]; MyParser parser; double xvar; parser.DefineVar("x", &xvar); for (int k=0; k<p; k++) { param[k] = gsl_vector_get(x,k); parser.DefineVar(parNames[k].ascii(), ¶m[k]); } QMapIterator<QString, double> i(fitter->constants()); while (i.hasNext()){ i.next(); parser.DefineConst(i.key().ascii(), i.value()); } parser.SetExpr(function); for (int i = 0; i < n; i++) { xvar = X[i]; double s = 1.0/sqrt(sigma[i]); for (int j = 0; j < p; j++) try { gsl_matrix_set (J, i, j, 1.0/s*parser.DiffRemoveSingularity(&xvar, ¶m[j], param[j])); } catch (MyParser::Pole) { return GSL_ESING; } } delete[] param; } catch (mu::ParserError &) { return GSL_EINVAL; } return GSL_SUCCESS; }
double ScaleDraw::transformValue(double value) const { if (!d_formula.isEmpty()){ double lbl=0.0; try{ MyParser parser; if (d_formula.contains("x", Qt::CaseInsensitive)) parser.DefineVar("x", &value); else if (d_formula.contains("y", Qt::CaseInsensitive)) parser.DefineVar("y", &value); parser.SetExpr(d_formula.lower().ascii()); lbl = parser.Eval(); } catch(mu::ParserError &){ return 0; } return lbl; } else return value; }
double UserFunction2D::operator()(double x, double y) { if (d_formula.isEmpty()) return 0.0; MyParser parser; double result = 0.0; try { parser.DefineVar("x", &x); parser.DefineVar("y", &y); parser.SetExpr((const std::string)d_formula.toAscii().constData()); result = parser.Eval(); } catch (mu::ParserError &e) { QMessageBox::critical(nullptr, "MantidPlot - Input function error", QString::fromStdString(e.GetMsg())); } return result; }
void FunctionDialog::acceptPolar() { QString from = boxPolarFrom->text().toLower(); QString to = boxPolarTo->text().toLower(); QString points = boxPolarPoints->text().toLower(); double start, end; try { MyParser parser; parser.SetExpr(from.toAscii().constData()); start = parser.Eval(); } catch (mu::ParserError &e) { QMessageBox::critical(0, tr("MantidPlot - Start limit error"), QString::fromStdString(e.GetMsg())); boxPolarFrom->setFocus(); return; } try { MyParser parser; parser.SetExpr(to.toAscii().constData()); end = parser.Eval(); } catch (mu::ParserError &e) { QMessageBox::critical(0, tr("MantidPlot - End limit error"), QString::fromStdString(e.GetMsg())); boxPolarTo->setFocus(); return; } if (start >= end) { QMessageBox::critical( 0, tr("MantidPlot - Input error"), tr("Please enter parameter limits that satisfy: from < end!")); boxPolarTo->setFocus(); return; } QString rformula = boxPolarRadius->currentText(); QString tformula = boxPolarTheta->currentText(); bool error = false; try { MyParser parser; double parameter = start; ; parser.DefineVar((boxPolarParameter->text()).toAscii().constData(), ¶meter); parser.SetExpr(rformula.toAscii().constData()); parser.Eval(); // cppcheck-suppress unreadVariable parameter = end; parser.Eval(); } catch (mu::ParserError &e) { QMessageBox::critical(0, tr("MantidPlot - Input function error"), QString::fromStdString(e.GetMsg())); boxPolarRadius->setFocus(); error = true; } try { MyParser parser; double parameter = start; ; parser.DefineVar((boxPolarParameter->text()).toAscii().constData(), ¶meter); parser.SetExpr(tformula.toAscii().constData()); parser.Eval(); // cppcheck-suppress unreadVariable parameter = end; parser.Eval(); } catch (mu::ParserError &e) { QMessageBox::critical(0, tr("MantidPlot - Input function error"), QString::fromStdString(e.GetMsg())); boxPolarTheta->setFocus(); error = true; } // Collecting all the information int type = boxType->currentIndex(); QStringList formulas; formulas += rformula; formulas += tformula; if (!error) { d_app->updateFunctionLists(type, formulas); if (!graph) d_app->newFunctionPlot(formulas, start, end, boxPolarPoints->value(), boxPolarParameter->text(), type); else { if (curveID >= 0) graph->modifyFunctionCurve(curveID, type, formulas, boxPolarParameter->text(), start, end, boxPolarPoints->value()); else graph->addFunction(formulas, start, end, boxPolarPoints->value(), boxPolarParameter->text(), type); } } }
void SurfaceDialog::acceptFunction() { ApplicationWindow *app = static_cast<ApplicationWindow *>(this->parent()); QString Xfrom=boxXFrom->text().lower(); QString Xto=boxXTo->text().lower(); QString Yfrom=boxYFrom->text().lower(); QString Yto=boxYTo->text().lower(); QString Zfrom=boxZFrom->text().lower(); QString Zto=boxZTo->text().lower(); double fromX, toX, fromY,toY, fromZ,toZ; try { MyParser parser; parser.SetExpr(Xfrom.ascii()); fromX=parser.Eval(); } catch(mu::ParserError &e) { QMessageBox::critical(app, tr("MantidPlot - X Start limit error"), QString::fromStdString(e.GetMsg())); boxXFrom->setFocus(); return; } try { MyParser parser; parser.SetExpr(Xto.ascii()); toX=parser.Eval(); } catch(mu::ParserError &e) { QMessageBox::critical(app, tr("MantidPlot - X End limit error"), QString::fromStdString(e.GetMsg())); boxXTo->setFocus(); return; } try { MyParser parser; parser.SetExpr(Yfrom.ascii()); fromY=parser.Eval(); } catch(mu::ParserError &e) { QMessageBox::critical(app, tr("MantidPlot - Y Start limit error"), QString::fromStdString(e.GetMsg())); boxYFrom->setFocus(); return; } try { MyParser parser; parser.SetExpr(Yto.ascii()); toY=parser.Eval(); } catch(mu::ParserError &e) { QMessageBox::critical(app, tr("MantidPlot - Y End limit error"), QString::fromStdString(e.GetMsg())); boxYTo->setFocus(); return; } try { MyParser parser; parser.SetExpr(Zfrom.ascii()); fromZ=parser.Eval(); } catch(mu::ParserError &e) { QMessageBox::critical(app, tr("MantidPlot - Z Start limit error"), QString::fromStdString(e.GetMsg())); boxZFrom->setFocus(); return; } try { MyParser parser; parser.SetExpr(Zto.ascii()); toZ=parser.Eval(); } catch(mu::ParserError &e) { QMessageBox::critical(app, tr("MantidPlot - Z End limit error"), QString::fromStdString(e.GetMsg())); boxZTo->setFocus(); return; } if (fromX >= toX || fromY >= toY || fromZ >= toZ) { QMessageBox::critical(app, tr("MantidPlot - Input error"), tr("Please enter limits that satisfy: from < end!")); boxXTo->setFocus(); return; } QString formula=boxFunction->currentText(); bool error=false; try { MyParser parser; double x=fromX; double y=fromY; parser.DefineVar("x", &x); parser.DefineVar("y", &y); parser.SetExpr(formula.ascii()); parser.Eval(); // cppcheck-suppress unreadVariable x=toX; // cppcheck-suppress unreadVariable y=toY; parser.Eval(); } catch(mu::ParserError &e) { QMessageBox::critical(0, tr("MantidPlot - Input function error"), QString::fromStdString(e.GetMsg())); boxFunction->setFocus(); error=true; } if (!error){ QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); if (!d_graph){ app->plotSurface(boxFunction->currentText(),fromX, toX, fromY, toY, fromZ, toZ, boxFuncColumns->value(), boxFuncRows->value()); } else d_graph->addFunction(boxFunction->currentText(),fromX, toX, fromY, toY, fromZ, toZ, boxFuncColumns->value(), boxFuncRows->value()); app->updateSurfaceFuncList(boxFunction->currentText()); QApplication::restoreOverrideCursor(); close(); } }
void SurfaceDialog::acceptParametricSurface() { ApplicationWindow *app = static_cast<ApplicationWindow *>(this->parent()); MyParser parser; double u = 1.0, v = 1.0; parser.DefineVar("u", &u); parser.DefineVar("v", &v); int list_size = 15; QString x_formula = boxX->text(); try { parser.SetExpr(x_formula.ascii()); parser.Eval(); } catch(mu::ParserError &e){ QMessageBox::critical(app, tr("MantidPlot - X Formula Error"), QString::fromStdString(e.GetMsg())); boxX->setFocus(); return; } app->d_param_surface_func.remove(x_formula); app->d_param_surface_func.push_front(x_formula); while ((int)app->d_param_surface_func.size() > list_size) app->d_param_surface_func.pop_back(); QString y_formula = boxY->text(); try { parser.SetExpr(y_formula.ascii()); parser.Eval(); } catch(mu::ParserError &e){ QMessageBox::critical(app, tr("MantidPlot - Y Formula Error"), QString::fromStdString(e.GetMsg())); boxY->setFocus(); return; } app->d_param_surface_func.remove(y_formula); app->d_param_surface_func.push_front(y_formula); while ((int)app->d_param_surface_func.size() > list_size) app->d_param_surface_func.pop_back(); QString z_formula = boxZ->text(); try { parser.SetExpr(z_formula.ascii()); parser.Eval(); } catch(mu::ParserError &e){ QMessageBox::critical(app, tr("MantidPlot - Z Formula Error"), QString::fromStdString(e.GetMsg())); boxZ->setFocus(); return; } app->d_param_surface_func.remove(z_formula); app->d_param_surface_func.push_front(z_formula); while ((int)app->d_param_surface_func.size() > list_size) app->d_param_surface_func.pop_back(); QString ufrom = boxUFrom->text().lower(); QString uto = boxUTo->text().lower(); QString vfrom = boxVFrom->text().lower(); QString vto = boxVTo->text().lower(); double ul, ur, vl, vr; try{ parser.SetExpr(ufrom.ascii()); ul = parser.Eval(); } catch(mu::ParserError &e){ QMessageBox::critical(app, tr("MantidPlot - u start limit error"), QString::fromStdString(e.GetMsg())); boxUFrom->setFocus(); return; } try{ parser.SetExpr(uto.ascii()); ur = parser.Eval(); } catch(mu::ParserError &e){ QMessageBox::critical(app, tr("MantidPlot - u end limit error"), QString::fromStdString(e.GetMsg())); boxUTo->setFocus(); return; } try{ parser.SetExpr(vfrom.ascii()); vl = parser.Eval(); } catch(mu::ParserError &e){ QMessageBox::critical(app, tr("MantidPlot - v start limit error"), QString::fromStdString(e.GetMsg())); boxVFrom->setFocus(); return; } try{ parser.SetExpr(vto.ascii()); vr = parser.Eval(); } catch(mu::ParserError &e){ QMessageBox::critical(app, tr("MantidPlot - u end limit error"), QString::fromStdString(e.GetMsg())); boxVTo->setFocus(); return; } QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); if (!d_graph) app->plotParametricSurface(x_formula, y_formula, z_formula, ul, ur, vl, vr, boxColumns->value(), boxRows->value(), boxUPeriodic->isChecked(), boxVPeriodic->isChecked()); else d_graph->addParametricSurface(x_formula, y_formula, z_formula, ul, ur, vl, vr, boxColumns->value(), boxRows->value(), boxUPeriodic->isChecked(), boxVPeriodic->isChecked()); QApplication::restoreOverrideCursor(); close(); }
bool FunctionCurve::loadData(int points, bool xLog10Scale) { if (!points) points = dataSize(); double *X = (double *)malloc(points*sizeof(double)); if (!X){ QMessageBox::critical(0, QObject::tr("QtiPlot - Memory Allocation Error"), QObject::tr("Not enough memory, operation aborted!")); return false; } double *Y = (double *)malloc(points*sizeof(double)); if (!Y){ QMessageBox::critical(0, QObject::tr("QtiPlot - Memory Allocation Error"), QObject::tr("Not enough memory, operation aborted!")); free(X); return false; } double step = (d_to - d_from)/(double)(points - 1.0); if (d_function_type == Normal){ MyParser parser; double x = d_from; try { parser.DefineVar(d_variable.ascii(), &x); QMapIterator<QString, double> i(d_constants); while (i.hasNext()){ i.next(); parser.DefineConst(i.key().ascii(), i.value()); } parser.SetExpr(d_formulas[0].ascii()); int lastButOne = points - 1; try { double xl = x, xr; double y = parser.EvalRemoveSingularity(&x, false); bool wellDefinedFunction = true; if (!gsl_finite(y)){// try to find a first well defined point (might help for some not really bad functions) wellDefinedFunction = false; for (int i = 0; i < lastButOne; i++){ xl = x; x += step; xr = x; y = parser.Eval(); if (gsl_finite(y)){ wellDefinedFunction = true; int iter = 0; double x0 = x, y0 = y; while(fabs(xr - xl)/step > 1e-15 && iter < points){ x = 0.5*(xl + xr); y = parser.Eval(); if (gsl_finite(y)){ xr = x; x0 = x; y0 = y; } else xl = x; iter++; } d_from = x0; X[0] = x0; Y[0] = y0; step = (d_to - d_from)/(double)(lastButOne); break; } } if (!wellDefinedFunction){ QMessageBox::critical(0, QObject::tr("QtiPlot"), QObject::tr("The function %1 is not defined in the specified interval!").arg(d_formulas[0])); free(X); free(Y); return false; } } else { X[0] = d_from; Y[0] = y; } } catch (MyParser::Pole) {} ScaleEngine *sc_engine = 0; if (plot()) sc_engine = (ScaleEngine *)plot()->axisScaleEngine(xAxis()); if (xLog10Scale || (d_from > 0 && d_to > 0 && sc_engine && sc_engine->type() == ScaleTransformation::Log10)){ step = log10(d_to/d_from)/(double)(points - 1); for (int i = 1; i < lastButOne; i++ ){ x = d_from*pow(10, i*step); X[i] = x; try { Y[i] = parser.EvalRemoveSingularity(&x, false); } catch (MyParser::Pole){} } } else { for (int i = 1; i < lastButOne; i++ ){ x += step; X[i] = x; try { Y[i] = parser.EvalRemoveSingularity(&x, false); } catch (MyParser::Pole){} } } //the last point might be outside the interval, therefore we calculate it separately at its precise value x = d_to; X[lastButOne] = x; try { Y[lastButOne] = parser.EvalRemoveSingularity(&x, false); } catch (MyParser::Pole){} } catch(mu::ParserError &e) {} } else if (d_function_type == Parametric || d_function_type == Polar) { QStringList aux = d_formulas; MyParser xparser; MyParser yparser; double par; if (d_function_type == Polar) { QString swap=aux[0]; aux[0]="("+swap+")*cos("+aux[1]+")"; aux[1]="("+swap+")*sin("+aux[1]+")"; } try { QMapIterator<QString, double> i(d_constants); while (i.hasNext()){ i.next(); xparser.DefineConst(i.key().ascii(), i.value()); yparser.DefineConst(i.key().ascii(), i.value()); } xparser.DefineVar(d_variable.ascii(), &par); yparser.DefineVar(d_variable.ascii(), &par); xparser.SetExpr(aux[0].ascii()); yparser.SetExpr(aux[1].ascii()); par = d_from; for (int i = 0; i<points; i++ ){ X[i] = xparser.Eval(); Y[i] = yparser.Eval(); par += step; } } catch(mu::ParserError &) {} } if (curveType() == QwtPlotCurve::Yfx) setData(X, Y, points); else setData(Y, X, points); free(X); free(Y); return true; }