[gnumeric] solver: reduce access directly into SolverConstraint's fields.
- From: Morten Welinder <mortenw src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gnumeric] solver: reduce access directly into SolverConstraint's fields.
- Date: Fri, 30 Oct 2009 13:45:00 +0000 (UTC)
commit f9b22c8df1c832ad36c768a90bf8ca7d720769c5
Author: Morten Welinder <terra gnome org>
Date: Fri Oct 30 09:44:45 2009 -0400
solver: reduce access directly into SolverConstraint's fields.
src/dialogs/dialog-solver.c | 88 +++++++++++++++++---------------------
src/solver.h | 9 +++-
src/tools/solver/reports-write.c | 19 ++++++--
src/tools/solver/reports.c | 61 +++++++++++++++++---------
src/tools/solver/solver.c | 19 ++++++++-
5 files changed, 118 insertions(+), 78 deletions(-)
---
diff --git a/src/dialogs/dialog-solver.c b/src/dialogs/dialog-solver.c
index 859d2bc..02d4b77 100644
--- a/src/dialogs/dialog-solver.c
+++ b/src/dialogs/dialog-solver.c
@@ -270,29 +270,32 @@ constraint_fill_row (SolverState *state, GtkListStore *store, GtkTreeIter *iter)
char *text;
constraint_t *the_constraint = g_new (constraint_t, 1);
SolverConstraint c;
- GnmCellRef a, b;
+ GnmCellRef a, b, ra;
+ gboolean has_rhs;
- the_constraint->lhs_value = gnm_expr_entry_parse_as_value
- (state->lhs.entry, state->sheet);
the_constraint->type = gtk_combo_box_get_active
(state->type_combo);
+ has_rhs = (the_constraint->type != SolverINT &&
+ the_constraint->type != SolverBOOL);
+
+ the_constraint->lhs_value = gnm_expr_entry_parse_as_value
+ (state->lhs.entry, state->sheet);
a = the_constraint->lhs_value->v_range.cell.a;
b = the_constraint->lhs_value->v_range.cell.b;
- c.type = the_constraint->type;
- c.lhs.col = a.col;
- c.lhs.row = a.row;
- c.rows = b.row - c.lhs.row + 1;
- c.cols = b.col - c.lhs.col + 1;
- if (c.type != SolverINT && c.type != SolverBOOL) {
+
+ if (has_rhs) {
the_constraint->rhs_value = gnm_expr_entry_parse_as_value
(state->rhs.entry, state->sheet);
- a = the_constraint->rhs_value->v_range.cell.a;
- c.rhs.col = a.col;
- c.rhs.row = a.row;
+ ra = the_constraint->rhs_value->v_range.cell.a;
} else {
- the_constraint->rhs_value = NULL;
- c.rhs.col = c.rhs.row = 0;
+ ra.col = ra.row = 0;
}
+
+ gnm_solver_constraint_set_old (&c, the_constraint->type,
+ a.col, a.row,
+ ra.col, ra.row,
+ b.col - a.col + 1,
+ b.row - a.row + 1);
/* FIXME: We are dropping cross sheet references!! */
text = gnm_solver_constraint_as_str (&c);
gtk_list_store_set (store, iter, 0, text, 1, the_constraint, -1);
@@ -561,32 +564,27 @@ convert_constraint_format (constraint_conversion_t *conv)
store = gtk_tree_view_get_model (conv->c_listing);
if (gtk_tree_model_get_iter_first (store, &iter))
do {
+ gboolean has_rhs;
+
gtk_tree_model_get (store, &iter, 1, &a_constraint, -1);
if (a_constraint == NULL)
break;
engine_constraint = g_new (SolverConstraint, 1);
- engine_constraint->lhs.col =
- a_constraint->lhs_value->v_range.cell.a.col;
- engine_constraint->lhs.row =
- a_constraint->lhs_value->v_range.cell.a.row;
- engine_constraint->rows =
- a_constraint->lhs_value->v_range.cell.b.row
- - a_constraint->lhs_value->v_range.cell.a.row +1;
- engine_constraint->cols =
- a_constraint->lhs_value->v_range.cell.b.col
- - a_constraint->lhs_value->v_range.cell.a.col +1;
- engine_constraint->type = a_constraint->type;
- if ((a_constraint->type == SolverINT)
- || (a_constraint->type == SolverBOOL)) {
- engine_constraint->rhs.col = 0;
- engine_constraint->rhs.row = 0;
- } else {
- engine_constraint->rhs.col =
- a_constraint->rhs_value->v_range.cell.a.col;
- engine_constraint->rhs.row =
- a_constraint->rhs_value->v_range.cell.a.row;
- }
+
+ has_rhs = (a_constraint->type != SolverINT &&
+ a_constraint->type != SolverBOOL);
+
+ gnm_solver_constraint_set_old
+ (engine_constraint, a_constraint->type,
+ a_constraint->lhs_value->v_range.cell.a.col,
+ a_constraint->lhs_value->v_range.cell.a.row,
+ has_rhs ? a_constraint->rhs_value->v_range.cell.a.col : 0,
+ has_rhs ? a_constraint->rhs_value->v_range.cell.a.row : 0,
+ (a_constraint->lhs_value->v_range.cell.b.col -
+ a_constraint->lhs_value->v_range.cell.a.col + 1),
+ (a_constraint->lhs_value->v_range.cell.b.row -
+ a_constraint->lhs_value->v_range.cell.a.row + 1));
conv->c_list = g_slist_append (conv->c_list, engine_constraint);
} while (gtk_tree_model_iter_next (store, &iter));
}
@@ -608,23 +606,15 @@ revert_constraint_format (constraint_conversion_t * conv)
while (engine_constraint_list != NULL) {
SolverConstraint const *engine_constraint =
engine_constraint_list->data;
- GnmRange r;
constraint_t *a_constraint = g_new (constraint_t, 1);
char *str;
- r.start.col = engine_constraint->lhs.col;
- r.start.row = engine_constraint->lhs.row;
- r.end.col = r.start.col + engine_constraint->cols - 1;
- r.end.row = r.start.row + engine_constraint->rows - 1;
- a_constraint->lhs_value = value_new_cellrange_r (conv->sheet,
- &r);
-
- r.start.col = engine_constraint->rhs.col;
- r.start.row = engine_constraint->rhs.row;
- r.end.col = r.start.col + engine_constraint->cols - 1;
- r.end.row = r.start.row + engine_constraint->rows - 1;
- a_constraint->rhs_value = value_new_cellrange_r (conv->sheet,
- &r);
+ a_constraint->lhs_value =
+ gnm_solver_constraint_get_lhs (engine_constraint,
+ conv->sheet);
+ a_constraint->rhs_value =
+ gnm_solver_constraint_get_rhs (engine_constraint,
+ conv->sheet);
a_constraint->type = engine_constraint->type;
gtk_list_store_append (store, &iter);
diff --git a/src/solver.h b/src/solver.h
index d9d8fa5..b7bc974 100644
--- a/src/solver.h
+++ b/src/solver.h
@@ -66,11 +66,11 @@ typedef enum {
} SolverConstraintType;
typedef struct {
+ SolverConstraintType type; /* <=, =, >=, int, bool */
GnmCellPos lhs; /* left hand side */
GnmCellPos rhs; /* right hand side */
gint rows; /* number of rows */
gint cols; /* number of columns */
- SolverConstraintType type; /* <=, =, >=, int, bool */
} SolverConstraint;
#ifdef GNM_ENABLE_SOLVER
@@ -86,11 +86,16 @@ void gnm_solver_constraint_set_old (SolverConstraint *c,
gboolean gnm_solver_constraint_has_rhs (SolverConstraint const *c);
gboolean gnm_solver_constraint_valid (SolverConstraint const *c);
-gboolean gnm_solver_constraint_get_part (SolverConstraint *c,
+gboolean gnm_solver_constraint_get_part (SolverConstraint const *c,
Sheet *sheet, int i,
GnmCell **lhs, gnm_float *cl,
GnmCell **rhs, gnm_float *cr);
+GnmValue *gnm_solver_constraint_get_lhs (SolverConstraint const *c,
+ Sheet *sheet);
+GnmValue *gnm_solver_constraint_get_rhs (SolverConstraint const *c,
+ Sheet *sheet);
+
char *gnm_solver_constraint_as_str (SolverConstraint const *c);
typedef enum {
diff --git a/src/tools/solver/reports-write.c b/src/tools/solver/reports-write.c
index 620e8c8..136c749 100644
--- a/src/tools/solver/reports-write.c
+++ b/src/tools/solver/reports-write.c
@@ -135,10 +135,16 @@ solver_answer_report (WorkbookControl *wbc,
for (i = 0; i < res->param->n_total_constraints; i++) {
SolverConstraint const *c = res->constraints_array[i];
char *str = gnm_solver_constraint_as_str (c);
+ gnm_float cl, cr;
+ GnmCell *lhs, *rhs;
+
+ gnm_solver_constraint_get_part (c, sheet, 0,
+ &lhs, &cl,
+ &rhs, &cr);
/* Set `Cell' column */
dao_set_cell (&dao, 1, 16 + vars + i,
- cell_coord_name (c->lhs.col, c->lhs.row));
+ cell_name (lhs));
/* Set `Name' column */
dao_set_cell (&dao, 2, 16 + vars + i,
@@ -291,19 +297,24 @@ solver_sensitivity_report (WorkbookControl *wbc,
for (i = 0; i < res->param->n_total_constraints; i++) {
SolverConstraint *c = res->constraints_array[i];
+ gnm_float cl, cr;
+ GnmCell *lhs, *rhs;
+
+ gnm_solver_constraint_get_part (c, sheet, 0,
+ &lhs, &cl,
+ &rhs, &cr);
/* Set `Cell' column */
dao_set_cell (&dao, 1, 12 + vars + i,
- cell_coord_name (c->lhs.col, c->lhs.row));
+ cell_name (lhs));
/* Set `Name' column */
dao_set_cell (&dao, 2, 12 + vars + i,
res->constraint_names [i]);
/* Set `Final Value' column */
- cell = sheet_cell_get (sheet, c->lhs.col, c->lhs.row);
dao_set_cell_value (&dao, 3, 12 + vars + i,
- value_dup (cell->value));
+ value_dup (lhs->value));
/* Set `Shadow Price' */
dao_set_cell_value (&dao, 4, 12 + vars + i,
diff --git a/src/tools/solver/reports.c b/src/tools/solver/reports.c
index a0320e3..6a760b7 100644
--- a/src/tools/solver/reports.c
+++ b/src/tools/solver/reports.c
@@ -70,8 +70,16 @@ get_constraint_names (SolverResults *res, Sheet *sheet)
for (i = 0; i < res->param->n_total_constraints; i++) {
SolverConstraint *c = solver_get_constraint (res, i);
- res->constraint_names[i] = dao_find_name (sheet, c->lhs.col,
- c->lhs.row);
+ GnmCell *lhs, *rhs;
+ gnm_float cl, cr;
+
+ gnm_solver_constraint_get_part (c, sheet, 0,
+ &lhs, &cl, &rhs, &cr);
+
+ res->constraint_names[i] = lhs
+ ? dao_find_name (sheet,
+ lhs->pos.row, lhs->pos.row)
+ : g_strdup ("?");
}
}
@@ -95,18 +103,21 @@ is_still_feasible (Sheet *sheet, SolverResults *res, int col, gnm_float value)
{
gnm_float c_value, rhs, old_value = res->optimal_values [col];
int i, n;
- GnmCell *cell;
gboolean status = FALSE;
res->optimal_values[col] = value;
for (i = 0; i < res->param->n_total_constraints; i++) {
SolverConstraint *c = solver_get_constraint (res, i);
+ GnmCell *cell, *lcell;
+ gnm_float cl, cr;
+
+ gnm_solver_constraint_get_part (c, sheet, 0,
+ &lcell, &cl, &cell, &cr);
c_value = 0;
for (n = 0; n < res->param->n_variables; n++)
c_value += res->constr_coeff[i][n]
* res->optimal_values[n];
- cell = sheet_cell_get (sheet, c->rhs.col, c->rhs.row);
rhs = value_get_as_float (cell->value);
switch (c->type) {
@@ -140,24 +151,27 @@ static void
calculate_limits (Sheet *sheet, SolverParameters *param, SolverResults *res)
{
int i, n;
+ GnmCell *tcell = solver_get_target_cell (sheet);
for (i = 0; i < param->n_total_constraints; i++) {
gnm_float slack, lhs, rhs, x, y, old_val;
SolverConstraint *c = res->constraints_array[i];
- GnmCell *cell;
+ GnmCell *lcell, *rcell;
+ gnm_float cl, cr;
+
+ gnm_solver_constraint_get_part (c, sheet, 0,
+ &lcell, &cl, &rcell, &cr);
+ rhs = value_get_as_float (rcell->value);
+ lhs = value_get_as_float (lcell->value);
- cell = sheet_cell_get (sheet, c->rhs.col, c->rhs.row);
- rhs = value_get_as_float (cell->value);
- cell = sheet_cell_get (sheet, c->lhs.col, c->lhs.row);
- lhs = value_get_as_float (cell->value);
slack = gnm_abs (rhs - lhs);
for (n = 0; n < param->n_variables; n++) {
- x = get_target_cell_value (res, cell, n, 0, &old_val);
+ x = get_target_cell_value (res, lcell, n, 0, &old_val);
x = rhs - x;
if (res->constr_coeff[i][n] != 0) {
x = x / res->constr_coeff[i][n];
if (! is_still_feasible (sheet, res, n, x)) {
- get_target_cell_value (res, cell, n,
+ get_target_cell_value (res, lcell, n,
old_val, &y);
continue;
}
@@ -165,25 +179,23 @@ calculate_limits (Sheet *sheet, SolverParameters *param, SolverResults *res)
&& (x >= 0 ||
!param->options.assume_non_negative)) {
res->limits[n].lower_limit = x;
- cell = solver_get_target_cell (sheet);
- get_target_cell_value (res, cell, n,
+ get_target_cell_value (res, tcell, n,
x, &y);
- gnm_cell_eval (cell);
+ gnm_cell_eval (tcell);
res->limits[n].lower_result =
- value_get_as_float (cell->value);
+ value_get_as_float (tcell->value);
}
if (x > res->limits[n].upper_limit) {
res->limits[n].upper_limit = x;
- cell = solver_get_target_cell (sheet);
- get_target_cell_value (res, cell, n,
+ get_target_cell_value (res, tcell, n,
x, &y);
- gnm_cell_eval (cell);
+ gnm_cell_eval (tcell);
res->limits[n].upper_result =
- value_get_as_float (cell->value);
+ value_get_as_float (tcell->value);
}
} else
; /* FIXME */
- get_target_cell_value (res, cell, n, old_val, &y);
+ get_target_cell_value (res, lcell, n, old_val, &y);
}
}
}
@@ -271,11 +283,16 @@ solver_prepare_reports_success (SolverProgram *program, SolverResults *res,
*/
for (i = 0; i < param->n_constraints; i++) {
SolverConstraint const *c = solver_get_constraint (res, i);
+ gnm_float cl, cr;
+ GnmCell *lhs, *rhs;
+
+ gnm_solver_constraint_get_part (c, sheet, 0,
+ &lhs, &cl,
+ &rhs, &cr);
res->shadow_prizes[i] = alg->get_shadow_prize_fn (program, i);
- cell = sheet_cell_get (sheet, c->lhs.col, c->lhs.row);
- res->lhs[i] = value_get_as_float (cell->value);
+ res->lhs[i] = value_get_as_float (lhs->value);
res->slack[i] = gnm_abs (res->rhs[i] - res->lhs[i]);
}
diff --git a/src/tools/solver/solver.c b/src/tools/solver/solver.c
index 9673b57..86efee0 100644
--- a/src/tools/solver/solver.c
+++ b/src/tools/solver/solver.c
@@ -310,8 +310,25 @@ gnm_solver_constraint_valid (SolverConstraint const *c)
return TRUE;
}
+GnmValue *
+gnm_solver_constraint_get_lhs (SolverConstraint const *c, Sheet *sheet)
+{
+ GnmRange r;
+ range_init_cellpos_size (&r, &c->lhs, c->cols, c->rows);
+ return value_new_cellrange_r (sheet, &r);
+}
+
+GnmValue *
+gnm_solver_constraint_get_rhs (SolverConstraint const *c, Sheet *sheet)
+{
+ GnmRange r;
+ range_init_cellpos_size (&r, &c->rhs, c->cols, c->rows);
+ return value_new_cellrange_r (sheet, &r);
+}
+
+
gboolean
-gnm_solver_constraint_get_part (SolverConstraint *c, Sheet *sheet, int i,
+gnm_solver_constraint_get_part (SolverConstraint const *c, Sheet *sheet, int i,
GnmCell **lhs, gnm_float *cl,
GnmCell **rhs, gnm_float *cr)
{
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]