[gnumeric] Functions: Add LINSOLVE.
- From: Morten Welinder <mortenw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnumeric] Functions: Add LINSOLVE.
- Date: Sun, 13 Jan 2013 16:52:52 +0000 (UTC)
commit f80a1beb44f0124f57dff8cb00b6fcc12f550963
Author: Morten Welinder <terra gnome org>
Date: Sun Jan 13 11:51:53 2013 -0500
Functions: Add LINSOLVE.
Without LINSOLVE, people get the idea that the inverse matrix can
help them. That really only works on a blackboard.
NEWS | 1 +
doc/C/func.defs | 12 +++++-
doc/C/functions.xml | 39 ++++++++++++++++++-
plugins/fn-math/ChangeLog | 4 ++
plugins/fn-math/functions.c | 85 ++++++++++++++++++++++++++++++++++++++++-
plugins/fn-math/plugin.xml.in | 1 +
6 files changed, 139 insertions(+), 3 deletions(-)
---
diff --git a/NEWS b/NEWS
index 8fdbf9b..1f8cbfc 100644
--- a/NEWS
+++ b/NEWS
@@ -19,6 +19,7 @@ Morten:
* Fix multihead issue with clipboard.
* Improve EIGEN. [#687926]
* Improve handling of unknown functions. [#109442]
+ * Add LINSOLVE function.
--------------------------------------------------------------------------
Gnumeric 1.12.0
diff --git a/doc/C/func.defs b/doc/C/func.defs
index 1f94cee..c1877a0 100644
--- a/doc/C/func.defs
+++ b/doc/C/func.defs
@@ -3419,6 +3419,16 @@ The depreciation coefficient used is:
@SEEALSO=GCD
@CATEGORY=Mathematics
+ FUNCTION=LINSOLVE
+ SHORTDESC=solve linear equation
+ SYNTAX=LINSOLVE(mat,col)
+ ARGUMENTDESCRIPTION=@{mat}: a matrix
+ {col}: a column
+ DESCRIPTION=Solves the equation @{mat}*x= {col} and returns x.
+ NOTE=If the matrix is singular, #VALUE! is returned.
+ SEEALSO=MINVERSE
+
+ CATEGORY=Mathematics
@FUNCTION=LN
@SHORTDESC=the natural logarithm of @{x}
@SYNTAX=LN(x)
@@ -3478,7 +3488,7 @@ The depreciation coefficient used is:
@ARGUMENTDESCRIPTION= {matrix}: a square matrix
@NOTE=If @{matrix} is not invertible, MINVERSE returns #NUM! If @{matrix} does not contain an equal number of columns and rows, MINVERSE returns #VALUE!
@EXCEL=This function is Excel compatible.
- SEEALSO=MMULT,MDETERM
+ SEEALSO=MMULT,MDETERM,LINSOLVE
@CATEGORY=Mathematics
@FUNCTION=MMULT
diff --git a/doc/C/functions.xml b/doc/C/functions.xml
index 0599684..4d546f6 100644
--- a/doc/C/functions.xml
+++ b/doc/C/functions.xml
@@ -11521,6 +11521,42 @@
</para>
</refsect1>
</refentry>
+ <refentry id="gnumeric-function-LINSOLVE">
+ <refmeta>
+ <refentrytitle>
+ <function>LINSOLVE</function>
+ </refentrytitle>
+ </refmeta>
+ <refnamediv>
+ <refname>
+ <function>LINSOLVE</function>
+ </refname>
+ <refpurpose>
+ solve linear equation
+ </refpurpose>
+ </refnamediv>
+ <refsynopsisdiv>
+ <synopsis><function>LINSOLVE</function>(<parameter>mat</parameter>,<parameter>col</parameter>)</synopsis>
+ </refsynopsisdiv>
+ <refsect1>
+ <title>Arguments</title>
+ <para><parameter>mat</parameter>: a matrix</para>
+ <para><parameter>col</parameter>: a column</para>
+ </refsect1>
+ <refsect1>
+ <title>Description</title>
+ <para>Solves the equation <parameter>mat</parameter>*x=<parameter>col</parameter> and returns x.</para>
+ </refsect1>
+ <refsect1>
+ <title>Note</title>
+ <para>If the matrix is singular, #VALUE! is returned.</para>
+ </refsect1>
+ <refsect1>
+ <title>See also</title>
+ <para><link linkend="gnumeric-function-MINVERSE"><function>MINVERSE</function></link>.
+ </para>
+ </refsect1>
+ </refentry>
<refentry id="gnumeric-function-LN">
<refmeta>
<refentrytitle>
@@ -11767,7 +11803,8 @@
<refsect1>
<title>See also</title>
<para><link linkend="gnumeric-function-MMULT"><function>MMULT</function></link>,
- <link linkend="gnumeric-function-MDETERM"><function>MDETERM</function></link>.
+ <link linkend="gnumeric-function-MDETERM"><function>MDETERM</function></link>,
+ <link linkend="gnumeric-function-LINSOLVE"><function>LINSOLVE</function></link>.
</para>
</refsect1>
</refentry>
diff --git a/plugins/fn-math/ChangeLog b/plugins/fn-math/ChangeLog
index 3211a08..bf68185 100644
--- a/plugins/fn-math/ChangeLog
+++ b/plugins/fn-math/ChangeLog
@@ -1,3 +1,7 @@
+2013-01-13 Morten Welinder <terra gnome org>
+
+ * functions.c (gnumeric_linsolve): New function.
+
2012-12-18 Morten Welinder <terra gnome org>
* Release 1.12.0
diff --git a/plugins/fn-math/functions.c b/plugins/fn-math/functions.c
index 5ec7813..9de078c 100644
--- a/plugins/fn-math/functions.c
+++ b/plugins/fn-math/functions.c
@@ -2588,7 +2588,7 @@ static GnmFuncHelp const help_minverse[] = {
{ GNM_FUNC_HELP_NOTE, F_("If @{matrix} is not invertible, MINVERSE returns #NUM!") },
{ GNM_FUNC_HELP_NOTE, F_("If @{matrix} does not contain an equal number of columns and rows, MINVERSE returns #VALUE!") },
{ GNM_FUNC_HELP_EXCEL, F_("This function is Excel compatible.") },
- { GNM_FUNC_HELP_SEEALSO, "MMULT,MDETERM"},
+ { GNM_FUNC_HELP_SEEALSO, "MMULT,MDETERM,LINSOLVE"},
{ GNM_FUNC_HELP_END}
};
@@ -2664,6 +2664,22 @@ value_to_matrix (GnmValue const *v, int cols, int rows, GnmEvalPos const *ep)
return res;
}
+static gnm_float **
+value_to_tmatrix (GnmValue const *v, int cols, int rows, GnmEvalPos const *ep)
+{
+ gnm_float **res = g_new (gnm_float *, cols);
+ int r, c;
+
+ for (c = 0; c < cols; c++) {
+ res[c] = g_new (gnm_float, rows);
+ for (r = 0; r < rows; r++)
+ res[c][r] =
+ value_get_as_float (value_area_get_x_y (v, c, r, ep));
+ }
+
+ return res;
+}
+
static void
free_matrix (gnm_float **mat, G_GNUC_UNUSED int cols, int rows)
{
@@ -2907,6 +2923,70 @@ gnumeric_mmult (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
/***************************************************************************/
+static GnmFuncHelp const help_linsolve[] = {
+ { GNM_FUNC_HELP_NAME, F_("LINSOLVE:solve linear equation")},
+ { GNM_FUNC_HELP_ARG, F_("mat:a matrix")},
+ { GNM_FUNC_HELP_ARG, F_("col:a column")},
+ { GNM_FUNC_HELP_DESCRIPTION,
+ F_("Solves the equation @{mat}*x= {col} and returns x.") },
+ { GNM_FUNC_HELP_NOTE, F_("If the matrix is singular, #VALUE! is returned.") },
+ { GNM_FUNC_HELP_SEEALSO, "MINVERSE"},
+ { GNM_FUNC_HELP_END}
+};
+
+
+static GnmValue *
+gnumeric_linsolve (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
+{
+ GnmEvalPos const * const ep = ei->pos;
+ int mrows, mcols, crows, ccols;
+ GORegressionResult regres;
+ gnm_float **A;
+ gnm_float **b;
+ GnmStdError err;
+ GnmValue const *mat = argv[0];
+ GnmValue const *col = argv[1];
+ gnm_float *x;
+ GnmValue *res;
+
+ if (validate_range_numeric_matrix (ep, mat, &mrows, &mcols, &err))
+ return value_new_error_std (ei->pos, err);
+
+ if (validate_range_numeric_matrix (ep, col, &crows, &ccols, &err))
+ return value_new_error_std (ei->pos, err);
+
+ /* Guarantee shape and non-zero size */
+ if (mrows != mcols || mrows != crows || ccols != 1 || !mcols)
+ return value_new_error_VALUE (ei->pos);
+
+ A = value_to_matrix (mat, mcols, mrows, ep);
+ b = value_to_tmatrix (col, ccols, crows, ep);
+ x = g_new (gnm_float, crows);
+ regres = gnm_linear_solve (A, b[0], crows, x);
+ free_matrix (A, mcols, mrows);
+ free_matrix (b, crows, ccols); /* tmatrix */
+
+ if (regres != GO_REG_ok && regres != GO_REG_near_singular_good) {
+ res = value_new_error_VALUE (ei->pos);
+ } else {
+ int c, r;
+
+ res = value_new_array_non_init (ccols, crows);
+ for (c = 0; c < ccols; c++) {
+ res->v_array.vals[c] = g_new (GnmValue *, crows);
+ for (r = 0; r < crows; r++)
+ res->v_array.vals[c][r] =
+ value_new_float (x[r]);
+ }
+ }
+
+ g_free (x);
+
+ return res;
+}
+
+/***************************************************************************/
+
static GnmFuncHelp const help_mdeterm[] = {
{ GNM_FUNC_HELP_NAME, F_("MDETERM:the determinant of the matrix @{matrix}")},
{ GNM_FUNC_HELP_ARG, F_("matrix:a square matrix")},
@@ -3479,6 +3559,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 },
+ { "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 },
{ "mdeterm", "A", help_mdeterm,
gnumeric_mdeterm, NULL, NULL, NULL,
GNM_FUNC_RETURNS_NON_SCALAR, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_BASIC },
diff --git a/plugins/fn-math/plugin.xml.in b/plugins/fn-math/plugin.xml.in
index c27aef3..457df3e 100644
--- a/plugins/fn-math/plugin.xml.in
+++ b/plugins/fn-math/plugin.xml.in
@@ -54,6 +54,7 @@
<function name="hypot"/>
<function name="int"/>
<function name="lcm"/>
+ <function name="linsolve"/>
<function name="ln"/>
<function name="ln1p"/>
<function name="log"/>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]