[gnumeric] GnmMatrix: add introspection
- From: Morten Welinder <mortenw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnumeric] GnmMatrix: add introspection
- Date: Fri, 18 May 2018 02:15:45 +0000 (UTC)
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]