All Downloads are FREE. Search and download functionalities are using the official Maven repository.

no.uib.cipr.matrix.BandMatrix Maven / Gradle / Ivy

Go to download

Matrix data structures, linear solvers, least squares methods, eigenvalue, and singular value decompositions. For larger random dense matrices (above ~ 350 x 350) matrix-matrix multiplication C = A.B is about 50% faster than MTJ.

There is a newer version: 1.1.0
Show newest version
/*
 * Copyright (C) 2003-2006 Bjørn-Ove Heimsund
 * 
 * This file is part of MTJ.
 * 
 * This library is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by the
 * Free Software Foundation; either version 2.1 of the License, or (at your
 * option) any later version.
 * 
 * This library is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
 * for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with this library; if not, write to the Free Software Foundation,
 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */

package no.uib.cipr.matrix;

import java.util.Arrays;

import com.github.fommil.netlib.BLAS;
import com.github.fommil.netlib.LAPACK;
import org.netlib.util.intW;

/**
 * Banded matrix. The banded matrix is a useful sparse structure for many kinds
 * of direct computations, however it should only be used if the band is
 * sufficiently narrow as wide bands actually wastes both memory and compute
 * time. The matrix
 * 

*

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
a11a12   
a21a22a23  
a31a32a33a34 
 a42a43a44a45
  a53a54a55
*

*

* has two lower diagonals and one upper diagonal. It will be stored in the * array *

*

*

* * * * * * * * * * * * * * * * * * * * * * *
 a11a21a31a21a22a32a42a23a33a43a53a34a44a54 a45a55  
*

*

* Empty cells are allocated, but never referenced. *

*/ public class BandMatrix extends AbstractBandMatrix { /** * Constructor for BandMatrix. * * @param n * Size of the matrix. Since the matrix must be square, this * equals both the number of rows and columns * @param kl * Number of bands above the main diagonal (superdiagonals) * @param ku * Number of bands below the main diagonal (subdiagonals) */ public BandMatrix(int n, int kl, int ku) { super(n, kl, ku); } /** * Constructor for BandMatrix. * * @param A * Matrix to copy contents from. Only the parts of A * that lie within the allocated band are copied over, the rest * is ignored * @param kl * Number of bands above the main diagonal (superdiagonals) * @param ku * Number of bands below the main diagonal (subdiagonals) */ public BandMatrix(Matrix A, int kl, int ku) { super(A, kl, ku); } /** * Constructor for BandMatrix. * * @param A * Matrix to copy contents from. Only the parts of A * that lie within the allocated band are copied over, the rest * is ignored * @param kl * Number of bands above the main diagonal (superdiagonals) * @param ku * Number of bands below the main diagonal (subdiagonals) * @param deep * True for a deep copy. For shallow copies, A must * be a banded matrix */ public BandMatrix(Matrix A, int kl, int ku, boolean deep) { super(A, kl, ku, deep); } @Override public BandMatrix copy() { return new BandMatrix(this, kl, ku); } @Override public Matrix zero() { Arrays.fill(data, 0); return this; } @Override public Vector multAdd(double alpha, Vector x, Vector y) { if (!(x instanceof DenseVector) || !(y instanceof DenseVector)) return super.multAdd(alpha, x, y); checkMultAdd(x, y); double[] xd = ((DenseVector) x).getData(), yd = ((DenseVector) y) .getData(); BLAS.getInstance().dgbmv(Transpose.NoTranspose.netlib(), numRows, numColumns, kl, ku, alpha, data, kl + ku + 1, xd, 1, 1, yd, 1); return y; } @Override public Vector transMultAdd(double alpha, Vector x, Vector y) { if (!(x instanceof DenseVector) || !(y instanceof DenseVector)) return super.transMultAdd(alpha, x, y); checkTransMultAdd(x, y); double[] xd = ((DenseVector) x).getData(), yd = ((DenseVector) y) .getData(); BLAS.getInstance().dgbmv(Transpose.Transpose.netlib(), numRows, numColumns, kl, ku, alpha, data, kl + ku + 1, xd, 1, 1, yd, 1); return y; } @Override public Matrix solve(Matrix B, Matrix X) { if (!(X instanceof DenseMatrix)) throw new UnsupportedOperationException("X must be a DenseMatrix"); checkSolve(B, X); double[] Xd = ((DenseMatrix) X).getData(); X.set(B); // Allocate factorization matrix. The factorization matrix will be // large enough to accommodate any pivots BandMatrix Af = new BandMatrix(this, kl, ku + kl); int[] ipiv = new int[numRows]; intW info = new intW(0); LAPACK.getInstance().dgbsv(numRows, kl, ku, X.numColumns(), Af.getData(), Matrices.ld(2 * kl + ku + 1), ipiv, Xd, Matrices.ld(numRows), info); if (info.val > 0) throw new MatrixSingularException(); else if (info.val < 0) throw new IllegalArgumentException(); return X; } @Override public Vector solve(Vector b, Vector x) { DenseMatrix B = new DenseMatrix(b, false), X = new DenseMatrix(x, false); solve(B, X); return x; } @Override public Matrix transpose() { checkTranspose(); if (kl != ku) throw new IllegalArgumentException("kl != ku"); for (int j = 0; j < numColumns; ++j) for (int i = j + 1; i < Math.min(j + kl + 1, numRows); ++i) { double value = get(i, j); set(i, j, get(j, i)); set(j, i, value); } return this; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy