File indexing completed on 2024-05-12 16:35:33

0001 /* This file is part of the KDE project
0002    Copyright (C) 1998-2002 The KSpread Team <calligra-devel@kde.org>
0003    Copyright (C) 2005 Tomas Mecir <mecirt@gmail.com>
0004    Copyright 2007 Sascha Pfau <MrPeacock@gmail.com>
0005    Copyright (C) 2010 Carlos Licea <carlos@kdab.com>
0006    Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
0007      Contact: Suresh Chande suresh.chande@nokia.com
0008 
0009    This library is free software; you can redistribute it and/or
0010    modify it under the terms of the GNU Library General Public
0011    License as published by the Free Software Foundation; only
0012    version 2 of the License.
0013 
0014    This library is distributed in the hope that it will be useful,
0015    but WITHOUT ANY WARRANTY; without even the implied warranty of
0016    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0017    Library General Public License for more details.
0018 
0019    You should have received a copy of the GNU Library General Public License
0020    along with this library; see the file COPYING.LIB.  If not, write to
0021    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0022    Boston, MA 02110-1301, USA.
0023 */
0024 
0025 // built-in math functions
0026 #include "MathModule.h"
0027 
0028 // needed for RANDBINOM and so
0029 #include <math.h>
0030 #include <qmath.h>
0031 
0032 #include "SheetsDebug.h"
0033 #include "FunctionModuleRegistry.h"
0034 #include "Function.h"
0035 #include "FunctionRepository.h"
0036 #include "ValueCalc.h"
0037 #include "ValueConverter.h"
0038 
0039 // needed for SUBTOTAL:
0040 #include "Cell.h"
0041 #include "Sheet.h"
0042 #include "RowColumnFormat.h"
0043 #include "RowFormatStorage.h"
0044 
0045 // needed by MDETERM and MINVERSE
0046 // Don't show this warning: it's an issue in eigen
0047 #ifdef __GNUC__
0048 #pragma GCC diagnostic ignored "-Wunused-local-typedefs"
0049 #endif
0050 
0051 #include <Eigen/LU>
0052 
0053 using namespace Calligra::Sheets;
0054 
0055 // RANDBINOM and RANDNEGBINOM won't support arbitrary precision
0056 
0057 // prototypes
0058 Value func_abs(valVector args, ValueCalc *calc, FuncExtra *);
0059 Value func_ceil(valVector args, ValueCalc *calc, FuncExtra *);
0060 Value func_ceiling(valVector args, ValueCalc *calc, FuncExtra *);
0061 Value func_count(valVector args, ValueCalc *calc, FuncExtra *);
0062 Value func_counta(valVector args, ValueCalc *calc, FuncExtra *);
0063 Value func_countblank(valVector args, ValueCalc *calc, FuncExtra *);
0064 Value func_countif(valVector args, ValueCalc *calc, FuncExtra *);
0065 Value func_countifs(valVector args, ValueCalc *calc, FuncExtra *e);
0066 Value func_cur(valVector args, ValueCalc *calc, FuncExtra *);
0067 Value func_div(valVector args, ValueCalc *calc, FuncExtra *);
0068 Value func_eps(valVector args, ValueCalc *calc, FuncExtra *);
0069 Value func_even(valVector args, ValueCalc *calc, FuncExtra *);
0070 Value func_exp(valVector args, ValueCalc *calc, FuncExtra *);
0071 Value func_fact(valVector args, ValueCalc *calc, FuncExtra *);
0072 Value func_factdouble(valVector args, ValueCalc *calc, FuncExtra *);
0073 Value func_fib(valVector args, ValueCalc *calc, FuncExtra *);
0074 Value func_floor(valVector args, ValueCalc *calc, FuncExtra *);
0075 Value func_gamma(valVector args, ValueCalc *calc, FuncExtra *);
0076 Value func_gcd(valVector args, ValueCalc *calc, FuncExtra *);
0077 Value func_int(valVector args, ValueCalc *calc, FuncExtra *);
0078 Value func_inv(valVector args, ValueCalc *calc, FuncExtra *);
0079 Value func_kproduct(valVector args, ValueCalc *calc, FuncExtra *);
0080 Value func_lcm(valVector args, ValueCalc *calc, FuncExtra *);
0081 Value func_ln(valVector args, ValueCalc *calc, FuncExtra *);
0082 Value func_log2(valVector args, ValueCalc *calc, FuncExtra *);
0083 Value func_log10(valVector args, ValueCalc *calc, FuncExtra *);
0084 Value func_logn(valVector args, ValueCalc *calc, FuncExtra *);
0085 Value func_max(valVector args, ValueCalc *calc, FuncExtra *);
0086 Value func_maxa(valVector args, ValueCalc *calc, FuncExtra *);
0087 Value func_mdeterm(valVector args, ValueCalc *calc, FuncExtra *);
0088 Value func_min(valVector args, ValueCalc *calc, FuncExtra *);
0089 Value func_mina(valVector args, ValueCalc *calc, FuncExtra *);
0090 Value func_minverse(valVector args, ValueCalc* calc, FuncExtra*);
0091 Value func_mmult(valVector args, ValueCalc *calc, FuncExtra *);
0092 Value func_mod(valVector args, ValueCalc *calc, FuncExtra *);
0093 Value func_mround(valVector args, ValueCalc *calc, FuncExtra *);
0094 Value func_mult(valVector args, ValueCalc *calc, FuncExtra *);
0095 Value func_multinomial(valVector args, ValueCalc *calc, FuncExtra *);
0096 Value func_munit(valVector args, ValueCalc* calc, FuncExtra*);
0097 Value func_odd(valVector args, ValueCalc *calc, FuncExtra *);
0098 Value func_pow(valVector args, ValueCalc *calc, FuncExtra *);
0099 Value func_quotient(valVector args, ValueCalc *calc, FuncExtra *);
0100 Value func_product(valVector args, ValueCalc *calc, FuncExtra *);
0101 Value func_rand(valVector args, ValueCalc *calc, FuncExtra *);
0102 Value func_randbetween(valVector args, ValueCalc *calc, FuncExtra *);
0103 Value func_randbernoulli(valVector args, ValueCalc *calc, FuncExtra *);
0104 Value func_randbinom(valVector args, ValueCalc *calc, FuncExtra *);
0105 Value func_randexp(valVector args, ValueCalc *calc, FuncExtra *);
0106 Value func_randnegbinom(valVector args, ValueCalc *calc, FuncExtra *);
0107 Value func_randnorm(valVector args, ValueCalc *calc, FuncExtra *);
0108 Value func_randpoisson(valVector args, ValueCalc *calc, FuncExtra *);
0109 Value func_rootn(valVector args, ValueCalc *calc, FuncExtra *);
0110 Value func_round(valVector args, ValueCalc *calc, FuncExtra *);
0111 Value func_rounddown(valVector args, ValueCalc *calc, FuncExtra *);
0112 Value func_roundup(valVector args, ValueCalc *calc, FuncExtra *);
0113 Value func_seriessum(valVector args, ValueCalc *calc, FuncExtra *);
0114 Value func_sign(valVector args, ValueCalc *calc, FuncExtra *);
0115 Value func_sqrt(valVector args, ValueCalc *calc, FuncExtra *);
0116 Value func_sqrtpi(valVector args, ValueCalc *calc, FuncExtra *);
0117 Value func_subtotal(valVector args, ValueCalc *calc, FuncExtra *);
0118 Value func_sum(valVector args, ValueCalc *calc, FuncExtra *);
0119 Value func_suma(valVector args, ValueCalc *calc, FuncExtra *);
0120 Value func_sumif(valVector args, ValueCalc *calc, FuncExtra *);
0121 Value func_sumifs(valVector args, ValueCalc *calc, FuncExtra *);     //here
0122 Value func_sumsq(valVector args, ValueCalc *calc, FuncExtra *);
0123 Value func_transpose(valVector args, ValueCalc *calc, FuncExtra *);
0124 Value func_trunc(valVector args, ValueCalc *calc, FuncExtra *);
0125 
0126 
0127 // Value func_multipleOP (valVector args, ValueCalc *calc, FuncExtra *);
0128 
0129 
0130 CALLIGRA_SHEETS_EXPORT_FUNCTION_MODULE("kspreadmathmodule.json", MathModule)
0131 
0132 
0133 MathModule::MathModule(QObject* parent, const QVariantList&)
0134         : FunctionModule(parent)
0135 {
0136     Function *f;
0137 
0138     /*
0139       f = new Function ("MULTIPLEOPERATIONS", func_multipleOP);
0140     add(f);
0141     */
0142 
0143     // functions that don't take array parameters
0144     f = new Function("ABS",           func_abs);
0145     add(f);
0146     f = new Function("CEIL",          func_ceil);
0147     add(f);
0148     f = new Function("CEILING",       func_ceiling);
0149     f->setParamCount(1, 3);
0150     add(f);
0151     f = new Function("CUR",           func_cur);
0152     add(f);
0153     f = new Function("EPS",           func_eps);
0154     f->setParamCount(0);
0155     add(f);
0156     f = new Function("EVEN",          func_even);
0157     add(f);
0158     f = new Function("EXP",           func_exp);
0159     add(f);
0160     f = new Function("FACT",          func_fact);
0161     add(f);
0162     f = new Function("FACTDOUBLE",    func_factdouble);
0163     f->setAlternateName("COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETFACTDOUBLE");
0164     add(f);
0165     f = new Function("FIB",           func_fib);  // Calligra Sheets-specific, like Quattro-Pro's FIB
0166     add(f);
0167     f = new Function("FLOOR",         func_floor);
0168     f->setParamCount(1, 3);
0169     add(f);
0170     f = new Function("GAMMA",         func_gamma);
0171     add(f);
0172     f = new Function("INT",           func_int);
0173     add(f);
0174     f = new Function("INV",           func_inv);
0175     add(f);
0176     f = new Function("LN",            func_ln);
0177     add(f);
0178     f = new Function("LOG",           func_logn);
0179     f->setParamCount(1, 2);
0180     add(f);
0181     f = new Function("LOG2",          func_log2);
0182     add(f);
0183     f = new Function("LOG10",         func_log10);
0184     add(f);
0185     f = new Function("LOGN",          func_logn);
0186     f->setParamCount(2);
0187     add(f);
0188     f = new Function("MOD",           func_mod);
0189     f->setParamCount(2);
0190     add(f);
0191     f = new Function("MROUND",        func_mround);
0192     f->setAlternateName("COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETMROUND");
0193     f->setParamCount(2);
0194     add(f);
0195     f = new Function("MULTINOMIAL",   func_multinomial);
0196     f->setAlternateName("COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETMULTINOMIAL");
0197     f->setParamCount(1, -1);
0198     add(f);
0199     f = new Function("ODD",           func_odd);
0200     add(f);
0201     f = new Function("POW",         func_pow);
0202     f->setParamCount(2);
0203     add(f);
0204     f = new Function("POWER",         func_pow);
0205     f->setParamCount(2);
0206     add(f);
0207     f = new Function("QUOTIENT",      func_quotient);
0208     f->setAlternateName("COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETQUOTIENT");
0209     f->setParamCount(2);
0210     add(f);
0211     f = new Function("RAND",          func_rand);
0212     f->setParamCount(0);
0213     add(f);
0214     f = new Function("RANDBERNOULLI", func_randbernoulli);
0215     add(f);
0216     f = new Function("RANDBETWEEN",   func_randbetween);
0217     f->setAlternateName("COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETRANDBETWEEN");
0218     f->setParamCount(2);
0219     add(f);
0220     f = new Function("RANDBINOM",     func_randbinom);
0221     f->setParamCount(2);
0222     add(f);
0223     f = new Function("RANDEXP",       func_randexp);
0224     add(f);
0225     f = new Function("RANDNEGBINOM",  func_randnegbinom);
0226     f->setParamCount(2);
0227     add(f);
0228     f = new Function("RANDNORM",      func_randnorm);
0229     f->setParamCount(2);
0230     add(f);
0231     f = new Function("RANDPOISSON",   func_randpoisson);
0232     add(f);
0233     f = new Function("ROOTN",         func_rootn);
0234     f->setParamCount(2);
0235     add(f);
0236     f = new Function("ROUND",         func_round);
0237     f->setParamCount(1, 2);
0238     add(f);
0239     f = new Function("ROUNDDOWN",     func_rounddown);
0240     f->setParamCount(1, 2);
0241     add(f);
0242     f = new Function("ROUNDUP",       func_roundup);
0243     f->setParamCount(1, 2);
0244     add(f);
0245     f = new Function("SIGN",          func_sign);
0246     add(f);
0247     f = new Function("SQRT",          func_sqrt);
0248     add(f);
0249     f = new Function("SQRTPI",        func_sqrtpi);
0250     f->setAlternateName("COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETSQRTPI");
0251     add(f);
0252     f = new Function("TRUNC",         func_trunc);
0253     f->setParamCount(1, 2);
0254     add(f);
0255 
0256     // functions that operate over arrays
0257     f = new Function("COUNT",         func_count);
0258     f->setParamCount(1, -1);
0259     f->setAcceptArray();
0260     add(f);
0261     f = new Function("COUNTA",        func_counta);
0262     f->setParamCount(1, -1);
0263     f->setAcceptArray();
0264     add(f);
0265     f = new Function("COUNTBLANK",    func_countblank);
0266     f->setParamCount(1, -1);
0267     f->setAcceptArray();
0268     add(f);
0269     f = new Function("COUNTIF",       func_countif);
0270     f->setParamCount(2);
0271     f->setAcceptArray();
0272     f->setNeedsExtra(true);
0273     add(f);
0274     f = new Function("COUNTIFS",         func_countifs);
0275     f->setParamCount(2, -1);
0276     f->setAcceptArray();
0277     f->setNeedsExtra(true);
0278     add(f);
0279     f = new Function("DIV",           func_div);
0280     f->setParamCount(1, -1);
0281     f->setAcceptArray();
0282     add(f);
0283     f = new Function("G_PRODUCT",     func_kproduct);  // Gnumeric compatibility
0284     f->setParamCount(1, -1);
0285     f->setAcceptArray();
0286     add(f);
0287     f = new Function("GCD",           func_gcd);
0288     f->setAlternateName("COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETGCD");
0289     f->setParamCount(1, -1);
0290     f->setAcceptArray();
0291     add(f);
0292     f = new Function("KPRODUCT",      func_kproduct);
0293     f->setParamCount(1, -1);
0294     f->setAcceptArray();
0295     add(f);
0296     f = new Function("LCM",           func_lcm);
0297     f->setAlternateName("COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETLCM");
0298     f->setParamCount(1, -1);
0299     f->setAcceptArray();
0300     add(f);
0301     f = new Function("MAX",           func_max);
0302     f->setParamCount(1, -1);
0303     f->setAcceptArray();
0304     add(f);
0305     f = new Function("MAXA",          func_maxa);
0306     f->setParamCount(1, -1);
0307     f->setAcceptArray();
0308     add(f);
0309     f = new Function("MDETERM",          func_mdeterm);
0310     f->setParamCount(1);
0311     f->setAcceptArray();
0312     add(f);
0313     f = new Function("MIN",           func_min);
0314     f->setParamCount(1, -1);
0315     f->setAcceptArray();
0316     add(f);
0317     f = new Function("MINA",          func_mina);
0318     f->setParamCount(1, -1);
0319     f->setAcceptArray();
0320     add(f);
0321     f = new Function("MINVERSE",         func_minverse);
0322     f->setParamCount(1);
0323     f->setAcceptArray();
0324     add(f);
0325     f = new Function("MMULT",          func_mmult);
0326     f->setParamCount(2);
0327     f->setAcceptArray();
0328     add(f);
0329     f = new Function("MULTIPLY",      func_product);   // same as PRODUCT
0330     f->setParamCount(1, -1);
0331     f->setAcceptArray();
0332     add(f);
0333     f = new Function("MUNIT",         func_munit);
0334     f->setParamCount(1);
0335     add(f);
0336     f = new Function("PRODUCT",       func_product);
0337     f->setParamCount(1, -1);
0338     f->setAcceptArray();
0339     add(f);
0340     f = new Function("SERIESSUM",     func_seriessum);
0341     f->setParamCount(3, -1);
0342     f->setAcceptArray();
0343     add(f);
0344     f = new Function("SUM",           func_sum);
0345     f->setParamCount(1, -1);
0346     f->setAcceptArray();
0347     add(f);
0348     f = new Function("SUMA",          func_suma);
0349     f->setParamCount(1, -1);
0350     f->setAcceptArray();
0351     add(f);
0352     f = new Function("SUBTOTAL",      func_subtotal);
0353     f->setParamCount(2);
0354     f->setAcceptArray();
0355     f->setNeedsExtra(true);
0356     add(f);
0357     f = new Function("SUMIF",         func_sumif);
0358     f->setParamCount(2, 3);
0359     f->setAcceptArray();
0360     f->setNeedsExtra(true);
0361     add(f);
0362     f = new Function("SUMIFS",         func_sumifs);
0363     f->setParamCount(3, -1);
0364     f->setAcceptArray();
0365     f->setNeedsExtra(true);
0366     add(f);
0367     f = new Function("SUMSQ",         func_sumsq);
0368     f->setParamCount(1, -1);
0369     f->setAcceptArray();
0370     add(f);
0371     f = new Function("TRANSPOSE",     func_transpose);
0372     f->setParamCount(1);
0373     f->setAcceptArray();
0374     add(f);
0375 }
0376 
0377 QString MathModule::descriptionFileName() const
0378 {
0379     return QString("math.xml");
0380 }
0381 
0382 
0383 // Function: SQRT
0384 Value func_sqrt(valVector args, ValueCalc *calc, FuncExtra *)
0385 {
0386     Value arg = args[0];
0387     if (calc->gequal(arg, Value(0.0)))
0388         return calc->sqrt(arg);
0389     else
0390         return Value::errorVALUE();
0391 }
0392 
0393 // Function: SQRTPI
0394 Value func_sqrtpi(valVector args, ValueCalc *calc, FuncExtra *)
0395 {
0396     // sqrt (val * PI)
0397     Value arg = args[0];
0398     if (calc->gequal(arg, Value(0.0)))
0399         return calc->sqrt(calc->mul(args[0], calc->pi()));
0400     else
0401         return Value::errorVALUE();
0402 }
0403 
0404 // Function: ROOTN
0405 Value func_rootn(valVector args, ValueCalc *calc, FuncExtra *)
0406 {
0407     return calc->pow(args[0], calc->div(Value(1), args[1]));
0408 }
0409 
0410 // Function: CUR
0411 Value func_cur(valVector args, ValueCalc *calc, FuncExtra *)
0412 {
0413     return calc->pow(args[0], Value(1.0 / 3.0));
0414 }
0415 
0416 // Function: ABS
0417 Value func_abs(valVector args, ValueCalc *calc, FuncExtra *)
0418 {
0419     return calc->abs(args[0]);
0420 }
0421 
0422 // Function: exp
0423 Value func_exp(valVector args, ValueCalc *calc, FuncExtra *)
0424 {
0425     return calc->exp(args[0]);
0426 }
0427 
0428 // Function: ceil
0429 Value func_ceil(valVector args, ValueCalc *calc, FuncExtra *)
0430 {
0431     return calc->roundUp(args[0], Value(0));
0432 }
0433 
0434 // Function: ceiling
0435 Value func_ceiling(valVector args, ValueCalc *calc, FuncExtra *)
0436 {
0437     Value number = args[0];
0438     Value res;
0439     if (args.count() >= 2)
0440         res = args[1];
0441     else
0442         res = calc->gequal(number, Value(0.0)) ? Value(1.0) : Value(-1.0);
0443     bool mode = (args.count() >= 3) ? calc->isZero (args[2]) : true;
0444 
0445     // short-circuit, and allow CEILING(0;0) to give 0 (which is correct)
0446     // instead of DIV0 error
0447     if (calc->isZero(number))
0448         return Value(0.0);
0449 
0450     if (calc->isZero(res))
0451         return Value::errorDIV0();
0452 
0453     Value d = calc->div(number, res);
0454     if (calc->greater(Value(0), d))
0455         return Value::errorNUM();
0456 
0457     Value rud = calc->roundDown(d);
0458     if (calc->approxEqual(rud, d))
0459         d = calc->mul(rud, res);
0460     else
0461     {
0462         // positive number or mode is 0 - round up
0463         if ((!mode) || calc->gequal (number, Value(0))) rud = calc->roundUp(d);
0464         d = calc->mul (rud, res);
0465     }
0466 
0467     return d;
0468 }
0469 
0470 // Function: FLOOR
0471 Value func_floor(valVector args, ValueCalc *calc, FuncExtra *)
0472 {
0473     if (calc->approxEqual(args[0], Value(0.0)))
0474         return Value(0);
0475     Number number = args[0].asFloat();
0476 
0477     Number significance;
0478     if (args.count() >= 2) { // we have the optional "significance" argument
0479         significance = args[1].asFloat();
0480         // Sign of number and significance must match.
0481         if (calc->gequal(args[0], Value(0.0)) != calc->gequal(args[1], Value(0.0)))
0482             return Value::errorVALUE();
0483     } else // use 1 or -1, depending on the sign of the first argument
0484         significance = calc->gequal(args[0], Value(0.0)) ? 1.0 : -1.0;
0485     if (calc->approxEqual(Value(significance), Value(0.0)))
0486         return Value(0);
0487 
0488     const bool mode = (args.count() == 3) ? (args[2].asFloat() != 0.0) : false;
0489 
0490     Number result;
0491     if (mode) // round towards zero
0492         result = ((int)(number / significance)) * significance;
0493     else { // round towards negative infinity
0494         result = number / significance; // always positive, because signs match
0495         if (calc->gequal(args[0], Value(0.0))) // positive values
0496             result = floor(result) * significance;
0497         else // negative values
0498             result = ceil(result) * significance;
0499     }
0500     return Value(result);
0501 }
0502 
0503 // Function: GAMMA
0504 Value func_gamma(valVector args, ValueCalc *calc, FuncExtra *)
0505 {
0506     return calc->GetGamma(args[0]);
0507 }
0508 
0509 // Function: ln
0510 Value func_ln(valVector args, ValueCalc *calc, FuncExtra *)
0511 {
0512     if ((args [0].isNumber() == false) || args[0].asFloat() <= 0)
0513         return Value::errorNUM();
0514     return calc->ln(args[0]);
0515 }
0516 
0517 // Function: LOGn
0518 Value func_logn(valVector args, ValueCalc *calc, FuncExtra *)
0519 {
0520     if (args [0].isError())
0521         return args [0];
0522     if (args [0].isEmpty())
0523         return Value::errorNUM();
0524     if (args [0].isNumber() == false)
0525         return Value::errorVALUE();
0526     if (args[0].asFloat() <= 0)
0527         return Value::errorNUM();
0528     if (args.count() == 2) {
0529         if (args [1].isError())
0530             return args [1];
0531         if (args [1].isEmpty())
0532             return Value::errorNUM();
0533         if (args [1].isNumber() == false)
0534             return Value::errorVALUE();
0535         if (args [1].asFloat() <= 0)
0536             return Value::errorNUM();
0537         return calc->log(args[0], args[1]);
0538     } else
0539         return calc->log(args[0]);
0540 }
0541 
0542 // Function: LOG2
0543 Value func_log2(valVector args, ValueCalc *calc, FuncExtra *)
0544 {
0545     return calc->log(args[0], Value(2.0));
0546 }
0547 
0548 // Function: LOG10
0549 Value func_log10(valVector args, ValueCalc *calc, FuncExtra *)
0550 {
0551     if (args [0].isError())
0552         return args [0];
0553     if ((args [0].isNumber() == false) || (args[0].asFloat() <= 0))
0554         return Value::errorNUM();
0555     return calc->log(args[0]);
0556 }
0557 
0558 // Function: sum
0559 Value func_sum(valVector args, ValueCalc *calc, FuncExtra *)
0560 {
0561     return calc->sum(args, false);
0562 }
0563 
0564 // Function: suma
0565 Value func_suma(valVector args, ValueCalc *calc, FuncExtra *)
0566 {
0567     return calc->sum(args, true);
0568 }
0569 
0570 // Function: SUMIF
0571 Value func_sumif(valVector args, ValueCalc *calc, FuncExtra *e)
0572 {
0573     Value checkRange = args[0];
0574     QString condition = calc->conv()->asString(args[1]).asString();
0575     Condition cond;
0576     calc->getCond(cond, Value(condition));
0577 
0578     if (args.count() == 3) {
0579         Cell sumRangeStart(e->regions[2].firstSheet(), e->regions[2].firstRange().topLeft());
0580         return calc->sumIf(sumRangeStart, checkRange, cond);
0581     } else {
0582         return calc->sumIf(checkRange, cond);
0583     }
0584 }
0585 
0586 //Function: SUMIFS
0587 Value func_sumifs(valVector args, ValueCalc *calc, FuncExtra *e)
0588 {
0589     int lim = (int) (args.count()-1)/2;
0590 
0591     QList<Value> c_Range;
0592     QStringList condition;
0593     QList<Condition> cond;
0594 
0595     c_Range.append(args.value(0));           //first element - range to be operated on
0596 
0597     for (int i = 1; i < args.count(); i += 2) {
0598         c_Range.append(args[i]);
0599         condition.append(calc->conv()->asString(args[i+1]).asString());
0600         Condition c;
0601         calc->getCond(c, Value(condition.last()));
0602         cond.append(c);
0603     }
0604     Cell sumRangeStart(e->sheet, e->ranges[2].col1, e->ranges[2].row1);
0605     return calc->sumIfs(sumRangeStart, c_Range, cond, lim);
0606 }
0607 
0608 // Function: product
0609 Value func_product(valVector args, ValueCalc *calc, FuncExtra *)
0610 {
0611     return calc->product(args, Value(0.0));
0612 }
0613 
0614 // Function: seriessum
0615 Value func_seriessum(valVector args, ValueCalc *calc, FuncExtra *)
0616 {
0617     double fX = calc->conv()->asFloat(args[0]).asFloat();
0618     double fN = calc->conv()->asFloat(args[1]).asFloat();
0619     double fM = calc->conv()->asFloat(args[2]).asFloat();
0620 
0621     if (fX == 0.0 && fN == 0.0)
0622         return Value::errorNUM();
0623 
0624     double res = 0.0;
0625 
0626     if (fX != 0.0) {
0627 
0628         for (unsigned int i = 0 ; i < args[3].count(); i++) {
0629             res += args[3].element(i).asFloat() * pow(fX, fN);
0630             fN += fM;
0631         }
0632     }
0633 
0634     return Value(res);
0635 }
0636 
0637 // Function: kproduct
0638 Value func_kproduct(valVector args, ValueCalc *calc, FuncExtra *)
0639 {
0640     return calc->product(args, Value(1.0));
0641 }
0642 
0643 // Function: DIV
0644 Value func_div(valVector args, ValueCalc *calc, FuncExtra *)
0645 {
0646     Value val = args[0];
0647     for (int i = 1; i < args.count(); ++i) {
0648         val = calc->div(val, args[i]);
0649         if (val.isError())
0650             return val;
0651     }
0652     return val;
0653 }
0654 
0655 // Function: SUMSQ
0656 Value func_sumsq(valVector args, ValueCalc *calc, FuncExtra *)
0657 {
0658     Value res;
0659     calc->arrayWalk(args, res, calc->awFunc("sumsq"), Value(0));
0660     return res;
0661 }
0662 
0663 // Function: MAX
0664 Value func_max(valVector args, ValueCalc *calc, FuncExtra *)
0665 {
0666     Value m = calc->max(args, false);
0667     return m.isEmpty() ? Value(0.0) : m;
0668 }
0669 
0670 // Function: MAXA
0671 Value func_maxa(valVector args, ValueCalc *calc, FuncExtra *)
0672 {
0673     Value m = calc->max(args);
0674     return m.isEmpty() ? Value(0.0) : m;
0675 }
0676 
0677 // Function: MIN
0678 Value func_min(valVector args, ValueCalc *calc, FuncExtra *)
0679 {
0680     Value m = calc->min(args, false);
0681     return m.isEmpty() ? Value(0.0) : m;
0682 }
0683 
0684 // Function: MINA
0685 Value func_mina(valVector args, ValueCalc *calc, FuncExtra *)
0686 {
0687     Value m = calc->min(args, true);
0688     return m.isEmpty() ? Value(0.0) : m;
0689 }
0690 
0691 // Function: INT
0692 Value func_int(valVector args, ValueCalc *calc, FuncExtra *)
0693 {
0694     return calc->conv()->asInteger(args[0]);
0695 }
0696 
0697 // Function: QUOTIENT
0698 Value func_quotient(valVector args, ValueCalc *calc, FuncExtra *)
0699 {
0700     if (calc->isZero(args[1]))
0701         return Value::errorDIV0();
0702 
0703     double res = calc->conv()->toFloat(calc->div(args[0], args[1]));
0704     if (res < 0)
0705         res = ceil(res);
0706     else
0707         res = floor(res);
0708 
0709     return Value(res);
0710 }
0711 
0712 
0713 // Function: eps
0714 Value func_eps(valVector, ValueCalc *calc, FuncExtra *)
0715 {
0716     return calc->eps();
0717 }
0718 
0719 Value func_randexp(valVector args, ValueCalc *calc, FuncExtra *)
0720 {
0721     // -1 * d * log (random)
0722     return calc->mul(calc->mul(args[0], Value(-1)), calc->random());
0723 }
0724 
0725 Value func_randbinom(valVector args, ValueCalc *calc, FuncExtra *)
0726 {
0727     // this function will not support arbitrary precision
0728 
0729     double d  = numToDouble(calc->conv()->toFloat(args[0]));
0730     int    tr = calc->conv()->toInteger(args[1]);
0731 
0732     if (d < 0 || d > 1)
0733         return Value::errorVALUE();
0734 
0735     if (tr < 0)
0736         return Value::errorVALUE();
0737 
0738     // taken from gnumeric
0739     double x = pow(1 - d, tr);
0740     double r = (double) rand() / (RAND_MAX + 1.0);
0741     double t = x;
0742     int i = 0;
0743 
0744     while (r > t) {
0745         x *= (((tr - i) * d) / ((1 + i) * (1 - d)));
0746         i++;
0747         t += x;
0748     }
0749 
0750     return Value(i);
0751 }
0752 
0753 Value func_randnegbinom(valVector args, ValueCalc *calc, FuncExtra *)
0754 {
0755     // this function will not support arbitrary precision
0756 
0757     double d  = numToDouble(calc->conv()->toFloat(args[0]));
0758     int    f = calc->conv()->toInteger(args[1]);
0759 
0760     if (d < 0 || d > 1)
0761         return Value::errorVALUE();
0762 
0763     if (f < 0)
0764         return Value::errorVALUE();
0765 
0766 
0767     // taken from Gnumeric
0768     double x = pow(d, f);
0769     double r = (double) rand() / (RAND_MAX + 1.0);
0770     double t = x;
0771     int i = 0;
0772 
0773     while (r > t) {
0774         x *= (((f + i) * (1 - d)) / (1 + i)) ;
0775         i++;
0776         t += x;
0777     }
0778 
0779     return Value(i);
0780 }
0781 
0782 Value func_randbernoulli(valVector args, ValueCalc *calc, FuncExtra *)
0783 {
0784     Value rnd = calc->random();
0785     return Value(calc->greater(rnd, args[0]) ? 1.0 : 0.0);
0786 }
0787 
0788 Value func_randnorm(valVector args, ValueCalc *calc, FuncExtra *)
0789 {
0790     Value mu = args[0];
0791     Value sigma = args[1];
0792 
0793     //using polar form of the Box-Muller transformation
0794     //refer to http://www.taygeta.com/random/gaussian.html for more info
0795 
0796     Value x1, x2, w;
0797     do {
0798         // x1,x2 = 2 * random() - 1
0799         x1 = calc->random(2.0);
0800         x2 = calc->random(2.0);
0801         x1 = calc->sub(x1, 1);
0802         x1 = calc->sub(x2, 1);
0803         w = calc->add(calc->sqr(x1), calc->sqr(x2));
0804     } while (calc->gequal(w, Value(1.0)));    // w >= 1.0
0805 
0806     //sqrt ((-2.0 * log (w)) / w) :
0807     w = calc->sqrt(calc->div(calc->mul(Value(-2.0), calc->ln(w)), w));
0808     Value res = calc->mul(x1, w);
0809 
0810     res = calc->add(calc->mul(res, sigma), mu);    // res*sigma + mu
0811     return res;
0812 }
0813 
0814 Value func_randpoisson(valVector args, ValueCalc *calc, FuncExtra *)
0815 {
0816     if (calc->lower(args[0], Value(0)))
0817         return Value::errorVALUE();
0818 
0819     // taken from Gnumeric...
0820     Value x = calc->exp(calc->mul(Value(-1), args[0]));     // e^(-A)
0821     Value r = calc->random();
0822     Value t = x;
0823     int i = 0;
0824 
0825     while (calc->greater(r, t)) {    // r > t
0826         x = calc->mul(x, calc->div(args[0], i + 1));    // x *= (A/(i+1))
0827         t = calc->add(t, x);     //t += x
0828         i++;
0829     }
0830 
0831     return Value(i);
0832 }
0833 
0834 // Function: rand
0835 Value func_rand(valVector, ValueCalc *calc, FuncExtra *)
0836 {
0837     return calc->random();
0838 }
0839 
0840 // Function: RANDBETWEEN
0841 Value func_randbetween(valVector args, ValueCalc *calc, FuncExtra *)
0842 {
0843     Value v1 = args[0];
0844     Value v2 = args[1];
0845     if (calc->greater(v2, v1)) {
0846         v1 = args[1];
0847         v2 = args[0];
0848     }
0849     return calc->add(v1, calc->random(calc->sub(v2, v1)));
0850 }
0851 
0852 // Function: POW
0853 Value func_pow(valVector args, ValueCalc *calc, FuncExtra *)
0854 {
0855     return calc->pow(args[0], args[1]);
0856 }
0857 
0858 // Function: MOD
0859 Value func_mod(valVector args, ValueCalc *calc, FuncExtra *)
0860 {
0861     return calc->mod(args[0], args[1]);
0862 }
0863 
0864 // Function: fact
0865 Value func_fact(valVector args, ValueCalc *calc, FuncExtra *)
0866 {
0867     if (args[0].isInteger() || args[0].asInteger() > 0)
0868         return calc->fact(args[0]);
0869     else
0870         return Value::errorNUM();
0871 }
0872 
0873 // Function: FACTDOUBLE
0874 Value func_factdouble(valVector args, ValueCalc *calc, FuncExtra *)
0875 {
0876     if (args[0].isInteger() || args[0].asInteger() > 0)
0877         return calc->factDouble(args[0]);
0878     else
0879         return Value::errorNUM();
0880 }
0881 
0882 // Function: MULTINOMIAL
0883 Value func_multinomial(valVector args, ValueCalc *calc, FuncExtra *)
0884 {
0885     // (a+b+c)! / a!b!c!  (any number of params possible)
0886     Value num = Value(0), den = Value(1);
0887     for (int i = 0; i < args.count(); ++i) {
0888         num = calc->add(num, args[i]);
0889         den = calc->mul(den, calc->fact(args[i]));
0890     }
0891     num = calc->fact(num);
0892     return calc->div(num, den);
0893 }
0894 
0895 // Function: sign
0896 Value func_sign(valVector args, ValueCalc *calc, FuncExtra *)
0897 {
0898     return Value(calc->sign(args[0]));
0899 }
0900 
0901 // Function: INV
0902 Value func_inv(valVector args, ValueCalc *calc, FuncExtra *)
0903 {
0904     return calc->mul(args[0], -1);
0905 }
0906 
0907 // Function: MROUND
0908 Value func_mround(valVector args, ValueCalc *calc, FuncExtra *)
0909 {
0910     Value d = args[0];
0911     Value m = args[1];
0912 
0913     // signs must be the same
0914     if ((calc->greater(d, Value(0)) && calc->lower(m, Value(0)))
0915             || (calc->lower(d, Value(0)) && calc->greater(m, Value(0))))
0916         return Value::errorVALUE();
0917 
0918     int sign = 1;
0919 
0920     if (calc->lower(d, Value(0))) {
0921         sign = -1;
0922         d = calc->mul(d, Value(-1));
0923         m = calc->mul(m, Value(-1));
0924     }
0925 
0926     // from gnumeric:
0927     Value mod = calc->mod(d, m);
0928     Value div = calc->sub(d, mod);
0929 
0930     Value result = div;
0931     if (calc->gequal(mod, calc->div(m, Value(2))))  // mod >= m/2
0932         result = calc->add(result, m);      // result += m
0933     result = calc->mul(result, sign);     // add the sign
0934 
0935     return result;
0936 }
0937 
0938 // Function: ROUNDDOWN
0939 Value func_rounddown(valVector args, ValueCalc *calc, FuncExtra *)
0940 {
0941     if (args.count() == 2) {
0942         if (calc->greater(args[0], 0.0))
0943             return calc->roundDown(args[0], args[1]);
0944         else
0945             return calc->roundUp(args[0], args[1]);
0946     }
0947 
0948     if (calc->greater(args[0], 0.0))
0949         return calc->roundDown(args[0], 0);
0950     else
0951         return calc->roundUp(args[0], 0);
0952 }
0953 
0954 // Function: ROUNDUP
0955 Value func_roundup(valVector args, ValueCalc *calc, FuncExtra *)
0956 {
0957     if (args.count() == 2) {
0958         if (calc->greater(args[0], 0.0))
0959             return calc->roundUp(args[0], args[1]);
0960         else
0961             return calc->roundDown(args[0], args[1]);
0962     }
0963 
0964     if (calc->greater(args[0], 0.0))
0965         return calc->roundUp(args[0], 0);
0966     else
0967         return calc->roundDown(args[0], 0);
0968 }
0969 
0970 // Function: ROUND
0971 Value func_round(valVector args, ValueCalc *calc, FuncExtra *)
0972 {
0973     if (args.count() == 2)
0974         return calc->round(args[0], args[1]);
0975     return calc->round(args[0], 0);
0976 }
0977 
0978 // Function: EVEN
0979 Value func_even(valVector args, ValueCalc *calc, FuncExtra *)
0980 {
0981     if (calc->greater(args[0], 0.0)) {
0982         const Value value = calc->roundUp(args[0], 0);
0983         return calc->isZero(calc->mod(value, Value(2))) ? value : calc->add(value, Value(1));
0984     } else {
0985         const Value value = calc->roundDown(args[0], 0);
0986         return calc->isZero(calc->mod(value, Value(2))) ? value : calc->sub(value, Value(1));
0987     }
0988 }
0989 
0990 // Function: ODD
0991 Value func_odd(valVector args, ValueCalc *calc, FuncExtra *)
0992 {
0993     if (calc->gequal(args[0], Value(0))) {
0994         const Value value = calc->roundUp(args[0], 0);
0995         return calc->isZero(calc->mod(value, Value(2))) ? calc->add(value, Value(1)) : value;
0996     } else {
0997         const Value value = calc->roundDown(args[0], 0);
0998         return calc->isZero(calc->mod(value, Value(2))) ? calc->add(value, Value(-1)) : value;
0999     }
1000 }
1001 
1002 Value func_trunc(valVector args, ValueCalc *calc, FuncExtra *)
1003 {
1004     Q_UNUSED(calc)
1005     Number result = args[0].asFloat();
1006     if (args.count() == 2)
1007         result = result * ::qPow(10, (int)args[1].asInteger());
1008     result = (args[0].asFloat() < 0) ? -(qint64)(-result) : (qint64)result;
1009     if (args.count() == 2)
1010         result = result * ::qPow(10, -(int)args[1].asInteger());
1011     return Value(result);
1012 }
1013 
1014 // Function: COUNT
1015 Value func_count(valVector args, ValueCalc *calc, FuncExtra *)
1016 {
1017     return Value(calc->count(args, false));
1018 }
1019 
1020 // Function: COUNTA
1021 Value func_counta(valVector args, ValueCalc *calc, FuncExtra *)
1022 {
1023     return Value(calc->count(args));
1024 }
1025 
1026 // Function: COUNTBLANK
1027 Value func_countblank(valVector args, ValueCalc *, FuncExtra *)
1028 {
1029     int cnt = 0;
1030     for (int i = 0; i < args.count(); ++i)
1031         if (args[i].isArray()) {
1032             int rows = args[i].rows();
1033             int cols = args[i].columns();
1034             for (int r = 0; r < rows; ++r)
1035                 for (int c = 0; c < cols; ++c)
1036                     if (args[i].element(c, r).isEmpty())
1037                         cnt++;
1038         } else if (args[i].isEmpty())
1039             cnt++;
1040     return Value(cnt);
1041 }
1042 
1043 // Function: COUNTIF
1044 Value func_countif(valVector args, ValueCalc *calc, FuncExtra *e)
1045 {
1046     // the first parameter must be a reference
1047     if ((e->ranges[0].col1 == -1) || (e->ranges[0].row1 == -1))
1048         return Value::errorNA();
1049 
1050     Value range = args[0];
1051     QString condition = calc->conv()->asString(args[1]).asString();
1052 
1053     Condition cond;
1054     calc->getCond(cond, Value(condition));
1055 
1056     return Value(calc->countIf(range, cond));
1057 }
1058 
1059 // Function: COUNTIFS
1060 Value func_countifs(valVector args, ValueCalc *calc, FuncExtra *e)
1061 {
1062     // the first parameter must be a reference
1063     if ((e->ranges[0].col1 == -1) || (e->ranges[0].row1 == -1))
1064         return Value::errorNA();
1065 
1066     int lim = (int) (args.count()-1)/2; 
1067 
1068     QList<Value> c_Range;
1069     QStringList condition;
1070     QList<Condition> cond;
1071 
1072     for (int i = 0; i < args.count(); i += 2) {
1073         c_Range.append(args[i]);
1074         condition.append(calc->conv()->asString(args[i+1]).asString());
1075         Condition c;
1076         calc->getCond(c, Value(condition.last()));
1077         cond.append(c);
1078     }
1079     Cell cntRangeStart(e->sheet, e->ranges[2].col1, e->ranges[2].row1);
1080     return calc->countIfs(cntRangeStart, c_Range, cond, lim);
1081 }
1082 
1083 // Function: FIB
1084 Value func_fib(valVector args, ValueCalc *calc, FuncExtra *)
1085 {
1086     /*
1087     Lucas' formula for the nth Fibonacci number F(n) is given by
1088 
1089              ((1+sqrt(5))/2)^n - ((1-sqrt(5))/2)^n
1090       F(n) = ------------------------------------- .
1091                              sqrt(5)
1092 
1093     */
1094     Value n = args[0];
1095     if (!n.isNumber())
1096         return Value::errorVALUE();
1097 
1098     if (!calc->greater(n, Value(0.0)))
1099         return Value::errorNUM();
1100 
1101     Value s = calc->sqrt(Value(5.0));
1102     // u1 = ((1+sqrt(5))/2)^n
1103     Value u1 = calc->pow(calc->div(calc->add(Value(1), s), Value(2)), n);
1104     // u2 = ((1-sqrt(5))/2)^n
1105     Value u2 = calc->pow(calc->div(calc->sub(Value(1), s), Value(2)), n);
1106 
1107     Value result = calc->div(calc->sub(u1, u2), s);
1108     return result;
1109 }
1110 
1111 static Value func_gcd_helper(const Value &val, ValueCalc *calc)
1112 {
1113     Value res(0);
1114     if (!val.isArray())
1115         return val;
1116     for (uint row = 0; row < val.rows(); ++row)
1117         for (uint col = 0; col < val.columns(); ++col) {
1118             Value v = val.element(col, row);
1119             if (v.isArray())
1120                 v = func_gcd_helper(v, calc);
1121             res = calc->gcd(res, calc->roundDown(v));
1122         }
1123     return res;
1124 }
1125 
1126 // Function: GCD
1127 Value func_gcd(valVector args, ValueCalc *calc, FuncExtra *)
1128 {
1129     Value result = Value(0);
1130     for (int i = 0; i < args.count(); ++i) {
1131         if (args[i].isArray()) {
1132             result = calc->gcd(result, func_gcd_helper(args[i], calc));
1133         } else {
1134             if (args[i].isNumber() && args[i].asInteger() >= 0) {
1135                 result = calc->gcd(result, calc->roundDown(args[i]));
1136             } else {
1137                 return Value::errorNUM();
1138             }
1139         }
1140     }
1141     return result;
1142 }
1143 
1144 static Value func_lcm_helper(const Value &val, ValueCalc *calc)
1145 {
1146     Value res = Value(0);
1147     if (!val.isArray())
1148         return val;
1149     for (unsigned int row = 0; row < val.rows(); ++row)
1150         for (unsigned int col = 0; col < val.columns(); ++col) {
1151             Value v = val.element(col, row);
1152             if (v.isArray())
1153                 v = func_lcm_helper(v, calc);
1154             res = calc->lcm(res, calc->roundDown(v));
1155         }
1156     return res;
1157 }
1158 
1159 // Function: lcm
1160 Value func_lcm(valVector args, ValueCalc *calc, FuncExtra *)
1161 {
1162     Value result = Value(0);
1163     for (int i = 0; i < args.count(); ++i) {
1164         if (args[i].isArray()) {
1165             result = calc->lcm(result, func_lcm_helper(args[i], calc));
1166         } else {
1167             if (args[i].isNumber() == false) {
1168                 return Value::errorNUM();
1169             } else {
1170                 // its a number
1171                 if (args[i].asInteger() < 0) {
1172                     return Value::errorNUM();
1173                 } else if (args[i].asInteger() == 0) {
1174                     return Value(0);
1175                 } else { // number > 0
1176                     result = calc->lcm(result, calc->roundDown(args[i]));
1177                 }
1178             }
1179         }
1180     }
1181     return result;
1182 }
1183 
1184 static Eigen::MatrixXd convert(const Value& matrix, ValueCalc *calc)
1185 {
1186     const int rows = matrix.rows(), cols = matrix.columns();
1187     Eigen::MatrixXd eMatrix(rows, cols);
1188     for (int row = 0; row < rows; ++row) {
1189         for (int col = 0; col < cols; ++col) {
1190             eMatrix(row, col) = numToDouble(calc->conv()->toFloat(matrix.element(col, row)));
1191         }
1192     }
1193     return eMatrix;
1194 }
1195 
1196 static Value convert(const Eigen::MatrixXd& eMatrix)
1197 {
1198     const int rows = eMatrix.rows(), cols = eMatrix.cols();
1199     Value matrix(Value::Array);
1200     for (int row = 0; row < rows; ++row) {
1201         for (int col = 0; col < cols; ++col) {
1202             matrix.setElement(col, row, Value(eMatrix(row, col)));
1203         }
1204     }
1205     return matrix;
1206 }
1207 
1208 // Function: MDETERM
1209 Value func_mdeterm(valVector args, ValueCalc* calc, FuncExtra*)
1210 {
1211     Value matrix = args[0];
1212     if (matrix.columns() != matrix.rows() || matrix.rows() < 1)
1213         return Value::errorVALUE();
1214 
1215     const Eigen::MatrixXd eMatrix = convert(matrix, calc);
1216 
1217     return Value(eMatrix.determinant());
1218 }
1219 
1220 // Function: MINVERSE
1221 Value func_minverse(valVector args, ValueCalc* calc, FuncExtra*)
1222 {
1223     Value matrix = args[0];
1224     if (matrix.columns() != matrix.rows() || matrix.rows() < 1)
1225         return Value::errorVALUE();
1226 
1227     Eigen::MatrixXd eMatrix = convert(matrix, calc);
1228     Eigen::FullPivLU<Eigen::MatrixXd> lu(eMatrix);
1229     if (lu.isInvertible()) {
1230         Eigen::MatrixXd eMatrixInverse = lu.inverse();
1231         return convert(eMatrixInverse);
1232     } else
1233         return Value::errorDIV0();
1234 }
1235 
1236 // Function: mmult
1237 Value func_mmult(valVector args, ValueCalc *calc, FuncExtra *)
1238 {
1239     const Eigen::MatrixXd eMatrix1 = convert(args[0], calc);
1240     const Eigen::MatrixXd eMatrix2 = convert(args[1], calc);
1241 
1242     if (eMatrix1.cols() != eMatrix2.rows())    // row/column counts must match
1243         return Value::errorVALUE();
1244 
1245     return convert(eMatrix1 * eMatrix2);
1246 }
1247 
1248 // Function: MUNIT
1249 Value func_munit(valVector args, ValueCalc* calc, FuncExtra*)
1250 {
1251     const int dim = calc->conv()->asInteger(args[0]).asInteger();
1252     if (dim < 1)
1253         return Value::errorVALUE();
1254     Value result(Value::Array);
1255     for (int row = 0; row < dim; ++row)
1256         for (int col = 0; col < dim; ++col)
1257             result.setElement(col, row, Value(col == row ? 1 : 0));
1258     return result;
1259 }
1260 
1261 // Function: SUBTOTAL
1262 // This function requires access to the Sheet and so on, because
1263 // it needs to check whether cells contain the SUBTOTAL formula or not ...
1264 // Cells containing a SUBTOTAL formula must be ignored.
1265 Value func_subtotal(valVector args, ValueCalc *calc, FuncExtra *e)
1266 {
1267     int function = calc->conv()->asInteger(args[0]).asInteger();
1268     Value range = args[1];
1269     int r1 = -1, c1 = -1, r2 = -1, c2 = -1;
1270     if (e) {
1271         r1 = e->ranges[1].row1;
1272         c1 = e->ranges[1].col1;
1273         r2 = e->ranges[1].row2;
1274         c2 = e->ranges[1].col2;
1275     }
1276 
1277     // exclude manually hidden rows. http://tools.oasis-open.org/issues/browse/OFFICE-2030
1278     bool excludeHiddenRows = false;
1279     if(function > 100) {
1280         excludeHiddenRows = true;
1281         function = function % 100; // translate e.g. 106 to 6.
1282     }
1283 
1284     // run through the cells in the selected range
1285     Value empty;
1286     if ((r1 > 0) && (c1 > 0) && (r2 > 0) && (c2 > 0)) {
1287         for (int r = r1; r <= r2; ++r) {
1288             const bool setAllEmpty = excludeHiddenRows && e->sheet->rowFormats()->isHidden(r);
1289             for (int c = c1; c <= c2; ++c) {
1290                 // put an empty value to all cells in a hidden row
1291                 if(setAllEmpty) {
1292                     range.setElement(c - c1, r - r1, empty);
1293                     continue;
1294                 }
1295                 Cell cell(e->sheet, c, r);
1296                 // put an empty value to the place of all occurrences of the SUBTOTAL function
1297                 if (!cell.isDefault() && cell.isFormula() && cell.userInput().indexOf("SUBTOTAL", 0, Qt::CaseInsensitive) != -1)
1298                     range.setElement(c - c1, r - r1, empty);
1299             }
1300         }
1301     }
1302 
1303     // Good. Now we can execute the necessary function on the range.
1304     Value res;
1305     QSharedPointer<Function> f;
1306     valVector a;
1307     switch (function) {
1308     case 1: // Average
1309         res = calc->avg(range, false);
1310         break;
1311     case 2: // Count
1312         res = Value(calc->count(range, false));
1313         break;
1314     case 3: // CountA
1315         res = Value(calc->count(range));
1316         break;
1317     case 4: // MAX
1318         res = calc->max(range, false);
1319         break;
1320     case 5: // Min
1321         res = calc->min(range, false);
1322         break;
1323     case 6: // Product
1324         res = calc->product(range, Value(0.0), false);
1325         break;
1326     case 7: // StDev
1327         res = calc->stddev(range, false);
1328         break;
1329     case 8: // StDevP
1330         res = calc->stddevP(range, false);
1331         break;
1332     case 9: // Sum
1333         res = calc->sum(range, false);
1334         break;
1335     case 10: // Var
1336         f = FunctionRepository::self()->function("VAR");
1337         if (!f) return Value::errorVALUE();
1338         a.resize(1);
1339         a[0] = range;
1340         res = f->exec(a, calc, 0);
1341         break;
1342     case 11: // VarP
1343         f = FunctionRepository::self()->function("VARP");
1344         if (!f) return Value::errorVALUE();
1345         a.resize(1);
1346         a[0] = range;
1347         res = f->exec(a, calc, 0);
1348         break;
1349     default:
1350         return Value::errorVALUE();
1351     }
1352     return res;
1353 }
1354 
1355 // Function: TRANSPOSE
1356 Value func_transpose(valVector args, ValueCalc *calc, FuncExtra *)
1357 {
1358     Q_UNUSED(calc);
1359     Value matrix = args[0];
1360     const int cols = matrix.columns();
1361     const int rows = matrix.rows();
1362 
1363     Value transpose(Value::Array);
1364     for (int row = 0; row < rows; ++row) {
1365         for (int col = 0; col < cols; ++col) {
1366             if (!matrix.element(col, row).isEmpty())
1367                 transpose.setElement(row, col, matrix.element(col, row));
1368         }
1369     }
1370     return transpose;
1371 }
1372 
1373 /*
1374 Commented out.
1375 Absolutely no idea what this thing is supposed to do.
1376 To anyone who would enable this code: it still uses koscript calls - you need
1377 to convert it to the new style prior to uncommenting.
1378 
1379 // Function: MULTIPLEOPERATIONS
1380 Value func_multipleOP (valVector args, ValueCalc *calc, FuncExtra *)
1381 {
1382   if (gCell)
1383   {
1384     context.setValue( new KSValue( ((Interpreter *) context.interpreter() )->cell()->value().asFloat() ) );
1385     return true;
1386   }
1387 
1388   gCell = ((Interpreter *) context.interpreter() )->cell();
1389 
1390   QValueList<KSValue::Ptr>& args = context.value()->listValue();
1391   QValueList<KSValue::Ptr>& extra = context.extraData()->listValue();
1392 
1393   if ( !KSUtil::checkArgumentsCount( context, 5, "MULTIPLEOPERATIONS", true ) )
1394   {
1395     gCell = 0;
1396     return false;
1397   }
1398 
1399   // 0: cell must contain formula with double/int result
1400   // 0, 1, 2, 3, 4: must contain integer/double
1401   for (int i = 0; i < 5; ++i)
1402   {
1403     if ( !KSUtil::checkType( context, args[i], KSValue::DoubleType, true ) )
1404     {
1405       gCell = 0;
1406       return false;
1407     }
1408   }
1409 
1410   //  ((Interpreter *) context.interpreter() )->document()->emitBeginOperation();
1411 
1412   double oldCol = args[1]->doubleValue();
1413   double oldRow = args[3]->doubleValue();
1414   debugSheets <<"Old values: Col:" << oldCol <<", Row:" << oldRow;
1415 
1416   Cell * cell;
1417   Sheet * sheet = ((Interpreter *) context.interpreter() )->sheet();
1418 
1419   Point point( extra[1]->stringValue() );
1420   Point point2( extra[3]->stringValue() );
1421   Point point3( extra[0]->stringValue() );
1422 
1423   if ( ( args[1]->doubleValue() != args[2]->doubleValue() )
1424        || ( args[3]->doubleValue() != args[4]->doubleValue() ) )
1425   {
1426     cell = Cell( sheet, point.pos.x(), point.pos.y() );
1427     cell->setValue( args[2]->doubleValue() );
1428     debugSheets <<"Setting value" << args[2]->doubleValue() <<" on cell" << point.pos.x()
1429               << ", " << point.pos.y() << endl;
1430 
1431     cell = Cell( sheet, point2.pos.x(), point.pos.y() );
1432     cell->setValue( args[4]->doubleValue() );
1433     debugSheets <<"Setting value" << args[4]->doubleValue() <<" on cell" << point2.pos.x()
1434               << ", " << point2.pos.y() << endl;
1435   }
1436 
1437   Cell * cell1 = Cell( sheet, point3.pos.x(), point3.pos.y() );
1438   cell1->calc( false );
1439 
1440   double d = cell1->value().asFloat();
1441   debugSheets <<"Cell:" << point3.pos.x() <<";" << point3.pos.y() <<" with value"
1442             << d << endl;
1443 
1444   debugSheets <<"Resetting old values";
1445 
1446   cell = Cell( sheet, point.pos.x(), point.pos.y() );
1447   cell->setValue( oldCol );
1448 
1449   cell = Cell( sheet, point2.pos.x(), point2.pos.y() );
1450   cell->setValue( oldRow );
1451 
1452   cell1->calc( false );
1453 
1454   // ((Interpreter *) context.interpreter() )->document()->emitEndOperation();
1455 
1456   context.setValue( new KSValue( (double) d ) );
1457 
1458   gCell = 0;
1459   return true;
1460 }
1461 
1462 */
1463 
1464 #include "math.moc"