[gnumeric] Solver: return Hessian as a GnmMatrix.
- From: Morten Welinder <mortenw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnumeric] Solver: return Hessian as a GnmMatrix.
- Date: Sun, 2 Oct 2016 20:03:56 +0000 (UTC)
commit 1c54df66562719fb9623234e7302586dd3000b10
Author: Morten Welinder <terra gnome org>
Date: Sun Oct 2 16:03:31 2016 -0400
Solver: return Hessian as a GnmMatrix.
src/tools/gnm-solver.c | 35 ++++++++++++++++++++++-------------
src/tools/gnm-solver.h | 2 +-
2 files changed, 23 insertions(+), 14 deletions(-)
---
diff --git a/src/tools/gnm-solver.c b/src/tools/gnm-solver.c
index c162b88..8303be4 100644
--- a/src/tools/gnm-solver.c
+++ b/src/tools/gnm-solver.c
@@ -9,6 +9,7 @@
#include "rangefunc.h"
#include "ranges.h"
#include "gutils.h"
+#include "mathfunc.h"
#include "gnm-solver.h"
#include "workbook-view.h"
#include "workbook-control.h"
@@ -2143,29 +2144,37 @@ gnm_solver_has_analytic_hessian (GnmSolver *sol)
* will be n+(n-1)+...+2+1 elements long containing the triangular
* Hessian. Use symmetry to obtain the full Hessian.
*/
-gnm_float *
+GnmMatrix *
gnm_solver_compute_hessian (GnmSolver *sol, gnm_float const *xs)
{
- int i, hlen;
- gnm_float *H;
+ int i, j, k;
+ GnmMatrix *H;
GnmEvalPos ep;
+ int const n = sol->input_cells->len;
if (!gnm_solver_has_analytic_hessian (sol))
return NULL;
gnm_solver_set_vars (sol, xs);
- hlen = sol->hessian->len;
- H = g_new (gnm_float, hlen);
+ H = gnm_matrix_new (n, n);
eval_pos_init_cell (&ep, sol->target);
- for (i = 0; i < hlen; i++) {
- GnmExprTop const *te = g_ptr_array_index (sol->hessian, i);
- GnmValue *v = gnm_expr_top_eval
- (te, &ep, GNM_EXPR_EVAL_SCALAR_NON_EMPTY);
- H[i] = VALUE_IS_NUMBER (v) ? value_get_as_float (v) : gnm_nan;
- if (sol->flip_sign)
- H[i] = 0 - H[i];
- value_release (v);
+ for (i = k = 0; i < n; i++) {
+ for (j = i; j < n; j++, k++) {
+ GnmExprTop const *te =
+ g_ptr_array_index (sol->hessian, k);
+ GnmValue *v = gnm_expr_top_eval
+ (te, &ep, GNM_EXPR_EVAL_SCALAR_NON_EMPTY);
+ gnm_float x = VALUE_IS_NUMBER (v)
+ ? value_get_as_float (v)
+ : gnm_nan;
+ if (sol->flip_sign)
+ x = 0 - x;
+ value_release (v);
+
+ H->data[i][j] = x;
+ H->data[j][i] = x;
+ }
}
return H;
diff --git a/src/tools/gnm-solver.h b/src/tools/gnm-solver.h
index 63eea58..7f33146 100644
--- a/src/tools/gnm-solver.h
+++ b/src/tools/gnm-solver.h
@@ -309,7 +309,7 @@ gboolean gnm_solver_has_analytic_gradient (GnmSolver *sol);
gnm_float *gnm_solver_compute_gradient (GnmSolver *sol, gnm_float const *xs);
gboolean gnm_solver_has_analytic_hessian (GnmSolver *sol);
-gnm_float *gnm_solver_compute_hessian (GnmSolver *sol, gnm_float const *xs);
+GnmMatrix *gnm_solver_compute_hessian (GnmSolver *sol, gnm_float const *xs);
gnm_float gnm_solver_line_search (GnmSolver *sol,
gnm_float const *x0, gnm_float const *dir,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]