[gnumeric] Add tool to create correlated normal random variates



commit 2db8ff5af4f1fd2c0c52cd9b6613bc6f1bbdf822
Author: Andreas J. Guelzow <aguelzow pyrshep ca>
Date:   Sun Sep 6 00:09:17 2009 -0600

    Add tool to create correlated normal random variates
    
    2009-09-06  Andreas J. Guelzow <aguelzow pyrshep ca>
    
    	* component/Gnumeric-embed.xml.in: split random generator menu item
    	* src/GNOME_Gnumeric-gtk.xml.in: ditto
    	* src/HILDON_Gnumeric-gtk.xml.in: ditto
    	* src/wbc-gtk-actions.c: ditto
    
    2009-09-06  Andreas J. Guelzow <aguelzow pyrshep ca>
    
    	* POTFILES.in: add src/dialogs/dialog-random-generator-cor.c,
    	  src/dialogs/random-generation-cor.glade and
    	  src/tools/random-generator-cor.c
    
    2009-09-06  Andreas J. Guelzow <aguelzow pyrshep ca>
    
    	* random-generator-cor.c: new
    	* random-generator-cor.h: new
    	* Makefile.am: add the above
    
    2009-09-06  Andreas J. Guelzow <aguelzow pyrshep ca>
    
    	* openoffice-write.c (odf_write_surface_chart_style): we consider
    	  multi-series=FALSE the default
    	(odf_write_xl_surface_chart_style): obey state->with_extension
    
    2009-09-06  Andreas J. Guelzow <aguelzow pyrshep ca>
    
    	* POTFILES.in: add src/dialogs/dialog-random-generator-cor.c
    	  and src/tools/random-generator-cor.c
    	* POTFILES.skip: add src/dialogs/random-generation-cor.glade
    
    2009-09-06  Andreas J. Guelzow <aguelzow pyrshep ca>
    
    	* random-generation-cor.glade: new
    	* dialog-random-generator-cor.c: new
    	* Makefile.am: add the above
    	* dialogs.h (dialog_random_cor_tool): new
    	* help.h (GNUMERIC_HELP_LINK_RANDOM_GENERATOR_COR): new

 ChangeLog                                 |    7 +
 component/Gnumeric-embed.xml.in           |    5 +-
 plugins/openoffice/ChangeLog              |    6 +
 plugins/openoffice/openoffice-write.c     |    4 +-
 po-functions/ChangeLog                    |    6 +
 po-functions/POTFILES.in                  |    2 +
 po-functions/POTFILES.skip                |    1 +
 po/ChangeLog                              |    6 +
 po/POTFILES.in                            |    3 +
 src/GNOME_Gnumeric-gtk.xml.in             |    5 +-
 src/HILDON_Gnumeric-gtk.xml.in            |    5 +-
 src/dialogs/ChangeLog                     |    8 +
 src/dialogs/Makefile.am                   |    2 +
 src/dialogs/dialog-random-generator-cor.c |  238 ++++++++++++++++++++++++++
 src/dialogs/dialogs.h                     |    1 +
 src/dialogs/help.h                        |    3 +
 src/dialogs/random-generation-cor.glade   |  260 +++++++++++++++++++++++++++++
 src/tools/ChangeLog                       |    6 +
 src/tools/Makefile.am                     |    2 +
 src/tools/random-generator-cor.c          |  168 +++++++++++++++++++
 src/tools/random-generator-cor.h          |   27 +++
 src/wbc-gtk-actions.c                     |   13 +-
 22 files changed, 769 insertions(+), 9 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 4abec13..3b9a2f7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2009-09-06  Andreas J. Guelzow <aguelzow pyrshep ca>
+
+	* component/Gnumeric-embed.xml.in: split random generator menu item
+	* src/GNOME_Gnumeric-gtk.xml.in: ditto
+	* src/HILDON_Gnumeric-gtk.xml.in: ditto
+	* src/wbc-gtk-actions.c: ditto
+
 2009-09-05  Morten Welinder  <terra gnome org>
 
 	* configure.in: Post-release bump.
diff --git a/component/Gnumeric-embed.xml.in b/component/Gnumeric-embed.xml.in
index 3b07ed2..1a86363 100644
--- a/component/Gnumeric-embed.xml.in
+++ b/component/Gnumeric-embed.xml.in
@@ -36,7 +36,10 @@
         <menuitem action="ToolsMerge"/>
         <menuitem action="ToolsTabulate"/>
         <menuitem action="EditFillSeries"/>
-        <menuitem action="RandomGenerator"/>
+        <menu name="RandomGenerator" action="MenuRandomGenerator">
+          <menuitem action="RandomGeneratorUncorrelated"/>
+          <menuitem action="RandomGeneratorCorrelated"/>
+        </menu>
       </menu>
       <menu name="Clear" action="MenuEditClear">
         <menuitem action="EditClearAll"/>
diff --git a/plugins/openoffice/ChangeLog b/plugins/openoffice/ChangeLog
index c158fc3..24f27f3 100644
--- a/plugins/openoffice/ChangeLog
+++ b/plugins/openoffice/ChangeLog
@@ -1,3 +1,9 @@
+2009-09-06  Andreas J. Guelzow <aguelzow pyrshep ca>
+
+	* openoffice-write.c (odf_write_surface_chart_style): we consider
+	  multi-series=FALSE the default
+	(odf_write_xl_surface_chart_style): obey state->with_extension
+
 2009-09-05  Morten Welinder <terra gnome org>
 
 	* Release 1.9.12
diff --git a/plugins/openoffice/openoffice-write.c b/plugins/openoffice/openoffice-write.c
index 2e7b2fa..c98c0ad 100644
--- a/plugins/openoffice/openoffice-write.c
+++ b/plugins/openoffice/openoffice-write.c
@@ -3375,14 +3375,14 @@ static void
 odf_write_surface_chart_style (GnmOOExport *state, G_GNUC_UNUSED GogObject const *chart, G_GNUC_UNUSED GogObject const *plot)
 {
 	odf_add_bool (state->xml, CHART "three-dimensional", TRUE);
-	odf_add_bool (state->xml, GNMSTYLE "multi-series", FALSE);
 }
 
 static void
 odf_write_xl_surface_chart_style (GnmOOExport *state, G_GNUC_UNUSED GogObject const *chart, G_GNUC_UNUSED GogObject const *plot)
 {
 	odf_add_bool (state->xml, CHART "three-dimensional", TRUE);
-	odf_add_bool (state->xml, GNMSTYLE "multi-series", TRUE);
+	if (state->with_extension)
+		odf_add_bool (state->xml, GNMSTYLE "multi-series", TRUE);
 }
 
 static void
diff --git a/po-functions/ChangeLog b/po-functions/ChangeLog
index 69d66a5..40bdecb 100644
--- a/po-functions/ChangeLog
+++ b/po-functions/ChangeLog
@@ -1,3 +1,9 @@
+2009-09-06  Andreas J. Guelzow <aguelzow pyrshep ca>
+
+	* POTFILES.in: add src/dialogs/dialog-random-generator-cor.c
+	  and src/tools/random-generator-cor.c
+	* POTFILES.skip: add src/dialogs/random-generation-cor.glade
+
 2009-09-05  Morten Welinder <terra gnome org>
 
 	* Release 1.9.12
diff --git a/po-functions/POTFILES.in b/po-functions/POTFILES.in
index 6fb849d..7473e41 100644
--- a/po-functions/POTFILES.in
+++ b/po-functions/POTFILES.in
@@ -101,6 +101,7 @@ src/dialogs/dialog-preferences.c
 src/dialogs/dialog-printer-setup.c
 src/dialogs/dialog-quit.c
 src/dialogs/dialog-random-generator.c
+src/dialogs/dialog-random-generator-cor.c
 src/dialogs/dialog-recent.c
 src/dialogs/dialog-row-height.c
 src/dialogs/dialog-scenarios.c
@@ -194,6 +195,7 @@ src/tools/data-shuffling.c
 src/tools/fill-series.c
 src/tools/filter.c
 src/tools/random-generator.c
+src/tools/random-generator-cor.c
 src/tools/scenarios.c
 src/tools/simulation.c
 src/tools/solver/reports-write.c
diff --git a/po-functions/POTFILES.skip b/po-functions/POTFILES.skip
index d0dba26..7da6c31 100644
--- a/po-functions/POTFILES.skip
+++ b/po-functions/POTFILES.skip
@@ -112,6 +112,7 @@ src/dialogs/plugin-manager.glade
 src/dialogs/preferences.glade
 src/dialogs/print.glade
 src/dialogs/random-generation.glade
+src/dialogs/random-generation-cor.glade
 src/dialogs/rank.glade
 src/dialogs/regression.glade
 src/dialogs/row-height.glade
diff --git a/po/ChangeLog b/po/ChangeLog
index 0b53b99..5982bdb 100644
--- a/po/ChangeLog
+++ b/po/ChangeLog
@@ -1,3 +1,9 @@
+2009-09-06  Andreas J. Guelzow <aguelzow pyrshep ca>
+
+	* POTFILES.in: add src/dialogs/dialog-random-generator-cor.c,
+	  src/dialogs/random-generation-cor.glade and
+	  src/tools/random-generator-cor.c
+
 2009-09-05  Morten Welinder <terra gnome org>
 
 	* Release 1.9.12
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 7cdfbcd..deb7f24 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -178,6 +178,7 @@ src/dialogs/dialog-preferences.c
 src/dialogs/dialog-printer-setup.c
 src/dialogs/dialog-quit.c
 src/dialogs/dialog-random-generator.c
+src/dialogs/dialog-random-generator-cor.c
 src/dialogs/dialog-recent.c
 src/dialogs/dialog-row-height.c
 src/dialogs/dialog-scenarios.c
@@ -228,6 +229,7 @@ src/dialogs/plugin-manager.glade
 src/dialogs/preferences.glade
 src/dialogs/print.glade
 src/dialogs/random-generation.glade
+src/dialogs/random-generation-cor.glade
 src/dialogs/rank.glade
 src/dialogs/regression.glade
 src/dialogs/row-height.glade
@@ -318,6 +320,7 @@ src/tools/data-shuffling.c
 src/tools/fill-series.c
 src/tools/filter.c
 src/tools/random-generator.c
+src/tools/random-generator-cor.c
 src/tools/scenarios.c
 src/tools/simulation.c
 src/tools/solver/reports-write.c
diff --git a/src/GNOME_Gnumeric-gtk.xml.in b/src/GNOME_Gnumeric-gtk.xml.in
index 82fa043..b0dc620 100644
--- a/src/GNOME_Gnumeric-gtk.xml.in
+++ b/src/GNOME_Gnumeric-gtk.xml.in
@@ -200,7 +200,10 @@
         <menuitem action="ToolsMerge"/>
         <menuitem action="ToolsTabulate"/>
         <menuitem action="EditFillSeries"/>
-        <menuitem action="RandomGenerator"/>
+        <menu name="RandomGenerator" action="MenuRandomGenerator">
+          <menuitem action="RandomGeneratorUncorrelated"/>
+          <menuitem action="RandomGeneratorCorrelated"/>
+        </menu>
       </menu>
       <menu name="Filter" action="MenuFilter">
         <menuitem action="DataAutoFilter"/>
diff --git a/src/HILDON_Gnumeric-gtk.xml.in b/src/HILDON_Gnumeric-gtk.xml.in
index 874e9cf..31b8bd2 100644
--- a/src/HILDON_Gnumeric-gtk.xml.in
+++ b/src/HILDON_Gnumeric-gtk.xml.in
@@ -43,7 +43,10 @@
         <menuitem action="ToolsMerge"/>
         <menuitem action="ToolsTabulate"/>
         <menuitem action="EditFillSeries"/>
-        <menuitem action="RandomGenerator"/>
+        <menu name="RandomGenerator" action="MenuRandomGenerator">
+          <menuitem action="RandomGeneratorUncorrelated"/>
+          <menuitem action="RandomGeneratorCorrelated"/>
+        </menu>
       </menu>
       <menu name="Clear" action="MenuEditClear">
         <menuitem action="EditClearAll"/>
diff --git a/src/dialogs/ChangeLog b/src/dialogs/ChangeLog
index db8c5b2..3bf4731 100644
--- a/src/dialogs/ChangeLog
+++ b/src/dialogs/ChangeLog
@@ -1,3 +1,11 @@
+2009-09-06  Andreas J. Guelzow <aguelzow pyrshep ca>
+
+	* random-generation-cor.glade: new
+	* dialog-random-generator-cor.c: new
+	* Makefile.am: add the above
+	* dialogs.h (dialog_random_cor_tool): new
+	* help.h (GNUMERIC_HELP_LINK_RANDOM_GENERATOR_COR): new
+
 2009-09-05  Morten Welinder  <terra gnome org>
 
 	* dialog-stf-export.c (sheet_page_separator_menu_changed): Don't
diff --git a/src/dialogs/Makefile.am b/src/dialogs/Makefile.am
index f3e78d1..ec44c36 100644
--- a/src/dialogs/Makefile.am
+++ b/src/dialogs/Makefile.am
@@ -57,6 +57,7 @@ base_files =					\
 	dialog-plugin-manager.c 		\
 	dialog-preferences.c			\
 	dialog-random-generator.c		\
+	dialog-random-generator-cor.c		\
 	dialog-recent.c				\
 	dialog-row-height.c			\
 	dialog-quit.c				\
@@ -140,6 +141,7 @@ glade_DATA = 				\
 	preferences.glade 		\
 	rank.glade			\
 	random-generation.glade		\
+	random-generation-cor.glade	\
 	regression.glade		\
 	row-height.glade		\
 	sampling.glade			\
diff --git a/src/dialogs/dialog-random-generator-cor.c b/src/dialogs/dialog-random-generator-cor.c
new file mode 100644
index 0000000..f53bff4
--- /dev/null
+++ b/src/dialogs/dialog-random-generator-cor.c
@@ -0,0 +1,238 @@
+/*
+ * dialog-random-generator.c:
+ *
+ * Authors:
+ *  Andreas J. Guelzow  <aguelzow pyrshep ca>
+ *
+ * (C) Copyright 2009  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 "help.h"
+#include "tool-dialogs.h"
+#include "random-generator-cor.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 <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 <widgets/gnumeric-expr-entry.h>
+#include <widgets/gnm-dao.h>
+
+#include <glade/glade.h>
+#include <gtk/gtk.h>
+#include <string.h>
+
+
+/**********************************************/
+/*  Generic guru items */
+/**********************************************/
+
+
+#define RANDOM_COR_KEY            "analysistools-random-cor-dialog"
+
+static char const * const matrix_group[] = {
+	"cov-button",
+	"cholesky-button",
+	NULL
+};
+
+typedef struct {
+	GenericToolState base;
+	GtkWidget *count_entry;
+} RandomCorToolState;
+
+
+/**********************************************/
+/*  Begin of random tool code */
+/**********************************************/
+
+
+/**
+ * random_tool_update_sensitivity:
+ * @dummy:
+ * @state:
+ *
+ * Update the dialog widgets sensitivity if the only items of interest
+ * are the standard input (one range) and output items.
+ **/
+static void
+random_cor_tool_update_sensitivity_cb (G_GNUC_UNUSED GtkWidget *dummy,
+				   RandomCorToolState *state)
+{
+        GnmValue *input_range;	
+	gint height, width, count;
+
+	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 matrix range is not valid."));
+		gtk_widget_set_sensitive (state->base.ok_button, FALSE);
+		return;
+	}
+
+	height = input_range->v_range.cell.b.row - input_range->v_range.cell.a.row;
+	width  = input_range->v_range.cell.b.col - input_range->v_range.cell.a.col;
+	value_release (input_range);
+
+	if (height != width || height == 0) {
+		gtk_label_set_text (GTK_LABEL (state->base.warning),
+				    _("The matrix must be symmetric positive-definite."));
+		gtk_widget_set_sensitive (state->base.ok_button, FALSE);
+		return;
+	}
+
+        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;
+	}
+
+	if (entry_to_int (GTK_ENTRY (state->count_entry), &count, FALSE) != 0 ||
+	    count <= 0) {
+		gtk_label_set_text (GTK_LABEL (state->base.warning),
+				    _("The number of random numbers requested 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);
+}
+
+/**
+ * random_cor_tool_ok_clicked_cb:
+ * @button:
+ * @state:
+ *
+ * Retrieve the information from the dialog and call the appropriate tool.
+ * Note that we assume that the ok_button is only active if the entry fields
+ * contain sensible data.
+ **/
+static void
+random_cor_tool_ok_clicked_cb (GtkWidget *button, RandomCorToolState *state)
+{
+	data_analysis_output_t  *dao;
+	tools_data_random_cor_t  *data;
+	gint err;
+
+	data = g_new0 (tools_data_random_cor_t, 1);
+
+	dao  = parse_output ((GenericToolState *)state, NULL);
+	err = entry_to_int (GTK_ENTRY (state->count_entry), &data->count, FALSE);
+	data->matrix = gnm_expr_entry_parse_as_value
+		(GNM_EXPR_ENTRY (state->base.input_entry),
+		 state->base.sheet);
+
+	data->variables = data->matrix->v_range.cell.b.row - 
+		data->matrix->v_range.cell.a.row + 1;
+
+	data->matrix_type = gnumeric_glade_group_value 
+		(state->base.gui, matrix_group);
+
+
+	if (!cmd_analysis_tool (WORKBOOK_CONTROL (state->base.wbcg),
+				state->base.sheet,
+				dao, data, tool_random_cor_engine) &&
+	    (button == state->base.ok_button))
+		gtk_widget_destroy (state->base.dialog);
+}
+
+
+/**
+ * dialog_random_tool_init:
+ * @state:
+ *
+ * Create the dialog (guru).
+ *
+ **/
+static void
+dialog_random_cor_tool_init (RandomCorToolState *state)
+{
+	state->count_entry = glade_xml_get_widget (state->base.gui, "count_entry");
+	int_to_entry (GTK_ENTRY (state->count_entry), 2);
+	gnumeric_editable_enters (GTK_WINDOW (state->base.dialog),
+				  GTK_WIDGET (state->count_entry));
+	g_signal_connect_after (G_OBJECT (state->count_entry),
+				"changed",
+				G_CALLBACK (random_cor_tool_update_sensitivity_cb), state);
+}
+
+
+/**
+ * dialog_random_tool:
+ * @wbcg:
+ * @sheet:
+ *
+ * Show the dialog (guru).
+ *
+ **/
+int
+dialog_random_cor_tool (WBCGtk *wbcg, Sheet *sheet)
+{
+        RandomCorToolState *state;
+
+	if (wbcg == NULL) {
+		return 1;
+	}
+
+
+	/* Only pop up one copy per workbook */
+	if (gnumeric_dialog_raise_if_exists (wbcg, RANDOM_COR_KEY)) {
+		return 0;
+	}
+
+	state = g_new (RandomCorToolState, 1);
+
+	if (dialog_tool_init ((GenericToolState *)state, wbcg, sheet,
+			      GNUMERIC_HELP_LINK_RANDOM_GENERATOR_COR,
+			      "random-generation-cor.glade", "CorRandom",
+			      _("Could not create the Correlated Random Tool dialog."),
+			      RANDOM_COR_KEY,
+			      G_CALLBACK (random_cor_tool_ok_clicked_cb), NULL,
+			      G_CALLBACK (random_cor_tool_update_sensitivity_cb),
+			      0))
+		return 0;
+
+
+	gnm_dao_set_put (GNM_DAO (state->base.gdao), TRUE, TRUE);
+	dialog_random_cor_tool_init (state);
+
+	tool_load_selection ((GenericToolState *)state, TRUE);
+
+	gtk_widget_show_all (state->base.dialog);
+
+        return 0;
+}
diff --git a/src/dialogs/dialogs.h b/src/dialogs/dialogs.h
index 6c9fa9b..3242ab3 100644
--- a/src/dialogs/dialogs.h
+++ b/src/dialogs/dialogs.h
@@ -82,6 +82,7 @@ int dialog_sampling_tool	 (WBCGtk *wbcg, Sheet *sheet);
 int dialog_ftest_tool		 (WBCGtk *wbcg, Sheet *sheet);
 int dialog_regression_tool	 (WBCGtk *wbcg, Sheet *sheet);
 int dialog_random_tool		 (WBCGtk *wbcg, Sheet *sheet);
+int dialog_random_cor_tool	 (WBCGtk *wbcg, Sheet *sheet);
 int dialog_average_tool		 (WBCGtk *wbcg, Sheet *sheet);
 int dialog_exp_smoothing_tool	 (WBCGtk *wbcg, Sheet *sheet);
 int dialog_fourier_tool		 (WBCGtk *wbcg, Sheet *sheet);
diff --git a/src/dialogs/help.h b/src/dialogs/help.h
index 90a2f1f..8f26fc5 100644
--- a/src/dialogs/help.h
+++ b/src/dialogs/help.h
@@ -164,6 +164,9 @@
 /* dialog-random-generator.c */
 #define GNUMERIC_HELP_LINK_RANDOM_GENERATOR "sect-dataentryadv"
 
+/* dialog-random-generator-cor.c */
+#define GNUMERIC_HELP_LINK_RANDOM_GENERATOR_COR "sect-dataentryadv"
+
 /* dialog-scenarios.c */
 #define GNUMERIC_HELP_LINK_SCENARIOS_ADD "sect-advanced-analysis-scenarios"
 #define GNUMERIC_HELP_LINK_SCENARIOS_VIEW "sect-advanced-analysis-scenarios"
diff --git a/src/dialogs/random-generation-cor.glade b/src/dialogs/random-generation-cor.glade
new file mode 100644
index 0000000..d8a2660
--- /dev/null
+++ b/src/dialogs/random-generation-cor.glade
@@ -0,0 +1,260 @@
+<?xml version="1.0"?>
+<glade-interface>
+  <widget class="GtkDialog" id="CorRandom">
+    <property name="border_width">5</property>
+    <property name="title" translatable="yes">Correlated Random Number Generator</property>
+    <property name="type_hint">dialog</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="GtkVBox" id="vbox2">
+            <property name="visible">True</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="GtkVBox" id="vbox3">
+                    <property name="visible">True</property>
+                    <child>
+                      <widget class="GtkTable" id="table4">
+                        <property name="visible">True</property>
+                        <property name="border_width">12</property>
+                        <property name="n_rows">2</property>
+                        <child>
+                          <widget class="GtkRadioButton" id="cholesky-button">
+                            <property name="label" translatable="yes">Cholesky _Decomposition of the Covariance Matrix</property>
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="receives_default">False</property>
+                            <property name="draw_indicator">True</property>
+                            <property name="group">cov-button</property>
+                            <property name="use_underline">True</property>
+                          </widget>
+                          <packing>
+                            <property name="top_attach">1</property>
+                            <property name="bottom_attach">2</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <widget class="GtkRadioButton" id="cov-button">
+                            <property name="label" translatable="yes">Co_variance Matrix</property>
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="receives_default">False</property>
+                            <property name="active">True</property>
+                            <property name="draw_indicator">True</property>
+                            <property name="use_underline">True</property>
+                          </widget>
+                        </child>
+                      </widget>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">False</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <widget class="GtkTable" id="input-table">
+                        <property name="visible">True</property>
+                        <property name="border_width">12</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">_Matrix:</property>
+                            <property name="use_underline">True</property>
+                          </widget>
+                          <packing>
+                            <property name="x_options">GTK_FILL</property>
+                            <property name="y_options"></property>
+                          </packing>
+                        </child>
+                        <child>
+                          <placeholder/>
+                        </child>
+                      </widget>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">False</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <placeholder/>
+                    </child>
+                  </widget>
+                </child>
+                <child>
+                  <widget class="GtkLabel" id="label2">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">Input</property>
+                    <property name="use_underline">True</property>
+                  </widget>
+                  <packing>
+                    <property name="tab_fill">False</property>
+                    <property name="type">tab</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkTable" id="table3">
+                    <property name="visible">True</property>
+                    <property name="border_width">12</property>
+                    <property name="n_columns">2</property>
+                    <property name="column_spacing">12</property>
+                    <child>
+                      <widget class="GtkEntry" id="count_entry">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+			<property name="editable">True</property>
+			<property name="visibility">True</property>
+			<property name="max_length">0</property>
+			<property name="text" translatable="yes"></property>
+			<property name="has_frame">True</property>
+			<property name="invisible_char" translatable="yes">*</property>
+			<property name="activates_default">False</property>
+                      </widget>
+                      <packing>
+                        <property name="left_attach">1</property>
+                        <property name="right_attach">2</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <widget class="GtkLabel" id="label3">
+                        <property name="visible">True</property>
+                        <property name="xalign">0</property>
+                        <property name="label" translatable="yes">Number of _random numbers:</property>
+                        <property name="use_underline">True</property>
+			<property name="mnemonic_widget">count_entry</property>
+                      </widget>
+                      <packing>
+                        <property name="x_options">GTK_FILL</property>
+                        <property name="y_options"></property>
+                      </packing>
+                    </child>
+                  </widget>
+                  <packing>
+                    <property name="tab_fill">False</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkLabel" id="label4">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">Options</property>
+                    <property name="use_underline">True</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="label5">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">Output</property>
+                    <property name="use_underline">True</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">0</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkLabel" id="warnings">
+                <property name="visible">True</property>
+              </widget>
+              <packing>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </widget>
+          <packing>
+            <property name="position">1</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/tools/ChangeLog b/src/tools/ChangeLog
index 73a7dea..fe5b6e9 100644
--- a/src/tools/ChangeLog
+++ b/src/tools/ChangeLog
@@ -1,3 +1,9 @@
+2009-09-06  Andreas J. Guelzow <aguelzow pyrshep ca>
+
+	* random-generator-cor.c: new
+	* random-generator-cor.h: new
+	* Makefile.am: add the above
+
 2009-09-05  Morten Welinder <terra gnome org>
 
 	* Release 1.9.12
diff --git a/src/tools/Makefile.am b/src/tools/Makefile.am
index 1e423d1..eaa1f76 100644
--- a/src/tools/Makefile.am
+++ b/src/tools/Makefile.am
@@ -35,6 +35,8 @@ libtools_la_SOURCES =					\
 	analysis-tools.h				\
 	random-generator.c				\
 	random-generator.h				\
+	random-generator-cor.c				\
+	random-generator-cor.h				\
 	dao.c						\
 	dao.h						\
 	data-shuffling.c				\
diff --git a/src/tools/random-generator-cor.c b/src/tools/random-generator-cor.c
new file mode 100644
index 0000000..35f7968
--- /dev/null
+++ b/src/tools/random-generator-cor.c
@@ -0,0 +1,168 @@
+/* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * random-generator-cor.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 "random-generator-cor.h"
+#include "analysis-tools.h"
+#include "value.h"
+#include "ranges.h"
+#include "expr.h"
+#include "dao.h"
+#include "dao.h"
+#include "sheet.h"
+#include "func.h"
+#include "numbers.h"
+
+static gboolean
+tool_random_cor_engine_run (data_analysis_output_t *dao,
+			    tools_data_random_cor_t *info)
+{
+	GnmExpr const *expr_matrix = gnm_expr_new_constant (value_dup (info->matrix));
+	GnmExpr const *expr_rand;
+	GnmFunc *fd_rand;
+	GnmFunc *fd_mmult;
+	GnmFunc *fd_transpose;
+
+	gint i, j;
+
+	if (info->matrix_type == random_gen_cor_type_cov) {
+		GnmFunc *fd_cholesky;
+		GnmExpr const *expr_cholesky;
+	
+		fd_cholesky = gnm_func_lookup_or_add_placeholder 
+			("CHOLESKY", dao->sheet ? dao->sheet->workbook : NULL, FALSE);
+		gnm_func_ref (fd_cholesky);
+		expr_cholesky = gnm_expr_new_funcall1 
+			(fd_cholesky, expr_matrix);
+
+		dao_set_merge (dao, 0, 0, 2 * info->variables, 0);
+		dao_set_italic (dao, 0, 0, 0, 0);
+		dao_set_cell (dao, 0, 0, _("Cholesky Decomposition of the Covariance Matrix"));
+		dao_set_array_expr (dao, 0, 1, info->variables, info->variables, 
+				    expr_cholesky);
+		 
+		gnm_func_unref (fd_cholesky);
+
+		expr_matrix = dao_get_rangeref (dao, 0, 1, info->variables - 1, info->variables);
+		dao->offset_row += info->variables + 2;
+	}
+
+	dao_set_merge (dao, 0, 0, info->variables - 1, 0);
+	dao_set_italic (dao, 0, 0, 0, 0);
+	dao_set_cell (dao, 0, 0, _("Uncorrelated Random Variables"));
+	
+	fd_rand = gnm_func_lookup_or_add_placeholder 
+			("RANDNORM", dao->sheet ? dao->sheet->workbook : NULL, FALSE);
+	gnm_func_ref (fd_rand);
+	expr_rand = gnm_expr_new_funcall2 (fd_rand, 
+					   gnm_expr_new_constant (value_new_int (0)), 
+					   gnm_expr_new_constant (value_new_int (1)));
+	for (i = 0; i < info->variables; i++)
+		for (j = 1; j <= info->count; j++)
+			dao_set_cell_expr (dao, i, j, gnm_expr_copy (expr_rand));
+	gnm_expr_free (expr_rand);
+	gnm_func_unref (fd_rand);
+
+	dao->offset_col += info->variables + 1;
+
+	fd_mmult = gnm_func_lookup_or_add_placeholder 
+		("MMULT", dao->sheet ? dao->sheet->workbook : NULL, FALSE);
+	gnm_func_ref (fd_mmult);
+	fd_transpose = gnm_func_lookup_or_add_placeholder 
+		("TRANSPOSE", dao->sheet ? dao->sheet->workbook : NULL, FALSE);
+	gnm_func_ref (fd_transpose);
+
+	dao_set_merge (dao, 0, 0, info->variables - 1, 0);
+	dao_set_italic (dao, 0, 0, 0, 0);
+	dao_set_cell (dao, 0, 0, _("Correlated Random Variables"));
+
+	expr_rand = gnm_expr_new_funcall2 (fd_mmult,
+					   make_rangeref (-4, 0, -2, 0),
+					   gnm_expr_new_funcall1 
+					   (fd_transpose,
+					    expr_matrix));
+
+	for (j = 1; j <= info->count; j++)
+		dao_set_array_expr (dao, 0, j, info->variables, 1, 
+				    gnm_expr_copy (expr_rand));
+	
+	gnm_expr_free (expr_rand);
+
+	gnm_func_unref (fd_mmult);
+	gnm_func_unref (fd_transpose);
+	dao_redraw_respan (dao);
+
+	return FALSE;
+}
+
+static gboolean
+tool_random_cor_clean (gpointer specs)
+{
+	tools_data_random_cor_t *info = specs;
+
+	if (info->matrix)
+		value_release (info->matrix);
+	info->matrix = NULL;
+
+	return FALSE;
+}
+
+
+gboolean
+tool_random_cor_engine (data_analysis_output_t *dao, gpointer specs,
+			      analysis_tool_engine_t selector, gpointer result)
+{
+	tools_data_random_cor_t *data = specs;
+
+	switch (selector) {
+	case TOOL_ENGINE_UPDATE_DESCRIPTOR:
+		return (dao_command_descriptor 
+			(dao,_("Correlated Random Numbers (%s)"), result)
+			== NULL);
+	case TOOL_ENGINE_UPDATE_DAO:
+		dao_adjust (dao, 2 * data->variables + 1, 
+			    data->variables + data->count + 3 );
+		return FALSE;
+	case TOOL_ENGINE_CLEAN_UP:
+		return tool_random_cor_clean (specs);
+	case TOOL_ENGINE_LAST_VALIDITY_CHECK:
+		return FALSE;
+	case TOOL_ENGINE_PREPARE_OUTPUT_RANGE:
+		dao_prepare_output (NULL, dao, _("Correlated Random Numbers"));
+		return FALSE;
+	case TOOL_ENGINE_FORMAT_OUTPUT_RANGE:
+		return dao_format_output (dao, _("Correlated Random Numbers"));
+	case TOOL_ENGINE_PERFORM_CALC:
+	default:
+		return tool_random_cor_engine_run (dao, specs);
+	}
+	return TRUE;
+}
+
+
+
+
diff --git a/src/tools/random-generator-cor.h b/src/tools/random-generator-cor.h
new file mode 100644
index 0000000..a104e0f
--- /dev/null
+++ b/src/tools/random-generator-cor.h
@@ -0,0 +1,27 @@
+#ifndef GNUMERIC_RANDOM_GENERATOR_COR_H
+#define GNUMERIC_RANDOM_GENERATOR_COR_H
+
+#include "gnumeric.h"
+#include "numbers.h"
+#include "dao.h"
+#include "tools.h"
+
+typedef enum {
+	random_gen_cor_type_cov = 0,
+	random_gen_cor_type_cholesky,
+} random_gen_cor_type_t;
+
+typedef struct {
+	WorkbookControl *wbc;       
+	GnmValue        *matrix;
+	random_gen_cor_type_t matrix_type;
+	gint count;
+	gint variables;
+} tools_data_random_cor_t;
+
+gboolean tool_random_cor_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 8bd1d24..417564a 100644
--- a/src/wbc-gtk-actions.c
+++ b/src/wbc-gtk-actions.c
@@ -866,7 +866,8 @@ static GNM_ACTION_DEF (cb_tools_ttest_equal_var) { dialog_ttest_tool (wbcg, wbcg
 static GNM_ACTION_DEF (cb_tools_ttest_unequal_var) { dialog_ttest_tool (wbcg, wbcg_cur_sheet (wbcg), TTEST_UNPAIRED_UNEQUALVARIANCES); }
 static GNM_ACTION_DEF (cb_tools_ztest)		{ dialog_ttest_tool (wbcg, wbcg_cur_sheet (wbcg), TTEST_ZTEST); }
 static GNM_ACTION_DEF (cb_tools_ftest)		{ dialog_ftest_tool (wbcg, wbcg_cur_sheet (wbcg)); }
-static GNM_ACTION_DEF (cb_tools_random_generator) { dialog_random_tool (wbcg, wbcg_cur_sheet (wbcg)); }
+static GNM_ACTION_DEF (cb_tools_random_generator_uncorrelated) { dialog_random_tool (wbcg, wbcg_cur_sheet (wbcg)); }
+static GNM_ACTION_DEF (cb_tools_random_generator_correlated) { dialog_random_cor_tool (wbcg, wbcg_cur_sheet (wbcg)); }
 static GNM_ACTION_DEF (cb_data_sort)		{ dialog_cell_sort (wbcg); }
 static GNM_ACTION_DEF (cb_data_shuffle)		{ dialog_shuffle (wbcg); }
 static GNM_ACTION_DEF (cb_data_import_text)	{ gui_file_open (wbcg, "Gnumeric_stf:stf_assistant"); }
@@ -1690,7 +1691,6 @@ static GtkActionEntry const permanent_actions[] = {
 		{ "MenuEditDelete",	GTK_STOCK_DELETE, N_("_Delete") },
 		{ "MenuEditSheet",	NULL, N_("S_heet") },
 		{ "MenuEditSelect",	NULL, N_("_Select") },
-		{ "MenuEditFill",	NULL, N_("F_ill") },
 	{ "MenuView",		NULL, N_("_View") },
 		{ "MenuViewWindows",		NULL, N_("_Windows") },
 		{ "MenuViewToolbars",		NULL, N_("_Toolbars") },
@@ -1711,6 +1711,8 @@ static GtkActionEntry const permanent_actions[] = {
 		{ "MenuToolTTest",	NULL,	N_("Two _Means") },
 	{ "MenuData",		NULL, N_("_Data") },
 		{ "MenuFilter",		NULL,	N_("_Filter") },
+		{ "MenuEditFill",	NULL, N_("F_ill") },
+	                { "MenuRandomGenerator",	NULL, N_("_Random Generators") },
 		{ "MenuOutline",	NULL,	N_("_Group and Outline") },
 		{ "MenuExternalData",	NULL,	N_("Get External _Data") },
 		{ "MenuSlicer",		NULL,	N_("Data S_licer") },
@@ -2186,9 +2188,12 @@ static GtkActionEntry const actions[] = {
 	{ "EditFillSeries", NULL, N_("_Series..."),
 		NULL, N_("Fill according to a linear or exponential series"),
 		G_CALLBACK (cb_edit_fill_series) },
-	{ "RandomGenerator", NULL, N_("_Random Generator..."),
+	{ "RandomGeneratorUncorrelated", NULL, N_("_Uncorrelated..."),
 		NULL, N_("Generate random numbers of a selection of distributions"),
-		G_CALLBACK (cb_tools_random_generator) },
+		G_CALLBACK (cb_tools_random_generator_uncorrelated) },
+	{ "RandomGeneratorCorrelated", NULL, N_("_Correlated..."),
+		NULL, N_("Generate varaites for correlated normal distributed random variables"),
+		G_CALLBACK (cb_tools_random_generator_correlated) },
 
 
 /* Data -> Outline */



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