📄 matrix.java
字号:
/* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *//* * Matrix.java * Copyright (C) 1999 Yong Wang, Eibe Frank, Len Trigg, Gabi Schmidberger * * The code contains some functions from the CERN Jet Java libraries * for these the following copyright applies: * * Copyright (C) 1999 CERN - European Organization for Nuclear Research. * Permission to use, copy, modify, distribute and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting documentation. * CERN and the University of Waikato make no representations about the * suitability of this software for any purpose. * It is provided "as is" without expressed or implied warranty. * */package weka.core;import java.io.Writer;import java.io.Reader;import java.io.LineNumberReader;import java.io.Serializable;import java.util.StringTokenizer;/** * Class for performing operations on a matrix of floating-point values. * * @author Gabi Schmidberger (gabi@cs.waikato.ac.nz) * @author Yong Wang (yongwang@cs.waikato.ac.nz) * @author Eibe Frank (eibe@cs.waikato.ac.nz) * @author Len Trigg (eibe@cs.waikato.ac.nz) * @version $Revision: 1.1.1.1 $ */public class Matrix implements Cloneable, Serializable { /** * The values of the matrix */ protected double [][] m_Elements; /** * Constructs a matrix and initializes it with default values. * * @param nr the number of rows * @param nc the number of columns */ public Matrix(int nr, int nc) { m_Elements = new double[nr][nc]; initialize(); } /** * Constructs a matrix using a given array. * * @param array the values of the matrix */ public Matrix(double[][] array) throws Exception { m_Elements = new double[array.length][array[0].length]; for (int i = 0; i < array.length; i++) { for (int j = 0; j < array[0].length; j++) { m_Elements[i][j] = array[i][j]; } } } /** * Reads a matrix from a reader. The first line in the file should * contain the number of rows and columns. Subsequent lines * contain elements of the matrix. * * @param r the reader containing the matrix * @exception Exception if an error occurs */ public Matrix(Reader r) throws Exception { LineNumberReader lnr = new LineNumberReader(r); String line; int currentRow = -1; while ((line = lnr.readLine()) != null) { if (line.startsWith("%")) { // Comments continue; } StringTokenizer st = new StringTokenizer(line); if (!st.hasMoreTokens()) { // Ignore blank lines continue; } if (currentRow < 0) { int rows = Integer.parseInt(st.nextToken()); if (!st.hasMoreTokens()) { throw new Exception("Line " + lnr.getLineNumber() + ": expected number of columns"); } int cols = Integer.parseInt(st.nextToken()); m_Elements = new double [rows][cols]; initialize(); currentRow ++; continue; } else { if (currentRow == numRows()) { throw new Exception("Line " + lnr.getLineNumber() + ": too many rows provided"); } for (int i = 0; i < numColumns(); i++) { if (!st.hasMoreTokens()) { throw new Exception("Line " + lnr.getLineNumber() + ": too few matrix elements provided"); } m_Elements[currentRow][i] = Double.valueOf(st.nextToken()) .doubleValue(); } currentRow ++; } } if (currentRow == -1) { throw new Exception("Line " + lnr.getLineNumber() + ": expected number of rows"); } else if (currentRow != numRows()) { throw new Exception("Line " + lnr.getLineNumber() + ": too few rows provided"); } } /** * Creates and returns a clone of this object. * * @return a clone of this instance. * @exception CloneNotSupportedException if an error occurs */ public Object clone() throws CloneNotSupportedException { Matrix m = (Matrix)super.clone(); m.m_Elements = new double[numRows()][numColumns()]; for (int r = 0; r < numRows(); r++) { for (int c = 0; c < numColumns(); c++) { m.m_Elements[r][c] = m_Elements[r][c]; } } return m; } /** * Writes out a matrix. * * @param w the output Writer * @exception Exception if an error occurs */ public void write(Writer w) throws Exception { w.write("% Rows\tColumns\n"); w.write("" + numRows() + "\t" + numColumns() + "\n"); w.write("% Matrix elements\n"); for(int i = 0; i < numRows(); i++) { for(int j = 0; j < numColumns(); j++) { w.write("" + m_Elements[i][j] + "\t"); } w.write("\n"); } w.flush(); } /** * Resets the elements to default values (i.e. 0). */ protected void initialize() { for (int i = 0; i < numRows(); i++) { for (int j = 0; j < numColumns(); j++) { m_Elements[i][j] = 0; } } } /** * Returns the value of a cell in the matrix. * * @param rowIndex the row's index * @param columnIndex the column's index * @return the value of the cell of the matrix */ public final double getElement(int rowIndex, int columnIndex) { return m_Elements[rowIndex][columnIndex]; } /** * Add a value to an element. * * @param rowIndex the row's index. * @param columnIndex the column's index. * @param value the value to add. */ public final void addElement(int rowIndex, int columnIndex, double value) { m_Elements[rowIndex][columnIndex] += value; } /** * Returns the number of rows in the matrix. * * @return the number of rows */ public final int numRows() { return m_Elements.length; } /** * Returns the number of columns in the matrix. * * @return the number of columns */ public final int numColumns() { return m_Elements[0].length; } /** * Sets an element of the matrix to the given value. * * @param rowIndex the row's index * @param columnIndex the column's index * @param value the value */ public final void setElement(int rowIndex, int columnIndex, double value) { m_Elements[rowIndex][columnIndex] = value; } /** * Sets a row of the matrix to the given row. Performs a deep copy. * * @param index the row's index * @param newRow an array of doubles */ public final void setRow(int index, double[] newRow) { for (int i = 0; i < newRow.length; i++) { m_Elements[index][i] = newRow[i]; } } /** * Gets a row of the matrix and returns it as double array. * * @param index the row's index * @return an array of doubles */ public double[] getRow(int index) { double [] newRow = new double[this.numColumns()]; for (int i = 0; i < newRow.length; i++) { newRow[i] = m_Elements[index][i]; } return newRow; } /** * Gets a column of the matrix and returns it as a double array. * * @param index the column's index * @return an array of doubles */ public double[] getColumn(int index) { double [] newColumn = new double[this.numRows()]; for (int i = 0; i < newColumn.length; i++) { newColumn[i] = m_Elements[i][index]; } return newColumn; } /** * Sets a column of the matrix to the given column. Performs a deep copy. * * @param index the column's index * @param newColumn an array of doubles */ public final void setColumn(int index, double[] newColumn) { for (int i = 0; i < m_Elements.length; i++) { m_Elements[i][index] = newColumn[i]; } } /** * Converts a matrix to a string * * @return the converted string */ public String toString() { // Determine the width required for the maximum element, // and check for fractional display requirement. double maxval = 0; boolean fractional = false; for(int i = 0; i < m_Elements.length; i++) { for(int j = 0; j < m_Elements[i].length; j++) { double current = m_Elements[i][j]; if (current < 0) { current *= -10; } if (current > maxval) { maxval = current; } double fract = current - Math.rint(current); if (!fractional && ((Math.log(fract) / Math.log(10)) >= -2)) { fractional = true; } } } int width = (int)(Math.log(maxval) / Math.log(10) + (fractional ? 4 : 1)); StringBuffer text = new StringBuffer(); for(int i = 0; i < m_Elements.length; i++) { for(int j = 0; j < m_Elements[i].length; j++) { text.append(" ").append(Utils.doubleToString(m_Elements[i][j], width, (fractional ? 2 : 0))); } text.append("\n"); } return text.toString(); } /** * Returns the sum of this matrix with another. * * @return a matrix containing the sum. */ public final Matrix add(Matrix other) { int nr = m_Elements.length, nc = m_Elements[0].length; Matrix b; try { b = (Matrix)clone(); } catch (CloneNotSupportedException ex) { b = new Matrix(nr, nc); } for(int i = 0;i < nc; i++) { for(int j = 0; j < nr; j++) { b.m_Elements[i][j] = m_Elements[j][i] + other.m_Elements[j][i]; } } return b; } /** * Returns the transpose of a matrix. * * @return the transposition of this instance. */ public final Matrix transpose() { int nr = m_Elements.length, nc = m_Elements[0].length; Matrix b = new Matrix(nc, nr); for(int i = 0;i < nc; i++) { for(int j = 0; j < nr; j++) { b.m_Elements[i][j] = m_Elements[j][i]; } } return b; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -