[gnumeric] Matrices: MPSEUDOINVERSE.



commit 7f60e3c0f74c3f0f524f317f96e8c54d2a6ba1ad
Author: Morten Welinder <terra gnome org>
Date:   Tue Apr 30 16:28:51 2013 -0400

    Matrices: MPSEUDOINVERSE.

 NEWS                          |    1 +
 configure.ac                  |    2 +-
 plugins/fn-math/functions.c   |   40 ++++++++++++++++++++++++++++++++++++++++
 plugins/fn-math/plugin.xml.in |    1 +
 src/regression.h              |    2 ++
 5 files changed, 45 insertions(+), 1 deletions(-)
---
diff --git a/NEWS b/NEWS
index 193c5b5..735f8b8 100644
--- a/NEWS
+++ b/NEWS
@@ -6,6 +6,7 @@ Andreas:
 Morten:
        * Improve xlsx import of style-only cells.
        * Don't write empty cells to .gnumeric.
+       * Add MPSEUDOINVERSE function.
 
 --------------------------------------------------------------------------
 Gnumeric 1.12.2
diff --git a/configure.ac b/configure.ac
index c4bcb7e..3e7413e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -152,7 +152,7 @@ PKG_PROG_PKG_CONFIG(0.18)
 
 dnl *****************************
 libspreadsheet_reqs="
-       libgoffice-${GOFFICE_API_VER}   >= 0.10.2
+       libgoffice-${GOFFICE_API_VER}   >= 0.10.3
        libgsf-1                >= 1.14.24
        libxml-2.0              >= 2.4.12
 "
diff --git a/plugins/fn-math/functions.c b/plugins/fn-math/functions.c
index 5218758..cd04fcb 100644
--- a/plugins/fn-math/functions.c
+++ b/plugins/fn-math/functions.c
@@ -2642,6 +2642,43 @@ out:
 
 /***************************************************************************/
 
+static GnmFuncHelp const help_mpseudoinverse[] = {
+        { GNM_FUNC_HELP_NAME, F_("MPSEUDOINVERSE:the pseudo-inverse matrix of @{matrix}")},
+        { GNM_FUNC_HELP_ARG, F_("matrix:a matrix")},
+        { GNM_FUNC_HELP_ARG, F_("threshold:a relative size threshold for discarding eigenvalues")},
+       { GNM_FUNC_HELP_SEEALSO, "MINVERSE"},
+        { GNM_FUNC_HELP_END}
+};
+
+
+static GnmValue *
+gnumeric_mpseudominverse (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
+{
+       GnmMatrix *A = NULL;
+       GnmMatrix *B = NULL;
+       GnmValue *res = NULL;
+        gnm_float threshold = argv[1] ? value_get_as_float (argv[1]) : GNM_EPSILON;
+
+       A = gnm_matrix_from_value (argv[0], &res, ei->pos);
+       if (!A) goto out;
+
+       if (A->cols != A->rows || gnm_matrix_is_empty (A)) {
+               res = value_new_error_VALUE (ei->pos);
+               goto out;
+       }
+
+       B = gnm_matrix_new (A->cols, A->rows);  /* Shape of A^t */
+       gnm_matrix_pseudo_inverse (A->data, A->rows, A->cols, threshold, B->data);
+       res = gnm_matrix_to_value (B);
+
+out:
+       if (A) gnm_matrix_free (A);
+       if (B) gnm_matrix_free (B);
+       return res;
+}
+
+/***************************************************************************/
+
 static GnmFuncHelp const help_cholesky[] = {
         { GNM_FUNC_HELP_NAME, F_("CHOLESKY:the Cholesky decomposition of the symmetric positive-definite 
@{matrix}")},
         { GNM_FUNC_HELP_ARG, F_("matrix:a symmetric positive definite matrix")},
@@ -3410,6 +3447,9 @@ GnmFuncDescriptor const math_functions[] = {
        { "minverse","A",      help_minverse,
          gnumeric_minverse, NULL, NULL, NULL,
          GNM_FUNC_RETURNS_NON_SCALAR, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_BASIC },
+       { "mpseudoinverse","A|f", help_mpseudoinverse,
+         gnumeric_mpseudominverse, NULL, NULL, NULL,
+         GNM_FUNC_RETURNS_NON_SCALAR, GNM_FUNC_IMPL_STATUS_UNIQUE_TO_GNUMERIC, 
GNM_FUNC_TEST_STATUS_NO_TESTSUITE },
        { "linsolve", "AA",  help_linsolve,
          gnumeric_linsolve, NULL, NULL, NULL,
          GNM_FUNC_RETURNS_NON_SCALAR, GNM_FUNC_IMPL_STATUS_UNIQUE_TO_GNUMERIC, 
GNM_FUNC_TEST_STATUS_NO_TESTSUITE },
diff --git a/plugins/fn-math/plugin.xml.in b/plugins/fn-math/plugin.xml.in
index 3e69e2d..2559246 100644
--- a/plugins/fn-math/plugin.xml.in
+++ b/plugins/fn-math/plugin.xml.in
@@ -64,6 +64,7 @@
                                <function name="minverse"/>
                                <function name="mmult"/>
                                <function name="mod"/>
+                               <function name="mpseudoinverse"/>
                                <function name="mround"/>
                                <function name="multinomial"/>
                                <function name="munit"/>
diff --git a/src/regression.h b/src/regression.h
index fa365fa..5aa8e4d 100644
--- a/src/regression.h
+++ b/src/regression.h
@@ -19,6 +19,7 @@ G_BEGIN_DECLS
 #      define GnmRegressionFunction GORegressionFunctionl
 #      define gnm_non_linear_regression go_non_linear_regressionl
 #      define gnm_matrix_invert go_matrix_invertl
+#      define gnm_matrix_pseudo_inverse go_matrix_pseudo_inversel
 #      define gnm_matrix_determinant go_matrix_determinantl
 #      define gnm_linear_solve go_linear_solvel
 #      define gnm_linear_solve_multiple go_linear_solve_multiplel
@@ -34,6 +35,7 @@ G_BEGIN_DECLS
 #      define GnmRegressionFunction GORegressionFunction
 #      define gnm_non_linear_regression go_non_linear_regression
 #      define gnm_matrix_invert go_matrix_invert
+#      define gnm_matrix_pseudo_inverse go_matrix_pseudo_inverse
 #      define gnm_matrix_determinant go_matrix_determinant
 #      define gnm_linear_solve go_linear_solve
 #      define gnm_linear_solve_multiple go_linear_solve_multiple


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