diff --git a/src/backend/nsl/nsl_complex.h b/src/backend/nsl/nsl_complex.h new file mode 100644 index 000000000..3ec8c97ec --- /dev/null +++ b/src/backend/nsl/nsl_complex.h @@ -0,0 +1,47 @@ +/*************************************************************************** + File : nsl_complex.h + Project : LabPlot + Description : NSL complex data type support + -------------------------------------------------------------------- + Copyright : (C) 2019 by Stefan Gerlach (stefan.gerlach@uni.kn) + + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, * + * Boston, MA 02110-1301 USA * + * * + ***************************************************************************/ + +#ifndef NSL_COMPLEX_H +#define NSL_COMPLEX_H + +#ifdef _MSC_VER +#include +#define COMPLEX _Dcomplex +#else + +/* C++ including this header */ +#ifdef __cplusplus +#define COMPLEX double _Complex +#else /* C */ +#include +#define COMPLEX double complex +#endif + +#endif /* _MSC_VER */ + +#endif /* NSL_COMPLEX_H */ diff --git a/src/backend/nsl/nsl_sf_basic.c b/src/backend/nsl/nsl_sf_basic.c index e4ed524cf..0844f7bf1 100644 --- a/src/backend/nsl/nsl_sf_basic.c +++ b/src/backend/nsl/nsl_sf_basic.c @@ -1,277 +1,312 @@ /*************************************************************************** File : nsl_sf_basic.c Project : LabPlot Description : NSL special basic functions -------------------------------------------------------------------- Copyright : (C) 2018 by Stefan Gerlach (stefan.gerlach@uni.kn) ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the Free Software * * Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301 USA * * * ***************************************************************************/ #include "nsl_sf_basic.h" #include #include #include #include #include #ifdef HAVE_LIBCERF #include #elif !defined(_MSC_VER) #include "Faddeeva.h" #endif /* stdlib.h */ double nsl_sf_rand(void) { return rand(); } #if defined(HAVE_RANDOM_FUNCTION) double nsl_sf_random(void) { return random(); } double nsl_sf_drand(void) { return random()/(double)RAND_MAX; } #else double nsl_sf_random(void) { return rand(); } double nsl_sf_drand(void) { return rand()/(double)RAND_MAX; } #endif double nsl_sf_sgn(double x) { #ifndef _WIN32 return copysign(1.0, x); #else if (x > 0) return 1; else if (x < 0) return -1; else return 0; #endif } double nsl_sf_theta(double x) { if (x >= 0) return 1; else return 0; } +/* + * source: https://stackoverflow.com/questions/11376288/fast-computing-of-log2-for-64-bit-integers + * source: http://graphics.stanford.edu/~seander/bithacks.html#IntegerLogLookup + */ +int nsl_sf_log2p1_int(int x) { + const signed char LogTable256[256] = { + -1,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3, + 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7 + }; + + unsigned int r; // r will be lg(v) + unsigned int t, tt; // temporaries + if ((tt = x >> 16)) + r = (t = tt >> 8) ? 24 + LogTable256[t] : 16 + LogTable256[tt]; + else + r = (t = x >> 8) ? 8 + LogTable256[t] : LogTable256[x]; + + return r + 1; +} + + double nsl_sf_sec(double x) { return 1./cos(x); } double nsl_sf_csc(double x) { return 1./sin(x); } double nsl_sf_cot(double x) { return 1./tan(x); } double nsl_sf_asec(double x) { return acos(1./x); } double nsl_sf_acsc(double x) { return asin(1./x); } double nsl_sf_acot(double x) { if (x > 0) return atan(1./x); else return atan(1./x) + M_PI; } double nsl_sf_sech(double x) { return 1./cosh(x); } double nsl_sf_csch(double x) { return 1./sinh(x); } double nsl_sf_coth(double x) { return 1./tanh(x); } double nsl_sf_asech(double x) { return gsl_acosh(1./x); } double nsl_sf_acsch(double x) { return gsl_asinh(1./x); } double nsl_sf_acoth(double x) { return gsl_atanh(1./x); } double nsl_sf_harmonic(double x) { // check if x is a negative integer if (x < 0 && !gsl_fcmp(round(x) - x, 0., 1.e-16)) return GSL_POSINF; return gsl_sf_psi(x + 1) + M_EULER; } /* error functions and related */ double nsl_sf_erfcx(double x) { #ifdef HAVE_LIBCERF return erfcx(x); #elif defined(_MSC_VER) return 0.; // not supported yet #else return Faddeeva_erfcx_re(x); #endif } double nsl_sf_erfi(double x) { #ifdef HAVE_LIBCERF return erfi(x); #elif defined(_MSC_VER) return 0.; // not supported yet #else return Faddeeva_erfi_re(x); #endif } double nsl_sf_im_w_of_x(double x) { #ifdef HAVE_LIBCERF return im_w_of_x(x); #elif defined(_MSC_VER) return 0.; // not supported yet #else return Faddeeva_w_im(x); #endif } #if !defined(_MSC_VER) -double nsl_sf_im_w_of_z(complex double z) { +double nsl_sf_im_w_of_z(COMPLEX z) { #ifdef HAVE_LIBCERF return cimag(w_of_z(z)); #else return cimag(Faddeeva_w(z, 0)); #endif } #endif double nsl_sf_dawson(double x) { #ifdef HAVE_LIBCERF return dawson(x); #elif defined(_MSC_VER) return 0.; // not supported yet #else return Faddeeva_Dawson_re(x); #endif } double nsl_sf_voigt(double x, double sigma, double gamma) { #ifdef HAVE_LIBCERF return voigt(x, sigma, gamma); #elif defined(_MSC_VER) return 0.; // not supported yet #else - double complex z = (x + I*gamma)/(sqrt(2.)*sigma); + COMPLEX z = (x + I*gamma)/(sqrt(2.)*sigma); return creal(Faddeeva_w(z, 0))/(sqrt(2.*M_PI)*sigma); #endif } double nsl_sf_pseudovoigt(double x, double eta, double sigma, double gamma) { if (sigma == 0 || gamma == 0) return 0; //TODO: what if eta < 0 or > 1? return (1. - eta) * gsl_ran_gaussian_pdf(x, sigma) + eta * gsl_ran_cauchy_pdf(x, gamma); } double nsl_sf_pseudovoigt1(double x, double eta, double w) { // 2w - FWHM, sigma_G = w/sqrt(2ln(2)) return nsl_sf_pseudovoigt(x, eta, w/sqrt(2.*log(2.)), w); } /* wrapper for GSL functions with integer parameters */ #define MODE GSL_PREC_DOUBLE /* mathematical functions */ double nsl_sf_ldexp(double x, double expo) { return gsl_ldexp(x, (int)round(expo)); } double nsl_sf_powint(double x, double n) { return gsl_sf_pow_int(x, (int)round(n)); } /* Airy functions */ double nsl_sf_airy_Ai(double x) { return gsl_sf_airy_Ai(x, MODE); } double nsl_sf_airy_Bi(double x) { return gsl_sf_airy_Bi(x, MODE); } double nsl_sf_airy_Ais(double x) { return gsl_sf_airy_Ai_scaled(x, MODE); } double nsl_sf_airy_Bis(double x) { return gsl_sf_airy_Bi_scaled(x, MODE); } double nsl_sf_airy_Aid(double x) { return gsl_sf_airy_Ai_deriv(x, MODE); } double nsl_sf_airy_Bid(double x) { return gsl_sf_airy_Bi_deriv(x, MODE); } double nsl_sf_airy_Aids(double x) { return gsl_sf_airy_Ai_deriv_scaled(x, MODE); } double nsl_sf_airy_Bids(double x) { return gsl_sf_airy_Bi_deriv_scaled(x, MODE); } double nsl_sf_airy_0_Ai(double s) { return gsl_sf_airy_zero_Ai((unsigned int)round(s)); } double nsl_sf_airy_0_Bi(double s) { return gsl_sf_airy_zero_Bi((unsigned int)round(s)); } double nsl_sf_airy_0_Aid(double s) { return gsl_sf_airy_zero_Ai_deriv((unsigned int)round(s)); } double nsl_sf_airy_0_Bid(double s) { return gsl_sf_airy_zero_Bi_deriv((unsigned int)round(s)); } /* Bessel functions */ double nsl_sf_bessel_Jn(double n, double x) { return gsl_sf_bessel_Jn((int)round(n), x); } double nsl_sf_bessel_Yn(double n, double x) { return gsl_sf_bessel_Yn((int)round(n), x); } double nsl_sf_bessel_In(double n, double x) { return gsl_sf_bessel_In((int)round(n), x); } double nsl_sf_bessel_Ins(double n, double x) { return gsl_sf_bessel_In_scaled((int)round(n), x); } double nsl_sf_bessel_Kn(double n, double x) { return gsl_sf_bessel_Kn((int)round(n), x); } double nsl_sf_bessel_Kns(double n, double x) { return gsl_sf_bessel_Kn_scaled((int)round(n), x); } double nsl_sf_bessel_jl(double l, double x) { return gsl_sf_bessel_jl((int)round(l), x); } double nsl_sf_bessel_yl(double l, double x) { return gsl_sf_bessel_yl((int)round(l), x); } double nsl_sf_bessel_ils(double l, double x) { return gsl_sf_bessel_il_scaled((int)round(l), x); } double nsl_sf_bessel_kls(double l, double x) { return gsl_sf_bessel_kl_scaled((int)round(l), x); } double nsl_sf_bessel_0_J0(double s) { return gsl_sf_bessel_zero_J0((unsigned int)round(s)); } double nsl_sf_bessel_0_J1(double s) { return gsl_sf_bessel_zero_J1((unsigned int)round(s)); } double nsl_sf_bessel_0_Jnu(double nu, double s) { return gsl_sf_bessel_zero_Jnu(nu, (unsigned int)round(s)); } double nsl_sf_hydrogenicR(double n, double l, double z, double r) { return gsl_sf_hydrogenicR((int)round(n), (int)round(l), z, r); } /* elliptic integrals */ double nsl_sf_ellint_Kc(double x) { return gsl_sf_ellint_Kcomp(x, MODE); } double nsl_sf_ellint_Ec(double x) { return gsl_sf_ellint_Ecomp(x, MODE); } double nsl_sf_ellint_Pc(double x, double n) { return gsl_sf_ellint_Pcomp(x, n, MODE); } double nsl_sf_ellint_F(double phi, double k) { return gsl_sf_ellint_F(phi, k, MODE); } double nsl_sf_ellint_E(double phi, double k) { return gsl_sf_ellint_E(phi, k, MODE); } double nsl_sf_ellint_P(double phi, double k, double n) { return gsl_sf_ellint_P(phi, k, n, MODE); } double nsl_sf_ellint_D(double phi, double k) { #if GSL_MAJOR_VERSION >= 2 return gsl_sf_ellint_D(phi,k,MODE); #else return gsl_sf_ellint_D(phi,k,0.0,MODE); #endif } double nsl_sf_ellint_RC(double x, double y) { return gsl_sf_ellint_RC(x, y, MODE); } double nsl_sf_ellint_RD(double x, double y, double z) { return gsl_sf_ellint_RD(x, y, z, MODE); } double nsl_sf_ellint_RF(double x, double y, double z) { return gsl_sf_ellint_RF(x, y, z, MODE); } double nsl_sf_ellint_RJ(double x, double y, double z, double p) { return gsl_sf_ellint_RJ(x, y, z, p, MODE); } double nsl_sf_exprel_n(double n, double x) { return gsl_sf_exprel_n((int)round(n), x); } double nsl_sf_fermi_dirac_int(double j, double x) { return gsl_sf_fermi_dirac_int((int)round(j), x); } /* Gamma */ double nsl_sf_fact(double n) { return gsl_sf_fact((unsigned int)round(n)); } double nsl_sf_doublefact(double n) { return gsl_sf_doublefact((unsigned int)round(n)); } double nsl_sf_lnfact(double n) { return gsl_sf_lnfact((unsigned int)round(n)); } double nsl_sf_lndoublefact(double n) { return gsl_sf_lndoublefact((unsigned int)round(n)); } double nsl_sf_choose(double n, double m) { return gsl_sf_choose((unsigned int)round(n), (unsigned int)round(m)); } double nsl_sf_lnchoose(double n, double m) { return gsl_sf_lnchoose((unsigned int)round(n), (unsigned int)round(m)); } double nsl_sf_taylorcoeff(double n, double x) { return gsl_sf_taylorcoeff((int)round(n), x); } double nsl_sf_gegenpoly_n(double n, double l, double x) { return gsl_sf_gegenpoly_n((int)round(n), l, x); } #if (GSL_MAJOR_VERSION > 2) || (GSL_MAJOR_VERSION == 2) && (GSL_MINOR_VERSION >= 4) double nsl_sf_hermite_prob(double n, double x) { return gsl_sf_hermite_prob(round(n), x); } double nsl_sf_hermite_phys(double n, double x) { return gsl_sf_hermite_phys(round(n), x); } double nsl_sf_hermite_func(double n, double x) { return gsl_sf_hermite_func(round(n), x); } double nsl_sf_hermite_prob_der(double m, double n, double x) { return gsl_sf_hermite_prob_der(round(m), round(n), x); } double nsl_sf_hermite_phys_der(double m, double n, double x) { return gsl_sf_hermite_phys_der(round(m), round(n), x); } double nsl_sf_hermite_func_der(double m, double n, double x) { return gsl_sf_hermite_func_der(round(m), round(n), x); } #endif double nsl_sf_hyperg_1F1i(double m, double n, double x) { return gsl_sf_hyperg_1F1_int((int)round(m), (int)round(n), x); } double nsl_sf_hyperg_Ui(double m, double n, double x) { return gsl_sf_hyperg_U_int((int)round(m), (int)round(n), x); } double nsl_sf_laguerre_n(double n, double a, double x) { return gsl_sf_laguerre_n((int)round(n), a, x); } double nsl_sf_legendre_Pl(double l, double x) { return gsl_sf_legendre_Pl((int)round(l), x); } double nsl_sf_legendre_Ql(double l, double x) { return gsl_sf_legendre_Ql((int)round(l), x); } double nsl_sf_legendre_Plm(double l, double m, double x) { return gsl_sf_legendre_Plm((int)round(l), (int)round(m), x); } double nsl_sf_legendre_sphPlm(double l, double m, double x) { return gsl_sf_legendre_sphPlm((int)round(l), (int)round(m), x); } double nsl_sf_conicalP_sphreg(double l, double L, double x) { return gsl_sf_conicalP_sph_reg((int)round(l), L, x); } double nsl_sf_conicalP_cylreg(double m, double l, double x) { return gsl_sf_conicalP_sph_reg((int)round(m), l, x); } double nsl_sf_legendre_H3d(double l, double L, double e) { return gsl_sf_legendre_H3d((int)round(l), L, e); } double nsl_sf_psiint(double n) { return gsl_sf_psi_int((int)round(n)); } double nsl_sf_psi1int(double n) { return gsl_sf_psi_1_int((int)round(n)); } double nsl_sf_psin(double n, double x) { return gsl_sf_psi_n((int)round(n), x); } double nsl_sf_zetaint(double n) { return gsl_sf_zeta_int((int)round(n)); } double nsl_sf_zetam1int(double n) { return gsl_sf_zetam1_int((int)round(n)); } double nsl_sf_etaint(double n) { return gsl_sf_eta_int((int)round(n)); } /* random number distributions */ double nsl_sf_poisson(double k, double m) { return gsl_ran_poisson_pdf((unsigned int)round(k), m); } double nsl_sf_bernoulli(double k, double p) { return gsl_ran_bernoulli_pdf((unsigned int)round(k), p); } double nsl_sf_binomial(double k, double p, double n) { return gsl_ran_binomial_pdf((unsigned int)round(k), p, (unsigned int)round(n)); } double nsl_sf_negative_binomial(double k, double p, double n) { return gsl_ran_negative_binomial_pdf((unsigned int)round(k), p, n); } double nsl_sf_pascal(double k, double p, double n) { return gsl_ran_pascal_pdf((unsigned int)round(k), p, (unsigned int)round(n)); } double nsl_sf_geometric(double k, double p) { return gsl_ran_geometric_pdf((unsigned int)round(k), p); } double nsl_sf_hypergeometric(double k, double n1, double n2, double t) { return gsl_ran_hypergeometric_pdf((unsigned int)round(k), (unsigned int)round(n1), (unsigned int)round(n2), (unsigned int)round(t)); } double nsl_sf_logarithmic(double k, double p) { return gsl_ran_logarithmic_pdf((unsigned int)round(k), p); } diff --git a/src/backend/nsl/nsl_sf_basic.h b/src/backend/nsl/nsl_sf_basic.h index 256b94898..31ed5e142 100644 --- a/src/backend/nsl/nsl_sf_basic.h +++ b/src/backend/nsl/nsl_sf_basic.h @@ -1,175 +1,176 @@ /*************************************************************************** File : nsl_sf_basic.h Project : LabPlot Description : NSL special basic functions -------------------------------------------------------------------- Copyright : (C) 2017-2018 by Stefan Gerlach (stefan.gerlach@uni.kn) ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the Free Software * * Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301 USA * * * ***************************************************************************/ #ifndef NSL_SF_BASIC_H #define NSL_SF_BASIC_H #include -#if !defined(_MSC_VER) -#include -#endif +#include "nsl_complex.h" /* random functions */ double nsl_sf_rand(void); double nsl_sf_random(void); double nsl_sf_drand(void); /* signum function */ double nsl_sf_sgn(double x); /* Heavyside theta function */ double nsl_sf_theta(double x); +/* log2(x) + 1 for integer value x */ +int nsl_sf_log2p1_int(int x); + /* more trig. functions */ double nsl_sf_sec(double x); double nsl_sf_csc(double x); double nsl_sf_cot(double x); double nsl_sf_asec(double x); double nsl_sf_acsc(double x); double nsl_sf_acot(double x); double nsl_sf_sech(double x); double nsl_sf_csch(double x); double nsl_sf_coth(double x); double nsl_sf_asech(double x); double nsl_sf_acsch(double x); double nsl_sf_acoth(double x); /* harmonic numbers (extended to non-integers) */ double nsl_sf_harmonic(double x); /* error function and related wrapper */ double nsl_sf_erfcx(double x); double nsl_sf_erfi(double x); double nsl_sf_im_w_of_x(double x); #if !defined(_MSC_VER) -double nsl_sf_im_w_of_z(complex double z); +double nsl_sf_im_w_of_z(COMPLEX z); #endif double nsl_sf_dawson(double x); double nsl_sf_voigt(double x, double sigma, double gamma); double nsl_sf_pseudovoigt(double x, double eta, double sigma, double gamma); /* same width pseudo Voigt*/ double nsl_sf_pseudovoigt1(double x, double eta, double w); /* wrapper for GSL functions with integer parameters */ /* mathematical functions */ double nsl_sf_ldexp(double x, double expo); double nsl_sf_powint(double x, double n); /* Airy functions */ double nsl_sf_airy_Ai(double x); double nsl_sf_airy_Bi(double x); double nsl_sf_airy_Ais(double x); double nsl_sf_airy_Bis(double x); double nsl_sf_airy_Aid(double x); double nsl_sf_airy_Bid(double x); double nsl_sf_airy_Aids(double x); double nsl_sf_airy_Bids(double x); double nsl_sf_airy_0_Ai(double s); double nsl_sf_airy_0_Bi(double s); double nsl_sf_airy_0_Aid(double s); double nsl_sf_airy_0_Bid(double s); /* Bessel functions */ double nsl_sf_bessel_Jn(double n, double x); double nsl_sf_bessel_Yn(double n, double x); double nsl_sf_bessel_In(double n, double x); double nsl_sf_bessel_Ins(double n, double x); double nsl_sf_bessel_Kn(double n, double x); double nsl_sf_bessel_Kns(double n, double x); double nsl_sf_bessel_jl(double l, double x); double nsl_sf_bessel_yl(double l, double x); double nsl_sf_bessel_ils(double l, double x); double nsl_sf_bessel_kls(double l, double x); double nsl_sf_bessel_0_J0(double s); double nsl_sf_bessel_0_J1(double s); double nsl_sf_bessel_0_Jnu(double nu, double s); double nsl_sf_hydrogenicR(double n, double l, double z, double r); /* elliptic integrals */ double nsl_sf_ellint_Kc(double x); double nsl_sf_ellint_Ec(double x); double nsl_sf_ellint_Pc(double x, double n); double nsl_sf_ellint_F(double phi, double k); double nsl_sf_ellint_E(double phi, double k); double nsl_sf_ellint_P(double phi, double k, double n); double nsl_sf_ellint_D(double phi, double k); double nsl_sf_ellint_RC(double x, double y); double nsl_sf_ellint_RD(double x, double y, double z); double nsl_sf_ellint_RF(double x, double y, double z); double nsl_sf_ellint_RJ(double x, double y, double z, double p); double nsl_sf_exprel_n(double n, double x); double nsl_sf_fermi_dirac_int(double j, double x); /* Gamma */ double nsl_sf_fact(double n); double nsl_sf_doublefact(double n); double nsl_sf_lnfact(double n); double nsl_sf_lndoublefact(double n); double nsl_sf_choose(double n, double m); double nsl_sf_lnchoose(double n, double m); double nsl_sf_taylorcoeff(double n, double x); double nsl_sf_gegenpoly_n(double n, double l, double x); #if (GSL_MAJOR_VERSION > 2) || (GSL_MAJOR_VERSION == 2) && (GSL_MINOR_VERSION >= 4) double nsl_sf_hermite_prob(double n, double x); double nsl_sf_hermite_phys(double n, double x); double nsl_sf_hermite_func(double n, double x); double nsl_sf_hermite_prob_der(double m, double n, double x); double nsl_sf_hermite_phys_der(double m, double n, double x); double nsl_sf_hermite_func_der(double m, double n, double x); #endif double nsl_sf_hyperg_1F1i(double m, double n, double x); double nsl_sf_hyperg_Ui(double m, double n, double x); double nsl_sf_laguerre_n(double n, double a, double x); double nsl_sf_legendre_Pl(double l, double x); double nsl_sf_legendre_Ql(double l, double x); double nsl_sf_legendre_Plm(double l, double m, double x); double nsl_sf_legendre_sphPlm(double l, double m, double x); double nsl_sf_conicalP_sphreg(double l, double L, double x); double nsl_sf_conicalP_cylreg(double m, double l, double x); double nsl_sf_legendre_H3d(double l, double L, double e); double nsl_sf_psiint(double n); double nsl_sf_psi1int(double n); double nsl_sf_psin(double n, double x); double nsl_sf_zetaint(double n); double nsl_sf_zetam1int(double n); double nsl_sf_etaint(double n); /* random number distributions */ double nsl_sf_poisson(double k, double m); double nsl_sf_bernoulli(double k, double p); double nsl_sf_binomial(double k, double p, double n); double nsl_sf_negative_binomial(double k, double p, double n); double nsl_sf_pascal(double k, double p, double n); double nsl_sf_geometric(double k, double p); double nsl_sf_hypergeometric(double k, double n1, double n2, double t); double nsl_sf_logarithmic(double k, double p); #endif /* NSL_SF_BASIC_H */ diff --git a/src/backend/nsl/nsl_sf_poly.h b/src/backend/nsl/nsl_sf_poly.h index 7fefc00a6..bfc84e8e0 100644 --- a/src/backend/nsl/nsl_sf_poly.h +++ b/src/backend/nsl/nsl_sf_poly.h @@ -1,94 +1,80 @@ /*************************************************************************** File : nsl_sf_poly.h Project : LabPlot Description : NSL special polynomial functions -------------------------------------------------------------------- Copyright : (C) 2016 by Stefan Gerlach (stefan.gerlach@uni.kn) ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the Free Software * * Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301 USA * * * ***************************************************************************/ #ifndef NSL_SF_POLY_H #define NSL_SF_POLY_H #include - -#ifdef _MSC_VER -#include -#define COMPLEX _Dcomplex -#else - -/* C++ including this header */ -#ifdef __cplusplus -#define COMPLEX double _Complex -#else /* C */ -#include -#define COMPLEX double complex -#endif - -#endif +#include "nsl_complex.h" /* Chebychev T_n(x) */ double nsl_sf_poly_chebyshev_T(int n, double x); /* Chebychev U_n(x) */ double nsl_sf_poly_chebyshev_U(int n, double x); /* Optimal "L"egendre Polynomials */ double nsl_sf_poly_optimal_legendre_L(int n, double x); /* Bessel polynomials y_n(x) */ COMPLEX nsl_sf_poly_bessel_y(int n, COMPLEX x); /* reversed Bessel polynomials \theta_n(x) */ COMPLEX nsl_sf_poly_reversed_bessel_theta(int n, COMPLEX x); /* interpolating polynomial (Lagrange) 0 - zeroth order (1-point) integral (rectangle rule) 1 - first order (2-point), derivative, integral and absolute area (trapezoid rule) 2 - second order (3-point), derivatives and integral (Simpson's 1/3 rule) 3 - third order (4-point), derivatives and integral (Simpson's 3/8 rule) 4 - fourth order (5-point) and derivatives 6 - sixth order (7-point) and derivatives TODO: barycentric form (https://en.wikipedia.org/wiki/Lagrange_polynomial) */ double nsl_sf_poly_interp_lagrange_0_int(double *x, double y); double nsl_sf_poly_interp_lagrange_1(double v, double *x, double *y); double nsl_sf_poly_interp_lagrange_1_deriv(double *x, double *y); double nsl_sf_poly_interp_lagrange_1_int(double *x, double *y); double nsl_sf_poly_interp_lagrange_1_absint(double *x, double *y); double nsl_sf_poly_interp_lagrange_2(double v, double *x, double *y); double nsl_sf_poly_interp_lagrange_2_deriv(double v, double *x, double *y); double nsl_sf_poly_interp_lagrange_2_deriv2(double *x, double *y); double nsl_sf_poly_interp_lagrange_2_int(double *x, double *y); double nsl_sf_poly_interp_lagrange_3(double v, double *x, double *y); double nsl_sf_poly_interp_lagrange_3_deriv(double v, double *x, double *y); double nsl_sf_poly_interp_lagrange_3_deriv2(double v, double *x, double *y); double nsl_sf_poly_interp_lagrange_3_deriv3(double *x, double *y); double nsl_sf_poly_interp_lagrange_3_int(double *x, double *y); double nsl_sf_poly_interp_lagrange_4(double v, double *x, double *y); double nsl_sf_poly_interp_lagrange_4_deriv(double v, double *x, double *y); double nsl_sf_poly_interp_lagrange_4_deriv2(double v, double *x, double *y); double nsl_sf_poly_interp_lagrange_4_deriv3(double v, double *x, double *y); double nsl_sf_poly_interp_lagrange_4_deriv4(double *x, double *y); double nsl_sf_poly_interp_lagrange_6_deriv4(double v, double *x, double *y); double nsl_sf_poly_interp_lagrange_6_deriv5(double v, double *x, double *y); double nsl_sf_poly_interp_lagrange_6_deriv6(double *x, double *y); #endif /* NSL_SF_POLY_H */ diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 339d2feb8..8bc6aeb4d 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,5 +1,6 @@ set(SRC_DIR ${labplot2_SOURCE_DIR}/src) INCLUDE_DIRECTORIES(${SRC_DIR}) add_subdirectory(analysis) add_subdirectory(import_export) +add_subdirectory(nsl) diff --git a/tests/nsl/CMakeLists.txt b/tests/nsl/CMakeLists.txt new file mode 100644 index 000000000..ef2e8a993 --- /dev/null +++ b/tests/nsl/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(sf_basic) diff --git a/tests/nsl/sf_basic/CMakeLists.txt b/tests/nsl/sf_basic/CMakeLists.txt new file mode 100644 index 000000000..106fbb362 --- /dev/null +++ b/tests/nsl/sf_basic/CMakeLists.txt @@ -0,0 +1,35 @@ +add_executable (nslsfbasictest NSLSFBasicTest.cpp) + +target_link_libraries(nslsfbasictest Qt5::Test) +target_link_libraries(nslsfbasictest KF5::Archive KF5::XmlGui ${GSL_LIBRARIES} ${GSL_CBLAS_LIBRARIES}) + +IF (Qt5SerialPort_FOUND) + target_link_libraries(nslsfbasictest Qt5::SerialPort ) +ENDIF () +IF (KF5SyntaxHighlighting_FOUND) + target_link_libraries(nslsfbasictest KF5::SyntaxHighlighting ) +ENDIF () +#TODO: KF5::NewStuff + +IF (CANTOR_LIBS_FOUND) + target_link_libraries(nslsfbasictest ${CANTOR_LIBS} ) +ENDIF () +IF (HDF5_FOUND) + target_link_libraries(nslsfbasictest ${HDF5_C_LIBRARIES} ) +ENDIF () +IF (FFTW_FOUND) + target_link_libraries(nslsfbasictest ${FFTW_LIBRARIES} ) +ENDIF () +IF (NETCDF_FOUND) + target_link_libraries(nslsfbasictest ${NETCDF_LIBRARY} ) +ENDIF () +IF (CFITSIO_FOUND) + target_link_libraries(nslsfbasictest ${CFITSIO_LIBRARY} ) +ENDIF () +IF (USE_LIBORIGIN) +target_link_libraries(nslsfbasictest liborigin-static ) +ENDIF () + +target_link_libraries(nslsfbasictest labplot2lib) + +add_test(NAME nslsfbasictest COMMAND nslsfbasictest) diff --git a/tests/nsl/sf_basic/NSLSFBasicTest.cpp b/tests/nsl/sf_basic/NSLSFBasicTest.cpp new file mode 100644 index 000000000..9ab1f3f2a --- /dev/null +++ b/tests/nsl/sf_basic/NSLSFBasicTest.cpp @@ -0,0 +1,53 @@ +/*************************************************************************** + File : NSLSFBasicTest.cpp + Project : LabPlot + Description : NSL Tests for basic special functions + -------------------------------------------------------------------- + Copyright : (C) 2019 Stefan Gerlach (stefan.gerlach@uni.kn) + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, * + * Boston, MA 02110-1301 USA * + * * + ***************************************************************************/ + +#include "NSLSFBasicTest.h" + +extern "C" { +#include "backend/nsl/nsl_sf_basic.h" +} + +void NSLSFBasicTest::initTestCase() { + const QString currentDir = __FILE__; + m_dataDir = currentDir.left(currentDir.lastIndexOf(QDir::separator())) + QDir::separator() + QLatin1String("data") + QDir::separator(); +} + +//############################################################################## +//################# handling of empty and sparse files ######################## +//############################################################################## +void NSLSFBasicTest::testlog2p1_int() { + + for (int i = 1; i < 1e6; i++) { + int result = nsl_sf_log2p1_int(i); + QCOMPARE(result, (int)log2(i) + 1); + } + + //TODO: Performance test + +} + +QTEST_MAIN(NSLSFBasicTest) diff --git a/tests/nsl/sf_basic/NSLSFBasicTest.h b/tests/nsl/sf_basic/NSLSFBasicTest.h new file mode 100644 index 000000000..fe94f208b --- /dev/null +++ b/tests/nsl/sf_basic/NSLSFBasicTest.h @@ -0,0 +1,43 @@ +/*************************************************************************** + File : NSLSFBasicTest.h + Project : LabPlot + Description : NSL Tests for the basic special functions + -------------------------------------------------------------------- + Copyright : (C) 2019 Stefan Gerlach (stefan.gerlach@uni.kn) + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, * + * Boston, MA 02110-1301 USA * + * * + ***************************************************************************/ +#ifndef NSLSFBASICTEST_H +#define NSLSFBASICTEST_H + +#include + +class NSLSFBasicTest : public QObject { + Q_OBJECT + +private slots: + void initTestCase(); + + //TODO + void testlog2p1_int(); +private: + QString m_dataDir; +}; +#endif