00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <stdlib.h>
00024 #include <math.h>
00025 #include <float.h>
00026
00027 #include <qvaluelist.h>
00028
00029 #include <kdebug.h>
00030 #include <klocale.h>
00031
00032 #include <koscript_parser.h>
00033 #include <koscript_util.h>
00034 #include <koscript_func.h>
00035 #include <koscript_synext.h>
00036
00037 #include "kspread_functions.h"
00038 #include "kspread_functions_helper.h"
00039 #include "kspread_util.h"
00040
00041
00042 bool kspreadfunc_arrang( KSContext& context );
00043 bool kspreadfunc_average( KSContext& context );
00044 bool kspreadfunc_averagea( KSContext& context );
00045 bool kspreadfunc_avedev( KSContext& context );
00046 bool kspreadfunc_betadist( KSContext& context );
00047 bool kspreadfunc_bino( KSContext& context );
00048 bool kspreadfunc_bino_inv( KSContext& context );
00049 bool kspreadfunc_chidist( KSContext& context );
00050 bool kspreadfunc_combin( KSContext& context );
00051 bool kspreadfunc_confidence( KSContext& context );
00052 bool kspreadfunc_correl_pop( KSContext & context );
00053 bool kspreadfunc_covar( KSContext & context );
00054 bool kspreadfunc_devsq( KSContext & context );
00055 bool kspreadfunc_expondist(KSContext& context );
00056 bool kspreadfunc_fdist( KSContext& context );
00057 bool kspreadfunc_fisher( KSContext& context );
00058 bool kspreadfunc_fisherinv( KSContext& context );
00059 bool kspreadfunc_gammadist( KSContext& context );
00060 bool kspreadfunc_gammaln( KSContext& context );
00061 bool kspreadfunc_gauss(KSContext& context);
00062 bool kspreadfunc_geomean( KSContext & context );
00063 bool kspreadfunc_harmean( KSContext & context );
00064 bool kspreadfunc_hypgeomdist( KSContext & context );
00065 bool kspreadfunc_kurtosis_est( KSContext & context );
00066 bool kspreadfunc_kurtosis_pop( KSContext & context );
00067 bool kspreadfunc_large(KSContext& context );
00068 bool kspreadfunc_loginv(KSContext& context );
00069 bool kspreadfunc_lognormdist(KSContext& context );
00070 bool kspreadfunc_median( KSContext& context );
00071 bool kspreadfunc_mode( KSContext& context );
00072 bool kspreadfunc_negbinomdist( KSContext & context );
00073 bool kspreadfunc_normdist(KSContext& context );
00074 bool kspreadfunc_norminv( KSContext& context );
00075 bool kspreadfunc_normsinv( KSContext& context );
00076 bool kspreadfunc_phi(KSContext& context);
00077 bool kspreadfunc_poisson( KSContext& context );
00078 bool kspreadfunc_skew_est(KSContext& context );
00079 bool kspreadfunc_skew_pop(KSContext& context );
00080 bool kspreadfunc_small(KSContext& context );
00081 bool kspreadfunc_standardize( KSContext & context );
00082 bool kspreadfunc_stddev( KSContext& context );
00083 bool kspreadfunc_stddeva( KSContext& context );
00084 bool kspreadfunc_stddevp( KSContext& context );
00085 bool kspreadfunc_stddevpa( KSContext& context );
00086 bool kspreadfunc_stdnormdist(KSContext& context );
00087 bool kspreadfunc_sumproduct( KSContext& context );
00088 bool kspreadfunc_sumx2py2( KSContext& context );
00089 bool kspreadfunc_sumx2my2( KSContext& context );
00090 bool kspreadfunc_sumxmy2( KSContext& context );
00091 bool kspreadfunc_tdist( KSContext& context );
00092 bool kspreadfunc_variance( KSContext& context );
00093 bool kspreadfunc_variancea( KSContext& context );
00094 bool kspreadfunc_variancep( KSContext& context );
00095 bool kspreadfunc_variancepa( KSContext& context );
00096 bool kspreadfunc_weibull( KSContext& context );
00097
00098 typedef QValueList<double> List;
00099
00100
00101 void KSpreadRegisterStatisticalFunctions()
00102 {
00103 KSpreadFunctionRepository* repo = KSpreadFunctionRepository::self();
00104
00105
00106 repo->registerFunction( "AVEDEV", kspreadfunc_avedev );
00107 repo->registerFunction( "AVERAGE", kspreadfunc_average );
00108 repo->registerFunction( "AVERAGEA", kspreadfunc_averagea );
00109 repo->registerFunction( "BETADIST", kspreadfunc_betadist );
00110 repo->registerFunction( "BINO", kspreadfunc_bino );
00111 repo->registerFunction( "CHIDIST", kspreadfunc_chidist );
00112 repo->registerFunction( "COMBIN", kspreadfunc_combin );
00113 repo->registerFunction( "CONFIDENCE", kspreadfunc_confidence );
00114 repo->registerFunction( "CORREL", kspreadfunc_correl_pop );
00115 repo->registerFunction( "COVAR", kspreadfunc_covar );
00116 repo->registerFunction( "DEVSQ", kspreadfunc_devsq );
00117 repo->registerFunction( "EXPONDIST", kspreadfunc_expondist );
00118 repo->registerFunction( "FDIST", kspreadfunc_fdist );
00119 repo->registerFunction( "FISHER", kspreadfunc_fisher );
00120 repo->registerFunction( "FISHERINV", kspreadfunc_fisherinv );
00121 repo->registerFunction( "GAMMADIST", kspreadfunc_gammadist );
00122 repo->registerFunction( "GAMMALN", kspreadfunc_gammaln );
00123 repo->registerFunction( "GAUSS", kspreadfunc_gauss );
00124 repo->registerFunction( "GEOMEAN", kspreadfunc_geomean );
00125 repo->registerFunction( "HARMEAN", kspreadfunc_harmean );
00126 repo->registerFunction( "HYPGEOMDIST", kspreadfunc_hypgeomdist );
00127 repo->registerFunction( "INVBINO", kspreadfunc_bino_inv );
00128 repo->registerFunction( "LARGE", kspreadfunc_large );
00129 repo->registerFunction( "LOGINV", kspreadfunc_loginv );
00130 repo->registerFunction( "LOGNORMDIST", kspreadfunc_lognormdist );
00131 repo->registerFunction( "KURT", kspreadfunc_kurtosis_est );
00132 repo->registerFunction( "KURTP", kspreadfunc_kurtosis_pop );
00133 repo->registerFunction( "MEDIAN", kspreadfunc_median );
00134 repo->registerFunction( "MODE", kspreadfunc_mode );
00135 repo->registerFunction( "NEGBINOMDIST", kspreadfunc_negbinomdist );
00136 repo->registerFunction( "NORMDIST", kspreadfunc_normdist );
00137 repo->registerFunction( "NORMINV", kspreadfunc_norminv );
00138 repo->registerFunction( "NORMSDIST", kspreadfunc_stdnormdist );
00139 repo->registerFunction( "NORMSINV", kspreadfunc_normsinv );
00140 repo->registerFunction( "PEARSON", kspreadfunc_correl_pop );
00141 repo->registerFunction( "PERMUT", kspreadfunc_arrang );
00142 repo->registerFunction( "PHI", kspreadfunc_phi );
00143 repo->registerFunction( "POISSON", kspreadfunc_poisson );
00144 repo->registerFunction( "SKEW", kspreadfunc_skew_est );
00145 repo->registerFunction( "SKEWP", kspreadfunc_skew_pop );
00146 repo->registerFunction( "SMALL", kspreadfunc_small );
00147 repo->registerFunction( "STANDARDIZE", kspreadfunc_standardize );
00148 repo->registerFunction( "STDEV", kspreadfunc_stddev );
00149 repo->registerFunction( "STDEVA", kspreadfunc_stddeva );
00150 repo->registerFunction( "STDEVP", kspreadfunc_stddevp );
00151 repo->registerFunction( "STDEVPA", kspreadfunc_stddevpa );
00152 repo->registerFunction( "SUM2XMY", kspreadfunc_sumxmy2 );
00153 repo->registerFunction( "SUMPRODUCT", kspreadfunc_sumproduct );
00154 repo->registerFunction( "SUMX2PY2", kspreadfunc_sumx2py2 );
00155 repo->registerFunction( "SUMX2MY2", kspreadfunc_sumx2my2 );
00156 repo->registerFunction( "TDIST", kspreadfunc_tdist );
00157 repo->registerFunction( "VARIANCE", kspreadfunc_variance );
00158 repo->registerFunction( "VAR", kspreadfunc_variance );
00159 repo->registerFunction( "VARP", kspreadfunc_variancep );
00160 repo->registerFunction( "VARA", kspreadfunc_variancea );
00161 repo->registerFunction( "VARPA", kspreadfunc_variancepa );
00162 repo->registerFunction( "WEIBULL", kspreadfunc_weibull );
00163 }
00164
00165 bool kspreadfunc_skew_helper( KSContext & context, QValueList<KSValue::Ptr> & args, double & result,
00166 double avg, double stdev )
00167 {
00168 QValueList<KSValue::Ptr>::Iterator it = args.begin();
00169 QValueList<KSValue::Ptr>::Iterator end = args.end();
00170
00171 for( ; it != end; ++it )
00172 {
00173 if ( KSUtil::checkType( context, *it, KSValue::ListType, false ) )
00174 {
00175 if ( !kspreadfunc_skew_helper( context, (*it)->listValue(), result, avg, stdev ) )
00176 return false;
00177 }
00178 else if ( KSUtil::checkType( context, *it, KSValue::DoubleType, true ) )
00179 {
00180 double d = ( (*it)->doubleValue() - avg ) / stdev;
00181 result += d * d * d;
00182 }
00183 }
00184
00185 return true;
00186 }
00187
00188 bool kspreadfunc_skew_est( KSContext & context )
00189 {
00190 QValueList<KSValue::Ptr> & args = context.value()->listValue();
00191
00192 double tskew = 0.0;
00193
00194 int number = 0;
00195 double res = 0.0;
00196
00197 if ( !kspreadfunc_average_helper( context, args, res, number, false ) )
00198 return false;
00199
00200 if ( number < 3 )
00201 return false;
00202
00203 double avg = res / (double) number;
00204
00205 res = 0.0;
00206
00207 if ( !kspreadfunc_stddev_helper( context, args, res, avg, false ) )
00208 return false;
00209
00210 res = sqrt( res / ((double)(number - 1) ) );
00211
00212 if ( res == 0.0 )
00213 return false;
00214
00215 if ( !kspreadfunc_skew_helper( context, args, tskew, avg, res ) )
00216 return false;
00217
00218 res = ( ( tskew * number ) / ( number - 1 ) ) / ( number - 2 );
00219
00220 context.setValue( new KSValue( res ) );
00221 return true;
00222 }
00223
00224 bool kspreadfunc_skew_pop( KSContext & context )
00225 {
00226
00227 QValueList<KSValue::Ptr> & args = context.value()->listValue();
00228
00229 double tskew = 0.0;
00230
00231 int number = 0;
00232 double res = 0.0;
00233
00234 if ( !kspreadfunc_average_helper( context, args, res, number, false ) )
00235 return false;
00236
00237 if ( number < 1 )
00238 return false;
00239
00240 double avg = res / (double) number;
00241
00242 res = 0.0;
00243
00244 if ( !kspreadfunc_stddev_helper( context, args, res, avg, false ) )
00245 return false;
00246
00247 res = sqrt( res / number );
00248
00249 if ( res == 0.0 )
00250 return false;
00251
00252 if ( !kspreadfunc_skew_helper( context, args, tskew, avg, res ) )
00253 return false;
00254
00255 res = tskew / number;
00256
00257 context.setValue( new KSValue( res ) );
00258 return true;
00259 }
00260
00261 class ContentSheet : public QMap<double, int> {};
00262
00263 bool kspreadfunc_mode_helper( KSContext & context, QValueList<KSValue::Ptr> & args,
00264 ContentSheet & sheet, double & number, int & value )
00265 {
00266 QValueList<KSValue::Ptr>::Iterator it = args.begin();
00267 QValueList<KSValue::Ptr>::Iterator end = args.end();
00268
00269 ContentSheet::Iterator iter;
00270
00271 for ( ; it != end; ++it )
00272 {
00273 if ( KSUtil::checkType( context, *it, KSValue::ListType, true ) )
00274 {
00275 if ( !kspreadfunc_mode_helper( context, (*it)->listValue(), sheet, number, value ) )
00276 return false;
00277 }
00278 else
00279 if ( KSUtil::checkType( context, *it, KSValue::DoubleType, true ) )
00280 {
00281 double d = (*it)->doubleValue();
00282
00283 iter = sheet.find( d );
00284 if ( iter != sheet.end() )
00285 sheet[d] = ++(iter.data());
00286 else
00287 {
00288 sheet[d] = 1;
00289 iter = sheet.find( d );
00290 }
00291
00292 if ( iter.data() > value )
00293 {
00294 value = iter.data();
00295 number = d;
00296 }
00297 }
00298 }
00299
00300 return true;
00301 }
00302
00303 bool kspreadfunc_mode( KSContext & context )
00304 {
00305 QValueList<KSValue::Ptr> & args = context.value()->listValue();
00306
00307 double number = 0.0;
00308 int value = 1;
00309 ContentSheet sheet;
00310
00311 if ( !kspreadfunc_mode_helper( context, args, sheet, number, value ) )
00312 return false;
00313
00314 context.setValue( new KSValue( number ) );
00315 return true;
00316 }
00317
00318 bool kspreadfunc_covar_helper( KSContext & context, QValueList<KSValue::Ptr> & args1,
00319 QValueList<KSValue::Ptr> & args2,
00320 double & result, double avg1, double avg2 )
00321 {
00322 QValueList<KSValue::Ptr>::Iterator it1 = args1.begin();
00323 QValueList<KSValue::Ptr>::Iterator end = args1.end();
00324 QValueList<KSValue::Ptr>::Iterator it2 = args2.begin();
00325
00326 for( ; it1 != end; ++it1 )
00327 {
00328 if ( ( KSUtil::checkType( context, *it1, KSValue::ListType, false ) )
00329 && ( KSUtil::checkType( context, *it2, KSValue::ListType, false ) ) )
00330 {
00331 if ( !kspreadfunc_covar_helper( context, (*it1)->listValue(), (*it2)->listValue(), result, avg1, avg2 ) )
00332 return false;
00333 }
00334 else
00335 {
00336 if ( !KSUtil::checkType( context, *it1, KSValue::DoubleType, true ) )
00337 return false;
00338 if ( !KSUtil::checkType( context, *it2, KSValue::DoubleType, true ) )
00339 return false;
00340
00341 result += ( (*it1)->doubleValue() - avg1 ) * ( (*it2)->doubleValue() - avg2 );
00342 }
00343 ++it2;
00344 }
00345
00346 return true;
00347 }
00348
00349 bool kspreadfunc_correl_pop( KSContext & context )
00350 {
00351 QValueList<KSValue::Ptr> & args = context.value()->listValue();
00352
00353 if ( !KSUtil::checkArgumentsCount( context, 2, "CORREL",true ) )
00354 return false;
00355
00356 if ( !KSUtil::checkType( context, args[0], KSValue::ListType, true ) )
00357 return false;
00358
00359 if ( !KSUtil::checkType( context, args[1], KSValue::ListType, true ) )
00360 return false;
00361
00362 double res1 = 0.0;
00363 double stdevp1 = 0.0;
00364 double res2 = 0.0;
00365 double stdevp2 = 0.0;
00366 int number = 0;
00367 int number2 = 0;
00368
00369 if ( !kspreadfunc_average_helper( context, args[0]->listValue(), res1, number, false ) )
00370 return false;
00371
00372 if ( number <= 0 )
00373 return false;
00374
00375 double avg1 = res1 / (double) number;
00376
00377 if ( !kspreadfunc_average_helper( context, args[1]->listValue(), res2, number2, false ) )
00378 return false;
00379
00380 if ( number2 <= 0 || number2 != number )
00381 return false;
00382
00383 double avg2 = res2 / (double) number;
00384
00385 if ( !kspreadfunc_stddev_helper( context, args[0]->listValue(), stdevp1, avg1, false ) )
00386 return false;
00387 if ( !kspreadfunc_stddev_helper( context, args[1]->listValue(), stdevp2, avg2, false ) )
00388 return false;
00389
00390 stdevp1 = sqrt( stdevp1 / number );
00391 stdevp2 = sqrt( stdevp2 / number );
00392
00393 if ( stdevp1 == 0 || stdevp2 == 0 )
00394 return false;
00395
00396 double covar = 0.0;
00397
00398 if ( !kspreadfunc_covar_helper( context, args[0]->listValue(), args[1]->listValue(),
00399 covar, avg1, avg2 ) )
00400 return false;
00401
00402 covar = covar / number;
00403
00404 context.setValue( new KSValue( covar / ( stdevp1 * stdevp2 ) ) );
00405 return true;
00406 }
00407
00408 bool kspreadfunc_covar( KSContext & context )
00409 {
00410 QValueList<KSValue::Ptr> & args = context.value()->listValue();
00411
00412 if ( !KSUtil::checkArgumentsCount( context, 2, "COVAR",true ) )
00413 return false;
00414
00415 if ( !KSUtil::checkType( context, args[0], KSValue::ListType, true ) )
00416 return false;
00417
00418 if ( !KSUtil::checkType( context, args[1], KSValue::ListType, true ) )
00419 return false;
00420
00421 double res1 = 0.0;
00422 double res2 = 0.0;
00423 int number = 0;
00424 int number2 = 0;
00425
00426 if ( !kspreadfunc_average_helper( context, args[0]->listValue(), res1, number, false ) )
00427 return false;
00428
00429 if ( number <= 0 )
00430 return false;
00431
00432 double avg1 = res1 / (double) number;
00433
00434 if ( !kspreadfunc_average_helper( context, args[1]->listValue(), res2, number2, false ) )
00435 return false;
00436
00437 if ( number2 <= 0 || number2 != number )
00438 return false;
00439
00440 double avg2 = res2 / (double) number;
00441
00442 double covar = 0.0;
00443
00444 if ( !kspreadfunc_covar_helper( context, args[0]->listValue(), args[1]->listValue(),
00445 covar, avg1, avg2 ) )
00446 return false;
00447
00448 covar = covar / number;
00449
00450 context.setValue( new KSValue( covar ) );
00451 return true;
00452 }
00453
00454 bool kspreadfunc_array_helper( KSContext & context, QValueList<KSValue::Ptr> & args, List & array, int & number )
00455 {
00456 QValueList<KSValue::Ptr>::Iterator it = args.begin();
00457 QValueList<KSValue::Ptr>::Iterator end = args.end();
00458
00459 for ( ; it != end; ++it )
00460 {
00461 if ( KSUtil::checkType( context, *it, KSValue::ListType, true ) )
00462 {
00463 if ( !kspreadfunc_array_helper( context, (*it)->listValue(), array, number ) )
00464 return false;
00465 }
00466 else
00467 if ( KSUtil::checkType( context, *it, KSValue::DoubleType, true ) )
00468 {
00469 array << (*it)->doubleValue();
00470 ++number;
00471 }
00472 }
00473
00474 return true;
00475 }
00476
00477 bool kspreadfunc_large( KSContext & context )
00478 {
00479 QValueList<KSValue::Ptr> & args = context.value()->listValue();
00480
00481 if ( !KSUtil::checkArgumentsCount( context, 2, "LARGE", true ) )
00482 return false;
00483
00484 if ( !KSUtil::checkType( context, args[1], KSValue::IntType, true ) )
00485 return false;
00486
00487 int k = args[1]->intValue();
00488
00489 if ( !KSUtil::checkType( context, args[0], KSValue::ListType, true ) )
00490 {
00491 if ( KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) && k == 1 )
00492 {
00493 context.setValue( new KSValue( args[0]->doubleValue() ) );
00494 return true;
00495 }
00496 return false;
00497 }
00498
00499 if ( k < 1 )
00500 return false;
00501
00502 QValueList<KSValue::Ptr>::Iterator it = args[0]->listValue().begin();
00503 QValueList<KSValue::Ptr>::Iterator end = args[0]->listValue().end();
00504
00505 List array;
00506 int number = 1;
00507
00508 for ( ; it != end; ++it )
00509 {
00510 if ( KSUtil::checkType( context, *it, KSValue::ListType, true ) )
00511 {
00512 if ( !kspreadfunc_array_helper( context, (*it)->listValue(), array, number ) )
00513 return false;
00514 }
00515 else
00516 if ( KSUtil::checkType( context, *it, KSValue::DoubleType, true ) )
00517 {
00518 array << (*it)->doubleValue();
00519 ++number;
00520 }
00521 }
00522
00523 if ( k > number )
00524 return false;
00525
00526 qHeapSort( array );
00527
00528 double d = *array.at( number - k - 1 );
00529
00530 context.setValue( new KSValue( d ) );
00531 return true;
00532 }
00533
00534 bool kspreadfunc_small( KSContext & context )
00535 {
00536 QValueList<KSValue::Ptr> & args = context.value()->listValue();
00537
00538 if ( !KSUtil::checkArgumentsCount( context, 2, "SMALL", true ) )
00539 return false;
00540
00541 if ( !KSUtil::checkType( context, args[1], KSValue::IntType, true ) )
00542 return false;
00543
00544 int k = args[1]->intValue();
00545
00546 if ( !KSUtil::checkType( context, args[0], KSValue::ListType, true ) )
00547 {
00548 if ( KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) && k == 1 )
00549 {
00550 context.setValue( new KSValue( args[0]->doubleValue() ) );
00551 return true;
00552 }
00553 return false;
00554 }
00555
00556 if ( k < 1 )
00557 return false;
00558
00559 QValueList<KSValue::Ptr>::Iterator it = args[0]->listValue().begin();
00560 QValueList<KSValue::Ptr>::Iterator end = args[0]->listValue().end();
00561
00562 typedef QValueList<double> List;
00563
00564 List array;
00565
00566 int number = 1;
00567
00568 for ( ; it != end; ++it )
00569 {
00570 if ( KSUtil::checkType( context, *it, KSValue::ListType, true ) )
00571 {
00572 if ( !kspreadfunc_array_helper( context, (*it)->listValue(), array, number ) )
00573 return false;
00574 }
00575 else
00576 if ( KSUtil::checkType( context, *it, KSValue::DoubleType, true ) )
00577 {
00578 array << (*it)->doubleValue();
00579 ++number;
00580 }
00581 }
00582
00583 if ( k > number )
00584 return false;
00585
00586 qHeapSort( array );
00587
00588 context.setValue( new KSValue( (double) (*array.at( k - 1 )) ) );
00589 return true;
00590 }
00591
00592 bool kspreadfunc_geomean_helper( KSContext & context, QValueList<KSValue::Ptr> & args,
00593 double & result, int & number)
00594 {
00595 QValueList<KSValue::Ptr>::Iterator it = args.begin();
00596 QValueList<KSValue::Ptr>::Iterator end = args.end();
00597
00598 for ( ; it != end; ++it )
00599 {
00600 if ( KSUtil::checkType( context, *it, KSValue::ListType, false ) )
00601 {
00602 if ( !kspreadfunc_geomean_helper( context, (*it)->listValue(), result, number) )
00603 return false;
00604 }
00605 else if ( KSUtil::checkType( context, *it, KSValue::DoubleType, true ) )
00606 {
00607 double d = (*it)->doubleValue();
00608
00609 if ( d <= 0 )
00610 return false;
00611
00612 result *= d;
00613 ++number;
00614 }
00615 }
00616
00617 return true;
00618 }
00619
00620 bool kspreadfunc_geomean( KSContext & context )
00621 {
00622 QValueList<KSValue::Ptr> & args = context.value()->listValue();
00623
00624 int number = 0;
00625 double result = 1.0;
00626
00627 if ( !kspreadfunc_geomean_helper( context, args, result, number ) )
00628 return false;
00629
00630 if ( number == 0 )
00631 return false;
00632
00633 result = pow( result, 1.0 / number);
00634
00635 context.setValue( new KSValue( result ) );
00636 return true;
00637 }
00638
00639 bool kspreadfunc_harmean_helper( KSContext & context, QValueList<KSValue::Ptr> & args, double & result, int & number)
00640 {
00641 QValueList<KSValue::Ptr>::Iterator it = args.begin();
00642 QValueList<KSValue::Ptr>::Iterator end = args.end();
00643
00644 for( ; it != end; ++it )
00645 {
00646 if ( KSUtil::checkType( context, *it, KSValue::ListType, false ) )
00647 {
00648 if ( !kspreadfunc_harmean_helper( context, (*it)->listValue(), result, number) )
00649 return false;
00650 }
00651 else if ( KSUtil::checkType( context, *it, KSValue::DoubleType, true ) )
00652 {
00653 double d = (*it)->doubleValue();
00654
00655 if ( d <= 0 )
00656 return false;
00657
00658 result += 1 / d;
00659 ++number;
00660 }
00661 }
00662
00663 return true;
00664 }
00665
00666
00667 bool kspreadfunc_harmean( KSContext & context )
00668 {
00669 QValueList<KSValue::Ptr> & args = context.value()->listValue();
00670
00671 int number = 0;
00672 double result = 0.0;
00673
00674 if ( !kspreadfunc_harmean_helper( context, args, result, number ) )
00675 return false;
00676
00677 if ( number == 0 )
00678 return false;
00679
00680 result = number / result;
00681
00682 context.setValue( new KSValue( result ) );
00683 return true;
00684 }
00685
00686 bool kspreadfunc_loginv( KSContext & context )
00687 {
00688 QValueList<KSValue::Ptr> & args = context.value()->listValue();
00689
00690 if ( !KSUtil::checkArgumentsCount( context, 3, "LOGINV",true ) )
00691 return false;
00692
00693 if ( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
00694 return false;
00695
00696 if ( !KSUtil::checkType( context, args[1], KSValue::DoubleType, true ) )
00697 return false;
00698
00699 if ( !KSUtil::checkType( context, args[2], KSValue::DoubleType, true ) )
00700 return false;
00701
00702 double p = args[0]->doubleValue();
00703 double m = args[1]->doubleValue();
00704 double s = args[2]->doubleValue();
00705
00706 if ( p < 0 || p > 1 )
00707 return false;
00708 if ( s <= 0 )
00709 return false;
00710
00711 double result;
00712
00713 if ( p == 1 )
00714 result = HUGE_VAL;
00715 else
00716 if ( p > 0 )
00717 result = exp( gaussinv_helper( p ) * s + m );
00718 else
00719 result = 0.0;
00720
00721 context.setValue( new KSValue( result ) );
00722 return true;
00723 }
00724
00725 bool kspreadfunc_devsq_helper( KSContext & context, QValueList<KSValue::Ptr> & args, double & result, double avg )
00726 {
00727 QValueList<KSValue::Ptr>::Iterator it = args.begin();
00728 QValueList<KSValue::Ptr>::Iterator end = args.end();
00729
00730 for( ; it != end; ++it )
00731 {
00732 if ( KSUtil::checkType( context, *it, KSValue::ListType, false ) )
00733 {
00734 if ( !kspreadfunc_devsq_helper( context, (*it)->listValue(), result, avg ) )
00735 return false;
00736 }
00737 else if ( KSUtil::checkType( context, *it, KSValue::DoubleType, true ) )
00738 {
00739 double d = (*it)->doubleValue() - avg;
00740 result += d * d;
00741 }
00742 }
00743
00744 return true;
00745 }
00746
00747 bool kspreadfunc_devsq( KSContext & context )
00748 {
00749 QValueList<KSValue::Ptr> & args = context.value()->listValue();
00750
00751 double res = 0.0;
00752 int number = 0;
00753
00754 if ( !kspreadfunc_average_helper( context, args, res, number, false ) )
00755 return false;
00756
00757 if ( number == 0 )
00758 {
00759 context.setValue( new KSValue( 0.0 ) );
00760 return true;
00761 }
00762
00763 double avg = res / (double) number;
00764
00765 res = 0.0;
00766
00767 if ( !kspreadfunc_devsq_helper( context, args, res, avg ) )
00768 return false;
00769
00770 context.setValue( new KSValue( res ) );
00771 return true;
00772 }
00773
00774 bool kspreadfunc_kurt_est_helper( KSContext & context, QValueList<KSValue::Ptr> & args, double & result,
00775 double avg, double stdev )
00776 {
00777 QValueList<KSValue::Ptr>::Iterator it = args.begin();
00778 QValueList<KSValue::Ptr>::Iterator end = args.end();
00779
00780 for( ; it != end; ++it )
00781 {
00782 if ( KSUtil::checkType( context, *it, KSValue::ListType, false ) )
00783 {
00784 if ( !kspreadfunc_kurt_est_helper( context, (*it)->listValue(), result, avg, stdev ) )
00785 return false;
00786 }
00787 else if ( KSUtil::checkType( context, *it, KSValue::DoubleType, true ) )
00788 {
00789 double d = ( (*it)->doubleValue() - avg ) / stdev;
00790 result += d * d * d * d;
00791 }
00792 }
00793
00794 return true;
00795 }
00796
00797 bool kspreadfunc_kurtosis_est( KSContext & context )
00798 {
00799 QValueList<KSValue::Ptr> & args = context.value()->listValue();
00800
00801 double x4 = 0.0;
00802
00803 int number = 0;
00804 double res = 0.0;
00805
00806 if ( !kspreadfunc_average_helper( context, args, res, number, false ) )
00807 return false;
00808
00809 if ( number < 4 )
00810 return false;
00811
00812 double avg = res / (double) number;
00813
00814 if ( !kspreadfunc_stddev_helper( context, args, res, avg, false ) )
00815 return false;
00816
00817 if ( res == 0.0 )
00818 return false;
00819
00820 if ( !kspreadfunc_kurt_est_helper( context, args, x4, avg, res ) )
00821 return false;
00822
00823 double den = ( double )( number - 2 ) * ( number - 3 );
00824 double nth = ( double ) number * ( number + 1 ) / ( ( number - 1 ) * den );
00825 double t = 3.0 * ( number - 1 ) * ( number - 1 ) / den;
00826
00827 context.setValue( new KSValue( x4 * nth - t ) );
00828 return true;
00829 }
00830
00831 bool kspreadfunc_kurtosis_pop( KSContext & context )
00832 {
00833 QValueList<KSValue::Ptr> & args = context.value()->listValue();
00834
00835 double x4 = 0.0;
00836
00837 int number = 0;
00838 double res = 0.0;
00839
00840 if ( !kspreadfunc_average_helper( context, args, res, number, false ) )
00841 return false;
00842
00843 if ( number < 1 )
00844 return false;
00845
00846 double avg = res / (double) number;
00847
00848 if ( !kspreadfunc_stddev_helper( context, args, res, avg, false ) )
00849 return false;
00850
00851 if ( res == 0.0 )
00852 return false;
00853
00854 if ( !kspreadfunc_kurt_est_helper( context, args, x4, avg, res ) )
00855 return false;
00856
00857 context.setValue( new KSValue( x4 / number - 3 ) );
00858 return true;
00859 }
00860
00861 bool kspreadfunc_standardize( KSContext & context )
00862 {
00863 QValueList<KSValue::Ptr> & args = context.value()->listValue();
00864
00865 if ( !KSUtil::checkArgumentsCount( context,3, "STANDARDIZE",true ) )
00866 return false;
00867
00868 if ( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
00869 return false;
00870
00871 if ( !KSUtil::checkType( context, args[1], KSValue::DoubleType, true ) )
00872 return false;
00873
00874 if ( !KSUtil::checkType( context, args[2], KSValue::DoubleType, true ) )
00875 return false;
00876
00877
00878 double x = args[0]->doubleValue();
00879 double m = args[1]->doubleValue();
00880 double s = args[2]->doubleValue();
00881
00882 if ( s <= 0 )
00883 return false;
00884
00885 context.setValue( new KSValue( ( x - m ) / s ) );
00886 return true;
00887 }
00888
00889
00890 bool kspreadfunc_hypgeomdist( KSContext & context )
00891 {
00892 QValueList<KSValue::Ptr> & args = context.value()->listValue();
00893
00894 if ( !KSUtil::checkArgumentsCount( context,4, "HYPGEOMDIST",true ) )
00895 return false;
00896
00897 if ( !KSUtil::checkType( context, args[0], KSValue::IntType, true ) )
00898 return false;
00899
00900 if ( !KSUtil::checkType( context, args[1], KSValue::IntType, true ) )
00901 return false;
00902
00903 if ( !KSUtil::checkType( context, args[2], KSValue::IntType, true ) )
00904 return false;
00905
00906 if ( !KSUtil::checkType( context, args[3], KSValue::IntType, true ) )
00907 return false;
00908
00909 int x = args[0]->intValue();
00910 int n = args[1]->intValue();
00911 int M = args[2]->intValue();
00912 int N = args[3]->intValue();
00913
00914 if ( x < 0 || n < 0 || M < 0 || N < 0 )
00915 return false;
00916
00917 if ( x > M || n > N )
00918 return false;
00919
00920 double d1 = combin( M, x );
00921 double d2 = combin( N - M, n - x );
00922 double d3 = combin( N, n );
00923
00924 context.setValue( new KSValue( d1 * d2 / d3 ) );
00925 return true;
00926 }
00927
00928 bool kspreadfunc_negbinomdist( KSContext & context )
00929 {
00930 QValueList<KSValue::Ptr> & args = context.value()->listValue();
00931
00932 if ( !KSUtil::checkArgumentsCount( context,3, "NEGBINOMDIST",true ) )
00933 return false;
00934
00935 if ( !KSUtil::checkType( context, args[0], KSValue::IntType, true ) )
00936 return false;
00937
00938 if ( !KSUtil::checkType( context, args[1], KSValue::IntType, true ) )
00939 return false;
00940
00941 if ( !KSUtil::checkType( context, args[2], KSValue::DoubleType, true ) )
00942 return false;
00943
00944 int x = args[0]->intValue();
00945 int r = args[1]->intValue();
00946 double p = args[2]->doubleValue();
00947
00948 if ( ( x + r - 1 ) <= 0 )
00949 return false;
00950 if ( p < 0 || p > 1 )
00951 return false;
00952
00953 double d1 = combin( x + r - 1, r - 1 );
00954 double d2 = pow( p, r ) * pow( 1 - p, x );
00955
00956 context.setValue( new KSValue( d1 * d2 ) );
00957 return true;
00958 }
00959
00960
00961 bool kspreadfunc_arrang( KSContext& context )
00962 {
00963 double result;
00964 QString tmp;
00965 QValueList<KSValue::Ptr>& args = context.value()->listValue();
00966
00967 if ( !KSUtil::checkArgumentsCount( context,2, "PERMUT",true ) )
00968 return false;
00969
00970 if ( !KSUtil::checkType( context, args[0], KSValue::IntType, true ) )
00971 return false;
00972
00973 if ( !KSUtil::checkType( context, args[1], KSValue::IntType, true ) )
00974 return false;
00975
00976 tmp=i18n("Err");
00977 if((double)args[0]->intValue()<(double)args[1]->intValue())
00978 context.setValue( new KSValue(tmp ));
00979
00980 else if((double)args[1]->intValue()<0)
00981 context.setValue( new KSValue(tmp ));
00982
00983 else
00984 {
00985 result=util_fact((double)args[0]->intValue(),
00986 ((double)args[0]->intValue()-(double)args[1]->intValue()));
00987
00988
00989 if(result==-1)
00990 context.setValue( new KSValue(tmp));
00991 else
00992 context.setValue( new KSValue(result ));
00993 }
00994 return true;
00995 }
00996
00997
00998 bool kspreadfunc_average( KSContext & context )
00999 {
01000 double result = 0.0;
01001
01002 int number = 0;
01003 bool b = kspreadfunc_average_helper( context, context.value()->listValue(), result, number, false );
01004
01005 if ( number == 0 )
01006 {
01007 context.setValue( new KSValue( i18n("#DIV/0") ) );
01008 return true;
01009 }
01010
01011 if ( b )
01012 context.setValue( new KSValue( result / (double) number ) );
01013
01014 return b;
01015 }
01016
01017 static bool kspreadfunc_median_helper
01018 (KSContext& context, QValueList<KSValue::Ptr>& args,
01019 QValueList<KSValue::Ptr>& sortedList)
01020 {
01021 QValueList<KSValue::Ptr>::Iterator it = args.begin();
01022 QValueList<KSValue::Ptr>::Iterator end = args.end();
01023 bool returnVal = true;
01024
01025
01026
01027 while(it != end && returnVal)
01028 {
01029 if ( KSUtil::checkType( context, *it, KSValue::ListType, false ) )
01030 {
01031
01032 returnVal = kspreadfunc_median_helper(context, (*it)->listValue(),
01033 sortedList);
01034 }
01035 else if ( KSUtil::checkType( context, *it, KSValue::DoubleType, true ) )
01036 {
01037
01038 QValueList<KSValue::Ptr>::Iterator ptr = sortedList.begin();
01039 QValueList<KSValue::Ptr>::Iterator endPtr = sortedList.end();
01040
01041
01042 while (ptr != endPtr && (*it)->doubleValue() > (*ptr)->doubleValue())
01043 {
01044 ++ptr;
01045 }
01046 sortedList.insert(ptr, *it);
01047 }
01048 ++it;
01049 }
01050
01051 return returnVal;
01052 }
01053
01054
01055 bool kspreadfunc_median( KSContext& context )
01056 {
01057 double result = 0.0;
01058 bool worked;
01059
01060
01061
01062 QValueList<KSValue::Ptr> sortedValues;
01063
01064 worked = kspreadfunc_median_helper(context, context.value()->listValue(),
01065 sortedValues);
01066
01067 if (worked && sortedValues.size() > 0)
01068 {
01069
01070 QValueList<KSValue::Ptr>::Iterator ptr =
01071 sortedValues.at((sortedValues.size() - 1) / 2);
01072
01073
01074
01075
01076 result = (*ptr)->doubleValue();
01077 if (sortedValues.size() % 2 == 0)
01078 {
01079 ++ptr;
01080 result = (result + (*ptr)->doubleValue()) / 2;
01081 }
01082
01083 }
01084
01085 context.setValue( new KSValue(result));
01086
01087 return worked;
01088 }
01089
01090
01091 bool kspreadfunc_variance( KSContext& context )
01092 {
01093 double result = 0.0;
01094 double avera = 0.0;
01095 int number = 0;
01096 bool b = kspreadfunc_average_helper( context, context.value()->listValue(), result, number, false );
01097
01098 if ( number == 0 )
01099 return false;
01100
01101 if ( b )
01102 {
01103 avera = result / (double)number;
01104 result = 0.0;
01105 bool b = kspreadfunc_variance_helper( context, context.value()->listValue(), result, avera, false );
01106 if(b)
01107 context.setValue( new KSValue(result / (double)(number - 1) ) );
01108 }
01109
01110 return b;
01111 }
01112
01113
01114 bool kspreadfunc_variancep( KSContext& context )
01115 {
01116 double result = 0.0;
01117 double avera = 0.0;
01118 int number = 0;
01119 bool b = kspreadfunc_average_helper( context, context.value()->listValue(), result, number, false );
01120
01121 if ( number == 0 )
01122 return false;
01123
01124 if ( b )
01125 {
01126 avera = result / (double)number;
01127 result = 0.0;
01128 bool b = kspreadfunc_variance_helper( context, context.value()->listValue(), result, avera, false );
01129 if(b)
01130 context.setValue( new KSValue(result / (double)number ) );
01131 }
01132
01133 return b;
01134 }
01135
01136
01137 bool kspreadfunc_variancea( KSContext& context )
01138 {
01139 double result = 0.0;
01140 double avera = 0.0;
01141 int number = 0;
01142 bool b = kspreadfunc_average_helper( context, context.value()->listValue(), result, number, true );
01143
01144 if ( number == 0 )
01145 return false;
01146
01147 if ( b )
01148 {
01149 avera = result / (double) number;
01150 result = 0.0;
01151 bool b = kspreadfunc_variance_helper( context, context.value()->listValue(), result, avera, true );
01152 if(b)
01153 context.setValue( new KSValue( result / (double)(number - 1) ) );
01154 }
01155
01156 return b;
01157 }
01158
01159
01160 bool kspreadfunc_variancepa( KSContext& context )
01161 {
01162 double result = 0.0;
01163 double avera = 0.0;
01164 int number = 0;
01165 bool b = kspreadfunc_average_helper( context, context.value()->listValue(), result, number, true );
01166
01167 if ( number == 0 )
01168 return false;
01169
01170 if ( b )
01171 {
01172 avera = result / (double)number;
01173 result = 0.0;
01174 bool b = kspreadfunc_variance_helper( context, context.value()->listValue(), result, avera, true );
01175 if(b)
01176 context.setValue( new KSValue(result / (double)number ) );
01177 }
01178
01179 return b;
01180 }
01181
01182
01183 bool kspreadfunc_stddev( KSContext& context )
01184 {
01185 double result = 0.0;
01186 double avera = 0.0;
01187 int number = 0;
01188 bool b = kspreadfunc_average_helper( context, context.value()->listValue(), result, number, false );
01189
01190 if ( number == 0 )
01191 return false;
01192
01193 if ( b )
01194 {
01195 avera = result / number;
01196 result = 0.0;
01197 bool b = kspreadfunc_stddev_helper( context, context.value()->listValue(), result, avera, false );
01198
01199 if (b)
01200 context.setValue( new KSValue(sqrt(result / ((double)(number - 1)) )) );
01201 }
01202
01203 return b;
01204 }
01205
01206
01207 bool kspreadfunc_stddeva( KSContext & context )
01208 {
01209 double result = 0.0;
01210 double avera = 0.0;
01211 int number = 0;
01212 bool b = kspreadfunc_average_helper( context, context.value()->listValue(), result, number, true );
01213
01214 if ( number == 0 )
01215 return false;
01216
01217 if ( b )
01218 {
01219 avera = result / number;
01220 result = 0.0;
01221 bool b = kspreadfunc_stddev_helper( context, context.value()->listValue(), result, avera, true );
01222
01223 if (b)
01224 context.setValue( new KSValue(sqrt(result / ((double)(number - 1)) )) );
01225 }
01226
01227 return b;
01228 }
01229
01230
01231 bool kspreadfunc_stddevp( KSContext& context )
01232 {
01233 double result = 0.0;
01234 double avera = 0.0;
01235 int number = 0;
01236 bool b = kspreadfunc_average_helper( context, context.value()->listValue(), result, number, false );
01237
01238 if ( number == 0 )
01239 return false;
01240
01241 if ( b )
01242 {
01243 avera = result / number;
01244 result = 0.0;
01245 bool b = kspreadfunc_stddev_helper( context, context.value()->listValue(), result, avera, false );
01246 if ( b )
01247 context.setValue( new KSValue( sqrt(result / number) ) );
01248 }
01249
01250 return b;
01251 }
01252
01253
01254 bool kspreadfunc_stddevpa( KSContext& context )
01255 {
01256 double result = 0.0;
01257 double avera = 0.0;
01258 int number = 0;
01259 bool b = kspreadfunc_average_helper( context, context.value()->listValue(), result, number, true );
01260
01261 if ( number == 0 )
01262 return false;
01263
01264 if ( b )
01265 {
01266 avera = result / number;
01267 result = 0.0;
01268 bool b = kspreadfunc_stddev_helper( context, context.value()->listValue(), result, avera, true );
01269 if ( b )
01270 context.setValue( new KSValue( sqrt(result / number) ) );
01271 }
01272
01273 return b;
01274 }
01275
01276
01277 bool kspreadfunc_combin( KSContext& context )
01278 {
01279 double result;
01280 QString tmp;
01281 QValueList<KSValue::Ptr>& args = context.value()->listValue();
01282
01283 if ( !KSUtil::checkArgumentsCount( context,2, "COMBIN",true ) )
01284 return false;
01285
01286 if ( !KSUtil::checkType( context, args[0], KSValue::IntType, true ) )
01287 return false;
01288
01289 if ( !KSUtil::checkType( context, args[1], KSValue::IntType, true ) )
01290 return false;
01291
01292 tmp=i18n("Err");
01293 if((double)args[0]->intValue()<(double)args[1]->intValue())
01294 context.setValue( new KSValue(tmp ));
01295
01296 else if((double)args[1]->intValue()<0)
01297 context.setValue( new KSValue(tmp ));
01298
01299 else
01300 {
01301 result=(util_fact((double)args[0]->intValue(),
01302 ((double)args[0]->intValue()-(double)args[1]->intValue()))
01303 /util_fact((double)args[1]->intValue(),0));
01304
01305
01306 if(result==-1)
01307 context.setValue( new KSValue(tmp));
01308 else
01309 context.setValue( new KSValue(result ));
01310 }
01311 return true;
01312 }
01313
01314
01315 bool kspreadfunc_bino( KSContext& context )
01316 {
01317 double result=0;
01318 QString tmp;
01319 QValueList<KSValue::Ptr>& args = context.value()->listValue();
01320
01321 if ( !KSUtil::checkArgumentsCount( context,3, "BINO",true ) )
01322 return false;
01323
01324 if ( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
01325 return false;
01326
01327 if ( !KSUtil::checkType( context, args[1], KSValue::DoubleType, true ) )
01328 return false;
01329
01330 if ( !KSUtil::checkType( context, args[2], KSValue::DoubleType, true ) )
01331 return false;
01332
01333 tmp=i18n("Err");
01334 if(args[0]->doubleValue()<args[1]->doubleValue())
01335 context.setValue( new KSValue(tmp ));
01336
01337 else if(args[1]->doubleValue()<0)
01338 context.setValue( new KSValue(tmp ));
01339
01340
01341 else if((args[2]->doubleValue()<0)||(args[2]->doubleValue()>1))
01342 context.setValue( new KSValue(tmp ));
01343 else
01344 {
01345 result=(util_fact(args[0]->doubleValue(),
01346 (args[0]->doubleValue()-args[1]->doubleValue()))
01347 /util_fact(args[1]->doubleValue(),0));
01348
01349
01350 if(result==-1)
01351 context.setValue( new KSValue(tmp));
01352 else
01353 {
01354 result=result*pow(args[2]->doubleValue(),(int)args[1]->doubleValue())*
01355 pow((1-args[2]->doubleValue()),((int)args[0]->doubleValue()-
01356 ((int)args[1]->doubleValue())));
01357 context.setValue( new KSValue(result ));
01358 }
01359 }
01360 return true;
01361
01362
01363 }
01364
01365
01366 bool kspreadfunc_bino_inv( KSContext& context )
01367 {
01368 double result=0;
01369 QString tmp;
01370 QValueList<KSValue::Ptr>& args = context.value()->listValue();
01371
01372 if ( !KSUtil::checkArgumentsCount( context,3, "INVBINO",true ) )
01373 return false;
01374
01375 if ( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
01376 return false;
01377
01378 if ( !KSUtil::checkType( context, args[1], KSValue::DoubleType, true ) )
01379 return false;
01380
01381 if ( !KSUtil::checkType( context, args[2], KSValue::DoubleType, true ) )
01382 return false;
01383
01384 tmp=i18n("Err");
01385 if(args[0]->doubleValue()<args[1]->doubleValue())
01386 context.setValue( new KSValue(tmp ));
01387
01388 else if(args[1]->doubleValue()<0)
01389 context.setValue( new KSValue(tmp ));
01390
01391
01392 else if((args[2]->doubleValue()<0)||(args[2]->doubleValue()>1))
01393 context.setValue( new KSValue(tmp ));
01394 else
01395 {
01396 result=(util_fact(args[0]->doubleValue(),
01397 (args[0]->doubleValue()-args[1]->doubleValue()))
01398 /util_fact(args[1]->doubleValue(),0));
01399
01400
01401 if(result==-1)
01402 context.setValue( new KSValue(tmp));
01403 else
01404 {
01405 result=result*pow((1-args[2]->doubleValue()),((int)args[0]->doubleValue()-
01406 (int)args[1]->doubleValue()))*pow(args[2]->doubleValue(),(
01407 (int)args[1]->doubleValue()));
01408 context.setValue( new KSValue(result ));
01409 }
01410 }
01411 return true;
01412 }
01413
01414 static double phi_helper(double x)
01415 {
01416 return 0.39894228040143268 * exp(-(x * x) / 2.0);
01417 }
01418
01419
01420 bool kspreadfunc_phi(KSContext& context)
01421 {
01422
01423
01424 QValueList<KSValue::Ptr>& args = context.value()->listValue();
01425
01426 if ( !KSUtil::checkArgumentsCount( context, 1, "PHI", true ) )
01427 return false;
01428
01429 if ( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
01430 return false;
01431
01432 double x = args[0]->doubleValue();
01433
01434 context.setValue( new KSValue(phi_helper(x)) );
01435
01436 return true;
01437 }
01438
01439 static double taylor_helper (double* pPolynom, uint nMax, double x)
01440 {
01441 double nVal = pPolynom[nMax];
01442 for (int i = nMax-1; i >= 0; i--) {
01443 nVal = pPolynom[i] + (nVal * x);
01444 }
01445 return nVal;
01446 }
01447
01448 static double gauss_helper( double x )
01449 {
01450 double t0[] =
01451 { 0.39894228040143268, -0.06649038006690545, 0.00997355701003582,
01452 -0.00118732821548045, 0.00011543468761616, -0.00000944465625950,
01453 0.00000066596935163, -0.00000004122667415, 0.00000000227352982,
01454 0.00000000011301172, 0.00000000000511243, -0.00000000000021218 };
01455 double t2[] =
01456 { 0.47724986805182079, 0.05399096651318805, -0.05399096651318805,
01457 0.02699548325659403, -0.00449924720943234, -0.00224962360471617,
01458 0.00134977416282970, -0.00011783742691370, -0.00011515930357476,
01459 0.00003704737285544, 0.00000282690796889, -0.00000354513195524,
01460 0.00000037669563126, 0.00000019202407921, -0.00000005226908590,
01461 -0.00000000491799345, 0.00000000366377919, -0.00000000015981997,
01462 -0.00000000017381238, 0.00000000002624031, 0.00000000000560919,
01463 -0.00000000000172127, -0.00000000000008634, 0.00000000000007894 };
01464 double t4[] =
01465 { 0.49996832875816688, 0.00013383022576489, -0.00026766045152977,
01466 0.00033457556441221, -0.00028996548915725, 0.00018178605666397,
01467 -0.00008252863922168, 0.00002551802519049, -0.00000391665839292,
01468 -0.00000074018205222, 0.00000064422023359, -0.00000017370155340,
01469 0.00000000909595465, 0.00000000944943118, -0.00000000329957075,
01470 0.00000000029492075, 0.00000000011874477, -0.00000000004420396,
01471 0.00000000000361422, 0.00000000000143638, -0.00000000000045848 };
01472 double asympt[] = { -1.0, 1.0, -3.0, 15.0, -105.0 };
01473
01474 double xAbs = fabs(x);
01475 uint xShort = static_cast<uint>(floor(xAbs));
01476 double nVal = 0.0;
01477 if (xShort == 0)
01478 nVal = taylor_helper(t0, 11, (xAbs * xAbs)) * xAbs;
01479 else if ((xShort >= 1) && (xShort <= 2))
01480 nVal = taylor_helper(t2, 23, (xAbs - 2.0));
01481 else if ((xShort >= 3) && (xShort <= 4))
01482 nVal = taylor_helper(t4, 20, (xAbs - 4.0));
01483 else
01484 nVal = 0.5 + phi_helper(xAbs) * taylor_helper(asympt, 4, 1.0 / (xAbs * xAbs)) / xAbs;
01485 if (x < 0.0)
01486 return -nVal;
01487 else
01488 return nVal;
01489 }
01490
01491
01492 bool kspreadfunc_gauss(KSContext& context)
01493 {
01494
01495 QValueList<KSValue::Ptr>& args = context.value()->listValue();
01496
01497 if ( !KSUtil::checkArgumentsCount( context, 1, "GAUSS", true ) )
01498 return false;
01499
01500 if ( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
01501 return false;
01502
01503 double x = args[0]->doubleValue();
01504
01505 double tmp = gauss_helper(x);
01506
01507 context.setValue( new KSValue(tmp) );
01508
01509 return true;
01510 }
01511
01512
01513 static double GammaHelp(double& x, bool& bReflect)
01514 {
01515 double c[6] = {76.18009173, -86.50532033, 24.01409822,
01516 -1.231739516, 0.120858003E-2, -0.536382E-5};
01517 if (x >= 1.0)
01518 {
01519 bReflect = FALSE;
01520 x -= 1.0;
01521 }
01522 else
01523 {
01524 bReflect = TRUE;
01525 x = 1.0 - x;
01526 }
01527 double s, anum;
01528 s = 1.0;
01529 anum = x;
01530 for (uint i = 0; i < 6; i++)
01531 {
01532 anum += 1.0;
01533 s += c[i]/anum;
01534 }
01535 s *= 2.506628275;
01536 return s;
01537 }
01538
01539
01540 static double GetGamma(double x)
01541 {
01542 bool bReflect;
01543 double G = GammaHelp(x, bReflect);
01544 G = pow(x+5.5,x+0.5)*G/exp(x+5.5);
01545 if (bReflect)
01546 G = M_PI*x/(G*sin(M_PI*x));
01547 return G;
01548 }
01549
01550
01551 static double GetGammaDist(double x, double alpha, double beta)
01552 {
01553 if (x == 0.0)
01554 return 0.0;
01555
01556 x /= beta;
01557 double gamma = alpha;
01558
01559 double c = 0.918938533204672741;
01560 double d[10] = {
01561 0.833333333333333333E-1,
01562 -0.277777777777777778E-2,
01563 0.793650793650793651E-3,
01564 -0.595238095238095238E-3,
01565 0.841750841750841751E-3,
01566 -0.191752691752691753E-2,
01567 0.641025641025641025E-2,
01568 -0.295506535947712418E-1,
01569 0.179644372368830573,
01570 -0.139243221690590111E1
01571 };
01572
01573 double dx = x;
01574 double dgamma = gamma;
01575 int maxit = 10000;
01576
01577 double z = dgamma;
01578 double den = 1.0;
01579 while ( z < 10.0 ) {
01580 den *= z;
01581 z += 1.0;
01582 }
01583
01584 double z2 = z*z;
01585 double z3 = z*z2;
01586 double z4 = z2*z2;
01587 double z5 = z2*z3;
01588 double a = ( z - 0.5 ) * log(z) - z + c;
01589 double b = d[0]/z + d[1]/z3 + d[2]/z5 + d[3]/(z2*z5) + d[4]/(z4*z5) +
01590 d[5]/(z*z5*z5) + d[6]/(z3*z5*z5) + d[7]/(z5*z5*z5) + d[8]/(z2*z5*z5*z5);
01591
01592
01593 double sum = 1.0 / dgamma;
01594 double term = 1.0 / dgamma;
01595 double cut1 = dx - dgamma;
01596 double cut2 = dx * 10000000000.0;
01597
01598 for ( int i=1; i<=maxit; i++ ) {
01599 double ai = i;
01600 term = dx * term / ( dgamma + ai );
01601 sum += term;
01602 double cutoff = cut1 + ( cut2 * term / sum );
01603 if ( ai > cutoff ) {
01604 double t = sum;
01605
01606 return exp( dgamma * log(dx) - dx - a - b ) * t * den;
01607 }
01608 }
01609
01610 return 1.0;
01611 }
01612
01613
01614 bool kspreadfunc_gammadist( KSContext& context )
01615 {
01616
01617 QValueList<KSValue::Ptr>& args = context.value()->listValue();
01618
01619 if ( !KSUtil::checkArgumentsCount( context, 4, "GAMMADIST", true ) )
01620 return false;
01621
01622 if ( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
01623 return false;
01624 if ( !KSUtil::checkType( context, args[1], KSValue::DoubleType, true ) )
01625 return false;
01626 if ( !KSUtil::checkType( context, args[2], KSValue::DoubleType, true ) )
01627 return false;
01628 if ( !KSUtil::checkType( context, args[3], KSValue::IntType, true ) )
01629 return false;
01630
01631 double x = args[0]->doubleValue();
01632 double alpha = args[1]->doubleValue();
01633 double beta = args[2]->doubleValue();
01634 int kum = args[3]->intValue();
01635 double result;
01636
01637 if (x < 0.0 || alpha <= 0.0 || beta <= 0.0)
01638
01639
01640 return false;
01641 else if (kum == 0) {
01642 double G = GetGamma(alpha);
01643 result = pow(x,alpha-1.0)/exp(x/beta)/pow(beta,alpha)/G;
01644 }
01645 else
01646 result = GetGammaDist(x, alpha, beta);
01647
01648 context.setValue( new KSValue(result) );
01649 return true;
01650 }
01651
01652 static double GetLogGamma(double x)
01653 {
01654 bool bReflect;
01655 double G = GammaHelp(x, bReflect);
01656 G = (x+0.5)*log(x+5.5)+log(G)-(x+5.5);
01657 if (bReflect)
01658 G = log(M_PI*x)-G-log(sin(M_PI*x));
01659 return G;
01660 }
01661
01662
01663 static double beta_helper(double x, double alpha, double beta) {
01664 if (beta == 1.0)
01665 return pow(x, alpha);
01666 else if (alpha == 1.0)
01667 return 1.0 - pow(1.0-x,beta);
01668
01669 double fEps = 1.0E-8;
01670 bool bReflect;
01671 double cf, fA, fB;
01672
01673 if (x < (alpha+1.0)/(alpha+beta+1.0)) {
01674 bReflect = FALSE;
01675 fA = alpha;
01676 fB = beta;
01677 }
01678 else {
01679 bReflect = TRUE;
01680 fA = beta;
01681 fB = alpha;
01682 x = 1.0 - x;
01683 }
01684 if (x < fEps)
01685 cf = 0.0;
01686 else {
01687 double a1, b1, a2, b2, fnorm, rm, apl2m, d2m, d2m1, cfnew;
01688 a1 = 1.0; b1 = 1.0;
01689 b2 = 1.0 - (fA+fB)*x/(fA+1.0);
01690 if (b2 == 0.0) {
01691 a2 = b2;
01692 fnorm = 1.0;
01693 cf = 1.0;
01694 }
01695 else {
01696 a2 = 1.0;
01697 fnorm = 1.0/b2;
01698 cf = a2*fnorm;
01699 }
01700 cfnew = 1.0;
01701 for (uint j = 1; j <= 100; j++) {
01702 rm = (double) j;
01703 apl2m = fA + 2.0*rm;
01704 d2m = rm*(fB-rm)*x/((apl2m-1.0)*apl2m);
01705 d2m1 = -(fA+rm)*(fA+fB+rm)*x/(apl2m*(apl2m+1.0));
01706 a1 = (a2+d2m*a1)*fnorm;
01707 b1 = (b2+d2m*b1)*fnorm;
01708 a2 = a1 + d2m1*a2*fnorm;
01709 b2 = b1 + d2m1*b2*fnorm;
01710 if (b2 != 0.0) {
01711 fnorm = 1.0/b2;
01712 cfnew = a2*fnorm;
01713 if (fabs(cf-cfnew)/cf < fEps)
01714 j = 101;
01715 else
01716 cf = cfnew;
01717 }
01718 }
01719 if (fB < fEps)
01720 b1 = 1.0E30;
01721 else
01722 b1 = exp(GetLogGamma(fA)+GetLogGamma(fB)-GetLogGamma(fA+fB));
01723
01724 cf *= pow(x, fA)*pow(1.0-x,fB)/(fA*b1);
01725 }
01726 if (bReflect)
01727 return 1.0-cf;
01728 else
01729 return cf;
01730 }
01731
01732
01733 bool kspreadfunc_betadist( KSContext& context ) {
01734 QValueList<KSValue::Ptr>& args = context.value()->listValue();
01735
01736 double fA, fB;
01737 fA = 0.0;
01738 fB = 1.0;
01739
01740 if ( KSUtil::checkArgumentsCount( context, 5, "BETADIST", false ) ) {
01741 if( KSUtil::checkType( context, args[3], KSValue::DoubleType, false ) )
01742 fA = args[3]->doubleValue();
01743 if( KSUtil::checkType( context, args[4], KSValue::DoubleType, false ) )
01744 fB = args[4]->doubleValue();
01745 }
01746 else if ( KSUtil::checkArgumentsCount( context, 4, "BETADIST", false ) ) {
01747 if( KSUtil::checkType( context, args[3], KSValue::DoubleType, false ) )
01748 fA = args[3]->doubleValue();
01749 }
01750 else if (!KSUtil::checkArgumentsCount( context, 3, "BETADIST", false ) )
01751 return false;
01752
01753 double x, alpha, beta;
01754 x = args[0]->doubleValue();
01755 alpha = args[1]->doubleValue();
01756 beta = args[2]->doubleValue();
01757
01758 if (x < fA || x > fB || fA == fB || alpha <= 0.0 || beta <= 0.0) {
01759 return false;
01760 }
01761 x = (x-fA)/(fB-fA);
01762
01763 context.setValue( new KSValue( beta_helper(x, alpha, beta) ));
01764 return true;
01765 }
01766
01767
01768 bool kspreadfunc_fisher( KSContext& context ) {
01769
01770 QValueList<KSValue::Ptr>& args = context.value()->listValue();
01771
01772 if ( !KSUtil::checkArgumentsCount( context, 1, "FISHER", true ) )
01773 return false;
01774
01775 if ( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
01776 return false;
01777
01778 double fVal = args[0]->doubleValue();
01779
01780 context.setValue( new KSValue(0.5*log((1.0+fVal)/(1.0-fVal))));
01781 return true;
01782 }
01783
01784
01785 bool kspreadfunc_fisherinv( KSContext& context ) {
01786
01787 QValueList<KSValue::Ptr>& args = context.value()->listValue();
01788
01789 if ( !KSUtil::checkArgumentsCount( context, 1, "FISHERINV", true ) )
01790 return false;
01791
01792 if ( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
01793 return false;
01794
01795 double fVal = args[0]->doubleValue();
01796
01797 context.setValue( new KSValue((exp(2.0*fVal)-1.0)/(exp(2.0*fVal)+1.0)));
01798 return true;
01799 }
01800
01801
01802 bool kspreadfunc_normdist(KSContext& context ) {
01803
01804 QValueList<KSValue::Ptr>& args = context.value()->listValue();
01805
01806 if ( !KSUtil::checkArgumentsCount( context, 4, "NORMDIST", true ) )
01807 return false;
01808
01809 if ( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
01810 return false;
01811 if ( !KSUtil::checkType( context, args[1], KSValue::DoubleType, true ) )
01812 return false;
01813 if ( !KSUtil::checkType( context, args[2], KSValue::DoubleType, true ) )
01814 return false;
01815 if ( !KSUtil::checkType( context, args[3], KSValue::IntType, true ) )
01816 return false;
01817
01818 double x = args[0]->doubleValue();
01819 double mue = args[1]->doubleValue();
01820 double sigma = args[2]->doubleValue();
01821 double k = args[3]->intValue();
01822
01823 if (sigma <= 0.0)
01824 return false;
01825 else if (k == 0)
01826 context.setValue( new KSValue(phi_helper((x-mue)/sigma)/sigma));
01827 else
01828 context.setValue( new KSValue(0.5 + gauss_helper((x-mue)/sigma)));
01829
01830 return true;
01831 }
01832
01833
01834 bool kspreadfunc_lognormdist(KSContext& context ) {
01835
01836 QValueList<KSValue::Ptr>& args = context.value()->listValue();
01837
01838 if ( !KSUtil::checkArgumentsCount( context, 3, "LOGNORMDIST", true ) )
01839 return false;
01840
01841 if ( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
01842 return false;
01843 if ( !KSUtil::checkType( context, args[1], KSValue::DoubleType, true ) )
01844 return false;
01845 if ( !KSUtil::checkType( context, args[2], KSValue::DoubleType, true ) )
01846 return false;
01847
01848 double x = args[0]->doubleValue();
01849 double mue = args[1]->doubleValue();
01850 double sigma = args[2]->doubleValue();
01851
01852 if (sigma <= 0.0 || x <= 0.0)
01853 return false;
01854 else
01855 context.setValue( new KSValue(0.5 + gauss_helper((log(x)-mue)/sigma)));
01856
01857 return true;
01858 }
01859
01860
01861 bool kspreadfunc_stdnormdist(KSContext& context )
01862 {
01863
01864 QValueList<KSValue::Ptr>& args = context.value()->listValue();
01865
01866 if ( !KSUtil::checkArgumentsCount( context, 1, "NORMSDIST", true ) )
01867 return false;
01868
01869 if ( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
01870 return false;
01871
01872 double x = args[0]->doubleValue();
01873
01874 context.setValue( new KSValue(0.5 + gauss_helper(x)));
01875 return true;
01876 }
01877
01878
01879 bool kspreadfunc_expondist(KSContext& context ) {
01880
01881 QValueList<KSValue::Ptr>& args = context.value()->listValue();
01882
01883 if ( !KSUtil::checkArgumentsCount( context, 3, "EXPONDIST", true ) )
01884 return false;
01885
01886 if ( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
01887 return false;
01888 if ( !KSUtil::checkType( context, args[1], KSValue::DoubleType, true ) )
01889 return false;
01890 if ( !KSUtil::checkType( context, args[2], KSValue::IntType, true ) )
01891 return false;
01892
01893 double x = args[0]->doubleValue();
01894 double lambda = args[1]->doubleValue();
01895 double kum = args[2]->intValue();
01896
01897 double result;
01898
01899 if (lambda <= 0.0)
01900 return false;
01901 else if (kum == 0) {
01902 if (x >= 0.0)
01903 result = lambda * exp(-lambda*x);
01904 else
01905 result = 0;
01906 }
01907 else {
01908 if (x > 0.0)
01909 result = 1.0 - exp(-lambda*x);
01910 else
01911 result = 0;
01912 }
01913
01914 context.setValue( new KSValue(result));
01915 return true;
01916 }
01917
01918
01919 bool kspreadfunc_weibull( KSContext& context ) {
01920
01921 QValueList<KSValue::Ptr>& args = context.value()->listValue();
01922
01923 if ( !KSUtil::checkArgumentsCount( context, 4, "WEIBULL", true ) )
01924 return false;
01925
01926 if ( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
01927 return false;
01928 if ( !KSUtil::checkType( context, args[1], KSValue::DoubleType, true ) )
01929 return false;
01930 if ( !KSUtil::checkType( context, args[2], KSValue::DoubleType, true ) )
01931 return false;
01932 if ( !KSUtil::checkType( context, args[3], KSValue::IntType, true ) )
01933 return false;
01934
01935 double x = args[0]->doubleValue();
01936 double alpha = args[1]->doubleValue();
01937 double beta = args[2]->doubleValue();
01938 double kum = args[3]->intValue();
01939
01940 double result;
01941
01942 if (alpha <= 0.0 || beta <= 0.0 || x < 0.0)
01943 return false;
01944 else if (kum == 0)
01945 result = alpha / pow(beta,alpha) * pow(x,alpha-1.0) * exp(-pow(x/beta,alpha));
01946 else
01947 result = 1.0 - exp(-pow(x/beta,alpha));
01948
01949 context.setValue( new KSValue(result));
01950 return true;
01951 }
01952
01953
01954 bool kspreadfunc_normsinv( KSContext& context ) {
01955
01956
01957 QValueList<KSValue::Ptr>& args = context.value()->listValue();
01958
01959 if ( !KSUtil::checkArgumentsCount( context, 1, "NORMSINV", true ) )
01960 return false;
01961
01962 if ( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
01963 return false;
01964
01965 double x = args[0]->doubleValue();
01966
01967 if (x <= 0.0 || x >= 1.0)
01968 return false;
01969 else
01970 context.setValue( new KSValue(gaussinv_helper(x)));
01971
01972 return true;
01973 }
01974
01975
01976 bool kspreadfunc_norminv( KSContext& context ) {
01977
01978 QValueList<KSValue::Ptr>& args = context.value()->listValue();
01979
01980 if ( !KSUtil::checkArgumentsCount( context, 3, "NORMINV", true ) )
01981 return false;
01982
01983 if ( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
01984 return false;
01985 if ( !KSUtil::checkType( context, args[1], KSValue::DoubleType, true ) )
01986 return false;
01987 if ( !KSUtil::checkType( context, args[2], KSValue::DoubleType, true ) )
01988 return false;
01989
01990 double x = args[0]->doubleValue();
01991 double mue = args[1]->doubleValue();
01992 double sigma = args[2]->doubleValue();
01993
01994 if (sigma <= 0.0 || x <= 0.0 || x >= 1.0)
01995 return false;
01996 else
01997 context.setValue( new KSValue((gaussinv_helper(x)*sigma + mue)));
01998
01999 return true;
02000 }
02001
02002
02003 bool kspreadfunc_gammaln( KSContext& context ) {
02004
02005 QValueList<KSValue::Ptr>& args = context.value()->listValue();
02006
02007 if ( !KSUtil::checkArgumentsCount( context, 1, "GAMMALN", true ) )
02008 return false;
02009
02010 if ( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
02011 return false;
02012
02013 double x = args[0]->doubleValue();
02014
02015 if (x > 0.0)
02016 context.setValue( new KSValue(GetLogGamma(x)));
02017 else
02018 return false;
02019
02020 return true;
02021 }
02022
02023
02024 bool kspreadfunc_poisson( KSContext& context ) {
02025
02026 QValueList<KSValue::Ptr>& args = context.value()->listValue();
02027
02028 if ( !KSUtil::checkArgumentsCount( context, 3, "POISSON", true ) )
02029 return false;
02030
02031 if ( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
02032 return false;
02033 if ( !KSUtil::checkType( context, args[1], KSValue::DoubleType, true ) )
02034 return false;
02035 if ( !KSUtil::checkType( context, args[2], KSValue::IntType, true ) )
02036 return false;
02037
02038 double x = args[0]->doubleValue();
02039 double lambda = args[1]->doubleValue();
02040 double kum = args[2]->intValue();
02041
02042 double result;
02043
02044 if (lambda < 0.0 || x < 0.0)
02045 return false;
02046 else if (kum == 0)
02047 {
02048 if (lambda == 0.0)
02049 result = 0;
02050 else
02051 result = exp(-lambda) * pow(lambda,x) / util_fact(x,0);
02052 }
02053 else
02054 {
02055 if (lambda == 0.0)
02056 result = 1;
02057 else
02058 {
02059 double sum = 1.0;
02060 double fFak = 1.0;
02061 unsigned long nEnd = static_cast<unsigned long > (x);
02062 for (unsigned long i = 1; i <= nEnd; i++)
02063 {
02064 fFak *= static_cast<double>(i);
02065 sum += pow( lambda, static_cast<double>(i) ) / fFak;
02066 }
02067 sum *= exp(-lambda);
02068 result = sum;
02069 }
02070 }
02071
02072 context.setValue( new KSValue(result));
02073 return true;
02074 }
02075
02076
02077 bool kspreadfunc_confidence( KSContext& context ) {
02078
02079 QValueList<KSValue::Ptr>& args = context.value()->listValue();
02080
02081 if ( !KSUtil::checkArgumentsCount( context, 3, "CONFIDENCE", true ) )
02082 return false;
02083
02084 if ( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
02085 return false;
02086 if ( !KSUtil::checkType( context, args[1], KSValue::DoubleType, true ) )
02087 return false;
02088 if ( !KSUtil::checkType( context, args[2], KSValue::IntType, true ) )
02089 return false;
02090
02091 double alpha = args[0]->doubleValue();
02092 double sigma = args[1]->doubleValue();
02093 double n = args[2]->intValue();
02094
02095 if (sigma <= 0.0 || alpha <= 0.0 || alpha >= 1.0 || n < 1)
02096 return false;
02097 else
02098 context.setValue( new KSValue(gaussinv_helper(1.0-alpha/2.0) * sigma/sqrt(n)));
02099
02100 return true;
02101 }
02102
02103 static double GetFDist(double x, double fF1, double fF2) {
02104 double arg = fF2/(fF2+fF1*x);
02105 double alpha = fF2/2.0;
02106 double beta = fF1/2.0;
02107 return beta_helper(arg, alpha, beta);
02108 }
02109
02110 static double GetTDist(double T, double fDF) {
02111 return 0.5 * beta_helper(fDF/(fDF+T*T), fDF/2.0, 0.5);
02112 }
02113
02114 static double GetChiDist(double fChi, double fDF) {
02115 return 1.0 - GetGammaDist(fChi/2.0, fDF/2.0, 1.0);
02116 }
02117
02118
02119 bool kspreadfunc_tdist( KSContext& context ) {
02120
02121 QValueList<KSValue::Ptr>& args = context.value()->listValue();
02122
02123 if ( !KSUtil::checkArgumentsCount( context, 3, "TDIST", true ) )
02124 return false;
02125
02126 if ( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
02127 return false;
02128 if ( !KSUtil::checkType( context, args[1], KSValue::IntType, true ) )
02129 return false;
02130 if ( !KSUtil::checkType( context, args[2], KSValue::IntType, true ) )
02131 return false;
02132
02133 double T = args[0]->doubleValue();
02134 double deg = args[1]->intValue();
02135 double flag = args[2]->intValue();
02136
02137 if (deg < 1 || T < 0.0 || (flag != 1 && flag != 2) )
02138 return false;
02139
02140 double R = GetTDist(T, deg);
02141 if (flag == 1)
02142 context.setValue( new KSValue(R));
02143 else
02144 context.setValue( new KSValue(2.0*R));
02145
02146 return true;
02147 }
02148
02149
02150 bool kspreadfunc_fdist( KSContext& context ) {
02151
02152 QValueList<KSValue::Ptr>& args = context.value()->listValue();
02153
02154 if ( !KSUtil::checkArgumentsCount( context, 3, "FDIST", true ) )
02155 return false;
02156
02157 if ( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
02158 return false;
02159 if ( !KSUtil::checkType( context, args[1], KSValue::IntType, true ) )
02160 return false;
02161 if ( !KSUtil::checkType( context, args[2], KSValue::IntType, true ) )
02162 return false;
02163
02164 double fF = args[0]->doubleValue();
02165 double fF1 = args[1]->intValue();
02166 double fF2 = args[2]->intValue();
02167
02168 if (fF < 0.0 || fF1 < 1 || fF2 < 1 || fF1 >= 1.0E10 || fF2 >= 1.0E10) {
02169 return false;
02170 }
02171
02172 context.setValue( new KSValue(GetFDist(fF, fF1, fF2)));
02173
02174 return true;
02175 }
02176
02177
02178 bool kspreadfunc_chidist( KSContext& context ) {
02179
02180 QValueList<KSValue::Ptr>& args = context.value()->listValue();
02181
02182 if ( !KSUtil::checkArgumentsCount( context, 2, "CHIDIST", true ) )
02183 return false;
02184
02185 if ( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
02186 return false;
02187 if ( !KSUtil::checkType( context, args[1], KSValue::IntType, true ) )
02188 return false;
02189
02190 double fChi = args[0]->doubleValue();
02191 double fDF = args[1]->intValue();
02192
02193 if (fDF < 1 || fDF >= 1.0E5 || fChi < 0.0 )
02194 return false;
02195
02196 context.setValue( new KSValue(GetChiDist(fChi, fDF)));
02197
02198 return true;
02199 }
02200
02201 static bool kspreadfunc_sumproduct_helper( KSContext& context, QValueList<KSValue::Ptr>& list,QValueList<KSValue::Ptr>& list2, double& result )
02202 {
02203 QValueList<KSValue::Ptr>::Iterator it = list.begin();
02204 QValueList<KSValue::Ptr>::Iterator end = list.end();
02205 QValueList<KSValue::Ptr>::Iterator it2 = list2.begin();
02206 QValueList<KSValue::Ptr>::Iterator end2 = list2.end();
02207
02208 for( ; it != end,it2!=end2; ++it,++it2 )
02209 {
02210 if ( KSUtil::checkType( context, *it, KSValue::ListType, false ) )
02211 {
02212 if ( !kspreadfunc_sumproduct_helper( context, (*it)->listValue(),(*it2)->listValue(), result ))
02213 return false;
02214 }
02215 else if ( KSUtil::checkType( context, *it, KSValue::DoubleType, true ) && KSUtil::checkType( context, *it2, KSValue::DoubleType, true ))
02216 {
02217 result +=( (*it)->doubleValue()*(*it2)->doubleValue());
02218 }
02219 else if (!( KSUtil::checkType( context, *it, KSValue::Empty, true ) || KSUtil::checkType( context, *it2, KSValue::Empty, true )))
02220 return false;
02221 }
02222
02223 return true;
02224 }
02225
02226
02227 bool kspreadfunc_sumproduct( KSContext& context )
02228 {
02229 double result = 0.0;
02230 QValueList<KSValue::Ptr>& args = context.value()->listValue();
02231 if ( !KSUtil::checkArgumentsCount( context, 2, "SUMPRODUCT", true ) )
02232 return false;
02233
02234 if ( !KSUtil::checkType( context, args[0], KSValue::ListType, true ) )
02235 return false;
02236 if ( !KSUtil::checkType( context, args[1], KSValue::ListType, true ) )
02237 return false;
02238 if(args[0]->listValue().count() !=args[1]->listValue() .count())
02239 {
02240 context.setValue( new KSValue( i18n("Err") ) );
02241 return true;
02242 }
02243 bool b = kspreadfunc_sumproduct_helper( context,args[0]->listValue(),args[1]->listValue() , result );
02244
02245 if ( b )
02246 context.setValue( new KSValue( result ) );
02247
02248 return b;
02249 }
02250
02251 static bool kspreadfunc_sumx2py2_helper( KSContext& context, QValueList<KSValue::Ptr>& list,QValueList<KSValue::Ptr>& list2, double& result )
02252 {
02253 QValueList<KSValue::Ptr>::Iterator it = list.begin();
02254 QValueList<KSValue::Ptr>::Iterator end = list.end();
02255 QValueList<KSValue::Ptr>::Iterator it2 = list2.begin();
02256 QValueList<KSValue::Ptr>::Iterator end2 = list2.end();
02257
02258 for( ; it != end,it2!=end2; ++it,++it2 )
02259 {
02260 if ( KSUtil::checkType( context, *it, KSValue::ListType, false ) )
02261 {
02262 if ( !kspreadfunc_sumx2py2_helper( context, (*it)->listValue(),(*it2)->listValue(), result ))
02263 return false;
02264 }
02265 else if ( KSUtil::checkType( context, *it, KSValue::DoubleType, true ) && KSUtil::checkType( context, *it2, KSValue::DoubleType, true ))
02266 {
02267 result +=( pow((*it)->doubleValue(),2)+pow((*it2)->doubleValue(),2));
02268 }
02269 else if(!(KSUtil::checkType( context, *it, KSValue::Empty, true ) || KSUtil::checkType( context, *it2, KSValue::Empty, true )))
02270 return false;
02271 }
02272
02273 return true;
02274 }
02275
02276
02277 bool kspreadfunc_sumx2py2( KSContext& context )
02278 {
02279 double result = 0.0;
02280 QValueList<KSValue::Ptr>& args = context.value()->listValue();
02281 if ( !KSUtil::checkArgumentsCount( context, 2, "SUMX2PY2", true ) )
02282 return false;
02283
02284 if ( !KSUtil::checkType( context, args[0], KSValue::ListType, true ) )
02285 return false;
02286 if ( !KSUtil::checkType( context, args[1], KSValue::ListType, true ) )
02287 return false;
02288 if(args[0]->listValue().count() !=args[1]->listValue() .count())
02289 {
02290 context.setValue( new KSValue( i18n("Err") ) );
02291 return true;
02292 }
02293 bool b = kspreadfunc_sumx2py2_helper( context,args[0]->listValue(),args[1]->listValue() , result );
02294
02295 if ( b )
02296 context.setValue( new KSValue( result ) );
02297
02298 return b;
02299 }
02300
02301
02302 static bool kspreadfunc_sumx2my2_helper( KSContext& context, QValueList<KSValue::Ptr>& list,QValueList<KSValue::Ptr>& list2, double& result )
02303 {
02304 QValueList<KSValue::Ptr>::Iterator it = list.begin();
02305 QValueList<KSValue::Ptr>::Iterator end = list.end();
02306 QValueList<KSValue::Ptr>::Iterator it2 = list2.begin();
02307 QValueList<KSValue::Ptr>::Iterator end2 = list2.end();
02308
02309 for( ; it != end,it2!=end2; ++it,++it2 )
02310 {
02311 if ( KSUtil::checkType( context, *it, KSValue::ListType, false ) )
02312 {
02313 if ( !kspreadfunc_sumx2my2_helper( context, (*it)->listValue(),(*it2)->listValue(), result ))
02314 return false;
02315 }
02316 else if ( KSUtil::checkType( context, *it, KSValue::DoubleType, true ) && KSUtil::checkType( context, *it2, KSValue::DoubleType, true ))
02317 {
02318 result +=( pow((*it)->doubleValue(),2)-pow((*it2)->doubleValue(),2));
02319 }
02320 else if(!(KSUtil::checkType( context, *it, KSValue::Empty, true ) || KSUtil::checkType( context, *it2, KSValue::Empty, true )))
02321 return false;
02322 }
02323
02324 return true;
02325 }
02326
02327
02328 bool kspreadfunc_sumx2my2( KSContext& context )
02329 {
02330 double result = 0.0;
02331 QValueList<KSValue::Ptr>& args = context.value()->listValue();
02332 if ( !KSUtil::checkArgumentsCount( context, 2, "SUMX2MY2", true ) )
02333 return false;
02334
02335 if ( !KSUtil::checkType( context, args[0], KSValue::ListType, true ) )
02336 return false;
02337 if ( !KSUtil::checkType( context, args[1], KSValue::ListType, true ) )
02338 return false;
02339 if(args[0]->listValue().count() !=args[1]->listValue() .count())
02340 {
02341 context.setValue( new KSValue( i18n("Err") ) );
02342 return true;
02343 }
02344 bool b = kspreadfunc_sumx2my2_helper( context,args[0]->listValue(),args[1]->listValue() , result );
02345
02346 if ( b )
02347 context.setValue( new KSValue( result ) );
02348
02349 return b;
02350 }
02351
02352 static bool kspreadfunc_sumxmy2_helper( KSContext& context, QValueList<KSValue::Ptr>& list,QValueList<KSValue::Ptr>& list2, double& result )
02353 {
02354 QValueList<KSValue::Ptr>::Iterator it = list.begin();
02355 QValueList<KSValue::Ptr>::Iterator end = list.end();
02356 QValueList<KSValue::Ptr>::Iterator it2 = list2.begin();
02357 QValueList<KSValue::Ptr>::Iterator end2 = list2.end();
02358
02359 for( ; it != end,it2!=end2; ++it,++it2 )
02360 {
02361 if ( KSUtil::checkType( context, *it, KSValue::ListType, false ) )
02362 {
02363 if ( !kspreadfunc_sumxmy2_helper( context, (*it)->listValue(),(*it2)->listValue(), result ))
02364 return false;
02365 }
02366 else if ( KSUtil::checkType( context, *it, KSValue::DoubleType, true ) && KSUtil::checkType( context, *it2, KSValue::DoubleType, true ))
02367 {
02368 result +=pow(( (*it)->doubleValue()-(*it2)->doubleValue()),2);
02369 }
02370 else if(!(KSUtil::checkType( context, *it, KSValue::Empty, true ) || KSUtil::checkType( context, *it2, KSValue::Empty, true )))
02371 return false;
02372 }
02373
02374 return true;
02375 }
02376
02377
02378 bool kspreadfunc_sumxmy2( KSContext& context )
02379 {
02380 double result = 0.0;
02381 QValueList<KSValue::Ptr>& args = context.value()->listValue();
02382 if ( !KSUtil::checkArgumentsCount( context, 2, "SUM2XMY", true ) )
02383 return false;
02384
02385 if ( !KSUtil::checkType( context, args[0], KSValue::ListType, true ) )
02386 return false;
02387 if ( !KSUtil::checkType( context, args[1], KSValue::ListType, true ) )
02388 return false;
02389 if(args[0]->listValue().count() !=args[1]->listValue() .count())
02390 {
02391 context.setValue( new KSValue( i18n("Err") ) );
02392 return true;
02393 }
02394 bool b = kspreadfunc_sumxmy2_helper( context,args[0]->listValue(),args[1]->listValue() , result );
02395
02396 if ( b )
02397 context.setValue( new KSValue( result ) );
02398
02399 return b;
02400 }
02401
02402 static bool kspreadfunc_avedev_helper(KSContext &context, QValueList<KSValue::Ptr> &args, double &result, double temp)
02403 {
02404 QValueList<KSValue::Ptr>::Iterator it = args.begin();
02405 QValueList<KSValue::Ptr>::Iterator end = args.end();
02406
02407 for(; it != end; ++it)
02408 {
02409 if(KSUtil::checkType(context, *it, KSValue::ListType, false))
02410 {
02411 if(!kspreadfunc_avedev_helper(context, (*it)->listValue(), result, temp))
02412 return false;
02413 }
02414 else if(KSUtil::checkType(context, *it, KSValue::DoubleType, true))
02415 result += fabs((*it)->doubleValue() - temp);
02416 }
02417
02418 return true;
02419 }
02420
02421
02422 bool kspreadfunc_avedev(KSContext &context)
02423 {
02424 double temp = 0.0, result = 0.0;
02425 int number = 0;
02426
02427
02428 bool b = kspreadfunc_average_helper(context, context.value()->listValue(), temp, number, false );
02429
02430 if(number == 0)
02431 {
02432 context.setValue(new KSValue(i18n("#DIV/0")));
02433 return true;
02434 }
02435
02436 if(!b)
02437 return false;
02438
02439
02440 temp /= number;
02441
02442 bool finish = kspreadfunc_avedev_helper(context, context.value()->listValue(), result, temp);
02443
02444 if(!finish)
02445 return false;
02446
02447
02448 result /= number;
02449
02450 context.setValue(new KSValue(result));
02451
02452 return b;
02453 }
02454
02455
02456 bool kspreadfunc_averagea( KSContext & context )
02457 {
02458 double result = 0.0;
02459
02460 int number = 0;
02461 bool b = kspreadfunc_average_helper( context, context.value()->listValue(), result, number, true );
02462
02463 if ( number == 0 )
02464 {
02465 context.setValue( new KSValue( i18n("#DIV/0") ) );
02466 return true;
02467 }
02468
02469 if ( b )
02470 context.setValue( new KSValue( result / (double) number ) );
02471
02472 return b;
02473 }
02474