Click here to Skip to main content
Click here to Skip to main content
Add your own
alternative version

A Calculation Engine for .NET

, 1 Sep 2013
A calculation engine that is small, fast, and extensible.
using System;
using System.Net;
using System.Collections;
using System.Collections.Generic;

namespace CalcEngine
{
    static class Statistical
    {
        public static void Register(CalcEngine ce)
        {
            //ce.RegisterFunction("AVEDEV", AveDev, 1, int.MaxValue);
            ce.RegisterFunction("AVERAGE", 1, int.MaxValue, Average);
            ce.RegisterFunction("AVERAGEA", 1, int.MaxValue, AverageA);
            //BETADIST	Returns the beta cumulative distribution function
            //BETAINV	Returns the inverse of the cumulative distribution function for a specified beta distribution
            //BINOMDIST	Returns the individual term binomial distribution probability
            //CHIDIST	Returns the one-tailed probability of the chi-squared distribution
            //CHIINV	Returns the inverse of the one-tailed probability of the chi-squared distribution
            //CHITEST	Returns the test for independence
            //CONFIDENCE	Returns the confidence interval for a population mean
            //CORREL	Returns the correlation coefficient between two data sets
            ce.RegisterFunction("COUNT", 1, int.MaxValue, Count);
            ce.RegisterFunction("COUNTA", 1, int.MaxValue, CountA);
            ce.RegisterFunction("COUNTBLANK", 1, int.MaxValue, CountBlank);
            ce.RegisterFunction("COUNTIF", 2, CountIf);
            //COVAR	Returns covariance, the average of the products of paired deviations
            //CRITBINOM	Returns the smallest value for which the cumulative binomial distribution is less than or equal to a criterion value
            //DEVSQ	Returns the sum of squares of deviations
            //EXPONDIST	Returns the exponential distribution
            //FDIST	Returns the F probability distribution
            //FINV	Returns the inverse of the F probability distribution
            //FISHER	Returns the Fisher transformation
            //FISHERINV	Returns the inverse of the Fisher transformation
            //FORECAST	Returns a value along a linear trend
            //FREQUENCY	Returns a frequency distribution as a vertical array
            //FTEST	Returns the result of an F-test
            //GAMMADIST	Returns the gamma distribution
            //GAMMAINV	Returns the inverse of the gamma cumulative distribution
            //GAMMALN	Returns the natural logarithm of the gamma function, Γ(x)
            //GEOMEAN	Returns the geometric mean
            //GROWTH	Returns values along an exponential trend
            //HARMEAN	Returns the harmonic mean
            //HYPGEOMDIST	Returns the hypergeometric distribution
            //INTERCEPT	Returns the intercept of the linear regression line
            //KURT	Returns the kurtosis of a data set
            //LARGE	Returns the k-th largest value in a data set
            //LINEST	Returns the parameters of a linear trend
            //LOGEST	Returns the parameters of an exponential trend
            //LOGINV	Returns the inverse of the lognormal distribution
            //LOGNORMDIST	Returns the cumulative lognormal distribution
            ce.RegisterFunction("MAX", 1, int.MaxValue, Max);
            ce.RegisterFunction("MAXA", 1, int.MaxValue, MaxA);
            //MEDIAN	Returns the median of the given numbers
            ce.RegisterFunction("MIN", 1, int.MaxValue, Min);
            ce.RegisterFunction("MINA", 1, int.MaxValue, MinA);
            //MODE	Returns the most common value in a data set
            //NEGBINOMDIST	Returns the negative binomial distribution
            //NORMDIST	Returns the normal cumulative distribution
            //NORMINV	Returns the inverse of the normal cumulative distribution
            //NORMSDIST	Returns the standard normal cumulative distribution
            //NORMSINV	Returns the inverse of the standard normal cumulative distribution
            //PEARSON	Returns the Pearson product moment correlation coefficient
            //PERCENTILE	Returns the k-th percentile of values in a range
            //PERCENTRANK	Returns the percentage rank of a value in a data set
            //PERMUT	Returns the number of permutations for a given number of objects
            //POISSON	Returns the Poisson distribution
            //PROB	Returns the probability that values in a range are between two limits
            //QUARTILE	Returns the quartile of a data set
            //RANK	Returns the rank of a number in a list of numbers
            //RSQ	Returns the square of the Pearson product moment correlation coefficient
            //SKEW	Returns the skewness of a distribution
            //SLOPE	Returns the slope of the linear regression line
            //SMALL	Returns the k-th smallest value in a data set
            //STANDARDIZE	Returns a normalized value
            ce.RegisterFunction("STDEV", 1, int.MaxValue, StDev);
            ce.RegisterFunction("STDEVA", 1, int.MaxValue, StDevA);
            ce.RegisterFunction("STDEVP", 1, int.MaxValue, StDevP);
            ce.RegisterFunction("STDEVPA", 1, int.MaxValue, StDevPA);
            //STEYX	Returns the standard error of the predicted y-value for each x in the regression
            //TDIST	Returns the Student's t-distribution
            //TINV	Returns the inverse of the Student's t-distribution
            //TREND	Returns values along a linear trend
            //TRIMMEAN	Returns the mean of the interior of a data set
            //TTEST	Returns the probability associated with a Student's t-test
            ce.RegisterFunction("VAR", 1, int.MaxValue, Var);
            ce.RegisterFunction("VARA", 1, int.MaxValue, VarA);
            ce.RegisterFunction("VARP", 1, int.MaxValue, VarP);
            ce.RegisterFunction("VARPA", 1, int.MaxValue, VarPA);
            //WEIBULL	Returns the Weibull distribution
            //ZTEST	Returns the one-tailed probability-value of a z-test
        }

#if DEBUG
        public static void Test(CalcEngine ce)
        {
            ce.Test("Average(1, 3, 3, 1, true, false, \"hello\")", 2.0);
            ce.Test("AverageA(1, 3, 3, 1, true, false, \"hello\")", (1 + 3 + 3 + 1 + 1 + 0 + 0) / 7.0);
            ce.Test("Count(1, 3, 3, 1, true, false, \"hello\")", 4.0);
            ce.Test("CountA(1, 3, 3, 1, true, false, \"hello\")", 7.0);
        }
#endif

        static object Average(List<Expression> p)
        {
            return GetTally(p, true).Average();
        }
        static object AverageA(List<Expression> p)
        {
            return GetTally(p, false).Average();
        }
        static object Count(List<Expression> p)
        {
            return GetTally(p, true).Count();
        }
        static object CountA(List<Expression> p)
        {
            return GetTally(p, false).Count();
        }
        static object CountBlank(List<Expression> p)
        {
            var cnt = 0.0;
            foreach (Expression e in p)
            {
                var ienum = e as IEnumerable;
                if (ienum != null)
                {
                    foreach (var value in ienum)
                    {
                        if (IsBlank(value))
                            cnt++;
                    }
                }
                else
                {
                    if (IsBlank(e.Evaluate()))
                        cnt++;
                }
            }
            return cnt;
        }
        static bool IsBlank(object value)
        {
            return 
                value == null || 
                value is string && ((string)value).Length == 0;
        }
        static object CountIf(List<Expression> p)
        {
            CalcEngine ce = new CalcEngine();
            var cnt = 0.0;
            var ienum = p[0] as IEnumerable;
            if (ienum != null)
            {
                var crit = (string)p[1].Evaluate();
                foreach (var value in ienum)
                {
                    if (!IsBlank(value))
                    {
                        var exp = string.Format("{0}{1}", value, crit);
                        if ((bool)ce.Evaluate(exp))
                            cnt++;
                    }
                }
            }
            return cnt;
        }
        static object Max(List<Expression> p)
        {
            return GetTally(p, true).Max();
        }
        static object MaxA(List<Expression> p)
        {
            return GetTally(p, false).Max();
        }
        static object Min(List<Expression> p)
        {
            return GetTally(p, true).Min();
        }
        static object MinA(List<Expression> p)
        {
            return GetTally(p, false).Min();
        }
        static object StDev(List<Expression> p)
        {
            return GetTally(p, true).Std();
        }
        static object StDevA(List<Expression> p)
        {
            return GetTally(p, false).Std();
        }
        static object StDevP(List<Expression> p)
        {
            return GetTally(p, true).StdP();
        }
        static object StDevPA(List<Expression> p)
        {
            return GetTally(p, false).StdP();
        }
        static object Var(List<Expression> p)
        {
            return GetTally(p, true).Var();
        }
        static object VarA(List<Expression> p)
        {
            return GetTally(p, false).Var();
        }
        static object VarP(List<Expression> p)
        {
            return GetTally(p, true).VarP();
        }
        static object VarPA(List<Expression> p)
        {
            return GetTally(p, false).VarP();
        }

        // utility for tallying statistics
        static Tally GetTally(List<Expression> p, bool numbersOnly)
        {
            var tally = new Tally(numbersOnly);
            foreach (Expression e in p)
            {
                tally.Add(e);
            }
            return tally;
        }
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Bernardo Castilho
Chief Technology Officer ComponentOne
United States United States
No Biography provided

| Advertise | Privacy | Mobile
Web03 | 2.8.140827.1 | Last Updated 1 Sep 2013
Article Copyright 2011 by Bernardo Castilho
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid