Updates referencesource to .NET 4.7
[mono.git] / mcs / class / referencesource / System.Web.DataVisualization / Common / General / Statistics.cs
1 //-------------------------------------------------------------
2 // <copyright company=\92Microsoft Corporation\92>
3 //   Copyright © Microsoft Corporation. All Rights Reserved.
4 // </copyright>
5 //-------------------------------------------------------------
6 // @owner=alexgor, deliant
7 //=================================================================
8 //  File:               StatisticFormula.cs
9 //
10 //  Namespace:  DataVisualization.Charting
11 //
12 //      Classes:        StatisticFormula, TTestResult, FTestResult, AnovaResult,
13 //              ZTestResult
14 //
15 //  Purpose:    StatisticFormula class provides helper methods for statistical
16 //              calculations like TTest, FTest, Anova, ZTest and others.
17 //              Actual calculations are made in the DataFormula class and 
18 //              the StatisticFormula class mange formula parameters, input and 
19 //              output series.
20 //
21 //              TTestResult, FTestResult, AnovaResult and ZTestResult
22 //              classes are used to store the results of the calculatiions.
23 //          
24 //              StatisticFormula class is exposed to the user through 
25 //              DataManipulator.StatisticFormula property. Here is an example of
26 //              using the Anova test:
27 //
28 //              AnovaResult result = Chart1.DataManipulator.StatisticFormula.Anova(0.6, "Group1,Group2,Group3");
29 //
30 //  NOTE:       First versions of the chart use single method to execute 
31 //              ALL formulas. Formula name and parameters were passed as
32 //              strings. Input and outpat data was passed through data
33 //              series.
34 //
35 //              This approach was hard to use by the end-user and was 
36 //              changed to a specific method for each formula. StatisticFormula
37 //              class provides that simplified interface for all statistics 
38 //              formulas. Internally it still uses the DataFormula.Formula
39 //              method with string parameters.
40 //
41 //      Reviewed:       AG - April 1, 2003
42 //              AG - Microsoft 14, 2007
43 //
44 //===================================================================
45
46 using System;
47 using System.Diagnostics.CodeAnalysis;
48
49 #if Microsoft_CONTROL
50         namespace System.Windows.Forms.DataVisualization.Charting
51 #else
52 namespace System.Web.UI.DataVisualization.Charting
53
54 #endif
55 {
56     /// <summary>
57     /// The StatisticFormula class provides helper methods for statistical calculations.
58     /// Actual calculations are made in the DataFormula class and the StatisticFormula
59     /// class provide a simplified API which automatically prepares parameters and 
60     /// deals with input and output series. 
61     /// </summary>
62 #if ASPPERM_35
63         [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
64     [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
65 #endif
66     public class StatisticFormula
67         {
68                 #region Fields
69
70         // Name used for temporary data series
71                 private string _tempOutputSeriesName = "Statistical Analyses Formula Temporary Output Series 2552003";
72
73         // Reference to the class which describes calculation settings and 
74         // provides access to chart common elements.
75                 private DataFormula _formulaData = null;
76
77                 #endregion // Fields
78                 
79                 #region Constructor
80
81                 /// <summary>
82         /// StatisticFormula Constructor
83                 /// </summary>
84                 /// <param name="formulaData">Formula Data</param>
85                 internal StatisticFormula( DataFormula formulaData )
86                 {
87                         this._formulaData = formulaData;
88                 }
89
90                 #endregion // Constructor
91
92                 #region Tests
93                 
94                 /// <summary>
95         /// This formula performs a Z Test using Normal distribution.
96                 /// </summary>
97                 /// <param name="hypothesizedMeanDifference">Hypothesized mean difference.</param>
98                 /// <param name="varianceFirstGroup">Variance first group.</param>
99                 /// <param name="varianceSecondGroup">Variance second group.</param>
100                 /// <param name="probability">Probability.</param>
101                 /// <param name="firstInputSeriesName">First input series name.</param>
102                 /// <param name="secondInputSeriesName">Second input series name.</param>
103         /// <returns>ZTestResult object.</returns>
104                 public ZTestResult ZTest( 
105                         double hypothesizedMeanDifference, 
106                         double varianceFirstGroup, 
107                         double varianceSecondGroup, 
108                         double probability, 
109                         string firstInputSeriesName, 
110                         string secondInputSeriesName )
111                 {
112             // Check arguments
113             if (firstInputSeriesName == null)
114                 throw new ArgumentNullException("firstInputSeriesName");
115             if (secondInputSeriesName == null)
116                 throw new ArgumentNullException("secondInputSeriesName");
117
118                         // Create output class
119                         ZTestResult zTestResult = new ZTestResult();
120
121                         // Make string with parameters
122                         string parameter = hypothesizedMeanDifference.ToString(System.Globalization.CultureInfo.InvariantCulture);
123                         parameter += "," + varianceFirstGroup.ToString(System.Globalization.CultureInfo.InvariantCulture);
124                         parameter += "," + varianceSecondGroup.ToString(System.Globalization.CultureInfo.InvariantCulture);
125                         parameter += "," + probability.ToString(System.Globalization.CultureInfo.InvariantCulture);
126                         
127                         // Create temporary output series.
128                         _formulaData.Common.DataManager.Series.Add( new Series(_tempOutputSeriesName) );
129
130                         // Set input series string
131                         string inputSeriesParameter = firstInputSeriesName.ToString(System.Globalization.CultureInfo.InvariantCulture) + "," + secondInputSeriesName.ToString(System.Globalization.CultureInfo.InvariantCulture);
132                         
133             // Execute formula
134             try
135             {
136                 _formulaData.Formula("ZTest", parameter, inputSeriesParameter, _tempOutputSeriesName);
137
138                 DataPointCollection points = _formulaData.Common.DataManager.Series[_tempOutputSeriesName].Points;
139
140                 // Fill Output class
141                 zTestResult.firstSeriesMean = points[0].YValues[0];
142                 zTestResult.secondSeriesMean = points[1].YValues[0];
143                 zTestResult.firstSeriesVariance = points[2].YValues[0];
144                 zTestResult.secondSeriesVariance = points[3].YValues[0];
145                 zTestResult.zValue = points[4].YValues[0];
146                 zTestResult.probabilityZOneTail = points[5].YValues[0];
147                 zTestResult.zCriticalValueOneTail = points[6].YValues[0];
148                 zTestResult.probabilityZTwoTail = points[7].YValues[0];
149                 zTestResult.zCriticalValueTwoTail = points[8].YValues[0];
150             }
151             finally
152             {
153                 // Remove Temporary output series
154                 _formulaData.Common.DataManager.Series.Remove(_formulaData.Common.DataManager.Series[_tempOutputSeriesName]);
155             }
156
157                         // Return result class
158                         return zTestResult;
159                         
160                 }
161
162                 /// <summary>
163         /// Perform a T Test using Students distribution (T distribution) with unequal variances.
164                 /// </summary>
165                 /// <param name="hypothesizedMeanDifference">Hypothesized mean difference.</param>
166                 /// <param name="probability">Probability.</param>
167                 /// <param name="firstInputSeriesName">First input series name.</param>
168                 /// <param name="secondInputSeriesName">Second input series name.</param>
169         /// <returns>TTestResult object.</returns>
170                 public TTestResult TTestUnequalVariances( 
171                         double hypothesizedMeanDifference, 
172                         double probability, 
173                         string firstInputSeriesName, 
174                         string secondInputSeriesName )
175                 {
176             // Check arguments
177             if (firstInputSeriesName == null)
178                 throw new ArgumentNullException("firstInputSeriesName");
179             if (secondInputSeriesName == null)
180                 throw new ArgumentNullException("secondInputSeriesName");
181
182                         // Create output class
183                         TTestResult tTestResult = new TTestResult();
184
185                         // Make string with parameters
186                         string parameter = hypothesizedMeanDifference.ToString(System.Globalization.CultureInfo.InvariantCulture);
187                         parameter += "," + probability.ToString(System.Globalization.CultureInfo.InvariantCulture);
188                         
189                         // Create temporary output series.
190                         _formulaData.Common.DataManager.Series.Add( new Series(_tempOutputSeriesName) );
191
192                         // Set input series string
193             try
194             {
195                 string inputSeriesParameter = firstInputSeriesName.ToString(System.Globalization.CultureInfo.InvariantCulture) + "," + secondInputSeriesName.ToString(System.Globalization.CultureInfo.InvariantCulture);
196
197                 // Execute formula
198                 _formulaData.Formula("TTestUnequalVariances", parameter, inputSeriesParameter, _tempOutputSeriesName);
199
200                 DataPointCollection points = _formulaData.Common.DataManager.Series[_tempOutputSeriesName].Points;
201
202                 // Fill Output class
203                 tTestResult.firstSeriesMean = points[0].YValues[0];
204                 tTestResult.secondSeriesMean = points[1].YValues[0];
205                 tTestResult.firstSeriesVariance = points[2].YValues[0];
206                 tTestResult.secondSeriesVariance = points[3].YValues[0];
207                 tTestResult.tValue = points[4].YValues[0];
208                 tTestResult.degreeOfFreedom = points[5].YValues[0];
209                 tTestResult.probabilityTOneTail = points[6].YValues[0];
210                 tTestResult.tCriticalValueOneTail = points[7].YValues[0];
211                 tTestResult.probabilityTTwoTail = points[8].YValues[0];
212                 tTestResult.tCriticalValueTwoTail = points[9].YValues[0];
213             }
214             finally
215             {
216                 // Remove Temporary output series
217                 _formulaData.Common.DataManager.Series.Remove(_formulaData.Common.DataManager.Series[_tempOutputSeriesName]);
218             }
219
220                         // Return result class
221                         return tTestResult;
222                         
223                 }
224
225                 /// <summary>
226         /// Perform a T Test using Students distribution (T distribution) with equal variances.
227                 /// </summary>
228                 /// <param name="hypothesizedMeanDifference">Hypothesized mean difference.</param>
229                 /// <param name="probability">Probability.</param>
230                 /// <param name="firstInputSeriesName">First input series name.</param>
231                 /// <param name="secondInputSeriesName">Second input series name.</param>
232         /// <returns>TTestResult object.</returns>
233                 public TTestResult TTestEqualVariances( 
234                         double hypothesizedMeanDifference, 
235                         double probability, 
236                         string firstInputSeriesName, 
237                         string secondInputSeriesName )
238                 {
239             // Check arguments
240             if (firstInputSeriesName == null)
241                 throw new ArgumentNullException("firstInputSeriesName");
242             if (secondInputSeriesName == null)
243                 throw new ArgumentNullException("secondInputSeriesName");
244
245                         // Create output class
246                         TTestResult tTestResult = new TTestResult();
247
248                         // Make string with parameters
249                         string parameter = hypothesizedMeanDifference.ToString(System.Globalization.CultureInfo.InvariantCulture);
250                         parameter += "," + probability.ToString(System.Globalization.CultureInfo.InvariantCulture);
251                         
252                         // Create temporary output series.
253                         _formulaData.Common.DataManager.Series.Add( new Series(_tempOutputSeriesName) );
254
255                         // Set input series string
256                         string inputSeriesParameter = firstInputSeriesName.ToString(System.Globalization.CultureInfo.InvariantCulture) + "," + secondInputSeriesName.ToString(System.Globalization.CultureInfo.InvariantCulture);
257                         
258                         // Execute formula
259             try
260             {
261                 _formulaData.Formula("TTestEqualVariances", parameter, inputSeriesParameter, _tempOutputSeriesName);
262
263                 DataPointCollection points = _formulaData.Common.DataManager.Series[_tempOutputSeriesName].Points;
264
265                 // Fill Output class
266                 tTestResult.firstSeriesMean = points[0].YValues[0];
267                 tTestResult.secondSeriesMean = points[1].YValues[0];
268                 tTestResult.firstSeriesVariance = points[2].YValues[0];
269                 tTestResult.secondSeriesVariance = points[3].YValues[0];
270                 tTestResult.tValue = points[4].YValues[0];
271                 tTestResult.degreeOfFreedom = points[5].YValues[0];
272                 tTestResult.probabilityTOneTail = points[6].YValues[0];
273                 tTestResult.tCriticalValueOneTail = points[7].YValues[0];
274                 tTestResult.probabilityTTwoTail = points[8].YValues[0];
275                 tTestResult.tCriticalValueTwoTail = points[9].YValues[0];
276             }
277             finally
278             {
279                 // Remove Temporary output series
280                 _formulaData.Common.DataManager.Series.Remove(_formulaData.Common.DataManager.Series[_tempOutputSeriesName]);
281             }
282
283                         // Return result class
284                         return tTestResult;                     
285                 }
286
287                 /// <summary>
288         /// Performs a T Test using Students distribution (T distribution) with paired samples. 
289         /// This is useful when there is a natural pairing of observations in samples.
290                 /// </summary>
291         /// <param name="hypothesizedMeanDifference">Hypothesized mean difference.</param>
292         /// <param name="probability">Probability.</param>
293         /// <param name="firstInputSeriesName">First input series name.</param>
294         /// <param name="secondInputSeriesName">Second input series name.</param>
295         /// <returns>TTestResult object.</returns>
296                 public TTestResult TTestPaired( 
297                         double hypothesizedMeanDifference, 
298                         double probability, 
299                         string firstInputSeriesName, 
300                         string secondInputSeriesName )
301                 {
302             // Check arguments
303             if (firstInputSeriesName == null)
304                 throw new ArgumentNullException("firstInputSeriesName");
305             if (secondInputSeriesName == null)
306                 throw new ArgumentNullException("secondInputSeriesName");
307
308                         // Create output class
309                         TTestResult tTestResult = new TTestResult();
310
311                         // Make string with parameters
312                         string parameter = hypothesizedMeanDifference.ToString(System.Globalization.CultureInfo.InvariantCulture);
313                         parameter += "," + probability.ToString(System.Globalization.CultureInfo.InvariantCulture);
314                         
315                         // Create temporary output series.
316                         _formulaData.Common.DataManager.Series.Add( new Series(_tempOutputSeriesName) );
317
318                         // Set input series string
319                         string inputSeriesParameter = firstInputSeriesName.ToString(System.Globalization.CultureInfo.InvariantCulture) + "," + secondInputSeriesName.ToString(System.Globalization.CultureInfo.InvariantCulture);
320                         
321                         // Execute formula
322             try
323             {
324                 _formulaData.Formula("TTestPaired", parameter, inputSeriesParameter, _tempOutputSeriesName);
325
326                 DataPointCollection points = _formulaData.Common.DataManager.Series[_tempOutputSeriesName].Points;
327
328                 // Fill Output class
329                 tTestResult.firstSeriesMean = points[0].YValues[0];
330                 tTestResult.secondSeriesMean = points[1].YValues[0];
331                 tTestResult.firstSeriesVariance = points[2].YValues[0];
332                 tTestResult.secondSeriesVariance = points[3].YValues[0];
333                 tTestResult.tValue = points[4].YValues[0];
334                 tTestResult.degreeOfFreedom = points[5].YValues[0];
335                 tTestResult.probabilityTOneTail = points[6].YValues[0];
336                 tTestResult.tCriticalValueOneTail = points[7].YValues[0];
337                 tTestResult.probabilityTTwoTail = points[8].YValues[0];
338                 tTestResult.tCriticalValueTwoTail = points[9].YValues[0];
339             }
340             finally
341             {
342                 // Remove Temporary output series
343                 _formulaData.Common.DataManager.Series.Remove(_formulaData.Common.DataManager.Series[_tempOutputSeriesName]);
344             }
345
346                         // Return result class
347                         return tTestResult;
348                         
349                 }
350
351         /// <summary>
352         /// Removes empty points from series.
353         /// </summary>
354         /// <param name="seriesName">series name</param>
355         private void RemoveEmptyPoints(string seriesName)
356         {
357             Series series = _formulaData.Common.DataManager.Series[seriesName];
358             for (int pointIndex = 0; pointIndex < series.Points.Count; pointIndex++)
359             {
360                 if (series.Points[pointIndex].IsEmpty)
361                 {
362                     series.Points.RemoveAt(pointIndex--);
363                 }
364             }
365         }
366
367         /// <summary>
368         /// This formula performs a two-sample F Test using the F distribution, and is used to see if the samples have different variances.
369         /// </summary>
370         /// <param name="probability">Probability.</param>
371         /// <param name="firstInputSeriesName">First input series name.</param>
372         /// <param name="secondInputSeriesName">Second input series name.</param>
373         /// <returns>FTestResult object.</returns>
374         public FTestResult FTest( 
375                         double probability, 
376                         string firstInputSeriesName, 
377                         string secondInputSeriesName )
378                 {
379             // Check arguments
380             if (firstInputSeriesName == null)
381                 throw new ArgumentNullException("firstInputSeriesName");
382             if (secondInputSeriesName == null)
383                 throw new ArgumentNullException("secondInputSeriesName");
384
385                         // Create output class
386                         FTestResult fTestResult = new FTestResult();
387
388                         // Make string with parameters
389                         string parameter = probability.ToString(System.Globalization.CultureInfo.InvariantCulture);
390
391                         // Set input series string
392                         string inputSeriesParameter = firstInputSeriesName.ToString(System.Globalization.CultureInfo.InvariantCulture) + "," + secondInputSeriesName.ToString(System.Globalization.CultureInfo.InvariantCulture);
393                         
394                         // Create temporary output series.
395                         _formulaData.Common.DataManager.Series.Add( new Series(_tempOutputSeriesName) );
396
397             
398             // remove empty points from the collection.
399             RemoveEmptyPoints(firstInputSeriesName);
400             RemoveEmptyPoints(secondInputSeriesName);
401
402                         // Execute formula
403             try
404             {
405                 _formulaData.Formula("FTest", parameter, inputSeriesParameter, _tempOutputSeriesName);
406
407                 DataPointCollection points = _formulaData.Common.DataManager.Series[_tempOutputSeriesName].Points;
408
409                 // Fill Output class
410                 fTestResult.firstSeriesMean = points[0].YValues[0];
411                 fTestResult.secondSeriesMean = points[1].YValues[0];
412                 fTestResult.firstSeriesVariance = points[2].YValues[0];
413                 fTestResult.secondSeriesVariance = points[3].YValues[0];
414                 fTestResult.fValue = points[4].YValues[0];
415                 fTestResult.probabilityFOneTail = points[5].YValues[0];
416                 fTestResult.fCriticalValueOneTail = points[6].YValues[0];
417             }
418             finally
419             {
420                 // Remove Temporary output series
421                 _formulaData.Common.DataManager.Series.Remove(_formulaData.Common.DataManager.Series[_tempOutputSeriesName]);
422             }
423
424                         // Return result class
425                         return fTestResult;
426                         
427                 }
428
429
430                 /// <summary>
431         /// An Anova test is used to determine the existence, or absence of a statistically 
432         /// significant difference between the mean values of two or more groups of data.
433                 /// </summary>
434                 /// <param name="probability">Probability.</param>
435         /// <param name="inputSeriesNames">Comma-delimited list of input series names.</param>
436         /// <returns>AnovaResult object.</returns>
437                 public AnovaResult Anova( 
438                         double probability, 
439                         string inputSeriesNames)
440                 {
441             // Check arguments
442             if (inputSeriesNames == null)
443                 throw new ArgumentNullException("inputSeriesNames");
444
445                         // Create output class
446                         AnovaResult anovaResult = new AnovaResult();
447
448                         // Make string with parameters
449                         string parameter = probability.ToString(System.Globalization.CultureInfo.InvariantCulture);
450                         
451                         // Create temporary output series.
452                         _formulaData.Common.DataManager.Series.Add( new Series(_tempOutputSeriesName) );
453
454                         // Execute formula
455             try
456             {
457                 _formulaData.Formula("Anova", parameter, inputSeriesNames, _tempOutputSeriesName);
458
459                 DataPointCollection points = _formulaData.Common.DataManager.Series[_tempOutputSeriesName].Points;
460
461                 // Fill Output class
462                 anovaResult.sumOfSquaresBetweenGroups = points[0].YValues[0];
463                 anovaResult.sumOfSquaresWithinGroups = points[1].YValues[0];
464                 anovaResult.sumOfSquaresTotal = points[2].YValues[0];
465                 anovaResult.degreeOfFreedomBetweenGroups = points[3].YValues[0];
466                 anovaResult.degreeOfFreedomWithinGroups = points[4].YValues[0];
467                 anovaResult.degreeOfFreedomTotal = points[5].YValues[0];
468                 anovaResult.meanSquareVarianceBetweenGroups = points[6].YValues[0];
469                 anovaResult.meanSquareVarianceWithinGroups = points[7].YValues[0];
470                 anovaResult.fRatio = points[8].YValues[0];
471                 anovaResult.fCriticalValue = points[9].YValues[0];
472             }
473             finally
474             {
475                 // Remove Temporary output series
476                 _formulaData.Common.DataManager.Series.Remove(_formulaData.Common.DataManager.Series[_tempOutputSeriesName]);
477             }
478
479                         // Return result class
480                         return anovaResult;                     
481                 }
482
483                 #endregion // Test
484
485                 #region Distributions
486
487                 /// <summary>
488         /// This method returns the probability for the standard normal cumulative distribution function.
489                 /// </summary>
490         /// <param name="zValue">The Z value for which the probability is required.</param>
491                 /// <returns>Returns value from the standard normal cumulative distribution function.</returns>
492         [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly",
493             Justification = "Z is a cartesian coordinate and well understood")]
494         public double NormalDistribution(double zValue)
495                 {
496                         // Make string with parameters
497                         string parameter = zValue.ToString(System.Globalization.CultureInfo.InvariantCulture);
498                         
499                         // Create temporary output series.
500                         _formulaData.Common.DataManager.Series.Add( new Series(_tempOutputSeriesName) );
501                         
502                         // Execute formula
503             double result = double.NaN;
504             try
505             {
506                 _formulaData.Formula("NormalDistribution", parameter, _tempOutputSeriesName, _tempOutputSeriesName);
507
508                 DataPointCollection points = _formulaData.Common.DataManager.Series[_tempOutputSeriesName].Points;
509
510                 // Fill Output class
511                 result = points[0].YValues[0];
512             }
513             finally
514             {
515                 // Remove Temporary output series
516                 _formulaData.Common.DataManager.Series.Remove(_formulaData.Common.DataManager.Series[_tempOutputSeriesName]);
517             }
518
519                         // Return result class
520                         return result;
521                         
522                 }
523
524                 /// <summary>
525         /// This method returns the inverse of the standard normal cumulative distribution.
526                 /// </summary>
527                 /// <param name="probability">Probability.</param>
528                 /// <returns>Returns value from the inverse standard normal cumulative distribution function.</returns>
529                 public double InverseNormalDistribution( double probability )
530                 {
531                         
532                         // Make string with parameters
533                         string parameter = probability.ToString(System.Globalization.CultureInfo.InvariantCulture);
534                         
535                         // Create temporary output series.
536                         _formulaData.Common.DataManager.Series.Add( new Series(_tempOutputSeriesName) );
537                         
538                         // Execute formula
539             double result = double.NaN;
540             try
541             {
542                 _formulaData.Formula("InverseNormalDistribution", parameter, _tempOutputSeriesName, _tempOutputSeriesName);
543
544                 DataPointCollection points = _formulaData.Common.DataManager.Series[_tempOutputSeriesName].Points;
545
546                 // Fill Output class
547                 result = points[0].YValues[0];
548             }
549             finally
550             {
551                 // Remove Temporary output series
552                 _formulaData.Common.DataManager.Series.Remove(_formulaData.Common.DataManager.Series[_tempOutputSeriesName]);
553             }
554
555                         // Return result class
556                         return result;                  
557                 }
558
559                 /// <summary>
560         /// This method returns the cumulative F distribution function probability.
561                 /// </summary>
562                 /// <param name="value">F Value.</param>
563                 /// <param name="firstDegreeOfFreedom">First degree of freedom.</param>
564                 /// <param name="secondDegreeOfFreedom">Second degree of freedom.</param>
565                 /// <returns>Returns value from the cumulative F distribution function.</returns>
566                 public double FDistribution( 
567                         double value,
568                         int firstDegreeOfFreedom,
569                         int secondDegreeOfFreedom )
570                 {
571                         
572                         // Make string with parameters
573                         string parameter = value.ToString(System.Globalization.CultureInfo.InvariantCulture);
574                         parameter += "," + firstDegreeOfFreedom.ToString(System.Globalization.CultureInfo.InvariantCulture);
575                         parameter += "," + secondDegreeOfFreedom.ToString(System.Globalization.CultureInfo.InvariantCulture);
576                         
577                         // Create temporary output series.
578                         _formulaData.Common.DataManager.Series.Add( new Series(_tempOutputSeriesName) );
579                         
580                         // Execute formula
581             double result = double.NaN;
582             try
583             {
584                 _formulaData.Formula("FDistribution", parameter, _tempOutputSeriesName, _tempOutputSeriesName);
585
586                 DataPointCollection points = _formulaData.Common.DataManager.Series[_tempOutputSeriesName].Points;
587
588                 // Fill Output class
589                 result = points[0].YValues[0];
590             }
591             finally
592             {
593                 // Remove Temporary output series
594                 _formulaData.Common.DataManager.Series.Remove(_formulaData.Common.DataManager.Series[_tempOutputSeriesName]);
595             }
596
597                         // Return result class
598                         return result;                  
599                 }
600
601                 /// <summary>
602         /// Returns the inverse of the F cumulative distribution.
603                 /// </summary>
604                 /// <param name="probability">Probability.</param>
605                 /// <param name="firstDegreeOfFreedom">First degree of freedom.</param>
606                 /// <param name="secondDegreeOfFreedom">Second degree of freedom.</param>
607                 /// <returns>Returns value from the inverse F distribution function.</returns>
608                 public double InverseFDistribution( 
609                         double probability,
610                         int firstDegreeOfFreedom,
611                         int secondDegreeOfFreedom )
612                 {
613                         
614                         // Make string with parameters
615                         string parameter = probability.ToString(System.Globalization.CultureInfo.InvariantCulture);
616                         parameter += "," + firstDegreeOfFreedom.ToString(System.Globalization.CultureInfo.InvariantCulture);
617                         parameter += "," + secondDegreeOfFreedom.ToString(System.Globalization.CultureInfo.InvariantCulture);
618                         
619                         // Create temporary output series.
620                         _formulaData.Common.DataManager.Series.Add( new Series(_tempOutputSeriesName) );
621                         
622                         // Execute formula
623             double result = double.NaN;
624             try
625             {
626                 _formulaData.Formula("InverseFDistribution", parameter, _tempOutputSeriesName, _tempOutputSeriesName);
627
628                 DataPointCollection points = _formulaData.Common.DataManager.Series[_tempOutputSeriesName].Points;
629
630                 // Fill Output class
631                 result = points[0].YValues[0];
632             }
633             finally
634             {
635                 // Remove Temporary output series
636                 _formulaData.Common.DataManager.Series.Remove(_formulaData.Common.DataManager.Series[_tempOutputSeriesName]);
637             }
638
639                         // Return result class
640                         return result;                  
641                 }
642                 
643                 /// <summary>
644         /// Returns the probability for the T distribution (student's distribution).
645                 /// </summary>
646                 /// <param name="value">T value</param>
647                 /// <param name="degreeOfFreedom">Degree of freedom</param>
648         /// <param name="oneTail">If true, one-tailed distribution is used; otherwise two-tailed distribution is used.</param>
649                 /// <returns>Returns T Distribution cumulative function</returns>
650                 public double TDistribution( 
651                         double value,
652                         int degreeOfFreedom,
653                         bool oneTail )
654                 {
655                         
656                         // Make string with parameters
657                         string parameter = value.ToString(System.Globalization.CultureInfo.InvariantCulture);
658                         parameter += "," + degreeOfFreedom.ToString(System.Globalization.CultureInfo.InvariantCulture);
659                         if( oneTail )
660                         {
661                                 parameter += ",1";
662                         }
663                         else
664                         {
665                                 parameter += ",2";
666                         }
667                         
668                                                 
669                         // Create temporary output series.
670                         _formulaData.Common.DataManager.Series.Add( new Series(_tempOutputSeriesName) );
671
672             // Execute formula
673             double result = double.NaN;
674             try
675             {
676                 _formulaData.Formula("TDistribution", parameter, _tempOutputSeriesName, _tempOutputSeriesName);
677
678                 DataPointCollection points = _formulaData.Common.DataManager.Series[_tempOutputSeriesName].Points;
679
680                 // Fill Output class
681                 result = points[0].YValues[0];
682             }
683             finally
684             {
685                 // Remove Temporary output series
686                 _formulaData.Common.DataManager.Series.Remove(_formulaData.Common.DataManager.Series[_tempOutputSeriesName]);
687             }
688
689                 // Return result class
690                         return result;
691                         
692                 }
693
694                 /// <summary>
695         /// Returns the T-value of the T distribution as a function of probability and degrees of freedom.
696                 /// </summary>
697                 /// <param name="probability">Probability.</param>
698                 /// <param name="degreeOfFreedom">Degree of freedom.</param>
699                 /// <returns>Returns Inverse T distribution.</returns>
700                 public double InverseTDistribution( 
701                         double probability,
702                         int degreeOfFreedom )
703                 {
704                         
705                         // Make string with parameters
706                         string parameter = probability.ToString(System.Globalization.CultureInfo.InvariantCulture);
707                         parameter += "," + degreeOfFreedom.ToString(System.Globalization.CultureInfo.InvariantCulture);
708                                                 
709                         // Create temporary output series.
710                         _formulaData.Common.DataManager.Series.Add( new Series(_tempOutputSeriesName) );
711
712             // Execute formula
713             double result = double.NaN;
714             try
715             {
716                 _formulaData.Formula("InverseTDistribution", parameter, _tempOutputSeriesName, _tempOutputSeriesName);
717
718                 DataPointCollection points = _formulaData.Common.DataManager.Series[_tempOutputSeriesName].Points;
719
720                 // Fill Output class
721                 result = points[0].YValues[0];
722             }
723             finally
724             {
725                 // Remove Temporary output series
726                 _formulaData.Common.DataManager.Series.Remove(_formulaData.Common.DataManager.Series[_tempOutputSeriesName]);
727             }
728
729                         // Return result class
730                         return result;
731                         
732                 }
733
734                 #endregion // Distributions
735
736                 #region Correlation and Covariance
737
738                 /// <summary>
739         /// This method gets the covariance value for two series of data.
740                 /// </summary>
741                 /// <param name="firstInputSeriesName">First input series name.</param>
742                 /// <param name="secondInputSeriesName">Second input series name.</param>
743                 /// <returns>Covariance.</returns>
744                 public double Covariance( 
745                         string firstInputSeriesName, 
746                         string secondInputSeriesName )
747                 {
748             // Check arguments
749             if (firstInputSeriesName == null)
750                 throw new ArgumentNullException("firstInputSeriesName");
751             if (secondInputSeriesName == null)
752                 throw new ArgumentNullException("secondInputSeriesName");                       
753
754                         // Create temporary output series.
755                         _formulaData.Common.DataManager.Series.Add( new Series(_tempOutputSeriesName) );
756
757                         // Set input series string
758                         string inputSeriesParameter = firstInputSeriesName.ToString(System.Globalization.CultureInfo.InvariantCulture) + "," + secondInputSeriesName.ToString(System.Globalization.CultureInfo.InvariantCulture);
759                         
760                         // Execute formula
761             double result = double.NaN;
762             try
763             {                
764                 _formulaData.Formula("Covariance", "", inputSeriesParameter, _tempOutputSeriesName);
765
766                 DataPointCollection points = _formulaData.Common.DataManager.Series[_tempOutputSeriesName].Points;
767
768                 // Fill Output value
769                 result = points[0].YValues[0];
770             }
771             finally
772             {
773                 // Remove Temporary output series
774                 _formulaData.Common.DataManager.Series.Remove(_formulaData.Common.DataManager.Series[_tempOutputSeriesName]);
775             }
776             
777                         // Return result
778                         return result;
779                         
780                 }
781
782                 /// <summary>
783         /// This method gets the correlation value for two series of data.
784                 /// </summary>
785                 /// <param name="firstInputSeriesName">First input series name.</param>
786                 /// <param name="secondInputSeriesName">Second input series name.</param>
787                 /// <returns>Returns Correlation</returns>
788                 public double Correlation( 
789                         string firstInputSeriesName, 
790                         string secondInputSeriesName )
791                 {
792             // Check arguments
793             if (firstInputSeriesName == null)
794                 throw new ArgumentNullException("firstInputSeriesName");
795             if (secondInputSeriesName == null)
796                 throw new ArgumentNullException("secondInputSeriesName");                       
797
798                         // Create temporary output series.
799                         _formulaData.Common.DataManager.Series.Add( new Series(_tempOutputSeriesName) );
800
801                         // Set input series string
802                         string inputSeriesParameter = firstInputSeriesName + "," + secondInputSeriesName;
803                         
804                         // Execute formula
805             double result = double.NaN;
806             try
807             {
808                 _formulaData.Formula("Correlation", "", inputSeriesParameter, _tempOutputSeriesName);
809
810                 DataPointCollection points = _formulaData.Common.DataManager.Series[_tempOutputSeriesName].Points;
811
812                 // Fill Output value
813                 result = points[0].YValues[0];
814             }
815             finally
816             {
817                 // Remove Temporary output series
818                 _formulaData.Common.DataManager.Series.Remove(_formulaData.Common.DataManager.Series[_tempOutputSeriesName]);
819             }
820
821                         // Return result
822                         return result;
823                         
824                 }
825
826                 /// <summary>
827         /// This method returns the average of all data points stored in the specified series.
828                 /// </summary>
829                 /// <param name="inputSeriesName">Input series name.</param>
830                 /// <returns>The average of all data points.</returns>
831                 public double Mean( 
832                         string inputSeriesName )
833                 {
834             // Check arguments
835             if (inputSeriesName == null)
836                 throw new ArgumentNullException("inputSeriesName");
837                         
838                         // Create temporary output series.
839                         _formulaData.Common.DataManager.Series.Add( new Series(_tempOutputSeriesName) );
840
841                         // Set input series string
842                         string inputSeriesParameter = inputSeriesName;
843                         
844                         // Execute formula
845             double result = double.NaN;
846             try
847             {
848                 _formulaData.Formula("Mean", "", inputSeriesParameter, _tempOutputSeriesName);
849
850                 DataPointCollection points = _formulaData.Common.DataManager.Series[_tempOutputSeriesName].Points;
851
852                 // Fill Output value
853                 result = points[0].YValues[0];
854             }
855             finally
856             {
857                 // Remove Temporary output series
858                 _formulaData.Common.DataManager.Series.Remove(_formulaData.Common.DataManager.Series[_tempOutputSeriesName]);
859             }
860
861                         // Return result
862                         return result;
863                         
864                 }
865
866                 /// <summary>
867         /// This method returns the median of all data points in the specified series.
868                 /// </summary>
869                 /// <param name="inputSeriesName">Input series name.</param>
870                 /// <returns>Median.</returns>
871                 public double Median( 
872                         string inputSeriesName )
873                 {
874             // Check arguments
875             if (inputSeriesName == null)
876                 throw new ArgumentNullException("inputSeriesName");                     
877
878                         // Create temporary output series.
879                         _formulaData.Common.DataManager.Series.Add( new Series(_tempOutputSeriesName) );
880
881                         // Set input series string
882                         string inputSeriesParameter = inputSeriesName;
883                         
884                         // Execute formula
885             double result = double.NaN;
886             try
887             {
888                 _formulaData.Formula("Median", "", inputSeriesParameter, _tempOutputSeriesName);
889
890                 DataPointCollection points = _formulaData.Common.DataManager.Series[_tempOutputSeriesName].Points;
891
892                 // Fill Output value
893                 result = points[0].YValues[0];
894             }
895             finally
896             {
897                 // Remove Temporary output series
898                 _formulaData.Common.DataManager.Series.Remove(_formulaData.Common.DataManager.Series[_tempOutputSeriesName]);
899             }
900
901                         // Return result
902                         return result;
903                         
904                 }
905
906         /// <summary>
907         /// This method returns the variance for a series.
908         /// </summary>
909         /// <param name="inputSeriesName">Input series name.</param>
910         /// <param name="sampleVariance">If true, the data is a sample of the population.  If false, it is the entire population.</param>
911         /// <returns>Variance.</returns>
912                 public double Variance( 
913                         string inputSeriesName,
914                         bool sampleVariance )
915                 {
916             // Check arguments
917             if (inputSeriesName == null)
918                 throw new ArgumentNullException("inputSeriesName");
919                         
920                         // Create temporary output series.
921                         _formulaData.Common.DataManager.Series.Add( new Series(_tempOutputSeriesName) );
922
923                         // Set input series string
924                         string inputSeriesParameter = inputSeriesName;
925
926                         // Formula parameter
927                         string parameter = sampleVariance.ToString(System.Globalization.CultureInfo.InvariantCulture);
928                         
929                         // Execute formula
930             double result = double.NaN;
931             try
932             {
933                 _formulaData.Formula("Variance", parameter, inputSeriesParameter, _tempOutputSeriesName);
934
935                 DataPointCollection points = _formulaData.Common.DataManager.Series[_tempOutputSeriesName].Points;
936
937                 // Fill Output value
938                 result = points[0].YValues[0];
939             }
940             finally
941             {
942                 // Remove Temporary output series
943                 _formulaData.Common.DataManager.Series.Remove(_formulaData.Common.DataManager.Series[_tempOutputSeriesName]);
944             }
945
946                         // Return result
947                         return result;
948                         
949                 }
950
951                 /// <summary>
952         /// This method returns the beta function for two given values.
953                 /// </summary>
954                 /// <param name="m">First parameter for beta function</param>
955                 /// <param name="n">Second Parameter for beta function</param>
956                 /// <returns>Returns beta function for the two given values.</returns>
957         [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly",
958              Justification = "The Beta Function is a mathematical function where arbitrary letters to indicate inputs are common")]  
959         public double BetaFunction( 
960                         double m,
961                         double n )
962                 {
963             // Fix for the VSTS 230829: The BetaFunction for the m=0,n=0 is double.NaN
964             if (m == 0 && n == 0)
965                 return double.NaN;
966
967                         // Create temporary output series.
968                         _formulaData.Common.DataManager.Series.Add( new Series(_tempOutputSeriesName) );
969                         
970                         // Formula parameter
971                         string parameter = m.ToString(System.Globalization.CultureInfo.InvariantCulture);
972                         parameter += "," + n.ToString(System.Globalization.CultureInfo.InvariantCulture);
973                         
974                         // Execute formula
975             double result = double.NaN;
976             try
977             {
978                 _formulaData.Formula("BetaFunction", parameter, _tempOutputSeriesName, _tempOutputSeriesName);
979
980                 DataPointCollection points = _formulaData.Common.DataManager.Series[_tempOutputSeriesName].Points;
981
982                 // Fill Output value
983                 result = points[0].YValues[0];
984             }
985             finally
986             {
987                 // Remove Temporary output series
988                 _formulaData.Common.DataManager.Series.Remove(_formulaData.Common.DataManager.Series[_tempOutputSeriesName]);
989             }
990
991                         // Return result
992                         return result;                  
993                 }
994
995         /// <summary>
996         /// This method returns the gamma function value for the given variable.
997         /// </summary>
998         /// <param name="value">The value.</param>
999         /// <returns>Returns gamma function</returns>
1000                 public double GammaFunction( 
1001                         double value )
1002                 {
1003                         
1004                         // Create temporary output series.
1005                         _formulaData.Common.DataManager.Series.Add( new Series(_tempOutputSeriesName) );
1006                         
1007                         // Formula parameter
1008                         string parameter = value.ToString(System.Globalization.CultureInfo.InvariantCulture);
1009                                                 
1010                         // Execute formula
1011             double result = double.NaN;
1012             try
1013             {
1014                 _formulaData.Formula("GammaFunction", parameter, _tempOutputSeriesName, _tempOutputSeriesName);
1015
1016                 DataPointCollection points = _formulaData.Common.DataManager.Series[_tempOutputSeriesName].Points;
1017
1018                 // Fill Output value
1019                 result = points[0].YValues[0];
1020             }
1021             finally
1022             {
1023                 // Remove Temporary output series
1024                 _formulaData.Common.DataManager.Series.Remove(_formulaData.Common.DataManager.Series[_tempOutputSeriesName]);
1025             }
1026
1027                         // Return result
1028                         return result;
1029                         
1030                 }
1031                 
1032                 #endregion
1033         }
1034
1035     #region Output classes used to store statistical calculations results
1036
1037     /// <summary>
1038     /// The TTestResult class stores the results of the TTest statistical calculations.
1039     /// </summary>
1040 #if ASPPERM_35
1041         [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
1042     [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
1043 #endif
1044     public class TTestResult
1045     {
1046         #region Fields
1047
1048         /// <summary>
1049         /// First series' mean.
1050         /// </summary>
1051         internal double firstSeriesMean = 0.0;
1052
1053         /// <summary>
1054         /// Second series' mean.
1055         /// </summary>
1056         internal double secondSeriesMean = 0.0;
1057
1058         /// <summary>
1059         /// First series' variance.
1060         /// </summary>
1061         internal double firstSeriesVariance = 0.0;
1062
1063         /// <summary>
1064         /// Second series' variance.
1065         /// </summary>
1066         internal double secondSeriesVariance = 0.0;
1067
1068         /// <summary>
1069         /// T value.
1070         /// </summary>
1071         internal double tValue = 0.0;
1072
1073         /// <summary>
1074         /// Degree of freedom.
1075         /// </summary>
1076         internal double degreeOfFreedom = 0.0;
1077
1078         /// <summary>
1079         /// Probability T one tail.
1080         /// </summary>
1081         internal double probabilityTOneTail = 0.0;
1082
1083         /// <summary>
1084         /// Critical T one tail.
1085         /// </summary>
1086         internal double tCriticalValueOneTail = 0.0;
1087
1088         /// <summary>
1089         /// Probability T two tails.
1090         /// </summary>
1091         internal double probabilityTTwoTail = 0.0;
1092
1093         /// <summary>
1094         /// Critical T two tails.
1095         /// </summary>
1096         internal double tCriticalValueTwoTail = 0.0;
1097
1098         #endregion
1099
1100         #region Properties
1101
1102         /// <summary>
1103         /// Gets the mean of the first series.
1104         /// </summary>
1105         public double FirstSeriesMean
1106         {
1107             get
1108             {
1109                 return firstSeriesMean;
1110             }
1111         }
1112
1113         /// <summary>
1114         /// Gets the mean of the second series.
1115         /// </summary>
1116         public double SecondSeriesMean
1117         {
1118             get
1119             {
1120                 return secondSeriesMean;
1121             }
1122         }
1123
1124         /// <summary>
1125         /// Gets the variance of the first series.
1126         /// </summary>
1127         public double FirstSeriesVariance
1128         {
1129             get
1130             {
1131                 return firstSeriesVariance;
1132             }
1133         }
1134
1135         /// <summary>
1136         /// Gets the variance of the second series.
1137         /// </summary>
1138         public double SecondSeriesVariance
1139         {
1140             get
1141             {
1142                 return secondSeriesVariance;
1143             }
1144         }
1145
1146         /// <summary>
1147         /// Gets the T value.
1148         /// </summary>
1149         public double TValue
1150         {
1151             get
1152             {
1153                 return tValue;
1154             }
1155         }
1156
1157         /// <summary>
1158         /// Gets the degree of freedom.
1159         /// </summary>
1160         public double DegreeOfFreedom
1161         {
1162             get
1163             {
1164                 return degreeOfFreedom;
1165             }
1166         }
1167
1168         /// <summary>
1169         /// Gets the probability T one tail value.
1170         /// </summary>
1171         [SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly",
1172             Justification = "T One Tail is a statistics term. 'Tone' is not the intended word here.")]   
1173         public double ProbabilityTOneTail
1174         {
1175             get
1176             {
1177                 return probabilityTOneTail;
1178             }
1179         }
1180
1181         /// <summary>
1182         /// Gets the critical T one tail value.
1183         /// </summary>
1184         public double TCriticalValueOneTail
1185         {
1186             get
1187             {
1188                 return tCriticalValueOneTail;
1189             }
1190         }
1191
1192         /// <summary>
1193         /// Gets the probability T two tails value.
1194         /// </summary>
1195         public double ProbabilityTTwoTail
1196         {
1197             get
1198             {
1199                 return probabilityTTwoTail;
1200             }
1201         }
1202
1203         /// <summary>
1204         /// Gets the critical T two tails value.
1205         /// </summary>
1206         public double TCriticalValueTwoTail
1207         {
1208             get
1209             {
1210                 return tCriticalValueTwoTail;
1211             }
1212         }
1213
1214         #endregion
1215     }
1216
1217     /// <summary>
1218     /// The FTestResult class stores the results of the FTest statistical calculations.
1219     /// </summary>
1220 #if ASPPERM_35
1221         [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
1222     [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
1223 #endif
1224     public class FTestResult
1225     {
1226         #region Fields
1227
1228         /// <summary>
1229         /// First series' mean.
1230         /// </summary>
1231         internal double firstSeriesMean = 0.0;
1232
1233         /// <summary>
1234         /// Second series' mean.
1235         /// </summary>
1236         internal double secondSeriesMean = 0.0;
1237
1238         /// <summary>
1239         /// First series' variance.
1240         /// </summary>
1241         internal double firstSeriesVariance = 0.0;
1242
1243         /// <summary>
1244         /// Second series' variance.
1245         /// </summary>
1246         internal double secondSeriesVariance = 0.0;
1247
1248         /// <summary>
1249         /// F value.
1250         /// </summary>
1251         internal double fValue = 0.0;
1252
1253         /// <summary>
1254         /// Probability F one tail.
1255         /// </summary>
1256         internal double probabilityFOneTail = 0.0;
1257
1258         /// <summary>
1259         /// Critical F one tail.
1260         /// </summary>
1261         internal double fCriticalValueOneTail = 0.0;
1262
1263         #endregion
1264
1265         #region Properties
1266
1267         /// <summary>
1268         /// Gets the mean of the first series.
1269         /// </summary>
1270         public double FirstSeriesMean
1271         {
1272             get
1273             {
1274                 return firstSeriesMean;
1275             }
1276         }
1277
1278         /// <summary>
1279         /// Gets the mean of the second series.
1280         /// </summary>
1281         public double SecondSeriesMean
1282         {
1283             get
1284             {
1285                 return secondSeriesMean;
1286             }
1287         }
1288
1289         /// <summary>
1290         /// Gets the variance of the first series.
1291         /// </summary>
1292         public double FirstSeriesVariance
1293         {
1294             get
1295             {
1296                 return firstSeriesVariance;
1297             }
1298         }
1299
1300         /// <summary>
1301         /// Gets the variance of the second series.
1302         /// </summary>
1303         public double SecondSeriesVariance
1304         {
1305             get
1306             {
1307                 return secondSeriesVariance;
1308             }
1309         }
1310
1311         /// <summary>
1312         /// Gets the F value.
1313         /// </summary>
1314         public double FValue
1315         {
1316             get
1317             {
1318                 return fValue;
1319             }
1320         }
1321
1322         /// <summary>
1323         /// Gets the probability F one tail.
1324         /// </summary>
1325         public double ProbabilityFOneTail
1326         {
1327             get
1328             {
1329                 return probabilityFOneTail;
1330             }
1331         }
1332
1333         /// <summary>
1334         /// Gets the critical F one tail.
1335         /// </summary>
1336         public double FCriticalValueOneTail
1337         {
1338             get
1339             {
1340                 return fCriticalValueOneTail;
1341             }
1342         }
1343
1344         #endregion
1345     }
1346
1347     /// <summary>
1348     /// The AnovaResult class stores the results of the Anova statistical calculations.
1349     /// </summary>
1350 #if ASPPERM_35
1351         [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
1352     [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
1353 #endif
1354     public class AnovaResult
1355     {
1356         #region Fields
1357
1358         /// <summary>
1359         /// Sum of squares between groups.
1360         /// </summary>
1361         internal double sumOfSquaresBetweenGroups = 0.0;
1362
1363         /// <summary>
1364         /// Sum of squares within groups.
1365         /// </summary>
1366         internal double sumOfSquaresWithinGroups = 0.0;
1367
1368         /// <summary>
1369         /// Total sum of squares.
1370         /// </summary>
1371         internal double sumOfSquaresTotal = 0.0;
1372
1373         /// <summary>
1374         /// Degree of freedom between groups.
1375         /// </summary>
1376         internal double degreeOfFreedomBetweenGroups = 0.0;
1377
1378         /// <summary>
1379         /// Degree of freedom within groups.
1380         /// </summary>
1381         internal double degreeOfFreedomWithinGroups = 0.0;
1382
1383         /// <summary>
1384         /// Total degree of freedom.
1385         /// </summary>
1386         internal double degreeOfFreedomTotal = 0.0;
1387
1388         /// <summary>
1389         /// Mean square variance between groups.
1390         /// </summary>
1391         internal double meanSquareVarianceBetweenGroups = 0.0;
1392
1393         /// <summary>
1394         /// Mean square variance between groups.
1395         /// </summary>
1396         internal double meanSquareVarianceWithinGroups = 0.0;
1397
1398         /// <summary>
1399         /// F ratio.
1400         /// </summary>
1401         internal double fRatio = 0.0;
1402
1403         /// <summary>
1404         /// F critical value.
1405         /// </summary>
1406         internal double fCriticalValue = 0.0;
1407
1408         #endregion
1409
1410         #region Properties
1411
1412         /// <summary>
1413         /// Gets the sum of squares between groups.
1414         /// </summary>
1415         public double SumOfSquaresBetweenGroups
1416         {
1417             get
1418             {
1419                 return sumOfSquaresBetweenGroups;
1420             }
1421         }
1422
1423         /// <summary>
1424         /// Gets the sum of squares within groups.
1425         /// </summary>
1426         public double SumOfSquaresWithinGroups
1427         {
1428             get
1429             {
1430                 return sumOfSquaresWithinGroups;
1431             }
1432         }
1433
1434
1435         /// <summary>
1436         /// Gets the total sum of squares.
1437         /// </summary>
1438         public double SumOfSquaresTotal
1439         {
1440             get
1441             {
1442                 return sumOfSquaresTotal;
1443             }
1444         }
1445
1446         /// <summary>
1447         /// Gets the degree of freedom between groups.
1448         /// </summary>
1449         public double DegreeOfFreedomBetweenGroups
1450         {
1451             get
1452             {
1453                 return degreeOfFreedomBetweenGroups;
1454             }
1455         }
1456
1457         /// <summary>
1458         /// Gets the degree of freedom within groups.
1459         /// </summary>
1460         public double DegreeOfFreedomWithinGroups
1461         {
1462             get
1463             {
1464                 return degreeOfFreedomWithinGroups;
1465             }
1466         }
1467
1468         /// <summary>
1469         /// Gets the total degree of freedom.
1470         /// </summary>
1471         public double DegreeOfFreedomTotal
1472         {
1473             get
1474             {
1475                 return degreeOfFreedomTotal;
1476             }
1477         }
1478
1479         /// <summary>
1480         /// Gets the mean square variance between groups.
1481         /// </summary>
1482         public double MeanSquareVarianceBetweenGroups
1483         {
1484             get
1485             {
1486                 return meanSquareVarianceBetweenGroups;
1487             }
1488         }
1489
1490         /// <summary>
1491         /// Gets the mean square variance within groups.
1492         /// </summary>
1493         public double MeanSquareVarianceWithinGroups
1494         {
1495             get
1496             {
1497                 return meanSquareVarianceWithinGroups;
1498             }
1499         }
1500
1501         /// <summary>
1502         /// Gets the F ratio.
1503         /// </summary>
1504         public double FRatio
1505         {
1506             get
1507             {
1508                 return fRatio;
1509             }
1510         }
1511
1512         /// <summary>
1513         /// Gets the F critical value.
1514         /// </summary>
1515         public double FCriticalValue
1516         {
1517             get
1518             {
1519                 return fCriticalValue;
1520             }
1521         }
1522
1523         #endregion
1524     }
1525
1526     /// <summary>
1527     /// The ZTestResult class stores the results of the ZTest statistical calculations.
1528     /// </summary>
1529 #if ASPPERM_35
1530         [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
1531     [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
1532 #endif
1533     public class ZTestResult
1534     {
1535         #region Constructor
1536
1537         /// <summary>
1538         /// ZTestResult Constructor
1539         /// </summary>
1540         public ZTestResult()
1541         {
1542         }
1543
1544         #endregion // Constructor
1545
1546         #region Fields
1547
1548         // Internal fields used for public properties
1549         internal double firstSeriesMean;
1550         internal double secondSeriesMean;
1551         internal double firstSeriesVariance;
1552         internal double secondSeriesVariance;
1553         internal double zValue;
1554         internal double probabilityZOneTail;
1555         internal double zCriticalValueOneTail;
1556         internal double probabilityZTwoTail;
1557         internal double zCriticalValueTwoTail;
1558
1559
1560         #endregion // Fields
1561
1562         #region Properties
1563
1564         /// <summary>
1565         /// Gets the mean of the first series.
1566         /// </summary>
1567         public double FirstSeriesMean
1568         {
1569             get
1570             {
1571                 return firstSeriesMean;
1572             }
1573         }
1574
1575         /// <summary>
1576         /// Gets the mean of the second series.
1577         /// </summary>
1578         public double SecondSeriesMean
1579         {
1580             get
1581             {
1582                 return secondSeriesMean;
1583             }
1584         }
1585
1586         /// <summary>
1587         /// Gets the variance of the first series.
1588         /// </summary>
1589         public double FirstSeriesVariance
1590         {
1591             get
1592             {
1593                 return firstSeriesVariance;
1594             }
1595         }
1596
1597         /// <summary>
1598         /// Gets the variance of the second series.
1599         /// </summary>
1600         public double SecondSeriesVariance
1601         {
1602             get
1603             {
1604                 return secondSeriesVariance;
1605             }
1606         }
1607
1608         /// <summary>
1609         /// Gets the Z Value
1610         /// </summary>
1611         public double ZValue
1612         {
1613             get
1614             {
1615                 return zValue;
1616             }
1617         }
1618
1619         /// <summary>
1620         /// Gets the probability Z one tail value.
1621         /// </summary>
1622         [SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly",
1623             Justification = "Z One Tail is a statistics term. 'Zone' is not the intended word here.")]  
1624         public double ProbabilityZOneTail
1625         {
1626             get
1627             {
1628                 return probabilityZOneTail;
1629             }
1630         }
1631
1632         /// <summary>
1633         /// Gets the Z critical value one tail value.
1634         /// </summary>
1635         public double ZCriticalValueOneTail
1636         {
1637             get
1638             {
1639                 return zCriticalValueOneTail;
1640             }
1641         }
1642
1643         /// <summary>
1644         /// Gets the probability Z two tail value.
1645         /// </summary>
1646         public double ProbabilityZTwoTail
1647         {
1648             get
1649             {
1650                 return probabilityZTwoTail;
1651             }
1652         }
1653
1654         /// <summary>
1655         /// Gets the Z critical value two tail value.
1656         /// </summary>
1657         public double ZCriticalValueTwoTail
1658         {
1659             get
1660             {
1661                 return zCriticalValueTwoTail;
1662             }
1663         }
1664
1665         #endregion // Properties
1666     }
1667
1668     #endregion // Output Classes
1669 }
1670
1671