From kde-commits Wed May 31 21:15:25 2017 From: Stefan Gerlach Date: Wed, 31 May 2017 21:15:25 +0000 To: kde-commits Subject: [labplot] src: added fit model for hypergeometric distribution Message-Id: X-MARC-Message: https://marc.info/?l=kde-commits&m=149626533727596 Git commit 55b1da8ed789b925a5566c6bee19c5767cd3c152 by Stefan Gerlach. Committed on 31/05/2017 at 21:15. Pushed by sgerlach into branch 'master'. added fit model for hypergeometric distribution M +16 -0 src/backend/nsl/nsl_fit.c M +1 -0 src/backend/nsl/nsl_fit.h M +17 -1 src/backend/worksheet/plots/cartesian/XYFitCurve.cpp M +4 -2 src/kdefrontend/dockwidgets/XYFitCurveDock.cpp M +- -- src/pics/gsl_distributions/hypergeometric.jpg https://commits.kde.org/labplot/55b1da8ed789b925a5566c6bee19c5767cd3c152 diff --git a/src/backend/nsl/nsl_fit.c b/src/backend/nsl/nsl_fit.c index be69838e..2888f6fc 100644 --- a/src/backend/nsl/nsl_fit.c +++ b/src/backend/nsl/nsl_fit.c @@ -617,6 +617,22 @@ double nsl_fit_model_geometric_param_deriv(int param, = double k, double p, double = return 0; } +double nsl_fit_model_hypergeometric_param_deriv(int param, double k, doubl= e n1, double n2, double t, double A, double weight) { + if (t > n1 + n2) + return 0; + + double norm =3D weight * gsl_ran_hypergeometric_pdf(k, n1, n2, t); + if (param =3D=3D 0) + return A * norm * (gsl_sf_psi(n1+1.) - gsl_sf_psi(n1-k+1.) - gsl_sf_psi(= n1+n2+1.) + gsl_sf_psi(n1+n2-t+1.)); + if (param =3D=3D 1) + return A * norm * (gsl_sf_psi(n2+1.) - gsl_sf_psi(n2+k-t+1.) - gsl_sf_ps= i(n1+n2+1.) + gsl_sf_psi(n1+n2-t+1.)); + if (param =3D=3D 2) + return A * norm * (gsl_sf_psi(n2+k-t+1.) - gsl_sf_psi(n1+n2-t+1.) - gsl_= sf_psi(t-k+1.) + gsl_sf_psi(t+1.)); + if (param =3D=3D 3) + return norm; + + return 0; +} double nsl_fit_model_logarithmic_param_deriv(int param, double k, double p= , double A, double weight) { if (param =3D=3D 0) return A * weight * pow(1.-p, k-2.) * (1.-k*p); diff --git a/src/backend/nsl/nsl_fit.h b/src/backend/nsl/nsl_fit.h index 7b006cd1..78e52a64 100644 --- a/src/backend/nsl/nsl_fit.h +++ b/src/backend/nsl/nsl_fit.h @@ -118,6 +118,7 @@ double nsl_fit_model_binomial_param_deriv(int param, do= uble x, double p, double double nsl_fit_model_negative_binomial_param_deriv(int param, double k, do= uble p, double n, double A, double weight); double nsl_fit_model_pascal_param_deriv(int param, double k, double p, dou= ble n, double A, double weight); double nsl_fit_model_geometric_param_deriv(int param, double k, double p, = double A, double weight); +double nsl_fit_model_hypergeometric_param_deriv(int param, double k, doubl= e n1, double n2, double t, double A, double weight); double nsl_fit_model_logarithmic_param_deriv(int param, double k, double p= , double A, double weight); = double nsl_fit_model_maxwell_param_deriv(int param, double x, double a, do= uble c, double weight); diff --git a/src/backend/worksheet/plots/cartesian/XYFitCurve.cpp b/src/bac= kend/worksheet/plots/cartesian/XYFitCurve.cpp index 8283b699..96559535 100644 --- a/src/backend/worksheet/plots/cartesian/XYFitCurve.cpp +++ b/src/backend/worksheet/plots/cartesian/XYFitCurve.cpp @@ -888,12 +888,28 @@ int func_df(const gsl_vector* paramValues, void* para= ms, gsl_matrix* J) { } break; } + case nsl_sf_stats_hypergeometric: { + double n1 =3D nsl_fit_map_bound(gsl_vector_get(paramValues, 0), min[0],= max[0]); + double n2 =3D nsl_fit_map_bound(gsl_vector_get(paramValues, 1), min[1],= max[1]); + double t =3D nsl_fit_map_bound(gsl_vector_get(paramValues, 2), min[2], = max[2]); + double a =3D nsl_fit_map_bound(gsl_vector_get(paramValues, 3), min[3], = max[3]); + for (size_t i =3D 0; i < n; i++) { + x =3D xVector[i]; + + for (int j =3D 0; j < 4; j++) { + if (fixed[j]) + gsl_matrix_set(J, i, j, 0.); + else + gsl_matrix_set(J, i, j, nsl_fit_model_hypergeometric_param_deriv(j, = x, n1, n2, t, a, weight[i])); + } + } + break; + } // TODO: not implemented yet: case nsl_sf_stats_levy_alpha_stable: case nsl_sf_stats_levy_skew_alpha_stable: case nsl_sf_stats_fdist: case nsl_sf_stats_bernoulli: - case nsl_sf_stats_hypergeometric: break; } break; diff --git a/src/kdefrontend/dockwidgets/XYFitCurveDock.cpp b/src/kdefronte= nd/dockwidgets/XYFitCurveDock.cpp index f2d7a06f..aeed2280 100644 --- a/src/kdefrontend/dockwidgets/XYFitCurveDock.cpp +++ b/src/kdefrontend/dockwidgets/XYFitCurveDock.cpp @@ -416,7 +416,7 @@ void XYFitCurveDock::categoryChanged(int index) { for(int i =3D 1; i < NSL_SF_STATS_DISTRIBUTION_COUNT; i++) { //TODO: not implemented yet: if (i =3D=3D nsl_sf_stats_levy_alpha_stable || i =3D=3D nsl_sf_stats_le= vy_skew_alpha_stable || - i =3D=3D nsl_sf_stats_fdist || i =3D=3D nsl_sf_stats_bernoulli || i = =3D=3D nsl_sf_stats_hypergeometric) { + i =3D=3D nsl_sf_stats_fdist || i =3D=3D nsl_sf_stats_bernoulli) { QStandardItem* item =3D model->item(i); item->setFlags(item->flags() & ~(Qt::ItemIsSelectable|Qt::ItemIsEnabl= ed)); } @@ -855,7 +855,9 @@ void XYFitCurveDock::updateModelEquation() { m_fitData.paramNames << "p" << "a"; m_fitData.paramNamesUtf8 << "p" << "A"; break; - case nsl_sf_stats_hypergeometric: // TODO + case nsl_sf_stats_hypergeometric: + m_fitData.paramNames << "n1" << "n2" << "t" << "a"; + m_fitData.paramNamesUtf8 << "n" + QString::fromUtf8("\u2081") << "n" + = QString::fromUtf8("\u2082") << "t" << "A"; break; case nsl_sf_stats_maxwell_boltzmann: m_fitData.paramNames << "s" << "a"; diff --git a/src/pics/gsl_distributions/hypergeometric.jpg b/src/pics/gsl_d= istributions/hypergeometric.jpg index 7f24fab2..005161c9 100644 Binary files a/src/pics/gsl_distributions/hypergeometric.jpg and b/src/pics= /gsl_distributions/hypergeometric.jpg differ