[gnumeric] add tests for independence and homogeneity



commit 9dece97e686da820d79f97f9f8e108faad35fa0b
Author: Andreas J. Guelzow <aguelzow pyrshep ca>
Date:   Sun Jun 7 10:39:26 2009 -0600

    add tests for independence and homogeneity
    
    2009-06-07  Andreas J. Guelzow <aguelzow pyrshep ca>
    
    	* src/GNOME_Gnumeric-gtk.xml.in: add ChiSquareTests
    	* src/wbc-gtk-actions.c add MenuContingencyTests and
    	  Tools -> Chi Square Tests items
    
    2009-06-07  Andreas J. Guelzow <aguelzow pyrshep ca>
    
    	* POTFILES.in: added src/dialogs/chi-squared.glade,
    	  src/dialogs/dialog-analysis-tool-chi-squared.c and
    	  src/tools/analysis-chi-squared.c
    
    2009-06-07  Andreas J. Guelzow <aguelzow pyrshep ca>
    
    	* analysis-chi-squared.[ch]: new
    	* Makefile.am: added the above
    
    2009-06-07  Andreas J. Guelzow <aguelzow pyrshep ca>
    
    	* chi-squared.glade: new
    	* dialog-analysis-tool-chi-squared.c: new
    	* Makefile.am: added the above
    	* dialogs.h (dialog_chi_square_tool): new
    	* help.h (GNUMERIC_HELP_LINK_CHI_SQUARED): new
---
 ChangeLog                                      |    6 +
 NEWS                                           |    1 +
 po/ChangeLog                                   |    6 +
 po/POTFILES.in                                 |    3 +
 src/GNOME_Gnumeric-gtk.xml.in                  |    4 +
 src/dialogs/ChangeLog                          |    8 +
 src/dialogs/Makefile.am                        |    2 +
 src/dialogs/chi-squared.glade                  |  372 ++++++++++++++++++++++++
 src/dialogs/dialog-analysis-tool-chi-squared.c |  249 ++++++++++++++++
 src/dialogs/dialogs.h                          |    1 +
 src/dialogs/help.h                             |    3 +
 src/tools/ChangeLog                            |    5 +
 src/tools/Makefile.am                          |    6 +-
 src/tools/analysis-chi-squared.c               |  213 ++++++++++++++
 src/tools/analysis-chi-squared.h               |   50 ++++
 src/wbc-gtk-actions.c                          |   11 +
 16 files changed, 938 insertions(+), 2 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 35fe21b..38f2b45 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2009-06-07  Andreas J. Guelzow <aguelzow pyrshep ca>
+
+	* src/GNOME_Gnumeric-gtk.xml.in: add ChiSquareTests
+	* src/wbc-gtk-actions.c add MenuContingencyTests and
+	  Tools -> Chi Square Tests items
+
 2009-06-06  Andreas J. Guelzow <aguelzow pyrshep ca>
 
 	* expr.h (gnm_expr_new_funcall5): new
diff --git a/NEWS b/NEWS
index aa0e50a..adc9787 100644
--- a/NEWS
+++ b/NEWS
@@ -10,6 +10,7 @@ Andreas:
 	* Improve Rank & Percentiles tool
 	* Improve Fourier transform tool
 	* New FOURIER function
+	* Added Tests for Independence and Homogeneity
 
 Morten:
 	* Add search-for-number.
diff --git a/po/ChangeLog b/po/ChangeLog
index 3a9f72d..ca4f29f 100644
--- a/po/ChangeLog
+++ b/po/ChangeLog
@@ -1,3 +1,9 @@
+2009-06-07  Andreas J. Guelzow <aguelzow pyrshep ca>
+
+	* POTFILES.in: added src/dialogs/chi-squared.glade,
+	  src/dialogs/dialog-analysis-tool-chi-squared.c and
+	  src/tools/analysis-chi-squared.c
+
 2009-06-02  Andreas J. Guelzow <aguelzow pyrshep ca>
 
 	* POTFILES.in: added src/tools/analysis-anova.c
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 5857d86..04fff94 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -128,6 +128,7 @@ src/dialogs/autosave.glade
 src/dialogs/cell-comment.glade
 src/dialogs/cell-format.glade
 src/dialogs/cell-sort.glade
+src/dialogs/chi-squared.glade
 src/dialogs/col-width.glade
 src/dialogs/colrow.glade
 src/dialogs/consolidate.glade
@@ -141,6 +142,7 @@ src/dialogs/delete-cells.glade
 src/dialogs/descriptive-stats.glade
 src/dialogs/dialog-about.c
 src/dialogs/dialog-advanced-filter.c
+src/dialogs/dialog-analysis-tool-chi-squared.c
 src/dialogs/dialog-analysis-tool-frequency.c
 src/dialogs/dialog-analysis-tool-kaplan-meier.c
 src/dialogs/dialog-analysis-tools.c
@@ -300,6 +302,7 @@ src/stf.c
 src/style.c
 src/test-pango.c
 src/tools/analysis-anova.c
+src/tools/analysis-chi-squared.c
 src/tools/analysis-exp-smoothing.c
 src/tools/analysis-frequency.c
 src/tools/analysis-histogram.c
diff --git a/src/GNOME_Gnumeric-gtk.xml.in b/src/GNOME_Gnumeric-gtk.xml.in
index 4becb02..976e0d9 100644
--- a/src/GNOME_Gnumeric-gtk.xml.in
+++ b/src/GNOME_Gnumeric-gtk.xml.in
@@ -166,6 +166,10 @@
           <menuitem action="ToolsANOVAoneFactor"/>
           <menuitem action="ToolsANOVAtwoFactor"/>
         </menu>
+        <menu name="ChiSquareTests" action="MenuContingencyTests">
+          <menuitem action="ToolsHomogeneity"/>
+          <menuitem action="ToolsIndependence"/>
+        </menu>
         <menuitem action="ToolsCorrelation"/>
         <menuitem action="ToolsCovariance"/>
         <menuitem action="ToolsDescStatistics"/>
diff --git a/src/dialogs/ChangeLog b/src/dialogs/ChangeLog
index 8971513..22812a0 100644
--- a/src/dialogs/ChangeLog
+++ b/src/dialogs/ChangeLog
@@ -1,3 +1,11 @@
+2009-06-07  Andreas J. Guelzow <aguelzow pyrshep ca>
+
+	* chi-squared.glade: new
+	* dialog-analysis-tool-chi-squared.c: new
+	* Makefile.am: added the above
+	* dialogs.h (dialog_chi_square_tool): new
+	* help.h (GNUMERIC_HELP_LINK_CHI_SQUARED): new
+
 2009-06-06  Andreas J. Guelzow <aguelzow pyrshep ca>
 
 	* dialog-analysis-tools.c (dialog_anova_two_factor_tool): enable
diff --git a/src/dialogs/Makefile.am b/src/dialogs/Makefile.am
index c1303de..2888cef 100644
--- a/src/dialogs/Makefile.am
+++ b/src/dialogs/Makefile.am
@@ -26,6 +26,7 @@ base_files =					\
 	dialog-about.c				\
 	dialog-advanced-filter.c		\
 	dialog-analysis-tools.c			\
+	dialog-analysis-tool-chi-squared.c	\
 	dialog-analysis-tool-frequency.c	\
 	dialog-analysis-tool-kaplan-meier.c	\
 	dialog-autocorrect.c			\
@@ -99,6 +100,7 @@ glade_DATA = 				\
 	cell-comment.glade		\
 	cell-format.glade		\
 	cell-sort.glade			\
+	chi-squared.glade			\
 	col-width.glade			\
 	colrow.glade			\
 	consolidate.glade		\
diff --git a/src/dialogs/chi-squared.glade b/src/dialogs/chi-squared.glade
new file mode 100644
index 0000000..bf66210
--- /dev/null
+++ b/src/dialogs/chi-squared.glade
@@ -0,0 +1,372 @@
+<?xml version="1.0"?>
+<glade-interface>
+  <!-- interface-requires gtk+ 2.16 -->
+  <!-- interface-naming-policy toplevel-contextual -->
+  <widget class="GtkDialog" id="Chi-Squared Tests">
+    <property name="border_width">5</property>
+    <property name="title" translatable="yes">Contingency Table Analysis</property>
+    <property name="type_hint">normal</property>
+    <property name="has_separator">False</property>
+    <child internal-child="vbox">
+      <widget class="GtkVBox" id="vbox1">
+        <property name="visible">True</property>
+        <property name="spacing">2</property>
+        <child>
+          <widget class="GtkNotebook" id="notebook1">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="border_width">5</property>
+            <child>
+              <widget class="GtkTable" id="input-table">
+                <property name="visible">True</property>
+                <property name="border_width">12</property>
+                <property name="n_rows">5</property>
+                <property name="n_columns">2</property>
+                <property name="column_spacing">12</property>
+                <property name="row_spacing">6</property>
+                <child>
+                  <widget class="GtkLabel" id="var1-label">
+                    <property name="visible">True</property>
+                    <property name="xalign">0</property>
+                    <property name="label" translatable="yes">_Contingency Table:</property>
+                    <property name="use_underline">True</property>
+                    <property name="justify">right</property>
+                  </widget>
+                  <packing>
+                    <property name="x_options">GTK_FILL</property>
+                    <property name="y_options"></property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkLabel" id="label2">
+                    <property name="sensitive">False</property>
+                    <property name="xalign">0</property>
+                    <property name="label" translatable="yes">Grouped by:</property>
+                    <property name="justify">center</property>
+                    <accessibility>
+                      <atkrelation type="label-for" target="grouped_by_col"/>
+                    </accessibility>
+                  </widget>
+                  <packing>
+                    <property name="top_attach">1</property>
+                    <property name="bottom_attach">2</property>
+                    <property name="x_options">GTK_FILL</property>
+                    <property name="y_options"></property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkCheckButton" id="labels_button">
+                    <property name="label" translatable="yes">_Labels</property>
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">False</property>
+                    <property name="use_underline">True</property>
+                    <property name="draw_indicator">True</property>
+                  </widget>
+                  <packing>
+                    <property name="top_attach">4</property>
+                    <property name="bottom_attach">5</property>
+                    <property name="x_options">GTK_FILL</property>
+                    <property name="y_options"></property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkHBox" id="vbox2">
+                    <property name="sensitive">False</property>
+                    <child>
+                      <widget class="GtkRadioButton" id="grouped_by_col">
+                        <property name="label" translatable="yes">_Columns</property>
+                        <property name="can_focus">True</property>
+                        <property name="receives_default">False</property>
+                        <property name="use_underline">True</property>
+                        <property name="active">True</property>
+                        <property name="draw_indicator">True</property>
+                        <accessibility>
+                          <atkrelation type="labelled-by" target="label2"/>
+                        </accessibility>
+                      </widget>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">False</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                  </widget>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="right_attach">2</property>
+                    <property name="top_attach">1</property>
+                    <property name="bottom_attach">2</property>
+                    <property name="y_options">GTK_FILL</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkRadioButton" id="grouped_by_row">
+                    <property name="label" translatable="yes">_Rows</property>
+                    <property name="sensitive">False</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">False</property>
+                    <property name="use_underline">True</property>
+                    <property name="draw_indicator">True</property>
+                    <property name="group">grouped_by_col</property>
+                  </widget>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="right_attach">2</property>
+                    <property name="top_attach">2</property>
+                    <property name="bottom_attach">3</property>
+                    <property name="x_options">GTK_FILL</property>
+                    <property name="y_options"></property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkRadioButton" id="grouped_by_area">
+                    <property name="label" translatable="yes">_Areas</property>
+                    <property name="sensitive">False</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">False</property>
+                    <property name="use_underline">True</property>
+                    <property name="draw_indicator">True</property>
+                    <property name="group">grouped_by_col</property>
+                  </widget>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="right_attach">2</property>
+                    <property name="top_attach">3</property>
+                    <property name="bottom_attach">4</property>
+                    <property name="x_options">GTK_FILL</property>
+                    <property name="y_options"></property>
+                  </packing>
+                </child>
+                <child>
+                  <placeholder/>
+                </child>
+                <child>
+                  <placeholder/>
+                </child>
+                <child>
+                  <placeholder/>
+                </child>
+                <child>
+                  <placeholder/>
+                </child>
+              </widget>
+            </child>
+            <child>
+              <widget class="GtkLabel" id="label5">
+                <property name="visible">True</property>
+                <property name="label" translatable="yes">Input</property>
+              </widget>
+              <packing>
+                <property name="tab_fill">False</property>
+                <property name="type">tab</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkVBox" id="vbox3">
+                <property name="visible">True</property>
+                <child>
+                  <widget class="GtkTable" id="table2">
+                    <property name="visible">True</property>
+                    <property name="border_width">12</property>
+                    <property name="n_rows">4</property>
+                    <property name="n_columns">2</property>
+                    <property name="column_spacing">12</property>
+                    <property name="row_spacing">6</property>
+                    <child>
+                      <widget class="GtkLabel" id="label3">
+                        <property name="visible">True</property>
+                        <property name="xalign">0</property>
+                        <property name="label" translatable="yes">_Alpha:</property>
+                        <property name="use_underline">True</property>
+                        <property name="justify">right</property>
+                        <property name="mnemonic_widget">alpha-entry</property>
+                      </widget>
+                      <packing>
+                        <property name="x_options">GTK_FILL</property>
+                        <property name="y_options"></property>
+                      </packing>
+                    </child>
+                    <child>
+                      <widget class="GtkSpinButton" id="alpha-entry">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="adjustment">0.050000000000000003 0 1 0.01 10 0</property>
+                        <property name="climb_rate">0.01</property>
+                        <property name="digits">2</property>
+                        <property name="numeric">True</property>
+                        <property name="update_policy">if-valid</property>
+                      </widget>
+                      <packing>
+                        <property name="left_attach">1</property>
+                        <property name="right_attach">2</property>
+                        <property name="y_options"></property>
+                      </packing>
+                    </child>
+                    <child>
+                      <widget class="GtkRadioButton" id="test-of-homogeneity">
+                        <property name="label" translatable="yes">Test of _Homogeneity</property>
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="receives_default">False</property>
+                        <property name="use_underline">True</property>
+                        <property name="active">True</property>
+                        <property name="draw_indicator">True</property>
+                      </widget>
+                      <packing>
+                        <property name="right_attach">2</property>
+                        <property name="top_attach">2</property>
+                        <property name="bottom_attach">3</property>
+                        <property name="y_options">GTK_FILL</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <widget class="GtkRadioButton" id="test-of-independence">
+                        <property name="label" translatable="yes">Test of _Independence</property>
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="receives_default">False</property>
+                        <property name="use_underline">True</property>
+                        <property name="active">True</property>
+                        <property name="draw_indicator">True</property>
+                        <property name="group">test-of-homogeneity</property>
+                      </widget>
+                      <packing>
+                        <property name="right_attach">2</property>
+                        <property name="top_attach">3</property>
+                        <property name="bottom_attach">4</property>
+                        <property name="y_options">GTK_FILL</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <widget class="GtkHSeparator" id="hseparator1">
+                        <property name="visible">True</property>
+                      </widget>
+                      <packing>
+                        <property name="right_attach">2</property>
+                        <property name="top_attach">1</property>
+                        <property name="bottom_attach">2</property>
+                        <property name="y_options">GTK_FILL</property>
+                      </packing>
+                    </child>
+                  </widget>
+                  <packing>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+              </widget>
+              <packing>
+                <property name="position">1</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkLabel" id="label6">
+                <property name="visible">True</property>
+                <property name="label" translatable="yes">Options</property>
+              </widget>
+              <packing>
+                <property name="position">1</property>
+                <property name="tab_fill">False</property>
+                <property name="type">tab</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkHBox" id="dao">
+                <property name="visible">True</property>
+                <child>
+                  <placeholder/>
+                </child>
+              </widget>
+              <packing>
+                <property name="position">2</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkLabel" id="label7">
+                <property name="visible">True</property>
+                <property name="label" translatable="yes">Output</property>
+              </widget>
+              <packing>
+                <property name="position">2</property>
+                <property name="tab_fill">False</property>
+                <property name="type">tab</property>
+              </packing>
+            </child>
+          </widget>
+          <packing>
+            <property name="position">1</property>
+          </packing>
+        </child>
+        <child>
+          <widget class="GtkLabel" id="warnings">
+            <property name="visible">True</property>
+            <property name="use_markup">True</property>
+            <property name="wrap">True</property>
+          </widget>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">False</property>
+            <property name="position">2</property>
+          </packing>
+        </child>
+        <child internal-child="action_area">
+          <widget class="GtkHButtonBox" id="hbuttonbox1">
+            <property name="visible">True</property>
+            <property name="layout_style">end</property>
+            <child>
+              <widget class="GtkButton" id="helpbutton">
+                <property name="label">gtk-help</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="can_default">True</property>
+                <property name="receives_default">False</property>
+                <property name="use_stock">True</property>
+              </widget>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkButton" id="cancelbutton">
+                <property name="label">gtk-cancel</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="can_default">True</property>
+                <property name="receives_default">False</property>
+                <property name="use_stock">True</property>
+              </widget>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkButton" id="okbutton">
+                <property name="label">gtk-ok</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="can_default">True</property>
+                <property name="has_default">True</property>
+                <property name="receives_default">False</property>
+                <property name="use_stock">True</property>
+              </widget>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">2</property>
+              </packing>
+            </child>
+          </widget>
+          <packing>
+            <property name="expand">False</property>
+            <property name="pack_type">end</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+      </widget>
+    </child>
+  </widget>
+</glade-interface>
diff --git a/src/dialogs/dialog-analysis-tool-chi-squared.c b/src/dialogs/dialog-analysis-tool-chi-squared.c
new file mode 100644
index 0000000..84e44d6
--- /dev/null
+++ b/src/dialogs/dialog-analysis-tool-chi-squared.c
@@ -0,0 +1,249 @@
+/* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * dialog-analysis-tool-chi-squared.c:
+ *
+ * Authors:
+  *  Andreas J. Guelzow  <aguelzow taliesin ca>
+ *
+ * (C) Copyright 2008 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 "dialogs.h"
+#include "analysis-chi-squared.h"
+#include "analysis-tools.h"
+
+#include <workbook.h>
+#include <workbook-control.h>
+#include <wbc-gtk.h>
+#include <workbook-view.h>
+#include <gui-util.h>
+#include <parse-util.h>
+#include <gnm-format.h>
+#include <tool-dialogs.h>
+#include <dao-gui-utils.h>
+#include <sheet.h>
+#include <expr.h>
+#include <number-match.h>
+#include <ranges.h>
+#include <selection.h>
+#include <value.h>
+#include <commands.h>
+#include "help.h"
+
+#include <widgets/gnm-dao.h>
+#include <widgets/gnumeric-expr-entry.h>
+
+#include <glade/glade.h>
+#include <string.h>
+#include <gtk/gtk.h>
+
+#define CHI_SQUARED_I_KEY      "analysistools-chi-square-independence-dialog"
+
+typedef struct {
+	GenericToolState base;
+	GtkWidget *alpha_entry;
+	GtkWidget *label;
+} ChiSquaredIToolState;
+
+/**
+ * chi_squared_tool_ok_clicked_cb:
+ * @button:
+ * @state:
+ *
+ * Retrieve the information from the dialog and call the fourier_tool.
+ * Note that we assume that the ok_button is only active if the entry fields
+ * contain sensible data.
+ **/
+static void
+chi_squared_tool_ok_clicked_cb (G_GNUC_UNUSED GtkWidget *button,
+				 ChiSquaredIToolState *state)
+{
+	data_analysis_output_t  *dao;
+	GtkWidget *w;
+	analysis_tools_data_chi_squared_t *data;
+
+	data = g_new0 (analysis_tools_data_chi_squared_t, 1);
+	dao  = parse_output ((GenericToolState *)state, NULL);
+
+	data->input = gnm_expr_entry_parse_as_value
+		(GNM_EXPR_ENTRY (state->base.input_entry),
+		 state->base.sheet);
+
+	data->wbc = WORKBOOK_CONTROL (state->base.wbcg);
+
+        data->labels = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (state->label));
+
+	data->alpha = gtk_spin_button_get_value
+		(GTK_SPIN_BUTTON (state->alpha_entry));
+
+	w = glade_xml_get_widget (state->base.gui, "test-of-independence");
+	data->independence = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w));
+
+	data->n_c = (data->input->v_range.cell.b.col - data->input->v_range.cell.a.col + 1);
+	data->n_r = (data->input->v_range.cell.b.row - data->input->v_range.cell.a.row + 1);
+
+	if (data->labels)
+		data->n_c--, data->n_r--;
+
+
+	if (!cmd_analysis_tool (data->wbc, state->base.sheet,
+				dao, data, analysis_tool_chi_squared_engine))
+		gtk_widget_destroy (state->base.dialog);
+
+	return;
+}
+
+static int
+calc_min_size (GnmValue *input_range)
+{
+	int row = (input_range->v_range.cell.b.row - input_range->v_range.cell.a.row + 1);
+	int col = (input_range->v_range.cell.b.col - input_range->v_range.cell.a.col + 1);
+	
+	return ((row < col) ? row : col);
+}
+
+/**
+ * chi_squared_tool_update_sensitivity_cb:
+ * @state:
+ *
+ * Update the dialog widgets sensitivity.
+ * We cannot use tool_update_sensitivity_cb
+ * since we are also considering whether in fact
+ * an alpha is given.
+ **/
+static void
+chi_squared_tool_update_sensitivity_cb (G_GNUC_UNUSED GtkWidget *dummy,
+					ChiSquaredIToolState  *state)
+{
+	gnm_float alpha;
+        GnmValue *input_range;
+
+	/* Checking Input Range */
+        input_range = gnm_expr_entry_parse_as_value
+		(GNM_EXPR_ENTRY (state->base.input_entry),
+		 state->base.sheet);
+	if (input_range == NULL) {
+		gtk_label_set_text (GTK_LABEL (state->base.warning),
+				    _("The input range is invalid."));
+		gtk_widget_set_sensitive (state->base.ok_button, FALSE);
+		return;
+	} else {
+		int min_size = calc_min_size (input_range);
+		gboolean label = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (state->label));
+		value_release (input_range);
+
+		if (min_size < (label ? 3 : 2)) {
+			gtk_label_set_text (GTK_LABEL (state->base.warning),
+					    _("The input range is too small."));
+			gtk_widget_set_sensitive (state->base.ok_button, FALSE);
+			return;
+		}
+	}
+
+	/* Checking Alpha*/
+	alpha = gtk_spin_button_get_value
+		(GTK_SPIN_BUTTON (state->alpha_entry));
+	if (!(alpha > 0 && alpha < 1)) {
+		gtk_label_set_text (GTK_LABEL (state->base.warning),
+				    _("The alpha value should "
+				      "be a number between 0 and 1."));
+		gtk_widget_set_sensitive (state->base.ok_button, FALSE);
+		return;
+	}
+
+	/* Checking Output Page */
+	if (!gnm_dao_is_ready (GNM_DAO (state->base.gdao))) {
+		gtk_label_set_text (GTK_LABEL (state->base.warning),
+				    _("The output specification "
+				      "is invalid."));
+		gtk_widget_set_sensitive (state->base.ok_button, FALSE);
+		return;
+	}
+
+	gtk_label_set_text (GTK_LABEL (state->base.warning), "");
+	gtk_widget_set_sensitive (state->base.ok_button, TRUE);
+
+}
+
+
+/**
+ * dialog_chi_squared_tool:
+ * @wbcg:
+ * @sheet:
+ * @independence
+ *
+ * Show the dialog (guru).
+ *
+ **/
+int
+dialog_chi_square_tool (WBCGtk *wbcg, Sheet *sheet, gboolean independence)
+{
+        ChiSquaredIToolState *state;
+	char const *type;
+
+	if (wbcg == NULL) {
+		return 1;
+	}
+
+
+	/* Only pop up one copy per workbook */
+	if (gnumeric_dialog_raise_if_exists (wbcg, CHI_SQUARED_I_KEY))
+		return 0;
+
+	state = g_new0 (ChiSquaredIToolState, 1);
+
+	if (dialog_tool_init (&state->base, wbcg, sheet,
+			      GNUMERIC_HELP_LINK_CHI_SQUARED,
+			      "chi-squared.glade", "Chi-Squared Tests",
+			      _("Could not create the Chi Squared Tests "
+				"tool dialog."),
+			      CHI_SQUARED_I_KEY,
+			      G_CALLBACK (chi_squared_tool_ok_clicked_cb),
+			      NULL,
+			      G_CALLBACK (chi_squared_tool_update_sensitivity_cb),
+			      GNM_EE_SINGLE_RANGE))
+		return 0;
+
+	if (independence)
+		type ="test-of-independence";
+	else
+		type ="test-of-homogeneity";
+	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (glade_xml_get_widget (state->base.gui, type)),
+				      TRUE);
+	state->label = glade_xml_get_widget (state->base.gui,
+						   "labels_button");
+	g_signal_connect_after (G_OBJECT (state->label),
+		"toggled",
+		G_CALLBACK (chi_squared_tool_update_sensitivity_cb), state);
+	state->alpha_entry = glade_xml_get_widget (state->base.gui,
+						   "alpha-entry");
+	float_to_entry (GTK_ENTRY (state->alpha_entry), 0.05);
+	g_signal_connect_after (G_OBJECT (state->alpha_entry),
+		"changed",
+		G_CALLBACK (chi_squared_tool_update_sensitivity_cb), state);
+	gnumeric_editable_enters (GTK_WINDOW (state->base.dialog),
+				  GTK_WIDGET (state->alpha_entry));
+
+	gnm_dao_set_put (GNM_DAO (state->base.gdao), TRUE, TRUE);
+	chi_squared_tool_update_sensitivity_cb (NULL, state);
+	tool_load_selection ((GenericToolState *)state, TRUE);
+
+        return 0;
+}
diff --git a/src/dialogs/dialogs.h b/src/dialogs/dialogs.h
index 99d9f60..68bebb1 100644
--- a/src/dialogs/dialogs.h
+++ b/src/dialogs/dialogs.h
@@ -90,6 +90,7 @@ int dialog_anova_two_factor_tool (WBCGtk *wbcg, Sheet *sheet);
 int dialog_histogram_tool	 (WBCGtk *wbcg, Sheet *sheet);
 int dialog_frequency_tool	 (WBCGtk *wbcg, Sheet *sheet);
 int dialog_kaplan_meier_tool	 (WBCGtk *wbcg, Sheet *sheet);
+int dialog_chi_square_tool       (WBCGtk *wbcg, Sheet *sheet, gboolean independence);
 
 typedef enum {
 	TTEST_PAIRED = 1,
diff --git a/src/dialogs/help.h b/src/dialogs/help.h
index d9b2a1f..42328e7 100644
--- a/src/dialogs/help.h
+++ b/src/dialogs/help.h
@@ -146,6 +146,9 @@
 #define GNUMERIC_HELP_LINK_ANOVA_SINGLE_FACTOR "sect-analysis-statistical"
 #define GNUMERIC_HELP_LINK_ANOVA_TWO_FACTOR "sect-analysis-statistical"
 
+/* dialog-analysis-tool-chi-squared.c */
+#define GNUMERIC_HELP_LINK_CHI_SQUARED "sect-analysis-statistical"
+
 /* dialog-analysis-tool-frequency.c */
 #define GNUMERIC_HELP_LINK_FREQUENCY "sect-analysis-statistical"
 
diff --git a/src/tools/ChangeLog b/src/tools/ChangeLog
index fcdc9c8..c0b35a6 100644
--- a/src/tools/ChangeLog
+++ b/src/tools/ChangeLog
@@ -1,3 +1,8 @@
+2009-06-07  Andreas J. Guelzow <aguelzow pyrshep ca>
+
+	* analysis-chi-squared.[ch]: new
+	* Makefile.am: added teh above
+
 2009-06-05  Andreas J. Guelzow <aguelzow pyrshep ca>
 
 	* analysis-tools.h (gnm_fourier_fft): moved to
diff --git a/src/tools/Makefile.am b/src/tools/Makefile.am
index e2af808..1e423d1 100644
--- a/src/tools/Makefile.am
+++ b/src/tools/Makefile.am
@@ -19,8 +19,10 @@ AM_CPPFLAGS = 						\
 noinst_LTLIBRARIES = libtools.la
 
 libtools_la_SOURCES =					\
-	analysis-anova.c			\
-	analysis-anova.h			\
+	analysis-anova.c				\
+	analysis-anova.h				\
+	analysis-chi-squared.c				\
+	analysis-chi-squared.h				\
 	analysis-exp-smoothing.c			\
 	analysis-exp-smoothing.h			\
 	analysis-frequency.c				\
diff --git a/src/tools/analysis-chi-squared.c b/src/tools/analysis-chi-squared.c
new file mode 100644
index 0000000..358b618
--- /dev/null
+++ b/src/tools/analysis-chi-squared.c
@@ -0,0 +1,213 @@
+/* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * analysis-chi-squared.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-chi-squared.h"
+#include "analysis-tools.h"
+#include "value.h"
+#include "ranges.h"
+#include "expr.h"
+#include "func.h"
+#include "numbers.h"
+
+static gboolean
+analysis_tool_chi_squared_engine_run (data_analysis_output_t *dao,
+				      analysis_tools_data_chi_squared_t *info)
+{
+	GnmExpr const *expr_check;
+	GnmExpr const *expr_region;
+	GnmExpr const *expr_statistic;
+	GnmExpr const *expr_ones;
+	GnmExpr const *expr_row;
+	GnmExpr const *expr_expect;
+
+	GnmFunc *fd_mmult;
+	GnmFunc *fd_row;
+	GnmFunc *fd_transpose;
+	GnmFunc *fd_sum;
+	GnmFunc *fd_min;
+	GnmFunc *fd_offset;
+	GnmFunc *fd_chiinv;
+	GnmFunc *fd_chidist;
+	char const *label;
+	char *cc;
+
+	label = (info->independence) 
+		? _("[>=5]\"Test of Independence\";[<5][Red]\"Invalid Test of Independence\"") 
+		: _("[>=5]\"Test of Homogeneity\";[<5][Red]\"Invalid Test of Homogeneity\"");
+
+	fd_mmult = gnm_func_lookup ("MMULT", NULL);
+	gnm_func_ref (fd_mmult);
+	fd_row = gnm_func_lookup ("ROW", NULL);
+	gnm_func_ref (fd_row);
+	fd_transpose = gnm_func_lookup ("TRANSPOSE", NULL);
+	gnm_func_ref (fd_transpose);
+	fd_sum = gnm_func_lookup ("SUM", NULL);
+	gnm_func_ref (fd_sum);
+	fd_min = gnm_func_lookup ("MIN", NULL);
+	gnm_func_ref (fd_min);
+	fd_offset = gnm_func_lookup ("OFFSET", NULL);
+	gnm_func_ref (fd_offset);
+	fd_chiinv = gnm_func_lookup ("CHIINV", NULL);
+	gnm_func_ref (fd_chiinv);
+	fd_chidist = gnm_func_lookup ("CHIDIST", NULL);
+	gnm_func_ref (fd_chidist);
+
+	dao_set_italic (dao, 0, 1, 0, 4);
+	set_cell_text_col (dao, 0, 1, _("/Test Statistic:"
+					"/Degrees of Freedom:"
+					"/p-Value:"
+					"/Critical Value:"));
+	cc = g_strdup_printf ("%s = %.2f", "\xce\xb1", info->alpha);
+	dao_set_cell_comment (dao, 0, 4, cc);
+	g_free (cc);
+
+	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_row = gnm_expr_new_funcall1 (fd_row, gnm_expr_copy (expr_region));
+	expr_ones = gnm_expr_new_binary (gnm_expr_copy (expr_row), 
+					 GNM_EXPR_OP_DIV,
+					 expr_row);
+	expr_expect = gnm_expr_new_binary (gnm_expr_new_funcall2
+					   (fd_mmult,
+					    gnm_expr_new_funcall2
+					    (fd_mmult,
+					     gnm_expr_copy (expr_region),
+					     gnm_expr_copy (expr_ones)),
+					    gnm_expr_new_funcall2
+					    (fd_mmult,
+					     gnm_expr_new_funcall1 (fd_transpose, gnm_expr_copy (expr_ones)),
+					     gnm_expr_copy (expr_region))),
+					   GNM_EXPR_OP_DIV,
+					   gnm_expr_new_funcall1 (fd_sum, gnm_expr_copy (expr_region)));
+
+	expr_check = gnm_expr_new_funcall1 (fd_min, gnm_expr_copy (expr_expect));
+	dao_set_merge (dao, 0, 0, 1, 0);
+	dao_set_italic (dao, 0, 0, 0, 0);
+	dao_set_cell_expr (dao, 0, 0, expr_check);
+	dao_set_format (dao, 0, 0, 0, 0, label);
+	dao_set_align (dao, 0, 0, 0, 0, HALIGN_CENTER, VALIGN_BOTTOM);
+
+	expr_statistic = gnm_expr_new_funcall1 (fd_sum, 
+						gnm_expr_new_binary 
+						(gnm_expr_new_binary (gnm_expr_new_binary 
+								      (gnm_expr_copy (expr_region), 
+								       GNM_EXPR_OP_SUB, 
+								       gnm_expr_copy (expr_expect)),
+								      GNM_EXPR_OP_EXP,
+								      gnm_expr_new_constant (value_new_int (2))),
+						 GNM_EXPR_OP_DIV,
+						 gnm_expr_copy (expr_expect)));
+	dao_set_cell_array_expr (dao, 1, 1, expr_statistic);
+	
+	dao_set_cell_int (dao, 1, 2, (info->n_r - 1)*(info->n_c - 1));
+	dao_set_cell_expr(dao, 1, 3, gnm_expr_new_funcall2
+			  (fd_chidist, make_cellref (0,-2),  make_cellref (0,-1)));
+	dao_set_cell_expr(dao, 1, 4, gnm_expr_new_funcall2
+			  (fd_chiinv, 
+			   gnm_expr_new_constant (value_new_float (info->alpha)),  
+			   make_cellref (0,-2)));
+
+	gnm_func_unref (fd_mmult);
+	gnm_func_unref (fd_row);
+	gnm_func_unref (fd_transpose);
+	gnm_func_unref (fd_sum);
+	gnm_func_unref (fd_min);
+	gnm_func_unref (fd_offset);
+	gnm_func_unref (fd_chiinv);
+	gnm_func_unref (fd_chidist);
+
+	gnm_expr_free (expr_ones);
+	gnm_expr_free (expr_expect);
+	gnm_expr_free (expr_region);
+	dao_redraw_respan (dao);
+
+	return FALSE;
+}
+
+static gboolean
+analysis_tool_chi_squared_clean (gpointer specs)
+{
+	analysis_tools_data_chi_squared_t *info = specs;
+
+	if (info->input)
+		value_release (info->input);
+	info->input = NULL;
+
+	return FALSE;
+}
+
+
+gboolean
+analysis_tool_chi_squared_engine (data_analysis_output_t *dao, gpointer specs,
+			      analysis_tool_engine_t selector, gpointer result)
+{
+	analysis_tools_data_chi_squared_t *info = specs;
+
+	switch (selector) {
+	case TOOL_ENGINE_UPDATE_DESCRIPTOR:
+		return (dao_command_descriptor 
+			(dao, 
+			 info->independence ? 
+			 _("Test of Independence (%s)")
+			 : _("Test of Homogeneity (%s)"), result)
+			== NULL);
+	case TOOL_ENGINE_UPDATE_DAO:
+		dao_adjust (dao, 2, 5);
+		return FALSE;
+	case TOOL_ENGINE_CLEAN_UP:
+		return analysis_tool_chi_squared_clean (specs);
+	case TOOL_ENGINE_LAST_VALIDITY_CHECK:
+		return FALSE;
+	case TOOL_ENGINE_PREPARE_OUTPUT_RANGE:
+		dao_prepare_output (NULL, dao, info->independence ? 
+				    _("Test of Independence")
+				    : _("Test of Homogeneity"));
+		return FALSE;
+	case TOOL_ENGINE_FORMAT_OUTPUT_RANGE:
+		return dao_format_output (dao,  info->independence ? 
+					  _("Test of Independence")
+					  : _("Test of Homogeneity"));
+	case TOOL_ENGINE_PERFORM_CALC:
+	default:
+		return analysis_tool_chi_squared_engine_run (dao, specs);
+	}
+	return TRUE;
+}
+
+
+
+
diff --git a/src/tools/analysis-chi-squared.h b/src/tools/analysis-chi-squared.h
new file mode 100644
index 0000000..86f541b
--- /dev/null
+++ b/src/tools/analysis-chi-squared.h
@@ -0,0 +1,50 @@
+/* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * analysis-chi-squared.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_CHI_SQUARED_H
+#define ANALYSIS_CHI_SQUARED_H
+
+#include "gnumeric.h"
+#include "numbers.h"
+#include "dao.h"
+#include "tools.h"
+#include "analysis-tools.h"
+
+typedef struct {
+	WorkbookControl *wbc;
+	GnmValue        *input;
+	gboolean         labels;
+	gboolean         independence;
+	gnm_float        alpha;
+	gint             n_c;
+	gint             n_r;
+} analysis_tools_data_chi_squared_t;
+
+gboolean analysis_tool_chi_squared_engine (data_analysis_output_t *dao, gpointer specs,
+					   analysis_tool_engine_t selector, gpointer result);
+
+
+#endif
diff --git a/src/wbc-gtk-actions.c b/src/wbc-gtk-actions.c
index cf65d41..9a89bc2 100644
--- a/src/wbc-gtk-actions.c
+++ b/src/wbc-gtk-actions.c
@@ -855,6 +855,8 @@ static GNM_ACTION_DEF (cb_tools_scenarios)	{ dialog_scenarios (wbcg); }
 static GNM_ACTION_DEF (cb_tools_simulation)	{ dialog_simulation (wbcg, wbcg_cur_sheet (wbcg)); }
 static GNM_ACTION_DEF (cb_tools_anova_one_factor) { dialog_anova_single_factor_tool (wbcg, wbcg_cur_sheet (wbcg)); }
 static GNM_ACTION_DEF (cb_tools_anova_two_factor) { dialog_anova_two_factor_tool (wbcg, wbcg_cur_sheet (wbcg)); }
+static GNM_ACTION_DEF (cb_tools_chi_square_independence) { dialog_chi_square_tool (wbcg, wbcg_cur_sheet (wbcg), TRUE); }
+static GNM_ACTION_DEF (cb_tools_chi_square_homogeneity) { dialog_chi_square_tool (wbcg, wbcg_cur_sheet (wbcg), FALSE); }
 static GNM_ACTION_DEF (cb_tools_correlation)	{ dialog_correlation_tool (wbcg, wbcg_cur_sheet (wbcg)); }
 static GNM_ACTION_DEF (cb_tools_covariance)	{ dialog_covariance_tool (wbcg, wbcg_cur_sheet (wbcg)); }
 static GNM_ACTION_DEF (cb_tools_desc_statistics) { dialog_descriptive_stat_tool (wbcg, wbcg_cur_sheet (wbcg)); }
@@ -1702,6 +1704,7 @@ static GtkActionEntry const permanent_actions[] = {
 		{ "MenuToolsScenarios",	NULL,	N_("Sce_narios") },
 		{ "MenuToolStatisticalAnalysis",	NULL,	N_("Statistical Anal_ysis") },
 		{ "MenuANOVA",	NULL,	N_("_ANOVA") },
+		{ "MenuContingencyTests",	NULL,	N_("Contin_gency Table") },
 		{ "MenuToolForecast",	NULL,	N_("F_orecast") },
 		{ "MenuToolFrequencies",	NULL,	N_("Fre_quency Tables") },
 		{ "MenuToolTTest",	NULL,	N_("Two _Means") },
@@ -2094,6 +2097,14 @@ static GtkActionEntry const actions[] = {
 		NULL, N_("Two Factor Analysis of Variance..."),
 		G_CALLBACK (cb_tools_anova_two_factor) },
 
+/* Tools -> Chi Square Tests */
+	{ "ToolsHomogeneity", NULL, N_("Test of _Homogeneity..."),
+		NULL, N_("Chi Squared Test of Homogeneity..."),
+		G_CALLBACK (cb_tools_chi_square_homogeneity) },
+	{ "ToolsIndependence", NULL, N_("Test of _Independence..."),
+		NULL, N_("Chi Squared Test of Independence..."),
+		G_CALLBACK (cb_tools_chi_square_independence) },
+
 /* Tools -> Forecasting */
 	{ "ToolsExpSmoothing", NULL, N_("_Exponential Smoothing..."),
 		NULL, N_("Exponential smoothing..."),



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]