OpenCores
URL https://opencores.org/ocsvn/gng/gng/trunk

Subversion Repositories gng

[/] [gng/] [trunk/] [c/] [icdf.c] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 guangxi.li
/*
2
 * Piecewise polynomial approximation of
3
 * inverse of the normal cumulative distribution function (CDF)
4
 */
5
 
6
/*
7
 * Copyright (C) 2014, Guangxi Liu <guangxi.liu@opencores.org>
8
 *
9
 * This source file may be used and distributed without restriction provided
10
 * that this copyright statement is not removed from the file and that any
11
 * derivative work contains the original copyright notice and the associated
12
 * disclaimer.
13
 *
14
 * This source file is free software; you can redistribute it and/or modify it
15
 * under the terms of the GNU Lesser General Public License as published by
16
 * the Free Software Foundation; either version 2.1 of the License,
17
 * or (at your option) any later version.
18
 *
19
 * This source is distributed in the hope that it will be useful, but
20
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
21
 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
22
 * License for more details.
23
 *
24
 * You should have received a copy of the GNU Lesser General Public License
25
 * along with this source; if not, download it from
26
 * http://www.opencores.org/lgpl.shtml
27
 */
28
 
29
 
30
#include "icdf.h"
31
 
32
 
33
/* Coefficients table */
34
static const long C0[248] = {
35
    11049, 8007, 5220, 2577, 18846, 16547, 14535, 12721, 25134, 23229,
36
    21594, 20150, 30518, 28863, 27458, 26231, 35288, 33808, 32562, 31479,
37
    39608, 38260, 37130, 36152, 43582, 42336, 41296, 40399, 47277, 46115,
38
    45147, 44314, 50745, 49651, 48742, 47963, 54020, 52985, 52126, 51390,
39
    57132, 56147, 55331, 54632, 60101, 59160, 58381, 57715, 62945, 62043,
40
    61296, 60659, 65679, 64811, 64093, 63481, 68314, 67476, 66784, 66194,
41
    70859, 70049, 69381, 68811, 73323, 72538, 71891, 71340, 75714, 74952,
42
    74324, 73790, 78036, 77296, 76686, 76167, 80297, 79576, 78982, 78477,
43
    82500, 81797, 81218, 80726, 84649, 83963, 83398, 82918, 86748, 86078,
44
    85526, 85057, 88800, 88145, 87606, 87147, 90809, 90167, 89640, 89191,
45
    92777, 92148, 91631, 91192, 94706, 94090, 93583, 93152, 96599, 95994,
46
    95496, 95074, 98457, 97863, 97374, 96960, 100282, 99698, 99219, 98811,
47
    102076, 101502, 101031, 100630, 103841, 103276, 102812, 102419, 105577, 105021,
48
    104565, 104178, 107286, 106739, 106290, 105909, 108970, 108431, 107989, 107613,
49
    110629, 110098, 109662, 109292, 112265, 111741, 111311, 110946, 113878, 113361,
50
    112937, 112578, 115469, 114959, 114541, 114186, 117040, 116536, 116124, 115774,
51
    118590, 118093, 117686, 117340, 120121, 119630, 119228, 118887, 121633, 121149,
52
    120751, 120414, 123128, 122649, 122256, 121923, 124605, 124132, 123743, 123414,
53
    126065, 125597, 125213, 124888, 127510, 127047, 126667, 126345, 128938, 128480,
54
    128105, 127786, 130351, 129898, 129527, 129212, 131750, 131301, 130934, 130622,
55
    133134, 132690, 132326, 132018, 134505, 134065, 133705, 133400, 135862, 135426,
56
    135070, 134767, 137206, 136775, 136421, 136122, 138537, 138110, 137760, 137463,
57
    139856, 139433, 139086, 138792, 141163, 140743, 140400, 140109, 142458, 142042,
58
    141702, 141413, 143742, 143330, 142992, 142706, 145015, 144606, 144272, 143988,
59
    146277, 145872, 145540, 145259, 150000, 148769, 147528, 146797
60
};
61
 
62
static const long C1[248] = {
63
    -102514, -92199, -86162, -82951, -79070, -68105, -60693, -55396, -66134, -55839,
64
    -48783, -43639, -57755, -48215, -41670, -36890, -51803, -42932, -36856, -32421,
65
    -47313, -39012, -33338, -29203, -43778, -35964, -30631, -26751, -40907, -33511,
66
    -28470, -24807, -38519, -31483, -26695, -23220, -36492, -29774, -25206, -21893,
67
    -34747, -28307, -23933, -20765, -33223, -27032, -22831, -19789, -31878, -25911,
68
    -21864, -18936, -30681, -24915, -21007, -18182, -29606, -24023, -20242, -17509,
69
    -28634, -23218, -19552, -16903, -27750, -22488, -18927, -16356, -26942, -21821,
70
    -18357, -15857, -26198, -21208, -17835, -15400, -25512, -20644, -17354, -14980,
71
    -24876, -20121, -16909, -14591, -24285, -19636, -16496, -14231, -23733, -19184,
72
    -16111, -13896, -23217, -18760, -15752, -13583, -22732, -18364, -15415, -13290,
73
    -22276, -17991, -15099, -13015, -21846, -17639, -14801, -12756, -21440, -17307,
74
    -14520, -12512, -21055, -16993, -14253, -12281, -20690, -16695, -14001, -12062,
75
    -20342, -16412, -13762, -11854, -20012, -16143, -13534, -11656, -19697, -15886,
76
    -13317, -11468, -19396, -15641, -13111, -11289, -19109, -15407, -12913, -11118,
77
    -18834, -15183, -12724, -10954, -18570, -14969, -12543, -10797, -18317, -14763,
78
    -12369, -10646, -18073, -14565, -12202, -10502, -17839, -14375, -12042, -10363,
79
    -17614, -14193, -11888, -10230, -17397, -14016, -11739, -10102, -17188, -13847,
80
    -11596, -9978, -16986, -13683, -11458, -9858, -16791, -13525, -11325, -9743,
81
    -16603, -13372, -11196, -9632, -16421, -13224, -11072, -9524, -16244, -13081,
82
    -10951, -9420, -16073, -12942, -10835, -9319, -15907, -12808, -10722, -9222,
83
    -15747, -12678, -10612, -9127, -15591, -12552, -10506, -9035, -15440, -12429,
84
    -10403, -8946, -15294, -12311, -10303, -8860, -15154, -12196, -10206, -8776,
85
    -15020, -12086, -10113, -8695, -14894, -11982, -10024, -8618, -14779, -11885,
86
    -9940, -8544, -14681, -11797, -9863, -8475, -13792, -11190, -9418, -8133,
87
    0, 0, 0, 0, 0, 0, 0, 0
88
};
89
 
90
static const long C2[248] = {
91
    83840, 48883, 25920, 8147, 88988, 59916, 42707, 31577, 83526, 57019,
92
    41464, 31523, 77411, 52885, 38533, 29386, 71990, 49106, 35743, 27241,
93
    67363, 45865, 33332, 25372, 63422, 43107, 31282, 23780, 60040, 40746,
94
    29530, 22422, 57109, 38706, 28020, 21254, 54545, 36926, 26705, 20239,
95
    52279, 35358, 25549, 19349, 50262, 33965, 24525, 18561, 48452, 32718,
96
    23609, 17858, 46818, 31593, 22785, 17226, 45333, 30573, 22038, 16654,
97
    43976, 29643, 21358, 16134, 42731, 28790, 20735, 15658, 41583, 28005,
98
    20163, 15221, 40521, 27279, 19634, 14817, 39534, 26606, 19143, 14444,
99
    38614, 25978, 18687, 14096, 37754, 25392, 18261, 13772, 36948, 24844,
100
    17862, 13468, 36190, 24328, 17488, 13184, 35477, 23843, 17136, 12916,
101
    34803, 23385, 16804, 12664, 34165, 22952, 16490, 12426, 33561, 22542,
102
    16193, 12200, 32987, 22153, 15911, 11986, 32441, 21783, 15643, 11783,
103
    31921, 21431, 15388, 11590, 31425, 21094, 15145, 11406, 30951, 20773,
104
    14913, 11230, 30497, 20466, 14691, 11061, 30063, 20173, 14479, 10901,
105
    29646, 19891, 14275, 10746, 29246, 19620, 14080, 10599, 28861, 19360,
106
    13892, 10456, 28492, 19110, 13711, 10320, 28135, 18870, 13538, 10189,
107
    27792, 18638, 13370, 10062, 27461, 18414, 13209, 9940, 27141, 18199,
108
    13053, 9822, 26832, 17990, 12903, 9709, 26534, 17788, 12758, 9599,
109
    26245, 17593, 12617, 9492, 25965, 17405, 12481, 9390, 25694, 17222,
110
    12349, 9290, 25432, 17045, 12222, 9194, 25178, 16874, 12098, 9100,
111
    24933, 16708, 11979, 9010, 24697, 16549, 11864, 8923, 24474, 16397,
112
    11754, 8840, 24268, 16255, 11650, 8761, 24088, 16129, 11557, 8689,
113
    23954, 16029, 11480, 8628, 23908, 15977, 11432, 8586, 24029, 16017,
114
    11440, 8581, 24481, 16238, 11559, 8648, 0, 0, 0, 0,
115
    0, 0, 0, 0, 0, 0, 0, 0
116
};
117
 
118
 
119
/* Calculate Inverse of the normal CDF */
120
long icdf(unsigned long long n)
121
{
122
    unsigned long long t;
123
    int i;
124
    unsigned num_lzd;
125
    unsigned addr;
126
    long c0, c1, c2;
127
    long x;
128
    long long y;
129
    int carry;
130
 
131
    t = n;
132
    num_lzd = 0;
133
    for (i = 0; i < 61; i++) {
134
        if (t & 0x8000000000000000ULL)
135
            break;
136
        else {
137
            ++num_lzd;
138
            t <<= 1;
139
        }
140
    }
141
    addr = num_lzd << 2;
142
    if (n & 2ULL)
143
        addr += 2;
144
    if (n & 4ULL)
145
        ++addr;
146
 
147
    c0 = C0[addr];
148
    c1 = C1[addr];
149
    c2 = C2[addr];
150
 
151
    if (num_lzd <= 60)
152
        n &= ~(1ULL << (63 - num_lzd));
153
 
154
    t = n >> 3;
155
    x = 0;
156
    for (i = 0; i < 15; i++) {
157
        x <<= 1;
158
        if (t & 1ULL)
159
            ++x;
160
        t >>= 1;
161
    }
162
 
163
    y = (long long)c2 * (long long)x;
164
    y += ((long long)c1 << 19);
165
    y >>= 20;
166
    y *= (long long)x;
167
    y >>= 19;
168
    y += (long long)c0;
169
    carry = (y & 4ULL) ? 1 : 0;
170
    y >>= 3;
171
    y += carry;
172
    if (n & 1ULL)
173
        y = -y;
174
 
175
    return (long)y;
176
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.