[gnumeric] solver: keep input and target as managed deps.
- From: Morten Welinder <mortenw src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gnumeric] solver: keep input and target as managed deps.
- Date: Sun, 1 Nov 2009 14:23:53 +0000 (UTC)
commit 9b9a7b44d464b965607bc71515bc20786278c93b
Author: Morten Welinder <terra gnome org>
Date: Sun Nov 1 09:23:21 2009 -0500
solver: keep input and target as managed deps.
ChangeLog | 7 +
plugins/lpsolve/lpsolve-write.c | 12 +-
plugins/mps/mps.c | 9 +-
src/dialogs/dialog-solver.c | 30 +++--
src/expr.c | 11 ++
src/expr.h | 1 +
src/sheet.c | 6 +-
src/solver.h | 23 ++--
src/tools/solver/ChangeLog | 8 +
src/tools/solver/reports-write.c | 8 +-
src/tools/solver/reports.c | 9 +-
src/tools/solver/solver.c | 266 ++++++++++++++------------------------
src/xml-sax-write.c | 16 ++-
13 files changed, 185 insertions(+), 221 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 492c22f..41fed47 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2009-11-01 Morten Welinder <terra gnome org>
+
+ * src/solver.h (struct _SolverParameters): Keep target and input
+ as deps so they get maintained.
+
+ * src/expr.c (gnm_expr_top_get_cellref): New function.
+
2009-10-31 Morten Welinder <terra gnome org>
* src/dependent.c (dependent_managed_init,
diff --git a/plugins/lpsolve/lpsolve-write.c b/plugins/lpsolve/lpsolve-write.c
index a0d6cb9..60858af 100644
--- a/plugins/lpsolve/lpsolve-write.c
+++ b/plugins/lpsolve/lpsolve-write.c
@@ -153,11 +153,12 @@ lpsolve_create_program (Sheet *sheet, GError **err)
GString *declarations = g_string_new (NULL);
GString *objfunc = g_string_new (NULL);
GSList *l;
+ GnmCell *target_cell = gnm_solver_param_get_target_cell (sp);
- /* This is insane -- why do we keep a string? */
+ /* This is insane */
{
- GnmValue *vr =
- value_new_cellrange_str (sheet, sp->input_entry_str);
+ GnmValue const *vr =
+ gnm_expr_top_get_constant (sheet, sp->input.texpr);
GnmEvalPos ep;
g_slist_free (sp->input_cells);
@@ -175,14 +176,13 @@ lpsolve_create_program (Sheet *sheet, GError **err)
workbook_foreach_cell_in_range (&ep, vr, CELL_ITER_ALL,
cb_grab_cells,
&sp->input_cells);
- value_release (vr);
}
/* ---------------------------------------- */
switch (sp->problem_type) {
case SolverEqualTo:
- if (!lpsolve_affine_func (constraints, sp->target_cell,
+ if (!lpsolve_affine_func (constraints, target_cell,
sp->input_cells, err))
goto fail;
/* FIXME -- what value goes here? */
@@ -198,7 +198,7 @@ lpsolve_create_program (Sheet *sheet, GError **err)
g_assert_not_reached ();
}
- if (!lpsolve_affine_func (objfunc, sp->target_cell,
+ if (!lpsolve_affine_func (objfunc, target_cell,
sp->input_cells, err))
goto fail;
g_string_append (objfunc, ";\n");
diff --git a/plugins/mps/mps.c b/plugins/mps/mps.c
index c9033fd..68f8ba8 100644
--- a/plugins/mps/mps.c
+++ b/plugins/mps/mps.c
@@ -437,8 +437,8 @@ mps_write_coefficients (MpsInputContext *ctxt, Sheet *sh,
cell_queue_recalc (cell);
/* Store the input cell range for the Solver dialog. */
- g_free (param->input_entry_str);
- param->input_entry_str = g_strdup (range_as_string (&v_range));
+ gnm_solver_param_set_input (param,
+ value_new_cellrange_r (NULL, &v_range));
}
/* Creates the spreadsheet model. */
@@ -453,6 +453,7 @@ mps_create_sheet (MpsInputContext *ctxt, WorkbookView *wbv)
ctxt->objective_row
? ctxt->objective_row->name
: "-";
+ GnmCellRef cr;
n_rows_per_fn = (ctxt->n_cols + MAX_COL - 1) / MAX_COL;
mps_prepare (wbv, ctxt);
@@ -477,8 +478,8 @@ mps_create_sheet (MpsInputContext *ctxt, WorkbookView *wbv)
}
}
- param->target_cell = sheet_cell_fetch (sh, OBJECTIVE_VALUE_COL,
- MAIN_INFO_ROW);
+ gnm_cellref_init (&cr, NULL, OBJECTIVE_VALUE_COL, MAIN_INFO_ROW, TRUE);
+ gnm_solver_param_set_target (param, &cr);
param->problem_type = SolverMinimize;
/* Write the name of the program. */
diff --git a/src/dialogs/dialog-solver.c b/src/dialogs/dialog-solver.c
index 027c943..f93b3ff 100644
--- a/src/dialogs/dialog-solver.c
+++ b/src/dialogs/dialog-solver.c
@@ -616,7 +616,8 @@ solver_add_scenario (SolverState *state, SolverResults *res, gchar const *name)
input_range = gnm_expr_entry_parse_as_value (state->change_cell_entry,
state->sheet);
- scenario_add_new (name, input_range, param->input_entry_str,
+ scenario_add_new (name, input_range,
+ value_peek_string (gnm_solver_param_get_input (param)),
comment, state->sheet, &scenario);
scenario_add (state->sheet, scenario);
if (input_range != NULL)
@@ -647,6 +648,7 @@ cb_dialog_solve_clicked (G_GNUC_UNUSED GtkWidget *button,
SolverParameters *param;
GtkTreeIter iter;
gchar const *name;
+ GnmCell *target_cell;
param = state->sheet->solver_parameters;
@@ -667,16 +669,14 @@ cb_dialog_solve_clicked (G_GNUC_UNUSED GtkWidget *button,
return;
}
- g_free (param->input_entry_str);
- param->input_entry_str = value_get_as_string (input_range);
+ gnm_solver_param_set_input (param, value_dup (input_range));
- param->target_cell =
- sheet_cell_fetch (state->sheet,
- target_range->v_range.cell.a.col,
- target_range->v_range.cell.a.row );
+ gnm_solver_param_set_target (param,
+ &target_range->v_range.cell.a);
+ target_cell = gnm_solver_param_get_target_cell (param);
/* Check that the target cell type is number. */
- if (! gnm_cell_is_number (param->target_cell)) {
+ if (!target_cell || !gnm_cell_is_number (target_cell)) {
go_gtk_notice_nonmodal_dialog
((GtkWindow *) state->dialog,
&(state->warning_dialog),
@@ -767,7 +767,7 @@ cb_dialog_solve_clicked (G_GNUC_UNUSED GtkWidget *button,
goto out;
}
- state->ov_target = value_get_as_float (param->target_cell->value);
+ state->ov_target = value_get_as_float (target_cell->value);
state->ov = save_original_values (input_cells);
state->ov_stack = g_slist_prepend (state->ov_stack, state->ov);
state->ov_cell_stack = g_slist_prepend (state->ov_cell_stack,
@@ -820,6 +820,8 @@ dialog_init (SolverState *state)
GtkTreeViewColumn *column;
GList *l = NULL;
GSList *cl;
+ GnmCell *target_cell;
+ GnmValue const *input;
param = state->sheet->solver_parameters;
@@ -1087,12 +1089,14 @@ dialog_init (SolverState *state)
glade_xml_get_widget(state->gui, "program")),
param->options.program_report);
- if (param->input_entry_str != NULL)
+ input = gnm_solver_param_get_input (param);
+ if (input != NULL)
gnm_expr_entry_load_from_text (state->change_cell_entry,
- param->input_entry_str);
- if (param->target_cell != NULL)
+ value_peek_string (input));
+ target_cell = gnm_solver_param_get_target_cell (param);
+ if (target_cell)
gnm_expr_entry_load_from_text (state->target_entry,
- cell_name(param->target_cell));
+ cell_name (target_cell));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (
glade_xml_get_widget(state->gui, "max_button")),
param->problem_type == SolverMaximize);
diff --git a/src/expr.c b/src/expr.c
index a990f03..213070f 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -3044,6 +3044,17 @@ gnm_expr_top_get_constant (GnmExprTop const *texpr)
return texpr->expr->constant.value;
}
+GnmCellRef *
+gnm_expr_top_get_cellref (GnmExprTop const *texpr)
+{
+ g_return_val_if_fail (IS_GNM_EXPR_TOP (texpr), NULL);
+
+ if (GNM_EXPR_GET_OPER (texpr->expr) != GNM_EXPR_OP_CELLREF)
+ return NULL;
+
+ return &texpr->expr->cellref.ref;
+}
+
/**
* gnm_expr_top_first_funcall :
* @texpr :
diff --git a/src/expr.h b/src/expr.h
index 5952a30..e7782b2 100644
--- a/src/expr.h
+++ b/src/expr.h
@@ -140,6 +140,7 @@ gboolean gnm_expr_top_is_array (GnmExprTop const *texpr);
GnmValue *gnm_expr_top_get_range (GnmExprTop const *texpr);
GSList *gnm_expr_top_get_ranges (GnmExprTop const *texpr);
GnmValue const *gnm_expr_top_get_constant (GnmExprTop const *texpr);
+GnmCellRef *gnm_expr_top_get_cellref (GnmExprTop const *texpr);
void gnm_expr_top_get_boundingbox (GnmExprTop const *texpr,
Sheet const *sheet,
GnmRange *bound);
diff --git a/src/sheet.c b/src/sheet.c
index 1255851..c867d97 100644
--- a/src/sheet.c
+++ b/src/sheet.c
@@ -755,7 +755,7 @@ gnm_sheet_init (Sheet *sheet)
sheet->sheet_objects = NULL;
sheet->max_object_extent.col = sheet->max_object_extent.row = 0;
- sheet->solver_parameters = solver_param_new ();
+ sheet->solver_parameters = solver_param_new (sheet);
sheet->cols.max_used = -1;
sheet->cols.info = g_ptr_array_new ();
@@ -4452,7 +4452,6 @@ sheet_insert_cols (Sheet *sheet, int col, int count,
colrow_move (sheet, i, 0, i, gnm_sheet_get_last_row (sheet),
&sheet->cols, i, i + count);
- solver_insert_cols (sheet, col, count);
scenarios_insert_cols (sheet->scenarios, col, count);
sheet_colrow_insert_finish (&reloc_info, TRUE, col, count, pundo);
@@ -4551,7 +4550,6 @@ sheet_delete_cols (Sheet *sheet, int col, int count,
colrow_move (sheet, i, 0, i, gnm_sheet_get_last_row (sheet),
&sheet->cols, i, i - count);
- solver_delete_cols (sheet, col, count);
scenarios_delete_cols (sheet->scenarios, col, count);
sheet_colrow_delete_finish (&reloc_info, TRUE, col, count, pundo);
@@ -4628,7 +4626,6 @@ sheet_insert_rows (Sheet *sheet, int row, int count,
colrow_move (sheet, 0, i, gnm_sheet_get_last_col (sheet), i,
&sheet->rows, i, i + count);
- solver_insert_rows (sheet, row, count);
scenarios_insert_rows (sheet->scenarios, row, count);
sheet_colrow_insert_finish (&reloc_info, FALSE, row, count, pundo);
@@ -4727,7 +4724,6 @@ sheet_delete_rows (Sheet *sheet, int row, int count,
colrow_move (sheet, 0, i, gnm_sheet_get_last_col (sheet), i,
&sheet->rows, i, i - count);
- solver_delete_rows (sheet, row, count);
scenarios_delete_rows (sheet->scenarios, row, count);
sheet_colrow_delete_finish (&reloc_info, FALSE, row, count, pundo);
diff --git a/src/solver.h b/src/solver.h
index acb3257..7c4a2b2 100644
--- a/src/solver.h
+++ b/src/solver.h
@@ -46,10 +46,11 @@ typedef enum {
struct _SolverParameters {
SolverProblemType problem_type;
- GnmCell *target_cell;
+ Sheet *sheet;
+ GnmDependent target;
+ GnmDependent input;
GSList *input_cells;
GSList *constraints;
- char *input_entry_str;
int n_constraints;
int n_variables;
int n_int_constraints;
@@ -242,7 +243,14 @@ gchar * solver_reports (WorkbookControl *wbc, Sheet *sheet,
/* Initializes the Solver's data structure containing the parameters.
* Each sheet can currently have one copy of this data structure. */
-SolverParameters *solver_param_new (void);
+SolverParameters *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);
+
+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 solver_param_destroy (SolverParameters *sp);
@@ -255,21 +263,12 @@ SolverParameters *solver_lp_copy (SolverParameters const *src_param,
/* Frees the data structure allocated for the results. */
void solver_results_free (SolverResults *res);
-/* Returns a pointer to the target cell of the model attached to the
- * given sheet. */
-GnmCell *solver_get_target_cell (Sheet *sheet);
-
/* Returns a pointer to a input variable cell. */
GnmCell *solver_get_input_var (SolverResults *res, int n);
/* Returns a pointer to a constraint. */
SolverConstraint* solver_get_constraint (SolverResults *res, int n);
-void solver_insert_cols (Sheet *sheet, int col, int count);
-void solver_insert_rows (Sheet *sheet, int row, int count);
-void solver_delete_rows (Sheet *sheet, int row, int count);
-void solver_delete_cols (Sheet *sheet, int col, int count);
-
void solver_param_read_sax (GsfXMLIn *xin, xmlChar const **attrs);
#else /* !GNM_ENABLE_SOLVER */
diff --git a/src/tools/solver/ChangeLog b/src/tools/solver/ChangeLog
index 117100b..3ac7fdf 100644
--- a/src/tools/solver/ChangeLog
+++ b/src/tools/solver/ChangeLog
@@ -1,3 +1,11 @@
+2009-11-01 Morten Welinder <terra gnome org>
+
+ * solver.c (gnm_solver_param_get_input,
+ gnm_solver_param_set_input, gnm_solver_param_set_target,
+ gnm_solver_param_get_target): New functions.
+ (solver_insert_rows, solver_insert_cols, solver_delete_rows,
+ solver_delete_cols): Removed -- no longer needed.
+
2009-10-31 Morten Welinder <terra gnome org>
* solver.c (solver_constr_start): Read the new format.
diff --git a/src/tools/solver/reports-write.c b/src/tools/solver/reports-write.c
index cc79e56..90f830b 100644
--- a/src/tools/solver/reports-write.c
+++ b/src/tools/solver/reports-write.c
@@ -82,7 +82,8 @@ solver_answer_report (WorkbookControl *wbc,
dao_set_bold (&dao, 0, 6, 4, 6);
/* Set `Cell' field (cell reference to the target cell). */
- dao_set_cell (&dao, 1, 7, cell_name (res->param->target_cell));
+ cell = gnm_solver_param_get_target_cell (res->param);
+ dao_set_cell (&dao, 1, 7, cell_name (cell));
/* Set `Name' field */
dao_set_cell (&dao, 2, 7, res->target_name);
@@ -431,14 +432,13 @@ solver_limits_report (WorkbookControl *wbc,
*/
/* Set `Target Cell' field (cell reference to the target cell). */
- dao_set_cell (&dao, 1, 7, cell_name (res->param->target_cell));
+ cell = gnm_solver_param_get_target_cell (res->param);
+ dao_set_cell (&dao, 1, 7, cell_name (cell));
/* Set `Target Name' field */
dao_set_cell (&dao, 2, 7, res->target_name);
/* Set `Target Value' field */
- cell = sheet_cell_get (sheet, res->param->target_cell->pos.col,
- res->param->target_cell->pos.row);
dao_set_cell_float (&dao, 3, 7, res->value_of_obj_fn);
diff --git a/src/tools/solver/reports.c b/src/tools/solver/reports.c
index 4a01956..a5f847c 100644
--- a/src/tools/solver/reports.c
+++ b/src/tools/solver/reports.c
@@ -149,7 +149,7 @@ static void
calculate_limits (Sheet *sheet, SolverParameters *param, SolverResults *res)
{
int i, n;
- GnmCell *tcell = solver_get_target_cell (sheet);
+ GnmCell *tcell = gnm_solver_param_get_target_cell (param);
for (i = 0; i < param->n_total_constraints; i++) {
gnm_float slack, lhs, rhs, x, y, old_val;
@@ -222,15 +222,14 @@ solver_prepare_reports (SolverProgram *program, SolverResults *res,
{
SolverParameters *param = res->param;
const SolverLPAlgorithm *alg;
+ GnmCell const *target_cell;
if (res->param->options.model_type == SolverLPModel)
alg = &lp_algorithm[param->options.algorithm];
else
alg = &qp_algorithm[param->options.algorithm];
- res->target_name = dao_find_name (sheet,
- res->param->target_cell->pos.col,
- res->param->target_cell->pos.row);
+ target_cell = gnm_solver_param_get_target_cell (res->param);
get_input_variable_names (res, sheet);
get_constraint_names (res, sheet);
@@ -261,7 +260,7 @@ solver_prepare_reports_success (SolverProgram *program, SolverResults *res,
* Fetch the target cell value from the sheet since it's
* formula may have a constant increment or decrement.
*/
- cell = solver_get_target_cell (sheet);
+ cell = gnm_solver_param_get_target_cell (param);
res->value_of_obj_fn = value_get_as_float (cell->value);
/*
diff --git a/src/tools/solver/solver.c b/src/tools/solver/solver.c
index dce5e0e..41e8181 100644
--- a/src/tools/solver/solver.c
+++ b/src/tools/solver/solver.c
@@ -66,18 +66,20 @@ attr_eq (const xmlChar *a, const char *s)
SolverParameters *
-solver_param_new (void)
+solver_param_new (Sheet *sheet)
{
SolverParameters *res = g_new0 (SolverParameters, 1);
+ dependent_managed_init (&res->target, sheet);
+ dependent_managed_init (&res->input, sheet);
+
res->options.model_type = SolverLPModel;
+ res->sheet = sheet;
res->options.assume_non_negative = TRUE;
res->options.algorithm = GLPKSimplex;
res->options.scenario_name = g_strdup ("Optimal");
- res->input_entry_str = g_strdup ("");
res->problem_type = SolverMaximize;
res->constraints = NULL;
- res->target_cell = NULL;
res->input_cells = NULL;
res->constraints = NULL;
@@ -87,14 +89,59 @@ solver_param_new (void)
void
solver_param_destroy (SolverParameters *sp)
{
+ dependent_managed_set_expr (&sp->target, NULL);
+ dependent_managed_set_expr (&sp->input, NULL);
go_slist_free_custom (sp->constraints,
(GFreeFunc)gnm_solver_constraint_free);
g_slist_free (sp->input_cells);
- g_free (sp->input_entry_str);
g_free (sp->options.scenario_name);
g_free (sp);
}
+GnmValue const *
+gnm_solver_param_get_input (SolverParameters const *sp)
+{
+ return sp->input.texpr
+ ? gnm_expr_top_get_constant (sp->input.texpr)
+ : NULL;
+}
+
+void
+gnm_solver_param_set_input (SolverParameters *sp, GnmValue *v)
+{
+ /* Takes ownership. */
+ GnmExprTop const *texpr = v ? gnm_expr_top_new_constant (v) : NULL;
+ dependent_managed_set_expr (&sp->input, texpr);
+ if (texpr) gnm_expr_top_unref (texpr);
+}
+
+void
+gnm_solver_param_set_target (SolverParameters *sp, GnmCellRef const *cr)
+{
+ GnmExprTop const *texpr = gnm_expr_top_new (gnm_expr_new_cellref (cr));
+ dependent_managed_set_expr (&sp->target, texpr);
+ gnm_expr_top_unref (texpr);
+}
+
+const GnmCellRef *
+gnm_solver_param_get_target (SolverParameters const *sp)
+{
+ return sp->target.texpr
+ ? gnm_expr_top_get_cellref (sp->target.texpr)
+ : NULL;
+}
+
+GnmCell *
+gnm_solver_param_get_target_cell (SolverParameters const *sp)
+{
+ const GnmCellRef *cr = gnm_solver_param_get_target (sp);
+ if (!cr)
+ return NULL;
+
+ return sheet_cell_get (eval_sheet (cr->sheet, sp->sheet),
+ cr->col, cr->row);
+}
+
static void
solver_constr_start (GsfXMLIn *xin, xmlChar const **attrs)
{
@@ -156,9 +203,9 @@ solver_param_read_sax (GsfXMLIn *xin, xmlChar const **attrs)
{
Sheet *sheet = gnm_xml_in_cur_sheet (xin);
SolverParameters *sp = sheet->solver_parameters;
- int i;
int col = -1, row = -1;
int ptype;
+ GnmParsePos pp;
static GsfXMLInNode const dtd[] = {
GSF_XML_IN_NODE (SHEET_SOLVER_CONSTR, SHEET_SOLVER_CONSTR, GNM, "Constr", GSF_XML_NO_CONTENT, &solver_constr_start, NULL),
@@ -166,31 +213,39 @@ solver_param_read_sax (GsfXMLIn *xin, xmlChar const **attrs)
};
static GsfXMLInDoc *doc;
- for (i = 0; attrs != NULL && attrs[i] && attrs[i + 1] ; i += 2) {
- if (gnm_xml_attr_int (attrs+i, "ProblemType", &ptype))
+ parse_pos_init_sheet (&pp, sheet);
+
+ for (; attrs && attrs[0] && attrs[1] ; attrs += 2) {
+ if (gnm_xml_attr_int (attrs, "ProblemType", &ptype))
sp->problem_type = (SolverProblemType)ptype;
- else if (strcmp (CXML2C (attrs[i]), "Inputs") == 0) {
- g_free (sp->input_entry_str);
- sp->input_entry_str = g_strdup (CXML2C (attrs[i+1]));
- } else if (gnm_xml_attr_int (attrs+i, "TargetCol", &col) ||
- gnm_xml_attr_int (attrs+i, "TargetRow", &row) ||
- gnm_xml_attr_int (attrs+i, "MaxTime", &(sp->options.max_time_sec)) ||
- gnm_xml_attr_int (attrs+i, "MaxIter", &(sp->options.max_iter)) ||
- gnm_xml_attr_bool (attrs+i, "NonNeg", &(sp->options.assume_non_negative)) ||
- gnm_xml_attr_bool (attrs+i, "Discr", &(sp->options.assume_discrete)) ||
- gnm_xml_attr_bool (attrs+i, "AutoScale", &(sp->options.automatic_scaling)) ||
- gnm_xml_attr_bool (attrs+i, "ShowIter", &(sp->options.show_iter_results)) ||
- gnm_xml_attr_bool (attrs+i, "AnswerR", &(sp->options.answer_report)) ||
- gnm_xml_attr_bool (attrs+i, "SensitivityR", &(sp->options.sensitivity_report)) ||
- gnm_xml_attr_bool (attrs+i, "LimitsR", &(sp->options.limits_report)) ||
- gnm_xml_attr_bool (attrs+i, "PerformR", &(sp->options.performance_report)) ||
- gnm_xml_attr_bool (attrs+i, "ProgramR", &(sp->options.program_report)))
+ else if (strcmp (CXML2C (attrs[0]), "Inputs") == 0) {
+ GnmValue *v = value_new_cellrange_parsepos_str
+ (&pp,
+ CXML2C (attrs[1]),
+ GNM_EXPR_PARSE_DEFAULT);
+ gnm_solver_param_set_input (sp, v);
+ } else if (gnm_xml_attr_int (attrs, "TargetCol", &col) ||
+ gnm_xml_attr_int (attrs, "TargetRow", &row) ||
+ gnm_xml_attr_int (attrs, "MaxTime", &(sp->options.max_time_sec)) ||
+ gnm_xml_attr_int (attrs, "MaxIter", &(sp->options.max_iter)) ||
+ 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 */
}
if (col >= 0 && col < gnm_sheet_get_max_cols (sheet) &&
- row >= 0 && row < gnm_sheet_get_max_rows (sheet))
- sp->target_cell = sheet_cell_fetch (sheet, col, row);
+ row >= 0 && row < gnm_sheet_get_max_rows (sheet)) {
+ GnmCellRef cr;
+ gnm_cellref_init (&cr, NULL, col, row, TRUE);
+ gnm_solver_param_set_target (sp, &cr);
+ }
if (!doc)
doc = gsf_xml_in_doc_new (dtd, NULL);
@@ -252,6 +307,9 @@ solver_results_free (SolverResults *res)
g_free (res->constraint_names);
g_free (res->shadow_prizes);
g_free (res->input_cells_array);
+ if (res->constraints_array)
+ for (i = 0; i < res->n_constraints; i++)
+ gnm_solver_constraint_free (res->constraints_array[i]);
g_free (res->constraints_array);
g_free (res->obj_coeff);
if (res->constr_coeff != NULL)
@@ -270,14 +328,6 @@ solver_results_free (SolverResults *res)
/* ------------------------------------------------------------------------- */
GnmCell *
-solver_get_target_cell (Sheet *sheet)
-{
- return sheet_cell_get (sheet,
- sheet->solver_parameters->target_cell->pos.col,
- sheet->solver_parameters->target_cell->pos.row);
-}
-
-GnmCell *
solver_get_input_var (SolverResults *res, int n)
{
return res->input_cells_array[n];
@@ -377,7 +427,7 @@ gnm_solver_constraint_get_size (SolverConstraint const *c)
if (lhs) {
if (VALUE_IS_FLOAT (lhs))
return 1;
- if (lhs->type != VALUE_CELLRANGE) {
+ if (lhs->type == VALUE_CELLRANGE) {
range_init_value (&r, lhs);
return range_width (&r) * range_height (&r);
}
@@ -433,7 +483,7 @@ gnm_solver_constraint_get_part (SolverConstraint const *c, Sheet *sheet, int i,
if (lhs) *lhs = NULL;
if (rhs) *rhs = NULL;
- if (gnm_solver_constraint_valid (c))
+ if (!gnm_solver_constraint_valid (c))
return FALSE;
vl = gnm_solver_constraint_get_lhs (c);
@@ -480,6 +530,9 @@ gnm_solver_constraint_get_part_val (SolverConstraint const *c,
if (lhs) *lhs = NULL;
if (rhs) *rhs = NULL;
+ if (!gnm_solver_constraint_valid (c))
+ return FALSE;
+
vl = gnm_solver_constraint_get_lhs (c);
vr = gnm_solver_constraint_get_rhs (c);
@@ -637,7 +690,7 @@ save_original_values (SolverResults *res,
++i;
}
- cell = solver_get_target_cell (sheet);
+ cell = gnm_solver_param_get_target_cell (param);
res->original_value_of_obj_fn = value_get_as_float (cell->value);
}
@@ -702,7 +755,7 @@ lp_qp_solver_init (Sheet *sheet, const SolverParameters *param,
program = alg->init_fn (param);
/* Set up the objective function coefficients. */
- target = solver_get_target_cell (sheet);
+ target = gnm_solver_param_get_target_cell (param);
clear_input_vars (param->n_variables, res);
gnm_cell_eval (target);
@@ -932,13 +985,13 @@ check_program_definition_failures (Sheet *sheet,
i = 0;
for (c = param->constraints; c ; c = c->next) {
SolverConstraint *sc = c->data;
- int i;
+ int j;
GnmValue *lhs, *rhs;
- for (i = 0;
- gnm_solver_constraint_get_part_val (sc, sheet, i,
+ for (j = 0;
+ gnm_solver_constraint_get_part_val (sc, sheet, j,
&lhs, &rhs);
- i++) {
+ j++) {
SolverConstraint *nc =
gnm_solver_constraint_new (sheet);
nc->type = sc->type;
@@ -1057,19 +1110,15 @@ solver (WorkbookControl *wbc, Sheet *sheet, const gchar **errmsg)
SolverParameters *
solver_lp_copy (const SolverParameters *src_param, Sheet *new_sheet)
{
- SolverParameters *dst_param = solver_param_new ();
+ SolverParameters *dst_param = solver_param_new (new_sheet);
GSList *constraints;
GSList *inputs;
- if (src_param->target_cell != NULL)
- dst_param->target_cell =
- sheet_cell_fetch (new_sheet,
- src_param->target_cell->pos.col,
- src_param->target_cell->pos.row);
-
dst_param->problem_type = src_param->problem_type;
- g_free (dst_param->input_entry_str);
- dst_param->input_entry_str = g_strdup (src_param->input_entry_str);
+ dependent_managed_set_expr (&dst_param->target,
+ src_param->target.texpr);
+ dependent_managed_set_expr (&dst_param->input,
+ src_param->input.texpr);
g_free (dst_param->options.scenario_name);
dst_param->options = src_param->options;
@@ -1106,120 +1155,3 @@ solver_lp_copy (const SolverParameters *src_param, Sheet *new_sheet)
return dst_param;
}
-
-/*
- * Adjusts the row indices in the Solver's data structures when rows
- * are inserted.
- */
-void
-solver_insert_rows (Sheet *sheet, int row, int count)
-{
- SolverParameters *param = sheet->solver_parameters;
- GnmValue *input_range;
- GnmRange range;
-
- /* Adjust the input range. */
- input_range = value_new_cellrange_str (sheet, param->input_entry_str);
- if (input_range != NULL) {
- if (input_range->v_range.cell.a.row >= row) {
- range.start.col = input_range->v_range.cell.a.col;
- range.start.row = input_range->v_range.cell.a.row +
- count;
- range.end.col = input_range->v_range.cell.b.col;
- range.end.row = input_range->v_range.cell.b.row +
- count;
- g_free (param->input_entry_str);
- param->input_entry_str =
- g_strdup (global_range_name (sheet, &range));
- }
- value_release (input_range);
- }
-}
-
-/*
- * Adjusts the column indices in the Solver's data structures when columns
- * are inserted.
- */
-void
-solver_insert_cols (Sheet *sheet, int col, int count)
-{
- SolverParameters *param = sheet->solver_parameters;
- GnmValue *input_range;
- GnmRange range;
-
- /* Adjust the input range. */
- input_range = value_new_cellrange_str (sheet, param->input_entry_str);
- if (input_range != NULL &&
- input_range->v_range.cell.a.col >= col) {
- range.start.col = input_range->v_range.cell.a.col + count;
- range.start.row = input_range->v_range.cell.a.row;
- range.end.col = input_range->v_range.cell.b.col + count;
- range.end.row = input_range->v_range.cell.b.row;
- g_free (param->input_entry_str);
- param->input_entry_str = g_strdup (
- global_range_name (sheet, &range));
- value_release (input_range);
- }
-}
-
-/*
- * Adjusts the row indices in the Solver's data structures when rows
- * are deleted.
- */
-void
-solver_delete_rows (Sheet *sheet, int row, int count)
-{
- SolverParameters *param = sheet->solver_parameters;
- GnmValue *input_range;
- GnmRange range;
-
- /* Adjust the input range. */
- input_range = value_new_cellrange_str (sheet, param->input_entry_str);
- if (input_range != NULL &&
- input_range->v_range.cell.a.row >= row) {
- range.start.col = input_range->v_range.cell.a.col;
- range.start.row = input_range->v_range.cell.a.row - count;
- range.end.col = input_range->v_range.cell.b.col;
- range.end.row = input_range->v_range.cell.b.row - count;
- g_free (param->input_entry_str);
- if (range.start.row < row || range.end.row < row)
- param->input_entry_str = g_strdup ("");
- else
- param->input_entry_str = g_strdup (
- global_range_name (sheet, &range));
- value_release (input_range);
- }
-}
-
-/*
- * Adjusts the column indices in the Solver's data structures when columns
- * are deleted.
- */
-void
-solver_delete_cols (Sheet *sheet, int col, int count)
-{
- SolverParameters *param = sheet->solver_parameters;
- GnmValue *input_range;
- GnmRange range;
-
- /* Adjust the input range. */
- input_range = value_new_cellrange_str (sheet, param->input_entry_str);
- if (input_range != NULL) {
- if (input_range->v_range.cell.a.col >= col) {
- range.start.col = input_range->v_range.cell.a.col -
- count;
- range.start.row = input_range->v_range.cell.a.row;
- range.end.col = input_range->v_range.cell.b.col -
- count;
- range.end.row = input_range->v_range.cell.b.row;
- g_free (param->input_entry_str);
- if (range.start.col < col || range.end.col < col)
- param->input_entry_str = g_strdup ("");
- else
- param->input_entry_str =
- g_strdup (global_range_name (sheet,
- &range));
- }
- value_release (input_range);
- }
-}
diff --git a/src/xml-sax-write.c b/src/xml-sax-write.c
index 24f8b2c..9a351be 100644
--- a/src/xml-sax-write.c
+++ b/src/xml-sax-write.c
@@ -967,22 +967,28 @@ xml_write_solver (GnmOutputXML *state)
{
SolverParameters *param = state->sheet->solver_parameters;
GSList *ptr;
+ GnmCellRef const *target;
+ GnmValue const *input;
if (param == NULL)
return;
gsf_xml_out_start_element (state->output, GNM "Solver");
- if (param->target_cell != NULL) {
+ target = gnm_solver_param_get_target (param);
+ if (target != NULL) {
+ /* FIXME: This drops sheet */
gsf_xml_out_add_int (state->output, "TargetCol",
- param->target_cell->pos.col);
+ target->col);
gsf_xml_out_add_int (state->output, "TargetRow",
- param->target_cell->pos.row);
+ target->row);
}
gsf_xml_out_add_int (state->output, "ProblemType", param->problem_type);
- gsf_xml_out_add_cstr (state->output, "Inputs",
- param->input_entry_str);
+ input = gnm_solver_param_get_input (param);
+ if (input)
+ gsf_xml_out_add_cstr (state->output, "Inputs",
+ value_peek_string (input));
gsf_xml_out_add_int (state->output, "MaxTime",
param->options.max_time_sec);
gsf_xml_out_add_int (state->output, "MaxIter",
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]