[gnumeric] solver: more cleanups.
- From: Morten Welinder <mortenw src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gnumeric] solver: more cleanups.
- Date: Mon, 2 Nov 2009 03:11:29 +0000 (UTC)
commit a44ae99e45047cbf78c5d1c872b52d879208e907
Author: Morten Welinder <terra gnome org>
Date: Sun Nov 1 22:06:39 2009 -0500
solver: more cleanups.
src/dialogs/dialog-solver.c | 20 ++++---
src/solver.h | 44 ++++++++-------
src/tools/solver/solver.c | 126 +++++++++++++++++++++++++++++++++---------
3 files changed, 135 insertions(+), 55 deletions(-)
---
diff --git a/src/dialogs/dialog-solver.c b/src/dialogs/dialog-solver.c
index fd39941..50dee76 100644
--- a/src/dialogs/dialog-solver.c
+++ b/src/dialogs/dialog-solver.c
@@ -485,7 +485,7 @@ save_original_values (GSList *input_cells)
/* Returns FALSE if the reports deleted the current sheet
* and forced the dialog to die */
static gboolean
-solver_reporting (SolverState *state, SolverResults *res, gchar const *errmsg)
+solver_reporting (SolverState *state, SolverResults *res)
{
SolverOptions *opt = &res->param->options;
gchar *err = NULL;
@@ -579,7 +579,8 @@ solver_reporting (SolverState *state, SolverResults *res, gchar const *errmsg)
go_gtk_notice_nonmodal_dialog
((GtkWindow *) state->dialog,
&(state->warning_dialog),
- GTK_MESSAGE_ERROR, errmsg);
+ GTK_MESSAGE_ERROR,
+ _("Unknown error."));
break;
}
if (NULL != state)
@@ -629,7 +630,7 @@ cb_dialog_solve_clicked (G_GNUC_UNUSED GtkWidget *button,
gint i;
gboolean answer, sensitivity, limits, performance;
gboolean program, dual_program;
- gchar const *errmsg = _("Unknown error.");
+ GError *err = NULL;
SolverParameters *param;
GtkTreeIter iter;
gchar const *name;
@@ -755,7 +756,7 @@ cb_dialog_solve_clicked (G_GNUC_UNUSED GtkWidget *button,
input_cells);
- res = solver (WORKBOOK_CONTROL (state->wbcg), state->sheet, &errmsg);
+ res = solver (WORKBOOK_CONTROL (state->wbcg), state->sheet, &err);
workbook_recalc (state->sheet->workbook);
if (res != NULL) {
@@ -763,7 +764,7 @@ cb_dialog_solve_clicked (G_GNUC_UNUSED GtkWidget *button,
/* WARNING : The dialog may be deleted by the reports
* solver_reporting will return FALSE if state is gone and cleared */
- if (solver_reporting (state, res, errmsg) &&
+ if (solver_reporting (state, res) &&
res->status == SolverOptimal &&
param->options.add_scenario)
solver_add_scenario (state, res,
@@ -771,9 +772,12 @@ cb_dialog_solve_clicked (G_GNUC_UNUSED GtkWidget *button,
solver_results_free (res);
} else
- go_gtk_notice_nonmodal_dialog (GTK_WINDOW (state->dialog),
- &(state->warning_dialog),
- GTK_MESSAGE_ERROR, errmsg);
+ go_gtk_notice_nonmodal_dialog
+ (GTK_WINDOW (state->dialog),
+ &(state->warning_dialog),
+ GTK_MESSAGE_ERROR,
+ err ? err->message : _("Unknown error."));
+
out:
if (target_range != NULL)
value_release (target_range);
diff --git a/src/solver.h b/src/solver.h
index d9d4352..006504a 100644
--- a/src/solver.h
+++ b/src/solver.h
@@ -12,6 +12,7 @@ G_BEGIN_DECLS
#define SOLVER_MAX_TIME_ERR _("The maximum time exceeded. The optimal value could not be found in given time.")
+/* -------------------------------------------------------------------------- */
typedef enum {
SolverLPModel, SolverQPModel, SolverNLPModel
@@ -40,6 +41,8 @@ typedef struct {
SolverAlgorithmType algorithm;
} SolverOptions;
+/* -------------------------------------------------------------------------- */
+
typedef enum {
SolverMinimize, SolverMaximize, SolverEqualTo
} SolverProblemType;
@@ -58,6 +61,26 @@ struct _SolverParameters {
SolverOptions options;
};
+/* Creates a new SolverParameters object. */
+SolverParameters *gnm_solver_param_new (Sheet *sheet);
+
+/* Duplicate a SolverParameters object. */
+SolverParameters *gnm_solver_param_dup (SolverParameters const *src_param,
+ Sheet *new_sheet);
+
+/* Frees the memory resources in the solver parameter structure. */
+void gnm_solver_param_free (SolverParameters *sp);
+
+GnmValue const *gnm_solver_param_get_input (SolverParameters const *sp);
+void gnm_solver_param_set_input (SolverParameters *sp, GnmValue *v);
+GSList *gnm_solver_param_get_input_cells (SolverParameters const *sp);
+
+const GnmCellRef *gnm_solver_param_get_target (SolverParameters const *sp);
+void gnm_solver_param_set_target (SolverParameters *sp, GnmCellRef const *cr);
+GnmCell *gnm_solver_param_get_target_cell (SolverParameters const *sp);
+
+gboolean gnm_solver_param_valid (SolverParameters const *sp, GError **err);
+
/* -------------------------------------------------------------------------- */
typedef enum {
@@ -239,7 +262,7 @@ typedef struct {
* the results of the run. Note that it should be freed when no longer
* needed (by calling solver_results_free). */
SolverResults *solver (WorkbookControl *wbc, Sheet *sheet,
- const gchar **errmsg);
+ GError **err);
/* Creates the Solver's reports. */
gchar * solver_reports (WorkbookControl *wbc, Sheet *sheet,
@@ -248,25 +271,6 @@ gchar * solver_reports (WorkbookControl *wbc, Sheet *sheet,
gboolean limits, gboolean performance,
gboolean program, gboolean dual);
-/* Creates a new SolverParameters object. */
-SolverParameters *gnm_solver_param_new (Sheet *sheet);
-
-GnmValue const *gnm_solver_param_get_input (SolverParameters const *sp);
-void gnm_solver_param_set_input (SolverParameters *sp, GnmValue *v);
-GSList *gnm_solver_param_get_input_cells (SolverParameters const *sp);
-
-const GnmCellRef *gnm_solver_param_get_target (SolverParameters const *sp);
-void gnm_solver_param_set_target (SolverParameters *sp, GnmCellRef const *cr);
-GnmCell *gnm_solver_param_get_target_cell (SolverParameters const *sp);
-
-/* Frees the memory resources in the solver parameter structure. */
-void gnm_solver_param_free (SolverParameters *sp);
-
-/* Creates a copy of the Solver's data structures when a sheet is
- * duplicated. */
-SolverParameters *gnm_solver_param_dup (SolverParameters const *src_param,
- Sheet *new_sheet);
-
/* Frees the data structure allocated for the results. */
void solver_results_free (SolverResults *res);
diff --git a/src/tools/solver/solver.c b/src/tools/solver/solver.c
index 05d8327..6cb5af4 100644
--- a/src/tools/solver/solver.c
+++ b/src/tools/solver/solver.c
@@ -179,6 +179,71 @@ gnm_solver_param_get_target_cell (SolverParameters const *sp)
cr->col, cr->row);
}
+gboolean
+gnm_solver_param_valid (SolverParameters const *sp, GError **err)
+{
+ GSList *l;
+ int i;
+ GnmCell *target_cell;
+ GSList *input_cells;
+
+ target_cell = gnm_solver_param_get_target_cell (sp);
+ if (!target_cell) {
+ g_set_error (err,
+ go_error_invalid (),
+ 0,
+ _("Invalid solver target"));
+ return FALSE;
+ }
+
+ if (!gnm_cell_has_expr (target_cell)) {
+ g_set_error (err,
+ go_error_invalid (),
+ 0,
+ _("Target cell, %s, must contain a formula"),
+ cell_name (target_cell));
+ return FALSE;
+ }
+
+ if (!gnm_solver_param_get_input (sp)) {
+ g_set_error (err,
+ go_error_invalid (),
+ 0,
+ _("Invalid solver input range"));
+ return FALSE;
+ }
+ input_cells = gnm_solver_param_get_input_cells (sp);
+ for (l = input_cells; l; l = l->next) {
+ GnmCell *cell = l->data;
+ if (gnm_cell_has_expr (cell)) {
+ g_set_error (err,
+ go_error_invalid (),
+ 0,
+ _("Input cell %s contains a formula"),
+ cell_name (cell));
+ g_slist_free (input_cells);
+ return FALSE;
+ }
+ }
+ g_slist_free (input_cells);
+
+ for (i = 1, l = sp->constraints; l; i++, l = l->next) {
+ SolverConstraint *c = l->data;
+ if (!gnm_solver_constraint_valid (c)) {
+ g_set_error (err,
+ go_error_invalid (),
+ 0,
+ _("Solver constraint #%d is invalid"),
+ i);
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+/* ------------------------------------------------------------------------- */
+
static void
solver_constr_start (GsfXMLIn *xin, xmlChar const **attrs)
{
@@ -787,7 +852,7 @@ clear_input_vars (int n_variables, SolverResults *res)
static SolverProgram
lp_qp_solver_init (Sheet *sheet, const SolverParameters *param,
SolverResults *res, const SolverLPAlgorithm *alg,
- gnm_float start_time, GTimeVal start, const gchar **errmsg)
+ gnm_float start_time, GTimeVal start, GError **err)
{
SolverProgram program;
GnmCell *target;
@@ -813,12 +878,6 @@ lp_qp_solver_init (Sheet *sheet, const SolverParameters *param,
res->obj_coeff[i] = x;
}
}
- /* Check that the target cell contains a formula. */
- if (! res->n_nonzeros_in_obj) {
- *errmsg = _("Target cell should contain a formula.");
- solver_results_free (res);
- return NULL;
- }
} else {
/* FIXME: Init qp */
}
@@ -842,9 +901,10 @@ lp_qp_solver_init (Sheet *sheet, const SolverParameters *param,
/* Check that LHS is a number type. */
if (lval == NULL || !VALUE_IS_NUMBER (lval)) {
- *errmsg = _("The LHS cells should contain formulas "
- "that yield proper numerical values. "
- "Specify valid LHS entries.");
+ g_set_error (err, go_error_invalid (), 0,
+ _("The LHS cells should contain formulas "
+ "that yield proper numerical values. "
+ "Specify valid LHS entries."));
solver_results_free (res);
return NULL;
}
@@ -887,9 +947,10 @@ lp_qp_solver_init (Sheet *sheet, const SolverParameters *param,
/* Check that RHS is a number type. */
if (rval == NULL || !VALUE_IS_NUMBER (rval)) {
- *errmsg = _("The RHS cells should contain proper "
- "numerical values only. Specify valid "
- "RHS entries.");
+ g_set_error (err, go_error_invalid (), 0,
+ _("The RHS cells should contain proper "
+ "numerical values only. Specify valid "
+ "RHS entries."));
solver_results_free (res);
return NULL;
}
@@ -904,7 +965,8 @@ lp_qp_solver_init (Sheet *sheet, const SolverParameters *param,
g_get_current_time (&cur_time);
if (cur_time.tv_sec - start.tv_sec >
param->options.max_time_sec) {
- *errmsg = SOLVER_MAX_TIME_ERR;
+ g_set_error (err, go_error_invalid (), 0,
+ SOLVER_MAX_TIME_ERR);
solver_results_free (res);
return NULL;
}
@@ -920,7 +982,9 @@ lp_qp_solver_init (Sheet *sheet, const SolverParameters *param,
alg->maxim_fn (program);
break;
case SolverEqualTo:
- *errmsg = _("EqualTo models are not supported yet. Please use Min or Max");
+ g_set_error (err, go_error_invalid (), 0,
+ _("EqualTo models are not supported yet. "
+ "Please use Min or Max"));
solver_results_free (res);
return NULL; /* FIXME: Equal to feature not yet implemented. */
default:
@@ -933,19 +997,22 @@ lp_qp_solver_init (Sheet *sheet, const SolverParameters *param,
if (alg->set_option_fn (program, SolverOptAutomaticScaling,
&(param->options.automatic_scaling),
NULL, NULL)) {
- *errmsg = _("Failure setting automatic scaling with this solver, try a different algorithm.");
+ g_set_error (err, go_error_invalid (), 0,
+ _("Failure setting automatic scaling with this solver, try a different algorithm."));
solver_results_free (res);
return NULL;
}
if (alg->set_option_fn (program, SolverOptMaxIter, NULL, NULL,
&(param->options.max_iter))) {
- *errmsg = _("Failure setting the maximum number of iterations with this solver, try a different algorithm.");
+ g_set_error (err, go_error_invalid (), 0,
+ _("Failure setting the maximum number of iterations with this solver, try a different algorithm."));
solver_results_free (res);
return NULL;
}
if (alg->set_option_fn (program, SolverOptMaxTimeSec, NULL, &start_time,
&(param->options.max_time_sec))) {
- *errmsg = _("Failure setting the maximum solving time with this solver, try a different algorithm.");
+ g_set_error (err, go_error_invalid (), 0,
+ _("Failure setting the maximum solving time with this solver, try a different algorithm."));
solver_results_free (res);
return NULL;
}
@@ -970,7 +1037,7 @@ static gboolean
check_program_definition_failures (Sheet *sheet,
SolverParameters *param,
SolverResults **res,
- const gchar **errmsg)
+ GError **err)
{
GSList *inputs;
GSList *c;
@@ -993,9 +1060,10 @@ check_program_definition_failures (Sheet *sheet,
/* Check that the cell contains a number or is empty. */
if (! (cell->value == NULL || VALUE_IS_EMPTY (cell->value)
|| VALUE_IS_NUMBER (cell->value))) {
- *errmsg = _("Some of the input cells contain "
- "non-numeric values. Specify a valid "
- "input range.");
+ g_set_error (err, go_error_invalid (), 0,
+ _("Some of the input cells contain "
+ "non-numeric values. Specify a valid "
+ "input range."));
g_slist_free (input_cells);
return TRUE;
}
@@ -1064,7 +1132,7 @@ check_program_definition_failures (Sheet *sheet,
static SolverResults *
solver_run (WorkbookControl *wbc, Sheet *sheet,
- const SolverLPAlgorithm *alg, const gchar **errmsg)
+ const SolverLPAlgorithm *alg, GError **err)
{
SolverParameters *param = sheet->solver_parameters;
SolverProgram program;
@@ -1078,7 +1146,11 @@ solver_run (WorkbookControl *wbc, Sheet *sheet,
#endif
g_get_current_time (&start);
- if (check_program_definition_failures (sheet, param, &res, errmsg))
+
+ if (!gnm_solver_param_valid (param, err))
+ return NULL;
+
+ if (check_program_definition_failures (sheet, param, &res, err))
return NULL;
#if defined(HAVE_TIMES) && defined(HAVE_SYSCONF)
@@ -1095,7 +1167,7 @@ solver_run (WorkbookControl *wbc, Sheet *sheet,
program = lp_qp_solver_init (sheet, param, res, alg,
-res->time_real, start,
- errmsg);
+ err);
if (program == NULL)
return NULL;
@@ -1129,7 +1201,7 @@ solver_run (WorkbookControl *wbc, Sheet *sheet,
}
SolverResults *
-solver (WorkbookControl *wbc, Sheet *sheet, const gchar **errmsg)
+solver (WorkbookControl *wbc, Sheet *sheet, GError **err)
{
const SolverLPAlgorithm *alg = NULL;
SolverParameters *param = sheet->solver_parameters;
@@ -1148,7 +1220,7 @@ solver (WorkbookControl *wbc, Sheet *sheet, const gchar **errmsg)
g_assert_not_reached ();
}
- return solver_run (wbc, sheet, alg, errmsg);
+ return solver_run (wbc, sheet, alg, err);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]