Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.Problems.GrammaticalOptimization/SharpVectorCore/Utils/Polynomials/Polynomial.cs @ 12762

Last change on this file since 12762 was 12762, checked in by aballeit, 9 years ago

#2283 GUI updates, Tree-chart, MCTS Version 2 (prune leaves)

File size: 7.0 KB
Line 
1using System;
2
3namespace SharpVectors.Polynomials
4{
5  /// <summary>
6  /// Summary description for Polynomial.
7  /// </summary>
8    /// <developer>kevin@kevlindev.com</developer>
9    /// <completed>100</completed>
10  public class Polynomial
11  {
12        #region fields
13        private double[] coefficients;
14        private double s;
15        #endregion
16
17        #region properties
18        public int Degree
19        {
20            get { return this.coefficients.Length - 1; }
21        }
22
23        public double this[int index]
24        {
25            get { return this.coefficients[index]; }
26        }
27        #endregion
28
29        #region constructors
30        /// <summary>
31        /// Polynomial constuctor
32        /// </summary>
33        /// <param name="coefficients"></param>
34    public Polynomial(params double[] coefficients)
35    {
36            int end = 0;
37            double TOLERANCE = 1e-9;
38
39            for ( end = coefficients.Length; end > 0; end-- )
40            {
41                if ( Math.Abs(coefficients[end-1]) > TOLERANCE )
42                    break;
43            }
44
45            if ( end > 0 )
46            {
47                this.coefficients = new double[coefficients.Length - (coefficients.Length - end)];
48                for ( int i = 0; i < end; i++ )
49                {
50                    this.coefficients[i] = coefficients[i];
51                }
52            }
53            else
54            {
55                this.coefficients = new double[0];
56            }
57    }
58
59        public Polynomial(Polynomial that)
60        {
61            this.coefficients = that.coefficients;
62        }
63        #endregion
64
65        #region class methods
66        /// <summary>
67        /// Interpolate - adapted from "Numerical Recipes in C"
68        /// </summary>
69        /// <param name="xs"></param>
70        /// <param name="ys"></param>
71        /// <param name="n"></param>
72        /// <param name="offset"></param>
73        /// <param name="x"></param>
74        /// <returns></returns>
75        static public ValueWithError Interpolate(double[] xs, double[] ys, int n, int offset, double x)
76        {
77            double y;
78            double dy = 0.0;
79            double[] c = new double[n];
80            double[] d = new double[n];
81            int ns = 0;
82       
83            double diff = Math.Abs(x - xs[offset]);
84            for ( int i = 0; i < n; i++ )
85            {
86                double dift = Math.Abs(x - xs[offset+i]);
87
88                if ( dift < diff )
89                {
90                    ns = i;
91                    diff = dift;
92                }
93                c[i] = d[i] = ys[offset+i];
94            }
95            y = ys[offset+ns];
96            ns--;
97
98            for ( int m = 1; m < n; m++ )
99            {
100                for ( int i = 0; i < n-m; i++ )
101                {
102                    double ho = xs[offset+i] - x;
103                    double hp = xs[offset+i+m] - x;
104                    double w = c[i+1]-d[i];
105                    double den = ho - hp;
106
107                    if ( den == 0.0 ) return new ValueWithError(0,0);
108
109                    den = w / den;
110                    d[i] = hp*den;
111                    c[i] = ho*den;
112                }
113                dy = (2*(ns+1) < (n-m)) ? c[ns+1] : d[ns--];
114                y += dy;
115            }
116
117            return new ValueWithError(y, dy);
118        }
119        #endregion
120
121        #region protected methods
122        /// <summary>
123        /// trapezoid - adapted from "Numerical Recipes in C"
124        /// </summary>
125        /// <param name="min"></param>
126        /// <param name="max"></param>
127        /// <param name="n"></param>
128        /// <returns></returns>
129        protected double trapezoid(double min, double max, int n)
130        {
131            double range = max - min;
132
133            if ( n == 1 )
134            {
135                this.s = 0.5*range*(this.Evaluate(min)+this.Evaluate(max));
136            }
137            else
138            {
139                int it = 1 << (n-2);
140                double delta = range / it;
141                double x = min + 0.5*delta;
142                double sum = 0.0;
143
144                for ( int i = 0; i < it; i++ )
145                {
146                    sum += this.Evaluate(x);
147                    x += delta;
148                }
149                this.s = 0.5*(this.s + range*sum/it);
150            }
151
152            return this.s;
153        }
154        #endregion
155
156        #region public methods
157        /// <summary>
158        /// Evaluate
159        /// </summary>
160        /// <param name="t"></param>
161        /// <returns></returns>
162        public virtual double Evaluate(double t)
163        {
164            double result = 0.0;
165
166            for ( int i = this.coefficients.Length - 1; i >= 0; i-- )
167            {
168                result = result * t + this.coefficients[i];
169            }
170
171            return result;
172        }
173
174        /// <summary>
175        /// Simspon - adapted from "Numerical Recipes in C"
176        /// </summary>
177        /// <param name="min"></param>
178        /// <param name="max"></param>
179        /// <returns></returns>
180        public double Simpson(double min, double max)
181        {
182            double s = 0.0;
183            double st = 0.0;
184            double os = 0.0;
185            double ost = 0.0;
186            int MAX = 20;
187            double TOLERANCE = 1e-7;
188
189            for ( int j = 1; j <= MAX; j++ )
190            {
191                st = this.trapezoid(min, max, j);
192                s = (4.0 * st - ost) / 3.0;
193                if ( Math.Abs(s - os) < TOLERANCE*Math.Abs(os)) break;
194                os = s;
195                ost = st;
196            }
197
198            return s;
199        }
200
201        /// <summary>
202        /// Romberg - adapted from "Numerical Recipes in C"
203        /// </summary>
204        /// <param name="min"></param>
205        /// <param name="max"></param>
206        /// <returns></returns>
207        public double Romberg(double min, double max)
208        {
209            int MAX = 20;
210            double TOLERANCE = 1e-7;
211            int K = 4;
212            double[] s = new double[MAX+1];
213            double[] h = new double[MAX+1];
214            ValueWithError result = new ValueWithError(0,0);
215
216            h[0] = 1.0;
217            for ( int j = 1; j <= MAX; j++ )
218            {
219                s[j-1] = trapezoid(min, max, j);
220                if ( j >= K )
221                {
222                    result = Polynomial.Interpolate(h, s, K, j-K, 0.0);
223                    if ( Math.Abs(result.Error) < TOLERANCE*result.Value ) break;
224                }
225                s[j] = s[j-1];
226                h[j] = 0.25 * h[j-1];
227            }
228
229            return result.Value;
230        }
231        #endregion
232  }
233
234    /// <summary>
235    /// Stucture used to return values with associated error tolerances
236    /// </summary>
237    public struct ValueWithError
238    {
239        public double Value;
240        public double Error;
241
242        public ValueWithError(double value, double error)
243        {
244            this.Value = value;
245            this.Error = error;
246        }
247    }
248}
Note: See TracBrowser for help on using the repository browser.