[gnumeric] nlsolve: take constraints into account.
- From: Morten Welinder <mortenw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnumeric] nlsolve: take constraints into account.
- Date: Tue, 3 Jul 2012 15:22:25 +0000 (UTC)
commit 6eaef9a8ef4b07ed78be56e293251bc9f830b46e
Author: Morten Welinder <terra gnome org>
Date: Tue Jul 3 11:21:54 2012 -0400
nlsolve: take constraints into account.
NEWS | 1 +
plugins/nlsolve/ChangeLog | 5 +++++
plugins/nlsolve/gnm-nlsolve.c | 20 +++++++++++++++-----
3 files changed, 21 insertions(+), 5 deletions(-)
---
diff --git a/NEWS b/NEWS
index bf3bc50..cb5123d 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,7 @@ Gnumeric 1.11.5
Morten:
* Solver translation fixes.
+ * Teach non-linear solver about constraints. [Part of #620368]
--------------------------------------------------------------------------
Gnumeric 1.11.4
diff --git a/plugins/nlsolve/ChangeLog b/plugins/nlsolve/ChangeLog
index eaec5d9..15b376a 100644
--- a/plugins/nlsolve/ChangeLog
+++ b/plugins/nlsolve/ChangeLog
@@ -1,3 +1,8 @@
+2012-07-02 Morten Welinder <terra gnome org>
+
+ * gnm-nlsolve.c (newton_improve, rosenbrock_iter): Check
+ constraints before using an improved solution.
+
2012-06-25 Morten Welinder <terra gnome org>
* Release 1.11.4
diff --git a/plugins/nlsolve/gnm-nlsolve.c b/plugins/nlsolve/gnm-nlsolve.c
index 1e0b8e8..5879bab 100644
--- a/plugins/nlsolve/gnm-nlsolve.c
+++ b/plugins/nlsolve/gnm-nlsolve.c
@@ -13,6 +13,13 @@
#define PRIVATE_KEY "::nlsolve::"
+/*
+ * Note: the solver code assumes the problem is a minimization problem.
+ * When used for a maximization problem, we flip the objective function
+ * sign. This is done in functions get_value and gnm_nlsolve_set_solution.
+ */
+
+
typedef struct {
GnmSolver *parent;
@@ -21,7 +28,7 @@ typedef struct {
GnmCell *target;
GnmCellPos origin;
int input_width, input_height;
- gboolean maximize;
+ gboolean maximize; /* See note above */
/* Initial point. */
gnm_float *x0;
@@ -304,6 +311,7 @@ compute_hessian (GnmNlsolve *nl, const gnm_float *xs, const gnm_float *g0)
static gboolean
newton_improve (GnmNlsolve *nl, gnm_float *xs, gnm_float *y, gnm_float ymax)
{
+ GnmSolver *sol = nl->parent;
const int n = nl->vars->len;
gnm_float *g, **H, *d;
gboolean ok;
@@ -331,7 +339,7 @@ newton_improve (GnmNlsolve *nl, gnm_float *xs, gnm_float *y, gnm_float ymax)
y2);
}
- if (y2 < ymax) {
+ if (y2 < ymax && gnm_solver_check_constraints (sol)) {
best_f = f;
ymax = y2;
break;
@@ -397,6 +405,7 @@ rosenbrock_tentative_end (GnmNlsolve *nl, gboolean accept)
static gboolean
rosenbrock_iter (GnmNlsolve *nl)
{
+ GnmSolver *sol = nl->parent;
const int n = nl->vars->len;
int i, j;
const gnm_float alpha = 3;
@@ -449,7 +458,7 @@ rosenbrock_iter (GnmNlsolve *nl)
while (dones < n) {
/*
* A safety that shouldn't get hit, but might if the function
- * being optimized in non-deterministic.
+ * being optimized is non-deterministic.
*/
if (safety++ > n * GNM_MANT_DIG)
break;
@@ -467,7 +476,7 @@ rosenbrock_iter (GnmNlsolve *nl)
set_vector (nl, x);
y = get_value (nl);
- if (y <= nl->yk) {
+ if (y <= nl->yk && gnm_solver_check_constraints (sol)) {
if (y < nl->yk) {
nl->yk = y;
memcpy (nl->xk, x, n * sizeof (gnm_float));
@@ -597,6 +606,7 @@ rosenbrock_shutdown (GnmNlsolve *nl)
static gboolean
polish_iter (GnmNlsolve *nl)
{
+ GnmSolver *sol = nl->parent;
const int n = nl->vars->len;
gnm_float *x;
gnm_float step;
@@ -620,7 +630,7 @@ polish_iter (GnmNlsolve *nl)
set_vector (nl, x);
y = get_value (nl);
- if (y < nl->yk) {
+ if (y < nl->yk && gnm_solver_check_constraints (sol)) {
nl->yk = y;
memcpy (nl->xk, x, n * sizeof (gnm_float));
any = TRUE;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]