[gnumeric] Improve 2 factor ANOVA tool
- From: Andreas J. Guelzow <guelzow src gnome org>
- To: svn-commits-list gnome org
- Subject: [gnumeric] Improve 2 factor ANOVA tool
- Date: Fri, 5 Jun 2009 03:39:19 -0400 (EDT)
commit 7757016d7f7af9bd8146c72e69fa1bc366ce723e
Author: Andreas J. Guelzow <aguelzow pyrshep ca>
Date: Fri Jun 5 01:38:08 2009 -0600
Improve 2 factor ANOVA tool
2009-06-06 Andreas J. Guelzow <aguelzow pyrshep ca>
* Makefile.am: added analysis-anova.[ch]
* analysis-tools.h (analysis_tool_anova_two_factor_engine):
deleted
* analysis-tools.c (analysis_tool_anova_two_factor_engine):
deleted
(check_data_for_missing): deleted
(analysis_tool_anova_two_factor_prepare_input_range): deleted
(analysis_tool_anova_two_factor_no_rep_engine_run): deleted
(make_label): deleted
(analysis_tool_anova_two_factor_engine_run): deleted
(analysis_tool_anova_two_factor_engine_clean): moved to
analysis-anova.c
(analysis_tool_anova_two_factor_engine): ditto
* dao.h (dao_set_border): new
* dao.c (dao_set_border): new
* analysis-anova.[hc]:new
2009-06-06 Andreas J. Guelzow <aguelzow pyrshep ca>
* expr.h (gnm_expr_new_funcall5): new
* src/expr.c (gnm_expr_new_funcall5): new
2009-06-02 Andreas J. Guelzow <aguelzow pyrshep ca>
* POTFILES.in: added src/tools/analysis-anova.c
2009-06-06 Andreas J. Guelzow <aguelzow pyrshep ca>
* dialog-analysis-tools.c (dialog_anova_two_factor_tool): enable
formula/variable selector
---
ChangeLog | 5 +
NEWS | 1 +
po/ChangeLog | 4 +
po/POTFILES.in | 1 +
src/dialogs/ChangeLog | 5 +
src/dialogs/dialog-analysis-tools.c | 3 +-
src/expr.c | 17 +
src/expr.h | 6 +
src/tools/ChangeLog | 19 +
src/tools/Makefile.am | 2 +
src/tools/analysis-anova.c | 865 +++++++++++++++++++++++++++++++++++
src/tools/analysis-anova.h | 56 +++
src/tools/analysis-tools.c | 700 +----------------------------
src/tools/analysis-tools.h | 37 +--
src/tools/dao.c | 30 ++
src/tools/dao.h | 8 +
16 files changed, 1027 insertions(+), 732 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 84f057e..35fe21b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2009-06-06 Andreas J. Guelzow <aguelzow pyrshep ca>
+
+ * expr.h (gnm_expr_new_funcall5): new
+ * src/expr.c (gnm_expr_new_funcall5): new
+
2009-06-04 Morten Welinder <terra gnome org>
* src/sheet.c (cb_set_cell_content): Fix critical when overwriting
diff --git a/NEWS b/NEWS
index 277b353..340dc0a 100644
--- a/NEWS
+++ b/NEWS
@@ -6,6 +6,7 @@ Andreas:
* Remove distinction between label and filled rectangle.
* Add superscipt and subscript buttons. [#583327]
* Improve ODF import.
+ * Improve 2 factor ANOVA tool
Morten:
* Add search-for-number.
diff --git a/po/ChangeLog b/po/ChangeLog
index 06b9f8d..3a9f72d 100644
--- a/po/ChangeLog
+++ b/po/ChangeLog
@@ -1,3 +1,7 @@
+2009-06-02 Andreas J. Guelzow <aguelzow pyrshep ca>
+
+ * POTFILES.in: added src/tools/analysis-anova.c
+
2009-05-23 Morten Welinder <terra gnome org>
* Release 1.9.8
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 1d02c5e..5857d86 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -299,6 +299,7 @@ src/stf-parse.c
src/stf.c
src/style.c
src/test-pango.c
+src/tools/analysis-anova.c
src/tools/analysis-exp-smoothing.c
src/tools/analysis-frequency.c
src/tools/analysis-histogram.c
diff --git a/src/dialogs/ChangeLog b/src/dialogs/ChangeLog
index 33d6059..8971513 100644
--- a/src/dialogs/ChangeLog
+++ b/src/dialogs/ChangeLog
@@ -1,3 +1,8 @@
+2009-06-06 Andreas J. Guelzow <aguelzow pyrshep ca>
+
+ * dialog-analysis-tools.c (dialog_anova_two_factor_tool): enable
+ formula/variable selector
+
2009-06-03 Andreas J. Guelzow <aguelzow pyrshep ca>
* dialog-analysis-tools.c (dialog_ranking_tool): enable formula/variable
diff --git a/src/dialogs/dialog-analysis-tools.c b/src/dialogs/dialog-analysis-tools.c
index 8391133..7eb5bdc 100644
--- a/src/dialogs/dialog-analysis-tools.c
+++ b/src/dialogs/dialog-analysis-tools.c
@@ -28,6 +28,7 @@
#include <gnumeric.h>
#include "dialogs.h"
#include "analysis-tools.h"
+#include "analysis-anova.h"
#include "analysis-histogram.h"
#include "analysis-exp-smoothing.h"
@@ -3604,7 +3605,7 @@ dialog_anova_two_factor_tool (WBCGtk *wbcg, Sheet *sheet)
gnumeric_editable_enters (GTK_WINDOW (state->base.dialog),
GTK_WIDGET (state->replication_entry));
- gnm_dao_set_put (GNM_DAO (state->base.gdao), FALSE, FALSE);
+ gnm_dao_set_put (GNM_DAO (state->base.gdao), TRUE, TRUE);
anova_two_factor_tool_update_sensitivity_cb (NULL, state);
tool_load_selection ((GenericToolState *)state, FALSE);
diff --git a/src/expr.c b/src/expr.c
index b11f91a..c836c56 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -169,6 +169,23 @@ gnm_expr_new_funcall4 (GnmFunc *func,
return gnm_expr_new_funcallv (func, 4, argv);
}
+GnmExpr const *
+gnm_expr_new_funcall5 (GnmFunc *func,
+ GnmExpr const *arg0,
+ GnmExpr const *arg1,
+ GnmExpr const *arg2,
+ GnmExpr const *arg3,
+ GnmExpr const *arg4)
+{
+ GnmExprConstPtr *argv = g_new (GnmExprConstPtr, 5);
+ argv[0] = arg0;
+ argv[1] = arg1;
+ argv[2] = arg2;
+ argv[3] = arg3;
+ argv[4] = arg4;
+ return gnm_expr_new_funcallv (func, 5, argv);
+}
+
/***************************************************************************/
diff --git a/src/expr.h b/src/expr.h
index 6ee851f..c99e48b 100644
--- a/src/expr.h
+++ b/src/expr.h
@@ -68,6 +68,12 @@ GnmExpr const *gnm_expr_new_funcall4 (GnmFunc *func,
GnmExpr const *arg1,
GnmExpr const *arg2,
GnmExpr const *arg3);
+GnmExpr const *gnm_expr_new_funcall5 (GnmFunc *func,
+ GnmExpr const *arg0,
+ GnmExpr const *arg1,
+ GnmExpr const *arg2,
+ GnmExpr const *arg3,
+ GnmExpr const *arg4);
GnmExpr const *gnm_expr_new_name (GnmNamedExpr *name,
Sheet *sheet_scope, Workbook *wb_scope);
GnmExpr const *gnm_expr_new_cellref (GnmCellRef const *cr);
diff --git a/src/tools/ChangeLog b/src/tools/ChangeLog
index 06d887c..2af4cc2 100644
--- a/src/tools/ChangeLog
+++ b/src/tools/ChangeLog
@@ -1,3 +1,22 @@
+2009-06-06 Andreas J. Guelzow <aguelzow pyrshep ca>
+
+ * Makefile.am: added analysis-anova.[ch]
+ * analysis-tools.h (analysis_tool_anova_two_factor_engine):
+ deleted
+ * analysis-tools.c (analysis_tool_anova_two_factor_engine):
+ deleted
+ (check_data_for_missing): deleted
+ (analysis_tool_anova_two_factor_prepare_input_range): deleted
+ (analysis_tool_anova_two_factor_no_rep_engine_run): deleted
+ (make_label): deleted
+ (analysis_tool_anova_two_factor_engine_run): deleted
+ (analysis_tool_anova_two_factor_engine_clean): moved to
+ analysis-anova.c
+ (analysis_tool_anova_two_factor_engine): ditto
+ * dao.h (dao_set_border): new
+ * dao.c (dao_set_border): new
+ * analysis-anova.[hc]:new
+
2009-06-03 Andreas J. Guelzow <aguelzow pyrshep ca>
* analysis-tools.c (analysis_tool_calc_length): also handle
diff --git a/src/tools/Makefile.am b/src/tools/Makefile.am
index f740151..e2af808 100644
--- a/src/tools/Makefile.am
+++ b/src/tools/Makefile.am
@@ -19,6 +19,8 @@ AM_CPPFLAGS = \
noinst_LTLIBRARIES = libtools.la
libtools_la_SOURCES = \
+ analysis-anova.c \
+ analysis-anova.h \
analysis-exp-smoothing.c \
analysis-exp-smoothing.h \
analysis-frequency.c \
diff --git a/src/tools/analysis-anova.c b/src/tools/analysis-anova.c
new file mode 100644
index 0000000..4cda737
--- /dev/null
+++ b/src/tools/analysis-anova.c
@@ -0,0 +1,865 @@
+/* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * analysis-anova.c:
+ *
+ *
+ * Author:
+ * Andreas J. Guelzow <aguelzow pyrshep ca>
+ *
+ * (C) Copyright 2009 by Andreas J. Guelzow <aguelzow pyrshep ca>
+ *
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <gnumeric-config.h>
+#include <glib/gi18n-lib.h>
+#include "gnumeric.h"
+#include "analysis-anova.h"
+#include "analysis-tools.h"
+#include "value.h"
+#include "ranges.h"
+#include "expr.h"
+#include "func.h"
+#include "numbers.h"
+#include "mstyle.h"
+#include "style-border.h"
+#include "style-color.h"
+
+
+static gboolean
+analysis_tool_anova_two_factor_prepare_input_range (
+ analysis_tools_data_anova_two_factor_t *info)
+{
+ info->rows = info->input->v_range.cell.b.row - info->input->v_range.cell.a.row +
+ (info->labels ? 0 : 1);
+ info->n_r = info->rows/info->replication;
+ info->n_c = info->input->v_range.cell.b.col - info->input->v_range.cell.a.col +
+ (info->labels ? 0 : 1);
+
+ /* Check that correct number of rows per sample */
+ if (info->rows % info->replication != 0) {
+ info->err = analysis_tools_replication_invalid;
+ return TRUE;
+ }
+
+ /* Check that at least two columns of data are given */
+ if (info->n_c < 2) {
+ info->err = analysis_tools_too_few_cols;
+ return TRUE;
+ }
+ /* Check that at least two data rows of data are given */
+ if (info->n_r < 2) {
+ info->err = analysis_tools_too_few_rows;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/************* Anova: Two-Factor Without Replication Tool ****************
+ *
+ * The results are given in a table which can be printed out in a new
+ * sheet, in a new workbook, or simply into an existing sheet.
+ *
+ **/
+
+static gboolean
+analysis_tool_anova_two_factor_no_rep_engine_run (data_analysis_output_t *dao,
+ analysis_tools_data_anova_two_factor_t *info)
+{
+ int i, r;
+ GnmExpr const *expr_check;
+ GnmExpr const *expr_region;
+
+ GnmFunc *fd_index;
+ GnmFunc *fd_offset;
+ GnmFunc *fd_count;
+ GnmFunc *fd_sum;
+ GnmFunc *fd_sumsq;
+ GnmFunc *fd_average;
+ GnmFunc *fd_var;
+ GnmFunc *fd_if;
+ GnmFunc *fd_fdist;
+ GnmFunc *fd_finv;
+
+ fd_index = gnm_func_lookup ("INDEX", NULL);
+ gnm_func_ref (fd_index);
+ fd_offset = gnm_func_lookup ("OFFSET", NULL);
+ gnm_func_ref (fd_offset);
+ fd_count = gnm_func_lookup ("COUNT", NULL);
+ gnm_func_ref (fd_count);
+ fd_sum = gnm_func_lookup ("SUM", NULL);
+ gnm_func_ref (fd_sum);
+ fd_sumsq = gnm_func_lookup ("SUMSQ", NULL);
+ gnm_func_ref (fd_sumsq);
+ fd_average = gnm_func_lookup ("AVERAGE", NULL);
+ gnm_func_ref (fd_average);
+ fd_var = gnm_func_lookup ("VAR", NULL);
+ gnm_func_ref (fd_var);
+ fd_if = gnm_func_lookup ("IF", NULL);
+ gnm_func_ref (fd_if);
+ fd_fdist = gnm_func_lookup ("FDIST", NULL);
+ gnm_func_ref (fd_fdist);
+ fd_finv = gnm_func_lookup ("FINV", NULL);
+ gnm_func_ref (fd_finv);
+
+ dao_set_merge (dao, 0, 0, 4, 0);
+ dao_set_italic (dao, 0, 0, 0, 0);
+ dao_set_cell (dao, 0, 0, _("Anova: Two-Factor Without Replication"));
+ dao_set_italic (dao, 0, 2, 4, 2);
+ set_cell_text_row (dao, 0, 2, _("/Summary"
+ "/Count"
+ "/Sum"
+ "/Average"
+ "/Variance"));
+ r = 3;
+
+ for (i = 1; i <= info->n_r; i++, r++) {
+ GnmExpr const *expr_source;
+ dao_set_italic (dao, 0, r, 0, r);
+ if (info->labels) {
+ GnmExpr const *expr_label;
+ expr_label = gnm_expr_new_funcall3
+ (fd_index,
+ gnm_expr_new_constant (value_dup (info->input)),
+ gnm_expr_new_constant (value_new_int (i+1)),
+ gnm_expr_new_constant (value_new_int (1)));
+ dao_set_cell_expr (dao, 0, r, expr_label);
+ expr_source = gnm_expr_new_funcall5
+ (fd_offset,
+ gnm_expr_new_constant (value_dup (info->input)),
+ gnm_expr_new_constant (value_new_int (i)),
+ gnm_expr_new_constant (value_new_int (1)),
+ gnm_expr_new_constant (value_new_int (1)),
+ gnm_expr_new_constant (value_new_int (info->n_c)));
+ } else {
+ dao_set_cell_printf (dao, 0, r, _("Row %i"), i);
+ expr_source = gnm_expr_new_funcall4
+ (fd_offset,
+ gnm_expr_new_constant (value_dup (info->input)),
+ gnm_expr_new_constant (value_new_int (i-1)),
+ gnm_expr_new_constant (value_new_int (0)),
+ gnm_expr_new_constant (value_new_int (1)));
+ }
+ dao_set_cell_expr (dao, 1, r, gnm_expr_new_funcall1
+ (fd_count, gnm_expr_copy (expr_source)));
+ dao_set_cell_expr (dao, 2, r, gnm_expr_new_funcall1
+ (fd_sum, gnm_expr_copy (expr_source)));
+ dao_set_cell_expr (dao, 3, r, gnm_expr_new_funcall1
+ (fd_average, gnm_expr_copy (expr_source)));
+ dao_set_cell_expr (dao, 4, r, gnm_expr_new_funcall1
+ (fd_var, expr_source));
+ }
+
+ r++;
+
+ for (i = 1; i <= info->n_c; i++, r++) {
+ GnmExpr const *expr_source;
+ dao_set_italic (dao, 0, r, 0, r);
+ if (info->labels) {
+ GnmExpr const *expr_label;
+ expr_label = gnm_expr_new_funcall3
+ (fd_index,
+ gnm_expr_new_constant (value_dup (info->input)),
+ gnm_expr_new_constant (value_new_int (1)),
+ gnm_expr_new_constant (value_new_int (i+1)));
+ dao_set_cell_expr (dao, 0, r, expr_label);
+ expr_source = gnm_expr_new_funcall5
+ (fd_offset,
+ gnm_expr_new_constant (value_dup (info->input)),
+ gnm_expr_new_constant (value_new_int (1)),
+ gnm_expr_new_constant (value_new_int (i)),
+ gnm_expr_new_constant (value_new_int (info->n_r)),
+ gnm_expr_new_constant (value_new_int (1)));
+ } else {
+ dao_set_cell_printf (dao, 0, r, _("Column %i"), i);
+ expr_source = gnm_expr_new_funcall5
+ (fd_offset,
+ gnm_expr_new_constant (value_dup (info->input)),
+ gnm_expr_new_constant (value_new_int (0)),
+ gnm_expr_new_constant (value_new_int (i-1)),
+ gnm_expr_new_constant (value_new_int (info->n_r)),
+ gnm_expr_new_constant (value_new_int (1)));
+ }
+ dao_set_cell_expr (dao, 1, r, gnm_expr_new_funcall1
+ (fd_count, gnm_expr_copy (expr_source)));
+ dao_set_cell_expr (dao, 2, r, gnm_expr_new_funcall1
+ (fd_sum, gnm_expr_copy (expr_source)));
+ dao_set_cell_expr (dao, 3, r, gnm_expr_new_funcall1
+ (fd_average, gnm_expr_copy (expr_source)));
+ dao_set_cell_expr (dao, 4, r, gnm_expr_new_funcall1
+ (fd_var, expr_source));
+ }
+
+ r += 2;
+
+ dao_set_merge (dao, 0, r, 6, r);
+ dao_set_italic (dao, 0, r, 6, r);
+
+ if (info->labels)
+ expr_region = gnm_expr_new_funcall5
+ (fd_offset,
+ gnm_expr_new_constant (value_dup (info->input)),
+ gnm_expr_new_constant (value_new_int (1)),
+ gnm_expr_new_constant (value_new_int (1)),
+ gnm_expr_new_constant (value_new_int (info->n_r)),
+ gnm_expr_new_constant (value_new_int (info->n_c)));
+ else
+ expr_region = gnm_expr_new_constant (value_dup (info->input));
+
+ expr_check = gnm_expr_new_funcall3
+ (fd_if,
+ gnm_expr_new_binary
+ (gnm_expr_new_funcall1
+ (fd_count, gnm_expr_copy (expr_region)),
+ GNM_EXPR_OP_EQUAL,
+ gnm_expr_new_constant (value_new_int (info->n_r*info->n_c))),
+ gnm_expr_new_constant (value_new_int (1)),
+ gnm_expr_new_constant (value_new_int (-1)));
+ dao_set_cell_expr (dao, 0, r, expr_check);
+ dao_set_format (dao, 0, r, 0, r,
+ _("\"ANOVA\";[Red]\"Invalid ANOVA: Missing Observations\""));
+ dao_set_align (dao, 0, r, 0, r, HALIGN_LEFT, VALIGN_BOTTOM);
+
+ r++;
+ dao_set_italic (dao, 0, r, 0, r + 4);
+ set_cell_text_col (dao, 0, r, _("/Source of Variation"
+ "/Rows"
+ "/Columns"
+ "/Error"
+ "/Total"));
+ dao_set_italic (dao, 1, r, 6, r);
+ dao_set_border (dao, 0, r, 6, r, MSTYLE_BORDER_BOTTOM, GNM_STYLE_BORDER_THICK,
+ style_color_black (), GNM_STYLE_BORDER_HORIZ);
+ dao_set_border (dao, 0, r+3, 6, r+3, MSTYLE_BORDER_BOTTOM, GNM_STYLE_BORDER_THICK,
+ style_color_black (), GNM_STYLE_BORDER_HORIZ);
+ set_cell_text_row (dao, 1, r, _("/SS"
+ "/df"
+ "/MS"
+ "/F"
+ "/P-value"
+ "/F critical"));
+
+ dao->offset_col += 1;
+ dao->offset_row += r + 1;
+
+ if (dao_cell_is_visible (dao, 5, 2)) {
+ char *cc;
+ GnmExprList *args;
+
+ GnmExpr const *expr_ms;
+ GnmExpr const *expr_total;
+ GnmExpr const *expr_a;
+ GnmExpr const *expr_b;
+ GnmExpr const *expr_t;
+ GnmExpr const *expr_cf;
+
+ expr_t = gnm_expr_new_funcall1 (fd_sumsq, gnm_expr_copy (expr_region));
+ expr_cf = gnm_expr_new_binary
+ (gnm_expr_new_binary
+ (gnm_expr_new_funcall1 (fd_sum, gnm_expr_copy (expr_region)),
+ GNM_EXPR_OP_EXP,
+ gnm_expr_new_constant (value_new_int (2))),
+ GNM_EXPR_OP_DIV,
+ gnm_expr_new_funcall1 (fd_count, gnm_expr_copy (expr_region)));
+
+ args = NULL;
+ for (i = 1; i <= info->n_r; i++) {
+ GnmExpr const *expr;
+ expr = gnm_expr_new_funcall1
+ (fd_sum,
+ gnm_expr_new_funcall5
+ (fd_offset,
+ gnm_expr_new_constant (value_dup (info->input)),
+ gnm_expr_new_constant (value_new_int
+ ((info->labels)?i:(i-1))),
+ gnm_expr_new_constant (value_new_int
+ ((info->labels)?1:0)),
+ gnm_expr_new_constant (value_new_int (1)),
+ gnm_expr_new_constant (value_new_int (info->n_c))));
+ args = gnm_expr_list_prepend (args, expr);
+ }
+ expr_a = gnm_expr_new_binary
+ (gnm_expr_new_funcall (fd_sumsq, args), GNM_EXPR_OP_DIV,
+ gnm_expr_new_constant (value_new_int (info->n_c)));
+
+ args = NULL;
+ for (i = 1; i <= info->n_c; i++) {
+ GnmExpr const *expr;
+ expr = gnm_expr_new_funcall1
+ (fd_sum,
+ gnm_expr_new_funcall5
+ (fd_offset,
+ gnm_expr_new_constant (value_dup (info->input)),
+ gnm_expr_new_constant (value_new_int
+ ((info->labels)?1:0)),
+ gnm_expr_new_constant (value_new_int
+ ((info->labels)?i:(i-1))),
+ gnm_expr_new_constant (value_new_int (info->n_r)),
+ gnm_expr_new_constant (value_new_int (1))));
+ args = gnm_expr_list_prepend (args, expr);
+ }
+ expr_b = gnm_expr_new_binary
+ (gnm_expr_new_funcall (fd_sumsq, args), GNM_EXPR_OP_DIV,
+ gnm_expr_new_constant (value_new_int (info->n_r)));
+
+ dao_set_cell_expr (dao, 0, 0, gnm_expr_new_binary
+ (gnm_expr_copy (expr_a), GNM_EXPR_OP_SUB,
+ gnm_expr_copy (expr_cf)));
+ dao_set_cell_expr (dao, 0, 1, gnm_expr_new_binary
+ (gnm_expr_copy (expr_b), GNM_EXPR_OP_SUB,
+ gnm_expr_copy (expr_cf)));
+ dao_set_cell_expr (dao, 0, 2, gnm_expr_new_binary
+ (gnm_expr_new_binary
+ (expr_t, GNM_EXPR_OP_ADD, expr_cf),
+ GNM_EXPR_OP_SUB ,
+ gnm_expr_new_binary
+ (expr_a, GNM_EXPR_OP_ADD, expr_b)));
+ expr_total = gnm_expr_new_funcall1
+ (fd_sum, make_rangeref (0, -3, 0, -1));
+ dao_set_cell_expr (dao, 0, 3, gnm_expr_copy (expr_total));
+ dao_set_cell_int (dao, 1, 0, info->n_r - 1);
+ dao_set_cell_int (dao, 1, 1, info->n_c - 1);
+ dao_set_cell_expr (dao, 1, 2, gnm_expr_new_binary
+ (make_cellref (0,-1), GNM_EXPR_OP_MULT,
+ make_cellref (0,-2)));
+ dao_set_cell_expr (dao, 1, 3, expr_total);
+
+ expr_ms = gnm_expr_new_binary (make_cellref (-2,0), GNM_EXPR_OP_DIV,
+ make_cellref (-1,0));
+ dao_set_cell_expr (dao, 2, 0, gnm_expr_copy (expr_ms));
+ dao_set_cell_expr (dao, 2, 1, gnm_expr_copy (expr_ms));
+ dao_set_cell_expr (dao, 2, 2, expr_ms);
+
+ dao_set_cell_expr (dao, 3, 0, gnm_expr_new_binary
+ (make_cellref (-1,0), GNM_EXPR_OP_DIV,
+ make_cellref (-1,2)));
+ dao_set_cell_expr (dao, 3, 1, gnm_expr_new_binary
+ (make_cellref (-1,0), GNM_EXPR_OP_DIV,
+ make_cellref (-1,1)));
+ dao_set_cell_expr
+ (dao, 4, 0,
+ gnm_expr_new_funcall3
+ (fd_fdist,
+ make_cellref (-1, 0),
+ make_cellref (-3, 0),
+ make_cellref (-3, 2)));
+ dao_set_cell_expr
+ (dao, 4, 1,
+ gnm_expr_new_funcall3
+ (fd_fdist,
+ make_cellref (-1, 0),
+ make_cellref (-3, 0),
+ make_cellref (-3, 1)));
+ dao_set_cell_expr
+ (dao, 5, 0,
+ gnm_expr_new_funcall3
+ (fd_finv,
+ gnm_expr_new_constant (value_new_float (info->alpha)),
+ make_cellref (-4, 0),
+ make_cellref (-4, 2)));
+ dao_set_cell_expr
+ (dao, 5, 1,
+ gnm_expr_new_funcall3
+ (fd_finv,
+ gnm_expr_new_constant (value_new_float (info->alpha)),
+ make_cellref (-4, 0),
+ make_cellref (-4, 1)));
+ cc = g_strdup_printf ("%s = %.2f", "\xce\xb1", info->alpha);
+ dao_set_cell_comment (dao, 5, 0, cc);
+ dao_set_cell_comment (dao, 5, 1, cc);
+ g_free (cc);
+ } else
+ dao_set_cell (dao, 0, 0, _("Insufficient space available for ANOVA table."));
+
+ gnm_func_unref (fd_index);
+ gnm_func_unref (fd_count);
+ gnm_func_unref (fd_offset);
+ gnm_func_unref (fd_sum);
+ gnm_func_unref (fd_sumsq);
+ gnm_func_unref (fd_average);
+ gnm_func_unref (fd_var);
+ gnm_func_unref (fd_if);
+ gnm_func_unref (fd_finv);
+ gnm_func_unref (fd_fdist);
+
+ gnm_expr_free (expr_region);
+
+ dao_redraw_respan (dao);
+
+ return FALSE;
+}
+
+
+/************* Anova: Two-Factor With Replication Tool *******************
+ *
+ * The results are given in a table which can be printed out in a new
+ * sheet, in a new workbook, or simply into an existing sheet.
+ *
+ **/
+
+
+static gboolean
+analysis_tool_anova_two_factor_engine_run (data_analysis_output_t *dao,
+ analysis_tools_data_anova_two_factor_t *info)
+{
+
+ int i, k, r;
+ GnmExpr const *expr_check;
+ GnmExpr const *expr_source;
+ GnmExpr const *expr_total_count;
+
+ GnmFunc *fd_index;
+ GnmFunc *fd_offset;
+ GnmFunc *fd_count;
+ GnmFunc *fd_sum;
+ GnmFunc *fd_sumsq;
+ GnmFunc *fd_average;
+ GnmFunc *fd_var;
+ GnmFunc *fd_if;
+ GnmFunc *fd_fdist;
+ GnmFunc *fd_finv;
+
+ fd_index = gnm_func_lookup ("INDEX", NULL);
+ gnm_func_ref (fd_index);
+ fd_offset = gnm_func_lookup ("OFFSET", NULL);
+ gnm_func_ref (fd_offset);
+ fd_count = gnm_func_lookup ("COUNT", NULL);
+ gnm_func_ref (fd_count);
+ fd_sum = gnm_func_lookup ("SUM", NULL);
+ gnm_func_ref (fd_sum);
+ fd_sumsq = gnm_func_lookup ("SUMSQ", NULL);
+ gnm_func_ref (fd_sumsq);
+ fd_average = gnm_func_lookup ("AVERAGE", NULL);
+ gnm_func_ref (fd_average);
+ fd_var = gnm_func_lookup ("VAR", NULL);
+ gnm_func_ref (fd_var);
+ fd_if = gnm_func_lookup ("IF", NULL);
+ gnm_func_ref (fd_if);
+ fd_fdist = gnm_func_lookup ("FDIST", NULL);
+ gnm_func_ref (fd_fdist);
+ fd_finv = gnm_func_lookup ("FINV", NULL);
+ gnm_func_ref (fd_finv);
+
+ dao_set_merge (dao, 0, 0, 4, 0);
+ dao_set_italic (dao, 0, 0, 0, 0);
+ dao_set_cell (dao, 0, 0, _("Anova: Two-Factor Fixed Effects With Replication"));
+ dao_set_italic (dao, 0, 2, info->n_c + 1, 2);
+ dao_set_cell (dao, 0, 2, _("Summary"));
+
+ for (k = 1; k <= info->n_c; k++) {
+ if (info->labels) {
+ GnmExpr const *expr_label;
+ expr_label = gnm_expr_new_funcall3
+ (fd_index,
+ gnm_expr_new_constant (value_dup (info->input)),
+ gnm_expr_new_constant (value_new_int (1)),
+ gnm_expr_new_constant (value_new_int (k+1)));
+ dao_set_cell_expr (dao, k, 2, expr_label);
+ } else
+ /*xgettext: this is a label for the first, second,... level of factor B in an ANOVA*/
+ dao_set_cell_printf (dao, k, 2, _("B, Level %i"), k);
+ }
+ dao_set_cell (dao, info->n_c + 1, 2, _("Subtotal"));
+
+ r = 3;
+ for (i = 1; i <= info->n_r; i++, r += 6) {
+ int level_start = (i-1)*info->replication + 1;
+
+ dao_set_italic (dao, 0, r, 0, r+4);
+ if (info->labels) {
+ GnmExpr const *expr_label;
+ expr_label = gnm_expr_new_funcall3
+ (fd_index,
+ gnm_expr_new_constant (value_dup (info->input)),
+ gnm_expr_new_constant (value_new_int (level_start + 1)),
+ gnm_expr_new_constant (value_new_int (1)));
+ dao_set_cell_expr (dao, 0, r, expr_label);
+ } else
+ /*xgettext: this is a label for the first, second,... level of factor A in an ANOVA*/
+ dao_set_cell_printf (dao, 0, r, _("A, Level %i"), i);
+ set_cell_text_col (dao, 0, r + 1, _("/Count"
+ "/Sum"
+ "/Average"
+ "/Variance"));
+ for (k = 1; k <= info->n_c; k++) {
+ expr_source = gnm_expr_new_funcall5
+ (fd_offset,
+ gnm_expr_new_constant (value_dup (info->input)),
+ gnm_expr_new_constant (value_new_int (level_start)),
+ gnm_expr_new_constant (value_new_int ((info->labels) ? k : (k - 1))),
+ gnm_expr_new_constant (value_new_int (info->replication)),
+ gnm_expr_new_constant (value_new_int (1)));
+ dao_set_cell_expr (dao, k, r + 1, gnm_expr_new_funcall1
+ (fd_count, gnm_expr_copy (expr_source)));
+ dao_set_cell_expr (dao, k, r + 2, gnm_expr_new_funcall1
+ (fd_sum, gnm_expr_copy (expr_source)));
+ dao_set_cell_expr (dao, k, r + 3, gnm_expr_new_funcall1
+ (fd_average, gnm_expr_copy (expr_source)));
+ dao_set_cell_expr (dao, k, r + 4, gnm_expr_new_funcall1
+ (fd_var, expr_source));
+ }
+
+ expr_source = gnm_expr_new_funcall5
+ (fd_offset,
+ gnm_expr_new_constant (value_dup (info->input)),
+ gnm_expr_new_constant (value_new_int (level_start)),
+ gnm_expr_new_constant (value_new_int ((info->labels) ? 1 : 0)),
+ gnm_expr_new_constant (value_new_int (info->replication)),
+ gnm_expr_new_constant (value_new_int (info->n_c)));
+ dao_set_cell_expr (dao, k, r + 1, gnm_expr_new_funcall1
+ (fd_count, gnm_expr_copy (expr_source)));
+ dao_set_cell_expr (dao, k, r + 2, gnm_expr_new_funcall1
+ (fd_sum, gnm_expr_copy (expr_source)));
+ dao_set_cell_expr (dao, k, r + 3, gnm_expr_new_funcall1
+ (fd_average, gnm_expr_copy (expr_source)));
+ dao_set_cell_expr (dao, k, r + 4, gnm_expr_new_funcall1
+ (fd_var, expr_source));
+ }
+
+ dao_set_italic (dao, 0, r, 0, r+4);
+ dao_set_cell (dao, 0, r, _("Subtotal"));
+ set_cell_text_col (dao, 0, r + 1, _("/Count"
+ "/Sum"
+ "/Average"
+ "/Variance"));
+
+ for (k = 1; k <= info->n_c; k++) {
+ expr_source = gnm_expr_new_funcall5
+ (fd_offset,
+ gnm_expr_new_constant (value_dup (info->input)),
+ gnm_expr_new_constant (value_new_int (1)),
+ gnm_expr_new_constant (value_new_int ((info->labels) ? k : (k - 1))),
+ gnm_expr_new_constant (value_new_int (info->replication * info->n_r)),
+ gnm_expr_new_constant (value_new_int (1)));
+ dao_set_cell_expr (dao, k, r + 1, gnm_expr_new_funcall1
+ (fd_count, gnm_expr_copy (expr_source)));
+ dao_set_cell_expr (dao, k, r + 2, gnm_expr_new_funcall1
+ (fd_sum, gnm_expr_copy (expr_source)));
+ dao_set_cell_expr (dao, k, r + 3, gnm_expr_new_funcall1
+ (fd_average, gnm_expr_copy (expr_source)));
+ dao_set_cell_expr (dao, k, r + 4, gnm_expr_new_funcall1
+ (fd_var, expr_source));
+ }
+
+ dao_set_italic (dao, info->n_c + 1, r, info->n_c + 1, r);
+ dao_set_cell (dao, info->n_c + 1, r, _("Total"));
+
+ expr_source = gnm_expr_new_funcall5
+ (fd_offset,
+ gnm_expr_new_constant (value_dup (info->input)),
+ gnm_expr_new_constant (value_new_int (1)),
+ gnm_expr_new_constant (value_new_int ((info->labels) ? 1 : (0))),
+ gnm_expr_new_constant (value_new_int (info->replication * info->n_r)),
+ gnm_expr_new_constant (value_new_int (info->n_c)));
+ expr_total_count = gnm_expr_new_funcall1 (fd_count, gnm_expr_copy (expr_source));
+ dao_set_cell_expr (dao, info->n_c + 1, r + 1, gnm_expr_copy (expr_total_count));
+ dao_set_cell_expr (dao, info->n_c + 1, r + 2, gnm_expr_new_funcall1
+ (fd_sum, gnm_expr_copy (expr_source)));
+ dao_set_cell_expr (dao, info->n_c + 1, r + 3, gnm_expr_new_funcall1
+ (fd_average, gnm_expr_copy (expr_source)));
+ dao_set_cell_expr (dao, info->n_c + 1, r + 4, gnm_expr_new_funcall1
+ (fd_var, gnm_expr_copy (expr_source)));
+
+ r += 7;
+
+ dao_set_merge (dao, 0, r, 6, r);
+ dao_set_italic (dao, 0, r, 6, r);
+
+ expr_check = gnm_expr_new_funcall3
+ (fd_if,
+ gnm_expr_new_binary
+ (gnm_expr_copy (expr_total_count),
+ GNM_EXPR_OP_EQUAL,
+ gnm_expr_new_constant (value_new_int (info->n_r*info->n_c*info->replication))),
+ gnm_expr_new_constant (value_new_int (1)),
+ gnm_expr_new_constant (value_new_int (-1)));
+ dao_set_cell_expr (dao, 0, r, expr_check);
+ dao_set_format (dao, 0, r, 0, r,
+ _("\"ANOVA\";[Red]\"Invalid ANOVA: Missing Observations\""));
+ dao_set_align (dao, 0, r, 0, r, HALIGN_LEFT, VALIGN_BOTTOM);
+
+ r++;
+ dao_set_italic (dao, 0, r, 0, r + 5);
+ set_cell_text_col (dao, 0, r, _("/Source of Variation"
+ "/Factor A"
+ "/Factor B"
+ "/Interaction"
+ "/Error"
+ "/Total"));
+ dao_set_italic (dao, 1, r, 6, r);
+ dao_set_border (dao, 0, r, 6, r, MSTYLE_BORDER_BOTTOM, GNM_STYLE_BORDER_THICK,
+ style_color_black (), GNM_STYLE_BORDER_HORIZ);
+ dao_set_border (dao, 0, r+4, 6, r+4, MSTYLE_BORDER_BOTTOM, GNM_STYLE_BORDER_THICK,
+ style_color_black (), GNM_STYLE_BORDER_HORIZ);
+ set_cell_text_row (dao, 1, r, _("/SS"
+ "/df"
+ "/MS"
+ "/F"
+ "/P-value"
+ "/F critical"));
+
+ dao->offset_col += 1;
+ dao->offset_row += r + 1;
+
+ if (dao_cell_is_visible (dao, 5, 2)) {
+ char *cc;
+ GnmExprList *args;
+
+ GnmExpr const *expr_ms;
+ GnmExpr const *expr_total;
+ GnmExpr const *expr_a;
+ GnmExpr const *expr_b;
+ GnmExpr const *expr_t;
+ GnmExpr const *expr_s;
+ GnmExpr const *expr_cf;
+
+ expr_t = gnm_expr_new_funcall1 (fd_sumsq, gnm_expr_copy (expr_source));
+ expr_cf = gnm_expr_new_binary
+ (gnm_expr_new_binary
+ (gnm_expr_new_funcall1 (fd_sum, gnm_expr_copy (expr_source)),
+ GNM_EXPR_OP_EXP,
+ gnm_expr_new_constant (value_new_int (2))),
+ GNM_EXPR_OP_DIV,
+ gnm_expr_copy (expr_total_count));
+
+ args = NULL;
+ for (i = 1; i <= info->n_r; i++) {
+ GnmExpr const *expr;
+ int level_start = (i-1)*info->replication + 1;
+
+ expr = gnm_expr_new_funcall1
+ (fd_sum,
+ gnm_expr_new_funcall5
+ (fd_offset,
+ gnm_expr_new_constant (value_dup (info->input)),
+ gnm_expr_new_constant (value_new_int
+ ((info->labels)?level_start:(level_start-1))),
+ gnm_expr_new_constant (value_new_int
+ ((info->labels)?1:0)),
+ gnm_expr_new_constant (value_new_int (info->replication)),
+ gnm_expr_new_constant (value_new_int (info->n_c))));
+ args = gnm_expr_list_prepend (args, expr);
+ }
+ expr_a = gnm_expr_new_binary
+ (gnm_expr_new_funcall (fd_sumsq, args), GNM_EXPR_OP_DIV,
+ gnm_expr_new_constant (value_new_int (info->n_c * info->replication)));
+
+ args = NULL;
+ for (k = 1; k <= info->n_c; k++) {
+ GnmExpr const *expr;
+ expr = gnm_expr_new_funcall1
+ (fd_sum,
+ gnm_expr_new_funcall5
+ (fd_offset,
+ gnm_expr_new_constant (value_dup (info->input)),
+ gnm_expr_new_constant (value_new_int
+ ((info->labels)?1:0)),
+ gnm_expr_new_constant (value_new_int
+ ((info->labels)?k:(k-1))),
+ gnm_expr_new_constant (value_new_int (info->n_r * info->replication)),
+ gnm_expr_new_constant (value_new_int (1))));
+ args = gnm_expr_list_prepend (args, expr);
+ }
+ expr_b = gnm_expr_new_binary
+ (gnm_expr_new_funcall (fd_sumsq, args), GNM_EXPR_OP_DIV,
+ gnm_expr_new_constant (value_new_int (info->n_r * info->replication)));
+
+ args = NULL;
+ for (i = 1; i <= info->n_r; i++) {
+ int level_start = (i-1)*info->replication + 1;
+ for (k = 1; k <= info->n_c; k++) {
+ GnmExpr const *expr;
+ expr = gnm_expr_new_funcall1
+ (fd_sum,
+ gnm_expr_new_funcall5
+ (fd_offset,
+ gnm_expr_new_constant (value_dup (info->input)),
+ gnm_expr_new_constant
+ (value_new_int ((info->labels)?level_start:level_start-1)),
+ gnm_expr_new_constant (value_new_int
+ ((info->labels)?k:(k-1))),
+ gnm_expr_new_constant (value_new_int (info->replication)),
+ gnm_expr_new_constant (value_new_int (1))));
+ args = gnm_expr_list_prepend (args, expr);
+ }
+ }
+ expr_s = gnm_expr_new_binary
+ (gnm_expr_new_funcall (fd_sumsq, args), GNM_EXPR_OP_DIV,
+ gnm_expr_new_constant (value_new_int (info->replication)));
+
+ dao_set_cell_expr (dao, 0, 0, gnm_expr_new_binary
+ (gnm_expr_copy (expr_a), GNM_EXPR_OP_SUB,
+ gnm_expr_copy (expr_cf)));
+ dao_set_cell_expr (dao, 0, 1, gnm_expr_new_binary
+ (gnm_expr_copy (expr_b), GNM_EXPR_OP_SUB,
+ gnm_expr_copy (expr_cf)));
+ dao_set_cell_expr (dao, 0, 2, gnm_expr_new_binary
+ (gnm_expr_new_binary
+ (gnm_expr_copy (expr_s), GNM_EXPR_OP_ADD, expr_cf),
+ GNM_EXPR_OP_SUB ,
+ gnm_expr_new_binary
+ (expr_a, GNM_EXPR_OP_ADD, expr_b)));
+ dao_set_cell_expr (dao, 0, 3, gnm_expr_new_binary (expr_t, GNM_EXPR_OP_SUB, expr_s));
+ expr_total = gnm_expr_new_funcall1
+ (fd_sum, make_rangeref (0, -4, 0, -1));
+ dao_set_cell_expr (dao, 0, 4, gnm_expr_copy (expr_total));
+ dao_set_cell_int (dao, 1, 0, info->n_r - 1);
+ dao_set_cell_int (dao, 1, 1, info->n_c - 1);
+ dao_set_cell_expr (dao, 1, 2, gnm_expr_new_binary
+ (make_cellref (0,-1), GNM_EXPR_OP_MULT,
+ make_cellref (0,-2)));
+ dao_set_cell_int (dao, 1, 3, info->n_c*info->n_r*(info->replication - 1));
+ dao_set_cell_expr (dao, 1, 4, expr_total);
+
+ expr_ms = gnm_expr_new_binary (make_cellref (-2,0), GNM_EXPR_OP_DIV,
+ make_cellref (-1,0));
+ dao_set_cell_expr (dao, 2, 0, gnm_expr_copy (expr_ms));
+ dao_set_cell_expr (dao, 2, 1, gnm_expr_copy (expr_ms));
+ dao_set_cell_expr (dao, 2, 2, gnm_expr_copy (expr_ms));
+ dao_set_cell_expr (dao, 2, 3, expr_ms);
+
+ dao_set_cell_expr (dao, 3, 0, gnm_expr_new_binary
+ (make_cellref (-1,0), GNM_EXPR_OP_DIV,
+ make_cellref (-1,3)));
+ dao_set_cell_expr (dao, 3, 1, gnm_expr_new_binary
+ (make_cellref (-1,0), GNM_EXPR_OP_DIV,
+ make_cellref (-1,2)));
+ dao_set_cell_expr (dao, 3, 2, gnm_expr_new_binary
+ (make_cellref (-1,0), GNM_EXPR_OP_DIV,
+ make_cellref (-1,1)));
+ dao_set_cell_expr
+ (dao, 4, 0,
+ gnm_expr_new_funcall3
+ (fd_fdist,
+ make_cellref (-1, 0),
+ make_cellref (-3, 0),
+ make_cellref (-3, 3)));
+ dao_set_cell_expr
+ (dao, 4, 1,
+ gnm_expr_new_funcall3
+ (fd_fdist,
+ make_cellref (-1, 0),
+ make_cellref (-3, 0),
+ make_cellref (-3, 2)));
+ dao_set_cell_expr
+ (dao, 4, 2,
+ gnm_expr_new_funcall3
+ (fd_fdist,
+ make_cellref (-1, 0),
+ make_cellref (-3, 0),
+ make_cellref (-3, 1)));
+ dao_set_cell_expr
+ (dao, 5, 0,
+ gnm_expr_new_funcall3
+ (fd_finv,
+ gnm_expr_new_constant (value_new_float (info->alpha)),
+ make_cellref (-4, 0),
+ make_cellref (-4, 3)));
+ dao_set_cell_expr
+ (dao, 5, 1,
+ gnm_expr_new_funcall3
+ (fd_finv,
+ gnm_expr_new_constant (value_new_float (info->alpha)),
+ make_cellref (-4, 0),
+ make_cellref (-4, 2)));
+ dao_set_cell_expr
+ (dao, 5, 2,
+ gnm_expr_new_funcall3
+ (fd_finv,
+ gnm_expr_new_constant (value_new_float (info->alpha)),
+ make_cellref (-4, 0),
+ make_cellref (-4, 1)));
+ cc = g_strdup_printf ("%s = %.2f", "\xce\xb1", info->alpha);
+ dao_set_cell_comment (dao, 5, 0, cc);
+ dao_set_cell_comment (dao, 5, 1, cc);
+ dao_set_cell_comment (dao, 5, 2, cc);
+ g_free (cc);
+ } else
+ dao_set_cell (dao, 0, 0, _("Insufficient space available for ANOVA table."));
+
+ gnm_func_unref (fd_index);
+ gnm_func_unref (fd_count);
+ gnm_func_unref (fd_offset);
+ gnm_func_unref (fd_sum);
+ gnm_func_unref (fd_sumsq);
+ gnm_func_unref (fd_average);
+ gnm_func_unref (fd_var);
+ gnm_func_unref (fd_if);
+ gnm_func_unref (fd_finv);
+ gnm_func_unref (fd_fdist);
+
+ gnm_expr_free (expr_source);
+ gnm_expr_free (expr_total_count);
+
+ dao_redraw_respan (dao);
+
+ return FALSE;
+}
+
+static gboolean
+analysis_tool_anova_two_factor_engine_clean (G_GNUC_UNUSED data_analysis_output_t *dao,
+ gpointer specs)
+{
+ analysis_tools_data_anova_two_factor_t *info = specs;
+
+ if (info->input)
+ value_release (info->input);
+ info->input = NULL;
+
+ return FALSE;
+}
+
+gboolean
+analysis_tool_anova_two_factor_engine (data_analysis_output_t *dao, gpointer specs,
+ analysis_tool_engine_t selector, gpointer result)
+{
+ analysis_tools_data_anova_two_factor_t *info = specs;
+
+ switch (selector) {
+ case TOOL_ENGINE_UPDATE_DESCRIPTOR:
+ return (dao_command_descriptor (
+ dao, (info->replication == 1) ?
+ _("Two Factor ANOVA (%s), no replication") :
+ _("Two Factor ANOVA (%s), with replication") , result)
+ == NULL);
+ case TOOL_ENGINE_UPDATE_DAO:
+ if (analysis_tool_anova_two_factor_prepare_input_range (info))
+ return TRUE;
+ if (info->replication == 1)
+ dao_adjust (dao, 7, info->n_c + info->n_r + 12);
+ else
+ dao_adjust (dao, MAX (2 + info->n_c, 7), info->n_r * 6 + 18);
+ return FALSE;
+ case TOOL_ENGINE_CLEAN_UP:
+ return analysis_tool_anova_two_factor_engine_clean (dao, specs);
+ case TOOL_ENGINE_LAST_VALIDITY_CHECK:
+ return FALSE;
+ case TOOL_ENGINE_PREPARE_OUTPUT_RANGE:
+ dao_prepare_output (NULL, dao, _("Anova"));
+ return FALSE;
+ case TOOL_ENGINE_FORMAT_OUTPUT_RANGE:
+ return dao_format_output (dao, _("Two Factor ANOVA"));
+ case TOOL_ENGINE_PERFORM_CALC:
+ default:
+ if (info->replication == 1)
+ return analysis_tool_anova_two_factor_no_rep_engine_run (dao, info);
+ else
+ return analysis_tool_anova_two_factor_engine_run (dao, info);
+ }
+ return TRUE; /* We shouldn't get here */
+}
+
diff --git a/src/tools/analysis-anova.h b/src/tools/analysis-anova.h
new file mode 100644
index 0000000..14cf4cb
--- /dev/null
+++ b/src/tools/analysis-anova.h
@@ -0,0 +1,56 @@
+/* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * analysis-anova.h:
+ *
+ * Author:
+ * Andreas J. Guelzow <aguelzow pyrshep ca>
+ *
+ * (C) Copyright 2009 by Andreas J. Guelzow <aguelzow pyrshep ca>
+ *
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#ifndef ANALYSIS_ANOVA_H
+#define ANALYSIS_ANOVA_H
+
+#include "gnumeric.h"
+#include "numbers.h"
+#include "dao.h"
+#include "tools.h"
+#include "analysis-tools.h"
+
+/**************** 2-Factor ANOVA ***************/
+/*** with contingency table like data provision **/
+
+typedef struct {
+ analysis_tools_error_code_t err;
+ WorkbookControl *wbc;
+ GnmValue *input;
+ group_by_t group_by;
+ gboolean labels;
+ gnm_float alpha;
+ gint replication;
+ gint rows;
+ gint n_c;
+ gint n_r;
+} analysis_tools_data_anova_two_factor_t;
+
+gboolean analysis_tool_anova_two_factor_engine (data_analysis_output_t *dao, gpointer specs,
+ analysis_tool_engine_t selector, gpointer result);
+
+
+#endif
diff --git a/src/tools/analysis-tools.c b/src/tools/analysis-tools.c
index 4fe4b62..bfd863e 100644
--- a/src/tools/analysis-tools.c
+++ b/src/tools/analysis-tools.c
@@ -580,26 +580,6 @@ gnm_check_input_range_list_homogeneity (GSList *input_range)
return state.hom;
}
-/*
- * check_data_for_missing:
- * @data:
- *
- * Check whether any data is missing
- *
- */
-static gboolean
-check_data_for_missing (GPtrArray *data)
-{
- guint i;
-
- for (i = 0; i < data->len; i++) {
- data_set_t *this_data = g_ptr_array_index (data, i);
- if (this_data->missing != NULL)
- return TRUE;
- }
-
- return FALSE;
-}
/***** Some general routines ***********************************************/
@@ -1666,8 +1646,7 @@ analysis_tool_ztest_engine_run (data_analysis_output_t *dao,
gnm_expr_new_funcall1
(fd_normsinv,
gnm_expr_new_constant
- (value_new_float (info->base.alpha))
- )));
+ (value_new_float (info->base.alpha)))));
/* P (T<=t) two-tail */
dao_set_cell_expr
@@ -3931,7 +3910,6 @@ analysis_tool_ranking_engine_run (data_analysis_output_t *dao,
expr_rank = gnm_expr_new_funcall2 (fd_rank,
make_cellref (-1,0),
-/* make_rangeref (-1, 0, -1, rows - 1), */
gnm_expr_new_constant (value_dup (val_org)));
if (info->av_ties) {
GnmExpr const *expr_rank_lower;
@@ -3950,7 +3928,6 @@ analysis_tool_ranking_engine_run (data_analysis_output_t *dao,
expr_rank_lower = gnm_expr_new_funcall3
(fd_rank,
make_cellref (-1,0),
-/* make_rangeref (-1, 0, -1, rows - 1), */
gnm_expr_new_constant (value_dup (val_org)),
gnm_expr_new_constant (value_new_int (1)));
expr_rank = gnm_expr_new_binary
@@ -3962,8 +3939,6 @@ analysis_tool_ranking_engine_run (data_analysis_output_t *dao,
gnm_func_unref (fd_count);
}
-/* dao_set_array_expr (dao, 2, 2, 1, rows, expr_rank); */
-
expr_percentile = gnm_expr_new_funcall3 (fd_percentrank,
gnm_expr_new_constant (value_dup (val_org)),
make_cellref (-2,0),
@@ -4359,679 +4334,6 @@ analysis_tool_anova_single_engine (data_analysis_output_t *dao, gpointer specs,
}
-
-/************* Anova: Two-Factor Without Replication Tool ****************
- *
- * The results are given in a table which can be printed out in a new
- * sheet, in a new workbook, or simply into an existing sheet.
- *
- **/
-
-static gboolean
-analysis_tool_anova_two_factor_prepare_input_range (
- analysis_tools_data_anova_two_factor_t *info)
-{
- info->row_input_range = NULL;
- info->col_input_range = NULL;
-
- info->rows = info->input->v_range.cell.b.row - info->input->v_range.cell.a.row +
- (info->labels ? 0 : 1);
- info->n_r = info->rows/info->replication;
- info->n_c = info->input->v_range.cell.b.col - info->input->v_range.cell.a.col +
- (info->labels ? 0 : 1);
-
- if (info->replication == 1) {
- info->row_input_range = g_slist_prepend (NULL, value_dup (info->input));
- prepare_input_range (&info->row_input_range, GROUPED_BY_ROW);
- if (info->labels) {
- GSList *list = info->row_input_range;
- info->row_input_range = g_slist_remove_link (info->row_input_range, list);
- range_list_destroy (list);
- }
- info->col_input_range = g_slist_prepend (NULL, info->input);
- prepare_input_range (&info->col_input_range, GROUPED_BY_COL);
- if (info->labels) {
- GSList *list = info->col_input_range;
- info->col_input_range = g_slist_remove_link (info->col_input_range, list);
- range_list_destroy (list);
- }
- info->input = NULL;
- if (info->col_input_range == NULL || info->row_input_range == NULL ||
- info->col_input_range->next == NULL || info->row_input_range->next == NULL) {
- range_list_destroy (info->col_input_range);
- info->col_input_range = NULL;
- range_list_destroy (info->row_input_range);
- info->row_input_range = NULL;
- info->err = analysis_tools_missing_data;
- return TRUE;
- }
- } else {
- /* Check that correct number of rows per sample */
- if (info->rows % info->replication != 0) {
- info->err = analysis_tools_replication_invalid;
- return TRUE;
- }
-
- /* Check that at least two columns of data are given */
- if (info->n_c < 2) {
- info->err = analysis_tools_too_few_cols;
- return TRUE;
- }
- /* Check that at least two data rows of data are given */
- if (info->n_r < 2) {
- info->err = analysis_tools_too_few_rows;
- return TRUE;
- }
-
- if (info->labels) {
- info->input->v_range.cell.a.row += 1;
- info->input->v_range.cell.a.col += 1;
- }
-
- }
- return FALSE;
-}
-
-static gboolean
-analysis_tool_anova_two_factor_no_rep_engine_run (data_analysis_output_t *dao,
- analysis_tools_data_anova_two_factor_t *info)
-{
- GPtrArray *row_data = NULL;
- GPtrArray *col_data = NULL;
-
- int i, n, error;
- int cols;
- int rows;
- gnm_float cm, sum = 0;
- gnm_float ss_r = 0, ss_c = 0, ss_e = 0, ss_t = 0;
- gnm_float ms_r, ms_c, ms_e, f1, f2, p1, p2, f1_c, f2_c;
- int df_r, df_c, df_e, df_t;
-
-
- row_data = new_data_set_list (info->row_input_range, GROUPED_BY_ROW,
- FALSE, info->labels, dao->sheet);
- col_data = new_data_set_list (info->col_input_range, GROUPED_BY_COL,
- FALSE, info->labels, dao->sheet);
- if (check_data_for_missing (row_data) ||
- check_data_for_missing (col_data)) {
- destroy_data_set_list (row_data);
- destroy_data_set_list (col_data);
- gnm_cmd_context_error_calc (GO_CMD_CONTEXT (info->wbc),
- _("The input range contains non-numeric data."));
- return TRUE;
- }
-
- cols = col_data->len;
- rows = row_data->len;
- n = rows * cols;
-
- dao_set_cell (dao, 0, 0, _("Anova: Two-Factor Without Replication"));
- set_cell_text_row (dao, 0, 2, _("/SUMMARY"
- "/Count"
- "/Sum"
- "/Average"
- "/Variance"));
-
- for (i = 0; i < rows; i++) {
- gnm_float v;
- data_set_t *data_set = g_ptr_array_index (row_data, i);
- gnm_float *the_data = (gnm_float *)data_set->data->data;
-
- dao_set_cell (dao, 0, i + 3, data_set->label);
- dao_set_cell_int (dao, 1, i + 3, data_set->data->len);
- error = gnm_range_sum (the_data, data_set->data->len, &v);
- sum += v;
- ss_r += v * v/ data_set->data->len;
- dao_set_cell_float_na (dao, 2, i + 3, v, error == 0);
- dao_set_cell_float_na (dao, 3, i + 3, v / data_set->data->len,
- error == 0 && data_set->data->len != 0);
- error = gnm_range_var_est (the_data, data_set->data->len , &v);
- dao_set_cell_float_na (dao, 4, i + 3, v, error == 0);
-
- error = gnm_range_sumsq (the_data, data_set->data->len, &v);
- ss_t += v;
- }
-
- for (i = 0; i < cols; i++) {
- gnm_float v;
- data_set_t *data_set = g_ptr_array_index (col_data, i);
- gnm_float *the_data = (gnm_float *)data_set->data->data;
-
- dao_set_cell (dao, 0, i + 4 + rows, data_set->label);
- dao_set_cell_int (dao, 1, i + 4 + rows, data_set->data->len);
- error = gnm_range_sum (the_data, data_set->data->len, &v);
- ss_c += v * v/ data_set->data->len;
- dao_set_cell_float_na (dao, 2, i + 4 + rows, v, error == 0);
- dao_set_cell_float_na (dao, 3, i + 4 + rows, v / data_set->data->len,
- error == 0 && data_set->data->len != 0);
- error = gnm_range_var_est (the_data, data_set->data->len , &v);
- dao_set_cell_float_na (dao, 4, i + 4 + rows, v, error == 0);
- }
-
- cm = sum * sum / n;
- ss_t -= cm;
- ss_r -= cm;
- ss_c -= cm;
- ss_e = ss_t - ss_r - ss_c;
-
-
- df_r = rows - 1;
- df_c = cols - 1;
- df_e = (rows - 1) * (cols - 1);
- df_t = n - 1;
- ms_r = ss_r / df_r;
- ms_c = ss_c / df_c;
- ms_e = ss_e / df_e;
- f1 = ms_r / ms_e;
- f2 = ms_c / ms_e;
- p1 = pf (f1, df_r, df_e, FALSE, FALSE);
- p2 = pf (f2, df_c, df_e, FALSE, FALSE);
- f1_c = qf (info->alpha, df_r, df_e, FALSE, FALSE);
- f2_c = qf (info->alpha, df_c, df_e, FALSE, FALSE);
-
- set_cell_text_col (dao, 0, 6 + rows + cols, _("/ANOVA"
- "/Source of Variation"
- "/Rows"
- "/Columns"
- "/Error"
- "/Total"));
- set_cell_text_row (dao, 1, 7 + rows + cols, _("/SS"
- "/df"
- "/MS"
- "/F"
- "/P-value"
- "/F critical"));
-
- dao_set_cell_float (dao, 1, 8 + rows + cols, ss_r);
- dao_set_cell_float (dao, 1, 9 + rows + cols, ss_c);
- dao_set_cell_float (dao, 1, 10 + rows + cols, ss_e);
- dao_set_cell_float (dao, 1, 11 + rows + cols, ss_t);
- dao_set_cell_int (dao, 2, 8 + rows + cols, df_r);
- dao_set_cell_int (dao, 2, 9 + rows + cols, df_c);
- dao_set_cell_int (dao, 2, 10 + rows + cols, df_e);
- dao_set_cell_int (dao, 2, 11 + rows + cols, df_t);
- dao_set_cell_float (dao, 3, 8 + rows + cols, ms_r);
- dao_set_cell_float (dao, 3, 9 + rows + cols, ms_c);
- dao_set_cell_float (dao, 3, 10 + rows + cols, ms_e);
- dao_set_cell_float_na (dao, 4, 8 + rows + cols, f1, ms_e != 0);
- dao_set_cell_float_na (dao, 4, 9 + rows + cols, f2, ms_e != 0);
- dao_set_cell_float_na (dao, 5, 8 + rows + cols, p1, ms_e != 0);
- dao_set_cell_float_na (dao, 5, 9 + rows + cols, p2, ms_e != 0);
- dao_set_cell_float (dao, 6, 8 + rows + cols, f1_c);
- dao_set_cell_float (dao, 6, 9 + rows + cols, f2_c);
-
- dao_set_italic (dao, 1, 2, 4, 2);
- dao_set_italic (dao, 1, 7 + rows + cols, 6, 7 + rows + cols);
- dao_set_italic (dao, 0, 0, 0, 11 + rows + cols);
-
- destroy_data_set_list (row_data);
- destroy_data_set_list (col_data);
-
- return FALSE;
-}
-
-
-/************* Anova: Two-Factor With Replication Tool *******************
- *
- * The results are given in a table which can be printed out in a new
- * sheet, in a new workbook, or simply into an existing sheet.
- *
- **/
-
-static char *
-make_label (Sheet *sheet, int col, int row, char *default_format, int index,
- gboolean read_cell)
-{
- char *rendered_text = NULL;
- if (read_cell) {
- GnmCell *cell = sheet_cell_get (sheet, col, row);
- if (cell && cell->value)
- rendered_text = value_get_as_string (cell->value);
- }
- if (rendered_text != NULL) {
- if (strlen (rendered_text) == 0)
- g_free (rendered_text);
- else
- return rendered_text;
- }
- return g_strdup_printf (default_format, index);
-}
-
-static gboolean
-analysis_tool_anova_two_factor_engine_run (data_analysis_output_t *dao,
- analysis_tools_data_anova_two_factor_t *info)
-{
- guint i_c, i_r;
- guint n = 0;
- GPtrArray *col_labels = NULL;
- GPtrArray *row_labels = NULL;
- GPtrArray *row_data = NULL;
- GnmValue *input_cp;
- gint df_r, df_c, df_rc, df_e, df_total;
- gnm_float ss_r = 0.0, ss_c = 0.0, ss_rc = 0.0, ss_e = 0.0, ss_total = 0.0;
- gnm_float ms_r, ms_c, ms_rc, ms_e;
- gnm_float f_r, f_c, f_rc;
- gnm_float p_r, p_c, p_rc;
- gnm_float cm = 0.0;
- guint max_sample_size = 0;
- guint missing_observations = 0;
- gboolean empty_sample = FALSE;
- gboolean return_value = FALSE;
-
-
- col_labels = g_ptr_array_new ();
- g_ptr_array_set_size (col_labels, info->n_c);
- for (i_c = 0; i_c < info->n_c; i_c++)
- g_ptr_array_index (col_labels, i_c) = make_label (
- dao->sheet, info->input->v_range.cell.a.col + i_c,
- info->input->v_range.cell.a.row - 1,
- _("Column %i"), i_c + 1, info->labels);
- row_labels = g_ptr_array_new ();
- g_ptr_array_set_size (row_labels, info->n_r);
- for (i_r = 0; i_r < info->n_r; i_r++)
- g_ptr_array_index (row_labels, i_r) = make_label (
- dao->sheet,
- info->input->v_range.cell.a.col - 1,
- info->input->v_range.cell.a.row + i_r * info->replication,
- _("Row %i"), i_r + 1, info->labels);
-
- input_cp = value_dup (info->input);
- input_cp->v_range.cell.b.row = input_cp->v_range.cell.a.row +
- info->replication - 1;
- row_data = g_ptr_array_new ();
- while (input_cp->v_range.cell.a.row < info->input->v_range.cell.b.row) {
- GPtrArray *col_data = NULL;
- GSList *col_input_range = NULL;
-
- col_input_range = g_slist_prepend (NULL, value_dup (input_cp));
- prepare_input_range (&col_input_range, GROUPED_BY_COL);
- col_data = new_data_set_list (col_input_range, GROUPED_BY_COL,
- TRUE, FALSE, dao->sheet);
- g_ptr_array_add (row_data, col_data);
- range_list_destroy (col_input_range);
- input_cp->v_range.cell.a.row += info->replication;
- input_cp->v_range.cell.b.row += info->replication;
- }
- value_release (input_cp);
-
-/* We have loaded the data, we should now check for missing observations */
-
- for (i_r = 0; i_r < info->n_r; i_r++) {
- GPtrArray *data = NULL;
-
- data = g_ptr_array_index (row_data, i_r);
- for (i_c = 0; i_c < info->n_c; i_c++) {
- data_set_t *cell_data = g_ptr_array_index (data, i_c);
- guint num = cell_data->data->len;
- if (num == 0)
- empty_sample = TRUE;
- else {
- if (num > max_sample_size)
- max_sample_size = num;
- missing_observations += (info->replication - num);
- }
- }
- }
-
- if (empty_sample) {
- gnm_cmd_context_error_calc (GO_CMD_CONTEXT (info->wbc),
- _("One of the factor combinations does not contain "
- "any observations!"));
- return_value = TRUE;
- goto anova_two_factor_with_r_tool_end;
- }
-
- missing_observations -= ((info->replication - max_sample_size) * info->n_c * info->n_r);
-
-/* We are ready to create the summary table */
- dao_set_cell (dao, 0, 0, _("Anova: Two-Factor With Replication"));
- dao_set_cell (dao, 0, 2, _("SUMMARY"));
- for (i_c = 0; i_c < info->n_c; i_c++)
- dao_set_cell (dao, 1 + i_c, 2,
- (char *)g_ptr_array_index (col_labels, i_c));
- dao_set_cell (dao, 1 + info->n_c, 2, _("Total"));
- for (i_r = 0; i_r <= info->n_r; i_r++) {
- set_cell_text_col (dao, 0, 4 + i_r * 6, _("/Count"
- "/Sum"
- "/Average"
- "/Variance"));
- if (i_r < info->n_r)
- dao_set_cell (dao, 0, 3 + i_r * 6,
- (char *)g_ptr_array_index (row_labels, i_r));
- }
- dao_set_cell (dao, 0, 3 + info->n_r * 6, _("Total"));
-
- set_cell_text_col (dao, 0, info->n_r * 6 + 10, _("/ANOVA"
- "/Source of Variation"
- "/Rows"
- "/Columns"
- "/Interaction"
- "/Within"));
- dao_set_cell (dao, 0, info->n_r * 6 + 17, _("Total"));
-
- set_cell_text_row (dao, 1, info->n_r * 6 + 11, _("/SS"
- "/df"
- "/MS"
- "/F"
- "/P-value"
- "/F critical"));
-
- for (i_r = 0; i_r < info->n_r; i_r++) {
- GPtrArray *data = NULL;
- gnm_float row_sum = 0.0;
- gnm_float row_sum_sq = 0.0;
- guint row_cnt = 0;
-
- data = g_ptr_array_index (row_data, i_r);
- for (i_c = 0; i_c < info->n_c; i_c++) {
- data_set_t *cell_data;
- gnm_float v;
- int error;
- int num;
- gnm_float *the_data;
-
- cell_data = g_ptr_array_index (data, i_c);
- the_data = (gnm_float *)cell_data->data->data;
- num = cell_data->data->len;
- row_cnt += num;
-
- dao_set_cell_int (dao, 1 + i_c, 4 + i_r * 6, num);
- error = gnm_range_sum (the_data, num, &v);
- row_sum += v;
- ss_rc += v * v / num;
- dao_set_cell_float_na (dao, 1 + i_c, 5 + i_r * 6, v, error == 0);
- dao_set_cell_float_na (dao, 1 + i_c, 6 + i_r * 6, v / num,
- error == 0 && num > 0);
- error = gnm_range_var_est (the_data, num , &v);
- dao_set_cell_float_na (dao, 1 + i_c, 7 + i_r * 6, v, error == 0);
-
- error = gnm_range_sumsq (the_data, num, &v);
- row_sum_sq += v;
- }
- cm += row_sum;
- n += row_cnt;
- ss_r += row_sum * row_sum / row_cnt;
- ss_total += row_sum_sq;
- dao_set_cell_int (dao, 1 + info->n_c, 4 + i_r * 6, row_cnt);
- dao_set_cell_float (dao, 1 + info->n_c, 5 + i_r * 6, row_sum);
- dao_set_cell_float (dao, 1 + info->n_c, 6 + i_r * 6, row_sum / row_cnt);
- dao_set_cell_float (dao, 1 + info->n_c, 7 + i_r * 6,
- (row_sum_sq - row_sum * row_sum / row_cnt) / (row_cnt - 1));
- }
-
- for (i_c = 0; i_c < info->n_c; i_c++) {
- gnm_float col_sum = 0.0;
- gnm_float col_sum_sq = 0.0;
- guint col_cnt = 0;
-
- for (i_r = 0; i_r < info->n_r; i_r++) {
- data_set_t *cell_data;
- gnm_float v;
- int error;
- gnm_float *the_data;
- GPtrArray *data = NULL;
-
- data = g_ptr_array_index (row_data, i_r);
- cell_data = g_ptr_array_index (data, i_c);
- the_data = (gnm_float *)cell_data->data->data;
-
- col_cnt += cell_data->data->len;
- error = gnm_range_sum (the_data, cell_data->data->len, &v);
- col_sum += v;
-
- error = gnm_range_sumsq (the_data, cell_data->data->len, &v);
- col_sum_sq += v;
- }
- ss_c += col_sum * col_sum / col_cnt;
- dao_set_cell_int (dao, 1 + i_c, 4 + info->n_r * 6, col_cnt);
- dao_set_cell_float (dao, 1 + i_c, 5 + info->n_r * 6, col_sum);
- dao_set_cell_float (dao, 1 + i_c, 6 + info->n_r * 6, col_sum / col_cnt);
- dao_set_cell_float (dao, 1 + i_c, 7 + info->n_r * 6,
- (col_sum_sq - col_sum * col_sum / col_cnt) / (col_cnt - 1));
- }
-
- dao_set_cell_int (dao, 1 + info->n_c, 4 + info->n_r * 6, n);
- dao_set_cell_float (dao, 1 + info->n_c, 5 + info->n_r * 6, cm);
- dao_set_cell_float (dao, 1 + info->n_c, 6 + info->n_r * 6, cm / n);
- cm = cm * cm/ n;
- dao_set_cell_float (dao, 1 + info->n_c, 7 + info->n_r * 6, (ss_total - cm) / (n - 1));
-
- df_r = info->n_r - 1;
- df_c = info->n_c - 1;
- df_rc = df_r * df_c;
- df_total = n - 1;
- df_e = df_total - df_rc - df_c - df_r;
-
- if (missing_observations > 0) {
- /* Oh bother: there is some data missing which means we have to: */
- /* -- Estimate the missing values */
- /* -- Recalculate the values obtained towards the SS */
- /* We couldn't do that above because the Summary table should */
- /* contain the real values */
-
- /* Estimate the missing values */
-
- for (i_r = 0; i_r < info->n_r; i_r++) {
- GPtrArray *data = NULL;
-
- data = g_ptr_array_index (row_data, i_r);
- for (i_c = 0; i_c < info->n_c; i_c++) {
- data_set_t *cell_data;
- guint num, error;
-
- cell_data = g_ptr_array_index (data, i_c);
- num = cell_data->data->len;
- if (num < max_sample_size) {
- gnm_float *the_data, v;
- guint i;
-
- the_data = (gnm_float *)cell_data->data->data;
- error = gnm_range_average (the_data, num, &v);
- for (i = num; i < max_sample_size; i++)
- g_array_append_val (cell_data->data, v);
- }
- }
- }
-
- /* Recalculate the values obtained towards the SS */
-
- ss_r = 0;
- ss_c = 0;
- ss_rc = 0;
- ss_total = 0;
- cm = 0;
- n = 0;
-
- for (i_r = 0; i_r < info->n_r; i_r++) {
- GPtrArray *data = NULL;
- gnm_float row_sum = 0.0;
- gnm_float row_sum_sq = 0.0;
- guint row_cnt = 0;
-
- data = g_ptr_array_index (row_data, i_r);
- for (i_c = 0; i_c < info->n_c; i_c++) {
- data_set_t *cell_data;
- gnm_float v;
- int error;
- int num;
- gnm_float *the_data;
-
- cell_data = g_ptr_array_index (data, i_c);
- the_data = (gnm_float *)cell_data->data->data;
- num = cell_data->data->len;
- row_cnt += num;
-
- error = gnm_range_sum (the_data, num, &v);
- row_sum += v;
- ss_rc += v * v / num;
-
- error = gnm_range_sumsq (the_data, num, &v);
- row_sum_sq += v;
- }
- cm += row_sum;
- n += row_cnt;
- ss_r += row_sum * row_sum / row_cnt;
- ss_total += row_sum_sq;
- }
-
- for (i_c = 0; i_c < info->n_c; i_c++) {
- gnm_float col_sum = 0.0;
- guint col_cnt = 0;
-
- for (i_r = 0; i_r < info->n_r; i_r++) {
- data_set_t *cell_data;
- gnm_float v;
- int error;
- gnm_float *the_data;
- GPtrArray *data = NULL;
-
- data = g_ptr_array_index (row_data, i_r);
- cell_data = g_ptr_array_index (data, i_c);
- the_data = (gnm_float *)cell_data->data->data;
-
- col_cnt += cell_data->data->len;
- error = gnm_range_sum (the_data, cell_data->data->len, &v);
- col_sum += v;
- }
- ss_c += col_sum * col_sum / col_cnt;
- }
-
- cm = cm * cm/ n;
- }
-
- ss_r = ss_r - cm;
- ss_c = ss_c - cm;
- ss_rc = ss_rc - ss_r - ss_c - cm;
- ss_total = ss_total - cm;
- ss_e = ss_total - ss_r - ss_c - ss_rc;
-
- dao_set_cell_float (dao, 1, info->n_r * 6 + 12, ss_r);
- dao_set_cell_float (dao, 1, info->n_r * 6 + 13, ss_c);
- dao_set_cell_float (dao, 1, info->n_r * 6 + 14, ss_rc);
- dao_set_cell_float (dao, 1, info->n_r * 6 + 15, ss_e);
- dao_set_cell_float (dao, 1, info->n_r * 6 + 17, ss_total);
-
- dao_set_cell_int (dao, 2, info->n_r * 6 + 12, df_r);
- dao_set_cell_int (dao, 2, info->n_r * 6 + 13, df_c);
- dao_set_cell_int (dao, 2, info->n_r * 6 + 14, df_rc);
- dao_set_cell_int (dao, 2, info->n_r * 6 + 15, df_e);
- dao_set_cell_int (dao, 2, info->n_r * 6 + 17, df_total);
-
- ms_r = ss_r / df_r;
- ms_c = ss_c / df_c;
- ms_rc = ss_rc / df_rc;
- ms_e = ss_e / df_e;
-
- dao_set_cell_float_na (dao, 3, info->n_r * 6 + 12, ms_r, df_r > 0);
- dao_set_cell_float_na (dao, 3, info->n_r * 6 + 13, ms_c, df_c > 0);
- dao_set_cell_float_na (dao, 3, info->n_r * 6 + 14, ms_rc, df_rc > 0);
- dao_set_cell_float_na (dao, 3, info->n_r * 6 + 15, ms_e, df_e > 0);
-
- f_r = ms_r / ms_e;
- f_c = ms_c / ms_e;
- f_rc = ms_rc / ms_e;
-
- dao_set_cell_float_na (dao, 4, info->n_r * 6 + 12, f_r, ms_e != 0 && df_r > 0);
- dao_set_cell_float_na (dao, 4, info->n_r * 6 + 13, f_c, ms_e != 0 && df_c > 0);
- dao_set_cell_float_na (dao, 4, info->n_r * 6 + 14, f_rc, ms_e != 0 && df_rc > 0);
-
- p_r = pf (f_r, df_r, df_e, FALSE, FALSE);
- p_c = pf (f_c, df_c, df_e, FALSE, FALSE);
- p_rc = pf (f_rc, df_rc, df_e, FALSE, FALSE);
-
- dao_set_cell_float_na (dao, 5, info->n_r * 6 + 12, p_r, ms_e != 0 && df_r > 0 && df_e > 0);
- dao_set_cell_float_na (dao, 5, info->n_r * 6 + 13, p_c, ms_e != 0 && df_c > 0 && df_e > 0);
- dao_set_cell_float_na (dao, 5, info->n_r * 6 + 14, p_rc, ms_e != 0 && df_rc > 0 && df_e > 0);
-
- dao_set_cell_float_na (dao, 6, info->n_r * 6 + 12,
- qf (info->alpha, df_r, df_e, FALSE, FALSE),
- df_r > 0 && df_e > 0);
- dao_set_cell_float_na (dao, 6, info->n_r * 6 + 13,
- qf (info->alpha, df_c, df_e, FALSE, FALSE),
- df_c > 0 && df_e > 0);
- dao_set_cell_float_na (dao, 6, info->n_r * 6 + 14,
- qf (info->alpha, df_rc, df_e, FALSE, FALSE),
- df_rc > 0 && df_e > 0);
-
- dao_set_italic (dao, 0, info->n_r * 6 + 11, 6, info->n_r * 6 + 11);
- dao_set_italic (dao, 0, 2, 1 + info->n_c, 2);
- dao_set_italic (dao, 0, 0, 0, 17 + info->n_r * 6);
-
- anova_two_factor_with_r_tool_end:
-
- for (i_r = 0; i_r < row_data->len; i_r++)
- destroy_data_set_list (g_ptr_array_index (row_data, i_r));
- g_ptr_array_free (row_data, TRUE);
-
- for (i_c = 0; i_c < info->n_c; i_c++)
- g_free (g_ptr_array_index (col_labels, i_c));
- g_ptr_array_free (col_labels, TRUE);
- for (i_r = 0; i_r < info->n_r; i_r++)
- g_free (g_ptr_array_index (row_labels, i_r));
- g_ptr_array_free (row_labels, TRUE);
-
- return return_value;
-}
-
-static gboolean
-analysis_tool_anova_two_factor_engine_clean (G_GNUC_UNUSED data_analysis_output_t *dao,
- gpointer specs)
-{
- analysis_tools_data_anova_two_factor_t *info = specs;
-
- range_list_destroy (info->col_input_range);
- info->col_input_range = NULL;
- range_list_destroy (info->row_input_range);
- info->row_input_range = NULL;
- if (info->input)
- value_release (info->input);
- info->input = NULL;
-
- return FALSE;
-}
-
-gboolean
-analysis_tool_anova_two_factor_engine (data_analysis_output_t *dao, gpointer specs,
- analysis_tool_engine_t selector, gpointer result)
-{
- analysis_tools_data_anova_two_factor_t *info = specs;
-
- switch (selector) {
- case TOOL_ENGINE_UPDATE_DESCRIPTOR:
- return (dao_command_descriptor (
- dao, (info->replication == 1) ?
- _("Two Factor ANOVA (%s), no replication") :
- _("Two Factor ANOVA (%s), with replication") , result)
- == NULL);
- case TOOL_ENGINE_UPDATE_DAO:
- if (analysis_tool_anova_two_factor_prepare_input_range (info))
- return TRUE;
- if (info->replication == 1)
- dao_adjust (dao, 7, info->n_c + info->n_r + 12);
- else
- dao_adjust (dao, MAX (2 + info->n_c, 7), info->n_r * 6 + 18);
- return FALSE;
- case TOOL_ENGINE_CLEAN_UP:
- return analysis_tool_anova_two_factor_engine_clean (dao, specs);
- case TOOL_ENGINE_LAST_VALIDITY_CHECK:
- return FALSE;
- case TOOL_ENGINE_PREPARE_OUTPUT_RANGE:
- dao_prepare_output (NULL, dao, _("Anova"));
- return FALSE;
- case TOOL_ENGINE_FORMAT_OUTPUT_RANGE:
- return dao_format_output (dao, _("Two Factor ANOVA"));
- case TOOL_ENGINE_PERFORM_CALC:
- default:
- if (info->replication == 1)
- return analysis_tool_anova_two_factor_no_rep_engine_run (dao, info);
- else
- return analysis_tool_anova_two_factor_engine_run (dao, info);
- }
- return TRUE; /* We shouldn't get here */
-}
-
-
-
/************* Fourier Analysis Tool **************************************
*
* This tool performes a fast fourier transform calculating the fourier
diff --git a/src/tools/analysis-tools.h b/src/tools/analysis-tools.h
index f70fac3..f100e3c 100644
--- a/src/tools/analysis-tools.h
+++ b/src/tools/analysis-tools.h
@@ -8,14 +8,9 @@
#include "regression.h"
#include "complex.h"
-/*******************************************************************/
-/* Section 1: gui utility functions for the tools */
-
-/*******************************************************************/
-/* Section 2: not undoable tools */
/*******************************************************************/
-/* Section 3: Undoable tools and their data structures */
+/* Section 1: Undoable tools and their data structures */
typedef enum {
analysis_tools_noerr = 0,
@@ -29,7 +24,7 @@ typedef enum {
/********************************************************************/
-/* Subsection 3a: Undoable Tools using the first common generic data struct */
+/* Section 2: Undoable Tools using the first common generic data struct */
typedef struct {
analysis_tools_error_code_t err;
@@ -52,7 +47,7 @@ gboolean analysis_tool_covariance_engine (data_analysis_output_t *dao, gpointer
/********************************************************************/
-/* Subsection 3b: Undoable Tools using the first common generic */
+/* Section 3: Undoable Tools using the first common generic */
/* data struct augmented with some simple fields */
/************** Single Factor ANOVA *************/
@@ -148,7 +143,7 @@ gboolean analysis_tool_ranking_engine (data_analysis_output_t *dao, gpointer spe
/********************************************************************/
-/* Subsection 3c: Undoable Tools using the second common generic */
+/* Section 4: Undoable Tools using the second common generic */
/* data struct augmented with some simple fields */
/*********************** FTest ************************/
@@ -206,31 +201,9 @@ gboolean analysis_tool_ztest_engine (data_analysis_output_t *dao, gpointer specs
analysis_tool_engine_t selector, gpointer result);
-/********************************************************************/
-/* Subsection 3d: Undoable Tools using their own data struct */
-
-/**************** 2-Factor ANOVA ***************/
-
-typedef struct {
- analysis_tools_error_code_t err;
- WorkbookControl *wbc;
- GnmValue *input;
- group_by_t group_by;
- gboolean labels;
- GSList *row_input_range;
- GSList *col_input_range;
- gnm_float alpha;
- gint replication;
- gint rows;
- guint n_c;
- guint n_r;
-} analysis_tools_data_anova_two_factor_t;
-
-gboolean analysis_tool_anova_two_factor_engine (data_analysis_output_t *dao, gpointer specs,
- analysis_tool_engine_t selector, gpointer result);
/********************************************************************/
-/* Functions also needed elsewhere. */
+/* Section 5 Functions also needed elsewhere. */
gboolean analysis_tool_generic_clean (gpointer specs);
gboolean analysis_tool_generic_b_clean (gpointer specs);
diff --git a/src/tools/dao.c b/src/tools/dao.c
index 07f03bc..81f99f1 100644
--- a/src/tools/dao.c
+++ b/src/tools/dao.c
@@ -43,6 +43,7 @@
#include "sheet-merge.h"
#include "sheet-object-cell-comment.h"
#include "style-color.h"
+#include "style-border.h"
#include "graph.h"
#include <goffice/app/go-doc.h>
#include <goffice/utils/go-glib-extras.h>
@@ -875,6 +876,35 @@ dao_set_align (data_analysis_output_t *dao, int col1, int row1,
dao_set_style (dao, col1, row1, col2, row2, mstyle);
}
+/**
+ * dao_set_border:
+ * @dao:
+ * @col1:
+ * @row1:
+ * @col2:
+ * @row2:
+ *
+ *
+ *
+ **/
+void
+dao_set_border (data_analysis_output_t *dao, int col1, int row1,
+ int col2, int row2,
+ GnmStyleElement elem, GnmStyleBorderType border,
+ GnmColor *color,
+ GnmStyleBorderOrientation orientation)
+{
+ GnmStyle *mstyle;
+
+ mstyle = gnm_style_new ();
+ gnm_style_set_border (mstyle, elem,
+ gnm_style_border_fetch (border,
+ color,
+ orientation));
+ dao_set_style (dao, col1, row1, col2, row2, mstyle);
+}
+
+
/**
* dao_get_colrow_state_list:
diff --git a/src/tools/dao.h b/src/tools/dao.h
index fe3a497..d977339 100644
--- a/src/tools/dao.h
+++ b/src/tools/dao.h
@@ -32,6 +32,9 @@
#include "numbers.h"
#include "style.h"
#include <goffice/data/goffice-data.h>
+#include "style-color.h"
+#include "style-border.h"
+#include "graph.h"
typedef enum {
NewSheetOutput, NewWorkbookOutput, RangeOutput, InPlaceOutput
@@ -86,6 +89,11 @@ void dao_set_colors (data_analysis_output_t *dao, int col1, int row1,
void dao_set_align (data_analysis_output_t *dao, int col1, int row1,
int col2, int row2,
GnmHAlign align_h, GnmVAlign align_v);
+void dao_set_border (data_analysis_output_t *dao, int col1,
+ int row1, int col2, int row2,
+ GnmStyleElement elem,GnmStyleBorderType border,
+ GnmColor *color,
+ GnmStyleBorderOrientation orientation);
void dao_set_cell (data_analysis_output_t *dao, int col, int row,
char const *text);
void dao_set_cell_printf (data_analysis_output_t *dao,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]