[gnumeric] GnmMatrix: add introspection



commit 137b0847f91b7890670734b076f23472aa4eae6d
Author: Morten Welinder <terra gnome org>
Date:   Thu May 17 22:15:14 2018 -0400

    GnmMatrix: add introspection

 plugins/fn-math/functions.c   |   26 ++++++------
 plugins/fn-stat/functions.c   |    2 +-
 plugins/nlsolve/gnm-nlsolve.c |    2 +-
 src/mathfunc.c                |   86 ++++++++++++++++++++++++++++++++++++----
 src/mathfunc.h                |    6 ++-
 src/tools/gnm-solver.c        |    8 +--
 6 files changed, 100 insertions(+), 30 deletions(-)
---
diff --git a/plugins/fn-math/functions.c b/plugins/fn-math/functions.c
index dc4c070..e880689 100644
--- a/plugins/fn-math/functions.c
+++ b/plugins/fn-math/functions.c
@@ -2859,7 +2859,7 @@ gnumeric_minverse (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
                res = value_new_error_NUM (ei->pos);
 
 out:
-       if (A) gnm_matrix_free (A);
+       if (A) gnm_matrix_unref (A);
        return res;
 }
 
@@ -2895,8 +2895,8 @@ gnumeric_mpseudoinverse (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
        res = gnm_matrix_to_value (B);
 
 out:
-       if (A) gnm_matrix_free (A);
-       if (B) gnm_matrix_free (B);
+       if (A) gnm_matrix_unref (A);
+       if (B) gnm_matrix_unref (B);
        return res;
 }
 
@@ -2973,8 +2973,8 @@ gnumeric_cholesky (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
                res = value_new_error_NUM (ei->pos);
 
 out:
-       if (A) gnm_matrix_free (A);
-       if (B) gnm_matrix_free (B);
+       if (A) gnm_matrix_unref (A);
+       if (B) gnm_matrix_unref (B);
        return res;
 }
 
@@ -3053,9 +3053,9 @@ gnumeric_mmult (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
        res = gnm_matrix_to_value (C);
 
 out:
-       if (A) gnm_matrix_free (A);
-       if (B) gnm_matrix_free (B);
-       if (C) gnm_matrix_free (C);
+       if (A) gnm_matrix_unref (A);
+       if (B) gnm_matrix_unref (B);
+       if (C) gnm_matrix_unref (C);
        return res;
 }
 
@@ -3110,8 +3110,8 @@ gnumeric_linsolve (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
        }
 
 out:
-       if (A) gnm_matrix_free (A);
-       if (B) gnm_matrix_free (B);
+       if (A) gnm_matrix_unref (A);
+       if (B) gnm_matrix_unref (B);
        return res;
 }
 
@@ -3143,7 +3143,7 @@ gnumeric_mdeterm (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
        res = value_new_float (gnm_matrix_determinant (A->data, A->rows));
 
 out:
-       if (A) gnm_matrix_free (A);
+       if (A) gnm_matrix_unref (A);
        return res;
 }
 
@@ -3402,8 +3402,8 @@ gnumeric_eigen (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
        g_free (ev_sort);
 
 out:
-       if (A) gnm_matrix_free (A);
-       if (EIG) gnm_matrix_free (EIG);
+       if (A) gnm_matrix_unref (A);
+       if (EIG) gnm_matrix_unref (EIG);
        g_free (eigenvalues);
        return res;
 }
diff --git a/plugins/fn-stat/functions.c b/plugins/fn-stat/functions.c
index 24d48c5..59ce410 100644
--- a/plugins/fn-stat/functions.c
+++ b/plugins/fn-stat/functions.c
@@ -3559,7 +3559,7 @@ gnumeric_leverage (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
        g_free (x);
 
 out:
-       if (A) gnm_matrix_free (A);
+       if (A) gnm_matrix_unref (A);
        return res;
 }
 
diff --git a/plugins/nlsolve/gnm-nlsolve.c b/plugins/nlsolve/gnm-nlsolve.c
index 1eaf612..396f120 100644
--- a/plugins/nlsolve/gnm-nlsolve.c
+++ b/plugins/nlsolve/gnm-nlsolve.c
@@ -261,7 +261,7 @@ newton_improve (GnmNlsolve *nl, gnm_float *xs)
 
        g_free (d);
        g_free (g);
-       gnm_matrix_free (H);
+       gnm_matrix_unref (H);
        g_free (xs2);
 
        return ok;
diff --git a/src/mathfunc.c b/src/mathfunc.c
index 76a915e..75f5a5e 100644
--- a/src/mathfunc.c
+++ b/src/mathfunc.c
@@ -5082,9 +5082,25 @@ pow1pm1 (gnm_float x, gnm_float y)
  ---------------------------------------------------------------------
  */
 
+GType
+gnm_matrix_get_type (void)
+{
+       static GType t = 0;
+
+       if (t == 0)
+               t = g_boxed_type_register_static ("GnmMatrix",
+                        (GBoxedCopyFunc)gnm_matrix_ref,
+                        (GBoxedFreeFunc)gnm_matrix_unref);
+       return t;
+}
+
 /**
- * gnm_matrix_new: (skip)
- **/
+ * gnm_matrix_new:
+ * @rows: Number of rows.
+ * @cols: Number of columns.
+ *
+ * Returns: (transfer full): A new #GnmMatrix.
+ */
 /* Note the order: y then x. */
 GnmMatrix *
 gnm_matrix_new (int rows, int cols)
@@ -5092,6 +5108,7 @@ gnm_matrix_new (int rows, int cols)
        GnmMatrix *m = g_new (GnmMatrix, 1);
        int r;
 
+       m->ref_count = 1;
        m->rows = rows;
        m->cols = cols;
        m->data = g_new (gnm_float *, rows);
@@ -5101,17 +5118,44 @@ gnm_matrix_new (int rows, int cols)
        return m;
 }
 
+/**
+ * gnm_matrix_ref:
+ * @m: (transfer none) (nullable): #GnmMatrix
+ *
+ * Returns: (transfer full) (nullable): a new reference to @m.
+ */
+GnmMatrix *
+gnm_matrix_ref (GnmMatrix *m)
+{
+       if (m)
+               m->ref_count++;
+       return m;
+}
+
+/**
+ * gnm_matrix_unref:
+ * @m: (transfer full) (nullable): #GnmMatrix
+ */
 void
-gnm_matrix_free (GnmMatrix *m)
+gnm_matrix_unref (GnmMatrix *m)
 {
        int r;
 
+       if (!m || m->ref_count-- > 1)
+               return;
+
        for (r = 0; r < m->rows; r++)
                g_free (m->data[r]);
        g_free (m->data);
        g_free (m);
 }
 
+/**
+ * gnm_matrix_is_empty:
+ * @m: (nullable): A #GnmMatrix
+ *
+ * Returns: %TRUE if @m is empty.
+ */
 gboolean
 gnm_matrix_is_empty (GnmMatrix const *m)
 {
@@ -5119,8 +5163,13 @@ gnm_matrix_is_empty (GnmMatrix const *m)
 }
 
 /**
- * gnm_matrix_from_value: (skip)
- **/
+ * gnm_matrix_from_value:
+ * @v: #GnmValue
+ * @perr: (out) (transfer full): #GnmValue with error value
+ * @ep: Evaluation location
+ *
+ * Returns: (transfer full) (nullable): A new #GnmMatrix, %NULL on error.
+ */
 GnmMatrix *
 gnm_matrix_from_value (GnmValue const *v, GnmValue **perr, GnmEvalPos const *ep)
 {
@@ -5137,7 +5186,7 @@ gnm_matrix_from_value (GnmValue const *v, GnmValue **perr, GnmEvalPos const *ep)
                        GnmValue const *v1 = value_area_fetch_x_y (v, c, r, ep);
                        if (VALUE_IS_ERROR (v1)) {
                                *perr = value_dup (v1);
-                               gnm_matrix_free (m);
+                               gnm_matrix_unref (m);
                                return NULL;
                        }
 
@@ -5147,6 +5196,12 @@ gnm_matrix_from_value (GnmValue const *v, GnmValue **perr, GnmEvalPos const *ep)
        return m;
 }
 
+/**
+ * gnm_matrix_to_value:
+ * @m: #GnmMatrix
+ *
+ * Returns: (transfer full): A #GnmValue array
+ */
 GnmValue *
 gnm_matrix_to_value (GnmMatrix const *m)
 {
@@ -5161,7 +5216,15 @@ gnm_matrix_to_value (GnmMatrix const *m)
        return res;
 }
 
-/* C = A * B */
+/**
+ * gnm_matrix_multiply:
+ * @C: Output #GnmMatrix
+ * @A: #GnmMatrix
+ * @B: #GnmMatrix
+ *
+ * Computes @A * @B and stores the result in @C.  The matrices must have
+ * suitable sizes.
+ */
 void
 gnm_matrix_multiply (GnmMatrix *C, const GnmMatrix *A, const GnmMatrix *B)
 {
@@ -5244,7 +5307,12 @@ gnm_matrix_eigen_update (guint k, gnm_float t, gnm_float *eigenvalues, gboolean
        }
 }
 
-/*
+/**
+ * gnm_matrix_eigen:
+ * @m: Input #GnmMatrix
+ * @EIG: Output #GnmMatrix
+ * @eigenvalues: (out): Output location for eigen values.
+ *
  * Calculates the eigenvalues and eigenvectors of a real symmetric matrix.
  *
  * This is the Jacobi iterative process in which we use a sequence of
@@ -5506,7 +5574,7 @@ done:
        g_free (P);
        g_free (E);
        g_free (D);
-       gnm_matrix_free (L);
+       gnm_matrix_unref (L);
 
        return res;
 }
diff --git a/src/mathfunc.h b/src/mathfunc.h
index 7646b82..98d8887 100644
--- a/src/mathfunc.h
+++ b/src/mathfunc.h
@@ -124,13 +124,17 @@ gnm_float qtukey(gnm_float p, gnm_float nmeans, gnm_float df, gnm_float nranges,
 
 /* Matrix functions. */
 
+GType gnm_matrix_get_type (void);
+
 struct GnmMatrix_ {
+       int ref_count;
        gnm_float **data;   /* [y][x] */
        int cols, rows;
 };
 
 GnmMatrix *gnm_matrix_new (int rows, int cols); /* Note the order: y then x. */
-void gnm_matrix_free (GnmMatrix *m);
+GnmMatrix *gnm_matrix_ref (GnmMatrix *m);
+void gnm_matrix_unref (GnmMatrix *m);
 GnmMatrix *gnm_matrix_from_value (GnmValue const *v, GnmValue **perr, GnmEvalPos const *ep);
 GnmValue *gnm_matrix_to_value (GnmMatrix const *m);
 gboolean gnm_matrix_is_empty (GnmMatrix const *m);
diff --git a/src/tools/gnm-solver.c b/src/tools/gnm-solver.c
index dcb488e..c1e9458 100644
--- a/src/tools/gnm-solver.c
+++ b/src/tools/gnm-solver.c
@@ -2222,14 +2222,12 @@ gnm_solver_has_analytic_hessian (GnmSolver *sol)
 }
 
 /**
- * gnm_solver_compute_hessian: (skip)
+ * gnm_solver_compute_hessian:
  * @sol: Solver
  * @xs: Point to compute Hessian at
  *
- * Returns: (transfer full): A vector containing the Hessian.  This
- * function takes the flip-sign property into account.  The result vector
- * will be n+(n-1)+...+2+1 elements long containing the triangular
- * Hessian.  Use symmetry to obtain the full Hessian.
+ * Returns: (transfer full): A matrix containing the Hessian.  This
+ * function takes the flip-sign property into account.
  */
 GnmMatrix *
 gnm_solver_compute_hessian (GnmSolver *sol, gnm_float const *xs)


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