Commit 137b0847 authored by Morten Welinder's avatar Morten Welinder

GnmMatrix: add introspection

parent ab31a649
......@@ -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;
}
......
......@@ -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;
}
......
......@@ -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;
......
......@@ -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;
}
......
......@@ -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);
......
......@@ -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)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment