[gnumeric] Deriv: handle LN too.



commit b037fc686287caaeaf83e6aee6ca1c38418b4f67
Author: Morten Welinder <terra gnome org>
Date:   Wed Sep 14 19:11:53 2016 -0400

    Deriv: handle LN too.
    
    We need that for the Nelson model.

 plugins/fn-math/functions.c |   14 ++++++++++++++
 src/expr-deriv.c            |   20 ++++++++++++++++----
 src/expr.c                  |   10 ++++++++++
 src/expr.h                  |    1 +
 4 files changed, 41 insertions(+), 4 deletions(-)
---
diff --git a/plugins/fn-math/functions.c b/plugins/fn-math/functions.c
index 1b3401c..949e11f 100644
--- a/plugins/fn-math/functions.c
+++ b/plugins/fn-math/functions.c
@@ -1316,6 +1316,15 @@ gnumeric_ln (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
        return value_new_float (gnm_log (t));
 }
 
+static GnmExpr const *
+gnumeric_ln_deriv (GnmExpr const *expr, GnmEvalPos const *ep,
+                  GnmExprDeriv *info)
+{
+       return gnm_expr_new_binary (gnm_expr_new_constant (value_new_int (1)),
+                                   GNM_EXPR_OP_DIV,
+                                   gnm_expr_copy (gnm_expr_get_func_arg (expr, 0)));
+}
+
 /***************************************************************************/
 
 static GnmFuncHelp const help_ln1p[] = {
@@ -3703,10 +3712,15 @@ go_plugin_init (GOPlugin *plugin, GOCmdContext *cc)
        gnm_expr_deriv_install_handler (gnm_func_lookup ("exp", NULL),
                                        gnumeric_exp_deriv,
                                        GNM_EXPR_DERIV_CHAIN);
+       gnm_expr_deriv_install_handler (gnm_func_lookup ("ln", NULL),
+                                       gnumeric_ln_deriv,
+                                       GNM_EXPR_DERIV_CHAIN);
 }
 
 G_MODULE_EXPORT void
 go_plugin_shutdown (GOPlugin *plugin, GOCmdContext *cc)
 {
        gnm_expr_deriv_uninstall_handler (gnm_func_lookup ("sumsq", NULL));
+       gnm_expr_deriv_uninstall_handler (gnm_func_lookup ("exp", NULL));
+       gnm_expr_deriv_uninstall_handler (gnm_func_lookup ("ln", NULL));
 }
diff --git a/src/expr-deriv.c b/src/expr-deriv.c
index 47bf419..4fc90ef 100644
--- a/src/expr-deriv.c
+++ b/src/expr-deriv.c
@@ -254,7 +254,14 @@ cb_arg_collect (GnmCellIter const *iter, gpointer user_)
        return NULL;
 }
 
-// Collect all arguments and expand range arguments into individual cells.
+/**
+ * gnm_expr_deriv_collect:
+ * @expr: expression
+ * @ep: evaluation position
+ * @info: extra information, not currently used
+ *
+ * Returns: (transfer full): list of expressions expanded from @expr
+ */
 GnmExprList *
 gnm_expr_deriv_collect (GnmExpr const *expr,
                        GnmEvalPos const *ep,
@@ -403,9 +410,8 @@ gnm_expr_deriv (GnmExpr const *expr,
                        return NULL;
 
                if (di->flags & GNM_EXPR_DERIV_CHAIN) {
-                       GnmExpr const *e2 = expr->func.argc == 1
-                               ? gnm_expr_deriv (expr->func.argv[0], ep, info)
-                               : NULL;
+                       GnmExpr const *e2 =
+                               gnm_expr_deriv (gnm_expr_get_func_arg (expr, 0), ep, info);
                        if (!e2) {
                                gnm_expr_free (res);
                                return NULL;
@@ -567,6 +573,12 @@ gnm_expr_cell_deriv_value (GnmCell *y, GnmCell *x)
 
 /* ------------------------------------------------------------------------- */
 
+/**
+ * gnm_expr_deriv_install_handler:
+ * @func: the function being given a handler
+ * @h: (scope async): #GnmExprDerivHandler
+ * @flags: 
+ */
 void
 gnm_expr_deriv_install_handler (GnmFunc *func, GnmExprDerivHandler h,
                                GnmExprDerivFlags flags)
diff --git a/src/expr.c b/src/expr.c
index 8d90c7d..c05733b 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -2272,6 +2272,16 @@ gnm_expr_get_func_def (GnmExpr const *expr)
        return expr->func.func;
 }
 
+GnmExpr const *
+gnm_expr_get_func_arg (GnmExpr const *expr, int i)
+{
+       g_return_val_if_fail (expr != NULL, NULL);
+       g_return_val_if_fail (GNM_EXPR_GET_OPER (expr) == GNM_EXPR_OP_FUNCALL, NULL);
+       g_return_val_if_fail (i >= 0 && i < expr->func.argc, NULL);
+
+       return expr->func.argv[i];
+}
+
 
 static void
 cellref_boundingbox (GnmCellRef const *cr, Sheet const *sheet, GnmRange *bound)
diff --git a/src/expr.h b/src/expr.h
index 8a9c217..1f7f38a 100644
--- a/src/expr.h
+++ b/src/expr.h
@@ -84,6 +84,7 @@ GnmExpr const *gnm_expr_new_range_ctor  (GnmExpr const *l, GnmExpr const *r);
 
 GnmValue      *gnm_expr_get_range    (GnmExpr const *expr);
 GnmFunc       *gnm_expr_get_func_def (GnmExpr const *expr);
+GnmExpr const *gnm_expr_get_func_arg (GnmExpr const *expr, int i);
 
 void     gnm_expr_free              (GnmExpr const *expr);
 GnmExpr const *gnm_expr_copy         (GnmExpr const *expr);


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