[gnumeric] solver: further cleanups.



commit aeeebb5704e587ebed95d8e68f14fb8a57b494ca
Author: Morten Welinder <terra gnome org>
Date:   Mon Nov 16 12:57:15 2009 -0500

    solver: further cleanups.

 plugins/glpk/gnm-glpk.c       |   15 +++++---
 plugins/lpsolve/ChangeLog     |    4 ++
 plugins/lpsolve/gnm-lpsolve.c |   16 ++++++---
 src/dialogs/dialog-solver.c   |   70 +++++++++++++++++++++++-----------------
 src/dialogs/solver.glade      |   59 ----------------------------------
 src/tools/gnm-solver.c        |   37 ++++++++++++---------
 src/tools/gnm-solver.h        |   16 ++-------
 src/xml-sax-read.c            |    5 ---
 src/xml-sax-write.c           |   10 ------
 9 files changed, 88 insertions(+), 144 deletions(-)
---
diff --git a/plugins/glpk/gnm-glpk.c b/plugins/glpk/gnm-glpk.c
index 6df34e2..64d9b97 100644
--- a/plugins/glpk/gnm-glpk.c
+++ b/plugins/glpk/gnm-glpk.c
@@ -257,15 +257,18 @@ gnm_glpk_start (GnmSolver *sol, WorkbookControl *wbc, GError **err,
 	GnmSubSolver *subsol = GNM_SUB_SOLVER (sol);
 	gboolean ok;
 	gchar *argv[6];
+	int argc = 0;
 
 	g_return_val_if_fail (sol->status == GNM_SOLVER_STATUS_PREPARED, FALSE);
 
-	argv[0] = (gchar *)"glpsol";
-	argv[1] = (gchar *)"--write";
-	argv[2] = lp->result_filename;
-	argv[3] = (gchar *)"--cpxlp";
-	argv[4] = subsol->program_filename;
-	argv[5] = NULL;
+	argv[argc++] = (gchar *)"glpsol";
+	// FIXME: Handle automatic scaling.
+	argv[argc++] = (gchar *)"--write";
+	argv[argc++] = lp->result_filename;
+	argv[argc++] = (gchar *)"--cpxlp";
+	argv[argc++] = subsol->program_filename;
+	argv[argc] = NULL;
+	g_assert (argc < (int)G_N_ELEMENTS (argv));
 
 	ok = gnm_sub_solver_spawn (subsol, argv,
 				   cb_child_setup, NULL,
diff --git a/plugins/lpsolve/ChangeLog b/plugins/lpsolve/ChangeLog
index 5c6e98f..3b6a02a 100644
--- a/plugins/lpsolve/ChangeLog
+++ b/plugins/lpsolve/ChangeLog
@@ -1,3 +1,7 @@
+2009-11-16  Morten Welinder  <terra gnome org>
+
+	* gnm-lpsolve.c (gnm_lpsolve_start): Handle automatic scaling.
+
 2009-11-15  Morten Welinder  <terra gnome org>
 
 	* gnm-lpsolve.c (gnm_lpsolve_stop): Fix precondition.
diff --git a/plugins/lpsolve/gnm-lpsolve.c b/plugins/lpsolve/gnm-lpsolve.c
index 4e2399f..968974b 100644
--- a/plugins/lpsolve/gnm-lpsolve.c
+++ b/plugins/lpsolve/gnm-lpsolve.c
@@ -253,14 +253,20 @@ gnm_lpsolve_start (GnmSolver *sol, WorkbookControl *wbc, GError **err,
 {
 	GnmSubSolver *subsol = GNM_SUB_SOLVER (sol);
 	gboolean ok;
-	gchar *argv[4];
+	gchar *argv[5];
+	int argc = 0;
+	GnmSolverParameters *param = sol->params;
 
 	g_return_val_if_fail (sol->status == GNM_SOLVER_STATUS_PREPARED, FALSE);
 
-	argv[0] = (gchar *)"lp_solve";
-	argv[1] = (gchar *)"-i";
-	argv[2] = subsol->program_filename;
-	argv[3] = NULL;
+	argv[argc++] = (gchar *)"lp_solve";
+	argv[argc++] = (gchar *)"-i";
+	argv[argc++] = (gchar *)(param->options.automatic_scaling
+				 ? "-s1"
+				 : "-s0");
+	argv[argc++] = subsol->program_filename;
+	argv[argc] = NULL;
+	g_assert (argc < (int)G_N_ELEMENTS (argv));
 
 	ok = gnm_sub_solver_spawn (subsol, argv,
 				   cb_child_setup, NULL,
diff --git a/src/dialogs/dialog-solver.c b/src/dialogs/dialog-solver.c
index e5d655f..7c31458 100644
--- a/src/dialogs/dialog-solver.c
+++ b/src/dialogs/dialog-solver.c
@@ -87,6 +87,7 @@ typedef struct {
 		GtkWidget   *result_widget;
 		GtkWidget   *stop_button;
 		GtkWidget   *ok_button;
+		gulong       sig_notify_result, sig_notify_status;
 	} run;
 
 	Sheet		    *sheet;
@@ -384,7 +385,6 @@ extract_settings (SolverState *state)
 	GnmValue *target_range;
 	GnmValue *input_range;
 	GnmSolverFactory *factory = NULL;
-	gboolean dual_program;
 
 	target_range = gnm_expr_entry_parse_as_value (state->target_entry,
 						      state->sheet);
@@ -404,26 +404,21 @@ extract_settings (SolverState *state)
 	param->options.model_type =
 		gnumeric_glade_group_value (state->gui, model_type_group);
 
-	gtk_combo_box_get_active_iter (state->algorithm_combo, &iter);
-	gtk_tree_model_get (gtk_combo_box_get_model (state->algorithm_combo),
-			    &iter, 1, &factory, -1);
-	param->options.algorithm = factory;
-
-	param->options.automatic_scaling = gtk_toggle_button_get_active
-		(GTK_TOGGLE_BUTTON (glade_xml_get_widget
-				    (state->gui, "autoscale_button")));
+	if (gtk_combo_box_get_active_iter (state->algorithm_combo, &iter)) {
+		gtk_tree_model_get (gtk_combo_box_get_model (state->algorithm_combo),
+				    &iter, 1, &factory, -1);
+		gnm_solver_param_set_algorithm (param, factory);
+	} else
+		gnm_solver_param_set_algorithm (param, NULL);
 
 	param->options.max_iter = gtk_spin_button_get_value
 		(GTK_SPIN_BUTTON (state->max_iter_entry));
 	param->options.max_time_sec = gtk_spin_button_get_value
 		(GTK_SPIN_BUTTON (state->max_time_entry));
 
+	GET_BOOL_ENTRY ("autoscale_button", options.automatic_scaling);
 	GET_BOOL_ENTRY ("non_neg_button", options.assume_non_negative);
 	GET_BOOL_ENTRY ("all_int_button", options.assume_discrete);
-	GET_BOOL_ENTRY ("answer", options.answer_report);
-	GET_BOOL_ENTRY ("sensitivity", options.sensitivity_report);
-	GET_BOOL_ENTRY ("limits", options.limits_report);
-	GET_BOOL_ENTRY ("performance", options.performance_report);
 	GET_BOOL_ENTRY ("program", options.program_report);
 
 	g_free (param->options.scenario_name);
@@ -432,9 +427,6 @@ extract_settings (SolverState *state)
 
 	GET_BOOL_ENTRY ("optimal_scenario", options.add_scenario);
 
-	dual_program = FALSE;
-	param->options.dual_program_report = dual_program;
-
 	value_release (target_range);
 }
 
@@ -497,6 +489,7 @@ cb_stop_solver (SolverState *state)
 		if (!ok) {
 			g_warning ("Failed to stop solver!");
 		}
+		g_object_set (sol, "result", NULL, NULL);
 		break;
 	}
 
@@ -511,6 +504,7 @@ cb_notify_status (SolverState *state)
 	GnmSolver *sol = state->run.solver;
 	const char *text;
 	gboolean finished = gnm_solver_finished (sol);
+	gboolean ok_ok = finished;
 
 	switch (sol->status) {
 	case GNM_SOLVER_STATUS_READY:
@@ -524,6 +518,12 @@ cb_notify_status (SolverState *state)
 		break;
 	case GNM_SOLVER_STATUS_RUNNING:
 		text = _("Running");
+		if (sol->result) {
+			GnmSolverResultQuality q = sol->result->quality;
+			if (q == GNM_SOLVER_RESULT_FEASIBLE ||
+			    q == GNM_SOLVER_RESULT_OPTIMAL)
+				ok_ok = TRUE;
+		}
 		break;
 	case GNM_SOLVER_STATUS_DONE:
 		text = _("Done");
@@ -547,16 +547,19 @@ cb_notify_status (SolverState *state)
 	}
 
 	gtk_widget_set_sensitive (state->run.stop_button, !finished);
-	gtk_widget_set_sensitive (state->run.ok_button, finished);
+	gtk_widget_set_sensitive (state->run.ok_button, ok_ok);
 }
 
 static void
 cb_notify_result (SolverState *state)
 {
 	GnmSolver *sol = state->run.solver;
-	GnmSolverResult *r = sol->result;
+	GnmSolverResult *r;
 	char *txt;
 
+	cb_notify_status (state);
+
+	r = sol->result;
 	switch (r ? r->quality : GNM_SOLVER_RESULT_NONE) {
 	default:
 	case GNM_SOLVER_RESULT_NONE:
@@ -680,16 +683,18 @@ run_solver (SolverState *state, GnmSolverParameters *param)
 	gtk_box_pack_start (GTK_BOX (dialog->vbox), hbox, TRUE, TRUE, 0);
 	gtk_widget_show_all (GTK_WIDGET (dialog));
 
-	g_signal_connect_swapped (G_OBJECT (sol),
-				  "notify::status",
-				  G_CALLBACK (cb_notify_status),
-				  state);
+	state->run.sig_notify_result =
+		g_signal_connect_swapped (G_OBJECT (sol),
+					  "notify::status",
+					  G_CALLBACK (cb_notify_status),
+					  state);
 	cb_notify_status (state);
 
-	g_signal_connect_swapped (G_OBJECT (sol),
-				  "notify::result",
-				  G_CALLBACK (cb_notify_result),
-				  state);
+	state->run.sig_notify_status =
+		g_signal_connect_swapped (G_OBJECT (sol),
+					  "notify::result",
+					  G_CALLBACK (cb_notify_result),
+					  state);
 	cb_notify_result (state);
 
 	state->run.dialog = g_object_ref (dialog);
@@ -716,6 +721,14 @@ run_solver (SolverState *state, GnmSolverParameters *param)
 		dialog_res = GTK_RESPONSE_DELETE_EVENT;
 	}
 
+	g_signal_handler_disconnect (G_OBJECT (sol),
+				     state->run.sig_notify_result);
+	g_signal_handler_disconnect (G_OBJECT (sol),
+				     state->run.sig_notify_status);
+
+	if (sol->status == GNM_SOLVER_STATUS_RUNNING)
+		gnm_solver_stop (sol, NULL);
+
 	/* ---------------------------------------- */
 
 	gtk_widget_destroy (GTK_WIDGET (state->run.dialog));
@@ -1067,12 +1080,9 @@ dialog_init (SolverState *state)
 		g_free (str);
 	}
 
+	INIT_BOOL_ENTRY ("autoscale_button", options.automatic_scaling);
 	INIT_BOOL_ENTRY ("non_neg_button", options.assume_non_negative);
 	INIT_BOOL_ENTRY ("all_int_button", options.assume_discrete);
-	INIT_BOOL_ENTRY ("answer", options.answer_report);
-	INIT_BOOL_ENTRY ("sensitivity", options.sensitivity_report);
-	INIT_BOOL_ENTRY ("limits", options.limits_report);
-	INIT_BOOL_ENTRY ("performance", options.performance_report);
 	INIT_BOOL_ENTRY ("program", options.program_report);
 
 	input = gnm_solver_param_get_input (param);
diff --git a/src/dialogs/solver.glade b/src/dialogs/solver.glade
index 9d9de5f..10f7b0a 100644
--- a/src/dialogs/solver.glade
+++ b/src/dialogs/solver.glade
@@ -537,65 +537,6 @@ Bool
                     <property name="border_width">8</property>
                     <property name="spacing">5</property>
                     <child>
-                      <widget class="GtkCheckButton" id="answer">
-                        <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="label" translatable="yes">_Answer</property>
-                        <property name="use_underline">True</property>
-                        <property name="response_id">0</property>
-                        <property name="draw_indicator">True</property>
-                      </widget>
-                      <packing>
-                        <property name="expand">False</property>
-                        <property name="fill">False</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <widget class="GtkCheckButton" id="sensitivity">
-                        <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="label" translatable="yes">_Sensitivity</property>
-                        <property name="use_underline">True</property>
-                        <property name="response_id">0</property>
-                        <property name="draw_indicator">True</property>
-                      </widget>
-                      <packing>
-                        <property name="expand">False</property>
-                        <property name="fill">False</property>
-                        <property name="position">1</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <widget class="GtkCheckButton" id="limits">
-                        <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="label" translatable="yes">_Limits</property>
-                        <property name="use_underline">True</property>
-                        <property name="response_id">0</property>
-                        <property name="draw_indicator">True</property>
-                      </widget>
-                      <packing>
-                        <property name="expand">False</property>
-                        <property name="fill">False</property>
-                        <property name="position">2</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <widget class="GtkCheckButton" id="performance">
-                        <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="label" translatable="yes">_Performance</property>
-                        <property name="use_underline">True</property>
-                        <property name="response_id">0</property>
-                        <property name="draw_indicator">True</property>
-                      </widget>
-                      <packing>
-                        <property name="expand">False</property>
-                        <property name="fill">False</property>
-                        <property name="position">3</property>
-                      </packing>
-                    </child>
-                    <child>
                       <widget class="GtkCheckButton" id="program">
                         <property name="visible">True</property>
                         <property name="can_focus">True</property>
diff --git a/src/tools/gnm-solver.c b/src/tools/gnm-solver.c
index 4ec4e86..51a7f82 100644
--- a/src/tools/gnm-solver.c
+++ b/src/tools/gnm-solver.c
@@ -392,10 +392,19 @@ gnm_solver_param_dup (GnmSolverParameters *src, Sheet *new_sheet)
 	dependent_managed_set_expr (&dst->target, src->target.texpr);
 	dependent_managed_set_expr (&dst->input, src->input.texpr);
 
+	dst->options.max_time_sec = src->options.max_time_sec;
+	dst->options.max_iter = src->options.max_iter;
+	dst->options.model_type = src->options.model_type;
+	dst->options.assume_non_negative = src->options.assume_non_negative;
+	dst->options.assume_discrete = src->options.assume_discrete;
+	dst->options.automatic_scaling = src->options.automatic_scaling;
+	dst->options.program_report = src->options.program_report;
+	dst->options.add_scenario = src->options.add_scenario;
+
 	g_free (dst->options.scenario_name);
-	dst->options = src->options;
-	dst->options.scenario_name = g_strdup (src->options.scenario_name);
-	/* Had there been any non-scalar options, we'd copy them here.  */
+	dst->options.scenario_name = g_strdup (src->options.scenario_name);	
+
+	gnm_solver_param_set_algorithm (dst, src->options.algorithm);
 
 	/* Copy the constraints */
 	for (l = src->constraints; l; l = l->next) {
@@ -407,12 +416,6 @@ gnm_solver_param_dup (GnmSolverParameters *src, Sheet *new_sheet)
 	}
 	dst->constraints = g_slist_reverse (dst->constraints);
 
-	dst->n_constraints       = src->n_constraints;
-	dst->n_variables         = src->n_variables;
-	dst->n_int_constraints   = src->n_int_constraints;
-	dst->n_bool_constraints  = src->n_bool_constraints;
-	dst->n_total_constraints = src->n_total_constraints;
-
 	return dst;
 }
 
@@ -433,13 +436,7 @@ gnm_solver_param_equal (GnmSolverParameters const *a,
             a->options.assume_non_negative != b->options.assume_non_negative ||
             a->options.assume_discrete != b->options.assume_discrete ||
             a->options.automatic_scaling != b->options.automatic_scaling ||
-            a->options.show_iter_results != b->options.show_iter_results ||
-            a->options.answer_report != b->options.answer_report ||
-            a->options.sensitivity_report != b->options.sensitivity_report ||
-            a->options.limits_report != b->options.limits_report ||
-            a->options.performance_report != b->options.performance_report ||
             a->options.program_report != b->options.program_report ||
-            a->options.dual_program_report != b->options.dual_program_report ||
             a->options.add_scenario != b->options.add_scenario ||
 	    strcmp (a->options.scenario_name, b->options.scenario_name))
 		return FALSE;
@@ -539,6 +536,13 @@ gnm_solver_param_get_target_cell (GnmSolverParameters const *sp)
 			       cr->col, cr->row);
 }
 
+void
+gnm_solver_param_set_algorithm (GnmSolverParameters *sp,
+				GnmSolverFactory *algo)
+{
+	sp->options.algorithm = algo;
+}
+
 gboolean
 gnm_solver_param_valid (GnmSolverParameters const *sp, GError **err)
 {
@@ -624,7 +628,8 @@ gnm_solver_param_constructor (GType type,
 	sp->options.max_time_sec = 30;
 	sp->options.assume_non_negative = TRUE;
 	sp->options.scenario_name = g_strdup ("Optimal");
-	sp->options.algorithm = g_slist_nth_data (gnm_solver_db_get (), 0);
+	gnm_solver_param_set_algorithm
+		(sp, g_slist_nth_data (gnm_solver_db_get (), 0));
 
 	return obj;
 }
diff --git a/src/tools/gnm-solver.h b/src/tools/gnm-solver.h
index ba7819b..7a6adad 100644
--- a/src/tools/gnm-solver.h
+++ b/src/tools/gnm-solver.h
@@ -108,13 +108,7 @@ typedef struct {
 	gboolean            assume_non_negative;
 	gboolean            assume_discrete;
 	gboolean            automatic_scaling;
-	gboolean            show_iter_results;
-	gboolean            answer_report;
-	gboolean            sensitivity_report;
-	gboolean            limits_report;
-	gboolean            performance_report;
 	gboolean            program_report;
-	gboolean            dual_program_report;
 	gboolean            add_scenario;
 	gchar               *scenario_name;
 } GnmSolverOptions;
@@ -134,13 +128,6 @@ struct GnmSolverParameters_ {
 	GnmDependent input;
 	GSList *constraints;
 	GnmSolverOptions options;
-
-	/* These will not survive long.  */
-	int                   n_constraints;
-	int                   n_variables;
-	int                   n_int_constraints;
-	int                   n_bool_constraints;
-	int                   n_total_constraints;
 };
 
 typedef struct {
@@ -168,6 +155,9 @@ void gnm_solver_param_set_target (GnmSolverParameters *sp,
 				  GnmCellRef const *cr);
 GnmCell *gnm_solver_param_get_target_cell (GnmSolverParameters const *sp);
 
+void gnm_solver_param_set_algorithm (GnmSolverParameters *sp,
+				     GnmSolverFactory *algo);
+
 gboolean gnm_solver_param_valid (GnmSolverParameters const *sp, GError **err);
 
 /* -------------------------------------------------------------------------- */
diff --git a/src/xml-sax-read.c b/src/xml-sax-read.c
index 12a591b..78138cc 100644
--- a/src/xml-sax-read.c
+++ b/src/xml-sax-read.c
@@ -2378,11 +2378,6 @@ xml_sax_solver_start (GsfXMLIn *xin, xmlChar const **attrs)
 			   gnm_xml_attr_bool (attrs, "NonNeg", &(sp->options.assume_non_negative)) ||
 			   gnm_xml_attr_bool (attrs, "Discr", &(sp->options.assume_discrete)) ||
 			   gnm_xml_attr_bool (attrs, "AutoScale", &(sp->options.automatic_scaling)) ||
-			   gnm_xml_attr_bool (attrs, "ShowIter", &(sp->options.show_iter_results)) ||
-			   gnm_xml_attr_bool (attrs, "AnswerR", &(sp->options.answer_report)) ||
-			   gnm_xml_attr_bool (attrs, "SensitivityR", &(sp->options.sensitivity_report)) ||
-			   gnm_xml_attr_bool (attrs, "LimitsR", &(sp->options.limits_report)) ||
-			   gnm_xml_attr_bool (attrs, "PerformR", &(sp->options.performance_report)) ||
 			   gnm_xml_attr_bool (attrs, "ProgramR", &(sp->options.program_report)))
 			; /* Nothing */
 	}
diff --git a/src/xml-sax-write.c b/src/xml-sax-write.c
index 7dc040f..359d2bd 100644
--- a/src/xml-sax-write.c
+++ b/src/xml-sax-write.c
@@ -1003,16 +1003,6 @@ xml_write_solver (GnmOutputXML *state)
 		param->options.assume_discrete);
 	gsf_xml_out_add_bool (state->output, "AutoScale",
 		param->options.automatic_scaling);
-	gsf_xml_out_add_bool (state->output, "ShowIter",
-		param->options.show_iter_results);
-	gsf_xml_out_add_bool (state->output, "AnswerR",
-		param->options.answer_report);
-	gsf_xml_out_add_bool (state->output, "SensitivityR",
-		param->options.sensitivity_report);
-	gsf_xml_out_add_bool (state->output, "LimitsR",
-		param->options.limits_report);
-	gsf_xml_out_add_bool (state->output, "PerformR",
-		param->options.performance_report);
 	gsf_xml_out_add_bool (state->output, "ProgramR",
 		param->options.program_report);
 



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