kspread Library API Documentation

kspread_functions_statistical.cc

00001 /* This file is part of the KDE project
00002    Copyright (C) 1998-2002 The KSpread Team
00003                            www.koffice.org/kspread
00004 
00005    This library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Library General Public
00007    License as published by the Free Software Foundation; either
00008    version 2 of the License.
00009 
00010    This library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Library General Public License for more details.
00014 
00015    You should have received a copy of the GNU Library General Public License
00016    along with this library; see the file COPYING.LIB.  If not, write to
00017    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00018    Boston, MA 02111-1307, USA.
00019 */
00020 
00021 // built-in statistical functions
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 // prototypes (sorted!)
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 // registers all statistical functions
00101 void KSpreadRegisterStatisticalFunctions()
00102 {
00103   KSpreadFunctionRepository* repo = KSpreadFunctionRepository::self();
00104 
00105   // insert them sorted please
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   // from gnumeric, thanks to the gnumeric developers!
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 // Function: permut
00961 bool kspreadfunc_arrang( KSContext& context )
00962 { /* arrang : util_fact(n)/(util_fact(n-m) */
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         //In util_fact function val must be positive
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 // Function: average
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   /* loop through each value, adding it to the sorted list (recursing
01026      whenever necessary */
01027   while(it != end && returnVal)
01028   {
01029     if ( KSUtil::checkType( context, *it, KSValue::ListType, false ) )
01030     {
01031       /* try to recurse */
01032       returnVal = kspreadfunc_median_helper(context, (*it)->listValue(),
01033                                             sortedList);
01034     }
01035     else if ( KSUtil::checkType( context, *it, KSValue::DoubleType, true ) )
01036     {
01037       /* insert it properly into the list */
01038       QValueList<KSValue::Ptr>::Iterator ptr = sortedList.begin();
01039       QValueList<KSValue::Ptr>::Iterator endPtr = sortedList.end();
01040 
01041       /* find the proper place */
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 // Function: median
01055 bool kspreadfunc_median( KSContext& context )
01056 {
01057   double result = 0.0;
01058   bool worked;
01059 
01060   /* need a list to hold all the values in sorted order so we can pick out the
01061      median one */
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     /* get the median value */
01070     QValueList<KSValue::Ptr>::Iterator ptr =
01071       sortedValues.at((sortedValues.size() - 1) / 2);
01072 
01073     /* now we're halfway through the list, or if there is an even number of
01074        items, we're on the 'first' of the 2 in the middle */
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 // Function: variance
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 // Function: varp
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 // Function: vara
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 // Function: varpa
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 // Function: stddev
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 // Function: stdeva
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 // Function: stddevp
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 // Function: stdevpa
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 // Function: combin
01277 bool kspreadfunc_combin( KSContext& context )
01278 { /*combin : util_fact(n)/(util_fact(n-m)*util_fact(m)) */
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         //In util_fact function val must be positive
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 // Function: bino
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   // 0<proba<1
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     //In util_fact function val must be positive
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 // Function: bino_inv
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   // 0<proba<1
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         //In util_fact function val must be positive
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 // Function: phi
01420 bool kspreadfunc_phi(KSContext& context)
01421 {
01422   //distribution function for a standard normal distribution
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 // Function: gauss
01492 bool kspreadfunc_gauss(KSContext& context)
01493 {
01494   //returns the integral values of the standard normal cumulative distribution
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 //helper for kspreadfunc_gammadist
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;   // sqrt(2*PI)
01536   return s;
01537 }
01538 
01539 //helper for kspreadfunc_gammadist
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 //helper for kspreadfunc_gammadist and others
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   // double g = exp(a+b) / den;
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       // return pow( dx, dgamma ) * exp( -dx ) * t / g;
01606       return exp( dgamma * log(dx) - dx - a - b ) * t * den;
01607     }
01608   }
01609 
01610   return 1.0;             // should not happen ...
01611 }
01612 
01613 // Function: gammadist
01614 bool kspreadfunc_gammadist( KSContext& context )
01615 {
01616   //returns the gamma distribution
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();  // 0 or 1
01635   double result;
01636 
01637   if (x < 0.0  || alpha <= 0.0 || beta <= 0.0)
01638     //SetIllegalArgument();
01639     //TODO error?
01640     return false;
01641   else if (kum == 0) {  //density
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 // Function: betadist
01733 bool kspreadfunc_betadist( KSContext& context ) {
01734   QValueList<KSValue::Ptr>& args = context.value()->listValue();
01735 
01736   double fA, fB;  //lower, upper bound
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) { //checks
01759     return false;
01760   }
01761   x = (x-fA)/(fB-fA); //scaling
01762 
01763   context.setValue( new KSValue( beta_helper(x, alpha, beta) ));
01764   return true;
01765 }
01766 
01767 // Function: fisher
01768 bool kspreadfunc_fisher( KSContext& context ) {
01769   //returns the Fisher transformation for x
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 // Function: fisherinv
01785 bool kspreadfunc_fisherinv( KSContext& context ) {
01786   //returns the inverse of the Fisher transformation for x
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 // Function: normdist
01802 bool kspreadfunc_normdist(KSContext& context ) {
01803   //returns the normal cumulative distribution
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)  // density
01826     context.setValue( new KSValue(phi_helper((x-mue)/sigma)/sigma));
01827   else          // distribution
01828     context.setValue( new KSValue(0.5 + gauss_helper((x-mue)/sigma)));
01829 
01830   return true;
01831 }
01832 
01833 // Function: lognormdist
01834 bool kspreadfunc_lognormdist(KSContext& context ) {
01835   //returns the cumulative lognormal distribution
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 // Function: normsdist
01861 bool kspreadfunc_stdnormdist(KSContext& context )
01862 {
01863   //returns the cumulative lognormal distribution
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 // Function: expondist
01879 bool kspreadfunc_expondist(KSContext& context ) {
01880   //returns the exponential distribution
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) {  //density
01902     if (x >= 0.0)
01903       result = lambda * exp(-lambda*x);
01904     else
01905       result = 0;
01906   }
01907   else {  //distribution
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 // Function: weibull
01919 bool kspreadfunc_weibull( KSContext& context ) {
01920   //returns the Weibull distribution
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)  // density
01945     result = alpha / pow(beta,alpha) * pow(x,alpha-1.0) * exp(-pow(x/beta,alpha));
01946   else  // distribution
01947     result = 1.0 - exp(-pow(x/beta,alpha));
01948 
01949   context.setValue( new KSValue(result));
01950   return true;
01951 }
01952 
01953 // Function: normsinv
01954 bool kspreadfunc_normsinv( KSContext& context ) {
01955   //returns the inverse of the standard normal cumulative distribution
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 // Function: norminv
01976 bool kspreadfunc_norminv( KSContext& context ) {
01977   //returns the inverse of the normal cumulative distribution
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 // Function: gammaln
02003 bool kspreadfunc_gammaln( KSContext& context ) {
02004   //returns the natural logarithm of the gamma function
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 // Function: poisson
02024 bool kspreadfunc_poisson( KSContext& context ) {
02025   //returns the Poisson distribution
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   { // density
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   { // distribution
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 // Function: confidence
02077 bool kspreadfunc_confidence( KSContext& context ) {
02078   //returns the confidence interval for a population mean
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 // Function: tdist
02119 bool kspreadfunc_tdist( KSContext& context ) {
02120   //returns the t-distribution
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 // Function: fdist
02150 bool kspreadfunc_fdist( KSContext& context ) {
02151   //returns the f-distribution
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 // Function: chidist
02178 bool kspreadfunc_chidist( KSContext& context ) {
02179   //returns the chi-distribution
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 // Function: sumproduct
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 // Function: sumx2py2
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 // Function: sumx2my2
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 // Function: sum2xmy
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 // Function: avedev
02422 bool kspreadfunc_avedev(KSContext &context)
02423 {
02424     double temp = 0.0, result = 0.0;
02425     int number = 0;
02426 
02427     // First sum the range into one double
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     // Devide by the number of values
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     // Devide by the number of values
02448     result /= number;
02449 
02450     context.setValue(new KSValue(result));
02451 
02452     return b;
02453 }
02454 
02455 // Function: averagea
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 
KDE Logo
This file is part of the documentation for kspread Library Version 1.4.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Mon Feb 13 09:43:12 2006 by doxygen 1.4.2 written by Dimitri van Heesch, © 1997-2003