[gnumeric] Solver: create gradient decent iterator.
- From: Morten Welinder <mortenw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnumeric] Solver: create gradient decent iterator.
- Date: Mon, 11 May 2015 12:12:30 +0000 (UTC)
commit f51f6b4a54376efff7339c9514261898f5864f0b
Author: Morten Welinder <terra gnome org>
Date: Mon May 11 08:12:06 2015 -0400
Solver: create gradient decent iterator.
src/tools/gnm-solver.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++-
src/tools/gnm-solver.h | 1 +
2 files changed, 47 insertions(+), 1 deletions(-)
---
diff --git a/src/tools/gnm-solver.c b/src/tools/gnm-solver.c
index 1311ac9..ba0dfca 100644
--- a/src/tools/gnm-solver.c
+++ b/src/tools/gnm-solver.c
@@ -2651,7 +2651,7 @@ cb_polish_iter (GnmSolverIterator *iter, GnmIterSolver *isol)
s0, sm, 0.0, &y);
dir[c] = 0;
- if (gnm_finite (s)) {
+ if (gnm_finite (s) && s != 0) {
isol->xk[c] += s;
isol->yk = y;
progress = TRUE;
@@ -2679,6 +2679,51 @@ gnm_solver_iterator_new_polish (GnmIterSolver *isol)
}
+static gboolean
+cb_gradient_iter (GnmSolverIterator *iter, GnmIterSolver *isol)
+{
+ GnmSolver *sol = GNM_SOLVER (isol);
+ const int n = sol->input_cells->len;
+ gboolean progress = FALSE;
+ gnm_float s, y;
+ gnm_float *g;
+ int i;
+
+ /* Search in opposite direction of gradient. */
+ g = gnm_solver_compute_gradient (sol, isol->xk);
+ for (i = 0; i < n; i++)
+ g[i] = -g[i];
+
+ s = gnm_solver_line_search (sol, isol->xk, g, FALSE,
+ 1, gnm_pinf, 0.0, &y);
+ if (s > 0) {
+ for (i = 0; i < n; i++)
+ isol->xk[i] += s * g[i];
+ isol->yk = y;
+ progress = TRUE;
+ }
+
+ g_free (g);
+
+ if (progress)
+ gnm_iter_solver_set_solution (isol);
+
+ return progress;
+}
+
+/**
+ * gnm_solver_iterator_new_gradient:
+ * @isol: the solver to operate on
+ *
+ * Returns: (transfer full): an iterator object that can be used to perform
+ * a gradient decent step.
+ */
+GnmSolverIterator *
+gnm_solver_iterator_new_gradient (GnmIterSolver *isol)
+{
+ return gnm_solver_iterator_new_func (G_CALLBACK (cb_gradient_iter), isol);
+}
+
GSF_CLASS (GnmSolverIterator, gnm_solver_iterator,
gnm_solver_iterator_class_init, NULL, G_TYPE_OBJECT)
diff --git a/src/tools/gnm-solver.h b/src/tools/gnm-solver.h
index 1f584d5..26345db 100644
--- a/src/tools/gnm-solver.h
+++ b/src/tools/gnm-solver.h
@@ -360,6 +360,7 @@ GType gnm_solver_iterator_get_type (void);
GnmSolverIterator *gnm_solver_iterator_new_func (GCallback iterate, gpointer user);
GnmSolverIterator *gnm_solver_iterator_new_polish (GnmIterSolver *isol);
+GnmSolverIterator *gnm_solver_iterator_new_gradient (GnmIterSolver *isol);
gboolean gnm_solver_iterator_iterate (GnmSolverIterator *iter);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]