gnumeric r16842 - in trunk: . src/dialogs src/tools



Author: guelzow
Date: Fri Oct  3 00:52:35 2008
New Revision: 16842
URL: http://svn.gnome.org/viewvc/gnumeric?rev=16842&view=rev

Log:
2008-10-02  Andreas J. Guelzow <aguelzow pyrshep ca>

	* analysis-exp-smoothing.h 
	(analysis_tools_data_exponential_smoothing_t): add field
	* analysis-exp-smoothing.c (attach_series): this should not
	  be called without a plot. Check for null plot before every call
	  to avoid creating unnecessary expressions
	(analysis_tool_exponential_smoothing_engine_ates_run): new
	(analysis_tool_exponential_smoothing_engine): call 
	  analysis_tool_exponential_smoothing_engine_ates_run if appropriate
	* analysis-tools.h (set_cell_text_row): new
	* analysis-tools.c (set_cell_text_row): make non-static
	(analysis_tool_calc_length): account for labels

2008-10-02  Andreas J. Guelzow <aguelzow pyrshep ca>

	* exp-smoothing.glade: added seasonal period entry
	* dialog-analysis-tools.c (exp_smoothing_tool_update_sensitivity_cb):
	  handle seasonal period
	(exp_smoothing_tool_ok_clicked_cb): ditto
	(dialog_exp_smoothing_tool): ditto and enable additive
	  Holt-Winters
	



Modified:
   trunk/NEWS
   trunk/src/dialogs/ChangeLog
   trunk/src/dialogs/dialog-analysis-tools.c
   trunk/src/dialogs/exp-smoothing.glade
   trunk/src/tools/ChangeLog
   trunk/src/tools/analysis-exp-smoothing.c
   trunk/src/tools/analysis-exp-smoothing.h
   trunk/src/tools/analysis-tools.c
   trunk/src/tools/analysis-tools.h

Modified: trunk/NEWS
==============================================================================
--- trunk/NEWS	(original)
+++ trunk/NEWS	Fri Oct  3 00:52:35 2008
@@ -20,6 +20,7 @@
 	* Add Spencer's 15-point moving average.
 	* Fix and improve exponential smoothing tool. [#553267]
 	* Added Holt's trend corrected exponential smoothing. [#385467]
+	* Added additive Holt-Winters exponential smoothing.
 
 Jean:
 	* Fix printing of rotated text. [#539734]

Modified: trunk/src/dialogs/dialog-analysis-tools.c
==============================================================================
--- trunk/src/dialogs/dialog-analysis-tools.c	(original)
+++ trunk/src/dialogs/dialog-analysis-tools.c	Fri Oct  3 00:52:35 2008
@@ -121,6 +121,7 @@
 	"n-button",
 	"nm1-button",
 	"nm2-button",
+	"nm3-button",
 	NULL
 };
 
@@ -217,10 +218,12 @@
         GtkWidget *damping_fact_entry;
         GtkWidget *g_damping_fact_entry;
         GtkWidget *s_damping_fact_entry;
+        GtkWidget *s_period_entry;
 	GtkWidget *show_std_errors;
 	GtkWidget *n_button;
 	GtkWidget *nm1_button;
 	GtkWidget *nm2_button;
+	GtkWidget *nm3_button;
 	GtkWidget *graph_button;
 	GtkWidget *ses_h_button;
 	GtkWidget *ses_r_button;
@@ -2326,6 +2329,8 @@
 			      &data->g_damp_fact, TRUE);
 	err = entry_to_float (GTK_ENTRY (state->s_damping_fact_entry), 
 			      &data->s_damp_fact, TRUE);
+	err = entry_to_int (GTK_ENTRY (state->s_period_entry), 
+			      &data->s_period, TRUE);
 
 	data->std_error_flag = gtk_toggle_button_get_active 
 		(GTK_TOGGLE_BUTTON (state->show_std_errors));
@@ -2355,7 +2360,7 @@
 exp_smoothing_tool_update_sensitivity_cb (G_GNUC_UNUSED GtkWidget *dummy,
 					  ExpSmoothToolState *state)
 {
-	int err;
+	int err, period;
 	gnm_float damp_fact;
         GSList *input_range;
 
@@ -2381,6 +2386,15 @@
 			gtk_widget_set_sensitive (state->base.ok_button, FALSE);
 			return;
 		}
+		err = entry_to_int (GTK_ENTRY (state->s_period_entry), 
+				      &period, FALSE);
+		if (err!= 0 || period < 2)  {
+			gtk_label_set_text (GTK_LABEL (state->base.warning),
+					    _("The given seasonal period "
+					      "is invalid."));
+			gtk_widget_set_sensitive (state->base.ok_button, FALSE);
+			return;
+		}
 		/* no break */
 	case exp_smoothing_type_des:
 		err = entry_to_float (GTK_ENTRY (state->g_damping_fact_entry), 
@@ -2490,7 +2504,7 @@
 	gtk_widget_set_sensitive (state->s_damping_fact_entry, TRUE);
 
 	std_error = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (state->show_std_errors));
-	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (state->nm2_button), TRUE);
+	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (state->nm3_button), TRUE);
 	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (state->show_std_errors), std_error);	
 }
 
@@ -2532,17 +2546,23 @@
 
 	state->damping_fact_entry = glade_xml_get_widget (state->base.gui,
 							  "damping-fact-spin");
+	gtk_spin_button_set_value (GTK_SPIN_BUTTON (state->damping_fact_entry), 0.2);
 	float_to_entry (GTK_ENTRY (state->damping_fact_entry), 0.2);
 	state->g_damping_fact_entry = glade_xml_get_widget (state->base.gui,
 							  "g-damping-fact-spin");
-	float_to_entry (GTK_ENTRY (state->g_damping_fact_entry), 0.2);
+	gtk_spin_button_set_value (GTK_SPIN_BUTTON (state->g_damping_fact_entry), 0.25);
 	state->s_damping_fact_entry = glade_xml_get_widget (state->base.gui,
 							  "s-damping-fact-spin");
-	float_to_entry (GTK_ENTRY (state->s_damping_fact_entry), 0.2);
+	gtk_spin_button_set_value (GTK_SPIN_BUTTON (state->s_damping_fact_entry), 0.3);
+	state->s_period_entry = glade_xml_get_widget (state->base.gui,
+							  "s-period-spin");
+	gtk_spin_button_set_value (GTK_SPIN_BUTTON (state->s_period_entry), 12.);
+	
 
 	state->n_button = glade_xml_get_widget (state->base.gui, "n-button");
 	state->nm1_button = glade_xml_get_widget (state->base.gui, "nm1-button");
 	state->nm2_button = glade_xml_get_widget (state->base.gui, "nm2-button");
+	state->nm3_button = glade_xml_get_widget (state->base.gui, "nm3-button");
 
 	state->show_std_errors = glade_xml_get_widget (state->base.gui, "std-errors-button");
 	state->graph_button = glade_xml_get_widget (state->base.gui, "graph-check");
@@ -2562,6 +2582,9 @@
 	g_signal_connect_after (G_OBJECT (state->nm2_button),
 		"toggled",
 		G_CALLBACK (exp_smoothing_tool_check_error_cb), state->show_std_errors);
+	g_signal_connect_after (G_OBJECT (state->nm3_button),
+		"toggled",
+		G_CALLBACK (exp_smoothing_tool_check_error_cb), state->show_std_errors);
 	g_signal_connect_after (G_OBJECT (state->damping_fact_entry),
 		"changed",
 		G_CALLBACK (exp_smoothing_tool_update_sensitivity_cb), state);
@@ -2595,7 +2618,6 @@
 	exp_smoothing_tool_update_sensitivity_cb (NULL, state);
 	tool_load_selection ((GenericToolState *)state, TRUE);
 	
-	gtk_widget_set_sensitive (state->ates_button, FALSE);
 	gtk_widget_set_sensitive (state->mtes_button, FALSE);
 
         return 0;

Modified: trunk/src/dialogs/exp-smoothing.glade
==============================================================================
--- trunk/src/dialogs/exp-smoothing.glade	(original)
+++ trunk/src/dialogs/exp-smoothing.glade	Fri Oct  3 00:52:35 2008
@@ -224,7 +224,7 @@
                       <widget class="GtkTable" id="table3">
                         <property name="visible">True</property>
                         <property name="border_width">12</property>
-                        <property name="n_rows">3</property>
+                        <property name="n_rows">4</property>
                         <property name="n_columns">2</property>
                         <property name="column_spacing">12</property>
                         <child>
@@ -313,6 +313,36 @@
                             <property name="y_options"></property>
                           </packing>
                         </child>
+                        <child>
+                          <widget class="GtkLabel" id="label9">
+                            <property name="visible">True</property>
+                            <property name="xalign">0</property>
+                            <property name="label" translatable="yes">Seasonal period:</property>
+                            <property name="use_underline">True</property>
+                          </widget>
+                          <packing>
+                            <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>
+                          <widget class="GtkSpinButton" id="s-period-spin">
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="xalign">1</property>
+                            <property name="adjustment">12 2 4096 1 10 10</property>
+                            <property name="snap_to_ticks">True</property>
+                            <property name="numeric">True</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>
+                          </packing>
+                        </child>
                       </widget>
                       <packing>
                         <property name="expand">False</property>
@@ -333,7 +363,7 @@
                         <property name="visible">True</property>
                         <property name="border_width">12</property>
                         <property name="n_rows">3</property>
-                        <property name="n_columns">4</property>
+                        <property name="n_columns">5</property>
                         <property name="column_spacing">12</property>
                         <property name="row_spacing">6</property>
                         <child>
@@ -413,12 +443,29 @@
                             <property name="draw_indicator">True</property>
                           </widget>
                           <packing>
-                            <property name="right_attach">4</property>
+                            <property name="right_attach">5</property>
                             <property name="bottom_attach">2</property>
                             <property name="x_options">GTK_FILL</property>
                             <property name="y_options"></property>
                           </packing>
                         </child>
+                        <child>
+                          <widget class="GtkRadioButton" id="nm3-button">
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="label" translatable="yes">nâ3</property>
+                            <property name="response_id">0</property>
+                            <property name="active">True</property>
+                            <property name="draw_indicator">True</property>
+                            <property name="group">n-button</property>
+                          </widget>
+                          <packing>
+                            <property name="left_attach">4</property>
+                            <property name="right_attach">5</property>
+                            <property name="top_attach">2</property>
+                            <property name="bottom_attach">3</property>
+                          </packing>
+                        </child>
                       </widget>
                       <packing>
                         <property name="expand">False</property>

Modified: trunk/src/tools/analysis-exp-smoothing.c
==============================================================================
--- trunk/src/tools/analysis-exp-smoothing.c	(original)
+++ trunk/src/tools/analysis-exp-smoothing.c	Fri Oct  3 00:52:35 2008
@@ -76,9 +76,8 @@
 attach_series (GogPlot *plot, GOData *expr)
 {
 	GogSeries    *series;
-	
-	if (plot == NULL)
-		return;
+
+	g_return_if_fail (plot != NULL);
 
 	series = gog_plot_new_series (plot);
 	gog_series_set_dim (series, 1, expr, NULL);	
@@ -98,7 +97,6 @@
 	GnmFunc *fd_sqrt = NULL;
 	GnmFunc *fd_sumxmy2 = NULL;
 	GnmExpr const *expr_alpha = NULL;
-	GnmExpr const *expr_gamma = NULL;
 
 	if (info->std_error_flag) {
 		fd_sqrt = gnm_func_lookup ("SQRT", NULL);
@@ -172,8 +170,11 @@
 		sheet = val->v_range.cell.a.sheet;
 		expr_input = gnm_expr_new_constant (val);
 
-		attach_series (plot, gnm_go_data_vector_new_expr (sheet, gnm_expr_top_new (gnm_expr_copy (expr_input))));
-		attach_series (plot, dao_go_data_vector (dao, col, 1, col, height));
+		if (plot != NULL) {
+			attach_series (plot, gnm_go_data_vector_new_expr (sheet, gnm_expr_top_new 
+									  (gnm_expr_copy (expr_input))));
+			attach_series (plot, dao_go_data_vector (dao, col, 1, col, height));
+		}
 
 		/*  F(t+1) = F(t) + damp_fact * ( A(t) - F(t) ) */
 		(*mover) = 1;
@@ -243,8 +244,6 @@
 		dao_set_sheet_object (dao, 0, 1, so);
 
 	gnm_expr_free (expr_alpha);
-	if (expr_gamma)
-		gnm_expr_free (expr_gamma);
 	if (fd_sqrt != NULL)
 		gnm_func_unref (fd_sqrt);
 	if (fd_sumxmy2 != NULL)
@@ -272,7 +271,6 @@
 	GnmFunc *fd_sqrt = NULL;
 	GnmFunc *fd_sumxmy2 = NULL;
 	GnmExpr const *expr_alpha = NULL;
-	GnmExpr const *expr_gamma = NULL;
 
 	if (info->std_error_flag) {
 		fd_sqrt = gnm_func_lookup ("SQRT", NULL);
@@ -347,8 +345,11 @@
 		sheet = val->v_range.cell.a.sheet;
 		expr_input = gnm_expr_new_constant (val);
 
-		attach_series (plot, gnm_go_data_vector_new_expr (sheet, gnm_expr_top_new (gnm_expr_copy (expr_input))));
-		attach_series (plot, dao_go_data_vector (dao, col, 2, col, height + 1));
+		if (plot != NULL) {
+			attach_series (plot, gnm_go_data_vector_new_expr (sheet, gnm_expr_top_new 
+									  (gnm_expr_copy (expr_input))));
+			attach_series (plot, dao_go_data_vector (dao, col, 2, col, height + 1));
+		}
 
 		/*  F(t+1) = F(t) + damp_fact * ( A(t+1) - F(t) ) */
 		
@@ -422,8 +423,6 @@
 		dao_set_sheet_object (dao, 0, 1, so);
 	
 	gnm_expr_free (expr_alpha);
-	if (expr_gamma)
-		gnm_expr_free (expr_gamma);
 	if (fd_sqrt != NULL)
 		gnm_func_unref (fd_sqrt);
 	if (fd_sumxmy2 != NULL)
@@ -533,8 +532,11 @@
 		sheet = val->v_range.cell.a.sheet;
 		expr_input = gnm_expr_new_constant (val);
 
-		attach_series (plot, gnm_go_data_vector_new_expr (sheet, gnm_expr_top_new (gnm_expr_copy (expr_input))));
-		attach_series (plot, dao_go_data_vector (dao, col, 2, col, height + 1));
+		if (plot != NULL) {
+			attach_series (plot, gnm_go_data_vector_new_expr (sheet, gnm_expr_top_new 
+									  (gnm_expr_copy (expr_input))));
+			attach_series (plot, dao_go_data_vector (dao, col, 2, col, height + 1));
+		}
 
 		if (dao_cell_is_visible (dao, col+1, 1))
 		{
@@ -648,15 +650,339 @@
 		dao_set_sheet_object (dao, 0, 1, so);
 
 	gnm_expr_free (expr_alpha);
-	if (expr_gamma)
-		gnm_expr_free (expr_gamma);
+	gnm_expr_free (expr_gamma);
+	if (fd_sqrt != NULL)
+		gnm_func_unref (fd_sqrt);
+	if (fd_sumxmy2 != NULL)
+		gnm_func_unref (fd_sumxmy2);
+	gnm_func_unref (fd_linest);
+	gnm_func_unref (fd_offset);
+	gnm_func_unref (fd_index);
+
+	dao_redraw_respan (dao);
+
+	return FALSE;
+}
+
+
+static gboolean
+analysis_tool_exponential_smoothing_engine_ates_run (data_analysis_output_t *dao,
+						     analysis_tools_data_exponential_smoothing_t *info)
+{
+	GSList *l;
+	gint col = 0, time, maxheight;
+	gint source;
+	SheetObject *so = NULL;
+	GogPlot	     *plot = NULL;
+	GnmFunc *fd_index;
+	GnmFunc *fd_offset;
+	GnmFunc *fd_linest;
+	GnmFunc *fd_average;
+	GnmFunc *fd_if;
+	GnmFunc *fd_mod;
+	GnmFunc *fd_row;
+	GnmFunc *fd_sqrt = NULL;
+	GnmFunc *fd_sumxmy2 = NULL;
+	GnmFunc *fd_sum = NULL;
+	GnmExpr const *expr_alpha = NULL;
+	GnmExpr const *expr_gamma = NULL;
+	GnmExpr const *expr_delta = NULL;
+
+	if (info->std_error_flag) {
+		fd_sqrt = gnm_func_lookup ("SQRT", NULL);
+		gnm_func_ref (fd_sqrt);		
+		fd_sumxmy2 = gnm_func_lookup ("SUMXMY2", NULL);
+		gnm_func_ref (fd_sumxmy2);		
+		fd_sum = gnm_func_lookup ("SUM", NULL);
+		gnm_func_ref (fd_sum);		
+	}
+		
+	fd_linest = gnm_func_lookup ("LINEST", NULL);
+	gnm_func_ref (fd_linest);				
+	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_average = gnm_func_lookup ("AVERAGE", NULL);
+	gnm_func_ref (fd_average);
+	fd_if = gnm_func_lookup ("IF", NULL);
+	gnm_func_ref (fd_if);
+	fd_mod = gnm_func_lookup ("mod", NULL);
+	gnm_func_ref (fd_mod);
+	fd_row = gnm_func_lookup ("row", NULL);
+	gnm_func_ref (fd_row);
+
+	if (info->show_graph)
+		create_line_plot (&plot, &so);
+
+	dao_set_italic (dao, 0, 0, 0, 0);
+	dao_set_cell (dao, 0, 0, _("Exponential Smoothing"));
+
+	dao_set_format  (dao, 2, 0, 2, 0, _("\"\xce\xb1 =\" * 0.000"));
+	dao_set_cell_expr (dao, 2, 0, gnm_expr_new_constant (value_new_float (info->damp_fact)));
+	expr_alpha = dao_get_cellref (dao, 2, 0);
+	
+	dao_set_format  (dao, 3, 0, 3, 0, _("\"\xce\xb3 =\" * 0.000"));
+	dao_set_cell_expr (dao, 3, 0, gnm_expr_new_constant (value_new_float (info->g_damp_fact)));
+	expr_gamma = dao_get_cellref (dao, 3, 0);
+
+	dao_set_format  (dao, 4, 0, 4, 0, _("\"\xce\xb4 =\" * 0.000"));
+	dao_set_cell_expr (dao, 4, 0, gnm_expr_new_constant (value_new_float (info->s_damp_fact)));
+	expr_delta = dao_get_cellref (dao, 4, 0);
+
+	dao_set_italic (dao, 0, 2, 0, 2);
+	dao_set_cell (dao, 0, 2, _("Time"));
+
+	maxheight = analysis_tool_calc_length (&info->base);
+
+	dao->offset_row = 2 + info->s_period;
+
+	for (time = 1 - info->s_period; time <= maxheight; time++)
+		dao_set_cell_int (dao, 0, time, time);
+
+	dao->offset_col = 1;
+
+	for (l = info->base.input, source = 1; l; l = l->next, source++) {
+		GnmValue *val = value_dup ((GnmValue *)l->data);
+		GnmValue *val_c = NULL;
+		GnmExpr const *expr_title = NULL;
+		GnmExpr const *expr_input = NULL;
+		GnmExpr const *expr_index = NULL;
+		GnmExpr const *expr_linest;
+		GnmExpr const *expr_level;
+		GnmExpr const *expr_trend;
+		GnmExpr const *expr_season;
+		GnmExpr const *expr_season_est;
+		GnmExpr const *expr_data;
+		GnmExpr const *expr_linest_intercept;
+		GnmExpr const *expr_linest_slope;
+		gint height;
+
+		if (dao_cell_is_visible (dao, col+3, 1))
+		{
+			dao_set_italic (dao, col + 1, -info->s_period, col + 3, -info->s_period);
+			set_cell_text_row (dao, col + 1, -info->s_period, _("/Level"
+									    "/Trend"
+									    "/Seasonal Adjustment"));
+			
+			if (info->base.labels) {
+				val_c = value_dup (val);
+				switch (info->base.group_by) {
+				case GROUPED_BY_ROW:
+					val->v_range.cell.a.col++;
+					break;
+				default:
+					val->v_range.cell.a.row++;
+					break;
+				}
+				expr_title = gnm_expr_new_funcall1 (fd_index,
+								    gnm_expr_new_constant (val_c));
+				
+				dao_set_italic (dao, col,  -info->s_period, col,  -info->s_period);
+				dao_set_cell_expr (dao, col,  -info->s_period, expr_title);
+			} else
+				dao_set_cell_printf
+					(dao, col,  -info->s_period,
+					 (info->base.group_by ? _("Row %d") : _("Column %d")),
+					 source);
+			
+			
+			switch (info->base.group_by) {
+			case GROUPED_BY_ROW:
+				height = value_area_get_width (val, NULL);
+				expr_input = gnm_expr_new_constant (val);
+				expr_index = gnm_expr_new_funcall3 (fd_index, gnm_expr_copy (expr_input),
+								    gnm_expr_new_constant (value_new_int (1)), 
+								    make_cellref (-1 - col, 0));
+				break;
+			default:
+				height = value_area_get_height (val, NULL);
+				expr_input = gnm_expr_new_constant (val);
+				expr_index = gnm_expr_new_funcall3 (fd_index, gnm_expr_copy (expr_input),
+								    make_cellref (-1 - col, 0), 
+								    gnm_expr_new_constant (value_new_int (1)));
+				break;
+			}
+
+			expr_data = dao_get_rangeref (dao, col, 1, col, height);
+			expr_linest = gnm_expr_new_funcall1
+				(fd_linest, gnm_expr_copy (expr_data));
+			dao_set_cell_expr (dao, col+1, 0,
+					   gnm_expr_new_funcall3 (fd_index,
+								  gnm_expr_copy (expr_linest),
+								  gnm_expr_new_constant (value_new_int (1)),
+								  gnm_expr_new_constant (value_new_int (2))));
+			expr_linest_intercept = dao_get_cellref (dao, col + 1, 0);
+			dao_set_cell_expr (dao, col + 2, 0,
+					   gnm_expr_new_funcall3 (fd_index,
+								  expr_linest,
+								  gnm_expr_new_constant (value_new_int (1)),
+								  gnm_expr_new_constant (value_new_int (1))));
+			expr_linest_slope = dao_get_cellref (dao, col + 2, 0);
+			expr_level = gnm_expr_new_binary (gnm_expr_new_binary 
+							  (gnm_expr_copy (expr_alpha),
+							   GNM_EXPR_OP_MULT,
+							   gnm_expr_new_binary 
+							   (make_cellref (-1,0),
+							    GNM_EXPR_OP_SUB,
+							    make_cellref (2,-info->s_period))),
+							  GNM_EXPR_OP_ADD,
+							  gnm_expr_new_binary 
+							  (gnm_expr_new_binary 
+							   (gnm_expr_new_constant (value_new_int (1)),
+							    GNM_EXPR_OP_SUB,
+							    gnm_expr_copy (expr_alpha)),
+							   GNM_EXPR_OP_MULT,
+							   gnm_expr_new_binary 
+							   (make_cellref (0,-1),
+							    GNM_EXPR_OP_ADD,
+							    make_cellref (1,-1))));
+			expr_trend = gnm_expr_new_binary (gnm_expr_new_binary 
+							  (gnm_expr_copy (expr_gamma),
+							   GNM_EXPR_OP_MULT,
+							   gnm_expr_new_binary 
+							   (make_cellref (-1,0),
+							    GNM_EXPR_OP_SUB,
+							    make_cellref (-1,-1))),
+							  GNM_EXPR_OP_ADD,
+							  gnm_expr_new_binary 
+							  (gnm_expr_new_binary 
+							   (gnm_expr_new_constant (value_new_int (1)),
+							    GNM_EXPR_OP_SUB,
+							    gnm_expr_copy (expr_gamma)),
+							   GNM_EXPR_OP_MULT,
+							   make_cellref (0,-1)));
+			expr_season = gnm_expr_new_binary (gnm_expr_new_binary 
+							  (gnm_expr_copy (expr_delta),
+							   GNM_EXPR_OP_MULT,
+							   gnm_expr_new_binary 
+							   (make_cellref (-3,0),
+							    GNM_EXPR_OP_SUB,
+							    make_cellref (-2,0))),
+							  GNM_EXPR_OP_ADD,
+							  gnm_expr_new_binary 
+							  (gnm_expr_new_binary 
+							   (gnm_expr_new_constant (value_new_int (1)),
+							    GNM_EXPR_OP_SUB,
+							    gnm_expr_copy (expr_delta)),
+							   GNM_EXPR_OP_MULT,
+							   make_cellref (0,-info->s_period)));
+			
+			for (time = 1; time <= maxheight; time++) {
+				dao_set_cell_expr (dao, col, time, gnm_expr_copy (expr_index));
+				dao_set_cell_expr (dao, col+1, time, gnm_expr_copy (expr_level));
+				dao_set_cell_expr (dao, col+2, time, gnm_expr_copy (expr_trend));
+				dao_set_cell_expr (dao, col+3, time, gnm_expr_copy (expr_season));
+			}
+			gnm_expr_free (expr_index);
+			gnm_expr_free (expr_level);
+			gnm_expr_free (expr_trend);
+			gnm_expr_free (expr_season);
+			
+			if (plot != NULL) {
+				attach_series (plot, dao_go_data_vector (dao, col, 1, col, height));
+				attach_series (plot, dao_go_data_vector (dao, col+1, 1, col+1, height));
+			}
+
+			/* We still need to calculate the estimates for the seasonal adjustment. */
+
+			expr_season_est = gnm_expr_new_funcall1 
+				(fd_average,
+				 gnm_expr_new_funcall3
+				 (fd_if,
+				  gnm_expr_new_binary 
+				  (gnm_expr_new_funcall2
+				   (fd_mod,
+				    gnm_expr_new_binary 
+				    (gnm_expr_new_funcall1
+				     (fd_row, 
+				      gnm_expr_copy (expr_data)),
+				     GNM_EXPR_OP_SUB,
+				     gnm_expr_new_funcall (fd_row, NULL)),
+				    gnm_expr_new_constant (value_new_int (info->s_period))),
+				   GNM_EXPR_OP_EQUAL,
+				   gnm_expr_new_constant (value_new_int (0))),
+				  gnm_expr_new_binary
+				  (expr_data,
+				   GNM_EXPR_OP_SUB,
+					  gnm_expr_new_binary
+				  (expr_linest_intercept,
+				   GNM_EXPR_OP_ADD,
+				   gnm_expr_new_binary
+				   (dao_get_rangeref (dao, -1, 1, -1, height),
+				    GNM_EXPR_OP_MULT,
+				    expr_linest_slope))),
+				  gnm_expr_new_constant (value_new_string ("NA"))));
+			
+			for (time = 0; time > -info->s_period; time--)
+				dao_set_cell_array_expr (dao, col+3, time, gnm_expr_copy (expr_season_est));
+
+			gnm_expr_free (expr_season_est);
+		} else {
+			dao_set_cell (dao, col, 0, _("The additive Holt-Winters exponential\n"
+						     "smoothing method requires at least 4\n"
+						     "output columns for each data set."));
+			dao_set_cell_comment (dao, col, 0, _("The additive Holt-Winters exponential\n"
+							     "smoothing method requires at least 4\n"
+							     "output columns for each data set."));
+		}
+		
+		col += 4;
+		if (info->std_error_flag) {
+			int row;
+
+			dao_set_italic (dao, col, - info->s_period, col, - info->s_period);
+			dao_set_cell (dao, col, - info->s_period, _("Standard Error"));
+			
+			for (row = 1; row <= height; row++) {
+				if (row > 1 && (row - info->df) > 0) {
+					GnmExpr const *expr_stderr;
+
+					expr_stderr = gnm_expr_new_funcall1
+						(fd_sqrt,
+						 gnm_expr_new_binary
+						 (gnm_expr_new_funcall2
+						  (fd_sumxmy2,
+						   make_rangeref (-4, 1 - row, -4, 0),
+						   gnm_expr_new_binary
+						   (make_rangeref (-1, 1 - row - info->s_period, 
+								   -1,  - info->s_period),
+						    GNM_EXPR_OP_ADD,
+						    gnm_expr_new_binary
+						    (make_rangeref (-2, - row, -2, -1),
+						     GNM_EXPR_OP_ADD,
+						     make_rangeref (-3, - row, -3, -1)))),
+						  GNM_EXPR_OP_DIV,
+						  gnm_expr_new_constant (value_new_int
+									 (row - info->df))));
+					dao_set_cell_expr (dao, col, row, expr_stderr);
+				} else
+					dao_set_cell_na (dao, col, row);
+			}
+			col++;
+		}
+		gnm_expr_free (expr_input);
+	}
+
+	if (so != NULL)
+		dao_set_sheet_object (dao, 0, 1, so);
+
+	gnm_expr_free (expr_alpha);
+	gnm_expr_free (expr_gamma);
+	gnm_expr_free (expr_delta);
 	if (fd_sqrt != NULL)
 		gnm_func_unref (fd_sqrt);
 	if (fd_sumxmy2 != NULL)
 		gnm_func_unref (fd_sumxmy2);
+	if (fd_sum != NULL)
+		gnm_func_unref (fd_sum);
 	gnm_func_unref (fd_linest);
 	gnm_func_unref (fd_offset);
 	gnm_func_unref (fd_index);
+	gnm_func_unref (fd_average);
+	gnm_func_unref (fd_if);
+	gnm_func_unref (fd_mod);
+	gnm_func_unref (fd_row);
 
 	dao_redraw_respan (dao);
 
@@ -690,6 +1016,10 @@
 			n++;
 			m++;
 		}
+		if (info->es_type == exp_smoothing_type_ates) {
+			n += 4;
+			m += info->s_period;
+		}
 		dao_adjust (dao, 
 			    n * g_slist_length (info->base.input), m);
 		return FALSE;
@@ -705,6 +1035,8 @@
 	case TOOL_ENGINE_PERFORM_CALC:
 	default:
 		switch (info->es_type) {
+		case exp_smoothing_type_ates:
+			return analysis_tool_exponential_smoothing_engine_ates_run (dao, specs);
 		case exp_smoothing_type_des:
 			return analysis_tool_exponential_smoothing_engine_des_run (dao, specs);
 		case exp_smoothing_type_ses_r:

Modified: trunk/src/tools/analysis-exp-smoothing.h
==============================================================================
--- trunk/src/tools/analysis-exp-smoothing.h	(original)
+++ trunk/src/tools/analysis-exp-smoothing.h	Fri Oct  3 00:52:35 2008
@@ -48,6 +48,7 @@
 	gnm_float damp_fact;
 	gnm_float g_damp_fact;
 	gnm_float s_damp_fact;
+	int s_period;
 	int std_error_flag;
 	int df;
 	gboolean show_graph;

Modified: trunk/src/tools/analysis-tools.c
==============================================================================
--- trunk/src/tools/analysis-tools.c	(original)
+++ trunk/src/tools/analysis-tools.c	Fri Oct  3 00:52:35 2008
@@ -657,7 +657,7 @@
 /*
  * Set a row of text from a string like "/first/second/third" or "|foo|bar|baz".
  */
-static void
+void
 set_cell_text_row (data_analysis_output_t *dao, int col, int row, const char *text)
 {
 	gboolean leave = 0;
@@ -719,6 +719,8 @@
 		if (given_length > result)
 			result = given_length;
 	}
+	if (info->labels)
+		result--;
 	return result;
 }
 

Modified: trunk/src/tools/analysis-tools.h
==============================================================================
--- trunk/src/tools/analysis-tools.h	(original)
+++ trunk/src/tools/analysis-tools.h	Fri Oct  3 00:52:35 2008
@@ -246,4 +246,7 @@
 void gnm_fourier_fft (complex_t const *in, int n, int skip,
 					  complex_t **fourier, gboolean inverse);
 
+void set_cell_text_row (data_analysis_output_t *dao, 
+			int col, int row, const char *text);
+
 #endif



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