[gnumeric] solver: reduce access directly into SolverConstraint's fields.



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]