goffice r2217 - in trunk: . goffice goffice/math pixmaps plugins/plot_boxes



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]