001    /*
002     * Copyright (C) 2008-2010 by Holger Arndt
003     * 
004     * This file is part of the Universal Java Matrix Package (UJMP).
005     * See the NOTICE file distributed with this work for additional
006     * information regarding copyright ownership and licensing.
007     *
008     * UJMP is free software; you can redistribute it and/or modify
009     * it under the terms of the GNU Lesser General Public License as
010     * published by the Free Software Foundation; either version 2
011     * of the License, or (at your option) any later version.
012     *
013     * UJMP is distributed in the hope that it will be useful,
014     * but WITHOUT ANY WARRANTY; without even the implied warranty of
015     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
016     * GNU Lesser General Public License for more details.
017     *
018     * You should have received a copy of the GNU Lesser General Public
019     * License along with UJMP; if not, write to the
020     * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
021     * Boston, MA  02110-1301  USA
022     */
023    
024    package org.ujmp.core.benchmark;
025    
026    import java.math.BigDecimal;
027    import java.net.Inet4Address;
028    import java.util.Random;
029    
030    import org.ujmp.core.Matrix;
031    import org.ujmp.core.doublematrix.DenseDoubleMatrix2D;
032    import org.ujmp.core.doublematrix.DoubleMatrix2D;
033    import org.ujmp.core.doublematrix.impl.DefaultDenseDoubleMatrix2D;
034    import org.ujmp.core.util.GCUtil;
035    import org.ujmp.core.util.MathUtil;
036    
037    public abstract class BenchmarkUtil {
038    
039            public static String getResultDir(BenchmarkConfig config) {
040                    String name = config.getName();
041                    if (name == null) {
042                            return "results/" + getHostName() + "/" + System.getProperty("os.name") + "/Java"
043                                            + System.getProperty("java.version") + "/";
044                    } else {
045                            return "results/" + name + "/";
046                    }
047            }
048    
049            public static String getHostName() {
050                    try {
051                            return Inet4Address.getLocalHost().getHostName();
052                    } catch (Exception e) {
053                            return "localhost";
054                    }
055            }
056    
057            public static void rand(long benchmarkSeed, int run, int id, DoubleMatrix2D matrix) {
058                    Random random = new Random(benchmarkSeed + (run + 2) * 31 * 31 + (id + 1) * 31);
059                    int rows = (int) matrix.getRowCount();
060                    int cols = (int) matrix.getColumnCount();
061                    for (int r = 0; r < rows; r++) {
062                            for (int c = 0; c < cols; c++) {
063                                    matrix.setDouble(random.nextDouble() - 0.5, r, c);
064                            }
065                    }
066            }
067    
068            public static void randSymm(long benchmarkSeed, int run, int id, DoubleMatrix2D matrix) {
069                    Random random = new Random(benchmarkSeed + (run + 2) * 31 * 31 + (id + 1) * 31);
070                    int rows = (int) matrix.getRowCount();
071                    int cols = (int) matrix.getColumnCount();
072                    for (int r = 0; r < rows; r++) {
073                            for (int c = 0; c < cols && c <= r; c++) {
074                                    double f = random.nextDouble() - 0.5;
075                                    matrix.setDouble(f, r, c);
076                                    matrix.setDouble(f, c, r);
077                            }
078                    }
079            }
080    
081            public static void randPositiveDefinite(long benchmarkSeed, int run, int id, Matrix matrix) {
082                    Random random = new Random(benchmarkSeed + (run + 2) * 31 * 31 + (id + 1) * 31);
083                    DenseDoubleMatrix2D temp = new DefaultDenseDoubleMatrix2D(matrix.getSize());
084                    int rows = (int) temp.getRowCount();
085                    int cols = (int) temp.getColumnCount();
086                    for (int r = 0; r < rows; r++) {
087                            for (int c = 0; c < cols; c++) {
088                                    temp.setDouble(random.nextDouble(), r, c);
089                            }
090                    }
091                    DenseDoubleMatrix2D result = (DenseDoubleMatrix2D) temp.mtimes(temp.transpose());
092                    for (int r = 0; r < rows; r++) {
093                            for (int c = 0; c < cols; c++) {
094                                    matrix.setAsDouble(result.getDouble(r, c), r, c);
095                            }
096                    }
097            }
098    
099            public static DoubleMatrix2D createMatrix(Class<? extends Matrix> matrixClass, long... size) {
100                    try {
101                            return (DoubleMatrix2D) matrixClass.getConstructor(long[].class).newInstance(size);
102                    } catch (Exception e) {
103                            e.printStackTrace();
104                            return null;
105                    }
106            }
107    
108            public static DoubleMatrix2D createMatrix(Class<? extends Matrix> matrixClass, Matrix source) {
109                    try {
110                            return (DoubleMatrix2D) matrixClass.getConstructor(Matrix.class).newInstance(source);
111                    } catch (Exception e) {
112                            e.printStackTrace();
113                            return null;
114                    }
115            }
116    
117            public static double difference(Matrix m1, Matrix m2) {
118                    Matrix d = m1.minus(m2);
119                    // return normF(d).doubleValue();
120                    return d.normF();
121            }
122    
123            public static BigDecimal normF(Matrix m) {
124                    long rows = m.getRowCount();
125                    long cols = m.getColumnCount();
126                    BigDecimal result = BigDecimal.ZERO;
127                    for (long ro = 0; ro < rows; ro++) {
128                            for (long c = 0; c < cols; c++) {
129                                    BigDecimal b = m.getAsBigDecimal(ro, c);
130                                    BigDecimal temp = BigDecimal.ZERO;
131                                    if (MathUtil.isGreater(result.abs(), b.abs())) {
132                                            temp = MathUtil.divide(b, result);
133                                            temp = MathUtil.times(result.abs(), MathUtil.sqrt(MathUtil.plus(BigDecimal.ONE,
134                                                            MathUtil.times(temp, temp))));
135                                    } else if (!MathUtil.isEqual(BigDecimal.ZERO, b)) {
136                                            temp = MathUtil.divide(result, b);
137                                            temp = MathUtil.times(b.abs(), MathUtil.sqrt(MathUtil.plus(BigDecimal.ONE,
138                                                            MathUtil.times(temp, temp))));
139                                    } else {
140                                            temp = BigDecimal.ZERO;
141                                    }
142                                    result = temp;
143                            }
144                    }
145                    return result;
146            }
147    
148            public static void purgeMemory(BenchmarkConfig config) {
149                    if (config.isPurgeMemory()) {
150                            GCUtil.purgeMemory();
151                    } else if (config.isGCMemory()) {
152                            GCUtil.gc();
153                    }
154            }
155    
156    }