File indexing completed on 2024-05-12 15:26:59

0001 /***************************************************************************
0002     File             : ExpressionParser.cpp
0003     Project          : LabPlot
0004     --------------------------------------------------------------------
0005     Copyright        : (C) 2014 Alexander Semke (alexander.semke@web.de)
0006     Copyright        : (C) 2014-2020 Stefan Gerlach (stefan.gerlach@uni.kn)
0007     Description      : C++ wrapper for the bison generated parser.
0008 
0009  ***************************************************************************/
0010 
0011 /***************************************************************************
0012  *                                                                         *
0013  *  This program is free software; you can redistribute it and/or modify   *
0014  *  it under the terms of the GNU General Public License as published by   *
0015  *  the Free Software Foundation; either version 2 of the License, or      *
0016  *  (at your option) any later version.                                    *
0017  *                                                                         *
0018  *  This program is distributed in the hope that it will be useful,        *
0019  *  but WITHOUT ANY WARRANTY; without even the implied warranty of         *
0020  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
0021  *  GNU General Public License for more details.                           *
0022  *                                                                         *
0023  *   You should have received a copy of the GNU General Public License     *
0024  *   along with this program; if not, write to the Free Software           *
0025  *   Foundation, Inc., 51 Franklin Street, Fifth Floor,                    *
0026  *   Boston, MA  02110-1301  USA                                           *
0027  *                                                                         *
0028  ***************************************************************************/
0029 
0030 #include <QRegularExpression>
0031 
0032 #include "backend/lib/macros.h"
0033 #include "backend/gsl/ExpressionParser.h"
0034 
0035 #include <klocalizedstring.h>
0036 
0037 extern "C" {
0038 #include "backend/gsl/parser.h"
0039 #include <gsl/gsl_version.h>
0040 #include <gsl/gsl_errno.h>
0041 #include <gsl/gsl_math.h>
0042 #include <gsl/gsl_const_mksa.h>
0043 #include <gsl/gsl_const_num.h>
0044 }
0045 
0046 ExpressionParser* ExpressionParser::m_instance{nullptr};
0047 
0048 ExpressionParser::ExpressionParser() {
0049     init_table();
0050     initFunctions();
0051     initConstants();
0052 }
0053 
0054 // initialize function list (sync with functions.h!)
0055 void ExpressionParser::initFunctions() {
0056     for (int i = 0; _functions[i].name != nullptr; i++)
0057         m_functions << _functions[i].name;
0058 
0059     m_functionsGroups << i18n("Standard Mathematical functions");
0060     //https://www.gnu.org/software/gsl/doc/html/specfunc.html
0061     m_functionsGroups << i18n("Airy Functions and Derivatives");
0062     m_functionsGroups << i18n("Bessel Functions");
0063     m_functionsGroups << i18n("Clausen Functions");
0064     m_functionsGroups << i18n("Coulomb Functions");
0065 //  m_functionsGroups << i18n("Coupling Coefficients");
0066     m_functionsGroups << i18n("Dawson Function");
0067     m_functionsGroups << i18n("Debye Functions");
0068     m_functionsGroups << i18n("Dilogarithm");
0069 //  m_functionsGroups << i18n("Elementary Operations");
0070     m_functionsGroups << i18n("Elliptic Integrals");
0071 //  m_functionsGroups << i18n("Elliptic Functions (Jacobi)");
0072 #ifndef _MSC_VER
0073     m_functionsGroups << i18n("Error Functions and Related Functions");
0074 #else
0075     m_functionsGroups << i18n("Error Functions");
0076 #endif
0077     m_functionsGroups << i18n("Exponential Functions");
0078     m_functionsGroups << i18n("Exponential Integrals");
0079     m_functionsGroups << i18n("Fermi-Dirac Function");
0080     m_functionsGroups << i18n("Gamma and Beta Functions");
0081     m_functionsGroups << i18n("Gegenbauer Functions");
0082 #if (GSL_MAJOR_VERSION > 2) || (GSL_MAJOR_VERSION == 2) && (GSL_MINOR_VERSION >= 4)
0083     m_functionsGroups << i18n("Hermite Polynomials and Functions");
0084 #endif
0085     m_functionsGroups << i18n("Hypergeometric Functions");
0086     m_functionsGroups << i18n("Laguerre Functions");
0087     m_functionsGroups << i18n("Lambert W Functions");
0088     m_functionsGroups << i18n("Legendre Functions and Spherical Harmonics");
0089     m_functionsGroups << i18n("Logarithm and Related Functions");
0090 //  m_functionsGroups << i18n("Mathieu Functions");
0091     m_functionsGroups << i18n("Power Function");
0092     m_functionsGroups << i18n("Psi (Digamma) Function");
0093     m_functionsGroups << i18n("Synchrotron Functions");
0094     m_functionsGroups << i18n("Transport Functions");
0095     m_functionsGroups << i18n("Trigonometric Functions");
0096     m_functionsGroups << i18n("Zeta Functions");
0097     // GSL random distribution functions
0098     m_functionsGroups << i18n("Gaussian Distribution");
0099     m_functionsGroups << i18n("Exponential Distribution");
0100     m_functionsGroups << i18n("Laplace Distribution");
0101     m_functionsGroups << i18n("Exponential Power Distribution");
0102     m_functionsGroups << i18n("Cauchy Distribution");
0103     m_functionsGroups << i18n("Rayleigh Distribution");
0104     m_functionsGroups << i18n("Landau Distribution");
0105     m_functionsGroups << i18n("Gamma Distribution");
0106     m_functionsGroups << i18n("Flat (Uniform) Distribution");
0107     m_functionsGroups << i18n("Lognormal Distribution");
0108     m_functionsGroups << i18n("Chi-squared Distribution");
0109     m_functionsGroups << i18n("F-distribution");
0110     m_functionsGroups << i18n("t-distribution");
0111     m_functionsGroups << i18n("Beta Distribution");
0112     m_functionsGroups << i18n("Logistic Distribution");
0113     m_functionsGroups << i18n("Pareto Distribution");
0114     m_functionsGroups << i18n("Weibull Distribution");
0115     m_functionsGroups << i18n("Gumbel Distribution");
0116     m_functionsGroups << i18n("Poisson Distribution");
0117     m_functionsGroups << i18n("Bernoulli Distribution");
0118     m_functionsGroups << i18n("Binomial Distribution");
0119     m_functionsGroups << i18n("Pascal Distribution");
0120     m_functionsGroups << i18n("Geometric Distribution");
0121     m_functionsGroups << i18n("Hypergeometric Distribution");
0122     m_functionsGroups << i18n("Logarithmic Distribution");
0123 
0124     int index = 0;
0125 
0126     // Standard mathematical functions
0127     m_functionsNames << i18n("pseudo-random integer [0,RAND_MAX]");
0128     m_functionsNames << i18n("nonlinear additive feedback rng [0,RAND_MAX]");
0129     m_functionsNames << i18n("nonlinear additive feedback rng [0,1]");
0130     m_functionsNames << i18n("Smallest integral value not less");
0131     m_functionsNames << i18n("Absolute value");
0132 
0133     m_functionsNames << i18n("Base 10 logarithm");
0134     m_functionsNames << i18n("Power function [x^y]");
0135     m_functionsNames << i18n("Nonnegative square root");
0136     m_functionsNames << i18n("Sign function");
0137     m_functionsNames << i18n("Heavyside theta function");
0138     m_functionsNames << i18n("Harmonic number function");
0139 
0140 #ifndef HAVE_WINDOWS
0141     m_functionsNames << i18n("Cube root");
0142     m_functionsNames << i18n("Extract the exponent");
0143     m_functionsNames << i18n("Round to an integer value");
0144     m_functionsNames << i18n("Round to the nearest integer");
0145     m_functionsNames << i18n("Round to the nearest integer");
0146 #endif
0147     m_functionsNames << QString("log(1+x)");
0148     m_functionsNames << QString("x * 2^e");
0149     m_functionsNames << QString("x^n");
0150     m_functionsNames << QString("x^2");
0151     m_functionsNames << QString("x^3");
0152     m_functionsNames << QString("x^4");
0153     m_functionsNames << QString("x^5");
0154     m_functionsNames << QString("x^6");
0155     m_functionsNames << QString("x^7");
0156     m_functionsNames << QString("x^8");
0157     m_functionsNames << QString("x^9");
0158 
0159 #ifndef HAVE_WINDOWS
0160     for (int i = 0; i < 27; i++)
0161 #else
0162     for (int i = 0; i < 22; i++)
0163 #endif
0164         m_functionsGroupIndex << index;
0165 
0166     // Airy Functions and Derivatives
0167     m_functionsNames << i18n("Airy function of the first kind");
0168     m_functionsNames << i18n("Airy function of the second kind");
0169     m_functionsNames << i18n("Scaled Airy function of the first kind");
0170     m_functionsNames << i18n("Scaled Airy function of the second kind");
0171     m_functionsNames << i18n("Airy function derivative of the first kind");
0172     m_functionsNames << i18n("Airy function derivative of the second kind");
0173     m_functionsNames << i18n("Scaled Airy function derivative of the first kind");
0174     m_functionsNames << i18n("Scaled Airy function derivative of the second kind");
0175     m_functionsNames << i18n("n-th zero of the Airy function of the first kind");
0176     m_functionsNames << i18n("n-th zero of the Airy function of the second kind");
0177     m_functionsNames << i18n("n-th zero of the Airy function derivative of the first kind");
0178     m_functionsNames << i18n("n-th zero of the Airy function derivative of the second kind");
0179 
0180     index++;
0181     for (int i = 0; i < 12; i++)
0182         m_functionsGroupIndex << index;
0183 
0184     // Bessel Functions
0185     m_functionsNames << i18n("Regular cylindrical Bessel function of zeroth order");
0186     m_functionsNames << i18n("Regular cylindrical Bessel function of first order");
0187     m_functionsNames << i18n("Regular cylindrical Bessel function of order n");
0188     m_functionsNames << i18n("Irregular cylindrical Bessel function of zeroth order");
0189     m_functionsNames << i18n("Irregular cylindrical Bessel function of first order");
0190     m_functionsNames << i18n("Irregular cylindrical Bessel function of order n");
0191     m_functionsNames << i18n("Regular modified cylindrical Bessel function of zeroth order");
0192     m_functionsNames << i18n("Regular modified cylindrical Bessel function of first order");
0193     m_functionsNames << i18n("Regular modified cylindrical Bessel function of order n");
0194     m_functionsNames << i18n("Scaled regular modified cylindrical Bessel function of zeroth order exp(-|x|) I0(x)");
0195 
0196     m_functionsNames << i18n("Scaled regular modified cylindrical Bessel function of first order exp(-|x|) I1(x)");
0197     m_functionsNames << i18n("Scaled regular modified cylindrical Bessel function of order n exp(-|x|) In(x)");
0198     m_functionsNames << i18n("Irregular modified cylindrical Bessel function of zeroth order");
0199     m_functionsNames << i18n("Irregular modified cylindrical Bessel function of first order");
0200     m_functionsNames << i18n("Irregular modified cylindrical Bessel function of order n");
0201     m_functionsNames << i18n("Scaled irregular modified cylindrical Bessel function of zeroth order exp(x) K0(x)");
0202     m_functionsNames << i18n("Scaled irregular modified cylindrical Bessel function of first order exp(x) K1(x)");
0203     m_functionsNames << i18n("Scaled irregular modified cylindrical Bessel function of order n exp(x) Kn(x)");
0204     m_functionsNames << i18n("Regular spherical Bessel function of zeroth order");
0205     m_functionsNames << i18n("Regular spherical Bessel function of first order");
0206 
0207     m_functionsNames << i18n("Regular spherical Bessel function of second order");
0208     m_functionsNames << i18n("Regular spherical Bessel function of order l");
0209     m_functionsNames << i18n("Irregular spherical Bessel function of zeroth order");
0210     m_functionsNames << i18n("Irregular spherical Bessel function of first order");
0211     m_functionsNames << i18n("Irregular spherical Bessel function of second order");
0212     m_functionsNames << i18n("Irregular spherical Bessel function of order l");
0213     m_functionsNames << i18n("Scaled regular modified spherical Bessel function of zeroth order, exp(-|x|) i0(x)");
0214     m_functionsNames << i18n("Scaled regular modified spherical Bessel function of first order, exp(-|x|) i1(x)");
0215     m_functionsNames << i18n("Scaled regular modified spherical Bessel function of second order, exp(-|x|) i2(x)");
0216     m_functionsNames << i18n("Scaled regular modified spherical Bessel function of order l, exp(-|x|) il(x)");
0217 
0218     m_functionsNames << i18n("Scaled irregular modified spherical Bessel function of zeroth order, exp(x) k0(x)");
0219     m_functionsNames << i18n("Scaled irregular modified spherical Bessel function of first order, exp(-|x|) k1(x)");
0220     m_functionsNames << i18n("Scaled irregular modified spherical Bessel function of second order, exp(-|x|) k2(x)");
0221     m_functionsNames << i18n("Scaled irregular modified spherical Bessel function of order l, exp(-|x|) kl(x)");
0222     m_functionsNames << i18n("Regular cylindrical Bessel function of fractional order");
0223     m_functionsNames << i18n("Irregular cylindrical Bessel function of fractional order");
0224     m_functionsNames << i18n("Regular modified Bessel function of fractional order");
0225     m_functionsNames << i18n("Scaled regular modified Bessel function of fractional order");
0226     m_functionsNames << i18n("Irregular modified Bessel function of fractional order");
0227     m_functionsNames << i18n("Logarithm of irregular modified Bessel function of fractional order");
0228 
0229     m_functionsNames << i18n("Scaled irregular modified Bessel function of fractional order");
0230     m_functionsNames << i18n("n-th positive zero of the Bessel function J0");
0231     m_functionsNames << i18n("n-th positive zero of the Bessel function J1");
0232     m_functionsNames << i18n("n-th positive zero of the Bessel function Jnu");
0233 
0234     index++;
0235     for (int i = 0; i < 44; i++)
0236         m_functionsGroupIndex << index;
0237 
0238     // Clausen Functions
0239     m_functionsNames << i18n("Clausen function");
0240     index++;
0241     m_functionsGroupIndex << index;
0242 
0243     // Coulomb Functions
0244     m_functionsNames << i18n("Lowest-order normalized hydrogenic bound state radial wavefunction");
0245     m_functionsNames << i18n("n-th normalized hydrogenic bound state radial wavefunction");
0246 
0247     index++;
0248     for (int i = 0; i < 2; i++)
0249         m_functionsGroupIndex << index;
0250 
0251     // Dawson Function
0252     m_functionsNames << i18n("Dawson integral");
0253     index++;
0254     m_functionsGroupIndex << index;
0255 
0256     // Debye Functions
0257     m_functionsNames << i18n("First-order Debye function");
0258     m_functionsNames << i18n("Second-order Debye function");
0259     m_functionsNames << i18n("Third-order Debye function");
0260     m_functionsNames << i18n("Fourth-order Debye function");
0261     m_functionsNames << i18n("Fifth-order Debye function");
0262     m_functionsNames << i18n("Sixth-order Debye function");
0263 
0264     index++;
0265     for (int i = 0; i < 6; i++)
0266         m_functionsGroupIndex << index;
0267 
0268     // Dilogarithm
0269     m_functionsNames << i18n("Dilogarithm for a real argument");
0270     index++;
0271     m_functionsGroupIndex << index;
0272 
0273     // Elliptic Integrals
0274     m_functionsNames << i18n("Legendre form of complete elliptic integral K");
0275     m_functionsNames << i18n("Legendre form of complete elliptic integral E");
0276     m_functionsNames << i18n("Legendre form of complete elliptic integral Pi");
0277     m_functionsNames << i18n("Legendre form of incomplete elliptic integral F");
0278     m_functionsNames << i18n("Legendre form of incomplete elliptic integral E");
0279     m_functionsNames << i18n("Legendre form of incomplete elliptic integral P");
0280     m_functionsNames << i18n("Legendre form of incomplete elliptic integral D");
0281     m_functionsNames << i18n("Carlson form of incomplete elliptic integral RC");
0282     m_functionsNames << i18n("Carlson form of incomplete elliptic integral RD");
0283     m_functionsNames << i18n("Carlson form of incomplete elliptic integral RF");
0284     m_functionsNames << i18n("Carlson form of incomplete elliptic integral RJ");
0285 
0286     index++;
0287     for (int i = 0; i < 11; i++)
0288         m_functionsGroupIndex << index;
0289 
0290     // Error Functions
0291     m_functionsNames << i18n("Error function");
0292     m_functionsNames << i18n("Complementary error function");
0293     m_functionsNames << i18n("Logarithm of complementary error function");
0294     m_functionsNames << i18n("Gaussian probability density function Z");
0295     m_functionsNames << i18n("Upper tail of the Gaussian probability function Q");
0296     m_functionsNames << i18n("Hazard function for the normal distribution Z/Q");
0297     int count = 6;
0298 #ifndef _MSC_VER
0299     m_functionsNames << i18n("Underflow-compensating function exp(x^2) erfc(x) for real x");
0300     m_functionsNames << i18n("Imaginary error function erfi(x) = -i erf(ix) for real x");
0301     m_functionsNames << i18n("Imaginary part of Faddeeva's scaled complex error function w(x) = exp(-x^2) erfc(-ix) for real x");
0302     m_functionsNames << i18n("Dawson's integral D(z) = sqrt(pi)/2 * exp(-z^2) * erfi(z)");
0303     m_functionsNames << i18n("Voigt profile");
0304     count += 5;
0305 #endif
0306     m_functionsNames << i18n("Pseudo-Voigt profile (same width)");
0307     count += 1;
0308 
0309     index++;
0310     for (int i = 0; i < count; i++)
0311         m_functionsGroupIndex << index;
0312 
0313     // Exponential Functions
0314     m_functionsNames << i18n("Exponential function");
0315     m_functionsNames << i18n("exponentiate x and multiply by y");
0316     m_functionsNames << QString("exp(x) - 1");
0317     m_functionsNames << QString("(exp(x)-1)/x");
0318     m_functionsNames << QString("2(exp(x)-1-x)/x^2");
0319     m_functionsNames << i18n("n-relative exponential");
0320 
0321     index++;
0322     for (int i = 0; i < 6; i++)
0323         m_functionsGroupIndex << index;
0324 
0325     // Exponential Integrals
0326     m_functionsNames << i18n("Exponential integral");
0327     m_functionsNames << i18n("Second order exponential integral");
0328     m_functionsNames << i18n("Exponential integral of order n");
0329     m_functionsNames << i18n("Exponential integral Ei");
0330     m_functionsNames << i18n("Hyperbolic integral Shi");
0331     m_functionsNames << i18n("Hyperbolic integral Chi");
0332     m_functionsNames << i18n("Third-order exponential integral");
0333     m_functionsNames << i18n("Sine integral");
0334     m_functionsNames << i18n("Cosine integral");
0335     m_functionsNames << i18n("Arctangent integral");
0336 
0337     index++;
0338     for (int i = 0; i < 10; i++)
0339         m_functionsGroupIndex << index;
0340 
0341     // Fermi-Dirac Function
0342     m_functionsNames << i18n("Complete Fermi-Dirac integral with index -1");
0343     m_functionsNames << i18n("Complete Fermi-Dirac integral with index 0");
0344     m_functionsNames << i18n("Complete Fermi-Dirac integral with index 1");
0345     m_functionsNames << i18n("Complete Fermi-Dirac integral with index 2");
0346     m_functionsNames << i18n("Complete Fermi-Dirac integral with integer index j");
0347     m_functionsNames << i18n("Complete Fermi-Dirac integral with index -1/2");
0348     m_functionsNames << i18n("Complete Fermi-Dirac integral with index 1/2");
0349     m_functionsNames << i18n("Complete Fermi-Dirac integral with index 3/2");
0350     m_functionsNames << i18n("Incomplete Fermi-Dirac integral with index zero");
0351 
0352     index++;
0353     for (int i = 0; i < 9; i++)
0354         m_functionsGroupIndex << index;
0355 
0356     // Gamma and Beta Functions
0357     m_functionsNames << i18n("Gamma function");
0358     m_functionsNames << i18n("Gamma function");
0359     m_functionsNames << i18n("Logarithm of the gamma function");
0360     m_functionsNames << i18n("Logarithm of the gamma function");
0361     m_functionsNames << i18n("Regulated gamma function");
0362     m_functionsNames << i18n("Reciprocal of the gamma function");
0363     m_functionsNames << i18n("Factorial n!");
0364     m_functionsNames << i18n("Double factorial n!!");
0365     m_functionsNames << i18n("Logarithm of the factorial");
0366     m_functionsNames << i18n("Logarithm of the double factorial");
0367 
0368     m_functionsNames << i18n("Combinatorial factor");
0369     m_functionsNames << i18n("Logarithm of the combinatorial factor");
0370     m_functionsNames << i18n("Taylor coefficient");
0371     m_functionsNames << i18n("Pochhammer symbol");
0372     m_functionsNames << i18n("Logarithm of the Pochhammer symbol");
0373     m_functionsNames << i18n("Relative Pochhammer symbol");
0374     m_functionsNames << i18n("Unnormalized incomplete gamma function");
0375     m_functionsNames << i18n("Normalized incomplete gamma function");
0376     m_functionsNames << i18n("Complementary normalized incomplete gamma function");
0377     m_functionsNames << i18n("Beta function");
0378 
0379     m_functionsNames << i18n("Logarithm of the beta function");
0380     m_functionsNames << i18n("Normalized incomplete beta function");
0381 
0382     index++;
0383     for (int i = 0; i < 22; i++)
0384         m_functionsGroupIndex << index;
0385 
0386     // Gegenbauer Functions
0387     m_functionsNames << i18n("Gegenbauer polynomial C_1");
0388     m_functionsNames << i18n("Gegenbauer polynomial C_2");
0389     m_functionsNames << i18n("Gegenbauer polynomial C_3");
0390     m_functionsNames << i18n("Gegenbauer polynomial C_n");
0391 
0392     index++;
0393     for (int i = 0; i < 4; i++)
0394         m_functionsGroupIndex << index;
0395 
0396 #if (GSL_MAJOR_VERSION > 2) || (GSL_MAJOR_VERSION == 2) && (GSL_MINOR_VERSION >= 4)
0397     // Hermite Polynomials and Functions
0398     m_functionsNames << i18n("Hermite polynomials physicists version");
0399     m_functionsNames << i18n("Hermite polynomials probabilists version");
0400     m_functionsNames << i18n("Hermite functions");
0401     m_functionsNames << i18n("Derivatives of Hermite polynomials physicists version");
0402     m_functionsNames << i18n("Derivatives of Hermite polynomials probabilists version");
0403     m_functionsNames << i18n("Derivatives of Hermite functions");
0404 
0405     index++;
0406     for (int i = 0; i < 6; i++)
0407         m_functionsGroupIndex << index;
0408 #endif
0409 
0410     // Hypergeometric Functions
0411     m_functionsNames << i18n("Hypergeometric function 0F1");
0412     m_functionsNames << i18n("Confluent hypergeometric function 1F1 for integer parameters");
0413     m_functionsNames << i18n("Confluent hypergeometric function 1F1 for general parameters");
0414     m_functionsNames << i18n("Confluent hypergeometric function U for integer parameters");
0415     m_functionsNames << i18n("Confluent hypergeometric function U");
0416     m_functionsNames << i18n("Gauss hypergeometric function 2F1");
0417     m_functionsNames << i18n("Gauss hypergeometric function 2F1 with complex parameters");
0418     m_functionsNames << i18n("Renormalized Gauss hypergeometric function 2F1");
0419     m_functionsNames << i18n("Renormalized Gauss hypergeometric function 2F1 with complex parameters");
0420     m_functionsNames << i18n("Hypergeometric function 2F0");
0421 
0422     index++;
0423     for (int i = 0; i < 10; i++)
0424         m_functionsGroupIndex << index;
0425 
0426     // Laguerre Functions
0427     m_functionsNames << i18n("generalized Laguerre polynomials L_1");
0428     m_functionsNames << i18n("generalized Laguerre polynomials L_2");
0429     m_functionsNames << i18n("generalized Laguerre polynomials L_3");
0430 
0431     index++;
0432     for (int i = 0; i < 3; i++)
0433         m_functionsGroupIndex << index;
0434 
0435     // Lambert W Functions
0436     m_functionsNames << i18n("Principal branch of the Lambert W function");
0437     m_functionsNames << i18n("Secondary real-valued branch of the Lambert W function");
0438 
0439     index++;
0440     for (int i = 0; i < 2; i++)
0441         m_functionsGroupIndex << index;
0442 
0443     // Legendre Functions and Spherical Harmonics
0444     m_functionsNames << i18n("Legendre polynomial P_1");
0445     m_functionsNames << i18n("Legendre polynomial P_2");
0446     m_functionsNames << i18n("Legendre polynomial P_3");
0447     m_functionsNames << i18n("Legendre polynomial P_l");
0448     m_functionsNames << i18n("Legendre function Q_0");
0449     m_functionsNames << i18n("Legendre function Q_1");
0450     m_functionsNames << i18n("Legendre function Q_l");
0451     m_functionsNames << i18n("Associated Legendre polynomial");
0452     m_functionsNames << i18n("Normalized associated Legendre polynomial");
0453     m_functionsNames << i18n("Irregular spherical conical function P^1/2");
0454 
0455     m_functionsNames << i18n("Regular spherical conical function P^(-1/2)");
0456     m_functionsNames << i18n("Conical function P^0");
0457     m_functionsNames << i18n("Conical function P^1");
0458     m_functionsNames << i18n("Regular spherical conical function P^(-1/2-l)");
0459     m_functionsNames << i18n("Regular cylindrical conical function P^(-m)");
0460     m_functionsNames << i18n("Zeroth radial eigenfunction of the Laplacian on the 3-dimensional hyperbolic space");
0461     m_functionsNames << i18n("First radial eigenfunction of the Laplacian on the 3-dimensional hyperbolic space");
0462     m_functionsNames << i18n("l-th radial eigenfunction of the Laplacian on the 3-dimensional hyperbolic space");
0463 
0464     index++;
0465     for (int i = 0; i < 18; i++)
0466         m_functionsGroupIndex << index;
0467 
0468     // Logarithm and Related Functions
0469     m_functionsNames << i18n("Logarithm");
0470     m_functionsNames << i18n("Logarithm of the magnitude");
0471     m_functionsNames << QString("log(1+x)");
0472     m_functionsNames << QString("log(1+x) - x");
0473 
0474     index++;
0475     for (int i = 0; i < 4; i++)
0476         m_functionsGroupIndex << index;
0477 
0478     // Power Function
0479     m_functionsNames << i18n("x^n for integer n with an error estimate");
0480     index++;
0481     m_functionsGroupIndex << index;
0482 
0483     // Psi (Digamma) Function
0484     m_functionsNames << i18n("Digamma function for positive integer n");
0485     m_functionsNames << i18n("Digamma function");
0486     m_functionsNames << i18n("Real part of the digamma function on the line 1+i y");
0487     m_functionsNames << i18n("Trigamma function psi' for positive integer n");
0488     m_functionsNames << i18n("Trigamma function psi'");
0489     m_functionsNames << i18n("Polygamma function psi^(n)");
0490 
0491     index++;
0492     for (int i = 0; i < 6; i++)
0493         m_functionsGroupIndex << index;
0494 
0495     // Synchrotron Functions
0496     m_functionsNames << i18n("First synchrotron function");
0497     m_functionsNames << i18n("Second synchrotron function");
0498 
0499     index++;
0500     for (int i = 0; i < 2; i++)
0501         m_functionsGroupIndex << index;
0502 
0503     // Transport Functions
0504     m_functionsNames << i18n("Transport function");
0505     m_functionsNames << i18n("Transport function");
0506     m_functionsNames << i18n("Transport function");
0507     m_functionsNames << i18n("Transport function");
0508 
0509     index++;
0510     for (int i = 0; i < 4; i++)
0511         m_functionsGroupIndex << index;
0512 
0513     // Trigonometric Functions
0514     m_functionsNames << i18n("Sine");
0515     m_functionsNames << i18n("Cosine");
0516     m_functionsNames << i18n("Tangent");
0517     m_functionsNames << i18n("Inverse sine");
0518     m_functionsNames << i18n("Inverse cosine");
0519     m_functionsNames << i18n("Inverse tangent");
0520     m_functionsNames << i18n("Inverse tangent using sign");
0521     m_functionsNames << i18n("Hyperbolic sine");
0522     m_functionsNames << i18n("Hyperbolic cosine");
0523     m_functionsNames << i18n("Hyperbolic tangent");
0524     m_functionsNames << i18n("Inverse hyperbolic cosine");
0525     m_functionsNames << i18n("Inverse hyperbolic sine");
0526     m_functionsNames << i18n("Inverse hyperbolic tangent");
0527     m_functionsNames << i18n("Secant");
0528     m_functionsNames << i18n("Cosecant");
0529     m_functionsNames << i18n("Cotangent");
0530     m_functionsNames << i18n("Inverse secant");
0531     m_functionsNames << i18n("Inverse cosecant");
0532     m_functionsNames << i18n("Inverse cotangent");
0533     m_functionsNames << i18n("Hyperbolic secant");
0534     m_functionsNames << i18n("Hyperbolic cosecant");
0535     m_functionsNames << i18n("Hyperbolic cotangent");
0536     m_functionsNames << i18n("Inverse hyperbolic secant");
0537     m_functionsNames << i18n("Inverse hyperbolic cosecant");
0538     m_functionsNames << i18n("Inverse hyperbolic cotangent");
0539     m_functionsNames << i18n("Sinc function sin(x)/x");
0540     m_functionsNames << QString("log(sinh(x))");
0541     m_functionsNames << QString("log(cosh(x))");
0542     m_functionsNames << i18n("Hypotenuse function");
0543     m_functionsNames << i18n("Three component hypotenuse function");
0544     m_functionsNames << i18n("restrict to [-pi,pi]");
0545     m_functionsNames << i18n("restrict to [0,2 pi]");
0546 
0547     index++;
0548     for (int i = 0; i < 32; i++)
0549         m_functionsGroupIndex << index;
0550 
0551     // Zeta Functions
0552     m_functionsNames << i18n("Riemann zeta function for integer n");
0553     m_functionsNames << i18n("Riemann zeta function");
0554     m_functionsNames << i18n("zeta(n)-1 for integer n");
0555     m_functionsNames << i18n("zeta(x)-1");
0556     m_functionsNames << i18n("Hurwitz zeta function");
0557     m_functionsNames << i18n("Eta function for integer n");
0558     m_functionsNames << i18n("Eta function");
0559 
0560     index++;
0561     for (int i = 0; i < 7; i++)
0562         m_functionsGroupIndex << index;
0563 
0564     // GSL Random Number Distributions: see https://www.gnu.org/software/gsl/doc/html/randist.html
0565     // Gaussian Distribution
0566     m_functionsNames << i18n("Probability density for a Gaussian distribution");
0567     m_functionsNames << i18n("Probability density for a unit Gaussian distribution");
0568     m_functionsNames << i18n("Cumulative distribution function P");
0569     m_functionsNames << i18n("Cumulative distribution function Q");
0570     m_functionsNames << i18n("Inverse cumulative distribution function P");
0571     m_functionsNames << i18n("Inverse cumulative distribution function Q");
0572     m_functionsNames << i18n("Cumulative unit distribution function P");
0573     m_functionsNames << i18n("Cumulative unit distribution function Q");
0574     m_functionsNames << i18n("Inverse cumulative unit distribution function P");
0575     m_functionsNames << i18n("Inverse cumulative unit distribution function Q");
0576 
0577     m_functionsNames << i18n("Probability density for Gaussian tail distribution");
0578     m_functionsNames << i18n("Probability density for unit Gaussian tail distribution");
0579     m_functionsNames << i18n("Probability density for a bivariate Gaussian distribution");
0580 
0581     index++;
0582     for (int i = 0; i < 13; i++)
0583         m_functionsGroupIndex << index;
0584 
0585     // Exponential Distribution
0586     m_functionsNames << i18n("Probability density for an exponential distribution");
0587     m_functionsNames << i18n("Cumulative distribution function P");
0588     m_functionsNames << i18n("Cumulative distribution function Q");
0589     m_functionsNames << i18n("Inverse cumulative distribution function P");
0590     m_functionsNames << i18n("Inverse cumulative distribution function Q");
0591 
0592     index++;
0593     for (int i = 0; i < 5; i++)
0594         m_functionsGroupIndex << index;
0595 
0596     // Laplace Distribution
0597     m_functionsNames << i18n("Probability density for a Laplace distribution");
0598     m_functionsNames << i18n("Cumulative distribution function P");
0599     m_functionsNames << i18n("Cumulative distribution function Q");
0600     m_functionsNames << i18n("Inverse cumulative distribution function P");
0601     m_functionsNames << i18n("Inverse cumulative distribution function Q");
0602 
0603     index++;
0604     for (int i = 0; i < 5; i++)
0605         m_functionsGroupIndex << index;
0606 
0607     // Exponential Power Distribution
0608     m_functionsNames << i18n("Probability density for an exponential power distribution");
0609     m_functionsNames << i18n("cumulative distribution function P");
0610     m_functionsNames << i18n("Cumulative distribution function Q");
0611 
0612     index++;
0613     for (int i = 0; i < 3; i++)
0614         m_functionsGroupIndex << index;
0615 
0616     // Cauchy Distribution
0617     m_functionsNames << i18n("Probability density for a Cauchy distribution");
0618     m_functionsNames << i18n("Cumulative distribution function P");
0619     m_functionsNames << i18n("Cumulative distribution function Q");
0620     m_functionsNames << i18n("Inverse cumulative distribution function P");
0621     m_functionsNames << i18n("Inverse cumulative distribution function Q");
0622 
0623     index++;
0624     for (int i = 0; i < 5; i++)
0625         m_functionsGroupIndex << index;
0626 
0627     // Rayleigh Distribution
0628     m_functionsNames << i18n("Probability density for a Rayleigh distribution");
0629     m_functionsNames << i18n("Cumulative distribution function P");
0630     m_functionsNames << i18n("Cumulative distribution function Q");
0631     m_functionsNames << i18n("Inverse cumulative distribution function P");
0632     m_functionsNames << i18n("Inverse cumulative distribution function Q");
0633     m_functionsNames << i18n("Probability density for a Rayleigh tail distribution");
0634 
0635     index++;
0636     for (int i = 0; i < 6; i++)
0637         m_functionsGroupIndex << index;
0638 
0639     // Landau Distribution
0640     m_functionsNames << i18n("Probability density for a Landau distribution");
0641     index++;
0642     m_functionsGroupIndex << index;
0643 
0644     // Gamma Distribution
0645     m_functionsNames << i18n("Probability density for a gamma distribution");
0646     m_functionsNames << i18n("Cumulative distribution function P");
0647     m_functionsNames << i18n("Cumulative distribution function Q");
0648     m_functionsNames << i18n("Inverse cumulative distribution function P");
0649     m_functionsNames << i18n("Inverse cumulative distribution function Q");
0650 
0651     index++;
0652     for (int i = 0; i < 5; i++)
0653         m_functionsGroupIndex << index;
0654 
0655     // Flat (Uniform) Distribution
0656     m_functionsNames << i18n("Probability density for a uniform distribution");
0657     m_functionsNames << i18n("Cumulative distribution function P");
0658     m_functionsNames << i18n("Cumulative distribution function Q");
0659     m_functionsNames << i18n("Inverse cumulative distribution function P");
0660     m_functionsNames << i18n("Inverse cumulative distribution function Q");
0661 
0662     index++;
0663     for (int i = 0; i < 5; i++)
0664         m_functionsGroupIndex << index;
0665 
0666     // Lognormal Distribution
0667     m_functionsNames << i18n("Probability density for a lognormal distribution");
0668     m_functionsNames << i18n("Cumulative distribution function P");
0669     m_functionsNames << i18n("Cumulative distribution function Q");
0670     m_functionsNames << i18n("Inverse cumulative distribution function P");
0671     m_functionsNames << i18n("Inverse cumulative distribution function Q");
0672 
0673     index++;
0674     for (int i = 0; i < 5; i++)
0675         m_functionsGroupIndex << index;
0676 
0677     // Chi-squared Distribution
0678     m_functionsNames << i18n("Probability density for a chi squared distribution");
0679     m_functionsNames << i18n("Cumulative distribution function P");
0680     m_functionsNames << i18n("Cumulative distribution function Q");
0681     m_functionsNames << i18n("Inverse cumulative distribution function P");
0682     m_functionsNames << i18n("Inverse cumulative distribution function Q");
0683 
0684     index++;
0685     for (int i = 0; i < 5; i++)
0686         m_functionsGroupIndex << index;
0687 
0688     // F-distribution
0689     m_functionsNames << i18n("Probability density for a F-distribution");
0690     m_functionsNames << i18n("Cumulative distribution function P");
0691     m_functionsNames << i18n("Cumulative distribution function Q");
0692     m_functionsNames << i18n("Inverse cumulative distribution function P");
0693     m_functionsNames << i18n("Inverse cumulative distribution function Q");
0694 
0695     index++;
0696     for (int i = 0; i < 5; i++)
0697         m_functionsGroupIndex << index;
0698 
0699     // t-distribution
0700     m_functionsNames << i18n("Probability density for a t-distribution");
0701     m_functionsNames << i18n("Cumulative distribution function P");
0702     m_functionsNames << i18n("Cumulative distribution function Q");
0703     m_functionsNames << i18n("Inverse cumulative distribution function P");
0704     m_functionsNames << i18n("Inverse cumulative distribution function Q");
0705 
0706     index++;
0707     for (int i = 0; i < 5; i++)
0708         m_functionsGroupIndex << index;
0709 
0710     // Beta Distribution
0711     m_functionsNames << i18n("Probability density for a beta distribution");
0712     m_functionsNames << i18n("Cumulative distribution function P");
0713     m_functionsNames << i18n("Cumulative distribution function Q");
0714     m_functionsNames << i18n("Inverse cumulative distribution function P");
0715     m_functionsNames << i18n("Inverse cumulative distribution function Q");
0716 
0717     index++;
0718     for (int i = 0; i < 5; i++)
0719         m_functionsGroupIndex << index;
0720 
0721     // Logistic Distribution
0722     m_functionsNames << i18n("Probability density for a logistic distribution");
0723     m_functionsNames << i18n("Cumulative distribution function P");
0724     m_functionsNames << i18n("Cumulative distribution function Q");
0725     m_functionsNames << i18n("Inverse cumulative distribution function P");
0726     m_functionsNames << i18n("Inverse cumulative distribution function Q");
0727 
0728     index++;
0729     for (int i = 0; i < 5; i++)
0730         m_functionsGroupIndex << index;
0731 
0732     // Pareto Distribution
0733     m_functionsNames << i18n("Probability density for a Pareto distribution");
0734     m_functionsNames << i18n("Cumulative distribution function P");
0735     m_functionsNames << i18n("Cumulative distribution function Q");
0736     m_functionsNames << i18n("Inverse cumulative distribution function P");
0737     m_functionsNames << i18n("Inverse cumulative distribution function Q");
0738 
0739     index++;
0740     for (int i = 0; i < 5; i++)
0741         m_functionsGroupIndex << index;
0742 
0743     // Weibull Distribution
0744     m_functionsNames << i18n("Probability density for a Weibull distribution");
0745     m_functionsNames << i18n("Cumulative distribution function P");
0746     m_functionsNames << i18n("Cumulative distribution function Q");
0747     m_functionsNames << i18n("Inverse cumulative distribution function P");
0748     m_functionsNames << i18n("Inverse cumulative distribution function Q");
0749 
0750     index++;
0751     for (int i = 0; i < 5; i++)
0752         m_functionsGroupIndex << index;
0753 
0754     // Gumbel Distribution
0755     m_functionsNames << i18n("Probability density for a Type-1 Gumbel distribution");
0756     m_functionsNames << i18n("Cumulative distribution function P");
0757     m_functionsNames << i18n("Cumulative distribution function Q");
0758     m_functionsNames << i18n("Inverse cumulative distribution function P");
0759     m_functionsNames << i18n("Inverse cumulative distribution function Q");
0760     m_functionsNames << i18n("Probability density for a Type-2 Gumbel distribution");
0761     m_functionsNames << i18n("Cumulative distribution function P");
0762     m_functionsNames << i18n("Cumulative distribution function Q");
0763     m_functionsNames << i18n("Inverse cumulative distribution function P");
0764     m_functionsNames << i18n("Inverse cumulative distribution function Q");
0765 
0766     index++;
0767     for (int i = 0; i < 10; i++)
0768         m_functionsGroupIndex << index;
0769 
0770     // Poisson Distribution
0771     m_functionsNames << i18n("Probability density for a Poisson distribution");
0772     m_functionsNames << i18n("Cumulative distribution function P");
0773     m_functionsNames << i18n("Cumulative distribution function Q");
0774 
0775     index++;
0776     for (int i = 0; i < 3; i++)
0777         m_functionsGroupIndex << index;
0778 
0779     // Bernoulli Distribution
0780     m_functionsNames << i18n("Probability density for a Bernoulli distribution");
0781     index++;
0782     m_functionsGroupIndex << index;
0783 
0784     // Binomial Distribution
0785     m_functionsNames << i18n("Probability density for a binomial distribution");
0786     m_functionsNames << i18n("Cumulative distribution function P");
0787     m_functionsNames << i18n("Cumulative distribution function Q");
0788     m_functionsNames << i18n("Probability density for a negative binomial distribution");
0789     m_functionsNames << i18n("Cumulative distribution function P");
0790     m_functionsNames << i18n("Cumulative distribution function Q");
0791 
0792     index++;
0793     for (int i = 0; i < 6; i++)
0794         m_functionsGroupIndex << index;
0795 
0796     // Pascal Distribution
0797     m_functionsNames << i18n("Probability density for a Pascal distribution");
0798     m_functionsNames << i18n("Cumulative distribution function P");
0799     m_functionsNames << i18n("Cumulative distribution function Q");
0800 
0801     index++;
0802     for (int i = 0; i < 3; i++)
0803         m_functionsGroupIndex << index;
0804 
0805     // Geometric Distribution
0806     m_functionsNames << i18n("Probability density for a geometric distribution");
0807     m_functionsNames << i18n("Cumulative distribution function P");
0808     m_functionsNames << i18n("Cumulative distribution function Q");
0809 
0810     index++;
0811     for (int i = 0; i < 3; i++)
0812         m_functionsGroupIndex << index;
0813 
0814     // Hypergeometric Distribution
0815     m_functionsNames << i18n("Probability density for a hypergeometric distribution");
0816     m_functionsNames << i18n("Cumulative distribution function P");
0817     m_functionsNames << i18n("Cumulative distribution function Q");
0818 
0819     index++;
0820     for (int i = 0; i < 3; i++)
0821         m_functionsGroupIndex << index;
0822 
0823     // Logarithmic Distribution
0824     m_functionsNames << i18n("Probability density for a logarithmic distribution");
0825     index++;
0826     m_functionsGroupIndex << index;
0827 }
0828 
0829 //TODO: decide whether we want to have i18n here in the backend part of the code
0830 void ExpressionParser::initConstants() {
0831     for (int i = 0; _constants[i].name != nullptr; i++)
0832         m_constants << _constants[i].name;
0833 
0834     //groups
0835     m_constantsGroups << i18n("Mathematical constants");
0836     m_constantsGroups << i18n("Fundamental constants");
0837     m_constantsGroups << i18n("Astronomy and Astrophysics");
0838     m_constantsGroups << i18n("Atomic and Nuclear Physics");
0839     m_constantsGroups << i18n("Measurement of Time");
0840     m_constantsGroups << i18n("Imperial Units");
0841     m_constantsGroups << i18n("Speed and Nautical Units");
0842     m_constantsGroups << i18n("Printers Units");
0843     m_constantsGroups << i18n("Volume, Area and Length");
0844     m_constantsGroups << i18n("Mass and Weight");
0845     m_constantsGroups << i18n("Thermal Energy and Power");
0846     m_constantsGroups << i18n("Pressure");
0847     m_constantsGroups << i18n("Viscosity");
0848     m_constantsGroups << i18n("Light and Illumination");
0849     m_constantsGroups << i18n("Radioactivity");
0850     m_constantsGroups << i18n("Force and Energy");
0851 
0852     //Mathematical constants
0853     m_constantsNames << i18n("Base of exponentials");
0854     m_constantsValues << QString::number(M_E,'g',15);
0855     m_constantsUnits << QString();
0856     m_constantsNames << i18n("Pi");
0857     m_constantsValues << QString::number(M_PI,'g',15);
0858     m_constantsUnits << QString();
0859     m_constantsNames << i18n("Euler's constant");
0860     m_constantsValues << QString::number(M_EULER,'g',15);
0861     m_constantsUnits << QString();
0862 
0863     for (int i = 0; i < 3; i++)
0864         m_constantsGroupIndex << 0;
0865 
0866     //Fundamental constants
0867     m_constantsNames << i18n("Speed of light");
0868     m_constantsValues << QString::number(GSL_CONST_MKSA_SPEED_OF_LIGHT,'g',15);
0869     m_constantsUnits << "m / s";
0870     m_constantsNames << i18n("Vacuum permeability");
0871     m_constantsValues << QString::number(GSL_CONST_MKSA_VACUUM_PERMEABILITY,'g',15);
0872     m_constantsUnits << "kg m / A^2 s^2";
0873     m_constantsNames << i18n("Vacuum permittivity");
0874     m_constantsValues << QString::number(GSL_CONST_MKSA_VACUUM_PERMITTIVITY,'g',15);
0875     m_constantsUnits << "A^2 s^4 / kg m^3";
0876     m_constantsNames << i18n("Planck constant");
0877     m_constantsValues << QString::number(GSL_CONST_MKSA_PLANCKS_CONSTANT_H,'g',15);
0878     m_constantsUnits << "kg m^2 / s";
0879     m_constantsNames << i18n("Reduced Planck constant");
0880     m_constantsValues << QString::number(GSL_CONST_MKSA_PLANCKS_CONSTANT_HBAR,'g',15);
0881     m_constantsUnits << "kg m^2 / s";
0882     m_constantsNames << i18n("Avogadro constant");
0883     m_constantsValues << QString::number(GSL_CONST_NUM_AVOGADRO,'g',15);
0884     m_constantsUnits << "1 / mol";
0885     m_constantsNames << i18n("Faraday");
0886     m_constantsValues << QString::number(GSL_CONST_MKSA_FARADAY,'g',15);
0887     m_constantsUnits << "A s / mol";
0888     m_constantsNames << i18n("Boltzmann constant");
0889     m_constantsValues << QString::number(GSL_CONST_MKSA_BOLTZMANN,'g',15);
0890     m_constantsUnits << "kg m^2 / K s^2";
0891     m_constantsNames << i18n("Molar gas");
0892     m_constantsValues << QString::number(GSL_CONST_MKSA_MOLAR_GAS,'g',15);
0893     m_constantsUnits << "kg m^2 / K mol s^2";
0894     m_constantsNames << i18n("Standard gas volume");
0895     m_constantsValues << QString::number(GSL_CONST_MKSA_STANDARD_GAS_VOLUME,'g',15);
0896     m_constantsUnits << "m^3 / mol";
0897     m_constantsNames << i18n("Stefan-Boltzmann constant");
0898     m_constantsValues << QString::number(GSL_CONST_MKSA_STEFAN_BOLTZMANN_CONSTANT,'g',15);
0899     m_constantsUnits << "kg / K^4 s^3";
0900     m_constantsNames << i18n("Gauss");
0901     m_constantsValues << QString::number(GSL_CONST_MKSA_GAUSS,'g',15);
0902     m_constantsUnits << "kg / A s^2";
0903 
0904     for (int i = 0; i < 12; i++)
0905         m_constantsGroupIndex << 1;
0906 
0907     // Astronomy and Astrophysics
0908     m_constantsNames << i18n("Astronomical unit");
0909     m_constantsValues << QString::number(GSL_CONST_MKSA_ASTRONOMICAL_UNIT,'g',15);
0910     m_constantsUnits << "m";
0911     m_constantsNames << i18n("Gravitational constant");
0912     m_constantsValues << QString::number(GSL_CONST_MKSA_GRAVITATIONAL_CONSTANT,'g',15);
0913     m_constantsUnits << "m^3 / kg s^2";
0914     m_constantsNames << i18n("Light year");
0915     m_constantsValues << QString::number(GSL_CONST_MKSA_LIGHT_YEAR,'g',15);
0916     m_constantsUnits << "m";
0917     m_constantsNames << i18n("Parsec");
0918     m_constantsValues << QString::number(GSL_CONST_MKSA_PARSEC,'g',15);
0919     m_constantsUnits << "m";
0920     m_constantsNames << i18n("Gravitational acceleration");
0921     m_constantsValues << QString::number(GSL_CONST_MKSA_GRAV_ACCEL,'g',15);
0922     m_constantsUnits << "m / s^2";
0923     m_constantsNames << i18n("Solar mass");
0924     m_constantsValues << QString::number(GSL_CONST_MKSA_SOLAR_MASS,'g',15);
0925     m_constantsUnits << "kg";
0926 
0927     for (int i = 0; i < 6; i++)
0928         m_constantsGroupIndex << 2;
0929 
0930     // Atomic and Nuclear Physics;
0931     m_constantsNames << i18n("Charge of the electron");
0932     m_constantsValues << QString::number(GSL_CONST_MKSA_ELECTRON_CHARGE,'g',15);
0933     m_constantsUnits << "A s";
0934     m_constantsNames << i18n("Energy of 1 electron volt");
0935     m_constantsValues << QString::number(GSL_CONST_MKSA_ELECTRON_VOLT,'g',15);
0936     m_constantsUnits << "kg m^2 / s^2";
0937     m_constantsNames << i18n("Unified atomic mass");
0938     m_constantsValues << QString::number(GSL_CONST_MKSA_UNIFIED_ATOMIC_MASS,'g',15);
0939     m_constantsUnits << "kg";
0940     m_constantsNames << i18n("Mass of the electron");
0941     m_constantsValues << QString::number(GSL_CONST_MKSA_MASS_ELECTRON,'g',15);
0942     m_constantsUnits << "kg";
0943     m_constantsNames << i18n("Mass of the muon");
0944     m_constantsValues << QString::number(GSL_CONST_MKSA_MASS_MUON,'g',15);
0945     m_constantsUnits << "kg";
0946     m_constantsNames << i18n("Mass of the proton");
0947     m_constantsValues << QString::number(GSL_CONST_MKSA_MASS_PROTON,'g',15);
0948     m_constantsUnits << "kg";
0949     m_constantsNames << i18n("Mass of the neutron");
0950     m_constantsValues << QString::number(GSL_CONST_MKSA_MASS_NEUTRON,'g',15);
0951     m_constantsUnits << "kg";
0952     m_constantsNames << i18n("Electromagnetic fine structure constant");
0953     m_constantsValues << QString::number(GSL_CONST_NUM_FINE_STRUCTURE,'g',15);
0954     m_constantsUnits << QString();
0955     m_constantsNames << i18n("Rydberg constant");
0956     m_constantsValues << QString::number(GSL_CONST_MKSA_RYDBERG,'g',15);
0957     m_constantsUnits << "kg m^2 / s^2";
0958     m_constantsNames << i18n("Bohr radius");
0959     m_constantsValues << QString::number(GSL_CONST_MKSA_BOHR_RADIUS,'g',15);
0960     m_constantsUnits << "m";
0961     m_constantsNames << i18n("Length of 1 angstrom");
0962     m_constantsValues << QString::number(GSL_CONST_MKSA_ANGSTROM,'g',15);
0963     m_constantsUnits << "m";
0964     m_constantsNames << i18n("Area of 1 barn");
0965     m_constantsValues << QString::number(GSL_CONST_MKSA_BARN,'g',15);
0966     m_constantsUnits << "m^2";
0967     m_constantsNames << i18n("Bohr Magneton");
0968     m_constantsValues << QString::number(GSL_CONST_MKSA_BOHR_MAGNETON,'g',15);
0969     m_constantsUnits << "A m^2";
0970     m_constantsNames << i18n("Nuclear Magneton");
0971     m_constantsValues << QString::number(GSL_CONST_MKSA_NUCLEAR_MAGNETON,'g',15);
0972     m_constantsUnits << "A m^2";
0973     m_constantsNames << i18n("Magnetic moment of the electron [absolute value]");
0974     m_constantsValues << QString::number(GSL_CONST_MKSA_ELECTRON_MAGNETIC_MOMENT,'g',15);
0975     m_constantsUnits << "A m^2";
0976     m_constantsNames << i18n("Magnetic moment of the proton");
0977     m_constantsValues << QString::number(GSL_CONST_MKSA_PROTON_MAGNETIC_MOMENT,'g',15);
0978     m_constantsUnits << "A m^2";
0979     m_constantsNames << i18n("Thomson cross section");
0980     m_constantsValues << QString::number(GSL_CONST_MKSA_THOMSON_CROSS_SECTION,'g',15);
0981     m_constantsUnits << "m^2";
0982     m_constantsNames << i18n("Electric dipole moment of 1 Debye");
0983     m_constantsValues << QString::number(GSL_CONST_MKSA_DEBYE,'g',15);
0984     m_constantsUnits << "A s^2 / m^2";
0985 
0986     for (int i = 0; i < 18; i++)
0987         m_constantsGroupIndex << 3;
0988 
0989     // Measurement of Time
0990     m_constantsNames << i18n("Number of seconds in 1 minute");
0991     m_constantsValues << QString::number(GSL_CONST_MKSA_MINUTE,'g',15);
0992     m_constantsUnits << "s";
0993     m_constantsNames << i18n("Number of seconds in 1 hour");
0994     m_constantsValues << QString::number(GSL_CONST_MKSA_HOUR,'g',15);
0995     m_constantsUnits << "s";
0996     m_constantsNames << i18n("Number of seconds in 1 day");
0997     m_constantsValues << QString::number(GSL_CONST_MKSA_DAY,'g',15);
0998     m_constantsUnits << "s";
0999     m_constantsNames << i18n("Number of seconds in 1 week");
1000     m_constantsValues << QString::number(GSL_CONST_MKSA_WEEK,'g',15);
1001     m_constantsUnits << "s";
1002 
1003     for (int i = 0; i < 4; i++)
1004         m_constantsGroupIndex << 4;
1005 
1006     // Imperial Units
1007     m_constantsNames << i18n("Length of 1 inch");
1008     m_constantsValues << QString::number(GSL_CONST_MKSA_INCH,'g',15);
1009     m_constantsUnits << "m";
1010     m_constantsNames << i18n("Length of 1 foot");
1011     m_constantsValues << QString::number(GSL_CONST_MKSA_FOOT,'g',15);
1012     m_constantsUnits << "m";
1013     m_constantsNames << i18n("Length of 1 yard");
1014     m_constantsValues << QString::number(GSL_CONST_MKSA_YARD,'g',15);
1015     m_constantsUnits << "m";
1016     m_constantsNames << i18n("Length of 1 mile");
1017     m_constantsValues << QString::number(GSL_CONST_MKSA_MILE,'g',15);
1018     m_constantsUnits << "m";
1019     m_constantsNames << i18n("Length of 1/1000th of an inch");
1020     m_constantsValues << QString::number(GSL_CONST_MKSA_MIL,'g',15);
1021     m_constantsUnits << "m";
1022 
1023     for (int i = 0; i < 5; i++)
1024         m_constantsGroupIndex << 5;
1025 
1026     // Speed and Nautical Units
1027     m_constantsNames << i18n("Speed of 1 kilometer per hour");
1028     m_constantsValues << QString::number(GSL_CONST_MKSA_KILOMETERS_PER_HOUR,'g',15);
1029     m_constantsUnits << "m / s";
1030     m_constantsNames << i18n("Speed of 1 mile per hour");
1031     m_constantsValues << QString::number(GSL_CONST_MKSA_MILES_PER_HOUR,'g',15);
1032     m_constantsUnits << "m / s";
1033     m_constantsNames << i18n("Length of 1 nautical mile");
1034     m_constantsValues << QString::number(GSL_CONST_MKSA_NAUTICAL_MILE,'g',15);
1035     m_constantsUnits << "m";
1036     m_constantsNames << i18n("Length of 1 fathom");
1037     m_constantsValues << QString::number(GSL_CONST_MKSA_FATHOM,'g',15);
1038     m_constantsUnits << "m";
1039     m_constantsNames << i18n("Speed of 1 knot");
1040     m_constantsValues << QString::number(GSL_CONST_MKSA_KNOT,'g',15);
1041     m_constantsUnits << "m / s";
1042 
1043     for (int i = 0; i < 5; i++)
1044         m_constantsGroupIndex << 6;
1045 
1046     // Printers Units
1047     m_constantsNames << i18n("length of 1 printer's point [1/72 inch]");
1048     m_constantsValues << QString::number(GSL_CONST_MKSA_POINT,'g',15);
1049     m_constantsUnits << "m";
1050     m_constantsNames << i18n("length of 1 TeX point [1/72.27 inch]");
1051     m_constantsValues << QString::number(GSL_CONST_MKSA_TEXPOINT,'g',15);
1052     m_constantsUnits << "m";
1053 
1054     for (int i = 0; i < 2; i++)
1055         m_constantsGroupIndex << 7;
1056 
1057     // Volume, Area and Length
1058     m_constantsNames << i18n("Length of 1 micron");
1059     m_constantsValues << QString::number(GSL_CONST_MKSA_MICRON,'g',15);
1060     m_constantsUnits << "m";
1061     m_constantsNames << i18n("Area of 1 hectare");
1062     m_constantsValues << QString::number(GSL_CONST_MKSA_HECTARE,'g',15);
1063     m_constantsUnits << "m^2";
1064     m_constantsNames << i18n("Area of 1 acre");
1065     m_constantsValues << QString::number(GSL_CONST_MKSA_ACRE,'g',15);
1066     m_constantsUnits << "m^2";
1067     m_constantsNames << i18n("Volume of 1 liter");
1068     m_constantsValues << QString::number(GSL_CONST_MKSA_LITER,'g',15);
1069     m_constantsUnits << "m^3";
1070     m_constantsNames << i18n("Volume of 1 US gallon");
1071     m_constantsValues << QString::number(GSL_CONST_MKSA_US_GALLON,'g',15);
1072     m_constantsUnits << "m^3";
1073     m_constantsNames << i18n("Volume of 1 Canadian gallon");
1074     m_constantsValues << QString::number(GSL_CONST_MKSA_CANADIAN_GALLON,'g',15);
1075     m_constantsUnits << "m^3";
1076     m_constantsNames << i18n("Volume of 1 UK gallon");
1077     m_constantsValues << QString::number(GSL_CONST_MKSA_UK_GALLON,'g',15);
1078     m_constantsUnits << "m^3";
1079     m_constantsNames << i18n("Volume of 1 quart");
1080     m_constantsValues << QString::number(GSL_CONST_MKSA_QUART,'g',15);
1081     m_constantsUnits << "m^3";
1082     m_constantsNames << i18n("Volume of 1 pint");
1083     m_constantsValues << QString::number(GSL_CONST_MKSA_PINT,'g',15);
1084     m_constantsUnits << "m^3";
1085 
1086     for (int i = 0; i < 9; i++)
1087         m_constantsGroupIndex << 8;
1088 
1089     // Mass and Weight
1090     m_constantsNames << i18n("Mass of 1 pound");
1091     m_constantsValues << QString::number(GSL_CONST_MKSA_POUND_MASS,'g',15);
1092     m_constantsUnits << "kg";
1093     m_constantsNames << i18n("Mass of 1 ounce");
1094     m_constantsValues << QString::number(GSL_CONST_MKSA_OUNCE_MASS,'g',15);
1095     m_constantsUnits << "kg";
1096     m_constantsNames << i18n("Mass of 1 ton");
1097     m_constantsValues << QString::number(GSL_CONST_MKSA_TON,'g',15);
1098     m_constantsUnits << "kg";
1099     m_constantsNames << i18n("Mass of 1 metric ton [1000 kg]");
1100     m_constantsValues << QString::number(GSL_CONST_MKSA_METRIC_TON,'g',15);
1101     m_constantsUnits << "kg";
1102     m_constantsNames << i18n("Mass of 1 UK ton");
1103     m_constantsValues << QString::number(GSL_CONST_MKSA_UK_TON,'g',15);
1104     m_constantsUnits << "kg";
1105     m_constantsNames << i18n("Mass of 1 troy ounce");
1106     m_constantsValues << QString::number(GSL_CONST_MKSA_TROY_OUNCE,'g',15);
1107     m_constantsUnits << "kg";
1108     m_constantsNames << i18n("Mass of 1 carat");
1109     m_constantsValues << QString::number(GSL_CONST_MKSA_CARAT,'g',15);
1110     m_constantsUnits << "kg";
1111     m_constantsNames << i18n("Force of 1 gram weight");
1112     m_constantsValues << QString::number(GSL_CONST_MKSA_GRAM_FORCE,'g',15);
1113     m_constantsUnits << "kg m / s^2";
1114     m_constantsNames << i18n("Force of 1 pound weight");
1115     m_constantsValues << QString::number(GSL_CONST_MKSA_POUND_FORCE,'g',15);
1116     m_constantsUnits << "kg m / s^2";
1117     m_constantsNames << i18n("Force of 1 kilopound weight");
1118     m_constantsValues << QString::number(GSL_CONST_MKSA_KILOPOUND_FORCE,'g',15);
1119     m_constantsUnits << "kg m / s^2";
1120     m_constantsNames << i18n("Force of 1 poundal");
1121     m_constantsValues << QString::number(GSL_CONST_MKSA_POUNDAL,'g',15);
1122     m_constantsUnits << "kg m / s^2";
1123 
1124     for (int i = 0; i < 11; i++)
1125         m_constantsGroupIndex << 9;
1126 
1127     // Thermal Energy and Power
1128     m_constantsNames << i18n("Energy of 1 calorie");
1129     m_constantsValues << QString::number(GSL_CONST_MKSA_CALORIE,'g',15);
1130     m_constantsUnits << "kg m^2 / s^2";
1131     m_constantsNames << i18n("Energy of 1 British Thermal Unit");
1132     m_constantsValues << QString::number(GSL_CONST_MKSA_BTU,'g',15);
1133     m_constantsUnits << "kg m^2 / s^2";
1134     m_constantsNames << i18n("Energy of 1 Therm");
1135     m_constantsValues << QString::number(GSL_CONST_MKSA_THERM,'g',15);
1136     m_constantsUnits << "kg m^2 / s^2";
1137     m_constantsNames << i18n("Power of 1 horsepower");
1138     m_constantsValues << QString::number(GSL_CONST_MKSA_HORSEPOWER,'g',15);
1139     m_constantsUnits << "kg m^2 / s^3";
1140 
1141     for (int i = 0; i < 4; i++)
1142         m_constantsGroupIndex << 10;
1143 
1144     // Pressure
1145     m_constantsNames << i18n("Pressure of 1 bar");
1146     m_constantsValues << QString::number(GSL_CONST_MKSA_BAR,'g',15);
1147     m_constantsUnits << "kg / m s^2";
1148     m_constantsNames << i18n("Pressure of 1 standard atmosphere");
1149     m_constantsValues << QString::number(GSL_CONST_MKSA_STD_ATMOSPHERE,'g',15);
1150     m_constantsUnits << "kg / m s^2";
1151     m_constantsNames << i18n("Pressure of 1 torr");
1152     m_constantsValues << QString::number(GSL_CONST_MKSA_TORR,'g',15);
1153     m_constantsUnits << "kg / m s^2";
1154     m_constantsNames << i18n("Pressure of 1 meter of mercury");
1155     m_constantsValues << QString::number(GSL_CONST_MKSA_METER_OF_MERCURY,'g',15);
1156     m_constantsUnits << "kg / m s^2";
1157     m_constantsNames << i18n("Pressure of 1 inch of mercury");
1158     m_constantsValues << QString::number(GSL_CONST_MKSA_INCH_OF_MERCURY,'g',15);
1159     m_constantsUnits << "kg / m s^2";
1160     m_constantsNames << i18n("Pressure of 1 inch of water");
1161     m_constantsValues << QString::number(GSL_CONST_MKSA_INCH_OF_WATER,'g',15);
1162     m_constantsUnits << "kg / m s^2";
1163     m_constantsNames << i18n("Pressure of 1 pound per square inch");
1164     m_constantsValues << QString::number(GSL_CONST_MKSA_PSI,'g',15);
1165     m_constantsUnits << "kg / m s^2";
1166 
1167     for (int i = 0; i < 7; i++)
1168         m_constantsGroupIndex << 11;
1169 
1170     // Viscosity
1171     m_constantsNames << i18n("Dynamic viscosity of 1 poise");
1172     m_constantsValues << QString::number(GSL_CONST_MKSA_POISE,'g',15);
1173     m_constantsUnits << "kg / m s";
1174     m_constantsNames << i18n("Kinematic viscosity of 1 stokes");
1175     m_constantsValues << QString::number(GSL_CONST_MKSA_STOKES,'g',15);
1176     m_constantsUnits << "m^2 / s";
1177 
1178     for (int i = 0; i < 2; i++)
1179         m_constantsGroupIndex << 12;
1180 
1181     // Light and Illumination
1182     m_constantsNames << i18n("Luminance of 1 stilb");
1183     m_constantsValues << QString::number(GSL_CONST_MKSA_STILB,'g',15);
1184     m_constantsUnits << "cd / m^2";
1185     m_constantsNames << i18n("Luminous flux of 1 lumen");
1186     m_constantsValues << QString::number(GSL_CONST_MKSA_LUMEN,'g',15);
1187     m_constantsUnits << "cd sr";
1188     m_constantsNames << i18n("Illuminance of 1 lux");
1189     m_constantsValues << QString::number(GSL_CONST_MKSA_LUX,'g',15);
1190     m_constantsUnits << "cd sr / m^2";
1191     m_constantsNames << i18n("Illuminance of 1 phot");
1192     m_constantsValues << QString::number(GSL_CONST_MKSA_PHOT,'g',15);
1193     m_constantsUnits << "cd sr / m^2";
1194     m_constantsNames << i18n("Illuminance of 1 footcandle");
1195     m_constantsValues << QString::number(GSL_CONST_MKSA_FOOTCANDLE,'g',15);
1196     m_constantsUnits << "cd sr / m^2";
1197     m_constantsNames << i18n("Luminance of 1 lambert");
1198     m_constantsValues << QString::number(GSL_CONST_MKSA_LAMBERT,'g',15);
1199     m_constantsUnits << "cd sr / m^2";
1200     m_constantsNames << i18n("Luminance of 1 footlambert");
1201     m_constantsValues << QString::number(GSL_CONST_MKSA_FOOTLAMBERT,'g',15);
1202     m_constantsUnits << "cd sr / m^2";
1203 
1204     for (int i = 0; i < 7; i++)
1205         m_constantsGroupIndex << 13;
1206 
1207     // Radioactivity
1208     m_constantsNames << i18n("Activity of 1 curie");
1209     m_constantsValues << QString::number(GSL_CONST_MKSA_CURIE,'g',15);
1210     m_constantsUnits << "1 / s";
1211     m_constantsNames << i18n("Exposure of 1 roentgen");
1212     m_constantsValues << QString::number(GSL_CONST_MKSA_ROENTGEN,'g',15);
1213     m_constantsUnits << "A s / kg";
1214     m_constantsNames << i18n("Absorbed dose of 1 rad");
1215     m_constantsValues << QString::number(GSL_CONST_MKSA_RAD,'g',15);
1216     m_constantsUnits << "m^2 / s^2";
1217 
1218     for (int i = 0; i < 3; i++)
1219         m_constantsGroupIndex << 14;
1220 
1221     // Force and Energy
1222     m_constantsNames << i18n("SI unit of force");
1223     m_constantsValues << QString::number(GSL_CONST_MKSA_NEWTON,'g',15);
1224     m_constantsUnits << "kg m / s^2";
1225     m_constantsNames << i18n("Force of 1 Dyne");
1226     m_constantsValues << QString::number(GSL_CONST_MKSA_DYNE,'g',15);
1227     m_constantsUnits << "kg m / s^2";
1228     m_constantsNames << i18n("SI unit of energy");
1229     m_constantsValues << QString::number(GSL_CONST_MKSA_JOULE,'g',15);
1230     m_constantsUnits << "kg m^2 / s^2";
1231     m_constantsNames << i18n("Energy 1 erg");
1232     m_constantsValues << QString::number(GSL_CONST_MKSA_ERG,'g',15);
1233     m_constantsUnits << "kg m^2 / s^2";
1234 
1235     for (int i = 0; i < 4; i++)
1236         m_constantsGroupIndex << 15;
1237 }
1238 
1239 /**********************************************************************************/
1240 
1241 ExpressionParser::~ExpressionParser() {
1242     delete_table();
1243 }
1244 
1245 ExpressionParser* ExpressionParser::getInstance() {
1246     if (!m_instance)
1247         m_instance = new ExpressionParser();
1248 
1249     return m_instance;
1250 }
1251 
1252 const QStringList& ExpressionParser::functions() {
1253     return m_functions;
1254 }
1255 
1256 const QStringList& ExpressionParser::functionsGroups() {
1257     return m_functionsGroups;
1258 }
1259 
1260 const QStringList& ExpressionParser::functionsNames() {
1261     return m_functionsNames;
1262 }
1263 
1264 const QVector<int>& ExpressionParser::functionsGroupIndices() {
1265     return m_functionsGroupIndex;
1266 }
1267 
1268 /* another idea:
1269  * https://stackoverflow.com/questions/36797770/get-function-parameters-count
1270  * but this does not work since all function pointer have zero args in the struct
1271  */
1272 int ExpressionParser::functionArgumentCount(const QString& functionName) {
1273     int index = 0;
1274     while (functionName != QString(_functions[index].name) && _functions[index].name != nullptr)
1275         index++;
1276 
1277     DEBUG(Q_FUNC_INFO << ", Found function " << STDSTRING(functionName) << " at index " << index);
1278     DEBUG(Q_FUNC_INFO << ", function " << STDSTRING(functionName) << " has " << _functions[index].argc << " arguments");
1279     return _functions[index].argc;
1280 }
1281 
1282 QString ExpressionParser::functionArgumentString(const QString& functionName, const XYEquationCurve::EquationType type) {
1283     switch (functionArgumentCount(functionName)) {
1284     case 0:
1285         return QString("()");
1286     case 1:
1287         switch(type) {
1288         case XYEquationCurve::EquationType::Cartesian:
1289             return QString("(x)");
1290         case XYEquationCurve::EquationType::Polar:
1291             return QString("(phi)");
1292         case XYEquationCurve::EquationType::Parametric:
1293             return QString("(t)");
1294         case XYEquationCurve::EquationType::Implicit:
1295         case XYEquationCurve::EquationType::Neutral:
1296             return QString("(x)");
1297         }
1298         break;
1299     case 2:
1300         switch(type) {
1301         case XYEquationCurve::EquationType::Cartesian:
1302             return QString("(x, y)");
1303         case XYEquationCurve::EquationType::Polar:
1304             return QString("(phi, theta)");
1305         case XYEquationCurve::EquationType::Parametric:
1306             return QString("(u, v)");
1307         case XYEquationCurve::EquationType::Implicit:
1308         case XYEquationCurve::EquationType::Neutral:
1309             return QString("(x, y)");
1310         }
1311         break;
1312     case 3:
1313         switch(type) {
1314         case XYEquationCurve::EquationType::Cartesian:
1315             return QString("(x, y, z)");
1316         case XYEquationCurve::EquationType::Polar:
1317             return QString("(alpha, beta, gamma)");
1318         case XYEquationCurve::EquationType::Parametric:
1319             return QString("(u, v, w)");
1320         case XYEquationCurve::EquationType::Implicit:
1321         case XYEquationCurve::EquationType::Neutral:
1322             return QString("(x, y, z)");
1323         }
1324         break;
1325     case 4:
1326         switch(type) {
1327         case XYEquationCurve::EquationType::Cartesian:
1328             return QString("(a, b, c, d)");
1329         case XYEquationCurve::EquationType::Polar:
1330             return QString("(alpha, beta, gamma, delta)");
1331         case XYEquationCurve::EquationType::Parametric:
1332             return QString("(a, b, c, d)");
1333         case XYEquationCurve::EquationType::Implicit:
1334         case XYEquationCurve::EquationType::Neutral:
1335             return QString("(a, b, c, d)");
1336         }
1337         break;
1338     }
1339 
1340     return QString("(...)");
1341 }
1342 
1343 const QStringList& ExpressionParser::constants() {
1344     return m_constants;
1345 }
1346 
1347 const QStringList& ExpressionParser::constantsGroups() {
1348     return m_constantsGroups;
1349 }
1350 
1351 const QStringList& ExpressionParser::constantsNames() {
1352     return m_constantsNames;
1353 }
1354 
1355 const QStringList& ExpressionParser::constantsValues() {
1356     return m_constantsValues;
1357 }
1358 
1359 const QStringList& ExpressionParser::constantsUnits() {
1360     return m_constantsUnits;
1361 }
1362 
1363 const QVector<int>& ExpressionParser::constantsGroupIndices() {
1364     return m_constantsGroupIndex;
1365 }
1366 
1367 bool ExpressionParser::isValid(const QString& expr, const QStringList& vars) {
1368     QDEBUG(Q_FUNC_INFO << ", expr:" << expr << ", vars:" << vars);
1369     gsl_set_error_handler_off();
1370 
1371     for (const auto& var: vars)
1372         assign_symbol(qPrintable(var), 0);
1373 
1374     SET_NUMBER_LOCALE
1375     parse(qPrintable(expr), qPrintable(numberLocale.name()));
1376 
1377     /* remove temporarily defined symbols */
1378     for (const auto& var: vars)
1379         remove_symbol(qPrintable(var));
1380 
1381     return !(parse_errors() > 0);
1382 }
1383 
1384 QStringList ExpressionParser::getParameter(const QString& expr, const QStringList& vars) {
1385     QDEBUG(Q_FUNC_INFO << ", variables:" << vars);
1386     QStringList parameters;
1387 
1388 #if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
1389     QStringList strings = expr.split(QRegularExpression(QStringLiteral("\\W+")), Qt::SkipEmptyParts);
1390 #else
1391     QStringList strings = expr.split(QRegularExpression(QStringLiteral("\\W+")), QString::SkipEmptyParts);
1392 #endif
1393     QDEBUG(Q_FUNC_INFO << ", found strings:" << strings);
1394     // RE for any number
1395 #if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 0))
1396     const QRegularExpression re(QRegularExpression::anchoredPattern(QStringLiteral("[0-9]*")));
1397 #else
1398     const QRegularExpression re("\\A(?:" +  QStringLiteral("[0-9]*") + ")\\z");
1399 #endif
1400     for (const QString& string: strings) {
1401         QDEBUG(string << ':' << constants().indexOf(string) << ' ' << functions().indexOf(string) << ' '
1402                    << vars.indexOf(string) << ' ' << re.match(string).hasMatch());
1403         // check if token is not a known constant/function/variable or number
1404         if (constants().indexOf(string) == -1 && functions().indexOf(string) == -1
1405             && vars.indexOf(string) == -1 && re.match(string).hasMatch() == false)
1406             parameters << string;
1407     }
1408     parameters.removeDuplicates();
1409     QDEBUG(Q_FUNC_INFO << ", parameters found:" << parameters);
1410 
1411     return parameters;
1412 }
1413 
1414 /*
1415  * Evaluate cartesian expression returning true on success and false if parsing fails
1416  */
1417 bool ExpressionParser::evaluateCartesian(const QString& expr, const QString& min, const QString& max,
1418         int count, QVector<double>* xVector, QVector<double>* yVector,
1419         const QStringList& paramNames, const QVector<double>& paramValues) {
1420     DEBUG(Q_FUNC_INFO << ", v1")
1421     gsl_set_error_handler_off();
1422 
1423     const Range<double> range{min, max};
1424     const double step = range.stepSize(count);
1425 
1426     for (int i = 0; i < paramNames.size(); ++i)
1427         assign_symbol(qPrintable(paramNames.at(i)), paramValues.at(i));
1428 
1429     SET_NUMBER_LOCALE
1430     for (int i = 0; i < count; i++) {
1431         const double x{ range.min() + step * i };
1432         assign_symbol("x", x);
1433 
1434         const double y{ parse(qPrintable(expr), qPrintable(numberLocale.name())) };
1435         if (parse_errors() > 0)
1436             return false;
1437 
1438         (*xVector)[i] = x;
1439         (*yVector)[i] = y;
1440     }
1441 
1442     return true;
1443 }
1444 
1445 bool ExpressionParser::evaluateCartesian(const QString& expr, const QString& min, const QString& max,
1446         int count, QVector<double>* xVector, QVector<double>* yVector) {
1447     DEBUG(Q_FUNC_INFO << ", v2")
1448     gsl_set_error_handler_off();
1449 
1450     const Range<double> range{min, max};
1451     const double step = range.stepSize(count);
1452 
1453     SET_NUMBER_LOCALE
1454     for (int i = 0; i < count; i++) {
1455         const double x{ range.min() + step * i };
1456         assign_symbol("x", x);
1457 
1458         const double y{ parse(qPrintable(expr), qPrintable(numberLocale.name())) };
1459         if (parse_errors() > 0)
1460             return false;
1461 
1462         (*xVector)[i] = x;
1463         (*yVector)[i] = y;
1464     }
1465 
1466     return true;
1467 }
1468 
1469 bool ExpressionParser::evaluateCartesian(const QString& expr, QVector<double>* xVector, QVector<double>* yVector) {
1470     DEBUG(Q_FUNC_INFO << ", v3")
1471     gsl_set_error_handler_off();
1472 
1473     SET_NUMBER_LOCALE
1474     for (int i = 0; i < xVector->count(); i++) {
1475         assign_symbol("x", xVector->at(i));
1476         const double y = parse(qPrintable(expr), qPrintable(numberLocale.name()));
1477 
1478         if (parse_errors() > 0)
1479             return false;
1480 
1481         (*yVector)[i] = y;
1482     }
1483 
1484     return true;
1485 }
1486 
1487 bool ExpressionParser::evaluateCartesian(const QString& expr, QVector<double>* xVector, QVector<double>* yVector,
1488         const QStringList& paramNames, const QVector<double>& paramValues) {
1489     DEBUG(Q_FUNC_INFO << ", v4")
1490     gsl_set_error_handler_off();
1491 
1492     for (int i = 0; i < paramNames.size(); ++i)
1493         assign_symbol(qPrintable(paramNames.at(i)), paramValues.at(i));
1494 
1495     SET_NUMBER_LOCALE
1496     for (int i = 0; i < xVector->count(); i++) {
1497         assign_symbol("x", xVector->at(i));
1498 
1499         const double y = parse(qPrintable(expr), qPrintable(numberLocale.name()));
1500         if (parse_errors() > 0)
1501             return false;
1502 
1503         (*yVector)[i] = y;
1504     }
1505 
1506     return true;
1507 }
1508 
1509 /*!
1510     evaluates multivariate function y=f(x_1, x_2, ...).
1511     Variable names (x_1, x_2, ...) are stored in \c vars.
1512     Data is stored in \c dataVectors.
1513  */
1514 bool ExpressionParser::evaluateCartesian(const QString& expr, const QStringList& vars, const QVector<QVector<double>*>& xVectors, QVector<double>* yVector) {
1515     DEBUG(Q_FUNC_INFO << ", v5")
1516     Q_ASSERT(vars.size() == xVectors.size());
1517     gsl_set_error_handler_off();
1518 
1519     //determine the minimal size of involved vectors
1520     double minSize = INFINITY;
1521     for (auto* xVector : xVectors) {
1522         if (xVector->size() < minSize)
1523             minSize = xVector->size();
1524     }
1525     if (yVector->size() < minSize)
1526         minSize = yVector->size();
1527 
1528     // calculate values
1529     SET_NUMBER_LOCALE
1530     for (int i = 0; i < minSize; i++) {
1531         for (int n = 0; n < vars.size(); ++n)
1532             assign_symbol(qPrintable(vars.at(n)), xVectors.at(n)->at(i));
1533 
1534         const double y = parse(qPrintable(expr), qPrintable(numberLocale.name()));
1535         if (parse_errors() > 0)
1536             return false;
1537 
1538         (*yVector)[i] = y;
1539     }
1540 
1541     //if the y-vector is longer than the x-vector(s), set all exceeding elements to NAN
1542     for (int i = minSize; i < yVector->size(); ++i)
1543         (*yVector)[i] = NAN;
1544 
1545     return true;
1546 }
1547 
1548 bool ExpressionParser::evaluatePolar(const QString& expr, const QString& min, const QString& max,
1549         int count, QVector<double>* xVector, QVector<double>* yVector) {
1550     gsl_set_error_handler_off();
1551 
1552     const Range<double> range{min, max};
1553     const double step = range.stepSize(count);
1554 
1555     SET_NUMBER_LOCALE
1556     for (int i = 0; i < count; i++) {
1557         const double phi = range.min() + step * i;
1558         assign_symbol("phi", phi);
1559 
1560         const double r = parse(qPrintable(expr), qPrintable(numberLocale.name()));
1561         if (parse_errors() > 0)
1562             return false;
1563 
1564         (*xVector)[i] = r*cos(phi);
1565         (*yVector)[i] = r*sin(phi);
1566     }
1567 
1568     return true;
1569 }
1570 
1571 bool ExpressionParser::evaluateParametric(const QString& xexpr, const QString& yexpr, const QString& min, const QString& max,
1572         int count, QVector<double>* xVector, QVector<double>* yVector) {
1573     gsl_set_error_handler_off();
1574 
1575     const Range<double> range{min, max};
1576     const double step = range.stepSize(count);
1577 
1578     SET_NUMBER_LOCALE
1579     for (int i = 0; i < count; i++) {
1580         assign_symbol("t", range.min() + step * i);
1581 
1582         const double x = parse(qPrintable(xexpr), qPrintable(numberLocale.name()));
1583         if (parse_errors() > 0)
1584             return false;
1585 
1586         const double y = parse(qPrintable(yexpr), qPrintable(numberLocale.name()));
1587         if (parse_errors() > 0)
1588             return false;
1589 
1590         (*xVector)[i] = x;
1591         (*yVector)[i] = y;
1592     }
1593 
1594     return true;
1595 }