📄 matrices.java
字号:
/* * 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 } /** * <code>max(1, M)</code> provided as a convenience for 'leading dimension' calculations. * * @param n */ static int ld(int n) { return Math.max(1, n); } /** * <code>max(1, max(M, N))</code> 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 * <code>set(int, double)</code> and <code>add(int, double)</code> * methods and their blocked versions are synchronized. * <p> * <b>Note: </b> 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 <code>x</code> */ public static Vector synchronizedVector(Vector x) { return new SynchronizedVector(x); } /** * Returns a synchronized matrix which wraps the given matrix. Only the * <code>set(int, int, double)</code> and * <code>add(int, int, double)</code> methods and their blocked versions * are synchronized. * <p> * <b>Note: </b> 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 <code>A</code> */ public static Matrix synchronizedMatrix(Matrix A) { return new SynchronizedMatrix(A); } /** * Returns a synchronized matrix which wraps the given matrix. Only the * <code>set(int, int, double)</code> and * <code>add(int, int, double)</code> methods and their blocked versions * are synchronized. * <p> * 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, * <i>not </i> for column-major matrices. * <p> * <b>Note: </b> 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 <code>A</code>. 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 * <code>set(int, int, double)</code> and * <code>add(int, int, double)</code> methods and their blocked versions * are synchronized. * <p> * 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, <i>not </i> for row-major matrices. * <p> * <b>Note: </b> 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 <code>A</code>. 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 <code>A</code> * @param column * Columns to access. Must be within the bounds of <code>A</code> * @return Submatrix of <code>A</code>. 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 <code>x</code> * @return Submatrix of <code>x</code>. 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 <code>getSubMatrix</code> */ 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 <code>getSubVector</code> */ 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]);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -