1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.math.util;
19
20 import java.io.File;
21 import java.io.DataOutputStream;
22 import java.io.InputStream;
23 import java.io.DataInputStream;
24 import java.io.BufferedOutputStream;
25 import java.io.BufferedInputStream;
26 import java.io.FileOutputStream;
27 import java.io.FileNotFoundException;
28 import java.io.IOException;
29 import java.nio.ByteBuffer;
30 import java.nio.DoubleBuffer;
31 import org.apache.commons.math.exception.MathInternalError;
32
33
34
35
36
37
38
39 class FastMathResources {
40
41
42
43
44 private static final String RES_DIR = "data/" +
45 FastMath.class.getPackage().getName().replace('.', '/') + "/";
46
47 private static final String RES_PREFIX = RES_DIR + "FastMath__";
48
49 private static final String EXP_INT = "exp_int";
50
51 private static final String EXP_FRAC = "exp_frac";
52
53 private static final String LN_MANT = "ln_mant";
54
55 private static final int BYTES_IN_DOUBLE = Double.SIZE / Byte.SIZE;
56
57
58
59
60 private FastMathResources() {}
61
62
63
64
65 static void createAll() {
66
67 final File resDir = new File(RES_DIR);
68 if (resDir.exists()) {
69 if (!resDir.isDirectory()) {
70 throw new MathInternalError();
71 }
72 } else {
73 try {
74 resDir.mkdirs();
75 } catch (SecurityException e) {
76 throw new MathInternalError(e);
77 }
78 }
79
80
81 final double[] expIntA = new double[FastMath.EXP_INT_TABLE_LEN];
82 final double[] expIntB = new double[FastMath.EXP_INT_TABLE_LEN];
83
84 final double tmp[] = new double[2];
85 final double recip[] = new double[2];
86
87 for (int i = 0; i < FastMath.EXP_INT_TABLE_MAX_INDEX; i++) {
88 FastMathCalc.expint(i, tmp);
89 expIntA[i + FastMath.EXP_INT_TABLE_MAX_INDEX] = tmp[0];
90 expIntB[i + FastMath.EXP_INT_TABLE_MAX_INDEX] = tmp[1];
91
92 if (i != 0) {
93
94 FastMathCalc.splitReciprocal(tmp, recip);
95 expIntA[FastMath.EXP_INT_TABLE_MAX_INDEX - i] = recip[0];
96 expIntB[FastMath.EXP_INT_TABLE_MAX_INDEX - i] = recip[1];
97 }
98 }
99
100 saveTable2d(EXP_INT, new double[][] { expIntA, expIntB });
101
102
103 final double[] expFracA = new double[FastMath.EXP_FRAC_TABLE_LEN];
104 final double[] expFracB = new double[FastMath.EXP_FRAC_TABLE_LEN];
105
106 for (int i = 0; i < FastMath.EXP_FRAC_TABLE_LEN; i++) {
107 FastMathCalc.slowexp(i / 1024d, tmp);
108 expFracA[i] = tmp[0];
109 expFracB[i] = tmp[1];
110 }
111
112 saveTable2d(EXP_FRAC, new double[][] { expFracA, expFracB });
113
114
115 final double[][] lnMant = new double[FastMath.LN_MANT_LEN][];
116
117 for (int i = 0; i < FastMath.LN_MANT_LEN; i++) {
118 final double d = Double.longBitsToDouble((((long) i) << 42) |
119 0x3ff0000000000000L);
120 lnMant[i] = FastMathCalc.slowLog(d);
121 }
122
123 saveTable2d(LN_MANT, transpose(lnMant));
124 }
125
126
127
128
129
130
131
132
133 static double[][] loadExpInt() {
134 return loadTable2d(EXP_INT, 2, FastMath.EXP_INT_TABLE_LEN);
135 }
136
137
138
139
140
141
142
143
144 static double[][] loadExpFrac() {
145 return loadTable2d(EXP_FRAC, 2, FastMath.EXP_FRAC_TABLE_LEN);
146 }
147
148
149
150
151
152
153 static double[][] loadLnMant() {
154 return transpose(loadTable2d(LN_MANT, 2, FastMath.LN_MANT_LEN));
155 }
156
157
158
159
160
161
162 private static DataOutputStream out(String name)
163 throws FileNotFoundException {
164 final String fullName = RES_PREFIX + name;
165 return new DataOutputStream(new BufferedOutputStream(new FileOutputStream(fullName)));
166 }
167
168
169
170
171
172 private static void saveTable1d(String name,
173 double[] data) {
174 final int len = data.length;
175
176 try {
177 final DataOutputStream out = out(name);
178
179 for (int i = 0; i < len; i++) {
180 out.writeDouble(data[i]);
181 }
182
183 out.close();
184 } catch (IOException e) {
185 throw new MathInternalError(e);
186 }
187 }
188
189
190
191
192
193 private static void saveTable2d(String name,
194 double[][] data) {
195 final int len = data.length;
196 final int rowLen = data[0].length;
197
198 try {
199 final DataOutputStream out = out(name);
200
201 for (int i = 0; i < len; i++) {
202 for (int j = 0; j < rowLen; j++) {
203 out.writeDouble(data[i][j]);
204 }
205 }
206
207 out.close();
208 } catch (IOException e) {
209 throw new MathInternalError(e);
210 }
211 }
212
213
214
215
216
217
218 private static DataInputStream in(String name)
219 throws FileNotFoundException {
220 final String fullName = "/" + RES_PREFIX + name;
221 final InputStream in = FastMathResources.class.getResourceAsStream(fullName);
222 return new DataInputStream(new BufferedInputStream(in));
223 }
224
225
226
227
228
229
230 private static double[] loadTable1d(String name,
231 int len) {
232 try {
233 final DataInputStream in = in(name);
234
235 final double[] data = new double[len];
236 for (int i = 0; i < len; i++) {
237 data[i] = in.readDouble();
238 }
239
240 in.close();
241 return data;
242 } catch (IOException e) {
243 throw new MathInternalError(e);
244 }
245 }
246
247
248
249
250
251
252
253 private static double[][] loadTable2d(String name,
254 int len,
255 int rowLen) {
256 try {
257 final DataInputStream in = in(name);
258 final byte[] b = new byte[BYTES_IN_DOUBLE * rowLen];
259 final double[][] data = new double[len][rowLen];
260 final ByteBuffer bBuf = ByteBuffer.wrap(b);
261
262 for (int i = 0; i < len; i++) {
263 in.readFully(b);
264 final DoubleBuffer dBuf = bBuf.asDoubleBuffer();
265 for (int j = 0; j < rowLen; j++) {
266 data[i][j] = dBuf.get();
267 }
268 }
269
270 in.close();
271 return data;
272 } catch (IOException e) {
273 throw new MathInternalError(e);
274 }
275 }
276
277
278
279
280
281
282
283
284
285 private static double[][] transpose(double[][] data) {
286 final int rowLen = data.length;
287 final int len = data[0].length;
288 final double[][] tData = new double[len][rowLen];
289
290 for (int i = 0; i < len; i++) {
291 for (int j = 0; j < rowLen; j++) {
292 tData[i][j] = data[j][i];
293 }
294 }
295
296 return tData;
297 }
298 }