You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1111 lines
32 KiB
C++

/* Copyright (C) 2004-2006 Ariya Hidayat <ariya@kde.org>
2007 Helder Correia <helder.pereira.correia@gmail.com>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "evaluator.h"
#include "functions.h"
#include "hmath.h"
#include <QCoreApplication>
#include <QHash>
#include <QObject>
#include <QStringList>
#include <QVector>
#include <float.h>
#include <math.h>
#define qApp QCoreApplication::instance()
HNumber deg2rad( HNumber x )
{
return x * HMath::pi() / HNumber(180);
}
HNumber rad2deg( HNumber x )
{
return HNumber(180) * x / HMath::pi();
}
HNumber function_abs( const Evaluator*, Function*, const FunctionArguments& args )
{
if( args.count() != 1 )
return HNumber::nan();
HNumber num = args[0];
return HMath::abs( num );
}
HNumber function_int( const Evaluator*, Function*, const FunctionArguments& args )
{
if( args.count() != 1 )
return HNumber::nan();
HNumber num = args[0];
return HMath::integer( num );
}
HNumber function_trunc( const Evaluator * evaluator,
Function * function,
const FunctionArguments & arguments )
{
int nArgs = arguments.count();
if( nArgs != 1 && nArgs != 2 )
{
function->setError( function->name(), QString( "function requires 1 or 2 arguments" ) );
return HNumber::nan();
}
HNumber num = arguments[0];
HNumber prec;
HNumber zero(0);
if( nArgs == 2)
prec = arguments[1];
else prec = zero;
if( !prec.isInteger() )
{
function->setError( function->name(), QString( "function undefined for specified arguments" ) );
return HNumber::nan();
}
HNumber limit(150);
if( prec > limit )
prec = limit;
else if( prec < zero )
prec = zero;
if( nArgs == 1 )
return HMath::trunc( num );
else // nArgs == 2
return HMath::trunc( num, prec.toInt() );
}
HNumber function_frac( const Evaluator * evaluator,
Function * function,
const FunctionArguments & arguments )
{
if ( arguments.count() != 1 )
return HNumber::nan();
HNumber x = arguments[0];
return HMath::frac( x );
}
HNumber function_floor( const Evaluator*, Function*, const FunctionArguments& args )
{
if( args.count() != 1 )
return HNumber::nan();
HNumber num = args[0];
return HMath::floor( num );
}
HNumber function_ceil( const Evaluator*, Function*, const FunctionArguments& args )
{
if( args.count() != 1 )
return HNumber::nan();
HNumber num = args[0];
return HMath::ceil( num );
}
HNumber function_gcd( const Evaluator*, Function* fn, const FunctionArguments& args )
{
int nArgs = args.count();
if ( nArgs < 2 )
{
fn->setError( fn->name(), QString( "function requires at least 2 arguments" ) );
return HNumber::nan();
}
for ( int i = 0; i < args.count(); i++ )
if ( !args[i].isInteger() )
{
fn->setError( fn->name(), QString( "function requires integer arguments" ) );
return HNumber::nan();
}
HNumber result = HMath::gcd( args[0], args[1] );
for ( int i = 2; i < nArgs; i++ )
{
result = HMath::gcd( result, args[i] );
}
return result;
}
HNumber function_round( const Evaluator*, Function* fn, const FunctionArguments& args )
{
int nArgs = args.count();
if( nArgs != 1 && nArgs != 2 )
{
fn->setError( fn->name(), QString( "function requires 1 or 2 arguments" ) );
return HNumber::nan();
}
HNumber num = args[0];
HNumber prec;
HNumber zero(0);
if( nArgs == 2)
prec = args[1];
else
prec = zero;
if( !prec.isInteger() )
{
fn->setError( fn->name(), QString( "function requires integer P2" ) );
return HNumber::nan();
}
HNumber limit(150);
if( prec > limit )
prec = limit;
else if( prec < zero )
prec = zero;
if( nArgs == 1 )
return HMath::round( num );
else // nArgs == 2
return HMath::round( num, prec.toInt() );
}
HNumber function_sqrt( const Evaluator*, Function* fn, const FunctionArguments& args )
{
if( args.count() != 1 )
return HNumber::nan();
HNumber num = args[0];
if( num < HNumber(0) )
{
fn->setError( fn->name(), QString( "function undefined for specified argument" ) );
return HNumber::nan();
}
return HMath::sqrt( num );
}
HNumber function_cbrt( const Evaluator*, Function*, const FunctionArguments& args )
{
if( args.count() != 1 )
return HNumber::nan();
HNumber num = args[0];
return HMath::cbrt( num );
}
HNumber function_exp( const Evaluator*, Function*, const FunctionArguments& args )
{
if( args.count() != 1 )
return HNumber::nan();
HNumber num = args[0];
return HMath::exp( num );
}
HNumber function_ln( const Evaluator*, Function* fn, const FunctionArguments& args )
{
if( args.count() != 1 )
return HNumber::nan();
HNumber x = args[0];
HNumber result = HMath::ln( x );
if( result.isNan() )
fn->setError( fn->name(), QString( "function undefined for specified argument" ) );
return result;
}
HNumber function_log( const Evaluator*, Function* fn, const FunctionArguments& args )
{
if( args.count() != 1 )
return HNumber::nan();
HNumber x = args[0];
HNumber result = HMath::log( x );
if( result.isNan() )
fn->setError( fn->name(), QString( "function undefined for specified argument" ) );
return result;
}
HNumber function_lg( const Evaluator*, Function* fn, const FunctionArguments& args )
{
if( args.count() != 1 )
return HNumber::nan();
HNumber x = args[0];
HNumber result = HMath::lg( x );
if( result.isNan() )
fn->setError( fn->name(), QString( "function undefined for specified argument" ) );
return result;
}
HNumber function_sin( const Evaluator* eval, Function*, const FunctionArguments& args )
{
if( args.count() != 1 )
return HNumber::nan();
HNumber angle = args[0];
if( eval->angleMode() == Evaluator::Degree )
angle = deg2rad( angle );
return HMath::sin( angle );
}
HNumber function_cos( const Evaluator* eval, Function*, const FunctionArguments& args )
{
if( args.count() != 1 )
return HNumber::nan();
HNumber angle = args[0];
if( eval->angleMode() == Evaluator::Degree )
angle = deg2rad( angle );
return HMath::cos( angle );
}
HNumber function_tan( const Evaluator* eval, Function* fn, const FunctionArguments& args )
{
if( args.count() != 1 )
return HNumber::nan();
HNumber angle = args[0];
if( eval->angleMode() == Evaluator::Degree )
angle = deg2rad( angle );
HNumber result = HMath::tan( angle );
if ( result.isNan() )
{
fn->setError( fn->name(), QString( "function undefined for specified argument" ) );
return HNumber::nan();
}
return result;
}
HNumber function_cot( const Evaluator* eval, Function* fn, const FunctionArguments& args )
{
if( args.count() != 1 )
return HNumber::nan();
HNumber angle = args[0];
if( eval->angleMode() == Evaluator::Degree )
angle = deg2rad( angle );
HNumber result = HMath::cot( angle );
if ( result.isNan() )
{
fn->setError( fn->name(), QString( "function undefined for specified argument" ) );
return HNumber::nan();
}
return result;
}
HNumber function_sec( const Evaluator* eval, Function* fn, const FunctionArguments& args )
{
if( args.count() != 1 )
return HNumber::nan();
HNumber angle = args[0];
if( eval->angleMode() == Evaluator::Degree )
angle = deg2rad( angle );
HNumber result = HMath::sec( angle );
if ( result.isNan() )
{
fn->setError( fn->name(), QString( "function undefined for specified argument" ) );
return HNumber::nan();
}
return result;
}
HNumber function_csc( const Evaluator* eval, Function* fn, const FunctionArguments& args )
{
if( args.count() != 1 )
return HNumber::nan();
HNumber angle = args[0];
if( eval->angleMode() == Evaluator::Degree )
angle = deg2rad( angle );
HNumber result = HMath::csc( angle );
if ( result.isNan() )
{
fn->setError( fn->name(), QString( "function undefined for specified argument" ) );
return HNumber::nan();
}
return result;
}
HNumber function_asin( const Evaluator * evaluator,
Function * function,
const FunctionArguments & arguments )
{
if ( arguments.count() != 1 )
return HNumber::nan();
HNumber x = arguments[0];
HNumber result = HMath::asin( x );
if ( result.isNan() )
{
function->setError( function->name(), QString( "function undefined for specified argument" ) );
return HNumber::nan();
}
if ( evaluator->angleMode() == Evaluator::Degree )
result = rad2deg( result );
return result;
}
HNumber function_acos( const Evaluator * evaluator,
Function * function,
const FunctionArguments & arguments )
{
if ( arguments.count() != 1 )
return HNumber::nan();
HNumber x = arguments[0];
HNumber result = HMath::acos( x );
if ( result.isNan() )
{
function->setError( function->name(), QString( "function undefined for specified argument" ) );
return HNumber::nan();
}
if ( evaluator->angleMode() == Evaluator::Degree )
result = rad2deg( result );
return result;
}
HNumber function_atan( const Evaluator* eval, Function*, const FunctionArguments& args )
{
if( args.count() != 1 )
return HNumber::nan();
HNumber num = args[0];
HNumber angle = HMath::atan( num );
if( eval->angleMode() == Evaluator::Degree )
angle = rad2deg( angle );
return angle;
}
HNumber function_sinh( const Evaluator* eval, Function*, const FunctionArguments& args )
{
if( args.count() != 1 )
return HNumber::nan();
HNumber angle = args[0];
if( eval->angleMode() == Evaluator::Degree )
angle = deg2rad( angle );
return HMath::sinh( angle );
}
HNumber function_cosh( const Evaluator* eval, Function*, const FunctionArguments& args )
{
if( args.count() != 1 )
return HNumber::nan();
HNumber angle = args[0];
if( eval->angleMode() == Evaluator::Degree )
angle = deg2rad( angle );
return HMath::cosh( angle );
}
HNumber function_tanh( const Evaluator* eval, Function*, const FunctionArguments& args )
{
if( args.count() != 1 )
return HNumber::nan();
HNumber angle = args[0];
if( eval->angleMode() == Evaluator::Degree )
angle = deg2rad( angle );
return HMath::tanh( angle );
}
HNumber function_sign( const Evaluator*, Function*, const FunctionArguments& args )
{
if( args.count() != 1 )
return HNumber::nan();
return HMath::sign( args[0] );
}
HNumber function_nCr( const Evaluator * evaluator,
Function * function,
const FunctionArguments & arguments )
{
// check number of arguments
if ( arguments.count() != 2 )
return HNumber::nan();
// compute result
// n = arguments[0]
// r = arguments[1]
HNumber result = HMath::nCr( arguments[0], arguments[1] );
// check invalid usage and set error accordingly
if ( result.isNan() )
function->setError( function->name(), QString( "function undefined for specified arguments" ) );
return result;
}
HNumber function_nPr( const Evaluator * evaluator,
Function * function,
const FunctionArguments & arguments )
{
// check number of arguments
if ( arguments.count() != 2 )
return HNumber::nan();
// compute result
// n = arguments[0]
// r = arguments[1]
HNumber result = HMath::nPr( arguments[0], arguments[1] );
// check invalid usage and set error accordingly
if ( result.isNan() )
function->setError( function->name(), QString( "function undefined for specified arguments" ) );
return result;
}
HNumber function_degrees( const Evaluator*, Function*, const FunctionArguments& args )
{
if ( args.count() != 1 )
return HNumber::nan();
HNumber angle = args[0];
return angle * HNumber(180) / HMath::pi();
}
HNumber function_radians( const Evaluator*, Function*, const FunctionArguments& args )
{
if ( args.count() != 1 )
return HNumber::nan();
HNumber angle = args[0];
return angle * HMath::pi() / HNumber(180);
}
HNumber function_max( const Evaluator * evaluator,
Function * function,
const FunctionArguments & arguments )
{
if ( arguments.count() < 1 )
{
function->setError( function->name(), QString( "function requires at least 1 argument" ) );
return HNumber::nan();
}
int totalParams = arguments.count();
HNumber result = arguments[0];
if(totalParams > 1)
for ( int i = 1; i < totalParams; i++ )
result = HMath::max( result, arguments[i] );
return result;
}
HNumber function_min( const Evaluator * evaluator,
Function * function,
const FunctionArguments & arguments )
{
if ( arguments.count() < 1 )
{
function->setError( function->name(), QString( "function requires at least 1 argument" ) );
return HNumber::nan();
}
int totalParams = arguments.count();
HNumber result = arguments[0];
if(totalParams > 1)
for ( int i = 1; i < totalParams; i++ )
result = HMath::min( result, arguments[i] );
return result;
}
HNumber function_sum( const Evaluator*, Function*, const FunctionArguments& args )
{
if( args.count() <= 0 )
return HNumber(0);
HNumber result = args[0];
for( int c = 1; c < args.count(); c++ )
result = result + args[c];
return result;
}
HNumber function_product( const Evaluator*, Function*, const FunctionArguments& args )
{
if( args.count() <= 0 )
return HNumber(0);
HNumber result = args[0];
for( int c = 1; c < args.count(); c++ )
result = result * args[c];
return result;
}
HNumber function_average( const Evaluator*, Function*, const FunctionArguments& args )
{
if( args.count() <= 0 )
return HNumber("NaN");
HNumber result = args[0];
for( int c = 1; c < args.count(); c++ )
result = result + args[c];
result = result / HNumber(args.count());
return result;
}
HNumber function_geomean( const Evaluator*, Function*, const FunctionArguments& args )
{
if( args.count() <= 0 )
return HNumber("NaN");
HNumber result = args[0];
for( int c = 1; c < args.count(); c++ )
result = result * args[c];
result = result / HNumber(args.count());
if( result <= HNumber(0))
return HNumber("NaN");
return result;
}
HNumber function_dec( const Evaluator*, Function*, const FunctionArguments& args )
{
if( args.count() < 1 )
return HNumber("NaN");
HNumber result = args[0];
result.setFormat('g');
return result;
}
HNumber function_hex( const Evaluator*, Function*, const FunctionArguments& args )
{
if( args.count() < 1 )
return HNumber("NaN");
HNumber result = args[0];
result.setFormat('h');
return result;
}
HNumber function_oct( const Evaluator*, Function*, const FunctionArguments& args )
{
if( args.count() < 1 )
return HNumber("NaN");
HNumber result = args[0];
result.setFormat('o');
return result;
}
HNumber function_bin( const Evaluator*, Function*, const FunctionArguments& args )
{
if( args.count() < 1 )
return HNumber("NaN");
HNumber result = args[0];
result.setFormat('b');
return result;
}
HNumber function_binompmf( const Evaluator * evaluator,
Function * function,
const FunctionArguments & arguments )
{
if ( arguments.count() != 3 )
return HNumber::nan();
HNumber k = arguments[0];
HNumber n = arguments[1];
HNumber p = arguments[2];
HNumber result = HMath::binomialPmf( k, n, p );
if ( result.isNan() )
function->setError( function->name(), QString( "function undefined for specified arguments" ) );
return result;
}
HNumber function_binomcdf( const Evaluator * evaluator,
Function * function,
const FunctionArguments & arguments )
{
if ( arguments.count() != 3 )
return HNumber::nan();
HNumber k = arguments[0];
HNumber n = arguments[1];
HNumber p = arguments[2];
HNumber result = HMath::binomialCdf( k, n, p );
if ( result.isNan() )
function->setError( function->name(), QString( "function undefined for specified arguments" ) );
return result;
}
HNumber function_binommean( const Evaluator * evaluator,
Function * function,
const FunctionArguments & arguments )
{
if ( arguments.count() != 2 )
return HNumber::nan();
HNumber n = arguments[0];
HNumber p = arguments[1];
HNumber result = HMath::binomialMean( n, p );
if ( result.isNan() )
function->setError( function->name(), QString( "function undefined for specified arguments" ) );
return result;
}
HNumber function_binomvar( const Evaluator * evaluator,
Function * function,
const FunctionArguments & arguments )
{
if ( arguments.count() != 2 )
return HNumber::nan();
HNumber n = arguments[0];
HNumber p = arguments[1];
HNumber result = HMath::binomialVariance( n, p );
if ( result.isNan() )
function->setError( function->name(), QString( "function undefined for specified arguments" ) );
return result;
}
HNumber function_hyperpmf( const Evaluator * evaluator,
Function * function,
const FunctionArguments & arguments )
{
if ( arguments.count() != 4 )
return HNumber::nan();
HNumber k = arguments[0];
HNumber N = arguments[1];
HNumber M = arguments[2];
HNumber n = arguments[3];
HNumber result = HMath::hypergeometricPmf( k, N, M, n );
if ( result.isNan() )
function->setError( function->name(), QString( "function undefined for specified arguments" ) );
return result;
}
HNumber function_hypercdf( const Evaluator * evaluator,
Function * function,
const FunctionArguments & arguments )
{
if ( arguments.count() != 4 )
return HNumber::nan();
HNumber k = arguments[0];
HNumber N = arguments[1];
HNumber M = arguments[2];
HNumber n = arguments[3];
HNumber result = HMath::hypergeometricCdf( k, N, M, n );
if ( result.isNan() )
function->setError( function->name(), QString( "function undefined for specified arguments" ) );
return result;
}
HNumber function_hypermean( const Evaluator * evaluator,
Function * function,
const FunctionArguments & arguments )
{
if ( arguments.count() != 3 )
return HNumber::nan();
HNumber N = arguments[0];
HNumber M = arguments[1];
HNumber n = arguments[2];
HNumber result = HMath::hypergeometricMean( N, M, n );
if ( result.isNan() )
function->setError( function->name(), QString( "function undefined for specified arguments" ) );
return result;
}
HNumber function_hypervar( const Evaluator * evaluator,
Function * function,
const FunctionArguments & arguments )
{
if ( arguments.count() != 3 )
return HNumber::nan();
HNumber N = arguments[0];
HNumber M = arguments[1];
HNumber n = arguments[2];
HNumber result = HMath::hypergeometricVariance( N, M, n );
if ( result.isNan() )
function->setError( function->name(), QString( "function undefined for specified arguments" ) );
return result;
}
HNumber function_poipmf( const Evaluator * evaluator,
Function * function,
const FunctionArguments & arguments )
{
if ( arguments.count() != 2 )
return HNumber::nan();
HNumber k = arguments[0];
HNumber l = arguments[1];
HNumber result = HMath::poissonPmf( k, l );
if ( result.isNan() )
function->setError( function->name(), QString( "function undefined for specified arguments" ) );
return result;
}
HNumber function_poicdf( const Evaluator * evaluator,
Function * function,
const FunctionArguments & arguments )
{
if ( arguments.count() != 2 )
return HNumber::nan();
HNumber k = arguments[0];
HNumber l = arguments[1];
HNumber result = HMath::poissonCdf( k, l );
if ( result.isNan() )
function->setError( function->name(), QString( "function undefined for specified arguments" ) );
return result;
}
HNumber function_poimean( const Evaluator * evaluator,
Function * function,
const FunctionArguments & arguments )
{
if ( arguments.count() != 1 )
return HNumber::nan();
HNumber l = arguments[0];
HNumber result = HMath::poissonMean( l );
if ( result.isNan() )
function->setError( function->name(), QString( "function undefined for specified arguments" ) );
return result;
}
HNumber function_poivar( const Evaluator * evaluator,
Function * function,
const FunctionArguments & arguments )
{
if ( arguments.count() != 1 )
return HNumber::nan();
HNumber l = arguments[0];
HNumber result = HMath::poissonVariance( l );
if ( result.isNan() )
function->setError( function->name(), QString( "function undefined for specified arguments" ) );
return result;
}
class FunctionPrivate
{
public:
QString name;
int argc;
QString desc;
QString error;
FunctionPtr ptr;
FunctionPrivate(): name(), argc(0), desc(), error(), ptr(0) {}
};
class FunctionRepositoryPrivate
{
public:
QHash<QString, Function*> functions;
};
Function::Function( const QString& name, int argc, FunctionPtr ptr, const QString& desc ):
d( new FunctionPrivate )
{
d->name = name;
d->argc = argc;
d->desc = QString( desc.toLatin1() );
d->ptr = ptr;
}
Function::Function( const QString& name, FunctionPtr ptr, const QString& desc ):
d( new FunctionPrivate )
{
d->name = name;
d->argc = -1;
d->desc = QString( desc.toLatin1() );
d->ptr = ptr;
}
Function::~Function()
{
delete d;
}
QString Function::name() const
{
return d->name;
}
QString Function::description() const
{
return d->desc;
}
QString Function::error() const
{
return d->error;
}
void Function::setError( const QString& context, const QString& error )
{
d->error = context + ": " + error;
}
HNumber Function::exec( const Evaluator* eval, const FunctionArguments& args )
{
d->error = QString();
if( !d->ptr )
{
setError( QString("error"), QString( QString( "cannot execute function %1") ).arg( name() ) );
return HNumber(0);
}
if( d->argc >= 0 )
if( args.count() != d->argc )
{
if ( d->argc == 1 )
setError( d->name, QString( QString( "function accepts 1 argument" ) ) );
else
setError( d->name, QString( QString( "function accepts %1 arguments" ) ).arg( d->argc ) );
return HNumber(0);
}
return (*d->ptr)( eval, this, args );
}
FunctionRepository* FunctionRepository::s_self = 0;
FunctionRepository* FunctionRepository::self()
{
if( !s_self )
s_self = new FunctionRepository();
return s_self;
}
FunctionRepository::FunctionRepository()
{
d = new FunctionRepositoryPrivate;
/*
ANALYSIS
*/
add( new Function( "abs", 1, function_abs,
QString("Absolute Value") ) );
add( new Function( "average", function_average,
QString("Average (Arithmetic Mean)") ) );
add( new Function( "log", 1, function_log,
QString("Base-10 Logarithm") ) );
add( new Function( "lg", 1, function_lg,
QString("Base-2 Logarithm") ) );
add( new Function( "bin", function_bin,
QString("Binary Representation") ) );
add( new Function( "ceil", 1, function_ceil,
QString("Ceiling") ) );
add( new Function( "cbrt", 1, function_cbrt,
QString("Cube Root") ) );
add( new Function( "dec", function_dec,
QString("Decimal Representation") ) );
add( new Function( "exp", 1, function_exp,
QString("Exponential") ) );
add( new Function( "floor", 1, function_floor,
QString("Floor") ) );
add( new Function( "frac", 1, function_frac,
QString("Fractional Part") ) );
add( new Function( "geomean", function_geomean,
QString("Geometric Mean") ) );
add( new Function( "hex", function_hex,
QString("Hexadecimal Representation") ) );
add( new Function( "int", 1, function_int,
QString("Integer Part") ) );
add( new Function( "max", function_max,
QString("Maximum") ) );
add( new Function( "min", function_min,
QString("Minimum") ) );
add( new Function( "ln", 1, function_ln,
QString("Natural Logarithm") ) );
add( new Function( "oct", function_oct,
QString("Octal Representation") ) );
add( new Function( "product", function_product,
QString("Product") ) );
add( new Function( "round", function_round,
QString("Rounding") ) );
add( new Function( "sign", 1, function_sign,
QString("Signum") ) );
add( new Function( "sqrt", 1, function_sqrt,
QString("Square Root") ) );
add( new Function( "sum", function_sum,
QString("Sum") ) );
add( new Function( "trunc", function_trunc,
QString("Truncation") ) );
/*
DISCRETE
*/
add( new Function( "gcd", function_gcd,
QString("Greatest Common Divisor") ) );
add( new Function( "ncr", 2, function_nCr,
QString("Combination (Binomial Coefficient)") ) );
add( new Function( "npr", 2, function_nPr,
QString("Permutation (Arrangement)") ) );
/*
PROBABILITY
*/
add( new Function( "binompmf", 3, function_binompmf,
QString("Binomial Probability Mass Function") ));
add( new Function( "binomcdf", 3, function_binomcdf,
QString("Binomial Cumulative Distribution Function") ));
add( new Function( "binommean", 2, function_binommean,
QString("Binomial Distribution Mean") ));
add( new Function( "binomvar", 2, function_binomvar,
QString("Binomial Distribution Variance") ));
add( new Function( "hyperpmf", 4, function_hyperpmf,
QString("Hypergeometric Probability Mass Function") ));
add( new Function( "hypercdf", 4, function_hypercdf,
QString("Hypergeometric Cumulative Distribution Function")));
add( new Function( "hypermean", 3, function_hypermean,
QString("Hypergeometric Distribution Mean") ));
add( new Function( "hypervar", 3, function_hypervar,
QString("Hypergeometric Distribution Variance") ));
add( new Function( "poipmf", 2, function_poipmf,
QString("Poissonian Probability Mass Function") ));
add( new Function( "poicdf", 2, function_poicdf,
QString("Poissonian Cumulative Distribution Function")));
add( new Function( "poimean", 1, function_poimean,
QString("Poissonian Distribution Mean") ));
add( new Function( "poivar", 1, function_poivar,
QString("Poissonian Distribution Variance") ));
/*
TRIGONOMETRY
*/
add( new Function( "acos", 1, function_acos,
QString("Arc Cosine") ) );
add( new Function( "asin", 1, function_asin,
QString("Arc Sine") ) );
add( new Function( "atan", 1, function_atan,
QString("Arc Tangent") ) );
add( new Function( "csc", 1, function_csc,
QString("Cosecant") ) );
add( new Function( "cos", 1, function_cos,
QString("Cosine") ) );
add( new Function( "cot", 1, function_cot,
QString("Cotangent") ) );
add( new Function( "cosh", 1, function_cosh,
QString("Hyperbolic Cosine") ) );
add( new Function( "degrees", 1, function_degrees,
QString("Degrees Of Arc") ) );
add( new Function( "radians", 1, function_radians,
QString("Radians") ) );
add( new Function( "sinh", 1, function_sinh,
QString("Hyperbolic Sine") ) );
add( new Function( "tanh", 1, function_tanh,
QString("Hyperbolic Tangent") ) );
add( new Function( "sec", 1, function_sec,
QString("Secant") ) );
add( new Function( "sin", 1, function_sin,
QString("Sine") ) );
add( new Function( "tan", 1, function_tan,
QString("Tangent") ) );
}
FunctionRepository::~FunctionRepository()
{
while( d->functions.size() > 0 )
{
delete d->functions[ 0 ];
d->functions.remove( 0 );
}
delete d;
}
void FunctionRepository::add( Function* function )
{
if( !function ) return;
d->functions.insert( function->name().toUpper(), function );
}
Function* FunctionRepository::function( const QString& name )
{
return d->functions.value( name.toUpper() );
}
QStringList FunctionRepository::functionNames() const
{
QStringList result;
QHashIterator<QString, Function*> it( d->functions );
while( it.hasNext() )
{
it.next();
result.append( it.key().toLower() );
}
return result;
}