Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.Problems.GaussianProcessTuning/ILNumerics.2.14.4735.573/Functions/builtin/eps.cs @ 9407

Last change on this file since 9407 was 9102, checked in by gkronber, 12 years ago

#1967: ILNumerics source for experimentation

File size: 18.7 KB
Line 
1///
2///    This file is part of ILNumerics Community Edition.
3///
4///    ILNumerics Community Edition - high performance computing for applications.
5///    Copyright (C) 2006 - 2012 Haymo Kutschbach, http://ilnumerics.net
6///
7///    ILNumerics Community Edition is free software: you can redistribute it and/or modify
8///    it under the terms of the GNU General Public License version 3 as published by
9///    the Free Software Foundation.
10///
11///    ILNumerics Community Edition is distributed in the hope that it will be useful,
12///    but WITHOUT ANY WARRANTY; without even the implied warranty of
13///    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14///    GNU General Public License for more details.
15///
16///    You should have received a copy of the GNU General Public License
17///    along with ILNumerics Community Edition. See the file License.txt in the root
18///    of your distribution package. If not, see <http://www.gnu.org/licenses/>.
19///
20///    In addition this software uses the following components and/or licenses:
21///
22///    =================================================================================
23///    The Open Toolkit Library License
24///   
25///    Copyright (c) 2006 - 2009 the Open Toolkit library.
26///   
27///    Permission is hereby granted, free of charge, to any person obtaining a copy
28///    of this software and associated documentation files (the "Software"), to deal
29///    in the Software without restriction, including without limitation the rights to
30///    use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
31///    the Software, and to permit persons to whom the Software is furnished to do
32///    so, subject to the following conditions:
33///
34///    The above copyright notice and this permission notice shall be included in all
35///    copies or substantial portions of the Software.
36///
37///    =================================================================================
38///   
39
40using System;
41using System.Collections.Generic;
42using System.Text;
43using ILNumerics.Storage;
44using ILNumerics.Misc;
45using ILNumerics.Exceptions;
46
47namespace ILNumerics {
48
49    public partial class ILMath {
50        /// <summary>
51        /// Double precision epsilon - the smallest difference from 1.0
52        /// </summary>
53        public static double eps {
54            get {
55                return MachineParameterDouble.eps;
56            }
57        }
58        /// <summary>
59        /// Single precision epsilon - the smalles difference from 1.0f
60        /// </summary>
61        public static float epsf {
62            get {
63                return MachineParameterSingle.eps;
64            }
65        }
66    }
67
68    /// <summary>
69    /// Extensive numerical machine parameter infos - single precision
70    /// </summary>
71    public struct MachineParameterSingle {
72        /// <summary>
73        /// Radix
74        /// </summary>
75        public int ibeta;
76        /// <summary>
77        /// Number of base digits(bits) in the mantissa
78        /// </summary>
79        public int it;
80        /// <summary>
81        /// Rounding and underflow information. 
82        /// </summary>
83        /// <remarks><list type="bullet"><listheader>Rounding properties</listheader>
84        /// <item>2,5: IEEE rounding conform </item>
85        /// <item>1,4: not IEEE conform rounding </item>
86        /// <item>0,3: truncating - no rounding </item></list>
87        /// <list type="bullet"><listheader>Under-/ Overflow. numbers below xmin will be interpreted as... </listheader>
88        /// <item>0,1,2: zero</item>
89        /// <item>3,4,5: xmin (IEEE conform)</item></list></remarks>
90        public int irnd;
91        /// <summary>
92        /// Number of guard digits in the product of 2 mantissas
93        /// </summary>
94        public int ngrd;
95        /// <summary>
96        /// Exponent of the smalles number ibeta^machep &gt; 1.0
97        /// </summary>
98        public int machep;
99        /// <summary>
100        /// Exponent of smallest number ibeta^negep wich may be substracted from 1.0, giving a result not equal to 1.0
101        /// </summary>
102        public int negep;
103        /// <summary>
104        /// Number of exponent bits
105        /// </summary>
106        public int iexp;
107        /// <summary>
108        /// Smallest power of ibeta without leading zeros in the mantissa
109        /// </summary>
110        public int minexp;
111        /// <summary>
112        /// Smallest power of ibeta where overflow occours
113        /// </summary>
114        public int maxexp;
115        /// <summary>
116        /// Distance between the smallest number &gt; 1.0, distinguishable from 1.0 and 1.0
117        /// </summary>
118        /// <remarks>This number is computed by ibeta <sup>machep</sup>.</remarks>
119        public float eps;
120        /// <summary>
121        /// Alternative eps. ibeta <sup>negep</sup>
122        /// </summary>
123        public float epsneg;
124        /// <summary>
125        /// Smallest floating point number
126        /// </summary>
127        public float xmin;
128        /// <summary>
129        /// Largest floating point number
130        /// </summary>
131        public float xmax;
132    }
133    /// <summary>
134    /// Extensive numerical machine parameter infos - double precision
135    /// </summary>
136    public struct MachineParameterDouble {
137        /// <summary>
138        /// Radix
139        /// </summary>
140        public int ibeta;
141        /// <summary>
142        /// Number of base digits(bits) in the mantissa
143        /// </summary>
144        public int it;
145        /// <summary>
146        /// Rounding and underflow information. 
147        /// </summary>
148        /// <remarks><list type="bullet"><listheader>Rounding properties</listheader>
149        /// <item>2,5: IEEE rounding conform </item>
150        /// <item>1,4: not IEEE conform rounding </item>
151        /// <item>0,3: truncating - no rounding </item></list>
152        /// <list type="bullet"><listheader>Under-/ Overflow. numbers below xmin will be interpreted as... </listheader>
153        /// <item>0,1,2: zero</item>
154        /// <item>3,4,5: xmin (IEEE conform)</item></list></remarks>
155        public int irnd;
156        /// <summary>
157        /// Number of guard digits in the product of 2 mantissas
158        /// </summary>
159        public int ngrd;
160        /// <summary>
161        /// Exponent of the smalles number ibeta^machep &gt; 1.0
162        /// </summary>
163        public int machep;
164        /// <summary>
165        /// Exponent of smallest number ibeta^negep wich may be substracted from 1.0, giving a result not equal to 1.0
166        /// </summary>
167        public int negep;
168        /// <summary>
169        /// Number of exponent bits
170        /// </summary>
171        public int iexp;
172        /// <summary>
173        /// Smallest power of ibeta without leading zeros in the mantissa
174        /// </summary>
175        public int minexp;
176        /// <summary>
177        /// Smallest power of ibeta where overflow occours
178        /// </summary>
179        public int maxexp;
180        /// <summary>
181        /// Distance between the smallest number &gt; 1.0, distinguishable from 1.0 and 1.0
182        /// </summary>
183        /// <remarks>This number is computed by ibeta <sup>machep</sup>.</remarks>
184        public double eps;
185        /// <summary>
186        /// Alternative eps. ibeta <sup>negep</sup>
187        /// </summary>
188        public double epsneg;
189        /// <summary>
190        /// Smallest floating point number
191        /// </summary>
192        public double xmin;
193        /// <summary>
194        /// Largest floating point number
195        /// </summary>
196        public double xmax;
197    }
198}
199
200
201namespace ILNumerics  {
202    public partial class ILMath {
203
204        /// <summary>
205        /// Definition of pi
206        /// </summary>
207        /// <remarks>This is an convenience alias for Math.PI</remarks>
208        public static readonly double pi = Math.PI;
209
210        /// <summary>
211        /// Definition of pi, single precision
212        /// </summary>
213        /// <remarks>This is an convenience alias for Math.PI</remarks>
214        public static readonly float pif = (float)Math.PI;
215
216        private static MachineParameterDouble m_machparDouble;
217        /// <summary>
218        /// Give extensive numerical machine parameter informations - double precision
219        /// </summary>
220        public static MachineParameterDouble MachineParameterDouble {
221            get {
222                return m_machparDouble;
223            }
224        }
225        private static MachineParameterSingle m_machparSingle;
226        /// <summary>
227        /// Give extensive numerical machine parameter informations - single precision
228        /// </summary>
229        public static MachineParameterSingle MachineParameterSingle {
230            get {
231                return m_machparSingle;
232            }
233        }
234        /// <summary>
235        /// Prevent JIT "optimizations" - force single precision to be applied
236        /// </summary>
237        /// <typeparam name="T">mainly float here</typeparam>
238        private class precisionHelper<T> {
239            public T V;
240        }
241        /// <summary>
242        /// Determine machine specific parameter
243        /// </summary>
244        /// <remarks>Source: Numerical Recipes in C, p.892</remarks>
245        internal static void macharF(ref int ibeta, ref int it, ref int irnd, ref int ngrd, ref int machep, ref int negep,
246                        ref int iexp, ref int minexp, ref int maxexp, ref float eps, ref float epsneg, ref float xmin, ref float xmax) {
247            int i, itemp, iz, j, k, mx, nxres;
248            precisionHelper<float> a = new precisionHelper<float>(),
249                b = new precisionHelper<float>(),
250                beta = new precisionHelper<float>(),
251                betah = new precisionHelper<float>(),
252                betain = new precisionHelper<float>(),
253                one = new precisionHelper<float>(),
254                t = new precisionHelper<float>(),
255                temp = new precisionHelper<float>(),
256                temp1 = new precisionHelper<float>(),
257                tempa = new precisionHelper<float>(),
258                two = new precisionHelper<float>(),
259                y = new precisionHelper<float>(),
260                z = new precisionHelper<float>(),
261                zero = new precisionHelper<float>();
262
263            one.V = 1f;
264            two.V = one.V + one.V;
265            zero.V = one.V - one.V;
266            a.V = one.V;
267            do {
268                a.V += a.V;
269                temp.V = a.V + one.V;
270                temp1.V = temp.V - a.V;
271            } while (temp1.V - one.V == zero.V);
272            b.V = one.V;
273            do {
274                b.V += b.V;
275                temp.V = a.V + b.V;
276                itemp = (int)(temp.V - a.V);
277            } while (itemp == 0);
278            ibeta = itemp;
279            beta.V = (float)ibeta;
280            it = 0;
281            b.V = one.V;
282            do {
283                ++it;
284                b.V *= beta.V;
285                temp.V = b.V + one.V;
286                temp1.V = temp.V - b.V;
287            } while (temp1.V - one.V == zero.V);
288            irnd = 0;
289            betah.V = beta.V / two.V;
290            temp.V = a.V + betah.V;
291            if (temp.V-a.V != zero.V) irnd = 1;
292            tempa.V = a.V + beta.V;
293            temp.V = tempa.V + betah.V;
294            if (irnd == 0 && temp.V - tempa.V != zero.V) irnd = 2;
295            negep = it + 3;
296            betain.V = one.V / beta.V;
297            a.V = one.V;
298            for (i = 1; i <= negep; i++) a.V *= betain.V;
299            b.V = a.V;
300            for (;;) {
301                temp.V = one.V -a.V;
302                if (temp.V-one.V != zero.V)  break;
303                a.V *= beta.V;
304                --negep;
305            }
306            negep = -negep;
307            epsneg = a.V;
308            machep = -it -3;
309            a.V = b.V;
310            for (;;) {
311                temp.V = one.V +a.V;
312                if (temp.V - one.V != zero.V) break;
313                a.V *= beta.V;
314                ++machep;
315            }
316            eps = a.V;
317            ngrd =0;
318            temp.V = one.V + eps;
319            if (irnd == 0 && temp.V * one.V - one.V != zero.V) ngrd = 1;
320            i = 0;
321            k = 1;
322            z.V = betain.V;
323            t.V = one.V + eps;
324            nxres = 0;
325            for (;;) {
326                y.V = z.V;
327                z.V = y.V *y.V;
328                a.V = z.V * one.V;
329                temp.V = z.V * t.V;
330                if (a.V + a.V == zero.V || (float)Math.Abs(z.V) >= y.V) break;
331                temp1.V = temp.V * betain.V;
332                if (temp1.V * beta.V == z.V) break;
333                ++i;
334                k += k;
335            }
336            if (ibeta != 10) {
337                iexp = i+1;
338                mx = k + k;
339            }else {
340                iexp = 2;
341                iz = ibeta;
342                while (k >= iz) {
343                    iz *= ibeta;
344                    ++iexp;
345                }
346                mx = iz + iz-1;
347            }
348            for (;;) {
349                xmin = y.V;
350                y.V *= betain.V;
351                a.V = y.V * one.V;
352                temp.V = y.V * t.V;
353                if (a.V+a.V != zero.V && (float)Math.Abs(y.V) < xmin) {
354                    ++k;
355                    temp1.V = temp.V* betain.V;
356                    if (temp1.V * beta.V == y.V && temp.V != y.V) {
357                        nxres = 3;
358                        xmin = y.V;
359                        break;
360                    }
361                }
362                else break;
363            }
364            minexp = -k;
365            if (mx <= k + k - 3 && ibeta != 10) {
366                mx += mx;
367                ++iexp;
368            }
369            maxexp = mx + minexp;
370            irnd += nxres;
371            if (irnd >= 2) maxexp -= 2;
372            i = maxexp + minexp;
373            if (ibeta == 2 && i != 0) --maxexp;
374            if (i > 20) --maxexp;
375            if (a.V != y.V) maxexp -= 2;
376            xmax = one.V -epsneg;
377            if (maxexp * one.V != xmax) xmax = one.V - beta.V * epsneg;
378            xmax /= xmin * beta.V * beta.V * beta.V;
379            i = maxexp + minexp + 3;
380            for (j = 1; j <= i; j++){
381                if (ibeta == 2) xmax += xmax;
382                else xmax *= beta.V;
383            }
384        }
385
386        /// <summary>
387        /// Determine machine specific parameter (double precision)
388        /// </summary>
389        /// <remarks>Source: Numerical Recipes in C, p.892</remarks>
390        internal static void macharD(ref int ibeta, ref int it, ref int irnd, ref int ngrd, ref int machep, ref int negep,
391                        ref int iexp, ref int minexp, ref int maxexp, ref double eps, ref double epsneg, ref double xmin, ref double xmax) {
392            int i, itemp, iz, j, k, mx, nxres;
393            double a,b,beta,betah,betain,one,t,temp,temp1,tempa,two,y,z,zero;
394
395            one= (double)1;
396            two = one + one;
397            zero = one - one;
398            a = one;
399            do {
400                a += a;
401                temp = a+one;
402                temp1= temp-a;
403            } while (temp1-one == zero);
404            b = one;
405            do {
406                b += b;
407                temp=a+b;
408                itemp=(int)(temp-a);
409            } while (itemp == 0);
410            ibeta = itemp;
411            beta = (double)ibeta;
412            it = 0;
413            b = one;
414            do {
415                ++it;
416                b *= beta;
417                temp = b +one;
418                temp1 = temp -b;
419            }while (temp1-one == zero);
420            irnd = 0;
421            betah = beta / two;
422            temp = a + betah;
423            if (temp-a != zero) irnd = 1;
424            tempa = a + beta;
425            temp = tempa + betah;
426            if (irnd == 0 && temp - tempa != zero) irnd = 2;
427            negep = it + 3;
428            betain = one / beta;
429            a = one;
430            for (i = 1; i <= negep; i++) a *= betain;
431            b =a;
432            for (;;) {
433                temp = one -a;
434                if (temp-one != zero)  break;
435                a *= beta;
436                --negep;
437            }
438            negep = -negep;
439            epsneg = a;
440            machep = -it -3;
441            a = b;
442            for (;;) {
443                temp = one +a;
444                if (temp - one != zero) break;
445                a *= beta;
446                ++machep;
447            }
448            eps = a;
449            ngrd =0;
450            temp = one + eps;
451            if (irnd == 0 && temp * one - one != zero) ngrd = 1;
452            i = 0;
453            k = 1;
454            z = betain;
455            t = one + eps;
456            nxres = 0;
457            for (;;) {
458                y = z;
459                z = y *y;
460                a = z * one;
461                temp = z * t;
462                if (a + a == zero || (double)Math.Abs(z) >= y) break;
463                temp1 = temp * betain;
464                if (temp1 * beta == z) break;
465                ++i;
466                k += k;
467            }
468            if (ibeta != 10) {
469                iexp = i+1;
470                mx = k + k;
471            }else {
472                iexp = 2;
473                iz = ibeta;
474                while (k >= iz) {
475                    iz *= ibeta;
476                    ++iexp;
477                }
478                mx = iz + iz-1;
479            }
480            for (;;) {
481                xmin = y;
482                y *= betain;
483                a = y * one;
484                temp = y * t;
485                if (a+a != zero && (double)Math.Abs(y) < xmin) {
486                    ++k;
487                    temp1 = temp* betain;
488                    if (temp1 * beta == y && temp != y) {
489                        nxres = 3;
490                        xmin = y;
491                        break;
492                    }
493                }
494                else break;
495            }
496            minexp = -k;
497            if (mx <= k + k - 3 && ibeta != 10) {
498                mx += mx;
499                ++iexp;
500            }
501            maxexp = mx + minexp;
502            irnd += nxres;
503            if (irnd >= 2) maxexp -= 2;
504            i = maxexp + minexp;
505            if (ibeta == 2 && i != 0) --maxexp;
506            if (i > 20) --maxexp;
507            if (a != y) maxexp -= 2;
508            xmax = one -epsneg;
509            if (maxexp * one != xmax) xmax = one - beta * epsneg;
510            xmax /= xmin * beta * beta * beta;
511            i = maxexp + minexp + 3;
512            for (j = 1; j <= i; j++){
513                if (ibeta == 2) xmax += xmax;
514                else xmax *= beta;
515            }
516        }
517
518    }
519}
Note: See TracBrowser for help on using the repository browser.