mtj-0.9.14/0000755000000000000000000000000011762646445011114 5ustar rootrootmtj-0.9.14/nbproject/0000755000000000000000000000000011467303576013077 5ustar rootrootmtj-0.9.14/nbproject/project.xml0000644000000000000000000000135211324170636015257 0ustar rootroot org.netbeans.modules.java.j2seproject Matrix Toolkits for Java 1.6.5 ./lib/nblibraries.properties mtj-0.9.14/nbproject/build-impl.xml0000644000000000000000000015664511554101200015651 0ustar rootroot Must set src.dir Must set test.src.dir Must set build.dir Must set dist.dir Must set build.classes.dir Must set dist.javadoc.dir Must set build.test.classes.dir Must set build.test.results.dir Must set build.classes.excludes Must set dist.jar Must set javac.includes Must set JVM to use for profiling in profiler.info.jvm Must set profiler agent JVM arguments in profiler.info.jvmargs.agent Must select some files in the IDE or set javac.includes To run this application from the command line without Ant, try: java -cp "${run.classpath.with.dist.jar}" ${main.class} To run this application from the command line without Ant, try: java -jar "${dist.jar.resolved}" Must select one file in the IDE or set run.class Must select one file in the IDE or set run.class Must select one file in the IDE or set debug.class Must select one file in the IDE or set debug.class Must set fix.includes Must select one file in the IDE or set profile.class Must select some files in the IDE or set javac.includes Some tests failed; see details above. Must select some files in the IDE or set test.includes Some tests failed; see details above. Must select one file in the IDE or set test.class Must select one file in the IDE or set applet.url Must select one file in the IDE or set applet.url mtj-0.9.14/nbproject/project.properties0000644000000000000000000000406211324170636016654 0ustar rootrootapplication.title=Matrix Toolkits for Java application.vendor=Google Code build.classes.dir=${build.dir}/classes build.classes.excludes=**/*.java,**/*.form, **/*.html # This directory is removed when the project is cleaned: build.dir=build build.generated.dir=${build.dir}/generated build.generated.sources.dir=${build.dir}/generated-sources # Only compile against the classpath explicitly listed here: build.sysclasspath=ignore build.test.classes.dir=${build.dir}/test/classes build.test.results.dir=${build.dir}/test/results debug.classpath=\ ${run.classpath} debug.test.classpath=\ ${run.test.classpath} # This directory is removed when the project is cleaned: dist.dir=dist dist.jar=${dist.dir}/Matrix_Toolkits_for_Java.jar dist.javadoc.dir=${dist.dir}/javadoc endorsed.classpath= excludes= file.reference.mtj-src=src file.reference.mtj-tests=tests includes=** jar.compress=false javac.classpath=\ ${libs.netlib-java.classpath} # Space-separated list of extra javac options javac.compilerargs= javac.deprecation=false javac.source=1.6 javac.target=1.6 javac.test.classpath=\ ${javac.classpath}:\ ${build.classes.dir}:\ ${libs.junit.classpath} javadoc.additionalparam= javadoc.author=false javadoc.encoding=${source.encoding} javadoc.noindex=false javadoc.nonavbar=false javadoc.notree=false javadoc.private=false javadoc.splitindex=true javadoc.use=true javadoc.version=false javadoc.windowtitle= jaxbwiz.endorsed.dirs="${netbeans.home}/../ide12/modules/ext/jaxb/api" main.class= manifest.file=manifest.mf meta.inf.dir=${src.dir}/META-INF platform.active=default_platform run.classpath=\ ${javac.classpath}:\ ${build.classes.dir} # Space-separated list of JVM arguments used when running the project # (you may also define separate properties like run-sys-prop.name=value instead of -Dname=value # or test-sys-prop.name=value to set system properties for unit tests): run.jvmargs=-ea run.test.classpath=\ ${javac.test.classpath}:\ ${build.test.classes.dir} source.encoding=UTF-8 src.dir=${file.reference.mtj-src} test.src.dir=${file.reference.mtj-tests} mtj-0.9.14/nbproject/private/0000755000000000000000000000000011027526336014542 5ustar rootrootmtj-0.9.14/nbproject/private/private.xml0000644000000000000000000000031711467462060016740 0ustar rootroot mtj-0.9.14/nbproject/private/config.properties0000644000000000000000000000000011027526336020113 0ustar rootrootmtj-0.9.14/nbproject/private/private.properties0000644000000000000000000000065411554101200020317 0ustar rootrootcompile.on.save=true do.depend=false do.jar=true file.reference.mtj-src=/Users/samuel/Documents/Java/matrix-toolkits-java/src file.reference.mtj-tests=/Users/samuel/Documents/Java/matrix-toolkits-java/tests javac.debug=true javadoc.preview=true jaxbwiz.endorsed.dirs=/Applications/NetBeans/NetBeans 6.8.app/Contents/Resources/NetBeans/ide12/modules/ext/jaxb/api user.properties.file=/Users/samuel/.netbeans/7.0/build.properties mtj-0.9.14/nbproject/genfiles.properties0000644000000000000000000000071111554101200016761 0ustar rootrootbuild.xml.data.CRC32=6c9798d6 build.xml.script.CRC32=9d16e40f build.xml.stylesheet.CRC32=be360661 # This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. # Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. nbproject/build-impl.xml.data.CRC32=c323db9c nbproject/build-impl.xml.script.CRC32=c8fc78f3 nbproject/build-impl.xml.stylesheet.CRC32=0c01fd8e@1.43.1.45 mtj-0.9.14/src/0000755000000000000000000000000011027515240011661 5ustar rootrootmtj-0.9.14/src/no/0000755000000000000000000000000011027515240012275 5ustar rootrootmtj-0.9.14/src/no/uib/0000755000000000000000000000000011027515240013054 5ustar rootrootmtj-0.9.14/src/no/uib/cipr/0000755000000000000000000000000011027515240014011 5ustar rootrootmtj-0.9.14/src/no/uib/cipr/matrix/0000755000000000000000000000000011467462040015324 5ustar rootrootmtj-0.9.14/src/no/uib/cipr/matrix/UnitLowerTriangBandMatrix.java0000644000000000000000000000717611027512662023247 0ustar rootroot/* * 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; /** * Unit lower triangular banded matrix. The same storage as * {@link no.uib.cipr.matrix.LowerTriangBandMatrix LowerTriangBandMatrix}, but * the main diagonal is assumed to be all ones. It is still allocated, however. */ public class UnitLowerTriangBandMatrix extends LowerTriangBandMatrix { /** * Constructor for UnitLowerTriangBandMatrix * * @param n * Size of the matrix. Since the matrix must be square, this * equals both the number of rows and columns * @param kd * Number of bands below the main diagonal (subdiagonals) */ public UnitLowerTriangBandMatrix(int n, int kd) { super(n, kd, Diag.Unit); } /** * Constructor for UnitLowerTriangBandMatrix * * @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 (including main diagonal entries) * @param kd * Number of bands below the main diagonal (subdiagonals) */ public UnitLowerTriangBandMatrix(Matrix A, int kd) { this(A, kd, true); } /** * Constructor for UnitLowerTriangBandMatrix * * @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 (including main diagonal entries) * @param kd * 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 UnitLowerTriangBandMatrix(Matrix A, int kd, boolean deep) { super(A, kd, deep, Diag.Unit); } @Override public void add(int row, int column, double value) { if (row == column) throw new IllegalArgumentException("row == column"); super.add(row, column, value); } @Override public double get(int row, int column) { if (row == column) return 1; return super.get(row, column); } @Override public void set(int row, int column, double value) { if (row == column) throw new IllegalArgumentException("row == column"); super.set(row, column, value); } @Override public UnitLowerTriangBandMatrix copy() { return new UnitLowerTriangBandMatrix(this, kl); } @Override public Matrix zero() { throw new UnsupportedOperationException(); } @Override void copy(Matrix A) { for (MatrixEntry e : A) if (inBand(e.row(), e.column()) && e.row() != e.column()) set(e.row(), e.column(), e.get()); } } mtj-0.9.14/src/no/uib/cipr/matrix/UpperSymmPackMatrix.java0000644000000000000000000000610511027512662022114 0ustar rootroot/* * 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; /** * Upper symmetric packed matrix. Same storage as * {@link no.uib.cipr.matrix.UpperTriangPackMatrix UpperTriangPackMatrix}, but * the lower triangular part is known by symmetry. */ public class UpperSymmPackMatrix extends AbstractSymmPackMatrix { /** * Constructor for UpperSymmPackMatrix * * @param n * Size of the matrix. Since the matrix must be square, this * equals both the number of rows and columns */ public UpperSymmPackMatrix(int n) { super(n, UpLo.Upper); } /** * Constructor for UpperSymmPackMatrix * * @param A * Matrix to copy contents from. Only the entries of the relevant * part are copied */ public UpperSymmPackMatrix(Matrix A) { this(A, true); } /** * Constructor for UpperSymmPackMatrix * * @param A * Matrix to copy contents from. Only the entries of the relevant * part are copied * @param deep * True if the copy is deep, else false (giving a shallow copy). * For shallow copies, A must be a packed matrix */ public UpperSymmPackMatrix(Matrix A, boolean deep) { super(A, deep, UpLo.Upper); } @Override public void add(int row, int column, double value) { if (row <= column) data[getIndex(row, column)] += value; } @Override public void set(int row, int column, double value) { if (row <= column) data[getIndex(row, column)] = value; } @Override public double get(int row, int column) { if (row <= column) return data[getIndex(row, column)]; return data[getIndex(column, row)]; } /** * Checks the row and column indices, and returns the linear data index */ int getIndex(int row, int column) { check(row, column); return row + (column + 1) * column / 2; } @Override void copy(Matrix A) { for (MatrixEntry e : A) if (e.row() <= e.column()) set(e.row(), e.column(), e.get()); } @Override public UpperSymmPackMatrix copy() { return new UpperSymmPackMatrix(this); } } mtj-0.9.14/src/no/uib/cipr/matrix/BandMatrix.java0000644000000000000000000001601711027512662020223 0ustar rootroot/* * 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 org.netlib.blas.BLAS; import org.netlib.lapack.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 accomodate 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; } } mtj-0.9.14/src/no/uib/cipr/matrix/UpperTriangPackMatrix.java0000644000000000000000000001162711027512662022420 0ustar rootroot/* * 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; /** * Upper triangular packed matrix. In contrast with * {@link no.uib.cipr.matrix.LowerTriangDenseMatrix LowerTriangDenseMatrix}, * this matrix exploits the sparsity by only storing about half the matrix. As * such, the triangular matrix *

* * * * * * * * * * * * * * * * * * * * * * * * * *
a11a12a13a14
 a22a23a24
  a33a34
   a44
*

*

* is packed as follows: *

*

* * * * * * * * * * * * * *
a11a12a22a13a23a33a14a24a34a44
*

*/ public class UpperTriangPackMatrix extends AbstractTriangPackMatrix { /** * Constructor for UpperTriangPackMatrix * * @param n * Size of the matrix. Since the matrix must be square, this * equals both the number of rows and columns */ public UpperTriangPackMatrix(int n) { super(n, UpLo.Upper, Diag.NonUnit); } /** * Constructor for UpperTriangPackMatrix * * @param n * Size of the matrix. Since the matrix must be square, this * equals both the number of rows and columns */ UpperTriangPackMatrix(int n, Diag diag) { super(n, UpLo.Upper, diag); } /** * Constructor for UpperTriangPackMatrix * * @param A * Matrix to copy contents from. Only the entries of the relevant * part are copied */ public UpperTriangPackMatrix(Matrix A) { this(A, true); } /** * Constructor for UpperTriangPackMatrix * * @param A * Matrix to copy contents from. Only the entries of the relevant * part are copied * @param deep * True if the copy is deep, else false (giving a shallow copy). * For shallow copies, A must be a packed matrix */ public UpperTriangPackMatrix(Matrix A, boolean deep) { super(A, deep, UpLo.Upper, Diag.NonUnit); } /** * Constructor for UpperTriangPackMatrix * * @param A * Matrix to copy contents from. Only the entries of the relevant * part are copied * @param deep * True if the copy is deep, else false (giving a shallow copy). * For shallow copies, A must be a packed matrix */ UpperTriangPackMatrix(Matrix A, boolean deep, Diag diag) { super(A, deep, UpLo.Upper, diag); } @Override public void add(int row, int column, double value) { if (row > column) throw new IllegalArgumentException("row > column"); data[getIndex(row, column)] += value; } @Override public void set(int row, int column, double value) { if (row > column) throw new IllegalArgumentException("row > column"); data[getIndex(row, column)] = value; } @Override public double get(int row, int column) { if (row > column) return 0; return data[getIndex(row, column)]; } /** * Checks the row and column indices, and returns the linear data index */ int getIndex(int row, int column) { check(row, column); return row + (column + 1) * column / 2; } @Override void copy(Matrix A) { for (MatrixEntry e : A) if (e.row() <= e.column()) set(e.row(), e.column(), e.get()); } @Override public UpperTriangPackMatrix copy() { return new UpperTriangPackMatrix(this); } } mtj-0.9.14/src/no/uib/cipr/matrix/UpperSymmDenseMatrix.java0000644000000000000000000000566211027512662022303 0ustar rootroot/* * 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; /** * Upper symmetrix dense matrix. It has the same storage layout as the * {@link no.uib.cipr.matrix.DenseMatrix DenseMatrix}, but only refers to * elements above or on the main diagonal. The remaining elements are never * accessed nor changed, and is known only by symmetry. */ public class UpperSymmDenseMatrix extends AbstractSymmDenseMatrix { /** * Constructor for UpperSymmDenseMatrix * * @param n * Size of the matrix. Since the matrix must be square, this * equals both the number of rows and columns */ public UpperSymmDenseMatrix(int n) { super(n, UpLo.Upper); } /** * Constructor for UpperSymmDenseMatrix * * @param A * Matrix to copy. It must be a square matrix, and only the upper * triangular part is copied */ public UpperSymmDenseMatrix(Matrix A) { this(A, true); } /** * Constructor for UpperSymmDenseMatrix * * @param A * Matrix to copy. It must be a square matrix, and only the upper * triangular part is copied * @param deep * If false, a shallow copy is made. In that case, A * must be a dense matrix */ public UpperSymmDenseMatrix(Matrix A, boolean deep) { super(A, deep, UpLo.Upper); } @Override public void add(int row, int column, double value) { if (row <= column) super.add(row, column, value); } @Override public double get(int row, int column) { if (row > column) return super.get(column, row); return super.get(row, column); } @Override public void set(int row, int column, double value) { if (row <= column) super.set(row, column, value); } @Override public UpperSymmDenseMatrix copy() { return new UpperSymmDenseMatrix(this); } @Override void copy(Matrix A) { for (MatrixEntry e : A) if (e.row() <= e.column()) set(e.row(), e.column(), e.get()); } } mtj-0.9.14/src/no/uib/cipr/matrix/SVD.java0000644000000000000000000001342111027512662016622 0ustar rootroot/* * 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 org.netlib.lapack.LAPACK; import org.netlib.util.intW; /** * Computes singular value decompositions */ public class SVD { /** * Work array */ private final double[] work; /** * Work array */ private final int[] iwork; /** * Matrix dimension */ private final int m, n; /** * Compute the singular vectors fully? */ private final boolean vectors; /** * Job to do */ private final JobSVD job; /** * The singular values */ private final double[] S; /** * Singular vectors */ private final DenseMatrix U, Vt; /** * Creates an empty SVD which will compute all singular values and vectors * * @param m * Number of rows * @param n * Number of columns */ public SVD(int m, int n) { this(m, n, true); } /** * Creates an empty SVD * * @param m * Number of rows * @param n * Number of columns * @param vectors * True to compute the singular vectors, false for just the * singular values */ public SVD(int m, int n, boolean vectors) { this.m = m; this.n = n; this.vectors = vectors; // Allocate space for the decomposition S = new double[Math.min(m, n)]; if (vectors) { U = new DenseMatrix(m, m); Vt = new DenseMatrix(n, n); } else U = Vt = null; job = vectors ? JobSVD.All : JobSVD.None; // Find workspace requirements iwork = new int[8 * Math.min(m, n)]; // Query optimal workspace double[] worksize = new double[1]; intW info = new intW(0); LAPACK.getInstance().dgesdd(job.netlib(), m, n, new double[0], Matrices.ld(m), new double[0], new double[0], Matrices.ld(m), new double[0], Matrices.ld(n), worksize, -1, iwork, info); // Allocate workspace int lwork = -1; if (info.val != 0) { if (vectors) lwork = 3 * Math.min(m, n) * Math.min(m, n) + Math.max(Math.max(m, n), 4 * Math.min(m, n) * Math.min(m, n) + 4 * Math.min(m, n)); else lwork = 3 * Math.min(m, n) * Math.min(m, n) + Math.max(Math.max(m, n), 5 * Math.min(m, n) * Math.min(m, n) + 4 * Math.min(m, n)); } else lwork = (int) worksize[0]; lwork = Math.max(lwork, 1); work = new double[lwork]; } /** * Convenience method for computing a full SVD * * @param A * Matrix to decompose, not modified * @return Newly allocated factorization * @throws NotConvergedException */ public static SVD factorize(Matrix A) throws NotConvergedException { return new SVD(A.numRows(), A.numColumns()).factor(new DenseMatrix(A)); } /** * Computes an SVD * * @param A * Matrix to decompose. Size must conform, and it will be * overwritten on return. Pass a copy to avoid this * @return The current decomposition * @throws NotConvergedException */ public SVD factor(DenseMatrix A) throws NotConvergedException { if (A.numRows() != m) throw new IllegalArgumentException("A.numRows() != m"); else if (A.numColumns() != n) throw new IllegalArgumentException("A.numColumns() != n"); intW info = new intW(0); LAPACK.getInstance().dgesdd(job.netlib(), m, n, A.getData(), Matrices.ld(m), S, vectors ? U.getData() : new double[0], Matrices.ld(m), vectors ? Vt.getData() : new double[0], Matrices.ld(n), work, work.length, iwork, info); if (info.val > 0) throw new NotConvergedException( NotConvergedException.Reason.Iterations); else if (info.val < 0) throw new IllegalArgumentException(); return this; } /** * True if singular vectors are stored */ public boolean hasSingularVectors() { return U != null; } /** * Returns the left singular vectors, column-wise. Not available for partial * decompositions * * @return Matrix of size m*m */ public DenseMatrix getU() { return U; } /** * Returns the right singular vectors, row-wise. Not available for partial * decompositions * * @return Matrix of size n*n */ public DenseMatrix getVt() { return Vt; } /** * Returns the singular values (stored in descending order) * * @return Array of size min(m,n) */ public double[] getS() { return S; } } mtj-0.9.14/src/no/uib/cipr/matrix/RQ.java0000644000000000000000000000776211027512662016523 0ustar rootroot/* * 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 org.netlib.lapack.LAPACK; import org.netlib.util.intW; /** * Computes RQ decompositions */ public class RQ extends OrthogonalComputer { /** * Constructs an empty RQ decomposition * * @param m * Number of rows * @param n * Number of columns. Must be larger than or equal the number of * rows */ public RQ(int m, int n) { super(m, n, true); if (n < m) throw new IllegalArgumentException("n < m"); int lwork; // Query optimal workspace. First for computing the factorization { work = new double[1]; intW info = new intW(0); LAPACK.getInstance().dgerqf(m, n, new double[0], Matrices.ld(m), new double[0], work, -1, info); if (info.val != 0) lwork = m; else lwork = (int) work[0]; lwork = Math.max(1, lwork); work = new double[lwork]; } // Workspace needed for generating an explicit orthogonal matrix { workGen = new double[1]; intW info = new intW(0); LAPACK.getInstance().dorgrq(m, n, m, new double[0],Matrices.ld(m), new double[0], workGen, -1, info); if (info.val != 0) lwork = m; else lwork = (int) workGen[0]; lwork = Math.max(1, lwork); workGen = new double[lwork]; } } /** * Convenience method to compute an RQ decomposition * * @param A * Matrix to decompose. Not modified * @return Newly allocated decomposition */ public static RQ factorize(Matrix A) { return new RQ(A.numRows(), A.numColumns()).factor(new DenseMatrix(A)); } @Override public RQ factor(DenseMatrix A) { if (Q.numRows() != A.numRows()) throw new IllegalArgumentException("Q.numRows() != A.numRows()"); else if (Q.numColumns() != A.numColumns()) throw new IllegalArgumentException( "Q.numColumns() != A.numColumns()"); else if (R == null) throw new IllegalArgumentException("R == null"); /* * Calculate factorisation, and extract the triangular factor */ intW info = new intW(0); LAPACK.getInstance().dgerqf(m, n, A.getData(), Matrices.ld(m), tau, work, work.length, info); if (info.val < 0) throw new IllegalArgumentException(); R.zero(); for (MatrixEntry e : A) if (e.column() >= (n - m) + e.row()) R.set(e.row(), e.column() - (n - m), e.get()); /* * Generate the orthogonal matrix */ info.val = 0; LAPACK.getInstance().dorgrq(m, n, k, A.getData(), Matrices.ld(m), tau, workGen, workGen.length, info); if (info.val < 0) throw new IllegalArgumentException(); Q.set(A); return this; } /** * Returns the upper triangular factor */ public UpperTriangDenseMatrix getR() { return R; } } mtj-0.9.14/src/no/uib/cipr/matrix/UpperSymmBandMatrix.java0000644000000000000000000000614011027512662022101 0ustar rootroot/* * 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; /** * Upper symmetrical banded matrix. The same storage as * {@link no.uib.cipr.matrix.BandMatrix BandMatrix}, but without subdiagonals. * Lower part of the matrix is implictly known by symmetry */ public class UpperSymmBandMatrix extends AbstractSymmBandMatrix { /** * Constructor for UpperSymmBandMatrix * * @param n * Size of the matrix. Since the matrix must be square, this * equals both the number of rows and columns * @param kd * Number of bands off the main diagonal (off diagonals) */ public UpperSymmBandMatrix(int n, int kd) { super(n, 0, kd, UpLo.Upper); } /** * Constructor for UpperSymmBandMatrix * * @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 kd * Number of bands off the main diagonal (off diagonals) */ public UpperSymmBandMatrix(Matrix A, int kd) { this(A, kd, true); } /** * Constructor for UpperSymmBandMatrix * * @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 kd * Number of bands off the main diagonal (off diagonals) * @param deep * True for a deep copy. For shallow copies, A * must be a banded matrix */ public UpperSymmBandMatrix(Matrix A, int kd, boolean deep) { super(A, 0, kd, deep, UpLo.Upper); } @Override public void add(int row, int column, double value) { if (row <= column) super.add(row, column, value); } @Override public double get(int row, int column) { if (row > column) return super.get(column, row); return super.get(row, column); } @Override public void set(int row, int column, double value) { if (row <= column) super.set(row, column, value); } @Override public UpperSymmBandMatrix copy() { return new UpperSymmBandMatrix(this, kd); } } mtj-0.9.14/src/no/uib/cipr/matrix/DenseCholesky.java0000644000000000000000000001511011034473524020724 0ustar rootroot/* * 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 no.uib.cipr.matrix.Matrix.Norm; import org.netlib.lapack.LAPACK; import org.netlib.util.doubleW; import org.netlib.util.intW; /** * Dense Cholesky decomposition */ public class DenseCholesky { /** * Matrix dimension */ private final int n; /** * Cholesky decomposition of a lower matrix */ private LowerTriangDenseMatrix Cl; /** * Cholesky decomposition of an upper matrix */ private UpperTriangDenseMatrix Cu; /** * If the matrix is SPD or not */ private boolean notspd; /** * True for upper part, else false */ private final boolean upper; /** * Constructor for DenseCholesky * * @param n * Matrix size * @param upper * True for decomposing an upper symmetrical matrix, false for a * lower symmetrical matrix */ public DenseCholesky(int n, boolean upper) { this.n = n; this.upper = upper; if (upper) Cu = new UpperTriangDenseMatrix(n); else Cl = new LowerTriangDenseMatrix(n); } /** * Calculates a Cholesky decomposition * * @param A * Matrix to decompose. Not modified * @return The current decomposition */ public static DenseCholesky factorize(Matrix A) { return new DenseCholesky(A.numRows(), true) .factor(new UpperSPDDenseMatrix(A)); } /** * Calculates a Cholesky decomposition * * @param A * Matrix to decompose. Overwritten on return * @return The current decomposition */ public DenseCholesky factor(LowerSPDDenseMatrix A) { if (upper) throw new IllegalArgumentException( "Cholesky decomposition constructed for upper matrices"); return decompose(A); } /** * Calculates a Cholesky decomposition * * @param A * Matrix to decompose. Overwritten on return * @return The current decomposition */ public DenseCholesky factor(UpperSPDDenseMatrix A) { if (!upper) throw new IllegalArgumentException( "Cholesky decomposition constructed for lower matrices"); return decompose(A); } private DenseCholesky decompose(AbstractDenseMatrix A) { if (n != A.numRows()) throw new IllegalArgumentException("n != A.numRows()"); notspd = false; intW info = new intW(0); if (upper) LAPACK.getInstance().dpotrf(UpLo.Upper.netlib(), A.numRows(), A.getData(), Matrices.ld(A.numRows()), info); else LAPACK.getInstance().dpotrf(UpLo.Lower.netlib(), A.numRows(), A.getData(), Matrices.ld(A.numRows()), info); if (info.val > 0) notspd = true; else if (info.val < 0) throw new IllegalArgumentException(); if (upper) Cu.set(A); else Cl.set(A); return this; } /** * Returns true if the matrix decomposed is symmetrical, positive definite */ public boolean isSPD() { return !notspd; } /** * Returns the decomposition matrix. Only valid for decomposition of a lower * SPD matrix */ public LowerTriangDenseMatrix getL() { if (!upper) return Cl; else throw new UnsupportedOperationException(); } /** * Returns the decomposition matrix. Only valid for decomposition of a upper * SPD matrix */ public UpperTriangDenseMatrix getU() { if (upper) return Cu; else throw new UnsupportedOperationException(); } /** * Solves for B, overwriting it on return */ public DenseMatrix solve(DenseMatrix B) throws MatrixNotSPDException { if (notspd) throw new MatrixNotSPDException(); if (n != B.numRows()) throw new IllegalArgumentException("n != B.numRows()"); intW info = new intW(0); if (upper) LAPACK.getInstance().dpotrs(UpLo.Upper.netlib(), Cu.numRows(), B.numColumns(), Cu.getData(), Matrices.ld(Cu.numRows()), B.getData(), Matrices.ld(Cu.numRows()), info); else LAPACK.getInstance().dpotrs(UpLo.Lower.netlib(), Cl.numRows(), B.numColumns(), Cl.getData(), Matrices.ld(Cl.numRows()), B.getData(), Matrices.ld(Cl.numRows()), info); if (info.val < 0) throw new IllegalArgumentException(); return B; } /** * Computes the reciprocal condition number * * @param A * The matrix this is a decomposition of * @return The reciprocal condition number. Values close to unity indicate a * well-conditioned system, while numbers close to zero do not. */ public double rcond(Matrix A) { if (n != A.numRows()) throw new IllegalArgumentException("n != A.numRows()"); if (!A.isSquare()) throw new IllegalArgumentException("!A.isSquare()"); double anorm = A.norm(Norm.One); double[] work = new double[3 * n]; int[] iwork = new int[n]; intW info = new intW(0); doubleW rcond = new doubleW(0); if (upper) LAPACK.getInstance().dpocon(UpLo.Upper.netlib(), n, Cu.getData(), Matrices.ld(n), anorm, rcond, work, iwork, info); else LAPACK.getInstance().dpocon(UpLo.Lower.netlib(), n, Cl.getData(), Matrices.ld(n), anorm, rcond, work, iwork, info); if (info.val < 0) throw new IllegalArgumentException(); return rcond.val; } } mtj-0.9.14/src/no/uib/cipr/matrix/SymmTridiagEVD.java0000644000000000000000000001260711027512662020763 0ustar rootroot/* * 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 org.netlib.lapack.LAPACK; import org.netlib.util.intW; /** * Computes eigenvalues of symmetrical, tridiagonal matrices */ public class SymmTridiagEVD extends SymmEVD { /** * Double work array */ private final double[] work; /** * Integer work array */ private final int[] iwork; /** * Range of eigenvalues to compute */ private final JobEigRange range; /** * Eigenvector supports */ private final int[] isuppz; /** * Tolerance criteria */ private final double abstol; /** * Sets up an eigenvalue decomposition for symmetrical, tridiagonal * matrices. Computes all eigenvalues and eigenvectors, and uses a low * default tolerance criteria * * @param n * Size of the matrix */ public SymmTridiagEVD(int n) { this(n, true); } /** * Sets up an eigenvalue decomposition for symmetrical, tridiagonal * matrices. Computes all eigenvalues and eigenvectors * * @param n * Size of the matrix * @param abstol * Absolute tolerance criteria */ public SymmTridiagEVD(int n, double abstol) { this(n, true, abstol); } /** * Sets up an eigenvalue decomposition for symmetrical, tridiagonal * matrices. Uses a low default tolerance criteria * * @param n * Size of the matrix * @param vectors * True to compute the eigenvectors, false for just the * eigenvalues */ public SymmTridiagEVD(int n, boolean vectors) { this(n, vectors, LAPACK.getInstance().dlamch("Safe minimum")); } /** * Sets up an eigenvalue decomposition for symmetrical, tridiagonal matrices * * @param n * Size of the matrix * @param vectors * True to compute the eigenvectors, false for just the * eigenvalues * @param abstol * Absolute tolerance criteria */ public SymmTridiagEVD(int n, boolean vectors, double abstol) { super(n, vectors); this.abstol = abstol; range = JobEigRange.All; isuppz = new int[2 * Math.max(1, n)]; // Find the needed workspace double[] worksize = new double[1]; int[] iworksize = new int[1]; intW info = new intW(0); LAPACK.getInstance().dstevr(job.netlib(), range.netlib(), n, new double[0], new double[0], 0, 0, 0, 0, abstol, new intW(1), new double[0], new double[0], Matrices.ld(n), isuppz, worksize, -1, iworksize, -1, info); // Allocate workspace int lwork = 0, liwork = 0; if (info.val != 0) { lwork = 20 * n; liwork = 10 * n; } else { lwork = (int) worksize[0]; liwork = iworksize[0]; } lwork = Math.max(1, lwork); liwork = Math.max(1, liwork); work = new double[lwork]; iwork = new int[liwork]; } /** * Convenience method for computing the full eigenvalue decomposition of the * given matrix * * @param A * Matrix to factorize. Main diagonal and superdiagonal is * copied, and the matrix is not modified * @return Newly allocated decomposition * @throws NotConvergedException */ public static SymmTridiagEVD factorize(Matrix A) throws NotConvergedException { return new SymmTridiagEVD(A.numRows()).factor(new SymmTridiagMatrix(A)); } /** * Computes the eigenvalue decomposition of the given matrix * * @param A * Matrix to factorize. Overwritten on return * @return The current eigenvalue decomposition * @throws NotConvergedException */ public SymmTridiagEVD factor(SymmTridiagMatrix A) throws NotConvergedException { if (A.numRows() != n) throw new IllegalArgumentException("A.numRows() != n"); intW info = new intW(0); LAPACK.getInstance().dstevr(job.netlib(), range.netlib(), n, A.getDiagonal(), A.getOffDiagonal(), 0, 0, 0, 0, abstol, new intW(1), w, job == JobEig.All ? Z.getData() : new double[0], Matrices.ld(n), isuppz, work, work.length, iwork, iwork.length, info); if (info.val > 0) throw new NotConvergedException( NotConvergedException.Reason.Iterations); else if (info.val < 0) throw new IllegalArgumentException(); return this; } } mtj-0.9.14/src/no/uib/cipr/matrix/sparse/0000755000000000000000000000000011554357132016623 5ustar rootrootmtj-0.9.14/src/no/uib/cipr/matrix/sparse/CG.java0000644000000000000000000000502711027512662017757 0ustar rootroot/* * 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 */ /* * Derived from public domain software at http://www.netlib.org/templates */ package no.uib.cipr.matrix.sparse; import no.uib.cipr.matrix.Matrix; import no.uib.cipr.matrix.Vector; /** * Conjugate Gradients solver. CG solves the symmetric positive definite linear * system Ax=b using the Conjugate Gradient method. * * @author Templates */ public class CG extends AbstractIterativeSolver { /** * Vectors for use in the iterative solution process */ private Vector p, z, q, r; /** * Constructor for CG. Uses the given vector as template for creating * scratch vectors. Typically, the solution or the right hand side vector * can be passed, and the template is not modified * * @param template * Vector to use as template for the work vectors needed in the * solution process */ public CG(Vector template) { p = template.copy(); z = template.copy(); q = template.copy(); r = template.copy(); } public Vector solve(Matrix A, Vector b, Vector x) throws IterativeSolverNotConvergedException { checkSizes(A, b, x); double alpha = 0, beta = 0, rho = 0, rho_1 = 0; A.multAdd(-1, x, r.set(b)); for (iter.setFirst(); !iter.converged(r, x); iter.next()) { M.apply(r, z); rho = r.dot(z); if (iter.isFirst()) p.set(z); else { beta = rho / rho_1; p.scale(beta).add(z); } A.mult(p, q); alpha = rho / p.dot(q); x.add(alpha, p); r.add(-alpha, q); rho_1 = rho; } return x; } } mtj-0.9.14/src/no/uib/cipr/matrix/sparse/QMR.java0000644000000000000000000001526511027512662020132 0ustar rootroot/* * 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 */ /* * Derived from public domain software at http://www.netlib.org/templates */ package no.uib.cipr.matrix.sparse; import no.uib.cipr.matrix.Matrix; import no.uib.cipr.matrix.NotConvergedException; import no.uib.cipr.matrix.Vector; import no.uib.cipr.matrix.Vector.Norm; /** * Quasi-Minimal Residual method. QMR solves the unsymmetric linear system * Ax = b using the Quasi-Minimal Residual method. QMR uses two * preconditioners, and by default these are the same preconditioner. * * @author Templates */ public class QMR extends AbstractIterativeSolver { /** * Left preconditioner */ private Preconditioner M1; /** * Right preconditioner */ private Preconditioner M2; /** * Vectors for use in the iterative solution process */ private Vector r, y, z, v, w, p, q, d, s, v_tld, w_tld, y_tld, z_tld, p_tld; /** * Constructor for QMR. Uses the given vector as template for creating * scratch vectors. Typically, the solution or the right hand side vector * can be passed, and the template is not modified * * @param template * Vector to use as template for the work vectors needed in the * solution process */ public QMR(Vector template) { M1 = M; M2 = M; r = template.copy(); y = template.copy(); z = template.copy(); v = template.copy(); w = template.copy(); p = template.copy(); q = template.copy(); d = template.copy(); s = template.copy(); v_tld = template.copy(); w_tld = template.copy(); y_tld = template.copy(); z_tld = template.copy(); p_tld = template.copy(); } /** * Constructor for QMR. Uses the given vector as template for creating * scratch vectors. Typically, the solution or the right hand side vector * can be passed, and the template is not modified. Allows setting different * right and left preconditioners * * @param template * Vector to use as template for the work vectors needed in the * solution process * @param M1 * Left preconditioner * @param M2 * Right preconditioner */ public QMR(Vector template, Preconditioner M1, Preconditioner M2) { this.M1 = M1; this.M2 = M2; r = template.copy(); y = template.copy(); z = template.copy(); v = template.copy(); w = template.copy(); p = template.copy(); q = template.copy(); d = template.copy(); s = template.copy(); v_tld = template.copy(); w_tld = template.copy(); y_tld = template.copy(); z_tld = template.copy(); p_tld = template.copy(); } public Vector solve(Matrix A, Vector b, Vector x) throws IterativeSolverNotConvergedException { checkSizes(A, b, x); double rho = 0, rho_1 = 0, xi = 0, gamma = 1., gamma_1 = 0, theta = 0, theta_1 = 0, eta = -1., delta = 0, ep = 0, beta = 0; A.multAdd(-1, x, r.set(b)); v_tld.set(r); M1.apply(v_tld, y); rho = y.norm(Norm.Two); w_tld.set(r); M2.transApply(w_tld, z); xi = z.norm(Norm.Two); for (iter.setFirst(); !iter.converged(r, x); iter.next()) { if (rho == 0) throw new IterativeSolverNotConvergedException( NotConvergedException.Reason.Breakdown, "rho", iter); if (xi == 0) throw new IterativeSolverNotConvergedException( NotConvergedException.Reason.Breakdown, "xi", iter); v.set(1 / rho, v_tld); y.scale(1 / rho); w.set(1 / xi, w_tld); z.scale(1 / xi); delta = z.dot(y); if (delta == 0) throw new IterativeSolverNotConvergedException( NotConvergedException.Reason.Breakdown, "delta", iter); M2.apply(y, y_tld); M1.transApply(z, z_tld); if (iter.isFirst()) { p.set(y_tld); q.set(z_tld); } else { p.scale(-xi * delta / ep).add(y_tld); q.scale(-rho * delta / ep).add(z_tld); } A.mult(p, p_tld); ep = q.dot(p_tld); if (ep == 0) throw new IterativeSolverNotConvergedException( NotConvergedException.Reason.Breakdown, "ep", iter); beta = ep / delta; if (beta == 0) throw new IterativeSolverNotConvergedException( NotConvergedException.Reason.Breakdown, "beta", iter); v_tld.set(-beta, v).add(p_tld); M1.apply(v_tld, y); rho_1 = rho; rho = y.norm(Norm.Two); A.transMultAdd(q, w_tld.set(-beta, w)); M2.transApply(w_tld, z); xi = z.norm(Norm.Two); gamma_1 = gamma; theta_1 = theta; theta = rho / (gamma_1 * beta); gamma = 1 / Math.sqrt(1 + theta * theta); if (gamma == 0) throw new IterativeSolverNotConvergedException( NotConvergedException.Reason.Breakdown, "gamma", iter); eta = -eta * rho_1 * gamma * gamma / (beta * gamma_1 * gamma_1); if (iter.isFirst()) { d.set(eta, p); s.set(eta, p_tld); } else { double val = theta_1 * theta_1 * gamma * gamma; d.scale(val).add(eta, p); s.scale(val).add(eta, p_tld); } x.add(d); r.add(-1, s); } return x; } @Override public void setPreconditioner(Preconditioner M) { super.setPreconditioner(M); M1 = M; M2 = M; } } mtj-0.9.14/src/no/uib/cipr/matrix/sparse/FlexCompColMatrix.java0000644000000000000000000001473511027512662023034 0ustar rootroot/* * 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.sparse; import java.util.Arrays; import java.util.Iterator; import no.uib.cipr.matrix.AbstractMatrix; import no.uib.cipr.matrix.DenseVector; import no.uib.cipr.matrix.Matrix; import no.uib.cipr.matrix.MatrixEntry; import no.uib.cipr.matrix.Vector; import no.uib.cipr.matrix.VectorEntry; import no.uib.cipr.matrix.sparse.SuperIterator.SuperIteratorEntry; /** * Matrix stored column-wise into sparse vectors */ public class FlexCompColMatrix extends AbstractMatrix { /** * Matrix data */ SparseVector[] colD; /** * Constructor for FlexCompColMatrix * * @param numRows * Number of rows * @param numColumns * Number of column */ public FlexCompColMatrix(int numRows, int numColumns) { super(numRows, numColumns); colD = new SparseVector[numColumns]; for (int i = 0; i < numColumns; ++i) colD[i] = new SparseVector(numRows); } /** * Constructor for FlexCompColMatrix * * @param A * Matrix to copy contents from * @param deep * True for a deep copy, false for a reference copy. A reference * copy can only be made of an FlexCompColMatrix */ public FlexCompColMatrix(Matrix A, boolean deep) { super(A); colD = new SparseVector[numColumns]; if (deep) { for (int i = 0; i < numColumns; ++i) colD[i] = new SparseVector(numRows); set(A); } else { FlexCompColMatrix Ar = (FlexCompColMatrix) A; for (int i = 0; i < numColumns; ++i) colD[i] = Ar.getColumn(i); } } /** * Constructor for FlexCompColMatrix * * @param A * Matrix to copy contents from. The copy will be deep */ public FlexCompColMatrix(Matrix A) { this(A, true); } /** * Returns the given column */ public SparseVector getColumn(int i) { return colD[i]; } /** * Sets the given column equal the passed vector */ public void setColumn(int i, SparseVector x) { if (x.size() != numRows) throw new IllegalArgumentException( "New column must be of the same size as existing column"); colD[i] = x; } @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(); double[] yd = ((DenseVector) y).getData(); // y = 1/alpha * y y.scale(1. / alpha); // y = A*x + y for (int i = 0; i < numColumns; ++i) { SparseVector v = colD[i]; int[] index = v.getIndex(); double[] data = v.getData(); int length = v.getUsed(); for (int j = 0; j < length; ++j) yd[index[j]] += data[j] * xd[i]; } // y = alpha*y = alpha * A'x + y return y.scale(alpha); } @Override public Vector transMultAdd(final double alpha, final Vector x, final Vector y) { checkTransMultAdd(x, y); for (int i = 0; i < numColumns; ++i) y.add(i, alpha * colD[i].dot(x)); return y; } @Override public void add(int row, int column, double value) { colD[column].add(row, value); } @Override public void set(int row, int column, double value) { colD[column].set(row, value); } @Override public double get(int row, int column) { return colD[column].get(row); } @Override public Iterator iterator() { return new ColMatrixIterator(); } @Override public FlexCompColMatrix copy() { return new FlexCompColMatrix(this); } @Override public FlexCompColMatrix zero() { for (int i = 0; i < numColumns; ++i) colD[i].zero(); return this; } /** * Tries to store the matrix as compactly as possible */ public void compact() { for (Vector v : colD) ((SparseVector) v).compact(); } /** * Iterator over a matrix stored vectorwise by columns */ private class ColMatrixIterator implements Iterator { /** * Iterates over each column vector */ private SuperIterator iterator = new SuperIterator( Arrays.asList(colD)); /** * Entry returned */ private ColMatrixEntry entry = new ColMatrixEntry(); public boolean hasNext() { return iterator.hasNext(); } public MatrixEntry next() { SuperIteratorEntry se = iterator.next(); entry.update(se.index(), se.get()); return entry; } public void remove() { iterator.remove(); } } /** * Entry of a matrix stored vectorwise by columns */ private static class ColMatrixEntry implements MatrixEntry { private int column; private VectorEntry entry; public void update(int column, VectorEntry entry) { this.column = column; this.entry = entry; } public int row() { return entry.index(); } public int column() { return column; } public double get() { return entry.get(); } public void set(double value) { entry.set(value); } } } mtj-0.9.14/src/no/uib/cipr/matrix/sparse/IterationReporter.java0000644000000000000000000000271511027512662023150 0ustar rootroot/* * 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.sparse; import no.uib.cipr.matrix.Vector; /** * Reports on the progress of an iterative solver */ public interface IterationReporter { /** * Registers current information * * @param r * Current residual norm * @param x * Current state vector * @param i * Current iteration number */ void monitor(double r, Vector x, int i); /** * Registers current information * * @param r * Current residual norm * @param i * Current iteration number */ void monitor(double r, int i); } mtj-0.9.14/src/no/uib/cipr/matrix/sparse/GMRES.java0000644000000000000000000001256511027512662020350 0ustar rootroot/* * 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 */ /* * Derived from public domain software at http://www.netlib.org/templates */ package no.uib.cipr.matrix.sparse; import no.uib.cipr.matrix.DenseMatrix; import no.uib.cipr.matrix.DenseVector; import no.uib.cipr.matrix.GivensRotation; import no.uib.cipr.matrix.Matrix; import no.uib.cipr.matrix.UpperTriangDenseMatrix; import no.uib.cipr.matrix.Vector; import no.uib.cipr.matrix.Vector.Norm; /** * GMRES solver. GMRES solves the unsymmetric linear system Ax = b * using the Generalized Minimum Residual method. The GMRES iteration is * restarted after a given number of iterations. By default it is restarted * after 30 iterations. * * @author Templates */ public class GMRES extends AbstractIterativeSolver { /** * After this many iterations, the GMRES will be restarted. */ private int restart; /** * Vectors for use in the iterative solution process */ private Vector w, u, r; /** * Vectors spanning the subspace */ private Vector[] v; /** * Restart vector */ private DenseVector s; /** * Hessenberg matrix */ private DenseMatrix H; /** * Givens rotations for the QR factorization */ private GivensRotation[] rotation; /** * Constructor for GMRES. Uses the given vector as template for creating * scratch vectors. Typically, the solution or the right hand side vector * can be passed, and the template is not modified. The iteration is * restarted every 30 iterations * * @param template * Vector to use as template for the work vectors needed in the * solution process */ public GMRES(Vector template) { this(template, 30); } /** * Constructor for GMRES. Uses the given vector as template for creating * scratch vectors. Typically, the solution or the right hand side vector * can be passed, and the template is not modified * * @param template * Vector to use as template for the work vectors needed in the * solution process * @param restart * GMRES iteration is restarted after this number of iterations */ public GMRES(Vector template, int restart) { w = template.copy(); u = template.copy(); r = template.copy(); setRestart(restart); } /** * Sets the restart parameter * * @param restart * GMRES iteration is restarted after this number of iterations */ public void setRestart(int restart) { this.restart = restart; if (restart <= 0) throw new IllegalArgumentException( "restart must be a positive integer"); s = new DenseVector(restart + 1); H = new DenseMatrix(restart + 1, restart); rotation = new GivensRotation[restart + 1]; v = new Vector[restart + 1]; for (int i = 0; i < v.length; ++i) v[i] = r.copy().zero(); } public Vector solve(Matrix A, Vector b, Vector x) throws IterativeSolverNotConvergedException { checkSizes(A, b, x); A.multAdd(-1, x, u.set(b)); M.apply(u, r); double normr = r.norm(Norm.Two); M.apply(b, u); // Outer iteration for (iter.setFirst(); !iter.converged(r, x); iter.next()) { v[0].set(1 / normr, r); s.zero().set(0, normr); int i = 0; // Inner iteration for (; i < restart && !iter.converged(Math.abs(s.get(i))); i++, iter .next()) { A.mult(v[i], u); M.apply(u, w); for (int k = 0; k <= i; k++) { H.set(k, i, w.dot(v[k])); w.add(-H.get(k, i), v[k]); } H.set(i + 1, i, w.norm(Norm.Two)); v[i + 1].set(1. / H.get(i + 1, i), w); // QR factorization of H using Givens rotations for (int k = 0; k < i; ++k) rotation[k].apply(H, i, k, k + 1); rotation[i] = new GivensRotation(H.get(i, i), H.get(i + 1, i)); rotation[i].apply(H, i, i, i + 1); rotation[i].apply(s, i, i + 1); } // Update solution in current subspace new UpperTriangDenseMatrix(H, i, false).solve(s, s); for (int j = 0; j < i; j++) x.add(s.get(j), v[j]); A.multAdd(-1, x, u.set(b)); M.apply(u, r); normr = r.norm(Norm.Two); } return x; } } mtj-0.9.14/src/no/uib/cipr/matrix/sparse/CompRowMatrix.java0000644000000000000000000004000611027512662022235 0ustar rootroot/* * 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.sparse; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import no.uib.cipr.matrix.AbstractMatrix; import no.uib.cipr.matrix.DenseVector; import no.uib.cipr.matrix.Matrix; import no.uib.cipr.matrix.MatrixEntry; import no.uib.cipr.matrix.Vector; import no.uib.cipr.matrix.io.MatrixInfo; import no.uib.cipr.matrix.io.MatrixSize; import no.uib.cipr.matrix.io.MatrixVectorReader; import org.netlib.blas.BLAS; /** * Compressed row storage (CRS) matrix */ public class CompRowMatrix extends AbstractMatrix { /** * Matrix data */ double[] data; /** * Column indices. These are kept sorted within each row. */ int[] columnIndex; /** * Indices to the start of each row */ int[] rowPointer; /** * Constructor for CompRowMatrix * * @param r * Reader to get sparse matrix from */ public CompRowMatrix(MatrixVectorReader r) throws IOException { // Start with a zero-sized matrix super(0, 0); // Get matrix information. Use the header if present, else just assume // that the matrix stores real numbers without any symmetry MatrixInfo info = null; if (r.hasInfo()) info = r.readMatrixInfo(); else info = new MatrixInfo(true, MatrixInfo.MatrixField.Real, MatrixInfo.MatrixSymmetry.General); // Check that the matrix is in an acceptable format if (info.isPattern()) throw new UnsupportedOperationException( "Pattern matrices are not supported"); if (info.isDense()) throw new UnsupportedOperationException( "Dense matrices are not supported"); if (info.isComplex()) throw new UnsupportedOperationException( "Complex matrices are not supported"); // Resize the matrix to correct size MatrixSize size = r.readMatrixSize(info); numRows = size.numRows(); numColumns = size.numColumns(); // Start reading entries int numEntries = size.numEntries(); int[] row = new int[numEntries]; int[] column = new int[numEntries]; double[] entry = new double[numEntries]; r.readCoordinate(row, column, entry); // Shift the indices from 1 based to 0 based r.add(-1, row); r.add(-1, column); // Find the number of entries on each row List> rnz = new ArrayList>(numRows); for (int i = 0; i < numRows; ++i) rnz.add(new HashSet()); for (int i = 0; i < numEntries; ++i) rnz.get(row[i]).add(column[i]); // Allocate some more in case of symmetry if (info.isSymmetric() || info.isSkewSymmetric()) for (int i = 0; i < numEntries; ++i) if (row[i] != column[i]) rnz.get(column[i]).add(row[i]); int[][] nz = new int[numRows][]; for (int i = 0; i < numRows; ++i) { nz[i] = new int[rnz.get(i).size()]; int j = 0; for (Integer colind : rnz.get(i)) nz[i][j++] = colind; } // Create the sparse matrix structure construct(nz); // Insert the entries for (int i = 0; i < size.numEntries(); ++i) set(row[i], column[i], entry[i]); // Put in extra entries from symmetry or skew symmetry if (info.isSymmetric()) for (int i = 0; i < numEntries; ++i) { if (row[i] != column[i]) set(column[i], row[i], entry[i]); } else if (info.isSkewSymmetric()) for (int i = 0; i < numEntries; ++i) { if (row[i] != column[i]) set(column[i], row[i], -entry[i]); } } /** * Constructor for CompRowMatrix * * @param numRows * Number of rows * @param numColumns * Number of columns * @param nz * The nonzero column indices on each row */ public CompRowMatrix(int numRows, int numColumns, int[][] nz) { super(numRows, numColumns); construct(nz); } private void construct(int[][] nz) { int nnz = 0; for (int i = 0; i < nz.length; ++i) nnz += nz[i].length; rowPointer = new int[numRows + 1]; columnIndex = new int[nnz]; data = new double[nnz]; if (nz.length != numRows) throw new IllegalArgumentException("nz.length != numRows"); for (int i = 1; i <= numRows; ++i) { rowPointer[i] = rowPointer[i - 1] + nz[i - 1].length; for (int j = rowPointer[i - 1], k = 0; j < rowPointer[i]; ++j, ++k) { columnIndex[j] = nz[i - 1][k]; if (nz[i - 1][k] < 0 || nz[i - 1][k] >= numColumns) throw new IllegalArgumentException("nz[" + (i - 1) + "][" + k + "]=" + nz[i - 1][k] + ", which is not a valid column index"); } Arrays.sort(columnIndex, rowPointer[i - 1], rowPointer[i]); } } private void construct(Matrix A, boolean deep) { if (deep) { if (A instanceof CompRowMatrix) { CompRowMatrix Ac = (CompRowMatrix) A; data = new double[Ac.data.length]; columnIndex = new int[Ac.columnIndex.length]; rowPointer = new int[Ac.rowPointer.length]; System.arraycopy(Ac.data, 0, data, 0, data.length); System.arraycopy(Ac.columnIndex, 0, columnIndex, 0, columnIndex.length); System.arraycopy(Ac.rowPointer, 0, rowPointer, 0, rowPointer.length); } else { List> rnz = new ArrayList>(numRows); for (int i = 0; i < numRows; ++i) rnz.add(new HashSet()); for (MatrixEntry e : A) rnz.get(e.row()).add(e.column()); int[][] nz = new int[numRows][]; for (int i = 0; i < numRows; ++i) { nz[i] = new int[rnz.get(i).size()]; int j = 0; for (Integer colind : rnz.get(i)) nz[i][j++] = colind; } construct(nz); set(A); } } else { CompRowMatrix Ac = (CompRowMatrix) A; columnIndex = Ac.getColumnIndices(); rowPointer = Ac.getRowPointers(); data = Ac.getData(); } } /** * Constructor for CompRowMatrix * * @param A * Copies from this matrix * @param deep * True if the copy is to be deep. If it is a shallow copy, * A must be a CompRowMatrix */ public CompRowMatrix(Matrix A, boolean deep) { super(A); construct(A, deep); } /** * Constructor for CompRowMatrix * * @param A * Copies from this matrix. The copy will be deep */ public CompRowMatrix(Matrix A) { this(A, true); } /** * Returns the column indices */ public int[] getColumnIndices() { return columnIndex; } /** * Returns the row pointers */ public int[] getRowPointers() { return rowPointer; } /** * Returns the internal data storage */ public double[] getData() { return data; } @Override public Matrix mult(Matrix B, Matrix C) { checkMultAdd(B, C); C.zero(); // optimised a little bit to avoid zeros in rows, but not to // exploit sparsity of matrix B for (int i = 0; i < numRows; ++i) { for (int j = 0; j < C.numColumns(); ++j) { double dot = 0; for (int k = rowPointer[i]; k < rowPointer[i + 1]; ++k) { dot += data[k] * B.get(columnIndex[k], j); } if (dot != 0) { C.set(i, j, dot); } } } return C; } @Override public Vector mult(Vector x, Vector y) { // check dimensions checkMultAdd(x, y); // can't assume this, unfortunately y.zero(); if (x instanceof DenseVector) { // DenseVector optimisations double[] xd = ((DenseVector) x).getData(); for (int i = 0; i < numRows; ++i) { double dot = 0; for (int j = rowPointer[i]; j < rowPointer[i + 1]; j++) { dot += data[j] * xd[columnIndex[j]]; } if (dot != 0) { y.set(i, dot); } } return y; } // use sparsity of matrix (not vector), as get(,) is slow // TODO: additional optimisations for mult(ISparseVector, Vector) // note that this would require Sparse BLAS, e.g. BLAS_DUSDOT(,,,,) // @see http://www.netlib.org/blas/blast-forum/chapter3.pdf for (int i = 0; i < numRows; ++i) { double dot = 0; for (int j = rowPointer[i]; j < rowPointer[i + 1]; j++) { dot += data[j] * x.get(columnIndex[j]); } y.set(i, dot); } return y; } @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(); double[] yd = ((DenseVector) y).getData(); for (int i = 0; i < numRows; ++i) { double dot = 0; for (int j = rowPointer[i]; j < rowPointer[i + 1]; ++j) dot += data[j] * xd[columnIndex[j]]; yd[i] += alpha * dot; } return y; } @Override public Vector transMult(Vector x, Vector y) { if (!(x instanceof DenseVector) || !(y instanceof DenseVector)) return super.transMult(x, y); checkTransMultAdd(x, y); double[] xd = ((DenseVector) x).getData(); double[] yd = ((DenseVector) y).getData(); y.zero(); for (int i = 0; i < numRows; ++i) for (int j = rowPointer[i]; j < rowPointer[i + 1]; ++j) yd[columnIndex[j]] += data[j] * xd[i]; 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(); double[] yd = ((DenseVector) y).getData(); // y = 1/alpha * y y.scale(1. / alpha); // y = A'x + y for (int i = 0; i < numRows; ++i) for (int j = rowPointer[i]; j < rowPointer[i + 1]; ++j) yd[columnIndex[j]] += data[j] * xd[i]; // y = alpha*y = alpha*A'x + y return y.scale(alpha); } @Override public void set(int row, int column, double value) { check(row, column); int index = getIndex(row, column); data[index] = value; } @Override public void add(int row, int column, double value) { check(row, column); int index = getIndex(row, column); data[index] += value; } @Override public double get(int row, int column) { check(row, column); int index = no.uib.cipr.matrix.sparse.Arrays.binarySearch(columnIndex, column, rowPointer[row], rowPointer[row + 1]); if (index >= 0) return data[index]; else return 0; } /** * Finds the insertion index */ private int getIndex(int row, int column) { int i = no.uib.cipr.matrix.sparse.Arrays.binarySearch(columnIndex, column, rowPointer[row], rowPointer[row + 1]); if (i != -1 && columnIndex[i] == column) return i; else throw new IndexOutOfBoundsException("Entry (" + (row + 1) + ", " + (column + 1) + ") is not in the matrix structure"); } @Override public CompRowMatrix copy() { return new CompRowMatrix(this); } @Override public Iterator iterator() { return new CompRowMatrixIterator(); } @Override public CompRowMatrix zero() { Arrays.fill(data, 0); return this; } @Override public Matrix set(Matrix B) { if (!(B instanceof CompRowMatrix)) return super.set(B); checkSize(B); CompRowMatrix Bc = (CompRowMatrix) B; // Reallocate matrix structure, if necessary if (Bc.columnIndex.length != columnIndex.length || Bc.rowPointer.length != rowPointer.length) { data = new double[Bc.data.length]; columnIndex = new int[Bc.columnIndex.length]; rowPointer = new int[Bc.rowPointer.length]; } System.arraycopy(Bc.data, 0, data, 0, data.length); System.arraycopy(Bc.columnIndex, 0, columnIndex, 0, columnIndex.length); System.arraycopy(Bc.rowPointer, 0, rowPointer, 0, rowPointer.length); return this; } /** * Iterator over a compressed row matrix */ private class CompRowMatrixIterator implements Iterator { private int row, cursor; private CompRowMatrixEntry entry = new CompRowMatrixEntry(); public CompRowMatrixIterator() { // Find first non-empty row nextNonEmptyRow(); } /** * Locates the first non-empty row, starting at the current. After the * new row has been found, the cursor is also updated */ private void nextNonEmptyRow() { while (row < numRows() && rowPointer[row] == rowPointer[row + 1]) row++; cursor = rowPointer[row]; } public boolean hasNext() { return cursor < data.length; } public MatrixEntry next() { entry.update(row, cursor); // Next position is in the same row if (cursor < rowPointer[row + 1] - 1) cursor++; // Next position is at the following (non-empty) row else { row++; nextNonEmptyRow(); } return entry; } public void remove() { entry.set(0); } } /** * Entry of a compressed row matrix */ private class CompRowMatrixEntry implements MatrixEntry { private int row, cursor; /** * Updates the entry */ public void update(int row, int cursor) { this.row = row; this.cursor = cursor; } public int row() { return row; } public int column() { return columnIndex[cursor]; } public double get() { return data[cursor]; } public void set(double value) { data[cursor] = value; } } } mtj-0.9.14/src/no/uib/cipr/matrix/sparse/AMG.java0000644000000000000000000006766111027512662020106 0ustar rootroot/* * 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.sparse; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; import no.uib.cipr.matrix.DenseLU; import no.uib.cipr.matrix.DenseMatrix; import no.uib.cipr.matrix.DenseVector; import no.uib.cipr.matrix.Matrix; import no.uib.cipr.matrix.Vector; /** * Algebraic multigrid preconditioner. Uses the smoothed aggregation method * described by Vanek, Mandel, and Brezina (1996). */ public class AMG implements Preconditioner { /** * Relaxations at each level */ private SSOR[] preM, postM; /** * The number of levels */ private int m; /** * System matrix at each level, except at the coarsest */ private CompRowMatrix[] A; /** * LU factorization at the coarsest level */ private DenseLU lu; /** * Solution, right-hand side, and residual vectors at each level */ private DenseVector[] u, f, r; /** * Interpolation operators going to a finer mesh */ private CompColMatrix[] I; /** * Smallest matrix size before terminating the AMG setup phase. Matrices * smaller than this will be solved by a direct solver */ private final int min; /** * Number of times to perform the pre- and post-smoothings */ private final int nu1, nu2; /** * Determines cycle type. gamma=1 is V, gamma=2 is W */ private final int gamma; /** * Overrelaxation parameters in the pre- and post-smoothings, and with the * possibility of distinct values in the forward and reverse sweeps */ private final double omegaPreF, omegaPreR, omegaPostF, omegaPostR; /** * Perform a reverse (backwards) smoothing sweep */ private final boolean reverse; /** * Jacobi damping parameter, between zero and one. If it equals zero, the * method reduces to the standard aggregate multigrid method */ private final double omega; /** * Operating in transpose mode? */ private boolean transpose; /** * Sets up the algebraic multigrid preconditioner * * @param omegaPreF * Overrelaxation parameter in the forward sweep of the * pre-smoothing * @param omegaPreR * Overrelaxation parameter in the backwards sweep of the * pre-smoothing * @param omegaPostF * Overrelaxation parameter in the forward sweep of the * post-smoothing * @param omegaPostR * Overrelaxation parameter in the backwards sweep of the * post-smoothing * @param nu1 * Number of pre-relaxations to perform * @param nu2 * Number of post-relaxations to perform * @param gamma * Number of times to go to a coarser level * @param min * Smallest matrix size before using a direct solver * @param omega * Jacobi damping parameter, between zero and one. If it equals * zero, the method reduces to the standard aggregate multigrid * method */ public AMG(double omegaPreF, double omegaPreR, double omegaPostF, double omegaPostR, int nu1, int nu2, int gamma, int min, double omega) { this.omegaPreF = omegaPreF; this.omegaPreR = omegaPreR; this.omegaPostF = omegaPostF; this.omegaPostR = omegaPostR; reverse = true; this.nu1 = nu1; this.nu2 = nu2; this.gamma = gamma; this.min = min; this.omega = omega; } /** * Sets up the algebraic multigrid preconditioner. Uses an SOR method, * without the backward sweep in SSOR * * @param omegaPre * Overrelaxation parameter in the pre-smoothing * @param omegaPost * Overrelaxation parameter in the post-smoothing * @param nu1 * Number of pre-relaxations to perform * @param nu2 * Number of post-relaxations to perform * @param gamma * Number of times to go to a coarser level * @param min * Smallest matrix size before using a direct solver * @param omega * Jacobi damping parameter, between zero and one. If it equals * zero, the method reduces to the standard aggregate multigrid * method */ public AMG(double omegaPre, double omegaPost, int nu1, int nu2, int gamma, int min, double omega) { this.omegaPreF = omegaPre; this.omegaPreR = omegaPre; this.omegaPostF = omegaPost; this.omegaPostR = omegaPost; reverse = false; this.nu1 = nu1; this.nu2 = nu2; this.gamma = gamma; this.min = min; this.omega = omega; } /** * Sets up the algebraic multigrid preconditioner using some default * parameters. In the presmoothing, omegaF=1 and * omegaR=1.85, while in the postsmoothing, * omegaF=1.85 and omegaR=1. Sets * nu1=nu2=gamma=1, has a smallest matrix size of 40, and * sets omega=2/3. */ public AMG() { this(1, 1.85, 1.85, 1, 1, 1, 1, 40, 2. / 3); } public Vector apply(Vector b, Vector x) { u[0].set(x); f[0].set(b); transpose = false; cycle(0); return x.set(u[0]); } public Vector transApply(Vector b, Vector x) { u[0].set(x); f[0].set(b); transpose = true; cycle(0); return x.set(u[0]); } public void setMatrix(Matrix A) { List Al = new LinkedList(); List Il = new LinkedList(); Al.add(new CompRowMatrix(A)); for (int k = 0; Al.get(k).numRows() > min; ++k) { CompRowMatrix Af = Al.get(k); double eps = 0.08 * Math.pow(0.5, k); // Create the aggregates Aggregator aggregator = new Aggregator(Af, eps); // If no aggregates were created, no interpolation operator will be // created, and the setup phase stops if (aggregator.getAggregates().size() == 0) break; // Create an interpolation operator using smoothing. This also // creates the Galerkin operator Interpolator sa = new Interpolator(aggregator, Af, omega); Al.add(sa.getGalerkinOperator()); Il.add(sa.getInterpolationOperator()); } // Copy to array storage m = Al.size(); if (m == 0) throw new RuntimeException("Matrix too small for AMG"); I = new CompColMatrix[m - 1]; this.A = new CompRowMatrix[m - 1]; Il.toArray(I); for (int i = 0; i < Al.size() - 1; ++i) this.A[i] = Al.get(i); // Create a LU decomposition of the smallest Galerkin matrix DenseMatrix Ac = new DenseMatrix(Al.get(Al.size() - 1)); lu = new DenseLU(Ac.numRows(), Ac.numColumns()); lu.factor(Ac); // Allocate vectors at each level u = new DenseVector[m]; f = new DenseVector[m]; r = new DenseVector[m]; for (int k = 0; k < m; ++k) { int n = Al.get(k).numRows(); u[k] = new DenseVector(n); f[k] = new DenseVector(n); r[k] = new DenseVector(n); } // Set up the SSOR relaxation schemes preM = new SSOR[m - 1]; postM = new SSOR[m - 1]; for (int k = 0; k < m - 1; ++k) { CompRowMatrix Ak = this.A[k]; preM[k] = new SSOR(Ak, reverse, omegaPreF, omegaPreR); postM[k] = new SSOR(Ak, reverse, omegaPostF, omegaPostR); preM[k].setMatrix(Ak); postM[k].setMatrix(Ak); } } /** * Performs a multigrid cycle * * @param k * Level to cycle at. Start by calling cycle(0) */ private void cycle(int k) { if (k == m - 1) directSolve(); else { // Presmoothings preRelax(k); u[k + 1].zero(); // Compute the residual A[k].multAdd(-1, u[k], r[k].set(f[k])); // Restrict to the next coarser level I[k].transMult(r[k], f[k + 1]); // Recurse to next level for (int i = 0; i < gamma; ++i) cycle(k + 1); // Add residual correction by prolongation I[k].multAdd(u[k + 1], u[k]); // Postsmoothings postRelax(k); } } /** * Solves directly at the coarsest level */ private void directSolve() { int k = m - 1; u[k].set(f[k]); DenseMatrix U = new DenseMatrix(u[k], false); if (transpose) lu.transSolve(U); else lu.solve(U); } /** * Applies the relaxation scheme at the given level * * @param k * Multigrid level */ private void preRelax(int k) { for (int i = 0; i < nu1; ++i) if (transpose) preM[k].transApply(f[k], u[k]); else preM[k].apply(f[k], u[k]); } /** * Applies the relaxation scheme at the given level * * @param k * Multigrid level */ private void postRelax(int k) { for (int i = 0; i < nu2; ++i) if (transpose) postM[k].transApply(f[k], u[k]); else postM[k].apply(f[k], u[k]); } /** * Creates aggregates. These are disjoint sets, each of which represents one * node at a coarser mesh by aggregating together a set of fine nodes */ private static class Aggregator { /** * The aggregates */ private List> C; /** * Diagonal indices into the sparse matrix */ private int[] diagind; /** * The strongly coupled node neighborhood of a given node */ private List> N; /** * Creates the aggregates * * @param A * Sparse matrix * @param eps * Tolerance for selecting the strongly coupled node * neighborhoods. Between zero and one. */ public Aggregator(CompRowMatrix A, double eps) { diagind = findDiagonalIndices(A); N = findNodeNeighborhood(A, diagind, eps); /* * Initialization. Remove isolated nodes from the aggregates */ boolean[] R = createInitialR(A); /* * Startup aggregation. Use disjoint strongly coupled neighborhoods * as the initial aggregate approximation */ C = createInitialAggregates(N, R); /* * Enlargment of the aggregates. Add nodes to each aggregate based * on how strongly connected the nodes are to a given aggregate */ C = enlargeAggregates(C, N, R); /* * Handling of the remenants. Put all remaining unallocated nodes * into new aggregates defined by the intersection of N and R */ C = createFinalAggregates(C, N, R); } /** * Gets the aggregates */ public List> getAggregates() { return C; } /** * Returns the matrix diagonal indices. This is a by-product of the * aggregation */ public int[] getDiagonalIndices() { return diagind; } /** * Returns the strongly coupled node neighborhoods of a given node. This * is a by-product of the aggregation */ public List> getNodeNeighborhoods() { return N; } /** * Finds the diagonal indices of the matrix */ private int[] findDiagonalIndices(CompRowMatrix A) { int[] rowptr = A.getRowPointers(); int[] colind = A.getColumnIndices(); int[] diagind = new int[A.numRows()]; for (int i = 0; i < A.numRows(); ++i) { diagind[i] = no.uib.cipr.matrix.sparse.Arrays.binarySearch( colind, i, rowptr[i], rowptr[i + 1]); if (diagind[i] < 0) throw new RuntimeException( "Matrix is missing a diagonal entry on row " + (i + 1)); } return diagind; } /** * Finds the strongly coupled node neighborhoods */ private List> findNodeNeighborhood(CompRowMatrix A, int[] diagind, double eps) { N = new ArrayList>(A.numRows()); int[] rowptr = A.getRowPointers(); int[] colind = A.getColumnIndices(); double[] data = A.getData(); for (int i = 0; i < A.numRows(); ++i) { Set Ni = new HashSet(); double aii = data[diagind[i]]; for (int j = rowptr[i]; j < rowptr[i + 1]; ++j) { double aij = data[j]; double ajj = data[diagind[colind[j]]]; if (Math.abs(aij) >= eps * Math.sqrt(aii * ajj)) Ni.add(colind[j]); } N.add(Ni); } return N; } /** * Creates the initial R-set by including only the connected nodes */ private boolean[] createInitialR(CompRowMatrix A) { boolean[] R = new boolean[A.numRows()]; int[] rowptr = A.getRowPointers(); int[] colind = A.getColumnIndices(); double[] data = A.getData(); for (int i = 0; i < A.numRows(); ++i) { boolean hasOffDiagonal = false; for (int j = rowptr[i]; j < rowptr[i + 1]; ++j) if (colind[j] != i && data[j] != 0) { hasOffDiagonal = true; break; } R[i] = hasOffDiagonal; } return R; } /** * Creates the initial aggregates */ private List> createInitialAggregates( List> N, boolean[] R) { C = new ArrayList>(); for (int i = 0; i < R.length; ++i) { // Skip non-free nodes if (!R[i]) continue; // See if all nodes in the current N-set are free boolean free = true; for (int j : N.get(i)) free &= R[j]; // Create an aggregate out of N[i] if (free) { C.add(new HashSet(N.get(i))); for (int j : N.get(i)) R[j] = false; } } return C; } /** * Enlarges the aggregates */ private List> enlargeAggregates(List> C, List> N, boolean[] R) { // Contains the aggregates each node is coupled to List> belong = new ArrayList>(R.length); for (int i = 0; i < R.length; ++i) belong.add(new ArrayList()); // Find which aggregate each node is coupled to. This is used for // the intersection between Ni and Ck for (int k = 0; k < C.size(); ++k) for (int j : C.get(k)) belong.get(j).add(k); // Number of nodes in the intersection between each C and Ni int[] intersect = new int[C.size()]; for (int i = 0; i < R.length; ++i) { // Skip non-free nodes if (!R[i]) continue; // Find the number of nodes intersecting Ni and every C, and // keep a track on the largest overlap Arrays.fill(intersect, 0); int largest = 0, maxValue = 0; for (int j : N.get(i)) // The k-index is to an aggregate coupled to node j for (int k : belong.get(j)) { intersect[k]++; if (intersect[k] > maxValue) { largest = k; maxValue = intersect[largest]; } } // Add the node to the proper C-set, and mark it as used // Also, check if the node actually does couple to a set if (maxValue > 0) { R[i] = false; C.get(largest).add(i); } } return C; } /** * Creates final aggregates from the remaining unallocated nodes */ private List> createFinalAggregates(List> C, List> N, boolean[] R) { for (int i = 0; i < R.length; ++i) { // Skip non-free nodes if (!R[i]) continue; // Create new aggregate from the nodes in N[i] which are free Set Cn = new HashSet(); for (int j : N.get(i)) if (R[j]) { R[j] = false; Cn.add(j); } if (!Cn.isEmpty()) C.add(Cn); } return C; } } /** * Creates interpolation (prolongation) operators using based on the * aggregates. Can optionally smooth the aggregates */ private static class Interpolator { /** * The Galerkin coarse-space operator */ private CompRowMatrix Ac; /** * The interpolation (prolongation) matrix */ private CompColMatrix I; /** * Creates the interpolation (prolongation) and Galerkin operators * * @param aggregator * Aggregates * @param A * Matrix * @param omega * Jacobi damping parameter between zero and one. If zero, no * smoothing is performed, and a faster algorithm for forming * the Galerkin operator will be used. */ public Interpolator(Aggregator aggregator, CompRowMatrix A, double omega) { List> C = aggregator.getAggregates(); List> N = aggregator.getNodeNeighborhoods(); int[] diagind = aggregator.getDiagonalIndices(); // Create the tentative prolongation, in compressed form int[] pt = createTentativeProlongation(C, A.numRows()); /* * Apply Jacobi smoothing to the prolongator */ if (omega != 0) { // Smooth the operator by a damped Jacobi method List> P = createSmoothedProlongation(C, N, A, diagind, omega, pt); // Form a compressed column storage for the operator I = createInterpolationMatrix(P, A.numRows()); // Create the Galerkin operator using a slow method Ac = createGalerkinSlow(I, A); } /* * Use the aggregates as-is */ else { // Create the Galerkin operator using a fast method Ac = createGalerkinFast(A, pt, C.size()); // Form an explicit interpolation operator I = createInterpolationMatrix(pt, C.size()); } } /** * Creates the tentative prolongation operator. Since the columns are * all disjoint, and its entries are binary, it is possible to store it * in a single array. Its length equals the number of fine nodes, and * the entries are the indices to the corresponding aggregate (C-set). */ private int[] createTentativeProlongation(List> C, int n) { int[] pt = new int[n]; Arrays.fill(pt, -1); for (int i = 0; i < C.size(); ++i) for (int j : C.get(i)) pt[j] = i; return pt; } /** * Creates the Galerkin operator using the assumption of disjoint * (non-smoothed) aggregates */ private CompRowMatrix createGalerkinFast(CompRowMatrix A, int[] pt, int c) { int n = pt.length; FlexCompRowMatrix Ac = new FlexCompRowMatrix(c, c); int[] rowptr = A.getRowPointers(); int[] colind = A.getColumnIndices(); double[] data = A.getData(); for (int i = 0; i < n; ++i) if (pt[i] != -1) for (int j = rowptr[i]; j < rowptr[i + 1]; ++j) if (pt[colind[j]] != -1) Ac.add(pt[i], pt[colind[j]], data[j]); return new CompRowMatrix(Ac); } /** * Creates the interpolation (prolongation) matrix based on the smoothed * aggregates */ private CompColMatrix createInterpolationMatrix( List> P, int n) { // Determine the sparsity pattern of I int c = P.size(); int[][] nz = new int[c][]; for (int j = 0; j < c; ++j) { Map Pj = P.get(j); nz[j] = new int[Pj.size()]; int l = 0; for (int k : Pj.keySet()) nz[j][l++] = k; } I = new CompColMatrix(n, c, nz); // Populate it with numerical entries for (int j = 0; j < c; ++j) { Map Pj = P.get(j); for (Map.Entry e : Pj.entrySet()) I.set(e.getKey(), j, e.getValue()); } return I; } /** * Creates the interpolation (prolongation) matrix based on the * non-smoothed aggregates */ private CompColMatrix createInterpolationMatrix(int[] pt, int c) { FlexCompColMatrix If = new FlexCompColMatrix(pt.length, c); for (int i = 0; i < pt.length; ++i) if (pt[i] != -1) If.set(i, pt[i], 1); return new CompColMatrix(If); } /** * Gets the interpolation (prolongation) operator */ public CompColMatrix getInterpolationOperator() { return I; } /** * Creates the smoothes interpolation (prolongation) operator by a * single sweep of the damped Jacobi method */ private List> createSmoothedProlongation( List> C, List> N, CompRowMatrix A, int[] diagind, double omega, int[] pt) { int n = A.numRows(), c = C.size(); // Allocate the interpolation (prolongation) operator // It is stored by columns, so the maps take row-indices as keys List> P = new ArrayList>( c); for (int i = 0; i < c; ++i) P.add(new HashMap()); int[] rowptr = A.getRowPointers(); int[] colind = A.getColumnIndices(); double[] data = A.getData(); double[] dot = new double[c]; // Apply the damped Jacobi smoother for (int i = 0; i < n; ++i) { if (pt[i] == -1) continue; Arrays.fill(dot, 0); Set Ni = N.get(i); // Calculate A*Pt, except for the diagonal double weakAij = 0; for (int j = rowptr[i]; j < rowptr[i + 1]; ++j) { if (pt[colind[j]] == -1) continue; double aij = data[j]; // Off-diagonal, include only strong couplings, and add the // weak couplings to the diagonal if (aij != 0 && !Ni.contains(colind[j])) { weakAij += aij; continue; } dot[pt[colind[j]]] += aij; } // Subtract the weak couplings from the diagonal part of A*Pt dot[pt[i]] -= weakAij; // Scale by omega and the inverse of the diagonal (damping) double scale = -omega / data[diagind[i]]; for (int j = 0; j < dot.length; ++j) dot[j] *= scale; // Set to (I-omega*D^{-1}*A)*Pt dot[pt[i]]++; // This has formed a whole row of P=(I-omega*D^{-1}*A)*Pt // Store the non-zeros into the sparse structure for (int j = 0; j < dot.length; ++j) if (dot[j] != 0) P.get(j).put(i, dot[j]); } return P; } /** * Creates the entries of the Galerkin operator * Ac = IT A I. This is a very * time-consuming operation */ private CompRowMatrix createGalerkinSlow(CompColMatrix I, CompRowMatrix A) { int n = I.numRows(), c = I.numColumns(); FlexCompRowMatrix Ac = new FlexCompRowMatrix(c, c); double[] aiCol = new double[n]; double[] iCol = new double[n]; DenseVector aiV = new DenseVector(aiCol, false); DenseVector iV = new DenseVector(iCol, false); double[] itaiCol = new double[c]; DenseVector itaiV = new DenseVector(itaiCol, false); int[] colptr = I.getColumnPointers(); int[] rowind = I.getRowIndices(); double[] Idata = I.getData(); for (int k = 0; k < c; ++k) { // Expand column 'k' of I to dense storage iV.zero(); for (int i = colptr[k]; i < colptr[k + 1]; ++i) iCol[rowind[i]] = Idata[i]; // Form column 'k' of A*I A.mult(iV, aiV); // Form column 'k' of I'*A*I I.transMult(aiV, itaiV); // Store non-zeros into Ac for (int i = 0; i < c; ++i) if (itaiCol[i] != 0) Ac.set(i, k, itaiCol[i]); } return new CompRowMatrix(Ac); } /** * Gets the Galerkin operator */ public CompRowMatrix getGalerkinOperator() { return Ac; } } } mtj-0.9.14/src/no/uib/cipr/matrix/sparse/SuperIterator.java0000644000000000000000000000774011027512662022302 0ustar rootroot/* * 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.sparse; import java.util.Iterator; import java.util.List; /** * An iterator over an array of iterable objects */ class SuperIterator, E> implements Iterator { private List iterable; /** * Two iterators. We need the "next" iterator so that hasNext works properly * from one iterable to the next. Using a single iterator won't do */ private Iterator current, next; private int currentIndex = 0, nextIndex = 0; /** * Recyled entry returned from next() */ private SuperIteratorEntry entry; /** * Constructor for SuperIterator * * @param iterable * Iterable objects to iterate over */ public SuperIterator(List iterable) { this.iterable = iterable; entry = new SuperIteratorEntry(); // Try to be somewhat fault tolerant if (iterable.size() == 0) { current = new DummyIterator(); next = new DummyIterator(); } else { // This moves the next pointer to a non-empty iterable next = iterable.get(nextIndex).iterator(); moveNext(); // Then we move the current pointer in the same way current = iterable.get(currentIndex).iterator(); moveCurrent(); // Finally, move the next one step ahead if possible if (next.hasNext()) next.next(); } } private void moveNext() { while (nextIndex < iterable.size() - 1 && !next.hasNext()) next = iterable.get(++nextIndex).iterator(); } private void moveCurrent() { while (currentIndex < iterable.size() - 1 && !current.hasNext()) current = iterable.get(++currentIndex).iterator(); } public boolean hasNext() { return current.hasNext() || next.hasNext(); } public SuperIteratorEntry next() { // A wrapped object containing the relevant index and data entry.update(currentIndex, current.next()); // Move current if necessary moveCurrent(); // Move the next pointer moveNext(); if (next.hasNext()) next.next(); return entry; } public void remove() { current.remove(); } /** * Dummy iterator, for degenerate cases */ private class DummyIterator implements Iterator { public boolean hasNext() { return false; } public E next() { return null; } public void remove() { throw new UnsupportedOperationException(); } } /** * Entry returned from this superiterator */ public static class SuperIteratorEntry { /** * Index of the iterator which returned this */ private int i; /** * Object returned */ private F o; void update(int i, F o) { this.i = i; this.o = o; } public int index() { return i; } public F get() { return o; } } } mtj-0.9.14/src/no/uib/cipr/matrix/sparse/SparseVector.java0000644000000000000000000002476211554357132022121 0ustar rootroot/* * 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.sparse; import java.util.Iterator; import no.uib.cipr.matrix.AbstractVector; import no.uib.cipr.matrix.DenseVector; import no.uib.cipr.matrix.Matrices; import no.uib.cipr.matrix.Vector; import no.uib.cipr.matrix.VectorEntry; /** * Sparse vector */ public class SparseVector extends AbstractVector implements ISparseVector { /** * Data */ double[] data; /** * Indices to data */ int[] index; /** * How much has been used */ int used; /** * Constructor for SparseVector. * * @param size * Size of the vector * @param nz * Initial number of non-zeros */ public SparseVector(int size, int nz) { super(size); data = new double[nz]; index = new int[nz]; } /** * Constructor for SparseVector, and copies the contents from the supplied * vector. * * @param x * Vector to copy from * @param deep * True if a deep copy is to be made. If the copy is shallow, * x must be a SparseVector */ public SparseVector(Vector x, boolean deep) { super(x); if (deep) { int nz = Matrices.cardinality(x); data = new double[nz]; index = new int[nz]; set(x); } else { SparseVector xs = (SparseVector) x; data = xs.getData(); index = xs.getIndex(); used = xs.getUsed(); } } /** * Constructor for SparseVector, and copies the contents from the supplied * vector. Zero initial pre-allocation * * @param x * Vector to copy from. A deep copy is made */ public SparseVector(Vector x) { this(x, true); } /** * Constructor for SparseVector. Zero initial pre-allocation * * @param size * Size of the vector */ public SparseVector(int size) { this(size, 0); } /** * Constructor for SparseVector * * @param size * Size of the vector * @param index * Indices of the vector * @param data * Entries of the vector * @param deep * True for a deep copy. For shallow copies, the given indices * will be used internally */ public SparseVector(int size, int[] index, double[] data, boolean deep) { super(size); if (index.length != data.length) throw new IllegalArgumentException("index.length != data.length"); if (deep) { used = index.length; this.index = index.clone(); this.data = data.clone(); } else { this.index = index; this.data = data; used = index.length; } } /** * Constructor for SparseVector * * @param size * Size of the vector * @param index * The vector indices are copies from this array * @param data * The vector entries are copies from this array */ public SparseVector(int size, int[] index, double[] data) { this(size, index, data, true); } @Override public void set(int index, double value) { check(index); // TODO: should we check against zero when setting zeros? int i = getIndex(index); data[i] = value; } @Override public void add(int index, double value) { check(index); int i = getIndex(index); data[i] += value; } @Override public double get(int index) { check(index); int in = Arrays.binarySearch(this.index, index, 0, used); if (in >= 0) return data[in]; return 0; } /** * Tries to find the index. If it is not found, a reallocation is done, and * a new index is returned. */ private int getIndex(int ind) { // Try to find column index int i = Arrays.binarySearchGreater(index, ind, 0, used); // Found if (i < used && index[i] == ind) return i; int[] newIndex = index; double[] newData = data; // Check available memory if (++used > data.length) { // If zero-length, use new length of 1, else double the bandwidth int newLength = data.length != 0 ? data.length << 1 : 1; // Copy existing data into new arrays newIndex = new int[newLength]; newData = new double[newLength]; System.arraycopy(index, 0, newIndex, 0, i); System.arraycopy(data, 0, newData, 0, i); } // All ok, make room for insertion System.arraycopy(index, i, newIndex, i + 1, used - i - 1); System.arraycopy(data, i, newData, i + 1, used - i - 1); // Put in new structure newIndex[i] = ind; newData[i] = 0.; // Update pointers index = newIndex; data = newData; // Return insertion index return i; } @Override public SparseVector copy() { return new SparseVector(this); } @Override public SparseVector zero() { java.util.Arrays.fill(data, 0); used = 0; return this; } @Override public SparseVector scale(double alpha) { // Quick return if possible if (alpha == 0) return zero(); else if (alpha == 1) return this; for (int i = 0; i < used; ++i) data[i] *= alpha; return this; } @Override public double dot(Vector y) { if (!(y instanceof DenseVector)) return super.dot(y); checkSize(y); double[] yd = ((DenseVector) y).getData(); double ret = 0; for (int i = 0; i < used; ++i) ret += data[i] * yd[index[i]]; return ret; } @Override protected double norm1() { double sum = 0; for (int i = 0; i < used; ++i) sum += Math.abs(data[i]); return sum; } @Override protected double norm2() { double norm = 0; for (int i = 0; i < used; ++i) norm += data[i] * data[i]; return Math.sqrt(norm); } @Override protected double norm2_robust() { double scale = 0, ssq = 1; for (int i = 0; i < used; ++i) { if (data[i] != 0) { double absxi = Math.abs(data[i]); if (scale < absxi) { ssq = 1 + ssq * Math.pow(scale / absxi, 2); scale = absxi; } else ssq = ssq + Math.pow(absxi / scale, 2); } } return scale * Math.sqrt(ssq); } @Override protected double normInf() { double max = 0; for (int i = 0; i < used; ++i) max = Math.max(Math.abs(data[i]), max); return max; } /** * Returns the internal data */ public double[] getData() { return data; } /** * Returns the indices */ public int[] getIndex() { if (used == index.length) return index; // could run compact, or return subarray // compact(); int [] indices = new int[used]; for (int i = 0 ; i < used; i++) { indices[i] = index[i]; } return indices; } /** * Number of entries used in the sparse structure */ public int getUsed() { return used; } /** * Compacts the vector */ public void compact() { int nz = Matrices.cardinality(this); // catches zero entries if (nz < data.length) { int[] newIndex = new int[nz]; double[] newData = new double[nz]; // Copy only non-zero entries for (int i = 0, j = 0; i < data.length; ++i) if (data[i] != 0.) { newIndex[j] = index[i]; newData[j] = data[i]; j++; } data = newData; index = newIndex; used = data.length; } } @Override public Iterator iterator() { return new SparseVectorIterator(); } @Override public Vector set(Vector y) { if (!(y instanceof SparseVector)) return super.set(y); checkSize(y); SparseVector yc = (SparseVector) y; if (yc.index.length != index.length) { data = new double[yc.data.length]; index = new int[yc.data.length]; } System.arraycopy(yc.data, 0, data, 0, data.length); System.arraycopy(yc.index, 0, index, 0, index.length); used = yc.used; return this; } /** * Iterator over a sparse vector */ private class SparseVectorIterator implements Iterator { private int cursor; private final SparseVectorEntry entry = new SparseVectorEntry(); public boolean hasNext() { return cursor < used; } public VectorEntry next() { entry.update(cursor); cursor++; return entry; } public void remove() { entry.set(0); } } /** * Entry of a sparse vector */ private class SparseVectorEntry implements VectorEntry { private int cursor; public void update(int cursor) { this.cursor = cursor; } public int index() { return index[cursor]; } public double get() { return data[cursor]; } public void set(double value) { data[cursor] = value; } } } mtj-0.9.14/src/no/uib/cipr/matrix/sparse/Preconditioner.java0000644000000000000000000000373611027512662022457 0ustar rootroot/* * 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.sparse; import no.uib.cipr.matrix.Matrix; import no.uib.cipr.matrix.Vector; /** * Preconditioner interface. Before a preconditioner is used, * setMatrix must be called */ public interface Preconditioner { /** * Solves the approximate problem with the given right hand side. Result is * stored in given solution vector * * @param b * Right hand side of problem * @param x * Result is stored here * @return x */ Vector apply(Vector b, Vector x); /** * Solves the approximate transpose problem with the given right hand side. * Result is stored in given solution vector * * @param b * Right hand side of problem * @param x * Result is stored here * @return x */ Vector transApply(Vector b, Vector x); /** * Sets the operator matrix for the preconditioner. This method must be * called before a preconditioner is used by an iterative solver * * @param A * Matrix to setup the preconditioner for. Not modified */ void setMatrix(Matrix A); } mtj-0.9.14/src/no/uib/cipr/matrix/sparse/CompDiagMatrix.java0000644000000000000000000003244411027512662022341 0ustar rootroot/* * 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.sparse; import java.io.IOException; import java.util.Arrays; import java.util.Iterator; import java.util.Set; import java.util.TreeSet; import no.uib.cipr.matrix.AbstractMatrix; import no.uib.cipr.matrix.DenseVector; import no.uib.cipr.matrix.Matrix; import no.uib.cipr.matrix.MatrixEntry; import no.uib.cipr.matrix.Vector; import no.uib.cipr.matrix.io.MatrixInfo; import no.uib.cipr.matrix.io.MatrixSize; import no.uib.cipr.matrix.io.MatrixVectorReader; /** * Compressed diagonal storage (CDS) matrix */ public class CompDiagMatrix extends AbstractMatrix { /** * The diagonals */ double[][] diag; /** * Indices to the start of the diagonal, relative to the main diagonal. * Positive means the number of diagonals shifted up, while negative is the * number of diagonals shifted down */ int[] ind; /** * Constructor for CompDiagMatrix * * @param r * Reader to get sparse matrix from */ public CompDiagMatrix(MatrixVectorReader r) throws IOException { // Start with a zero-sized matrix super(0, 0); // Get matrix information. Use the header if present, else use a safe // default MatrixInfo info = null; if (r.hasInfo()) info = r.readMatrixInfo(); else info = new MatrixInfo(true, MatrixInfo.MatrixField.Real, MatrixInfo.MatrixSymmetry.General); MatrixSize size = r.readMatrixSize(info); // Resize the matrix to correct size numRows = size.numRows(); numColumns = size.numColumns(); // Check that the matrix is in an acceptable format if (info.isPattern()) throw new UnsupportedOperationException( "Pattern matrices are not supported"); if (info.isDense()) throw new UnsupportedOperationException( "Dense matrices are not supported"); if (info.isComplex()) throw new UnsupportedOperationException( "Complex matrices are not supported"); // Start reading entries int[] row = new int[size.numEntries()], column = new int[size .numEntries()]; double[] entry = new double[size.numEntries()]; r.readCoordinate(row, column, entry); // Shift the indices from 1 based to 0 based r.add(-1, row); r.add(-1, column); // Find all the diagonals so that we can preallocate Set diags = new TreeSet(); for (int i = 0; i < size.numEntries(); ++i) diags.add(getDiagonal(row[i], column[i])); if (info.isSymmetric() || info.isSkewSymmetric()) for (int i = 0; i < size.numEntries(); ++i) if (row[i] != column[i]) diags.add(getDiagonal(column[i], row[i])); // Convert into an integer array int[] ind = new int[diags.size()]; { Integer[] ints = new Integer[diags.size()]; diags.toArray(ints); for (int i = 0; i < diags.size(); ++i) ind[i] = ints[i]; } // Create the structure with preallocation construct(ind); // Insert the entries for (int i = 0; i < size.numEntries(); ++i) set(row[i], column[i], entry[i]); // Put in missing entries from symmetry or skew symmetry if (info.isSymmetric()) for (int i = 0; i < size.numEntries(); ++i) { if (row[i] != column[i]) set(column[i], row[i], entry[i]); } else if (info.isSkewSymmetric()) for (int i = 0; i < size.numEntries(); ++i) { if (row[i] != column[i]) set(column[i], row[i], -entry[i]); } } /** * Creates a new sparse matrix with the given diagonals preallocated. A * negative index is a subdiagonal, positive is superdiagonal */ public CompDiagMatrix(int numRows, int numColumns, int[] diagonal) { super(numRows, numColumns); construct(diagonal); } private void construct(int[] diagonal) { diag = new double[diagonal.length][]; ind = new int[diagonal.length]; // Keep the diagonal indices sorted int[] sortedDiagonal = new int[diagonal.length]; System.arraycopy(diagonal, 0, sortedDiagonal, 0, diagonal.length); Arrays.sort(sortedDiagonal); for (int i = 0; i < diagonal.length; ++i) { ind[i] = sortedDiagonal[i]; diag[i] = new double[getDiagSize(sortedDiagonal[i])]; } } /** * Creates a new sparse matrix without preallocation */ public CompDiagMatrix(int numRows, int numColumns) { this(numRows, numColumns, new int[0]); } /** * Creates a new sparse matrix copied from the given matrix. Can take a deep * copy or a shallow copy. For the latter, the supplied matrix must be a * CompDiagMatrix. Preallocation is also possible, but is only used for the * deep copy. */ public CompDiagMatrix(Matrix A, int[] diagonal, boolean deep) { super(A); if (deep) { construct(diagonal); set(A); } else { CompDiagMatrix Ac = (CompDiagMatrix) A; diag = Ac.getDiagonals(); ind = Ac.getIndex(); } } /** * Creates a new sparse matrix copied from the given matrix. Takes a deep * copy, with possibility to specify preallocation */ public CompDiagMatrix(Matrix A, int[] diagonal) { this(A, diagonal, true); } /** * Creates a new sparse matrix copied from the given matrix. Can take a deep * copy or a shallow copy. For the latter, the supplied matrix must be a * CompDiagMatrix. No preallocation is done */ public CompDiagMatrix(Matrix A, boolean deep) { this(A, new int[0], deep); } /** * Creates a new sparse matrix copied from the given matrix. Takes a deep * copy without preallocation */ public CompDiagMatrix(Matrix A) { this(A, new int[0], true); } /** * Returns the internal diagonal storage */ public double[][] getDiagonals() { return diag; } /** * Returns the diagonal offsets */ public int[] getIndex() { return ind; } @Override public void add(int row, int column, double value) { check(row, column); int diagonal = getCompDiagIndex(row, column); diag[diagonal][getOnDiagIndex(row, column)] += value; } @Override public double get(int row, int column) { check(row, column); int diagonal = Arrays.binarySearch(ind, getDiagonal(row, column)); if (diagonal >= 0) return diag[diagonal][getOnDiagIndex(row, column)]; else return 0; } @Override public void set(int row, int column, double value) { check(row, column); int diagonal = getCompDiagIndex(row, column); diag[diagonal][getOnDiagIndex(row, column)] = value; } private int getDiagonal(int row, int column) { return column - row; } private int getOnDiagIndex(int row, int column) { return row > column ? column : row; } private int getCompDiagIndex(int row, int column) { int diagonal = getDiagonal(row, column); // Check if the diagonal is already present int index = no.uib.cipr.matrix.sparse.Arrays.binarySearchGreater(ind, diagonal); if (index < ind.length && ind[index] == diagonal) return index; // Need to allocate new diagonal. Get the diagonal size int size = getDiagSize(diagonal); // Allocate new primary structure double[] newDiag = new double[size]; double[][] newDiagArray = new double[diag.length + 1][]; int[] newInd = new int[ind.length + 1]; // Move data from the old into the new structure System.arraycopy(ind, 0, newInd, 0, index); System.arraycopy(ind, index, newInd, index + 1, ind.length - index); for (int i = 0; i < index; ++i) newDiagArray[i] = diag[i]; for (int i = index; i < diag.length; ++i) newDiagArray[i + 1] = diag[i]; newInd[index] = diagonal; newDiagArray[index] = newDiag; // Update pointers ind = newInd; diag = newDiagArray; return index; } /** * Finds the size of the requested diagonal to be allocated */ private int getDiagSize(int diagonal) { if (diagonal < 0) return Math.min(numRows + diagonal, numColumns); else return Math.min(numRows, numColumns - diagonal); } @Override public Matrix copy() { return new CompDiagMatrix(this, ind); } @Override public Matrix zero() { for (int i = 0; i < diag.length; ++i) Arrays.fill(diag[i], 0); return this; } @Override public Vector mult(Vector x, Vector y) { if (!(x instanceof DenseVector) || !(y instanceof DenseVector)) return super.mult(x, y); checkMultAdd(x, y); double[] xd = ((DenseVector) x).getData(); double[] yd = ((DenseVector) y).getData(); y.zero(); for (int i = 0; i < ind.length; ++i) { int row = ind[i] < 0 ? -ind[i] : 0; int column = ind[i] > 0 ? ind[i] : 0; double[] locDiag = diag[i]; for (int j = 0; j < locDiag.length; ++j, ++row, ++column) yd[row] += locDiag[j] * xd[column]; } return y; } @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(); double[] yd = ((DenseVector) y).getData(); for (int i = 0; i < ind.length; ++i) { int row = ind[i] < 0 ? -ind[i] : 0; int column = ind[i] > 0 ? ind[i] : 0; double[] locDiag = diag[i]; for (int j = 0; j < locDiag.length; ++j, ++row, ++column) yd[row] += alpha * locDiag[j] * xd[column]; } 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(); double[] yd = ((DenseVector) y).getData(); for (int i = 0; i < ind.length; ++i) { int row = ind[i] < 0 ? -ind[i] : 0; int column = ind[i] > 0 ? ind[i] : 0; double[] locDiag = diag[i]; for (int j = 0; j < locDiag.length; ++j, ++row, ++column) yd[column] += alpha * locDiag[j] * xd[row]; } return y; } @Override public Iterator iterator() { return new CompDiagMatrixIterator(); } /** * Iterator over a compressed diagonal matrix */ private class CompDiagMatrixIterator implements Iterator { private int diagonal, index; private CompDiagMatrixEntry entry = new CompDiagMatrixEntry(); public boolean hasNext() { return diagonal < diag.length; } public MatrixEntry next() { entry.update(diagonal, index); // Move along current diagonal if (index < diag[diagonal].length - 1) index++; // Move to the next diagonal else { diagonal++; index = 0; } return entry; } public void remove() { entry.set(0); } } /** * Entry of a compressed diagonal matrix */ private class CompDiagMatrixEntry implements MatrixEntry { private int diagonal, index; public void update(int diagonal, int index) { this.diagonal = diagonal; this.index = index; } public int row() { return index + (ind[diagonal] < 0 ? -ind[diagonal] : 0); } public int column() { return index + (ind[diagonal] > 0 ? ind[diagonal] : 0); } public double get() { return diag[diagonal][index]; } public void set(double value) { diag[diagonal][index] = value; } } } mtj-0.9.14/src/no/uib/cipr/matrix/sparse/NoIterationReporter.java0000644000000000000000000000221011027512662023433 0ustar rootroot/* * 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.sparse; import no.uib.cipr.matrix.Vector; /** * An iteration reporter which does nothing. */ public class NoIterationReporter implements IterationReporter { public void monitor(double r, int i) { // void } public void monitor(double r, Vector x, int i) { // void } } mtj-0.9.14/src/no/uib/cipr/matrix/sparse/UpperCompRowMatrix.java0000644000000000000000000000514611027512662023257 0ustar rootroot/* * 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.sparse; import no.uib.cipr.matrix.AbstractMatrix; import no.uib.cipr.matrix.DenseVector; import no.uib.cipr.matrix.Vector; /** * Upper triangular CRS matrix. Only used for triangular solves */ class UpperCompRowMatrix extends AbstractMatrix { private int[] rowptr; private int[] colind; private double[] data; private int[] diagind; public UpperCompRowMatrix(CompRowMatrix LU, int[] diagind) { super(LU); rowptr = LU.getRowPointers(); colind = LU.getColumnIndices(); data = LU.getData(); this.diagind = diagind; } @Override public Vector solve(Vector b, Vector x) { if (!(b instanceof DenseVector) || !(x instanceof DenseVector)) return super.solve(b, x); double[] bd = ((DenseVector) b).getData(); double[] xd = ((DenseVector) x).getData(); for (int i = numRows - 1; i >= 0; --i) { // xi = (bi - sum[j>i] Uij * xj) / Uii double sum = 0; for (int j = diagind[i] + 1; j < rowptr[i + 1]; ++j) sum += data[j] * xd[colind[j]]; xd[i] = (bd[i] - sum) / data[diagind[i]]; } return x; } @Override public Vector transSolve(Vector b, Vector x) { if (!(x instanceof DenseVector)) return super.transSolve(b, x); x.set(b); double[] xd = ((DenseVector) x).getData(); for (int i = 0; i < numRows; ++i) { // Solve for the current entry xd[i] /= data[diagind[i]]; // Move this known solution over to the right hand side for the // remaining equations for (int j = diagind[i] + 1; j < rowptr[i + 1]; ++j) xd[colind[j]] -= data[j] * xd[i]; } return x; } } mtj-0.9.14/src/no/uib/cipr/matrix/sparse/ICC.java0000644000000000000000000001071711027512662020066 0ustar rootroot/* * 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.sparse; import java.util.Arrays; import no.uib.cipr.matrix.DenseVector; import no.uib.cipr.matrix.Matrix; import no.uib.cipr.matrix.Vector; /** * Incomplete Cholesky preconditioner without fill-in using a compressed row * matrix as internal storage */ public class ICC implements Preconditioner { /** * Factorisation matrix */ private final CompRowMatrix R; /** * Triangular view onto R for solution purposes */ private Matrix Rt; /** * Temporary vector for solving the factorised system */ private final Vector y; /** * Sets up the ICC preconditioner * * @param R * Matrix to use internally. For best performance, its non-zero * pattern must conform to that of the system matrix */ public ICC(CompRowMatrix R) { if (!R.isSquare()) throw new IllegalArgumentException( "ICC only applies to square matrices"); this.R = R; int n = R.numRows(); y = new DenseVector(n); } public Vector apply(Vector b, Vector x) { // R'y = b, y = R'\b Rt.transSolve(b, y); // Rx = R'\b = y return Rt.solve(y, x); } public Vector transApply(Vector b, Vector x) { return apply(b, x); } public void setMatrix(Matrix A) { R.set(A); factor(); } private void factor() { int n = R.numRows(); // Internal CRS matrix storage int[] colind = R.getColumnIndices(); int[] rowptr = R.getRowPointers(); double[] data = R.getData(); // Temporary storage of a dense row double[] Rk = new double[n]; // Find the indices to the diagonal entries int[] diagind = findDiagonalIndices(n, colind, rowptr); // Go down along the main diagonal for (int k = 0; k < n; ++k) { // Expand current row to dense storage Arrays.fill(Rk, 0); for (int i = rowptr[k]; i < rowptr[k + 1]; ++i) Rk[colind[i]] = data[i]; for (int i = 0; i < k; ++i) { // Get the current diagonal entry double Rii = data[diagind[i]]; if (Rii == 0) throw new RuntimeException("Zero pivot encountered on row " + (i + 1) + " during ICC process"); // Elimination factor double Rki = Rk[i] / Rii; if (Rki == 0) continue; // Traverse the sparse row i, reducing on row k for (int j = diagind[i] + 1; j < rowptr[i + 1]; ++j) Rk[colind[j]] -= Rki * data[j]; } // Store the row back into the factorisation matrix if (Rk[k] == 0) throw new RuntimeException( "Zero diagonal entry encountered on row " + (k + 1) + " during ICC process"); double sqRkk = Math.sqrt(Rk[k]); for (int i = diagind[k]; i < rowptr[k + 1]; ++i) data[i] = Rk[colind[i]] / sqRkk; } Rt = new UpperCompRowMatrix(R, diagind); } private int[] findDiagonalIndices(int m, int[] colind, int[] rowptr) { int[] diagind = new int[m]; for (int k = 0; k < m; ++k) { diagind[k] = no.uib.cipr.matrix.sparse.Arrays.binarySearch(colind, k, rowptr[k], rowptr[k + 1]); if (diagind[k] < 0) throw new RuntimeException("Missing diagonal entry on row " + (k + 1)); } return diagind; } } mtj-0.9.14/src/no/uib/cipr/matrix/sparse/ISparseVector.java0000644000000000000000000000067511051614112022211 0ustar rootroot/** * May 21, 2007 * @author Samuel Halliday, ThinkTank Maths Limited * Copyright ThinkTank Maths Limited 2007 */ package no.uib.cipr.matrix.sparse; import no.uib.cipr.matrix.Vector; /** * @author Samuel Halliday, ThinkTank Maths Limited */ public interface ISparseVector extends Vector { /** * Returns the indices */ public int[] getIndex(); /** * Number of entries used in the sparse structure */ public int getUsed(); } mtj-0.9.14/src/no/uib/cipr/matrix/sparse/IterativeSolver.java0000644000000000000000000000412011027512662022606 0ustar rootroot/* * 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.sparse; import no.uib.cipr.matrix.Matrix; import no.uib.cipr.matrix.Vector; /** * Iterative linear solver. Solves Ax=b for x, * and it supports preconditioning and convergence monitoring. */ public interface IterativeSolver { /** * Solves the given problem, writing result into the vector. * * @param A * Matrix of the problem * @param b * Right hand side * @param x * Solution is stored here. Also used as initial guess * @return The solution vector x */ Vector solve(Matrix A, Vector b, Vector x) throws IterativeSolverNotConvergedException; /** * Sets preconditioner * * @param M * Preconditioner to use */ void setPreconditioner(Preconditioner M); /** * Gets preconditioner * * @return Current preconditioner */ Preconditioner getPreconditioner(); /** * Sets iteration monitor * * @param iter * Iteration monitor */ void setIterationMonitor(IterationMonitor iter); /** * Gets the iteration monitor * * @return Current iteration monitor */ IterationMonitor getIterationMonitor(); } mtj-0.9.14/src/no/uib/cipr/matrix/sparse/ILUT.java0000644000000000000000000003203411027512662020241 0ustar rootroot/* * 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.sparse; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import no.uib.cipr.matrix.AbstractMatrix; import no.uib.cipr.matrix.DenseVector; import no.uib.cipr.matrix.Matrix; import no.uib.cipr.matrix.Vector; import no.uib.cipr.matrix.VectorEntry; /** * ILU preconditioner with fill-in. Uses the dual threshold approach of Saad. */ public class ILUT implements Preconditioner { /** * Factorisation matrix */ private final FlexCompRowMatrix LU; /** * The L and U factors */ private Matrix L, U; /** * Temporary vector for solving the factorised system */ private final Vector y; /** * Drop-tolerance */ private final double tau; /** * Diagonal indices */ private final int[] diagind; /** * Stores entries in the lower and upper part of the matrix. Used by the * dropping rule to determine the largest entries in the two parts of the * matrix */ private final List lower, upper; /** * Number of additional entries to keep in the lower and upper part of the * factored matrix. The entries of the original matrix are always kept, * unless they numerically too small */ private final int p; /** * Sets up the preconditioner for the given matrix * * @param LU * Matrix to use internally. For best performance, its non-zero * pattern should conform to that of the system matrix * @param tau * Drop tolerance * @param p * Number of entries to keep on each row in of the factored * matrix. This is in addition to the entries of the original * matrix */ public ILUT(FlexCompRowMatrix LU, double tau, int p) { if (!LU.isSquare()) throw new IllegalArgumentException( "ILU only applies to square matrices"); this.LU = LU; this.tau = tau; this.p = p; int n = LU.numRows(); lower = new ArrayList(n); upper = new ArrayList(n); y = new DenseVector(n); diagind = new int[n]; } /** * Sets up the preconditioner for the given matrix. Uses a drop-tolerance of * 10-6, and keeps 50 entries on each row, including the main * diagonal and any previous entries in the matrix structure * * @param LU * Matrix to use internally. For best performance, its non-zero * pattern should conform to that of the system matrix */ public ILUT(FlexCompRowMatrix LU) { this(LU, 1e-6, 25); } public Vector apply(Vector b, Vector x) { // Ly = b, y = L\b L.solve(b, y); // Ux = L\b = y return U.solve(y, x); } public Vector transApply(Vector b, Vector x) { // U'y = b, y = U'\b U.transSolve(b, y); // L'x = U'\b = y return L.transSolve(y, x); } public void setMatrix(Matrix A) { LU.set(A); LU.compact(); factor(); } private void factor() { int n = LU.numRows(); double[] LUi = new double[n]; // Find the indices to the diagonal entries for (int k = 0; k < n; ++k) { SparseVector row = LU.getRow(k); diagind[k] = findDiagonalIndex(row, k); if (diagind[k] < 0) throw new RuntimeException("Missing diagonal entry on row " + (k + 1)); } for (int i = 1; i < n; ++i) { // Get row i SparseVector rowi = LU.getRow(i); // Drop tolerance on current row double taui = rowi.norm(Vector.Norm.Two) * tau; // Store in dense format scatter(rowi, LUi); for (int k = 0; k < i; ++k) { // Get row k SparseVector rowk = LU.getRow(k); int[] rowIndex = rowk.getIndex(); int rowUsed = rowk.getUsed(); double[] rowData = rowk.getData(); if (rowData[diagind[k]] == 0) throw new RuntimeException("Zero diagonal entry on row " + (k + 1) + " during ILU process"); double LUik = LUi[k] / rowData[diagind[k]]; // Check for small elimination entry if (Math.abs(LUik) <= taui) continue; // Traverse the sparse row k, reducing row i for (int j = diagind[k] + 1; j < rowUsed; ++j) LUi[rowIndex[j]] -= LUik * rowData[j]; // The above has overwritten LUik, so remedy that LUi[k] = LUik; } // Store back into the LU matrix, dropping as needed gather(LUi, rowi, taui, i); // Update diagonal index on row i if it is outdated if (rowi.getIndex()[diagind[i]] != i) { diagind[i] = findDiagonalIndex(rowi, i); if (diagind[i] < 0) throw new RuntimeException("Missing diagonal entry on row " + (i + 1) + " during ILU process"); } } L = new UnitLowerFlexCompRowMatrix(LU, diagind); U = new UpperFlexCompRowMatrix(LU, diagind); } private int findDiagonalIndex(SparseVector v, int k) { return no.uib.cipr.matrix.sparse.Arrays.binarySearch(v.getIndex(), k, 0, v.getUsed()); } /** * Copies the sparse vector into a dense array */ private void scatter(SparseVector v, double[] z) { int[] index = v.getIndex(); int used = v.getUsed(); double[] data = v.getData(); Arrays.fill(z, 0); for (int i = 0; i < used; ++i) z[index[i]] = data[i]; } /** * Copies the dense array back into the sparse vector, applying a numerical * dropping rule and keeping only a given number of entries */ private void gather(double[] z, SparseVector v, double taui, int d) { // Number of entries in the lower and upper part of the original matrix int nl = 0, nu = 0; for (VectorEntry e : v) { if (e.index() < d) nl++; else if (e.index() > d) nu++; } v.zero(); // Entries in the L part of the vector lower.clear(); for (int i = 0; i < d; ++i) if (Math.abs(z[i]) > taui) lower.add(new IntDoubleEntry(i, z[i])); // Entries in the U part of the vector upper.clear(); for (int i = d + 1; i < z.length; ++i) if (Math.abs(z[i]) > taui) upper.add(new IntDoubleEntry(i, z[i])); // Sort in descending order Collections.sort(lower); Collections.sort(upper); // Always keep the diagonal v.set(d, z[d]); // Keep at most nl+p lower entries for (int i = 0; i < Math.min(nl + p, lower.size()); ++i) { IntDoubleEntry e = lower.get(i); v.set(e.index, e.value); } // Keep at most nu+p upper entries for (int i = 0; i < Math.min(nu + p, upper.size()); ++i) { IntDoubleEntry e = upper.get(i); v.set(e.index, e.value); } } /** * Stores an integer/value pair, sorted by descending order according to the * value */ private static class IntDoubleEntry implements Comparable { public int index; public double value; public IntDoubleEntry(int index, double value) { this.index = index; this.value = value; } public int compareTo(IntDoubleEntry o) { // Descending order, so keep the largest entries first if (Math.abs(value) < Math.abs(o.value)) return 1; else if (Math.abs(value) == Math.abs(o.value)) return 0; else return -1; } @Override public String toString() { return "(" + index + "=" + value + ")"; } } /** * Unit lower triangular flex-CRS matrix. Only used for triangular solves */ private static class UnitLowerFlexCompRowMatrix extends AbstractMatrix { private final FlexCompRowMatrix LU; private final int[] diagind; public UnitLowerFlexCompRowMatrix(FlexCompRowMatrix LU, int[] diagind) { super(LU); this.LU = LU; this.diagind = diagind; } @Override public Vector solve(Vector b, Vector x) { if (!(b instanceof DenseVector) || !(x instanceof DenseVector)) return super.solve(b, x); double[] bd = ((DenseVector) b).getData(); double[] xd = ((DenseVector) x).getData(); for (int i = 0; i < numRows; ++i) { // Get row i SparseVector row = LU.getRow(i); int[] index = row.getIndex(); double[] data = row.getData(); // xi = bi - sum[j= 0; --i) { // Get row i SparseVector row = LU.getRow(i); int[] index = row.getIndex(); double[] data = row.getData(); // At this stage, x[i] is known, so move it over to the right // hand side for the remaining equations for (int j = 0; j < diagind[i]; ++j) xd[index[j]] -= data[j] * xd[i]; } return x; } } /** * Upper triangular flex-CRS matrix. Only used for triangular solves */ private static class UpperFlexCompRowMatrix extends AbstractMatrix { private final FlexCompRowMatrix LU; private final int[] diagind; public UpperFlexCompRowMatrix(FlexCompRowMatrix LU, int[] diagind) { super(LU); this.LU = LU; this.diagind = diagind; } @Override public Vector solve(Vector b, Vector x) { if (!(b instanceof DenseVector) || !(x instanceof DenseVector)) return super.solve(b, x); double[] bd = ((DenseVector) b).getData(); double[] xd = ((DenseVector) x).getData(); for (int i = numRows - 1; i >= 0; --i) { // Get row i SparseVector row = LU.getRow(i); int[] index = row.getIndex(); int used = row.getUsed(); double[] data = row.getData(); // xi = (bi - sum[j>i] Uij * xj) / Uii double sum = 0; for (int j = diagind[i] + 1; j < used; ++j) sum += data[j] * xd[index[j]]; xd[i] = (bd[i] - sum) / data[diagind[i]]; } return x; } @Override public Vector transSolve(Vector b, Vector x) { if (!(x instanceof DenseVector)) return super.transSolve(b, x); x.set(b); double[] xd = ((DenseVector) x).getData(); for (int i = 0; i < numRows; ++i) { // Get row i SparseVector row = LU.getRow(i); int[] index = row.getIndex(); int used = row.getUsed(); double[] data = row.getData(); // Solve for the current entry xd[i] /= data[diagind[i]]; // Move this known solution over to the right hand side for the // remaining equations for (int j = diagind[i] + 1; j < used; ++j) xd[index[j]] -= data[j] * xd[i]; } return x; } } } mtj-0.9.14/src/no/uib/cipr/matrix/sparse/SSOR.java0000644000000000000000000001406611027512662020257 0ustar rootroot/* * 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.sparse; import no.uib.cipr.matrix.DenseVector; import no.uib.cipr.matrix.Matrix; import no.uib.cipr.matrix.Vector; /** * SSOR preconditioner. Uses symmetrical sucessive overrelaxation as a * preconditioner. Meant for symmetrical, positive definite matrices. For best * performance, omega must be carefully chosen (between 0 and 2). */ public class SSOR implements Preconditioner { /** * Overrelaxation parameter for the forward sweep */ private double omegaF; /** * Overrelaxation parameter for the backwards sweep */ private double omegaR; /** * Holds a copy of the matrix A in the compressed row format */ private final CompRowMatrix F; /** * Indices to the diagonal entries of the matrix */ private final int[] diagind; /** * Temporary vector for holding the half-step state */ private final double[] xx; /** * True if the reverse (backward) sweep is to be done. Without this, the * method is SOR instead of SSOR */ private final boolean reverse; /** * Constructor for SSOR * * @param F * Matrix to use internally. It will not be modified, thus the * system matrix may be passed * @param reverse * True to perform a reverse sweep as well as the forward sweep. * If false, this preconditioner becomes the SOR method instead * @param omegaF * Overrelaxation parameter for the forward sweep. Between 0 and * 2. * @param omegaR * Overrelaxation parameter for the backwards sweep. Between 0 * and 2. */ public SSOR(CompRowMatrix F, boolean reverse, double omegaF, double omegaR) { if (!F.isSquare()) throw new IllegalArgumentException( "SSOR only applies to square matrices"); this.F = F; this.reverse = reverse; setOmega(omegaF, omegaR); int n = F.numRows(); diagind = new int[n]; xx = new double[n]; } /** * Constructor for SSOR. Uses omega=1 with a backwards sweep * * @param F * Matrix to use internally. It will not be modified, thus the * system matrix may be passed */ public SSOR(CompRowMatrix F) { this(F, true, 1, 1); } /** * Sets the overrelaxation parameters * * @param omegaF * Overrelaxation parameter for the forward sweep. Between 0 and * 2. * @param omegaR * Overrelaxation parameter for the backwards sweep. Between 0 * and 2. */ public void setOmega(double omegaF, double omegaR) { if (omegaF < 0 || omegaF > 2) throw new IllegalArgumentException("omegaF must be between 0 and 2"); if (omegaR < 0 || omegaR > 2) throw new IllegalArgumentException("omegaR must be between 0 and 2"); this.omegaF = omegaF; this.omegaR = omegaR; } public void setMatrix(Matrix A) { F.set(A); int n = F.numRows(); int[] rowptr = F.getRowPointers(); int[] colind = F.getColumnIndices(); // Find the indices to the diagonal entries for (int k = 0; k < n; ++k) { diagind[k] = Arrays.binarySearch(colind, k, rowptr[k], rowptr[k + 1]); if (diagind[k] < 0) throw new RuntimeException("Missing diagonal on row " + (k + 1)); } } public Vector apply(Vector b, Vector x) { if (!(b instanceof DenseVector) || !(x instanceof DenseVector)) throw new IllegalArgumentException("Vectors must be a DenseVectors"); int[] rowptr = F.getRowPointers(); int[] colind = F.getColumnIndices(); double[] data = F.getData(); double[] bd = ((DenseVector) b).getData(); double[] xd = ((DenseVector) x).getData(); int n = F.numRows(); System.arraycopy(xd, 0, xx, 0, n); // Forward sweep (xd oldest, xx halfiterate) for (int i = 0; i < n; ++i) { double sigma = 0; for (int j = rowptr[i]; j < diagind[i]; ++j) sigma += data[j] * xx[colind[j]]; for (int j = diagind[i] + 1; j < rowptr[i + 1]; ++j) sigma += data[j] * xd[colind[j]]; sigma = (bd[i] - sigma) / data[diagind[i]]; xx[i] = xd[i] + omegaF * (sigma - xd[i]); } // Stop here if the reverse sweep was not requested if (!reverse) { System.arraycopy(xx, 0, xd, 0, n); return x; } // Backward sweep (xx oldest, xd halfiterate) for (int i = n - 1; i >= 0; --i) { double sigma = 0; for (int j = rowptr[i]; j < diagind[i]; ++j) sigma += data[j] * xx[colind[j]]; for (int j = diagind[i] + 1; j < rowptr[i + 1]; ++j) sigma += data[j] * xd[colind[j]]; sigma = (bd[i] - sigma) / data[diagind[i]]; xd[i] = xx[i] + omegaR * (sigma - xx[i]); } return x; } public Vector transApply(Vector b, Vector x) { // Assume a symmetric matrix return apply(b, x); } } mtj-0.9.14/src/no/uib/cipr/matrix/sparse/BiCG.java0000644000000000000000000000622511027512662020233 0ustar rootroot/* * 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 */ /* * Derived from public domain software at http://www.netlib.org/templates */ package no.uib.cipr.matrix.sparse; import no.uib.cipr.matrix.Matrix; import no.uib.cipr.matrix.NotConvergedException; import no.uib.cipr.matrix.Vector; /** * BiCG solver. BiCG solves the unsymmetric linear system Ax = b * using the Preconditioned BiConjugate Gradient method. * * @author Templates */ public class BiCG extends AbstractIterativeSolver { /** * Vectors for use in the iterative solution process */ private Vector z, p, q, r, ztilde, ptilde, qtilde, rtilde; /** * Constructor for BiCG. Uses the given vector as template for creating * scratch vectors. Typically, the solution or the right hand side vector * can be passed, and the template is not modified * * @param template * Vector to use as template for the work vectors needed in the * solution process */ public BiCG(Vector template) { z = template.copy(); p = template.copy(); q = template.copy(); r = template.copy(); ztilde = template.copy(); ptilde = template.copy(); qtilde = template.copy(); rtilde = template.copy(); } public Vector solve(Matrix A, Vector b, Vector x) throws IterativeSolverNotConvergedException { checkSizes(A, b, x); double rho_1 = 1, rho_2 = 1, alpha = 1, beta = 1; A.multAdd(-1, x, r.set(b)); rtilde.set(r); for (iter.setFirst(); !iter.converged(r, x); iter.next()) { M.apply(r, z); M.transApply(rtilde, ztilde); rho_1 = z.dot(rtilde); if (rho_1 == 0.) throw new IterativeSolverNotConvergedException( NotConvergedException.Reason.Breakdown, "rho", iter); if (iter.isFirst()) { p.set(z); ptilde.set(ztilde); } else { beta = rho_1 / rho_2; p.scale(beta).add(z); ptilde.scale(beta).add(ztilde); } A.mult(p, q); A.transMult(ptilde, qtilde); alpha = rho_1 / ptilde.dot(q); x.add(alpha, p); r.add(-alpha, q); rtilde.add(-alpha, qtilde); rho_2 = rho_1; } return x; } }mtj-0.9.14/src/no/uib/cipr/matrix/sparse/IterativeSolverNotConvergedException.java0000644000000000000000000000516011027512662027010 0ustar rootroot/* * 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.sparse; import no.uib.cipr.matrix.NotConvergedException; /** * Exception for lack of convergence in a linear problem. Contains the final * computed residual. */ public class IterativeSolverNotConvergedException extends NotConvergedException { private static final long serialVersionUID = 5354102050137093202L; /** * Iteration count when this exception was thrown */ private int iterations; /** * Final residual */ private double r; /** * Constructor for IterativeSolverNotConvergedException * * @param reason * Reason for this exception * @param message * A more detailed message * @param iter * Associated iteration monitor, for extracting residual and * iteration number */ public IterativeSolverNotConvergedException(Reason reason, String message, IterationMonitor iter) { super(reason, message); this.r = iter.residual(); this.iterations = iter.iterations(); } /** * Constructor for IterativeSolverNotConvergedException * * @param reason * Reason for this exception * @param iter * Associated iteration monitor, for extracting residual and * iteration number */ public IterativeSolverNotConvergedException(Reason reason, IterationMonitor iter) { super(reason); this.r = iter.residual(); this.iterations = iter.iterations(); } /** * Returns final computed residual */ public double getResidual() { return r; } /** * Gets the number of iterations used when this exception was thrown */ public int getIterations() { return iterations; } } mtj-0.9.14/src/no/uib/cipr/matrix/sparse/OutputIterationReporter.java0000644000000000000000000000340511027512662024366 0ustar rootroot/* * 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.sparse; import java.io.OutputStream; import java.io.PrintWriter; import no.uib.cipr.matrix.Vector; /** * Outputs iteration information to an output stream. */ public class OutputIterationReporter implements IterationReporter { /** * Platform-dependent output */ private PrintWriter out; /** * Constructor for OutputIterationReporter * * @param out * Writes iteration count and current residual here */ public OutputIterationReporter(OutputStream out) { this.out = new PrintWriter(out, true); } /** * Constructor for OutputIterationReporter, using System.err. */ public OutputIterationReporter() { this(System.err); } public void monitor(double r, int i) { out.format("%10d % .12e\n", i, r); out.flush(); } public void monitor(double r, Vector x, int i) { monitor(r, i); } } mtj-0.9.14/src/no/uib/cipr/matrix/sparse/DiagonalPreconditioner.java0000644000000000000000000000461211027512662024110 0ustar rootroot/* * 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.sparse; import no.uib.cipr.matrix.DenseVector; import no.uib.cipr.matrix.Matrix; import no.uib.cipr.matrix.Vector; /** * Diagonal preconditioner. Uses the inverse of the diagonal as preconditioner */ public class DiagonalPreconditioner implements Preconditioner { /** * This contains the inverse of the diagonal */ private double[] invdiag; /** * Constructor for DiagonalPreconditioner * * @param n * Problem size (number of rows) */ public DiagonalPreconditioner(int n) { invdiag = new double[n]; } public Vector apply(Vector b, Vector x) { if (!(x instanceof DenseVector) || !(b instanceof DenseVector)) throw new IllegalArgumentException("Vector must be DenseVectors"); double[] xd = ((DenseVector) x).getData(); double[] bd = ((DenseVector) b).getData(); for (int i = 0; i < invdiag.length; ++i) xd[i] = bd[i] * invdiag[i]; return x; } public Vector transApply(Vector b, Vector x) { return apply(b, x); } public void setMatrix(Matrix A) { if (A.numRows() != invdiag.length) throw new IllegalArgumentException( "Matrix size differs from preconditioner size"); for (int i = 0; i < invdiag.length; ++i) { invdiag[i] = A.get(i, i); if (invdiag[i] == 0) // Avoid zero-division throw new RuntimeException("Zero diagonal on row " + (i + 1)); else invdiag[i] = 1 / invdiag[i]; } } } mtj-0.9.14/src/no/uib/cipr/matrix/sparse/Arrays.java0000644000000000000000000001330511027512662020725 0ustar rootroot/* * 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.sparse; /** * Array utilities. Complements java.util.Arrays */ class Arrays { private Arrays() { // No need to instantiate } /** * Searches for a key in a sorted array, and returns an index to an element * which is greater than or equal key. * * @param index * Sorted array of integers * @param key * Search for something equal or greater * @param begin * Start posisiton in the index * @param end * One past the end position in the index * @return end if nothing greater or equal was found, else an index * satisfying the search criteria */ public static int binarySearchGreater(int[] index, int key, int begin, int end) { return binarySearchInterval(index, key, begin, end, true); } /** * Searches for a key in a sorted array, and returns an index to an element * which is greater than or equal key. * * @param index * Sorted array of integers * @param key * Search for something equal or greater * @return index.length if nothing greater or equal was found, else an index * satisfying the search criteria */ public static int binarySearchGreater(int[] index, int key) { return binarySearchInterval(index, key, 0, index.length, true); } /** * Searches for a key in a sorted array, and returns an index to an element * which is smaller than or equal key. * * @param index * Sorted array of integers * @param key * Search for something equal or greater * @param begin * Start posisiton in the index * @param end * One past the end position in the index * @return begin-1 if nothing smaller or equal was found, else an index * satisfying the search criteria */ public static int binarySearchSmaller(int[] index, int key, int begin, int end) { return binarySearchInterval(index, key, begin, end, false); } /** * Searches for a key in a sorted array, and returns an index to an element * which is smaller than or equal key. * * @param index * Sorted array of integers * @param key * Search for something equal or greater * @return -1 if nothing smaller or equal was found, else an index * satisfying the search criteria */ public static int binarySearchSmaller(int[] index, int key) { return binarySearchInterval(index, key, 0, index.length, false); } /** * Searches for a key in a subset of a sorted array. * * @param index * Sorted array of integers * @param key * Key to search for * @param begin * Start posisiton in the index * @param end * One past the end position in the index * @return Integer index to key. -1 if not found */ public static int binarySearch(int[] index, int key, int begin, int end) { end--; while (begin <= end) { int mid = (end + begin) >> 1; if (index[mid] < key) begin = mid + 1; else if (index[mid] > key) end = mid - 1; else return mid; } return -1; } private static int binarySearchInterval(int[] index, int key, int begin, int end, boolean greater) { // Zero length array? if (begin == end) if (greater) return end; else return begin - 1; end--; // Last index int mid = (end + begin) >> 1; // The usual binary search while (begin <= end) { mid = (end + begin) >> 1; if (index[mid] < key) begin = mid + 1; else if (index[mid] > key) end = mid - 1; else return mid; } // No direct match, but an inf/sup was found if ((greater && index[mid] >= key) || (!greater && index[mid] <= key)) return mid; // No inf/sup, return at the end of the array else if (greater) return mid + 1; // One past end else return mid - 1; // One before start } /** * Finds the number of repeated entries * * @param num * Maximum index value * @param ind * Indices to check for repetitions * @return Array of length num with the number of repeated * indices of ind */ public static int[] bandwidth(int num, int[] ind) { int[] nz = new int[num]; for (int i = 0; i < ind.length; ++i) nz[ind[i]]++; return nz; } } mtj-0.9.14/src/no/uib/cipr/matrix/sparse/Chebyshev.java0000644000000000000000000000722711166446524021421 0ustar rootroot/* * 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 */ /* * Derived from public domain software at http://www.netlib.org/templates */ package no.uib.cipr.matrix.sparse; import no.uib.cipr.matrix.Matrix; import no.uib.cipr.matrix.Vector; /** * Chebyshev solver. Solves the symmetric positive definite linear system * Ax = b using the Preconditioned Chebyshev Method. Chebyshev * requires an acurate estimate on the bounds of the spectrum of the matrix. * * @author Templates */ public class Chebyshev extends AbstractIterativeSolver { /** * Estimates for the eigenvalue of the matrix */ private double eigmin, eigmax; /** * Vectors for use in the iterative solution process */ private Vector p, z, r, q; /** * Constructor for Chebyshev. Uses the given vector as template for creating * scratch vectors. Typically, the solution or the right hand side vector * can be passed, and the template is not modified. Eigenvalue estimates * must also be provided * * @param template * Vector to use as template for the work vectors needed in the * solution process * @param eigmin * Smallest eigenvalue. Must be positive * @param eigmax * Largest eigenvalue. Must be positive */ public Chebyshev(Vector template, double eigmin, double eigmax) { p = template.copy(); z = template.copy(); r = template.copy(); q = template.copy(); setEigenvalues(eigmin, eigmax); } /** * Sets the eigenvalue estimates. * * @param eigmin * Smallest eigenvalue. Must be positive * @param eigmax * Largest eigenvalue. Must be positive */ public void setEigenvalues(double eigmin, double eigmax) { this.eigmin = eigmin; this.eigmax = eigmax; if (eigmin <= 0) throw new IllegalArgumentException("eigmin <= 0"); if (eigmax <= 0) throw new IllegalArgumentException("eigmax <= 0"); if (eigmin > eigmax) throw new IllegalArgumentException("eigmin > eigmax"); } public Vector solve(Matrix A, Vector b, Vector x) throws IterativeSolverNotConvergedException { checkSizes(A, b, x); double alpha = 0, beta = 0, c = 0, d = 0; A.multAdd(-1, x, r.set(b)); c = (eigmax - eigmin) / 2.0; d = (eigmax + eigmin) / 2.0; for (iter.setFirst(); !iter.converged(r, x); iter.next()) { M.apply(r, z); if (iter.isFirst()) { p.set(z); alpha = 2.0 / d; } else { beta = (alpha * c) / 2.0; beta *= beta; alpha = 1.0 / (d - beta); p.scale(beta).add(z); } A.mult(p, q); x.add(alpha, p); r.add(-alpha, q); } return x; } }mtj-0.9.14/src/no/uib/cipr/matrix/sparse/IterationMonitor.java0000644000000000000000000000545011027512662022774 0ustar rootroot/* * 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.sparse; import no.uib.cipr.matrix.Vector; import no.uib.cipr.matrix.Vector.Norm; /** * Monitors the iterative solution process for convergence and divergence. Can * also report the current progress. */ public interface IterationMonitor { /** * Resets the iteration */ void setFirst(); /** * Returns true for the first iteration */ boolean isFirst(); /** * Increases iteration counter */ void next(); /** * Number of iterations performed */ int iterations(); /** * Returns current residual */ double residual(); /** * Checks for convergence * * @param r * Residual-vector * @param x * State-vector * @return True if converged */ boolean converged(Vector r, Vector x) throws IterativeSolverNotConvergedException; /** * Checks for convergence * * @param r * Residual-norm * @param x * State-vector * @return True if converged */ boolean converged(double r, Vector x) throws IterativeSolverNotConvergedException; /** * Checks for convergence * * @param r * Residual-norm * @return True if converged */ boolean converged(double r) throws IterativeSolverNotConvergedException; /** * Checks for convergence * * @param r * Residual-vector * @return True if converged */ boolean converged(Vector r) throws IterativeSolverNotConvergedException; /** * Sets new iteration reporter */ void setIterationReporter(IterationReporter monitor); /** * Returns current iteration reporter */ IterationReporter getIterationReporter(); /** * Sets the vector-norm to calculate with */ void setNormType(Norm normType); /** * Returns the vector-norm in use */ Norm getNormType(); } mtj-0.9.14/src/no/uib/cipr/matrix/sparse/package.html0000644000000000000000000000443311027512662021104 0ustar rootroot Unstructured sparse matrices and vectors with iterative solvers and preconditioners. The classes and interfaces can be grouped as follows:
  • General sparse matrices
    • CompRowMatrix - Compressed row storage. Generally the best sparse matrix if the non-zero structure is known.
    • CompColMatrix - Compressed column storage.
    • CompDiagMatrix - Compressed diagonal storage.
    • FlexCompRowMatrix - Flexible compressed row storage. Stores each row as a growable sparse vector.
    • FlexCompColMatrix - Flexible compressed column storage. Stores each column as a growable sparse vector.
    • SparseVector - Growable sparse vector.
  • Iterative solvers
    • BiCG - BiConjugate gradients.
    • BiCGstab - BiConjugate gradients stabilized.
    • CG - Conjugate gradients.
    • CGS - Conjugate gradients squared.
    • Chebyshev - The Chebyshev iteration for symmetrical, positive definite matrices.
    • GMRES - Generalized minimal residual using restart.
    • IR - Iterative refinement (Richardson's method).
    • QMR - Quasi-minimal residual.
  • Preconditioners
    • DiagonalPreconditioner - Diagonal preconditioning.
    • SSOR - Symmetrical sucessive overrelaxation.
    • ICC - Incomplete Cholesky without fill-in.
    • ILU - Incomplete LU without fill-in.
    • ILUT - Incomplete LU with fill-in using a threshold approach.
    • AMG - Algebraic multigrid by smoothed aggregation.
mtj-0.9.14/src/no/uib/cipr/matrix/sparse/MatrixIterationMonitor.java0000644000000000000000000000773111027512662024165 0ustar rootroot/* * 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.sparse; import no.uib.cipr.matrix.NotConvergedException; import no.uib.cipr.matrix.Vector; /** * Iteration monitor based on matrix norms. Extends the default linear iteration * object to compare with the norm of the system matrix and the right hand side. * Can often be a better convergence criteria than the default, but requires the * computation of the matrix norm. */ public class MatrixIterationMonitor extends DefaultIterationMonitor { /** * Norm of the system matrix */ private double normA; /** * Norm of the right hand side */ private double normb; /** * Constructor for MatrixIterationMonitor * * @param normA * Norm of the matrix A * @param normb * Norm of the vector b * @param maxIter * Maximum number of iterations * @param rtol * Relative convergence tolerance (to initial residual) * @param atol * Absolute convergence tolerance * @param dtol * Relative divergence tolerance (to initial residual) */ public MatrixIterationMonitor(double normA, double normb, int maxIter, double rtol, double atol, double dtol) { this.normA = normA; this.normb = normb; this.maxIter = maxIter; this.rtol = rtol; this.atol = atol; this.dtol = dtol; } /** * Constructor for MatrixIterationMonitor. Default is 100000 iterations at * most, relative tolerance of 1e-5, absolute tolerance of 1e-50 and a * divergence tolerance of 1e+5. */ public MatrixIterationMonitor(double normA, double normb) { this.normA = normA; this.normb = normb; } /** * Sets the norm of the system matrix * * @param normA * Norm of the matrix A */ public void setMatrixNorm(double normA) { this.normA = normA; } /** * Sets the norm of the right hand side vector * * @param normb * Norm of the vector b */ public void setVectorNorm(double normb) { this.normb = normb; } @Override protected boolean convergedI(double r, Vector x) throws IterativeSolverNotConvergedException { // Store initial residual if (isFirst()) initR = r; // Check for convergence if (r < Math.max(rtol * (normA * x.norm(normType) + normb), atol)) return true; // Check for divergence if (r > dtol * initR) throw new IterativeSolverNotConvergedException( NotConvergedException.Reason.Divergence, this); if (iter >= maxIter) throw new IterativeSolverNotConvergedException( NotConvergedException.Reason.Iterations, this); if (Double.isNaN(r)) throw new IterativeSolverNotConvergedException( NotConvergedException.Reason.Divergence, this); // Neither convergence nor divergence return false; } @Override protected boolean convergedI(double r) { throw new UnsupportedOperationException(); } } mtj-0.9.14/src/no/uib/cipr/matrix/sparse/FlexCompRowMatrix.java0000644000000000000000000001526511027512662023065 0ustar rootroot/* * 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.sparse; import java.util.Arrays; import java.util.Iterator; import no.uib.cipr.matrix.AbstractMatrix; import no.uib.cipr.matrix.DenseVector; import no.uib.cipr.matrix.Matrix; import no.uib.cipr.matrix.MatrixEntry; import no.uib.cipr.matrix.Vector; import no.uib.cipr.matrix.VectorEntry; import no.uib.cipr.matrix.sparse.SuperIterator.SuperIteratorEntry; /** * Matrix stored row-wise into sparse vectors */ public class FlexCompRowMatrix extends AbstractMatrix { /** * Matrix data */ SparseVector[] rowD; /** * Constructor for FlexCompRowMatrix * * @param numRows * Number of rows * @param numColumns * Number of column */ public FlexCompRowMatrix(int numRows, int numColumns) { super(numRows, numColumns); rowD = new SparseVector[numRows]; for (int i = 0; i < numRows; ++i) rowD[i] = new SparseVector(numColumns); } /** * Constructor for FlexCompRowMatrix * * @param A * Matrix to copy contents from * @param deep * True for a deep copy, false for a reference copy. A reference * copy can only be made of an FlexCompRowMatrix */ public FlexCompRowMatrix(Matrix A, boolean deep) { super(A); rowD = new SparseVector[numRows]; if (deep) { for (int i = 0; i < numRows; ++i) rowD[i] = new SparseVector(numColumns); set(A); } else { FlexCompRowMatrix Ar = (FlexCompRowMatrix) A; for (int i = 0; i < numRows; ++i) rowD[i] = Ar.getRow(i); } } /** * Constructor for FlexCompRowMatrix * * @param A * Matrix to copy contents from. The copy will be deep */ public FlexCompRowMatrix(Matrix A) { this(A, true); } /** * Returns the given row */ public SparseVector getRow(int i) { return rowD[i]; } /** * Sets the given row equal the passed vector */ public void setRow(int i, SparseVector x) { if (x.size() != numColumns) throw new IllegalArgumentException( "New row must be of the same size as existing row"); rowD[i] = x; } @Override public Vector multAdd(double alpha, Vector x, Vector y) { checkMultAdd(x, y); for (int i = 0; i < numRows; ++i) y.add(i, alpha * rowD[i].dot(x)); 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(); // y = 1/alpha * y y.scale(1. / alpha); // y = A'x + y for (int i = 0; i < numRows; ++i) { SparseVector v = rowD[i]; int[] index = v.getIndex(); double[] data = v.getData(); int length = v.getUsed(); for (int j = 0; j < length; ++j) yd[index[j]] += data[j] * xd[i]; } // y = alpha*y = alpha * A'x + y return y.scale(alpha); } @Override public void add(int row, int column, double value) { rowD[row].add(column, value); } @Override public void set(int row, int column, double value) { rowD[row].set(column, value); } @Override public double get(int row, int column) { return rowD[row].get(column); } @Override public Iterator iterator() { return new RowMatrixIterator(); } @Override public Matrix copy() { return new FlexCompRowMatrix(this); } @Override public FlexCompRowMatrix zero() { for (int i = 0; i < numRows; ++i) rowD[i].zero(); return this; } @Override public Matrix set(Matrix B) { if (!(B instanceof FlexCompRowMatrix)) return super.set(B); checkSize(B); FlexCompRowMatrix Bc = (FlexCompRowMatrix) B; for (int i = 0; i < numRows; ++i) rowD[i].set(Bc.rowD[i]); return this; } /** * Tries to store the matrix as compactly as possible */ public void compact() { for (Vector v : rowD) ((SparseVector) v).compact(); } /** * Iterator over a matrix stored vectorwise by rows */ private class RowMatrixIterator implements Iterator { /** * Iterates over each row vector */ private SuperIterator iterator = new SuperIterator( Arrays.asList(rowD)); /** * Entry returned */ private RowMatrixEntry entry = new RowMatrixEntry(); public boolean hasNext() { return iterator.hasNext(); } public MatrixEntry next() { SuperIteratorEntry se = iterator.next(); entry.update(se.index(), se.get()); return entry; } public void remove() { iterator.remove(); } } /** * Entry of a matrix stored vectorwise by rows */ private static class RowMatrixEntry implements MatrixEntry { private int row; private VectorEntry entry; public void update(int row, VectorEntry entry) { this.row = row; this.entry = entry; } public int row() { return row; } public int column() { return entry.index(); } public double get() { return entry.get(); } public void set(double value) { entry.set(value); } } } mtj-0.9.14/src/no/uib/cipr/matrix/sparse/IR.java0000644000000000000000000000422011027512662017772 0ustar rootroot/* * 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 */ /* * Derived from public domain software at http://www.netlib.org/templates */ package no.uib.cipr.matrix.sparse; import no.uib.cipr.matrix.Matrix; import no.uib.cipr.matrix.Vector; /** * Iterative Refinement. IR solves the unsymmetric linear system * Ax = b using Iterative Refinement (preconditioned Richardson * iteration). * * @author Templates */ public class IR extends AbstractIterativeSolver { /** * Vectors for use in the iterative solution process */ private Vector z, r; /** * Constructor for IR. Uses the given vector as template for creating * scratch vectors. Typically, the solution or the right hand side vector * can be passed, and the template is not modified * * @param template * Vector to use as template for the work vectors needed in the * solution process */ public IR(Vector template) { z = template.copy(); r = template.copy(); } public Vector solve(Matrix A, Vector b, Vector x) throws IterativeSolverNotConvergedException { checkSizes(A, b, x); A.multAdd(-1, x, r.set(b)); for (iter.setFirst(); !iter.converged(r, x); iter.next()) { M.apply(r, z); x.add(z); A.multAdd(-1, x, r.set(b)); } return x; } }mtj-0.9.14/src/no/uib/cipr/matrix/sparse/CompColMatrix.java0000644000000000000000000003332111260441062022177 0ustar rootroot/* * 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.sparse; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import no.uib.cipr.matrix.AbstractMatrix; import no.uib.cipr.matrix.DenseVector; import no.uib.cipr.matrix.Matrix; import no.uib.cipr.matrix.MatrixEntry; import no.uib.cipr.matrix.Vector; import no.uib.cipr.matrix.io.MatrixInfo; import no.uib.cipr.matrix.io.MatrixSize; import no.uib.cipr.matrix.io.MatrixVectorReader; /** * Compressed column storage (CCS) matrix */ public class CompColMatrix extends AbstractMatrix { /** * Matrix data */ double[] data; /** * Column indices. These are kept sorted within each row. */ int[] columnPointer; /** * Indices to the start of each row */ int[] rowIndex; /** * Constructor for CompColMatrix * * @param r * Reader to get sparse matrix from */ public CompColMatrix(MatrixVectorReader r) throws IOException { // Start with a zero-sized matrix super(0, 0); // Get matrix information. Use the header if present, else just assume // that the matrix stores real numbers without any symmetry MatrixInfo info = null; if (r.hasInfo()) info = r.readMatrixInfo(); else info = new MatrixInfo(true, MatrixInfo.MatrixField.Real, MatrixInfo.MatrixSymmetry.General); // Check that the matrix is in an acceptable format if (info.isPattern()) throw new UnsupportedOperationException( "Pattern matrices are not supported"); if (info.isDense()) throw new UnsupportedOperationException( "Dense matrices are not supported"); if (info.isComplex()) throw new UnsupportedOperationException( "Complex matrices are not supported"); // Resize the matrix to correct size MatrixSize size = r.readMatrixSize(info); numRows = size.numRows(); numColumns = size.numColumns(); // Start reading entries int numEntries = size.numEntries(); int[] row = new int[numEntries]; int[] column = new int[numEntries]; double[] entry = new double[numEntries]; r.readCoordinate(row, column, entry); // Shift the indices from 1 based to 0 based r.add(-1, row); r.add(-1, column); // Find the number of entries on each column List> cnz = new ArrayList>(numColumns); for (int i = 0; i < numColumns; ++i) cnz.add(new HashSet()); for (int i = 0; i < numEntries; ++i) cnz.get(column[i]).add(row[i]); // Allocate some more in case of symmetry if (info.isSymmetric() || info.isSkewSymmetric()) for (int i = 0; i < numEntries; ++i) if (row[i] != column[i]) cnz.get(row[i]).add(column[i]); int[][] nz = new int[numColumns][]; for (int i = 0; i < numColumns; ++i) { nz[i] = new int[cnz.get(i).size()]; int j = 0; for (Integer rowind : cnz.get(i)) nz[i][j++] = rowind; } // Create the sparse matrix structure construct(nz); // Insert the entries for (int i = 0; i < size.numEntries(); ++i) set(row[i], column[i], entry[i]); // Put in extra entries from symmetry or skew symmetry if (info.isSymmetric()) for (int i = 0; i < numEntries; ++i) { if (row[i] != column[i]) set(column[i], row[i], entry[i]); } else if (info.isSkewSymmetric()) for (int i = 0; i < numEntries; ++i) { if (row[i] != column[i]) set(column[i], row[i], -entry[i]); } } /** * Constructor for CompColMatrix * * @param numRows * Number of rows * @param numColumns * Number of columns * @param nz * The nonzero column indices on each column */ public CompColMatrix(int numRows, int numColumns, int[][] nz) { super(numRows, numColumns); construct(nz); } private void construct(int[][] nz) { int nnz = 0; for (int i = 0; i < nz.length; ++i) nnz += nz[i].length; columnPointer = new int[numColumns + 1]; rowIndex = new int[nnz]; data = new double[nnz]; if (nz.length != numColumns) throw new IllegalArgumentException("nz.length != numColumns"); for (int i = 1; i <= numColumns; ++i) { columnPointer[i] = columnPointer[i - 1] + nz[i - 1].length; for (int j = columnPointer[i - 1], k = 0; j < columnPointer[i]; ++j, ++k) { rowIndex[j] = nz[i - 1][k]; if (nz[i - 1][k] < 0 || nz[i - 1][k] >= numRows) throw new IllegalArgumentException("nz[" + (i - 1) + "][" + k + "]=" + nz[i - 1][k] + ", which is not a valid row index"); } Arrays.sort(rowIndex, columnPointer[i - 1], columnPointer[i]); } } private void construct(Matrix A, boolean deep) { if (deep) { if (A instanceof CompColMatrix) { CompColMatrix Ac = (CompColMatrix) A; data = new double[Ac.data.length]; columnPointer = new int[Ac.columnPointer.length]; rowIndex = new int[Ac.rowIndex.length]; System.arraycopy(Ac.data, 0, data, 0, data.length); System.arraycopy(Ac.columnPointer, 0, columnPointer, 0, columnPointer.length); System.arraycopy(Ac.rowIndex, 0, rowIndex, 0, rowIndex.length); } else { List> cnz = new ArrayList>(numColumns); for (int i = 0; i < numColumns; ++i) cnz.add(new HashSet()); for (MatrixEntry e : A) cnz.get(e.column()).add(e.row()); int[][] nz = new int[numColumns][]; for (int i = 0; i < numColumns; ++i) { nz[i] = new int[cnz.get(i).size()]; int j = 0; for (Integer rowind : cnz.get(i)) nz[i][j++] = rowind; } construct(nz); set(A); } } else { CompColMatrix Ac = (CompColMatrix) A; columnPointer = Ac.getColumnPointers(); rowIndex = Ac.getRowIndices(); data = Ac.getData(); } } /** * Constructor for CompColMatrix * * @param A * Copies from this matrix * @param deep * True if the copy is to be deep. If it is a shallow copy, * A must be a CompColMatrix */ public CompColMatrix(Matrix A, boolean deep) { super(A); construct(A, deep); } /** * Constructor for CompColMatrix * * @param A * Copies from this matrix. The copy will be deep */ public CompColMatrix(Matrix A) { this(A, true); } /** * Returns the column pointers */ public int[] getColumnPointers() { return columnPointer; } /** * Returns the row indices */ public int[] getRowIndices() { return rowIndex; } /** * Returns the internal data storage */ public double[] getData() { return data; } @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(); // y = 1/alpha * y y.scale(1 / alpha); // y = A*x + y for (int i = 0; i < numColumns; ++i) for (int j = columnPointer[i]; j < columnPointer[i + 1]; ++j) yd[rowIndex[j]] += data[j] * xd[i]; // y = alpha*y = alpha*A*x + y return y.scale(alpha); } @Override public Vector transMult(Vector x, Vector y) { if (!(x instanceof DenseVector) || !(y instanceof DenseVector)) return super.transMult(x, y); checkTransMultAdd(x, y); double[] xd = ((DenseVector) x).getData(); double[] yd = ((DenseVector) y).getData(); for (int i = 0; i < numColumns; ++i) { double dot = 0; for (int j = columnPointer[i]; j < columnPointer[i + 1]; ++j) dot += data[j] * xd[rowIndex[j]]; yd[i] = dot; } 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(); double[] yd = ((DenseVector) y).getData(); for (int i = 0; i < numColumns; ++i) { double dot = 0; for (int j = columnPointer[i]; j < columnPointer[i + 1]; ++j) dot += data[j] * xd[rowIndex[j]]; yd[i] += alpha * dot; } return y; } @Override public void set(int row, int column, double value) { check(row, column); int index = getIndex(row, column); data[index] = value; } @Override public void add(int row, int column, double value) { check(row, column); int index = getIndex(row, column); data[index] += value; } @Override public double get(int row, int column) { check(row, column); int index = no.uib.cipr.matrix.sparse.Arrays.binarySearch(rowIndex, row, columnPointer[column], columnPointer[column + 1]); if (index >= 0) return data[index]; else return 0; } /** * Finds the insertion index */ private int getIndex(int row, int column) { int i = no.uib.cipr.matrix.sparse.Arrays.binarySearch(rowIndex, row, columnPointer[column], columnPointer[column + 1]); if (i != -1 && rowIndex[i] == row) return i; else throw new IndexOutOfBoundsException("Entry (" + (row + 1) + ", " + (column + 1) + ") is not in the matrix structure"); } @Override public CompColMatrix copy() { return new CompColMatrix(this); } @Override public Iterator iterator() { return new CompColMatrixIterator(); } @Override public CompColMatrix zero() { Arrays.fill(data, 0); return this; } /** * Iterator over a compressed column matrix */ private class CompColMatrixIterator implements Iterator { private int column, cursor; private CompColMatrixEntry entry = new CompColMatrixEntry(); public CompColMatrixIterator() { // Find first non-empty column nextNonEmptyColumn(); } /** * Locates the first non-empty column, starting at the current. After * the new column has been found, the cursor is also updated */ private void nextNonEmptyColumn() { while (column < numColumns() && columnPointer[column] == columnPointer[column + 1]) column++; cursor = columnPointer[column]; } public boolean hasNext() { return cursor < data.length; } public MatrixEntry next() { entry.update(column, cursor); // Next position is in the same column if (cursor < columnPointer[column + 1] - 1) cursor++; // Next position is at the following (non-empty) column else { column++; nextNonEmptyColumn(); } return entry; } public void remove() { entry.set(0); } } /** * Entry of a compressed column matrix */ private class CompColMatrixEntry implements MatrixEntry { private int column, cursor; /** * Updates the entry */ public void update(int column, int cursor) { this.column = column; this.cursor = cursor; } public int row() { return rowIndex[cursor]; } public int column() { return column; } public double get() { return data[cursor]; } public void set(double value) { data[cursor] = value; } } } mtj-0.9.14/src/no/uib/cipr/matrix/sparse/AbstractIterativeSolver.java0000644000000000000000000000533311027512662024301 0ustar rootroot/* * 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.sparse; import no.uib.cipr.matrix.Matrix; import no.uib.cipr.matrix.Vector; /** * Partial implementation of an iterative solver */ public abstract class AbstractIterativeSolver implements IterativeSolver { /** * Preconditioner to use */ protected Preconditioner M; /** * Iteration monitor */ protected IterationMonitor iter; /** * Constructor for AbstractIterativeSolver. Does not use preconditioning, * and uses the default linear iteration object. */ public AbstractIterativeSolver() { M = new IdentityPreconditioner(); iter = new DefaultIterationMonitor(); } public void setPreconditioner(Preconditioner M) { this.M = M; } public Preconditioner getPreconditioner() { return M; } public IterationMonitor getIterationMonitor() { return iter; } public void setIterationMonitor(IterationMonitor iter) { this.iter = iter; } /** * Checks sizes of input data for {@link #solve(Matrix, Vector, Vector)}. * Throws an exception if the sizes does not match. */ protected void checkSizes(Matrix A, Vector b, Vector x) { if (!A.isSquare()) throw new IllegalArgumentException("!A.isSquare()"); if (b.size() != A.numRows()) throw new IllegalArgumentException("b.size() != A.numRows()"); if (b.size() != x.size()) throw new IllegalArgumentException("b.size() != x.size()"); } /** * Identity preconditioner which does nothing */ private static class IdentityPreconditioner implements Preconditioner { public Vector apply(Vector b, Vector x) { return x.set(b); } public Vector transApply(Vector b, Vector x) { return x.set(b); } public void setMatrix(Matrix A) { // nothing to do } } } mtj-0.9.14/src/no/uib/cipr/matrix/sparse/UnitLowerCompRowMatrix.java0000644000000000000000000000476711027512662024124 0ustar rootroot/* * 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.sparse; import no.uib.cipr.matrix.AbstractMatrix; import no.uib.cipr.matrix.DenseVector; import no.uib.cipr.matrix.Vector; /** * Unit lower triangular CRS matrix. Only used for triangular solves */ class UnitLowerCompRowMatrix extends AbstractMatrix { private int[] rowptr; private int[] colind; private double[] data; private int[] diagind; public UnitLowerCompRowMatrix(CompRowMatrix LU, int[] diagind) { super(LU); rowptr = LU.getRowPointers(); colind = LU.getColumnIndices(); data = LU.getData(); this.diagind = diagind; } @Override public Vector solve(Vector b, Vector x) { if (!(b instanceof DenseVector) || !(x instanceof DenseVector)) return super.solve(b, x); double[] bd = ((DenseVector) b).getData(); double[] xd = ((DenseVector) x).getData(); for (int i = 0; i < numRows; ++i) { // xi = bi - sum[j= 0; --i) // At this stage, x[i] is known, so move it over to the right hand // side for the remaining equations for (int j = rowptr[i]; j < diagind[i]; ++j) xd[colind[j]] -= data[j] * xd[i]; return x; } } mtj-0.9.14/src/no/uib/cipr/matrix/sparse/BiCGstab.java0000644000000000000000000000716111027512662021105 0ustar rootroot/* * 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 */ /* * Derived from public domain software at http://www.netlib.org/templates */ package no.uib.cipr.matrix.sparse; import no.uib.cipr.matrix.Matrix; import no.uib.cipr.matrix.NotConvergedException; import no.uib.cipr.matrix.Vector; /** * BiCG stablized solver. BiCGstab solves the unsymmetric linear system * Ax = b using the Preconditioned BiConjugate Gradient * Stabilized method * * @author Templates */ public class BiCGstab extends AbstractIterativeSolver { /** * Vectors for use in the iterative solution process */ private Vector p, s, phat, shat, t, v, temp, r, rtilde; /** * Constructor for BiCGstab. Uses the given vector as template for creating * scratch vectors. Typically, the solution or the right hand side vector * can be passed, and the template is not modified * * @param template * Vector to use as template for the work vectors needed in the * solution process */ public BiCGstab(Vector template) { p = template.copy(); s = template.copy(); phat = template.copy(); shat = template.copy(); t = template.copy(); v = template.copy(); temp = template.copy(); r = template.copy(); rtilde = template.copy(); } public Vector solve(Matrix A, Vector b, Vector x) throws IterativeSolverNotConvergedException { checkSizes(A, b, x); double rho_1 = 1, rho_2 = 1, alpha = 1, beta = 1, omega = 1; A.multAdd(-1, x, r.set(b)); rtilde.set(r); for (iter.setFirst(); !iter.converged(r, x); iter.next()) { rho_1 = rtilde.dot(r); if (rho_1 == 0) throw new IterativeSolverNotConvergedException( NotConvergedException.Reason.Breakdown, "rho", iter); if (omega == 0) throw new IterativeSolverNotConvergedException( NotConvergedException.Reason.Breakdown, "omega", iter); if (iter.isFirst()) p.set(r); else { beta = (rho_1 / rho_2) * (alpha / omega); // temp = p - omega * v temp.set(-omega, v).add(p); // p = r + beta * temp = r + beta * (p - omega * v) p.set(r).add(beta, temp); } M.apply(p, phat); A.mult(phat, v); alpha = rho_1 / rtilde.dot(v); s.set(r).add(-alpha, v); if (iter.converged(s, x)) return x.add(alpha, phat); M.apply(s, shat); A.mult(shat, t); omega = t.dot(s) / t.dot(t); x.add(alpha, phat); x.add(omega, shat); r.set(s).add(-omega, t); rho_2 = rho_1; } return x; } }mtj-0.9.14/src/no/uib/cipr/matrix/sparse/DefaultIterationMonitor.java0000644000000000000000000001076211027512662024303 0ustar rootroot/* * 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.sparse; import no.uib.cipr.matrix.NotConvergedException; import no.uib.cipr.matrix.Vector; /** * Default iteration monitor. This tester checks declares convergence if the * absolute value of the residual norm is sufficiently small, or if the relative * decrease is small. Divergence is decleared if too many iterations are spent, * or the residual has grown too much. NaNs will also cause divergence to be * flagged. */ public class DefaultIterationMonitor extends AbstractIterationMonitor { /** * Initial residual */ double initR; /** * Relative tolerance */ double rtol; /** * Absolute tolerance */ double atol; /** * Divergence tolerance */ double dtol; /** * Maximum number of iterations */ int maxIter; /** * Constructor for DefaultIterationMonitor * * @param maxIter * Maximum number of iterations * @param rtol * Relative convergence tolerance (to initial residual) * @param atol * Absolute convergence tolerance * @param dtol * Relative divergence tolerance (to initial residual) */ public DefaultIterationMonitor(int maxIter, double rtol, double atol, double dtol) { this.maxIter = maxIter; this.rtol = rtol; this.atol = atol; this.dtol = dtol; } /** * Constructor for DefaultIterationMonitor. Default is 100000 iterations at * most, relative tolerance of 1e-5, absolute tolerance of 1e-50 and a * divergence tolerance of 1e+5. */ public DefaultIterationMonitor() { this.maxIter = 100000; this.rtol = 1e-5; this.atol = 1e-50; this.dtol = 1e+5; } /** * Sets maximum number of iterations to permit * * @param maxIter * Maximum number of iterations */ public void setMaxIterations(int maxIter) { this.maxIter = maxIter; } /** * Sets the relative tolerance * * @param rtol * Relative convergence tolerance (to initial residual) */ public void setRelativeTolerance(double rtol) { this.rtol = rtol; } /** * Sets the absolute tolerance * * @param atol * Absolute convergence tolerance */ public void setAbsoluteTolerance(double atol) { this.atol = atol; } /** * Sets the divergence tolerance * * @param dtol * Relative divergence tolerance (to initial residual) */ public void setDivergenceTolerance(double dtol) { this.dtol = dtol; } @Override protected boolean convergedI(double r) throws IterativeSolverNotConvergedException { // Store initial residual if (isFirst()) initR = r; // Check for convergence if (r < Math.max(rtol * initR, atol)) return true; // Check for divergence if (r > dtol * initR) throw new IterativeSolverNotConvergedException( NotConvergedException.Reason.Divergence, this); if (iter >= maxIter) throw new IterativeSolverNotConvergedException( NotConvergedException.Reason.Iterations, this); if (Double.isNaN(r)) throw new IterativeSolverNotConvergedException( NotConvergedException.Reason.Divergence, this); // Neither convergence nor divergence return false; } @Override protected boolean convergedI(double r, Vector x) throws IterativeSolverNotConvergedException { return convergedI(r); } } mtj-0.9.14/src/no/uib/cipr/matrix/sparse/AbstractIterationMonitor.java0000644000000000000000000000616511027512662024464 0ustar rootroot/* * 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.sparse; import no.uib.cipr.matrix.Vector; import no.uib.cipr.matrix.Vector.Norm; /** * Partial implementation of an iteration reporter */ public abstract class AbstractIterationMonitor implements IterationMonitor { /** * Iteration number */ protected int iter; /** * Vector-norm */ protected Norm normType; /** * Iteration reporter */ protected IterationReporter reporter; /** * Current residual */ protected double residual; /** * Constructor for AbstractIterationMonitor. Default norm is the 2-norm with * no iteration reporting. */ public AbstractIterationMonitor() { normType = Norm.Two; reporter = new NoIterationReporter(); } public void setFirst() { iter = 0; } public boolean isFirst() { return iter == 0; } public void next() { iter++; } public int iterations() { return iter; } public boolean converged(Vector r, Vector x) throws IterativeSolverNotConvergedException { return converged(r.norm(normType), x); } public boolean converged(double r, Vector x) throws IterativeSolverNotConvergedException { reporter.monitor(r, x, iter); this.residual = r; return convergedI(r, x); } public boolean converged(double r) throws IterativeSolverNotConvergedException { reporter.monitor(r, iter); this.residual = r; return convergedI(r); } protected abstract boolean convergedI(double r, Vector x) throws IterativeSolverNotConvergedException; protected abstract boolean convergedI(double r) throws IterativeSolverNotConvergedException; public boolean converged(Vector r) throws IterativeSolverNotConvergedException { return converged(r.norm(normType)); } public Norm getNormType() { return normType; } public void setNormType(Norm normType) { this.normType = normType; } public IterationReporter getIterationReporter() { return reporter; } public void setIterationReporter(IterationReporter monitor) { this.reporter = monitor; } public double residual() { return residual; } } mtj-0.9.14/src/no/uib/cipr/matrix/sparse/ILU.java0000644000000000000000000000777711027512662020135 0ustar rootroot/* * 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.sparse; import no.uib.cipr.matrix.DenseVector; import no.uib.cipr.matrix.Matrix; import no.uib.cipr.matrix.Vector; /** * ILU(0) preconditioner using a compressed row matrix as internal storage */ public class ILU implements Preconditioner { /** * Factorisation matrix */ private final CompRowMatrix LU; /** * The L and U factors */ private Matrix L, U; /** * Temporary vector for solving the factorised system */ private final Vector y; /** * Sets up the ILU preconditioner * * @param LU * Matrix to use internally. For best performance, its non-zero * pattern must conform to that of the system matrix */ public ILU(CompRowMatrix LU) { if (!LU.isSquare()) throw new IllegalArgumentException( "ILU only applies to square matrices"); this.LU = LU; int n = LU.numRows(); y = new DenseVector(n); } public Vector apply(Vector b, Vector x) { // Ly = b, y = L\b L.solve(b, y); // Ux = L\b = y return U.solve(y, x); } public Vector transApply(Vector b, Vector x) { // U'y = b, y = U'\b U.transSolve(b, y); // L'x = U'\b = y return L.transSolve(y, x); } public void setMatrix(Matrix A) { LU.set(A); factor(); } private void factor() { int n = LU.numRows(); // Internal CRS matrix storage int[] colind = LU.getColumnIndices(); int[] rowptr = LU.getRowPointers(); double[] data = LU.getData(); // Find the indices to the diagonal entries int[] diagind = findDiagonalIndices(n, colind, rowptr); // Go down along the main diagonal for (int k = 1; k < n; ++k) for (int i = rowptr[k]; i < diagind[k]; ++i) { // Get the current diagonal entry int index = colind[i]; double LUii = data[diagind[index]]; if (LUii == 0) throw new RuntimeException("Zero pivot encountered on row " + (i + 1) + " during ILU process"); // Elimination factor double LUki = (data[i] /= LUii); // Traverse the sparse row i, reducing on row k for (int j = diagind[index] + 1, l = rowptr[k] + 1; j < rowptr[index + 1]; ++j) { while (l < rowptr[k + 1] && colind[l] < colind[j]) l++; if (colind[l] == colind[j]) data[l] -= LUki * data[j]; } } L = new UnitLowerCompRowMatrix(LU, diagind); U = new UpperCompRowMatrix(LU, diagind); } private int[] findDiagonalIndices(int m, int[] colind, int[] rowptr) { int[] diagind = new int[m]; for (int k = 0; k < m; ++k) { diagind[k] = Arrays.binarySearch(colind, k, rowptr[k], rowptr[k + 1]); if (diagind[k] < 0) throw new RuntimeException("Missing diagonal entry on row " + (k + 1)); } return diagind; } } mtj-0.9.14/src/no/uib/cipr/matrix/sparse/CGS.java0000644000000000000000000000640111027512662020077 0ustar rootroot/* * 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 */ /* * Derived from public domain software at http://www.netlib.org/templates */ package no.uib.cipr.matrix.sparse; import no.uib.cipr.matrix.Matrix; import no.uib.cipr.matrix.NotConvergedException; import no.uib.cipr.matrix.Vector; /** * Conjugate Gradients squared solver. CGS solves the unsymmetric linear system * Ax = b using the Conjugate Gradient Squared method * * @author Templates */ public class CGS extends AbstractIterativeSolver { /** * Vectors for use in the iterative solution process */ private Vector p, q, u, phat, qhat, vhat, uhat, sum, r, rtilde; /** * Constructor for CGS. Uses the given vector as template for creating * scratch vectors. Typically, the solution or the right hand side vector * can be passed, and the template is not modified * * @param template * Vector to use as template for the work vectors needed in the * solution process */ public CGS(Vector template) { p = template.copy(); q = template.copy(); u = template.copy(); phat = template.copy(); qhat = template.copy(); vhat = template.copy(); uhat = template.copy(); sum = template.copy(); r = template.copy(); rtilde = template.copy(); } public Vector solve(Matrix A, Vector b, Vector x) throws IterativeSolverNotConvergedException { checkSizes(A, b, x); double rho_1 = 0, rho_2 = 0, alpha = 0, beta = 0; A.multAdd(-1, x, r.set(b)); rtilde.set(r); for (iter.setFirst(); !iter.converged(r, x); iter.next()) { rho_1 = rtilde.dot(r); if (rho_1 == 0) throw new IterativeSolverNotConvergedException( NotConvergedException.Reason.Breakdown, "rho", iter); if (iter.isFirst()) { u.set(r); p.set(u); } else { beta = rho_1 / rho_2; u.set(r).add(beta, q); sum.set(q).add(beta, p); p.set(u).add(beta, sum); } M.apply(p, phat); A.mult(phat, vhat); alpha = rho_1 / rtilde.dot(vhat); q.set(-alpha, vhat).add(u); M.apply(sum.set(u).add(q), uhat); x.add(alpha, uhat); A.mult(uhat, qhat); r.add(-alpha, qhat); rho_2 = rho_1; } return x; } }mtj-0.9.14/src/no/uib/cipr/matrix/AbstractSymmPackMatrix.java0000644000000000000000000001135611027512662022570 0ustar rootroot/* * 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 org.netlib.blas.BLAS; import org.netlib.lapack.LAPACK; import org.netlib.util.intW; /** * Partial implementation of a symmetrical, packed matrix */ abstract class AbstractSymmPackMatrix extends AbstractPackMatrix { /** * Which part of the matrix which is stored */ private UpLo uplo; /** * Constructor for AbstractSymmPackMatrix */ AbstractSymmPackMatrix(int n, UpLo uplo) { super(n); this.uplo = uplo; } /** * Constructor for AbstractSymmPackMatrix */ AbstractSymmPackMatrix(Matrix A, UpLo uplo) { this(A, true, uplo); } /** * Constructor for AbstractSymmPackMatrix */ AbstractSymmPackMatrix(Matrix A, boolean deep, UpLo uplo) { super(A, deep); this.uplo = uplo; } @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().dspmv(uplo.netlib(), numRows, alpha, data, xd, 1, 1, yd, 1); return y; } @Override public Vector transMultAdd(double alpha, Vector x, Vector y) { return multAdd(alpha, x, y); } @Override public Matrix rank1(double alpha, Vector x, Vector y) { if (x != y) throw new IllegalArgumentException("x != y"); if (!(x instanceof DenseVector)) return super.rank1(alpha, x, y); checkRank1(x, y); double[] xd = ((DenseVector) x).getData(); BLAS.getInstance().dspr(uplo.netlib(), numRows, alpha, xd, 1, data); return this; } @Override public Matrix rank2(double alpha, Vector x, Vector y) { if (!(x instanceof DenseVector) || !(y instanceof DenseVector)) return super.rank2(alpha, x, y); checkRank2(x, y); double[] xd = ((DenseVector) x).getData(), yd = ((DenseVector) y) .getData(); BLAS.getInstance().dspr2(uplo.netlib(), numRows, alpha, xd, 1, yd, 1, data); return this; } @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); int[] ipiv = new int[numRows]; intW info = new intW(0); LAPACK.getInstance().dspsv(uplo.netlib(), numRows, X.numColumns(), data.clone(), 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 transSolve(Matrix B, Matrix X) { return solve(B, X); } @Override public Vector transSolve(Vector b, Vector x) { return solve(b, x); } Matrix SPDsolve(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); intW info = new intW(0); LAPACK.getInstance().dppsv(uplo.netlib(), numRows, X.numColumns(), data.clone(), Xd, Matrices.ld(numRows), info); if (info.val > 0) throw new MatrixNotSPDException(); else if (info.val < 0) throw new IllegalArgumentException(); return X; } @Override public Matrix transpose() { return this; } } mtj-0.9.14/src/no/uib/cipr/matrix/AbstractDenseMatrix.java0000644000000000000000000000661711027512662022106 0ustar rootroot/* * 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; /** * Partial implementation of a dense matrix */ abstract class AbstractDenseMatrix extends AbstractMatrix { /** * Matrix contents */ double[] data; /** * Constructor for AbstractDenseMatrix. The matrix contents will be set to * zero * * @param numRows * Number of rows * @param numColumns * Number of columns */ public AbstractDenseMatrix(int numRows, int numColumns) { super(numRows, numColumns); data = new double[numRows * numColumns]; } /** * Constructor for AbstractDenseMatrix. Matrix is copied from the supplied * matrix * * @param A * Matrix to copy from */ public AbstractDenseMatrix(Matrix A) { this(A, true); } /** * Constructor for AbstractDenseMatrix. Matrix is copied from the supplied * matrix * * @param A * Matrix to copy from * @param deep * True for deep copy, false for reference */ public AbstractDenseMatrix(Matrix A, boolean deep) { super(A); if (deep) { data = new double[numRows * numColumns]; copy(A); } else this.data = ((AbstractDenseMatrix) A).getData(); } /** * Set this matrix equal to the given matrix */ abstract void copy(Matrix A); /** * Returns the matrix contents. Ordering depends on the underlying storage * assumptions */ public double[] getData() { return data; } @Override public void add(int row, int column, double value) { data[getIndex(row, column)] += value; } @Override public void set(int row, int column, double value) { data[getIndex(row, column)] = value; } @Override public double get(int row, int column) { return data[getIndex(row, column)]; } /** * Checks the row and column indices, and returns the linear data index */ int getIndex(int row, int column) { check(row, column); return row + column * numRows; } @Override public Matrix set(Matrix B) { if (!(B instanceof AbstractDenseMatrix)) return super.set(B); checkSize(B); double[] Bd = ((AbstractDenseMatrix) B).getData(); if (Bd == data) return this; System.arraycopy(Bd, 0, data, 0, data.length); return this; } @Override public Matrix zero() { Arrays.fill(data, 0); return this; } } mtj-0.9.14/src/no/uib/cipr/matrix/Diag.java0000644000000000000000000000220411027512662017027 0ustar rootroot/* * 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; /** Diagonal enumeration */ enum Diag { /** Matrix is not unit diagonal */ NonUnit, /** Matrix is unit diagonal */ Unit; /** * @return the netlib character version of this designation, for use with F2J. */ public String netlib() { if (this == NonUnit) return "N"; return "U"; } } mtj-0.9.14/src/no/uib/cipr/matrix/LowerTriangBandMatrix.java0000644000000000000000000000723111027512662022377 0ustar rootroot/* * 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; /** * Lower triangular banded matrix. The same storage as * {@link no.uib.cipr.matrix.BandMatrix BandMatrix}, but without * superdiagonals. */ public class LowerTriangBandMatrix extends AbstractTriangBandMatrix { /** * Constructor for LowerTriangBandMatrix * * @param n * Size of the matrix. Since the matrix must be square, this * equals both the number of rows and columns * @param kd * Number of bands below the main diagonal (subdiagonals) */ public LowerTriangBandMatrix(int n, int kd) { super(n, kd, 0, UpLo.Lower, Diag.NonUnit); } /** * Constructor for LowerTriangBandMatrix * * @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 kd * Number of bands below the main diagonal (subdiagonals) */ public LowerTriangBandMatrix(Matrix A, int kd) { this(A, kd, true); } /** * Constructor for LowerTriangBandMatrix * * @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 kd * 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 LowerTriangBandMatrix(Matrix A, int kd, boolean deep) { super(A, kd, 0, deep, UpLo.Lower, Diag.NonUnit); } /** * Constructor for LowerTriangBandMatrix * * @param n * Size of the matrix. Since the matrix must be square, this * equals both the number of rows and columns * @param kd * Number of bands below the main diagonal (subdiagonals) */ LowerTriangBandMatrix(int n, int kd, Diag diag) { super(n, kd, 0, UpLo.Lower, diag); } /** * Constructor for LowerTriangBandMatrix * * @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 kd * Number of bands below the main diagonal (subdiagonals) * @param deep * True for a deep copy. For shallow copies, A * must be a banded matrix */ LowerTriangBandMatrix(Matrix A, int kd, boolean deep, Diag diag) { super(A, kd, 0, deep, UpLo.Lower, diag); } @Override public LowerTriangBandMatrix copy() { return new LowerTriangBandMatrix(this, kl); } } mtj-0.9.14/src/no/uib/cipr/matrix/SymmPackEVD.java0000644000000000000000000001262611027512662020257 0ustar rootroot/* * 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 org.netlib.lapack.LAPACK; import org.netlib.util.intW; /** * Computes eigenvalues of symmetrical, packed matrices */ public class SymmPackEVD extends SymmEVD { /** * Double work array */ private final double[] work; /** * Integer work array */ private final int[] iwork; /** * Upper or lower part stored */ private final UpLo uplo; /** * Sets up an eigenvalue decomposition for symmetrical, packed matrices. * Computes all eigenvalues and eigenvectors * * @param n * Size of the matrix * @param upper * True if the upper part of the matrix is stored, and false if * the lower part of the matrix is stored instead */ public SymmPackEVD(int n, boolean upper) { this(n, upper, true); } /** * Sets up an eigenvalue decomposition for symmetrical, packed matrices * * @param n * Size of the matrix * @param upper * True if the upper part of the matrix is stored, and false if * the lower part of the matrix is stored instead * @param vectors * True to compute the eigenvectors, false for just the * eigenvalues */ public SymmPackEVD(int n, boolean upper, boolean vectors) { super(n, vectors); uplo = upper ? UpLo.Upper : UpLo.Lower; // Find the needed workspace double[] worksize = new double[1]; int[] iworksize = new int[1]; intW info = new intW(0); LAPACK.getInstance().dspevd(job.netlib(), uplo.netlib(), n, new double[0], new double[0], new double[0], Matrices.ld(n), worksize, -1, iworksize, -1, info); // Allocate workspace int lwork = 0, liwork = 0; if (info.val != 0) { if (job == JobEig.All) { lwork = 1 + 6 * n + n * n; liwork = 3 + 5 * n; } else { lwork = 2 * n; liwork = 1; } } else { lwork = (int) worksize[0]; liwork = iworksize[0]; } lwork = Math.max(1, lwork); liwork = Math.max(1, liwork); work = new double[lwork]; iwork = new int[liwork]; } /** * Convenience method for computing the full eigenvalue decomposition of the * given matrix * * @param A * Matrix to factorize. Upper part extracted, and the matrix is * not modified * @return Newly allocated decomposition * @throws NotConvergedException */ public static SymmPackEVD factorize(Matrix A) throws NotConvergedException { return new SymmPackEVD(A.numRows(), true) .factor(new UpperSymmPackMatrix(A)); } /** * Computes the eigenvalue decomposition of the given matrix * * @param A * Matrix to factorize. Overwritten on return * @return The current eigenvalue decomposition * @throws NotConvergedException */ public SymmPackEVD factor(LowerSymmPackMatrix A) throws NotConvergedException { if (uplo != UpLo.Lower) throw new IllegalArgumentException( "Eigenvalue computer configured for lower-symmetrical matrices"); return factor(A, A.getData()); } /** * Computes the eigenvalue decomposition of the given matrix * * @param A * Matrix to factorize. Overwritten on return * @return The current eigenvalue decomposition * @throws NotConvergedException */ public SymmPackEVD factor(UpperSymmPackMatrix A) throws NotConvergedException { if (uplo != UpLo.Upper) throw new IllegalArgumentException( "Eigenvalue computer configured for upper-symmetrical matrices"); return factor(A, A.getData()); } private SymmPackEVD factor(Matrix A, double[] data) throws NotConvergedException { if (A.numRows() != n) throw new IllegalArgumentException("A.numRows() != n"); intW info = new intW(0); LAPACK.getInstance().dspevd(job.netlib(), uplo.netlib(), n, data, w, job == JobEig.All ? Z.getData() : new double[0], Matrices.ld(n), work, work.length, iwork, iwork.length, info); if (info.val > 0) throw new NotConvergedException( NotConvergedException.Reason.Iterations); else if (info.val < 0) throw new IllegalArgumentException(); return this; } } mtj-0.9.14/src/no/uib/cipr/matrix/Matrices.java0000644000000000000000000004674311027512662017752 0ustar rootroot/* * 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; /** * Static utility methods for matrices and vectors */ public final class Matrices { private Matrices() { // No need to instantiate } /** * max(1, M) provided as a convenience for 'leading dimension' calculations. * * @param n */ static int ld(int n) { return Math.max(1, n); } /** * max(1, max(M, N)) provided as a convenience for 'leading dimension' * calculations. * * @param m * @param n */ static int ld(int m, int n) { return Math.max(1, Math.max(m, n)); } /** * Returns the number of non-zero entries in the given vector */ public static int cardinality(Vector x) { int nz = 0; for (VectorEntry e : x) if (e.get() != 0) nz++; return nz; } /** * Returns the number of non-zero entries in the given matrix */ public static int cardinality(Matrix A) { int nz = 0; for (MatrixEntry e : A) if (e.get() != 0) nz++; return nz; } /** * Returns an array of arrays containing a copy of the given matrix. Each * array contains one row. */ public static double[][] getArray(Matrix A) { double[][] Ad = new double[A.numRows()][A.numColumns()]; for (MatrixEntry e : A) Ad[e.row()][e.column()] = e.get(); return Ad; } /** * Returns a dense array containing a copy of the given vector */ public static double[] getArray(Vector x) { double[] xd = new double[x.size()]; for (VectorEntry e : x) xd[e.index()] = e.get(); return xd; } /** * Returns the identity matrix of the given size * * @param size * Number of rows/columns of the matrix * @return Matrix of the given size, with ones on the main diagonal */ public static DenseMatrix identity(int size) { DenseMatrix A = new DenseMatrix(size, size); for (int i = 0; i < size; ++i) A.set(i, i, 1); return A; } /** * Creates a random vector. Numbers are drawn from a uniform distribution * between 0 and 1 * * @param size * Size of the vector */ public static Vector random(int size) { return random(new DenseVector(size)); } /** * Populates a vector with random numbers drawn from a uniform distribution * between 0 and 1 * * @param x * Vector to populate */ public static Vector random(Vector x) { for (int i = 0; i < x.size(); ++i) x.set(i, Math.random()); return x; } /** * Creates a random matrix. Numbers are drawn from a uniform distribution * between 0 and 1 * * @param numRows * Number of rows * @param numColumns * Number of columns */ public static Matrix random(int numRows, int numColumns) { return random(new DenseMatrix(numRows, numColumns)); } /** * Populates a matrix with random numbers drawn from a uniform distribution * between 0 and 1 * * @param A * Matrix to populate */ public static Matrix random(Matrix A) { for (int j = 0; j < A.numColumns(); ++j) for (int i = 0; i < A.numRows(); ++i) A.set(i, j, Math.random()); return A; } /** * Returns a synchronized vector which wraps the given vector. Only the * set(int, double) and add(int, double) * methods and their blocked versions are synchronized. *

* Note: Do not use the wrapped vector for any operations besides * matrix assembly, as these operations may be very slow. * * @param x * Vector to be wrapped * @return A thin wrapper around x */ public static Vector synchronizedVector(Vector x) { return new SynchronizedVector(x); } /** * Returns a synchronized matrix which wraps the given matrix. Only the * set(int, int, double) and * add(int, int, double) methods and their blocked versions * are synchronized. *

* Note: Do not use the wrapped matrix for any operations besides * matrix assembly, as these operations may be very slow. * * @param A * Matrix to be wrapped * @return A thin wrapper around A */ public static Matrix synchronizedMatrix(Matrix A) { return new SynchronizedMatrix(A); } /** * Returns a synchronized matrix which wraps the given matrix. Only the * set(int, int, double) and * add(int, int, double) methods and their blocked versions * are synchronized. *

* The locking provided is finer than the locking of the whole matrix, as * different threads can access different rows simultaneous, while only one * thread can access a given row at a time. Use this for row-major matrices, * not for column-major matrices. *

* Note: Do not use the wrapped matrix for any operations besides * matrix assembly, as these operations may be very slow. * * @param A * Matrix to be wrapped * @return A thin wrapper around A. Individual rows are * locked */ public static Matrix synchronizedMatrixByRows(Matrix A) { return new SynchronizedRowMatrix(A); } /** * Returns a synchronized matrix which wraps the given matrix. Only the * set(int, int, double) and * add(int, int, double) methods and their blocked versions * are synchronized. *

* The locking provided is finer than the locking of the whole matrix, as * different threads can access different columns simultaneous, while only * one thread can access a given column at a time. Use this for column-major * matrices, not for row-major matrices. *

* Note: Do not use the wrapped matrix for any operations besides * matrix assembly, as these operations may be very slow. * * @param A * Matrix to be wrapped * @return A thin wrapper around A. Individual columns are * locked */ public static Matrix synchronizedMatrixByColumns(Matrix A) { return new SynchronizedColumnMatrix(A); } /** * Returns a view into the given matrix. This view is only for easing some * matrix-assembly cases, not for general use. To extract a more * higher-performing and general matrix, create a copy of the submatrix. The * result is a {@link no.uib.cipr.matrix.DenseMatrix DenseMatrix}. * * @param A * Matrix to create view on * @param row * Rows to access. Must be within the bounds of A * @param column * Columns to access. Must be within the bounds of A * @return Submatrix of A. Changing it will change the * backing matrix */ public static Matrix getSubMatrix(Matrix A, int[] row, int[] column) { return new RefMatrix(A, row, column); } /** * Returns a view into the given vector. This view is only for easing some * vector-assembly cases, not for general use. To extract a more * higher-performing and general vector, create a copy of the subvector. The * result is a {@link no.uib.cipr.matrix.DenseVector DenseVector}. * * @param x * Vector to create view on * @param index * Indices to access. Must be within the bounds of x * @return Submatrix of x. Changing it will change the * backing matrix */ public static Vector getSubVector(Vector x, int[] index) { return new RefVector(x, index); } /** * Matrix backed by another matrix. Used by getSubMatrix */ private static class RefMatrix extends AbstractMatrix { private Matrix A; private int[] row, column; public RefMatrix(Matrix A, int[] row, int[] column) { super(row.length, column.length); this.A = A; this.row = row; this.column = column; } @Override public void add(int row, int column, double value) { A.add(this.row[row], this.column[column], value); } @Override public DenseMatrix copy() { return new DenseMatrix(this); } @Override public double get(int row, int column) { return A.get(this.row[row], this.column[column]); } @Override public void set(int row, int column, double value) { A.set(this.row[row], this.column[column], value); } } /** * Vector backed by another vector. Used by getSubVector */ private static class RefVector extends AbstractVector { private Vector x; private int[] index; public RefVector(Vector x, int[] index) { super(index.length); this.x = x; this.index = index; } @Override public void add(int index, double value) { x.add(this.index[index], value); } @Override public DenseVector copy() { return new DenseVector(this); } @Override public double get(int index) { return x.get(this.index[index]); } @Override public void set(int index, double value) { x.set(this.index[index], value); } } /** * Ensures correctness in the vector assembly. Since it extends the * AbstractVector class, algebraic operations will be slow. It is not * possible to implement Vector and delegate calls to the imbedded vector, * since casting to the imbedded vector is not possible */ private static class SynchronizedVector extends AbstractVector { private Vector x; public SynchronizedVector(Vector x) { super(x); this.x = x; } @Override public synchronized void add(int index, double value) { x.add(index, value); } @Override public synchronized void set(int index, double value) { x.set(index, value); } @Override public synchronized double get(int index) { return x.get(index); } @Override public Vector copy() { return Matrices.synchronizedVector(x.copy()); } } /** * Ensures correctness in the matrix assembly. Since it extends the * AbstractMatrix class, algebraic operations will be slow. It is not * possible to implement Matrix and delegate calls to the imbedded matrix, * since casting to the imbedded matrix is not possible */ private static class SynchronizedMatrix extends AbstractMatrix { private Matrix A; public SynchronizedMatrix(Matrix A) { super(A); this.A = A; } @Override public synchronized void add(int row, int column, double value) { A.add(row, column, value); } @Override public synchronized void set(int row, int column, double value) { A.set(row, column, value); } @Override public synchronized double get(int row, int column) { return A.get(row, column); } @Override public Matrix copy() { return Matrices.synchronizedMatrix(A.copy()); } } /** * Ensures correctness in the matrix assembly. Since it extends the * AbstractMatrix class, algebraic operations will be slow. It is not * possible to implement Matrix and delegate calls to the imbedded matrix, * since casting to the imbedded matrix is not possible *

* Locks individual rows instead of the whole matrix */ private static class SynchronizedRowMatrix extends AbstractMatrix { private Matrix A; private Object[] lock; public SynchronizedRowMatrix(Matrix A) { super(A); this.A = A; lock = new Object[A.numRows()]; for (int i = 0; i < lock.length; ++i) lock[i] = new Object(); } @Override public void add(int row, int column, double value) { synchronized (lock[row]) { A.add(row, column, value); } } @Override public void set(int row, int column, double value) { synchronized (lock[row]) { A.set(row, column, value); } } @Override public double get(int row, int column) { return A.get(row, column); } @Override public Matrix copy() { return Matrices.synchronizedMatrixByRows(A.copy()); } } /** * Ensures correctness in the matrix assembly. Implements matrix instead of * subclassing the abstract matrix in order to correctly delegate every * method to possbly overridden method in the encapsulated matrix. *

* Locks individual columns instead of the whole matrix */ private static class SynchronizedColumnMatrix extends AbstractMatrix { private Matrix A; private Object[] lock; public SynchronizedColumnMatrix(Matrix A) { super(A); this.A = A; lock = new Object[A.numColumns()]; for (int i = 0; i < lock.length; ++i) lock[i] = new Object(); } @Override public void add(int row, int column, double value) { synchronized (lock[column]) { A.add(row, column, value); } } @Override public void set(int row, int column, double value) { synchronized (lock[column]) { A.set(row, column, value); } } @Override public double get(int row, int column) { return A.get(row, column); } @Override public Matrix copy() { return Matrices.synchronizedMatrixByColumns(A.copy()); } } /** * Creates a continuous linear index. * * @param from * Start, inclusive * @param to * Stop, exclusive */ public static int[] index(int from, int to) { int length = to - from; if (length < 0) length = 0; int[] index = new int[length]; for (int i = from, j = 0; j < length; ++i, ++j) index[j] = i; return index; } /** * Creates a strided linear index. * * @param from * Start, inclusive * @param stride * stride=1 for continuous. Negative strides are * allowed * @param to * Stop, exclusive */ public static int[] index(int from, int stride, int to) { if (stride == 1) return index(from, to); else if (stride == 0) return new int[0]; if (to <= from && stride > 0) return new int[0]; if (from <= to && stride < 0) return new int[0]; int length = Math.abs((to - from) / stride); if (Math.abs((to - from) % stride) > 0) length++; if (length < 0) length = 0; int[] index = new int[length]; for (int i = from, j = 0; j < length; i += stride, ++j) index[j] = i; return index; } /** * Finds the number of non-zero entries on each row */ public static int[] rowBandwidth(Matrix A) { int[] nz = new int[A.numRows()]; for (MatrixEntry e : A) nz[e.row()]++; return nz; } /** * Finds the number of non-zero entries on each column */ public static int[] columnBandwidth(Matrix A) { int[] nz = new int[A.numColumns()]; for (MatrixEntry e : A) nz[e.column()]++; return nz; } /** * Finds the number of diagonals below the main diagonal. Useful for * converting a general matrix into a banded matrix */ public static int getNumSubDiagonals(Matrix A) { int kl = 0; for (MatrixEntry e : A) kl = Math.max(kl, e.row() - e.column()); return kl; } /** * Finds the number of diagonals above the main diagonal. Useful for * converting a general matrix into a banded matrix */ public static int getNumSuperDiagonals(Matrix A) { int ku = 0; for (MatrixEntry e : A) ku = Math.max(ku, e.column() - e.row()); return ku; } /** * Sets the selected rows of A equal zero, and puts * diagonal on the diagonal of those rows. Useful for * enforcing boundary conditions */ public static void zeroRows(Matrix A, double diagonal, int... row) { // Sort the rows int[] rowS = row.clone(); Arrays.sort(rowS); for (MatrixEntry e : A) { int j = java.util.Arrays.binarySearch(rowS, e.row()); if (j >= 0) { // Found if (e.row() == e.column()) // Diagonal e.set(diagonal); else // Off diagonal e.set(0); } } // Ensure the diagonal is set. This is necessary in case of missing // rows if (diagonal != 0) for (int rowI : row) A.set(rowI, rowI, diagonal); } /** * Sets the selected columns of A equal zero, and puts * diagonal on the diagonal of those columns. Useful for * enforcing boundary conditions */ public static void zeroColumns(Matrix A, double diagonal, int... column) { // Sort the columns int[] columnS = column.clone(); Arrays.sort(columnS); for (MatrixEntry e : A) { int j = java.util.Arrays.binarySearch(columnS, e.column()); if (j >= 0) { // Found if (e.row() == e.column()) // Diagonal e.set(diagonal); else // Off diagonal e.set(0); } } // Ensure the diagonal is set. This is necessary in case of missing // columns if (diagonal != 0) for (int columnI : column) A.set(columnI, columnI, diagonal); } } mtj-0.9.14/src/no/uib/cipr/matrix/QRP.java0000644000000000000000000001213511467462040016633 0ustar rootroot/* * Copyright (C) 2006 Rafael de Pelegrini Soares * * MTJ additions. * * 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 org.netlib.lapack.LAPACK; import org.netlib.util.intW; /** * Computes QR decompositions with column pivoting: * * {@code A*P = Q*R} where * * {@code A(m,n)}, {@code Q(m,m)}, and {@code R(m,n)}, more generally: * * {@code A*P = [Q1 Q2] * [R11, R12; 0 R22]} and {@code R22} elements are * negligible. * */ public class QRP { /** Pivoting vector */ int jpvt[]; /** * Scales for the reflectors */ final double[] tau; /** * Factorisation sizes */ final int m, n, k; /** The factored matrix rank */ int rank; /** * Work array */ double[] work; /** * The factored matrix */ final DenseMatrix Afact; /** * The orthogonal matrix */ final DenseMatrix Q; /** * The general upper triangular matrix. */ final DenseMatrix R; /** * Constructs an empty QR decomposition * * @param m the number of rows. * @param n the number of columns. */ public QRP(int m, int n) { this.m = m; this.n = n; this.k = Math.min(m, n); this.rank = 0; jpvt = new int[n]; tau = new double[k]; Q = new DenseMatrix(m, m); R = new DenseMatrix(m, n); Afact = new DenseMatrix(m, Math.max(m, n)); int lwork1, lwork2; intW info = new intW(0); double dummy[] = new double[1]; double ret[] = new double[1]; LAPACK lapack = LAPACK.getInstance(); // Query optimal workspace. First for computing the factorization lapack.dgeqrf(m, n, dummy, Matrices.ld(m), dummy, ret, -1, info); lwork1 = (info.val != 0) ? n : (int) ret[0]; // Workspace needed for generating an explicit orthogonal matrix lapack.dorgqr(m, m, k, dummy, Matrices.ld(m), dummy, ret, -1, info); lwork2 = (info.val != 0) ? n : (int) ret[0]; work = new double[Math.max(lwork1, lwork2)]; } /** * Convenience method to compute a QR decomposition * * @param A the matrix to decompose (not modified) * @return Newly allocated decomposition */ public static QRP factorize(Matrix A) { return new QRP(A.numRows(), A.numColumns()).factor(A); } /** * Executes a QR factorization for the given matrix. * * @param A the matrix to be factored (not modified) * @return the factorization object */ public QRP factor(Matrix A) { if (Q.numRows() != A.numRows()) throw new IllegalArgumentException("Q.numRows() != A.numRows()"); else if (R.numColumns() != A.numColumns()) throw new IllegalArgumentException("R.numColumns() != A.numColumns()"); // copy A values in Afact Afact.zero(); for (MatrixEntry e : A) { Afact.set(e.row(), e.column(), e.get()); } intW info = new intW(0); LAPACK lapack = LAPACK.getInstance(); /* * Calculate factorisation */ lapack.dgeqp3(m, n, Afact.getData(), Matrices.ld(m), jpvt, tau, work, work.length, info); if (info.val < 0) throw new IllegalArgumentException(); /* * Get R from Afact */ R.zero(); for (MatrixEntry e : Afact) { if (e.row() <= e.column() && e.column() < R.numColumns()) { R.set(e.row(), e.column(), e.get()); } } /* * Calculate the rank based on a precision EPS */ final double EPS = 1e-12; for (rank = 0; rank < k; rank++) { if (Math.abs(R.get(rank, rank)) < EPS) break; } /* * Explicit the orthogonal matrix */ lapack.dorgqr(m, m, k, Afact.getData(), Matrices.ld(m), tau, work, work.length, info); for (MatrixEntry e : Afact) { if (e.column() < Q.numColumns()) Q.set(e.row(), e.column(), e.get()); } if (info.val < 0) throw new IllegalArgumentException(); // Adjust the permutation to zero offset for (int i = 0; i < jpvt.length; i++) { --jpvt[i]; } return this; } /** * Returns the upper triangular factor */ public DenseMatrix getR() { return R; } /** * Returns the orthogonal matrix */ public DenseMatrix getQ() { return Q; } /** * Returns the column pivoting vector. * This function is cheaper than {@link #getP()}. */ public int[] getPVector() { return jpvt; } /** * Returns the column pivoting matrix. * This function allocates a new Matrix to be returned, * a more cheap option is tu use {@link #getPVector()}. */ public Matrix getP() { Matrix P = new DenseMatrix(jpvt.length, jpvt.length); for (int i = 0; i < jpvt.length; i++) { P.set(jpvt[i], i, 1); } return P; } /** * Returns the rank of the factored matrix */ public int getRank() { return rank; } } mtj-0.9.14/src/no/uib/cipr/matrix/MatrixEntry.java0000644000000000000000000000240611027512662020455 0ustar rootroot/* * 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; /** * An entry of a matrix. Returned by the iterators over a matrix structure */ public interface MatrixEntry { /** * Returns the current row index */ int row(); /** * Returns the current column index */ int column(); /** * Returns the value at the current index */ double get(); /** * Sets the value at the current index */ void set(double value); } mtj-0.9.14/src/no/uib/cipr/matrix/SymmTridiagMatrix.java0000644000000000000000000002115611027512662021610 0ustar rootroot/* * 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 java.util.Iterator; import org.netlib.lapack.LAPACK; import org.netlib.util.intW; /** * Symmetrical tridiagonal matrix. Storage as for * {@link no.uib.cipr.matrix.TridiagMatrix TridiagMatrix}, but only one * off-diagonal array is stored. */ public class SymmTridiagMatrix extends AbstractMatrix { /** * Diagonal and off-diagonal */ double[] diag, offDiag; /** * Size of the matrix */ int n; /** * Constructor for SymmTridiagMatrix * * @param diag * Main diagonal * @param offDiag * Offdiagonals, both upper and lower * @param n * Size of the matrix. The main diagonal must be at least as long * as n, and the off diagonal part must be at least as long as * n-1 */ public SymmTridiagMatrix(double[] diag, double[] offDiag, int n) { super(n, n); this.n = n; if (n < 1) throw new IllegalArgumentException("n must be >= 1"); if (diag.length < n) throw new IllegalArgumentException("diag.length < n"); if (offDiag.length < n - 1) throw new IllegalArgumentException("offDiag.length < n - 1"); this.diag = diag; this.offDiag = offDiag; } /** * Constructor for SymmTridiagMatrix * * @param diag * Main diagonal * @param offDiag * Offdiagonals. Must be one shorter than diag */ public SymmTridiagMatrix(double[] diag, double[] offDiag) { this(diag, offDiag, diag.length); } /** * Constructor for SymmTridiagMatrix * * @param n * Size of the matrix. Since the matrix must be square, this * equals both the number of rows and columns. n * cannot be zero */ public SymmTridiagMatrix(int n) { super(n, n); if (n < 1) throw new IllegalArgumentException("n must be >= 1"); this.n = numRows; diag = new double[n]; offDiag = new double[n - 1]; } /** * Constructor for SymmTridiagMatrix * * @param A * Matrix to copy contents from. Only main and the superdiagonal * is copied over */ public SymmTridiagMatrix(Matrix A) { this(A, true); } /** * Constructor for SymmTridiagMatrix * * @param A * Matrix to copy contents from. Only main and the superdiagonal * is copied over. It must be square and cannot have any zero * dimension lengths * @param deep * True for a deep copy. For shallow copies A must * be a SymmTridiagMatrix */ public SymmTridiagMatrix(Matrix A, boolean deep) { super(A); if (!isSquare()) throw new IllegalArgumentException( "Symmetric matrix must be square"); if (A.numRows() < 1) throw new IllegalArgumentException("numRows must be >= 1"); n = numRows; if (deep) { diag = new double[n]; offDiag = new double[Math.max(n - 1, 0)]; for (MatrixEntry e : A) if (e.row() == e.column() || e.row() == e.column() + 1) set(e.row(), e.column(), e.get()); } else { SymmTridiagMatrix B = (SymmTridiagMatrix) A; this.diag = B.getDiagonal(); this.offDiag = B.getOffDiagonal(); } } /** * Returns the diagonal entries. Length equal n */ public double[] getDiagonal() { return diag; } /** * Returns the off diagonal entries. Length equal n-1 */ public double[] getOffDiagonal() { return offDiag; } @Override public void add(int row, int column, double value) { check(row, column); if (row == column) diag[row] += value; else if (row == column + 1) offDiag[column] += value; else if (row != column - 1) throw new IndexOutOfBoundsException( "Insertion index outside of band"); } @Override public double get(int row, int column) { check(row, column); if (row == column) return diag[row]; else if (row == column + 1) return offDiag[column]; else if (row == column - 1) return offDiag[row]; else return 0; } @Override public void set(int row, int column, double value) { check(row, column); if (row == column) diag[row] = value; else if (row == column + 1) offDiag[column] = value; else if (row != column - 1) throw new IndexOutOfBoundsException( "Insertion index outside of band"); } @Override public SymmTridiagMatrix copy() { return new SymmTridiagMatrix(this); } @Override public SymmTridiagMatrix zero() { Arrays.fill(diag, 0); Arrays.fill(offDiag, 0); return this; } @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); intW info = new intW(0); LAPACK.getInstance().dgtsv(numRows, X.numColumns(), offDiag.clone(), diag.clone(), offDiag.clone(), 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 transSolve(Matrix B, Matrix X) { return solve(B, X); } @Override public Vector transSolve(Vector b, Vector x) { return solve(b, x); } @Override public Matrix transpose() { return this; } @Override public Iterator iterator() { return new SymmTridiagMatrixIterator(); } /** * Iterator over a symmetrical, tridiagonal matrix */ private class SymmTridiagMatrixIterator extends RefMatrixIterator { /** * Current band, starting with the main diagonal */ private double[] band = diag; /** * Band index */ private int bandIndex; /** * Which band in use (0 for main, 1 for off) */ private int whichBand; @Override public boolean hasNext() { return whichBand < 3; } @Override public MatrixEntry next() { entry.update(row, column); // Move in the band if (bandIndex < band.length - 1) bandIndex++; else { // Move to the off-diagonal (twice) bandIndex = 0; whichBand++; band = offDiag; // If the off-diagonals are zero-sized, we are done // This happens if the matrix is 1*1 if (band.length == 0) whichBand = 3; } // Set row index if (whichBand == 1) row = bandIndex + 1; else row = bandIndex; // Set column index if (whichBand == 2) column = bandIndex + 1; else column = bandIndex; return entry; } } } mtj-0.9.14/src/no/uib/cipr/matrix/GivensRotation.java0000644000000000000000000000534211027512662021144 0ustar rootroot/* * 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; /** * Givens plane rotation */ public class GivensRotation { /** * Cosine and sine of the rotation angle. c = x / sqrt(x^2 + y^2), and s = * -y / sqrt(x^2 + y^2) */ private final double c, s; /** * Constructs a Givens plane rotation for a given 2-vector * * @param x * First component of the vector * @param y * Second component of the vector */ public GivensRotation(double x, double y) { double roe = Math.abs(x) > Math.abs(y) ? x : y; double scale = Math.abs(x) + Math.abs(y); if (scale != 0) { double xs = x / scale; double ys = y / scale; double r = scale * Math.sqrt(xs * xs + ys * ys); if (roe < 0) r *= -1; c = x / r; s = y / r; } else { c = 1; s = 0; } } /** * Applies the Givens rotation to two elements in a matrix column * * @param H * Matrix to apply to * @param column * Column index * @param i1 * Row index of first element * @param i2 * Row index of second element */ public void apply(Matrix H, int column, int i1, int i2) { double temp = c * H.get(i1, column) + s * H.get(i2, column); H.set(i2, column, -s * H.get(i1, column) + c * H.get(i2, column)); H.set(i1, column, temp); } /** * Applies the Givens rotation to two elements of a vector * * @param x * Vector to apply to * @param i1 * Index of first element * @param i2 * Index of second element */ public void apply(Vector x, int i1, int i2) { double temp = c * x.get(i1) + s * x.get(i2); x.set(i2, -s * x.get(i1) + c * x.get(i2)); x.set(i1, temp); } } mtj-0.9.14/src/no/uib/cipr/matrix/TridiagMatrix.java0000644000000000000000000001737411027512662020751 0ustar rootroot/* * 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 java.util.Iterator; import org.netlib.lapack.LAPACK; import org.netlib.util.intW; /** * Tridiagonal matrix. Stored in three arrays, one of length n * for the diagonal, two of length n-1 for the superdiagonal and * subdiagonal entries. */ public class TridiagMatrix extends AbstractMatrix { /** * Diagonal, super-diagonal and sub-diagonal */ double[] diag, superDiag, subDiag; /** * Size of the matrix */ private int n; /** * Constructor for TridiagMatrix * * @param n * Size of the matrix. Since the matrix must be square, this * equals both the number of rows and columns */ public TridiagMatrix(int n) { super(n, n); if (n < 1) throw new IllegalArgumentException("n must be >= 1"); this.n = n; diag = new double[n]; superDiag = new double[n - 1]; subDiag = new double[n - 1]; } /** * Constructor for TridiagMatrix * * @param A * Matrix to copy from. Only the tridiagonal part is copied */ public TridiagMatrix(Matrix A) { this(A, true); } /** * Constructor for TridiagMatrix * * @param A * Matrix to copy from. Only the tridiagonal part is copied * @param deep * True for a deep copy, else it's shallow. For shallow copies, * A must be a TridiagMatrix */ public TridiagMatrix(Matrix A, boolean deep) { super(A); if (!isSquare()) throw new IllegalArgumentException( "Tridiagonal matrix must be square"); if (A.numRows() < 1) throw new IllegalArgumentException("numRows must be >= 1"); n = numRows; if (deep) { diag = new double[n]; superDiag = new double[n - 1]; subDiag = new double[n - 1]; for (MatrixEntry e : A) if (e.row() == e.column() || e.row() == e.column() - 1 || e.row() == e.column() + 1) set(e.row(), e.column(), e.get()); } else { TridiagMatrix B = (TridiagMatrix) A; this.diag = B.getDiagonal(); this.subDiag = B.getSubDiagonal(); this.superDiag = B.getSuperDiagonal(); } } /** * Returns the diagonal entries. Length equal n */ public double[] getDiagonal() { return diag; } /** * Returns the sub diagonal entries. Length equal n-1 */ public double[] getSubDiagonal() { return subDiag; } /** * Returns the super diagonal entries. Length equal n-1 */ public double[] getSuperDiagonal() { return superDiag; } @Override public void add(int row, int column, double value) { check(row, column); if (row == column) diag[row] += value; else if (row == column + 1) subDiag[column] += value; else if (row == column - 1) superDiag[row] += value; else throw new IndexOutOfBoundsException( "Insertion index outside of band"); } @Override public double get(int row, int column) { check(row, column); if (row == column) return diag[row]; else if (row == column + 1) return subDiag[column]; else if (row == column - 1) return superDiag[row]; else return 0; } @Override public void set(int row, int column, double value) { check(row, column); if (row == column) diag[row] = value; else if (row == column + 1) subDiag[column] = value; else if (row == column - 1) superDiag[row] = value; else throw new IndexOutOfBoundsException( "Insertion index outside of band"); } @Override public TridiagMatrix copy() { return new TridiagMatrix(this); } @Override public TridiagMatrix zero() { Arrays.fill(diag, 0); Arrays.fill(subDiag, 0); Arrays.fill(superDiag, 0); return this; } @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); intW info = new intW(0); LAPACK.getInstance().dgtsv(numRows, X.numColumns(), subDiag.clone(), diag.clone(), superDiag.clone(), 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() { double[] otherDiag = subDiag; subDiag = superDiag; superDiag = otherDiag; return this; } @Override public Iterator iterator() { return new TridiagMatrixIterator(); } /** * Iterator over a tridiagonal matrix */ private class TridiagMatrixIterator extends RefMatrixIterator { /** * Current band, starting with the main diagonal */ private double[] band = diag; /** * Band index */ private int bandIndex; /** * Which band in use (0 for main, 1 for sub, 2 for super) */ private int whichBand; @Override public boolean hasNext() { return whichBand < 3; } @Override public MatrixEntry next() { entry.update(row, column); // Move in the band if (bandIndex < band.length - 1) bandIndex++; else { // Move to the next band bandIndex = 0; whichBand++; if (whichBand == 1) band = subDiag; else if (whichBand == 2) band = superDiag; // If the off-diagonals are zero-sized, we are done // This happens if the matrix is 1*1 if (band.length == 0) whichBand = 3; } // Set row index if (whichBand == 1) row = bandIndex + 1; else row = bandIndex; // Set column index if (whichBand == 2) column = bandIndex + 1; else column = bandIndex; return entry; } } } mtj-0.9.14/src/no/uib/cipr/matrix/MatrixNotSPDException.java0000644000000000000000000000255711027512662022351 0ustar rootroot/* * 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; /** * Matrix is not symmetrical, positive definite */ public class MatrixNotSPDException extends RuntimeException { private static final long serialVersionUID = 4806417891899193518L; /** * Constructor for MatrixNotSPDException */ public MatrixNotSPDException() { super(); } /** * Constructor for MatrixNotSPDException * * @param message * Description of the exception */ public MatrixNotSPDException(String message) { super(message); } } mtj-0.9.14/src/no/uib/cipr/matrix/AbstractBandMatrix.java0000644000000000000000000001477611027512662021721 0ustar rootroot/* * 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 java.util.Iterator; /** * Partial implementation of a banded matrix */ abstract class AbstractBandMatrix extends AbstractMatrix { /** * Matrix data */ double[] data; /** * Number of upper and lower diagonals */ int kl, ku; /** * Size of the matrix. It is always square */ int n; /** * Constructor for AbstractBandMatrix * * @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 diagonals below the main diagonal * @param ku * Number of diagonals above the main diagonal */ public AbstractBandMatrix(int n, int kl, int ku) { super(n, n); this.n = n; if (kl < 0 || ku < 0) throw new IllegalArgumentException("kl < 0 || ku < 0"); this.kl = kl; this.ku = ku; data = new double[numColumns * (1 + kl + ku)]; } /** * Constructor for AbstractBandMatrix * * @param A * Matrix to copy from * @param kl * Number of diagonals below the main diagonal * @param ku * Number of diagonals above the main diagonal */ public AbstractBandMatrix(Matrix A, int kl, int ku) { this(A, kl, ku, true); } /** * Constructor for AbstractBandMatrix * * @param A * Matrix to copy from * @param kl * Number of diagonals below the main diagonal * @param ku * Number of diagonals above the main diagonal * @param deep * True if a deep copy is made. For a shallow copy, * A must be a banded matrix */ public AbstractBandMatrix(Matrix A, int kl, int ku, boolean deep) { super(A); if (kl < 0 || ku < 0) throw new IllegalArgumentException("kl < 0 || ku < 0"); if (!isSquare()) throw new IllegalArgumentException("Band matrix must be square"); this.n = numRows; this.kl = kl; this.ku = ku; if (deep) { data = new double[numColumns * (1 + kl + ku)]; copy(A); } else this.data = ((AbstractBandMatrix) A).getData(); } /** * Returns the matrix contents */ public double[] getData() { return data; } @Override public void add(int row, int column, double value) { checkBand(row, column); data[getIndex(row, column)] += value; } @Override public void set(int row, int column, double value) { checkBand(row, column); data[getIndex(row, column)] = value; } @Override public double get(int row, int column) { if (!inBand(row, column)) return 0; return data[getIndex(row, column)]; } /** * Returns the number of lower diagonals */ public int numSubDiagonals() { return kl; } /** * Returns the number of upper diagonals */ public int numSuperDiagonals() { return ku; } /** * Returns true if the given indices are within the band */ boolean inBand(int row, int column) { return column - ku <= row && row <= column + kl; } /** * Checks that the indices are within the band */ void checkBand(int row, int column) { if (!inBand(row, column)) throw new IndexOutOfBoundsException("Insertion index out of band"); } /** * Checks the row and column indices, and returns the linear data index */ int getIndex(int row, int column) { check(row, column); return ku + row - column + column * (kl + ku + 1); } /** * Set this matrix equal to the given matrix */ void copy(Matrix A) { for (MatrixEntry e : A) if (inBand(e.row(), e.column())) set(e.row(), e.column(), e.get()); } @Override public Matrix set(Matrix B) { if (!(B instanceof AbstractBandMatrix)) return super.set(B); checkSize(B); AbstractBandMatrix Bb = (AbstractBandMatrix) B; if (Bb.kl != kl) throw new IllegalArgumentException("B.kl != kl"); if (Bb.ku != ku) throw new IllegalArgumentException("B.ku != ku"); double[] Bd = Bb.getData(); if (Bd == data) return this; System.arraycopy(Bd, 0, data, 0, data.length); return this; } @Override public Matrix zero() { Arrays.fill(data, 0); return this; } @Override public Iterator iterator() { return new BandMatrixIterator(); } /** * Iterator over a band matrix */ class BandMatrixIterator extends RefMatrixIterator { /** * Matrix bandwidths. Cannot be taken directly from the matrix since * that breaks iterating over symmetrical matrices */ private final int lkl, lku; public BandMatrixIterator(int lkl, int lku) { this.lkl = lkl; this.lku = lku; } public BandMatrixIterator() { this(kl, ku); } @Override public MatrixEntry next() { entry.update(row, column); // Traversal first down the columns, then the rows if (row < Math.min(column + lkl, n - 1) && row >= Math.max(column - lku, 0)) row++; else { column++; row = Math.max(column - lku, 0); } return entry; } } } mtj-0.9.14/src/no/uib/cipr/matrix/UpperSPDPackMatrix.java0000644000000000000000000000455511027512662021624 0ustar rootroot/* * 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; /** * Upper symmetrical positive definite packed matrix. Same layout as * {@link no.uib.cipr.matrix.UpperSymmPackMatrix UpperSymmPackMatrix}. This * class does not enforce the SPD property, but serves as a tag so that more * efficient algorithms can be used in the solvers. */ public class UpperSPDPackMatrix extends UpperSymmPackMatrix { /** * Constructor for UpperSPDPackMatrix * * @param n * Size of the matrix. Since the matrix must be square, this * equals both the number of rows and columns */ public UpperSPDPackMatrix(int n) { super(n); } /** * Constructor for UpperSPDPackMatrix * * @param A * Matrix to copy contents from. Only the entries of the relevant * part are copied */ public UpperSPDPackMatrix(Matrix A) { super(A); } /** * Constructor for UpperSPDPackMatrix * * @param A * Matrix to copy contents from. Only the entries of the relevant * part are copied * @param deep * True if the copy is deep, else false (giving a shallow copy). * For shallow copies, A must be a packed matrix */ public UpperSPDPackMatrix(Matrix A, boolean deep) { super(A, deep); } @Override public UpperSPDPackMatrix copy() { return new UpperSPDPackMatrix(this); } @Override public Matrix solve(Matrix B, Matrix X) { return SPDsolve(B, X); } } mtj-0.9.14/src/no/uib/cipr/matrix/AbstractSymmBandMatrix.java0000644000000000000000000001073411034475642022561 0ustar rootroot/* * 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.Iterator; import org.netlib.blas.BLAS; import org.netlib.lapack.LAPACK; import org.netlib.util.intW; /** * Partial implementation of a symmetrical, banded matrix */ abstract class AbstractSymmBandMatrix extends AbstractBandMatrix { /** * Upper or lower part stored? */ private UpLo uplo; /** * Diagonals in relevant band */ int kd; /** * Constructor for AbstractSymmBandMatrix */ AbstractSymmBandMatrix(int n, int kl, int ku, UpLo uplo) { super(n, kl, ku); kd = Math.max(kl, ku); this.uplo = uplo; } /** * Constructor for AbstractSymmBandMatrix */ AbstractSymmBandMatrix(Matrix A, int kl, int ku, UpLo uplo) { this(A, kl, ku, true, uplo); } /** * Constructor for AbstractSymmBandMatrix */ AbstractSymmBandMatrix(Matrix A, int kl, int ku, boolean deep, UpLo uplo) { super(A, kl, ku, deep); kd = Math.max(kl, ku); this.uplo = uplo; } @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().dsbmv(uplo.netlib(), numRows, kd, alpha, data, kd + 1, xd, 1, 1, yd, 1); return y; } @Override public Vector transMultAdd(double alpha, Vector x, Vector y) { return multAdd(alpha, x, y); } @Override public Iterator iterator() { return new BandMatrixIterator(kd, kd); } @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 accomodate any pivots BandMatrix Af = new BandMatrix(this, kd, kd + kd); int[] ipiv = new int[numRows]; intW info = new intW(0); LAPACK.getInstance().dgbsv(numRows, kd, kd, X.numColumns(), Af.getData(), Matrices.ld(2 * kd + kd + 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 transSolve(Matrix B, Matrix X) { return solve(B, X); } @Override public Vector transSolve(Vector b, Vector x) { return solve(b, x); } Matrix SPDsolve(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); intW info = new intW(0); LAPACK.getInstance().dpbsv(uplo.netlib(), numRows, kd, X.numColumns(), data.clone(), Matrices.ld(kd + 1), Xd, Matrices.ld(numRows), info); if (info.val > 0) throw new MatrixNotSPDException(); else if (info.val < 0) throw new IllegalArgumentException(); return X; } @Override public Matrix transpose() { return this; } } mtj-0.9.14/src/no/uib/cipr/matrix/Matrix.java0000644000000000000000000005726411027526642017452 0ustar rootroot/* * 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; /** * Basic matrix interface. It holds doubles in a rectangular 2D * array, and it is used alongside Vector in numerical * computations. Implementing classes decides on the actual storage. * *

Basic operations

*

* Use numRows and numColumns to get the basic * size of a matrix. get(int,int) gets an element, and there are * corresponding set(int,int,double) and * add(int,int,double) methods as well. Note that matrix indices * are zero-based (typical for Java and C). This means that the row-indices * range from 0 to numRows-1, likewise for the columns. It is * legal to have numRows or numColumns equal zero. *

*

* Other basic operations are zero which zeros all the entries of * the matrix, which can be cheaper than either zeroing the matrix manually, or * creating a new matrix, and the operation copy which creates a * deep copy of the matrix. This copy has separate storage, but starts with the * same contents as the current matrix. *

* *

Iterators

*

* The matrix interface extends Iterable, and the iterator * returns a MatrixEntry which contains current index and entry * value. Note that the iterator may skip non-zero entries. Using an iterator, * many simple and efficient algorithms can be created. The iterator also * permits changing values in the matrix, however only non-zero entries can be * changed. *

* *

Basic linear algebra

*

* A large selection of basic linear algebra operations are available. To ensure * high efficiency, little or no internal memory allocation is done, and the * user is required to supply the output arguments. *

*

* The operations available include: *

*
*
Additions
*
Matrices can be added to each other, even if their underlying matrix * structures are different.
*
Multiplications
*
A matrix can be multiplied with vectors and other matrices. For * increased efficiency, a multiplication can be combined with addition and * scaling, and transpose matrix multiplications are also available.
*
Rank-updates
*
A matrix can be efficiently updated using low-rank updates. The updates * can be contained in both matrices or vectors.
*
Transpositions
*
In-place transpositions of square matrices is supported, and the * transpose of a matrix can be stored in another matrix of compatible size * (possibly non-rectangular)
*
Solvers
*
Many dense and structured sparse matrices have fast, direct solvers, and * can be used to solve linear systems without creating a factorization. These * solvers are typically backed by subroutines in LAPACK
*
*/ public interface Matrix extends Iterable { /** * Number of rows in the matrix */ int numRows(); /** * Number of columns in the matrix */ int numColumns(); /** * Returns true if the matrix is square */ boolean isSquare(); /** * A(row,column) = value */ void set(int row, int column, double value); /** * A(row,column) += value */ void add(int row, int column, double value); /** * Returns A(row,column) */ double get(int row, int column); /** * Creates a deep copy of the matrix * * @return A */ Matrix copy(); /** * Zeros all the entries in the matrix, while preserving any underlying * structure. Useful for general, unstructured matrices. * * @return A */ Matrix zero(); /** * y = A*x * * @param x * Vector of size A.numColumns() * @param y * Vector of size A.numRows() * @return y */ Vector mult(Vector x, Vector y); /** * y = alpha*A*x * * @param x * Vector of size A.numColumns() * @param y * Vector of size A.numRows() * @return y */ Vector mult(double alpha, Vector x, Vector y); /** * y = A*x + y * * @param x * Vector of size A.numColumns() * @param y * Vector of size A.numRows() * @return y */ Vector multAdd(Vector x, Vector y); /** * y = alpha*A*x + y * * @param x * Vector of size A.numColumns() * @param y * Vector of size A.numRows() * @return y */ Vector multAdd(double alpha, Vector x, Vector y); /** * y = AT*x * * @param x * Vector of size A.numRows() * @param y * Vector of size A.numColumns() * @return y */ Vector transMult(Vector x, Vector y); /** * y = alpha*AT*x * * @param x * Vector of size A.numRows() * @param y * Vector of size A.numColumns() * @return y */ Vector transMult(double alpha, Vector x, Vector y); /** * y = AT*x + y * * @param x * Vector of size A.numRows() * @param y * Vector of size A.numColumns() * @return y */ Vector transMultAdd(Vector x, Vector y); /** * y = alpha*AT*x + y * * @param x * Vector of size A.numRows() * @param y * Vector of size A.numColumns() * @return y */ Vector transMultAdd(double alpha, Vector x, Vector y); /** * x = A\b. Not all matrices support this operation, those * that do not throw UnsupportedOperationException. Note * that it is often more efficient to use a matrix decomposition and its * associated solver * * @param b * Vector of size A.numRows() * @param x * Vector of size A.numColumns() * @return x * @throws MatrixSingularException * If the matrix is singular * @throws MatrixNotSPDException * If the solver assumes that the matrix is symmetrical, * positive definite, but that that property does not hold */ Vector solve(Vector b, Vector x) throws MatrixSingularException, MatrixNotSPDException; /** * x = AT\b. Not all matrices support this * operation, those that do not throw * UnsupportedOperationException. Note that it is often more * efficient to use a matrix decomposition and its associated solver * * @param b * Vector of size A.numColumns() * @param x * Vector of size A.numRows() * @return x * @throws MatrixSingularException * If the matrix is singular * @throws MatrixNotSPDException * If the solver assumes that the matrix is symmetrical, * positive definite, but that that property does not hold */ Vector transSolve(Vector b, Vector x) throws MatrixSingularException, MatrixNotSPDException; /** * A = x*xT + A. The matrix must be square, and * the vector of the same length * * @return A */ Matrix rank1(Vector x); /** * A = alpha*x*xT + A. The matrix must be * square, and the vector of the same length * * @return A */ Matrix rank1(double alpha, Vector x); /** * A = x*yT + A. The matrix must be square, and * the vectors of the same length * * @return A */ Matrix rank1(Vector x, Vector y); /** * A = alpha*x*yT + A. The matrix must be * square, and the vectors of the same length * * @return A */ Matrix rank1(double alpha, Vector x, Vector y); /** * A = x*yT + y*xT + A. The matrix * must be square, and the vectors of the same length * * @return A */ Matrix rank2(Vector x, Vector y); /** * A = alpha*x*yT + alpha*y*xT + A. * The matrix must be square, and the vectors of the same length * * @return A */ Matrix rank2(double alpha, Vector x, Vector y); /** * C = A*B * * @param B * Matrix such that B.numRows() == A.numColumns() * and B.numColumns() == C.numColumns() * @param C * Matrix such that C.numRows() == A.numRows() and * B.numColumns() == C.numColumns() * @return C */ Matrix mult(Matrix B, Matrix C); /** * C = alpha*A*B * * @param B * Matrix such that B.numRows() == A.numColumns() * and B.numColumns() == C.numColumns() * @param C * Matrix such that C.numRows() == A.numRows() and * B.numColumns() == C.numColumns() * @return C */ Matrix mult(double alpha, Matrix B, Matrix C); /** * C = A*B + C * * @param B * Matrix such that B.numRows() == A.numColumns() * and B.numColumns() == C.numColumns() * @param C * Matrix such that C.numRows() == A.numRows() and * B.numColumns() == C.numColumns() * @return C */ Matrix multAdd(Matrix B, Matrix C); /** * C = alpha*A*B + C * * @param B * Matrix such that B.numRows() == A.numColumns() * and B.numColumns() == C.numColumns() * @param C * Matrix such that C.numRows() == A.numRows() and * B.numColumns() == C.numColumns() * @return C */ Matrix multAdd(double alpha, Matrix B, Matrix C); /** * C = AT*B * * @param B * Matrix such that B.numRows() == A.numRows() and * B.numColumns() == C.numColumns() * @param C * Matrix such that C.numRows() == A.numColumns() * and B.numColumns() == C.numColumns() * @return C */ Matrix transAmult(Matrix B, Matrix C); /** * C = alpha*AT*B * * @param B * Matrix such that B.numRows() == A.numRows() and * B.numColumns() == C.numColumns() * @param C * Matrix such that C.numRows() == A.numColumns() * and B.numColumns() == C.numColumns() * @return C */ Matrix transAmult(double alpha, Matrix B, Matrix C); /** * C = AT*B + C * * @param B * Matrix such that B.numRows() == A.numRows() and * B.numColumns() == C.numColumns() * @param C * Matrix such that C.numRows() == A.numColumns() * and B.numColumns() == C.numColumns() * @return C */ Matrix transAmultAdd(Matrix B, Matrix C); /** * C = alpha*AT*B + C * * @param B * Matrix such that B.numRows() == A.numRows() and * B.numColumns() == C.numColumns() * @param C * Matrix such that C.numRows() == A.numColumns() * and B.numColumns() == C.numColumns() * @return C */ Matrix transAmultAdd(double alpha, Matrix B, Matrix C); /** * C = A*BT * * @param B * Matrix such that B.numRows() == A.numRows() and * B.numColumns() == C.numColumns() * @param C * Matrix such that C.numRows() == A.numColumns() * and B.numColumns() == C.numColumns() * @return C */ Matrix transBmult(Matrix B, Matrix C); /** * C = alpha*A*BT * * @param B * Matrix such that B.numRows() == A.numRows() and * B.numColumns() == C.numColumns() * @param C * Matrix such that C.numRows() == A.numColumns() * and B.numColumns() == C.numColumns() * @return C */ Matrix transBmult(double alpha, Matrix B, Matrix C); /** * C = A*BT + C * * @param B * Matrix such that B.numRows() == A.numRows() and * B.numColumns() == C.numColumns() * @param C * Matrix such that C.numRows() == A.numColumns() * and B.numColumns() == C.numColumns() * @return C */ Matrix transBmultAdd(Matrix B, Matrix C); /** * C = alpha*A*BT + C * * @param B * Matrix such that B.numRows() == A.numRows() and * B.numColumns() == C.numColumns() * @param C * Matrix such that C.numRows() == A.numColumns() * and B.numColumns() == C.numColumns() * @return C */ Matrix transBmultAdd(double alpha, Matrix B, Matrix C); /** * C = AT*BT * * @param B * Matrix such that B.numColumns() == A.numRows() * and B.numRows() == C.numColumns() * @param C * Matrix such that C.numRows() == A.numColumns() * and B.numRows() == C.numColumns() * @return C */ Matrix transABmult(Matrix B, Matrix C); /** * C = alpha*AT*BT * * @param B * Matrix such that B.numColumns() == A.numRows() * and B.numRows() == C.numColumns() * @param C * Matrix such that C.numRows() == A.numColumns() * and B.numRows() == C.numColumns() * @return C */ Matrix transABmult(double alpha, Matrix B, Matrix C); /** * C = AT*BT + C * * @param B * Matrix such that B.numColumns() == A.numRows() * and B.numRows() == C.numColumns() * @param C * Matrix such that C.numRows() == A.numColumns() * and B.numRows() == C.numColumns() * @return C */ Matrix transABmultAdd(Matrix B, Matrix C); /** * C = alpha*AT*BT + C * * @param B * Matrix such that B.numColumns() == A.numRows() * and B.numRows() == C.numColumns() * @param C * Matrix such that C.numRows() == A.numColumns() * and B.numRows() == C.numColumns() * @return C */ Matrix transABmultAdd(double alpha, Matrix B, Matrix C); /** * X = A\B. Not all matrices support this operation, those * that do not throw UnsupportedOperationException. Note * that it is often more efficient to use a matrix decomposition and its * associated solver * * @param B * Matrix with the same number of rows as A, and * the same number of columns as X * @param X * Matrix with a number of rows equal A.numColumns(), * and the same number of columns as B * @return X * @throws MatrixSingularException * If the matrix is singular * @throws MatrixNotSPDException * If the solver assumes that the matrix is symmetrical, * positive definite, but that that property does not hold */ Matrix solve(Matrix B, Matrix X) throws MatrixSingularException, MatrixNotSPDException; /** * X = AT\B. Not all matrices support this * operation, those that do not throw * UnsupportedOperationException. Note that it is often more * efficient to use a matrix decomposition and its associated transpose * solver * * @param B * Matrix with a number of rows equal A.numColumns(), * and the same number of columns as X * @param X * Matrix with the same number of rows as A, and * the same number of columns as B * @return X * @throws MatrixSingularException * If the matrix is singular * @throws MatrixNotSPDException * If the solver assumes that the matrix is symmetrical, * positive definite, but that that property does not hold */ Matrix transSolve(Matrix B, Matrix X) throws MatrixSingularException, MatrixNotSPDException; /** * A = C*CT + A. The matrices must be square * and of the same size * * @return A */ Matrix rank1(Matrix C); /** * A = alpha*C*CT + A. The matrices must be * square and of the same size * * @return A */ Matrix rank1(double alpha, Matrix C); /** * A = CT*C + A The matrices must be square and * of the same size * * @return A */ Matrix transRank1(Matrix C); /** * A = alpha*CT*C + A The matrices must be * square and of the same size * * @return A */ Matrix transRank1(double alpha, Matrix C); /** * A = B*CT + C*BT + A. This * matrix must be square * * @param B * Matrix with the same number of rows as A and * the same number of columns as C * @param C * Matrix with the same number of rows as A and * the same number of columns as B * @return A */ Matrix rank2(Matrix B, Matrix C); /** * A = alpha*B*CT + alpha*C*BT + A. * This matrix must be square * * @param B * Matrix with the same number of rows as A and * the same number of columns as C * @param C * Matrix with the same number of rows as A and * the same number of columns as B * @return A */ Matrix rank2(double alpha, Matrix B, Matrix C); /** * A = BT*C + CT*B + A. This * matrix must be square * * @param B * Matrix with the same number of rows as C and * the same number of columns as A * @param C * Matrix with the same number of rows as B and * the same number of columns as A * @return A */ Matrix transRank2(Matrix B, Matrix C); /** * A = alpha*BT*C + alpha*CT*B + A. * This matrix must be square * * @param B * Matrix with the same number of rows as C and * the same number of columns as A * @param C * Matrix with the same number of rows as B and * the same number of columns as A * @return A */ Matrix transRank2(double alpha, Matrix B, Matrix C); /** * A = alpha*A * * @return A */ Matrix scale(double alpha); /** * A=B. The matrices must be of the same size * * @return A */ Matrix set(Matrix B); /** * A=alpha*B. The matrices must be of the same size * * @return A */ Matrix set(double alpha, Matrix B); /** * A = B + A. The matrices must be of the same size * * @return A */ Matrix add(Matrix B); /** * A = alpha*B + A. The matrices must be of the same size * * @return A */ Matrix add(double alpha, Matrix B); /** * Transposes the matrix in-place. In most cases, the matrix must be square * for this to work. * * @return This matrix */ Matrix transpose(); /** * Sets the tranpose of this matrix into B. Matrix * dimensions must be compatible * * @param B * Matrix with as many rows as this matrix has columns, and as * many columns as this matrix has rows * @return The matrix B=AT */ Matrix transpose(Matrix B); /** * Computes the given norm of the matrix * * @param type * The type of norm to compute */ double norm(Norm type); /** * Supported matrix-norms. Note that Maxvalue is not a proper * matrix norm */ enum Norm { /** * Maximum absolute row sum */ One, /** * The root of sum of the sum of squares */ Frobenius, /** * Maximum column sum */ Infinity, /** * Largest entry in absolute value. Not a proper matrix norm */ Maxvalue; /** * @return the String as required by the netlib libraries to represent this norm. */ public String netlib() { // TODO: this is a bit of a hack // shouldn't need to know about the internals of netlib if (this == One) return "1"; else if (this == Infinity) return "I"; else throw new IllegalArgumentException( "Norm must be the 1 or the Infinity norm"); } } } mtj-0.9.14/src/no/uib/cipr/matrix/Transpose.java0000644000000000000000000000217611027512662020151 0ustar rootroot/* * 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; /** Transpose enumeration */ enum Transpose { /** Do not transpose */ NoTranspose, /** Transpose */ Transpose; /** * @return the netlib character version of this designation, for use with F2J. */ public String netlib() { if (this == NoTranspose) return "N"; return "T"; } } mtj-0.9.14/src/no/uib/cipr/matrix/VectorEntry.java0000644000000000000000000000227111027512662020453 0ustar rootroot/* * 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; /** * An entry of a vector. Returned by the iterators over a vector structure */ public interface VectorEntry { /** * Returns the current index */ int index(); /** * Returns the value at the current index */ double get(); /** * Sets the value at the current index */ void set(double value); } mtj-0.9.14/src/no/uib/cipr/matrix/JobEig.java0000644000000000000000000000225211027512662017325 0ustar rootroot/* * 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; /** The job the eigenvectors solvers are to do */ enum JobEig { /** Compute eigenvalues and eigenvectors */ All, /** Only compute the eigenvalues */ Eigenvalues; /** * @return the netlib character version of this designation, for use with F2J. */ public String netlib() { if (this == All) return "V"; return "N"; } } mtj-0.9.14/src/no/uib/cipr/matrix/distributed/0000755000000000000000000000000011027515240017637 5ustar rootrootmtj-0.9.14/src/no/uib/cipr/matrix/distributed/DistVector.java0000644000000000000000000002100711467312236022600 0ustar rootroot/* * 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.distributed; import java.util.Iterator; import no.uib.cipr.matrix.AbstractVector; import no.uib.cipr.matrix.Vector; import no.uib.cipr.matrix.VectorEntry; /** * Distributed memory vector * * @deprecated the no.uib.cipr.matrix.distributed package has been deprecated because * of a number of hard to fix concurrency bugs. It is distributed only for backwards compatibility, * but is not recommended. The utility of this package is questionable, as it does not allow * distribution of computation between JVMs or across a network. For many people, distributed * computing of multiple matrices can be achieved at a user-level through the * JPPF Framework. * Users who need to deal with few very large matrices may wish to implement their own storage classes * and solvers using JPPF, but this will not be supported directly in matrix-toolkits-java. */ @Deprecated public class DistVector extends AbstractVector { private static final long serialVersionUID = 4048795671438309432L; /** * Communicator in use */ private Communicator comm; /** * Local part of the vector */ Vector x; /** * The subdivisions of the global vector */ int[] n; int rank; /** * Rank and size of the communicator */ private int commSize; /** * Constructor for DistVector * * @param size * Global vector size * @param comm * Communicator to use * @param x * Local vector, its size cannot exceed the global size, and the * sum of the local vector sizes must equal the global vector * size (this is checked) */ public DistVector(int size, Communicator comm, Vector x) { super(size); this.comm = comm; this.x = x; rank = comm.rank(); commSize = comm.size(); n = new int[commSize + 1]; // Find out the sizes of all the parts of the distributed vector int[] send = new int[] { x.size() }; int[][] recv = new int[comm.size()][1]; comm.allGather(send, recv); for (int i = 0; i < commSize; ++i) n[i + 1] = n[i] + recv[i][0]; if (n[commSize] != size) throw new IllegalArgumentException("Sum of local vector sizes (" + n[commSize] + ") do not match the global vector size (" + size + ")"); } @Override public void set(int index, double value) { check(index); if (local(index)) x.set(index - n[rank], value); else throw new IllegalArgumentException("Index " + index + " is not local"); } @Override public void add(int index, double value) { check(index); if (local(index)) x.add(index - n[rank], value); else throw new IllegalArgumentException("Index " + index + " is not local"); } @Override public double get(int index) { check(index); if (local(index)) return x.get(index - n[rank]); else throw new IllegalArgumentException("Entry not available locally"); } @Override public DistVector copy() { return new DistVector(size, comm, x.copy()); } @Override public DistVector zero() { x.zero(); return this; } @Override public DistVector scale(double alpha) { x.scale(alpha); return this; } @Override public DistVector set(double alpha, Vector y) { if (!(y instanceof DistVector)) throw new IllegalArgumentException("Vector must be DistVector"); checkSize(y); Vector yb = ((DistVector) y).getLocal(); x.set(alpha, yb); return this; } @Override public DistVector add(double alpha, Vector y) { if (!(y instanceof DistVector)) throw new IllegalArgumentException("Vector must be DistVector"); checkSize(y); Vector yb = ((DistVector) y).getLocal(); x.add(alpha, yb); return this; } @Override public double dot(Vector y) { if (!(y instanceof DistVector)) throw new IllegalArgumentException("Vector must be a DistVector"); checkSize(y); // Compute local part Vector yb = ((DistVector) y).getLocal(); double ldot = x.dot(yb); // Sum all local parts double[] recv = new double[1]; comm.allReduce(new double[] { ldot }, recv, Reductions.sum()); return recv[0]; } @Override protected double norm1() { double norm = x.norm(Norm.One); double[] recv = new double[1]; comm.allReduce(new double[] { norm }, recv, Reductions.sum()); return norm; } @Override protected double norm2_robust() { // We'll just call the fast version, as we have to square the norm // anyways during communications return norm2(); } @Override protected double norm2() { // Compute local norm squared double norm = x.norm(Norm.Two); norm *= norm; double[] recv = new double[1]; comm.allReduce(new double[] { norm }, recv, Reductions.sum()); return Math.sqrt(recv[0]); } @Override protected double normInf() { double norm = x.norm(Norm.Infinity); double[] recv = new double[1]; comm.allReduce(new double[] { norm }, recv, Reductions.max()); return norm; } /** * Returns the local part of the vector */ public Vector getLocal() { return x; } /** * Returns which indices are owned by which ranks. The current rank owns the * indices n[comm.rank()] (inclusive) to * n[comm.rank()+1] (exclusive) */ public int[] getOwnerships() { return n; } /** * Returns true if the insertion index is local to this rank, and no * communication is needed afterwards. */ public boolean local(int index) { return index >= n[rank] && index < n[rank + 1]; } @Override public Iterator iterator() { return new DistVectorIterator(); } /** * Gets the communicator associated with this vector */ public Communicator getCommunicator() { return comm; } /** * Iterator over a distributed memory vector */ private class DistVectorIterator implements Iterator { /** * Entry of local iterator */ private DistVectorEntry entry; /** * Iterator of local vector */ private Iterator i; /** * Constructor for DistVectorIterator */ public DistVectorIterator() { i = x.iterator(); entry = new DistVectorEntry(); } public void remove() { i.remove(); } public boolean hasNext() { return i.hasNext(); } public VectorEntry next() { entry.update(i.next()); return entry; } } /** * Entry returned by the iterator */ private class DistVectorEntry implements VectorEntry { private int offset; private VectorEntry e; public DistVectorEntry() { offset = n[rank]; } public void update(VectorEntry e) { this.e = e; } public int index() { return e.index() + offset; } public double get() { return e.get(); } public void set(double value) { e.set(value); } } } mtj-0.9.14/src/no/uib/cipr/matrix/distributed/Communicator.java0000644000000000000000000003407611467312214023160 0ustar rootroot/* * 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.distributed; import java.lang.reflect.Array; import java.util.List; import java.util.concurrent.CyclicBarrier; import java.util.concurrent.Exchanger; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.ThreadFactory; /** * Inter-thread communications. Supports point-to-point communications using * barriers between the threads. Construct it using the * CollectiveCommunications.createCommunicator method. *

* All Objects which are sent and recieved are arrays (for * instance, double[] or int[]), and the types * must be compatible. It follows that Object[] is an array of * native arrays, such as int[][]. * * @deprecated the no.uib.cipr.matrix.distributed package has been deprecated because * of a number of hard to fix concurrency bugs. It is distributed only for backwards compatibility, * but is not recommended. The utility of this package is questionable, as it does not allow * distribution of computation between JVMs or across a network. For many people, distributed * computing of multiple matrices can be achieved at a user-level through the * JPPF Framework. * Users who need to deal with few very large matrices may wish to implement their own storage classes * and solvers using JPPF, but this will not be supported directly in matrix-toolkits-java. */ @Deprecated public class Communicator { /** * My rank */ private final int rank; /** * Executes asynchronous operations */ private final ExecutorService executor; /** * Collective communications */ private final CollectiveCommunications coll; /** * Input and output locks for irecv/isend */ final Object[] in, out; /** * Barrier for communication with a peer */ final SendRecv[] send, recv; static class SendRecv implements Runnable { CyclicBarrier barrier = new CyclicBarrier(2, this); Object send, recv; int sendOffset, recvOffset, length; public void run() { System.arraycopy(send, sendOffset, recv, recvOffset, length); } } /** * Sets up a communicator between the given number of threads */ Communicator(int rank, final List> ex, CollectiveCommunications coll) { this.rank = rank; this.coll = coll; if (rank < 0) throw new IllegalArgumentException("rank < 0"); if (rank >= size()) throw new IllegalArgumentException("rank >= size"); // Create daemon threads for running async communications executor = Executors.newCachedThreadPool(new ThreadFactory() { public Thread newThread(Runnable r) { Thread t = new Thread(r); t.setDaemon(true); return t; } }); in = new Object[size()]; out = new Object[size()]; for (int i = 0; i < size(); ++i) { in[i] = new Object(); out[i] = new Object(); } send = new SendRecv[size()]; recv = new SendRecv[size()]; // Create local sends, and get recvs from the peers for (int i = 0; i < size(); ++i) if (i != rank) try { send[i] = new SendRecv(); recv[i] = ex.get(i).exchange(send[i]); } catch (InterruptedException e) { throw new RuntimeException(e); } } /** * Rank of this thread in the collective */ public int rank() { return rank; } /** * Size of the collective */ public int size() { return coll.size(); } /** * Gathers data from all tasks and distribute it to all. *

* Row corresponds to ranks, and columns corresponds to data. *

* Input: * * * * * * * * * * * * * * * * * * * * * * * * *
A1   
B1   
C1   
D1   
*

* Output: * * * * * * * * * * * * * * * * * * * * * * * * *
A1B1C1D1
A1B1C1D1
A1B1C1D1
A1B1C1D1
*/ public void allGather(Object sendbuf, Object[] recvbuf) { coll.allGather(sendbuf, recvbuf, rank); } /** * Combines values from all processes and distribute the result back to all * processes. */ public void allReduce(Object sendbuf, Object recvbuf, Reduction op) { coll.allReduce(sendbuf, recvbuf, op, rank); } /** * Sends data from all to all processes. *

* Row corresponds to ranks, and columns corresponds to data. *

* Input: * * * * * * * * * * * * * * * * * * * * * * * * *
A1A2A3A4
B1B2B3B4
C1C2C3C4
D1D2D3D4
*

* Output: * * * * * * * * * * * * * * * * * * * * * * * * *
A1B1C1D1
A2B2C2D2
A3B3C3D3
A4B4C4D4
*/ public void allToAll(Object[] sendbuf, Object[] recvbuf) { coll.allToAll(sendbuf, recvbuf, rank); } /** * Blocks until all process have reached this routine. */ public void barrier() { coll.barrier(); } /** * Broadcasts a message from the process with rank "root" to all other * processes of the group. *

* Row corresponds to ranks, and columns corresponds to data. *

* Input: * * * * * * * * * * * * * * * * * * * * * * * * *
A1   
    
    
    
*

* Output: * * * * * * * * * * * * * * * * * * * * * * * * *
A1   
A1   
A1   
A1   
*/ public void broadcast(Object buffer, int root) { coll.broadcast(buffer, root, rank); } /** * Gathers together values from a group of processes. *

* Row corresponds to ranks, and columns corresponds to data. *

* Input: * * * * * * * * * * * * * * * * * * * * * * * * *
A1   
A2   
A3   
A4   
*

* Output: * * * * * * * * * * * * * * * * * * * * * * * * *
A1A2A3A4
    
    
    
*/ public void gather(Object sendbuf, Object[] recvbuf, int root) { coll.gather(sendbuf, recvbuf, root, rank); } /** * Reduces values on all processes to a single value */ public void reduce(Object sendbuf, Object recvbuf, Reduction op, int root) { coll.reduce(sendbuf, recvbuf, op, root, rank); } /** * Sends data from one task to all other tasks in a group. *

* Row corresponds to ranks, and columns corresponds to data. *

* Input: * * * * * * * * * * * * * * * * * * * * * * * * *
A1A2A3A4
    
    
    
*

* Output: * * * * * * * * * * * * * * * * * * * * * * * * *
A1   
A2   
A3   
A4   
*/ public void scatter(Object[] sendbuf, Object recvbuf, int root) { coll.scatter(sendbuf, recvbuf, root, rank); } /** * Sends data[offset:offset+length] to peer */ public void send(Object data, int offset, int length, int peer) { checkArgs(data, offset, length, peer); send[peer].length = length; send[peer].sendOffset = offset; send[peer].send = data; CollectiveCommunications.await(send[peer].barrier); } /** * Receives data[offset:offset+length] from peer */ public void recv(Object data, int offset, int length, int peer) { checkArgs(data, offset, length, peer); recv[peer].recvOffset = offset; recv[peer].recv = data; CollectiveCommunications.await(recv[peer].barrier); } public Future isend(final Object data, final int offset, final int length, final int peer) { return executor.submit(new Runnable() { public void run() { synchronized (out[peer]) { send(data, offset, length, peer); } } }); } public Future irecv(final Object data, final int offset, final int length, final int peer) { return executor.submit(new Runnable() { public void run() { synchronized (in[peer]) { recv(data, offset, length, peer); } } }); } public void send(Object data, int peer) { send(data, 0, Array.getLength(data), peer); } public void recv(Object data, int peer) { recv(data, 0, Array.getLength(data), peer); } public Future isend(Object data, int peer) { return isend(data, 0, Array.getLength(data), peer); } public Future irecv(Object data, int peer) { return irecv(data, 0, Array.getLength(data), peer); } /** * Waits for the given asynchronous operations to finish */ public void await(Future[] future) { for (Future f : future) await(f); } /** * Waits for the given asynchronous operation to finish */ public void await(Future f) { if (f == null) return; try { f.get(); } catch (Exception e) { throw new RuntimeException(e); } } private void checkArgs(Object data, int offset, int length, int peer) { if (peer == rank) throw new IllegalArgumentException("peer == rank"); if (length + offset > Array.getLength(data)) throw new IllegalArgumentException("Buffer underflow"); if (peer < 0 || peer >= coll.size) throw new IllegalArgumentException("Invalid peer"); } } mtj-0.9.14/src/no/uib/cipr/matrix/distributed/SuperIterator.java0000644000000000000000000001127011467312254023323 0ustar rootroot/* * 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.distributed; import java.util.Iterator; import java.util.List; /** * An iterator over an array of iterable objects * * @deprecated the no.uib.cipr.matrix.distributed package has been deprecated because * of a number of hard to fix concurrency bugs. It is distributed only for backwards compatibility, * but is not recommended. The utility of this package is questionable, as it does not allow * distribution of computation between JVMs or across a network. For many people, distributed * computing of multiple matrices can be achieved at a user-level through the * JPPF Framework. * Users who need to deal with few very large matrices may wish to implement their own storage classes * and solvers using JPPF, but this will not be supported directly in matrix-toolkits-java. */ @Deprecated class SuperIterator, E> implements Iterator { private List iterable; /** * Two iterators. We need the "next" iterator so that hasNext works properly * from one iterable to the next. Using a single iterator won't do */ private Iterator current, next; private int currentIndex = 0, nextIndex = 0; /** * Recyled entry returned from next() */ private SuperIteratorEntry entry; /** * Constructor for SuperIterator * * @param iterable * Iterable objects to iterate over */ public SuperIterator(List iterable) { this.iterable = iterable; entry = new SuperIteratorEntry(); // Try to be somewhat fault tolerant if (iterable.size() == 0) { current = new DummyIterator(); next = new DummyIterator(); } else { // This moves the next pointer to a non-empty iterable next = iterable.get(nextIndex).iterator(); moveNext(); // Then we move the current pointer in the same way current = iterable.get(currentIndex).iterator(); moveCurrent(); // Finally, move the next one step ahead if possible if (next.hasNext()) next.next(); } } private void moveNext() { while (nextIndex < iterable.size() - 1 && !next.hasNext()) next = iterable.get(++nextIndex).iterator(); } private void moveCurrent() { while (currentIndex < iterable.size() - 1 && !current.hasNext()) current = iterable.get(++currentIndex).iterator(); } public boolean hasNext() { return current.hasNext() || next.hasNext(); } public SuperIteratorEntry next() { // A wrapped object containing the relevant index and data entry.update(currentIndex, current.next()); // Move current if necessary moveCurrent(); // Move the next pointer moveNext(); if (next.hasNext()) next.next(); return entry; } public void remove() { current.remove(); } /** * Dummy iterator, for degenerate cases */ private class DummyIterator implements Iterator { public boolean hasNext() { return false; } public E next() { return null; } public void remove() { throw new UnsupportedOperationException(); } } /** * Entry returned from this superiterator */ public static class SuperIteratorEntry { /** * Index of the iterator which returned this */ private int i; /** * Object returned */ private F o; void update(int i, F o) { this.i = i; this.o = o; } public int index() { return i; } public F get() { return o; } } } mtj-0.9.14/src/no/uib/cipr/matrix/distributed/VectorScatter.java0000644000000000000000000002030511467312262023301 0ustar rootroot/* * 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.distributed; import java.util.concurrent.Future; import no.uib.cipr.matrix.Vector; /** * Vector scatter. Transfers values between distributed vectors and local * vectors, both ways (scatters and gathers). After starting a scatter or * gather, it must be ended using one of the two possible scatters/gathers * closing operations (set or add). *

* The operations in this class are not thread-safe. *

* * @deprecated the no.uib.cipr.matrix.distributed package has been deprecated because * of a number of hard to fix concurrency bugs. It is distributed only for backwards compatibility, * but is not recommended. The utility of this package is questionable, as it does not allow * distribution of computation between JVMs or across a network. For many people, distributed * computing of multiple matrices can be achieved at a user-level through the * JPPF Framework. * Users who need to deal with few very large matrices may wish to implement their own storage classes * and solvers using JPPF, but this will not be supported directly in matrix-toolkits-java. */ @Deprecated class VectorScatter { /** * Communicator in use */ private final Communicator comm; /** * For asynchronous communications */ private final Future[] t; /** * Contains the entries recieved from other ranks. Must be used in * conjunction with the indices to assemble the local vector */ private final double[][] recvD; /** * Contains the indices to put entries recieved from other ranks into the * local vector. Used during local vector assembly */ private final int[][] recvI; /** * The indices of the local part of the global vector to send to the other * ranks */ private final int[][] sendI; /** * Will contain the data of local part of the global vector which is to be * sent to the other ranks */ private final double[][] sendD; /** * Who to send/receive to/from */ private final boolean[] send, recv; /** * Constructor for VecScatter * * @param comm * Communicator to operate within * @param sendI * The indices to send data from to each rank * @param recvI * The indices to recieve data from each rank */ public VectorScatter(Communicator comm, int[][] sendI, int[][] recvI) { this.comm = comm; this.sendI = sendI; this.recvI = recvI; if (sendI[comm.rank()].length != 0) throw new IllegalArgumentException("Illegal local send detected"); if (recvI[comm.rank()].length != 0) throw new IllegalArgumentException("Illegal local recv detected"); // Some preallocations t = new Future[2 * comm.size()]; sendD = new double[comm.size()][]; recvD = new double[comm.size()][]; for (int i = 0; i < comm.size(); ++i) { sendD[i] = new double[sendI[i].length]; recvD[i] = new double[recvI[i].length]; } // For optimized communications send = new boolean[comm.size()]; recv = new boolean[comm.size()]; for (int i = 0; i < comm.size(); ++i) { send[i] = sendI[i].length > 0; recv[i] = recvI[i].length > 0; } } /** * Starts a scatter from x into y. It must be ended using an appropriate * operation */ public void startScatter(DistVector x, Vector y) { if (x.size() != y.size()) throw new IllegalArgumentException( "Vectors must be of the same global size"); // Assemble the arrays to send for (int i = 0; i < comm.size(); ++i) if (i != comm.rank()) for (int j = 0; j < sendI[i].length; ++j) sendD[i][j] = x.get(sendI[i][j]); // Start the sends and recieves for (int i = 0; i < comm.size(); ++i) if (i != comm.rank()) { if (send[i]) t[i] = comm.isend(sendD[i], i); if (recv[i]) t[i + comm.size()] = comm.irecv(recvD[i], i); } } /** * Finishes the scatter by inserting the values over those already in y */ public void endSetScatter(DistVector x, Vector y) { if (x.size() != y.size()) throw new IllegalArgumentException( "Vectors must be of the same global size"); // Finish pending communications comm.await(t); // Assemble the local vector by insertion for (int i = 0; i < comm.size(); ++i) if (i != comm.rank()) for (int j = 0; j < recvI[i].length; ++j) y.set(recvI[i][j], recvD[i][j]); } /** * Finished the scatter by adding the values to those already in y */ public void endAddScatter(DistVector x, Vector y) { if (x.size() != y.size()) throw new IllegalArgumentException( "Vectors must be of the same global size"); // Finish pending communications comm.await(t); // Assemble the local vector by addition for (int i = 0; i < comm.size(); ++i) if (i != comm.rank()) for (int j = 0; j < recvI[i].length; ++j) y.add(recvI[i][j], recvD[i][j]); } /** * Starts a gather from x into y. It must be ended using an apropriate * operation */ public void startGather(Vector x, DistVector y) { if (x.size() != y.size()) throw new IllegalArgumentException( "Vectors must be of the same global size"); // Assemble the arrays to send for (int i = 0; i < comm.size(); ++i) if (i != comm.rank()) for (int j = 0; j < recvI[i].length; ++j) recvD[i][j] = x.get(recvI[i][j]); // Start the sends and recieves for (int i = 0; i < comm.size(); ++i) if (i != comm.rank()) { if (send[i]) t[i] = comm.isend(recvD[i], i); if (recv[i]) t[i + comm.size()] = comm.irecv(sendD[i], i); } } /** * Finishes the gather by inserting the values over those already in y */ public void endSetGather(Vector x, DistVector y) { if (x.size() != y.size()) throw new IllegalArgumentException( "Vectors must be of the same global size"); // Finish pending communications comm.await(t); // Assemble the global vector by insertion for (int i = 0; i < comm.size(); ++i) if (i != comm.rank()) for (int j = 0; j < sendI[i].length; ++j) y.set(sendI[i][j], sendD[i][j]); } /** * Finishes the gather by adding the values to those already in y */ public void endAddGather(Vector x, DistVector y) { if (x.size() != y.size()) throw new IllegalArgumentException( "Vectors must be of the same global size"); // Finish pending communications comm.await(t); // Assemble the global vector by insertion for (int i = 0; i < comm.size(); ++i) if (i != comm.rank()) for (int j = 0; j < sendI[i].length; ++j) y.add(sendI[i][j], sendD[i][j]); } } mtj-0.9.14/src/no/uib/cipr/matrix/distributed/TwoLevelPreconditioner.java0000644000000000000000000002064211467312260025161 0ustar rootroot/* * 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.distributed; import java.util.Arrays; import no.uib.cipr.matrix.DenseLU; import no.uib.cipr.matrix.DenseMatrix; import no.uib.cipr.matrix.DenseVector; import no.uib.cipr.matrix.Matrix; import no.uib.cipr.matrix.MatrixEntry; import no.uib.cipr.matrix.Vector; import no.uib.cipr.matrix.VectorEntry; import no.uib.cipr.matrix.sparse.Preconditioner; /** * Two level preconditioner. Uses a block preconditioner as a subdomain solver, * and algebraically constructs a coarse grid correcion operator * * @deprecated the no.uib.cipr.matrix.distributed package has been deprecated because * of a number of hard to fix concurrency bugs. It is distributed only for backwards compatibility, * but is not recommended. The utility of this package is questionable, as it does not allow * distribution of computation between JVMs or across a network. For many people, distributed * computing of multiple matrices can be achieved at a user-level through the * JPPF Framework. * Users who need to deal with few very large matrices may wish to implement their own storage classes * and solvers using JPPF, but this will not be supported directly in matrix-toolkits-java. */ @Deprecated public class TwoLevelPreconditioner extends BlockDiagonalPreconditioner { private final static int root = 0; private final DistMatrix A; private final Communicator comm; private final int rank, size; private final int[] indexToRank; private final DistVector z, r; private final DenseMatrix A0; private final DenseVector b0; private final DenseLU lu; private final double[] Ai; private final double[][] Ai0; private final boolean row; private final double[][] zi0; public TwoLevelPreconditioner(Preconditioner prec, DistRowMatrix A, DistVector z) { super(prec); this.A = A; this.z = z; this.r = z.copy(); row = true; indexToRank = createIndexToRank(A.numColumns(), A.getColumnOwnerships()); this.comm = A.getCommunicator(); rank = comm.rank(); size = comm.size(); A0 = new DenseMatrix(size, size); b0 = new DenseVector(size); lu = new DenseLU(size, size); Ai = new double[size]; if (rank == root) { Ai0 = new double[size][size]; zi0 = new double[size][1]; } else { Ai0 = null; zi0 = null; } } public TwoLevelPreconditioner(Preconditioner prec, DistColMatrix A, DistVector z) { super(prec); this.A = A; this.z = z; this.r = z.copy(); row = false; indexToRank = createIndexToRank(A.numColumns(), A.getColumnOwnerships()); this.comm = A.getCommunicator(); rank = comm.rank(); size = comm.size(); A0 = new DenseMatrix(size, size); b0 = new DenseVector(size); lu = new DenseLU(size, size); Ai = new double[size]; if (rank == root) { Ai0 = new double[size][size]; zi0 = new double[size][1]; } else { Ai0 = null; zi0 = null; } } /** * Creates a mapping from a row/column index to the associated rank * * @param size * Number of rows/columns * @param n * Row/column ownerships */ private int[] createIndexToRank(int size, int[] n) { int[] indexToRank = new int[size]; for (int i = 0; i < n.length - 1; ++i) for (int j = n[i]; j < n[i + 1]; ++j) indexToRank[j] = i; return indexToRank; } @Override public Vector apply(Vector b, Vector x) { if (!(b instanceof DistVector) || !(x instanceof DistVector)) throw new IllegalArgumentException("Vectors must be DistVectors"); boolean transpose = false; return apply(b, x, transpose); } @Override public Vector transApply(Vector b, Vector x) { if (!(b instanceof DistVector) || !(x instanceof DistVector)) throw new IllegalArgumentException("Vectors must be DistVectors"); boolean transpose = true; return apply(b, x, transpose); } private Vector apply(Vector b, Vector x, boolean transpose) { // Calculate R * (b - A*x) calculateCoarseResidual(b, x, transpose); // Calculate A0 \ R * (b - A*x) if (rank == root) solveCoarseSystem(transpose); // Update x += R^T A0 \ R * (b - A*x) updateWithCoarseCorrection(x); return applyBlockPreconditioner(b, x, transpose); } /** * Calculates the residual, and projects it onto the coarse grid */ private void calculateCoarseResidual(Vector b, Vector x, boolean transpose) { // z = b - A*x if (transpose) A.transMultAdd(-1, x, z.set(b)); else A.multAdd(-1, x, z.set(b)); // Piecewise constant projection R * (b - A*x) double zi = 0; for (VectorEntry e : z.getLocal()) zi += e.get(); // Gather the results on rank zero double[] zij = new double[] { zi }; comm.gather(zij, zi0, root); } /** * Solves the coarse system. Only the root thread should call */ private void solveCoarseSystem(boolean transpose) { for (int i = 0; i < size; ++i) b0.set(i, zi0[i][0]); if (transpose) lu.transSolve(new DenseMatrix(b0, false)); else lu.solve(new DenseMatrix(b0, false)); double[] data = b0.getData(); for (int i = 0; i < size; ++i) zi0[i][0] = data[i]; } /** * Updates the global solution with the coarse correction */ private void updateWithCoarseCorrection(Vector x) { DistVector xd = (DistVector) x; double[] zij = new double[1]; comm.scatter(zi0, zij, root); for (VectorEntry e : xd.getLocal()) e.set(e.get() + zij[0]); } /** * Applies the local block preconditioner */ private Vector applyBlockPreconditioner(Vector b, Vector x, boolean transpose) { // Recalculate residual if (transpose) A.transMultAdd(-1, x, z.set(b)); else A.multAdd(-1, x, z.set(b)); // Apply block preconditioner on the residual r.set(b); if (transpose) super.transApply(z, r); else super.apply(z, r); return x.add(r); } @Override public void setMatrix(Matrix A) { if (!(A instanceof DistMatrix)) throw new IllegalArgumentException( "A is not a DistRowMatrix or a DistColMatrix"); Matrix Ad = this.A.getBlock(); Matrix Ao = this.A.getOff(); super.setMatrix(A); Arrays.fill(Ai, 0); for (MatrixEntry e : Ad) Ai[rank] += e.get(); if (row) { for (MatrixEntry e : Ao) Ai[indexToRank[e.column()]] += e.get(); comm.gather(Ai, Ai0, root); if (rank == root) for (int i = 0; i < size; ++i) for (int j = 0; j < size; ++j) A0.set(i, j, Ai0[i][j]); } else { for (MatrixEntry e : Ao) Ai[indexToRank[e.row()]] += e.get(); comm.gather(Ai, Ai0, root); if (rank == root) for (int i = 0; i < size; ++i) for (int j = 0; j < size; ++j) A0.set(i, j, Ai0[j][i]); } if (rank == root) lu.factor(A0); } } mtj-0.9.14/src/no/uib/cipr/matrix/distributed/CollectiveCommunications.java0000644000000000000000000002231611467312174025521 0ustar rootroot/* * 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.distributed; import java.lang.reflect.Array; import java.util.ArrayList; import java.util.List; import java.util.concurrent.BrokenBarrierException; import java.util.concurrent.CyclicBarrier; import java.util.concurrent.Exchanger; import no.uib.cipr.matrix.distributed.Communicator.SendRecv; /** * Collective communications between all the participating threads. * * @deprecated the no.uib.cipr.matrix.distributed package has been deprecated because * of a number of hard to fix concurrency bugs. It is distributed only for backwards compatibility, * but is not recommended. The utility of this package is questionable, as it does not allow * distribution of computation between JVMs or across a network. For many people, distributed * computing of multiple matrices can be achieved at a user-level through the * JPPF Framework. * Users who need to deal with few very large matrices may wish to implement their own storage classes * and solvers using JPPF, but this will not be supported directly in matrix-toolkits-java. */ @Deprecated public class CollectiveCommunications { /** * Size of the whole collective */ final int size; /** * Exchanges pipes between the threads. Only used for setup of the * point-to-point communications */ private final List>> ex; /** * Sets up a collective of the given size * * @param size * Number of members of the collective */ public CollectiveCommunications(int size) { if (size < 1) throw new IllegalArgumentException("size < 1"); this.size = size; barrier = new CyclicBarrier(size); broadcast = new Broadcast(); gather = new Gather(); scatter = new Scatter(); allGather = new AllGather(); allToAll = new AllToAll(); reduce = new Reduce(); ex = new ArrayList>>(); for (int i = 0; i < size; ++i) { List> iex = new ArrayList>(); // Get from symmetry for (int j = 0; j < i; ++j) iex.add(ex.get(j).get(i)); // Main diagonal (ignored) iex.add(null); // New entries for (int j = i + 1; j < size; ++j) iex.add(new Exchanger()); ex.add(iex); } } /** * Gets the size of the collective */ public int size() { return size; } /** * Creates a communicator for point-to-point data-exchange. This method * should be called by all the threads in the collective * * @param rank * Rank of the communicator */ public Communicator createCommunicator(int rank) { if (rank < 0 || rank >= size) throw new IllegalArgumentException("rank < 0 || rank >= size"); return new Communicator(rank, ex.get(rank), this); } static void await(CyclicBarrier barrier) { try { barrier.await(); } catch (InterruptedException e) { throw new RuntimeException(e); } catch (BrokenBarrierException e) { throw new RuntimeException(e); } } /** * Blocks the caller until all threads have called */ void barrier() { await(barrier); } private final CyclicBarrier barrier; void broadcast(Object buffer, int root, int rank) { broadcast.buffer[rank] = buffer; if (rank == root) broadcast.root = root; await(broadcast.barrier); } private final Broadcast broadcast; private class Broadcast implements Runnable { final CyclicBarrier barrier = new CyclicBarrier(size, this); int root; final Object[] buffer = new Object[size]; public void run() { int length = Array.getLength(buffer[root]); for (int i = 0; i < size; ++i) System.arraycopy(buffer[root], 0, buffer[i], 0, length); } } void gather(Object sendbuf, Object[] recvbuf, int root, int rank) { gather.setSend(sendbuf, rank); if (rank == root) gather.recvbuf = recvbuf; await(gather.barrier); } private final Gather gather; private class Gather implements Runnable { CyclicBarrier barrier = new CyclicBarrier(size, this); Object[] recvbuf = new Object[size], sendbuf = new Object[size]; private final int[] length = new int[size]; public void setSend(Object sendbuf, int rank) { this.sendbuf[rank] = sendbuf; length[rank] = Array.getLength(sendbuf); } public void run() { for (int i = 0; i < size; ++i) System.arraycopy(sendbuf[i], 0, recvbuf[i], 0, length[i]); } } void scatter(Object[] sendbuf, Object recvbuf, int root, int rank) { scatter.setRecv(recvbuf, rank); if (rank == root) scatter.sendbuf = sendbuf; await(scatter.barrier); } private final Scatter scatter; private class Scatter implements Runnable { final CyclicBarrier barrier = new CyclicBarrier(size, this); Object[] sendbuf = new Object[size], recvbuf = new Object[size]; private final int[] length = new int[size]; public void setRecv(Object recvbuf, int rank) { this.recvbuf[rank] = recvbuf; length[rank] = Array.getLength(recvbuf); } public void run() { for (int i = 0; i < size; ++i) System.arraycopy(sendbuf[i], 0, recvbuf[i], 0, length[i]); } } void allGather(Object sendbuf, Object[] recvbuf, int rank) { allGather.setSendRecv(sendbuf, recvbuf, rank); await(allGather.barrier); } private final AllGather allGather; private class AllGather implements Runnable { final CyclicBarrier barrier = new CyclicBarrier(size, this); private final Object sendbuf[] = new Object[size], recvbuf[][] = new Object[size][size]; private final int[] length = new int[size]; public void setSendRecv(Object send, Object[] recv, int rank) { sendbuf[rank] = send; recvbuf[rank] = recv; length[rank] = Array.getLength(send); } public void run() { for (int i = 0; i < size; ++i) for (int j = 0; j < size; ++j) System .arraycopy(sendbuf[i], 0, recvbuf[j][i], 0, length[i]); } } void allToAll(Object[] sendbuf, Object[] recvbuf, int rank) { allToAll.setSendRecv(sendbuf, recvbuf, rank); await(allToAll.barrier); } private final AllToAll allToAll; private class AllToAll implements Runnable { final CyclicBarrier barrier = new CyclicBarrier(size, this); private final Object[][] sendbuf = new Object[size][size], recvbuf = new Object[size][size]; private final int[][] length = new int[size][size]; public void setSendRecv(Object[] send, Object[] recv, int rank) { sendbuf[rank] = send; recvbuf[rank] = recv; for (int i = 0; i < size; ++i) length[rank][i] = Array.getLength(send[i]); } public void run() { for (int i = 0; i < size; ++i) for (int j = 0; j < size; ++j) System.arraycopy(sendbuf[i][j], 0, recvbuf[j][i], 0, length[i][j]); } } void reduce(Object sendbuf, Object recvbuf, Reduction op, int root, int rank) { reduce.sendbuf[rank] = sendbuf; if (rank == root) { reduce.op = op; reduce.recvbuf = recvbuf; } await(reduce.barrier); } private final Reduce reduce; private class Reduce implements Runnable { CyclicBarrier barrier = new CyclicBarrier(size, this); Reduction op; Object sendbuf[] = new Object[size], recvbuf; public void run() { op.init(recvbuf); for (int i = 0; i < size; ++i) op.op(recvbuf, sendbuf[i]); } } void allReduce(Object sendbuf, Object recvbuf, Reduction op, int rank) { reduce(sendbuf, recvbuf, op, 0, rank); broadcast(recvbuf, 0, rank); } } mtj-0.9.14/src/no/uib/cipr/matrix/distributed/DistRowMatrix.java0000644000000000000000000001671411467312230023275 0ustar rootroot/* * 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.distributed; import java.util.Collection; import java.util.HashSet; import java.util.Iterator; import no.uib.cipr.matrix.Matrix; import no.uib.cipr.matrix.MatrixEntry; import no.uib.cipr.matrix.Vector; /** * Distributed matrix with row major blocks * * @deprecated the no.uib.cipr.matrix.distributed package has been deprecated because * of a number of hard to fix concurrency bugs. It is distributed only for backwards compatibility, * but is not recommended. The utility of this package is questionable, as it does not allow * distribution of computation between JVMs or across a network. For many people, distributed * computing of multiple matrices can be achieved at a user-level through the * JPPF Framework. * Users who need to deal with few very large matrices may wish to implement their own storage classes * and solvers using JPPF, but this will not be supported directly in matrix-toolkits-java. */ @Deprecated public class DistRowMatrix extends DistMatrix { private static final long serialVersionUID = 3258129167668229176L; /** * Constructor for DistRowMatrix * * @param numRows * Global number of rows * @param numColumns * Global number of columns * @param comm * Communicator to use * @param A * Block diagonal matrix. The sum of the local row sizes of * A must equal the global number, and likewise * with the column sizes. * @param B * Off-diagonal matrix part. Its number of columns must equal the * global number of columns, and its number of rows must equal * that of A */ public DistRowMatrix(int numRows, int numColumns, Communicator comm, Matrix A, Matrix B) { super(numRows, numColumns, comm, A, B); if (A.numRows() != B.numRows()) throw new IllegalArgumentException("A.numRows() != B.numRows()"); if (B.numColumns() != numColumns) throw new IllegalArgumentException("B.numColumns() != numColumns"); } @Override public void add(int row, int column, double value) { check(row, column); if (inA(row, column)) A.add(row - n[rank], column - m[rank], value); else if (local(row, column)) B.add(row - n[rank], column, value); else throw new IllegalArgumentException("Row index " + row + " is not local"); } @Override public void set(int row, int column, double value) { check(row, column); if (inA(row, column)) A.set(row - n[rank], column - m[rank], value); else if (local(row, column)) B.set(row - n[rank], column, value); else throw new IllegalArgumentException("Row index " + row + " is not local"); } @Override public double get(int row, int column) { check(row, column); if (inA(row, column)) return A.get(row - n[rank], column - m[rank]); else if (local(row, column)) return B.get(row - n[rank], column); else throw new IndexOutOfBoundsException("Entry not available locally"); } @Override public DistRowMatrix copy() { return new DistRowMatrix(numRows, numColumns, comm, A.copy(), B.copy()); } @Override public Iterator iterator() { return new DistMatrixIterator(n[rank], m[rank], n[rank], 0); } @Override public Vector multAdd(double alpha, Vector x, Vector y) { if (!(x instanceof DistVector && y instanceof DistVector)) throw new IllegalArgumentException("Vectors must be DistVectors"); checkMultAdd(x, y); DistVector xd = (DistVector) x, yd = (DistVector) y; // Recieve the needed components of the global x into the local vector scatter.startScatter(xd, locC); // Local part A.multAdd(alpha, xd.getLocal(), yd.getLocal()); // Finish communications scatter.endSetScatter(xd, locC); // Non-local part B.multAdd(alpha, locC, yd.getLocal()); return y; } @Override public Vector transMultAdd(double alpha, Vector x, Vector y) { if (!(x instanceof DistVector && y instanceof DistVector)) throw new IllegalArgumentException("Vectors must be DistVectors"); checkTransMultAdd(x, y); // y = 1/alpha * y y.scale(1. / alpha); // y = A'x + y = A'x + 1/alpha * y DistVector xd = (DistVector) x, yd = (DistVector) y; // Non-local part B.transMult(xd.getLocal(), locR); // Send it to the others scatter.startGather(locR, yd); // Local part A.transMultAdd(xd.getLocal(), yd.getLocal()); // Finish communications, concluding the matrix product scatter.endAddGather(locR, yd); // y = alpha*y = alpha * A'x + y return y.scale(alpha); } @Override public boolean local(int row, int column) { return row >= n[rank] && row < n[rank + 1]; } int getRank(int row) { int i = 1; for (; i < n.length; ++i) if (row < n[i]) break; return i - 1; } @Override int[] getDelimiter() { return n; } @Override int[] getCommIndices() { // Get the unique row indices from B Collection set = new HashSet(); for (MatrixEntry e : B) if (!local(e.column(), e.column())) set.add(e.column()); // Get an array representation int[] indices = new int[set.size()]; int j = 0; for (Integer i : set) indices[j++] = i; return indices; } @Override protected double norm1() { // Compute local norm double norm = super.norm1(); // Find the maximum double[] recv = new double[1]; comm.allReduce(new double[] { norm }, recv, Reductions.max()); return recv[0]; } @Override protected double normInf() { // Compute as much locally as possible double[] columnSum = new double[numColumns]; for (MatrixEntry e : this) columnSum[e.column()] += Math.abs(e.get()); // Sum in the rest from the other ranks double[] recv = new double[numColumns]; comm.allReduce(columnSum, recv, Reductions.sum()); // The global maximum return max(recv); } @Override public DistRowMatrix zero() { super.zero(); return this; } } mtj-0.9.14/src/no/uib/cipr/matrix/distributed/BlockDiagonalPreconditioner.java0000644000000000000000000000646311467312536026124 0ustar rootroot/* * 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.distributed; import no.uib.cipr.matrix.Matrix; import no.uib.cipr.matrix.Vector; import no.uib.cipr.matrix.sparse.Preconditioner; /** * Block diagonal preconditioner * * @deprecated the no.uib.cipr.matrix.distributed package has been deprecated because * of a number of hard to fix concurrency bugs. It is distributed only for backwards compatibility, * but is not recommended. The utility of this package is questionable, as it does not allow * distribution of computation between JVMs or across a network. For many people, distributed * computing of multiple matrices can be achieved at a user-level through the * JPPF Framework. * Users who need to deal with few very large matrices may wish to implement their own storage classes * and solvers using JPPF, but this will not be supported directly in matrix-toolkits-java. */ @Deprecated public class BlockDiagonalPreconditioner implements Preconditioner { /** * Preconditioner to apply on the block */ private Preconditioner prec; /** * Constructor for BlockDiagonalPreconditioner * * @param prec * Preconditioner to apply on the blocks. As this preconditioner * is meant to be used for distributed memory matrices, the * preconditioner should be constructed on * A.getBlock() */ public BlockDiagonalPreconditioner(Preconditioner prec) { this.prec = prec; } public Vector apply(Vector b, Vector x) { if (!(b instanceof DistVector) || !(x instanceof DistVector)) throw new IllegalArgumentException("Vectors must be DistVectors"); return prec.apply(((DistVector) b).getLocal(), ((DistVector) x) .getLocal()); } public Vector transApply(Vector b, Vector x) { if (!(b instanceof DistVector) || !(x instanceof DistVector)) throw new IllegalArgumentException("Vectors must be DistVectors"); return prec.transApply(((DistVector) b).getLocal(), ((DistVector) x) .getLocal()); } public void setMatrix(Matrix A) { if (A instanceof DistRowMatrix) prec.setMatrix(((DistRowMatrix) A).getBlock()); else if (A instanceof DistColMatrix) prec.setMatrix(((DistColMatrix) A).getBlock()); else throw new IllegalArgumentException( "!(A instanceof DistRowMatrix) && !(A instanceof DistColMatrix)"); } } mtj-0.9.14/src/no/uib/cipr/matrix/distributed/package.html0000644000000000000000000000153111467312356022133 0ustar rootroot Message passing interface (MPI) for Java. Includes memory-distributed matrices and vectors.

DEPRECATED: the no.uib.cipr.matrix.distributed package has been deprecated because of a number of hard to fix concurrency bugs. It is distributed only for backwards compatibility, but is not recommended. The utility of this package is questionable, as it does not allow distribution of computation between JVMs or across a network. For many people, distributed computing of multiple matrices can be achieved at a user-level through the JPPF Framework. Users who need to deal with few very large matrices may wish to implement their own storage classes and solvers using JPPF, but this will not be supported directly in matrix-toolkits-java. mtj-0.9.14/src/no/uib/cipr/matrix/distributed/DistColMatrix.java0000644000000000000000000001674011467312220023241 0ustar rootroot/* * 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.distributed; import java.util.Collection; import java.util.HashSet; import java.util.Iterator; import no.uib.cipr.matrix.Matrix; import no.uib.cipr.matrix.MatrixEntry; import no.uib.cipr.matrix.Vector; /** * Distributed matrix with column major blocks * * @deprecated the no.uib.cipr.matrix.distributed package has been deprecated because * of a number of hard to fix concurrency bugs. It is distributed only for backwards compatibility, * but is not recommended. The utility of this package is questionable, as it does not allow * distribution of computation between JVMs or across a network. For many people, distributed * computing of multiple matrices can be achieved at a user-level through the * JPPF Framework. * Users who need to deal with few very large matrices may wish to implement their own storage classes * and solvers using JPPF, but this will not be supported directly in matrix-toolkits-java. */ @Deprecated public class DistColMatrix extends DistMatrix { private static final long serialVersionUID = 3618421523053359673L; /** * Constructor for DistColMatrix * * @param numRows * Global number of rows * @param numColumns * Global number of columns * @param comm * Communicator to use * @param A * Block diagonal matrix. The sum of the local row sizes of * A must equal the global number, and likewise * with the column sizes. * @param B * Off-diagonal matrix part. Its number of rows must equal the * global number of rows, and its number of columns must equal * that of A */ public DistColMatrix(int numRows, int numColumns, Communicator comm, Matrix A, Matrix B) { super(numRows, numColumns, comm, A, B); if (A.numColumns() != B.numColumns()) throw new IllegalArgumentException( "A.numColumns() != B.numColumns()"); if (B.numRows() != numRows) throw new IllegalArgumentException("B.numRows() != numRows"); } @Override public void add(int row, int column, double value) { check(row, column); if (inA(row, column)) A.add(row - n[rank], column - m[rank], value); else if (local(row, column)) B.add(row, column - m[rank], value); else throw new IllegalArgumentException("Column index " + column + " is not local"); } @Override public void set(int row, int column, double value) { check(row, column); if (inA(row, column)) A.set(row - n[rank], column - m[rank], value); else if (local(row, column)) B.set(row, column - m[rank], value); else throw new IllegalArgumentException("Column index " + column + " is not local"); } @Override public double get(int row, int column) { check(row, column); if (inA(row, column)) return A.get(row - n[rank], column - m[rank]); else if (local(row, column)) return B.get(row, column - m[rank]); else throw new IndexOutOfBoundsException("Entry not available locally"); } @Override public DistColMatrix copy() { return new DistColMatrix(numRows, numColumns, comm, A.copy(), B.copy()); } @Override public Iterator iterator() { return new DistMatrixIterator(n[rank], m[rank], 0, m[rank]); } @Override public Vector multAdd(double alpha, Vector x, Vector y) { if (!(x instanceof DistVector && y instanceof DistVector)) throw new IllegalArgumentException("Vectors must be DistVectors"); checkMultAdd(x, y); // y = 1/alpha * y y.scale(1. / alpha); // y = A*x + y = A*x + 1/alpha * y DistVector xd = (DistVector) x, yd = (DistVector) y; // Non-local part B.mult(xd.getLocal(), locR); // Send it to the others scatter.startGather(locR, yd); // Local part A.multAdd(xd.getLocal(), yd.getLocal()); // Finish communications, concluding the matrix product scatter.endAddGather(locR, yd); // y = alpha*y = alpha * A*x + y return y.scale(alpha); } @Override public Vector transMultAdd(double alpha, Vector x, Vector y) { if (!(x instanceof DistVector && y instanceof DistVector)) throw new IllegalArgumentException("Vectors must be DistVectors"); checkTransMultAdd(x, y); DistVector xd = (DistVector) x, yd = (DistVector) y; // Recieve the needed components of the global x into the local vector scatter.startScatter(xd, locC); // Local part A.transMultAdd(alpha, xd.getLocal(), yd.getLocal()); // Finish communications scatter.endSetScatter(xd, locC); // Non-local part B.transMultAdd(alpha, locC, yd.getLocal()); return y; } @Override public boolean local(int row, int column) { return column >= m[rank] && column < m[rank + 1]; } int getRank(int column) { int i = 1; for (; i < m.length; ++i) if (column < m[i]) break; return i - 1; } @Override int[] getDelimiter() { return m; } @Override int[] getCommIndices() { // Get the unique row indices from B Collection set = new HashSet(); for (MatrixEntry e : B) if (!local(e.row(), e.row())) set.add(e.row()); // Get an array representation int[] indices = new int[set.size()]; int j = 0; for (Integer i : set) indices[j++] = i; return indices; } @Override protected double norm1() { // Compute as much locally as possible double[] rowSum = new double[numRows]; for (MatrixEntry e : this) rowSum[e.row()] += Math.abs(e.get()); // Sum in the rest from the other ranks double[] recv = new double[numRows]; comm.allReduce(rowSum, recv, Reductions.sum()); // The global maximum return max(recv); } @Override protected double normInf() { // Compute local norm double norm = super.normInf(); // Find the maximum double[] recv = new double[1]; comm.allReduce(new double[] { norm }, recv, Reductions.max()); return recv[0]; } @Override public DistColMatrix zero() { super.zero(); return this; } } mtj-0.9.14/src/no/uib/cipr/matrix/distributed/Reductions.java0000644000000000000000000003527611467312246022647 0ustar rootroot/* * 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.distributed; /** * Contains predefined reductions * * @deprecated the no.uib.cipr.matrix.distributed package has been deprecated because * of a number of hard to fix concurrency bugs. It is distributed only for backwards compatibility, * but is not recommended. The utility of this package is questionable, as it does not allow * distribution of computation between JVMs or across a network. For many people, distributed * computing of multiple matrices can be achieved at a user-level through the * JPPF Framework. * Users who need to deal with few very large matrices may wish to implement their own storage classes * and solvers using JPPF, but this will not be supported directly in matrix-toolkits-java. */ @Deprecated public class Reductions { private Reductions() { // No need to instantiate } public static Reduction sum() { return new Sum(); } public static Reduction product() { return new Product(); } public static Reduction max() { return new Max(); } public static Reduction min() { return new Min(); } public static Reduction and() { return new And(); } public static Reduction or() { return new Or(); } /** * Does a sum */ private static class Sum extends NumericalReduction { @Override protected void initByte(byte[] x) { for (int i = 0; i < x.length; ++i) x[i] = 0; } @Override protected void initChar(char[] x) { for (int i = 0; i < x.length; ++i) x[i] = 0; } @Override protected void initShort(short[] x) { for (int i = 0; i < x.length; ++i) x[i] = 0; } @Override protected void initInt(int[] x) { for (int i = 0; i < x.length; ++i) x[i] = 0; } @Override protected void initFloat(float[] x) { for (int i = 0; i < x.length; ++i) x[i] = 0; } @Override protected void initLong(long[] x) { for (int i = 0; i < x.length; ++i) x[i] = 0; } @Override protected void initDouble(double[] x) { for (int i = 0; i < x.length; ++i) x[i] = 0; } @Override protected void opByte(byte[] x, byte[] y) { assert x.length == y.length; for (int i = 0; i < x.length; ++i) x[i] += y[i]; } @Override protected void opChar(char[] x, char[] y) { assert x.length == y.length; for (int i = 0; i < x.length; ++i) x[i] += y[i]; } @Override protected void opShort(short[] x, short[] y) { assert x.length == y.length; for (int i = 0; i < x.length; ++i) x[i] += y[i]; } @Override protected void opInt(int[] x, int[] y) { assert x.length == y.length; for (int i = 0; i < x.length; ++i) x[i] += y[i]; } @Override protected void opFloat(float[] x, float[] y) { assert x.length == y.length; for (int i = 0; i < x.length; ++i) x[i] += y[i]; } @Override protected void opLong(long[] x, long[] y) { assert x.length == y.length; for (int i = 0; i < x.length; ++i) x[i] += y[i]; } @Override protected void opDouble(double[] x, double[] y) { assert x.length == y.length; for (int i = 0; i < x.length; ++i) x[i] += y[i]; } } /** * Multiplies the elements */ private static class Product extends NumericalReduction { @Override protected void initByte(byte[] x) { for (int i = 0; i < x.length; ++i) x[i] = 1; } @Override protected void initChar(char[] x) { for (int i = 0; i < x.length; ++i) x[i] = 1; } @Override protected void initShort(short[] x) { for (int i = 0; i < x.length; ++i) x[i] = 1; } @Override protected void initInt(int[] x) { for (int i = 0; i < x.length; ++i) x[i] = 1; } @Override protected void initFloat(float[] x) { for (int i = 0; i < x.length; ++i) x[i] = 1; } @Override protected void initLong(long[] x) { for (int i = 0; i < x.length; ++i) x[i] = 1; } @Override protected void initDouble(double[] x) { for (int i = 0; i < x.length; ++i) x[i] = 1; } @Override protected void opByte(byte[] x, byte[] y) { for (int i = 0; i < x.length; ++i) x[i] *= y[i]; } @Override protected void opChar(char[] x, char[] y) { for (int i = 0; i < x.length; ++i) x[i] *= y[i]; } @Override protected void opShort(short[] x, short[] y) { for (int i = 0; i < x.length; ++i) x[i] *= y[i]; } @Override protected void opInt(int[] x, int[] y) { for (int i = 0; i < x.length; ++i) x[i] *= y[i]; } @Override protected void opFloat(float[] x, float[] y) { for (int i = 0; i < x.length; ++i) x[i] *= y[i]; } @Override protected void opLong(long[] x, long[] y) { for (int i = 0; i < x.length; ++i) x[i] *= y[i]; } @Override protected void opDouble(double[] x, double[] y) { for (int i = 0; i < x.length; ++i) x[i] *= y[i]; } } /** * Finds max */ private static class Max extends NumericalReduction { @Override protected void initByte(byte[] x) { for (int i = 0; i < x.length; ++i) x[i] = Byte.MIN_VALUE; } @Override protected void initChar(char[] x) { for (int i = 0; i < x.length; ++i) x[i] = Character.MIN_VALUE; } @Override protected void initShort(short[] x) { for (int i = 0; i < x.length; ++i) x[i] = Short.MIN_VALUE; } @Override protected void initInt(int[] x) { for (int i = 0; i < x.length; ++i) x[i] = Integer.MIN_VALUE; } @Override protected void initFloat(float[] x) { for (int i = 0; i < x.length; ++i) x[i] = Float.MIN_VALUE; } @Override protected void initLong(long[] x) { for (int i = 0; i < x.length; ++i) x[i] = Long.MIN_VALUE; } @Override protected void initDouble(double[] x) { for (int i = 0; i < x.length; ++i) x[i] = Double.MIN_VALUE; } @Override protected void opByte(byte[] x, byte[] y) { for (int i = 0; i < x.length; ++i) x[i] = (byte) Math.max(x[i], y[i]); } @Override protected void opChar(char[] x, char[] y) { for (int i = 0; i < x.length; ++i) x[i] = (char) Math.max(x[i], y[i]); } @Override protected void opShort(short[] x, short[] y) { for (int i = 0; i < x.length; ++i) x[i] = (short) Math.max(x[i], y[i]); } @Override protected void opInt(int[] x, int[] y) { for (int i = 0; i < x.length; ++i) x[i] = Math.max(x[i], y[i]); } @Override protected void opFloat(float[] x, float[] y) { for (int i = 0; i < x.length; ++i) x[i] = Math.max(x[i], y[i]); } @Override protected void opLong(long[] x, long[] y) { for (int i = 0; i < x.length; ++i) x[i] = Math.max(x[i], y[i]); } @Override protected void opDouble(double[] x, double[] y) { for (int i = 0; i < x.length; ++i) x[i] = Math.max(x[i], y[i]); } } /** * Finds min */ private static class Min extends NumericalReduction { @Override protected void initByte(byte[] x) { for (int i = 0; i < x.length; ++i) x[i] = Byte.MAX_VALUE; } @Override protected void initChar(char[] x) { for (int i = 0; i < x.length; ++i) x[i] = Character.MAX_VALUE; } @Override protected void initShort(short[] x) { for (int i = 0; i < x.length; ++i) x[i] = Short.MAX_VALUE; } @Override protected void initInt(int[] x) { for (int i = 0; i < x.length; ++i) x[i] = Integer.MAX_VALUE; } @Override protected void initFloat(float[] x) { for (int i = 0; i < x.length; ++i) x[i] = Float.MAX_VALUE; } @Override protected void initLong(long[] x) { for (int i = 0; i < x.length; ++i) x[i] = Long.MAX_VALUE; } @Override protected void initDouble(double[] x) { for (int i = 0; i < x.length; ++i) x[i] = Double.MAX_VALUE; } @Override protected void opByte(byte[] x, byte[] y) { for (int i = 0; i < x.length; ++i) x[i] = (byte) Math.min(x[i], y[i]); } @Override protected void opChar(char[] x, char[] y) { for (int i = 0; i < x.length; ++i) x[i] = (char) Math.min(x[i], y[i]); } @Override protected void opShort(short[] x, short[] y) { for (int i = 0; i < x.length; ++i) x[i] = (short) Math.min(x[i], y[i]); } @Override protected void opInt(int[] x, int[] y) { for (int i = 0; i < x.length; ++i) x[i] = Math.min(x[i], y[i]); } @Override protected void opFloat(float[] x, float[] y) { for (int i = 0; i < x.length; ++i) x[i] = Math.min(x[i], y[i]); } @Override protected void opLong(long[] x, long[] y) { for (int i = 0; i < x.length; ++i) x[i] = Math.min(x[i], y[i]); } @Override protected void opDouble(double[] x, double[] y) { for (int i = 0; i < x.length; ++i) x[i] = Math.min(x[i], y[i]); } } private static abstract class NumericalReduction extends Reduction { @Override protected void initBoolean(boolean[] x) { throw new UnsupportedOperationException(); } @Override protected void opBoolean(boolean[] x, boolean[] y) { throw new UnsupportedOperationException(); } } private static abstract class BooleanReduction extends Reduction { @Override protected void initByte(byte[] x) { throw new UnsupportedOperationException(); } @Override protected void initChar(char[] x) { throw new UnsupportedOperationException(); } @Override protected void initShort(short[] x) { throw new UnsupportedOperationException(); } @Override protected void initInt(int[] x) { throw new UnsupportedOperationException(); } @Override protected void initFloat(float[] x) { throw new UnsupportedOperationException(); } @Override protected void initLong(long[] x) { throw new UnsupportedOperationException(); } @Override protected void initDouble(double[] x) { throw new UnsupportedOperationException(); } @Override protected void opByte(byte[] x, byte[] y) { throw new UnsupportedOperationException(); } @Override protected void opChar(char[] x, char[] y) { throw new UnsupportedOperationException(); } @Override protected void opShort(short[] x, short[] y) { throw new UnsupportedOperationException(); } @Override protected void opInt(int[] x, int[] y) { throw new UnsupportedOperationException(); } @Override protected void opFloat(float[] x, float[] y) { throw new UnsupportedOperationException(); } @Override protected void opLong(long[] x, long[] y) { throw new UnsupportedOperationException(); } @Override protected void opDouble(double[] x, double[] y) { throw new UnsupportedOperationException(); } } /** * And boolean reduction */ private static class And extends BooleanReduction { @Override protected void initBoolean(boolean[] x) { for (int i = 0; i < x.length; ++i) x[i] = true; } @Override protected void opBoolean(boolean[] x, boolean[] y) { for (int i = 0; i < x.length; ++i) x[i] &= y[i]; } } /** * Or boolean reduction */ private static class Or extends BooleanReduction { @Override protected void initBoolean(boolean[] x) { for (int i = 0; i < x.length; ++i) x[i] = false; } @Override protected void opBoolean(boolean[] x, boolean[] y) { for (int i = 0; i < x.length; ++i) x[i] |= y[i]; } } } mtj-0.9.14/src/no/uib/cipr/matrix/distributed/Reduction.java0000644000000000000000000001076611467312242022455 0ustar rootroot/* * 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.distributed; /** * Performs a reduction operation. When performing a reduction, start with the * value return by the init function, for example: * *

 * int[] x, y;
 * Reduction r;
 * // ...
 * r.initInt(x);
 * r.opInt(x, y);
 * 
* *

* Many predefined reductions are available in * {@link no.uib.cipr.matrix.distributed.Reductions}. *

* * @deprecated the no.uib.cipr.matrix.distributed package has been deprecated because * of a number of hard to fix concurrency bugs. It is distributed only for backwards compatibility, * but is not recommended. The utility of this package is questionable, as it does not allow * distribution of computation between JVMs or across a network. For many people, distributed * computing of multiple matrices can be achieved at a user-level through the * JPPF Framework. * Users who need to deal with few very large matrices may wish to implement their own storage classes * and solvers using JPPF, but this will not be supported directly in matrix-toolkits-java. */ @Deprecated public abstract class Reduction { /** * Sets up the output data */ public void init(Object x) { if (x instanceof double[]) initDouble((double[]) x); else if (x instanceof int[]) initInt((int[]) x); else if (x instanceof boolean[]) initBoolean((boolean[]) x); else if (x instanceof byte[]) initByte((byte[]) x); else if (x instanceof char[]) initChar((char[]) x); else if (x instanceof short[]) initShort((short[]) x); else if (x instanceof long[]) initLong((long[]) x); else if (x instanceof float[]) initFloat((float[]) x); else throw new IllegalArgumentException("Datatype is not supported"); } /** * Adds to the output data * * @param x * Output data * @param y * New input data */ public void op(Object x, Object y) { if (x instanceof double[]) opDouble((double[]) x, (double[]) y); else if (x instanceof int[]) opInt((int[]) x, (int[]) y); else if (x instanceof boolean[]) opBoolean((boolean[]) x, (boolean[]) y); else if (x instanceof byte[]) opByte((byte[]) x, (byte[]) y); else if (x instanceof char[]) opChar((char[]) x, (char[]) y); else if (x instanceof short[]) opShort((short[]) x, (short[]) y); else if (x instanceof long[]) opLong((long[]) x, (long[]) y); else if (x instanceof float[]) opFloat((float[]) x, (float[]) y); else throw new IllegalArgumentException("Datatype is not supported"); } protected abstract void initBoolean(boolean[] x); protected abstract void initByte(byte[] x); protected abstract void initChar(char[] x); protected abstract void initShort(short[] x); protected abstract void initInt(int[] x); protected abstract void initFloat(float[] x); protected abstract void initLong(long[] x); protected abstract void initDouble(double[] x); protected abstract void opBoolean(boolean[] x, boolean[] y); protected abstract void opByte(byte[] x, byte[] y); protected abstract void opChar(char[] x, char[] y); protected abstract void opShort(short[] x, short[] y); protected abstract void opInt(int[] x, int[] y); protected abstract void opFloat(float[] x, float[] y); protected abstract void opLong(long[] x, long[] y); protected abstract void opDouble(double[] x, double[] y); }mtj-0.9.14/src/no/uib/cipr/matrix/distributed/DistMatrix.java0000644000000000000000000002400211467312224022575 0ustar rootroot/* * 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.distributed; import java.util.Arrays; import java.util.Iterator; import no.uib.cipr.matrix.AbstractMatrix; import no.uib.cipr.matrix.DenseVector; import no.uib.cipr.matrix.Matrix; import no.uib.cipr.matrix.MatrixEntry; import no.uib.cipr.matrix.Vector; import no.uib.cipr.matrix.distributed.SuperIterator.SuperIteratorEntry; /** * Distributed memory matrix * * @deprecated the no.uib.cipr.matrix.distributed package has been deprecated because * of a number of hard to fix concurrency bugs. It is distributed only for backwards compatibility, * but is not recommended. The utility of this package is questionable, as it does not allow * distribution of computation between JVMs or across a network. For many people, distributed * computing of multiple matrices can be achieved at a user-level through the * JPPF Framework. * Users who need to deal with few very large matrices may wish to implement their own storage classes * and solvers using JPPF, but this will not be supported directly in matrix-toolkits-java. */ @Deprecated abstract class DistMatrix extends AbstractMatrix { /** * Communicator in use */ final Communicator comm; /** * Block diagonal part */ final Matrix A; /** * Off-diagonal part */ final Matrix B; /** * Offsets into the local matrix */ final int[] n, m; /** * Rank and size of the communicator */ final int rank, size; /** * Local vector caches, for scatter/gather operations. The first with size * equal numRows, the other of numColumns size */ final Vector locR, locC; /** * Scatters global vectors into local, and the other way around */ final VectorScatter scatter; /** * Constructor for DistMatrix */ public DistMatrix(int numRows, int numColumns, Communicator comm, Matrix A, Matrix B) { super(numRows, numColumns); this.comm = comm; this.A = A; this.B = B; locR = new DenseVector(numRows); locC = new DenseVector(numColumns); rank = comm.rank(); size = comm.size(); n = new int[size + 1]; m = new int[size + 1]; // Find out the sizes of all the parts of the distributed vector int[] send = new int[] { A.numRows(), A.numColumns() }; int[][] recv = new int[size][2]; comm.allGather(send, recv); for (int i = 0; i < size; ++i) { n[i + 1] = n[i] + recv[i][0]; // rows m[i + 1] = m[i] + recv[i][1]; // columns } if (n[size] != numRows) throw new IllegalArgumentException("Sum of local row sizes (" + n[size] + ") do not match the global row size (" + numRows + ")"); if (m[size] != numColumns) throw new IllegalArgumentException("Sum of local column sizes (" + m[size] + ") do not match the global column size (" + numColumns + ")"); scatter = scatterSetup(); } /** * Sets up vector scatter for matrix/vector products. Collective operation */ private VectorScatter scatterSetup() { // Get all the indices needing communication int[] ind = getCommIndices(); Arrays.sort(ind); // Find who owns what int[] N = getDelimiter(); // Then get the number of entries to recieve and their indices int[][] recv = new int[size][1]; int[][] recvI = new int[size][]; for (int k = 0, i = 0; k < size; ++k) { // Number of entries for (int l = 0, I = i; I < ind.length && ind[I] < N[k + 1]; ++I, ++l) recv[k][0]++; // The indices recvI[k] = new int[recv[k][0]]; for (int l = 0, I = i; I < ind.length && ind[I] < N[k + 1]; ++I, ++l) recvI[k][l] = ind[I]; i += recv[k][0]; } // Get the number of entries to send int[][] send = new int[size][1]; comm.allToAll(recv, send); // Then the indices to send int[][] sendI = new int[size][]; for (int i = 0; i < size; ++i) sendI[i] = new int[send[i][0]]; // Send what we need to recieve, and in return, get what the other // threads need comm.allToAll(recvI, sendI); // Create vector scatter object return new VectorScatter(comm, sendI, recvI); } /** * Returns delimiters */ abstract int[] getDelimiter(); /** * Returns indices needing communication (off the block diagonal) */ abstract int[] getCommIndices(); /** * Returns which rows are owned by which ranks. The current rank owns the * rows n[comm.rank()] (inclusive) to * n[comm.rank()+1] (exclusive) */ public int[] getRowOwnerships() { return n; } /** * Returns which columns are owned by which ranks. The current rank owns the * columns m[comm.rank()] (inclusive) to * m[comm.rank()+1] (exclusive) */ public int[] getColumnOwnerships() { return m; } /** * Returns the diagonal block matrix */ public Matrix getBlock() { return A; } /** * Returns the off-diagonal matrix */ public Matrix getOff() { return B; } @Override public DistMatrix zero() { A.zero(); B.zero(); return this; } @Override protected double max() { // Compute local norms double normA = A.norm(Norm.Maxvalue), normB = B.norm(Norm.Maxvalue); // Find global maximum double[] recv = new double[2]; comm.allReduce(new double[] { normA, normB }, recv, Reductions.max()); return recv[0] + recv[1]; } @Override protected double normF() { // Compute local norms double normA = A.norm(Norm.Frobenius), normB = B.norm(Norm.Frobenius); normA *= normA; normB *= normB; // Sum the global norms double[] recv = new double[2]; comm.allReduce(new double[] { normA, normB }, recv, Reductions.sum()); return Math.sqrt(recv[0] + recv[1]); } /** * Returns true if the insertion indices are local to this rank, and no * communication is required afterwards. However, you still need to call * flushAssembly to set up things like matrix/vector * multiplication */ public abstract boolean local(int row, int column); boolean inA(int row, int column) { return row >= n[rank] && row < n[rank + 1] && column >= m[rank] && column < m[rank + 1]; } @Override public Matrix rank1(double alpha, Vector x, Vector y) { throw new UnsupportedOperationException(); } @Override public Matrix rank2(double alpha, Vector x, Vector y) { throw new UnsupportedOperationException(); } /** * Gets the communicator associated with this matrix */ public Communicator getCommunicator() { return comm; } /** * Iterator for a distributed memory matrix */ class DistMatrixIterator implements Iterator { /** * Iterates over each column vector */ private SuperIterator iterator; /** * Entry returned */ private DistMatrixEntry entry; private int rowAOffset, columnAOffset, rowBOffset, columnBOffset; public DistMatrixIterator(int rowAOffset, int columnAOffset, int rowBOffset, int columnBOffset) { this.rowAOffset = rowAOffset; this.rowBOffset = rowBOffset; this.columnAOffset = columnAOffset; this.columnBOffset = columnBOffset; iterator = new SuperIterator(Arrays.asList(A, B)); entry = new DistMatrixEntry(); } public boolean hasNext() { return iterator.hasNext(); } public MatrixEntry next() { SuperIteratorEntry se = iterator.next(); if (se.index() == 0) // Block diagonal part entry.update(rowAOffset, columnAOffset, se.get()); else // Off diagonal block entry.update(rowBOffset, columnBOffset, se.get()); return entry; } public void remove() { iterator.remove(); } } /** * Entry of a distributed memory matrix */ private static class DistMatrixEntry implements MatrixEntry { private int row, column; private MatrixEntry entry; public void update(int rowOffset, int columnOffset, MatrixEntry entry) { row = rowOffset + entry.row(); column = columnOffset + entry.column(); this.entry = entry; } public int row() { return row; } public int column() { return column; } public double get() { return entry.get(); } public void set(double value) { entry.set(value); } } } mtj-0.9.14/src/no/uib/cipr/matrix/PackCholesky.java0000644000000000000000000001462411034475754020564 0ustar rootroot/* * 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 no.uib.cipr.matrix.Matrix.Norm; import org.netlib.lapack.LAPACK; import org.netlib.util.doubleW; import org.netlib.util.intW; /** * Packed Cholesky decomposition */ public class PackCholesky { /** * Matrix dimension */ private final int n; /** * Cholesky decomposition of a lower matrix */ private LowerTriangPackMatrix Cl; /** * Cholesky decomposition of an upper matrix */ private UpperTriangPackMatrix Cu; /** * If the matrix is SPD or not */ private boolean notspd; /** * True for upper part, else false */ private final boolean upper; /** * Constructor for DenseCholesky * * @param n * Matrix size * @param upper * True for decomposing an upper symmetrical matrix, false for a * lower symmetrical matrix */ public PackCholesky(int n, boolean upper) { this.n = n; this.upper = upper; if (upper) Cu = new UpperTriangPackMatrix(n); else Cl = new LowerTriangPackMatrix(n); } /** * Calculates a Cholesky decomposition * * @param A * Matrix to decompose. Not modified * @return The current decomposition */ public static PackCholesky factorize(Matrix A) { return new PackCholesky(A.numRows(), true) .factor(new UpperSPDPackMatrix(A)); } /** * Calculates a Cholesky decomposition * * @param A * Matrix to decompose. Overwritten on return * @return The current decomposition */ public PackCholesky factor(LowerSPDPackMatrix A) { if (upper) throw new IllegalArgumentException( "Cholesky decomposition constructed for upper matrices"); return decompose(A); } /** * Calculates a Cholesky decomposition * * @param A * Matrix to decompose. Overwritten on return * @return The current decomposition */ public PackCholesky factor(UpperSPDPackMatrix A) { if (!upper) throw new IllegalArgumentException( "Cholesky decomposition constructed for lower matrices"); return decompose(A); } private PackCholesky decompose(AbstractPackMatrix A) { if (n != A.numRows()) throw new IllegalArgumentException("n != A.numRows()"); notspd = false; intW info = new intW(0); if (upper) LAPACK.getInstance().dpptrf(UpLo.Upper.netlib(), A.numRows(), A.getData(), info); else LAPACK.getInstance().dpptrf(UpLo.Lower.netlib(), A.numRows(), A.getData(), info); if (info.val > 0) notspd = true; else if (info.val < 0) throw new IllegalArgumentException(); if (upper) Cu.set(A); else Cl.set(A); return this; } /** * Returns true if the matrix decomposed is symmetrical, positive definite */ public boolean isSPD() { return !notspd; } /** * Returns the decomposition matrix. Only valid for decomposition of a lower * SPD matrix */ public LowerTriangPackMatrix getL() { if (!upper) return Cl; else throw new UnsupportedOperationException(); } /** * Returns the decomposition matrix. Only valid for decomposition of a upper * SPD matrix */ public UpperTriangPackMatrix getU() { if (upper) return Cu; else throw new UnsupportedOperationException(); } /** * Solves for B, overwriting it on return */ public DenseMatrix solve(DenseMatrix B) throws MatrixNotSPDException { if (notspd) throw new MatrixNotSPDException(); if (B.numRows() != n) throw new IllegalArgumentException("B.numRows() != n"); intW info = new intW(0); if (upper) LAPACK.getInstance().dpptrs(UpLo.Upper.netlib(), Cu.numRows(), B.numColumns(), Cu.getData(), B.getData(), Matrices.ld(Cu.numRows()), info); else LAPACK.getInstance().dpptrs(UpLo.Lower.netlib(), Cl.numRows(), B.numColumns(), Cl.getData(), B.getData(), Matrices.ld(Cl.numRows()), info); if (info.val < 0) throw new IllegalArgumentException(); return B; } /** * Computes the reciprocal condition number * * @param A * The matrix this is a decomposition of * @return The reciprocal condition number. Values close to unity indicate a * well-conditioned system, while numbers close to zero do not. */ public double rcond(Matrix A) { if (A.numRows() != n) throw new IllegalArgumentException("A.numRows() != n"); if (!A.isSquare()) throw new IllegalArgumentException("!A.isSquare()"); double anorm = A.norm(Norm.One); double[] work = new double[3 * n]; int[] iwork = new int[n]; intW info = new intW(0); doubleW rcond = new doubleW(0); if (upper) LAPACK.getInstance().dppcon(UpLo.Upper.netlib(), n, Cu.getData(), anorm, rcond, work, iwork, info); else LAPACK.getInstance().dppcon(UpLo.Lower.netlib(), n, Cl.getData(), anorm, rcond, work, iwork, info); if (info.val < 0) throw new IllegalArgumentException(); return rcond.val; } } mtj-0.9.14/src/no/uib/cipr/matrix/SPDTridiagMatrix.java0000644000000000000000000000551011027512662021305 0ustar rootroot/* * 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 org.netlib.lapack.LAPACK; import org.netlib.util.intW; /** * Symmetrical positive definite tridiagonal matrix. Same as * {@link no.uib.cipr.matrix.SymmTridiagMatrix SymmTridiagMatrix}, and is used * as a marker class to allow for more efficient solvers. */ public class SPDTridiagMatrix extends SymmTridiagMatrix { /** * Constructor for SPDTridiagMatrix * * @param n * Size of the matrix. Since the matrix must be square, this * equals both the number of rows and columns */ public SPDTridiagMatrix(int n) { super(n); } /** * Constructor for SPDTridiagMatrix * * @param A * Matrix to copy contents from. Only main and the superdiagonal * is copied over */ public SPDTridiagMatrix(Matrix A) { super(A); } /** * Constructor for SPDTridiagMatrix * * @param A * Matrix to copy contents from. Only main and the superdiagonal * is copied over * @param deep * True for a deep copy. For shallow copies A must * be a SymmTridiagMatrix */ public SPDTridiagMatrix(Matrix A, boolean deep) { super(A, deep); } @Override public SPDTridiagMatrix copy() { return new SPDTridiagMatrix(this); } @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); intW info = new intW(0); LAPACK.getInstance().dptsv(numRows, X.numColumns(), diag.clone(), offDiag.clone(), Xd, Matrices.ld(numRows), info); if (info.val > 0) throw new MatrixNotSPDException(); else if (info.val < 0) throw new IllegalArgumentException(); return X; } } mtj-0.9.14/src/no/uib/cipr/matrix/MatrixSingularException.java0000644000000000000000000000254011027512662023016 0ustar rootroot/* * 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; /** * Matrix is singular */ public class MatrixSingularException extends RuntimeException { private static final long serialVersionUID = -8054618754675367225L; /** * Constructor for MatrixSingularException */ public MatrixSingularException() { super(); } /** * Constructor for MatrixSingularException * * @param message * Description of the exception */ public MatrixSingularException(String message) { super(message); } } mtj-0.9.14/src/no/uib/cipr/matrix/AbstractMatrix.java0000644000000000000000000006522211165464734021135 0ustar rootroot/* * 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.Formatter; import java.util.Iterator; /** * Partial implementation of Matrix. The following methods throw * UnsupportedOperationException, and should be overridden by a * subclass: *
    *
  • get(int,int)
  • *
  • set(int,int,double)
  • *
  • copy
  • *
  • All the direct solution methods
  • *
*

* For the rest of the methods, simple default implementations using a matrix * iterator has been provided. There are some kernel operations which the * simpler operations forward to, for instance, mult(Matrix,Matrix) * forwards to multAdd(double,Matrix,Matrix). Subclasses can * thus focus on overriding the kernel operations, which are: *

    *
  • multAdd(double,Vector,Vector) and * transMultAdd(double,Vector,Vector).
  • *
  • rank1(double,Vector,Vector) and * rank1(double,Vector,Vector).
  • *
  • multAdd(double,Matrix,Matrix), * transAmultAdd(double,Matrix,Matrix), * transBmultAdd(double,Matrix,Matrix), and * transABmultAdd(double,Matrix,Matrix).
  • *
  • scale(double).
  • *
  • set(double,Matrix) and add(double,Matrix). *
  • *
  • transpose and transpose(Matrix).
  • *
  • All the norms.
  • *
*

* Finally, a default iterator is provided by this class, which works by calling * the get function. A tailored replacement should be used by * subclasses. * */ public abstract class AbstractMatrix implements Matrix { /** * Number of rows */ protected int numRows; /** * Number of columns */ protected int numColumns; /** * Constructor for AbstractMatrix */ protected AbstractMatrix(int numRows, int numColumns) { if (numRows < 0 || numColumns < 0) throw new IndexOutOfBoundsException( "Matrix size cannot be negative"); this.numRows = numRows; this.numColumns = numColumns; } /** * Constructor for AbstractMatrix, same size as A. The invoking constructor * should set this matrix equal the argument matrix */ protected AbstractMatrix(Matrix A) { this(A.numRows(), A.numColumns()); } public int numRows() { return numRows; } public int numColumns() { return numColumns; } public boolean isSquare() { return numRows == numColumns; } public void set(int row, int column, double value) { throw new UnsupportedOperationException(); } public void add(int row, int column, double value) { set(row, column, value + get(row, column)); } public double get(int row, int column) { throw new UnsupportedOperationException(); } /** * Checks the passed row and column indices */ protected void check(int row, int column) { if (row < 0) throw new IndexOutOfBoundsException("row index is negative (" + row + ")"); if (column < 0) throw new IndexOutOfBoundsException("column index is negative (" + column + ")"); if (row >= numRows) throw new IndexOutOfBoundsException("row index >= numRows (" + row + " >= " + numRows + ")"); if (column >= numColumns) throw new IndexOutOfBoundsException("column index >= numColumns (" + column + " >= " + numColumns + ")"); } public Matrix copy() { throw new UnsupportedOperationException(); } public Matrix zero() { for (MatrixEntry e : this) e.set(0); return this; } public Vector mult(Vector x, Vector y) { return mult(1, x, y); } public Vector mult(double alpha, Vector x, Vector y) { return multAdd(alpha, x, y.zero()); } public Vector multAdd(Vector x, Vector y) { return multAdd(1, x, y); } public Vector multAdd(double alpha, Vector x, Vector y) { checkMultAdd(x, y); if (alpha != 0) for (MatrixEntry e : this) y.add(e.row(), alpha * e.get() * x.get(e.column())); return y; } /** * Checks the arguments to mult and multAdd */ protected void checkMultAdd(Vector x, Vector y) { if (numColumns != x.size()) throw new IndexOutOfBoundsException("A.numColumns != x.size (" + numColumns + " != " + x.size() + ")"); if (numRows != y.size()) throw new IndexOutOfBoundsException("A.numRows != y.size (" + numRows + " != " + y.size() + ")"); } public Vector transMult(Vector x, Vector y) { return transMult(1, x, y); } public Vector transMult(double alpha, Vector x, Vector y) { return transMultAdd(alpha, x, y.zero()); } public Vector transMultAdd(Vector x, Vector y) { return transMultAdd(1, x, y); } public Vector transMultAdd(double alpha, Vector x, Vector y) { checkTransMultAdd(x, y); if (alpha != 0) for (MatrixEntry e : this) y.add(e.column(), alpha * e.get() * x.get(e.row())); return y; } /** * Checks the arguments to transMult and * transMultAdd */ protected void checkTransMultAdd(Vector x, Vector y) { if (numRows != x.size()) throw new IndexOutOfBoundsException("A.numRows != x.size (" + numRows + " != " + x.size() + ")"); if (numColumns != y.size()) throw new IndexOutOfBoundsException("A.numColumns != y.size (" + numColumns + " != " + y.size() + ")"); } public Vector solve(Vector b, Vector x) { throw new UnsupportedOperationException(); } public Vector transSolve(Vector b, Vector x) { throw new UnsupportedOperationException(); } /** * Checks that a matrix inversion is legal for the given arguments. This is * for the square case, not for least-squares problems */ protected void checkSolve(Vector b, Vector x) { if (!isSquare()) throw new IndexOutOfBoundsException("!A.isSquare"); if (numRows != b.size()) throw new IndexOutOfBoundsException("numRows != b.size (" + numRows + " != " + b.size() + ")"); if (numColumns != x.size()) throw new IndexOutOfBoundsException("numColumns != x.size (" + numColumns + " != " + x.size() + ")"); } public Matrix rank1(Vector x) { return rank1(1, x); } public Matrix rank1(double alpha, Vector x) { return rank1(alpha, x, x); } public Matrix rank1(Vector x, Vector y) { return rank1(1, x, y); } public Matrix rank1(double alpha, Vector x, Vector y) { checkRank1(x, y); if (alpha == 0) return this; for (VectorEntry ei : x) if (ei.get() != 0) for (VectorEntry ej : y) if (ej.get() != 0) add(ei.index(), ej.index(), alpha * ei.get() * ej.get()); return this; } /** * Checks that a vector rank1 update is possible for the given vectors */ protected void checkRank1(Vector x, Vector y) { if (!isSquare()) throw new IndexOutOfBoundsException("!A.isSquare"); if (x.size() != numRows) throw new IndexOutOfBoundsException("x.size != A.numRows (" + x.size() + " != " + numRows + ")"); if (y.size() != numColumns) throw new IndexOutOfBoundsException("y.size != A.numColumns (" + y.size() + " != " + numColumns + ")"); } public Matrix rank2(Vector x, Vector y) { return rank2(1, x, y); } public Matrix rank2(double alpha, Vector x, Vector y) { checkRank2(x, y); if (alpha == 0) return this; for (VectorEntry ei : x) for (VectorEntry ej : y) { add(ei.index(), ej.index(), alpha * ei.get() * ej.get()); add(ej.index(), ei.index(), alpha * ei.get() * ej.get()); } return this; } /** * Checks that a vector rank2 update is legal with the given vectors */ protected void checkRank2(Vector x, Vector y) { if (!isSquare()) throw new IndexOutOfBoundsException("!A.isSquare"); if (x.size() != numRows) throw new IndexOutOfBoundsException("x.size != A.numRows (" + x.size() + " != " + numRows + ")"); if (y.size() != numRows) throw new IndexOutOfBoundsException("y.size != A.numRows (" + y.size() + " != " + numRows + ")"); } public Matrix mult(Matrix B, Matrix C) { return mult(1, B, C); } public Matrix mult(double alpha, Matrix B, Matrix C) { return multAdd(alpha, B, C.zero()); } public Matrix multAdd(Matrix B, Matrix C) { return multAdd(1, B, C); } public Matrix multAdd(double alpha, Matrix B, Matrix C) { checkMultAdd(B, C); if (alpha != 0) for (int i = 0; i < numRows; ++i) for (int j = 0; j < C.numColumns(); ++j) { double dot = 0; for (int k = 0; k < numColumns; ++k) dot += get(i, k) * B.get(k, j); C.add(i, j, alpha * dot); } return C; } /** * Checks the arguments to mult and multAdd */ protected void checkMultAdd(Matrix B, Matrix C) { if (numRows != C.numRows()) throw new IndexOutOfBoundsException("A.numRows != C.numRows (" + numRows + " != " + C.numRows() + ")"); if (numColumns != B.numRows()) throw new IndexOutOfBoundsException("A.numColumns != B.numRows (" + numColumns + " != " + B.numRows() + ")"); if (B.numColumns() != C.numColumns()) throw new IndexOutOfBoundsException( "B.numColumns != C.numColumns (" + B.numRows() + " != " + C.numColumns() + ")"); } public Matrix transAmult(Matrix B, Matrix C) { return transAmult(1, B, C); } public Matrix transAmult(double alpha, Matrix B, Matrix C) { return transAmultAdd(alpha, B, C.zero()); } public Matrix transAmultAdd(Matrix B, Matrix C) { return transAmultAdd(1, B, C); } public Matrix transAmultAdd(double alpha, Matrix B, Matrix C) { checkTransAmultAdd(B, C); if (alpha != 0) for (int i = 0; i < numColumns; ++i) for (int j = 0; j < C.numColumns(); ++j) { double dot = 0; for (int k = 0; k < numRows; ++k) dot += get(k, i) * B.get(k, j); C.add(i, j, alpha * dot); } return C; } /** * Checks the arguments to transAmult and * transAmultAdd */ protected void checkTransAmultAdd(Matrix B, Matrix C) { if (numRows != B.numRows()) throw new IndexOutOfBoundsException("A.numRows != B.numRows (" + numRows + " != " + B.numRows() + ")"); if (numColumns != C.numRows()) throw new IndexOutOfBoundsException("A.numColumns != C.numRows (" + numColumns + " != " + C.numRows() + ")"); if (B.numColumns() != C.numColumns()) throw new IndexOutOfBoundsException( "B.numColumns != C.numColumns (" + B.numColumns() + " != " + C.numColumns() + ")"); } public Matrix transBmult(Matrix B, Matrix C) { return transBmult(1, B, C); } public Matrix transBmult(double alpha, Matrix B, Matrix C) { return transBmultAdd(alpha, B, C.zero()); } public Matrix transBmultAdd(Matrix B, Matrix C) { return transBmultAdd(1, B, C); } public Matrix transBmultAdd(double alpha, Matrix B, Matrix C) { checkTransBmultAdd(B, C); if (alpha != 0) for (int i = 0; i < numRows; ++i) for (int j = 0; j < C.numColumns(); ++j) { double dot = 0; for (int k = 0; k < numColumns; ++k) dot += get(i, k) * B.get(j, k); C.add(i, j, alpha * dot); } return C; } /** * Checks the arguments to transBmult and * transBmultAdd */ protected void checkTransBmultAdd(Matrix B, Matrix C) { if (numColumns != B.numColumns()) throw new IndexOutOfBoundsException( "A.numColumns != B.numColumns (" + numColumns + " != " + B.numColumns() + ")"); if (numRows != C.numRows()) throw new IndexOutOfBoundsException("A.numRows != C.numRows (" + numRows + " != " + C.numRows() + ")"); if (B.numRows() != C.numColumns()) throw new IndexOutOfBoundsException("B.numRows != C.numColumns (" + B.numRows() + " != " + C.numColumns() + ")"); } public Matrix transABmult(Matrix B, Matrix C) { return transABmult(1, B, C); } public Matrix transABmult(double alpha, Matrix B, Matrix C) { return transABmultAdd(alpha, B, C.zero()); } public Matrix transABmultAdd(Matrix B, Matrix C) { return transABmultAdd(1, B, C); } public Matrix transABmultAdd(double alpha, Matrix B, Matrix C) { checkTransABmultAdd(B, C); if (alpha != 0) for (int i = 0; i < numColumns; ++i) for (int j = 0; j < C.numColumns(); ++j) { double dot = 0; for (int k = 0; k < numRows; ++k) dot += get(k, i) * B.get(j, k); C.add(i, j, alpha * dot); } return C; } /** * Checks the arguments to transABmultAdd and * transABmultAdd */ protected void checkTransABmultAdd(Matrix B, Matrix C) { if (numRows != B.numColumns()) throw new IndexOutOfBoundsException("A.numRows != B.numColumns (" + numRows + " != " + B.numColumns() + ")"); if (numColumns != C.numRows()) throw new IndexOutOfBoundsException("A.numColumns != C.numRows (" + numColumns + " != " + C.numRows() + ")"); if (B.numRows() != C.numColumns()) throw new IndexOutOfBoundsException("B.numRows != C.numColumns (" + B.numRows() + " != " + C.numColumns() + ")"); } public Matrix solve(Matrix B, Matrix X) { throw new UnsupportedOperationException(); } public Matrix transSolve(Matrix B, Matrix X) { throw new UnsupportedOperationException(); } /** * Checks that a matrix inversion is legal for the given arguments. This is * for the square case, not for least-squares problems */ protected void checkSolve(Matrix B, Matrix X) { if (!isSquare()) throw new IndexOutOfBoundsException("!A.isSquare"); if (B.numRows() != numRows) throw new IndexOutOfBoundsException("B.numRows != A.numRows (" + B.numRows() + " != " + numRows + ")"); if (B.numColumns() != X.numColumns()) throw new IndexOutOfBoundsException( "B.numColumns != X.numColumns (" + B.numColumns() + " != " + X.numColumns() + ")"); if (X.numRows() != numColumns) throw new IndexOutOfBoundsException("X.numRows != A.numColumns (" + X.numRows() + " != " + numColumns + ")"); } public Matrix rank1(Matrix C) { return rank1(1, C); } public Matrix rank1(double alpha, Matrix C) { checkRank1(C); if (alpha == 0) return this; return C.transBmultAdd(alpha, C, this); } /** * Checks that a matrix rank1 update is possible for the given matrix */ protected void checkRank1(Matrix C) { if (!isSquare()) throw new IndexOutOfBoundsException("!A.isSquare"); if (numRows != C.numRows()) throw new IndexOutOfBoundsException("A.numRows != C.numRows (" + numRows + " != " + C.numRows() + ")"); } public Matrix transRank1(Matrix C) { return transRank1(1, C); } public Matrix transRank1(double alpha, Matrix C) { checkTransRank1(C); if (alpha == 0) return this; return C.transAmultAdd(alpha, C, this); } /** * Checks that a transposed rank1 update is leagal with the given argument */ protected void checkTransRank1(Matrix C) { if (!isSquare()) throw new IndexOutOfBoundsException("!A.isSquare"); if (numRows != C.numColumns()) throw new IndexOutOfBoundsException("A.numRows != C.numColumns (" + numRows + " != " + C.numColumns() + ")"); } public Matrix rank2(Matrix B, Matrix C) { return rank2(1, B, C); } public Matrix rank2(double alpha, Matrix B, Matrix C) { checkRank2(B, C); if (alpha == 0) return this; return B.transBmultAdd(alpha, C, C.transBmultAdd(alpha, B, this)); } /** * Checks that a rank2 update is legal for the given arguments */ protected void checkRank2(Matrix B, Matrix C) { if (!isSquare()) throw new IndexOutOfBoundsException("!A.isSquare"); if (B.numRows() != C.numRows()) throw new IndexOutOfBoundsException("B.numRows != C.numRows (" + B.numRows() + " != " + C.numRows() + ")"); if (B.numColumns() != C.numColumns()) throw new IndexOutOfBoundsException( "B.numColumns != C.numColumns (" + B.numColumns() + " != " + C.numColumns() + ")"); } public Matrix transRank2(Matrix B, Matrix C) { return transRank2(1, B, C); } public Matrix transRank2(double alpha, Matrix B, Matrix C) { checkTransRank2(B, C); if (alpha == 0) return this; return B.transAmultAdd(alpha, C, C.transAmultAdd(alpha, B, this)); } /** * Checks that a transposed rank2 update is leagal with the given arguments */ protected void checkTransRank2(Matrix B, Matrix C) { if (!isSquare()) throw new IndexOutOfBoundsException("!A.isSquare"); if (numRows != B.numColumns()) throw new IndexOutOfBoundsException("A.numRows != B.numColumns (" + numRows + " != " + B.numColumns() + ")"); if (B.numRows() != C.numRows()) throw new IndexOutOfBoundsException("B.numRows != C.numRows (" + B.numRows() + " != " + C.numRows() + ")"); if (B.numColumns() != C.numColumns()) throw new IndexOutOfBoundsException( "B.numColumns != C.numColumns (" + B.numColumns() + " != " + C.numColumns() + ")"); } public Matrix scale(double alpha) { if (alpha == 1) return this; else if (alpha == 0) return zero(); for (MatrixEntry e : this) e.set(alpha * e.get()); return this; } public Matrix set(Matrix B) { return set(1, B); } public Matrix set(double alpha, Matrix B) { checkSize(B); if (alpha == 0.) return zero(); if (B == this) return scale(alpha); zero(); for (MatrixEntry e : B) set(e.row(), e.column(), alpha * e.get()); return this; } public Matrix add(Matrix B) { return add(1, B); } public Matrix add(double alpha, Matrix B) { checkSize(B); if (alpha != 0) for (MatrixEntry e : B) add(e.row(), e.column(), alpha * e.get()); return this; } /** * Checks that the sizes of this matrix and the given conform */ protected void checkSize(Matrix B) { if (numRows != B.numRows()) throw new IndexOutOfBoundsException("A.numRows != B.numRows (" + numRows + " != " + B.numRows() + ")"); if (numColumns != B.numColumns()) throw new IndexOutOfBoundsException( "A.numColumns != B.numColumns (" + numColumns + " != " + B.numColumns() + ")"); } public Matrix transpose() { checkTranspose(); for (int j = 0; j < numColumns; ++j) for (int i = j + 1; i < numRows; ++i) { double value = get(i, j); set(i, j, get(j, i)); set(j, i, value); } return this; } /** * Checks that the matrix may be transposed */ protected void checkTranspose() { if (!isSquare()) throw new IndexOutOfBoundsException("!A.isSquare"); } public Matrix transpose(Matrix B) { checkTranspose(B); if (B == this) return transpose(); B.zero(); for (MatrixEntry e : this) B.set(e.column(), e.row(), e.get()); return B; } /** * Checks that this matrix can be transposed into the given matrix */ protected void checkTranspose(Matrix B) { if (numRows != B.numColumns()) throw new IndexOutOfBoundsException("A.numRows != B.numColumns (" + numRows + " != " + B.numColumns() + ")"); if (numColumns != B.numRows()) throw new IndexOutOfBoundsException("A.numColumns != B.numRows (" + numColumns + " != " + B.numRows() + ")"); } public double norm(Norm type) { if (type == Norm.One) return norm1(); else if (type == Norm.Frobenius) return normF(); else if (type == Norm.Infinity) return normInf(); else // Maxvalue return max(); } /** * Computes the 1 norm */ protected double norm1() { double[] rowSum = new double[numRows]; for (MatrixEntry e : this) rowSum[e.row()] += Math.abs(e.get()); return max(rowSum); } /** * Computes the Frobenius norm. This implementation is overflow resistant */ protected double normF() { double scale = 0, ssq = 1; for (MatrixEntry e : this) { double Aval = e.get(); if (Aval != 0) { double absxi = Math.abs(Aval); if (scale < absxi) { ssq = 1 + ssq * Math.pow(scale / absxi, 2); scale = absxi; } else ssq = ssq + Math.pow(absxi / scale, 2); } } return scale * Math.sqrt(ssq); } /** * Computes the infinity norm */ protected double normInf() { double[] columnSum = new double[numColumns]; for (MatrixEntry e : this) columnSum[e.column()] += Math.abs(e.get()); return max(columnSum); } /** * Returns the largest absolute value */ protected double max() { double max = 0; for (MatrixEntry e : this) max = Math.max(Math.abs(e.get()), max); return max; } /** * Returns the largest element of the passed array */ protected double max(double[] x) { double max = 0; for (int i = 0; i < x.length; ++i) max = Math.max(x[i], max); return max; } @Override public String toString() { // Output into coordinate format. Indices start from 1 instead of 0 Formatter out = new Formatter(); out.format("%10d %10d %19d\n", numRows, numColumns, Matrices .cardinality(this)); for (MatrixEntry e : this) if (e.get() != 0) out.format("%10d %10d % .12e\n", e.row() + 1, e.column() + 1, e .get()); return out.toString(); } public Iterator iterator() { return new RefMatrixIterator(); } /** * Iterator over a general matrix. Uses column-major traversal */ class RefMatrixIterator implements Iterator { /** * Matrix cursor */ int row, column; /** * Matrix entry */ final RefMatrixEntry entry = new RefMatrixEntry(); public boolean hasNext() { return (row < numRows) && (column < numColumns); } public MatrixEntry next() { entry.update(row, column); // Traversal first down the columns, then the rows if (row < numRows - 1) row++; else { column++; row = 0; } return entry; } public void remove() { entry.set(0); } } /** * Matrix entry backed by the matrix. May be reused for higher performance */ class RefMatrixEntry implements MatrixEntry { /** * Matrix position */ private int row, column; /** * Updates the entry */ public void update(int row, int column) { this.row = row; this.column = column; } public int row() { return row; } public int column() { return column; } public double get() { return AbstractMatrix.this.get(row, column); } public void set(double value) { AbstractMatrix.this.set(row, column, value); } } } mtj-0.9.14/src/no/uib/cipr/matrix/AbstractVector.java0000644000000000000000000001664211027512662021124 0ustar rootroot/* * 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.io.Serializable; import java.util.Formatter; import java.util.Iterator; /** * Partial implementation of Vector. The following methods throw * UnsupportedOperationException, and should be overridden by a * subclass: *

    *
  • get(int)
  • *
  • set(int,double)
  • *
  • copy
  • *
*

* For the rest of the methods, simple default implementations using a vector * iterator has been provided. There are some kernel operations which the * simpler operations forward to, and they are: *

    *
  • add(double,Vector) and set(double,Vector). *
  • *
  • scale(double).
  • *
  • dot(Vector) and all the norms.
  • *
*

* Finally, a default iterator is provided by this class, which works by calling * the get function. A tailored replacement should be used by * subclasses. * */ public abstract class AbstractVector implements Vector, Serializable { /** * Size of the vector */ protected int size; /** * Constructor for AbstractVector. * * @param size * Size of the vector */ protected AbstractVector(int size) { if (size < 0) throw new IllegalArgumentException("Vector size cannot be negative"); this.size = size; } /** * Constructor for AbstractVector, same size as x * * @param x * Vector to get the size from */ protected AbstractVector(Vector x) { this.size = x.size(); } public int size() { return size; } public void set(int index, double value) { throw new UnsupportedOperationException(); } public void add(int index, double value) { set(index, value + get(index)); } public double get(int index) { throw new UnsupportedOperationException(); } public Vector copy() { throw new UnsupportedOperationException(); } /** * Checks the index */ protected void check(int index) { if (index < 0) throw new IndexOutOfBoundsException("index is negative (" + index + ")"); if (index >= size) throw new IndexOutOfBoundsException("index >= size (" + index + " >= " + size + ")"); } public Vector zero() { for (VectorEntry e : this) e.set(0); return this; } public Vector scale(double alpha) { if (alpha == 0) return zero(); else if (alpha == 1) return this; for (VectorEntry e : this) e.set(alpha * e.get()); return this; } public Vector set(Vector y) { return set(1, y); } public Vector set(double alpha, Vector y) { checkSize(y); if (alpha == 0) return zero(); zero(); for (VectorEntry e : y) set(e.index(), alpha * e.get()); return this; } public Vector add(Vector y) { return add(1, y); } public Vector add(double alpha, Vector y) { checkSize(y); if (alpha == 0) return this; for (VectorEntry e : y) add(e.index(), alpha * e.get()); return this; } public double dot(Vector y) { checkSize(y); double ret = 0; for (VectorEntry e : this) ret += e.get() * y.get(e.index()); return ret; } /** * Checks for conformant sizes */ protected void checkSize(Vector y) { if (size != y.size()) throw new IndexOutOfBoundsException("x.size != y.size (" + size + " != " + y.size() + ")"); } public double norm(Norm type) { if (type == Norm.One) return norm1(); else if (type == Norm.Two) return norm2(); else if (type == Norm.TwoRobust) return norm2_robust(); else // Infinity return normInf(); } protected double norm1() { double sum = 0; for (VectorEntry e : this) sum += Math.abs(e.get()); return sum; } protected double norm2() { double norm = 0; for (VectorEntry e : this) norm += e.get() * e.get(); return Math.sqrt(norm); } protected double norm2_robust() { double scale = 0, ssq = 1; for (VectorEntry e : this) { double xval = e.get(); if (xval != 0) { double absxi = Math.abs(xval); if (scale < absxi) { ssq = 1 + ssq * Math.pow(scale / absxi, 2); scale = absxi; } else ssq = ssq + Math.pow(absxi / scale, 2); } } return scale * Math.sqrt(ssq); } protected double normInf() { double max = 0; for (VectorEntry e : this) max = Math.max(Math.abs(e.get()), max); return max; } public Iterator iterator() { return new RefVectorIterator(); } @Override public String toString() { // Output into coordinate format. Indices start from 1 instead of 0 Formatter out = new Formatter(); out.format("%10d %19d\n", size, Matrices.cardinality(this)); for (VectorEntry e : this) if (e.get() != 0) out.format("%10d % .12e\n", e.index() + 1, e.get()); return out.toString(); } /** * Iterator over a general vector */ private class RefVectorIterator implements Iterator { private int index; private final RefVectorEntry entry = new RefVectorEntry(); public boolean hasNext() { return index < size; } public VectorEntry next() { entry.update(index); index++; return entry; } public void remove() { entry.set(0); } } /** * Vector entry backed by the vector. May be reused for higher performance */ private class RefVectorEntry implements VectorEntry { private int index; /** * Updates the entry */ public void update(int index) { this.index = index; } public int index() { return index; } public double get() { return AbstractVector.this.get(index); } public void set(double value) { AbstractVector.this.set(index, value); } } } mtj-0.9.14/src/no/uib/cipr/matrix/AbstractPackMatrix.java0000644000000000000000000000600711027512662021717 0ustar rootroot/* * 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; /** * Partial implementation of a packed matrix */ abstract class AbstractPackMatrix extends AbstractMatrix { /** * Matrix contents */ double[] data; /** * Matrix is square, so this is either numRows or numColumns */ int n; /** * Constructor for AbstractPackMatrix * * @param n * Size of the matrix. Since the matrix must be square, this * equals both the number of rows and columns */ public AbstractPackMatrix(int n) { super(n, n); this.n = numRows; data = new double[(n * n + n) / 2]; } /** * Constructor for AbstractPackMatrix * * @param A * Matrix to copy */ public AbstractPackMatrix(Matrix A) { this(A, true); } /** * Constructor for AbstractPackMatrix * * @param A * A square matrix to copy from * @param deep * True for a deep copy, false for a shallow (reference) copy. * References must be instances of a packed matrix */ public AbstractPackMatrix(Matrix A, boolean deep) { super(A); if (!isSquare()) throw new IllegalArgumentException("Packed matrix must be square"); n = A.numRows(); if (deep) { data = new double[(n * n + n) / 2]; copy(A); } else this.data = ((AbstractPackMatrix) A).getData(); } /** * Set this matrix equal to the given matrix */ abstract void copy(Matrix A); /** * Returns the matrix contents. Ordering depends on the underlying storage * assumptions */ public double[] getData() { return data; } @Override public Matrix set(Matrix B) { if (!(B instanceof AbstractPackMatrix)) return super.set(B); checkSize(B); double[] Bd = ((AbstractPackMatrix) B).getData(); if (Bd == data) return this; System.arraycopy(Bd, 0, data, 0, data.length); return this; } @Override public Matrix zero() { Arrays.fill(data, 0); return this; } } mtj-0.9.14/src/no/uib/cipr/matrix/SymmDenseEVD.java0000644000000000000000000001611611027512662020435 0ustar rootroot/* * 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 org.netlib.lapack.LAPACK; import org.netlib.util.intW; /** * Computes eigenvalues of symmetrical, dense matrices */ public class SymmDenseEVD extends SymmEVD { /** * Double work array */ private final double[] work; /** * Integer work array */ private final int[] iwork; /** * Upper or lower part stored */ private final UpLo uplo; /** * Range of eigenvalues to compute */ private final JobEigRange range; /** * Eigenvector supports */ private final int[] isuppz; /** * Tolerance criteria */ private final double abstol; /** * Sets up an eigenvalue decomposition for symmetrical, dense matrices. * Computes all eigenvalues and eigenvectors, and uses a low default * tolerance criteria * * @param n * Size of the matrix * @param upper * True if the upper part of the matrix is stored, and false if * the lower part of the matrix is stored instead */ public SymmDenseEVD(int n, boolean upper) { this(n, upper, true, LAPACK.getInstance().dlamch("Safe minimum")); } /** * Sets up an eigenvalue decomposition for symmetrical, dense matrices. * Computes all eigenvalues and eigenvectors * * @param n * Size of the matrix * @param upper * True if the upper part of the matrix is stored, and false if * the lower part of the matrix is stored instead * @param abstol * Absolute tolerance criteria */ public SymmDenseEVD(int n, boolean upper, double abstol) { this(n, upper, true, abstol); } /** * Sets up an eigenvalue decomposition for symmetrical, dense matrices. Uses * a low default tolerance criteria * * @param n * Size of the matrix * @param upper * True if the upper part of the matrix is stored, and false if * the lower part of the matrix is stored instead * @param vectors * True to compute the eigenvectors, false for just the * eigenvalues */ public SymmDenseEVD(int n, boolean upper, boolean vectors) { this(n, upper, vectors, LAPACK.getInstance().dlamch("Safe minimum")); } /** * Sets up an eigenvalue decomposition for symmetrical, dense matrices * * @param n * Size of the matrix * @param upper * True if the upper part of the matrix is stored, and false if * the lower part of the matrix is stored instead * @param vectors * True to compute the eigenvectors, false for just the * eigenvalues * @param abstol * Absolute tolerance criteria */ public SymmDenseEVD(int n, boolean upper, boolean vectors, double abstol) { super(n, vectors); this.abstol = abstol; uplo = upper ? UpLo.Upper : UpLo.Lower; range = JobEigRange.All; isuppz = new int[2 * Math.max(1, n)]; // Find the needed workspace double[] worksize = new double[1]; int[] iworksize = new int[1]; intW info = new intW(0); LAPACK.getInstance().dsyevr(job.netlib(), range.netlib(), uplo.netlib(), n, new double[0], Matrices.ld(n), 0, 0, 0, 0, abstol, new intW(1), new double[0], new double[0], Matrices.ld(n), isuppz, worksize, -1, iworksize, -1, info); // Allocate workspace int lwork = 0, liwork = 0; if (info.val != 0) { lwork = 26 * n; liwork = 10 * n; } else { lwork = (int) worksize[0]; liwork = iworksize[0]; } lwork = Math.max(1, lwork); liwork = Math.max(1, liwork); work = new double[lwork]; iwork = new int[liwork]; } /** * Convenience method for computing the full eigenvalue decomposition of the * given matrix * * @param A * Matrix to factorize. Upper part extracted, and the matrix is * not modified * @return Newly allocated decomposition * @throws NotConvergedException */ public static SymmDenseEVD factorize(Matrix A) throws NotConvergedException { return new SymmDenseEVD(A.numRows(), true) .factor(new UpperSymmDenseMatrix(A)); } /** * Computes the eigenvalue decomposition of the given matrix * * @param A * Matrix to factorize. Overwritten on return * @return The current eigenvalue decomposition * @throws NotConvergedException */ public SymmDenseEVD factor(LowerSymmDenseMatrix A) throws NotConvergedException { if (uplo != UpLo.Lower) throw new IllegalArgumentException( "Eigenvalue computer configured for lower-symmetrical matrices"); return factor(A, A.getData()); } /** * Computes the eigenvalue decomposition of the given matrix * * @param A * Matrix to factorize. Overwritten on return * @return The current eigenvalue decomposition * @throws NotConvergedException */ public SymmDenseEVD factor(UpperSymmDenseMatrix A) throws NotConvergedException { if (uplo != UpLo.Upper) throw new IllegalArgumentException( "Eigenvalue computer configured for upper-symmetrical matrices"); return factor(A, A.getData()); } private SymmDenseEVD factor(Matrix A, double[] data) throws NotConvergedException { if (A.numRows() != n) throw new IllegalArgumentException("A.numRows() != n"); intW info = new intW(0); LAPACK.getInstance().dsyevr(job.netlib(), range.netlib(), uplo.netlib(), n, data, Matrices.ld(n), 0, 0, 0, 0, abstol, new intW(1), w, job == JobEig.All ? Z.getData() : new double[0], Matrices.ld(n), isuppz, work, work.length, iwork, iwork.length, info); if (info.val > 0) throw new NotConvergedException( NotConvergedException.Reason.Iterations); else if (info.val < 0) throw new IllegalArgumentException(); return this; } } mtj-0.9.14/src/no/uib/cipr/matrix/LowerSPDDenseMatrix.java0000644000000000000000000000460711027512662021777 0ustar rootroot/* * 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; /** * Lower symmetrical positive definite dense matrix. Same layout as * {@link no.uib.cipr.matrix.LowerSymmDenseMatrix LowerSymmDenseMatrix}. This * class does not enforce the SPD property, but serves as a tag so that more * efficient algorithms can be used in the solvers. */ public class LowerSPDDenseMatrix extends LowerSymmDenseMatrix { /** * Constructor for LowerSPDDenseMatrix * * @param n * Size of the matrix. Since the matrix must be square, this * equals both the number of rows and columns */ public LowerSPDDenseMatrix(int n) { super(n); } /** * Constructor for LowerSPDDenseMatrix * * @param A * Matrix to copy. It must be a square matrix, and only the lower * triangular part is copied */ public LowerSPDDenseMatrix(Matrix A) { this(A, true); } /** * Constructor for LowerSPDDenseMatrix * * @param A * Matrix to copy. It must be a square matrix, and only the lower * triangular part is copied * @param deep * False for a shallow copy, else it'll be a deep copy. For * shallow copies, A must be a dense matrix */ public LowerSPDDenseMatrix(Matrix A, boolean deep) { super(A, deep); } @Override public LowerSPDDenseMatrix copy() { return new LowerSPDDenseMatrix(this); } @Override public Matrix solve(Matrix B, Matrix X) { return SPDsolve(B, X); } } mtj-0.9.14/src/no/uib/cipr/matrix/DenseVector.java0000644000000000000000000001775711027512662020427 0ustar rootroot/* * 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.io.IOException; import java.io.Serializable; import java.util.Arrays; import no.uib.cipr.matrix.io.MatrixVectorReader; import no.uib.cipr.matrix.io.VectorInfo; import no.uib.cipr.matrix.io.VectorSize; import no.uib.cipr.matrix.io.VectorInfo.VectorField; /** * Dense vector. Stored by a double[] array of the same length as * the vector itself. */ public class DenseVector extends AbstractVector implements Serializable { /** just the private data */ private static final long serialVersionUID = 5358813524094629362L; /** * Vector data */ private final double[] data; /** * Constructor for DenseVector * * @param r * Reader to get vector from */ public DenseVector(MatrixVectorReader r) throws IOException { // Start with a zero-sized vector super(0); // Get vector information. Use the header if present, else use a safe // default VectorInfo info = null; if (r.hasInfo()) info = r.readVectorInfo(); else info = new VectorInfo(true, VectorField.Real); VectorSize size = r.readVectorSize(info); // Resize the vector to correct size this.size = size.size(); data = new double[size.size()]; // Check that the vector is in an acceptable format if (info.isPattern()) throw new UnsupportedOperationException( "Pattern vectors are not supported"); if (info.isComplex()) throw new UnsupportedOperationException( "Complex vectors are not supported"); // Read the entries if (info.isCoordinate()) { // Read coordinate data int nz = size.numEntries(); int[] index = new int[nz]; double[] entry = new double[nz]; r.readCoordinate(index, entry); // Shift indices from 1-offset to 0-offset r.add(-1, index); // Store them for (int i = 0; i < nz; ++i) set(index[i], entry[i]); } else // info.isArray() r.readArray(data); } /** * Constructor for DenseVector * * @param size * Size of the vector */ public DenseVector(int size) { super(size); data = new double[size]; } /** * Constructor for DenseVector * * @param x * Copies contents from this vector. A deep copy is made */ public DenseVector(Vector x) { this(x, true); } /** * Constructor for DenseVector * * @param x * Copies contents from this vector * @param deep * True for a deep copy. For a shallow copy, x * must be a DenseVector */ public DenseVector(Vector x, boolean deep) { super(x); if (deep) { data = new double[size]; set(x); } else data = ((DenseVector) x).getData(); } /** * Constructor for DenseVector * * @param x * Copies contents from this array * @param deep * True for a deep copy. For a shallow copy, x is * aliased with the internal storage */ public DenseVector(double[] x, boolean deep) { super(x.length); if (deep) data = x.clone(); else data = x; } /** * Constructor for DenseVector * * @param x * Copies contents from this array in a deep copy */ public DenseVector(double[] x) { this(x, true); } @Override public void set(int index, double value) { check(index); data[index] = value; } @Override public void add(int index, double value) { check(index); data[index] += value; } @Override public double get(int index) { check(index); return data[index]; } @Override public DenseVector copy() { return new DenseVector(this); } @Override public DenseVector zero() { Arrays.fill(data, 0); return this; } @Override public DenseVector scale(double alpha) { for (int i = 0; i < size; ++i) data[i] *= alpha; return this; } @Override public Vector set(Vector y) { if (!(y instanceof DenseVector)) return super.set(y); checkSize(y); double[] yd = ((DenseVector) y).getData(); System.arraycopy(yd, 0, data, 0, size); return this; } @Override public Vector set(double alpha, Vector y) { if (!(y instanceof DenseVector)) return super.set(alpha, y); checkSize(y); if (alpha == 0) return zero(); double[] yd = ((DenseVector) y).getData(); for (int i = 0; i < size; ++i) data[i] = alpha * yd[i]; return this; } @Override public Vector add(Vector y) { if (!(y instanceof DenseVector)) return super.add(y); checkSize(y); double[] yd = ((DenseVector) y).getData(); for (int i = 0; i < size; i++) data[i] += yd[i]; return this; } @Override public Vector add(double alpha, Vector y) { if (!(y instanceof DenseVector)) return super.add(alpha, y); checkSize(y); if (alpha == 0) return this; double[] yd = ((DenseVector) y).getData(); for (int i = 0; i < size; i++) data[i] += alpha * yd[i]; return this; } @Override public double dot(Vector y) { if (!(y instanceof DenseVector)) return super.dot(y); checkSize(y); double[] yd = ((DenseVector) y).getData(); double dot = 0.; for (int i = 0; i < size; ++i) dot += data[i] * yd[i]; return dot; } @Override protected double norm1() { double sum = 0; for (int i = 0; i < size; ++i) sum += Math.abs(data[i]); return sum; } @Override protected double norm2() { double norm = 0; for (int i = 0; i < size; ++i) norm += data[i] * data[i]; return Math.sqrt(norm); } @Override protected double norm2_robust() { double scale = 0, ssq = 1; for (int i = 0; i < size; ++i) if (data[i] != 0) { double absxi = Math.abs(data[i]); if (scale < absxi) { ssq = 1 + ssq * (scale / absxi) * (scale / absxi); scale = absxi; } else ssq += (absxi / scale) * (absxi / scale); } return scale * Math.sqrt(ssq); } @Override protected double normInf() { double max = 0; for (int i = 0; i < size; ++i) max = Math.max(Math.abs(data[i]), max); return max; } /** * Returns the internal vector contents. The array indices correspond to the * vector indices */ public double[] getData() { return data; } } mtj-0.9.14/src/no/uib/cipr/matrix/LowerSymmPackMatrix.java0000644000000000000000000000611711027512662022114 0ustar rootroot/* * 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; /** * Lower symmetric packed matrix. Same storage as * {@link no.uib.cipr.matrix.LowerTriangPackMatrix LowerTriangPackMatrix}, but * the upper triangular part is known by symmetry. */ public class LowerSymmPackMatrix extends AbstractSymmPackMatrix { /** * Constructor for LowerSymmPackMatrix * * @param n * Size of the matrix. Since the matrix must be square, this * equals both the number of rows and columns */ public LowerSymmPackMatrix(int n) { super(n, UpLo.Lower); } /** * Constructor for LowerSymmPackMatrix * * @param A * Matrix to copy contents from. Only the entries of the relevant * part are copied */ public LowerSymmPackMatrix(Matrix A) { this(A, true); } /** * Constructor for LowerSymmPackMatrix * * @param A * Matrix to copy contents from. Only the entries of the relevant * part are copied * @param deep * True if the copy is deep, else false (giving a shallow copy). * For shallow copies, A must be a packed matrix */ public LowerSymmPackMatrix(Matrix A, boolean deep) { super(A, deep, UpLo.Lower); } @Override public void add(int row, int column, double value) { if (column <= row) data[getIndex(row, column)] += value; } @Override public void set(int row, int column, double value) { if (column <= row) data[getIndex(row, column)] = value; } @Override public double get(int row, int column) { if (column <= row) return data[getIndex(row, column)]; return data[getIndex(column, row)]; } /** * Checks the row and column indices, and returns the linear data index */ int getIndex(int row, int column) { check(row, column); return row + (2 * n - (column + 1)) * column / 2; } @Override void copy(Matrix A) { for (MatrixEntry e : A) if (e.row() >= e.column()) set(e.row(), e.column(), e.get()); } @Override public LowerSymmPackMatrix copy() { return new LowerSymmPackMatrix(this); } } mtj-0.9.14/src/no/uib/cipr/matrix/UpperSPDDenseMatrix.java0000644000000000000000000000456011027512662022000 0ustar rootroot/* * 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; /** * Upper symmetrical positive definite dense matrix. Same layout as * {@link no.uib.cipr.matrix.UpperSymmDenseMatrix UpperSymmDenseMatrix}. This * class does not enforce the SPD property, but serves as a tag so that more * efficient algorithms can be used in the solvers. */ public class UpperSPDDenseMatrix extends UpperSymmDenseMatrix { /** * Constructor for UpperSPDDenseMatrix * * @param n * Size of the matrix. Since the matrix must be square, this * equals both the number of rows and columns */ public UpperSPDDenseMatrix(int n) { super(n); } /** * Constructor for UpperSPDDenseMatrix * * @param A * Matrix to copy. It must be a square matrix, and only the upper * triangular part is copied */ public UpperSPDDenseMatrix(Matrix A) { this(A, true); } /** * Constructor for UpperSPDDenseMatrix * * @param A * Matrix to copy. It must be a square matrix, and only the upper * triangular part is copied * @param deep * True for a deep copy, else shallow. In that case, * A must be a dense matrix */ public UpperSPDDenseMatrix(Matrix A, boolean deep) { super(A, deep); } @Override public UpperSPDDenseMatrix copy() { return new UpperSPDDenseMatrix(this); } @Override public Matrix solve(Matrix B, Matrix X) { return SPDsolve(B, X); } } mtj-0.9.14/src/no/uib/cipr/matrix/UnitLowerTriangDenseMatrix.java0000644000000000000000000000633111027512662023431 0ustar rootroot/* * 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; /** * Unit lower triangular dense matrix. Almost the same as the * {@link no.uib.cipr.matrix.LowerTriangDenseMatrix LowerTriangDenseMatrix}, * but additionally assumes the main diagonal to be all ones. However it does * not access it, so it may be actually be different. */ public class UnitLowerTriangDenseMatrix extends LowerTriangDenseMatrix { /** * Constructor for UnitLowerTriangDenseMatrix * * @param n * Size of the matrix. Since the matrix must be square, this * equals both the number of rows and columns */ public UnitLowerTriangDenseMatrix(int n) { super(n, Diag.Unit); } /** * Constructor for UnitLowerTriangDenseMatrix * * @param A * Matrix to copy from. Only the strictly lower triangular part * is copied */ public UnitLowerTriangDenseMatrix(Matrix A) { this(A, true); } /** * Constructor for UnitLowerTriangDenseMatrix * * @param A * Matrix to copy from. Only the strictly lower triangular part * is copied * @param deep * If true, A is copied, else a shallow copy is * made and the matrices share underlying storage. For this, * A must be a dense matrix */ public UnitLowerTriangDenseMatrix(Matrix A, boolean deep) { super(A, deep, Diag.Unit); } @Override public void add(int row, int column, double value) { if (column == row) throw new IllegalArgumentException("column == row"); super.add(row, column, value); } @Override public double get(int row, int column) { if (column == row) return 1; return super.get(row, column); } @Override public void set(int row, int column, double value) { if (column == row) throw new IllegalArgumentException("column == row"); super.set(row, column, value); } @Override void copy(Matrix A) { for (MatrixEntry e : A) if (e.row() > e.column()) set(e.row(), e.column(), e.get()); } @Override public UnitLowerTriangDenseMatrix copy() { return new UnitLowerTriangDenseMatrix(this); } @Override public Matrix zero() { throw new UnsupportedOperationException(); } } mtj-0.9.14/src/no/uib/cipr/matrix/LowerSPDBandMatrix.java0000644000000000000000000000532611027512662021604 0ustar rootroot/* * 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; /** * Lower symmetrical positive definite banded matrix. It does not enforce this * property (except for symmetry), and has the same storage layout as * {@link no.uib.cipr.matrix.LowerSymmBandMatrix LowerSymmBandMatrix}. */ public class LowerSPDBandMatrix extends LowerSymmBandMatrix { /** * Constructor for LowerSPDBandMatrix * * @param n * Size of the matrix. Since the matrix must be square, this * equals both the number of rows and columns * @param kd * Number of bands off the main diagonal (off diagonals) */ public LowerSPDBandMatrix(int n, int kd) { super(n, kd); } /** * Constructor for LowerSPDBandMatrix * * @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 kd * Number of bands off the main diagonal (off diagonals) */ public LowerSPDBandMatrix(Matrix A, int kd) { super(A, kd); } /** * Constructor for LowerSPDBandMatrix * * @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 kd * Number of bands off the main diagonal (off diagonals) * @param deep * True for a deep copy. For shallow copies, A * must be a banded matrix */ public LowerSPDBandMatrix(Matrix A, int kd, boolean deep) { super(A, kd, deep); } @Override public LowerSPDBandMatrix copy() { return new LowerSPDBandMatrix(this, kd); } @Override public Matrix solve(Matrix B, Matrix X) { return SPDsolve(B, X); } } mtj-0.9.14/src/no/uib/cipr/matrix/QR.java0000644000000000000000000000773311027512662016521 0ustar rootroot/* * 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 org.netlib.lapack.LAPACK; import org.netlib.util.intW; /** * Computers QR decompositions */ public class QR extends OrthogonalComputer { /** * Constructs an empty QR decomposition * * @param m * Number of rows. Must be larger than or equal the number of * columns * @param n * Number of columns */ public QR(int m, int n) { super(m, n, true); if (n > m) throw new IllegalArgumentException("n > m"); int lwork; // Query optimal workspace. First for computing the factorization { work = new double[1]; intW info = new intW(0); LAPACK.getInstance().dgeqrf(m, n, new double[0], Matrices.ld(m), new double[0], work, -1, info); if (info.val != 0) lwork = n; else lwork = (int) work[0]; lwork = Math.max(1, lwork); work = new double[lwork]; } // Workspace needed for generating an explicit orthogonal matrix { workGen = new double[1]; intW info = new intW(0); LAPACK.getInstance().dorgqr(m, n, k, new double[0], Matrices.ld(m), new double[0], workGen, -1, info); if (info.val != 0) lwork = n; else lwork = (int) workGen[0]; lwork = Math.max(1, lwork); workGen = new double[lwork]; } } /** * Convenience method to compute a QR decomposition * * @param A * Matrix to decompose. Not modified * @return Newly allocated decomposition */ public static QR factorize(Matrix A) { return new QR(A.numRows(), A.numColumns()).factor(new DenseMatrix(A)); } @Override public QR factor(DenseMatrix A) { if (Q.numRows() != A.numRows()) throw new IllegalArgumentException("Q.numRows() != A.numRows()"); else if (Q.numColumns() != A.numColumns()) throw new IllegalArgumentException( "Q.numColumns() != A.numColumns()"); else if (R == null) throw new IllegalArgumentException("R == null"); /* * Calculate factorisation, and extract the triangular factor */ intW info = new intW(0); LAPACK.getInstance().dgeqrf(m, n, A.getData(), Matrices.ld(m), tau, work, work.length, info); if (info.val < 0) throw new IllegalArgumentException(); R.zero(); for (MatrixEntry e : A) if (e.row() <= e.column()) R.set(e.row(), e.column(), e.get()); /* * Generate the orthogonal matrix */ info.val = 0; LAPACK.getInstance().dorgqr(m, n, k, A.getData(), Matrices.ld(m), tau, workGen, workGen.length, info); if (info.val < 0) throw new IllegalArgumentException(); Q.set(A); return this; } /** * Returns the upper triangular factor */ public UpperTriangDenseMatrix getR() { return R; } } mtj-0.9.14/src/no/uib/cipr/matrix/LowerTriangPackMatrix.java0000644000000000000000000001164111027512662022411 0ustar rootroot/* * 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; /** * Lower triangular packed matrix. In contrast with * {@link no.uib.cipr.matrix.LowerTriangDenseMatrix LowerTriangDenseMatrix}, * this matrix exploits the sparsity by only storing about half the matrix. As * such, the triangular matrix *

* * * * * * * * * * * * * * * * * * * * * * * * * *
a11   
a21a22  
a31a32a33 
a41a42a43a44
*

*

* is packed as follows: *

*

* * * * * * * * * * * * * *
a11a21a31a41a22a32a42a33a43a44
*

*/ public class LowerTriangPackMatrix extends AbstractTriangPackMatrix { /** * Constructor for LowerTriangPackMatrix * * @param n * Size of the matrix. Since the matrix must be square, this * equals both the number of rows and columns */ public LowerTriangPackMatrix(int n) { super(n, UpLo.Lower, Diag.NonUnit); } /** * Constructor for LowerTriangPackMatrix * * @param n * Size of the matrix. Since the matrix must be square, this * equals both the number of rows and columns */ LowerTriangPackMatrix(int n, Diag diag) { super(n, UpLo.Lower, diag); } /** * Constructor for LowerTriangPackMatrix * * @param A * Matrix to copy contents from. Only the entries of the relevant * part are copied */ public LowerTriangPackMatrix(Matrix A) { this(A, true); } /** * Constructor for LowerTriangPackMatrix * * @param A * Matrix to copy contents from. Only the entries of the relevant * part are copied * @param deep * True if the copy is deep, else false (giving a shallow copy). * For shallow copies, A must be a packed matrix */ public LowerTriangPackMatrix(Matrix A, boolean deep) { super(A, deep, UpLo.Lower, Diag.NonUnit); } /** * Constructor for LowerTriangPackMatrix * * @param A * Matrix to copy contents from. Only the entries of the relevant * part are copied * @param deep * True if the copy is deep, else false (giving a shallow copy). * For shallow copies, A must be a packed matrix */ LowerTriangPackMatrix(Matrix A, boolean deep, Diag diag) { super(A, deep, UpLo.Lower, diag); } @Override public void add(int row, int column, double value) { if (column > row) throw new IllegalArgumentException("column > row"); data[getIndex(row, column)] += value; } @Override public void set(int row, int column, double value) { if (column > row) throw new IllegalArgumentException("column > row"); data[getIndex(row, column)] = value; } @Override public double get(int row, int column) { if (column > row) return 0; return data[getIndex(row, column)]; } /** * Checks the row and column indices, and returns the linear data index */ int getIndex(int row, int column) { check(row, column); return row + (2 * n - (column + 1)) * column / 2; } @Override void copy(Matrix A) { for (MatrixEntry e : A) if (e.row() >= e.column()) set(e.row(), e.column(), e.get()); } @Override public LowerTriangPackMatrix copy() { return new LowerTriangPackMatrix(this); } } mtj-0.9.14/src/no/uib/cipr/matrix/LowerTriangDenseMatrix.java0000644000000000000000000001306511027512662022573 0ustar rootroot/* * 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; /** * Lower triangular dense matrix. It has the same storage layout as the * {@link no.uib.cipr.matrix.DenseMatrix DenseMatrix}, but only refers to * elements below or on the main diagonal. The remaining elements are assumed to * be zero, but since they are never accessed, they need not be. */ public class LowerTriangDenseMatrix extends AbstractTriangDenseMatrix { /** * Constructor for LowerTriangDenseMatrix * * @param n * Size of the matrix. Since the matrix must be square, this * equals both the number of rows and columns */ public LowerTriangDenseMatrix(int n) { super(n, UpLo.Lower, Diag.NonUnit); } /** * Constructor for LowerTriangDenseMatrix * * @param n * Size of the matrix. Since the matrix must be square, this * equals both the number of rows and columns */ LowerTriangDenseMatrix(int n, Diag diag) { super(n, UpLo.Lower, diag); } /** * Constructor for LowerTriangDenseMatrix * * @param A * Matrix to copy from. Only the lower triangular part is copied */ public LowerTriangDenseMatrix(Matrix A) { this(A, Math.min(A.numRows(), A.numColumns())); } /** * Constructor for LowerTriangDenseMatrix * * @param A * Matrix to copy from. Only the lower triangular part is copied * @param deep * If true, A is copied, else a shallow copy is * made and the matrices share underlying storage. For this, * A must be a dense matrix */ public LowerTriangDenseMatrix(Matrix A, boolean deep) { this(A, Math.min(A.numRows(), A.numColumns()), deep); } /** * Constructor for LowerTriangDenseMatrix * * @param A * Matrix to copy from. Only the lower triangular part is copied * @param deep * If true, A is copied, else a shallow copy is * made and the matrices share underlying storage. For this, * A must be a dense matrix */ LowerTriangDenseMatrix(Matrix A, boolean deep, Diag diag) { this(A, Math.min(A.numRows(), A.numColumns()), deep, diag); } /** * Constructor for LowerTriangDenseMatrix * * @param A * Matrix to copy from. Only the lower triangular part is copied * @param k * Size of matrix to refer. * k<min(numRows,numColumns) */ public LowerTriangDenseMatrix(Matrix A, int k) { this(A, k, true); } /** * Constructor for LowerTriangDenseMatrix * * @param A * Matrix to copy from. Only the lower triangular part is copied * @param k * Size of matrix to refer. * k<min(numRows,numColumns) * @param deep * If true, A is copied, else a shallow copy is * made and the matrices share underlying storage. For this, * A must be a dense matrix */ public LowerTriangDenseMatrix(Matrix A, int k, boolean deep) { super(A, k, deep, UpLo.Lower, Diag.NonUnit); } /** * Constructor for LowerTriangDenseMatrix * * @param A * Matrix to copy from. Only the lower triangular part is copied * @param k * Size of matrix to refer. * k<min(numRows,numColumns) * @param deep * If true, A is copied, else a shallow copy is * made and the matrices share underlying storage. For this, * A must be a dense matrix */ LowerTriangDenseMatrix(Matrix A, int k, boolean deep, Diag diag) { super(A, k, deep, UpLo.Lower, diag); } @Override public void add(int row, int column, double value) { if (column > row) throw new IllegalArgumentException("column > row"); super.add(row, column, value); } @Override public double get(int row, int column) { if (column > row) return 0; return super.get(row, column); } @Override public void set(int row, int column, double value) { if (column > row) throw new IllegalArgumentException("column > row"); super.set(row, column, value); } @Override public LowerTriangDenseMatrix copy() { return new LowerTriangDenseMatrix(this); } @Override void copy(Matrix A) { for (MatrixEntry e : A) if (e.row() >= e.column()) set(e.row(), e.column(), e.get()); } } mtj-0.9.14/src/no/uib/cipr/matrix/UnitUpperTriangBandMatrix.java0000644000000000000000000000720411027512662023242 0ustar rootroot/* * 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; /** * Unit upper triangular banded matrix. The same storage as * {@link no.uib.cipr.matrix.LowerTriangBandMatrix LowerTriangBandMatrix}, but * the main diagonal is assumed to be all ones. It is still allocated, however. */ public class UnitUpperTriangBandMatrix extends UpperTriangBandMatrix { /** * Constructor for UnitUpperTriangBandMatrix * * @param n * Size of the matrix. Since the matrix must be square, this * equals both the number of rows and columns * @param kd * Number of bands above the main diagonal (superdiagonals) */ public UnitUpperTriangBandMatrix(int n, int kd) { super(n, kd, Diag.Unit); } /** * Constructor for UnitUpperTriangBandMatrix * * @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 (including main diagonal entries) * @param kd * Number of bands above the main diagonal (superdiagonals) */ public UnitUpperTriangBandMatrix(Matrix A, int kd) { this(A, kd, true); } /** * Constructor for UnitUpperTriangBandMatrix * * @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 (including main diagonal entries) * @param kd * Number of bands above the main diagonal (superdiagonals) * @param deep * True for a deep copy. For shallow copies, A * must be a banded matrix */ public UnitUpperTriangBandMatrix(Matrix A, int kd, boolean deep) { super(A, kd, deep, Diag.Unit); } @Override public void add(int row, int column, double value) { if (row == column) throw new IllegalArgumentException("row == column"); super.add(row, column, value); } @Override public double get(int row, int column) { if (row == column) return 1; return super.get(row, column); } @Override public void set(int row, int column, double value) { if (row == column) throw new IllegalArgumentException("row == column"); super.set(row, column, value); } @Override public UnitUpperTriangBandMatrix copy() { return new UnitUpperTriangBandMatrix(this, ku); } @Override public Matrix zero() { throw new UnsupportedOperationException(); } @Override void copy(Matrix A) { for (MatrixEntry e : A) if (inBand(e.row(), e.column()) && e.row() != e.column()) set(e.row(), e.column(), e.get()); } } mtj-0.9.14/src/no/uib/cipr/matrix/AbstractTriangPackMatrix.java0000644000000000000000000001132211027512662023060 0ustar rootroot/* * 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.Iterator; import org.netlib.blas.BLAS; import org.netlib.lapack.LAPACK; import org.netlib.util.intW; /** * Partial implementation of a triangular, packed matrix */ abstract class AbstractTriangPackMatrix extends AbstractPackMatrix { /** * Upper or lower triangular */ UpLo uplo; /** * If the matrix is unit diagonal or not unit */ Diag diag; /** * Constructor for AbstractTriangPackMatrix */ AbstractTriangPackMatrix(int n, UpLo uplo, Diag diag) { super(n); this.uplo = uplo; this.diag = diag; } /** * Constructor for AbstractTriangPackMatrix */ AbstractTriangPackMatrix(Matrix A, UpLo uplo, Diag diag) { this(A, false, uplo, diag); } /** * Constructor for AbstractTriangPackMatrix */ AbstractTriangPackMatrix(Matrix A, boolean deep, UpLo uplo, Diag diag) { super(A, deep); this.uplo = uplo; this.diag = diag; } @Override public Vector mult(double alpha, Vector x, Vector y) { if (!(y instanceof DenseVector)) return super.mult(alpha, x, y); checkMultAdd(x, y); double[] yd = ((DenseVector) y).getData(); // y = alpha*x y.set(alpha, x); // y = A*z BLAS.getInstance().dtpmv(uplo.netlib(), Transpose.NoTranspose.netlib(), diag.netlib(), numRows, data, yd, 1); return y; } @Override public Vector transMult(double alpha, Vector x, Vector y) { if (!(y instanceof DenseVector)) return super.transMult(alpha, x, y); checkTransMultAdd(x, y); double[] yd = ((DenseVector) y).getData(); // y = alpha*x y.set(alpha, x); // y = A*z BLAS.getInstance().dtpmv(uplo.netlib(), Transpose.Transpose.netlib(), diag.netlib(), numRows, data, yd, 1); return y; } @Override public Matrix solve(Matrix B, Matrix X) { return solve(B, X, Transpose.NoTranspose); } @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 transSolve(Matrix B, Matrix X) { return solve(B, X, Transpose.Transpose); } @Override public Vector transSolve(Vector b, Vector x) { DenseMatrix B = new DenseMatrix(b, false), X = new DenseMatrix(x, false); transSolve(B, X); return x; } Matrix solve(Matrix B, Matrix X, Transpose trans) { if (!(X instanceof DenseMatrix)) throw new UnsupportedOperationException("X must be a DenseMatrix"); checkSolve(B, X); double[] Xd = ((DenseMatrix) X).getData(); X.set(B); intW info = new intW(0); LAPACK.getInstance().dtptrs(uplo.netlib(), trans.netlib(), diag.netlib(), numRows, X.numColumns(), data, Xd, Matrices.ld(numRows), info); if (info.val > 0) throw new MatrixSingularException(); else if (info.val < 0) throw new IllegalArgumentException(); return X; } @Override public Iterator iterator() { return new TriangPackMatrixIterator(); } private class TriangPackMatrixIterator extends RefMatrixIterator { @Override public MatrixEntry next() { entry.update(row, column); if (uplo == UpLo.Lower) if (row < numRows - 1) row++; else { column++; row = column; } else { // uplo == UpLo.Upper if (row < column) row++; else { column++; row = 0; } } return entry; } } } mtj-0.9.14/src/no/uib/cipr/matrix/JobEigRange.java0000644000000000000000000000252511027512662020305 0ustar rootroot/* * 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; /** When computing eigenvalues, this indicates which eigenvalues to locate. */ enum JobEigRange { /** All eigenvalues will be computed */ All, /** The eigenvalues with the given indices are computed */ Indices, /** Eigenvalues in a given interval will be found */ Interval; /** * @return the netlib character version of this designation, for use with F2J. */ public String netlib() { switch (this) { case All: return "A"; case Indices: return "I"; default: return "V"; } } }mtj-0.9.14/src/no/uib/cipr/matrix/SymmEVD.java0000644000000000000000000000441311027512662017453 0ustar rootroot/* * 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; /** * Symmetric eigenvalue decomposition */ abstract class SymmEVD { /** * Size of the matrix */ final int n; /** * The eigenvalues */ final double[] w; /** * The eigenvectors stored columnwise */ final DenseMatrix Z; /** * Job to do */ final JobEig job; /** * Allocates storage for an eigenvalue computation * * @param n * Size of the matrix * @param vectors * True to compute the eigenvectors, false for just the * eigenvalues */ public SymmEVD(int n, boolean vectors) { this.n = n; w = new double[n]; job = vectors ? JobEig.All : JobEig.Eigenvalues; if (vectors) Z = new DenseMatrix(n, n); else Z = null; } /** * Allocates storage for an eigenvalue computation. Includes eigenvectors * * @param n * Size of the matrix */ public SymmEVD(int n) { this(n, true); } /** * Gets the eigenvalues (stored in ascending order) */ public double[] getEigenvalues() { return w; } /** * Gets the eigenvectors, if available */ public DenseMatrix getEigenvectors() { return Z; } /** * True if the eigenvectors have been computed */ public boolean hasEigenvectors() { return Z != null; } } mtj-0.9.14/src/no/uib/cipr/matrix/UpLo.java0000644000000000000000000000213211027512662017042 0ustar rootroot/* * 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; /** * Designates the Upper or lower part of a Matrix. */ enum UpLo { Upper, Lower; /** * @return the netlib character version of this designation, for use with F2J. */ public String netlib() { if (this == Upper) return "U"; return "L"; } } mtj-0.9.14/src/no/uib/cipr/matrix/package.html0000644000000000000000000001216211027512662017605 0ustar rootroot Dense and structured sparse matrices, along with matrix factorisations and solvers. The main components are:
  • Matrix and vector interfaces
    • Matrix - Linear algebra matrix.
    • Vector - Linear algebra vector.
  • Matrix and vector implementations
    • DenseVector - Stores the vector in a dense array.
    • Dense matrices - Stores the data columnwise in a linear array.
      • DenseMatrix - Recommended matrix for general cases.
      • {Lower,Upper}{Symm,SPD}DenseMatrix - Assumes implicit symmetry, and that the matrix is positive definite (SPD). Stores entries in either the upper or lower triangular part.
      • [Unit]{Lower,Upper}TriangDenseMatrix - Only stores in the lower or upper triangular part, and assumes the rest is zero. If the matrix is unit, the main diagonal is implicitly assumes to be one.
    • Packed matrices - Stores either the lower or upper triangular part of the matrix.
      • {Lower,Upper}{Symm,SPD}PackMatrix - Like their dense counterparts, but consumes less memory.
      • [Unit]{Lower,Upper}TriangPackMatrix - Also like their dense counterparts, but consumes less memory.
    • Banded matrices - Stores the matrix in a dense band.
      • BandMatrix - General band matrix with the possibility of different upper and lower triangular bandwidths.
      • {Lower,Upper}{Symm,SPD}BandMatrix - Like their dense counterparts, but consumes less memory by only storing the lower or upper parts.
      • [Unit]{Lower,Upper}TriangBandMatrix - Also like their dense counterparts, but consumes less memory by only storing the lower or upper parts..
    • Tridiagonal matrices - Stores just three diagonals.
      • TridiagMatrix - Standard tridiagonal matrix.
      • {Symm,SPD}TridiagMatrix - Stores only the main diagonal and an off-diagonal. May also assume that the matrix is positive definite.
  • Abstract implementations
    • AbstractMatrix - Implements all the matrix operations, but doesn't specify the matrix storage.
    • AbstractVector - Implements all the vector operations, but doesn't specify the vector storage.
  • Utility methods and iterators
    • Matrices - Creates submatrices and synchronized matrices. Also has several miscellaneous utility methods.
    • MatrixEntry - Entry returned when iterating over a matrix using the for-each statement.
    • VectorEntry - Entry returned when iterating over a vector using the for-each statement.
  • LU decompositions
    • BandLU - LU decomposition of a banded matrix.
    • DenseLU - LU decomposition of a dense matrix.
    • BandCholesky - Cholesky decomposition of a banded matrix.
    • DenseCholesky - Cholesky decomposition of a dense SPD matrix.
    • PackCholesky - Cholesky decomposition of a packed SPD matrix.
  • Orthogonal decompositions
    • LQ - LQ decomposition.
    • QL - QL decomposition.
    • QR - QR decomposition.
    • RQ - RQ decomposition.
    • GivensRotation - Givens plane rotation.
  • Spectral decompositions
    • EVD - Eigenvalue decomposition of general matrices.
    • SVD - Singular value decomposition
    • SymmBandEVD - Eigenvalue decomposition of symmetrical, banded matrices.
    • SymmDenseEVD - Eigenvalue decomposition of symmetrical, dense matrices.
    • SymmPackEVD - Eigenvalue decomposition of symmetrical, packed matrices.
    • SymmTridiagEVD - Eigenvalue decomposition of symmetrical, tridiagonal matrices.

mtj-0.9.14/src/no/uib/cipr/matrix/Vector.java0000644000000000000000000001162311027512662017432 0ustar rootroot/* * 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.io.Serializable; /** * Basic vector interface. It holds doubles in an array, and is * used alongside Matrix in numerical computations. Implementing * classes decides on the actual storage. * *

Basic operations

*

* Use size to get the vector size. get(int) gets * an element, and there are corresponding set(int,double) and * add(int,double) methods as well. Note that vector indices are * zero-based (typical for Java and C). This means that they range from 0 to * size-1. It is legal to have size equal zero. *

*

* Other basic operations are zero which zeros all the entries of * the vector, which can be cheaper than either zeroing the vector manually, or * creating a new vector, and the operation copy which creates a * deep copy of the vector. This copy has separate storage, but starts with the * same contents as the current vector. *

*

Iterators

*

* The vector interface extends Iterable, and the iterator * returns a VectorEntry which contains current index and entry * value. Note that the iterator may skip non-zero entries. Using an iterator, * many simple and efficient algorithms can be created. The iterator also * permits changing values in the vector, however only non-zero entries can be * changed. *

*

Basic linear algebra

*

* A selection of basic linear algebra operations are available. To ensure high * efficiency, little or no internal memory allocation is done, and the user is * required to supply the output arguments. *

*

* The operations available include: *

*
*
Additions
*
Vectors can be added to each other, even if their underlying vector * structures are incompatible
*
Scaling
*
Scalar multiplication (scaling) of a whole vector
*
Norms
*
Both innerproducts and norms can be computed. Several common norms are * supported
*
*/ public interface Vector extends Iterable, Serializable { /** * Size of the vector */ int size(); /** * x(index) = value */ void set(int index, double value); /** * x(index) += value */ void add(int index, double value); /** * Returns x(index) */ double get(int index); /** * Creates a deep copy of the vector */ Vector copy(); /** * Zeros all the entries in the vector, while preserving any underlying * structure */ Vector zero(); /** * x=alpha*x * * @return x */ Vector scale(double alpha); /** * x=y * * @return x */ Vector set(Vector y); /** * x=alpha*y * * @return x */ Vector set(double alpha, Vector y); /** * x = y + x * * @return x */ Vector add(Vector y); /** * x = alpha*y + x * * @return x */ Vector add(double alpha, Vector y); /** * xT*y */ double dot(Vector y); /** * Computes the given norm of the vector * * @param type * The type of norm to compute */ double norm(Norm type); /** * Supported vector-norms. The difference between the two 2-norms is that * one is fast, but can overflow, while the robust version is overflow * resistant, but slower. */ enum Norm { /** * Sum of the absolute values of the entries */ One, /** * The root of sum of squares */ Two, /** * As the 2 norm may overflow, an overflow resistant version is also * available. Note that it may be slower. */ TwoRobust, /** * Largest entry in absolute value */ Infinity } } mtj-0.9.14/src/no/uib/cipr/matrix/UnitUpperTriangDenseMatrix.java0000644000000000000000000000647511027512662023445 0ustar rootroot/* * 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; /** * Unit upper triangular dense matrix. Almost the same as the * {@link no.uib.cipr.matrix.UpperTriangDenseMatrix UpperTriangDenseMatrix}, * but additionally assumes the main diagonal to be all ones. However it does * not access it, so it may be actually be different. */ public class UnitUpperTriangDenseMatrix extends UpperTriangDenseMatrix { /** * Constructor for UnitUpperTriangDenseMatrix * * @param n * Size of the matrix. Since the matrix must be square, this * equals both the number of rows and columns */ public UnitUpperTriangDenseMatrix(int n) { super(n, Diag.Unit); } /** * Constructor for UnitUpperTriangDenseMatrix. Matrix is copied from the * supplied matrix * * @param A * Matrix to copy from. Only the strictly upper triangular part * is copied */ public UnitUpperTriangDenseMatrix(Matrix A) { this(A, true); } /** * Constructor for UnitUpperTriangDenseMatrix. Matrix is copied from the * supplied matrix * * @param A * Matrix to copy from. Only the strictly upper triangular part * is copied * @param deep * If true, A is copied, else a shallow copy is * made and the matrices share underlying storage. For this, * A must be a dense matrix */ public UnitUpperTriangDenseMatrix(Matrix A, boolean deep) { super(A, deep, Diag.Unit); } @Override public void add(int row, int column, double value) { if (column == row) throw new IllegalArgumentException("column == row"); super.add(row, column, value); } @Override public double get(int row, int column) { if (row == column) return 1; return super.get(row, column); } @Override public void set(int row, int column, double value) { if (column == row) throw new IllegalArgumentException("column == row"); super.set(row, column, value); } @Override void copy(Matrix A) { for (MatrixEntry e : A) if (e.row() < e.column()) set(e.row(), e.column(), e.get()); } @Override public UnitUpperTriangDenseMatrix copy() { return new UnitUpperTriangDenseMatrix(this); } @Override public Matrix zero() { throw new UnsupportedOperationException(); } } mtj-0.9.14/src/no/uib/cipr/matrix/BandLU.java0000644000000000000000000001521711027512662017300 0ustar rootroot/* * 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 no.uib.cipr.matrix.Matrix.Norm; import org.netlib.lapack.LAPACK; import org.netlib.util.doubleW; import org.netlib.util.intW; /** * Banded LU decomposition */ public class BandLU { /** * Matrix dimension */ private final int n; /** * Number of bands in the matrix A */ private final int kl, ku; /** * Holds the LU factors */ private final BandMatrix LU; /** * Row pivotations */ private final int[] ipiv; /** * True if the matrix was singular */ private boolean singular; /** * Constructor for BandLU * * @param n * Matrix size * @param kl * Number of lower matrix bands * @param ku * Number of upper matrix bands */ public BandLU(int n, int kl, int ku) { this.n = n; this.kl = kl; this.ku = ku; LU = new BandMatrix(n, kl, ku + kl); ipiv = new int[n]; } /** * Creates an LU decomposition of the given matrix * * @param A * Matrix to decompose. Not modified * @return A LU decomposition of the matrix */ public static BandLU factorize(BandMatrix A) { return new BandLU(A.numRows(), A.kl, A.ku).factor(A, false); } /** * Creates an LU decomposition of the given matrix * * @param A * Matrix to decompose. If the decomposition is in-place, its * number of superdiagonals must equal kl+ku * @param inplace * Wheter or not the decomposition should overwrite the passed * matrix * @return The current decomposition */ public BandLU factor(BandMatrix A, boolean inplace) { if (inplace) return factor(A); else return factor(new BandMatrix(A, kl, kl + ku)); } /** * Creates an LU decomposition of the given matrix * * @param A * Matrix to decompose. It will be overwritten with the * decomposition. Its number of superdiagonals must equal * kl+ku * @return The current decomposition */ public BandLU factor(BandMatrix A) { if (!(A.isSquare())) throw new IllegalArgumentException("!A.isSquare()"); if (n != A.numRows()) throw new IllegalArgumentException("n != A.numRows()"); if (A.ku != ku + kl) throw new IllegalArgumentException("A.ku != ku + kl"); singular = false; intW info = new intW(0); LAPACK.getInstance().dgbtrf(n, n, kl, ku, A.getData(), 2 * kl + ku + 1, ipiv, info); if (info.val > 0) singular = true; else if (info.val < 0) throw new IllegalArgumentException(); LU.set(A); return this; } /** * Returns the lower triangular factor */ public UnitLowerTriangBandMatrix getL() { return new UnitLowerTriangBandMatrix(LU, LU.numSubDiagonals(), false); } /** * Returns the upper triangular factor */ public UpperTriangBandMatrix getU() { return new UpperTriangBandMatrix(LU, LU.numSuperDiagonals(), false); } /** * Returns the decomposition matrix */ public BandMatrix getLU() { return LU; } /** * Returns the row pivots */ public int[] getPivots() { return ipiv; } /** * Checks for singularity */ public boolean isSingular() { return singular; } /** * Computes the reciprocal condition number, using either the infinity norm * of the 1 norm. * * @param A * The matrix this is a decomposition of * @param norm * Either Norm.One or Norm.Infinity * @return The reciprocal condition number. Values close to unity indicate a * well-conditioned system, while numbers close to zero do not. */ public double rcond(Matrix A, Norm norm) { if (norm != Norm.One && norm != Norm.Infinity) throw new IllegalArgumentException( "Only the 1 or the Infinity norms are supported"); if (A.numRows() != n) throw new IllegalArgumentException("A.numRows() != n"); if (!A.isSquare()) throw new IllegalArgumentException("!A.isSquare()"); double anorm = A.norm(norm); double[] work = new double[3 * n]; int[] lwork = new int[n]; intW info = new intW(0); doubleW rcond = new doubleW(0); LAPACK.getInstance().dgbcon(norm.netlib(), n, kl, ku, LU.getData(), Matrices.ld(2 * kl + ku + 1), ipiv, anorm, rcond, work, lwork, info); if (info.val < 0) throw new IllegalArgumentException(); return rcond.val; } /** * Computes A\B, overwriting B */ public DenseMatrix solve(DenseMatrix B) throws MatrixSingularException { return solve(B, Transpose.NoTranspose); } /** * Computes AT\B, overwriting B */ public DenseMatrix transSolve(DenseMatrix B) throws MatrixSingularException { return solve(B, Transpose.Transpose); } private DenseMatrix solve(DenseMatrix B, Transpose trans) throws MatrixSingularException { if (singular) throw new MatrixSingularException(); if (B.numRows() != n) throw new IllegalArgumentException("B.numRows() != n"); intW info = new intW(0); LAPACK.getInstance().dgbtrs(trans.netlib(), n, kl, ku, B.numColumns(), LU.getData(), 2 * kl + ku + 1, ipiv, B.getData(), Matrices.ld(n), info); if (info.val < 0) throw new IllegalArgumentException(); return B; } } mtj-0.9.14/src/no/uib/cipr/matrix/DenseMatrix.java0000644000000000000000000004037211166446172020424 0ustar rootroot/* * 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.io.IOException; import no.uib.cipr.matrix.io.MatrixInfo; import no.uib.cipr.matrix.io.MatrixSize; import no.uib.cipr.matrix.io.MatrixVectorReader; import org.netlib.blas.BLAS; import org.netlib.lapack.LAPACK; import org.netlib.util.intW; /** * Dense matrix. It is a good all-round matrix structure, with fast access and * efficient algebraic operations. The matrix *

* * * * * * * * * * * * * * * * * * * * * * * * * *
a11a12a13a14
a21a22a23a24
a31a32a33a34
a41a42a43a44
*

*

* is stored column major in a single array, as follows: *

*

* * * * * * * * * * * * * * * * * * * *
a11a21a31a41a12a22a32a42a13a23a33a43a14a24a34a44
*

*/ public class DenseMatrix extends AbstractDenseMatrix { /** * Constructor for DenseMatrix * * @param r * Reader to get the matrix from */ public DenseMatrix(MatrixVectorReader r) throws IOException { // Start with a zero-sized matrix super(0, 0); // Get matrix information. Use the header if present, else use a safe // default MatrixInfo info = null; if (r.hasInfo()) info = r.readMatrixInfo(); else info = new MatrixInfo(true, MatrixInfo.MatrixField.Real, MatrixInfo.MatrixSymmetry.General); MatrixSize size = r.readMatrixSize(info); // Resize the matrix to correct size numRows = size.numRows(); numColumns = size.numColumns(); data = new double[numRows * numColumns]; // Check that the matrix is in an acceptable format if (info.isPattern()) throw new UnsupportedOperationException( "Pattern matrices are not supported"); if (info.isComplex()) throw new UnsupportedOperationException( "Complex matrices are not supported"); // Read the entries, in either coordinate or array format if (info.isCoordinate()) { // Read coordinate data int nz = size.numEntries(); int[] row = new int[nz]; int[] column = new int[nz]; double[] entry = new double[nz]; r.readCoordinate(row, column, entry); // Shift indices from 1-offset to 0-offset r.add(-1, row); r.add(-1, column); // Store them for (int i = 0; i < nz; ++i) set(row[i], column[i], entry[i]); } else // info.isArray() r.readArray(data); // Put in missing entries from symmetry or skew symmetry if (info.isSymmetric()) for (int i = 0; i < numRows; ++i) for (int j = 0; j < i; ++j) set(j, i, get(i, j)); else if (info.isSkewSymmetric()) for (int i = 0; i < numRows; ++i) for (int j = 0; j < i; ++j) set(j, i, -get(i, j)); } /** * Constructor for DenseMatrix * * @param numRows * Number of rows * @param numColumns * Number of columns */ public DenseMatrix(int numRows, int numColumns) { super(numRows, numColumns); } /** * Constructor for DenseMatrix * * @param A * Matrix to copy. A deep copy is made */ public DenseMatrix(Matrix A) { super(A); } /** * Constructor for DenseMatrix * * @param A * Matrix to copy contents from * @param deep * If true, A is copied, else a shallow copy is * made and the matrices share underlying storage. For this, * A must be a dense matrix */ public DenseMatrix(Matrix A, boolean deep) { super(A, deep); } /** * Constructor for DenseMatrix. Builds the matrix from a vector * * @param x * Vector to copy from. This will form this matrix' single column * @param deep * If true, x is copied, if false, the internal storage of this * matrix is the same as that of the vector. In that case, * x must be a DenseVector */ public DenseMatrix(Vector x, boolean deep) { super(x.size(), 1); if (deep) for (VectorEntry e : x) set(e.index(), 0, e.get()); else { if (!(x instanceof DenseVector)) throw new IllegalArgumentException("x must be a DenseVector"); data = ((DenseVector) x).getData(); } } /** * Constructor for DenseMatrix. Builds the matrix from a vector * * @param x * The vector which forms this matrix' single column. It is * copied, not referenced */ public DenseMatrix(Vector x) { this(x, true); } /** * Constructor for DenseMatrix. Builds the matrix from vectors. Each vector * will correspond to a column of the matrix * * @param x * Vectors which forms the columns of this matrix. Every vector * must have the same size */ public DenseMatrix(Vector[] x) { super(x[0].size(), x.length); // Ensure correct sizes for (Vector v : x) if (v.size() != numRows) throw new IllegalArgumentException( "All vectors must be of the same size"); // Copy the contents for (int j = 0; j < x.length; ++j) for (VectorEntry e : x[j]) set(e.index(), j, e.get()); } /** * Constructor for DenseMatrix. Copies from the passed array * * @param values * Arrays to copy from. Every sub-array must have the same size */ public DenseMatrix(double[][] values) { super(values.length, values[0].length); // Copy the contents for (int i = 0; i < values.length; ++i) { if (values[i].length != numColumns) throw new IllegalArgumentException("Array cannot be jagged"); for (int j = 0; j < values[i].length; ++j) set(i, j, values[i][j]); } } @Override public DenseMatrix copy() { return new DenseMatrix(this); } @Override void copy(Matrix A) { for (MatrixEntry e : A) set(e.row(), e.column(), e.get()); } @Override public Matrix multAdd(double alpha, Matrix B, Matrix C) { if (!(B instanceof DenseMatrix) || !(C instanceof DenseMatrix)) return super.multAdd(alpha, B, C); checkMultAdd(B, C); double[] Bd = ((DenseMatrix) B).getData(), Cd = ((DenseMatrix) C) .getData(); BLAS.getInstance().dgemm(Transpose.NoTranspose.netlib(), Transpose.NoTranspose.netlib(), C.numRows(), C.numColumns(), numColumns, alpha, data, Math.max(1, numRows), Bd, Math.max(1, B.numRows()), 1, Cd, Math.max(1, C.numRows())); return C; } @Override public Matrix transAmultAdd(double alpha, Matrix B, Matrix C) { if (!(B instanceof DenseMatrix) || !(C instanceof DenseMatrix)) return super.transAmultAdd(alpha, B, C); checkTransAmultAdd(B, C); double[] Bd = ((DenseMatrix) B).getData(), Cd = ((DenseMatrix) C) .getData(); BLAS.getInstance().dgemm(Transpose.Transpose.netlib(), Transpose.NoTranspose.netlib(), C.numRows(), C.numColumns(), numRows, alpha, data, Math.max(1, numRows), Bd, Math.max(1, B.numRows()), 1, Cd, Math.max(1, C.numRows())); return C; } @Override public Matrix transBmultAdd(double alpha, Matrix B, Matrix C) { if (!(B instanceof DenseMatrix) || !(C instanceof DenseMatrix)) return super.transBmultAdd(alpha, B, C); checkTransBmultAdd(B, C); double[] Bd = ((DenseMatrix) B).getData(), Cd = ((DenseMatrix) C) .getData(); BLAS.getInstance().dgemm(Transpose.NoTranspose.netlib(), Transpose.Transpose.netlib(), C.numRows(), C.numColumns(), numColumns, alpha, data, Math.max(1, numRows), Bd, Math.max(1, B.numRows()), 1, Cd, Math.max(1, C.numRows())); return C; } @Override public Matrix transABmultAdd(double alpha, Matrix B, Matrix C) { if (!(B instanceof DenseMatrix) || !(C instanceof DenseMatrix)) return super.transABmultAdd(alpha, B, C); checkTransABmultAdd(B, C); double[] Bd = ((DenseMatrix) B).getData(), Cd = ((DenseMatrix) C) .getData(); BLAS.getInstance().dgemm(Transpose.Transpose.netlib(), Transpose.Transpose.netlib(), C.numRows(), C.numColumns(), numRows, alpha, data, Math.max(1, numRows), Bd, Math.max(1, B.numRows()), 1, Cd, Math.max(1, C.numRows())); return C; } @Override public Matrix rank1(double alpha, Vector x, Vector y) { if (!(x instanceof DenseVector) || !(y instanceof DenseVector)) return super.rank1(alpha, x, y); checkRank1(x, y); double[] xd = ((DenseVector) x).getData(), yd = ((DenseVector) y) .getData(); BLAS.getInstance().dger(numRows, numColumns, alpha, xd, 1, yd, 1, data, Math.max(1, numRows)); 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().dgemv(Transpose.NoTranspose.netlib(), numRows, numColumns, alpha, data, Math.max(numRows, 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().dgemv(Transpose.Transpose.netlib(), numRows, numColumns, alpha, data, Math.max(numRows, 1), xd, 1, 1, yd, 1); return y; } @Override public Matrix solve(Matrix B, Matrix X) { // We allow non-square matrices, as we then use a least-squares solver if (numRows != B.numRows()) throw new IllegalArgumentException("numRows != B.numRows() (" + numRows + " != " + B.numRows() + ")"); if (numColumns != X.numRows()) throw new IllegalArgumentException("numColumns != X.numRows() (" + numColumns + " != " + X.numRows() + ")"); if (X.numColumns() != B.numColumns()) throw new IllegalArgumentException( "X.numColumns() != B.numColumns() (" + X.numColumns() + " != " + B.numColumns() + ")"); if (isSquare()) return LUsolve(B, X); else return QRsolve(B, X, Transpose.NoTranspose); } @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 transSolve(Matrix B, Matrix X) { // We allow non-square matrices, as we then use a least-squares solver if (numColumns != B.numRows()) throw new IllegalArgumentException("numColumns != B.numRows() (" + numColumns + " != " + B.numRows() + ")"); if (numRows != X.numRows()) throw new IllegalArgumentException("numRows != X.numRows() (" + numRows + " != " + X.numRows() + ")"); if (X.numColumns() != B.numColumns()) throw new IllegalArgumentException( "X.numColumns() != B.numColumns() (" + X.numColumns() + " != " + B.numColumns() + ")"); return QRsolve(B, X, Transpose.Transpose); } @Override public Vector transSolve(Vector b, Vector x) { DenseMatrix B = new DenseMatrix(b, false), X = new DenseMatrix(x, false); transSolve(B, X); return x; } Matrix LUsolve(Matrix B, Matrix X) { if (!(X instanceof DenseMatrix)) throw new UnsupportedOperationException("X must be a DenseMatrix"); double[] Xd = ((DenseMatrix) X).getData(); X.set(B); int[] piv = new int[numRows]; intW info = new intW(0); LAPACK.getInstance().dgesv(numRows, B.numColumns(), data.clone(), Matrices.ld(numRows), piv, Xd, Matrices.ld(numRows), info); if (info.val > 0) throw new MatrixSingularException(); else if (info.val < 0) throw new IllegalArgumentException(); return X; } Matrix QRsolve(Matrix B, Matrix X, Transpose trans) { int nrhs = B.numColumns(); // Allocate temporary solution matrix DenseMatrix Xtmp = new DenseMatrix(Math.max(numRows, numColumns), nrhs); int M = trans == Transpose.NoTranspose ? numRows : numColumns; for (int j = 0; j < nrhs; ++j) for (int i = 0; i < M; ++i) Xtmp.set(i, j, B.get(i, j)); double[] newData = data.clone(); // Query optimal workspace double[] work = new double[1]; intW info = new intW(0); LAPACK.getInstance().dgels(trans.netlib(), numRows, numColumns, nrhs, newData, Matrices.ld(numRows), Xtmp.getData(), Matrices.ld(numRows, numColumns), work, -1, info); // Allocate workspace int lwork = -1; if (info.val != 0) lwork = Math.max(1, Math.min(numRows, numColumns) + Math.max(Math.min(numRows, numColumns), nrhs)); else lwork = Math.max((int) work[0], 1); work = new double[lwork]; // Compute the factorization info.val = 0; LAPACK.getInstance().dgels(trans.netlib(), numRows, numColumns, nrhs, newData, Matrices.ld(numRows), Xtmp.getData(), Matrices.ld(numRows, numColumns), work, lwork, info); if (info.val < 0) throw new IllegalArgumentException(); // Extract the solution int N = trans == Transpose.NoTranspose ? numColumns : numRows; for (int j = 0; j < nrhs; ++j) for (int i = 0; i < N; ++i) X.set(i, j, Xtmp.get(i, j)); return X; } } mtj-0.9.14/src/no/uib/cipr/matrix/LQ.java0000644000000000000000000000773011027512662016510 0ustar rootroot/* * 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 org.netlib.lapack.LAPACK; import org.netlib.util.intW; /** * Computes LQ decompositions */ public class LQ extends OrthogonalComputer { /** * Constructs an empty LQ decomposition * * @param m * Number of rows * @param n * Number of columns. Must be larger than or equal the number of * rows */ public LQ(int m, int n) { super(m, n, false); if (n < m) throw new IllegalArgumentException("n < m"); int lwork; // Query optimal workspace. First for computing the factorization { work = new double[1]; intW info = new intW(0); LAPACK.getInstance().dgelqf(m, n, new double[0], Matrices.ld(m), new double[0], work, -1, info); if (info.val != 0) lwork = m; else lwork = (int) work[0]; lwork = Math.max(1, lwork); work = new double[lwork]; } // Workspace needed for generating an explicit orthogonal matrix { workGen = new double[1]; intW info = new intW(0); LAPACK.getInstance().dorglq(m, n, m, new double[0], Matrices.ld(m), new double[0], workGen, -1, info); if (info.val != 0) lwork = m; else lwork = (int) workGen[0]; lwork = Math.max(1, lwork); workGen = new double[lwork]; } } /** * Convenience method to compute a LQ decomposition * * @param A * Matrix to decompose. Not modified * @return Newly allocated decomposition */ public static LQ factorize(Matrix A) { return new LQ(A.numRows(), A.numColumns()).factor(new DenseMatrix(A)); } @Override public LQ factor(DenseMatrix A) { if (Q.numRows() != A.numRows()) throw new IllegalArgumentException("Q.numRows() != A.numRows()"); else if (Q.numColumns() != A.numColumns()) throw new IllegalArgumentException( "Q.numColumns() != A.numColumns()"); else if (L == null) throw new IllegalArgumentException("L == null"); /* * Calculate factorisation, and extract the triangular factor */ intW info = new intW(0); LAPACK.getInstance().dgelqf(m, n, A.getData(), Matrices.ld(m), tau, work, work.length, info); if (info.val < 0) throw new IllegalArgumentException(); L.zero(); for (MatrixEntry e : A) if (e.row() >= e.column()) L.set(e.row(), e.column(), e.get()); /* * Generate the orthogonal matrix */ info.val = 0; LAPACK.getInstance().dorglq(m, n, k, A.getData(), Matrices.ld(m), tau, workGen, workGen.length, info); if (info.val < 0) throw new IllegalArgumentException(); Q.set(A); return this; } /** * Returns the lower triangular factor */ public LowerTriangDenseMatrix getL() { return L; } } mtj-0.9.14/src/no/uib/cipr/matrix/NotConvergedException.java0000644000000000000000000000427411027512662022450 0ustar rootroot/* * 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; /** * Signals lack of convergence of an iterative process */ public class NotConvergedException extends Exception { private static final long serialVersionUID = -2305369220010776320L; /** * Possible reasons for lack of convergence */ public enum Reason { /** * Did not converge after a maximum number of iterations */ Iterations, /** * Divergence detected */ Divergence, /** * The iterative process detected a breakdown */ Breakdown } /** * The reason for this exception */ protected Reason reason; /** * Constructor for NotConvergedException * * @param reason * The reason for the lack of convergence * @param message * A more descriptive explanation */ public NotConvergedException(Reason reason, String message) { super(message); this.reason = reason; } /** * Constructor for NotConvergedException. No message is provided * * @param reason * The reason for the lack of convergence */ public NotConvergedException(Reason reason) { this.reason = reason; } /** * Returns the reason for the exception */ public Reason getReason() { return reason; } } mtj-0.9.14/src/no/uib/cipr/matrix/LowerSymmBandMatrix.java0000644000000000000000000000614211027512662022100 0ustar rootroot/* * 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; /** * Lower symmetrical banded matrix. The same storage as * {@link no.uib.cipr.matrix.BandMatrix BandMatrix}, but without * superdiagonals. Upper part of the matrix is implictly known by symmetry */ public class LowerSymmBandMatrix extends AbstractSymmBandMatrix { /** * Constructor for LowerSymmBandMatrix * * @param n * Size of the matrix. Since the matrix must be square, this * equals both the number of rows and columns * @param kd * Number of bands off the main diagonal (off diagonals) */ public LowerSymmBandMatrix(int n, int kd) { super(n, kd, 0, UpLo.Lower); } /** * Constructor for LowerSymmBandMatrix * * @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 kd * Number of bands off the main diagonal (off diagonals) */ public LowerSymmBandMatrix(Matrix A, int kd) { this(A, kd, true); } /** * Constructor for LowerSymmBandMatrix * * @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 kd * Number of bands off the main diagonal (off diagonals) * @param deep * True for a deep copy. For shallow copies, A * must be a banded matrix */ public LowerSymmBandMatrix(Matrix A, int kd, boolean deep) { super(A, kd, 0, deep, UpLo.Lower); } @Override public void add(int row, int column, double value) { if (column <= row) super.add(row, column, value); } @Override public double get(int row, int column) { if (column > row) return super.get(column, row); return super.get(row, column); } @Override public void set(int row, int column, double value) { if (column <= row) super.set(row, column, value); } @Override public LowerSymmBandMatrix copy() { return new LowerSymmBandMatrix(this, kd); } } mtj-0.9.14/src/no/uib/cipr/matrix/LowerSPDPackMatrix.java0000644000000000000000000000456211027512662021617 0ustar rootroot/* * 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; /** * Lower symmetrical positive definite packed matrix. Same layout as * {@link no.uib.cipr.matrix.LowerSymmPackMatrix LowerSymmPackMatrix}. This * class does not enforce the SPD property, but serves as a tag so that more * efficient algorithms can be used in the solvers. */ public class LowerSPDPackMatrix extends LowerSymmPackMatrix { /** * Constructor for LowerSPDPackMatrix * * @param n * Size of the matrix. Since the matrix must be square, this * equals both the number of rows and columns */ public LowerSPDPackMatrix(int n) { super(n); } /** * Constructor for LowerSPDPackMatrix * * @param A * Matrix to copy contents from. Only the entries of the relevant * part are copied */ public LowerSPDPackMatrix(Matrix A) { this(A, true); } /** * Constructor for LowerSPDPackMatrix * * @param A * Matrix to copy contents from. Only the entries of the relevant * part are copied * @param deep * True if the copy is deep, else false (giving a shallow copy). * For shallow copies, A must be a packed matrix */ public LowerSPDPackMatrix(Matrix A, boolean deep) { super(A, deep); } @Override public LowerSPDPackMatrix copy() { return new LowerSPDPackMatrix(this); } @Override public Matrix solve(Matrix B, Matrix X) { return SPDsolve(B, X); } } mtj-0.9.14/src/no/uib/cipr/matrix/AbstractSymmDenseMatrix.java0000644000000000000000000002047711027512662022754 0ustar rootroot/* * 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 org.netlib.blas.BLAS; import org.netlib.lapack.LAPACK; import org.netlib.util.intW; /** * Partial implementation of a symmetrical, dense matrix */ abstract class AbstractSymmDenseMatrix extends AbstractDenseMatrix { /** * Upper or lower part stored? */ private UpLo uplo; /** * Constructor for AbstractSymmDenseMatrix */ AbstractSymmDenseMatrix(int n, UpLo uplo) { super(n, n); this.uplo = uplo; } /** * Constructor for AbstractSymmDenseMatrix */ AbstractSymmDenseMatrix(Matrix A, UpLo uplo) { this(A, true, uplo); } /** * Constructor for AbstractSymmDenseMatrix */ AbstractSymmDenseMatrix(Matrix A, boolean deep, UpLo uplo) { super(A, deep); if (!isSquare()) throw new IllegalArgumentException( "Symmetric matrix must be square"); this.uplo = uplo; } @Override public Matrix multAdd(double alpha, Matrix B, Matrix C) { if (!(B instanceof DenseMatrix) || !(C instanceof DenseMatrix)) return super.multAdd(alpha, B, C); checkMultAdd(B, C); double[] Bd = ((DenseMatrix) B).getData(), Cd = ((DenseMatrix) C) .getData(); BLAS.getInstance().dsymm(Side.Left.netlib(), uplo.netlib(), C.numRows(), C.numColumns(), alpha, data, Math.max(1, C.numRows()), Bd, Math.max(1, C.numRows()), 1, Cd, Math.max(1, C.numRows())); return C; } @Override public Matrix transAmultAdd(double alpha, Matrix B, Matrix C) { return multAdd(alpha, B, C); } @Override public Matrix rank1(double alpha, Vector x, Vector y) { if (x != y) throw new IllegalArgumentException("x != y"); if (!(x instanceof DenseVector)) return super.rank1(alpha, x, y); checkRank1(x, y); double[] xd = ((DenseVector) x).getData(); BLAS.getInstance().dsyr(uplo.netlib(), numRows, alpha, xd, 1, data, Math.max(1, numRows)); return this; } @Override public Matrix rank2(double alpha, Vector x, Vector y) { if (!(x instanceof DenseVector) || !(y instanceof DenseVector)) return super.rank2(alpha, x, y); checkRank2(x, y); double[] xd = ((DenseVector) x).getData(), yd = ((DenseVector) y) .getData(); BLAS.getInstance().dsyr2(uplo.netlib(), numRows, alpha, xd, 1, yd, 1, data, Math.max(1, numRows)); 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().dsymv(uplo.netlib(), numRows, alpha, data, Math.max(1, numRows), xd, 1, 1, yd, 1); return y; } @Override public Vector transMultAdd(double alpha, Vector x, Vector y) { return multAdd(alpha, x, y); } @Override public Matrix rank1(double alpha, Matrix C) { if (!(C instanceof DenseMatrix)) return super.rank1(alpha, C); checkRank1(C); double[] Cd = ((DenseMatrix) C).getData(); BLAS.getInstance().dsyrk(uplo.netlib(), Transpose.NoTranspose.netlib(), numRows, C.numColumns(), alpha, Cd, Math.max(1, numRows), 1, data, Math.max(1, numRows)); return this; } @Override public Matrix transRank1(double alpha, Matrix C) { if (!(C instanceof DenseMatrix)) return super.transRank1(alpha, C); checkTransRank1(C); double[] Cd = ((DenseMatrix) C).getData(); BLAS.getInstance().dsyrk(uplo.netlib(), Transpose.Transpose.netlib(), numRows, numRows, alpha, Cd, Math.max(1, numRows), 1, data, Math.max(1, numRows)); return this; } @Override public Matrix rank2(double alpha, Matrix B, Matrix C) { if (!(B instanceof DenseMatrix) || !(C instanceof DenseMatrix)) return super.rank2(alpha, B, C); checkRank2(B, C); double[] Bd = ((DenseMatrix) B).getData(), Cd = ((DenseMatrix) C) .getData(); BLAS.getInstance().dsyr2k(uplo.netlib(), Transpose.NoTranspose.netlib(), numRows, B.numColumns(), alpha, Bd, Math.max(1, numRows), Cd, Math.max(1, numRows), 1, data, Math.max(1, numRows)); return this; } @Override public Matrix transRank2(double alpha, Matrix B, Matrix C) { if (!(B instanceof DenseMatrix) || !(C instanceof DenseMatrix)) return super.transRank2(alpha, B, C); checkTransRank2(B, C); double[] Bd = ((DenseMatrix) B).getData(), Cd = ((DenseMatrix) C) .getData(); BLAS.getInstance().dsyr2k(uplo.netlib(), Transpose.Transpose.netlib(), numRows, B.numRows(), alpha, Bd, Math.max(1, B.numRows()), Cd, Math.max(1, B.numRows()), 1, data, Math.max(1, numRows)); return this; } @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 double[] newData = data.clone(); int[] ipiv = new int[numRows]; // Query optimal workspace double[] work = new double[1]; intW info = new intW(0); LAPACK.getInstance().dsysv(uplo.netlib(), numRows, X.numColumns(), newData, Matrices.ld(numRows), ipiv, Xd, Matrices.ld(numRows), work, -1, info); // Allocate workspace int lwork = -1; if (info.val != 0) lwork = 1; else lwork = Math.max((int) work[0], 1); work = new double[lwork]; // Solve info.val = 0; LAPACK.getInstance().dsysv(uplo.netlib(), numRows, X.numColumns(), newData, Matrices.ld(numRows), ipiv, Xd, Matrices.ld(numRows), work, lwork, 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 transSolve(Matrix B, Matrix X) { return solve(B, X); } @Override public Vector transSolve(Vector b, Vector x) { return solve(b, x); } Matrix SPDsolve(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); intW info = new intW(0); LAPACK.getInstance().dposv(uplo.netlib(), numRows, X.numColumns(), data.clone(), Matrices.ld(numRows), Xd, Matrices.ld(numRows), info); if (info.val > 0) throw new MatrixNotSPDException(); else if (info.val < 0) throw new IllegalArgumentException(); return X; } @Override public Matrix transpose() { return this; } } mtj-0.9.14/src/no/uib/cipr/matrix/UpperTriangDenseMatrix.java0000644000000000000000000001237511027512662022601 0ustar rootroot/* * 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; /** * Upper triangular dense matrix. It has the same storage layout as the * {@link no.uib.cipr.matrix.DenseMatrix DenseMatrix}, but only refers to * elements above or on the main diagonal. The remaining elements are assumed to * be zero, but since they are never accessed, they need not be. */ public class UpperTriangDenseMatrix extends AbstractTriangDenseMatrix { /** * Constructor for UpperTriangDenseMatrix * * @param n * Size of the matrix. Since the matrix must be square, this * equals both the number of rows and columns */ public UpperTriangDenseMatrix(int n) { super(n, UpLo.Upper, Diag.NonUnit); } /** * Constructor for UpperTriangDenseMatrix * * @param n * Size of the matrix. Since the matrix must be square, this * equals both the number of rows and columns */ UpperTriangDenseMatrix(int n, Diag diag) { super(n, UpLo.Upper, diag); } /** * Constructor for UpperTriangDenseMatrix * * @param A * Matrix to copy from. Only the upper triangular part is copied */ public UpperTriangDenseMatrix(Matrix A) { this(A, Math.min(A.numRows(), A.numColumns())); } /** * Constructor for UpperTriangDenseMatrix * * @param A * Matrix to copy from. Only the upper triangular part is copied * @param deep * True for deep copy, false for reference (in which case * A must be a dense matrix) */ public UpperTriangDenseMatrix(Matrix A, boolean deep) { this(A, Math.min(A.numRows(), A.numColumns()), deep); } /** * Constructor for UpperTriangDenseMatrix * * @param A * Matrix to copy from. Only the upper triangular part is copied * @param deep * True for deep copy, false for reference (in which case * A must be a dense matrix) */ UpperTriangDenseMatrix(Matrix A, boolean deep, Diag diag) { this(A, Math.min(A.numRows(), A.numColumns()), deep, diag); } /** * Constructor for UpperTriangDenseMatrix * * @param A * Matrix to copy from. Only the upper triangular part is copied * @param k * Size of matrix to refer. * k<min(numRows,numColumns) */ public UpperTriangDenseMatrix(Matrix A, int k) { this(A, k, true); } /** * Constructor for UpperTriangDenseMatrix * * @param A * Matrix to copy from. Only the upper triangular part is copied * @param k * Size of matrix to refer. * k<min(numRows,numColumns) * @param deep * True for deep copy, false for reference (in which case * A must be a dense matrix) */ public UpperTriangDenseMatrix(Matrix A, int k, boolean deep) { super(A, k, deep, UpLo.Upper, Diag.NonUnit); } /** * Constructor for UpperTriangDenseMatrix * * @param A * Matrix to copy from. Only the upper triangular part is copied * @param k * Size of matrix to refer. * k<min(numRows,numColumns) * @param deep * True for deep copy, false for reference (in which case * A must be a dense matrix) */ UpperTriangDenseMatrix(Matrix A, int k, boolean deep, Diag diag) { super(A, k, deep, UpLo.Upper, diag); } @Override public void add(int row, int column, double value) { if (row > column) throw new IllegalArgumentException("row > column"); super.add(row, column, value); } @Override public double get(int row, int column) { if (row > column) return 0; return super.get(row, column); } @Override public void set(int row, int column, double value) { if (row > column) throw new IllegalArgumentException("row > column"); super.set(row, column, value); } @Override void copy(Matrix A) { for (MatrixEntry e : A) if (e.row() <= e.column()) set(e.row(), e.column(), e.get()); } @Override public UpperTriangDenseMatrix copy() { return new UpperTriangDenseMatrix(this); } } mtj-0.9.14/src/no/uib/cipr/matrix/JobSVD.java0000644000000000000000000000333711027512662017262 0ustar rootroot/* * 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; /** * The job the singular value solvers are to do. This only limits which singular vectors * are computed, all the singular values are always computed */ enum JobSVD { /** Compute all of the singular vectors */ All, /** Do not compute any singular vectors */ None, /** * Overwrite passed data. For an M*N matrix, this either overwrites the * passed matrix with as many singular vectors as there is room for. Details depend on * the actual algorithm */ Overwrite, /** * Compute parts of the singular vectors. For an M*N matrix, this * computes min(M,N) singular vectors */ Part; /** * @return the netlib character version of this designation, for use with F2J. */ public String netlib() { switch (this) { case All: return "A"; case Part: return "S"; case Overwrite: return "O"; default: return "N"; } } }mtj-0.9.14/src/no/uib/cipr/matrix/io/0000755000000000000000000000000011027515240015724 5ustar rootrootmtj-0.9.14/src/no/uib/cipr/matrix/io/MatrixVectorReader.java0000644000000000000000000005136111027512662022354 0ustar rootroot/* * 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.io; import java.io.BufferedReader; import java.io.EOFException; import java.io.IOException; import java.io.Reader; import java.io.StreamTokenizer; import java.util.LinkedList; import java.util.List; /** * Reads matrices and vectors */ public class MatrixVectorReader extends BufferedReader { /** * Reads the entries of the matrix or vector */ private StreamTokenizer st; /** * Constructor for MatrixVectorReader * * @param in * A Reader */ public MatrixVectorReader(Reader in) { super(in); setup(); } /** * Constructor for MatrixVectorReader * * @param in * A Reader * @param sz * Input buffer size */ public MatrixVectorReader(Reader in, int sz) { super(in, sz); setup(); } /** * Sets up the stream tokenizer */ private void setup() { st = new StreamTokenizer(this); st.resetSyntax(); st.eolIsSignificant(false); st.lowerCaseMode(true); // Parse numbers as words st.wordChars('0', '9'); st.wordChars('-', '.'); // Characters as words st.wordChars('\u0000', '\u00FF'); // Skip comments st.commentChar('%'); // Skip whitespace and newlines st.whitespaceChars(' ', ' '); st.whitespaceChars('\u0009', '\u000e'); } /** * Shifts the indices. Useful for converting between 0- and 1-based * indicing. * * @param num * Added to every index * @param indices * Indices to shift */ public void add(int num, int[] indices) { for (int i = 0; i < indices.length; ++i) indices[i] += num; } /** * Reads a line, and trims it of surrounding whitespace * * @throws IOException * If either I/O errors occur, or there was nothing to read */ private String readTrimmedLine() throws IOException { String line = readLine(); if (line != null) return line.trim(); else throw new EOFException(); } /** * Reads the matrix info for the Matrix Market exchange format. The line * must consist of exactly 5 space-separated entries, the first being * "%%MatrixMarket" */ public MatrixInfo readMatrixInfo() throws IOException { String[] component = readTrimmedLine().split(" +"); if (component.length != 5) throw new IOException( "Current line unparsable. It must consist of 5 tokens"); // Read header if (!component[0].equalsIgnoreCase("%%MatrixMarket")) throw new IOException("Not in Matrix Market exchange format"); // This will always be "matrix" if (!component[1].equalsIgnoreCase("matrix")) throw new IOException("Expected \"matrix\", got " + component[1]); // Sparse or dense? boolean sparse = false; if (component[2].equalsIgnoreCase("coordinate")) sparse = true; else if (component[2].equalsIgnoreCase("array")) sparse = false; else throw new IOException("Unknown layout " + component[2]); // Dataformat MatrixInfo.MatrixField field = null; if (component[3].equalsIgnoreCase("real")) field = MatrixInfo.MatrixField.Real; else if (component[3].equalsIgnoreCase("integer")) field = MatrixInfo.MatrixField.Integer; else if (component[3].equalsIgnoreCase("complex")) field = MatrixInfo.MatrixField.Complex; else if (component[3].equalsIgnoreCase("pattern")) field = MatrixInfo.MatrixField.Pattern; else throw new IOException("Unknown field specification " + component[3]); // Matrix pattern MatrixInfo.MatrixSymmetry symmetry = null; if (component[4].equalsIgnoreCase("general")) symmetry = MatrixInfo.MatrixSymmetry.General; else if (component[4].equalsIgnoreCase("symmetric")) symmetry = MatrixInfo.MatrixSymmetry.Symmetric; else if (component[4].equalsIgnoreCase("skew-symmetric")) symmetry = MatrixInfo.MatrixSymmetry.SkewSymmetric; else if (component[4].equalsIgnoreCase("Hermitian")) symmetry = MatrixInfo.MatrixSymmetry.Hermitian; else throw new IOException("Unknown symmetry specification " + component[4]); // Pack together. This also verifies the format return new MatrixInfo(sparse, field, symmetry); } /** * Reads the vector info for the Matrix Market exchange format. The line * must consist of exactly 4 space-separated entries, the first being * "%%MatrixMarket" */ public VectorInfo readVectorInfo() throws IOException { String[] component = readTrimmedLine().split(" +"); if (component.length != 4) throw new IOException( "Current line unparsable. It must consist of 4 tokens"); // Read header if (!component[0].equalsIgnoreCase("%%MatrixMarket")) throw new IOException("Not in Matrix Market exchange format"); // This will always be "vector" if (!component[1].equalsIgnoreCase("vector")) throw new IOException("Expected \"vector\", got " + component[1]); // Sparse or dense? boolean sparse = false; if (component[2].equalsIgnoreCase("coordinate")) sparse = true; else if (component[2].equalsIgnoreCase("array")) sparse = false; else throw new IOException("Unknown layout " + component[2]); // Dataformat VectorInfo.VectorField field = null; if (component[3].equalsIgnoreCase("real")) field = VectorInfo.VectorField.Real; else if (component[3].equalsIgnoreCase("integer")) field = VectorInfo.VectorField.Integer; else if (component[3].equalsIgnoreCase("complex")) field = VectorInfo.VectorField.Complex; else if (component[3].equalsIgnoreCase("pattern")) field = VectorInfo.VectorField.Pattern; else throw new IOException("Unknown field specification " + component[3]); // Pack together. This also verifies the format return new VectorInfo(sparse, field); } /** * Checks if a Matrix Market header is present ("%%MatrixMarket") * * @return True if a header was found, else false * @throws IOException */ public boolean hasInfo() throws IOException { // Read a line, then skip back mark(1024); String[] component = readTrimmedLine().split(" +"); reset(); return component[0].equalsIgnoreCase("%%MatrixMarket"); } /** * Reads all the comments (lines starting with '%'). Positions the reader at * the first non-comment line. Can only be called after reading the matrix * or vector info. The comments read does not include '%' or the newline */ public String[] readComments() throws IOException { List list = new LinkedList(); while (true) { mark(1024); // Line length equal 1024 at most String line = readTrimmedLine(); if (line.length() > 0) if (line.charAt(0) != '%') { reset(); break; } else list.add(line.substring(1)); } return list.toArray(new String[list.size()]); } /** * Reads in the size of a matrix. Skips initial comments */ public MatrixSize readMatrixSize(MatrixInfo info) throws IOException { // Always read the matrix size int numRows = getInt(), numColumns = getInt(); // For coordinate matrices we also read the number of entries if (info.isDense()) return new MatrixSize(numRows, numColumns, info); else { int numEntries = getInt(); return new MatrixSize(numRows, numColumns, numEntries); } } /** * Reads in the size of an array matrix. Skips initial comments */ public MatrixSize readArraySize() throws IOException { int numRows = getInt(), numColumns = getInt(); return new MatrixSize(numRows, numColumns, numRows * numColumns); } /** * Reads in the size of a coordinate matrix. Skips initial comments */ public MatrixSize readCoordinateSize() throws IOException { int numRows = getInt(), numColumns = getInt(), numEntries = getInt(); return new MatrixSize(numRows, numColumns, numEntries); } /** * Reads in the size of a vector. Skips initial comments */ public VectorSize readVectorSize(VectorInfo info) throws IOException { // Always read the vector size int size = getInt(); // For coordinate vectors we also read the number of entries if (info.isDense()) return new VectorSize(size); else { int numEntries = getInt(); return new VectorSize(size, numEntries); } } /** * Reads in the size of a dense vector. Skips initial comments */ public VectorSize readVectorArraySize() throws IOException { int size = getInt(); return new VectorSize(size); } /** * Reads in the size of a coordinate vector. Skips initial comments */ public VectorSize readVectorCoordinateSize() throws IOException { int size = getInt(), numEntries = getInt(); return new VectorSize(size, numEntries); } /** * Reads the array data */ public void readArray(double[] data) throws IOException { int size = data.length; for (int i = 0; i < size; ++i) data[i] = getDouble(); } /** * Reads the array data */ public void readArray(float[] data) throws IOException { int size = data.length; for (int i = 0; i < size; ++i) data[i] = getFloat(); } /** * Reads the array data */ public void readArray(int[] data) throws IOException { int size = data.length; for (int i = 0; i < size; ++i) data[i] = getInt(); } /** * Reads the array data */ public void readArray(long[] data) throws IOException { int size = data.length; for (int i = 0; i < size; ++i) data[i] = getLong(); } /** * Reads the array data. The first array will contain real entries, while * the second contain imaginary entries */ public void readArray(double[] dataR, double[] dataI) throws IOException { int size = dataR.length; if (size != dataI.length) throw new IllegalArgumentException( "All arrays must be of the same size"); for (int i = 0; i < size; ++i) { dataR[i] = getDouble(); dataI[i] = getDouble(); } } /** * Reads the array data. The first array will contain real entries, while * the second contain imaginary entries */ public void readArray(float[] dataR, float[] dataI) throws IOException { int size = dataR.length; if (size != dataI.length) throw new IllegalArgumentException( "All arrays must be of the same size"); for (int i = 0; i < size; ++i) { dataR[i] = getFloat(); dataI[i] = getFloat(); } } /** * Reads a coordinate vector */ public void readCoordinate(int[] index, double[] data) throws IOException { int size = index.length; if (size != data.length) throw new IllegalArgumentException( "All arrays must be of the same size"); for (int i = 0; i < size; ++i) { index[i] = getInt(); data[i] = getDouble(); } } /** * Reads a coordinate vector */ public void readCoordinate(int[] index, float[] data) throws IOException { int size = index.length; if (size != data.length) throw new IllegalArgumentException( "All arrays must be of the same size"); for (int i = 0; i < size; ++i) { index[i] = getInt(); data[i] = getFloat(); } } /** * Reads a coordinate vector */ public void readCoordinate(int[] index, int[] data) throws IOException { int size = index.length; if (size != data.length) throw new IllegalArgumentException( "All arrays must be of the same size"); for (int i = 0; i < size; ++i) { index[i] = getInt(); data[i] = getInt(); } } /** * Reads a coordinate vector */ public void readCoordinate(int[] index, long[] data) throws IOException { int size = index.length; if (size != data.length) throw new IllegalArgumentException( "All arrays must be of the same size"); for (int i = 0; i < size; ++i) { index[i] = getInt(); data[i] = getLong(); } } /** * Reads a coordinate vector. First data array contains real entries, and * the second contains imaginary entries */ public void readCoordinate(int[] index, float[] dataR, float[] dataI) throws IOException { int size = index.length; if (size != dataR.length || size != dataI.length) throw new IllegalArgumentException( "All arrays must be of the same size"); for (int i = 0; i < size; ++i) { index[i] = getInt(); dataR[i] = getFloat(); dataI[i] = getFloat(); } } /** * Reads a coordinate vector. First data array contains real entries, and * the second contains imaginary entries */ public void readCoordinate(int[] index, double[] dataR, double[] dataI) throws IOException { int size = index.length; if (size != dataR.length || size != dataI.length) throw new IllegalArgumentException( "All arrays must be of the same size"); for (int i = 0; i < size; ++i) { index[i] = getInt(); dataR[i] = getDouble(); dataI[i] = getDouble(); } } /** * Reads a pattern vector */ public void readPattern(int[] index) throws IOException { int size = index.length; for (int i = 0; i < size; ++i) index[i] = getInt(); } /** * Reads a coordinate matrix */ public void readCoordinate(int[] row, int[] column, double[] data) throws IOException { int size = row.length; if (size != column.length || size != data.length) throw new IllegalArgumentException( "All arrays must be of the same size"); for (int i = 0; i < size; ++i) { row[i] = getInt(); column[i] = getInt(); data[i] = getDouble(); } } /** * Reads a coordinate matrix */ public void readCoordinate(int[] row, int[] column, float[] data) throws IOException { int size = row.length; if (size != column.length || size != data.length) throw new IllegalArgumentException( "All arrays must be of the same size"); for (int i = 0; i < size; ++i) { row[i] = getInt(); column[i] = getInt(); data[i] = getFloat(); } } /** * Reads a coordinate matrix */ public void readCoordinate(int[] row, int[] column, int[] data) throws IOException { int size = row.length; if (size != column.length || size != data.length) throw new IllegalArgumentException( "All arrays must be of the same size"); for (int i = 0; i < size; ++i) { row[i] = getInt(); column[i] = getInt(); data[i] = getInt(); } } /** * Reads a coordinate matrix */ public void readCoordinate(int[] row, int[] column, long[] data) throws IOException { int size = row.length; if (size != column.length || size != data.length) throw new IllegalArgumentException( "All arrays must be of the same size"); for (int i = 0; i < size; ++i) { row[i] = getInt(); column[i] = getInt(); data[i] = getLong(); } } /** * Reads a pattern matrix */ public void readPattern(int[] row, int[] column) throws IOException { int size = row.length; if (size != column.length) throw new IllegalArgumentException( "All arrays must be of the same size"); for (int i = 0; i < size; ++i) { row[i] = getInt(); column[i] = getInt(); } } /** * Reads a coordinate matrix. First data array contains real entries, and * the second contains imaginary entries */ public void readCoordinate(int[] row, int[] column, double[] dataR, double[] dataI) throws IOException { int size = row.length; if (size != column.length || size != dataR.length || size != dataI.length) throw new IllegalArgumentException( "All arrays must be of the same size"); for (int i = 0; i < size; ++i) { row[i] = getInt(); column[i] = getInt(); dataR[i] = getDouble(); dataI[i] = getDouble(); } } /** * Reads a coordinate matrix. First data array contains real entries, and * the second contains imaginary entries */ public void readCoordinate(int[] row, int[] column, float[] dataR, float[] dataI) throws IOException { int size = row.length; if (size != column.length || size != dataR.length || size != dataI.length) throw new IllegalArgumentException( "All arrays must be of the same size"); for (int i = 0; i < size; ++i) { row[i] = getInt(); column[i] = getInt(); dataR[i] = getFloat(); dataI[i] = getFloat(); } } /** * Reads an integer */ private int getInt() throws IOException { st.nextToken(); if (st.ttype == StreamTokenizer.TT_WORD) return Integer.parseInt(st.sval); else if (st.ttype == StreamTokenizer.TT_EOF) throw new EOFException("End-of-File encountered during parsing"); else throw new IOException("Unknown token found during parsing"); } /** * Reads a long */ private long getLong() throws IOException { st.nextToken(); if (st.ttype == StreamTokenizer.TT_WORD) return Long.parseLong(st.sval); else if (st.ttype == StreamTokenizer.TT_EOF) throw new EOFException("End-of-File encountered during parsing"); else throw new IOException("Unknown token found during parsing"); } /** * Reads a double */ private double getDouble() throws IOException { st.nextToken(); if (st.ttype == StreamTokenizer.TT_WORD) return Double.parseDouble(st.sval); else if (st.ttype == StreamTokenizer.TT_EOF) throw new EOFException("End-of-File encountered during parsing"); else throw new IOException("Unknown token found during parsing"); } /** * Reads a float */ private float getFloat() throws IOException { st.nextToken(); if (st.ttype == StreamTokenizer.TT_WORD) return Float.parseFloat(st.sval); else if (st.ttype == StreamTokenizer.TT_EOF) throw new EOFException("End-of-File encountered during parsing"); else throw new IOException("Unknown token found during parsing"); } } mtj-0.9.14/src/no/uib/cipr/matrix/io/MatrixInfo.java0000644000000000000000000001556011027512662020663 0ustar rootroot/* * 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.io; /** * Contains information on a matrix in the Matrix Market exchange format. * Supports all valid matrices. */ public class MatrixInfo { /** * What kind of numbers are stored */ public enum MatrixField { /** * Real numbers */ Real, /** * Integers */ Integer, /** * Complex numbers */ Complex, /** * Pattern matrix. No numbers stored */ Pattern; } /** * Symmetry structure of the matrix, if any */ public enum MatrixSymmetry { /** * General matrix, no symmetry */ General, /** * Symmetrical matrix */ Symmetric, /** * Skew symmetrical matrix */ SkewSymmetric, /** * Hermitian matrix. Only applicable for complex entris */ Hermitian; } /** * True if the matrix is sparse, else false */ private boolean sparse; /** * Type of data stored */ private MatrixField field; /** * Matrix symmetry */ private MatrixSymmetry symmetry; /** * Creates a specific type * * @param sparse * True for sparse matrices, else false * @param field * Type of data stored * @param symmetry * Matrix symmetry */ public MatrixInfo(boolean sparse, MatrixField field, MatrixSymmetry symmetry) { this.sparse = sparse; this.field = field; this.symmetry = symmetry; validate(); } /** * Validates the representation */ private void validate() { if (isDense() && isPattern()) throw new IllegalArgumentException( "Matrix cannot be dense with pattern storage"); if (isReal() && isHermitian()) throw new IllegalArgumentException( "Data cannot be real with hermitian symmetry"); if (!isComplex() && isHermitian()) throw new IllegalArgumentException( "Data must be complex with hermitian symmetry"); if (isPattern() && isSkewSymmetric()) throw new IllegalArgumentException( "Storage cannot be pattern and skew symmetrical"); } /** * Returns true if the matrix is in coordinate format, else * false */ public boolean isSparse() { return sparse; } /** * Returns true if the matrix is in coordinate format, else * false */ public boolean isCoordinate() { return sparse; } /** * Returns true if the matrix is in array format, else * false */ public boolean isDense() { return !sparse; } /** * Returns true if the matrix is in array format, else * false */ public boolean isArray() { return !sparse; } /** * Returns true if the matrix stores real numbers, else * false */ public boolean isReal() { return field == MatrixField.Real; } /** * Returns true if the matrix stores integers, else * false */ public boolean isInteger() { return field == MatrixField.Integer; } /** * Returns true if the matrix stores complex numbers, else * false */ public boolean isComplex() { return field == MatrixField.Complex; } /** * Returns true if the matrix does not store any numbers, * else false */ public boolean isPattern() { return field == MatrixField.Pattern; } /** * Returns true if the matrix form is general, else * false */ public boolean isGeneral() { return symmetry == MatrixSymmetry.General; } /** * Returns true if the matrix is symmetrical, else * false */ public boolean isSymmetric() { return symmetry == MatrixSymmetry.Symmetric; } /** * Returns true if the matrix is skew-symmetrical, else * false */ public boolean isSkewSymmetric() { return symmetry == MatrixSymmetry.SkewSymmetric; } /** * Returns true if the matrix is Hermitian, else * false */ public boolean isHermitian() { return symmetry == MatrixSymmetry.Hermitian; } /** * Returns a string representation of the specifier. Can be used to provide * a header for writing to a file. It is a two-line output, which can look * like this: * *
     *       %%MatrixMarket matrix coordinate real general
     * 
*/ @Override public String toString() { StringBuilder buf = new StringBuilder(); buf.append("%%MatrixMarket matrix "); if (isSparse()) buf.append("coordinate "); else buf.append("array "); if (isReal()) buf.append("real "); else if (isComplex()) buf.append("complex "); else if (isPattern()) buf.append("pattern "); else if (isInteger()) buf.append("integer "); else // This should never happen throw new IllegalArgumentException("Unknown field specification"); if (isGeneral()) buf.append("general\n"); else if (isSymmetric()) buf.append("symmetric\n"); else if (isSkewSymmetric()) buf.append("skew-symmetric\n"); else if (isHermitian()) buf.append("Hermitian\n"); else // This should never happen throw new IllegalArgumentException("Unknown symmetry specification"); return buf.toString(); } } mtj-0.9.14/src/no/uib/cipr/matrix/io/MatrixSize.java0000644000000000000000000000636211027512662020702 0ustar rootroot/* * 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.io; /** * Contains the size of a matrix stored in the Matrix Market exchange format */ public class MatrixSize { /** * Number of rows */ private int numRows; /** * Number of columns */ private int numColumns; /** * Number of entries stored */ private int numEntries; /** * Constructor for MatrixSize * * @param numRows * Number of rows in the matrix * @param numColumns * Number of columns in the matrix * @param info * Info on the matrix */ public MatrixSize(int numRows, int numColumns, MatrixInfo info) { this.numRows = numRows; this.numColumns = numColumns; if (!info.isDense()) throw new IllegalArgumentException("Matrix must be dense"); if (info.isGeneral()) numEntries = numRows * numColumns; else if (info.isSymmetric() || info.isHermitian()) numEntries = ((numRows * numColumns - numRows) / 2 + numRows); else if (info.isSkewSymmetric()) numEntries = (numRows * numColumns - numRows) / 2; } /** * Constructor for MatrixSize * * @param numRows * Number of rows in the matrix * @param numColumns * Number of columns in the matrix * @param numEntries * Number of entries stored */ public MatrixSize(int numRows, int numColumns, int numEntries) { this.numRows = numRows; this.numColumns = numColumns; this.numEntries = numEntries; // We do this to avoid overflows long maxR = numRows, maxC = numColumns, max = maxR * maxC; if (numEntries > max) throw new IllegalArgumentException( "numEntries > numRows*numColumns"); } /** * Returns the number of rows in the matrix */ public int numRows() { return numRows; } /** * Returns the number of columns in the matrix */ public int numColumns() { return numColumns; } /** * Returns the number of entries stored */ public int numEntries() { return numEntries; } /** * Returns true if the matrix is square, else * false */ public boolean isSquare() { return numRows == numColumns; } } mtj-0.9.14/src/no/uib/cipr/matrix/io/MatrixVectorWriter.java0000644000000000000000000004422311027512662022425 0ustar rootroot/* * 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.io; import java.io.OutputStream; import java.io.PrintWriter; import java.io.Writer; /** * Writes matrices and vectors */ public class MatrixVectorWriter extends PrintWriter { /** * Constructor for MatrixVectorWriter * * @param out */ public MatrixVectorWriter(OutputStream out) { super(out); } /** * Constructor for MatrixVectorWriter * * @param out * @param autoFlush */ public MatrixVectorWriter(OutputStream out, boolean autoFlush) { super(out, autoFlush); } /** * Constructor for MatrixVectorWriter * * @param out */ public MatrixVectorWriter(Writer out) { super(out); } /** * Constructor for MatrixVectorWriter * * @param out * @param autoFlush */ public MatrixVectorWriter(Writer out, boolean autoFlush) { super(out, autoFlush); } /** * Shifts the indices. Useful for converting between 0- and 1-based * indicing. * * @param num * Added to every index * @param indices * Indices to shift */ public void add(int num, int[] indices) { for (int i = 0; i < indices.length; ++i) indices[i] += num; } /** * Prints the matrix info */ public void printMatrixInfo(MatrixInfo info) { print(info.toString()); } /** * Prints the vector info */ public void printVectorInfo(VectorInfo info) { print(info.toString()); } /** * Prints the matrix size */ public void printMatrixSize(MatrixSize size, MatrixInfo info) { format("%10d %10d", size.numRows(), size.numColumns()); if (info.isCoordinate()) format(" %19d", size.numEntries()); println(); } /** * Prints the matrix size. Assumes coordinate format */ public void printMatrixSize(MatrixSize size) { format("%10d %10d %19d\n", size.numRows(), size.numColumns(), size .numEntries()); } /** * Prints the vector size */ public void printVectorSize(VectorSize size, VectorInfo info) { format("%10d", size.size()); if (info.isCoordinate()) format(" %19d", size.numEntries()); println(); } /** * Prints the vector size. Assumes coordinate format */ public void printVectorSize(VectorSize size) { format("%10d %19d\n", size.size(), size.numEntries()); } /** * Prints an array to the underlying stream. One entry per line. */ public void printArray(float[] data) { for (int i = 0; i < data.length; ++i) format("% .12e\n", data[i]); } /** * Prints an array to the underlying stream. One entry per line. */ public void printArray(double[] data) { for (int i = 0; i < data.length; ++i) format("% .12e\n", data[i]); } /** * Prints an array to the underlying stream. One entry per line. The first * array specifies the real entries, and the second is the imaginary entries */ public void printArray(float[] dataR, float[] dataI) { int size = dataR.length; if (size != dataI.length) throw new IllegalArgumentException( "All arrays must be of the same size"); for (int i = 0; i < size; ++i) format("% .12e % .12e\n", dataR[i], dataI[i]); } /** * Prints an array to the underlying stream. One entry per line. The first * array specifies the real entries, and the second is the imaginary entries */ public void printArray(double[] dataR, double[] dataI) { int size = dataR.length; if (size != dataI.length) throw new IllegalArgumentException( "All arrays must be of the same size"); for (int i = 0; i < size; ++i) format("% .12e % .12e\n", dataR[i], dataI[i]); } /** * Prints an array to the underlying stream. One entry per line. */ public void printArray(int[] data) { for (int i = 0; i < data.length; ++i) format("%10d\n", data[i]); } /** * Prints an array to the underlying stream. One entry per line. */ public void printArray(long[] data) { for (int i = 0; i < data.length; ++i) format("%10d\n", data[i]); } /** * Prints the coordinate format to the underlying stream. One index and * entry on each line. The offset is added to the index, typically, this can * transform from a 0-based indicing to a 1-based. */ public void printCoordinate(int[] index, float[] data, int offset) { int size = index.length; if (size != data.length) throw new IllegalArgumentException( "All arrays must be of the same size"); for (int i = 0; i < size; ++i) format("%10d % .12e\n", index[i] + offset, data[i]); } /** * Prints the coordinate format to the underlying stream. One index and * entry on each line. The offset is added to the index, typically, this can * transform from a 0-based indicing to a 1-based. */ public void printCoordinate(int[] index, double[] data, int offset) { int size = index.length; if (size != data.length) throw new IllegalArgumentException( "All arrays must be of the same size"); for (int i = 0; i < size; ++i) format("%10d % .12e\n", index[i] + offset, data[i]); } /** * Prints the coordinate format to the underlying stream. One index and * entry on each line. The offset is added to the index, typically, this can * transform from a 0-based indicing to a 1-based. */ public void printCoordinate(int[] index, int[] data, int offset) { int size = index.length; if (size != data.length) throw new IllegalArgumentException( "All arrays must be of the same size"); for (int i = 0; i < size; ++i) format("%10d %10d\n", index[i] + offset, data[i]); } /** * Prints the coordinate format to the underlying stream. One index and * entry on each line. The offset is added to the index, typically, this can * transform from a 0-based indicing to a 1-based. */ public void printCoordinate(int[] index, long[] data, int offset) { int size = index.length; if (size != data.length) throw new IllegalArgumentException( "All arrays must be of the same size"); for (int i = 0; i < size; ++i) format("%10d %10d\n", index[i] + offset, data[i]); } /** * Prints the coordinate format to the underlying stream. One index pair and * entry on each line. The offset is added to each index, typically, this * can transform from a 0-based indicing to a 1-based. */ public void printCoordinate(int[] row, int[] column, float[] data, int offset) { int size = row.length; if (size != column.length || size != data.length) throw new IllegalArgumentException( "All arrays must be of the same size"); for (int i = 0; i < size; ++i) format("%10d %10d % .12e\n", row[i] + offset, column[i] + offset, data[i]); } /** * Prints the coordinate format to the underlying stream. One index pair and * entry on each line. The offset is added to each index, typically, this * can transform from a 0-based indicing to a 1-based. */ public void printCoordinate(int[] row, int[] column, double[] data, int offset) { int size = row.length; if (size != column.length || size != data.length) throw new IllegalArgumentException( "All arrays must be of the same size"); for (int i = 0; i < size; ++i) format("%10d %10d % .12e\n", row[i] + offset, column[i] + offset, data[i]); } /** * Prints the coordinate format to the underlying stream. One index and * entry on each line. The offset is added to each index, typically, this * can transform from a 0-based indicing to a 1-based. The first float array * specifies the real entries, and the second is the imaginary entries */ public void printCoordinate(int[] index, float[] dataR, float[] dataI, int offset) { int size = index.length; if (size != dataR.length || size != dataI.length) throw new IllegalArgumentException( "All arrays must be of the same size"); for (int i = 0; i < size; ++i) format("%10d % .12e % .12e\n", index[i] + offset, dataR[i], dataI[i]); } /** * Prints the coordinate format to the underlying stream. One index and * entry on each line. The offset is added to each index, typically, this * can transform from a 0-based indicing to a 1-based. The first double * array specifies the real entries, and the second is the imaginary entries */ public void printCoordinate(int[] index, double[] dataR, double[] dataI, int offset) { int size = index.length; if (size != dataR.length || size != dataI.length) throw new IllegalArgumentException( "All arrays must be of the same size"); for (int i = 0; i < size; ++i) format("%10d % .12e % .12e\n", index[i] + offset, dataR[i], dataI[i]); } /** * Prints the coordinate format to the underlying stream. One index pair and * entry on each line. The offset is added to each index, typically, this * can transform from a 0-based indicing to a 1-based. The first float array * specifies the real entries, and the second is the imaginary entries */ public void printCoordinate(int[] row, int[] column, float[] dataR, float[] dataI, int offset) { int size = row.length; if (size != column.length || size != dataR.length || size != dataI.length) throw new IllegalArgumentException( "All arrays must be of the same size"); for (int i = 0; i < size; ++i) format("%10d %10d % .12e % .12e\n", row[i] + offset, column[i] + offset, dataR[i], dataI[i]); } /** * Prints the coordinate format to the underlying stream. One index pair and * entry on each line. The offset is added to each index, typically, this * can transform from a 0-based indicing to a 1-based. The first double * array specifies the real entries, and the second is the imaginary entries */ public void printCoordinate(int[] row, int[] column, double[] dataR, double[] dataI, int offset) { int size = row.length; if (size != column.length || size != dataR.length || size != dataI.length) throw new IllegalArgumentException( "All arrays must be of the same size"); for (int i = 0; i < size; ++i) format("%10d %10d % .12e % .12e\n", row[i] + offset, column[i] + offset, dataR[i], dataI[i]); } /** * Prints the coordinate format to the underlying stream. One index pair and * entry on each line. The offset is added to each index, typically, this * can transform from a 0-based indicing to a 1-based. */ public void printCoordinate(int[] row, int[] column, int[] data, int offset) { int size = row.length; if (size != column.length || size != data.length) throw new IllegalArgumentException( "All arrays must be of the same size"); for (int i = 0; i < size; ++i) format("%10d %10d %19d\n", row[i] + offset, column[i] + offset, data[i]); } /** * Prints the coordinate format to the underlying stream. One index pair and * entry on each line. The offset is added to each index, typically, this * can transform from a 0-based indicing to a 1-based. */ public void printCoordinate(int[] row, int[] column, long[] data, int offset) { int size = row.length; if (size != column.length || size != data.length) throw new IllegalArgumentException( "All arrays must be of the same size"); for (int i = 0; i < size; ++i) format("%10d %10d %19d\n", row[i] + offset, column[i] + offset, data[i]); } /** * Prints the coordinates to the underlying stream. One index pair on each * line. The offset is added to each index, typically, this can transform * from a 0-based indicing to a 1-based. */ public void printPattern(int[] row, int[] column, int offset) { int size = row.length; if (size != column.length) throw new IllegalArgumentException( "All arrays must be of the same size"); for (int i = 0; i < size; ++i) format("%10d %10d\n", row[i] + offset, column[i] + offset); } /** * Prints the coordinates to the underlying stream. One index on each line. * The offset is added to each index, typically, this can transform from a * 0-based indicing to a 1-based. */ public void printPattern(int[] index, int offset) { int size = index.length; for (int i = 0; i < size; ++i) format("%10d\n", index[i] + offset); } /** * Prints the coordinate format to the underlying stream. One index pair and * entry on each line */ public void printCoordinate(int[] row, int[] column, float[] data) { printCoordinate(row, column, data, 0); } /** * Prints the coordinate format to the underlying stream. One index pair and * entry on each line */ public void printCoordinate(int[] row, int[] column, double[] data) { printCoordinate(row, column, data, 0); } /** * Prints the coordinate format to the underlying stream. One index pair and * entry on each line. The first double array specifies the real entries, * and the second is the imaginary entries */ public void printCoordinate(int[] row, int[] column, float[] dataR, float[] dataI) { printCoordinate(row, column, dataR, dataI, 0); } /** * Prints the coordinate format to the underlying stream. One index pair and * entry on each line. The first double array specifies the real entries, * and the second is the imaginary entries */ public void printCoordinate(int[] row, int[] column, double[] dataR, double[] dataI) { printCoordinate(row, column, dataR, dataI, 0); } /** * Prints the coordinate format to the underlying stream. One index pair and * entry on each line */ public void printCoordinate(int[] row, int[] column, int[] data) { printCoordinate(row, column, data, 0); } /** * Prints the coordinate format to the underlying stream. One index pair and * entry on each line */ public void printCoordinate(int[] row, int[] column, long[] data) { printCoordinate(row, column, data, 0); } /** * Prints the coordinates to the underlying stream. One index pair on each * line */ public void printPattern(int[] row, int[] column) { printPattern(row, column, 0); } /** * Prints the coordinate format to the underlying stream. One index and * entry on each line */ public void printCoordinate(int[] index, float[] data) { printCoordinate(index, data, 0); } /** * Prints the coordinate format to the underlying stream. One index and * entry on each line */ public void printCoordinate(int[] index, double[] data) { printCoordinate(index, data, 0); } /** * Prints the coordinate format to the underlying stream. One index and * entry on each line. The first double array specifies the real entries, * and the second is the imaginary entries */ public void printCoordinate(int[] index, float[] dataR, float[] dataI) { printCoordinate(index, dataR, dataI, 0); } /** * Prints the coordinate format to the underlying stream. One index and * entry on each line. The first double array specifies the real entries, * and the second is the imaginary entries */ public void printCoordinate(int[] index, double[] dataR, double[] dataI) { printCoordinate(index, dataR, dataI, 0); } /** * Prints the coordinate format to the underlying stream. One index and * entry on each line */ public void printCoordinate(int[] index, int[] data) { printCoordinate(index, data, 0); } /** * Prints the coordinate format to the underlying stream. One index and * entry on each line */ public void printCoordinate(int[] index, long[] data) { printCoordinate(index, data, 0); } /** * Prints the coordinates to the underlying stream. One index on each line */ public void printPattern(int[] index) { printPattern(index, 0); } /** * Prints all the comments. Prepends a '%' and appends a newline to every * comment */ public void printComments(String[] comments) { for (String comment : comments) println("%" + comment); } } mtj-0.9.14/src/no/uib/cipr/matrix/io/VectorSize.java0000644000000000000000000000431211027512662020671 0ustar rootroot/* * 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.io; /** * Contains the size of a vectir stored in a variant of the Matrix Market exchange format */ public class VectorSize { /** * Size of the vector */ private int size; /** * Number of entries stored */ private int numEntries; /** * Constructor for VectorSize. Assumes dense format * * @param size * Size of the matrix */ public VectorSize(int size) { this.size = size; numEntries = size; if (size < 0) throw new IllegalArgumentException("size < 0"); } /** * Constructor for VectorSize * * @param size * Size of the matrix * @param numEntries * Number of entries stored */ public VectorSize(int size, int numEntries) { this.size = size; this.numEntries = numEntries; if (size < 0 || numEntries < 0) throw new IllegalArgumentException("size < 0 || numEntries < 0"); if (numEntries > size) throw new IllegalArgumentException("numEntries > size"); } /** * Returns the size of the vector */ public int size() { return size; } /** * Returns the number of entries in the vector */ public int numEntries() { return numEntries; } } mtj-0.9.14/src/no/uib/cipr/matrix/io/package.html0000644000000000000000000000067211027512662020217 0ustar rootroot I/O operations with matrices and vectors. The formats supported are:

The Harwell-Boeing format is not supported.

mtj-0.9.14/src/no/uib/cipr/matrix/io/VectorInfo.java0000644000000000000000000001102211027512662020646 0ustar rootroot/* * 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.io; /** * Contains information on a vector in a variant of the Matrix Market exchange format */ public class VectorInfo { /** * What kind of numbers are stored */ public enum VectorField { /** * Real numbers */ Real, /** * Integers */ Integer, /** * Complex numbers */ Complex, /** * Pattern matrix. No numbers stored */ Pattern; } /** * True if the vector is sparse, else false */ private boolean sparse; /** * Type of data stored */ private VectorField field; /** * Creates a specific type * * @param sparse * True for sparse vectors, else false * @param field * Type of data stored */ public VectorInfo(boolean sparse, VectorField field) { this.sparse = sparse; this.field = field; validate(); } /** * Validates the representation */ private void validate() { if (isDense() && isPattern()) throw new IllegalArgumentException( "Vector cannot be dense with pattern storage"); } /** * Returns true if the vector is in coordinate format, else * false */ public boolean isSparse() { return sparse; } /** * Returns true if the vector is in coordinate format, else * false */ public boolean isCoordinate() { return sparse; } /** * Returns true if the vector is in array format, else * false */ public boolean isDense() { return !sparse; } /** * Returns true if the vector is in array format, else * false */ public boolean isArray() { return !sparse; } /** * Returns true if the vector stores real numbers, else * false */ public boolean isReal() { return field == VectorField.Real; } /** * Returns true if the vector stores integers, else * false */ public boolean isInteger() { return field == VectorField.Integer; } /** * Returns true if the vector stores complex numbers, else * false */ public boolean isComplex() { return field == VectorField.Complex; } /** * Returns true if the vector does not store any numbers, * else false */ public boolean isPattern() { return field == VectorField.Pattern; } /** * Returns a string representation of the specifier. Can be used to provide * a header for writing to a file. It is a two-line output, which can look * like this: * *
     *      %%MatrixMarket vector coordinate real
     * 
*/ @Override public String toString() { StringBuilder buf = new StringBuilder(); buf.append("%%MatrixMarket vector "); if (isSparse()) buf.append("coordinate "); else buf.append("array "); if (isReal()) buf.append("real\n"); else if (isComplex()) buf.append("complex\n"); else if (isPattern()) buf.append("pattern\n"); else if (isInteger()) buf.append("integer\n"); else // This should never happen throw new IllegalArgumentException("Unknown field specification"); return buf.toString(); } } mtj-0.9.14/src/no/uib/cipr/matrix/DenseLU.java0000644000000000000000000001240211027512662017463 0ustar rootroot/* * 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 no.uib.cipr.matrix.Matrix.Norm; import org.netlib.lapack.LAPACK; import org.netlib.util.doubleW; import org.netlib.util.intW; /** * Dense LU decomposition * * FIXME: DenseLU is broken! Fix it */ public class DenseLU { /** * Holds the LU factors */ private DenseMatrix LU; /** * Row pivotations */ private int[] piv; /** * True if the matrix was singular */ private boolean singular; /** * Constructor for DenseLU * * @param m * Number of rows * @param n * Number of columns */ public DenseLU(int m, int n) { LU = new DenseMatrix(m, n); piv = new int[Math.min(m, n)]; } /** * Creates an LU decomposition of the given matrix * * @param A * Matrix to decompose. Not modified * @return The current decomposition */ public static DenseLU factorize(Matrix A) { return new DenseLU(A.numRows(), A.numColumns()).factor(new DenseMatrix( A)); } /** * Creates an LU decomposition of the given matrix * * @param A * Matrix to decompose. Overwritten with the decomposition * @return The current decomposition */ public DenseLU factor(DenseMatrix A) { singular = false; intW info = new intW(0); LAPACK.getInstance().dgetrf(A.numRows(), A.numColumns(), A.getData(), Matrices.ld(A.numRows()), piv, info); if (info.val > 0) singular = true; else if (info.val < 0) throw new IllegalArgumentException(); LU.set(A); return this; } /** * Returns the lower triangular factor */ public UnitLowerTriangDenseMatrix getL() { return new UnitLowerTriangDenseMatrix(LU, false); } /** * Returns the upper triangular factor */ public UpperTriangDenseMatrix getU() { return new UpperTriangDenseMatrix(LU, false); } /** * Returns the decomposition matrix */ public DenseMatrix getLU() { return LU; } /** * Computes the reciprocal condition number, using either the infinity norm * of the 1 norm. * * @param A * The matrix this is a decomposition of * @param norm * Either Norm.One or Norm.Infinity * @return The reciprocal condition number. Values close to unity indicate a * well-conditioned system, while numbers close to zero do not. */ public double rcond(Matrix A, Norm norm) { if (norm != Norm.One && norm != Norm.Infinity) throw new IllegalArgumentException( "Only the 1 or the Infinity norms are supported"); double anorm = A.norm(norm); int n = A.numRows(); intW info = new intW(0); doubleW rcond = new doubleW(0); LAPACK.getInstance().dgecon(norm.netlib(), n, LU.getData(), Matrices.ld(n), anorm, rcond, new double[4 * n], new int[n], info); if (info.val < 0) throw new IllegalArgumentException(); return rcond.val; } /** * Returns the row pivots */ public int[] getPivots() { return piv; } /** * Checks for singularity */ public boolean isSingular() { return singular; } /** * Computes A\B, overwriting B */ public DenseMatrix solve(DenseMatrix B) throws MatrixSingularException { return solve(B, Transpose.NoTranspose); } /** * Computes AT\B, overwriting B */ public DenseMatrix transSolve(DenseMatrix B) throws MatrixSingularException { return solve(B, Transpose.Transpose); } private DenseMatrix solve(DenseMatrix B, Transpose trans) throws MatrixSingularException { if (singular) throw new MatrixSingularException(); if (B.numRows() != LU.numRows()) throw new IllegalArgumentException("B.numRows() != LU.numRows()"); intW info = new intW(0); LAPACK.getInstance().dgetrs(trans.netlib(), LU.numRows(), B.numColumns(), LU.getData(), Matrices.ld(LU.numRows()), piv, B.getData(), Matrices.ld(LU.numRows()), info); if (info.val < 0) throw new IllegalArgumentException(); return B; } } mtj-0.9.14/src/no/uib/cipr/matrix/EVD.java0000644000000000000000000001302411027512662016603 0ustar rootroot/* * 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 org.netlib.lapack.LAPACK; import org.netlib.util.intW; /** * Computes eigenvalue decompositions of general matrices */ public class EVD { /** * Double work array */ private final double[] work; /** * Size of the matrix */ private final int n; /** * Job to do on the left and right eigenvectors */ private final JobEig jobLeft, jobRight; /** * Contains the real and imaginary parts of the eigenvalues */ private final double[] Wr, Wi; /** * Contains the left and the right eigenvectors */ private final DenseMatrix Vl, Vr; /** * Creates an empty eigenvalue decomposition which will compute all the * eigenvalues and eigenvectors (left and right) * * @param n * Size of the matrix */ public EVD(int n) { this(n, true, true); } /** * Creates an empty eigenvalue decomposition * * @param n * Size of the matrix * @param left * Whether to compute the left eigenvectors or not * @param right * Whether to compute the right eigenvectors or not */ public EVD(int n, boolean left, boolean right) { this.n = n; this.jobLeft = left ? JobEig.All : JobEig.Eigenvalues; this.jobRight = right ? JobEig.All : JobEig.Eigenvalues; // Allocate space for the decomposition Wr = new double[n]; Wi = new double[n]; if (left) Vl = new DenseMatrix(n, n); else Vl = null; if (right) Vr = new DenseMatrix(n, n); else Vr = null; // Find the needed workspace double[] worksize = new double[1]; intW info = new intW(0); LAPACK.getInstance().dgeev(jobLeft.netlib(), jobRight.netlib(), n, new double[0], Matrices.ld(n), new double[0], new double[0], new double[0], Matrices.ld(n), new double[0], Matrices.ld(n), worksize, -1, info); // Allocate workspace int lwork = 0; if (info.val != 0) { if (jobLeft == JobEig.All || jobRight == JobEig.All) lwork = 4 * n; else lwork = 3 * n; } else lwork = (int) worksize[0]; lwork = Math.max(1, lwork); work = new double[lwork]; } /** * Convenience method for computing the complete eigenvalue decomposition of * the given matrix * * @param A * Matrix to factorize. Not modified * @return Newly allocated decomposition * @throws NotConvergedException */ public static EVD factorize(Matrix A) throws NotConvergedException { return new EVD(A.numRows()).factor(new DenseMatrix(A)); } /** * Computes the eigenvalue decomposition of the given matrix * * @param A * Matrix to factorize. Overwritten on return * @return The current decomposition * @throws NotConvergedException */ public EVD factor(DenseMatrix A) throws NotConvergedException { if (!A.isSquare()) throw new IllegalArgumentException("!A.isSquare()"); else if (A.numRows() != n) throw new IllegalArgumentException("A.numRows() != n"); intW info = new intW(0); LAPACK.getInstance().dgeev(jobLeft.netlib(), jobRight.netlib(), n, A.getData(), Matrices.ld(n), Wr, Wi, jobLeft == JobEig.All ? Vl.getData() : new double[0], Matrices.ld(n), jobRight == JobEig.All ? Vr.getData() : new double[0], Matrices.ld(n), work, work.length, info); if (info.val > 0) throw new NotConvergedException( NotConvergedException.Reason.Iterations); else if (info.val < 0) throw new IllegalArgumentException(); return this; } /** * Gets the left eigenvectors, if available */ public DenseMatrix getLeftEigenvectors() { return Vl; } /** * Gets the right eigenvectors, if available */ public DenseMatrix getRightEigenvectors() { return Vr; } /** * Gets the real part of the eigenvalues */ public double[] getRealEigenvalues() { return Wr; } /** * Gets the imaginary part of the eigenvalues */ public double[] getImaginaryEigenvalues() { return Wi; } /** * True if the left eigenvectors have been computed */ public boolean hasLeftEigenvectors() { return Vl != null; } /** * True if the right eigenvectors have been computed */ public boolean hasRightEigenvectors() { return Vr != null; } } mtj-0.9.14/src/no/uib/cipr/matrix/overview.html0000644000000000000000000000036511027512662020062 0ustar rootroot

A library for high performance scientific computing in Java.

Visit the homepage for the most recent releases, examples and documentation.

mtj-0.9.14/src/no/uib/cipr/matrix/QL.java0000644000000000000000000000776111027512662016514 0ustar rootroot/* * 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 org.netlib.lapack.LAPACK; import org.netlib.util.intW; /** * Computes QL decompositions */ public class QL extends OrthogonalComputer { /** * Constructs an empty QL decomposition * * @param m * Number of rows. Must be larger than or equal the number of * columns * @param n * Number of columns */ public QL(int m, int n) { super(m, n, false); if (n > m) throw new IllegalArgumentException("n > m"); int lwork; // Query optimal workspace. First for computing the factorization { work = new double[1]; intW info = new intW(0); LAPACK.getInstance().dgeqlf(m, n, new double[0], Matrices.ld(m), new double[0], work, -1, info); if (info.val != 0) lwork = n; else lwork = (int) work[0]; lwork = Math.max(1, lwork); work = new double[lwork]; } // Workspace needed for generating an explicit orthogonal matrix { workGen = new double[1]; intW info = new intW(0); LAPACK.getInstance().dorgql(m, n, k, new double[0], Matrices.ld(m), new double[0], workGen, -1, info); if (info.val != 0) lwork = n; else lwork = (int) workGen[0]; lwork = Math.max(1, lwork); workGen = new double[lwork]; } } /** * Convenience method to compute a QL decomposition * * @param A * Matrix to decompose. Not modified * @return Newly allocated decomposition */ public static QL factorize(Matrix A) { return new QL(A.numRows(), A.numColumns()).factor(new DenseMatrix(A)); } @Override public QL factor(DenseMatrix A) { if (Q.numRows() != A.numRows()) throw new IllegalArgumentException("Q.numRows() != A.numRows()"); else if (Q.numColumns() != A.numColumns()) throw new IllegalArgumentException( "Q.numColumns() != A.numColumns()"); else if (L == null) throw new IllegalArgumentException("L == null"); /* * Calculate factorisation, and extract the triangular factor */ intW info = new intW(0); LAPACK.getInstance().dgeqlf(m, n, A.getData(), Matrices.ld(m), tau, work, work.length, info); if (info.val < 0) throw new IllegalArgumentException(); L.zero(); for (MatrixEntry e : A) if (e.row() >= (m - n) + e.column()) L.set(e.row() - (m - n), e.column(), e.get()); /* * Generate the orthogonal matrix */ info.val = 0; LAPACK.getInstance().dorgql(m, n, k, A.getData(), Matrices.ld(m), tau, workGen, workGen.length, info); if (info.val < 0) throw new IllegalArgumentException(); Q.set(A); return this; } /** * Returns the lower triangular factor */ public LowerTriangDenseMatrix getL() { return L; } } mtj-0.9.14/src/no/uib/cipr/matrix/UpperSPDBandMatrix.java0000644000000000000000000000532611027512662021607 0ustar rootroot/* * 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; /** * Upper symmetrical positive definite banded matrix. It does not enforce this * property (except for symmetry), and has the same storage layout as * {@link no.uib.cipr.matrix.UpperSymmBandMatrix UpperSymmBandMatrix}. */ public class UpperSPDBandMatrix extends UpperSymmBandMatrix { /** * Constructor for UpperSPDBandMatrix * * @param n * Size of the matrix. Since the matrix must be square, this * equals both the number of rows and columns * @param kd * Number of bands off the main diagonal (off diagonals) */ public UpperSPDBandMatrix(int n, int kd) { super(n, kd); } /** * Constructor for UpperSPDBandMatrix * * @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 kd * Number of bands off the main diagonal (off diagonals) */ public UpperSPDBandMatrix(Matrix A, int kd) { super(A, kd); } /** * Constructor for UpperSPDBandMatrix * * @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 kd * Number of bands off the main diagonal (off diagonals) * @param deep * True for a deep copy. For shallow copies, A * must be a banded matrix */ public UpperSPDBandMatrix(Matrix A, int kd, boolean deep) { super(A, kd, deep); } @Override public UpperSPDBandMatrix copy() { return new UpperSPDBandMatrix(this, kd); } @Override public Matrix solve(Matrix B, Matrix X) { return SPDsolve(B, X); } } mtj-0.9.14/src/no/uib/cipr/matrix/UpperTriangBandMatrix.java0000644000000000000000000000723611027512662022407 0ustar rootroot/* * 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; /** * Upper triangular banded matrix. The same storage as * {@link no.uib.cipr.matrix.BandMatrix BandMatrix}, but without subdiagonals. */ public class UpperTriangBandMatrix extends AbstractTriangBandMatrix { /** * Constructor for UpperTriangBandMatrix * * @param n * Size of the matrix. Since the matrix must be square, this * equals both the number of rows and columns * @param kd * Number of bands above the main diagonal (superdiagonals) */ public UpperTriangBandMatrix(int n, int kd) { super(n, 0, kd, UpLo.Upper, Diag.NonUnit); } /** * Constructor for UpperTriangBandMatrix * * @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 kd * Number of bands above the main diagonal (superdiagonals) */ public UpperTriangBandMatrix(Matrix A, int kd) { this(A, kd, true); } /** * Constructor for UpperTriangBandMatrix * * @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 kd * Number of bands above the main diagonal (superdiagonals) * @param deep * True for a deep copy. For shallow copies, A * must be a banded matrix */ public UpperTriangBandMatrix(Matrix A, int kd, boolean deep) { super(A, 0, kd, deep, UpLo.Upper, Diag.NonUnit); } /** * Constructor for UpperTriangBandMatrix * * @param n * Size of the matrix. Since the matrix must be square, this * equals both the number of rows and columns * @param kd * Number of bands above the main diagonal (superdiagonals) */ UpperTriangBandMatrix(int n, int kd, Diag diag) { super(n, 0, kd, UpLo.Upper, diag); } /** * Constructor for UpperTriangBandMatrix * * @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 kd * Number of bands above the main diagonal (superdiagonals) * @param deep * True for a deep copy. For shallow copies, A * must be a banded matrix */ UpperTriangBandMatrix(Matrix A, int kd, boolean deep, Diag diag) { super(A, 0, kd, deep, UpLo.Upper, diag); } @Override public UpperTriangBandMatrix copy() { return new UpperTriangBandMatrix(this, ku); } } mtj-0.9.14/src/no/uib/cipr/matrix/LowerSymmDenseMatrix.java0000644000000000000000000000566211027512662022300 0ustar rootroot/* * 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; /** * Lower symmetric dense matrix. It has the same storage layout as the * {@link no.uib.cipr.matrix.DenseMatrix DenseMatrix}, but only refers to * elements below or on the main diagonal. The remaining elements are never * accessed nor changed, and is known only by symmetry. */ public class LowerSymmDenseMatrix extends AbstractSymmDenseMatrix { /** * Constructor for LowerSymmDenseMatrix * * @param n * Size of the matrix. Since the matrix must be square, this * equals both the number of rows and columns */ public LowerSymmDenseMatrix(int n) { super(n, UpLo.Lower); } /** * Constructor for LowerSymmDenseMatrix * * @param A * Matrix to copy. It must be a square matrix, and only the lower * triangular part is copied */ public LowerSymmDenseMatrix(Matrix A) { this(A, true); } /** * Constructor for LowerSymmDenseMatrix * * @param A * Matrix to copy. It must be a square matrix, and only the lower * triangular part is copied * @param deep * If false, a shallow copy is made. In that case, A * must be a dense matrix */ public LowerSymmDenseMatrix(Matrix A, boolean deep) { super(A, deep, UpLo.Lower); } @Override public void add(int row, int column, double value) { if (column <= row) super.add(row, column, value); } @Override public double get(int row, int column) { if (column > row) return super.get(column, row); return super.get(row, column); } @Override public void set(int row, int column, double value) { if (column <= row) super.set(row, column, value); } @Override public LowerSymmDenseMatrix copy() { return new LowerSymmDenseMatrix(this); } @Override void copy(Matrix A) { for (MatrixEntry e : A) if (e.row() >= e.column()) set(e.row(), e.column(), e.get()); } } mtj-0.9.14/src/no/uib/cipr/matrix/AbstractTriangDenseMatrix.java0000644000000000000000000002030311027512662023237 0ustar rootroot/* * 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.Iterator; import org.netlib.blas.BLAS; import org.netlib.lapack.LAPACK; import org.netlib.util.intW; /** * Partial implementation of a triangular, dense matrix */ abstract class AbstractTriangDenseMatrix extends AbstractDenseMatrix { /** * If the matrix is upper triangular */ UpLo uplo; /** * If the matrix is unit diagonal or not unit */ Diag diag; /** * Leading dimension of the matrix */ int ld; /** * Constructor for AbstractTriangDenseMatrix * * @param n * Size of the matrix. Since the matrix must be square, this * equals both the number of rows and columns */ AbstractTriangDenseMatrix(int n, UpLo uplo, Diag diag) { super(n, n); ld = n; this.uplo = uplo; this.diag = diag; } /** * Constructor for AbstractTriangDenseMatrix * * @param A * Matrix to copy from */ AbstractTriangDenseMatrix(Matrix A, UpLo uplo, Diag diag) { this(A, Math.min(A.numRows(), A.numColumns()), uplo, diag); } /** * Constructor for AbstractTriangDenseMatrix * * @param A * Matrix to copy from * @param deep * If true, A is copied, else a shallow copy is * made and the matrices share underlying storage. For this, * A must be a dense matrix */ AbstractTriangDenseMatrix(Matrix A, boolean deep, UpLo uplo, Diag diag) { this(A, Math.min(A.numRows(), A.numColumns()), deep, uplo, diag); } /** * Constructor for AbstractTriangDenseMatrix * * @param A * Matrix to copy from * @param k * Size of matrix to refer. * k<min(numRows,numColumns) */ AbstractTriangDenseMatrix(Matrix A, int k, UpLo uplo, Diag diag) { this(A, k, true, uplo, diag); } /** * Constructor for AbstractTriangDenseMatrix * * @param A * Matrix to copy from * @param k * Size of matrix to refer. * k<min(numRows,numColumns) * @param deep * If true, A is copied, else a shallow copy is * made and the matrices share underlying storage. For this, * A must be a dense matrix */ AbstractTriangDenseMatrix(Matrix A, int k, boolean deep, UpLo uplo, Diag diag) { super(A, deep); if (deep && !A.isSquare()) throw new IllegalArgumentException("deep && !A.isSquare()"); ld = A.numRows(); numRows = numColumns = k; this.uplo = uplo; this.diag = diag; } @Override public Vector mult(double alpha, Vector x, Vector y) { if (!(y instanceof DenseVector)) return super.mult(alpha, x, y); checkMultAdd(x, y); double[] yd = ((DenseVector) y).getData(); // y = alpha*x y.set(alpha, x); // y = A*z BLAS.getInstance().dtrmv(uplo.netlib(), Transpose.NoTranspose.netlib(), diag.netlib(), numRows, data, Math.max(1, ld), yd, 1); return y; } @Override public Vector transMult(double alpha, Vector x, Vector y) { if (!(y instanceof DenseVector)) return super.transMult(alpha, x, y); checkTransMultAdd(x, y); double[] yd = ((DenseVector) y).getData(); // y = alpha*x y.set(alpha, x); // y = A'*y BLAS.getInstance().dtrmv(uplo.netlib(), Transpose.Transpose.netlib(), diag.netlib(), numRows, data, Math.max(1, ld), yd, 1); return y; } @Override public Matrix mult(double alpha, Matrix B, Matrix C) { if (!(C instanceof DenseMatrix)) return super.mult(alpha, B, C); checkMultAdd(B, C); double[] Cd = ((DenseMatrix) C).getData(); C.set(B); // C = alpha*A*C BLAS.getInstance().dtrmm(Side.Left.netlib(), uplo.netlib(), Transpose.NoTranspose.netlib(), diag.netlib(), C.numRows(), C.numColumns(), alpha, data, Math.max(1, ld), Cd, Math.max(1, C.numRows())); return C; } @Override public Matrix transAmult(double alpha, Matrix B, Matrix C) { if (!(C instanceof DenseMatrix)) return super.transAmult(alpha, B, C); checkTransAmultAdd(B, C); double[] Cd = ((DenseMatrix) C).getData(); C.set(B); // C = alpha*A'*C BLAS.getInstance().dtrmm(Side.Left.netlib(), uplo.netlib(), Transpose.Transpose.netlib(), diag.netlib(), C.numRows(), C.numColumns(), alpha, data, Math.max(1, ld), Cd, Math.max(1, C.numRows())); return C; } @Override public Matrix solve(Matrix B, Matrix X) { return solve(B, X, Transpose.NoTranspose); } @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 transSolve(Matrix B, Matrix X) { return solve(B, X, Transpose.Transpose); } @Override public Vector transSolve(Vector b, Vector x) { DenseMatrix B = new DenseMatrix(b, false), X = new DenseMatrix(x, false); transSolve(B, X); return x; } Matrix solve(Matrix B, Matrix X, Transpose trans) { if (!(X instanceof DenseMatrix)) throw new UnsupportedOperationException("X must be a DenseMatrix"); // Different argument checking to support Hessenberg type matrices for // solvers such as GMRES if (B.numRows() < numRows) throw new IllegalArgumentException("B.numRows() < A.numRows()"); if (B.numColumns() != X.numColumns()) throw new IllegalArgumentException( "B.numColumns() != X.numColumns()"); if (X.numRows() < numRows) throw new IllegalArgumentException("X.numRows() < A.numRows()"); double[] Xd = ((DenseMatrix) X).getData(); X.set(B); intW info = new intW(0); LAPACK.getInstance().dtrtrs(uplo.netlib(), trans.netlib(), diag.netlib(), numRows, X.numColumns(), data, Math.max(1, ld), Xd, Matrices.ld(numRows), info); if (info.val > 0) throw new MatrixSingularException(); else if (info.val < 0) throw new IllegalArgumentException(); return X; } @Override int getIndex(int row, int column) { check(row, column); return row + column * Math.max(ld, numRows); } @Override public Iterator iterator() { return new TriangDenseMatrixIterator(); } private class TriangDenseMatrixIterator extends RefMatrixIterator { @Override public MatrixEntry next() { entry.update(row, column); if (uplo == UpLo.Lower) if (row < numRows - 1) row++; else { column++; row = column; } else { // uplo == UpLo.Upper if (row < column) row++; else { column++; row = 0; } } return entry; } } } mtj-0.9.14/src/no/uib/cipr/matrix/UnitUpperTriangPackMatrix.java0000644000000000000000000000576111027512662023262 0ustar rootroot/* * 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; /** * Unit upper triangular packed matrix. Same storage as * {@link no.uib.cipr.matrix.UpperTriangPackMatrix UpperTriangPackMatrix}, but * the main diagonal is assumed to be all ones. */ public class UnitUpperTriangPackMatrix extends UpperTriangPackMatrix { /** * Constructor for UnitUpperTriangPackMatrix * * @param n * Size of the matrix. Since the matrix must be square, this * equals both the number of rows and columns */ public UnitUpperTriangPackMatrix(int n) { super(n, Diag.Unit); } /** * Constructor for UnitUpperTriangPackMatrix * * @param A * Matrix to copy contents from. Only the entries of the relevant * part are copied */ public UnitUpperTriangPackMatrix(Matrix A) { this(A, true); } /** * Constructor for UnitUpperTriangPackMatrix * * @param A * Matrix to copy contents from. Only the entries of the relevant * part are copied * @param deep * True if the copy is deep, else false (giving a shallow copy). * For shallow copies, A must be a packed matrix */ public UnitUpperTriangPackMatrix(Matrix A, boolean deep) { super(A, deep, Diag.Unit); } @Override public void add(int row, int column, double value) { if (row == column) throw new IllegalArgumentException("row == column"); super.add(row, column, value); } @Override public double get(int row, int column) { if (row == column) return 1; return super.get(row, column); } @Override public void set(int row, int column, double value) { if (row == column) throw new IllegalArgumentException("row == column"); super.set(row, column, value); } @Override void copy(Matrix A) { for (MatrixEntry e : A) if (e.row() < e.column()) set(e.row(), e.column(), e.get()); } @Override public UnitUpperTriangPackMatrix copy() { return new UnitUpperTriangPackMatrix(this); } } mtj-0.9.14/src/no/uib/cipr/matrix/SymmBandEVD.java0000644000000000000000000001310711027512662020240 0ustar rootroot/* * 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 org.netlib.lapack.LAPACK; import org.netlib.util.intW; /** * Computes eigenvalues of symmetrical, banded matrices */ public class SymmBandEVD extends SymmEVD { /** * Double work array */ private final double[] work; /** * Integer work array */ private final int[] iwork; /** * Upper or lower part stored */ private final UpLo uplo; /** * Sets up an eigenvalue decomposition for symmetrical, banded matrices. * Computes all eigenvalues and eigenvectors * * @param n * Size of the matrix * @param upper * True if the upper part of the matrix is stored, and false if * the lower part of the matrix is stored instead */ public SymmBandEVD(int n, boolean upper) { this(n, upper, true); } /** * Sets up an eigenvalue decomposition for symmetrical, banded matrices * * @param n * Size of the matrix * @param upper * True if the upper part of the matrix is stored, and false if * the lower part of the matrix is stored instead * @param vectors * True to compute the eigenvectors, false for just the * eigenvalues */ public SymmBandEVD(int n, boolean upper, boolean vectors) { super(n, vectors); uplo = upper ? UpLo.Upper : UpLo.Lower; // Find the needed workspace double[] worksize = new double[1]; int[] iworksize = new int[1]; intW info = new intW(0); LAPACK.getInstance().dsbevd(job.netlib(), uplo.netlib(), n, 0, new double[0], 1, new double[0], new double[0], Matrices.ld(n), worksize, -1, iworksize, -1, info); // Allocate workspace int lwork = 0, liwork = 0; if (info.val != 0) { if (job == JobEig.All) { lwork = 1 + 6 * n + 2 * n * n; liwork = 3 + 5 * n; } else { lwork = 2 * n; liwork = 1; } } else { lwork = (int) worksize[0]; liwork = iworksize[0]; } lwork = Math.max(1, lwork); liwork = Math.max(1, liwork); work = new double[lwork]; iwork = new int[liwork]; } /** * Convenience method for computing the full eigenvalue decomposition of the * given matrix * * @param A * Matrix to factorize. The upper triangular part is extracted, * and the matrix is not modified * @param kd * Number of diagonals to extract * @return Newly allocated decomposition * @throws NotConvergedException */ public static SymmBandEVD factorize(Matrix A, int kd) throws NotConvergedException { return new SymmBandEVD(A.numRows(), true) .factor(new UpperSymmBandMatrix(A, kd)); } /** * Computes the eigenvalue decomposition of the given matrix * * @param A * Matrix to factorize. Overwritten on return * @return The current eigenvalue decomposition * @throws NotConvergedException */ public SymmBandEVD factor(LowerSymmBandMatrix A) throws NotConvergedException { if (uplo != UpLo.Lower) throw new IllegalArgumentException( "Eigenvalue computer configured for lower-symmetrical matrices"); return factor(A, A.getData(), A.numSubDiagonals()); } /** * Computes the eigenvalue decomposition of the given matrix * * @param A * Matrix to factorize. Overwritten on return * @return The current eigenvalue decomposition * @throws NotConvergedException */ public SymmBandEVD factor(UpperSymmBandMatrix A) throws NotConvergedException { if (uplo != UpLo.Upper) throw new IllegalArgumentException( "Eigenvalue computer configured for upper-symmetrical matrices"); return factor(A, A.getData(), A.numSuperDiagonals()); } private SymmBandEVD factor(Matrix A, double[] data, int kd) throws NotConvergedException { if (A.numRows() != n) throw new IllegalArgumentException("A.numRows() != n"); intW info = new intW(0); LAPACK.getInstance().dsbevd(job.netlib(), uplo.netlib(), n, kd, data, Matrices.ld(kd + 1), w, job == JobEig.All ? Z.getData() : new double[0], Matrices.ld(n), work, work.length, iwork, iwork.length, info); if (info.val > 0) throw new NotConvergedException( NotConvergedException.Reason.Iterations); else if (info.val < 0) throw new IllegalArgumentException(); return this; } } mtj-0.9.14/src/no/uib/cipr/matrix/UnitLowerTriangPackMatrix.java0000644000000000000000000000576111027512662023257 0ustar rootroot/* * 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; /** * Unit lower triangular packed matrix. Same storage as * {@link no.uib.cipr.matrix.LowerTriangPackMatrix LowerTriangPackMatrix}, but * the main diagonal is assumed to be all ones. */ public class UnitLowerTriangPackMatrix extends LowerTriangPackMatrix { /** * Constructor for UnitLowerTriangPackMatrix * * @param n * Size of the matrix. Since the matrix must be square, this * equals both the number of rows and columns */ public UnitLowerTriangPackMatrix(int n) { super(n, Diag.Unit); } /** * Constructor for UnitLowerTriangPackMatrix * * @param A * Matrix to copy contents from. Only the entries of the relevant * part are copied */ public UnitLowerTriangPackMatrix(Matrix A) { this(A, true); } /** * Constructor for UnitLowerTriangPackMatrix * * @param A * Matrix to copy contents from. Only the entries of the relevant * part are copied * @param deep * True if the copy is deep, else false (giving a shallow copy). * For shallow copies, A must be a packed matrix */ public UnitLowerTriangPackMatrix(Matrix A, boolean deep) { super(A, deep, Diag.Unit); } @Override public void add(int row, int column, double value) { if (column == row) throw new IllegalArgumentException("column == row"); super.add(row, column, value); } @Override public double get(int row, int column) { if (column == row) return 1; return super.get(row, column); } @Override public void set(int row, int column, double value) { if (column == row) throw new IllegalArgumentException("column == row"); super.set(row, column, value); } @Override void copy(Matrix A) { for (MatrixEntry e : A) if (e.row() > e.column()) set(e.row(), e.column(), e.get()); } @Override public UnitLowerTriangPackMatrix copy() { return new UnitLowerTriangPackMatrix(this); } } mtj-0.9.14/src/no/uib/cipr/matrix/BandCholesky.java0000644000000000000000000001630311027512662020536 0ustar rootroot/* * 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 no.uib.cipr.matrix.Matrix.Norm; import org.netlib.lapack.LAPACK; import org.netlib.util.doubleW; import org.netlib.util.intW; /** * Banded Cholesky decomposition */ public class BandCholesky { /** * Matrix dimension */ private final int n; /** * Number of bands in the matrix A */ private final int kd; /** * Cholesky decomposition of a lower matrix */ private LowerTriangBandMatrix Cl; /** * Cholesky decomposition of an upper matrix */ private UpperTriangBandMatrix Cu; /** * If the matrix is SPD or not */ private boolean notspd; /** * True for upper part, else false */ private final boolean upper; /** * Constructor for BandCholesky * * @param n * Matrix size * @param kd * Number of matrix bands * @param upper * True for decomposing an upper symmetrical matrix, false for a * lower symmetrical matrix */ public BandCholesky(int n, int kd, boolean upper) { this.n = n; this.kd = kd; this.upper = upper; if (upper) Cu = new UpperTriangBandMatrix(n, kd); else Cl = new LowerTriangBandMatrix(n, kd); } /** * Creates a Cholesky decomposition of the given matrix * * @param A * Matrix to decompose. Not modified * @return A Cholesky decomposition of the matrix */ public static BandCholesky factorize(LowerSPDBandMatrix A) { return new BandCholesky(A.numRows(), A.kl, false).factor(A); } /** * Creates a Cholesky decomposition of the given matrix * * @param A * Matrix to decompose. Not modified * @return A Cholesky decomposition of the matrix */ public static BandCholesky factorize(UpperSPDBandMatrix A) { return new BandCholesky(A.numRows(), A.ku, true).factor(A); } /** * Creates a Cholesky decomposition of the given matrix * * @param A * Matrix to decompose. Overwritten on return * @return The current decomposition */ public BandCholesky factor(LowerSPDBandMatrix A) { if (upper) throw new IllegalArgumentException( "Cholesky decomposition constructed for upper matrices"); return decompose(A); } /** * Creates a Cholesky decomposition of the given matrix * * @param A * Matrix to decompose. Overwritten on return * @return The current decomposition */ public BandCholesky factor(UpperSPDBandMatrix A) { if (!upper) throw new IllegalArgumentException( "Cholesky decomposition constructed for lower matrices"); return decompose(A); } private BandCholesky decompose(AbstractBandMatrix A) { if (n != A.numRows()) throw new IllegalArgumentException("n != A.numRows()"); if (upper && A.ku != kd) throw new IllegalArgumentException("A.ku != kd"); if (!upper && A.kl != kd) throw new IllegalArgumentException("A.kl != kd"); notspd = false; intW info = new intW(0); if (upper) LAPACK.getInstance().dpbtrf(UpLo.Upper.netlib(), n, kd, A.getData(), Matrices.ld(kd + 1), info); else LAPACK.getInstance().dpbtrf(UpLo.Lower.netlib(), n, kd, A.getData(), Matrices.ld(kd + 1), info); if (info.val > 0) notspd = true; else if (info.val < 0) throw new IllegalArgumentException(); if (upper) Cu.set(A); else Cl.set(A); return this; } /** * Returns the decomposition matrix. Only valid for decomposition of a lower * SPD matrix */ public LowerTriangBandMatrix getL() { if (!upper) return Cl; else throw new UnsupportedOperationException(); } /** * Returns the decomposition matrix. Only valid for decomposition of a upper * SPD matrix */ public UpperTriangBandMatrix getU() { if (upper) return Cu; else throw new UnsupportedOperationException(); } /** * Returns true if the matrix decomposed is symmetrical, positive definite */ public boolean isSPD() { return !notspd; } /** * Computes the reciprocal condition number * * @param A * The matrix this is a decomposition of * @return The reciprocal condition number. Values close to unity indicate a * well-conditioned system, while numbers close to zero do not. */ public double rcond(Matrix A) { if (A.numRows() != n) throw new IllegalArgumentException("A.numRows() != n"); if (!A.isSquare()) throw new IllegalArgumentException("!A.isSquare()"); double anorm = A.norm(Norm.One); double[] work = new double[3 * n]; int[] lwork = new int[n]; intW info = new intW(0); doubleW rcond = new doubleW(0); if (upper) LAPACK.getInstance().dpbcon(UpLo.Upper.netlib(), n, kd, Cu.getData(), Matrices.ld(kd + 1), anorm, rcond, work, lwork, info); else LAPACK.getInstance().dpbcon(UpLo.Lower.netlib(), n, kd, Cl.getData(), Matrices.ld(kd + 1), anorm, rcond, work, lwork, info); if (info.val < 0) throw new IllegalArgumentException(); return rcond.val; } /** * Computes A\B, overwriting B */ public DenseMatrix solve(DenseMatrix B) throws MatrixNotSPDException { if (notspd) throw new MatrixNotSPDException(); if (B.numRows() != n) throw new IllegalArgumentException("B.numRows() != n"); intW info = new intW(0); if (upper) LAPACK.getInstance().dpbtrs(UpLo.Upper.netlib(), n, kd, B.numColumns(), Cu.getData(), Matrices.ld(kd + 1), B.getData(), Matrices.ld(n), info); else LAPACK.getInstance().dpbtrs(UpLo.Lower.netlib(), n, kd, B.numColumns(), Cl.getData(), Matrices.ld(kd + 1), B.getData(), Matrices.ld(n), info); if (info.val < 0) throw new IllegalArgumentException(); return B; } } mtj-0.9.14/src/no/uib/cipr/matrix/Side.java0000644000000000000000000000217411027512662017055 0ustar rootroot/* * 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; /** Side enumeration */ enum Side { /** Apply operation from left */ Left, /** Apply operation from right */ Right; /** * @return the netlib character version of this designation, for use with F2J. */ public String netlib() { if (this == Left) return "L"; return "R"; } } mtj-0.9.14/src/no/uib/cipr/matrix/AbstractTriangBandMatrix.java0000644000000000000000000001030511027512662023046 0ustar rootroot/* * 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 org.netlib.blas.BLAS; import org.netlib.lapack.LAPACK; import org.netlib.util.intW; /** * Partial implementation of a triangular, banded matrix */ abstract class AbstractTriangBandMatrix extends AbstractBandMatrix { /** * Upper or lower part stored? */ private UpLo uplo; /** * Diagonal stored or not? */ private Diag diag; /** * Diagonals in relevant band */ int kd; /** * Constructor for AbstractTriangBandMatrix */ AbstractTriangBandMatrix(int n, int kl, int ku, UpLo uplo, Diag diag) { super(n, kl, ku); kd = Math.max(kl, ku); this.uplo = uplo; this.diag = diag; } /** * Constructor for AbstractTriangBandMatrix */ AbstractTriangBandMatrix(Matrix A, int kl, int ku, UpLo uplo, Diag diag) { this(A, kl, ku, true, uplo, diag); } /** * Constructor for AbstractTriangBandMatrix */ AbstractTriangBandMatrix(Matrix A, int kl, int ku, boolean deep, UpLo uplo, Diag diag) { super(A, kl, ku, deep); kd = Math.max(kl, ku); this.uplo = uplo; this.diag = diag; } @Override public Vector mult(double alpha, Vector x, Vector y) { if (!(y instanceof DenseVector)) return super.mult(alpha, x, y); checkMultAdd(x, y); double[] yd = ((DenseVector) y).getData(); // y = alpha*x y.set(alpha, x); // y = A*y BLAS.getInstance().dtbmv(uplo.netlib(), Transpose.NoTranspose.netlib(), diag.netlib(), numRows, kd, data, kd + 1, yd, 1); return y; } @Override public Vector transMult(double alpha, Vector x, Vector y) { if (!(y instanceof DenseVector)) return super.transMult(alpha, x, y); checkTransMultAdd(x, y); double[] yd = ((DenseVector) y).getData(); // y = alpha*x y.set(alpha, x); // y = A*y BLAS.getInstance().dtbmv(uplo.netlib(), Transpose.Transpose.netlib(), diag.netlib(), numRows, kd, data, kd + 1, yd, 1); return y; } @Override public Matrix solve(Matrix B, Matrix X) { return solve(B, X, Transpose.NoTranspose); } @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 transSolve(Matrix B, Matrix X) { return solve(B, X, Transpose.Transpose); } @Override public Vector transSolve(Vector b, Vector x) { DenseMatrix B = new DenseMatrix(b, false), X = new DenseMatrix(x, false); transSolve(B, X); return x; } Matrix solve(Matrix B, Matrix X, Transpose trans) { if (!(X instanceof DenseMatrix)) throw new UnsupportedOperationException("X must be a DenseMatrix"); checkSolve(B, X); double[] Xd = ((DenseMatrix) X).getData(); X.set(B); intW info = new intW(0); LAPACK.getInstance().dtbtrs(uplo.netlib(), trans.netlib(), diag.netlib(), numRows, kd, X.numColumns(), data, Matrices.ld(kd + 1), Xd, Matrices.ld(n), info); if (info.val > 0) throw new MatrixSingularException(); else if (info.val < 0) throw new IllegalArgumentException(); return X; } } mtj-0.9.14/src/no/uib/cipr/matrix/OrthogonalComputer.java0000644000000000000000000000505011027512662022020 0ustar rootroot/* * 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; /** * Base class for the orthogonal matrix decompositions (QR, RQ, LQ, and QL) */ abstract class OrthogonalComputer { /** * The orthogonal matrix */ final DenseMatrix Q; /** * Lower triangular factor. May not be present */ final LowerTriangDenseMatrix L; /** * Upper triangular factor. May not be present */ final UpperTriangDenseMatrix R; /** * Factorisation sizes */ final int m, n, k; /** * Work arrays */ double[] work, workGen; /** * Scales for the reflectors */ final double[] tau; /** * Constructor for OrthogonalComputer * * @param m * Number of rows * @param n * Number of columns * @param upper * True for storing an upper triangular factor, false for a lower * triangular factor */ OrthogonalComputer(int m, int n, boolean upper) { this.m = m; this.n = n; this.k = Math.min(m, n); tau = new double[k]; Q = new DenseMatrix(m, n); if (upper) { R = new UpperTriangDenseMatrix(Math.min(m, n)); L = null; } else { L = new LowerTriangDenseMatrix(Math.min(m, n)); R = null; } } /** * Computes an orthogonal decomposition * * @param A * Matrix to decompose. Overwritten on exit. Pass a copy to avoid * this * @return The current decomposition */ public abstract OrthogonalComputer factor(DenseMatrix A); /** * Returns the orthogonal part of the factorization */ public DenseMatrix getQ() { return Q; } } mtj-0.9.14/lib/0000755000000000000000000000000011762646445011662 5ustar rootrootmtj-0.9.14/lib/nblibraries.properties0000644000000000000000000000035611554372566016277 0ustar rootrootlibs.junit.classpath=\ ${base}/junit/junit-3.8.2.jar libs.junit.javadoc=\ ${base}/junit/junit-3.8.2-api.zip libs.netlib-java.classpath=\ ${base}/netlib-java/arpack_combo-0.1.jar:\ ${base}/netlib-java/netlib-java-0.9.3.jar mtj-0.9.14/tests/0000755000000000000000000000000011027515240012234 5ustar rootrootmtj-0.9.14/tests/no/0000755000000000000000000000000011027515240012650 5ustar rootrootmtj-0.9.14/tests/no/uib/0000755000000000000000000000000011027515240013427 5ustar rootrootmtj-0.9.14/tests/no/uib/cipr/0000755000000000000000000000000011027515240014364 5ustar rootrootmtj-0.9.14/tests/no/uib/cipr/matrix/0000755000000000000000000000000011107366110015667 5ustar rootrootmtj-0.9.14/tests/no/uib/cipr/matrix/LowerTriangPackMatrixTest.java0000644000000000000000000000255211027514550023623 0ustar rootroot/* * 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 no.uib.cipr.matrix.LowerTriangPackMatrix; /** * Test of LowerTriangPackMatrix */ public class LowerTriangPackMatrixTest extends TriangMatrixTestAbstract { public LowerTriangPackMatrixTest(String arg0) { super(arg0); } @Override protected void createPrimary() throws Exception { int n = Utilities.getInt(1, max); A = new LowerTriangPackMatrix(n); Ad = Utilities.lowerPopulate(A); // This ensures non-singularity Utilities.addDiagonal(A, Ad, 1); } } mtj-0.9.14/tests/no/uib/cipr/matrix/sparse/0000755000000000000000000000000011554357106017177 5ustar rootrootmtj-0.9.14/tests/no/uib/cipr/matrix/sparse/CGAMGTest.java0000644000000000000000000000221711027512662021515 0ustar rootroot/* * 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.sparse; import no.uib.cipr.matrix.sparse.AMG; /** * Test of CG with AMG */ public class CGAMGTest extends CGTest { public CGAMGTest(String arg0) { super(arg0); } @Override protected void createSolver() throws Exception { super.createSolver(); M = new AMG(); } } mtj-0.9.14/tests/no/uib/cipr/matrix/sparse/SparseStructImmutableMatrixTestAbstract.java0000644000000000000000000000307111027515002030040 0ustar rootroot/* * 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.sparse; import no.uib.cipr.matrix.StructImmutableMatrixTestAbstract; /** * Test of sparse matrices whose sparsity structure is immutable */ public abstract class SparseStructImmutableMatrixTestAbstract extends StructImmutableMatrixTestAbstract { protected int bmax = 100, tmax = 10; public SparseStructImmutableMatrixTestAbstract(String arg0) { super(arg0); } @Override public void testMatrixSolve() { // Not applicable } @Override public void testTransMatrixSolve() { // Not applicable } @Override public void testTransVectorSolve() { // Not applicable } @Override public void testVectorSolve() { // Not applicable } } mtj-0.9.14/tests/no/uib/cipr/matrix/sparse/ChebyshevICCTest.java0000644000000000000000000000235711027512662023143 0ustar rootroot/* * 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.sparse; import no.uib.cipr.matrix.sparse.CompRowMatrix; import no.uib.cipr.matrix.sparse.ICC; /** * Test of Chebyshev with ICC */ public class ChebyshevICCTest extends ChebyshevTest { public ChebyshevICCTest(String arg0) { super(arg0); } @Override protected void createSolver() throws Exception { super.createSolver(); M = new ICC(new CompRowMatrix(A)); } } mtj-0.9.14/tests/no/uib/cipr/matrix/sparse/ILUTest.java0000644000000000000000000000263311027514740021331 0ustar rootroot/* * 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.sparse; import no.uib.cipr.matrix.Matrix; import no.uib.cipr.matrix.Vector; import no.uib.cipr.matrix.sparse.CompRowMatrix; import no.uib.cipr.matrix.sparse.ILU; /** * Test of ILU(0) */ public class ILUTest extends IncompleteFactorizationTestAbstract { @Override void testFactorization(Matrix A, Vector x) { Vector b = A.mult(x, x.copy()); ILU ilu = new ILU(new CompRowMatrix(A)); ilu.setMatrix(A); ilu.apply(b, x); Vector r = A.multAdd(-1, x, b.copy()); assertEquals(0, r.norm(Vector.Norm.TwoRobust), 1e-5); } } mtj-0.9.14/tests/no/uib/cipr/matrix/sparse/SPDIterativeSolverTestAbstract.java0000644000000000000000000000337211027514762026067 0ustar rootroot/* * 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.sparse; import no.uib.cipr.matrix.SymmDenseEVD; import no.uib.cipr.matrix.sparse.FlexCompRowMatrix; import no.uib.cipr.matrix.Utilities; /** * Test of iterative solvers for SPD matrices */ public abstract class SPDIterativeSolverTestAbstract extends IterativeSolverTestAbstract { public SPDIterativeSolverTestAbstract(String arg0) { super(arg0); } @Override protected void createMatrix() throws Exception { // Create a symmetrical matrix int n = Utilities.getInt(1, max); int b = Utilities.getInt(Math.min(bmax, n)); A = new FlexCompRowMatrix(n, n); Utilities.symmetryPopulate(A, b); // Need positive eigenvalues addDiagonal(A, shift); SymmDenseEVD evd = SymmDenseEVD.factorize(A); while (n > 0 && evd.getEigenvalues()[0] <= 0) { addDiagonal(A, shift); evd = SymmDenseEVD.factorize(A); } } } mtj-0.9.14/tests/no/uib/cipr/matrix/sparse/CGSILUTest.java0000644000000000000000000000232711027512662021667 0ustar rootroot/* * 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.sparse; import no.uib.cipr.matrix.sparse.CompRowMatrix; import no.uib.cipr.matrix.sparse.ILU; /** * Test of CGS with ILU */ public class CGSILUTest extends CGSTest { public CGSILUTest(String arg0) { super(arg0); } @Override protected void createSolver() throws Exception { super.createSolver(); M = new ILU(new CompRowMatrix(A)); } } mtj-0.9.14/tests/no/uib/cipr/matrix/sparse/CGSTest.java0000644000000000000000000000220011027514750021303 0ustar rootroot/* * 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.sparse; import no.uib.cipr.matrix.sparse.CGS; /** * Test of CGS */ public class CGSTest extends IterativeSolverTestAbstract { public CGSTest(String arg0) { super(arg0); } @Override protected void createSolver() throws Exception { solver = new CGS(x); } } mtj-0.9.14/tests/no/uib/cipr/matrix/sparse/GMRESTest.java0000644000000000000000000000221211027514750021547 0ustar rootroot/* * 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.sparse; import no.uib.cipr.matrix.sparse.GMRES; /** * Test of GMRES */ public class GMRESTest extends IterativeSolverTestAbstract { public GMRESTest(String arg0) { super(arg0); } @Override protected void createSolver() throws Exception { solver = new GMRES(x); } } mtj-0.9.14/tests/no/uib/cipr/matrix/sparse/QMRILUTTest.java0000644000000000000000000000234411027512662022035 0ustar rootroot/* * 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.sparse; import no.uib.cipr.matrix.sparse.FlexCompRowMatrix; import no.uib.cipr.matrix.sparse.ILUT; /** * Test of QMR with ILUT */ public class QMRILUTTest extends QMRTest { public QMRILUTTest(String arg0) { super(arg0); } @Override protected void createSolver() throws Exception { super.createSolver(); M = new ILUT(new FlexCompRowMatrix(A)); } } mtj-0.9.14/tests/no/uib/cipr/matrix/sparse/QMRILUTest.java0000644000000000000000000000232711027512662021712 0ustar rootroot/* * 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.sparse; import no.uib.cipr.matrix.sparse.CompRowMatrix; import no.uib.cipr.matrix.sparse.ILU; /** * Test of QMR with ILU */ public class QMRILUTest extends QMRTest { public QMRILUTest(String arg0) { super(arg0); } @Override protected void createSolver() throws Exception { super.createSolver(); M = new ILU(new CompRowMatrix(A)); } } mtj-0.9.14/tests/no/uib/cipr/matrix/sparse/QMRTest.java0000644000000000000000000000220011027514750021326 0ustar rootroot/* * 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.sparse; import no.uib.cipr.matrix.sparse.QMR; /** * Test of QMR */ public class QMRTest extends IterativeSolverTestAbstract { public QMRTest(String arg0) { super(arg0); } @Override protected void createSolver() throws Exception { solver = new QMR(x); } } mtj-0.9.14/tests/no/uib/cipr/matrix/sparse/BiCGstabILUTTest.java0000644000000000000000000000237011027512662023013 0ustar rootroot/* * 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.sparse; import no.uib.cipr.matrix.sparse.FlexCompRowMatrix; import no.uib.cipr.matrix.sparse.ILUT; /** * Test of BiCGstab with ILUT */ public class BiCGstabILUTTest extends BiCGstabTest { public BiCGstabILUTTest(String arg0) { super(arg0); } @Override protected void createSolver() throws Exception { super.createSolver(); M = new ILUT(new FlexCompRowMatrix(A)); } } mtj-0.9.14/tests/no/uib/cipr/matrix/sparse/GMRESILUTTest.java0000644000000000000000000000235411027512662022254 0ustar rootroot/* * 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.sparse; import no.uib.cipr.matrix.sparse.FlexCompRowMatrix; import no.uib.cipr.matrix.sparse.ILUT; /** * Test of GMRES with ILUT */ public class GMRESILUTTest extends GMRESTest { public GMRESILUTTest(String arg0) { super(arg0); } @Override protected void createSolver() throws Exception { super.createSolver(); M = new ILUT(new FlexCompRowMatrix(A)); } } mtj-0.9.14/tests/no/uib/cipr/matrix/sparse/FlexCompRowMatrixTest.java0000644000000000000000000000263211027514772024276 0ustar rootroot/* * 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.sparse; import no.uib.cipr.matrix.sparse.FlexCompRowMatrix; import no.uib.cipr.matrix.Utilities; /** * Test of FlexCompRowMatrix */ public class FlexCompRowMatrixTest extends SparseMatrixTestAbstract { public FlexCompRowMatrixTest(String arg0) { super(arg0); } @Override protected void createPrimary() throws Exception { int n = Utilities.getInt(1, max); int m = Utilities.getInt(1, max); int b = Utilities.getInt(Math.min(bmax, m)); A = new FlexCompRowMatrix(n, m); Ad = Utilities.rowPopulate(A, b); } } mtj-0.9.14/tests/no/uib/cipr/matrix/sparse/ChebyshevTest.java0000644000000000000000000000301011027514762022612 0ustar rootroot/* * 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.sparse; import no.uib.cipr.matrix.SymmDenseEVD; import no.uib.cipr.matrix.sparse.Chebyshev; /** * Test of Chebyshev solver */ public class ChebyshevTest extends SPDIterativeSolverTestAbstract { public ChebyshevTest(String arg0) { super(arg0); } @Override protected void createSolver() throws Exception { // Get the extremal eigenvalues SymmDenseEVD evd = SymmDenseEVD.factorize(A); double[] eigs = evd.getEigenvalues(); double eigmin = 1, eigmax = 1; if (eigs.length > 0) { eigmin = eigs[0]; eigmax = eigs[eigs.length - 1]; } solver = new Chebyshev(x, eigmin, eigmax); } } mtj-0.9.14/tests/no/uib/cipr/matrix/sparse/CompColMatrixTest.java0000644000000000000000000000272711027515002023415 0ustar rootroot/* * 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.sparse; import no.uib.cipr.matrix.sparse.CompColMatrix; import no.uib.cipr.matrix.Utilities; /** * Test of CompColMatrix */ public class CompColMatrixTest extends SparseStructImmutableMatrixTestAbstract { public CompColMatrixTest(String arg0) { super(arg0); } @Override protected void createPrimary() throws Exception { int n = Utilities.getInt(1, max); int m = Utilities.getInt(1, max); int b = Utilities.getInt(Math.min(bmax, m)); int[][] nz = Utilities.getColumnPattern(n, m, b); A = new CompColMatrix(n, m, nz); Ad = Utilities.columnPopulate(A, nz); } } mtj-0.9.14/tests/no/uib/cipr/matrix/sparse/ICCTest.java0000644000000000000000000000263411027514740021277 0ustar rootroot/* * 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.sparse; import no.uib.cipr.matrix.Matrix; import no.uib.cipr.matrix.Vector; import no.uib.cipr.matrix.sparse.CompRowMatrix; import no.uib.cipr.matrix.sparse.ICC; /** * Test of ICC(0) */ public class ICCTest extends IncompleteFactorizationTestAbstract { @Override void testFactorization(Matrix A, Vector x) { Vector b = A.mult(x, x.copy()); ICC icc = new ICC(new CompRowMatrix(A)); icc.setMatrix(A); icc.apply(b, x); Vector r = A.multAdd(-1, x, b.copy()); assertEquals(0, r.norm(Vector.Norm.TwoRobust), 1e-5); } } mtj-0.9.14/tests/no/uib/cipr/matrix/sparse/SparseMatrixTestAbstract.java0000644000000000000000000000271711027514772025016 0ustar rootroot/* * 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.sparse; import no.uib.cipr.matrix.MatrixTestAbstract; /** * Test of sparse matrices */ public abstract class SparseMatrixTestAbstract extends MatrixTestAbstract { protected int bmax = 100, tmax = 10; public SparseMatrixTestAbstract(String arg0) { super(arg0); } @Override public void testMatrixSolve() { // Not applicable } @Override public void testTransMatrixSolve() { // Not applicable } @Override public void testTransVectorSolve() { // Not applicable } @Override public void testVectorSolve() { // Not applicable } } mtj-0.9.14/tests/no/uib/cipr/matrix/sparse/BiCGstabTest.java0000644000000000000000000000223111027514750022311 0ustar rootroot/* * 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.sparse; import no.uib.cipr.matrix.sparse.BiCGstab; /** * Test of BiCGstab */ public class BiCGstabTest extends IterativeSolverTestAbstract { public BiCGstabTest(String arg0) { super(arg0); } @Override protected void createSolver() throws Exception { solver = new BiCGstab(x); } } mtj-0.9.14/tests/no/uib/cipr/matrix/sparse/GMRESDiagonalTest.java0000644000000000000000000000235311027512662023214 0ustar rootroot/* * 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.sparse; import no.uib.cipr.matrix.sparse.DiagonalPreconditioner; /** * Test of GMRES with diagonal preconditioning */ public class GMRESDiagonalTest extends GMRESTest { public GMRESDiagonalTest(String arg0) { super(arg0); } @Override protected void createSolver() throws Exception { super.createSolver(); M = new DiagonalPreconditioner(A.numRows()); } } mtj-0.9.14/tests/no/uib/cipr/matrix/sparse/ChebyshevSSORTest.java0000644000000000000000000000250211027512662023323 0ustar rootroot/* * 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.sparse; import no.uib.cipr.matrix.sparse.CompRowMatrix; import no.uib.cipr.matrix.sparse.SSOR; /** * Test of Chebyshev with SSOR preconditioning */ public class ChebyshevSSORTest extends ChebyshevTest { public ChebyshevSSORTest(String arg0) { super(arg0); } @Override protected void createSolver() throws Exception { super.createSolver(); double omega = Math.random() + 1; M = new SSOR(new CompRowMatrix(A), true, omega, omega); } } mtj-0.9.14/tests/no/uib/cipr/matrix/sparse/ChebyshevAMGTest.java0000644000000000000000000000225311027512662023144 0ustar rootroot/* * 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.sparse; import no.uib.cipr.matrix.sparse.AMG; /** * Test of Chebyshev with AMG */ public class ChebyshevAMGTest extends ChebyshevTest { public ChebyshevAMGTest(String arg0) { super(arg0); } @Override protected void createSolver() throws Exception { super.createSolver(); M = new AMG(); } } mtj-0.9.14/tests/no/uib/cipr/matrix/sparse/ChebyshevDiagonalTest.java0000644000000000000000000000237311027512662024261 0ustar rootroot/* * 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.sparse; import no.uib.cipr.matrix.sparse.DiagonalPreconditioner; /** * Test of Chebyshev with diagonal preconditioning */ public class ChebyshevDiagonalTest extends ChebyshevTest { public ChebyshevDiagonalTest(String arg0) { super(arg0); } @Override protected void createSolver() throws Exception { super.createSolver(); M = new DiagonalPreconditioner(A.numRows()); } } mtj-0.9.14/tests/no/uib/cipr/matrix/sparse/BiCGDiagonalTest.java0000644000000000000000000000234711027512662023106 0ustar rootroot/* * 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.sparse; import no.uib.cipr.matrix.sparse.DiagonalPreconditioner; /** * Test of BiCG with diagonal preconditioning */ public class BiCGDiagonalTest extends BiCGTest { public BiCGDiagonalTest(String arg0) { super(arg0); } @Override protected void createSolver() throws Exception { super.createSolver(); M = new DiagonalPreconditioner(A.numRows()); } } mtj-0.9.14/tests/no/uib/cipr/matrix/sparse/SparseVectorTest.java0000644000000000000000000000647311554357106023334 0ustar rootroot/* * 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.sparse; import java.util.Arrays; import java.util.Iterator; import no.uib.cipr.matrix.DenseVector; import no.uib.cipr.matrix.Vector; import no.uib.cipr.matrix.Utilities; import no.uib.cipr.matrix.VectorEntry; import no.uib.cipr.matrix.VectorTestAbstract; /** * Test of SparseVector */ public class SparseVectorTest extends VectorTestAbstract { public SparseVectorTest(String arg0) { super(arg0); } @Override protected void createPrimary() throws Exception { int n = Utilities.getInt(1, max); int m = Math.min(Utilities.getInt(max), n); x = new SparseVector(n); xd = Utilities.populate(x, m); } public void testSparseVectorIndices() { /* * MTJ subtlety in getIndex() for SparseVector. before calling * getIndex(), you must call compact()... implementations may choose to * do nothing in this call, but the Intel extended LAPACK * implementations (and MTJ's SparseVector) require it. An alternative * to vector.getIndex() is VectorMethods.getIndex(Vector) which will * wrap this for you. It can take an arbitrary Vector and if it can be * cast to a SparseVector will compact it and use its getIndex() method * instead. (just so you're aware of this). Sam. */ // check that "infinite dimensions" doesn't use infinite memory SparseVector vector = new SparseVector(Integer.MAX_VALUE); int[] index = vector.getIndex(); assert index != null; assert index.length == 0; // check that creating with double[] with zeros works double[] entries = new double[5]; entries[0] = 0.0; entries[1] = 0.0; entries[2] = 1.0; entries[3] = 0.0; entries[4] = 2.0; Vector dense = new DenseVector(entries, false); vector = new SparseVector(dense); // NOTE: must compact before calling getIndex()!!! // vector.compact(); index = vector.getIndex(); assert index != null; assert index.length == 5 : "expected length of 5, but got " + index.length + ", with elements " + Arrays.toString(index); } public void testBug27() { double[] tfVector = {0.0,0.5,0.0,0.4,0.0}; DenseVector dense= new DenseVector(tfVector, false); SparseVector vectorTF = new SparseVector(dense); vectorTF.compact(); assertTrue(vectorTF.getUsed() == 2); // vectorTF.getUsed() returns 5 for (Iterator it = vectorTF.iterator();it.hasNext();) { VectorEntry ve= it.next(); int index = ve.index(); double value = ve.get(); assertTrue(tfVector[index]== value); } } } mtj-0.9.14/tests/no/uib/cipr/matrix/sparse/CGSSORTest.java0000644000000000000000000000242611027512662021701 0ustar rootroot/* * 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.sparse; import no.uib.cipr.matrix.sparse.CompRowMatrix; import no.uib.cipr.matrix.sparse.SSOR; /** * Test of CG with SSOR */ public class CGSSORTest extends CGTest { public CGSSORTest(String arg0) { super(arg0); } @Override protected void createSolver() throws Exception { super.createSolver(); double omega = Math.random() + 1; M = new SSOR(new CompRowMatrix(A), true, omega, omega); } } mtj-0.9.14/tests/no/uib/cipr/matrix/sparse/GMRESILUTest.java0000644000000000000000000000233711027512662022131 0ustar rootroot/* * 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.sparse; import no.uib.cipr.matrix.sparse.CompRowMatrix; import no.uib.cipr.matrix.sparse.ILU; /** * Test of GMRES with ILU */ public class GMRESILUTest extends GMRESTest { public GMRESILUTest(String arg0) { super(arg0); } @Override protected void createSolver() throws Exception { super.createSolver(); M = new ILU(new CompRowMatrix(A)); } } mtj-0.9.14/tests/no/uib/cipr/matrix/sparse/BiCGstabDiagonalTest.java0000644000000000000000000000236711027512662023762 0ustar rootroot/* * 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.sparse; import no.uib.cipr.matrix.sparse.DiagonalPreconditioner; /** * Test of BiCGstab with diagonal preconditioning */ public class BiCGstabDiagonalTest extends BiCGstabTest { public BiCGstabDiagonalTest(String arg0) { super(arg0); } @Override protected void createSolver() throws Exception { super.createSolver(); M = new DiagonalPreconditioner(A.numRows()); } } mtj-0.9.14/tests/no/uib/cipr/matrix/sparse/CGTest.java0000644000000000000000000000217611027514762021177 0ustar rootroot/* * 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.sparse; import no.uib.cipr.matrix.sparse.CG; /** * Test of CG */ public class CGTest extends SPDIterativeSolverTestAbstract { public CGTest(String arg0) { super(arg0); } @Override protected void createSolver() throws Exception { solver = new CG(x); } } mtj-0.9.14/tests/no/uib/cipr/matrix/sparse/CompDiagMatrixTest.java0000644000000000000000000000261111027514772023551 0ustar rootroot/* * 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.sparse; import no.uib.cipr.matrix.sparse.CompDiagMatrix; import no.uib.cipr.matrix.Utilities; /** * Test of CompDiagMatrix */ public class CompDiagMatrixTest extends SparseMatrixTestAbstract { public CompDiagMatrixTest(String arg0) { super(arg0); } @Override protected void createPrimary() throws Exception { int n = Utilities.getInt(1, max); int m = Utilities.getInt(1, max); int b = Utilities.getInt(Math.min(bmax, m)); A = new CompDiagMatrix(n, m); Ad = Utilities.rowPopulate(A, b); } }mtj-0.9.14/tests/no/uib/cipr/matrix/sparse/CGSDiagonalTest.java0000644000000000000000000000234311027512662022752 0ustar rootroot/* * 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.sparse; import no.uib.cipr.matrix.sparse.DiagonalPreconditioner; /** * Test of CGS with diagonal preconditioning */ public class CGSDiagonalTest extends CGSTest { public CGSDiagonalTest(String arg0) { super(arg0); } @Override protected void createSolver() throws Exception { super.createSolver(); M = new DiagonalPreconditioner(A.numRows()); } } mtj-0.9.14/tests/no/uib/cipr/matrix/sparse/CGDiagonalTest.java0000644000000000000000000000233711027512662022632 0ustar rootroot/* * 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.sparse; import no.uib.cipr.matrix.sparse.DiagonalPreconditioner; /** * Test of CG with diagonal preconditioning */ public class CGDiagonalTest extends CGTest { public CGDiagonalTest(String arg0) { super(arg0); } @Override protected void createSolver() throws Exception { super.createSolver(); M = new DiagonalPreconditioner(A.numRows()); } } mtj-0.9.14/tests/no/uib/cipr/matrix/sparse/BiCGTest.java0000644000000000000000000000220511027514750021440 0ustar rootroot/* * 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.sparse; import no.uib.cipr.matrix.sparse.BiCG; /** * Test of BiCG */ public class BiCGTest extends IterativeSolverTestAbstract { public BiCGTest(String arg0) { super(arg0); } @Override protected void createSolver() throws Exception { solver = new BiCG(x); } } mtj-0.9.14/tests/no/uib/cipr/matrix/sparse/IterativeSolverTestAbstract.java0000644000000000000000000001127511027514750025516 0ustar rootroot/* * 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.sparse; import no.uib.cipr.matrix.DenseLU; import no.uib.cipr.matrix.Matrices; import no.uib.cipr.matrix.Matrix; import no.uib.cipr.matrix.Vector; import no.uib.cipr.matrix.sparse.FlexCompRowMatrix; import no.uib.cipr.matrix.sparse.IterativeSolver; import no.uib.cipr.matrix.sparse.IterativeSolverNotConvergedException; import no.uib.cipr.matrix.sparse.Preconditioner; import no.uib.cipr.matrix.Utilities; import junit.framework.TestCase; /** * Test of the iterative solvers and preconditioners */ public abstract class IterativeSolverTestAbstract extends TestCase { /** * Number of times to repeat tests */ private int repeat = 5; /** * Sizes of the system matrix */ protected int max = 50, bmax = 10; /** * Numerical tolerance */ protected double tol = 1e-4; /** * Diagonal shift for singularity handling */ protected double shift = 100; /** * Square system matrix */ protected Matrix A; /** * Right hand side, right hand for transpose system, and the solution vector * in both cases */ protected Vector b, bt, x; /** * Stores the data of x */ protected double[] xd; /** * Iterative solver to use */ protected IterativeSolver solver; /** * Preconditioner to use */ protected Preconditioner M; /** * Constructor for IterativeSolverTestAbstract */ public IterativeSolverTestAbstract(String arg0) { super(arg0); } @Override protected void setUp() throws Exception { createMatrix(); int n = A.numRows(); x = Matrices.random(n); b = Matrices.random(n); bt = Matrices.random(n); // Create solver and preconditioner createSolver(); if (M == null) M = solver.getPreconditioner(); M.setMatrix(A); // Compute the correct right hand sides b = A.mult(x, b); bt = A.transMult(x, bt); // Store x for later. It is overwritten xd = Matrices.getArray(x); // Randomize the inital solution vector Matrices.random(x); } protected abstract void createSolver() throws Exception; protected void createMatrix() throws Exception { // Create an arbitrary matrix int n = Utilities.getInt(1, max); int b = Utilities.getInt(Math.min(bmax, n)); A = new FlexCompRowMatrix(n, n); Utilities.rowPopulate(A, b); // Make it non-singular addDiagonal(A, shift); DenseLU lu = DenseLU.factorize(A); while (lu.isSingular()) { addDiagonal(A, shift); lu = DenseLU.factorize(A); } } protected void addDiagonal(Matrix A, double shift) { int n = A.numRows(), m = A.numColumns(); for (int i = 0; i < Math.min(n, m); ++i) A.add(i, i, shift); } @Override protected void tearDown() throws Exception { A = null; b = bt = x = null; xd = null; solver = null; } public void testSolve() { try { solver.solve(A, b, x); assertSolved(); } catch (IterativeSolverNotConvergedException e) { fail("Solver did not converge: " + e.getReason() + ". Residual=" + e.getResidual()); } } public void testRepeatSolve() { try { for (int i = 0; i < repeat; ++i) { solver.solve(A, b, x); assertSolved(); x = Matrices.random(A.numRows()); } } catch (IterativeSolverNotConvergedException e) { fail("Solver did not converge: " + e.getReason() + ". Residual=" + e.getResidual()); } } protected void assertSolved() { for (int i = 0; i < xd.length; ++i) assertEquals(xd[i], x.get(i), tol); } } mtj-0.9.14/tests/no/uib/cipr/matrix/sparse/IncompleteFactorizationTestAbstract.java0000644000000000000000000000440611027514740027220 0ustar rootroot/* * 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.sparse; import no.uib.cipr.matrix.DenseMatrix; import no.uib.cipr.matrix.DenseVector; import no.uib.cipr.matrix.Matrix; import no.uib.cipr.matrix.Vector; import no.uib.cipr.matrix.Utilities; import junit.framework.TestCase; /** * Test of incomplete factorizations */ public abstract class IncompleteFactorizationTestAbstract extends TestCase { @Override protected void setUp() throws Exception { super.setUp(); } public void testTriDiagonal() { int n = Utilities.getInt(1, 10); Matrix A = new DenseMatrix(n, n); Vector x = new DenseVector(n); for (int i = 0; i < n; ++i) { A.set(i, i, 2); x.set(i, 1); } for (int i = 0; i < n - 1; ++i) { A.set(i, i + 1, -1); A.set(i + 1, i, -1); } testFactorization(A, x); } public void testPentaDiagonal() { int n = Utilities.getInt(1, 10); Matrix A = new DenseMatrix(n, n); Vector x = new DenseVector(n); for (int i = 0; i < n; ++i) { A.set(i, i, 4); x.set(i, 1); } for (int i = 0; i < n - 1; ++i) { A.set(i, i + 1, -1); A.set(i + 1, i, -1); } for (int i = 0; i < n - 2; ++i) { A.set(i, i + 2, -1); A.set(i + 2, i, -1); } testFactorization(A, x); } abstract void testFactorization(Matrix A, Vector x); } mtj-0.9.14/tests/no/uib/cipr/matrix/sparse/BiCGILUTest.java0000644000000000000000000000233311027512662022014 0ustar rootroot/* * 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.sparse; import no.uib.cipr.matrix.sparse.CompRowMatrix; import no.uib.cipr.matrix.sparse.ILU; /** * Test of BiCG with ILU */ public class BiCGILUTest extends BiCGTest { public BiCGILUTest(String arg0) { super(arg0); } @Override protected void createSolver() throws Exception { super.createSolver(); M = new ILU(new CompRowMatrix(A)); } } mtj-0.9.14/tests/no/uib/cipr/matrix/sparse/CGSILUTTest.java0000644000000000000000000000234411027512662022012 0ustar rootroot/* * 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.sparse; import no.uib.cipr.matrix.sparse.FlexCompRowMatrix; import no.uib.cipr.matrix.sparse.ILUT; /** * Test of CGS with ILUT */ public class CGSILUTTest extends CGSTest { public CGSILUTTest(String arg0) { super(arg0); } @Override protected void createSolver() throws Exception { super.createSolver(); M = new ILUT(new FlexCompRowMatrix(A)); } } mtj-0.9.14/tests/no/uib/cipr/matrix/sparse/CGICCTest.java0000644000000000000000000000232311027512662021505 0ustar rootroot/* * 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.sparse; import no.uib.cipr.matrix.sparse.CompRowMatrix; import no.uib.cipr.matrix.sparse.ICC; /** * Test of CG with ICC */ public class CGICCTest extends CGTest { public CGICCTest(String arg0) { super(arg0); } @Override protected void createSolver() throws Exception { super.createSolver(); M = new ICC(new CompRowMatrix(A)); } } mtj-0.9.14/tests/no/uib/cipr/matrix/sparse/CompRowMatrixTest.java0000644000000000000000000000272111027515002023441 0ustar rootroot/* * 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.sparse; import no.uib.cipr.matrix.sparse.CompRowMatrix; import no.uib.cipr.matrix.Utilities; /** * Test of CompRowMatrix */ public class CompRowMatrixTest extends SparseStructImmutableMatrixTestAbstract { public CompRowMatrixTest(String arg0) { super(arg0); } @Override protected void createPrimary() throws Exception { int n = Utilities.getInt(1, max); int m = Utilities.getInt(1, max); int b = Utilities.getInt(Math.min(bmax, m)); int[][] nz = Utilities.getRowPattern(n, m, b); A = new CompRowMatrix(n, m, nz); Ad = Utilities.rowPopulate(A, nz); } } mtj-0.9.14/tests/no/uib/cipr/matrix/sparse/FlexCompColMatrixTest.java0000644000000000000000000000263511027514772024247 0ustar rootroot/* * 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.sparse; import no.uib.cipr.matrix.sparse.FlexCompColMatrix; import no.uib.cipr.matrix.Utilities; /** * Test of FlexCompColMatrix */ public class FlexCompColMatrixTest extends SparseMatrixTestAbstract { public FlexCompColMatrixTest(String arg0) { super(arg0); } @Override protected void createPrimary() throws Exception { int n = Utilities.getInt(1, max); int m = Utilities.getInt(1, max); int b = Utilities.getInt(Math.min(bmax, m)); A = new FlexCompColMatrix(n, m); Ad = Utilities.columnPopulate(A, b); } } mtj-0.9.14/tests/no/uib/cipr/matrix/sparse/ILUTTest.java0000644000000000000000000000265711027514740021463 0ustar rootroot/* * 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.sparse; import no.uib.cipr.matrix.Matrix; import no.uib.cipr.matrix.Vector; import no.uib.cipr.matrix.sparse.CompRowMatrix; import no.uib.cipr.matrix.sparse.ILU; /** * Test of ILU with thresholding */ public class ILUTTest extends IncompleteFactorizationTestAbstract { @Override void testFactorization(Matrix A, Vector x) { Vector b = A.mult(x, x.copy()); ILU ilut = new ILU(new CompRowMatrix(A)); ilut.setMatrix(A); ilut.apply(b, x); Vector r = A.multAdd(-1, x, b.copy()); assertEquals(0, r.norm(Vector.Norm.TwoRobust), 1e-5); } } mtj-0.9.14/tests/no/uib/cipr/matrix/sparse/BiCGstabILUTest.java0000644000000000000000000000235311027512662022670 0ustar rootroot/* * 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.sparse; import no.uib.cipr.matrix.sparse.CompRowMatrix; import no.uib.cipr.matrix.sparse.ILU; /** * Test of BiCGstab with ILU */ public class BiCGstabILUTest extends BiCGstabTest { public BiCGstabILUTest(String arg0) { super(arg0); } @Override protected void createSolver() throws Exception { super.createSolver(); M = new ILU(new CompRowMatrix(A)); } } mtj-0.9.14/tests/no/uib/cipr/matrix/sparse/QMRDiagonalTest.java0000644000000000000000000000234011027512662022772 0ustar rootroot/* * 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.sparse; import no.uib.cipr.matrix.sparse.DiagonalPreconditioner; /** * Test QMR with diagonal preconditioning */ public class QMRDiagonalTest extends QMRTest { public QMRDiagonalTest(String arg0) { super(arg0); } @Override protected void createSolver() throws Exception { super.createSolver(); M = new DiagonalPreconditioner(A.numRows()); } } mtj-0.9.14/tests/no/uib/cipr/matrix/Utilities.java0000644000000000000000000003522211027512662020517 0ustar rootroot/* * 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 java.util.HashSet; import java.util.Random; import java.util.Set; import no.uib.cipr.matrix.EVD; import no.uib.cipr.matrix.Matrix; import no.uib.cipr.matrix.NotConvergedException; import no.uib.cipr.matrix.SVD; import no.uib.cipr.matrix.Vector; /** * Utilities for the testers */ public final class Utilities { private Utilities() { // No need to instantiate } /** * Populates the sparse matrix in a symmetric fashion * * @param A * Matrix to populate * @param num * Number of entries on each symmetry band * @return The matrix data in dense format */ public static double[][] symmetryPopulate(Matrix A, int num) { int n = A.numRows(), m = A.numColumns(); if (m != n) throw new IllegalArgumentException("m != n"); double[][] values = new double[n][m]; if (n == 0) return values; for (int j = 0; j < m; ++j) for (int i = 0; i < num; ++i) { double value = Math.random(); int k = (int) (Math.random() * n); values[k][j] = value; values[j][k] = value; A.set(k, j, value); A.set(j, k, value); } return values; } /** * Populates the matrix, putting a given number of entries on each column * * @param A * Matrix to populate * @param num * Number of entries on each column * @return The matrix data in dense format */ public static double[][] columnPopulate(Matrix A, int num) { int n = A.numRows(), m = A.numColumns(); double[][] values = new double[n][m]; if (n == 0) return values; for (int j = 0; j < m; ++j) for (int i = 0; i < num; ++i) { double value = Math.random(); int k = (int) (Math.random() * n); values[k][j] = value; A.set(k, j, value); } return values; } /** * Populates the matrix, putting a given number of entries on each row * * @param A * Matrix to populate * @param num * Number of entries on each row * @return The matrix data in dense format */ public static double[][] rowPopulate(Matrix A, int num) { int n = A.numRows(), m = A.numColumns(); double[][] values = new double[n][m]; if (m == 0) return values; for (int i = 0; i < n; ++i) for (int j = 0; j < num; ++j) { double value = Math.random(); int k = (int) (Math.random() * m); values[i][k] = value; A.set(i, k, value); } return values; } /** * Gets a row-wise non-zero pattern suitable for creating compressed row * matrices * * @param n * Number of rows * @param m * Number of columns * @param b * Number of entries on each row */ public static int[][] getRowPattern(int n, int m, int b) { int[][] nz = new int[n][]; for (int i = 0; i < n; ++i) { Set row = new HashSet(); for (int j = 0; j < b; ++j) row.add(getInt(m)); nz[i] = new int[row.size()]; int j = 0; for (Integer colind : row) nz[i][j++] = colind; } return nz; } /** * Gets a column-wise non-zero pattern suitable for creating compressed * column matrices * * @param n * Number of rows * @param m * Number of columns * @param b * Number of entries on each column */ public static int[][] getColumnPattern(int n, int m, int b) { int[][] nz = new int[m][]; for (int i = 0; i < m; ++i) { Set column = new HashSet(); for (int j = 0; j < b; ++j) column.add(getInt(n)); nz[i] = new int[column.size()]; int j = 0; for (Integer rowind : column) nz[i][j++] = rowind; } return nz; } /** * Populates the matrix, using the given non-zero pattern * * @param A * Matrix to populate * @param nz * Column indices on each row * @return The matrix data in dense format */ public static double[][] rowPopulate(Matrix A, int[][] nz) { int n = A.numRows(), m = A.numColumns(); double[][] values = new double[n][m]; if (m == 0) return values; for (int i = 0; i < n; ++i) for (int j = 0; j < nz[i].length; ++j) { double value = Math.random(); int k = nz[i][j]; values[i][k] = value; A.set(i, k, value); } return values; } /** * Populates the matrix, using the given non-zero pattern * * @param A * Matrix to populate * @param nz * Row indices on each column * @return The matrix data in dense format */ public static double[][] columnPopulate(Matrix A, int[][] nz) { int n = A.numRows(), m = A.numColumns(); double[][] values = new double[n][m]; if (n == 0) return values; for (int j = 0; j < m; ++j) for (int i = 0; i < nz[j].length; ++i) { double value = Math.random(); int k = nz[j][i]; values[k][j] = value; A.set(k, j, value); } return values; } /** * Populates the matrix fully * * @param A * Matrix to populate * @return The matrix data in dense format */ public static double[][] populate(Matrix A) { int n = A.numRows(), m = A.numColumns(); double[][] values = new double[n][m]; for (int i = 0; i < n; ++i) for (int j = 0; j < m; ++j) { double value = Math.random(); values[i][j] = value; A.set(i, j, value); } return values; } /** * Populates the banded matrix * * @param A * Matrix to populate * @param kl * Number of subdiagonls * @param ku * Number of superdiagonals * @return The matrix data in dense format */ public static double[][] bandPopulate(Matrix A, int kl, int ku) { int n = A.numRows(), m = A.numColumns(); double[][] values = new double[n][m]; for (int i = 0; i < n; ++i) for (int j = 0; j < m; ++j) if (j - ku <= i && i <= j + kl) { double value = Math.random(); values[i][j] = value; A.set(i, j, value); } return values; } /** * Populates the banded matrix, but not its main diagonal * * @param A * Matrix to populate * @param kl * Number of subdiagonls * @param ku * Number of superdiagonals * @return The matrix data in dense format */ public static double[][] unitBandPopulate(Matrix A, int kl, int ku) { int n = A.numRows(), m = A.numColumns(); double[][] values = new double[n][m]; for (int i = 0; i < n; ++i) for (int j = 0; j < m; ++j) if (i != j && j - ku <= i && i <= j + kl) { double value = Math.random(); values[i][j] = value; A.set(i, j, value); } return values; } /** * Populates the lower triangular part of the matrix * * @param A * Matrix to populate * @return The matrix data in dense format */ public static double[][] lowerPopulate(Matrix A) { int n = A.numRows(), m = A.numColumns(); double[][] values = new double[n][m]; for (int i = 0; i < n; ++i) for (int j = 0; j < m; ++j) if (j <= i) { double value = Math.random(); values[i][j] = value; A.set(i, j, value); } return values; } /** * Populates the upper triangular part of the matrix * * @param A * Matrix to populate * @return The matrix data in dense format */ public static double[][] upperPopulate(Matrix A) { int n = A.numRows(), m = A.numColumns(); double[][] values = new double[n][m]; for (int i = 0; i < n; ++i) for (int j = 0; j < m; ++j) if (i <= j) { double value = Math.random(); values[i][j] = value; A.set(i, j, value); } return values; } /** * Populates the strictly lower triangular part of the matrix * * @param A * Matrix to populate * @return The matrix data in dense format */ public static double[][] unitLowerPopulate(Matrix A) { int n = A.numRows(), m = A.numColumns(); double[][] values = new double[n][m]; for (int i = 0; i < n; ++i) for (int j = 0; j < m; ++j) if (j < i) { double value = Math.random(); values[i][j] = value; A.set(i, j, value); } return values; } /** * Populates the strictly upper triangular part of the matrix * * @param A * Matrix to populate * @return The matrix data in dense format */ public static double[][] unitUpperPopulate(Matrix A) { int n = A.numRows(), m = A.numColumns(); double[][] values = new double[n][m]; for (int i = 0; i < n; ++i) for (int j = 0; j < m; ++j) if (i < j) { double value = Math.random(); values[i][j] = value; A.set(i, j, value); } return values; } /** * Puts the upper triangular part into the lower triangle */ public static void lowerSymmetrice(double[][] Ad) { int n = Ad.length; for (int i = 0; i < n; ++i) for (int j = 0; j < i; ++j) Ad[j][i] = Ad[i][j]; } /** * Puts the lower triangular part into the upper triangle */ public static void upperSymmetrice(double[][] Ad) { int n = Ad.length; for (int i = 0; i < n; ++i) { int m = Ad[0].length; for (int j = i + 1; j < m; ++j) Ad[j][i] = Ad[i][j]; } } /** * Sets one on the main diagonal */ public static double[][] unitSet(double[][] Ad) { for (int i = 0; i < Ad.length; ++i) Ad[i][i] = 1; return Ad; } private final static Random r = new Random(); /** * Returns an integer between zero (inclusive) and max (exclusive) */ public static int getInt(int max) { return r.nextInt(max); } /** * Returns an integer between min (inclusive) and max (exclusive) */ public static int getInt(int min, int max) { return Math.max(min, getInt(max)); } /** * Returns true if the matrix is singular */ public static boolean singular(Matrix A) throws NotConvergedException { SVD svd = SVD.factorize(A); double[] S = svd.getS(); for (int i = 0; i < S.length; ++i) if (S[i] == 0) return true; return false; } /** * Returns true if the matrix is positive definite */ public static boolean spd(Matrix A) throws NotConvergedException { EVD evd = EVD.factorize(A); { double[] S = evd.getRealEigenvalues(); for (int i = 0; i < S.length; ++i) if (S[i] <= 0.) return false; } { double[] S = evd.getImaginaryEigenvalues(); for (int i = 0; i < S.length; ++i) if (Math.abs(S[i]) > 1e-10) return false; } return true; } /** * Populates the given vector, and returns an array containing its values */ public static double[] populate(Vector x) { double[] xd = new double[x.size()]; for (int i = 0; i < x.size(); ++i) { double alpha = Math.random(); xd[i] = alpha; x.set(i, alpha); } return xd; } /** * Populates the given vector, and returns an array containing its values. * Only m entries are inserted */ public static double[] populate(Vector x, int m) { double[] xd = new double[x.size()]; for (int i = 0; i < m; ++i) { double alpha = Math.random(); int k = (int) (Math.random() * x.size()); xd[k] = alpha; x.set(k, alpha); } return xd; } /** * Zeros the given array */ public static void zero(double[][] A) { for (int i = 0; i < A.length; ++i) Arrays.fill(A[i], 0); } /** * Adds to the diagonal of both the matrix and the array */ public static void addDiagonal(Matrix A, double[][] Ad, double shift) { int n = A.numRows(), m = A.numColumns(); for (int i = 0; i < Math.min(m, n); ++i) { A.add(i, i, shift); Ad[i][i] += shift; } } /** * Adds to the diagonal of the matrix */ public static void addDiagonal(Matrix A, double shift) { int n = A.numRows(), m = A.numColumns(); for (int i = 0; i < Math.min(m, n); ++i) A.add(i, i, shift); } } mtj-0.9.14/tests/no/uib/cipr/matrix/OrthogonalTestAbstract.java0000644000000000000000000000361511027514476023212 0ustar rootroot/* * 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 no.uib.cipr.matrix.Matrices; import no.uib.cipr.matrix.Matrix; import junit.framework.TestCase; /** * Orthogonal matrix decomposition tests */ public abstract class OrthogonalTestAbstract extends TestCase { /** * Initial work-matrix, and non-square matrices */ protected Matrix A, Ar, Ac; /** * Maximum matrix size, to avoid too slow tests */ private final int max = 100; public OrthogonalTestAbstract(String arg0) { super(arg0); } @Override protected void setUp() throws Exception { int n = Utilities.getInt(1, max); int m = Utilities.getInt(1, n); A = Matrices.random(n, n); Ar = Matrices.random(n, m); Ac = Matrices.random(m, n); } @Override protected void tearDown() throws Exception { A = Ar = Ac = null; } protected void assertEquals(Matrix A, Matrix B) { for (int i = 0; i < A.numRows(); ++i) for (int j = 0; j < A.numColumns(); ++j) assertEquals(A.get(i, j), B.get(i, j), 1e-12); } } mtj-0.9.14/tests/no/uib/cipr/matrix/SquareDenseMatrixTest.java0000644000000000000000000000247411027514324023010 0ustar rootroot/* * 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 no.uib.cipr.matrix.DenseMatrix; /** * Test of square dense matrices. This is done as some solvers change for square * matrices (LU and QR) */ public class SquareDenseMatrixTest extends MatrixTestAbstract { public SquareDenseMatrixTest(String arg0) { super(arg0); } @Override protected void createPrimary() throws Exception { int n = Utilities.getInt(1, max); A = new DenseMatrix(n, n); Ad = Utilities.populate(A); } } mtj-0.9.14/tests/no/uib/cipr/matrix/UpperSPDPackMatrixTest.java0000644000000000000000000000245611027514536023037 0ustar rootroot/* * 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 no.uib.cipr.matrix.UpperSPDPackMatrix; /** * Test of UpperSPDPackMatrix */ public class UpperSPDPackMatrixTest extends SymmetricMatrixTestAbstract { public UpperSPDPackMatrixTest(String arg0) { super(arg0); } @Override protected void createPrimary() throws Exception { int n = Utilities.getInt(1, max); A = new UpperSPDPackMatrix(n); Ad = Utilities.populate(A); Utilities.upperSymmetrice(Ad); } } mtj-0.9.14/tests/no/uib/cipr/matrix/UpperSPDBandMatrixTest.java0000644000000000000000000000261211027514432023012 0ustar rootroot/* * 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 no.uib.cipr.matrix.UpperSPDBandMatrix; /** * Test of UpperSPDBandMatrix */ public class UpperSPDBandMatrixTest extends StructImmutableMatrixTestAbstract { public UpperSPDBandMatrixTest(String arg0) { super(arg0); } @Override protected void createPrimary() throws Exception { int n = Utilities.getInt(1, max); int kd = Math.min(Utilities.getInt(max), Math.max(n - 1, 0)); A = new UpperSPDBandMatrix(n, kd); Ad = Utilities.bandPopulate(A, kd, kd); Utilities.upperSymmetrice(Ad); } } mtj-0.9.14/tests/no/uib/cipr/matrix/SymmBandEigenvalueTest.java0000644000000000000000000000633111027514520023115 0ustar rootroot/* * 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 no.uib.cipr.matrix.LowerSymmBandMatrix; import no.uib.cipr.matrix.NotConvergedException; import no.uib.cipr.matrix.SymmBandEVD; import no.uib.cipr.matrix.UpperSymmBandMatrix; /** * Test of the symmetric, tridiagonal eigenvalue solver */ public class SymmBandEigenvalueTest extends SymmEigenvalueTestAbstract { private LowerSymmBandMatrix L; private UpperSymmBandMatrix U; public SymmBandEigenvalueTest(String arg0) { super(arg0); } @Override protected void setUp() throws Exception { super.setUp(); int kd = Utilities.getInt(1, A.numRows()); L = new LowerSymmBandMatrix(A, kd); U = new UpperSymmBandMatrix(A, kd); } @Override protected void tearDown() throws Exception { super.tearDown(); L = null; U = null; } public void testLowerStaticFactorize() throws NotConvergedException { SymmBandEVD evd = SymmBandEVD.factorize(L, L.numSubDiagonals()); assertEquals(L, evd.getEigenvalues(), evd.getEigenvectors()); } public void testUpperStaticFactorize() throws NotConvergedException { SymmBandEVD evd = SymmBandEVD.factorize(U, U.numSuperDiagonals()); assertEquals(U, evd.getEigenvalues(), evd.getEigenvectors()); } public void testLowerFactor() throws NotConvergedException { SymmBandEVD evd = new SymmBandEVD(A.numRows(), false); evd.factor(L.copy()); assertEquals(L, evd.getEigenvalues(), evd.getEigenvectors()); } public void testUpperFactor() throws NotConvergedException { SymmBandEVD evd = new SymmBandEVD(A.numRows(), true); evd.factor(U.copy()); assertEquals(U, evd.getEigenvalues(), evd.getEigenvectors()); } public void testLowerRepeatFactor() throws NotConvergedException { SymmBandEVD evd = new SymmBandEVD(A.numRows(), false); evd.factor(L.copy()); assertEquals(L, evd.getEigenvalues(), evd.getEigenvectors()); evd.factor(L.copy()); assertEquals(L, evd.getEigenvalues(), evd.getEigenvectors()); } public void testUpperRepeatFactor() throws NotConvergedException { SymmBandEVD evd = new SymmBandEVD(A.numRows(), true); evd.factor(U.copy()); assertEquals(U, evd.getEigenvalues(), evd.getEigenvectors()); evd.factor(U.copy()); assertEquals(U, evd.getEigenvalues(), evd.getEigenvectors()); } } mtj-0.9.14/tests/no/uib/cipr/matrix/TridiagMatrixTest.java0000644000000000000000000000266311027514432022154 0ustar rootroot/* * 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 no.uib.cipr.matrix.TridiagMatrix; /** * Test of tridiagonal matrices */ public class TridiagMatrixTest extends StructImmutableMatrixTestAbstract { public TridiagMatrixTest(String arg0) { super(arg0); } @Override protected void createPrimary() throws Exception { int n = Utilities.getInt(1, max); A = new TridiagMatrix(n); Ad = Utilities.bandPopulate(A, 1, 1); } @Override public void testTransMatrixSolve() { // Not supported } @Override public void testTransVectorSolve() { // Not supported } } mtj-0.9.14/tests/no/uib/cipr/matrix/BandCholeskyTest.java0000644000000000000000000000676311027516254021763 0ustar rootroot/* * 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 junit.framework.TestCase; import no.uib.cipr.matrix.BandCholesky; import no.uib.cipr.matrix.DenseMatrix; import no.uib.cipr.matrix.LowerSPDBandMatrix; import no.uib.cipr.matrix.Matrices; import no.uib.cipr.matrix.Matrix; import no.uib.cipr.matrix.UpperSPDBandMatrix; /** * Tests the banded Cholesky decomposition */ public class BandCholeskyTest extends TestCase { private LowerSPDBandMatrix L; private UpperSPDBandMatrix U; private DenseMatrix I; private int kl, ku; private final int max = 100, bmax = 10; public BandCholeskyTest(String arg0) { super(arg0); } @Override protected void setUp() throws Exception { int n = Utilities.getInt(1, max); kl = Math.min(n, Utilities.getInt(bmax)); ku = Math.min(n, Utilities.getInt(bmax)); L = new LowerSPDBandMatrix(n, kl); Utilities.bandPopulate(L, kl, 0); Utilities.addDiagonal(L, 1); while (!Utilities.spd(L)) Utilities.addDiagonal(L, 1); U = new UpperSPDBandMatrix(n, ku); Utilities.bandPopulate(U, 0, ku); Utilities.addDiagonal(U, 1); while (!Utilities.spd(U)) Utilities.addDiagonal(U, 1); I = Matrices.identity(n); } @Override protected void tearDown() throws Exception { L = null; U = null; I = null; } public void testLowerBandCholesky() { int n = L.numRows(); BandCholesky c = new BandCholesky(n, kl, false); c.factor(L.copy()); c.solve(I); Matrix J = I.mult(L, new DenseMatrix(n, n)); for (int i = 0; i < n; ++i) for (int j = 0; j < n; ++j) if (i != j) assertEquals(J.get(i, j), 0, 1e-10); else assertEquals(J.get(i, j), 1, 1e-10); } public void testUpperBandCholesky() { int n = U.numRows(); BandCholesky c = new BandCholesky(n, ku, true); c.factor(U.copy()); c.solve(I); Matrix J = I.mult(U, new DenseMatrix(n, n)); for (int i = 0; i < n; ++i) for (int j = 0; j < n; ++j) if (i != j) assertEquals(J.get(i, j), 0, 1e-10); else assertEquals(J.get(i, j), 1, 1e-10); } public void testLowerBandCholeskyrcond() { int n = L.numRows(); BandCholesky c = new BandCholesky(n, kl, false); c.factor(L.copy()); c.rcond(L); } public void testUpperBandCholeskyrcond() { int n = U.numRows(); BandCholesky c = new BandCholesky(n, ku, true); c.factor(U.copy()); c.rcond(U); } } mtj-0.9.14/tests/no/uib/cipr/matrix/LowerSPDBandMatrixTest.java0000644000000000000000000000261211027514432023007 0ustar rootroot/* * 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 no.uib.cipr.matrix.LowerSPDBandMatrix; /** * Test of LowerSPDBandMatrix */ public class LowerSPDBandMatrixTest extends StructImmutableMatrixTestAbstract { public LowerSPDBandMatrixTest(String arg0) { super(arg0); } @Override protected void createPrimary() throws Exception { int n = Utilities.getInt(1, max); int kd = Math.min(Utilities.getInt(max), Math.max(n - 1, 0)); A = new LowerSPDBandMatrix(n, kd); Ad = Utilities.bandPopulate(A, kd, kd); Utilities.lowerSymmetrice(Ad); } } mtj-0.9.14/tests/no/uib/cipr/matrix/DenseVectorTest.java0000644000000000000000000000233311027514630021617 0ustar rootroot/* * 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 no.uib.cipr.matrix.DenseVector; /** * Test of DenseVector */ public class DenseVectorTest extends VectorTestAbstract { public DenseVectorTest(String arg0) { super(arg0); } @Override protected void createPrimary() throws Exception { int n = Utilities.getInt(1, max); x = new DenseVector(n); xd = Utilities.populate(x); } } mtj-0.9.14/tests/no/uib/cipr/matrix/SymmPackEigenvalueTest.java0000644000000000000000000000615411027514520023132 0ustar rootroot/* * 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 no.uib.cipr.matrix.LowerSymmPackMatrix; import no.uib.cipr.matrix.NotConvergedException; import no.uib.cipr.matrix.SymmPackEVD; import no.uib.cipr.matrix.UpperSymmPackMatrix; /** * Test of the symmetric, dense eigenvalue solver */ public class SymmPackEigenvalueTest extends SymmEigenvalueTestAbstract { private LowerSymmPackMatrix L; private UpperSymmPackMatrix U; public SymmPackEigenvalueTest(String arg0) { super(arg0); } @Override protected void setUp() throws Exception { super.setUp(); L = new LowerSymmPackMatrix(A); U = new UpperSymmPackMatrix(A); } @Override protected void tearDown() throws Exception { super.tearDown(); L = null; U = null; } public void testLowerStaticFactorize() throws NotConvergedException { SymmPackEVD evd = SymmPackEVD.factorize(L); assertEquals(L, evd.getEigenvalues(), evd.getEigenvectors()); } public void testUpperStaticFactorize() throws NotConvergedException { SymmPackEVD evd = SymmPackEVD.factorize(U); assertEquals(U, evd.getEigenvalues(), evd.getEigenvectors()); } public void testLowerFactor() throws NotConvergedException { SymmPackEVD evd = new SymmPackEVD(A.numRows(), false); evd.factor(L.copy()); assertEquals(L, evd.getEigenvalues(), evd.getEigenvectors()); } public void testUpperFactor() throws NotConvergedException { SymmPackEVD evd = new SymmPackEVD(A.numRows(), true); evd.factor(U.copy()); assertEquals(U, evd.getEigenvalues(), evd.getEigenvectors()); } public void testLowerRepeatFactor() throws NotConvergedException { SymmPackEVD evd = new SymmPackEVD(A.numRows(), false); evd.factor(L.copy()); assertEquals(L, evd.getEigenvalues(), evd.getEigenvectors()); evd.factor(L.copy()); assertEquals(L, evd.getEigenvalues(), evd.getEigenvectors()); } public void testUpperRepeatFactor() throws NotConvergedException { SymmPackEVD evd = new SymmPackEVD(A.numRows(), true); evd.factor(U.copy()); assertEquals(U, evd.getEigenvalues(), evd.getEigenvectors()); evd.factor(U.copy()); assertEquals(U, evd.getEigenvalues(), evd.getEigenvectors()); } } mtj-0.9.14/tests/no/uib/cipr/matrix/SPDTridiagMatrixTest.java0000644000000000000000000000252711027514432022522 0ustar rootroot/* * 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 no.uib.cipr.matrix.SPDTridiagMatrix; /** * Test of symmetrical, positive definite tridiagonal matrices */ public class SPDTridiagMatrixTest extends StructImmutableMatrixTestAbstract { public SPDTridiagMatrixTest(String arg0) { super(arg0); } @Override protected void createPrimary() throws Exception { int n = Utilities.getInt(1, max); A = new SPDTridiagMatrix(n); Ad = Utilities.bandPopulate(A, 1, 1); Utilities.lowerSymmetrice(Ad); } } mtj-0.9.14/tests/no/uib/cipr/matrix/UpperTriangBandMatrixTest.java0000644000000000000000000000267211027514550023617 0ustar rootroot/* * 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 no.uib.cipr.matrix.UpperTriangBandMatrix; /** * Test of UpperTriangBandMatrix */ public class UpperTriangBandMatrixTest extends TriangMatrixTestAbstract { public UpperTriangBandMatrixTest(String arg0) { super(arg0); } @Override protected void createPrimary() throws Exception { int n = Utilities.getInt(1, max); int kd = Math.min(Utilities.getInt(max), Math.max(n - 1, 0)); A = new UpperTriangBandMatrix(n, kd); Ad = Utilities.bandPopulate(A, 0, kd); // This ensures non-singularity Utilities.addDiagonal(A, Ad, 1); } } mtj-0.9.14/tests/no/uib/cipr/matrix/SymmEigenvalueTestAbstract.java0000644000000000000000000000421611027514520024014 0ustar rootroot/* * 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 no.uib.cipr.matrix.DenseMatrix; import no.uib.cipr.matrix.Matrices; import no.uib.cipr.matrix.Matrix; import junit.framework.TestCase; /** * Tests the symmetric eigenvalue computers */ public abstract class SymmEigenvalueTestAbstract extends TestCase { /** * Initial work-matrix */ protected Matrix A; /** * Maximum matrix size, to avoid too slow tests */ private final int max = 100; public SymmEigenvalueTestAbstract(String arg0) { super(arg0); } @Override protected void setUp() throws Exception { int n = Utilities.getInt(max); A = Matrices.random(n, n); } @Override protected void tearDown() throws Exception { A = null; } protected void assertEquals(Matrix A, double[] w, DenseMatrix Z) { // A*X Matrix left = A.mult(Z, new DenseMatrix(A.numRows(), A.numColumns())); // lambda*X Matrix right = new DenseMatrix(Z); for (int i = 0; i < w.length; ++i) for (int j = 0; j < w.length; ++j) right.set(i, j, w[j] * right.get(i, j)); // Check that A*X=lambda*X for (int i = 0; i < A.numRows(); ++i) for (int j = 0; j < A.numColumns(); ++j) assertEquals(left.get(i, j), right.get(i, j), 1e-12); } } mtj-0.9.14/tests/no/uib/cipr/matrix/VectorTestAbstract.java0000644000000000000000000001616411027514630022333 0ustar rootroot/* * 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 junit.framework.TestCase; import no.uib.cipr.matrix.Vector.Norm; /** * Test of vectors */ public abstract class VectorTestAbstract extends TestCase { /** * Max vector size */ protected int max = 100; /** * Vector to test */ protected Vector x; /** * Data of the vector */ protected double[] xd; /** * Vectors of the same size as x, dense and non-dense */ protected Vector y, yDense, z, zDense; /** * Data of those vectors */ protected double[] yd, zd; /** * Tolerance for floating-point comparisons */ protected double tol = 1e-5; public VectorTestAbstract(String arg0) { super(arg0); } @Override protected void setUp() throws Exception { createPrimary(); createAuxillerary(); } protected abstract void createPrimary() throws Exception; protected void createAuxillerary() throws Exception { yDense = Matrices.random(x.size()); y = Matrices.synchronizedVector(yDense); zDense = Matrices.random(x.size()); z = Matrices.synchronizedVector(zDense); yd = Matrices.getArray(y); zd = Matrices.getArray(z); } @Override protected void tearDown() throws Exception { x = null; xd = null; } public void testSize() { assertEquals(xd.length, x.size()); } public void testCopy() { Vector y = x.copy(); assertEquals(xd, y); y.scale(Math.random()); assertEquals(xd, x); } public void testZero() { assertEquals(scale(0), x.zero()); } public void testScale() { double alpha = Math.random(); assertEquals(scale(alpha), x.scale(alpha)); } public void testScaleZero() { assertEquals(scale(0), x.scale(0)); } public void testScaleOne() { assertEquals(scale(1), x.scale(1)); } protected double[] scale(double alpha) { for (int i = 0; i < xd.length; ++i) xd[i] *= alpha; return xd; } /* * Test for Vector set(Vector) */ public void testSetVectorDense() { assertEquals(set(1, yd, 0, zd), x.set(yDense)); } /* * Test for Vector set(double, Vector) */ public void testSetdoubleVectorDense() { double alpha = Math.random(); assertEquals(set(alpha, yd, 0, zd), x.set(alpha, yDense)); } /* * Test for Vector set(Vector) */ public void testSetVector() { assertEquals(set(1, yd, 0, zd), x.set(y)); } /* * Test for Vector set(double, Vector) */ public void testSetDoubleVector() { double alpha = Math.random(); assertEquals(set(alpha, yd, 0, zd), x.set(alpha, y)); } protected double[] set(double alpha, double[] yd, double beta, double[] zd) { for (int i = 0; i < xd.length; ++i) xd[i] = alpha * yd[i] + beta * zd[i]; return xd; } /* * Test for Vector add(double, Vector) */ public void testAddDoubleVectorDense() { double alpha = Math.random(); assertEquals(add(alpha, yd), x.add(alpha, yDense)); } /* * Test for Vector add(Vector) */ public void testAddVectorDense() { assertEquals(add(1, yd), x.add(yDense)); } /* * Test for Vector add(double, Vector) */ public void testAddDoubleVector() { double alpha = Math.random(); assertEquals(add(alpha, yd), x.add(alpha, y)); } /* * Test for Vector add(Vector) */ public void testAddVector() { assertEquals(add(1, yd), x.add(y)); } protected double[] add(double alpha, double[] yd) { for (int i = 0; i < xd.length; ++i) xd[i] += alpha * yd[i]; return xd; } public void testDotDense() { assertEquals(dot(yd), x.dot(yDense), tol); assertEquals(xd, x); assertEquals(yd, yDense); } public void testDot() { assertEquals(dot(yd), x.dot(y), tol); assertEquals(xd, x); assertEquals(yd, y); } protected double dot(double[] yd) { double dot = 0; for (int i = 0; i < yd.length; ++i) dot += xd[i] * yd[i]; return dot; } public void testCardinality() { assertEquals(cardinality(), Matrices.cardinality(x)); } protected int cardinality() { int nz = 0; for (double d : xd) if (d != 0) nz++; return nz; } public void testNorm1() { assertEquals(norm1(), x.norm(Norm.One), tol); } public void testNorm2() { assertEquals(norm2(), x.norm(Norm.Two), tol); } public void testNormInf() { assertEquals(normInf(), x.norm(Norm.Infinity), tol); } protected double norm1() { double norm = 0; for (double d : xd) norm += Math.abs(d); return norm; } protected double norm2() { double norm = 0; for (double d : xd) norm += d * d; return Math.sqrt(norm); } protected double normInf() { double norm = 0; for (double d : xd) norm = Math.max(Math.abs(d), norm); return norm; } public void testIteratorSetGet() { double alpha = Math.random(); double[] data = new double[x.size()]; for (VectorEntry e : x) { data[e.index()] = e.get(); e.set(alpha * e.get()); e.set(e.get() / alpha); } assertEquals(xd, x); assertEquals(xd, data); } public void testIteratorGet() { double[] data = new double[x.size()]; for (VectorEntry e : x) data[e.index()] = e.get(); assertEquals(xd, x); assertEquals(xd, data); } public void testIteratorSet() { double alpha = Math.random(); for (VectorEntry e : x) e.set(alpha * e.get()); assertEquals(scale(alpha), x); } protected void assertEquals(double[] xd, Vector x) { assertEquals(xd.length, x.size()); for (int i = 0; i < xd.length; ++i) assertEquals(xd[i], x.get(i), tol); } protected void assertEquals(double[] xd, double[] yd) { for (int i = 0; i < xd.length; ++i) assertEquals(xd[i], yd[i], tol); } } mtj-0.9.14/tests/no/uib/cipr/matrix/QRTest.java0000644000000000000000000000466511027514476017742 0ustar rootroot/* * 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 no.uib.cipr.matrix.DenseMatrix; import no.uib.cipr.matrix.Matrix; import no.uib.cipr.matrix.QR; /** * QR test */ public class QRTest extends OrthogonalTestAbstract { public QRTest(String arg0) { super(arg0); } public void testStaticFactorize() { assertEquals(A, QR.factorize(A)); } public void testRepeatStaticFactorize() { assertEquals(A, QR.factorize(A)); assertEquals(A, QR.factorize(A)); } public void testFactor() { QR qr = new QR(A.numRows(), A.numColumns()); assertEquals(A, qr.factor(new DenseMatrix(A))); } public void testRepeatFactor() { QR qr = new QR(A.numRows(), A.numColumns()); qr.factor(new DenseMatrix(A)); assertEquals(A, qr); qr.factor(new DenseMatrix(A)); assertEquals(A, qr); } public void testStaticFactorizeNonSquare() { assertEquals(Ar, QR.factorize(Ar)); } public void testRepeatStaticFactorizeNonSquare() { assertEquals(Ar, QR.factorize(Ar)); assertEquals(Ar, QR.factorize(Ar)); } public void testFactorNonSquare() { QR qr = new QR(Ar.numRows(), Ar.numColumns()); assertEquals(Ar, qr.factor(new DenseMatrix(Ar))); } public void testRepeatFactorNonSquare() { QR qr = new QR(Ar.numRows(), Ar.numColumns()); qr.factor(new DenseMatrix(Ar)); assertEquals(Ar, qr); qr.factor(new DenseMatrix(Ar)); assertEquals(Ar, qr); } private void assertEquals(Matrix A, QR qr) { assertEquals(A, qr.getQ().mult(qr.getR(), A.copy().zero())); } } mtj-0.9.14/tests/no/uib/cipr/matrix/distributed/0000755000000000000000000000000011034476206020220 5ustar rootrootmtj-0.9.14/tests/no/uib/cipr/matrix/distributed/PointToPointTest.java0000644000000000000000000001066011467312526024340 0ustar rootrootpackage no.uib.cipr.matrix.distributed; import java.util.Random; import junit.framework.TestCase; import no.uib.cipr.matrix.distributed.CollectiveCommunications; import no.uib.cipr.matrix.distributed.Communicator; /** * Tests point-to-point communications of seven basic types * * @deprecated the no.uib.cipr.matrix.distributed package has been deprecated because * of a number of hard to fix concurrency bugs. It is distributed only for backwards compatibility, * but is not recommended. The utility of this package is questionable, as it does not allow * distribution of computation between JVMs or across a network. For many people, distributed * computing of multiple matrices can be achieved at a user-level through the * JPPF Framework. * Users who need to deal with few very large matrices may wish to implement their own storage classes * and solvers using JPPF, but this will not be supported directly in matrix-toolkits-java. */ @Deprecated public class PointToPointTest extends TestCase { CollectiveCommunications coll; byte[] bsend, brecv; char[] csend, crecv; short[] ssend, srecv; int[] isend, irecv; long[] lsend, lrecv; float[] fsend, frecv; double[] dsend, drecv; int length; @Override protected void setUp() throws Exception { coll = new CollectiveCommunications(2); Random r = new Random(); length = r.nextInt(100); bsend = new byte[length]; brecv = new byte[length]; csend = new char[length]; crecv = new char[length]; ssend = new short[length]; srecv = new short[length]; isend = new int[length]; irecv = new int[length]; lsend = new long[length]; lrecv = new long[length]; fsend = new float[length]; frecv = new float[length]; dsend = new double[length]; drecv = new double[length]; for (int i = 0; i < length; ++i) { dsend[i] = r.nextDouble(); fsend[i] = r.nextFloat(); lsend[i] = r.nextLong(); isend[i] = r.nextInt(); ssend[i] = (short) r.nextInt(); csend[i] = (char) r.nextInt(); bsend[i] = (byte) r.nextInt(); } } public void testByteSendRecv() throws Exception { runSendRecv(bsend, brecv); for (int i = 0; i < length; ++i) assertEquals(bsend[i], brecv[i]); } public void testCharSendRecv() throws Exception { runSendRecv(csend, crecv); for (int i = 0; i < length; ++i) assertEquals(csend[i], crecv[i]); } public void testShortSendRecv() throws Exception { runSendRecv(ssend, srecv); for (int i = 0; i < length; ++i) assertEquals(ssend[i], srecv[i]); } public void testIntSendRecv() throws Exception { runSendRecv(isend, irecv); for (int i = 0; i < length; ++i) assertEquals(isend[i], irecv[i]); } public void testLongSendRecv() throws Exception { runSendRecv(lsend, lrecv); for (int i = 0; i < length; ++i) assertEquals(lsend[i], lrecv[i]); } public void testFloatSendRecv() throws Exception { runSendRecv(fsend, frecv); for (int i = 0; i < length; ++i) assertEquals(fsend[i], frecv[i], 1e-10); } public void testDoubleSendRecv() throws Exception { runSendRecv(dsend, drecv); for (int i = 0; i < length; ++i) assertEquals(dsend[i], drecv[i], 1e-10); } private void runSendRecv(Object send, Object recv) throws InterruptedException { Thread sender = createSender(send, 0, 1); Thread receiver = createReceiver(recv, 1, 0); sender.start(); receiver.start(); sender.join(); receiver.join(); } private Thread createSender(final Object send, final int rank, final int peer) { return new Thread(new Runnable() { public void run() { Communicator c = coll.createCommunicator(rank); c.send(send, peer); } }); } private Thread createReceiver(final Object recv, final int rank, final int peer) { return new Thread(new Runnable() { public void run() { Communicator c = coll.createCommunicator(rank); c.recv(recv, peer); } }); } } mtj-0.9.14/tests/no/uib/cipr/matrix/distributed/DistIterativeSolverTest.java0000644000000000000000000004061011467312514025700 0ustar rootrootpackage no.uib.cipr.matrix.distributed; import java.util.Arrays; import java.util.concurrent.Executor; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import junit.framework.TestCase; import no.uib.cipr.matrix.DenseMatrix; import no.uib.cipr.matrix.DenseVector; import no.uib.cipr.matrix.Matrix; import no.uib.cipr.matrix.UpperSymmDenseMatrix; import no.uib.cipr.matrix.Vector; import no.uib.cipr.matrix.distributed.CollectiveCommunications; import no.uib.cipr.matrix.distributed.Communicator; import no.uib.cipr.matrix.distributed.DistColMatrix; import no.uib.cipr.matrix.distributed.DistRowMatrix; import no.uib.cipr.matrix.distributed.DistVector; import no.uib.cipr.matrix.sparse.BiCGstab; import no.uib.cipr.matrix.sparse.CG; import no.uib.cipr.matrix.sparse.DefaultIterationMonitor; import no.uib.cipr.matrix.sparse.GMRES; import no.uib.cipr.matrix.sparse.IterationMonitor; import no.uib.cipr.matrix.sparse.IterativeSolver; import no.uib.cipr.matrix.sparse.IterativeSolverNotConvergedException; import no.uib.cipr.matrix.Utilities; /** * @deprecated the no.uib.cipr.matrix.distributed package has been deprecated because * of a number of hard to fix concurrency bugs. It is distributed only for backwards compatibility, * but is not recommended. The utility of this package is questionable, as it does not allow * distribution of computation between JVMs or across a network. For many people, distributed * computing of multiple matrices can be achieved at a user-level through the * JPPF Framework. * Users who need to deal with few very large matrices may wish to implement their own storage classes * and solvers using JPPF, but this will not be supported directly in matrix-toolkits-java. */ @Deprecated public class DistIterativeSolverTest extends TestCase { volatile CollectiveCommunications coll; volatile DenseMatrix A_unsymm; volatile UpperSymmDenseMatrix A_symm; volatile DenseVector x, b_unsymm, b_symm; /** * Partitioning */ volatile int[] localLength; volatile double[] output; @Override protected void setUp() throws Exception { int size = Utilities.getInt(1, 8); coll = new CollectiveCommunications(size); int n = Utilities.getInt(size, 250); A_unsymm = new DenseMatrix(n, n); A_symm = new UpperSymmDenseMatrix(n); Utilities.populate(A_unsymm); Utilities.upperPopulate(A_unsymm); double shift = 10; do { Utilities.addDiagonal(A_unsymm, shift); } while (Utilities.singular(A_unsymm)); do { Utilities.addDiagonal(A_symm, shift); } while (!Utilities.spd(A_symm)); x = new DenseVector(n); b_unsymm = x.copy(); b_symm = x.copy(); Utilities.populate(x); A_unsymm.mult(x, b_unsymm); A_symm.mult(x, b_symm); output = new double[n]; // Set local lengths localLength = new int[size]; Arrays.fill(localLength, n / size); // Adjust the last length to ensure the whole vector is covered int sum = n; for (int l : localLength) sum -= l; localLength[size - 1] += sum; } public void testRowGMRES_1() throws InterruptedException { Thread[] t = new Thread[coll.size()]; for (int i = 0; i < t.length; ++i) t[i] = new Thread(new GMRESRowDistIterativeSolver(i, Vector.Norm.One)); compare(t); } public void testRowGMRES_2() throws InterruptedException { Thread[] t = new Thread[coll.size()]; for (int i = 0; i < t.length; ++i) t[i] = new Thread(new GMRESRowDistIterativeSolver(i, Vector.Norm.Two)); compare(t); } public void testRowGMRES_inf() throws InterruptedException { Thread[] t = new Thread[coll.size()]; for (int i = 0; i < t.length; ++i) t[i] = new Thread(new GMRESRowDistIterativeSolver(i, Vector.Norm.Infinity)); compare(t); } public void testRowBiCGstab_1() throws InterruptedException { Thread[] t = new Thread[coll.size()]; for (int i = 0; i < t.length; ++i) t[i] = new Thread(new BiCGstabRowDistIterativeSolver(i, Vector.Norm.One)); compare(t); } public void testRowBiCGstab_2() throws InterruptedException { Thread[] t = new Thread[coll.size()]; for (int i = 0; i < t.length; ++i) t[i] = new Thread(new BiCGstabRowDistIterativeSolver(i, Vector.Norm.Two)); compare(t); } public void testRowBiCGstab_inf() throws InterruptedException { Thread[] t = new Thread[coll.size()]; for (int i = 0; i < t.length; ++i) t[i] = new Thread(new BiCGstabRowDistIterativeSolver(i, Vector.Norm.Infinity)); compare(t); } public void testColumnGMRES_1() throws InterruptedException { Thread[] t = new Thread[coll.size()]; for (int i = 0; i < t.length; ++i) t[i] = new Thread(new GMRESColumnDistIterativeSolver(i, Vector.Norm.One)); compare(t); } public void testColumnGMRES_2() throws InterruptedException { Thread[] t = new Thread[coll.size()]; for (int i = 0; i < t.length; ++i) t[i] = new Thread(new GMRESColumnDistIterativeSolver(i, Vector.Norm.Two)); compare(t); } public void testColumnGMRES_inf() throws InterruptedException { Thread[] t = new Thread[coll.size()]; for (int i = 0; i < t.length; ++i) t[i] = new Thread(new GMRESColumnDistIterativeSolver(i, Vector.Norm.Infinity)); compare(t); } public void testColumnBiCGstab_1() throws InterruptedException { Thread[] t = new Thread[coll.size()]; for (int i = 0; i < t.length; ++i) t[i] = new Thread(new BiCGstabColumnDistIterativeSolver(i, Vector.Norm.One)); compare(t); } public void testColumnBiCGstab_2() throws InterruptedException { Thread[] t = new Thread[coll.size()]; for (int i = 0; i < t.length; ++i) t[i] = new Thread(new BiCGstabColumnDistIterativeSolver(i, Vector.Norm.Two)); compare(t); } public void testColumnBiCGstab_inf() throws InterruptedException { Thread[] t = new Thread[coll.size()]; for (int i = 0; i < t.length; ++i) t[i] = new Thread(new BiCGstabColumnDistIterativeSolver(i, Vector.Norm.Infinity)); compare(t); } public void testRowCG_1() throws InterruptedException { Thread[] t = new Thread[coll.size()]; for (int i = 0; i < t.length; ++i) t[i] = new Thread(new CGRowDistIterativeSolver(i, Vector.Norm.One)); compare(t); } public void testRowCG_2() throws InterruptedException { Thread[] t = new Thread[coll.size()]; for (int i = 0; i < t.length; ++i) t[i] = new Thread(new CGRowDistIterativeSolver(i, Vector.Norm.Two)); compare(t); } public void testRowCG_inf() throws InterruptedException { Thread[] t = new Thread[coll.size()]; for (int i = 0; i < t.length; ++i) t[i] = new Thread(new CGRowDistIterativeSolver(i, Vector.Norm.Infinity)); compare(t); } public void testColumnCG_1() throws InterruptedException { Thread[] t = new Thread[coll.size()]; for (int i = 0; i < t.length; ++i) t[i] = new Thread(new CGColumnDistIterativeSolver(i, Vector.Norm.One)); compare(t); } public void testColumnCG_2() throws InterruptedException { Thread[] t = new Thread[coll.size()]; for (int i = 0; i < t.length; ++i) t[i] = new Thread(new CGColumnDistIterativeSolver(i, Vector.Norm.Two)); compare(t); } public void testColumnCG_inf() throws InterruptedException { Thread[] t = new Thread[coll.size()]; for (int i = 0; i < t.length; ++i) t[i] = new Thread(new CGColumnDistIterativeSolver(i, Vector.Norm.Infinity)); compare(t); } private void compare(Thread[] t) throws InterruptedException { ExecutorService pool = Executors.newFixedThreadPool(t.length); for (Thread ti : t) pool.execute(ti); pool.shutdown(); pool.awaitTermination(20, TimeUnit.SECONDS); for (int i = 0; i < x.size(); ++i) assertEquals(x.get(i), output[i], 1e-10); } private abstract class DistIterativeSolver implements Runnable { final protected int rank; final protected Vector.Norm norm; public DistIterativeSolver(int rank, Vector.Norm norm) { this.rank = rank; this.norm = norm; } protected abstract Matrix createMatrix(Communicator comm); protected abstract int[] getRowOwnerships(Matrix A); protected abstract int[] getColumnOwnerships(Matrix A); protected abstract void populateMatrix(Matrix A); protected abstract double getVectorEntry(int i); protected abstract IterativeSolver createSolver(Vector x); public void run() { Communicator comm = coll.createCommunicator(rank); Matrix A = createMatrix(comm); populateMatrix(A); DenseVector bl = new DenseVector(localLength[rank]); DistVector b_dist = new DistVector(x.size(), comm, bl); DistVector x_dist = b_dist.copy(); int[] n = getRowOwnerships(A); for (int i = n[rank]; i < n[rank + 1]; ++i) b_dist.set(i, getVectorEntry(i)); IterativeSolver solver = createSolver(b_dist); IterationMonitor monitor = new DefaultIterationMonitor(1000, 1e-50, 1e-12, 1e+5); monitor.setNormType(norm); solver.setIterationMonitor(monitor); try { solver.solve(A, b_dist, x_dist); } catch (IterativeSolverNotConvergedException e) { // This will just lead to an error later on } for (int i = n[rank]; i < n[rank + 1]; ++i) output[i] = x_dist.get(i); } } private abstract class RowDistIterativeSolver extends DistIterativeSolver { public RowDistIterativeSolver(int rank, Vector.Norm norm) { super(rank, norm); } @Override protected Matrix createMatrix(Communicator comm) { int n = x.size(); Matrix Al = new DenseMatrix(localLength[rank], localLength[rank]); Matrix Bl = new DenseMatrix(localLength[rank], n); return new DistRowMatrix(n, n, comm, Al, Bl); } @Override protected int[] getColumnOwnerships(Matrix A) { return ((DistRowMatrix) A).getColumnOwnerships(); } @Override protected int[] getRowOwnerships(Matrix A) { return ((DistRowMatrix) A).getRowOwnerships(); } } private abstract class ColumnDistIterativeSolver extends DistIterativeSolver { public ColumnDistIterativeSolver(int rank, Vector.Norm norm) { super(rank, norm); } @Override protected Matrix createMatrix(Communicator comm) { int n = x.size(); Matrix Al = new DenseMatrix(localLength[rank], localLength[rank]); Matrix Bl = new DenseMatrix(n, localLength[rank]); return new DistColMatrix(n, n, comm, Al, Bl); } @Override protected int[] getColumnOwnerships(Matrix A) { return ((DistColMatrix) A).getColumnOwnerships(); } @Override protected int[] getRowOwnerships(Matrix A) { return ((DistColMatrix) A).getRowOwnerships(); } } private abstract class SymmRowDistIterativeSolver extends RowDistIterativeSolver { public SymmRowDistIterativeSolver(int rank, Vector.Norm norm) { super(rank, norm); } @Override protected void populateMatrix(Matrix A) { int[] n = getRowOwnerships(A); for (int i = n[rank]; i < n[rank + 1]; ++i) for (int j = 0; j < A.numColumns(); ++j) A.set(i, j, A_symm.get(i, j)); } @Override protected double getVectorEntry(int i) { return b_symm.get(i); } } private abstract class UnSymmRowDistIterativeSolver extends RowDistIterativeSolver { public UnSymmRowDistIterativeSolver(int rank, Vector.Norm norm) { super(rank, norm); } @Override protected void populateMatrix(Matrix A) { int[] n = getRowOwnerships(A); for (int i = n[rank]; i < n[rank + 1]; ++i) for (int j = 0; j < A.numColumns(); ++j) A.set(i, j, A_unsymm.get(i, j)); } @Override protected double getVectorEntry(int i) { return b_unsymm.get(i); } } private abstract class SymmColumnDistIterativeSolver extends ColumnDistIterativeSolver { public SymmColumnDistIterativeSolver(int rank, Vector.Norm norm) { super(rank, norm); } @Override protected void populateMatrix(Matrix A) { int[] m = getColumnOwnerships(A); for (int i = 0; i < A.numRows(); ++i) for (int j = m[rank]; j < m[rank + 1]; ++j) A.set(i, j, A_symm.get(i, j)); } @Override protected double getVectorEntry(int i) { return b_symm.get(i); } } private abstract class UnSymmColumnDistIterativeSolver extends ColumnDistIterativeSolver { public UnSymmColumnDistIterativeSolver(int rank, Vector.Norm norm) { super(rank, norm); } @Override protected void populateMatrix(Matrix A) { int[] m = getColumnOwnerships(A); for (int i = 0; i < A.numRows(); ++i) for (int j = m[rank]; j < m[rank + 1]; ++j) A.set(i, j, A_unsymm.get(i, j)); } @Override protected double getVectorEntry(int i) { return b_unsymm.get(i); } } private class GMRESRowDistIterativeSolver extends UnSymmRowDistIterativeSolver { public GMRESRowDistIterativeSolver(int rank, Vector.Norm norm) { super(rank, norm); } @Override protected IterativeSolver createSolver(Vector x) { return new GMRES(x); } } private class BiCGstabRowDistIterativeSolver extends UnSymmRowDistIterativeSolver { public BiCGstabRowDistIterativeSolver(int rank, Vector.Norm norm) { super(rank, norm); } @Override protected IterativeSolver createSolver(Vector x) { return new BiCGstab(x); } } private class GMRESColumnDistIterativeSolver extends UnSymmColumnDistIterativeSolver { public GMRESColumnDistIterativeSolver(int rank, Vector.Norm norm) { super(rank, norm); } @Override protected IterativeSolver createSolver(Vector x) { return new GMRES(x); } } private class BiCGstabColumnDistIterativeSolver extends UnSymmColumnDistIterativeSolver { public BiCGstabColumnDistIterativeSolver(int rank, Vector.Norm norm) { super(rank, norm); } @Override protected IterativeSolver createSolver(Vector x) { return new BiCGstab(x); } } private class CGRowDistIterativeSolver extends SymmRowDistIterativeSolver { public CGRowDistIterativeSolver(int rank, Vector.Norm norm) { super(rank, norm); } @Override protected IterativeSolver createSolver(Vector x) { return new CG(x); } } private class CGColumnDistIterativeSolver extends SymmColumnDistIterativeSolver { public CGColumnDistIterativeSolver(int rank, Vector.Norm norm) { super(rank, norm); } @Override protected IterativeSolver createSolver(Vector x) { return new CG(x); } } } mtj-0.9.14/tests/no/uib/cipr/matrix/distributed/CollectiveTest.java0000644000000000000000000002170211467312510024013 0ustar rootrootpackage no.uib.cipr.matrix.distributed; import java.util.Random; import no.uib.cipr.matrix.distributed.CollectiveCommunications; import no.uib.cipr.matrix.distributed.Communicator; import no.uib.cipr.matrix.distributed.Reductions; import junit.framework.TestCase; /** * @deprecated the no.uib.cipr.matrix.distributed package has been deprecated because * of a number of hard to fix concurrency bugs. It is distributed only for backwards compatibility, * but is not recommended. The utility of this package is questionable, as it does not allow * distribution of computation between JVMs or across a network. For many people, distributed * computing of multiple matrices can be achieved at a user-level through the * JPPF Framework. * Users who need to deal with few very large matrices may wish to implement their own storage classes * and solvers using JPPF, but this will not be supported directly in matrix-toolkits-java. */ @Deprecated public class CollectiveTest extends TestCase { CollectiveCommunications coll; Random r; @Override protected void setUp() throws Exception { r = new Random(); int size = Math.max(1, r.nextInt(16)); coll = new CollectiveCommunications(size); } public void testBarrier() throws InterruptedException { Thread[] t = new Thread[coll.size()]; for (int i = 0; i < t.length; ++i) { final int rank = i; t[i] = new Thread(new Runnable() { public void run() { Communicator comm = coll.createCommunicator(rank); comm.barrier(); } }); t[i].start(); } for (int i = 0; i < t.length; ++i) t[i].join(10000); for (int i = 0; i < t.length; ++i) assertTrue(!t[i].isAlive()); } public void testBroadcast() throws InterruptedException { final int[] send = new int[r.nextInt(100)]; for (int i = 0; i < send.length; ++i) send[i] = r.nextInt(); final int[][] recv = new int[coll.size()][send.length]; recv[0] = send; Thread[] t = new Thread[coll.size()]; for (int i = 0; i < t.length; ++i) { final int rank = i; t[i] = new Thread(new Runnable() { public void run() { Communicator comm = coll.createCommunicator(rank); comm.broadcast(recv[rank], 0); } }); t[i].start(); } for (int i = 0; i < t.length; ++i) t[i].join(); for (int i = 0; i < coll.size(); ++i) for (int j = 0; j < send.length; ++j) assertEquals(send[j], recv[i][j]); } public void testScatter() throws InterruptedException { int length = r.nextInt(100); final int[][] send = new int[coll.size()][length]; for (int i = 0; i < coll.size(); ++i) for (int j = 0; j < length; ++j) send[i][j] = r.nextInt(); final int[][] recv = new int[coll.size()][length]; Thread[] t = new Thread[coll.size()]; for (int i = 0; i < t.length; ++i) { final int rank = i; t[i] = new Thread(new Runnable() { public void run() { Communicator comm = coll.createCommunicator(rank); comm.scatter(send, recv[rank], 0); } }); t[i].start(); } for (int i = 0; i < t.length; ++i) t[i].join(); for (int i = 0; i < coll.size(); ++i) for (int j = 0; j < length; ++j) assertEquals(send[i][j], recv[i][j]); } public void testGather() throws InterruptedException { int length = r.nextInt(100); final int[][] send = new int[coll.size()][length]; for (int i = 0; i < coll.size(); ++i) for (int j = 0; j < length; ++j) send[i][j] = r.nextInt(); final int[][] recv = new int[coll.size()][length]; Thread[] t = new Thread[coll.size()]; for (int i = 0; i < t.length; ++i) { final int rank = i; t[i] = new Thread(new Runnable() { public void run() { Communicator comm = coll.createCommunicator(rank); comm.gather(send[rank], recv, 0); } }); t[i].start(); } for (int i = 0; i < t.length; ++i) t[i].join(); for (int i = 0; i < coll.size(); ++i) for (int j = 0; j < length; ++j) assertEquals(send[i][j], recv[i][j]); } public void testAllGather() throws InterruptedException { int length = r.nextInt(100); final int[][] send = new int[coll.size()][length]; for (int i = 0; i < coll.size(); ++i) for (int j = 0; j < length; ++j) send[i][j] = r.nextInt(); final int[][][] recv = new int[coll.size()][coll.size()][length]; Thread[] t = new Thread[coll.size()]; for (int i = 0; i < t.length; ++i) { final int rank = i; t[i] = new Thread(new Runnable() { public void run() { Communicator comm = coll.createCommunicator(rank); comm.allGather(send[rank], recv[rank]); } }); t[i].start(); } for (int i = 0; i < t.length; ++i) t[i].join(); for (int i = 0; i < coll.size(); ++i) for (int j = 0; j < length; ++j) assertEquals(send[i][j], recv[i][i][j]); } public void testAllToAll() throws InterruptedException { int length = r.nextInt(100); final int[][][] send = new int[coll.size()][coll.size()][length]; for (int i = 0; i < coll.size(); ++i) for (int j = 0; j < coll.size(); ++j) for (int k = 0; k < length; ++k) send[i][j][k] = r.nextInt(); final int[][][] recv = new int[coll.size()][coll.size()][length]; Thread[] t = new Thread[coll.size()]; for (int i = 0; i < t.length; ++i) { final int rank = i; t[i] = new Thread(new Runnable() { public void run() { Communicator comm = coll.createCommunicator(rank); comm.allToAll(send[rank], recv[rank]); } }); t[i].start(); } for (int i = 0; i < t.length; ++i) t[i].join(); for (int i = 0; i < coll.size(); ++i) for (int j = 0; j < coll.size(); ++j) for (int k = 0; k < length; ++k) assertEquals(send[i][j][k], recv[j][i][k]); } public void testReduce() throws InterruptedException { int length = r.nextInt(100); final int[][] send = new int[coll.size()][length]; for (int i = 0; i < coll.size(); ++i) for (int j = 0; j < length; ++j) send[i][j] = r.nextInt(1000); final int[] recv = new int[length]; Thread[] t = new Thread[coll.size()]; for (int i = 0; i < t.length; ++i) { final int rank = i; t[i] = new Thread(new Runnable() { public void run() { Communicator comm = coll.createCommunicator(rank); comm.reduce(send[rank], recv, Reductions.sum(), 0); } }); t[i].start(); } for (int i = 0; i < t.length; ++i) t[i].join(); int[] mysum = new int[length]; for (int i = 0; i < coll.size(); ++i) for (int j = 0; j < length; ++j) mysum[j] += send[i][j]; for (int j = 0; j < length; ++j) assertEquals(mysum[j], recv[j]); } public void testAllReduce() throws InterruptedException { int length = r.nextInt(100); final int[][] send = new int[coll.size()][length]; for (int i = 0; i < coll.size(); ++i) for (int j = 0; j < length; ++j) send[i][j] = r.nextInt(1000); final int[][] recv = new int[coll.size()][length]; Thread[] t = new Thread[coll.size()]; for (int i = 0; i < t.length; ++i) { final int rank = i; t[i] = new Thread(new Runnable() { public void run() { Communicator comm = coll.createCommunicator(rank); comm.allReduce(send[rank], recv[rank], Reductions.sum()); } }); t[i].start(); } for (int i = 0; i < t.length; ++i) t[i].join(); int[] mysum = new int[length]; for (int i = 0; i < coll.size(); ++i) for (int j = 0; j < length; ++j) mysum[j] += send[i][j]; for (int i = 0; i < coll.size(); ++i) for (int j = 0; j < length; ++j) assertEquals(mysum[j], recv[i][j]); } } mtj-0.9.14/tests/no/uib/cipr/matrix/MatrixTestAbstract.java0000644000000000000000000010543211027514324022332 0ustar rootroot/* * 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 no.uib.cipr.matrix.Matrices; import no.uib.cipr.matrix.Matrix; import no.uib.cipr.matrix.MatrixEntry; import no.uib.cipr.matrix.MatrixNotSPDException; import no.uib.cipr.matrix.MatrixSingularException; import no.uib.cipr.matrix.Vector; import junit.framework.TestCase; /** * Tests a matrix */ public abstract class MatrixTestAbstract extends TestCase { /** * Matrix to test */ protected Matrix A; /** * Jagged array version of A */ protected double[][] Ad; /** * Matrix of the same size as A, dense and non-dense */ protected Matrix Bdense, B; /** * Contents of B */ protected double[][] Bd; /** * Non-dense vectors with size equal the number of rows in A */ protected Vector xR, yR; /** * Non-dense vectors with size equal the number of columns in A */ protected Vector xC, yC; /** * Dense vectors with size equal the number of rows in A */ protected Vector xDenseR, yDenseR; /** * Dense vectors with size equal the number of columns in A */ protected Vector xDenseC, yDenseC; /** * Contents of the vectors */ protected double[] xdR, ydR, xdC, ydC; /** * Tolerance for floating-point comparisons */ protected double tol = 1e-5; /** * Maximum matrix size, to avoid too slow tests */ protected int max = 100; /** * Constructor for MatrixTestAbstract */ public MatrixTestAbstract(String arg0) { super(arg0); } @Override protected void setUp() throws Exception { createPrimary(); createAuxillerary(); } protected abstract void createPrimary() throws Exception; @Override protected void tearDown() throws Exception { A = B = Bdense = null; Ad = Bd = null; xC = xDenseC = xDenseR = xR = yC = yDenseC = yDenseR = yR = null; xdC = xdR = ydC = ydR = null; } /** * Called after setUp() to create additional datastructures */ protected void createAuxillerary() { Bdense = Matrices.random(A.numRows(), A.numColumns()); B = Matrices.synchronizedMatrix(Bdense.copy()); Bd = Matrices.getArray(B); xDenseC = Matrices.random(A.numColumns()); yDenseC = Matrices.random(A.numColumns()); xDenseR = Matrices.random(A.numRows()); yDenseR = Matrices.random(A.numRows()); xC = Matrices.synchronizedVector(xDenseC); yC = Matrices.synchronizedVector(yDenseC); xR = Matrices.synchronizedVector(xDenseR); yR = Matrices.synchronizedVector(yDenseR); xdC = Matrices.getArray(xC); ydC = Matrices.getArray(yC); xdR = Matrices.getArray(xR); ydR = Matrices.getArray(yR); } public void testMatrixRank2Dense() { if (A.isSquare()) { int n = Utilities.getInt(1, max); Matrix B = Matrices.random(A.numRows(), n), C = Matrices.random(A .numRows(), n); double[][] Bd = Matrices.getArray(B), Cd = Matrices.getArray(C); double alpha = Math.random(); A = A.rank2(alpha, B, C); rank2(Ad, alpha, Bd, Cd); assertEquals(Ad, A); assertEquals(Bd, B); assertEquals(Cd, C); } } public void testMatrixRank2() { if (A.isSquare()) { int n = Utilities.getInt(1, max); Matrix B = Matrices.synchronizedMatrix(Matrices.random(A.numRows(), n)), C = Matrices.synchronizedMatrix(Matrices.random(A .numRows(), n)); double[][] Bd = Matrices.getArray(B), Cd = Matrices.getArray(C); double alpha = Math.random(); A = A.rank2(alpha, B, C); rank2(Ad, alpha, Bd, Cd); assertEquals(Ad, A); assertEquals(Bd, B); assertEquals(Cd, C); } } public void testMatrixTransRank2Dense() { if (A.isSquare()) { int n = Utilities.getInt(1, max); Matrix B = Matrices.random(n, A.numColumns()), C = Matrices.random( n, A.numColumns()); double[][] Bd = Matrices.getArray(B), Cd = Matrices.getArray(C); double alpha = Math.random(); A = A.transRank2(alpha, B, C); transRank2(Ad, alpha, Bd, Cd); assertEquals(Ad, A); assertEquals(Bd, B); assertEquals(Cd, C); } } public void testMatrixTransRank2() { if (A.isSquare()) { int n = Utilities.getInt(1, max); Matrix B = Matrices.synchronizedMatrix(Matrices.random(n, A .numColumns())), C = Matrices.synchronizedMatrix(Matrices .random(n, A.numColumns())); double[][] Bd = Matrices.getArray(B), Cd = Matrices.getArray(C); double alpha = Math.random(); A = A.transRank2(alpha, B, C); transRank2(Ad, alpha, Bd, Cd); assertEquals(Ad, A); assertEquals(Bd, B); assertEquals(Cd, C); } } public void testMatrixRank1Dense() { if (A.isSquare()) { Matrix C = Matrices.random(A.numRows(), A.numColumns()); double[][] Cd = Matrices.getArray(C); double alpha = Math.random(); A = A.rank1(alpha, C); rank1(Ad, alpha, Cd); assertEquals(Ad, A); assertEquals(Cd, C); } } public void testMatrixRank1() { if (A.isSquare()) { Matrix C = Matrices.synchronizedMatrix(Matrices.random(A.numRows(), A.numColumns())); double[][] Cd = Matrices.getArray(C); double alpha = Math.random(); A = A.rank1(alpha, C); rank1(Ad, alpha, Cd); assertEquals(Ad, A); assertEquals(Cd, C); } } public void testMatrixTransRank1Dense() { if (A.isSquare()) { Matrix C = Matrices.random(A.numRows(), A.numColumns()); double[][] Cd = Matrices.getArray(C); double alpha = Math.random(); A = A.transRank1(alpha, C); transRank1(Ad, alpha, Cd); assertEquals(Ad, A); assertEquals(Cd, C); } } public void testMatrixTransRank1() { if (A.isSquare()) { Matrix C = Matrices.synchronizedMatrix(Matrices.random(A.numRows(), A.numColumns())); double[][] Cd = Matrices.getArray(C); double alpha = Math.random(); A = A.transRank1(alpha, C); transRank1(Ad, alpha, Cd); assertEquals(Ad, A); assertEquals(Cd, C); } } public void testMatrixMultDense() { int m = A.numRows(), k = A.numColumns(), n = Utilities.getInt(1, max); Matrix B = Matrices.random(k, n), C = Matrices.random(m, n); double[][] Bd = Matrices.getArray(B), Cd = Matrices.getArray(C); double alpha = Math.random(); C = A.mult(alpha, B, C); Cd = mult(Ad, alpha, Bd, Cd); assertEquals(Ad, A); assertEquals(Bd, B); assertEquals(Cd, C); } public void testMatrixMult() { int m = A.numRows(), k = A.numColumns(), n = Utilities.getInt(1, max); Matrix B = Matrices.synchronizedMatrix(Matrices.random(k, n)), C = Matrices .synchronizedMatrix(Matrices.random(m, n)); double[][] Bd = Matrices.getArray(B), Cd = Matrices.getArray(C); double alpha = Math.random(); C = A.mult(alpha, B, C); Cd = mult(Ad, alpha, Bd, Cd); assertEquals(Ad, A); assertEquals(Bd, B); assertEquals(Cd, C); } public void testMatrixTransAmultDense() { int m = A.numColumns(), k = A.numRows(), n = Utilities.getInt(1, max); Matrix B = Matrices.random(k, n), C = Matrices.random(m, n); double[][] Bd = Matrices.getArray(B), Cd = Matrices.getArray(C); double alpha = Math.random(); C = A.transAmult(alpha, B, C); Cd = transAmult(Ad, alpha, Bd, Cd); assertEquals(Ad, A); assertEquals(Bd, B); assertEquals(Cd, C); } public void testMatrixTransAmult() { int m = A.numColumns(), k = A.numRows(), n = Utilities.getInt(1, max); Matrix B = Matrices.synchronizedMatrix(Matrices.random(k, n)), C = Matrices .synchronizedMatrix(Matrices.random(m, n)); double[][] Bd = Matrices.getArray(B), Cd = Matrices.getArray(C); double alpha = Math.random(); C = A.transAmult(alpha, B, C); Cd = transAmult(Ad, alpha, Bd, Cd); assertEquals(Ad, A); assertEquals(Bd, B); assertEquals(Cd, C); } public void testMatrixTransABmultDense() { int m = A.numColumns(), k = A.numRows(), n = Utilities.getInt(1, max); Matrix B = Matrices.random(n, k), C = Matrices.random(m, n); double[][] Bd = Matrices.getArray(B), Cd = Matrices.getArray(C); double alpha = Math.random(); C = A.transABmult(alpha, B, C); Cd = transABmult(Ad, alpha, Bd, Cd); assertEquals(Ad, A); assertEquals(Bd, B); assertEquals(Cd, C); } public void testMatrixTransABmult() { int m = A.numColumns(), k = A.numRows(), n = Utilities.getInt(1, max); Matrix B = Matrices.synchronizedMatrix(Matrices.random(n, k)), C = Matrices .synchronizedMatrix(Matrices.random(m, n)); double[][] Bd = Matrices.getArray(B), Cd = Matrices.getArray(C); double alpha = Math.random(); C = A.transABmult(alpha, B, C); Cd = transABmult(Ad, alpha, Bd, Cd); assertEquals(Ad, A); assertEquals(Bd, B); assertEquals(Cd, C); } public void testMatrixTransBmultDense() { int m = A.numRows(), k = A.numColumns(), n = Utilities.getInt(1, max); Matrix B = Matrices.random(n, k), C = Matrices.random(m, n); double[][] Bd = Matrices.getArray(B), Cd = Matrices.getArray(C); double alpha = Math.random(); C = A.transBmult(alpha, B, C); Cd = transBmult(Ad, alpha, Bd, Cd); assertEquals(Ad, A); assertEquals(Bd, B); assertEquals(Cd, C); } public void testMatrixTransBmult() { int m = A.numRows(), k = A.numColumns(), n = Utilities.getInt(1, max); Matrix B = Matrices.synchronizedMatrix(Matrices.random(n, k)), C = Matrices .synchronizedMatrix(Matrices.random(m, n)); double[][] Bd = Matrices.getArray(B), Cd = Matrices.getArray(C); double alpha = Math.random(); C = A.transBmult(alpha, B, C); Cd = transBmult(Ad, alpha, Bd, Cd); assertEquals(Ad, A); assertEquals(Bd, B); assertEquals(Cd, C); } public void testMatrixMultAddDense() { int m = A.numRows(), k = A.numColumns(), n = Utilities.getInt(1, max); Matrix B = Matrices.random(k, n), C = Matrices.random(m, n); double[][] Bd = Matrices.getArray(B), Cd = Matrices.getArray(C); double alpha = Math.random(); C = A.multAdd(alpha, B, C); Cd = multAdd(Ad, alpha, Bd, Cd); assertEquals(Ad, A); assertEquals(Bd, B); assertEquals(Cd, C); } public void testMatrixMultAdd() { int m = A.numRows(), k = A.numColumns(), n = Utilities.getInt(1, max); Matrix B = Matrices.synchronizedMatrix(Matrices.random(k, n)), C = Matrices .synchronizedMatrix(Matrices.random(m, n)); double[][] Bd = Matrices.getArray(B), Cd = Matrices.getArray(C); double alpha = Math.random(); C = A.multAdd(alpha, B, C); Cd = multAdd(Ad, alpha, Bd, Cd); assertEquals(Ad, A); assertEquals(Bd, B); assertEquals(Cd, C); } public void testMatrixTransAmultAddDense() { int m = A.numColumns(), k = A.numRows(), n = Utilities.getInt(1, max); Matrix B = Matrices.random(k, n), C = Matrices.random(m, n); double[][] Bd = Matrices.getArray(B), Cd = Matrices.getArray(C); double alpha = Math.random(); C = A.transAmultAdd(alpha, B, C); Cd = transAmultAdd(Ad, alpha, Bd, Cd); assertEquals(Ad, A); assertEquals(Bd, B); assertEquals(Cd, C); } public void testMatrixTransAmultAdd() { int m = A.numColumns(), k = A.numRows(), n = Utilities.getInt(1, max); Matrix B = Matrices.synchronizedMatrix(Matrices.random(k, n)), C = Matrices .synchronizedMatrix(Matrices.random(m, n)); double[][] Bd = Matrices.getArray(B), Cd = Matrices.getArray(C); double alpha = Math.random(); C = A.transAmultAdd(alpha, B, C); Cd = transAmultAdd(Ad, alpha, Bd, Cd); assertEquals(Ad, A); assertEquals(Bd, B); assertEquals(Cd, C); } public void testMatrixTransABmultAddDense() { int m = A.numColumns(), k = A.numRows(), n = Utilities.getInt(1, max); Matrix B = Matrices.random(n, k), C = Matrices.random(m, n); double[][] Bd = Matrices.getArray(B), Cd = Matrices.getArray(C); double alpha = Math.random(); C = A.transABmultAdd(alpha, B, C); Cd = transABmultAdd(Ad, alpha, Bd, Cd); assertEquals(Ad, A); assertEquals(Bd, B); assertEquals(Cd, C); } public void testMatrixTransABmultAdd() { int m = A.numColumns(), k = A.numRows(), n = Utilities.getInt(1, max); Matrix B = Matrices.synchronizedMatrix(Matrices.random(n, k)), C = Matrices .synchronizedMatrix(Matrices.random(m, n)); double[][] Bd = Matrices.getArray(B), Cd = Matrices.getArray(C); double alpha = Math.random(); C = A.transABmultAdd(alpha, B, C); Cd = transABmultAdd(Ad, alpha, Bd, Cd); assertEquals(Ad, A); assertEquals(Bd, B); assertEquals(Cd, C); } public void testMatrixTransBmultAddDense() { int m = A.numRows(), k = A.numColumns(), n = Utilities.getInt(1, max); Matrix B = Matrices.random(n, k), C = Matrices.random(m, n); double[][] Bd = Matrices.getArray(B), Cd = Matrices.getArray(C); double alpha = Math.random(); C = A.transBmultAdd(alpha, B, C); Cd = transBmultAdd(Ad, alpha, Bd, Cd); assertEquals(Ad, A); assertEquals(Bd, B); assertEquals(Cd, C); } public void testMatrixTransBmultAdd() { int m = A.numRows(), k = A.numColumns(), n = Utilities.getInt(1, max); Matrix B = Matrices.synchronizedMatrix(Matrices.random(n, k)), C = Matrices .synchronizedMatrix(Matrices.random(m, n)); double[][] Bd = Matrices.getArray(B), Cd = Matrices.getArray(C); double alpha = Math.random(); C = A.transBmultAdd(alpha, B, C); Cd = transBmultAdd(Ad, alpha, Bd, Cd); assertEquals(Ad, A); assertEquals(Bd, B); assertEquals(Cd, C); } protected double[][] rank2(double[][] Ad, double alpha, double[][] Bd, double[][] Cd) { return transBmultAdd(Bd, alpha, Cd, transBmultAdd(Cd, alpha, Bd, Ad)); } protected double[][] transRank2(double[][] Ad, double alpha, double[][] Bd, double[][] Cd) { return transAmultAdd(Bd, alpha, Cd, transAmultAdd(Cd, alpha, Bd, Ad)); } protected double[][] rank1(double[][] Ad, double alpha, double[][] Cd) { return transBmultAdd(Cd, alpha, Cd, Ad); } protected double[][] transRank1(double[][] Ad, double alpha, double[][] Cd) { return transAmultAdd(Cd, alpha, Cd, Ad); } public void testVectorRank2Dense() { if (A.isSquare()) { double alpha = Math.random(); assertEquals(rank2(alpha, xdR, ydR), A.rank2(alpha, xDenseR, yDenseR)); } } public void testVectorRank2() { if (A.isSquare()) { double alpha = Math.random(); assertEquals(rank2(alpha, xdR, ydR), A.rank2(alpha, xR, yR)); } } public void testVectorRank1Dense() { if (A.isSquare()) { double alpha = Math.random(); assertEquals(rank1(alpha, xdR, ydR), A.rank1(alpha, xDenseR, yDenseR)); } } public void testVectorRank1() { if (A.isSquare()) { double alpha = Math.random(); assertEquals(rank1(alpha, xdR, ydR), A.rank1(alpha, xR, yR)); } } protected double[][] rank2(double alpha, double[] xd, double[] yd) { rank1(alpha, xd, yd); rank1(alpha, yd, xd); return Ad; } protected double[][] rank1(double alpha, double[] xd, double[] yd) { for (int i = 0; i < xd.length; ++i) for (int j = 0; j < yd.length; ++j) Ad[i][j] += alpha * xd[i] * yd[j]; return Ad; } public void testVectorTransMultAddDense() { double alpha = Math.random(); assertEquals(transMultAdd(alpha, xdR, ydC), A.transMultAdd(alpha, xDenseR, yDenseC)); assertEquals(Ad, A); assertEquals(xdR, xDenseR); assertEquals(ydC, yDenseC); } public void testVectorTransMultAdd() { double alpha = Math.random(); assertEquals(transMultAdd(alpha, xdR, ydC), A.transMultAdd(alpha, xR, yC)); assertEquals(Ad, A); assertEquals(xdR, xR); assertEquals(ydC, yC); } protected double[] transMultAdd(double alpha, double[] xd, double[] yd) { int rows = Ad.length, cols = 0; if (rows > 0) cols = Ad[0].length; for (int j = 0; j < cols; ++j) { double dot = 0; for (int i = 0; i < rows; ++i) dot += Ad[i][j] * xd[i]; yd[j] += alpha * dot; } return yd; } public void testVectorMultDense() { double alpha = Math.random(); assertEquals(mult(alpha, xdC, ydR), A.mult(alpha, xDenseC, yDenseR)); assertEquals(Ad, A); assertEquals(xdC, xDenseC); assertEquals(ydR, yDenseR); } public void testVectorMult() { double alpha = Math.random(); assertEquals(mult(alpha, xdC, ydR), A.mult(alpha, xC, yR)); assertEquals(Ad, A); assertEquals(xdC, xC); assertEquals(ydR, yR); } protected double[] mult(double alpha, double[] xd, double[] yd) { for (int i = 0; i < Ad.length; ++i) { double dot = 0; for (int j = 0; j < Ad[i].length; ++j) dot += Ad[i][j] * xd[j]; yd[i] = alpha * dot; } return yd; } public void testVectorMultAddDense() { double alpha = Math.random(); assertEquals(multAdd(Ad, alpha, xdC, ydR), A.multAdd(alpha, xDenseC, yDenseR)); assertEquals(Ad, A); assertEquals(xdC, xDenseC); assertEquals(ydR, yDenseR); } public void testVectorMultAdd() { double alpha = Math.random(); assertEquals(multAdd(Ad, alpha, xdC, ydR), A.multAdd(alpha, xC, yR)); assertEquals(Ad, A); assertEquals(xdC, xC); assertEquals(ydR, yR); } protected double[] multAdd(double[][] Ad, double alpha, double[] xd, double[] yd) { for (int i = 0; i < Ad.length; ++i) { double dot = 0; for (int j = 0; j < Ad[i].length; ++j) dot += Ad[i][j] * xd[j]; yd[i] += alpha * dot; } return yd; } protected double[][] mult(double[][] Ad, double alpha, double[][] Bd, double[][] Cd) { int m = Cd.length, n = 0, k = Bd.length; if (k > 0) n = Bd[0].length; Utilities.zero(Cd); for (int j = 0; j < n; ++j) for (int l = 0; l < k; ++l) for (int i = 0; i < m; ++i) Cd[i][j] += alpha * Ad[i][l] * Bd[l][j]; return Cd; } protected double[][] transAmult(double[][] Ad, double alpha, double[][] Bd, double[][] Cd) { int m = Cd.length, n = 0, k = Bd.length; if (k > 0) n = Bd[0].length; for (int j = 0; j < n; ++j) for (int i = 0; i < m; ++i) { double temp = 0; for (int l = 0; l < k; ++l) temp += Ad[l][i] * Bd[l][j]; Cd[i][j] = alpha * temp; } return Cd; } protected double[][] transBmult(double[][] Ad, double alpha, double[][] Bd, double[][] Cd) { int m = Cd.length, n = Bd.length, k = 0; if (n > 0) k = Bd[0].length; Utilities.zero(Cd); for (int j = 0; j < n; ++j) { for (int l = 0; l < k; ++l) for (int i = 0; i < m; ++i) Cd[i][j] += alpha * Ad[i][l] * Bd[j][l]; } return Cd; } protected double[][] transABmult(double[][] Ad, double alpha, double[][] Bd, double[][] Cd) { int m = Cd.length, n = Bd.length, k = 0; if (n > 0) k = Bd[0].length; for (int j = 0; j < n; ++j) for (int i = 0; i < m; ++i) { double temp = 0; for (int l = 0; l < k; ++l) temp += Ad[l][i] * Bd[j][l]; Cd[i][j] = alpha * temp; } return Cd; } protected double[][] multAdd(double[][] Ad, double alpha, double[][] Bd, double[][] Cd) { int m = Cd.length, n = 0, k = Bd.length; if (k > 0) n = Bd[0].length; for (int j = 0; j < n; ++j) for (int l = 0; l < k; ++l) for (int i = 0; i < m; ++i) Cd[i][j] += alpha * Ad[i][l] * Bd[l][j]; return Cd; } protected double[][] transAmultAdd(double[][] Ad, double alpha, double[][] Bd, double[][] Cd) { int m = Cd.length, n = 0, k = Bd.length; if (k > 0) n = Bd[0].length; for (int j = 0; j < n; ++j) for (int i = 0; i < m; ++i) { double temp = 0; for (int l = 0; l < k; ++l) temp += Ad[l][i] * Bd[l][j]; Cd[i][j] += alpha * temp; } return Cd; } protected double[][] transBmultAdd(double[][] Ad, double alpha, double[][] Bd, double[][] Cd) { int m = Cd.length, n = Bd.length, k = 0; if (n > 0) k = Bd[0].length; for (int j = 0; j < n; ++j) for (int l = 0; l < k; ++l) for (int i = 0; i < m; ++i) Cd[i][j] += alpha * Ad[i][l] * Bd[j][l]; return Cd; } protected double[][] transABmultAdd(double[][] Ad, double alpha, double[][] Bd, double[][] Cd) { int m = Cd.length, n = Bd.length, k = 0; if (n > 0) k = Bd[0].length; for (int j = 0; j < n; ++j) for (int i = 0; i < m; ++i) { double temp = 0; for (int l = 0; l < k; ++l) temp += Ad[l][i] * Bd[j][l]; Cd[i][j] += alpha * temp; } return Cd; } /** * Tests A = A + alpha*B */ public void testRandomMatrixAdd() { double alpha = Math.random(); A = A.add(alpha, B); add(Ad, alpha, Bd); assertEquals(Ad, A); assertEquals(Bd, B); } /** * Tests A = A + B */ public void testMatrixAdd() { A = A.add(B); add(Ad, 1, Bd); assertEquals(Ad, A); assertEquals(Bd, B); } /** * Tests A = A + 1*B */ public void testOneMatrixAdd() { A = A.add(1, B); add(Ad, 1, Bd); assertEquals(Ad, A); assertEquals(Bd, B); } /** * Tests A = A + 0*B */ public void testZeroMatrixAdd() { A = A.add(0, B); add(Ad, 0, Bd); assertEquals(Ad, A); assertEquals(Bd, B); } /** * Tests A = alpha*B */ public void testRandomMatrixSet() { double alpha = Math.random(); A = A.set(alpha, B); set(Ad, alpha, Bd); assertEquals(Ad, A); assertEquals(Bd, B); } /** * Tests A = B */ public void testMatrixSet() { A = A.set(B); set(Ad, 1, Bd); assertEquals(Ad, A); assertEquals(Bd, B); } /** * Tests A = 1*B */ public void testOneMatrixSet() { A = A.set(1, B); set(Ad, 1, Bd); assertEquals(Ad, A); assertEquals(Bd, B); } /** * Tests A = 0*B */ public void testZeroMatrixSet() { A = A.set(0, B); set(Ad, 0, Bd); assertEquals(Ad, A); assertEquals(Bd, B); } /** * Checks transpose */ public void testTranspose() { Matrix At = Matrices.random(A.numColumns(), A.numRows()); assertEquals(transpose(), A.transpose(At)); } protected void set(double[][] A, double alpha, double[][] B) { for (int i = 0; i < A.length; ++i) for (int j = 0; j < A[i].length; ++j) A[i][j] = alpha * B[i][j]; } protected void add(double[][] A, double alpha, double[][] B) { for (int i = 0; i < A.length; ++i) for (int j = 0; j < A[i].length; ++j) A[i][j] += alpha * B[i][j]; } protected double[][] transpose() { if (Ad.length == 0) return new double[0][0]; double[][] Adt = new double[Ad[0].length][Ad.length]; for (int i = 0; i < Ad.length; ++i) for (int j = 0; j < Ad[i].length; ++j) Adt[j][i] = Ad[i][j]; return Adt; } /** * Test of direct matrix solver */ public void testMatrixSolve() { while (true) { try { Matrix B = Matrices.random(A.numRows(), A.numColumns()); Matrix X = Matrices.random(A.numRows(), A.numColumns()); X = A.solve(B, X); Matrix Y = A.multAdd(X, X.copy().set(-1, B)); assertEquals(0, Y.norm(Matrix.Norm.Frobenius), tol); assertEquals(Ad, A); return; } catch (MatrixSingularException e) { Utilities.addDiagonal(A, Ad, 1); } catch (MatrixNotSPDException e) { Utilities.addDiagonal(A, Ad, 1); } } } /** * Test of direct transpose matrix solver */ public void testTransMatrixSolve() { while (true) { try { Matrix B = Matrices.random(A.numRows(), A.numColumns()); Matrix X = Matrices.random(A.numRows(), A.numColumns()); X = A.transSolve(B, X); Matrix Y = A.transAmultAdd(X, X.copy().set(-1, B)); assertEquals(0, Y.norm(Matrix.Norm.Frobenius), tol); assertEquals(Ad, A); return; } catch (MatrixSingularException e) { Utilities.addDiagonal(A, Ad, 1); } catch (MatrixNotSPDException e) { Utilities.addDiagonal(A, Ad, 1); } } } /** * Test of direct vector solver */ public void testVectorSolve() { while (true) { try { Vector b = Matrices.random(A.numRows()); Vector x = Matrices.random(A.numRows()); x = A.solve(b, x); Vector y = A.multAdd(-1, x, x.copy().set(b)); assertEquals(0, y.norm(Vector.Norm.Two), tol); assertEquals(Ad, A); return; } catch (MatrixSingularException e) { Utilities.addDiagonal(A, Ad, 1); } catch (MatrixNotSPDException e) { Utilities.addDiagonal(A, Ad, 1); } } } /** * Test of direct transpose vector solver */ public void testTransVectorSolve() { while (true) { try { Vector b = Matrices.random(A.numRows()); Vector x = Matrices.random(A.numRows()); x = A.transSolve(b, x); Vector y = A.transMultAdd(-1, x, x.copy().set(b)); assertEquals(0, y.norm(Vector.Norm.Two), tol); assertEquals(Ad, A); return; } catch (MatrixSingularException e) { Utilities.addDiagonal(A, Ad, 1); } catch (MatrixNotSPDException e) { Utilities.addDiagonal(A, Ad, 1); } } } /** * Test additions using iterators */ public void testAdd() { double alpha = Math.random(); for (MatrixEntry e : A) { A.add(e.row(), e.column(), alpha); A.add(e.row(), e.column(), -alpha); } assertEquals(Ad, A); } /** * Checks that copy is deep, not reference */ public void testCopy() { Matrix Ac = A.copy(); A = A.zero(); assertEquals(Ad, Ac); } /** * Test iterator get */ public void testIterator() { double[][] Ac = new double[A.numRows()][A.numColumns()]; for (MatrixEntry e : A) Ac[e.row()][e.column()] = e.get(); assertEquals(Ad, Ac); } /** * Test iterator set */ public void testIteratorSet() { double alpha = Math.random(); for (MatrixEntry e : A) e.set(e.get() * alpha); assertEquals(scale(alpha), A); } /** * Test iterator read and write */ public void testIteratorSetGet() { double alpha = Math.random(); double[][] Ac = new double[A.numRows()][A.numColumns()]; for (MatrixEntry e : A) { Ac[e.row()][e.column()] = e.get(); e.set(alpha * e.get()); e.set(e.get() / alpha); } assertEquals(Ad, Ac); assertEquals(Ad, A); } /** * Checks zero() */ public void testZero() { assertEquals(zero(), A.zero()); } protected double[][] zero() { for (int i = 0; i < Ad.length; ++i) for (int j = 0; j < Ad[i].length; ++j) Ad[i][j] = 0; return Ad; } /** * Cardinality computation */ public void testCardinality() { assertEquals(Matrices.cardinality(A), cardinality()); } protected int cardinality() { int nz = 0; for (int i = 0; i < Ad.length; ++i) for (int j = 0; j < Ad[i].length; ++j) if (Ad[i][j] != 0.) nz++; return nz; } /** * Checks in-place transpose for square matrices */ public void testTransposeInplace() { if (A.isSquare()) assertEquals(transpose(), A.copy().transpose()); } /** * Scaling with an arbitrary scalar */ public void testScale() { double alpha = Math.random(); A = A.scale(alpha); scale(alpha); assertEquals(Ad, A); } /** * Scaling by zero */ public void testZeroScale() { A = A.scale(0); scale(0); assertEquals(Ad, A); } /** * Scaling by one */ public void testOneScale() { A = A.scale(1); scale(1); assertEquals(Ad, A); } protected double[][] scale(double alpha) { for (int i = 0; i < Ad.length; ++i) for (int j = 0; j < Ad[i].length; ++j) Ad[i][j] *= alpha; return Ad; } /** * Checks the 1 norm */ public void testOneNorm() { assertEquals(norm1(Ad), A.norm(Matrix.Norm.One), tol); assertEquals(Ad, A); } /** * Checks the Frobenius norm */ public void testFrobeniusNorm() { assertEquals(normF(Ad), A.norm(Matrix.Norm.Frobenius), tol); assertEquals(Ad, A); } /** * Checks the infinity norm */ public void testInfinityNorm() { assertEquals(normInf(Ad), A.norm(Matrix.Norm.Infinity), tol); assertEquals(Ad, A); } protected double norm1(double[][] A) { double max = 0; for (int i = 0; i < A.length; ++i) { double rowsum = 0; for (int j = 0; j < A[i].length; ++j) rowsum += Math.abs(A[i][j]); max = Math.max(rowsum, max); } return max; } protected double normF(double[][] A) { double norm = 0; for (int i = 0; i < A.length; ++i) for (int j = 0; j < A[i].length; ++j) norm += A[i][j] * A[i][j]; return Math.sqrt(norm); } protected double normInf(double[][] A) { if (A.length == 0) return 0; double[] columnSum = new double[A[0].length]; for (int i = 0; i < A.length; ++i) for (int j = 0; j < A[i].length; ++j) columnSum[j] += Math.abs(A[i][j]); double max = 0; for (double d : columnSum) max = Math.max(max, d); return max; } /** * Checks for equality between the matrix and the array */ protected void assertEquals(double[][] Ad, Matrix A) { assertTrue(A != null); assertTrue(Ad != null); assertTrue(A.numRows() == Ad.length); for (int i = 0; i < A.numRows(); ++i) { assertTrue(A.numColumns() == Ad[i].length); for (int j = 0; j < A.numColumns(); ++j) assertEquals(Ad[i][j], A.get(i, j), 1e-12); } } /** * Checks for equality between two arrays */ protected void assertEquals(double[][] Ad, double[][] Ac) { assertTrue(Ac.length == Ad.length); for (int i = 0; i < A.numRows(); ++i) { assertTrue(Ac[i].length == Ad[i].length); for (int j = 0; j < A.numColumns(); ++j) assertEquals(Ad[i][j], Ac[i][j], 1e-12); } } protected void assertEquals(double[] xd, Vector x) { assertEquals(xd.length, x.size()); for (int i = 0; i < xd.length; ++i) assertEquals(xd[i], x.get(i), tol); } protected void assertEquals(double[] xd, double[] yd) { for (int i = 0; i < xd.length; ++i) assertEquals(xd[i], yd[i], tol); } } mtj-0.9.14/tests/no/uib/cipr/matrix/DenseMatrixTest.java0000644000000000000000000000403111166443546021631 0ustar rootroot/* * 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 no.uib.cipr.matrix.DenseMatrix; /** * Test of a dense matrix */ public class DenseMatrixTest extends MatrixTestAbstract { public DenseMatrixTest(String arg0) { super(arg0); } @Override protected void createPrimary() throws Exception { int n = Utilities.getInt(1, max); int m = Utilities.getInt(1, max); A = new DenseMatrix(n, m); Ad = Utilities.populate(A); } @Override public void testMatrixSolve() { if (A.isSquare()) super.testMatrixSolve(); } @Override public void testTransMatrixSolve() { if (A.isSquare()) super.testTransMatrixSolve(); } @Override public void testTransVectorSolve() { if (A.isSquare()) super.testTransVectorSolve(); } @Override public void testVectorSolve() { if (A.isSquare()) super.testVectorSolve(); } public void testIssue13(){ Vector bv = Matrices.random(100); Matrix am = Matrices.random(100, 50); Vector xv = new DenseVector(am.numColumns()); for (int x = 0; x < am.numColumns(); x++) { xv.set(x, 1); } xv = Matrices.random(xv.size()); xv = am.solve(bv, xv); } } mtj-0.9.14/tests/no/uib/cipr/matrix/SingularvalueTest.java0000644000000000000000000000503711027512662022226 0ustar rootroot/* * 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 no.uib.cipr.matrix.DenseMatrix; import no.uib.cipr.matrix.Matrix; import no.uib.cipr.matrix.NotConvergedException; import no.uib.cipr.matrix.SVD; import no.uib.cipr.matrix.TridiagMatrix; import junit.framework.TestCase; /** * Test the singular value solver */ public class SingularvalueTest extends TestCase { /** * Matrix to decompose */ private DenseMatrix A; /** * Maximum matrix size, to avoid too slow tests */ private final int max = 100; public SingularvalueTest(String arg0) { super(arg0); } @Override protected void setUp() throws Exception { int n = Utilities.getInt(1, max); A = new DenseMatrix(n, n); } @Override protected void tearDown() throws Exception { A = null; } public void testStaticFactorize() throws NotConvergedException { assertEquals(A, SVD.factorize(A)); } public void testFactor() throws NotConvergedException { SVD svd = new SVD(A.numRows(), A.numColumns()); assertEquals(A, svd.factor(A.copy())); } private void assertEquals(Matrix A, SVD svd) { TridiagMatrix S = new TridiagMatrix(svd.getS().length); System.arraycopy(svd.getS(), 0, S.getDiagonal(), 0, svd.getS().length); DenseMatrix U = svd.getU(); DenseMatrix Vt = svd.getVt(); // Compute U*S*Vt Matrix s = U.mult(S.mult(Vt, new DenseMatrix(S.numRows(), Vt .numColumns())), new DenseMatrix(A.numRows(), A.numColumns())); // Check that A=U*S*Vt for (int i = 0; i < A.numRows(); ++i) for (int j = 0; j < A.numColumns(); ++j) assertEquals(A.get(i, j), s.get(i, j), 1e-12); } } mtj-0.9.14/tests/no/uib/cipr/matrix/UnitLowerTriangBandMatrixTest.java0000644000000000000000000000264311027514616024455 0ustar rootroot/* * 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 no.uib.cipr.matrix.UnitLowerTriangBandMatrix; /** * Test of UnitLowerTriangBandMatrix */ public class UnitLowerTriangBandMatrixTest extends UnitTriangMatrixTestAbstract { public UnitLowerTriangBandMatrixTest(String arg0) { super(arg0); } @Override protected void createPrimary() throws Exception { int n = Utilities.getInt(1, max); int kd = Math.min(Utilities.getInt(max), Math.max(n - 1, 0)); A = new UnitLowerTriangBandMatrix(n, kd); Ad = Utilities.unitBandPopulate(A, kd, 0); Utilities.unitSet(Ad); } } mtj-0.9.14/tests/no/uib/cipr/matrix/LowerSPDDenseMatrixTest.java0000644000000000000000000000246311027514536023212 0ustar rootroot/* * 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 no.uib.cipr.matrix.LowerSPDDenseMatrix; /** * Test of LowerSPDDenseMatrix */ public class LowerSPDDenseMatrixTest extends SymmetricMatrixTestAbstract { public LowerSPDDenseMatrixTest(String arg0) { super(arg0); } @Override protected void createPrimary() throws Exception { int n = Utilities.getInt(1, max); A = new LowerSPDDenseMatrix(n); Ad = Utilities.populate(A); Utilities.lowerSymmetrice(Ad); } } mtj-0.9.14/tests/no/uib/cipr/matrix/UpperSymmBandMatrixTest.java0000644000000000000000000000261711027514432023316 0ustar rootroot/* * 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 no.uib.cipr.matrix.UpperSymmBandMatrix; /** * Test of UpperSymmBandMatrix */ public class UpperSymmBandMatrixTest extends StructImmutableMatrixTestAbstract { public UpperSymmBandMatrixTest(String arg0) { super(arg0); } @Override protected void createPrimary() throws Exception { int n = Utilities.getInt(1, max); int kd = Math.min(Utilities.getInt(max), Math.max(n - 1, 0)); A = new UpperSymmBandMatrix(n, kd); Ad = Utilities.bandPopulate(A, kd, kd); Utilities.upperSymmetrice(Ad); } } mtj-0.9.14/tests/no/uib/cipr/matrix/LowerSPDPackMatrixTest.java0000644000000000000000000000245611027514536023034 0ustar rootroot/* * 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 no.uib.cipr.matrix.LowerSPDPackMatrix; /** * Test of LowerSPDPackMatrix */ public class LowerSPDPackMatrixTest extends SymmetricMatrixTestAbstract { public LowerSPDPackMatrixTest(String arg0) { super(arg0); } @Override protected void createPrimary() throws Exception { int n = Utilities.getInt(1, max); A = new LowerSPDPackMatrix(n); Ad = Utilities.populate(A); Utilities.lowerSymmetrice(Ad); } } mtj-0.9.14/tests/no/uib/cipr/matrix/UnitLowerTriangPackMatrixTest.java0000644000000000000000000000252311027514616024464 0ustar rootroot/* * 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 no.uib.cipr.matrix.UnitLowerTriangPackMatrix; /** * Test of UnitLowerTriangPackMatrix */ public class UnitLowerTriangPackMatrixTest extends UnitTriangMatrixTestAbstract { public UnitLowerTriangPackMatrixTest(String arg0) { super(arg0); } @Override protected void createPrimary() throws Exception { int n = Utilities.getInt(1, max); A = new UnitLowerTriangPackMatrix(n); Ad = Utilities.unitLowerPopulate(A); Utilities.unitSet(Ad); } } mtj-0.9.14/tests/no/uib/cipr/matrix/LQTest.java0000644000000000000000000000466511027514476017734 0ustar rootroot/* * 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 no.uib.cipr.matrix.DenseMatrix; import no.uib.cipr.matrix.LQ; import no.uib.cipr.matrix.Matrix; /** * LQ test */ public class LQTest extends OrthogonalTestAbstract { public LQTest(String arg0) { super(arg0); } public void testStaticFactorize() { assertEquals(A, LQ.factorize(A)); } public void testRepeatStaticFactorize() { assertEquals(A, LQ.factorize(A)); assertEquals(A, LQ.factorize(A)); } public void testFactor() { LQ lq = new LQ(A.numRows(), A.numColumns()); assertEquals(A, lq.factor(new DenseMatrix(A))); } public void testRepeatFactor() { LQ lq = new LQ(A.numRows(), A.numColumns()); lq.factor(new DenseMatrix(A)); assertEquals(A, lq); lq.factor(new DenseMatrix(A)); assertEquals(A, lq); } public void testStaticFactorizeNonSquare() { assertEquals(Ac, LQ.factorize(Ac)); } public void testRepeatStaticFactorizeNonSquare() { assertEquals(Ac, LQ.factorize(Ac)); assertEquals(Ac, LQ.factorize(Ac)); } public void testFactorNonSquare() { LQ lq = new LQ(Ac.numRows(), Ac.numColumns()); assertEquals(Ac, lq.factor(new DenseMatrix(Ac))); } public void testRepeatFactorNonSquare() { LQ lq = new LQ(Ac.numRows(), Ac.numColumns()); lq.factor(new DenseMatrix(Ac)); assertEquals(Ac, lq); lq.factor(new DenseMatrix(Ac)); assertEquals(Ac, lq); } private void assertEquals(Matrix A, LQ lq) { assertEquals(A, lq.getL().mult(lq.getQ(), A.copy().zero())); } } mtj-0.9.14/tests/no/uib/cipr/matrix/StructImmutableMatrixTestAbstract.java0000644000000000000000000000565311027514432025403 0ustar rootroot/* * 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; /** * Test of a matrix whose structure cannot change, but its numerical values can */ public abstract class StructImmutableMatrixTestAbstract extends MatrixTestAbstract { public StructImmutableMatrixTestAbstract(String arg0) { super(arg0); } @Override public void testMatrixAdd() { // Not supported } @Override public void testMatrixSet() { // Not supported } @Override public void testOneMatrixAdd() { // Not supported } @Override public void testOneMatrixSet() { // Not supported } @Override public void testRandomMatrixAdd() { // Not supported } @Override public void testRandomMatrixSet() { // Not supported } @Override public void testZeroMatrixAdd() { // Not supported } @Override public void testZeroMatrixSet() { // Not supported } @Override public void testVectorRank1() { // Not supported } @Override public void testVectorRank1Dense() { // Not supported } @Override public void testVectorRank2() { // Not supported } @Override public void testVectorRank2Dense() { // Not supported } @Override public void testMatrixRank1() { // Not supported } @Override public void testMatrixRank1Dense() { // Not supported } @Override public void testMatrixTransRank1Dense() { // Not supported } @Override public void testMatrixTransRank1() { // Not supported } @Override public void testMatrixRank2() { // Not supported } @Override public void testMatrixRank2Dense() { // Not supported } @Override public void testMatrixTransRank2() { // Not supported } @Override public void testMatrixTransRank2Dense() { // Not supported } @Override public void testTranspose() { // Not supported } @Override public void testTransposeInplace() { // Not supported } } mtj-0.9.14/tests/no/uib/cipr/matrix/DenseCholeskyTest.java0000644000000000000000000000655511034472622022152 0ustar rootroot/* * 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 no.uib.cipr.matrix.DenseCholesky; import no.uib.cipr.matrix.DenseMatrix; import no.uib.cipr.matrix.LowerSPDDenseMatrix; import no.uib.cipr.matrix.Matrices; import no.uib.cipr.matrix.Matrix; import no.uib.cipr.matrix.UpperSPDDenseMatrix; import junit.framework.TestCase; /** * Tests the dense Cholesky decomposition */ public class DenseCholeskyTest extends TestCase { private LowerSPDDenseMatrix L; private UpperSPDDenseMatrix U; private DenseMatrix I; private final int max = 50; public DenseCholeskyTest(String arg0) { super(arg0); } @Override protected void setUp() throws Exception { int n = Utilities.getInt(1, max); L = new LowerSPDDenseMatrix(n); Utilities.lowerPopulate(L); Utilities.addDiagonal(L, 1); while (!Utilities.spd(L)) Utilities.addDiagonal(L, 1); U = new UpperSPDDenseMatrix(n); Utilities.upperPopulate(U); Utilities.addDiagonal(U, 1); while (!Utilities.spd(U)) Utilities.addDiagonal(U, 1); I = Matrices.identity(n); } @Override protected void tearDown() throws Exception { L = null; U = null; I = null; } public void testLowerDenseCholesky() { int n = L.numRows(); DenseCholesky c = new DenseCholesky(n, false); c.factor(L.copy()); assert I != null; c.solve(I); Matrix J = I.mult(L, new DenseMatrix(n, n)); for (int i = 0; i < n; ++i) for (int j = 0; j < n; ++j) if (i != j) assertEquals(J.get(i, j), 0, 1e-10); else assertEquals(J.get(i, j), 1, 1e-10); } public void testUpperDenseCholesky() { int n = U.numRows(); DenseCholesky c = new DenseCholesky(n, true); c.factor(U.copy()); c.solve(I); Matrix J = I.mult(U, new DenseMatrix(n, n)); for (int i = 0; i < n; ++i) for (int j = 0; j < n; ++j) if (i != j) assertEquals(J.get(i, j), 0, 1e-10); else assertEquals(J.get(i, j), 1, 1e-10); } public void testLowerDenseCholeskyrcond() { int n = L.numRows(); DenseCholesky c = new DenseCholesky(n, false); c.factor(L.copy()); c.rcond(L); } public void testUpperDenseCholeskyrcond() { int n = U.numRows(); DenseCholesky c = new DenseCholesky(n, true); c.factor(U.copy()); c.rcond(U); } } mtj-0.9.14/tests/no/uib/cipr/matrix/UpperTriangPackMatrixTest.java0000644000000000000000000000255211027514550023626 0ustar rootroot/* * 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 no.uib.cipr.matrix.UpperTriangPackMatrix; /** * Test of UpperTriangPackMatrix */ public class UpperTriangPackMatrixTest extends TriangMatrixTestAbstract { public UpperTriangPackMatrixTest(String arg0) { super(arg0); } @Override protected void createPrimary() throws Exception { int n = Utilities.getInt(1, max); A = new UpperTriangPackMatrix(n); Ad = Utilities.upperPopulate(A); // This ensures non-singularity Utilities.addDiagonal(A, Ad, 1); } } mtj-0.9.14/tests/no/uib/cipr/matrix/UnitLowerTriangDenseMatrixTest.java0000644000000000000000000000253011027514616024642 0ustar rootroot/* * 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 no.uib.cipr.matrix.UnitLowerTriangDenseMatrix; /** * Test of UnitLowerTriangDenseMatrix */ public class UnitLowerTriangDenseMatrixTest extends UnitTriangMatrixTestAbstract { public UnitLowerTriangDenseMatrixTest(String arg0) { super(arg0); } @Override protected void createPrimary() throws Exception { int n = Utilities.getInt(1, max); A = new UnitLowerTriangDenseMatrix(n); Ad = Utilities.unitLowerPopulate(A); Utilities.unitSet(Ad); } } mtj-0.9.14/tests/no/uib/cipr/matrix/UpperTriangDenseMatrixTest.java0000644000000000000000000000255711027514550024013 0ustar rootroot/* * 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 no.uib.cipr.matrix.UpperTriangDenseMatrix; /** * Test of UpperTriangDenseMatrix */ public class UpperTriangDenseMatrixTest extends TriangMatrixTestAbstract { public UpperTriangDenseMatrixTest(String arg0) { super(arg0); } @Override protected void createPrimary() throws Exception { int n = Utilities.getInt(1, max); A = new UpperTriangDenseMatrix(n); Ad = Utilities.upperPopulate(A); // This ensures non-singularity Utilities.addDiagonal(A, Ad, 1); } } mtj-0.9.14/tests/no/uib/cipr/matrix/LowerSymmDenseMatrixTest.java0000644000000000000000000000247011027514536023507 0ustar rootroot/* * 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 no.uib.cipr.matrix.LowerSymmDenseMatrix; /** * Test of LowerSymmDenseMatrix */ public class LowerSymmDenseMatrixTest extends SymmetricMatrixTestAbstract { public LowerSymmDenseMatrixTest(String arg0) { super(arg0); } @Override protected void createPrimary() throws Exception { int n = Utilities.getInt(1, max); A = new LowerSymmDenseMatrix(n); Ad = Utilities.populate(A); Utilities.lowerSymmetrice(Ad); } } mtj-0.9.14/tests/no/uib/cipr/matrix/PackCholeskyTest.java0000644000000000000000000000650511027512662021766 0ustar rootroot/* * 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 junit.framework.TestCase; import no.uib.cipr.matrix.DenseMatrix; import no.uib.cipr.matrix.LowerSPDPackMatrix; import no.uib.cipr.matrix.Matrices; import no.uib.cipr.matrix.Matrix; import no.uib.cipr.matrix.PackCholesky; import no.uib.cipr.matrix.UpperSPDPackMatrix; /** * Tests the packed Cholesky decomposition */ public class PackCholeskyTest extends TestCase { private LowerSPDPackMatrix L; private UpperSPDPackMatrix U; private DenseMatrix I; private final int max = 50; public PackCholeskyTest(String arg0) { super(arg0); } @Override protected void setUp() throws Exception { int n = Utilities.getInt(1, max); L = new LowerSPDPackMatrix(n); Utilities.lowerPopulate(L); Utilities.addDiagonal(L, 1); while (!Utilities.spd(L)) Utilities.addDiagonal(L, 1); U = new UpperSPDPackMatrix(n); Utilities.upperPopulate(U); Utilities.addDiagonal(U, 1); while (!Utilities.spd(U)) Utilities.addDiagonal(U, 1); I = Matrices.identity(n); } @Override protected void tearDown() throws Exception { L = null; U = null; I = null; } public void testLowerPackCholesky() { int n = L.numRows(); PackCholesky c = new PackCholesky(n, false); c.factor(L.copy()); c.solve(I); Matrix J = I.mult(L, new DenseMatrix(n, n)); for (int i = 0; i < n; ++i) for (int j = 0; j < n; ++j) if (i != j) assertEquals(J.get(i, j), 0, 1e-10); else assertEquals(J.get(i, j), 1, 1e-10); } public void testUpperPackCholesky() { int n = U.numRows(); PackCholesky c = new PackCholesky(n, true); c.factor(U.copy()); c.solve(I); Matrix J = I.mult(U, new DenseMatrix(n, n)); for (int i = 0; i < n; ++i) for (int j = 0; j < n; ++j) if (i != j) assertEquals(J.get(i, j), 0, 1e-10); else assertEquals(J.get(i, j), 1, 1e-10); } public void testLowerPackCholeskyrcond() { int n = L.numRows(); PackCholesky c = new PackCholesky(n, false); c.factor(L.copy()); c.rcond(L); } public void testUpperPackCholeskyrcond() { int n = U.numRows(); PackCholesky c = new PackCholesky(n, true); c.factor(U.copy()); c.rcond(U); } } mtj-0.9.14/tests/no/uib/cipr/matrix/UnitUpperTriangBandMatrixTest.java0000644000000000000000000000264311027514616024460 0ustar rootroot/* * 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 no.uib.cipr.matrix.UnitUpperTriangBandMatrix; /** * Test of UnitUpperTriangBandMatrix */ public class UnitUpperTriangBandMatrixTest extends UnitTriangMatrixTestAbstract { public UnitUpperTriangBandMatrixTest(String arg0) { super(arg0); } @Override protected void createPrimary() throws Exception { int n = Utilities.getInt(1, max); int kd = Math.min(Utilities.getInt(max), Math.max(n - 1, 0)); A = new UnitUpperTriangBandMatrix(n, kd); Ad = Utilities.unitBandPopulate(A, 0, kd); Utilities.unitSet(Ad); } } mtj-0.9.14/tests/no/uib/cipr/matrix/BandLUTest.java0000644000000000000000000000576511027512662020522 0ustar rootroot/* * 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 no.uib.cipr.matrix.BandLU; import no.uib.cipr.matrix.BandMatrix; import no.uib.cipr.matrix.DenseMatrix; import no.uib.cipr.matrix.Matrices; import no.uib.cipr.matrix.Matrix; import junit.framework.TestCase; /** * Tests the banded LU decomposition */ public class BandLUTest extends TestCase { private BandMatrix A; private DenseMatrix I; private int kl, ku; private final int max = 100, bmax = 10; public BandLUTest(String arg0) { super(arg0); } @Override protected void setUp() throws Exception { int n = Utilities.getInt(1, max); kl = Math.min(n, Utilities.getInt(bmax)); ku = Math.min(n, Utilities.getInt(bmax)); A = new BandMatrix(n, kl, kl + ku); Utilities.bandPopulate(A, kl, ku); Utilities.addDiagonal(A, 1); while (Utilities.singular(A)) Utilities.addDiagonal(A, 1); I = Matrices.identity(n); } @Override protected void tearDown() throws Exception { A = null; I = null; } public void testBandLU() { int n = A.numRows(); BandLU lu = new BandLU(n, kl, ku); lu.factor(A.copy()); lu.solve(I); Matrix J = I.mult(A, new DenseMatrix(n, n)); for (int i = 0; i < n; ++i) for (int j = 0; j < n; ++j) if (i != j) assertEquals(J.get(i, j), 0, 1e-10); else assertEquals(J.get(i, j), 1, 1e-10); } public void testBandLUtranspose() { int n = A.numRows(); BandLU lu = new BandLU(n, kl, ku); lu.factor(A.copy()); lu.transSolve(I); Matrix J = I.transAmult(A, new DenseMatrix(n, n)); for (int i = 0; i < n; ++i) for (int j = 0; j < n; ++j) if (i != j) assertEquals(J.get(i, j), 0, 1e-10); else assertEquals(J.get(i, j), 1, 1e-10); } public void testBandLUrcond() { int n = A.numRows(); BandLU lu = new BandLU(n, kl, ku); lu.factor(A.copy()); lu.rcond(A, Matrix.Norm.One); lu.rcond(A, Matrix.Norm.Infinity); } } mtj-0.9.14/tests/no/uib/cipr/matrix/SymmTridiagMatrixTest.java0000644000000000000000000000247111027514432023017 0ustar rootroot/* * 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 no.uib.cipr.matrix.SymmTridiagMatrix; /** * Test of SymmTridiagMatrix */ public class SymmTridiagMatrixTest extends StructImmutableMatrixTestAbstract { public SymmTridiagMatrixTest(String arg0) { super(arg0); } @Override protected void createPrimary() throws Exception { int n = Utilities.getInt(1, max); A = new SymmTridiagMatrix(n); Ad = Utilities.bandPopulate(A, 1, 1); Utilities.lowerSymmetrice(Ad); } } mtj-0.9.14/tests/no/uib/cipr/matrix/UnitUpperTriangPackMatrixTest.java0000644000000000000000000000252311027514616024467 0ustar rootroot/* * 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 no.uib.cipr.matrix.UnitUpperTriangPackMatrix; /** * Test of UnitUpperTriangPackMatrix */ public class UnitUpperTriangPackMatrixTest extends UnitTriangMatrixTestAbstract { public UnitUpperTriangPackMatrixTest(String arg0) { super(arg0); } @Override protected void createPrimary() throws Exception { int n = Utilities.getInt(1, max); A = new UnitUpperTriangPackMatrix(n); Ad = Utilities.unitUpperPopulate(A); Utilities.unitSet(Ad); } } mtj-0.9.14/tests/no/uib/cipr/matrix/UnitTriangMatrixTestAbstract.java0000644000000000000000000000506411027514616024343 0ustar rootroot/* * 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 no.uib.cipr.matrix.Matrix; import no.uib.cipr.matrix.MatrixEntry; /** * Test of unit, triangular matrices */ public abstract class UnitTriangMatrixTestAbstract extends TriangMatrixTestAbstract { public UnitTriangMatrixTestAbstract(String arg0) { super(arg0); } public void testAddDiagonal() { // Not applicable to unit triangular matrices } public void testAddOneDiagonal() { // Not applicable to unit triangular matrices } public void testAddZeroDiagonal() { // Not applicable to unit triangular matrices } @Override public void testIteratorSet() { double alpha = Math.random(); for (MatrixEntry e : A) if (e.row() != e.column()) e.set(e.get() * alpha); assertEquals(Utilities.unitSet(scale(alpha)), A); } @Override public void testIteratorSetGet() { // Not applicable to unit triangular matrices } @Override public void testScale() { // Not applicable to unit triangular matrices } @Override public void testZero() { // Not applicable to unit triangular matrices } @Override public void testZeroScale() { // Not applicable to unit triangular matrices } /** * We can't zero, so we do without */ @Override public void testCopy() { Matrix Ac = A.copy(); assertEquals(Ad, Ac); } @Override public void testAdd() { double alpha = Math.random(); for (MatrixEntry e : A) if (e.row() != e.column()) { A.add(e.row(), e.column(), alpha); A.add(e.row(), e.column(), -alpha); } assertEquals(Ad, A); } } mtj-0.9.14/tests/no/uib/cipr/matrix/UpperSPDDenseMatrixTest.java0000644000000000000000000000246311027514536023215 0ustar rootroot/* * 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 no.uib.cipr.matrix.UpperSPDDenseMatrix; /** * Test of UpperSPDDenseMatrix */ public class UpperSPDDenseMatrixTest extends SymmetricMatrixTestAbstract { public UpperSPDDenseMatrixTest(String arg0) { super(arg0); } @Override protected void createPrimary() throws Exception { int n = Utilities.getInt(1, max); A = new UpperSPDDenseMatrix(n); Ad = Utilities.populate(A); Utilities.upperSymmetrice(Ad); } } mtj-0.9.14/tests/no/uib/cipr/matrix/QLTest.java0000644000000000000000000000466511027514476017734 0ustar rootroot/* * 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 no.uib.cipr.matrix.DenseMatrix; import no.uib.cipr.matrix.Matrix; import no.uib.cipr.matrix.QL; /** * QL test */ public class QLTest extends OrthogonalTestAbstract { public QLTest(String arg0) { super(arg0); } public void testStaticFactorize() { assertEquals(A, QL.factorize(A)); } public void testRepeatStaticFactorize() { assertEquals(A, QL.factorize(A)); assertEquals(A, QL.factorize(A)); } public void testFactor() { QL ql = new QL(A.numRows(), A.numColumns()); assertEquals(A, ql.factor(new DenseMatrix(A))); } public void testRepeatFactor() { QL ql = new QL(A.numRows(), A.numColumns()); ql.factor(new DenseMatrix(A)); assertEquals(A, ql); ql.factor(new DenseMatrix(A)); assertEquals(A, ql); } public void testStaticFactorizeNonSquare() { assertEquals(Ar, QL.factorize(Ar)); } public void testRepeatStaticFactorizeNonSquare() { assertEquals(Ar, QL.factorize(Ar)); assertEquals(Ar, QL.factorize(Ar)); } public void testFactorNonSquare() { QL ql = new QL(Ar.numRows(), Ar.numColumns()); assertEquals(Ar, ql.factor(new DenseMatrix(Ar))); } public void testRepeatFactorNonSquare() { QL ql = new QL(Ar.numRows(), Ar.numColumns()); ql.factor(new DenseMatrix(Ar)); assertEquals(Ar, ql); ql.factor(new DenseMatrix(Ar)); assertEquals(Ar, ql); } private void assertEquals(Matrix A, QL ql) { assertEquals(A, ql.getQ().mult(ql.getL(), A.copy().zero())); } } mtj-0.9.14/tests/no/uib/cipr/matrix/QRPTest.java0000644000000000000000000001060511107366262020046 0ustar rootroot/* * Copyright (C) 2006 Rafael de Pelegrini Soares * * MTJ additions. * * 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 junit.framework.TestCase; /** * QRP test */ public class QRPTest extends TestCase { public void testIdentity() { Matrix A = Matrices.identity(5); QRP qrp = QRP.factorize(A); assertEquals(A, mult(qrp.getQ(), qrp.getPVector(), qrp.getR(), A.copy().zero())); } public void testRectangularIdentity1() { Matrix A = new DenseMatrix(5, 6); for (MatrixEntry i : A) { if (i.row() == i.column()) i.set(1); } QRP qrp = QRP.factorize(A); assertEquals(A, mult(qrp.getQ(), qrp.getPVector(), qrp.getR(), A.copy().zero())); } public void testRectangularIdentity2() { Matrix A = new DenseMatrix(6, 5); for (MatrixEntry i : A) { if (i.row() == i.column()) i.set(1); } QRP qrp = QRP.factorize(A); assertEquals(A, mult(qrp.getQ(), qrp.getPVector(), qrp.getR(), A.copy().zero())); } public void testOrthogonality() { Matrix A = Matrices.random(6, 4); QRP qrp = QRP.factorize(A); Matrix QP = qrp.getQ(); assertEquals(Matrices.identity(QP.numRows()), QP.transAmult(QP, QP.copy().zero())); } public void testOrthogonality2() { Matrix A = Matrices.random(4, 6); QRP qrp = QRP.factorize(A); Matrix QP = qrp.getQ(); assertEquals(Matrices.identity(QP.numRows()), QP.transAmult(QP, QP.copy().zero())); } public void testRandSquare() { Matrix A = Matrices.random(5, 5); QRP qrp = QRP.factorize(A); Matrix Q = qrp.getQ(); Matrix R = qrp.getR(); int P[] = qrp.getPVector(); assertEquals(A, mult(Q, P, R, A.copy().zero())); } public void testRandRectangular1() { Matrix A = Matrices.random(4, 6); QRP qrp = QRP.factorize(A); assertEquals(A, mult(qrp.getQ(), qrp.getPVector(), qrp.getR(), A.copy().zero())); } public void testRandRectangular2() { Matrix A = Matrices.random(6, 4); QRP qrp = QRP.factorize(A); assertEquals(A, mult(qrp.getQ(), qrp.getPVector(), qrp.getR(), A.copy().zero())); } public void testPivotingMatrix() { Matrix A = Matrices.random(6, 4); QRP qrp = QRP.factorize(A); Matrix Q = qrp.getQ(); Matrix R = qrp.getR(); Matrix P = qrp.getP(); Matrix C = A.copy().zero(); Matrix D = A.copy().zero(); Q.mult(R, C); C.transBmult(P, D); assertEquals(A, D); } public void testRank1() { Matrix rand = Matrices.random(6, 4); Matrix A = new DenseMatrix(rand.numRows(), rand.numRows()); rand.transBmult(rand, A); QRP qrp = QRP.factorize(A); assertEquals(Math.min(rand.numRows(), rand.numColumns()), qrp.getRank()); } public void testRank2() { Matrix rand = Matrices.random(4, 6); Matrix A = new DenseMatrix(rand.numRows(), rand.numRows()); rand.transBmult(rand, A); QRP qrp = QRP.factorize(A); assertEquals(Math.min(rand.numRows(), rand.numColumns()), qrp.getRank()); } /** * Executes the multiplication C = Q*P*R * @param Q matrix Q * @param P column permutation of R * @param R matrix R * @param C matrix tu put the results * @return the matrix C */ protected Matrix mult(Matrix Q, int[] P, Matrix R, Matrix C) { for (int i = 0; i < Q.numRows(); ++i) { for (int j = 0; j < C.numColumns(); ++j) { double dot = 0; for (int k = 0; k < Q.numColumns(); ++k) { dot += Q.get(i, k) * R.get(k, j); } C.add(i, P[j], dot); } } return C; } private static final double DELTA = 1e-12; /** * Assert that the given matrices are identical */ protected void assertEquals(Matrix A, Matrix B) { assertEquals(A.numRows(), B.numRows()); assertEquals(A.numColumns(), B.numColumns()); for (int i = 0; i < A.numRows(); ++i) { for (int j = 0; j < A.numColumns(); ++j) { assertEquals(A.get(i, j), B.get(i, j), DELTA); } } } } mtj-0.9.14/tests/no/uib/cipr/matrix/BandMatrixTest.java0000644000000000000000000000337411027514432021435 0ustar rootroot/* * 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 no.uib.cipr.matrix.BandMatrix; /** * Test of BandMatrix */ public class BandMatrixTest extends StructImmutableMatrixTestAbstract { public BandMatrixTest(String arg0) { super(arg0); } @Override protected void createPrimary() throws Exception { int n = Utilities.getInt(1, max); int kl = Math.min(Utilities.getInt(max), Math.max(n - 1, 0)); int ku = Math.min(Utilities.getInt(max), Math.max(n - 1, 0)); A = new BandMatrix(n, kl, ku); Ad = Utilities.bandPopulate(A, kl, ku); } @Override public void testTransposeInplace() { BandMatrix B = (BandMatrix) A; if (B.numSubDiagonals() == B.numSuperDiagonals()) super.testTransposeInplace(); } @Override public void testTransMatrixSolve() { // Not supported } @Override public void testTransVectorSolve() { // Not supported } } mtj-0.9.14/tests/no/uib/cipr/matrix/RQTest.java0000644000000000000000000000466311027514476017740 0ustar rootroot/* * 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 no.uib.cipr.matrix.DenseMatrix; import no.uib.cipr.matrix.Matrix; import no.uib.cipr.matrix.RQ; /** * RQ test */ public class RQTest extends OrthogonalTestAbstract { public RQTest(String arg0) { super(arg0); } public void testStaticFactorize() { assertEquals(A, RQ.factorize(A)); } public void testRepeatStaticFactorize() { assertEquals(A, RQ.factorize(A)); assertEquals(A, RQ.factorize(A)); } public void testFactor() { RQ c = new RQ(A.numRows(), A.numColumns()); assertEquals(A, c.factor(new DenseMatrix(A))); } public void testRepeatFactor() { RQ rq = new RQ(A.numRows(), A.numColumns()); rq.factor(new DenseMatrix(A)); assertEquals(A, rq); rq.factor(new DenseMatrix(A)); assertEquals(A, rq); } public void testStaticFactorizeNonSquare() { assertEquals(Ac, RQ.factorize(Ac)); } public void testRepeatStaticFactorizeNonSquare() { assertEquals(Ac, RQ.factorize(Ac)); assertEquals(Ac, RQ.factorize(Ac)); } public void testFactorNonSquare() { RQ rq = new RQ(Ac.numRows(), Ac.numColumns()); assertEquals(Ac, rq.factor(new DenseMatrix(Ac))); } public void testRepeatFactorNonSquare() { RQ rq = new RQ(Ac.numRows(), Ac.numColumns()); rq.factor(new DenseMatrix(Ac)); assertEquals(Ac, rq); rq.factor(new DenseMatrix(Ac)); assertEquals(Ac, rq); } private void assertEquals(Matrix A, RQ rq) { assertEquals(A, rq.getR().mult(rq.getQ(), A.copy().zero())); } } mtj-0.9.14/tests/no/uib/cipr/matrix/DenseLUTest.java0000644000000000000000000000754111027512662020706 0ustar rootroot/* * 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 no.uib.cipr.matrix.DenseLU; import no.uib.cipr.matrix.DenseMatrix; import no.uib.cipr.matrix.Matrices; import no.uib.cipr.matrix.Matrix; import no.uib.cipr.matrix.MatrixEntry; import junit.framework.TestCase; /** * Tests the dense LU decomposition */ public class DenseLUTest extends TestCase { /** * Matrix to decompose */ private DenseMatrix A; private DenseMatrix I; private final int max = 100; public DenseLUTest(String arg0) { super(arg0); } @Override protected void setUp() throws Exception { int n = Utilities.getInt(1, max); A = new DenseMatrix(n, n); Utilities.populate(A); Utilities.addDiagonal(A, 1); while (Utilities.singular(A)) Utilities.addDiagonal(A, 1); I = Matrices.identity(n); } @Override protected void tearDown() throws Exception { A = null; I = null; } public void testDenseLU() { int n = A.numRows(); DenseLU lu = new DenseLU(n, n); lu.factor(A.copy()); lu.solve(I); Matrix J = I.mult(A, new DenseMatrix(n, n)); for (int i = 0; i < n; ++i) for (int j = 0; j < n; ++j) if (i != j) assertEquals(J.get(i, j), 0, 1e-10); else assertEquals(J.get(i, j), 1, 1e-10); } public void testDenseLUtranspose() { int n = A.numRows(); DenseLU lu = new DenseLU(n, n); lu.factor(A.copy()); lu.transSolve(I); Matrix J = I.transAmult(A, new DenseMatrix(n, n)); for (int i = 0; i < n; ++i) for (int j = 0; j < n; ++j) if (i != j) assertEquals(J.get(i, j), 0, 1e-10); else assertEquals(J.get(i, j), 1, 1e-10); } public void testDenseLUrcond() { int n = A.numRows(); DenseLU lu = new DenseLU(n, n); lu.factor(A.copy()); lu.rcond(A, Matrix.Norm.One); lu.rcond(A, Matrix.Norm.Infinity); } public void testDenseLUToInput() { // MTJ bug in DenseLU code Matrix m = new DenseMatrix(3, 3); // -2 2 -3 // -1 1 3 // 2 0 -1 m.set(0, 0, -2); m.set(0, 1, 2); m.set(0, 2, -3); m.set(1, 0, -1); m.set(1, 1, 1); m.set(1, 2, 3); m.set(2, 0, 2); m.set(2, 1, 0); m.set(2, 2, -1); // SHOULD BE: // L: // 1.000 0.000 0.000 // -1.000 1.000 0.000 // 0.500 0.000 1.000 // // U: // -2.000 2.000 -3.000 // 0.000 2.000 -4.000 // 0.000 0.000 4.500 // // Permutation matrix: // 1.000 0.000 0.000 // 0.000 0.000 1.000 // 0.000 1.000 0.000 DenseLU dlu = DenseLU.factorize(m); // check that m = L . U Matrix lTimesU = new DenseMatrix(3, 3); dlu.getL().mult(dlu.getU(), lTimesU); int[] pivots = dlu.getPivots(); for (MatrixEntry entry : m) { int row = entry.row(); int col = entry.column(); double val = entry.get(); double valLU = pivots[row] * lTimesU.get(row, col); assert val == valLU : "Row " + row + ", Col " + col + " wasn't equal! " + val + " " + valLU; } Matrix lu = dlu.getLU(); // m == lu for (MatrixEntry entry : m) { int row = entry.row(); int col = entry.column(); double val = entry.get(); double valLU = lu.get(row, col); assert val == valLU : "Row " + row + ", Col " + col + " wasn't equal! " + val + " " + valLU; } } } mtj-0.9.14/tests/no/uib/cipr/matrix/UpperSymmPackMatrixTest.java0000644000000000000000000000246711027514536023340 0ustar rootroot/* * 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 no.uib.cipr.matrix.UpperSymmPackMatrix; /** * Test of UpperSymmPackMatrixTest */ public class UpperSymmPackMatrixTest extends SymmetricMatrixTestAbstract { public UpperSymmPackMatrixTest(String arg0) { super(arg0); } @Override protected void createPrimary() throws Exception { int n = Utilities.getInt(1, max); A = new UpperSymmPackMatrix(n); Ad = Utilities.populate(A); Utilities.upperSymmetrice(Ad); } } mtj-0.9.14/tests/no/uib/cipr/matrix/LowerTriangBandMatrixTest.java0000644000000000000000000000267211027514550023614 0ustar rootroot/* * 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 no.uib.cipr.matrix.LowerTriangBandMatrix; /** * Test of LowerTriangBandMatrix */ public class LowerTriangBandMatrixTest extends TriangMatrixTestAbstract { public LowerTriangBandMatrixTest(String arg0) { super(arg0); } @Override protected void createPrimary() throws Exception { int n = Utilities.getInt(1, max); int kd = Math.min(Utilities.getInt(max), Math.max(n - 1, 0)); A = new LowerTriangBandMatrix(n, kd); Ad = Utilities.bandPopulate(A, kd, 0); // This ensures non-singularity Utilities.addDiagonal(A, Ad, 1); } } mtj-0.9.14/tests/no/uib/cipr/matrix/LowerSymmBandMatrixTest.java0000644000000000000000000000261711034474306023316 0ustar rootroot/* * 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 no.uib.cipr.matrix.LowerSymmBandMatrix; /** * Test of LowerSymmBandMatrix */ public class LowerSymmBandMatrixTest extends StructImmutableMatrixTestAbstract { public LowerSymmBandMatrixTest(String arg0) { super(arg0); } @Override protected void createPrimary() throws Exception { int n = Utilities.getInt(1, max); int kd = Math.min(Utilities.getInt(max), Math.max(n - 1, 0)); A = new LowerSymmBandMatrix(n, kd); Ad = Utilities.bandPopulate(A, kd, kd); Utilities.lowerSymmetrice(Ad); } } mtj-0.9.14/tests/no/uib/cipr/matrix/SymmTridiagEigenvalueTest.java0000644000000000000000000000433611027514520023637 0ustar rootroot/* * 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 no.uib.cipr.matrix.Matrices; import no.uib.cipr.matrix.NotConvergedException; import no.uib.cipr.matrix.SymmTridiagEVD; import no.uib.cipr.matrix.SymmTridiagMatrix; /** * Test of the symmetric, tridiagonal eigenvalue solver */ public class SymmTridiagEigenvalueTest extends SymmEigenvalueTestAbstract { private SymmTridiagMatrix T; private final int max = 100; public SymmTridiagEigenvalueTest(String arg0) { super(arg0); } @Override protected void setUp() throws Exception { int n = Utilities.getInt(1, max); A = Matrices.random(n, n); T = new SymmTridiagMatrix(A); } public void testStaticFactorize() throws NotConvergedException { SymmTridiagEVD evd = SymmTridiagEVD.factorize(A); assertEquals(T, evd.getEigenvalues(), evd.getEigenvectors()); } public void testFactor() throws NotConvergedException { SymmTridiagEVD evd = new SymmTridiagEVD(A.numRows()); evd.factor(T.copy()); assertEquals(T, evd.getEigenvalues(), evd.getEigenvectors()); } public void testRepeatFactor() throws NotConvergedException { SymmTridiagEVD evd = new SymmTridiagEVD(A.numRows()); evd.factor(T.copy()); assertEquals(T, evd.getEigenvalues(), evd.getEigenvectors()); evd.factor(T.copy()); assertEquals(T, evd.getEigenvalues(), evd.getEigenvectors()); } } mtj-0.9.14/tests/no/uib/cipr/matrix/SymmetricMatrixTestAbstract.java0000644000000000000000000000373711027514536024241 0ustar rootroot/* * 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; /** * Test of symmetrical matrices */ public abstract class SymmetricMatrixTestAbstract extends MatrixTestAbstract { public SymmetricMatrixTestAbstract(String arg0) { super(arg0); } @Override public void testMatrixAdd() { // Not supported } @Override public void testMatrixSet() { // Not supported } @Override public void testOneMatrixAdd() { // Not supported } @Override public void testOneMatrixSet() { // Not supported } @Override public void testRandomMatrixAdd() { // Not supported } @Override public void testRandomMatrixSet() { // Not supported } @Override public void testVectorRank1() { if (A.isSquare()) { double alpha = Math.random(); assertEquals(rank1(alpha, xdR, xdR), A.rank1(alpha, xR, xR)); } } @Override public void testVectorRank1Dense() { if (A.isSquare()) { double alpha = Math.random(); assertEquals(rank1(alpha, xdR, xdR), A.rank1(alpha, xDenseR, xDenseR)); } } } mtj-0.9.14/tests/no/uib/cipr/matrix/LowerTriangDenseMatrixTest.java0000644000000000000000000000255711027514550024010 0ustar rootroot/* * 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 no.uib.cipr.matrix.LowerTriangDenseMatrix; /** * Test of LowerTriangDenseMatrix */ public class LowerTriangDenseMatrixTest extends TriangMatrixTestAbstract { public LowerTriangDenseMatrixTest(String arg0) { super(arg0); } @Override protected void createPrimary() throws Exception { int n = Utilities.getInt(1, max); A = new LowerTriangDenseMatrix(n); Ad = Utilities.lowerPopulate(A); // This ensures non-singularity Utilities.addDiagonal(A, Ad, 1); } } mtj-0.9.14/tests/no/uib/cipr/matrix/TriangMatrixTestAbstract.java0000644000000000000000000000220311027514550023470 0ustar rootroot/* * 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; /** * Test of triangular matrices */ public abstract class TriangMatrixTestAbstract extends StructImmutableMatrixTestAbstract { public TriangMatrixTestAbstract(String arg0) { super(arg0); } @Override public void testTransposeInplace() { // Not supported } } mtj-0.9.14/tests/no/uib/cipr/matrix/UpperSymmDenseMatrixTest.java0000644000000000000000000000247011027514536023512 0ustar rootroot/* * 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 no.uib.cipr.matrix.UpperSymmDenseMatrix; /** * Test of UpperSymmDenseMatrix */ public class UpperSymmDenseMatrixTest extends SymmetricMatrixTestAbstract { public UpperSymmDenseMatrixTest(String arg0) { super(arg0); } @Override protected void createPrimary() throws Exception { int n = Utilities.getInt(1, max); A = new UpperSymmDenseMatrix(n); Ad = Utilities.populate(A); Utilities.upperSymmetrice(Ad); } } mtj-0.9.14/tests/no/uib/cipr/matrix/LowerSymmPackMatrixTest.java0000644000000000000000000000246311027514536023331 0ustar rootroot/* * 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 no.uib.cipr.matrix.LowerSymmPackMatrix; /** * Test of LowerSymmPackMatrix */ public class LowerSymmPackMatrixTest extends SymmetricMatrixTestAbstract { public LowerSymmPackMatrixTest(String arg0) { super(arg0); } @Override protected void createPrimary() throws Exception { int n = Utilities.getInt(1, max); A = new LowerSymmPackMatrix(n); Ad = Utilities.populate(A); Utilities.lowerSymmetrice(Ad); } } mtj-0.9.14/tests/no/uib/cipr/matrix/UnitUpperTriangDenseMatrixTest.java0000644000000000000000000000252511027514616024651 0ustar rootroot/* * 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 no.uib.cipr.matrix.UnitUpperTriangDenseMatrix; /** * Test of UnitUpperTriangDenseMatrix */ public class UnitUpperTriangDenseMatrixTest extends UnitTriangMatrixTestAbstract { public UnitUpperTriangDenseMatrixTest(String arg0) { super(arg0); } @Override protected void createPrimary() throws Exception { int n = Utilities.getInt(max); A = new UnitUpperTriangDenseMatrix(n); Ad = Utilities.unitUpperPopulate(A); Utilities.unitSet(Ad); } } mtj-0.9.14/tests/no/uib/cipr/matrix/SymmDenseEigenvalueTest.java0000644000000000000000000000620111027514520023303 0ustar rootroot/* * 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 no.uib.cipr.matrix.LowerSymmDenseMatrix; import no.uib.cipr.matrix.NotConvergedException; import no.uib.cipr.matrix.SymmDenseEVD; import no.uib.cipr.matrix.UpperSymmDenseMatrix; /** * Test of the symmetric, dense eigenvalue solver */ public class SymmDenseEigenvalueTest extends SymmEigenvalueTestAbstract { private LowerSymmDenseMatrix L; private UpperSymmDenseMatrix U; public SymmDenseEigenvalueTest(String arg0) { super(arg0); } @Override protected void setUp() throws Exception { super.setUp(); L = new LowerSymmDenseMatrix(A); U = new UpperSymmDenseMatrix(A); } @Override protected void tearDown() throws Exception { super.tearDown(); L = null; U = null; } public void testLowerStaticFactorize() throws NotConvergedException { SymmDenseEVD evd = SymmDenseEVD.factorize(L); assertEquals(L, evd.getEigenvalues(), evd.getEigenvectors()); } public void testUpperStaticFactorize() throws NotConvergedException { SymmDenseEVD evd = SymmDenseEVD.factorize(U); assertEquals(U, evd.getEigenvalues(), evd.getEigenvectors()); } public void testLowerFactor() throws NotConvergedException { SymmDenseEVD evd = new SymmDenseEVD(A.numRows(), false); evd.factor(L.copy()); assertEquals(L, evd.getEigenvalues(), evd.getEigenvectors()); } public void testUpperFactor() throws NotConvergedException { SymmDenseEVD evd = new SymmDenseEVD(A.numRows(), true); evd.factor(U.copy()); assertEquals(U, evd.getEigenvalues(), evd.getEigenvectors()); } public void testLowerRepeatFactor() throws NotConvergedException { SymmDenseEVD evd = new SymmDenseEVD(A.numRows(), false); evd.factor(L.copy()); assertEquals(L, evd.getEigenvalues(), evd.getEigenvectors()); evd.factor(L.copy()); assertEquals(L, evd.getEigenvalues(), evd.getEigenvectors()); } public void testUpperRepeatFactor() throws NotConvergedException { SymmDenseEVD evd = new SymmDenseEVD(A.numRows(), true); evd.factor(U.copy()); assertEquals(U, evd.getEigenvalues(), evd.getEigenvectors()); evd.factor(U.copy()); assertEquals(U, evd.getEigenvalues(), evd.getEigenvectors()); } } mtj-0.9.14/build.xml0000644000000000000000000000145511554373176012737 0ustar rootroot Builds, tests, and runs the project Matrix Toolkits for Java. mtj-0.9.14/manifest.mf0000644000000000000000000000012211027512662013224 0ustar rootrootManifest-Version: 1.0 X-COMMENT: Main-Class will be added automatically by build