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



commit 47b450a6041fd7f8a2d1d2b4a736ae7eea8d172c
Author: Morten Welinder <terra gnome org>
Date:   Fri Oct 30 09:02:13 2009 -0400

    solver: reduce access directly into SolverConstraint's fields.

 plugins/lpsolve/lpsolve-write.c |   70 +++++++++++--------------
 plugins/mps/mps.c               |   13 ++---
 src/solver.h                    |   17 ++++++-
 src/tools/solver/solver.c       |  112 ++++++++++++++++++++++++++++++++++++---
 4 files changed, 156 insertions(+), 56 deletions(-)
---
diff --git a/plugins/lpsolve/lpsolve-write.c b/plugins/lpsolve/lpsolve-write.c
index f925ba2..a0d6cb9 100644
--- a/plugins/lpsolve/lpsolve-write.c
+++ b/plugins/lpsolve/lpsolve-write.c
@@ -230,8 +230,10 @@ lpsolve_create_program (Sheet *sheet, GError **err)
 		SolverConstraint *c = l->data;
 		const char *op = NULL;
 		const char *type = NULL;
-		int dx, dy;
 		gboolean right_small = TRUE;
+		int i;
+		gnm_float cl, cr;
+		GnmCell *lhs, *rhs;
 
 		switch (c->type) {
 		case SolverLE:
@@ -254,44 +256,34 @@ lpsolve_create_program (Sheet *sheet, GError **err)
 			g_assert_not_reached ();
 		}
 
-		for (dy = 0; dy < c->rows; dy++) {
-			for (dx = 0; dx < c->cols; dx++) {
-				GnmCell *lhs =
-					sheet_cell_get (sheet,
-							c->lhs.col + dx,
-							c->lhs.row + dy);
-				GnmCell *rhs =
-					sheet_cell_get (sheet,
-							c->rhs.col + dx,
-							c->rhs.row + dy);
-
-				if (!lhs || (op && !rhs))
-					continue;
-
-				if (type) {
-					g_string_append (declarations, type);
-					g_string_append_c (declarations, ' ');
-					g_string_append (declarations, lpsolve_var_name (lhs));
-					g_string_append (declarations, ";\n");
-				} else {
-					gboolean ok;
-
-					ok = lpsolve_affine_func
-						(constraints, lhs, sp->input_cells, err);
-					if (!ok)
-						goto fail;
-
-					g_string_append_c (constraints, ' ');
-					g_string_append (constraints, op);
-					g_string_append_c (constraints, ' ');
-
-					ok = lpsolve_affine_func
-						(constraints, rhs, sp->input_cells, err);
-					if (!ok)
-						goto fail;
-
-					g_string_append (constraints, ";\n");
-				}
+		for (i = 0;
+		     gnm_solver_constraint_get_part (c, sheet, i,
+						     &lhs, &cl,
+						     &rhs, &cr);
+		     i++) {
+			if (type) {
+				g_string_append (declarations, type);
+				g_string_append_c (declarations, ' ');
+				g_string_append (declarations, lpsolve_var_name (lhs));
+				g_string_append (declarations, ";\n");
+			} else {
+				gboolean ok;
+
+				ok = lpsolve_affine_func
+					(constraints, lhs, sp->input_cells, err);
+				if (!ok)
+					goto fail;
+
+				g_string_append_c (constraints, ' ');
+				g_string_append (constraints, op);
+				g_string_append_c (constraints, ' ');
+
+				ok = lpsolve_affine_func
+					(constraints, rhs, sp->input_cells, err);
+				if (!ok)
+					goto fail;
+
+				g_string_append (constraints, ";\n");
 			}
 		}
 	}
diff --git a/plugins/mps/mps.c b/plugins/mps/mps.c
index 8b7864c..2564136 100644
--- a/plugins/mps/mps.c
+++ b/plugins/mps/mps.c
@@ -397,14 +397,11 @@ mps_write_coefficients (MpsInputContext *ctxt, Sheet *sh,
 		  cell_queue_recalc (cell);
 
 		  /* Add Solver constraint */
-		  c          = g_new (SolverConstraint, 1);
-		  c->lhs.col = ecol + 1;
-		  c->lhs.row = r;
-		  c->rhs.col = ecol + 3;
-		  c->rhs.row = r;
-		  c->type    = type_map[row->type];  /* const_cast */
-		  c->cols    = 1;
-		  c->rows    = 1;
+		  c = g_new0 (SolverConstraint, 1);
+		  gnm_solver_constraint_set_old (c, type_map[row->type],
+						 ecol + 1, r,
+						 ecol + 3, r,
+						 1, 1);
 
 		  param->constraints = g_slist_append (param->constraints, c);
 		  i++;
diff --git a/src/solver.h b/src/solver.h
index 795ef23..d9d8fa5 100644
--- a/src/solver.h
+++ b/src/solver.h
@@ -75,8 +75,23 @@ typedef struct {
 
 #ifdef GNM_ENABLE_SOLVER
 
-char *gnm_solver_constraint_as_str (SolverConstraint const *c);
 void gnm_solver_constraint_free (SolverConstraint *c);
+SolverConstraint *gnm_solver_constraint_dup (SolverConstraint *c);
+
+void gnm_solver_constraint_set_old (SolverConstraint *c,
+				    SolverConstraintType type,
+				    int lhs_col, int lhs_row,
+				    int rhs_col, int rhs_row,
+				    int cols, int rows);
+
+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,
+					 Sheet *sheet, int i,
+					 GnmCell **lhs, gnm_float *cl,
+					 GnmCell **rhs, gnm_float *cr);
+
+char *gnm_solver_constraint_as_str (SolverConstraint const *c);
 
 typedef enum {
 	SolverRunning, SolverOptimal, SolverUnbounded, SolverInfeasible,
diff --git a/src/tools/solver/solver.c b/src/tools/solver/solver.c
index 81e517a..9673b57 100644
--- a/src/tools/solver/solver.c
+++ b/src/tools/solver/solver.c
@@ -91,22 +91,26 @@ solver_param_destroy (SolverParameters *sp)
 static void
 solver_constr_start (GsfXMLIn *xin, xmlChar const **attrs)
 {
-	int type;
+	int type = 0;
 	SolverConstraint *c;
 	int i;
 	Sheet *sheet = gnm_xml_in_cur_sheet (xin);
 	SolverParameters *sp = sheet->solver_parameters;
+	int lhs_col = 0, lhs_row = 0, rhs_col = 0, rhs_row = 0;
+	int cols = 1, rows = 1;
+	gboolean old = FALSE;
 
 	c = g_new0 (SolverConstraint, 1);
 
 	for (i = 0; attrs != NULL && attrs[i] && attrs[i + 1] ; i += 2) {
-		if (gnm_xml_attr_int (attrs+i, "Lcol", &c->lhs.col) ||
-		    gnm_xml_attr_int (attrs+i, "Lrow", &c->lhs.row) ||
-		    gnm_xml_attr_int (attrs+i, "Rcol", &c->rhs.col) ||
-		    gnm_xml_attr_int (attrs+i, "Rrow", &c->rhs.row) ||
-		    gnm_xml_attr_int (attrs+i, "Cols", &c->cols) ||
-		    gnm_xml_attr_int (attrs+i, "Rows", &c->rows) ||
-		    gnm_xml_attr_int (attrs+i, "Type", &type))
+		if (gnm_xml_attr_int (attrs+i, "Lcol", &lhs_col) ||
+		    gnm_xml_attr_int (attrs+i, "Lrow", &lhs_row) ||
+		    gnm_xml_attr_int (attrs+i, "Rcol", &rhs_col) ||
+		    gnm_xml_attr_int (attrs+i, "Rrow", &rhs_row) ||
+		    gnm_xml_attr_int (attrs+i, "Cols", &cols) ||
+		    gnm_xml_attr_int (attrs+i, "Rows", &rows))
+			old = TRUE;
+		else if (gnm_xml_attr_int (attrs+i, "Type", &type))
 			; /* Nothing */
 	}
 
@@ -119,6 +123,12 @@ solver_constr_start (GsfXMLIn *xin, xmlChar const **attrs)
 	default: c->type = SolverLE; break;
 	}
 
+	if (old)
+		gnm_solver_constraint_set_old (c, c->type,
+					       lhs_col, lhs_row,
+					       rhs_col, rhs_row,
+					       cols, rows);
+
 	sp->constraints = g_slist_append (sp->constraints, c);
 }
 
@@ -266,6 +276,92 @@ gnm_solver_constraint_free (SolverConstraint *c)
 	g_free (c);
 }
 
+SolverConstraint *
+gnm_solver_constraint_dup (SolverConstraint *c)
+{
+	SolverConstraint *res = g_new (SolverConstraint, 1);
+	*res = *c;
+	return res;
+}
+
+
+gboolean
+gnm_solver_constraint_has_rhs (SolverConstraint const *c)
+{
+	g_return_val_if_fail (c != NULL, FALSE);
+
+	switch (c->type) {
+	case SolverLE:
+	case SolverGE:
+	case SolverEQ:
+		return TRUE;
+	case SolverINT:
+	case SolverBOOL:
+	default:
+		return FALSE;
+	}
+}
+
+gboolean
+gnm_solver_constraint_valid (SolverConstraint const *c)
+{
+	g_return_val_if_fail (c != NULL, FALSE);
+
+	return TRUE;
+}
+
+gboolean
+gnm_solver_constraint_get_part (SolverConstraint *c, Sheet *sheet, int i,
+				GnmCell **lhs, gnm_float *cl,
+				GnmCell **rhs, gnm_float *cr)
+{
+	GnmRange r;
+	int h, w, dx, dy;
+
+	range_init_cellpos (&r, &c->lhs);
+	w = c->cols;
+	h = c->rows;
+
+	dy = i / w;
+	dx = i % w;
+	if (dy >= h)
+		return FALSE;
+
+	*lhs = sheet_cell_get (sheet, r.start.col + dx, r.start.row + dy);
+	*cl = 0;
+
+	if (!gnm_solver_constraint_has_rhs (c)) {
+		*rhs = NULL;
+		*cr = 0;
+	} else if (0) {
+		*rhs = NULL;
+		*cr = 0;
+	} else {
+		range_init_cellpos (&r, &c->rhs);
+		*rhs = sheet_cell_get (sheet,
+				       r.start.col + dx, r.start.row + dy);
+		*cl = 0;
+	}
+
+	return TRUE;
+}
+
+void
+gnm_solver_constraint_set_old (SolverConstraint *c,
+			       SolverConstraintType type,
+			       int lhs_col, int lhs_row,
+			       int rhs_col, int rhs_row,
+			       int cols, int rows)
+{
+	c->type = type;
+	c->lhs.col = lhs_col;
+	c->lhs.row = lhs_row;
+	c->rhs.col = rhs_col;
+	c->rhs.row = rhs_row;
+	c->cols = cols;
+	c->rows = rows;
+}
+
 /* ------------------------------------------------------------------------- */
 
 static SolverConstraint*



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