goffice r2217 - in trunk: . goffice goffice/math pixmaps plugins/plot_boxes
- From: jbrefort svn gnome org
- To: svn-commits-list gnome org
- Subject: goffice r2217 - in trunk: . goffice goffice/math pixmaps plugins/plot_boxes
- Date: Fri, 12 Sep 2008 20:40:00 +0000 (UTC)
Author: jbrefort
Date: Fri Sep 12 20:40:00 2008
New Revision: 2217
URL: http://svn.gnome.org/viewvc/goffice?rev=2217&view=rev
Log:
2008-09-12 Jean Brefort <jean brefort normalesup org>
* goffice/goffice.c: (libgoffice_init): init distributions.
* goffice/math/Makefile.am: support distributions.
* goffice/math/go-R.c: ditto.
* goffice/math/go-R.h: ditto.
* goffice/math/go-distribution.c: ditto.
* goffice/math/go-distribution.h: ditto.
* goffice/math/go-rangefunc.c: renamed range_sort to go_range_sort
and make it public.
* goffice/math/go-rangefunc.h: ditto.
* pixmaps/Makefile.am: add new pixmaps.
* pixmaps/chart_prob_1_1.svg: implement probablility plots. [#500168]
* plugins/plot_boxes/Makefile.am: ditto (and renamed the plugin).
* plugins/plot_boxes/go-distribution-prefs.c: ditto.
* plugins/plot_boxes/go-distribution-prefs.h: ditto.
* plugins/plot_boxes/gog-boxplot.c: moved some code to plugin.c.
* plugins/plot_boxes/gog-probability-plot.c: implement probablility plots.
* plugins/plot_boxes/gog-probability-plot.h: ditto.
* plugins/plot_boxes/plot-types.xml.in: ditto.
* plugins/plot_boxes/plugin.xml.in: ditto.
Added:
trunk/goffice/math/go-R.c
trunk/goffice/math/go-R.h
trunk/goffice/math/go-distribution.c
trunk/goffice/math/go-distribution.h
trunk/pixmaps/chart_prob_1_1.png (contents, props changed)
trunk/pixmaps/chart_prob_1_1.svg
trunk/plugins/plot_boxes/go-distribution-prefs.c
trunk/plugins/plot_boxes/go-distribution-prefs.h
trunk/plugins/plot_boxes/gog-probability-plot.c
trunk/plugins/plot_boxes/gog-probability-plot.h
Modified:
trunk/ChangeLog
trunk/NEWS
trunk/goffice/goffice.c
trunk/goffice/math/Makefile.am
trunk/goffice/math/go-rangefunc.c
trunk/goffice/math/go-rangefunc.h
trunk/pixmaps/Makefile.am
trunk/plugins/plot_boxes/Makefile.am
trunk/plugins/plot_boxes/gog-boxplot.c
trunk/plugins/plot_boxes/plot-types.xml.in
trunk/plugins/plot_boxes/plugin.xml.in
Modified: trunk/NEWS
==============================================================================
--- trunk/NEWS (original)
+++ trunk/NEWS Fri Sep 12 20:40:00 2008
@@ -1,5 +1,8 @@
goffice 0.7.2:
+Jean:
+ * Implement probability plots for some common distributions. [#500168]
+
Morten:
* Fix go_url_resolve_relative. [#550898]
Modified: trunk/goffice/goffice.c
==============================================================================
--- trunk/goffice/goffice.c (original)
+++ trunk/goffice/goffice.c Fri Sep 12 20:40:00 2008
@@ -37,6 +37,7 @@
#include <goffice/graph/gog-series-lines.h>
#include <goffice/graph/gog-3d-box.h>
#include <goffice/data/go-data-simple.h>
+#include <goffice/math/go-distribution.h>
#include <goffice/math/go-math.h>
#include <goffice/utils/go-format.h>
#include <goffice/utils/go-font.h>
@@ -133,6 +134,7 @@
gog_themes_init ();
go_number_format_init ();
go_currency_date_format_init ();
+ go_distributions_init ();
initialized = TRUE;
}
Modified: trunk/goffice/math/Makefile.am
==============================================================================
--- trunk/goffice/math/Makefile.am (original)
+++ trunk/goffice/math/Makefile.am Fri Sep 12 20:40:00 2008
@@ -7,7 +7,9 @@
go-cspline.c \
go-complex.c \
go-fft.c \
- go-matrix3x3.c
+ go-matrix3x3.c \
+ go-R.c \
+ go-distribution.c
libgoffice_math_ladir = $(goffice_include_dir)/math
libgoffice_math_la_HEADERS = \
@@ -17,7 +19,9 @@
go-cspline.h \
go-complex.h \
go-fft.h \
- go-matrix3x3.h
+ go-matrix3x3.h \
+ go-R.h \
+ go-distribution.h
include $(top_srcdir)/goffice.mk
Added: trunk/goffice/math/go-R.c
==============================================================================
--- (empty file)
+++ trunk/goffice/math/go-R.c Fri Sep 12 20:40:00 2008
@@ -0,0 +1,1336 @@
+/* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * go-pnorm.h
+ *
+ * Copyright (C) 2008 Jean Brefort (jean brefort normalesup org)
+ *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301
+ * USA
+ */
+
+#include <goffice/goffice-config.h>
+#include "go-math.h"
+#include "go-R.h"
+
+#ifndef DOUBLE
+
+#define DOUBLE double
+#define SUFFIX(_n) _n
+#define GO_const(_c) _c
+#define GO_MIN DBL_MIN
+#define GO_EPSILON DBL_EPSILON
+#define GO_FORMAT_f "f"
+#define GO_FORMAT_g "g"
+
+#define M_LN_SQRT_2PI GO_const(0.918938533204672741780329736406) /* log(sqrt(2*pi)) */
+#define M_SQRT_32 GO_const(5.656854249492380195206754896838) /* sqrt(32) */
+#define M_1_SQRT_2PI GO_const(0.398942280401432677939946059934) /* 1/sqrt(2pi) */
+#define M_LN2goffice GO_const(0.693147180559945309417232121458176568075500134360255254120680009493393621969694715605863326996419)
+#define M_PIgoffice GO_const(3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117)
+#define ML_ERR_return_NAN { return go_nan; }
+
+/* ------------------------------------------------------------------------- */
+/* --- BEGIN MAGIC R HEADER 1 MARKER --- */
+
+/* The following source code was imported from the R project. */
+/* It was automatically transformed by tools/import-R. */
+
+/*
+ * R : A Computer Language for Statistical Data Analysis
+ * Copyright (C) 2000--2007 R Development Core Team
+ *
+ * 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, a copy is available at
+ * http://www.r-project.org/Licenses/
+ */
+ /* Utilities for `dpq' handling (density/probability/quantile) */
+
+/* give_log in "d"; log_p in "p" & "q" : */
+#define give_log log_p
+ /* "DEFAULT" */
+ /* --------- */
+#define R_D__0 (log_p ? SUFFIX (go_ninf) : 0.) /* 0 */
+#define R_D__1 (log_p ? 0. : 1.) /* 1 */
+#define R_DT_0 (lower_tail ? R_D__0 : R_D__1) /* 0 */
+#define R_DT_1 (lower_tail ? R_D__1 : R_D__0) /* 1 */
+
+/* Use 0.5 - p + 0.5 to perhaps gain 1 bit of accuracy */
+#define R_D_Lval(p) (lower_tail ? (p) : (0.5 - (p) + 0.5)) /* p */
+#define R_D_Cval(p) (lower_tail ? (0.5 - (p) + 0.5) : (p)) /* 1 - p */
+
+#define R_D_val(x) (log_p ? SUFFIX (log) (x) : (x)) /* x in pF(x,..) */
+#define R_D_qIv(p) (log_p ? SUFFIX (exp) (p) : (p)) /* p in qF(p,..) */
+#define R_D_exp(x) (log_p ? (x) : SUFFIX (exp) (x)) /* SUFFIX (exp) (x) */
+#define R_D_log(p) (log_p ? (p) : SUFFIX (log) (p)) /* SUFFIX (log) (p) */
+#define R_D_Clog(p) (log_p ? SUFFIX (log1p) (-(p)) : (0.5 - (p) + 0.5)) /* [log](1-p) */
+
+/* SUFFIX (log) (1 - SUFFIX (exp) (x)) in more stable form than SUFFIX (log1p) (- R_D_qIv(x))) : */
+#define swap_log_tail(x) ((x) > -M_LN2goffice ? SUFFIX (log) (-SUFFIX (expm1) (x)) : SUFFIX (log1p) (-SUFFIX (exp) (x)))
+
+/* SUFFIX (log) (1-SUFFIX (exp) (x)): R_D_LExp(x) == (SUFFIX (log1p) (- R_D_qIv(x))) but even more stable:*/
+#define R_D_LExp(x) (log_p ? swap_log_tail(x) : SUFFIX (log1p) (-x))
+
+#define R_DT_val(x) (lower_tail ? R_D_val(x) : R_D_Clog(x))
+#define R_DT_Cval(x) (lower_tail ? R_D_Clog(x) : R_D_val(x))
+
+/*#define R_DT_qIv(p) R_D_Lval(R_D_qIv(p)) * p in qF ! */
+#define R_DT_qIv(p) (log_p ? (lower_tail ? SUFFIX (exp) (p) : - SUFFIX (expm1) (p)) \
+ : R_D_Lval(p))
+
+/*#define R_DT_CIv(p) R_D_Cval(R_D_qIv(p)) * 1 - p in qF */
+#define R_DT_CIv(p) (log_p ? (lower_tail ? -SUFFIX (expm1) (p) : SUFFIX (exp) (p)) \
+ : R_D_Cval(p))
+
+#define R_DT_exp(x) R_D_exp(R_D_Lval(x)) /* SUFFIX (exp) (x) */
+#define R_DT_Cexp(x) R_D_exp(R_D_Cval(x)) /* SUFFIX (exp) (1 - x) */
+
+#define R_DT_log(p) (lower_tail? R_D_log(p) : R_D_LExp(p))/* SUFFIX (log) (p) in qF */
+#define R_DT_Clog(p) (lower_tail? R_D_LExp(p): R_D_log(p))/* SUFFIX (go_log1p) (-p) in qF*/
+#define R_DT_Log(p) (lower_tail? (p) : swap_log_tail(p))
+/* == R_DT_log when we already "know" log_p == TRUE :*/
+
+
+#define R_Q_P01_check(p) \
+ if ((log_p && p > 0) || \
+ (!log_p && (p < 0 || p > 1)) ) \
+ ML_ERR_return_NAN
+
+/* Do the boundaries exactly for q*() functions :
+ * Often _LEFT_ = SUFFIX (go_ninf) , and very often _RIGHT_ = SUFFIX (go_pinf);
+ *
+ * R_Q_P01_boundaries(p, _LEFT_, _RIGHT_) :<==>
+ *
+ * R_Q_P01_check(p);
+ * if (p == R_DT_0) return _LEFT_ ;
+ * if (p == R_DT_1) return _RIGHT_;
+ *
+ * the following implementation should be more efficient (less tests):
+ */
+#define R_Q_P01_boundaries(p, _LEFT_, _RIGHT_) \
+ if (log_p) { \
+ if(p > 0) \
+ ML_ERR_return_NAN; \
+ if(p == 0) /* upper bound*/ \
+ return lower_tail ? _RIGHT_ : _LEFT_; \
+ if(p == SUFFIX (go_ninf)) \
+ return lower_tail ? _LEFT_ : _RIGHT_; \
+ } \
+ else { /* !log_p */ \
+ if(p < 0 || p > 1) \
+ ML_ERR_return_NAN; \
+ if(p == 0) \
+ return lower_tail ? _LEFT_ : _RIGHT_; \
+ if(p == 1) \
+ return lower_tail ? _RIGHT_ : _LEFT_; \
+ }
+
+#define R_P_bounds_01(x, x_min, x_max) \
+ if(x <= x_min) return R_DT_0; \
+ if(x >= x_max) return R_DT_1
+/* is typically not quite optimal for (-Inf,Inf) where
+ * you'd rather have */
+#define R_P_bounds_Inf_01(x) \
+ if(!SUFFIX (go_finite)(x)) { \
+ if (x > 0) return R_DT_1; \
+ /* x < 0 */return R_DT_0; \
+ }
+
+
+
+/* additions for density functions (C.Loader) */
+#define R_D_fexp(f,x) (give_log ? -0.5*SUFFIX (log) (f)+(x) : SUFFIX (exp) (x)/SUFFIX (sqrt) (f))
+#define R_D_forceint(x) SUFFIX (floor) ((x) + 0.5)
+#define R_D_nonint(x) (SUFFIX (fabs) ((x) - SUFFIX (floor) ((x)+0.5)) > 1e-7)
+/* [neg]ative or [non int]eger : */
+#define R_D_negInonint(x) (x < 0. || R_D_nonint(x))
+
+#define R_D_nonint_check(x) \
+ if(R_D_nonint(x)) { \
+ MATHLIB_WARNING("non-integer x = %" GO_FORMAT_f "", x); \
+ return R_D__0; \
+ }
+/* --- END MAGIC R HEADER 1 MARKER --- */
+
+#ifdef GOFFICE_WITH_LONG_DOUBLE
+#include "go-R.c"
+#undef DOUBLE
+#undef SUFFIX
+#undef GO_const
+#undef GO_MIN
+#undef GO_EPSILON
+#undef GO_FORMAT_f
+#undef GO_FORMAT_g
+
+#undef M_LN_SQRT_2PI
+#undef M_SQRT_32
+#undef M_1_SQRT_2PI
+#undef ML_ERR_return_NAN
+
+#ifdef HAVE_SUNMATH_H
+#include <sunmath.h>
+#endif
+#define DOUBLE long double
+#define SUFFIX(_n) _n ## l
+#define GO_const(_c) _c ## L
+#define GO_MIN LDBL_MIN
+#define GO_EPSILON LDBL_EPSILON
+#define GO_FORMAT_f "Lf"
+#define GO_FORMAT_g "Lg"
+
+#define M_LN_SQRT_2PI GO_const(0.918938533204672741780329736406) /* log(sqrt(2*pi)) */
+#define M_SQRT_32 GO_const(5.656854249492380195206754896838) /* sqrt(32) */
+#define M_1_SQRT_2PI GO_const(0.398942280401432677939946059934) /* 1/sqrt(2pi) */
+#define ML_ERR_return_NAN { return go_nanl; }
+
+/* ------------------------------------------------------------------------- */
+/* --- BEGIN MAGIC R HEADER 2 MARKER --- */
+/* Cleaning up done by tools/import-R: */
+#undef R_DT_0
+#undef R_DT_1
+#undef R_DT_CIv
+#undef R_DT_Cexp
+#undef R_DT_Clog
+#undef R_DT_Cval
+#undef R_DT_Log
+#undef R_DT_exp
+#undef R_DT_log
+#undef R_DT_qIv
+#undef R_DT_val
+#undef R_D_Clog
+#undef R_D_Cval
+#undef R_D_LExp
+#undef R_D_Lval
+#undef R_D__0
+#undef R_D__1
+#undef R_D_exp
+#undef R_D_fexp
+#undef R_D_forceint
+#undef R_D_log
+#undef R_D_negInonint
+#undef R_D_nonint
+#undef R_D_nonint_check
+#undef R_D_qIv
+#undef R_D_val
+#undef R_Log1_Exp
+#undef R_P_bounds_01
+#undef R_P_bounds_Inf_01
+#undef R_Q_P01_boundaries
+#undef R_Q_P01_check
+#undef give_log
+
+/* The following source code was imported from the R project. */
+/* It was automatically transformed by tools/import-R. */
+
+/*
+ * R : A Computer Language for Statistical Data Analysis
+ * Copyright (C) 2000--2007 R Development Core Team
+ *
+ * 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, a copy is available at
+ * http://www.r-project.org/Licenses/
+ */
+ /* Utilities for `dpq' handling (density/probability/quantile) */
+
+/* give_log in "d"; log_p in "p" & "q" : */
+#define give_log log_p
+ /* "DEFAULT" */
+ /* --------- */
+#define R_D__0 (log_p ? SUFFIX (go_ninf) : 0.) /* 0 */
+#define R_D__1 (log_p ? 0. : 1.) /* 1 */
+#define R_DT_0 (lower_tail ? R_D__0 : R_D__1) /* 0 */
+#define R_DT_1 (lower_tail ? R_D__1 : R_D__0) /* 1 */
+
+/* Use 0.5 - p + 0.5 to perhaps gain 1 bit of accuracy */
+#define R_D_Lval(p) (lower_tail ? (p) : (0.5 - (p) + 0.5)) /* p */
+#define R_D_Cval(p) (lower_tail ? (0.5 - (p) + 0.5) : (p)) /* 1 - p */
+
+#define R_D_val(x) (log_p ? SUFFIX (log) (x) : (x)) /* x in pF(x,..) */
+#define R_D_qIv(p) (log_p ? SUFFIX (exp) (p) : (p)) /* p in qF(p,..) */
+#define R_D_exp(x) (log_p ? (x) : SUFFIX (exp) (x)) /* SUFFIX (exp) (x) */
+#define R_D_log(p) (log_p ? (p) : SUFFIX (log) (p)) /* SUFFIX (log) (p) */
+#define R_D_Clog(p) (log_p ? SUFFIX (log1p) (-(p)) : (0.5 - (p) + 0.5)) /* [log](1-p) */
+
+/* SUFFIX (log) (1 - SUFFIX (exp) (x)) in more stable form than SUFFIX (log1p) (- R_D_qIv(x))) : */
+#define swap_log_tail(x) ((x) > -M_LN2goffice ? SUFFIX (log) (-SUFFIX (expm1) (x)) : SUFFIX (log1p) (-SUFFIX (exp) (x)))
+
+/* SUFFIX (log) (1-SUFFIX (exp) (x)): R_D_LExp(x) == (SUFFIX (log1p) (- R_D_qIv(x))) but even more stable:*/
+#define R_D_LExp(x) (log_p ? swap_log_tail(x) : SUFFIX (log1p) (-x))
+
+#define R_DT_val(x) (lower_tail ? R_D_val(x) : R_D_Clog(x))
+#define R_DT_Cval(x) (lower_tail ? R_D_Clog(x) : R_D_val(x))
+
+/*#define R_DT_qIv(p) R_D_Lval(R_D_qIv(p)) * p in qF ! */
+#define R_DT_qIv(p) (log_p ? (lower_tail ? SUFFIX (exp) (p) : - SUFFIX (expm1) (p)) \
+ : R_D_Lval(p))
+
+/*#define R_DT_CIv(p) R_D_Cval(R_D_qIv(p)) * 1 - p in qF */
+#define R_DT_CIv(p) (log_p ? (lower_tail ? -SUFFIX (expm1) (p) : SUFFIX (exp) (p)) \
+ : R_D_Cval(p))
+
+#define R_DT_exp(x) R_D_exp(R_D_Lval(x)) /* SUFFIX (exp) (x) */
+#define R_DT_Cexp(x) R_D_exp(R_D_Cval(x)) /* SUFFIX (exp) (1 - x) */
+
+#define R_DT_log(p) (lower_tail? R_D_log(p) : R_D_LExp(p))/* SUFFIX (log) (p) in qF */
+#define R_DT_Clog(p) (lower_tail? R_D_LExp(p): R_D_log(p))/* SUFFIX (go_log1p) (-p) in qF*/
+#define R_DT_Log(p) (lower_tail? (p) : swap_log_tail(p))
+/* == R_DT_log when we already "know" log_p == TRUE :*/
+
+
+#define R_Q_P01_check(p) \
+ if ((log_p && p > 0) || \
+ (!log_p && (p < 0 || p > 1)) ) \
+ ML_ERR_return_NAN
+
+/* Do the boundaries exactly for q*() functions :
+ * Often _LEFT_ = SUFFIX (go_ninf) , and very often _RIGHT_ = SUFFIX (go_pinf);
+ *
+ * R_Q_P01_boundaries(p, _LEFT_, _RIGHT_) :<==>
+ *
+ * R_Q_P01_check(p);
+ * if (p == R_DT_0) return _LEFT_ ;
+ * if (p == R_DT_1) return _RIGHT_;
+ *
+ * the following implementation should be more efficient (less tests):
+ */
+#define R_Q_P01_boundaries(p, _LEFT_, _RIGHT_) \
+ if (log_p) { \
+ if(p > 0) \
+ ML_ERR_return_NAN; \
+ if(p == 0) /* upper bound*/ \
+ return lower_tail ? _RIGHT_ : _LEFT_; \
+ if(p == SUFFIX (go_ninf)) \
+ return lower_tail ? _LEFT_ : _RIGHT_; \
+ } \
+ else { /* !log_p */ \
+ if(p < 0 || p > 1) \
+ ML_ERR_return_NAN; \
+ if(p == 0) \
+ return lower_tail ? _LEFT_ : _RIGHT_; \
+ if(p == 1) \
+ return lower_tail ? _RIGHT_ : _LEFT_; \
+ }
+
+#define R_P_bounds_01(x, x_min, x_max) \
+ if(x <= x_min) return R_DT_0; \
+ if(x >= x_max) return R_DT_1
+/* is typically not quite optimal for (-Inf,Inf) where
+ * you'd rather have */
+#define R_P_bounds_Inf_01(x) \
+ if(!SUFFIX (go_finite)(x)) { \
+ if (x > 0) return R_DT_1; \
+ /* x < 0 */return R_DT_0; \
+ }
+
+
+
+/* additions for density functions (C.Loader) */
+#define R_D_fexp(f,x) (give_log ? -0.5*SUFFIX (log) (f)+(x) : SUFFIX (exp) (x)/SUFFIX (sqrt) (f))
+#define R_D_forceint(x) SUFFIX (floor) ((x) + 0.5)
+#define R_D_nonint(x) (SUFFIX (fabs) ((x) - SUFFIX (floor) ((x)+0.5)) > 1e-7)
+/* [neg]ative or [non int]eger : */
+#define R_D_negInonint(x) (x < 0. || R_D_nonint(x))
+
+#define R_D_nonint_check(x) \
+ if(R_D_nonint(x)) { \
+ MATHLIB_WARNING("non-integer x = %" GO_FORMAT_f "", x); \
+ return R_D__0; \
+ }
+/* --- END MAGIC R HEADER 2 MARKER --- */
+#endif /* GOFFICE_WITH_LONG_DOUBLE */
+
+#endif /* DOUBLE */
+
+/* ------------------------------------------------------------------------- */
+/* --- BEGIN MAGIC R SOURCE MARKER --- */
+
+/* The following source code was imported from the R project. */
+/* It was automatically transformed by tools/import-R. */
+
+/* Imported src/nmath/ftrunc.c from R. */
+/*
+ * Mathlib : A C Library of Special Functions
+ * Copyright (C) 1998 Ross Ihaka
+ *
+ * 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, a copy is available at
+ * http://www.r-project.org/Licenses/
+ *
+ * SYNOPSIS
+ *
+ * #include <Rmath.h>
+ * double ftrunc(double x);
+ *
+ * DESCRIPTION
+ *
+ * Truncation toward zero.
+ */
+
+
+DOUBLE SUFFIX (go_trunc) (DOUBLE x)
+{
+ if(x >= 0) return SUFFIX (floor) (x);
+ else return SUFFIX (ceil) (x);
+}
+
+/* ------------------------------------------------------------------------ */
+/* Imported src/nmath/dnorm.c from R. */
+/*
+ * Mathlib : A C Library of Special Functions
+ * Copyright (C) 1998 Ross Ihaka
+ * Copyright (C) 2000 The R Development Core Team
+ * Copyright (C) 2003 The R Foundation
+ *
+ * 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, a copy is available at
+ * http://www.r-project.org/Licenses/
+ *
+ * SYNOPSIS
+ *
+ * double dnorm4(double x, double mu, double sigma, int give_log)
+ * {dnorm (..) is synonymous and preferred inside R}
+ *
+ * DESCRIPTION
+ *
+ * Compute the density of the normal distribution.
+ */
+
+
+DOUBLE SUFFIX (go_dnorm) (DOUBLE x, DOUBLE mu, DOUBLE sigma, gboolean give_log)
+{
+#ifdef IEEE_754
+ if (SUFFIX (isnan) (x) || SUFFIX (isnan) (mu) || SUFFIX (isnan) (sigma))
+ return x + mu + sigma;
+#endif
+ if(!SUFFIX (go_finite)(sigma)) return R_D__0;
+ if(!SUFFIX (go_finite)(x) && mu == x) return SUFFIX (go_nan);/* x-mu is NaN */
+ if (sigma <= 0) {
+ if (sigma < 0) ML_ERR_return_NAN;
+ /* sigma == 0 */
+ return (x == mu) ? SUFFIX (go_pinf) : R_D__0;
+ }
+ x = (x - mu) / sigma;
+
+ if(!SUFFIX (go_finite)(x)) return R_D__0;
+ return (give_log ?
+ -(M_LN_SQRT_2PI + 0.5 * x * x + SUFFIX (log) (sigma)) :
+ M_1_SQRT_2PI * SUFFIX (exp) (-0.5 * x * x) / sigma);
+ /* M_1_SQRT_2PI = 1 / SUFFIX (sqrt) (2 * pi) */
+}
+
+/* ------------------------------------------------------------------------ */
+/* Imported src/nmath/pnorm.c from R. */
+/*
+ * Mathlib : A C Library of Special Functions
+ * Copyright (C) 1998 Ross Ihaka
+ * Copyright (C) 2000-2002 The R Development Core Team
+ * Copyright (C) 2003 The R Foundation
+ *
+ * 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, a copy is available at
+ * http://www.r-project.org/Licenses/
+ *
+ * SYNOPSIS
+ *
+ * #include <Rmath.h>
+ *
+ * double pnorm5(double x, double mu, double sigma, int lower_tail,int log_p);
+ * {pnorm (..) is synonymous and preferred inside R}
+ *
+ * void pnorm_both(double x, double *cum, double *ccum,
+ * int i_tail, int log_p);
+ *
+ * DESCRIPTION
+ *
+ * The main computation evaluates near-minimax approximations derived
+ * from those in "Rational Chebyshev approximations for the error
+ * function" by W. J. Cody, Math. Comp., 1969, 631-637. This
+ * transportable program uses rational functions that theoretically
+ * approximate the normal distribution function to at least 18
+ * significant decimal digits. The accuracy achieved depends on the
+ * arithmetic system, the compiler, the intrinsic functions, and
+ * proper selection of the machine-dependent constants.
+ *
+ * REFERENCE
+ *
+ * Cody, W. D. (1993).
+ * ALGORITHM 715: SPECFUN - A Portable FORTRAN Package of
+ * Special Function Routines and Test Drivers".
+ * ACM Transactions on Mathematical Software. 19, 22-32.
+ *
+ * EXTENSIONS
+ *
+ * The "_both" , lower, upper, and log_p variants were added by
+ * Martin Maechler, Jan.2000;
+ * as well as log1p() and similar improvements later on.
+ *
+ * James M. Rath contributed bug report PR#699 and patches correcting SIXTEN
+ * and if() clauses {with a bug: "|| instead of &&" -> PR #2883) more in line
+ * with the original Cody code.
+ */
+
+DOUBLE SUFFIX (go_pnorm) (DOUBLE x, DOUBLE mu, DOUBLE sigma, gboolean lower_tail, gboolean log_p)
+{
+ DOUBLE p, cp;
+
+ /* Note: The structure of these checks has been carefully thought through.
+ * For example, if x == mu and sigma == 0, we get the correct answer 1.
+ */
+#ifdef IEEE_754
+ if(SUFFIX (isnan) (x) || SUFFIX (isnan) (mu) || SUFFIX (isnan) (sigma))
+ return x + mu + sigma;
+#endif
+ if(!SUFFIX (go_finite)(x) && mu == x) return SUFFIX (go_nan);/* x-mu is NaN */
+ if (sigma <= 0) {
+ if(sigma < 0) ML_ERR_return_NAN;
+ /* sigma = 0 : */
+ return (x < mu) ? R_DT_0 : R_DT_1;
+ }
+ p = (x - mu) / sigma;
+ if(!SUFFIX (go_finite)(p))
+ return (x < mu) ? R_DT_0 : R_DT_1;
+ x = p;
+
+ SUFFIX (go_pnorm_both) (x, &p, &cp, (lower_tail ? 0 : 1), log_p);
+
+ return(lower_tail ? p : cp);
+}
+
+#define SIXTEN 16 /* Cutoff allowing exact "*" and "/" */
+
+void SUFFIX (go_pnorm_both) (DOUBLE x, DOUBLE *cum, DOUBLE *ccum, int i_tail, gboolean log_p)
+{
+/* i_tail in {0,1,2} means: "lower", "upper", or "both" :
+ if(lower) return *cum := P[X <= x]
+ if(upper) return *ccum := P[X > x] = 1 - P[X <= x]
+*/
+ const static DOUBLE a[5] = {
+ GO_const (2.2352520354606839287),
+ GO_const (161.02823106855587881),
+ GO_const (1067.6894854603709582),
+ GO_const (18154.981253343561249),
+ GO_const (0.065682337918207449113)
+ };
+ const static DOUBLE b[4] = {
+ GO_const (47.20258190468824187),
+ GO_const (976.09855173777669322),
+ GO_const (10260.932208618978205),
+ GO_const (45507.789335026729956)
+ };
+ const static DOUBLE c[9] = {
+ GO_const (0.39894151208813466764),
+ GO_const (8.8831497943883759412),
+ GO_const (93.506656132177855979),
+ GO_const (597.27027639480026226),
+ GO_const (2494.5375852903726711),
+ GO_const (6848.1904505362823326),
+ GO_const (11602.651437647350124),
+ GO_const (9842.7148383839780218),
+ GO_const (1.0765576773720192317e-8)
+ };
+ const static DOUBLE d[8] = {
+ GO_const (22.266688044328115691),
+ GO_const (235.38790178262499861),
+ GO_const (1519.377599407554805),
+ GO_const (6485.558298266760755),
+ GO_const (18615.571640885098091),
+ GO_const (34900.952721145977266),
+ GO_const (38912.003286093271411),
+ GO_const (19685.429676859990727)
+ };
+ const static DOUBLE p[6] = {
+ GO_const (0.21589853405795699),
+ GO_const (0.1274011611602473639),
+ GO_const (0.022235277870649807),
+ GO_const (0.001421619193227893466),
+ GO_const (2.9112874951168792e-5),
+ GO_const (0.02307344176494017303)
+ };
+ const static DOUBLE q[5] = {
+ GO_const (1.28426009614491121),
+ GO_const (0.468238212480865118),
+ GO_const (0.0659881378689285515),
+ GO_const (0.00378239633202758244),
+ GO_const (7.29751555083966205e-5)
+ };
+
+ DOUBLE xden, xnum, temp, del, eps, xsq, y;
+#ifdef NO_DENORMS
+ DOUBLE min = GO_MIN;
+#endif
+ int i, lower, upper;
+
+#ifdef IEEE_754
+ if(SUFFIX (isnan) (x)) { *cum = *ccum = x; return; }
+#endif
+
+ /* Consider changing these : */
+ eps = GO_EPSILON * 0.5;
+
+ /* i_tail in {0,1,2} =^= {lower, upper, both} */
+ lower = i_tail != 1;
+ upper = i_tail != 0;
+
+ y = SUFFIX (fabs) (x);
+ if (y <= GO_const (0.67448975)) { /* SUFFIX (go_qnorm) (3/4) = .6744.... -- earlier had GO_const (0.66291) */
+ if (y > eps) {
+ xsq = x * x;
+ xnum = a[4] * xsq;
+ xden = xsq;
+ for (i = 0; i < 3; ++i) {
+ xnum = (xnum + a[i]) * xsq;
+ xden = (xden + b[i]) * xsq;
+ }
+ } else xnum = xden = 0.0;
+
+ temp = x * (xnum + a[3]) / (xden + b[3]);
+ if(lower) *cum = 0.5 + temp;
+ if(upper) *ccum = 0.5 - temp;
+ if(log_p) {
+ if(lower) *cum = SUFFIX (log) (*cum);
+ if(upper) *ccum = SUFFIX (log) (*ccum);
+ }
+ }
+ else if (y <= M_SQRT_32) {
+
+ /* Evaluate SUFFIX (go_pnorm) for 0.674.. = SUFFIX (go_qnorm) (3/4) < |x| <= SUFFIX (sqrt) (32) ~= 5.657 */
+
+ xnum = c[8] * y;
+ xden = y;
+ for (i = 0; i < 7; ++i) {
+ xnum = (xnum + c[i]) * y;
+ xden = (xden + d[i]) * y;
+ }
+ temp = (xnum + c[7]) / (xden + d[7]);
+
+#define do_del(X) \
+ xsq = SUFFIX (go_trunc) (X * SIXTEN) / SIXTEN; \
+ del = (X - xsq) * (X + xsq); \
+ if(log_p) { \
+ *cum = (-xsq * xsq * 0.5) + (-del * 0.5) + SUFFIX (log) (temp); \
+ if((lower && x > 0.) || (upper && x <= 0.)) \
+ *ccum = SUFFIX (log1p) (-SUFFIX (exp) (-xsq * xsq * 0.5) * \
+ SUFFIX (exp) (-del * 0.5) * temp); \
+ } \
+ else { \
+ *cum = SUFFIX (exp) (-xsq * xsq * 0.5) * SUFFIX (exp) (-del * 0.5) * temp; \
+ *ccum = 1.0 - *cum; \
+ }
+
+#define swap_tail \
+ if (x > 0.) {/* swap ccum <--> cum */ \
+ temp = *cum; if(lower) *cum = *ccum; *ccum = temp; \
+ }
+
+ do_del(y);
+ swap_tail;
+ }
+
+/* else |x| > SUFFIX (sqrt) (32) = 5.657 :
+ * the next two case differentiations were really for lower=T, log=F
+ * Particularly *not* for log_p !
+
+ * Cody had (-37.5193 < x && x < 8.2924) ; R originally had y < 50
+ *
+ * Note that we do want symmetry(0), lower/upper -> hence use y
+ */
+ else if(log_p
+ /* ^^^^^ MM FIXME: can speedup for log_p and much larger |x| !
+ * Then, make use of Abramowitz & Stegun, 26.2.13, something like
+
+ xsq = x*x;
+
+ if(xsq * GO_EPSILON < 1.)
+ del = (1. - (1. - 5./(xsq+6.)) / (xsq+4.)) / (xsq+2.);
+ else
+ del = 0.;
+ *cum = -.5*xsq - M_LN_SQRT_2PI - SUFFIX (log) (x) + SUFFIX (log1p) (-del);
+ *ccum = SUFFIX (log1p) (-SUFFIX (exp) (*cum)); /.* ~ SUFFIX (log) (1) = 0 *./
+
+ swap_tail;
+
+ */
+ || (lower && -37.5193 < x && x < 8.2924)
+ || (upper && -8.2924 < x && x < 37.5193)
+ ) {
+
+ /* Evaluate SUFFIX (go_pnorm) for x in (-37.5, -5.657) union (5.657, 37.5) */
+ xsq = 1.0 / (x * x);
+ xnum = p[5] * xsq;
+ xden = xsq;
+ for (i = 0; i < 4; ++i) {
+ xnum = (xnum + p[i]) * xsq;
+ xden = (xden + q[i]) * xsq;
+ }
+ temp = xsq * (xnum + p[4]) / (xden + q[4]);
+ temp = (M_1_SQRT_2PI - temp) / y;
+
+ do_del(x);
+ swap_tail;
+ }
+ else { /* no log_p , large x such that probs are 0 or 1 */
+ if(x > 0) { *cum = 1.; *ccum = 0.; }
+ else { *cum = 0.; *ccum = 1.; }
+ }
+
+
+#ifdef NO_DENORMS
+ /* do not return "denormalized" -- we do in R */
+ if(log_p) {
+ if(*cum > -min) *cum = -0.;
+ if(*ccum > -min)*ccum = -0.;
+ }
+ else {
+ if(*cum < min) *cum = 0.;
+ if(*ccum < min) *ccum = 0.;
+ }
+#endif
+ return;
+}
+/* Cleaning up done by tools/import-R: */
+#undef SIXTEN
+#undef do_del
+#undef swap_tail
+
+/* ------------------------------------------------------------------------ */
+/* Imported src/nmath/qnorm.c from R. */
+/*
+ * Mathlib : A C Library of Special Functions
+ * Copyright (C) 1998 Ross Ihaka
+ * Copyright (C) 2000--2005 The R Development Core Team
+ * based on AS 111 (C) 1977 Royal Statistical Society
+ * and on AS 241 (C) 1988 Royal Statistical Society
+ *
+ * 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, a copy is available at
+ * http://www.r-project.org/Licenses/
+ *
+ * SYNOPSIS
+ *
+ * double qnorm5(double p, double mu, double sigma,
+ * int lower_tail, int log_p)
+ * {qnorm (..) is synonymous and preferred inside R}
+ *
+ * DESCRIPTION
+ *
+ * Compute the quantile function for the normal distribution.
+ *
+ * For small to moderate probabilities, algorithm referenced
+ * below is used to obtain an initial approximation which is
+ * polished with a final Newton step.
+ *
+ * For very large arguments, an algorithm of Wichura is used.
+ *
+ * REFERENCE
+ *
+ * Beasley, J. D. and S. G. Springer (1977).
+ * Algorithm AS 111: The percentage points of the normal distribution,
+ * Applied Statistics, 26, 118-121.
+ *
+ * Wichura, M.J. (1988).
+ * Algorithm AS 241: The Percentage Points of the Normal Distribution.
+ * Applied Statistics, 37, 477-484.
+ */
+
+
+DOUBLE SUFFIX (go_qnorm) (DOUBLE p, DOUBLE mu, DOUBLE sigma, gboolean lower_tail, gboolean log_p)
+{
+ DOUBLE p_, q, r, val;
+
+#ifdef IEEE_754
+ if (SUFFIX (isnan) (p) || SUFFIX (isnan) (mu) || SUFFIX (isnan) (sigma))
+ return p + mu + sigma;
+#endif
+ R_Q_P01_boundaries(p, SUFFIX (go_ninf), SUFFIX (go_pinf));
+
+ if(sigma < 0) ML_ERR_return_NAN;
+ if(sigma == 0) return mu;
+
+ p_ = R_DT_qIv(p);/* real lower_tail prob. p */
+ q = p_ - 0.5;
+
+#ifdef DEBUG_qnorm
+ REprintf("SUFFIX (go_qnorm) (p=%10.7" GO_FORMAT_g ", m=%" GO_FORMAT_g ", s=%" GO_FORMAT_g ", l.t.= %d, log= %d): q = %" GO_FORMAT_g "\n",
+ p,mu,sigma, lower_tail, log_p, q);
+#endif
+
+
+/*-- use AS 241 --- */
+/* DOUBLE ppnd16_(DOUBLE *p, long *ifault)*/
+/* ALGORITHM AS241 APPL. STATIST. (1988) VOL. 37, NO. 3
+
+ Produces the normal deviate Z corresponding to a given lower
+ tail area of P; Z is accurate to about 1 part in 10**16.
+
+ (original fortran code used PARAMETER(..) for the coefficients
+ and provided hash codes for checking them...)
+*/
+ if (SUFFIX (fabs) (q) <= .425) {/* 0.075 <= p <= 0.925 */
+ r = GO_const (.180625) - q * q;
+ val =
+ q * (((((((r * GO_const (2509.0809287301226727) +
+ GO_const (33430.575583588128105)) * r + GO_const (67265.770927008700853)) * r +
+ GO_const (45921.953931549871457)) * r + GO_const (13731.693765509461125)) * r +
+ GO_const (1971.5909503065514427)) * r + GO_const (133.14166789178437745)) * r +
+ GO_const (3.387132872796366608))
+ / (((((((r * GO_const (5226.495278852854561) +
+ GO_const (28729.085735721942674)) * r + GO_const (39307.89580009271061)) * r +
+ GO_const (21213.794301586595867)) * r + GO_const (5394.1960214247511077)) * r +
+ GO_const (687.1870074920579083)) * r + GO_const (42.313330701600911252)) * r + 1.);
+ }
+ else { /* closer than 0.075 from {0,1} boundary */
+
+ /* r = min(p, 1-p) < 0.075 */
+ if (q > 0)
+ r = R_DT_CIv(p);/* 1-p */
+ else
+ r = p_;/* = R_DT_Iv(p) ^= p */
+
+ r = SUFFIX (sqrt) (- ((log_p &&
+ ((lower_tail && q <= 0) || (!lower_tail && q > 0))) ?
+ p : /* else */ SUFFIX (log) (r)));
+ /* r = SUFFIX (sqrt) (-SUFFIX (log) (r)) <==> min(p, 1-p) = SUFFIX (exp) ( - r^2 ) */
+#ifdef DEBUG_qnorm
+ REprintf("\t close to 0 or 1: r = %7" GO_FORMAT_g "\n", r);
+#endif
+
+ if (r <= 5.) { /* <==> min(p,1-p) >= SUFFIX (exp) (-25) ~= 1.3888e-11 */
+ r += -1.6;
+ val = (((((((r * GO_const (7.7454501427834140764e-4) +
+ GO_const (.0227238449892691845833)) * r + GO_const (.24178072517745061177)) *
+ r + GO_const (1.27045825245236838258)) * r +
+ GO_const (3.64784832476320460504)) * r + GO_const (5.7694972214606914055)) *
+ r + GO_const (4.6303378461565452959)) * r +
+ GO_const (1.42343711074968357734))
+ / (((((((r *
+ GO_const (1.05075007164441684324e-9) + GO_const (5.475938084995344946e-4)) *
+ r + GO_const (.0151986665636164571966)) * r +
+ GO_const (.14810397642748007459)) * r + GO_const (.68976733498510000455)) *
+ r + GO_const (1.6763848301838038494)) * r +
+ GO_const (2.05319162663775882187)) * r + 1.);
+ }
+ else { /* very close to 0 or 1 */
+ r += -5.;
+ val = (((((((r * GO_const (2.01033439929228813265e-7) +
+ GO_const (2.71155556874348757815e-5)) * r +
+ GO_const (.0012426609473880784386)) * r + GO_const (.026532189526576123093)) *
+ r + GO_const (.29656057182850489123)) * r +
+ GO_const (1.7848265399172913358)) * r + GO_const (5.4637849111641143699)) *
+ r + GO_const (6.6579046435011037772))
+ / (((((((r *
+ GO_const (2.04426310338993978564e-15) + GO_const (1.4215117583164458887e-7))*
+ r + GO_const (1.8463183175100546818e-5)) * r +
+ GO_const (7.868691311456132591e-4)) * r + GO_const (.0148753612908506148525))
+ * r + GO_const (.13692988092273580531)) * r +
+ GO_const (.59983220655588793769)) * r + 1.);
+ }
+
+ if(q < 0.0)
+ val = -val;
+ /* return (q >= 0.)? r : -r ;*/
+ }
+ return mu + sigma * val;
+}
+
+
+
+
+/* ------------------------------------------------------------------------ */
+/* Imported src/nmath/dlnorm.c from R. */
+/*
+ * Mathlib : A C Library of Special Functions
+ * Copyright (C) 1998 Ross Ihaka
+ * Copyright (C) 2000-8 The R Development Core Team
+ *
+ * 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, a copy is available at
+ * http://www.r-project.org/Licenses/
+ *
+ * DESCRIPTION
+ *
+ * The density of the lognormal distribution.
+ */
+
+
+DOUBLE SUFFIX (go_dlnorm) (DOUBLE x, DOUBLE meanlog, DOUBLE sdlog, gboolean give_log)
+{
+ DOUBLE y;
+
+#ifdef IEEE_754
+ if (SUFFIX (isnan) (x) || SUFFIX (isnan) (meanlog) || SUFFIX (isnan) (sdlog))
+ return x + meanlog + sdlog;
+#endif
+ if(sdlog <= 0) ML_ERR_return_NAN;
+
+ if(x <= 0) return R_D__0;
+
+ y = (SUFFIX (log) (x) - meanlog) / sdlog;
+ return (give_log ?
+ -(M_LN_SQRT_2PI + 0.5 * y * y + SUFFIX (log) (x * sdlog)) :
+ M_1_SQRT_2PI * SUFFIX (exp) (-0.5 * y * y) / (x * sdlog));
+ /* M_1_SQRT_2PI = 1 / SUFFIX (sqrt) (2 * pi) */
+
+}
+
+/* ------------------------------------------------------------------------ */
+/* Imported src/nmath/plnorm.c from R. */
+/*
+ * Mathlib : A C Library of Special Functions
+ * Copyright (C) 1998 Ross Ihaka
+ * Copyright (C) 2000-8 The R Development Core Team
+ *
+ * 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, a copy is available at
+ * http://www.r-project.org/Licenses/
+ *
+ * DESCRIPTION
+ *
+ * The lognormal distribution function.
+ */
+
+
+DOUBLE SUFFIX (go_plnorm) (DOUBLE x, DOUBLE meanlog, DOUBLE sdlog, gboolean lower_tail, gboolean log_p)
+{
+#ifdef IEEE_754
+ if (SUFFIX (isnan) (x) || SUFFIX (isnan) (meanlog) || SUFFIX (isnan) (sdlog))
+ return x + meanlog + sdlog;
+#endif
+ if (sdlog <= 0) ML_ERR_return_NAN;
+
+ if (x > 0)
+ return SUFFIX (go_pnorm) (SUFFIX (log) (x), meanlog, sdlog, lower_tail, log_p);
+ return lower_tail ? 0 : 1;
+}
+
+/* ------------------------------------------------------------------------ */
+/* Imported src/nmath/qlnorm.c from R. */
+/*
+ * Mathlib : A C Library of Special Functions
+ * Copyright (C) 1998 Ross Ihaka
+ * Copyright (C) 2000-8 The R Development Core Team
+ * Copyright (C) 2005 The R Foundation
+ *
+ * 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, a copy is available at
+ * http://www.r-project.org/Licenses/
+ *
+ * DESCRIPTION
+ *
+ * This the lognormal quantile function.
+ */
+
+
+DOUBLE SUFFIX (go_qlnorm) (DOUBLE p, DOUBLE meanlog, DOUBLE sdlog, gboolean lower_tail, gboolean log_p)
+{
+#ifdef IEEE_754
+ if (SUFFIX (isnan) (p) || SUFFIX (isnan) (meanlog) || SUFFIX (isnan) (sdlog))
+ return p + meanlog + sdlog;
+#endif
+ R_Q_P01_boundaries(p, 0, SUFFIX (go_pinf));
+
+ return SUFFIX (exp) (SUFFIX (go_qnorm) (p, meanlog, sdlog, lower_tail, log_p));
+}
+
+/* ------------------------------------------------------------------------ */
+/* Imported src/nmath/dweibull.c from R. */
+/*
+ * Mathlib : A C Library of Special Functions
+ * Copyright (C) 1998 Ross Ihaka
+ * Copyright (C) 2000-6 The R Development Core Team
+ *
+ * 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, a copy is available at
+ * http://www.r-project.org/Licenses/
+ *
+ * DESCRIPTION
+ *
+ * The density function of the Weibull distribution.
+ */
+
+
+DOUBLE SUFFIX (go_dweibull) (DOUBLE x, DOUBLE shape, DOUBLE scale, gboolean give_log)
+{
+ DOUBLE tmp1, tmp2;
+#ifdef IEEE_754
+ if (SUFFIX (isnan) (x) || SUFFIX (isnan) (shape) || SUFFIX (isnan) (scale))
+ return x + shape + scale;
+#endif
+ if (shape <= 0 || scale <= 0) ML_ERR_return_NAN;
+
+ if (x < 0) return R_D__0;
+ if (!SUFFIX (go_finite)(x)) return R_D__0;
+ /* need to handle x == 0 separately */
+ if(x == 0 && shape < 1) return SUFFIX (go_pinf);
+ tmp1 = SUFFIX (pow) (x / scale, shape - 1);
+ tmp2 = tmp1 * (x / scale);
+ /* These are incorrect if tmp1 == 0 */
+ return give_log ?
+ -tmp2 + SUFFIX (log) (shape * tmp1 / scale) :
+ shape * tmp1 * SUFFIX (exp) (-tmp2) / scale;
+}
+
+/* ------------------------------------------------------------------------ */
+/* Imported src/nmath/pweibull.c from R. */
+/*
+ * Mathlib : A C Library of Special Functions
+ * Copyright (C) 1998 Ross Ihaka
+ * Copyright (C) 2000-2002 The R Development Core Team
+ *
+ * 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, a copy is available at
+ * http://www.r-project.org/Licenses/
+ *
+ * DESCRIPTION
+ *
+ * The distribution function of the Weibull distribution.
+ */
+
+
+DOUBLE SUFFIX (go_pweibull) (DOUBLE x, DOUBLE shape, DOUBLE scale, gboolean lower_tail, gboolean log_p)
+{
+#ifdef IEEE_754
+ if (SUFFIX (isnan) (x) || SUFFIX (isnan) (shape) || SUFFIX (isnan) (scale))
+ return x + shape + scale;
+#endif
+ if(shape <= 0 || scale <= 0) ML_ERR_return_NAN;
+
+ if (x <= 0)
+ return R_DT_0;
+ x = -SUFFIX (pow) (x / scale, shape);
+ if (lower_tail)
+ return (log_p
+ /* SUFFIX (log) (1 - SUFFIX (exp) (x)) for x < 0 : */
+ ? (x > -M_LN2goffice ? SUFFIX (log) (-SUFFIX (expm1) (x)) : SUFFIX (log1p) (-SUFFIX (exp) (x)))
+ : -SUFFIX (expm1) (x));
+ /* else: !lower_tail */
+ return R_D_exp(x);
+}
+
+/* ------------------------------------------------------------------------ */
+/* Imported src/nmath/qweibull.c from R. */
+/*
+ * Mathlib : A C Library of Special Functions
+ * Copyright (C) 1998 Ross Ihaka
+ * Copyright (C) 2000 The R Development Core Team
+ * Copyright (C) 2005 The R Foundation
+ *
+ * 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, a copy is available at
+ * http://www.r-project.org/Licenses/
+ *
+ * DESCRIPTION
+ *
+ * The quantile function of the Weibull distribution.
+ */
+
+
+DOUBLE SUFFIX (go_qweibull) (DOUBLE p, DOUBLE shape, DOUBLE scale, gboolean lower_tail, gboolean log_p)
+{
+#ifdef IEEE_754
+ if (SUFFIX (isnan) (p) || SUFFIX (isnan) (shape) || SUFFIX (isnan) (scale))
+ return p + shape + scale;
+#endif
+ if (shape <= 0 || scale <= 0) ML_ERR_return_NAN;
+
+ R_Q_P01_boundaries(p, 0, SUFFIX (go_pinf));
+
+ return scale * SUFFIX (pow) (- R_DT_Clog(p), 1./shape) ;
+}
+
+/* ------------------------------------------------------------------------ */
+/* Imported src/nmath/dcauchy.c from R. */
+/*
+ * Mathlib : A C Library of Special Functions
+ * Copyright (C) 1998 Ross Ihaka
+ * Copyright (C) 2000 The R Development Core Team
+ *
+ * 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, a copy is available at
+ * http://www.r-project.org/Licenses/
+ *
+ * DESCRIPTION
+ *
+ * The density of the Cauchy distribution.
+ */
+
+
+DOUBLE SUFFIX (go_dcauchy) (DOUBLE x, DOUBLE location, DOUBLE scale, gboolean give_log)
+{
+ DOUBLE y;
+#ifdef IEEE_754
+ /* NaNs propagated correctly */
+ if (SUFFIX (isnan) (x) || SUFFIX (isnan) (location) || SUFFIX (isnan) (scale))
+ return x + location + scale;
+#endif
+ if (scale <= 0) ML_ERR_return_NAN;
+
+ y = (x - location) / scale;
+ return give_log ?
+ - SUFFIX (log) (M_PIgoffice * scale * (1. + y * y)) :
+ 1. / (M_PIgoffice * scale * (1. + y * y));
+}
+
+/* ------------------------------------------------------------------------ */
+/* Imported src/nmath/pcauchy.c from R. */
+/*
+ * Mathlib : A C Library of Special Functions
+ * Copyright (C) 1998 Ross Ihaka
+ * Copyright (C) 2000 The R Development Core Team
+ * Copyright (C) 2004 The R Foundation
+ *
+ * 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, a copy is available at
+ * http://www.r-project.org/Licenses/
+ *
+ * DESCRIPTION
+ *
+ * The distribution function of the Cauchy distribution.
+ */
+
+
+DOUBLE SUFFIX (go_pcauchy) (DOUBLE x, DOUBLE location, DOUBLE scale,
+ gboolean lower_tail, gboolean log_p)
+{
+#ifdef IEEE_754
+ if (SUFFIX (isnan) (x) || SUFFIX (isnan) (location) || SUFFIX (isnan) (scale))
+ return x + location + scale;
+#endif
+ if (scale <= 0) ML_ERR_return_NAN;
+
+ x = (x - location) / scale;
+ if (SUFFIX (isnan) (x)) ML_ERR_return_NAN;
+#ifdef IEEE_754
+ if(!SUFFIX (go_finite)(x)) {
+ if(x < 0) return R_DT_0;
+ else return R_DT_1;
+ }
+#endif
+ if (!lower_tail)
+ x = -x;
+ /* for large x, the standard formula suffers from cancellation.
+ * This is from Morten Welinder thanks to Ian Smith's atan(1/x) : */
+ if (SUFFIX (fabs) (x) > 1) {
+ DOUBLE y = atan(1/x) / M_PIgoffice;
+ return (x > 0) ? R_D_Clog(y) : R_D_val(-y);
+ } else
+ return R_D_val(0.5 + atan(x) / M_PIgoffice);
+}
+
+/* ------------------------------------------------------------------------ */
+/* Imported src/nmath/qcauchy.c from R. */
+/*
+ * Mathlib : A C Library of Special Functions
+ * Copyright (C) 1998 Ross Ihaka
+ * Copyright (C) 2000 The R Development Core Team
+ * Copyright (C) 2005-6 The R Foundation
+ *
+ * This version is based on a suggestion by Morten Welinder.
+ *
+ * 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
+ * http://www.gnu.org/copyleft/gpl.html.
+ *
+ * DESCRIPTION
+ *
+ * The quantile function of the Cauchy distribution.
+ */
+
+
+DOUBLE SUFFIX (go_qcauchy) (DOUBLE p, DOUBLE location, DOUBLE scale,
+ gboolean lower_tail, gboolean log_p)
+{
+#ifdef IEEE_754
+ if (SUFFIX (isnan) (p) || SUFFIX (isnan) (location) || SUFFIX (isnan) (scale))
+ return p + location + scale;
+#endif
+ R_Q_P01_check(p);
+ if (scale <= 0 || !SUFFIX (go_finite)(scale)) {
+ if (scale == 0) return location;
+ /* else */ ML_ERR_return_NAN;
+ }
+
+#define my_INF location + (lower_tail ? scale : -scale) * SUFFIX (go_pinf)
+ if (log_p) {
+ if (p > -1) {
+ /* when ep := SUFFIX (exp) (p),
+ * SUFFIX (tan) (pi*ep)= -SUFFIX (tan) (pi*(-ep))= -SUFFIX (tan) (pi*(-ep)+pi) = -SUFFIX (tan) (pi*(1-ep)) =
+ * = -SUFFIX (tan) (pi*(-SUFFIX (expm1) (p))
+ * for p ~ 0, SUFFIX (exp) (p) ~ 1, SUFFIX (tan) (~0) may be better than SUFFIX (tan) (~pi).
+ */
+ if (p == 0.) /* needed, since 1/SUFFIX (tan) (-0) = -Inf for some arch. */
+ return my_INF;
+ lower_tail = !lower_tail;
+ p = -SUFFIX (expm1) (p);
+ } else
+ p = SUFFIX (exp) (p);
+ } else if (p == 1.)
+ return my_INF;
+
+ return location + (lower_tail ? -scale : scale) / SUFFIX (tan) (M_PIgoffice * p);
+ /* -1/SUFFIX (tan) (pi * p) = -cot(pi * p) = SUFFIX (tan) (pi * (p - 1/2)) */
+}
+/* Cleaning up done by tools/import-R: */
+#undef my_INF
+
+/* ------------------------------------------------------------------------ */
+/* --- END MAGIC R SOURCE MARKER --- */
Added: trunk/goffice/math/go-R.h
==============================================================================
--- (empty file)
+++ trunk/goffice/math/go-R.h Fri Sep 12 20:40:00 2008
@@ -0,0 +1,60 @@
+/* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * go-pnorm.h
+ *
+ * Copyright (C) 2008 Jean Brefort (jean brefort normalesup org)
+ *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301
+ * USA
+ */
+
+#ifndef GO_PNORM_H
+#define GO_PNORM_H
+
+double go_trunc (double);
+double go_dnorm (double x, double mu, double sigma, gboolean give_log);
+double go_pnorm (double x, double mu, double sigma, gboolean lower_tail, gboolean log_p);
+void go_pnorm_both (double x, double *cum, double *ccum, int i_tail, gboolean log_p);
+double go_qnorm (double p, double mu, double sigma, gboolean lower_tail, gboolean log_p);
+double go_dlnorm (double x, double meanlog, double sdlog, gboolean give_log);
+double go_plnorm (double x, double logmean, double logsd, gboolean lower_tail, gboolean log_p);
+double go_qlnorm (double p, double logmean, double logsd, gboolean lower_tail, gboolean log_p);
+double go_dweibull (double x, double shape, double scale, gboolean give_log);
+double go_pweibull (double x, double shape, double scale, gboolean lower_tail, gboolean log_p);
+double go_qweibull (double p, double shape, double scale, gboolean lower_tail, gboolean log_p);
+double go_dcauchy (double x, double location, double scale, gboolean give_log);
+double go_pcauchy (double x, double location, double scale, gboolean lower_tail, gboolean log_p);
+double go_qcauchy (double p, double location, double scale, gboolean lower_tail, gboolean log_p);
+
+#ifdef GOFFICE_WITH_LONG_DOUBLE
+
+long double go_truncl (long double);
+long double go_dnorml (long double x, long double mu, long double sigma, gboolean give_log);
+long double go_pnorml (long double x, long double mu, long double sigma, gboolean lower_tail, gboolean log_p);
+void go_pnorm_bothl (long double x, long double *cum, long double *ccum, int i_tail, gboolean log_p);
+long double go_qnorml (long double p, long double mu, long double sigma, gboolean lower_tail, gboolean log_p);
+long double go_dlnorml (long double x, long double meanlog, long double sdlog, gboolean give_log);
+long double go_plnorml (long double x, long double logmean, long double logsd, gboolean lower_tail, gboolean log_p);
+long double go_qlnorml (long double p, long double logmean, long double logsd, gboolean lower_tail, gboolean log_p);
+long double go_dweibulll (long double x, long double shape, long double scale, gboolean give_log);
+long double go_pweibulll (long double x, long double shape, long double scale, gboolean lower_tail, gboolean log_p);
+long double go_qweibulll (long double p, long double shape, long double scale, gboolean lower_tail, gboolean log_p);
+long double go_dcauchyl (long double x, long double location, long double scale, gboolean give_log);
+long double go_pcauchyl (long double x, long double location, long double scale, gboolean lower_tail, gboolean log_p);
+long double go_qcauchyl (long double p, long double location, long double scale, gboolean lower_tail, gboolean log_p);
+
+#endif
+
+#endif /* GO_PNORM_H */
Added: trunk/goffice/math/go-distribution.c
==============================================================================
--- (empty file)
+++ trunk/goffice/math/go-distribution.c Fri Sep 12 20:40:00 2008
@@ -0,0 +1,882 @@
+/* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * gog-probability-plot.c
+ *
+ * Copyright (C) 2007-2008 Jean Brefort (jean brefort normalesup org)
+ *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301
+ * USA
+ */
+
+#include <goffice/goffice-config.h>
+#include "go-distribution.h"
+#include "go-math.h"
+#include "go-R.h"
+#include <goffice/utils/go-persist.h>
+#include <gsf/gsf-impl-utils.h>
+#include <glib/gi18n-lib.h>
+#include <string.h>
+
+#ifndef DOUBLE
+
+#define DOUBLE double
+#define SUFFIX(_n) _n
+
+#ifdef GOFFICE_WITH_LONG_DOUBLE
+#include "go-distribution.c"
+#undef DOUBLE
+#undef SUFFIX
+
+#ifdef HAVE_SUNMATH_H
+#include <sunmath.h>
+#endif
+#define DOUBLE long double
+#define SUFFIX(_n) _n ## l
+#endif
+
+#endif
+
+#ifndef DISTRIBUTION_FIRST_PATH
+
+enum {
+ DIST_PROP_0,
+ DIST_PROP_LOCATION,
+ DIST_PROP_SCALE
+};
+
+static struct
+{
+ GODistributionType type;
+ char const *name;
+} DistributionTypes [] = {
+ {GO_DISTRIBUTION_NORMAL, N_("Normal")},
+ {GO_DISTRIBUTION_UNIFORM, N_("Uniform")},
+ {GO_DISTRIBUTION_CAUCHY, N_("Cauchy")},
+ {GO_DISTRIBUTION_WEIBULL, N_("Weibull")},
+ {GO_DISTRIBUTION_LOGNORMAL, N_("Lognormal")}
+};
+
+char const *go_distribution_type_to_string (GODistributionType type)
+{
+ return DistributionTypes[type].name;
+}
+
+GODistributionType go_distribution_type_from_string (char const *name)
+{
+ int i = -1;
+ while (++i < GO_DISTRIBUTION_MAX)
+ if (!strcmp (DistributionTypes[i].name, name))
+ return i;
+ return GO_DISTRIBUTION_INVALID;
+}
+
+#define GO_DISTRIBUTION_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GO_DISTRIBUTION_TYPE, GODistributionClass))
+
+struct _GODistribution {
+ GObject base;
+
+ double location, scale;
+};
+
+typedef struct {
+ GObjectClass base;
+ GODistributionType dist_type;
+
+ double (*get_density) (GODistribution *dist, double x);
+ double (*get_cumulative) (GODistribution *dist, double x);
+ double (*get_ppf) (GODistribution *dist, double x);
+
+ GtkWidget * (*get_property_page) (GODistribution *dist);
+
+#ifdef GOFFICE_WITH_LONG_DOUBLE
+ long double (*get_densityl) (GODistribution *dist, long double x);
+ long double (*get_cumulativel) (GODistribution *dist, long double x);
+ long double (*get_ppfl) (GODistribution *dist, long double x);
+#endif
+
+} GODistributionClass;
+
+static void
+go_distribution_set_property (GObject *obj, guint param_id,
+ GValue const *value, GParamSpec *pspec)
+{
+ GODistribution *dist = GO_DISTRIBUTION (obj);
+
+ switch (param_id) {
+ case DIST_PROP_LOCATION:
+ dist->location = g_value_get_double (value);
+ break;
+ case DIST_PROP_SCALE:
+ dist->scale = g_value_get_double (value);
+ break;
+ default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, param_id, pspec);
+ return; /* NOTE : RETURN */
+ }
+}
+
+static void
+go_distribution_get_property (GObject *obj, guint param_id,
+ GValue *value, GParamSpec *pspec)
+{
+ GODistribution *dist = GO_DISTRIBUTION (obj);
+
+ switch (param_id) {
+ case DIST_PROP_LOCATION:
+ g_value_set_double (value, dist->location);
+ break;
+ case DIST_PROP_SCALE:
+ g_value_set_double (value, dist->scale);
+ break;
+ default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, param_id, pspec);
+ break;
+ }
+}
+
+static void
+go_distribution_class_init (GObjectClass *klass)
+{
+ klass->set_property = go_distribution_set_property;
+ klass->get_property = go_distribution_get_property;
+ g_object_class_install_property (klass, DIST_PROP_LOCATION,
+ g_param_spec_double ("location",
+ _("Location"),
+ _("Location"),
+ -G_MAXDOUBLE,
+ G_MAXDOUBLE,
+ 0.0,
+ GSF_PARAM_STATIC | G_PARAM_READWRITE));
+ g_object_class_install_property (klass, DIST_PROP_SCALE,
+ g_param_spec_double ("scale",
+ _("Scale"),
+ _("Scale"),
+ G_MINDOUBLE,
+ G_MAXDOUBLE,
+ 1.0,
+ GSF_PARAM_STATIC | G_PARAM_READWRITE));
+}
+
+static void
+go_distribution_init (GODistribution *dist)
+{
+ dist->location = 0.;
+ dist->scale = 1.;
+}
+
+static void
+go_distribution_persist_sax_save (GOPersist const *gp, GsfXMLOut *output)
+{
+ GODistribution const *dist = GO_DISTRIBUTION (gp);
+ GParamSpec **props;
+ int n;
+
+ g_return_if_fail (dist);
+ gsf_xml_out_add_cstr_unchecked (output, "type",
+ G_OBJECT_TYPE_NAME (dist));
+
+ if (dist->location != 0.)
+ gsf_xml_out_add_float (output, "location", dist->location, -1);
+ if (dist->scale != 1.)
+ gsf_xml_out_add_float (output, "scale", dist->scale, -1);
+
+ /* properties */
+ props = g_object_class_list_properties (G_OBJECT_GET_CLASS (dist), &n);
+ while (n-- > 0)
+ if (props[n]->flags & GO_PARAM_PERSISTENT) {
+ GType prop_type = G_PARAM_SPEC_VALUE_TYPE (props[n]);
+ GValue value = { 0 };
+
+ g_value_init (&value, prop_type);
+ g_object_get_property (G_OBJECT (dist), props[n]->name, &value);
+
+ /* No need to save default values */
+ if (g_param_value_defaults (props[n], &value)) {
+ g_value_unset (&value);
+ continue;
+ }
+
+ switch (G_TYPE_FUNDAMENTAL (prop_type)) {
+ case G_TYPE_CHAR:
+ case G_TYPE_UCHAR:
+ case G_TYPE_BOOLEAN:
+ case G_TYPE_INT:
+ case G_TYPE_UINT:
+ case G_TYPE_LONG:
+ case G_TYPE_ULONG:
+ case G_TYPE_FLOAT:
+ case G_TYPE_DOUBLE:
+ case G_TYPE_ENUM:
+ case G_TYPE_FLAGS: {
+ GValue str = { 0 };
+ g_value_init (&str, G_TYPE_STRING);
+ g_value_transform (&value, &str);
+ gsf_xml_out_add_cstr (output, props[n]->name, g_value_get_string (&str));
+ g_value_unset (&str);
+ break;
+ }
+
+ case G_TYPE_STRING: {
+ char const *str = g_value_get_string (&value);
+ if (str != NULL) {
+ gsf_xml_out_add_cstr (output, props[n]->name, str);
+ }
+ break;
+ }
+
+ default:
+ g_warning ("I could not persist property \"%s\", since type \"%s\" is unhandled.",
+ g_param_spec_get_name (props[n]), g_type_name (G_TYPE_FUNDAMENTAL(prop_type)));
+ }
+ g_value_unset (&value);
+ }
+}
+
+static void
+go_distribution_persist_prep_sax (GOPersist *gp, GsfXMLIn *xin, xmlChar const **attrs)
+{
+ GODistribution *dist = GO_DISTRIBUTION (gp);
+ while (*attrs) {
+ if (!strcmp ((char const*) *attrs, "name") || !strcmp ((char const*) *attrs, "type"));
+ else if (!strcmp ((char const*) *attrs, "location"))
+ dist->location = g_strtod (attrs[1], NULL);
+ else if (!strcmp ((char const*) *attrs, "scale"))
+ dist->scale = g_strtod (attrs[1], NULL);
+ else {
+ GParamSpec *spec = g_object_class_find_property (G_OBJECT_GET_CLASS (dist), *attrs);
+ if (spec == NULL)
+ g_warning ("unknown property `%s' for class `%s'",
+ *attrs, G_OBJECT_TYPE_NAME (gp));
+ else {
+ GType prop_type = G_PARAM_SPEC_VALUE_TYPE (spec);
+ switch G_TYPE_FUNDAMENTAL (prop_type) {
+ case G_TYPE_DOUBLE: {
+ GValue value = {0};
+ g_value_init (&value, G_TYPE_DOUBLE);
+ g_value_set_double (&value, g_strtod (attrs[1], NULL));
+ g_object_set_property (G_OBJECT (dist), *attrs, &value);
+ g_value_unset (&value);
+ break;
+ }
+ default:
+ g_critical ("Unsupported property type. Please report.");
+ break;
+ }
+ }
+ }
+ attrs += 2;
+ }
+}
+
+static void
+go_distribution_persist_init (GOPersistClass *iface)
+{
+ iface->prep_sax = go_distribution_persist_prep_sax;
+ iface->sax_save = go_distribution_persist_sax_save;
+}
+
+GSF_CLASS_FULL (GODistribution, go_distribution, NULL,
+ NULL, go_distribution_class_init, NULL, go_distribution_init,
+ G_TYPE_OBJECT, G_TYPE_FLAG_ABSTRACT,
+ GSF_INTERFACE (go_distribution_persist_init, GO_PERSIST_TYPE))
+
+GtkWidget *
+go_distribution_get_property_page (GODistribution *dist)
+{
+ GODistributionClass *go_dist_klass;
+
+ g_return_val_if_fail (GO_DISTRIBUTION (dist), NULL);
+
+ go_dist_klass = GO_DISTRIBUTION_GET_CLASS (dist);
+ if (go_dist_klass->get_property_page != NULL)
+ return go_dist_klass->get_property_page (dist);
+ return NULL;
+}
+
+void
+go_distribution_scale (GODistribution *dist, double location, double scale)
+{
+ dist->location = location;
+ dist->scale = scale;
+}
+
+#endif /* DISTRIBUTION_FIRST_PATH */
+
+DOUBLE
+SUFFIX (go_distribution_get_density) (GODistribution *dist, DOUBLE x)
+{
+ GODistributionClass *go_dist_klass;
+
+ g_return_val_if_fail (GO_DISTRIBUTION (dist), SUFFIX (go_nan));
+
+ go_dist_klass = GO_DISTRIBUTION_GET_CLASS (dist);
+ if (go_dist_klass->SUFFIX (get_density) != NULL)
+ return go_dist_klass->SUFFIX (get_density) (dist, x);
+ return SUFFIX (go_nan);
+}
+
+DOUBLE
+SUFFIX (go_distribution_get_cumulative) (GODistribution *dist, DOUBLE x)
+{
+ GODistributionClass *go_dist_klass;
+
+ g_return_val_if_fail (GO_DISTRIBUTION (dist), SUFFIX (go_nan));
+
+ go_dist_klass = GO_DISTRIBUTION_GET_CLASS (dist);
+ if (go_dist_klass->SUFFIX (get_cumulative) != NULL)
+ return go_dist_klass->SUFFIX (get_cumulative) (dist, x);
+ return SUFFIX (go_nan);
+}
+
+DOUBLE
+SUFFIX (go_distribution_get_ppf) (GODistribution *dist, DOUBLE x)
+{
+ GODistributionClass *go_dist_klass;
+
+ g_return_val_if_fail (GO_DISTRIBUTION (dist), SUFFIX (go_nan));
+
+ go_dist_klass = GO_DISTRIBUTION_GET_CLASS (dist);
+ if (go_dist_klass->SUFFIX (get_ppf) != NULL)
+ return go_dist_klass->SUFFIX (get_ppf) (dist, x);
+ return SUFFIX (go_nan);
+}
+
+DOUBLE
+SUFFIX (go_distribution_get_hazard) (GODistribution *dist, DOUBLE x)
+{
+ GODistributionClass *go_dist_klass;
+
+ g_return_val_if_fail (GO_DISTRIBUTION (dist), SUFFIX (go_nan));
+
+ go_dist_klass = GO_DISTRIBUTION_GET_CLASS (dist);
+ if (go_dist_klass->SUFFIX (get_density) != NULL &&
+ go_dist_klass->SUFFIX (get_cumulative) != NULL)
+ return go_dist_klass->SUFFIX (get_density) (dist, x) /
+ (1. - go_dist_klass->SUFFIX (get_cumulative) (dist, x));
+ return SUFFIX (go_nan);
+}
+
+DOUBLE
+SUFFIX (go_distribution_get_cumulative_hazard) (GODistribution *dist, DOUBLE x)
+{
+ GODistributionClass *go_dist_klass;
+
+ g_return_val_if_fail (GO_DISTRIBUTION (dist), SUFFIX (go_nan));
+
+ go_dist_klass = GO_DISTRIBUTION_GET_CLASS (dist);
+ if (go_dist_klass->SUFFIX (get_cumulative) != NULL)
+ return SUFFIX (log) (1. - go_dist_klass->SUFFIX (get_cumulative) (dist, x));
+ return SUFFIX (go_nan);
+}
+
+DOUBLE
+SUFFIX (go_distribution_get_survival) (GODistribution *dist, DOUBLE x)
+{
+ GODistributionClass *go_dist_klass;
+
+ g_return_val_if_fail (GO_DISTRIBUTION (dist), SUFFIX (go_nan));
+
+ go_dist_klass = GO_DISTRIBUTION_GET_CLASS (dist);
+ if (go_dist_klass->SUFFIX (get_cumulative) != NULL)
+ return 1. - go_dist_klass->SUFFIX (get_cumulative) (dist, x);
+ return SUFFIX (go_nan);
+}
+
+DOUBLE
+SUFFIX (go_distribution_get_inverse_survival) (GODistribution *dist, DOUBLE x)
+{
+ GODistributionClass *go_dist_klass;
+
+ g_return_val_if_fail (GO_DISTRIBUTION (dist), SUFFIX (go_nan));
+
+ go_dist_klass = GO_DISTRIBUTION_GET_CLASS (dist);
+ if (go_dist_klass->SUFFIX (get_ppf) != NULL)
+ return 1. - go_dist_klass->SUFFIX (get_ppf) (dist, x);
+ return SUFFIX (go_nan);
+}
+
+/*****************************************************************************/
+/* Normal distribution */
+/*****************************************************************************/
+#ifndef DISTRIBUTION_FIRST_PATH
+
+typedef struct {
+ GODistribution base;
+
+} GODistNormal;
+
+#define GO_DIST_NORMAL_TYPE (go_dist_normal_get_type ())
+#define GO_DIST_NORMAL(o) (G_TYPE_CHECK_INSTANCE_CAST((o), GO_DIST_NORMAL_TYPE, GODistNormal))
+#define IS_GO_DIST_NORMAL(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), GO_DIST_NORMAL_TYPE))
+
+GType go_dist_normal_get_type (void);
+
+typedef GODistributionClass GODistNormalClass;
+
+#endif /* DISTRIBUTION_FIRST_PATH */
+
+static DOUBLE
+SUFFIX (go_normal_get_density) (GODistribution *dist, DOUBLE x)
+{
+ return SUFFIX (go_dnorm) (x, dist->location, dist->scale, FALSE);
+}
+
+static DOUBLE
+SUFFIX (go_normal_get_cumulative) (GODistribution *dist, DOUBLE x)
+{
+ return SUFFIX (go_pnorm) (x, dist->location, dist->scale, TRUE, FALSE);
+}
+
+static DOUBLE
+SUFFIX (go_normal_get_ppf) (GODistribution *dist, DOUBLE x)
+{
+ return SUFFIX (go_qnorm) (x, dist->location, dist->scale, TRUE, FALSE);
+}
+
+#ifdef DISTRIBUTION_FIRST_PATH
+
+static void
+go_dist_normal_class_init (GObjectClass *klass)
+{
+ GODistributionClass *dist_klass = (GODistributionClass *) klass;
+ dist_klass->dist_type = GO_DISTRIBUTION_NORMAL;
+ dist_klass->get_density = go_normal_get_density;
+ dist_klass->get_cumulative = go_normal_get_cumulative;
+ dist_klass->get_ppf = go_normal_get_ppf;
+#ifdef GOFFICE_WITH_LONG_DOUBLE
+ dist_klass->get_densityl = go_normal_get_densityl;
+ dist_klass->get_cumulativel = go_normal_get_cumulativel;
+ dist_klass->get_ppfl = go_normal_get_ppfl;
+#endif
+}
+
+static void
+go_dist_normal_init (GODistribution *dist)
+{
+}
+
+GSF_CLASS (GODistNormal, go_dist_normal,
+ go_dist_normal_class_init, go_dist_normal_init,
+ GO_DISTRIBUTION_TYPE)
+
+#endif /* DISTRIBUTION_FIRST_PATH */
+
+/*****************************************************************************/
+/* Uniform distribution */
+/*****************************************************************************/
+#ifndef DISTRIBUTION_FIRST_PATH
+
+typedef struct {
+ GODistribution base;
+
+} GODistUniform;
+
+#define GO_DIST_UNIFORM_TYPE (go_dist_uniform_get_type ())
+#define GO_DIST_UNIFORM(o) (G_TYPE_CHECK_INSTANCE_CAST((o), GO_DIST_UNIFORM_TYPE, GODistUniform))
+#define IS_GO_DIST_UNIFORM(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), GO_DIST_UNIFORM_TYPE))
+
+GType go_dist_uniform_get_type (void);
+
+typedef GODistributionClass GODistUniformClass;
+
+#endif /* DISTRIBUTION_FIRST_PATH */
+
+static DOUBLE
+SUFFIX (go_uniform_get_density) (GODistribution *dist, DOUBLE x)
+{
+ x = (x - dist->location) / dist->scale;
+ return (x >= 0. && x < 1.)? SUFFIX (1.) / dist->scale: SUFFIX (0.);
+}
+
+static DOUBLE
+SUFFIX (go_uniform_get_cumulative) (GODistribution *dist, DOUBLE x)
+{
+ x = (x - dist->location) / dist->scale;
+ if (x < 0.)
+ return SUFFIX (0.);
+ else if (x >= 1.)
+ return SUFFIX (1.);
+ else
+ return x;
+}
+
+static DOUBLE
+SUFFIX (go_uniform_get_ppf) (GODistribution *dist, DOUBLE x)
+{
+ return x * dist->scale + dist->location;
+}
+
+#ifdef DISTRIBUTION_FIRST_PATH
+
+static void
+go_dist_uniform_class_init (GObjectClass *klass)
+{
+ GODistributionClass *dist_klass = (GODistributionClass *) klass;
+ dist_klass->dist_type = GO_DISTRIBUTION_UNIFORM;
+ dist_klass->get_density = go_uniform_get_density;
+ dist_klass->get_cumulative = go_uniform_get_cumulative;
+ dist_klass->get_ppf = go_uniform_get_ppf;
+#ifdef GOFFICE_WITH_LONG_DOUBLE
+ dist_klass->get_densityl = go_uniform_get_densityl;
+ dist_klass->get_cumulativel = go_uniform_get_cumulativel;
+ dist_klass->get_ppfl = go_uniform_get_ppfl;
+#endif
+}
+
+static void
+go_dist_uniform_init (GODistribution *dist)
+{
+}
+
+GSF_CLASS (GODistUniform, go_dist_uniform,
+ go_dist_uniform_class_init, go_dist_uniform_init,
+ GO_DISTRIBUTION_TYPE)
+
+#endif /* DISTRIBUTION_FIRST_PATH */
+
+/*****************************************************************************/
+/* Cauchy distribution */
+/*****************************************************************************/
+#ifndef DISTRIBUTION_FIRST_PATH
+
+typedef struct {
+ GODistribution base;
+
+} GODistCauchy;
+
+#define GO_DIST_CAUCHY_TYPE (go_dist_cauchy_get_type ())
+#define GO_DIST_CAUCHY(o) (G_TYPE_CHECK_INSTANCE_CAST((o), GO_DIST_CAUCHY_TYPE, GODistCauchy))
+#define IS_GO_DIST_CAUCHY(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), GO_DIST_CAUCHY_TYPE))
+
+GType go_dist_cauchy_get_type (void);
+
+typedef GODistributionClass GODistCauchyClass;
+
+#endif /* DISTRIBUTION_FIRST_PATH */
+
+static DOUBLE
+SUFFIX (go_cauchy_get_density) (GODistribution *dist, DOUBLE x)
+{
+ return SUFFIX (go_dcauchy) (x, dist->location, dist->scale, FALSE);
+}
+
+static DOUBLE
+SUFFIX (go_cauchy_get_cumulative) (GODistribution *dist, DOUBLE x)
+{
+ return SUFFIX (go_pcauchy) (x, dist->location, dist->scale, TRUE, FALSE);
+}
+
+static DOUBLE
+SUFFIX (go_cauchy_get_ppf) (GODistribution *dist, DOUBLE x)
+{
+ return SUFFIX (go_qcauchy) (x, dist->location, dist->scale, TRUE, FALSE);
+}
+
+#ifdef DISTRIBUTION_FIRST_PATH
+
+static void
+go_dist_cauchy_class_init (GObjectClass *klass)
+{
+ GODistributionClass *dist_klass = (GODistributionClass *) klass;
+ dist_klass->dist_type = GO_DISTRIBUTION_CAUCHY;
+ dist_klass->get_density = go_cauchy_get_density;
+ dist_klass->get_cumulative = go_cauchy_get_cumulative;
+ dist_klass->get_ppf = go_cauchy_get_ppf;
+#ifdef GOFFICE_WITH_LONG_DOUBLE
+ dist_klass->get_densityl = go_cauchy_get_densityl;
+ dist_klass->get_cumulativel = go_cauchy_get_cumulativel;
+ dist_klass->get_ppfl = go_cauchy_get_ppfl;
+#endif
+}
+
+static void
+go_dist_cauchy_init (GODistribution *dist)
+{
+}
+
+GSF_CLASS (GODistCauchy, go_dist_cauchy,
+ go_dist_cauchy_class_init, go_dist_cauchy_init,
+ GO_DISTRIBUTION_TYPE)
+
+#endif /* DISTRIBUTION_FIRST_PATH */
+
+/*****************************************************************************/
+/* Weibull distribution */
+/*****************************************************************************/
+#ifndef DISTRIBUTION_FIRST_PATH
+
+typedef struct {
+ GODistribution base;
+ double shape;
+} GODistWeibull;
+
+#define GO_DIST_WEIBULL_TYPE (go_dist_weibull_get_type ())
+#define GO_DIST_WEIBULL(o) (G_TYPE_CHECK_INSTANCE_CAST((o), GO_DIST_WEIBULL_TYPE, GODistWeibull))
+#define IS_GO_DIST_WEIBULL(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), GO_DIST_WEIBULL_TYPE))
+
+GType go_dist_weibull_get_type (void);
+
+typedef GODistributionClass GODistWeibullClass;
+
+enum {
+ WEIBULL_PROP_0,
+ WEIBULL_PROP_SHAPE
+};
+
+#endif /* DISTRIBUTION_FIRST_PATH */
+
+static DOUBLE
+SUFFIX (go_weibull_get_density) (GODistribution *dist, DOUBLE x)
+{
+ return SUFFIX (go_dweibull) (x - dist->location, GO_DIST_WEIBULL (dist)->shape, dist->scale, FALSE) ;
+}
+
+static DOUBLE
+SUFFIX (go_weibull_get_cumulative) (GODistribution *dist, DOUBLE x)
+{
+ return SUFFIX (go_pweibull) (x - dist->location, GO_DIST_WEIBULL (dist)->shape, dist->scale, TRUE, FALSE) ;
+}
+
+static DOUBLE
+SUFFIX (go_weibull_get_ppf) (GODistribution *dist, DOUBLE x)
+{
+ return SUFFIX (go_qweibull) (x, GO_DIST_WEIBULL (dist)->shape, dist->scale, TRUE, FALSE) + dist->location;
+}
+
+#ifdef DISTRIBUTION_FIRST_PATH
+
+static void
+go_dist_weibull_set_property (GObject *obj, guint param_id,
+ GValue const *value, GParamSpec *pspec)
+{
+ GODistWeibull *dist = GO_DIST_WEIBULL (obj);
+
+ switch (param_id) {
+ case LNORM_PROP_SHAPE:
+ dist->shape = g_value_get_double (value);
+ break;
+ default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, param_id, pspec);
+ return; /* NOTE : RETURN */
+ }
+}
+
+static void
+go_dist_weibull_get_property (GObject *obj, guint param_id,
+ GValue *value, GParamSpec *pspec)
+{
+ GODistWeibull *dist = GO_DIST_WEIBULL (obj);
+
+ switch (param_id) {
+ case LNORM_PROP_SHAPE:
+ g_value_set_double (value, dist->shape);
+ break;
+ default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, param_id, pspec);
+ break;
+ }
+}
+
+static void
+go_dist_weibull_class_init (GObjectClass *klass)
+{
+ GODistributionClass *dist_klass = (GODistributionClass *) klass;
+ dist_klass->dist_type = GO_DISTRIBUTION_WEIBULL;
+ dist_klass->get_density = go_weibull_get_density;
+ dist_klass->get_cumulative = go_weibull_get_cumulative;
+ dist_klass->get_ppf = go_weibull_get_ppf;
+#ifdef GOFFICE_WITH_LONG_DOUBLE
+ dist_klass->get_densityl = go_weibull_get_densityl;
+ dist_klass->get_cumulativel = go_weibull_get_cumulativel;
+ dist_klass->get_ppfl = go_weibull_get_ppfl;
+#endif
+ klass->set_property = go_dist_weibull_set_property;
+ klass->get_property = go_dist_weibull_get_property;
+ g_object_class_install_property (klass, WEIBULL_PROP_SHAPE,
+ g_param_spec_double ("shape",
+ _("Shape"),
+ _("Shape factor"),
+ G_MINDOUBLE,
+ G_MAXDOUBLE,
+ 1.0,
+ GSF_PARAM_STATIC | G_PARAM_READWRITE | GO_PARAM_PERSISTENT));
+}
+
+static void
+go_dist_weibull_init (GODistWeibull *dist)
+{
+ dist->shape = 1.;
+}
+
+GSF_CLASS (GODistWeibull, go_dist_weibull,
+ go_dist_weibull_class_init, go_dist_weibull_init,
+ GO_DISTRIBUTION_TYPE)
+
+#endif /* DISTRIBUTION_FIRST_PATH */
+
+/*****************************************************************************/
+/* Lognormal distribution */
+/*****************************************************************************/
+#ifndef DISTRIBUTION_FIRST_PATH
+
+typedef struct {
+ GODistribution base;
+ double shape;
+} GODistLogNormal;
+
+#define GO_DIST_LOG_NORMAL_TYPE (go_dist_log_normal_get_type ())
+#define GO_DIST_LOG_NORMAL(o) (G_TYPE_CHECK_INSTANCE_CAST((o), GO_DIST_LOG_NORMAL_TYPE, GODistLogNormal))
+#define IS_GO_DIST_LOG_NORMAL(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), GO_DIST_LOG_NORMAL_TYPE))
+
+GType go_dist_log_normal_get_type (void);
+
+typedef GODistributionClass GODistLogNormalClass;
+
+enum {
+ LNORM_PROP_0,
+ LNORM_PROP_SHAPE
+};
+
+#endif /* DISTRIBUTION_FIRST_PATH */
+
+static DOUBLE
+SUFFIX (go_log_normal_get_density) (GODistribution *dist, DOUBLE x)
+{
+ return SUFFIX (go_dlnorm) ((x - dist->location) / dist->scale, 0., GO_DIST_LOG_NORMAL (dist)->shape, FALSE);
+}
+
+static DOUBLE
+SUFFIX (go_log_normal_get_cumulative) (GODistribution *dist, DOUBLE x)
+{
+ return SUFFIX (go_plnorm) ((x - dist->location) / dist->scale, 0., GO_DIST_LOG_NORMAL (dist)->shape, TRUE, FALSE);
+}
+
+static DOUBLE
+SUFFIX (go_log_normal_get_ppf) (GODistribution *dist, DOUBLE x)
+{
+ return SUFFIX (go_qlnorm) (x, 0., GO_DIST_LOG_NORMAL (dist)->shape, TRUE, FALSE) * dist->scale + dist->location;
+}
+
+#ifdef DISTRIBUTION_FIRST_PATH
+
+static void
+go_dist_log_normal_set_property (GObject *obj, guint param_id,
+ GValue const *value, GParamSpec *pspec)
+{
+ GODistLogNormal *dist = GO_DIST_LOG_NORMAL (obj);
+
+ switch (param_id) {
+ case LNORM_PROP_SHAPE:
+ dist->shape = g_value_get_double (value);
+ break;
+ default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, param_id, pspec);
+ return; /* NOTE : RETURN */
+ }
+}
+
+static void
+go_dist_log_normal_get_property (GObject *obj, guint param_id,
+ GValue *value, GParamSpec *pspec)
+{
+ GODistLogNormal *dist = GO_DIST_LOG_NORMAL (obj);
+
+ switch (param_id) {
+ case LNORM_PROP_SHAPE:
+ g_value_set_double (value, dist->shape);
+ break;
+ default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, param_id, pspec);
+ break;
+ }
+}
+
+static void
+go_dist_log_normal_class_init (GObjectClass *klass)
+{
+ GODistributionClass *dist_klass = (GODistributionClass *) klass;
+ dist_klass->dist_type = GO_DISTRIBUTION_LOGNORMAL;
+ dist_klass->get_density = go_log_normal_get_density;
+ dist_klass->get_cumulative = go_log_normal_get_cumulative;
+ dist_klass->get_ppf = go_log_normal_get_ppf;
+#ifdef GOFFICE_WITH_LONG_DOUBLE
+ dist_klass->get_densityl = go_log_normal_get_densityl;
+ dist_klass->get_cumulativel = go_log_normal_get_cumulativel;
+ dist_klass->get_ppfl = go_log_normal_get_ppfl;
+#endif
+ klass->set_property = go_dist_log_normal_set_property;
+ klass->get_property = go_dist_log_normal_get_property;
+ g_object_class_install_property (klass, LNORM_PROP_SHAPE,
+ g_param_spec_double ("shape",
+ _("Shape"),
+ _("Shape factor"),
+ G_MINDOUBLE,
+ G_MAXDOUBLE,
+ 1.0,
+ GSF_PARAM_STATIC | G_PARAM_READWRITE | GO_PARAM_PERSISTENT));
+}
+
+static void
+go_dist_log_normal_init (GODistLogNormal *dist)
+{
+ dist->shape = 1.;
+}
+
+GSF_CLASS (GODistLogNormal, go_dist_log_normal,
+ go_dist_log_normal_class_init, go_dist_log_normal_init,
+ GO_DISTRIBUTION_TYPE)
+
+#endif /* DISTRIBUTION_FIRST_PATH */
+
+#ifndef DISTRIBUTION_FIRST_PATH
+
+GODistribution*
+go_distribution_new (GODistributionType type)
+{
+ switch (type) {
+ case GO_DISTRIBUTION_NORMAL:
+ return (GODistribution *) g_object_new (GO_DIST_NORMAL_TYPE, NULL);
+ case GO_DISTRIBUTION_UNIFORM:
+ return (GODistribution *) g_object_new (GO_DIST_UNIFORM_TYPE, NULL);
+ case GO_DISTRIBUTION_CAUCHY:
+ return (GODistribution *) g_object_new (GO_DIST_CAUCHY_TYPE, NULL);
+ case GO_DISTRIBUTION_WEIBULL:
+ return (GODistribution *) g_object_new (GO_DIST_WEIBULL_TYPE, NULL);
+ case GO_DISTRIBUTION_LOGNORMAL:
+ return (GODistribution *) g_object_new (GO_DIST_LOG_NORMAL_TYPE, NULL);
+ default:
+ return NULL;
+ }
+}
+
+GODistributionType
+go_distribution_get_distribution_type (GODistribution *dist)
+{
+ return GO_DISTRIBUTION_GET_CLASS (dist)->dist_type;
+}
+
+char const *
+go_distribution_get_distribution_name (GODistribution *dist)
+{
+ return _(go_distribution_type_to_string (go_distribution_get_distribution_type (dist)));
+}
+
+void
+go_distributions_init ()
+{
+ go_dist_normal_get_type ();
+ go_dist_uniform_get_type ();
+ go_dist_cauchy_get_type ();
+ go_dist_weibull_get_type ();
+ go_dist_log_normal_get_type ();
+}
+
+#define DISTRIBUTION_FIRST_PATH
+
+#endif /* DISTRIBUTION_FIRST_PATH */
Added: trunk/goffice/math/go-distribution.h
==============================================================================
--- (empty file)
+++ trunk/goffice/math/go-distribution.h Fri Sep 12 20:40:00 2008
@@ -0,0 +1,83 @@
+/* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * go-distribution.h
+ *
+ * Copyright (C) 2007 Jean Brefort (jean brefort normalesup org)
+ *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301
+ * USA
+ */
+
+#ifndef GO_DISTRIBUTION_H
+#define GO_DISTRIBUTION_H
+
+#include <glib-object.h>
+#include <gtk/gtkwidget.h>
+
+G_BEGIN_DECLS
+
+typedef enum {
+ GO_DISTRIBUTION_INVALID = -1,
+ GO_DISTRIBUTION_NORMAL,
+ GO_DISTRIBUTION_UNIFORM,
+ GO_DISTRIBUTION_CAUCHY,
+ GO_DISTRIBUTION_WEIBULL,
+ GO_DISTRIBUTION_LOGNORMAL,
+ GO_DISTRIBUTION_MAX
+} GODistributionType;
+
+char const *go_distribution_type_to_string (GODistributionType type);
+GODistributionType go_distribution_type_from_string (char const *name);
+
+typedef struct _GODistribution GODistribution;
+
+#define GO_DISTRIBUTION_TYPE (go_distribution_get_type ())
+#define GO_DISTRIBUTION(o) (G_TYPE_CHECK_INSTANCE_CAST((o), GO_DISTRIBUTION_TYPE, GODistribution))
+#define IS_GO_DISTRIBUTION(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), GO_DISTRIBUTION_TYPE))
+
+GType go_distribution_get_type (void);
+
+GODistribution *go_distribution_new (GODistributionType type);
+GODistribution *go_distribution_new_by_name (char const *name);
+GODistributionType go_distribution_get_distribution_type (GODistribution *dist);
+char const *go_distribution_get_distribution_name (GODistribution *dist);
+
+double go_distribution_get_density (GODistribution *dist, double x);
+double go_distribution_get_cumulative (GODistribution *dist, double x);
+double go_distribution_get_ppf (GODistribution *dist, double x);
+double go_distribution_get_hazard (GODistribution *dist, double x);
+double go_distribution_get_cumulative_hazard (GODistribution *dist, double x);
+double go_distribution_get_survival (GODistribution *dist, double x);
+double go_distribution_get_inverse_survival (GODistribution *dist, double x);
+
+GtkWidget *go_distribution_get_property_page (GODistribution *dist);
+
+#ifdef GOFFICE_WITH_LONG_DOUBLE
+long double go_distribution_get_densityl (GODistribution *dist, long double x);
+long double go_distribution_get_cumulativel (GODistribution *dist, long double x);
+long double go_distribution_get_ppfl (GODistribution *dist, long double x);
+long double go_distribution_get_hazardl (GODistribution *dist, long double x);
+long double go_distribution_get_cumulative_hazardl (GODistribution *dist, long double x);
+long double go_distribution_get_survivall (GODistribution *dist, long double x);
+long double go_distribution_get_inverse_survivall (GODistribution *dist, long double x);
+#endif
+
+void go_distribution_scale (GODistribution *dist, double location, double scale);
+
+void go_distributions_init (void);
+
+G_END_DECLS
+
+#endif
Modified: trunk/goffice/math/go-rangefunc.c
==============================================================================
--- trunk/goffice/math/go-rangefunc.c (original)
+++ trunk/goffice/math/go-rangefunc.c Fri Sep 12 20:40:00 2008
@@ -162,8 +162,8 @@
return 1;
}
-static DOUBLE *
-SUFFIX(range_sort) (DOUBLE const *xs, int n)
+DOUBLE *
+SUFFIX(go_range_sort) (DOUBLE const *xs, int n)
{
if (n <= 0)
return NULL;
@@ -199,7 +199,7 @@
int
SUFFIX(go_range_fractile_inter) (DOUBLE const *xs, int n, DOUBLE *res, DOUBLE f)
{
- DOUBLE *ys = SUFFIX(range_sort) (xs, n);
+ DOUBLE *ys = SUFFIX(go_range_sort) (xs, n);
int error = SUFFIX(go_range_fractile_inter_sorted) (ys, n, res, f);
g_free (ys);
return error;
Modified: trunk/goffice/math/go-rangefunc.h
==============================================================================
--- trunk/goffice/math/go-rangefunc.h (original)
+++ trunk/goffice/math/go-rangefunc.h Fri Sep 12 20:40:00 2008
@@ -20,6 +20,7 @@
int go_range_increasing (double const *xs, int n);
int go_range_decreasing (double const *xs, int n);
int go_range_vary_uniformly (double const *xs, int n);
+double *go_range_sort (double const *xs, int n);
#ifdef GOFFICE_WITH_LONG_DOUBLE
int go_range_suml (long double const *xs, int n, long double *res);
@@ -38,6 +39,7 @@
int go_range_increasingl (long double const *xs, int n);
int go_range_decreasingl (long double const *xs, int n);
int go_range_vary_uniformlyl (long double const *xs, int n);
+long double *go_range_sortl (long double const *xs, int n);
#endif
G_END_DECLS
Modified: trunk/pixmaps/Makefile.am
==============================================================================
--- trunk/pixmaps/Makefile.am (original)
+++ trunk/pixmaps/Makefile.am Fri Sep 12 20:40:00 2008
@@ -41,17 +41,17 @@
chart_minmax_2_1.png chart_minmax_2_2.png \
chart_histogram_1_1.png \
chart_surface_2_1.png chart_surface_2_2.png \
+ chart_prob_1_1.png \
\
area.xpm \
bar.xpm \
- boxplot.xpm \
bubble.xpm \
color.xpm \
column.xpm \
contour.xpm \
+ dist.xpm \
doughnut.xpm \
dropbar.xpm \
- hist.xpm \
linegraph.xpm \
minmax.xpm \
pie.xpm \
Added: trunk/pixmaps/chart_prob_1_1.png
==============================================================================
Binary file. No diff available.
Added: trunk/pixmaps/chart_prob_1_1.svg
==============================================================================
--- (empty file)
+++ trunk/pixmaps/chart_prob_1_1.svg Fri Sep 12 20:40:00 2008
@@ -0,0 +1,226 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ id="svg1"
+ sodipodi:version="0.32"
+ inkscape:version="0.46"
+ width="64.000000mm"
+ height="60.000000mm"
+ sodipodi:docbase="/home/jean/devel/svn/goffice-orig/pixmaps"
+ sodipodi:docname="chart_prob_1_1.svg"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape"
+ inkscape:export-filename="/home/jean/devel/goffice/pixmaps/chart_prob_1_1.png"
+ inkscape:export-xdpi="25.4"
+ inkscape:export-ydpi="25.4">
+ <defs
+ id="defs3">
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 106.29921 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="226.77165 : 106.29921 : 1"
+ inkscape:persp3d-origin="113.38583 : 70.86614 : 1"
+ id="perspective2504" />
+ <linearGradient
+ id="linearGradient4044">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.0000000;"
+ offset="0.0000000"
+ id="stop4045" />
+ <stop
+ style="stop-color:#363636;stop-opacity:0.18750000;"
+ offset="1.0000000"
+ id="stop4046" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3418">
+ <stop
+ style="stop-color:#f7f7f7;stop-opacity:1.0000000;"
+ offset="0.0000000"
+ id="stop3419" />
+ <stop
+ style="stop-color:#dedede;stop-opacity:1.0000000;"
+ offset="1.0000000"
+ id="stop3420" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2791">
+ <stop
+ style="stop-color:#fbfbfb;stop-opacity:1.0000000;"
+ offset="0.0000000"
+ id="stop2792" />
+ <stop
+ style="stop-color:#e9e9e9;stop-opacity:1.0000000;"
+ offset="1.0000000"
+ id="stop2793" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2791"
+ id="linearGradient2794"
+ x1="0.49693251"
+ y1="0.058441557"
+ x2="0.49079755"
+ y2="0.96103895" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4044"
+ id="linearGradient4043"
+ x1="0.49689442"
+ y1="0.012987013"
+ x2="0.49689442"
+ y2="0.99350649" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0000000"
+ inkscape:pageshadow="2"
+ inkscape:zoom="4.4593316"
+ inkscape:cx="115.25215"
+ inkscape:cy="105.90324"
+ inkscape:window-width="1440"
+ inkscape:window-height="825"
+ showborder="true"
+ showgrid="true"
+ inkscape:grid-points="true"
+ inkscape:grid-bbox="true"
+ gridtolerance="1.0000000px"
+ inkscape:guide-bbox="true"
+ inkscape:guide-points="true"
+ guidetolerance="1.0000000mm"
+ inkscape:window-x="0"
+ inkscape:window-y="25"
+ showguides="true"
+ inkscape:current-layer="svg1">
+ <sodipodi:guide
+ orientation="vertical"
+ position="23.994627"
+ id="guide5924" />
+ <sodipodi:guide
+ orientation="vertical"
+ position="58.080453"
+ id="guide5925" />
+ <sodipodi:guide
+ orientation="vertical"
+ position="92.166278"
+ id="guide5926" />
+ <sodipodi:guide
+ orientation="vertical"
+ position="126.25210"
+ id="guide5927" />
+ <inkscape:grid
+ id="GridFromPre046Settings"
+ type="xygrid"
+ originx="0px"
+ originy="0.50000000mm"
+ spacingx="1.0000000mm"
+ spacingy="1.0000000mm"
+ color="#0000ff"
+ empcolor="#0000ff"
+ opacity="0.2"
+ empopacity="0.4"
+ empspacing="5" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata4">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <rect
+ style="fill:url(#linearGradient4043);fill-opacity:0.74901998;fill-rule:evenodd;stroke:none;stroke-width:3.0000000pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000;"
+ id="rect4047"
+ width="184.25197"
+ height="177.15660"
+ x="23.031496"
+ y="23.040251"
+ rx="17.594519"
+ ry="14.164467" />
+ <rect
+ style="fill:url(#linearGradient4043);fill-opacity:0.74901998;fill-rule:evenodd;stroke:none;stroke-width:3.0000000pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000;"
+ id="rect3421"
+ width="177.16536"
+ height="173.62204"
+ x="26.574802"
+ y="23.031490"
+ rx="17.594519"
+ ry="14.164467" />
+ <rect
+ style="fill:url(#linearGradient2794);fill-opacity:0.74901998;fill-rule:evenodd;stroke:none;stroke-width:3.5262673;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000;"
+ id="rect2169"
+ width="170.38249"
+ height="159.80026"
+ x="30.118111"
+ y="26.554472"
+ rx="17.594519"
+ ry="14.164467" />
+ <rect
+ style="fill:none;fill-opacity:0.74901998;fill-rule:evenodd;stroke:#000000;stroke-width:3.5262673;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000;"
+ id="rect5928"
+ width="170.38249"
+ height="159.80026"
+ x="29.993284"
+ y="26.574797"
+ rx="17.594519"
+ ry="14.164467" />
+ <rect
+ style="fill:#83a67f;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ id="rect6060"
+ width="21.259842"
+ height="21.259842"
+ x="76.181099"
+ y="123.54579"
+ rx="0" />
+ <rect
+ style="fill:#83a67f;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ id="rect6146"
+ width="21.259842"
+ height="21.259842"
+ x="108.07087"
+ y="95.150276"
+ rx="0" />
+ <rect
+ style="fill:#83a67f;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ id="rect6147"
+ width="21.259842"
+ height="21.259842"
+ x="148.61699"
+ y="58.464561"
+ rx="0" />
+ <rect
+ style="fill:#83a67f;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ id="rect6148"
+ width="21.259842"
+ height="21.259842"
+ x="164.76378"
+ y="40.748024"
+ rx="0" />
+ <rect
+ style="fill:#83a67f;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ id="rect6149"
+ width="21.259842"
+ height="21.259842"
+ x="51.377953"
+ y="148.7072"
+ rx="0" />
+ <path
+ style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:3.412;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
+ d="M 47.765006,174.25187 L 188.36904,39.029806"
+ id="path2287" />
+</svg>
Modified: trunk/plugins/plot_boxes/Makefile.am
==============================================================================
--- trunk/plugins/plot_boxes/Makefile.am (original)
+++ trunk/plugins/plot_boxes/Makefile.am Fri Sep 12 20:40:00 2008
@@ -1,25 +1,32 @@
-goffice_graph_boxplotdir = $(goffice_plugindir)/plot_boxes
-xmldir = $(goffice_graph_boxplotdir)
-gladedir = $(goffice_graph_boxplotdir)
-
-goffice_graph_boxplot_LTLIBRARIES = boxplot.la
-boxplot_la_LDFLAGS = -module $(GOFFICE_PLUGIN_FLAGS)
-boxplot_la_LIBADD = $(GOFFICE_PLUGIN_LIBADD)
+goffice_graph_distribdir = $(goffice_plugindir)/plot_distrib
+xmldir = $(goffice_graph_distribdir)
+gladedir = $(goffice_graph_distribdir)
+
+goffice_graph_distrib_LTLIBRARIES = distrib.la
+distrib_la_LDFLAGS = -module $(GOFFICE_PLUGIN_FLAGS)
+distrib_la_LIBADD = $(GOFFICE_PLUGIN_LIBADD)
-boxplot_la_SOURCES = gog-boxplot.c \
+distrib_la_SOURCES = gog-boxplot.c \
gog-boxplot.h \
gog-histogram.c \
- gog-histogram.h
+ gog-histogram.h \
+ gog-probability-plot.c \
+ gog-probability-plot.h \
+ plugin.c
xml_in_files = plugin.xml.in plot-types.xml.in
xml_DATA = $(xml_in_files:.xml.in=.xml)
- INTLTOOL_XML_RULE@
-
if WITH_GTK
-dist_glade_DATA = gog-boxplot-prefs.glade
+ distrib_la_SOURCES += \
+ go-distribution-prefs.c \
+ go-distribution-prefs.h
+
+ dist_glade_DATA = gog-boxplot-prefs.glade
endif
+ INTLTOOL_XML_RULE@
+
# do not use the intl-tool stuff to merge the text back
# its simpler to just use gettext directly
plot-types.xml : plot-types.xml.in
Added: trunk/plugins/plot_boxes/go-distribution-prefs.c
==============================================================================
--- (empty file)
+++ trunk/plugins/plot_boxes/go-distribution-prefs.c Fri Sep 12 20:40:00 2008
@@ -0,0 +1,157 @@
+/* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * go-distribution-prefs.c
+ *
+ * Copyright (C) 2008 Jean Brefort (jean brefort normalesup org)
+ *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301
+ * USA
+ */
+
+#include "goffice-config.h"
+#include "go-distribution-prefs.h"
+#include <goffice/graph/gog-data-set.h>
+#include <goffice/math/go-distribution.h>
+#include <goffice/utils/go-persist.h>
+#include <glib/gi18n-lib.h>
+
+typedef struct
+{
+ GObject *client;
+ GParamSpec *props[2];
+ GtkWidget *labels[2];
+ GtkWidget *data[2];
+ GtkTable *table;
+ GogDataAllocator *dalloc;
+} DistPrefs;
+
+static void
+destroy_cb (DistPrefs *prefs)
+{
+ g_free (prefs);
+}
+
+static void
+distribution_changed_cb (GtkComboBox *box, DistPrefs *prefs)
+{
+ GODistribution *dist = NULL;
+ int i, j, n;
+ GtkTreeIter iter;
+ GODistributionType dist_type;
+ GParamSpec **props;
+ GtkTreeModel *model = gtk_combo_box_get_model (box);
+ gtk_combo_box_get_active_iter (box, &iter);
+ gtk_tree_model_get (model, &iter, 1, &dist_type, -1);
+ dist = go_distribution_new (dist_type);
+ g_object_set (prefs->client, "distribution", dist, NULL);
+ props = g_object_class_list_properties (G_OBJECT_GET_CLASS (dist), &n);
+ for (j = i = 0; j < n; j++)
+ if (props[j]->flags & GO_PARAM_PERSISTENT) {
+ char *lbl = g_strconcat (_(g_param_spec_get_nick (props[j])), _(":"), NULL);
+ if (!prefs->labels[i]) {
+ GtkWidget *w = gtk_label_new (lbl);
+ g_free (lbl);
+ g_object_set (w, "xalign", 0., NULL);
+ gtk_table_attach (prefs->table, w, 0, 1, i+ 1, i + 2, GTK_FILL, GTK_FILL, 0, 0);
+ prefs->labels[i] = w;
+ } else
+ gtk_label_set_text (GTK_LABEL (prefs->labels[i]), lbl);
+ if (!prefs->data[i]) {
+ GtkWidget *w = GTK_WIDGET (gog_data_allocator_editor (prefs->dalloc, GOG_DATASET (prefs->client), i, GOG_DATA_SCALAR));
+ gtk_table_attach (prefs->table, w, 1, 2, i+ 1, i + 2, GTK_FILL, GTK_FILL, 0, 0);
+ prefs->data[i] = w;
+ }
+ gtk_widget_show (prefs->labels[i]);
+ gtk_widget_show (prefs->data[i]);
+ prefs->props[i++] = props[j];
+ }
+ while (i < 2) {
+ if (prefs->labels[i])
+ gtk_widget_hide (prefs->labels[i]);
+ if (prefs->data[i])
+ gtk_widget_hide (prefs->data[i]);
+ prefs->props[i++] = NULL;
+ }
+ g_free (props);
+ g_object_unref (dist);
+}
+
+GtkWidget *
+go_distribution_pref_new (GObject *obj, GogDataAllocator *dalloc, G_GNUC_UNUSED GOCmdContext *cc)
+{
+ GtkListStore *model;
+ GtkCellRenderer *renderer;
+ GtkTreeViewColumn *column;
+ GtkTreeIter iter;
+ GParamSpec **props;
+ int n, i, j;
+ DistPrefs *prefs = g_new0 (DistPrefs, 1);
+ GtkWidget *res = gtk_table_new (3, 2, FALSE);
+ GtkWidget *w = gtk_label_new (_("Distribution:"));
+ GODistribution *dist = NULL;
+ GODistributionType dist_type;
+
+ prefs->dalloc = dalloc;
+ prefs->table = GTK_TABLE (res);
+ g_object_get (obj, "distribution", &dist, NULL);
+ g_return_val_if_fail (IS_GO_DISTRIBUTION (dist), NULL);
+
+ dist_type = go_distribution_get_distribution_type (dist);
+ g_object_set (res, "border-width", 12, "row-spacing", 12, "column-spacing", 24, NULL);
+ g_object_set (w, "xalign", 0., NULL);
+ gtk_table_attach (prefs->table, w, 0, 1, 0, 1, GTK_FILL, GTK_FILL, 0, 0);
+ g_signal_connect_swapped (res, "destroy", G_CALLBACK (destroy_cb), prefs);
+ prefs->client = obj;
+
+ /* add the list of known distributions in a combobox */
+ model = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_INT);
+ w = gtk_combo_box_new_with_model (GTK_TREE_MODEL (model));
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (w), renderer, FALSE);
+ gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (w), renderer,
+ "text", 0,
+ NULL);
+ renderer = gtk_cell_renderer_text_new ();
+ for (i =0 ; i < GO_DISTRIBUTION_MAX; i++) {
+ gtk_list_store_append (model, &iter);
+ gtk_list_store_set (model, &iter, 0, _(go_distribution_type_to_string (i)), 1, i, -1);
+ if (i == dist_type)
+ gtk_combo_box_set_active_iter (GTK_COMBO_BOX (w), &iter);
+ }
+ g_signal_connect (w, "changed", G_CALLBACK (distribution_changed_cb), prefs);
+ gtk_table_attach (prefs->table, w, 1, 2, 0, 1, GTK_FILL, GTK_FILL, 0, 0);
+
+ /* other persistent properties */
+ i = 1;
+ props = g_object_class_list_properties (G_OBJECT_GET_CLASS (dist), &n);
+ for (j = 0; j < n; j++)
+ if (props[j]->flags & GO_PARAM_PERSISTENT) {
+ char *lbl = g_strconcat (_(g_param_spec_get_nick (props[j])), _(":"), NULL);
+ w = gtk_label_new (lbl);
+ g_free (lbl);
+ g_object_set (w, "xalign", 0., NULL);
+ gtk_table_attach (prefs->table, w, 0, 1, i, i + 1, GTK_FILL, GTK_FILL, 0, 0);
+ prefs->labels[i-1] = w;
+ prefs->props[i-1] = props[n];
+ w = GTK_WIDGET (gog_data_allocator_editor (dalloc, GOG_DATASET (obj), i - 1, GOG_DATA_SCALAR));
+ gtk_table_attach (prefs->table, w, 1, 2, i, i + 1, GTK_FILL, GTK_FILL, 0, 0);
+ prefs->data[i] = w;
+ i++;
+ }
+ g_free (props);
+
+ gtk_widget_show_all (res);
+ return res;
+}
Added: trunk/plugins/plot_boxes/go-distribution-prefs.h
==============================================================================
--- (empty file)
+++ trunk/plugins/plot_boxes/go-distribution-prefs.h Fri Sep 12 20:40:00 2008
@@ -0,0 +1,37 @@
+/* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * go-distribution-prefs.h
+ *
+ * Copyright (C) 2008 Jean Brefort (jean brefort normalesup org)
+ *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301
+ * USA
+ */
+
+#ifndef GO_DISTRIBUTION_PREFS_H
+#define GO_DISTRIBUTION_PREFS_H
+
+#include <goffice/app/go-cmd-context.h>
+#include <goffice/graph/gog-data-allocator.h>
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+GtkWidget *go_distribution_pref_new (GObject *obj, GogDataAllocator *dalloc,
+ GOCmdContext *cc);
+
+G_END_DECLS
+
+#endif
Modified: trunk/plugins/plot_boxes/gog-boxplot.c
==============================================================================
--- trunk/plugins/plot_boxes/gog-boxplot.c (original)
+++ trunk/plugins/plot_boxes/gog-boxplot.c Fri Sep 12 20:40:00 2008
@@ -34,14 +34,11 @@
#include <goffice/utils/go-marker.h>
#include <goffice/utils/go-path.h>
#include <goffice/utils/go-persist.h>
-#include <goffice/app/module-plugin-defs.h>
#include <glib/gi18n-lib.h>
#include <gsf/gsf-impl-utils.h>
#include <string.h>
-GOFFICE_PLUGIN_MODULE_HEADER;
-
struct _GogBoxPlot {
GogPlot base;
@@ -662,27 +659,3 @@
GSF_DYNAMIC_CLASS (GogBoxPlotSeries, gog_box_plot_series,
gog_box_plot_series_class_init, NULL,
GOG_SERIES_TYPE)
-
-/* Plugin initialization */
-void gog_histogram_plot_register_type (GTypeModule *module);
-void gog_histogram_plot_series_register_type (GTypeModule *module);
-void gog_histogram_plot_view_register_type (GTypeModule *module);
-void gog_histogram_series_view_register_type (GTypeModule *module);
-
-G_MODULE_EXPORT void
-go_plugin_init (GOPlugin *plugin, GOCmdContext *cc)
-{
- GTypeModule *module = go_plugin_get_type_module (plugin);
- gog_box_plot_register_type (module);
- gog_box_plot_view_register_type (module);
- gog_box_plot_series_register_type (module);
- gog_histogram_plot_register_type (module);
- gog_histogram_plot_view_register_type (module);
- gog_histogram_plot_series_register_type (module);
- gog_histogram_series_view_register_type (module);
-}
-
-G_MODULE_EXPORT void
-go_plugin_shutdown (GOPlugin *plugin, GOCmdContext *cc)
-{
-}
Added: trunk/plugins/plot_boxes/gog-probability-plot.c
==============================================================================
--- (empty file)
+++ trunk/plugins/plot_boxes/gog-probability-plot.c Fri Sep 12 20:40:00 2008
@@ -0,0 +1,478 @@
+/* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * gog-probability-plot.c
+ *
+ * Copyright (C) 2007 Jean Brefort (jean brefort normalesup org)
+ *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301
+ * USA
+ */
+
+#include <goffice/goffice-config.h>
+#include "gog-probability-plot.h"
+#include "go-distribution-prefs.h"
+#include <goffice/graph/gog-axis.h>
+#include <goffice/graph/gog-chart-map.h>
+#include <goffice/graph/gog-renderer.h>
+#include <goffice/math/go-rangefunc.h>
+#include <goffice/utils/go-persist.h>
+#include <glib/gi18n-lib.h>
+#include <gsf/gsf-impl-utils.h>
+#include <math.h>
+#include <string.h>
+
+#define GOG_PROBABILITY_PLOT_SERIES_TYPE (gog_probability_plot_series_get_type ())
+#define GOG_PROBABILITY_PLOT_SERIES(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GOG_PROBABILITY_PLOT_SERIES_TYPE, GogProbabilityPlotSeries))
+#define IS_GOG_PROBABILITY_PLOT_SERIES(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GOG_PROBABILITY_PLOT_SERIES_TYPE))
+
+typedef struct {
+ GogSeries base;
+ double *x, *y;
+} GogProbabilityPlotSeries;
+typedef GogSeriesClass GogProbabilityPlotSeriesClass;
+
+GType gog_probability_plot_series_get_type (void);
+GType gog_probability_plot_view_get_type (void);
+
+typedef GogPlotClass GogProbabilityPlotClass;
+
+static GogObjectClass *probability_plot_parent_klass;
+
+#ifdef GOFFICE_WITH_GTK
+static void
+gog_probability_plot_populate_editor (GogObject *item,
+ GogEditor *editor,
+ GogDataAllocator *dalloc,
+ GOCmdContext *cc)
+{
+ gog_editor_add_page (editor, go_distribution_pref_new (G_OBJECT (item), dalloc, cc), _("Distribution"));
+
+ (GOG_OBJECT_CLASS(probability_plot_parent_klass)->populate_editor) (item, editor, dalloc, cc);
+}
+#endif
+
+static void
+gog_probability_plot_update (GogObject *obj)
+{
+ GogProbabilityPlot *plot = GOG_PROBABILITY_PLOT (obj);
+ GogProbabilityPlotSeries *series = GOG_PROBABILITY_PLOT_SERIES (
+ plot->base.series->data);
+
+
+ if (!gog_series_is_valid (GOG_SERIES (series)) || series->base.num_elements == 0)
+ return;
+ if (plot->x.minima != series->x[0] || plot->x.maxima != series->x[series->base.num_elements - 1]) {
+ plot->x.minima = series->x[0];
+ plot->x.maxima = series->x[series->base.num_elements - 1];
+ gog_axis_bound_changed (plot->base.axis[0], GOG_OBJECT (plot));
+ }
+ if (plot->y.minima != series->y[0] || plot->y.maxima != series->y[series->base.num_elements - 1]) {
+ plot->y.minima = series->y[0];
+ plot->y.maxima = series->y[series->base.num_elements - 1];
+ gog_axis_bound_changed (plot->base.axis[1], GOG_OBJECT (plot));
+ }
+}
+
+static GOData *
+gog_probability_plot_axis_get_bounds (GogPlot *plot, GogAxisType axis,
+ GogPlotBoundInfo *bounds)
+{
+ GogProbabilityPlot *model = GOG_PROBABILITY_PLOT (plot);
+
+
+ if (axis == GOG_AXIS_X) {
+ bounds->val.minima = model->x.minima;
+ bounds->val.maxima = model->x.maxima;
+ if (bounds->fmt == NULL && model->x.fmt != NULL)
+ bounds->fmt = go_format_ref (model->x.fmt);
+ } else {
+ bounds->val.minima = model->y.minima;
+ bounds->val.maxima = model->y.maxima;
+ if (bounds->fmt == NULL && model->y.fmt != NULL)
+ bounds->fmt = go_format_ref (model->y.fmt);
+ }
+ bounds->is_discrete = FALSE;
+ return NULL;
+}
+
+static char const *
+gog_probability_plot_type_name (G_GNUC_UNUSED GogObject const *item)
+{
+ /* xgettext : the base for how to name probability-plot objects
+ * eg The 2nd probability-plot in a chart will be called
+ * ProbabilityPlot2 */
+ return N_("ProbabilityPlot");
+}
+
+/* We do not support distributions with more than two shape parameters */
+enum {
+ PROBABILITY_PLOT_PROP_0,
+ PROBABILITY_PLOT_PROP_DISTRIBUTION,
+ PROBABILITY_PLOT_PROP_SHAPE_PARAM1,
+ PROBABILITY_PLOT_PROP_SHAPE_PARAM2
+};
+
+static void
+gog_probability_plot_set_property (GObject *obj, guint param_id,
+ GValue const *value, GParamSpec *pspec)
+{
+ GogProbabilityPlot *plot = GOG_PROBABILITY_PLOT (obj);
+
+ switch (param_id) {
+ case PROBABILITY_PLOT_PROP_DISTRIBUTION: {
+ GODistribution *dist = GO_DISTRIBUTION (g_value_get_object (value));
+ if (dist) {
+ GParamSpec **props;
+ int i, j, n;
+ if (plot->dist)
+ g_object_unref (plot->dist);
+ plot->dist = g_object_ref (dist);
+ /* search the properties */
+ props = g_object_class_list_properties (G_OBJECT_GET_CLASS (dist), &n);
+ for (i = j = 0; j < n; j++)
+ if (props[j]->flags & GO_PARAM_PERSISTENT) {
+ g_free (plot->shape_params[i].prop_name);
+ plot->shape_params[i].prop_name = g_strdup (g_param_spec_get_name (props[j]));
+ /* set the property */
+ i++;
+ }
+ while (i < 2) {
+ g_free (plot->shape_params[i].prop_name);
+ plot->shape_params[i].prop_name = NULL;
+ i++;
+ }
+ g_free (props);
+ if (plot->base.series)
+ gog_object_request_update (GOG_OBJECT (plot->base.series->data));
+ gog_object_emit_changed (GOG_OBJECT (obj), FALSE);
+ }
+ break;
+ }
+ case PROBABILITY_PLOT_PROP_SHAPE_PARAM1: {
+
+ char const *name = g_value_get_string (value);
+ g_free (plot->shape_params[0].prop_name);
+ plot->shape_params[0].prop_name =
+ (name && *name && strcmp (name, "none"))?
+ g_strdup (name): NULL;
+ break;
+ }
+ case PROBABILITY_PLOT_PROP_SHAPE_PARAM2: {
+ char const *name = g_value_get_string (value);
+ g_free (plot->shape_params[1].prop_name);
+ plot->shape_params[1].prop_name =
+ (name && *name && strcmp (name, "none"))?
+ g_strdup (name): NULL;
+ break;
+ }
+ default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, param_id, pspec);
+ return; /* NOTE : RETURN */
+ }
+}
+
+static void
+gog_probability_plot_get_property (GObject *obj, guint param_id,
+ GValue *value, GParamSpec *pspec)
+{
+ GogProbabilityPlot *plot = GOG_PROBABILITY_PLOT (obj);
+
+ switch (param_id) {
+ case PROBABILITY_PLOT_PROP_DISTRIBUTION:
+ g_value_set_object (value, plot->dist);
+ break;
+ case PROBABILITY_PLOT_PROP_SHAPE_PARAM1:
+ g_value_set_string (value, ((plot->shape_params[0].prop_name)? plot->shape_params[0].prop_name: NULL));
+ break;
+ case PROBABILITY_PLOT_PROP_SHAPE_PARAM2:
+ g_value_set_string (value, ((plot->shape_params[1].prop_name)? plot->shape_params[1].prop_name: NULL));
+ break;
+ default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, param_id, pspec);
+ break;
+ }
+}
+
+static void
+gog_probability_plot_finalize (GObject *obj)
+{
+ GogProbabilityPlot *plot = GOG_PROBABILITY_PLOT (obj);
+ g_return_if_fail (plot != NULL);
+ if (plot->dist != NULL)
+ g_object_unref (plot->dist);
+ gog_dataset_finalize (GOG_DATASET (plot));
+ g_free (plot->shape_params[0].prop_name);
+ g_free (plot->shape_params[0].elem);
+ g_free (plot->shape_params[1].prop_name);
+ g_free (plot->shape_params[1].elem);
+ G_OBJECT_CLASS (probability_plot_parent_klass)->finalize (obj);
+}
+
+static void
+gog_probability_plot_class_init (GogPlotClass *gog_plot_klass)
+{
+ GObjectClass *gobject_klass = (GObjectClass *) gog_plot_klass;
+ GogObjectClass *gog_object_klass = (GogObjectClass *) gog_plot_klass;
+ GogPlotClass *plot_klass = (GogPlotClass *) gog_plot_klass;
+
+ probability_plot_parent_klass = g_type_class_peek_parent (gog_plot_klass);
+
+ gobject_klass->set_property = gog_probability_plot_set_property;
+ gobject_klass->get_property = gog_probability_plot_get_property;
+ gobject_klass->finalize = gog_probability_plot_finalize;
+
+ g_object_class_install_property (gobject_klass, PROBABILITY_PLOT_PROP_DISTRIBUTION,
+ g_param_spec_object ("distribution",
+ _("Distribution"),
+ _("A pointer to the GODistribution used by this plot"),
+ GO_DISTRIBUTION_TYPE,
+ GSF_PARAM_STATIC | G_PARAM_READWRITE | GO_PARAM_PERSISTENT));
+ g_object_class_install_property (gobject_klass, PROBABILITY_PLOT_PROP_SHAPE_PARAM1,
+ g_param_spec_string ("param1",
+ _("Shape parameter"),
+ _("Name of the first shape parameter if any"),
+ "none",
+ GSF_PARAM_STATIC | G_PARAM_READWRITE | GO_PARAM_PERSISTENT));
+ g_object_class_install_property (gobject_klass, PROBABILITY_PLOT_PROP_SHAPE_PARAM2,
+ g_param_spec_string ("param2",
+ _("Second shape parameter"),
+ _("Name of the first shape parameter if any"),
+ "none",
+ GSF_PARAM_STATIC | G_PARAM_READWRITE | GO_PARAM_PERSISTENT));
+
+ gog_object_klass->type_name = gog_probability_plot_type_name;
+ gog_object_klass->view_type = gog_probability_plot_view_get_type ();
+ gog_object_klass->update = gog_probability_plot_update;
+
+ {
+ static GogSeriesDimDesc dimensions[] = {
+ { N_("Values"), GOG_SERIES_REQUIRED, FALSE,
+ GOG_DIM_INDEX, GOG_MS_DIM_VALUES },
+ };
+ plot_klass->desc.series.dim = dimensions;
+ plot_klass->desc.series.num_dim = G_N_ELEMENTS (dimensions);
+ }
+ plot_klass->desc.num_series_min = 1;
+ plot_klass->desc.num_series_max = 1;
+ plot_klass->series_type = gog_probability_plot_series_get_type ();
+ plot_klass->axis_set = GOG_AXIS_SET_XY;
+ plot_klass->desc.series.style_fields = GOG_STYLE_MARKER;
+ plot_klass->axis_get_bounds = gog_probability_plot_axis_get_bounds;
+#ifdef GOFFICE_WITH_GTK
+ gog_object_klass->populate_editor = gog_probability_plot_populate_editor;
+#endif
+}
+
+static void
+gog_probability_plot_init (GogProbabilityPlot *plot)
+{
+ plot->dist = go_distribution_new (plot->dist_type = GO_DISTRIBUTION_NORMAL);
+ plot->shape_params[0].elem = g_new0 (GogDatasetElement, 1);
+ plot->shape_params[1].elem = g_new0 (GogDatasetElement, 1);
+};
+
+static void
+gog_probability_plot_dataset_dims (GogDataset const *set, int *first, int *last)
+{
+ GogProbabilityPlot const *plot = GOG_PROBABILITY_PLOT (set);
+ *first = 0;
+ *last = 1;
+}
+
+static GogDatasetElement *
+gog_probability_plot_dataset_get_elem (GogDataset const *set, int dim_i)
+{
+ GogProbabilityPlot const *plot = GOG_PROBABILITY_PLOT (set);
+ g_return_val_if_fail (2 > dim_i, NULL);
+ g_return_val_if_fail (dim_i >= 0, NULL);
+ return plot->shape_params[dim_i].elem;
+}
+
+static void
+gog_probability_plot_dataset_dim_changed (GogDataset *set, int dim_i)
+{
+ GogProbabilityPlot const *plot = GOG_PROBABILITY_PLOT (set);
+ GParamSpec *spec;
+ GType prop_type;
+
+ if (!plot->shape_params[dim_i].prop_name)
+ return;
+ spec = g_object_class_find_property (G_OBJECT_GET_CLASS (plot->dist), plot->shape_params[dim_i].prop_name);
+ prop_type = G_PARAM_SPEC_VALUE_TYPE (spec);
+ switch G_TYPE_FUNDAMENTAL (prop_type) {
+ case G_TYPE_DOUBLE: {
+ GValue value = {0};
+ g_value_init (&value, G_TYPE_DOUBLE);
+ if (plot->shape_params[dim_i].elem->data)
+ g_value_set_double (&value, go_data_scalar_get_value (GO_DATA_SCALAR (plot->shape_params[dim_i].elem->data)));
+ else
+ g_param_value_set_default (spec, &value);
+ g_param_value_validate (spec, &value);
+ g_object_set_property (G_OBJECT (plot->dist), plot->shape_params[dim_i].prop_name, &value);
+ g_value_unset (&value);
+ break;
+ }
+ default:
+ g_critical ("Unsupported property type. Please report.");
+ break;
+ }
+ if (plot->base.series)
+ gog_object_request_update (GOG_OBJECT (plot->base.series->data));
+ gog_object_request_update (GOG_OBJECT (set));
+}
+
+static void
+gog_probability_plot_dataset_init (GogDatasetClass *iface)
+{
+ iface->get_elem = gog_probability_plot_dataset_get_elem;
+ iface->dims = gog_probability_plot_dataset_dims;
+ iface->dim_changed = gog_probability_plot_dataset_dim_changed;
+}
+
+GSF_DYNAMIC_CLASS_FULL (GogProbabilityPlot, gog_probability_plot,
+ NULL, NULL, gog_probability_plot_class_init, NULL,
+ gog_probability_plot_init, GOG_PLOT_TYPE, 0,
+ GSF_INTERFACE (gog_probability_plot_dataset_init, GOG_DATASET_TYPE))
+
+/************************************************,*****************************/
+typedef GogPlotView GogProbabilityPlotView;
+typedef GogPlotViewClass GogProbabilityPlotViewClass;
+
+static void
+gog_probability_plot_view_render (GogView *view, GogViewAllocation const *bbox)
+{
+ GogProbabilityPlot const *model = GOG_PROBABILITY_PLOT (view->model);
+ GogChart *chart = GOG_CHART (view->model->parent);
+ GogChartMap *chart_map;
+ GogAxisMap *x_map, *y_map;
+ GogViewAllocation const *area;
+ GogProbabilityPlotSeries const *series;
+ unsigned i, nb;
+ GogStyle *style;
+
+ if (model->base.series == NULL)
+ return;
+ series = GOG_PROBABILITY_PLOT_SERIES (model->base.series->data);
+ nb = series->base.num_elements;
+ style = GOG_STYLED_OBJECT (series)->style;
+ if (nb == 0 || series->x == NULL || series->y == NULL)
+ return;
+ area = gog_chart_view_get_plot_area (view->parent);
+ chart_map = gog_chart_map_new (chart, area,
+ GOG_PLOT (model)->axis[GOG_AXIS_X],
+ GOG_PLOT (model)->axis[GOG_AXIS_Y],
+ NULL, FALSE);
+ if (!gog_chart_map_is_valid (chart_map)) {
+ gog_chart_map_free (chart_map);
+ return;
+ }
+
+ x_map = gog_chart_map_get_axis_map (chart_map, 0);
+ y_map = gog_chart_map_get_axis_map (chart_map, 1);
+
+ gog_renderer_push_style (view->renderer, style);
+ for (i = 0; i < nb; i++) {
+ gog_renderer_draw_marker (view->renderer,
+ gog_axis_map_to_view (x_map, series->x[i]),
+ gog_axis_map_to_view (y_map, series->y[i]));
+ }
+ gog_renderer_pop_style (view->renderer);
+ gog_chart_map_free (chart_map);
+}
+
+static GogViewClass *probability_plot_view_parent_klass;
+
+static void
+gog_probability_plot_view_class_init (GogViewClass *view_klass)
+{
+ probability_plot_view_parent_klass = (GogViewClass*) g_type_class_peek_parent (view_klass);
+ view_klass->render = gog_probability_plot_view_render;
+ view_klass->clip = FALSE;
+}
+
+GSF_DYNAMIC_CLASS (GogProbabilityPlotView, gog_probability_plot_view,
+ gog_probability_plot_view_class_init, NULL,
+ GOG_PLOT_VIEW_TYPE)
+
+/****************************************************************************/
+
+static GogObjectClass *gog_probability_plot_series_parent_klass;
+
+static GObjectClass *series_parent_klass;
+
+static void
+gog_probability_plot_series_update (GogObject *obj)
+{
+ double *x_vals = NULL;
+ GogProbabilityPlotSeries *series = GOG_PROBABILITY_PLOT_SERIES (obj);
+ double mn, d;
+ unsigned i;
+ GODistribution *dist = GO_DISTRIBUTION (((GogProbabilityPlot *) series->base.plot)->dist);
+
+ g_free (series->x);
+ series->x = NULL;
+ if (series->base.values[0].data != NULL) {
+ x_vals = go_data_vector_get_values (GO_DATA_VECTOR (series->base.values[0].data));
+ series->base.num_elements = go_data_vector_get_len
+ (GO_DATA_VECTOR (series->base.values[0].data));
+ if (x_vals)
+ series->x = go_range_sort (x_vals, series->base.num_elements);
+ }
+ mn = pow (0.5, 1. / series->base.num_elements);
+ d = series->base.num_elements + .365;
+ g_free (series->y);
+ if (series->base.num_elements > 0) {
+ series->y = g_new0 (double, series->base.num_elements);
+ series->y[0] = go_distribution_get_ppf (dist, 1. - mn);
+ for (i = 1; i < series->base.num_elements - 1; i++)
+ series->y[i] = go_distribution_get_ppf (dist, (i + .6825) / d);
+ series->y[i] = go_distribution_get_ppf (dist, mn);
+ } else
+ series->y = NULL;
+
+ /* queue plot for redraw */
+ gog_object_request_update (GOG_OBJECT (series->base.plot));
+
+ if (gog_probability_plot_series_parent_klass->update)
+ gog_probability_plot_series_parent_klass->update (obj);
+}
+
+static void
+gog_probability_plot_series_finalize (GObject *obj)
+{
+ GogProbabilityPlotSeries *series = GOG_PROBABILITY_PLOT_SERIES (obj);
+
+ g_free (series->y);
+ series->y = NULL;
+ g_free (series->x);
+ series->x = NULL;
+
+ G_OBJECT_CLASS (series_parent_klass)->finalize (obj);
+}
+
+static void
+gog_probability_plot_series_class_init (GogObjectClass *obj_klass)
+{
+ GogStyledObjectClass *gso_klass = (GogStyledObjectClass*) obj_klass;
+ GObjectClass *gobject_klass = (GObjectClass *) gso_klass;
+
+ series_parent_klass = g_type_class_peek_parent (obj_klass);
+ gobject_klass->finalize = gog_probability_plot_series_finalize;
+
+ gog_probability_plot_series_parent_klass = g_type_class_peek_parent (obj_klass);
+ obj_klass->update = gog_probability_plot_series_update;
+}
+
+GSF_DYNAMIC_CLASS (GogProbabilityPlotSeries, gog_probability_plot_series,
+ gog_probability_plot_series_class_init, NULL,
+ GOG_SERIES_TYPE)
Added: trunk/plugins/plot_boxes/gog-probability-plot.h
==============================================================================
--- (empty file)
+++ trunk/plugins/plot_boxes/gog-probability-plot.h Fri Sep 12 20:40:00 2008
@@ -0,0 +1,55 @@
+/* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * gog-probability-plot.h
+ *
+ * Copyright (C) 2007 Jean Brefort (jean brefort normalesup org)
+ *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301
+ * USA
+ */
+
+#ifndef GOG_PROBABILITY_PLOT_H
+#define GOG_PROBABILITY_PLOT_H
+
+#include <goffice/graph/gog-plot-impl.h>
+#include <goffice/math/go-distribution.h>
+#include <goffice/utils/go-format.h>
+
+G_BEGIN_DECLS
+
+typedef struct {
+ GogPlot base;
+
+ GODistribution *dist;
+ GODistributionType dist_type;
+ struct {
+ double minima, maxima;
+ GOFormat *fmt;
+ } x, y;
+ struct {
+ char *prop_name;
+ GogDatasetElement *elem;
+ } shape_params[2];
+} GogProbabilityPlot;
+
+#define GOG_PROBABILITY_PLOT_TYPE (gog_probability_plot_get_type ())
+#define GOG_PROBABILITY_PLOT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GOG_PROBABILITY_PLOT_TYPE, GogProbabilityPlot))
+#define GOG_IS_PROBABILITY_PLOT(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GOG_PROBABILITY_PLOT_TYPE))
+
+GType gog_probability_plot_get_type (void);
+
+G_END_DECLS
+
+#endif
Modified: trunk/plugins/plot_boxes/plot-types.xml.in
==============================================================================
--- trunk/plugins/plot_boxes/plot-types.xml.in (original)
+++ trunk/plugins/plot_boxes/plot-types.xml.in Fri Sep 12 20:40:00 2008
@@ -1,29 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<Types xmlns:graph="http://www.gnumeric.org/graph_v2.dtd">
- <Family _name="BoxPlot" sample_image_file="boxplot.xpm" axis_set="xy"/>
+ <Family _name="Statistics" sample_image_file="dist.xpm" axis_set="xy"/>
<Type _name="HBoxPlots" row="1" col="1"
- engine="GogBoxPlot" family="BoxPlot"
+ engine="GogBoxPlot" family="Statistics"
_description="Horizontal Box-Plot."
sample_image_file="chart_boxplot_1_1.png">
<property name="guru-hints">backplane</property>
</Type>
<Type _name="VBoxPlots" row="1" col="2"
- engine="GogBoxPlot" family="BoxPlot"
+ engine="GogBoxPlot" family="Statistics"
_description="Vertical Box-Plot."
sample_image_file="chart_boxplot_1_2.png">
<property name="vertical">true</property>
<property name="guru-hints">backplane</property>
</Type>
<Type _name="HBoxPlotOutliers" row="2" col="1"
- engine="GogBoxPlot" family="BoxPlot"
+ engine="GogBoxPlot" family="Statistics"
_description="Horizontal Box-Plot showing outliers."
sample_image_file="chart_boxplot_2_1.png">
<property name="outliers">true</property>
<property name="guru-hints">backplane</property>
</Type>
<Type _name="VBoxPlotOutliers" row="2" col="2"
- engine="GogBoxPlot" family="BoxPlot"
+ engine="GogBoxPlot" family="Statistics"
_description="Vertical Box-Plot showing outliers."
sample_image_file="chart_boxplot_2_2.png">
<property name="outliers">true</property>
@@ -31,10 +31,15 @@
<property name="guru-hints">backplane</property>
</Type>
<Family _name="Histogram" sample_image_file="hist.xpm" axis_set="xy"/>
- <Type _name="Histogram" row="1" col="1"
- engine="GogHistogramPlot" family="Histogram"
+ <Type _name="Histogram" row="3" col="1"
+ engine="GogHistogramPlot" family="Statistics"
_description="Histogram."
sample_image_file="chart_histogram_1_1.png">
<property name="guru-hints">backplane</property>
</Type>
+ <Type _name="ProbabilityPlot" row="4" col="1"
+ engine="GogProbabilityPlot" family="Statistics"
+ _description="Probability plot."
+ sample_image_file="chart_prob_1_1.png">
+ </Type>
</Types>
Modified: trunk/plugins/plot_boxes/plugin.xml.in
==============================================================================
--- trunk/plugins/plot_boxes/plugin.xml.in (original)
+++ trunk/plugins/plot_boxes/plugin.xml.in Fri Sep 12 20:40:00 2008
@@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<plugin id="GOffice_plot_boxes">
<information>
- <_name>Charting : Box-Plots/Histograms</_name>
- <_description>Box-Plots and Histograms</_description>
+ <_name>Charting : distribution related plots</_name>
+ <_description>box-blots, histograms, and other distribution related plots</_description>
</information>
<loader type="Gnumeric_Builtin:module">
- <attribute name="module_file" value="boxplot"/>
+ <attribute name="module_file" value="distrib"/>
</loader>
<services>
<service type="plot_engine" id="GogBoxPlot">
@@ -18,6 +18,11 @@
<_description>Histograms plotting engine</_description>
</information>
</service>
+ <service type="plot_engine" id="GogProbabilityPlot">
+ <information>
+ <_description>Probability plots engine</_description>
+ </information>
+ </service>
<service type="plot_type" id="boxplot">
<file>plot-types.xml</file>
<information>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]