Click here to Skip to main content
Click here to Skip to main content

A computational statistics class

By , 21 Nov 2004
 

Introduction

This is a computational statistics class written in C#. The public methods are described below.

Public methods

  • Constructor: public statistics(params double[] list)
  • Update the design: public void update(params double[] list)
  • Compute the mode: public double mode() - If there is more then one mode the NaN value will be returned.
  • Compute the size of the design: public int length()
  • Compute the minimum value of the design: public double min()
  • Compute the maximum value of the design: public double max()
  • Compute the first quarter : public double Q1()
  • Compute the median : public double Q2()
  • Compute the third quarter : public double Q3()
  • Compute the average: public double mean()
  • Compute the range: public double range()
  • Compute the inter quantile range: public double IQ()
  • Compute middle of range: public double middle_of_range()
  • Compute sample variance: public double var()
  • Compute standard deviation: public double s()
  • Compute the YULE index: public double YULE()
  • compute the index standard of a given member of the design: public double Z(double member)
  • compute the covariance: public double cov(statistics s), public static double cov(statistics s1,statistics s2)
  • compute the correlation coefficient: public double r(statistics design), public static double r(statistics design1,statistics design2)
  • compute the "a" factor of the linear function of design: public double a(statistics design)
  • compute the "a" factor of the linear function of design2: public static double a(statistics design1,statistics design2)
  • compute the "b" factor of the linear function of design: public double b(statistics design)
  • compute the "b" factor of the linear function of design 2: public static double b(statistics design1,statistics design2)

Source Code

using System;
 
namespace statistic
{
    
    public class statistics
    {
 
      private double[] list;
 
      public statistics(params double[] list)
      {
        this.list=list;
      }
      
      public void update(params double[] list)
      {
         this.list=list;
      }
 
      public double mode()
      {
         try
         {
                  double[] i=new double[list.Length];
                  list.CopyTo(i,0);
                  sort(i);
                  double val_mode=i[0],help_val_mode=i[0];
                  int old_counter=0,new_counter=0;
                  int j=0;
                  for (;j<=i.Length-1;j++)
                           if (i[j]==help_val_mode) new_counter++;
                           else if (new_counter>old_counter) 
                           {
                                   old_counter=new_counter;
                                   new_counter=1;
                                   help_val_mode=i[j];
                                   val_mode=i[j-1];
                           }
                           else if (new_counter==old_counter) 
                           {
                                   val_mode=double.NaN;
                                   help_val_mode=i[j];
                                   new_counter=1;
                           }
                           else 
                           {
                                   help_val_mode=i[j];
                                   new_counter=1;
                           }
                  if (new_counter>old_counter) val_mode=i[j-1]; 
                  else if (new_counter==old_counter) val_mode=double.NaN;
                  return val_mode;
         }
         catch (Exception)
         {
                  return double.NaN;
         }
      }
 
      public int length()
      {
         return list.Length;
      }
 
      public double min()
      {
         double minimum=double.PositiveInfinity;
         for (int i=0;i<=list.Length-1;i++)
                  if (list[i]<minimum) minimum=list[i];
         return minimum;
      }
 
      public double max()
      {
         double maximum=double.NegativeInfinity;
         for (int i=0;i<=list.Length-1;i++)
                  if (list[i]>maximum) maximum=list[i];
         return maximum;
      }   
    
      public double Q1()
      {
         return Qi(0.25);
      }
 
      public double Q2()
      {
         return Qi(0.5);
      }
 
      public double Q3()
      {
         return Qi(0.75);
      }
 
      public double mean()
      {
         try
         {
                  double sum=0;
                  for (int i=0;i<=list.Length-1;i++)
                           sum+=list[i];
                  return sum/list.Length;
         }
         catch (Exception)
         {
                  return double.NaN;
         }
      }
 
      public double range()
      {
         double minimum=min();
         double maximum=max();
         return (maximum-minimum);
      }
 
      public double IQ()
      { 
         return Q3()-Q1();
      }
 
      public double middle_of_range()
      {
         double minimum=min();
         double maximum=max();
         return (minimum+maximum)/2; 
      }
 
      public double var()
      {
         try
         {
                  double s=0;
                  for (int i=0;i<=list.Length-1;i++)
                           s+=Math.Pow(list[i],2);
                  return (s-list.Length*Math.Pow(mean(),2))/(list.Length-1);
         }
         catch (Exception)
         {
                  return double.NaN;
         }
      }
 
      public double s()
      {
         return Math.Sqrt(var());
      }
 
      public double YULE()
      {
         try
         {
                  return ((Q3()-Q2())-(Q2()-Q1()))/(Q3()-Q1());
         }
         catch (Exception)
         {
      return double.NaN;
         }
      }
 
      public double Z(double member)
      {
         try
         {
                  if (exist(member)) return (member-mean())/s();
                  else return double.NaN;
         }
         catch(Exception)
         {
                  return double.NaN;
         }
      }
 
      public double cov(statistics s)
      {
         try
         {
                  if (this.length()!=s.length()) return double.NaN;
                  int len=this.length();
                  double sum_mul=0;
                  for (int i=0;i<=len-1;i++)
                           sum_mul+=(this.list[i]*s.list[i]);
                  return (sum_mul-len*this.mean()*s.mean())/(len-1);
         }
         catch(Exception)
         {
      return double.NaN;
         }
      }
 
      public static double cov(statistics s1,statistics s2)
      {
         try
         {
                  if (s1.length()!=s2.length()) return double.NaN;
                  int len=s1.length();
                  double sum_mul=0;
                  for (int i=0;i<=len-1;i++)
                           sum_mul+=(s1.list[i]*s2.list[i]);
                  return (sum_mul-len*s1.mean()*s2.mean())/(len-1);
         }
         catch(Exception)
         {
                  return double.NaN;
         }
    }
 
      public double r(statistics design)
      {
         try
         {
                  return this.cov(design)/(this.s()*design.s());
         }
         catch(Exception)
         {
                  return double.NaN;
         }
      }
 
      public static double r(statistics design1,statistics design2)
      {
         try
         {
                  return cov(design1,design2)/(design1.s()*design2.s());
         }
         catch(Exception)
         {
                  return double.NaN;
         }
      }
 
      public double a(statistics design)
      {
         try
         {
                  return this.cov(design)/(Math.Pow(design.s(),2));
         }
         catch(Exception)
         {
             return double.NaN;
         }
      }
 
      public static double a(statistics design1,statistics design2)
      {
         try
         {
                  return cov(design1,design2)/(Math.Pow(design2.s(),2));
         }
         catch (Exception)
         {
                  return double.NaN;
         }
      }
 
      public double b(statistics design)
      {
         return this.mean()-this.a(design)*design.mean();
      }
 
      public static double b(statistics design1,statistics design2)
      {
         return design1.mean()-a(design1,design2)*design2.mean();
      }
 
      private double Qi(double i)
      {
         try
         {
                  double[] j=new double[list.Length];
                  list.CopyTo(j,0);
                  sort(j);
                  if (Math.Ceiling(list.Length*i)==list.Length*i) 
 return (j[(int)(list.Length*i-1)]+j[(int)(list.Length*i)])/2;
                  else return j[((int)(Math.Ceiling(list.Length*i)))-1];
          }
         catch(Exception)
         {
                  return double.NaN;
         }
      }
      
      private void sort(double[] i)
   {
         double[] temp=new double[i.Length];
          merge_sort(i,temp,0,i.Length-1);
    }
 
      private void  merge_sort(double[] source,
 double[] temp,int left,int right)
      {
         int mid;
         if (left<right) 
         {
                  mid=(left+right) / 2;
                  merge_sort(source,temp,left,mid);
                  merge_sort(source,temp,mid+1,right);
                  merge(source,temp,left,mid+1,right);
         }
      }
 
      private void  merge(double[] source,double[] temp,
int left,int mid,int right)
      {
         int i,left_end,num_elements,tmp_pos;
         left_end=mid - 1;
         tmp_pos=left;
         num_elements=right - left + 1;
         while ((left <= left_end) && (mid <= right)) 
         {
                  if (source[left] <= source[mid]) 
                  {            
                           temp[tmp_pos]= source[left];
                           tmp_pos++;
                           left++;
                  }
                  else
                  {   
                           temp[tmp_pos] = source[mid];
                           tmp_pos++;
                           mid++;
                  }
         }
         while (left <= left_end) 
         {
                  temp[tmp_pos]= source[left];
                  left++;
                  tmp_pos++;
         }
         while (mid <= right) 
         {
                  temp[tmp_pos]= source[mid];
                  mid++;
                  tmp_pos++;
         }
         for (i=1;i<=num_elements;i++)
         {
                  source[right]= temp[right];
                  right--;
         }
      }
 
      private bool exist(double member)
      {
         bool is_exist=false;
         int i=0;
    while (i<=list.Length-1 && !is_exist)
         {
          is_exist=(list[i]==member);
           i++;
         }
         return is_exist;
      }
      
    }
      
}

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

YOSSI ROZENBERG
Israel Israel
Member
No Biography provided

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionHow use?memberRSaldanha4 Aug '10 - 13:37 
Hi! I'm completely newbie to C#.
 
I had added the reference to the DLL, and called "using statistic" in the beginning of the code. But how can I call the functions, by example, the mean() ? I have a array of double, called 'valores'.
 
Thanks!
GeneralMy vote of 1memberDeep Ash23 Feb '10 - 1:54 
no description and somehow poor code structure
GeneralMy vote of 2memberSaar Yahalom15 Aug '09 - 11:31 
1. Code is written without numeric stability in mind.
2. Exceptions are swallowed without giving the user a proper indication, this is just plain bad practice.
3. Naming convention is poor.
 
Not an article to learn from.
GeneralRe: My vote of 2memberladuran6 May '10 - 11:33 
I cut the author some slack and give him a four. This is a functional library that works as advertised for "normal" data. The author is probably a math major and not a CS person. writing readable, maintainable code takes a while to get right. If you don't like it, then fix it.
GeneralVariancememberMember 453856011 Jun '09 - 10:52 
Hi. Thanks a bunch for that lovely class. I was looking for something like this for a while.
 
I feel that the function that computes the variance may be using an inaccurate algorithm. The right formula used to compute variance is listed here http://mathworld.wolfram.com/SampleVariance.html[^]
 
I have a feeling that the function should look something like this :
 
public double var()
{
try
{
double sum=0;
double difference, squaredDifference;
double theMean = mean();

for (int i = 0; i <= list.Length - 1; i++)
{
difference = list[i] - theMean;
squaredDifference = Math.Pow(difference, 2.0);
sum = sum + squaredDifference;
}
 
double variance = sum / list.Length;
return variance;

}
catch (Exception)
{
return double.NaN;
}
}
 
Thanks and Regards,
Ash.
GeneralPotential inaccuracymemberJohn D. Cook22 Oct '08 - 6:40 
Thank you for making your statistical code available.
 
I wanted to let you know there are potential problems with the algorithm you use for computing variance. Your algorithm is theoretically correct, but can fail numerically for some inputs. See comparing three methods of computing standard-deviation[^] and the link in the article giving a theoretical explanation of the problem.
Generalcovariancememberjimrob7818 Jan '07 - 6:31 
think the covariance method should return
return (sum_mul-len*s1.mean()*s2.mean())/(len);
not
return (sum_mul-len*s1.mean()*s2.mean())/(len-1);
GeneralQuantLibmemberTomaž Štih7 Nov '04 - 21:44 
Don't know if you know this one.
http://www.quantlib.org/[^]
There is a .NET version port. If nothing else it has really nice object design and one can learn from it (even if developing his own).
Regards,
Tomaz
GeneralRe: QuantLibmemberloizzi2 Sep '05 - 7:35 
Tomaž Štih wrote:
Don't know if you know this one.
http://www.quantlib.org/[^]
There is a .NET version port.

 

At time there is no available .NET port of this library, both known projects are "abandoned" like quantlib.org writes.
 
Bye
 
Frank Loizzi
GeneralRe: QuantLibmemberanybudy8 Apr '07 - 8:14 
It can be ported using SWIG but,(i couldnt see)does it have a statistics module?
GeneralArray.Sort() ...memberSébastien Lorion7 Nov '04 - 20:09 
Your sorting method is O(N^2), you should use Array.Sort() instead Smile | :)
 
Sébastien
 


Intelligence shared is intelligence squared.
 
Homepage : http://sebastienlorion.com

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web01 | 2.6.130516.1 | Last Updated 22 Nov 2004
Article Copyright 2004 by YOSSI ROZENBERG
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid