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.util;
025    
026    import java.lang.reflect.Method;
027    
028    import org.ujmp.core.Coordinates;
029    import org.ujmp.core.doublematrix.DenseDoubleMatrix2D;
030    import org.ujmp.core.doublematrix.impl.DefaultDenseDoubleMatrix2D;
031    import org.ujmp.core.exceptions.MatrixException;
032    
033    public abstract class BLAS {
034    
035            private static Method dgemm = null;
036    
037            static {
038                    try {
039                            Class<?> c = Class.forName("org.netlib.blas.Dgemm");
040                            dgemm = c.getMethod("dgemm", String.class, String.class, Integer.TYPE, Integer.TYPE,
041                                            Integer.TYPE, Double.TYPE, double[].class, Integer.TYPE, Integer.TYPE,
042                                            double[].class, Integer.TYPE, Integer.TYPE, Double.TYPE, double[].class,
043                                            Integer.TYPE, Integer.TYPE);
044                    } catch (Throwable e) {
045                            System.out.println("arpack-combo.jar not found, cannot use BLAS");
046                    }
047            }
048    
049            public static synchronized void dgemm(int rows, int retcols, int cols, int i, double[] values,
050                            int j, int rows2, double[] m2, int k, int l, int m, double[] ret, int n, int rows3) {
051                    try {
052                            dgemm.invoke(null, "N", "N", rows, retcols, cols, i, values, j, rows2, m2, k, l, m,
053                                            ret, n, rows3);
054                    } catch (Exception e) {
055                            e.printStackTrace();
056                    }
057            }
058    
059            public static boolean isAvailable() {
060                    return dgemm != null;
061            }
062    
063            public static final DenseDoubleMatrix2D mtimes(DefaultDenseDoubleMatrix2D A,
064                            DefaultDenseDoubleMatrix2D B) {
065                    if (A.getColumnCount() != B.getRowCount()) {
066                            throw new MatrixException("matrices have wrong size: "
067                                            + Coordinates.toString(A.getSize()) + " and "
068                                            + Coordinates.toString(B.getSize()));
069                    }
070                    final int alpha = 1;
071                    final int beta = 1;
072                    final int acols = (int) A.getColumnCount();
073                    final int arows = (int) A.getRowCount();
074                    final int bcols = (int) B.getColumnCount();
075                    final int brows = (int) B.getRowCount();
076                    final double[] avalues = A.getColumnMajorDoubleArray1D();
077                    final double[] bvalues = B.getColumnMajorDoubleArray1D();
078                    final double[] cvalues = new double[arows * bcols];
079                    BLAS.dgemm(arows, bcols, acols, alpha, avalues, 0, arows, bvalues, 0, brows, beta, cvalues,
080                                    0, arows);
081                    final DefaultDenseDoubleMatrix2D c = new DefaultDenseDoubleMatrix2D(cvalues, arows, bcols);
082                    return c;
083            }
084    
085    }