[goffice] Fixed flawed exponential fit in graphs for small values. [#633735]
- From: Jean Bréfort <jbrefort src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [goffice] Fixed flawed exponential fit in graphs for small values. [#633735]
- Date: Mon, 1 Nov 2010 20:05:57 +0000 (UTC)
commit e1d5d12da829a672a77664ac027984805af13e2a
Author: Jean Brefort <jean brefort normalesup org>
Date: Mon Nov 1 21:07:30 2010 +0100
Fixed flawed exponential fit in graphs for small values. [#633735]
ChangeLog | 11 ++++++
NEWS | 1 +
goffice/math/go-regression.c | 67 ++++++++++++++++++++++++++++++++++++++
goffice/math/go-regression.h | 12 ++++++-
plugins/reg_linear/gog-exp-reg.c | 24 +++++++-------
5 files changed, 102 insertions(+), 13 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 3899d50..f761862 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2010-11-01 Jean Brefort <jean brefort normalesup org>
+
+ * goffice/math/go-regression.c (go_exponential_regression_as_log): new
+ regression utility returning the logarithms of the coefficients instead of
+ the coefficients to avoid roundint to 0 or infinite.
+ * goffice/math/go-regression.h: ditto.
+ * plugins/reg_linear/gog-exp-reg.c
+ (gog_exp_reg_curve_get_value_at), (gog_exp_reg_curve_get_equation),
+ (gog_exp_reg_curve_class_init): use go_exponential_regression_as_log.
+ [#633735]
+
2010-10-26 Jean Brefort <jean brefort normalesup org>
* goffice/utils/go-pattern.c (go_pattern_create_cairo_pattern): enclose
diff --git a/NEWS b/NEWS
index 67937d0..2675ca9 100644
--- a/NEWS
+++ b/NEWS
@@ -7,6 +7,7 @@ Jean:
* Fixed sorting with accentuated characters. [#631504]
* Allow filled plots to be displayed behind the grids. [#632310]
* Fixed patterns with cairo-1.10.
+ * Fixed flawed exponential fit in graphs for small values. [#633735]
Morten:
* Fix GOImage-vs-cairo lifecycle issue.
diff --git a/goffice/math/go-regression.c b/goffice/math/go-regression.c
index 385394e..4ca70f1 100644
--- a/goffice/math/go-regression.c
+++ b/goffice/math/go-regression.c
@@ -1160,6 +1160,73 @@ SUFFIX(go_exponential_regression) (MATRIX xss, int dim,
}
/**
+ * go_exponential_regression_as_log:
+ * @xss: x-vectors (i.e. independent data)
+ * @dim: number of x-vectors
+ * @ys: y-vector (dependent data)
+ * @n: number of data points
+ * @affine: if %TRUE, a non-one multiplier is allowed
+ * @res: output place for constant[0] and root1[1], root2[2],... There will be dim+1 results.
+ * @stat_ : non-NULL storage for additional results.
+ *
+ * Performs one-dimensional linear regressions on the input points as
+ * go_exponential_regression, but returns the logarithm of the coefficients instead
+ * or the coefficients themselves.
+ * Fits to "y = b * exp (m1*x1) * ... * exp (md*xd) " or equivalently to
+ * "ln y = ln b + x1 * m1 + ... + xd * md".
+ *
+ * Returns: #GORegressionResult as above.
+ **/
+GORegressionResult
+SUFFIX(go_exponential_regression_as_log) (MATRIX xss, int dim,
+ const DOUBLE *ys, int n,
+ gboolean affine,
+ DOUBLE *res,
+ SUFFIX(go_regression_stat_t) *stat_)
+{
+ DOUBLE *log_ys;
+ GORegressionResult result;
+ int i;
+
+ g_return_val_if_fail (dim >= 1, GO_REG_invalid_dimensions);
+ g_return_val_if_fail (n >= 1, GO_REG_invalid_dimensions);
+
+ log_ys = g_new (DOUBLE, n);
+ for (i = 0; i < n; i++)
+ if (ys[i] > 0)
+ log_ys[i] = SUFFIX(log) (ys[i]);
+ else {
+ result = GO_REG_invalid_data;
+ goto out;
+ }
+
+ if (affine) {
+ int i;
+ DOUBLE **xss2 = g_new (DOUBLE *, dim + 1);
+
+ xss2[0] = g_new (DOUBLE, n);
+ for (i = 0; i < n; i++)
+ xss2[0][i] = 1;
+ memcpy (xss2 + 1, xss, dim * sizeof (DOUBLE *));
+
+ result = SUFFIX(general_linear_regression)
+ (xss2, dim + 1, log_ys,
+ n, res, stat_, affine);
+ g_free (xss2[0]);
+ g_free (xss2);
+ } else {
+ res[0] = 0;
+ result = SUFFIX(general_linear_regression)
+ (xss, dim, log_ys, n,
+ res + 1, stat_, affine);
+ }
+
+ out:
+ g_free (log_ys);
+ return result;
+}
+
+/**
* go_power_regression:
* @xss: x-vectors (i.e. independent data)
* @dim: number of x-vectors
diff --git a/goffice/math/go-regression.h b/goffice/math/go-regression.h
index 573085d..ea80650 100644
--- a/goffice/math/go-regression.h
+++ b/goffice/math/go-regression.h
@@ -48,6 +48,11 @@ GORegressionResult go_exponential_regression (double **xss, int dim,
gboolean affine,
double *res,
go_regression_stat_t *stat_);
+GORegressionResult go_exponential_regression_as_log (double **xss, int dim,
+ const double *ys, int n,
+ gboolean affine,
+ double *res,
+ go_regression_stat_t *stat_);
GORegressionResult go_power_regression (double **xss, int dim,
const double *ys, int n,
gboolean affine,
@@ -129,7 +134,12 @@ GORegressionResult go_linear_regressionl (long double **xss, int dim,
gboolean affine,
long double *res,
go_regression_stat_tl *stat_);
-GORegressionResult go_exponential_regressionl(long double **xss, int dim,
+GORegressionResult go_exponential_regressionl (long double **xss, int dim,
+ const long double *ys, int n,
+ gboolean affine,
+ long double *res,
+ go_regression_stat_tl *stat_);
+GORegressionResult go_exponential_regression_as_logl (long double **xss, int dim,
const long double *ys, int n,
gboolean affine,
long double *res,
diff --git a/plugins/reg_linear/gog-exp-reg.c b/plugins/reg_linear/gog-exp-reg.c
index 1227037..ead1298 100644
--- a/plugins/reg_linear/gog-exp-reg.c
+++ b/plugins/reg_linear/gog-exp-reg.c
@@ -30,7 +30,7 @@
static double
gog_exp_reg_curve_get_value_at (GogRegCurve *curve, double x)
{
- return curve->a[0] * pow (curve->a[1], x);
+ return exp (curve->a[0] + curve->a[1] * x);
}
static gchar const*
@@ -39,17 +39,17 @@ gog_exp_reg_curve_get_equation (GogRegCurve *curve)
if (!curve->equation) {
GogLinRegCurve *lin = GOG_LIN_REG_CURVE (curve);
if (lin->affine)
- curve->equation = (curve->a[0] < 1.)?
- ((curve->a[1] < 1.)?
- g_strdup_printf ("ln(y) = \xE2\x88\x92%gx \xE2\x88\x92 %g", -log (curve->a[1]), -log (curve->a[0])):
- g_strdup_printf ("ln(y) = %gx \xE2\x88\x92% g", log (curve->a[1]), -log (curve->a[0]))):
- ((curve->a[1] < 1.)?
- g_strdup_printf ("ln(y) = \xE2\x88\x92%gx + %g", -log (curve->a[1]), log (curve->a[0])):
- g_strdup_printf ("ln(y) = %gx + %g", log (curve->a[1]), log (curve->a[0])));
+ curve->equation = (curve->a[0] < 0.)?
+ ((curve->a[1] < 0.)?
+ g_strdup_printf ("ln(y) = \xE2\x88\x92%gx \xE2\x88\x92 %g", -curve->a[1], -curve->a[0]):
+ g_strdup_printf ("ln(y) = %gx \xE2\x88\x92% g", curve->a[1], -curve->a[0])):
+ ((curve->a[1] < 0.)?
+ g_strdup_printf ("ln(y) = \xE2\x88\x92%gx + %g", -curve->a[1], curve->a[0]):
+ g_strdup_printf ("ln(y) = %gx + %g", curve->a[1], curve->a[0]));
else
- curve->equation = (curve->a[1] < 1.)?
- g_strdup_printf ("ln(y) = \xE2\x88\x92%gx", -log (curve->a[1])):
- g_strdup_printf ("ln(y) = %gx", log (curve->a[1]));
+ curve->equation = (curve->a[1] < 0.)?
+ g_strdup_printf ("ln(y) = \xE2\x88\x92%gx", -curve->a[1]):
+ g_strdup_printf ("ln(y) = %gx", curve->a[1]);
}
return curve->equation;
}
@@ -69,7 +69,7 @@ gog_exp_reg_curve_class_init (GogRegCurveClass *reg_curve_klass)
GogLinRegCurveClass *lin_reg_klass = (GogLinRegCurveClass *) reg_curve_klass;
GogObjectClass *gog_object_klass = (GogObjectClass *) reg_curve_klass;
- lin_reg_klass->lin_reg_func = go_exponential_regression;
+ lin_reg_klass->lin_reg_func = go_exponential_regression_as_log;
reg_curve_klass->get_value_at = gog_exp_reg_curve_get_value_at;
reg_curve_klass->get_equation = gog_exp_reg_curve_get_equation;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]