[gnumeric] Calculate residuals when using the regression tool. [#635064]
- From: Andreas J. Guelzow <guelzow src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnumeric] Calculate residuals when using the regression tool. [#635064]
- Date: Fri, 26 Nov 2010 02:03:05 +0000 (UTC)
commit 2e143616e2c5e5011200d5536ca53026277a4a70
Author: Andreas J Guelzow <aguelzow pyrshep ca>
Date: Thu Nov 25 18:58:19 2010 -0700
Calculate residuals when using the regression tool. [#635064]
2010-11-25 Andreas J. Guelzow <aguelzow pyrshep ca>
* analysis-tools.h (analysis_tools_data_regression_t): add field
* analysis-tools.c (calculate_n_obs): new
(analysis_tool_regression_engine_run): calculate residuals
(analysis_tool_regression_engine): allocate space for residuals
2010-11-25 Andreas J. Guelzow <aguelzow pyrshep ca>
* regression.ui: added residuals checkbox
* dialog-analysis-tools.c (RegressionToolState): add field
(regression_tool_ok_clicked_cb): handle residuals checkbox
(regression_tool_regression_radio_toggled_cb): ditto
(dialog_regression_tool): ditto
NEWS | 3 +
src/dialogs/ChangeLog | 8 +++
src/dialogs/dialog-analysis-tools.c | 22 +++++++-
src/dialogs/regression.ui | 15 +++++-
src/tools/ChangeLog | 8 +++
src/tools/analysis-tools.c | 89 +++++++++++++++++++++++++++++++++--
src/tools/analysis-tools.h | 4 +-
7 files changed, 138 insertions(+), 11 deletions(-)
---
diff --git a/NEWS b/NEWS
index f5508b1..db6e857 100644
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,8 @@
Gnumeric 1.10.13
+Andreas:
+ * Calculate residuals when using the regression tool. [#635064]
+
--------------------------------------------------------------------------
Gnumeric 1.10.12
diff --git a/src/dialogs/ChangeLog b/src/dialogs/ChangeLog
index ecd1e1f..80f3ae0 100644
--- a/src/dialogs/ChangeLog
+++ b/src/dialogs/ChangeLog
@@ -1,3 +1,11 @@
+2010-11-25 Andreas J. Guelzow <aguelzow pyrshep ca>
+
+ * regression.ui: added residuals checkbox
+ * dialog-analysis-tools.c (RegressionToolState): add field
+ (regression_tool_ok_clicked_cb): handle residuals checkbox
+ (regression_tool_regression_radio_toggled_cb): ditto
+ (dialog_regression_tool): ditto
+
2010-11-25 Morten Welinder <terra gnome org>
* Release 1.10.12
diff --git a/src/dialogs/dialog-analysis-tools.c b/src/dialogs/dialog-analysis-tools.c
index ce760df..6c81b84 100644
--- a/src/dialogs/dialog-analysis-tools.c
+++ b/src/dialogs/dialog-analysis-tools.c
@@ -235,6 +235,7 @@ typedef struct {
GtkWidget *confidence_entry;
GtkWidget *simple_linear_regression_radio;
GtkWidget *switch_variables_check;
+ GtkWidget *residuals_check;
} RegressionToolState;
typedef struct {
@@ -2180,7 +2181,10 @@ regression_tool_ok_clicked_cb (G_GNUC_UNUSED GtkWidget *button,
data->base.alpha = 1 - confidence;
w = go_gtk_builder_get_widget (state->base.gui, "intercept-button");
- data->intercept = 1 - gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w));
+ data->intercept = !gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w));
+
+ data->residual = gtk_toggle_button_get_active
+ (GTK_TOGGLE_BUTTON (state->residuals_check));
data->multiple_regression
= !gtk_toggle_button_get_active
@@ -2332,11 +2336,17 @@ regression_tool_regression_radio_toggled_cb (G_GNUC_UNUSED
GtkToggleButton *togglebutton,
RegressionToolState *state)
{
- if (!gtk_toggle_button_get_active
- (GTK_TOGGLE_BUTTON (state->simple_linear_regression_radio)))
+ gboolean simple = gtk_toggle_button_get_active
+ (GTK_TOGGLE_BUTTON (state->simple_linear_regression_radio));
+ if (!simple)
gtk_toggle_button_set_active
(GTK_TOGGLE_BUTTON (state->switch_variables_check),
FALSE);
+
+ gtk_toggle_button_set_active
+ (GTK_TOGGLE_BUTTON (state->residuals_check), !simple);
+ gtk_widget_set_sensitive (state->residuals_check, !simple);
+
}
static void
@@ -2422,12 +2432,18 @@ dialog_regression_tool (WBCGtk *wbcg, Sheet *sheet)
state->switch_variables_check
= go_gtk_builder_get_widget
(state->base.gui, "multiple-independent-check");
+ state->residuals_check
+ = go_gtk_builder_get_widget
+ (state->base.gui, "residuals-button");
gtk_toggle_button_set_active
(GTK_TOGGLE_BUTTON (state->simple_linear_regression_radio),
FALSE);
gtk_toggle_button_set_active
(GTK_TOGGLE_BUTTON (state->switch_variables_check),
FALSE);
+ gtk_toggle_button_set_active
+ (GTK_TOGGLE_BUTTON (state->residuals_check),
+ TRUE);
g_signal_connect
(G_OBJECT (state->simple_linear_regression_radio),
"toggled",
diff --git a/src/dialogs/regression.ui b/src/dialogs/regression.ui
index 66c3b18..73b8ac5 100644
--- a/src/dialogs/regression.ui
+++ b/src/dialogs/regression.ui
@@ -9,7 +9,6 @@
<child internal-child="vbox">
<object class="GtkVBox" id="vbox1">
<property name="visible">True</property>
- <property name="orientation">vertical</property>
<property name="spacing">8</property>
<child>
<object class="GtkNotebook" id="notebook1">
@@ -163,7 +162,6 @@
<object class="GtkVBox" id="vbox2">
<property name="visible">True</property>
<property name="border_width">12</property>
- <property name="orientation">vertical</property>
<child>
<object class="GtkHBox" id="hbox1">
<property name="visible">True</property>
@@ -214,7 +212,18 @@
</packing>
</child>
<child>
- <placeholder/>
+ <object class="GtkCheckButton" id="residuals-button">
+ <property name="label" translatable="yes">Calculate residuals</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="border_width">3</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">2</property>
+ </packing>
</child>
<child>
<placeholder/>
diff --git a/src/tools/ChangeLog b/src/tools/ChangeLog
index 2733981..ddaf13c 100644
--- a/src/tools/ChangeLog
+++ b/src/tools/ChangeLog
@@ -1,3 +1,11 @@
+<<<<<<< HEAD
+2010-11-25 Andreas J. Guelzow <aguelzow pyrshep ca>
+
+ * analysis-tools.h (analysis_tools_data_regression_t): add field
+ * analysis-tools.c (calculate_n_obs): new
+ (analysis_tool_regression_engine_run): calculate residuals
+ (analysis_tool_regression_engine): allocate space for residuals
+
2010-11-25 Morten Welinder <terra gnome org>
* Release 1.10.12
diff --git a/src/tools/analysis-tools.c b/src/tools/analysis-tools.c
index 5723e7f..1d3831d 100644
--- a/src/tools/analysis-tools.c
+++ b/src/tools/analysis-tools.c
@@ -2820,6 +2820,22 @@ calculate_xdim (GnmValue *input, group_by_t group_by)
return range_width (&r);
}
+static gint
+calculate_n_obs (GnmValue *input, group_by_t group_by)
+{
+ GnmRange r;
+
+ g_return_val_if_fail (input != NULL, 0);
+
+ if (NULL == range_init_value (&r, input))
+ return 0;
+
+ if (group_by == GROUPED_BY_ROW)
+ return range_width (&r);
+
+ return range_height (&r);
+}
+
static gboolean
analysis_tool_regression_engine_run (data_analysis_output_t *dao,
@@ -2859,6 +2875,7 @@ analysis_tool_regression_engine_run (data_analysis_output_t *dao,
GnmFunc *fd_concatenate = NULL;
GnmFunc *fd_cell = NULL;
GnmFunc *fd_offset = NULL;
+ GnmFunc *fd_sumproduct = NULL;
char const *str = ((info->group_by == GROUPED_BY_ROW) ? "row" : "col");
char const *label = ((info->group_by == GROUPED_BY_ROW) ? _("Row")
@@ -2870,6 +2887,8 @@ analysis_tool_regression_engine_run (data_analysis_output_t *dao,
fd_cell = analysis_tool_get_function ("CELL", dao);
fd_offset = analysis_tool_get_function ("OFFSET", dao);
}
+ if (info->residual)
+ fd_sumproduct = analysis_tool_get_function ("SUMPRODUCT", dao);
cb_adjust_areas (val_1, NULL);
cb_adjust_areas (val_2, NULL);
@@ -3253,11 +3272,59 @@ analysis_tool_regression_engine_run (data_analysis_output_t *dao,
gnm_expr_free (expr_lower);
gnm_expr_free (expr_upper);
- value_release (val_1);
- value_release (val_2);
value_release (val_1_cp);
value_release (val_2_cp);
+ if (info->residual) {
+ gint n_obs = calculate_n_obs (val_1, info->group_by);
+ GnmExpr const *expr_diff;
+ GnmExpr const *expr_prediction;
+
+ dao->offset_row += xdim + 1;
+ dao_set_italic (dao, 0, 0, xdim + 3, 0);
+ dao_set_array_expr (dao, 0, 0, xdim, 1,
+ gnm_expr_new_funcall1
+ (fd_transpose,
+ make_rangeref (0, - xdim - 1, 0, -2)));
+ set_cell_text_row (dao, xdim, 0, _("/Prediction"
+ "/"
+ "/Residual"));
+ dao_set_cell_expr (dao, xdim + 1, 0, make_cellref (2 - xdim, - 18 - xdim));
+ if (info->group_by == GROUPED_BY_ROW) {
+ dao_set_array_expr (dao, 0, 1, xdim, n_obs,
+ gnm_expr_new_funcall1
+ (fd_transpose,
+ gnm_expr_new_constant (val_1)));
+ dao_set_array_expr (dao, xdim + 1, 1, 1, n_obs,
+ gnm_expr_new_funcall1
+ (fd_transpose,
+ gnm_expr_new_constant (val_2)));
+ } else {
+ dao_set_array_expr (dao, 0, 1, xdim, n_obs,
+ gnm_expr_new_constant (val_1));
+ dao_set_array_expr (dao, xdim + 1, 1, 1, n_obs,
+ gnm_expr_new_constant (val_2));
+ }
+
+ expr_prediction = gnm_expr_new_binary
+ (gnm_expr_new_funcall2 (fd_sumproduct,
+ dao_get_rangeref (dao, 1, - 1 - xdim, 1, - 2),
+ gnm_expr_new_funcall1
+ (fd_transpose, make_rangeref (- xdim, 0, -1, 0))),
+ GNM_EXPR_OP_ADD, dao_get_cellref (dao, 1, - 2 - xdim));
+ expr_diff = gnm_expr_new_binary (make_cellref (-1, 0), GNM_EXPR_OP_SUB,make_cellref (-2, 0));
+
+ for (i = 0; i < n_obs; i++) {
+ dao_set_cell_expr (dao, xdim, i + 1, gnm_expr_copy (expr_prediction));
+ dao_set_cell_expr (dao, xdim + 2, i + 1, gnm_expr_copy (expr_diff));
+ }
+ gnm_expr_free (expr_diff);
+ gnm_expr_free (expr_prediction);
+ } else {
+ value_release (val_1);
+ value_release (val_2);
+ }
+
gnm_func_unref (fd_linest);
gnm_func_unref (fd_index);
gnm_func_unref (fd_fdist);
@@ -3273,6 +3340,8 @@ analysis_tool_regression_engine_run (data_analysis_output_t *dao,
gnm_func_unref (fd_cell);
if (fd_offset != NULL)
gnm_func_unref (fd_offset);
+ if (fd_sumproduct != NULL)
+ gnm_func_unref (fd_sumproduct);
dao_redraw_respan (dao);
@@ -3404,16 +3473,28 @@ analysis_tool_regression_engine (data_analysis_output_t *dao, gpointer specs,
case TOOL_ENGINE_UPDATE_DAO:
{
gint xdim = calculate_xdim (info->base.range_1, info->group_by);
+ gint cols, rows;
if (info->multiple_regression) {
+ cols = 7;
+ rows = 17 + xdim;
info->indep_vars = NULL;
- dao_adjust (dao, 7, 17 + xdim);
+ if (info->residual) {
+ gint residual_cols = xdim + 3;
+ GnmValue *val = info->base.range_1;
+
+ if (cols < residual_cols)
+ cols = residual_cols;
+ rows += 2 + calculate_n_obs (val, info->group_by);
+ }
} else {
info->indep_vars = g_slist_prepend (NULL, info->base.range_1);
info->base.range_1 = NULL;
prepare_input_range (&info->indep_vars, info->group_by);
- dao_adjust (dao, 6, 3 + xdim);
+ cols = 6;
+ rows = 3 + xdim;
}
+ dao_adjust (dao, cols, rows);
return FALSE;
}
case TOOL_ENGINE_CLEAN_UP:
diff --git a/src/tools/analysis-tools.h b/src/tools/analysis-tools.h
index 2d47b26..d323e2e 100644
--- a/src/tools/analysis-tools.h
+++ b/src/tools/analysis-tools.h
@@ -1,3 +1,4 @@
+/* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
#ifndef GNUMERIC_ANALYSIS_TOOLS_H
#define GNUMERIC_ANALYSIS_TOOLS_H
@@ -167,10 +168,11 @@ gboolean analysis_tool_ftest_engine (data_analysis_output_t *dao, gpointer specs
typedef struct {
analysis_tools_data_generic_b_t base;
- gint intercept;
group_by_t group_by;
+ gboolean intercept;
gboolean multiple_regression;
gboolean multiple_y;
+ gboolean residual;
GSList *indep_vars;
} analysis_tools_data_regression_t;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]