Large literal arrays factored out of "FastMath".
Slight efficiency improvement of "resource" alternative.
Output result in "FastMathLoadCheck".


git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@1180294 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Gilles Sadowski 2011-10-08 02:02:07 +00:00
parent 0eee4b6f14
commit d0633b818e
5 changed files with 6281 additions and 6160 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -26,6 +26,8 @@ import java.io.BufferedInputStream;
import java.io.FileOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.DoubleBuffer;
import org.apache.commons.math.exception.MathInternalError;
/**
@ -49,6 +51,8 @@ public class FastMathResources {
private static final String EXP_FRAC = "exp_frac";
/** Resource basename for "LN_MANT". */
private static final String LN_MANT = "ln_mant";
/** Number of bytes in a "double". */
private static final int BYTES_IN_DOUBLE = Double.SIZE / Byte.SIZE;
/**
* Class contains only static methods.
@ -93,8 +97,7 @@ public class FastMathResources {
}
}
saveTable2d(EXP_INT, 2, FastMath.EXP_INT_TABLE_LEN,
new double[][] { expIntA, expIntB });
saveTable2d(EXP_INT, new double[][] { expIntA, expIntB });
// "EXP_FRAC" tables.
final double[] expFracA = new double[FastMath.EXP_FRAC_TABLE_LEN];
@ -106,8 +109,7 @@ public class FastMathResources {
expFracB[i] = tmp[1];
}
saveTable2d(EXP_FRAC, 2, FastMath.EXP_FRAC_TABLE_LEN,
new double[][] { expFracA, expFracB });
saveTable2d(EXP_FRAC, new double[][] { expFracA, expFracB });
// "LN_MANT" table.
final double[][] lnMant = new double[FastMath.LN_MANT_LEN][];
@ -118,7 +120,7 @@ public class FastMathResources {
lnMant[i] = FastMathCalc.slowLog(d);
}
saveTable2d(LN_MANT, FastMath.LN_MANT_LEN, 2, lnMant);
saveTable2d(LN_MANT, transpose(lnMant));
}
/**
@ -149,7 +151,7 @@ public class FastMathResources {
* @return the retrieved data.
*/
public static double[][] loadLnMant() {
return loadTable2d(LN_MANT, FastMath.LN_MANT_LEN, 2);
return transpose(loadTable2d(LN_MANT, 2, FastMath.LN_MANT_LEN));
}
/**
@ -165,12 +167,12 @@ public class FastMathResources {
/**
* @param name Basename of the resource.
* @param len Number of {@code double}s to be stored.
* @param data Data to be stored.
*/
private static void saveTable1d(String name,
int len,
double[] data) {
final int len = data.length;
try {
final DataOutputStream out = out(name);
@ -186,14 +188,13 @@ public class FastMathResources {
/**
* @param name Basename of the resource.
* @param len Number of table rows to be stored.
* @param rowLen Number of {@code double}s per table row.
* @param data Data to be stored.
*/
private static void saveTable2d(String name,
int len,
int rowLen,
double[][] data) {
final int len = data.length;
final int rowLen = data[0].length;
try {
final DataOutputStream out = out(name);
@ -223,7 +224,7 @@ public class FastMathResources {
/**
* @param name Basename of the resource.
* @param len Number of {@code double}s to be retrieved.
* @param len Size of the data.
* @return the retrieved data.
*/
private static double[] loadTable1d(String name,
@ -245,8 +246,8 @@ public class FastMathResources {
/**
* @param name Basename of the resource.
* @param len Number of table rows to be retrieved.
* @param rowLen Number of {@code double}s per table row.
* @param len Size of the table.
* @param rowLen Size of each row of the table.
* @return the retrieved data.
*/
private static double[][] loadTable2d(String name,
@ -254,11 +255,15 @@ public class FastMathResources {
int rowLen) {
try {
final DataInputStream in = in(name);
final byte[] b = new byte[BYTES_IN_DOUBLE * rowLen];
final double[][] data = new double[len][rowLen];
final ByteBuffer bBuf = ByteBuffer.wrap(b);
for (int i = 0; i < len; i++) {
in.readFully(b);
final DoubleBuffer dBuf = bBuf.asDoubleBuffer();
for (int j = 0; j < rowLen; j++) {
data[i][j] = in.readDouble();
data[i][j] = dBuf.get();
}
}
@ -268,4 +273,26 @@ public class FastMathResources {
throw new MathInternalError(e);
}
}
/**
* Transposes a two-dimensional array: The number of rows becomes the
* number of columns and vice-versa.
* The array must be rectangular (same number of colums in each row).
*
* @param data Array to be transposed.
* @return the transposed array.
*/
private static double[][] transpose(double[][] data) {
final int rowLen = data.length;
final int len = data[0].length;
final double[][] tData = new double[len][rowLen];
for (int i = 0; i < len; i++) {
for (int j = 0; j < rowLen; j++) {
tData[i][j] = data[j][i];
}
}
return tData;
}
}

View File

@ -12,22 +12,51 @@ import java.lang.reflect.Field;
*
* For example, this shell command:
* <pre>
* $ for max in false true ; do for how in compute resources array; do java -cp target/classes:target/test-classes org.apache.commons.math.util.FastMathLoadCheck $max $how ; done ; done
* $ for max in false true ; do for how in compute resources array; do java -cp target/classes:target/test-classes org.apache.commons.math.util.FastMathLoadCheck $max $how 4 ; done ; done
* </pre>
* will produce an output similar to the following:
* <pre>
* Using exp(100); how=compute
* times 50955053 4062 1783 1708 1731 1728 1739 1735 1746 1735
* Using exp(100); how=resources
* times 18467554 4822 1953 1769 1851 1746 1821 1817 1813 1742
* Using exp(100); how=array
* times 5952415 2960 1839 1776 1720 1847 1839 1780 1788 1742
* Using max(0,0); how=compute
* times 1596 521 401 352 345 405 393 390 397 382
* Using max(0,0); how=resources
* times 1517 521 401 386 386 394 363 386 382 383
* Using max(0,0); how=array
* times 1569 453 398 390 389 394 333 390 334 359
* Using exp(100); how=computeUsing exp(100); how=compute
* times result
* 43534147 2.688117e+43
* 4547 2.688117e+43
* 1970 2.688117e+43
* 1823 2.688117e+43
*
* Using exp(100); how=array
* times result
* 12596573 2.688117e+43
* 4484 2.688117e+43
* 1861 2.688117e+43
* 1864 2.688117e+43
*
* Using exp(100); how=resources
* times result
* 13087186 2.688117e+43
* 4974 2.688117e+43
* 1834 2.688117e+43
* 1900 2.688117e+43
*
* Using max(0,0); how=compute
* times result
* 3172 0.000000e+00
* 692 0.000000e+00
* 385 0.000000e+00
* 358 0.000000e+00
*
* Using max(0,0); how=array
* times result
* 2746 0.000000e+00
* 527 0.000000e+00
* 382 0.000000e+00
* 390 0.000000e+00
*
* Using max(0,0); how=resources
* times result
* 3762 0.000000e+00
* 506 0.000000e+00
* 394 0.000000e+00
* 364 0.000000e+00
* </pre>
*/
public class FastMathLoadCheck {
@ -47,50 +76,42 @@ public class FastMathLoadCheck {
final Field recompute = FastMath.class.getDeclaredField("RECOMPUTE_TABLES_AT_RUNTIME");
final Field load = FastMath.class.getDeclaredField("LOAD_RESOURCES");
recompute.setAccessible(true);
load.setAccessible(true);
if (how.equals(COMP)) {
recompute.setAccessible(true);
recompute.setBoolean(null, true);
recompute.setAccessible(false);
load.setAccessible(true);
load.setBoolean(null, false);
load.setAccessible(false);
} else if (how.equals(RES)) {
recompute.setAccessible(true);
recompute.setBoolean(null, false);
recompute.setAccessible(false);
load.setAccessible(true);
load.setBoolean(null, true);
load.setAccessible(false);
} else if (how.equals(ARR)) {
recompute.setAccessible(true);
recompute.setBoolean(null, false);
recompute.setAccessible(false);
load.setAccessible(true);
load.setBoolean(null, false);
load.setAccessible(false);
} else {
throw new IllegalArgumentException("'how' must be 'compute' or 'resources' or 'array'");
}
recompute.setAccessible(false);
load.setAccessible(false);
test();
}
private static void test(){
p("times");
for(int i = 0; i < LOOPS; i++){
p(" ");
p("%9s %12s\n", "times", "result");
double result;
for(int i = 0; i < LOOPS; i++) {
long t1 = System.nanoTime();
if (MAX) {
FastMath.max(0, 0);
result = FastMath.max(0, 0);
} else {
FastMath.exp(100);
result = FastMath.exp(100);
}
long t2 = System.nanoTime();
p("%9d", t2 - t1);
p("%9d %e\n", t2 - t1, result);
}
p("\n");
}
private static void p(String format, Object p){
private static void p(String format, Object ... p){
System.out.printf(format, p);
}
private static void p(Object p){