[gnumeric] Add simplification to the r.qbinom->binom.inf translations



commit 135c101f2255f0125b243479573777ad365e52ad
Author: Andreas J Guelzow <aguelzow pyrshep ca>
Date:   Mon Jun 24 15:42:25 2013 -0600

    Add simplification to the r.qbinom->binom.inf translations
    
    2013-06-24  Andreas J. Guelzow <aguelzow pyrshep ca>
    
        * xlsx-utils.c (xlsx_func_binominv_output_handler):
        simplify the expression if some of the flags are constant

 plugins/excel/ChangeLog    |    5 +++
 plugins/excel/xlsx-utils.c |   69 +++++++++++++++++++++++++++++++++++++++++--
 src/expr.c                 |   23 +++++++++++---
 src/expr.h                 |    2 +
 4 files changed, 90 insertions(+), 9 deletions(-)
---
diff --git a/plugins/excel/ChangeLog b/plugins/excel/ChangeLog
index 0ddd143..40705a0 100644
--- a/plugins/excel/ChangeLog
+++ b/plugins/excel/ChangeLog
@@ -1,6 +1,11 @@
 2013-06-24  Andreas J. Guelzow <aguelzow pyrshep ca>
 
        * xlsx-utils.c (xlsx_func_binominv_output_handler):
+       simplify the expression if some of the flags are constant
+
+2013-06-24  Andreas J. Guelzow <aguelzow pyrshep ca>
+
+       * xlsx-utils.c (xlsx_func_binominv_output_handler):
        translate the expression even for more than 3 arguments
 
 2013-06-22  Andreas J. Guelzow <aguelzow pyrshep ca>
diff --git a/plugins/excel/xlsx-utils.c b/plugins/excel/xlsx-utils.c
index 5ed1820..f6dc90b 100644
--- a/plugins/excel/xlsx-utils.c
+++ b/plugins/excel/xlsx-utils.c
@@ -38,6 +38,7 @@
 #include <glib-object.h>
 #include <string.h>
 #include <expr.h>
+#include <value.h>
 
 typedef struct {
        GnmConventions base;
@@ -224,11 +225,38 @@ xlsx_func_binominv_output_handler (GnmConventionsOut *out, GnmExprFunction const
        GnmExprConstPtr const *ptr = func->argv;
        GString *target = out->accum;
 
-       if (func->argc == 3) {
+       int use_lower_tail; /* 0: never; 1: always; 2: sometimes */
+       int use_log;        /* 0: never; 1: always; 2: sometimes */
+
+       if (func->argc < 3 || func->argc > 5)
+               return FALSE;
+
+       if (func->argc > 3) {
+               GnmValue const *constant = gnm_expr_get_constant (ptr[3]);
+               if (constant == NULL || !VALUE_IS_NUMBER (constant))
+                       use_lower_tail = 2;
+               else
+                       use_lower_tail = value_is_zero (constant) ? 0 : 1;
+       } else
+               use_lower_tail = 1;
+       if (func->argc > 4) {
+               GnmValue const *constant = gnm_expr_get_constant (ptr[4]);
+               if (constant == NULL || !VALUE_IS_NUMBER (constant))
+                       use_log = 2;
+               else 
+                       use_log = value_is_zero (constant) ? 0 : 1;
+       } else
+               use_log = 0;
+
+       if (use_lower_tail == 1 && use_log == 0) {
                /* R.QBINOM(c,a,b) --> BINOM.INV(a,b,c) */
                OUTPUT_BINOM_INV (",",")");
                return TRUE;
-       } else if (func->argc == 4) {
+       } else if (use_lower_tail == 0 && use_log == 0) {
+               /* R.QBINOM(c,a,b) --> BINOM.INV(a,b,1-c) */
+               OUTPUT_BINOM_INV (",1-",")");
+               return TRUE;
+       } else if (/* use_lower_tail == 2 && */ use_log == 0) {
                /* R.QBINOM(c,a,b,d) --> if(d,binom.inv(a,b,c), binom.inv(a,b,1-c)) */
                g_string_append (target, "if(");
                gnm_expr_as_gstring (ptr[3], out);
@@ -236,7 +264,41 @@ xlsx_func_binominv_output_handler (GnmConventionsOut *out, GnmExprFunction const
                OUTPUT_BINOM_INV(",","),");
                OUTPUT_BINOM_INV(",1-","))");
                return TRUE;
-       } else if (func->argc == 5) {
+       } else if (use_lower_tail == 1 && use_log == 1) {
+               /* R.QBINOM(c,a,b) --> BINOM.INV(a,b,exp(c)) */
+               OUTPUT_BINOM_INV (",exp(","))");
+               return TRUE;
+       } else if (use_lower_tail == 0 && use_log == 1) {
+               /* R.QBINOM(c,a,b) --> BINOM.INV(a,b,1-exp(c)) */
+               OUTPUT_BINOM_INV (",1-exp(","))");
+               return TRUE;
+       } else if (/* use_lower_tail == 2 && */ use_log == 1) {
+               /* R.QBINOM(c,a,b,d) --> if(d,binom.inv(a,b,exp(c)), binom.inv(a,b,1-exp(c))) */
+               g_string_append (target, "if(");
+               gnm_expr_as_gstring (ptr[3], out);
+               g_string_append (target, ",");
+               OUTPUT_BINOM_INV(",exp(",")),");
+               OUTPUT_BINOM_INV(",1-exp(",")))");
+               return TRUE;
+       } else if (use_lower_tail == 0 /* && use_log == 2 */) {
+               /* R.QBINOM(c,a,b,d,e) -->
+                               if(e,binom.inv(a,b,1-exp(c)),binom.inv(a,b,1-c))*/
+               g_string_append (target, "if(");
+               gnm_expr_as_gstring (ptr[4], out);
+               g_string_append (target, ",");
+               OUTPUT_BINOM_INV(",1-exp(",")),");
+               OUTPUT_BINOM_INV(",1-","))");
+               return TRUE;
+       } else if (use_lower_tail == 1 /* && use_log == 2 */) {
+               /* R.QBINOM(c,a,b,d,e) -->
+                          if(e,binom.inv(a,b,exp(c)),binom.inv(a,b,c))*/
+               g_string_append (target, "if(");
+               gnm_expr_as_gstring (ptr[4], out);
+               g_string_append (target, ",");
+               OUTPUT_BINOM_INV(",exp(",")),");
+               OUTPUT_BINOM_INV(",","))");
+               return TRUE;
+       } else /*if (use_lower_tail == 2 && use_log == 2 */ {
                /* R.QBINOM(c,a,b,d,e) -->
                           if(d,if(e,binom.inv(a,b,exp(c)),binom.inv(a,b,c)),
                                if(e,binom.inv(a,b,1-exp(c)),binom.inv(a,b,1-c)))*/
@@ -253,7 +315,6 @@ xlsx_func_binominv_output_handler (GnmConventionsOut *out, GnmExprFunction const
                OUTPUT_BINOM_INV(",1-",")))");
                return TRUE;
        }
-       return FALSE;
 #undef OUTPUT_BINOM_INV
 }
 
diff --git a/src/expr.c b/src/expr.c
index 7be26f8..9c3e612 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -1861,6 +1861,22 @@ gnm_expr_is_err (GnmExpr const *expr, GnmStdError err)
        return err == err2;
 }
 
+/**
+ * gnm_expr_get_constant:
+ * @expr:
+ *
+ * If this expression consists of just a constant, return it.
+ */
+GnmValue const *
+gnm_expr_get_constant (GnmExpr const *expr)
+{
+       if (GNM_EXPR_GET_OPER (expr) != GNM_EXPR_OP_CONSTANT)
+               return NULL;
+
+       return expr->constant.value;
+}
+
+
 typedef struct {
        GnmExprRelocateInfo const *details;
        gboolean from_inside;
@@ -3208,11 +3224,8 @@ GnmValue const *
 gnm_expr_top_get_constant (GnmExprTop const *texpr)
 {
        g_return_val_if_fail (IS_GNM_EXPR_TOP (texpr), NULL);
-
-       if (GNM_EXPR_GET_OPER (texpr->expr) != GNM_EXPR_OP_CONSTANT)
-               return NULL;
-
-       return texpr->expr->constant.value;
+       
+       return gnm_expr_get_constant (texpr->expr);
 }
 
 GnmCellRef const *
diff --git a/src/expr.h b/src/expr.h
index 6294644..57c6ce8 100644
--- a/src/expr.h
+++ b/src/expr.h
@@ -92,6 +92,8 @@ gboolean  gnm_expr_is_data_table     (GnmExpr const *expr,
                                      GnmCellPos *c_in, GnmCellPos *r_in);
 gboolean  gnm_expr_is_empty          (GnmExpr const *expr);
 
+GnmValue const *gnm_expr_get_constant  (GnmExpr const *expr);
+
 void     gnm_expr_as_gstring        (GnmExpr const *expr,
                                      GnmConventionsOut *out);
 char    *gnm_expr_as_string         (GnmExpr const *expr, GnmParsePos const *pp,


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