26#include "valueconverter.h"
42Value func_confidence (valVector args, ValueCalc *calc, FuncExtra *);
43Value func_correl_pop (valVector args, ValueCalc *calc, FuncExtra *);
47Value func_expondist (valVector args, ValueCalc *calc, FuncExtra *);
50Value func_fisherinv (valVector args, ValueCalc *calc, FuncExtra *);
51Value func_gammadist (valVector args, ValueCalc *calc, FuncExtra *);
56Value func_hypgeomdist (valVector args, ValueCalc *calc, FuncExtra *);
57Value func_kurtosis_est (valVector args, ValueCalc *calc, FuncExtra *);
58Value func_kurtosis_pop (valVector args, ValueCalc *calc, FuncExtra *);
61Value func_lognormdist (valVector args, ValueCalc *calc, FuncExtra *);
64Value func_negbinomdist (valVector args, ValueCalc *calc, FuncExtra *);
73Value func_standardize (valVector args, ValueCalc *calc, FuncExtra *);
78Value func_stdnormdist (valVector args, ValueCalc *calc, FuncExtra *);
79Value func_sumproduct (valVector args, ValueCalc *calc, FuncExtra *);
85Value func_variancea (valVector args, ValueCalc *calc, FuncExtra *);
86Value func_variancep (valVector args, ValueCalc *calc, FuncExtra *);
87Value func_variancepa (valVector args, ValueCalc *calc, FuncExtra *);
90typedef TQValueList<double> List;
93void RegisterStatisticalFunctions()
95 FunctionRepository* repo = FunctionRepository::self();
98 f = new Function ( "AVEDEV", func_avedev);
99 f->setParamCount (1, -1);
100 f->setAcceptArray ();
102 f = new Function ( "AVERAGE", func_average);
103 f->setParamCount (1, -1);
104 f->setAcceptArray ();
106 f = new Function ( "AVERAGEA", func_averagea);
107 f->setParamCount (1, -1);
108 f->setAcceptArray ();
110 f = new Function ( "BETADIST", func_betadist);
111 f->setParamCount (3, 5);
113 f = new Function ( "BINO", func_bino);
114 f->setParamCount (3);
116 f = new Function ( "CHIDIST", func_chidist);
117 f->setParamCount (2);
119 f = new Function ( "COMBIN", func_combin);
120 f->setParamCount (2);
122 f = new Function ( "CONFIDENCE", func_confidence);
123 f->setParamCount (3);
125 f = new Function ( "CORREL", func_correl_pop);
126 f->setParamCount (2);
127 f->setAcceptArray ();
129 f = new Function ( "COVAR", func_covar);
130 f->setParamCount (2);
131 f->setAcceptArray ();
133 f = new Function ( "DEVSQ", func_devsq);
134 f->setParamCount (1, -1);
135 f->setAcceptArray ();
137 f = new Function ( "DEVSQA", func_devsqa);
138 f->setParamCount (1, -1);
139 f->setAcceptArray ();
141 f = new Function ( "EXPONDIST", func_expondist);
142 f->setParamCount (3);
144 f = new Function ( "FDIST", func_fdist);
145 f->setParamCount (3);
147 f = new Function ( "FISHER", func_fisher);
149 f = new Function ( "FISHERINV", func_fisherinv);
151 f = new Function ( "GAMMADIST", func_gammadist);
152 f->setParamCount (4);
154 f = new Function ( "GAMMALN", func_gammaln);
156 f = new Function ( "GAUSS", func_gauss);
158 f = new Function ( "GEOMEAN", func_geomean);
159 f->setParamCount (1, -1);
160 f->setAcceptArray ();
162 f = new Function ( "HARMEAN", func_harmean);
163 f->setParamCount (1, -1);
164 f->setAcceptArray ();
166 f = new Function ( "HYPGEOMDIST", func_hypgeomdist);
167 f->setParamCount (4);
169 f = new Function ( "INVBINO", func_bino);
171 f = new Function ( "KURT", func_kurtosis_est);
172 f->setParamCount (1, -1);
173 f->setAcceptArray ();
175 f = new Function ( "KURTP", func_kurtosis_pop);
176 f->setParamCount (1, -1);
177 f->setAcceptArray ();
179 f = new Function ( "LARGE", func_large);
180 f->setParamCount (2);
181 f->setAcceptArray ();
183 f = new Function ( "LOGINV", func_loginv);
184 f->setParamCount (3);
186 f = new Function ( "LOGNORMDIST", func_lognormdist);
187 f->setParamCount (3);
189 f = new Function ( "MEDIAN", func_median);
190 f->setParamCount (1, -1);
191 f->setAcceptArray ();
193 f = new Function ( "MODE", func_mode);
194 f->setParamCount (1, -1);
195 f->setAcceptArray ();
197 f = new Function ( "NEGBINOMDIST", func_negbinomdist);
198 f->setParamCount (3);
200 f = new Function ( "NORMDIST", func_normdist);
201 f->setParamCount (4);
203 f = new Function ( "NORMINV", func_norminv);
204 f->setParamCount (3);
206 f = new Function ( "NORMSDIST", func_stdnormdist);
208 f = new Function ( "NORMSINV", func_normsinv);
210 f = new Function ( "PEARSON", func_correl_pop);
211 f->setParamCount (2);
212 f->setAcceptArray ();
214 f = new Function ( "PERMUT", func_arrang);
215 f->setParamCount (2);
217 f = new Function ( "PHI", func_phi);
219 f = new Function ( "POISSON", func_poisson);
220 f->setParamCount (3);
222 f = new Function ( "SKEW", func_skew_est);
223 f->setParamCount (1, -1);
224 f->setAcceptArray ();
226 f = new Function ( "SKEWP", func_skew_pop);
227 f->setParamCount (1, -1);
228 f->setAcceptArray ();
230 f = new Function ( "SMALL", func_small);
231 f->setParamCount (2);
232 f->setAcceptArray ();
234 f = new Function ( "STANDARDIZE", func_standardize);
235 f->setParamCount (3);
237 f = new Function ( "STDEV", func_stddev);
238 f->setParamCount (1, -1);
239 f->setAcceptArray ();
241 f = new Function ( "STDEVA", func_stddeva);
242 f->setParamCount (1, -1);
243 f->setAcceptArray ();
245 f = new Function ( "STDEVP", func_stddevp);
246 f->setParamCount (1, -1);
247 f->setAcceptArray ();
249 f = new Function ( "STDEVPA", func_stddevpa);
250 f->setParamCount (1, -1);
251 f->setAcceptArray ();
253 f = new Function ( "SUM2XMY", func_sumxmy2);
254 f->setParamCount (2);
255 f->setAcceptArray ();
257 f = new Function ( "SUMPRODUCT", func_sumproduct);
258 f->setParamCount (2);
259 f->setAcceptArray ();
261 f = new Function ( "SUMX2PY2", func_sumx2py2);
262 f->setParamCount (2);
263 f->setAcceptArray ();
265 f = new Function ( "SUMX2MY2", func_sumx2my2);
266 f->setParamCount (2);
267 f->setAcceptArray ();
269 f = new Function ( "TDIST", func_tdist);
270 f->setParamCount (3);
272 f = new Function ( "VARIANCE", func_variance);
273 f->setParamCount (1, -1);
274 f->setAcceptArray ();
276 f = new Function ( "VAR", func_variance);
277 f->setParamCount (1, -1);
278 f->setAcceptArray ();
280 f = new Function ( "VARP", func_variancep);
281 f->setParamCount (1, -1);
282 f->setAcceptArray ();
284 f = new Function ( "VARA", func_variancea);
285 f->setParamCount (1, -1);
286 f->setAcceptArray ();
288 f = new Function ( "VARPA", func_variancepa);
289 f->setParamCount (1, -1);
290 f->setAcceptArray ();
292 f = new Function ( "WEIBULL", func_weibull);
293 f->setParamCount (4);
304 Value d = c->div (c->sub (val, avg), stdev);
306 res = c-> add (res, c->mul (d, c->mul (d, d)));
312 res = c-> add (res, c->div (1.0, val));
319 res = c-> add (res, c->abs (c->sub (val, p)));
328 Value d = c->div (c->sub (val, avg), stdev);
330 res = c-> add (res, c->pow (d, 4));
336 int number = calc->count (args);
337 Value avg = calc->avg (args);
341 Value res = calc->stddev (args, avg);
346 params.setElement (0, 0, avg);
347 params.setElement (1, 0, res);
349 calc-> arrayWalk (args, tskew, awSkew, params);
352 return calc->div (calc->div (calc->mul (tskew, number), number-1), number-2);
357 int number = calc->count (args);
358 Value avg = calc->avg (args);
362 Value res = calc->stddevP (args, avg);
367 params.setElement (0, 0, avg);
368 params.setElement (1, 0, res);
370 calc-> arrayWalk (args, tskew, awSkew, params);
373 return calc->div (tskew, number);
376class ContentSheet : public TQMap<double, int> {};
378void func_mode_helper ( Value range, ValueCalc *calc, ContentSheet &sh)
382 double d = calc->conv()->asFloat (range). asFloat();
387 for ( unsigned int row = 0; row < range. rows(); ++row)
388 for ( unsigned int col = 0; col < range. columns(); ++col) {
391 func_mode_helper (v, calc, sh);
393 double d = calc->conv()->asFloat (v). asFloat();
403 for ( unsigned int i = 0; i < args.count(); ++i)
404 func_mode_helper (args[i], calc, sh);
409 ContentSheet::iterator it;
410 for (it = sh.begin(); it != sh.end(); ++it)
411 if (it.data() > maxcount) {
413 maxcount = it.data();
424 return calc->mul (calc->sub (range1, avg1), calc->sub (range2, avg2));
426 int rows = range1. rows();
428 int rows2 = range2. rows();
430 if ((rows != rows2) || (cols != cols2))
434 for ( int row = 0; row < rows; ++row)
435 for ( int col = 0; col < cols; ++col) {
439 result = calc-> add (result,
440 func_covar_helper (v1, v2, calc, avg1, avg2));
443 result = calc-> add (result, calc->mul (calc->sub (v1, avg1),
444 calc->sub (v2, avg2)));
452 Value avg1 = calc->avg (args[0]);
453 Value avg2 = calc->avg (args[1]);
454 int number = calc->count (args[0]);
455 int number2 = calc->count (args[1]);
457 if (number2 <= 0 || number2 != number)
460 Value covar = func_covar_helper (args[0], args[1], calc, avg1, avg2);
461 return calc->div (covar, number);
464Value func_correl_pop (valVector args, ValueCalc *calc, FuncExtra *)
466 Value covar = func_covar (args, calc, 0);
467 Value stdevp1 = calc->stddevP (args[0]);
468 Value stdevp2 = calc->stddevP (args[1]);
474 return calc->div (covar, calc->mul (stdevp1, stdevp2));
478 List &array, int &number)
482 array << calc->conv()->asFloat (range). asFloat();
487 for ( unsigned int row = 0; row < range. rows(); ++row)
488 for ( unsigned int col = 0; col < range. columns(); ++col) {
491 func_array_helper (v, calc, array, number);
493 array << calc->conv()->asFloat (v). asFloat();
502 int k = calc->conv()->asInteger (args[1]). asInteger();
509 func_array_helper (args[0], calc, array, number);
515 double d = *array.at (number - k - 1);
522 int k = calc->conv()->asInteger (args[1]). asInteger();
529 func_array_helper (args[0], calc, array, number);
535 double d = *array.at (k - 1);
541 Value count = calc->count (args);
542 Value prod = calc->product (args, 1.0);
545 return calc->pow (prod, calc->div (1.0, count));
550 Value count = calc->count (args);
554 calc-> arrayWalk (args, suminv, awSumInv, 0);
555 return calc->div (suminv, count);
571 if (calc-> equal (p, 1))
573 else if (calc-> greater (p, 0)) {
574 Value gaussInv = calc->gaussinv (p);
576 result = calc->exp (calc-> add (calc->mul (s, gaussInv), m));
585 calc-> arrayWalk (args, res, calc->awFunc ( "devsq"), calc->avg (args, false));
592 calc-> arrayWalk (args, res, calc->awFunc ( "devsqa"), calc->avg (args));
596Value func_kurtosis_est (valVector args, ValueCalc *calc, FuncExtra *)
598 int count = calc->count (args);
602 Value avg = calc->avg (args);
604 calc-> arrayWalk (args, devsq, calc->awFunc ( "devsqa"), avg);
610 params.setElement (0, 0, avg);
611 params.setElement (1, 0, devsq);
613 calc-> arrayWalk (args, x4, awKurtosis, params);
615 double den = (double) (count - 2) * (count - 3);
616 double nth = (double) count * (count + 1) / ((count - 1) * den);
617 double t = 3.0 * (count - 1) * (count - 1) / den;
620 return calc->sub (calc->mul (x4, nth), t);
623Value func_kurtosis_pop (valVector args, ValueCalc *calc, FuncExtra *)
625 int count = calc->count (args);
629 Value avg = calc->avg (args);
631 calc-> arrayWalk (args, devsq, calc->awFunc ( "devsqa"), avg);
637 params.setElement (0, 0, avg);
638 params.setElement (1, 0, devsq);
640 calc-> arrayWalk (args, x4, awKurtosis, params);
643 return calc->sub (calc->div (x4, count), 3);
646Value func_standardize (valVector args, ValueCalc *calc, FuncExtra *)
656 return calc->div (calc->sub (x, m), s);
659Value func_hypgeomdist (valVector args, ValueCalc *calc, FuncExtra *)
661 int x = calc->conv()->asInteger (args[0]). asInteger();
662 int n = calc->conv()->asInteger (args[1]). asInteger();
663 int M = calc->conv()->asInteger (args[2]). asInteger();
664 int N = calc->conv()->asInteger (args[3]). asInteger();
666 if ( x < 0 || n < 0 || M < 0 || N < 0 )
669 if ( x > M || n > N )
677 return calc->div (calc->mul (d1, d2), d3);
680Value func_negbinomdist (valVector args, ValueCalc *calc, FuncExtra *)
682 int x = calc->conv()->asInteger (args[0]). asInteger();
683 int r = calc->conv()->asInteger (args[1]). asInteger();
686 if ((x + r - 1) <= 0)
693 Value d2 = calc->mul (calc->pow (p, r),
694 calc->pow (calc->sub (1, p), x));
696 return calc->mul (d1, d2);
704 if (calc-> lower (n, m))
707 if (calc-> lower (m, 0))
711 return calc-> fact (n, calc->sub (n, m));
717 return calc->avg (args, false);
723 return calc->avg (args);
730 calc-> arrayWalk (args, result, awAveDev, calc->avg (args));
741 for ( unsigned int i = 0; i < args.count(); ++i)
742 func_array_helper (args[i], calc, array, number);
745 double d = *array.at (number / 2 + number % 2);
752 int count = calc->count (args, false);
756 Value result = func_devsq (args, calc, 0);
757 return calc->div (result, count-1);
761Value func_variancea (valVector args, ValueCalc *calc, FuncExtra *)
763 int count = calc->count (args);
767 Value result = func_devsqa (args, calc, 0);
768 return calc->div (result, count-1);
772Value func_variancep (valVector args, ValueCalc *calc, FuncExtra *)
774 int count = calc->count (args, false);
778 Value result = func_devsq (args, calc, 0);
779 return calc->div (result, count);
783Value func_variancepa (valVector args, ValueCalc *calc, FuncExtra *)
785 int count = calc->count (args);
789 Value result = func_devsqa (args, calc, 0);
790 return calc->div (result, count);
796 return calc->stddev (args, false);
802 return calc->stddev (args);
808 return calc->stddevP (args, false);
814 return calc->stddevP (args);
820 return calc-> combin (args[0], args[1]);
829 Value prob = args[2];
835 Value pow1 = calc->pow (prob, m);
836 Value pow2 = calc->pow (calc->sub (1, prob), calc->sub (n, m));
837 return calc->mul (comb, calc->mul (pow1, pow2));
844 return calc-> phi (args[0]);
851 return calc->gauss (args[0]);
855Value func_gammadist (valVector args, ValueCalc *calc, FuncExtra *)
858 Value alpha = args[1];
859 Value beta = args[2];
860 int kum = calc->conv()->asInteger (args[3]). asInteger();
864 if (calc-> lower (x, 0.0) || (!calc-> greater (alpha, 0.0)) ||
869 Value G = calc->GetGamma (alpha);
871 Value pow1 = calc->pow (x, calc->sub (alpha, 1.0));
872 Value pow2 = calc->exp (calc->div (x, beta));
873 Value pow3 = calc->pow (beta, alpha);
874 result = calc->div (calc->div (calc->div (pow1, pow2), pow3), G);
877 result = calc->GetGammaDist (x, alpha, beta);
879 return Value (result);
886 Value alpha = args[1];
887 Value beta = args[2];
891 if (args.count() > 3) fA = args[3];
892 if (args.count() == 5) fB = args[4];
900 Value xx = calc->div (calc->sub (x, fA), calc->sub (fB, fA));
902 return calc->GetBeta (xx, alpha, beta);
910 Value fVal = args[0];
911 Value num = calc->div (calc-> add (fVal, 1.0), calc->sub (1.0, fVal));
912 return calc->mul (calc->ln (num), 0.5);
916Value func_fisherinv (valVector args, ValueCalc *calc, FuncExtra *) {
919 Value fVal = args[0];
921 Value ex = calc->exp (calc->mul (fVal, 2.0));
922 return calc->div (calc->sub (ex, 1.0), calc-> add (ex, 1.0));
926Value func_normdist (valVector args, ValueCalc *calc, FuncExtra *) {
930 Value sigma = args[2];
933 if (!calc-> greater (sigma, 0.0))
937 Value Y = calc->div (calc->sub (x, mue), sigma);
939 return calc->div (calc-> phi (Y), sigma);
941 return calc-> add (calc->gauss (Y), 0.5);
945Value func_lognormdist (valVector args, ValueCalc *calc, FuncExtra *) {
949 Value sigma = args[2];
955 Value Y = calc->div (calc->sub (calc->ln (x), mue), sigma);
956 return calc-> add (calc->gauss (Y), 0.5);
960Value func_stdnormdist (valVector args, ValueCalc *calc, FuncExtra *)
963 return calc-> add (calc->gauss (args[0]), 0.5);
967Value func_expondist (valVector args, ValueCalc *calc, FuncExtra *) {
970 Value lambda = args[1];
975 if (!calc-> greater (lambda, 0.0))
979 Value ex = calc->exp (calc->mul (calc->mul (lambda, -1), x));
981 if (!calc-> lower (x, 0.0))
983 result = calc->mul (lambda, ex);
988 result = calc->sub (1.0, ex);
994Value func_weibull (valVector args, ValueCalc *calc, FuncExtra *) {
998 Value alpha = args[1];
999 Value beta = args[2];
1000 Value kum = args[3];
1004 if ((!calc-> greater (alpha, 0.0)) || (!calc-> greater (beta, 0.0)) ||
1005 calc-> lower (x, 0.0))
1010 ex = calc->exp (calc->mul (calc->pow (calc->div (x, beta), alpha), -1));
1014 result = calc->div (alpha, calc->pow (beta, alpha));
1015 result = calc->mul (result, calc->mul (calc->pow (x,
1016 calc->sub (alpha, 1)), ex));
1019 result = calc->sub (1.0, ex);
1025Value func_normsinv (valVector args, ValueCalc *calc, FuncExtra *) {
1032 return calc->gaussinv (x);
1036Value func_norminv (valVector args, ValueCalc *calc, FuncExtra *) {
1039 Value mue = args[1];
1040 Value sigma = args[2];
1042 if (!calc-> greater (sigma, 0.0))
1048 return calc-> add (calc->mul (calc->gaussinv (x), sigma), mue);
1052Value func_gammaln (valVector args, ValueCalc *calc, FuncExtra *) {
1055 if (calc-> greater (args[0], 0.0))
1056 return calc->GetLogGamma (args[0]);
1061Value func_poisson (valVector args, ValueCalc *calc, FuncExtra *) {
1065 Value lambda = args[1];
1066 Value kum = args[2];
1069 if (calc-> lower (lambda, 0.0) || calc-> lower (x, 0.0))
1075 Value ex = calc->exp (calc->mul (lambda, -1));
1077 if (calc-> isZero (kum)) {
1078 if (calc-> isZero (lambda))
1082 result = calc->div (calc->mul (ex, calc->pow (lambda, x)), calc-> fact (x));
1085 if (calc-> isZero (lambda))
1091 unsigned long nEnd = calc->conv()->asInteger (x). asInteger();
1092 for ( unsigned long i = 1; i <= nEnd; i++)
1095 fFak = calc->mul (fFak, i);
1097 result = calc-> add (result, calc->div (calc->pow (lambda, i), fFak));
1099 result = calc->mul (result, ex);
1107Value func_confidence (valVector args, ValueCalc *calc, FuncExtra *) {
1109 Value alpha = args[0];
1110 Value sigma = args[1];
1114 if ((!calc-> greater (sigma, 0.0)) || (!calc-> greater (alpha, 0.0)) ||
1115 (!calc-> lower (alpha, 1.0)) || calc-> lower (n, 1))
1119 Value g = calc->gaussinv (calc->sub (1.0, calc->div (alpha, 2.0)));
1121 return calc->div (calc->mul (g, sigma), calc->sqrt (n));
1129 Value fDF = args[1];
1130 int flag = calc->conv()->asInteger (args[2]). asInteger();
1132 if (calc-> lower (fDF, 1) || calc-> lower (T, 0.0) || (flag != 1 && flag != 2))
1136 Value arg = calc->div (fDF, calc-> add (fDF, calc->sqr (T)));
1139 R = calc->mul (calc->GetBeta (arg, calc->div (fDF, 2.0), 0.5), 0.5);
1143 return calc->mul (R, 2);
1151 Value fF1 = args[1];
1152 Value fF2 = args[2];
1155 if (calc-> lower (x, 0.0) || calc-> lower (fF1, 1) || calc-> lower (fF2, 1) ||
1156 (!calc-> lower (fF1, 1.0E10)) || (!calc-> lower (fF2, 1.0E10)))
1160 Value arg = calc->div (fF2, calc-> add (fF2, calc->mul (fF1, x)));
1162 Value alpha = calc->div (fF2, 2.0);
1164 Value beta = calc->div (fF1, 2.0);
1165 return calc->GetBeta (arg, alpha, beta);
1169Value func_chidist (valVector args, ValueCalc *calc, FuncExtra *) {
1172 Value fChi = args[0];
1173 Value fDF = args[1];
1176 if (calc-> lower (fDF, 1) || (!calc-> lower (fDF, 1.0E5)) ||
1177 calc-> lower (fChi, 0.0))
1181 return calc->sub (1.0, calc->GetGammaDist (calc->div (fChi, 2.0),
1182 calc->div (fDF, 2.0), 1.0));
1191 res = c-> add (res, c->mul (v1, v2));
1197 res = c-> add (res, c-> add (c->sqr (v1), c->sqr (v2)));
1203 res = c-> add (res, c->sub (c->sqr (v1), c->sqr (v2)));
1209 res = c-> add (res, c->sqr (c->sub (v1, v2)));
1214Value func_sumproduct (valVector args, ValueCalc *calc, FuncExtra *)
1217 calc->twoArrayWalk (args[0], args[1], result, tawSumproduct);
1222Value func_sumx2py2 (valVector args, ValueCalc *calc, FuncExtra *)
1225 calc->twoArrayWalk (args[0], args[1], result, tawSumx2py2);
1230Value func_sumx2my2 (valVector args, ValueCalc *calc, FuncExtra *)
1233 calc->twoArrayWalk (args[0], args[1], result, tawSumx2my2);
1241 calc->twoArrayWalk (args[0], args[1], result, tawSumxmy2);
The ValueCalc class is used to perform all sorts of calculations.
Value phi(Value x) some statistical stuff TODO: we may want to move these over to a separate class or something,...
bool greater(const Value &a, const Value &b) numerical comparison
bool isZero(const Value &a) comparison and related
Value fact(const Value &which) some computational functions
Value combin(int n, int k) combinations
bool equal(const Value &a, const Value &b) numerical comparison
void arrayWalk(const Value &range, Value &res, arrayWalkFunc func, Value param) array/range walking
bool lower(const Value &a, const Value &b) numerical comparison
Value add(const Value &a, const Value &b) basic arithmetic operations
Provides a wrapper for cell value.
unsigned columns() const If this value is an array, return the number of columns.
Value element(unsigned column, unsigned row) const Return an element in the array value.
static const Value & errorDIV0() Returns constant reference to #DIV/0! error.
unsigned rows() const If this value is an array, return the number of rows.
bool isArray() const Returns true if the type of this value is array.
double asFloat() const Returns the floating-point value of this value.
long asInteger() const Returns the integer value of this value.
static const Value & errorVALUE() Returns constant reference to #VALUE! error.
|