1/*
2 * [The "BSD licence"]
3 * Copyright (c) 2005-2008 Terence Parr
4 * All rights reserved.
5 *
6 * Conversion to C#:
7 * Copyright (c) 2008-2009 Sam Harwell, Pixel Mine, Inc.
8 * All rights reserved.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 *    notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in the
17 *    documentation and/or other materials provided with the distribution.
18 * 3. The name of the author may not be used to endorse or promote products
19 *    derived from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33namespace Antlr.Runtime.Misc
34{
35    using System.Collections.Generic;
36
37    using Directory = System.IO.Directory;
38    using Environment = System.Environment;
39    using File = System.IO.File;
40    using Math = System.Math;
41    using Path = System.IO.Path;
42
43    /** <summary>Stats routines needed by profiler etc...</summary>
44     *
45     *  <remarks>
46     *  note that these routines return 0.0 if no values exist in the X[]
47     *  which is not "correct", but it is useful so I don't generate NaN
48     *  in my output
49     *  </remarks>
50     */
51    public class Stats
52    {
53        public const string ANTLRWORKS_DIR = "antlrworks";
54
55        /** <summary>Compute the sample (unbiased estimator) standard deviation following:</summary>
56         *
57         *  <remarks>
58         *  Computing Deviations: Standard Accuracy
59         *  Tony F. Chan and John Gregg Lewis
60         *  Stanford University
61         *  Communications of ACM September 1979 of Volume 22 the ACM Number 9
62         *
63         *  The "two-pass" method from the paper; supposed to have better
64         *  numerical properties than the textbook summation/sqrt.  To me
65         *  this looks like the textbook method, but I ain't no numerical
66         *  methods guy.
67         *  </remarks>
68         */
69        public static double Stddev( int[] X )
70        {
71            int m = X.Length;
72            if ( m <= 1 )
73            {
74                return 0;
75            }
76            double xbar = Average(X);
77            double s2 = 0.0;
78            for ( int i = 0; i < m; i++ )
79            {
80                s2 += ( X[i] - xbar ) * ( X[i] - xbar );
81            }
82            s2 = s2 / ( m - 1 );
83            return Math.Sqrt( s2 );
84        }
85        public static double Stddev( List<int> X )
86        {
87            int m = X.Count;
88            if ( m <= 1 )
89            {
90                return 0;
91            }
92            double xbar = Average(X);
93            double s2 = 0.0;
94            for ( int i = 0; i < m; i++ )
95            {
96                s2 += ( X[i] - xbar ) * ( X[i] - xbar );
97            }
98            s2 = s2 / ( m - 1 );
99            return Math.Sqrt( s2 );
100        }
101
102        /** <summary>Compute the sample mean</summary> */
103        public static double Average(ICollection<int> X)
104        {
105            if (X.Count == 0)
106                return 0.0;
107
108            double sum = 0.0;
109            foreach (int i in X)
110                sum += i;
111
112            return sum / X.Count;
113        }
114
115        public static void WriteReport( string filename, string data )
116        {
117            string absoluteFilename = GetAbsoluteFileName( filename );
118
119            Directory.CreateDirectory( Path.GetDirectoryName( absoluteFilename ) );
120            File.AppendAllText( absoluteFilename, data );
121        }
122
123        public static string GetAbsoluteFileName( string filename )
124        {
125            string personalFolder = Environment.GetFolderPath( Environment.SpecialFolder.Personal );
126            return personalFolder + Path.DirectorySeparatorChar +
127                        ANTLRWORKS_DIR + Path.DirectorySeparatorChar +
128                        filename;
129        }
130    }
131}
132