[gnumeric] Solver: code cleanup.
- From: Morten Welinder <mortenw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnumeric] Solver: code cleanup.
- Date: Sat, 25 Apr 2015 16:57:59 +0000 (UTC)
commit 43196c099a9a22695476ba07a4df0df9c115b4da
Author: Morten Welinder <terra gnome org>
Date: Sat Apr 25 12:57:33 2015 -0400
Solver: code cleanup.
plugins/glpk/glpk-write.c | 52 ++++++++++++++-----------------
plugins/lpsolve/lpsolve-write.c | 45 +++++++++++++--------------
plugins/nlsolve/gnm-nlsolve.c | 53 ++++++--------------------------
src/gnm-marshalers.list | 2 +-
src/tools/ChangeLog | 5 +++
src/tools/gnm-solver.c | 64 ++++++++++++++++++++++----------------
src/tools/gnm-solver.h | 4 +-
7 files changed, 100 insertions(+), 125 deletions(-)
---
diff --git a/plugins/glpk/glpk-write.c b/plugins/glpk/glpk-write.c
index f3892ae..a9b9a73 100644
--- a/plugins/glpk/glpk-write.c
+++ b/plugins/glpk/glpk-write.c
@@ -85,12 +85,12 @@ glpk_var_name (GnmSubSolver *ssol, GnmCell const *cell)
static gboolean
glpk_affine_func (GString *dst, GnmCell *target, GnmSubSolver *ssol,
gboolean zero_too,
- gnm_float cst, GSList *input_cells, GError **err)
+ gnm_float cst, GPtrArray *input_cells, GError **err)
{
- GSList *l, *ol;
+ unsigned ui;
gboolean any = FALSE;
gnm_float y;
- GSList *old_values = NULL;
+ GPtrArray *old_values;
gboolean ok = TRUE;
if (!target) {
@@ -98,20 +98,19 @@ glpk_affine_func (GString *dst, GnmCell *target, GnmSubSolver *ssol,
return TRUE;
}
- for (l = input_cells; l; l = l->next) {
- GnmCell *cell = l->data;
- old_values = g_slist_prepend (old_values,
- value_dup (cell->value));
+ old_values = g_ptr_array_new ();
+ for (ui = 0; ui < input_cells->len; ui++) {
+ GnmCell *cell = g_ptr_array_index (input_cells, ui);
+ g_ptr_array_add (old_values, value_dup (cell->value));
gnm_cell_set_value (cell, value_new_int (0));
cell_queue_recalc (cell);
}
- old_values = g_slist_reverse (old_values);
gnm_cell_eval (target);
y = cst + value_get_as_float (target->value);
- for (l = input_cells; l; l = l->next) {
- GnmCell *cell = l->data;
+ for (ui = 0; ui < input_cells->len; ui++) {
+ GnmCell *cell = g_ptr_array_index (input_cells, ui);
gnm_float x;
ok = gnm_solver_get_lp_coeff (target, cell, &x, err);
if (!ok)
@@ -150,15 +149,13 @@ glpk_affine_func (GString *dst, GnmCell *target, GnmSubSolver *ssol,
}
fail:
- for (l = input_cells, ol = old_values;
- l;
- l = l->next, ol = ol->next) {
- GnmCell *cell = l->data;
- GnmValue *old = ol->data;
+ for (ui = 0; ui < input_cells->len; ui++) {
+ GnmCell *cell = g_ptr_array_index (input_cells, ui);
+ GnmValue *old = g_ptr_array_index (old_values, ui);
gnm_cell_set_value (cell, old);
cell_queue_recalc (cell);
}
- g_slist_free (old_values);
+ g_ptr_array_free (old_values, TRUE);
return ok;
}
@@ -175,7 +172,7 @@ glpk_create_program (Sheet *sheet, GOIOContext *io_context,
GString *objfunc = g_string_new (NULL);
GSList *l;
GnmCell *target_cell = gnm_solver_param_get_target_cell (sp);
- GSList *input_cells = gnm_solver_param_get_input_cells (sp);
+ GPtrArray *input_cells = gnm_solver_param_get_input_cells (sp);
gsize progress;
/* ---------------------------------------- */
@@ -192,11 +189,10 @@ glpk_create_program (Sheet *sheet, GOIOContext *io_context,
if (ssol) {
unsigned ui;
- GSList *l;
- for (ui = 1, l = input_cells; l; ui++, l = l->next) {
- GnmCell *cell = l->data;
- char *name = g_strdup_printf ("X_%u", ui);
+ for (ui = 0; ui < input_cells->len; ui++) {
+ GnmCell *cell = g_ptr_array_index (input_cells, ui);
+ char *name = g_strdup_printf ("X_%u", ui + 1);
gnm_sub_solver_name_cell (ssol, cell, name);
g_free (name);
}
@@ -235,9 +231,9 @@ glpk_create_program (Sheet *sheet, GOIOContext *io_context,
/* ---------------------------------------- */
if (sp->options.assume_non_negative) {
- GSList *l;
- for (l = input_cells; l; l = l->next) {
- GnmCell *cell = l->data;
+ unsigned ui;
+ for (ui = 0; ui < input_cells->len; ui++) {
+ GnmCell *cell = g_ptr_array_index (input_cells, ui);
g_string_append_printf (constraints, " %s >= 0\n",
glpk_var_name (ssol, cell));
}
@@ -245,9 +241,9 @@ glpk_create_program (Sheet *sheet, GOIOContext *io_context,
}
if (sp->options.assume_discrete) {
- GSList *l;
- for (l = input_cells; l; l = l->next) {
- GnmCell *cell = l->data;
+ unsigned ui;
+ for (ui = 0; ui < input_cells->len; ui++) {
+ GnmCell *cell = g_ptr_array_index (input_cells, ui);
g_string_append_printf (integers, " %s\n",
glpk_var_name (ssol, cell));
}
@@ -343,7 +339,7 @@ fail:
g_string_free (constraints, TRUE);
g_string_free (integers, TRUE);
g_string_free (binaries, TRUE);
- g_slist_free (input_cells);
+ g_ptr_array_free (input_cells, TRUE);
return prg;
}
diff --git a/plugins/lpsolve/lpsolve-write.c b/plugins/lpsolve/lpsolve-write.c
index 863d34c..cb9cee9 100644
--- a/plugins/lpsolve/lpsolve-write.c
+++ b/plugins/lpsolve/lpsolve-write.c
@@ -88,12 +88,12 @@ lpsolve_var_name (GnmSubSolver *ssol, GnmCell const *cell)
static gboolean
lpsolve_affine_func (GString *dst, GnmCell *target, GnmSubSolver *ssol,
- gnm_float cst, GSList *input_cells, GError **err)
+ gnm_float cst, GPtrArray *input_cells, GError **err)
{
- GSList *l, *ol;
+ unsigned ui;
gboolean any = FALSE;
gnm_float y;
- GSList *old_values = NULL;
+ GPtrArray *old_values;
gboolean ok = TRUE;
if (!target) {
@@ -101,20 +101,19 @@ lpsolve_affine_func (GString *dst, GnmCell *target, GnmSubSolver *ssol,
return TRUE;
}
- for (l = input_cells; l; l = l->next) {
- GnmCell *cell = l->data;
- old_values = g_slist_prepend (old_values,
- value_dup (cell->value));
+ old_values = g_ptr_array_new ();
+ for (ui = 0; ui < input_cells->len; ui++) {
+ GnmCell *cell = g_ptr_array_index (input_cells, ui);
+ g_ptr_array_add (old_values, value_dup (cell->value));
gnm_cell_set_value (cell, value_new_int (0));
cell_queue_recalc (cell);
}
- old_values = g_slist_reverse (old_values);
gnm_cell_eval (target);
y = cst + value_get_as_float (target->value);
- for (l = input_cells; l; l = l->next) {
- GnmCell *cell = l->data;
+ for (ui = 0; ui < input_cells->len; ui++) {
+ GnmCell *cell = g_ptr_array_index (input_cells, ui);
gnm_float x;
ok = gnm_solver_get_lp_coeff (target, cell, &x, err);
if (!ok)
@@ -153,15 +152,13 @@ lpsolve_affine_func (GString *dst, GnmCell *target, GnmSubSolver *ssol,
}
fail:
- for (l = input_cells, ol = old_values;
- l;
- l = l->next, ol = ol->next) {
- GnmCell *cell = l->data;
- GnmValue *old = ol->data;
+ for (ui = 0; ui < input_cells->len; ui++) {
+ GnmCell *cell = g_ptr_array_index (input_cells, ui);
+ GnmValue *old = g_ptr_array_index (old_values, ui);
gnm_cell_set_value (cell, old);
cell_queue_recalc (cell);
}
- g_slist_free (old_values);
+ g_ptr_array_free (old_values, TRUE);
return ok;
}
@@ -177,7 +174,7 @@ lpsolve_create_program (Sheet *sheet, GOIOContext *io_context,
GString *objfunc = g_string_new (NULL);
GSList *l;
GnmCell *target_cell = gnm_solver_param_get_target_cell (sp);
- GSList *input_cells = gnm_solver_param_get_input_cells (sp);
+ GPtrArray *input_cells = gnm_solver_param_get_input_cells (sp);
gsize progress;
/* ---------------------------------------- */
@@ -222,9 +219,9 @@ lpsolve_create_program (Sheet *sheet, GOIOContext *io_context,
/* ---------------------------------------- */
if (sp->options.assume_non_negative) {
- GSList *l;
- for (l = input_cells; l; l = l->next) {
- GnmCell *cell = l->data;
+ unsigned ui;
+ for (ui = 0; ui < input_cells->len; ui++) {
+ GnmCell *cell = g_ptr_array_index (input_cells, ui);
g_string_append (constraints,
lpsolve_var_name (ssol, cell));
g_string_append (constraints, " >= 0;\n");
@@ -233,9 +230,9 @@ lpsolve_create_program (Sheet *sheet, GOIOContext *io_context,
}
if (sp->options.assume_discrete) {
- GSList *l;
- for (l = input_cells; l; l = l->next) {
- GnmCell *cell = l->data;
+ unsigned ui;
+ for (ui = 0; ui < input_cells->len; ui++) {
+ GnmCell *cell = g_ptr_array_index (input_cells, ui);
g_string_append (declarations, "int ");
g_string_append (declarations,
lpsolve_var_name (ssol, cell));
@@ -326,7 +323,7 @@ fail:
g_string_free (objfunc, TRUE);
g_string_free (constraints, TRUE);
g_string_free (declarations, TRUE);
- g_slist_free (input_cells);
+ g_ptr_array_free (input_cells, TRUE);
return prg;
}
diff --git a/plugins/nlsolve/gnm-nlsolve.c b/plugins/nlsolve/gnm-nlsolve.c
index ff7401d..046d4f4 100644
--- a/plugins/nlsolve/gnm-nlsolve.c
+++ b/plugins/nlsolve/gnm-nlsolve.c
@@ -7,7 +7,6 @@
#include "regression.h"
#include "rangefunc.h"
#include "workbook.h"
-#include "application.h"
#include <gsf/gsf-impl-utils.h>
#include <glib/gi18n-lib.h>
#include <string.h>
@@ -64,17 +63,19 @@ typedef struct {
/* Parameters: */
gboolean debug;
- guint64 max_iter;
gnm_float min_factor;
} GnmNlsolve;
static void free_matrix (gnm_float **m, int n);
+static void rosenbrock_tentative_end (GnmNlsolve *nl, gboolean accept);
static void
gnm_nlsolve_final (GnmNlsolve *nl)
{
const int n = nl->vars->len;
+ rosenbrock_tentative_end (nl, FALSE);
+
if (nl->vars)
g_ptr_array_free (nl->vars, TRUE);
g_free (nl->xk);
@@ -620,17 +621,6 @@ rosenbrock_iter (GnmNlsolve *nl)
return any_at_all;
}
-static void
-rosenbrock_shutdown (GnmNlsolve *nl)
-{
- const int n = nl->vars->len;
-
- rosenbrock_tentative_end (nl, FALSE);
-
- free_matrix (nl->xi, n);
- nl->xi = NULL;
-}
-
static gboolean
polish_iter (GnmNlsolve *nl)
{
@@ -679,13 +669,11 @@ polish_iter (GnmNlsolve *nl)
return any_at_all;
}
-static void
+static gboolean
gnm_nlsolve_iterate (GnmIterSolver *isol, GnmNlsolve *nl)
{
- GnmSolver *sol = GNM_SOLVER (isol);
const int n = nl->vars->len;
- gboolean ok;
- gboolean call_again = TRUE;
+ gboolean progress;
if (isol->iterations == 0)
rosenbrock_init (nl);
@@ -696,28 +684,13 @@ gnm_nlsolve_iterate (GnmIterSolver *isol, GnmNlsolve *nl)
print_vector ("Current point", nl->xk, n);
}
- ok = rosenbrock_iter (nl);
-
- if (!ok && !nl->tentative) {
- ok = polish_iter (nl);
- }
+ progress = rosenbrock_iter (nl);
- if (!ok) {
- gnm_solver_set_status (sol, GNM_SOLVER_STATUS_DONE);
- call_again = FALSE;
+ if (!progress && !nl->tentative) {
+ progress = polish_iter (nl);
}
- if (call_again && isol->iterations >= nl->max_iter) {
- gnm_solver_set_status (sol, GNM_SOLVER_STATUS_DONE);
- call_again = FALSE;
- }
-
- if (!call_again) {
- set_vector (nl, nl->x0);
- gnm_app_recalc ();
-
- rosenbrock_shutdown (nl);
- }
+ return progress;
}
gboolean
@@ -740,7 +713,6 @@ nlsolve_solver_factory (GnmSolverFactory *factory, GnmSolverParameters *params)
"params", params,
NULL);
GnmNlsolve *nl = g_new0 (GnmNlsolve, 1);
- GSList *input_cells, *l;
int n;
GnmValue const *vinput = gnm_solver_param_get_input (params);
GnmEvalPos ep;
@@ -760,16 +732,11 @@ nlsolve_solver_factory (GnmSolverFactory *factory, GnmSolverParameters *params)
}
nl->debug = gnm_solver_debug ();
- nl->max_iter = params->options.max_iter;
nl->min_factor = 1e-10;
nl->target = gnm_solver_param_get_target_cell (params);
- nl->vars = g_ptr_array_new ();
- input_cells = gnm_solver_param_get_input_cells (params);
- for (l = input_cells; l; l = l->next)
- g_ptr_array_add (nl->vars, l->data);
- g_slist_free (input_cells);
+ nl->vars = gnm_solver_param_get_input_cells (params);
n = nl->vars->len;
nl->x0 = g_new (gnm_float, n);
diff --git a/src/gnm-marshalers.list b/src/gnm-marshalers.list
index 8961862..7b01393 100644
--- a/src/gnm-marshalers.list
+++ b/src/gnm-marshalers.list
@@ -23,4 +23,4 @@
BOOLEAN:POINTER
BOOLEAN:OBJECT,POINTER
VOID:BOOLEAN,INT
-VOID:VOID
+BOOLEAN:VOID
diff --git a/src/tools/ChangeLog b/src/tools/ChangeLog
index 385d9ad..c10f211 100644
--- a/src/tools/ChangeLog
+++ b/src/tools/ChangeLog
@@ -1,3 +1,8 @@
+2015-04-25 Morten Welinder <terra gnome org>
+
+ * gnm-solver.c (gnm_solver_param_get_input_cells): Return result
+ as a GPtrArray for random access. All callers changed.
+
2015-04-24 Morten Welinder <terra gnome org>
* gnm-solver.c (gnm_solver_get_current_values): Delete unused
diff --git a/src/tools/gnm-solver.c b/src/tools/gnm-solver.c
index d0279f1..6c9abce 100644
--- a/src/tools/gnm-solver.c
+++ b/src/tools/gnm-solver.c
@@ -10,6 +10,7 @@
#include "gnm-solver.h"
#include "workbook-view.h"
#include "workbook-control.h"
+#include "application.h"
#include "gnm-marshalers.h"
#include "dao.h"
#include "gui-util.h"
@@ -507,31 +508,31 @@ gnm_solver_param_set_input (GnmSolverParameters *sp, GnmValue *v)
static GnmValue *
cb_grab_cells (GnmCellIter const *iter, gpointer user)
{
- GSList **the_list = user;
+ GPtrArray *input_cells = user;
GnmCell *cell;
if (NULL == (cell = iter->cell))
cell = sheet_cell_create (iter->pp.sheet,
iter->pp.eval.col, iter->pp.eval.row);
- *the_list = g_slist_prepend (*the_list, cell);
+ g_ptr_array_add (input_cells, cell);
return NULL;
}
-GSList *
+GPtrArray *
gnm_solver_param_get_input_cells (GnmSolverParameters const *sp)
{
GnmValue const *vr = gnm_solver_param_get_input (sp);
- GSList *input_cells = NULL;
- GnmEvalPos ep;
+ GPtrArray *input_cells = g_ptr_array_new ();
- if (!vr)
- return NULL;
+ if (vr) {
+ GnmEvalPos ep;
+ eval_pos_init_sheet (&ep, sp->sheet);
+ workbook_foreach_cell_in_range (&ep, vr, CELL_ITER_ALL,
+ cb_grab_cells,
+ input_cells);
+ }
- eval_pos_init_sheet (&ep, sp->sheet);
- workbook_foreach_cell_in_range (&ep, vr, CELL_ITER_ALL,
- cb_grab_cells,
- &input_cells);
- return g_slist_reverse (input_cells);
+ return input_cells;
}
void
@@ -584,7 +585,8 @@ gnm_solver_param_valid (GnmSolverParameters const *sp, GError **err)
GSList *l;
int i;
GnmCell *target_cell;
- GSList *input_cells;
+ GPtrArray *input_cells;
+ unsigned ui;
target_cell = gnm_solver_param_get_target_cell (sp);
if (!target_cell) {
@@ -617,8 +619,8 @@ gnm_solver_param_valid (GnmSolverParameters const *sp, GError **err)
return FALSE;
}
input_cells = gnm_solver_param_get_input_cells (sp);
- for (l = input_cells; l; l = l->next) {
- GnmCell *cell = l->data;
+ for (ui = 0; ui < input_cells->len; ui++) {
+ GnmCell *cell = g_ptr_array_index (input_cells, ui);
if (gnm_cell_has_expr (cell)) {
char *cname = gnm_solver_cell_name (cell, sp->sheet);
g_set_error (err,
@@ -627,11 +629,11 @@ gnm_solver_param_valid (GnmSolverParameters const *sp, GError **err)
_("Input cell %s contains a formula"),
cname);
g_free (cname);
- g_slist_free (input_cells);
+ g_ptr_array_free (input_cells, TRUE);
return FALSE;
}
}
- g_slist_free (input_cells);
+ g_ptr_array_free (input_cells, TRUE);
for (i = 1, l = sp->constraints; l; i++, l = l->next) {
GnmSolverConstraint *c = l->data;
@@ -1136,12 +1138,12 @@ gnm_solver_check_constraints (GnmSolver *solver)
if (sp->options.assume_non_negative ||
sp->options.assume_discrete) {
- GSList *input_cells = gnm_solver_param_get_input_cells (sp);
- GSList *l;
+ GPtrArray *input_cells = gnm_solver_param_get_input_cells (sp);
+ unsigned ui;
gboolean bad;
- for (l = input_cells; l; l = l->next) {
- GnmCell *cell = l->data;
+ for (ui = 0; ui < input_cells->len; ui++) {
+ GnmCell *cell = g_ptr_array_index (input_cells, ui);
gnm_float val;
gnm_cell_eval (cell);
@@ -1152,8 +1154,8 @@ gnm_solver_check_constraints (GnmSolver *solver)
val != gnm_floor (val))
break;
}
- bad = (l != NULL);
- g_slist_free (input_cells);
+ bad = (ui < input_cells->len);
+ g_ptr_array_free (input_cells, TRUE);
if (bad)
return FALSE;
@@ -2169,13 +2171,21 @@ gnm_iter_solver_idle (gpointer data)
{
GnmIterSolver *isol = data;
GnmSolver *sol = &isol->parent;
+ GnmSolverParameters *params = sol->params;
+ gboolean progress;
- g_signal_emit (isol, iter_solver_signals[ITER_SOL_SIG_ITERATE], 0);
-
+ g_signal_emit (isol, iter_solver_signals[ITER_SOL_SIG_ITERATE], 0, &progress);
isol->iterations++;
+ if (!gnm_solver_finished (sol) &&
+ (!progress || isol->iterations >= params->options.max_iter))
+ gnm_solver_set_status (sol, GNM_SOLVER_STATUS_DONE);
+
if (gnm_solver_finished (sol)) {
isol->idle_tag = 0;
+
+ gnm_app_recalc ();
+
return FALSE;
} else {
/* Call again. */
@@ -2227,8 +2237,8 @@ gnm_iter_solver_class_init (GObjectClass *object_class)
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GnmIterSolverClass, iterate),
NULL, NULL,
- gnm__VOID__VOID,
- G_TYPE_NONE, 0);
+ gnm__BOOLEAN__VOID,
+ G_TYPE_BOOLEAN, 0);
}
GSF_CLASS (GnmIterSolver, gnm_iter_solver,
diff --git a/src/tools/gnm-solver.h b/src/tools/gnm-solver.h
index ca9a9b2..5711837 100644
--- a/src/tools/gnm-solver.h
+++ b/src/tools/gnm-solver.h
@@ -103,7 +103,7 @@ char *gnm_solver_constraint_as_str (GnmSolverConstraint const *c, Sheet *sheet);
typedef struct {
int max_time_sec;
- int max_iter;
+ unsigned max_iter;
GnmSolverFactory *algorithm;
GnmSolverModelType model_type;
gboolean assume_non_negative;
@@ -149,7 +149,7 @@ gboolean gnm_solver_param_equal (GnmSolverParameters const *a,
GnmValue const *gnm_solver_param_get_input (GnmSolverParameters const *sp);
void gnm_solver_param_set_input (GnmSolverParameters *sp, GnmValue *v);
-GSList *gnm_solver_param_get_input_cells (GnmSolverParameters const *sp);
+GPtrArray *gnm_solver_param_get_input_cells (GnmSolverParameters const *sp);
const GnmCellRef *gnm_solver_param_get_target (GnmSolverParameters const *sp);
void gnm_solver_param_set_target (GnmSolverParameters *sp,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]