📄 matrix.java
字号:
// Matrix - simple double matrix class
//
// Copyright (C)1996,2000 by Jef Poskanzer <jef@acme.com>. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE.
//
// Visit the ACME Labs Java page for up-to-date versions of this and other
// fine Java utilities: http://www.acme.com/java/
package Acme;
import java.util.*;
/// Simple double matrix class.
// <P>
// <A HREF="/resources/classes/Acme/Matrix.java">Fetch the software.</A><BR>
// <A HREF="/resources/classes/Acme.tar.gz">Fetch the entire Acme package.</A>
public class Matrix
{
private int rows, cols;
private double values[][];
// Constructor - create a matrix of a given size, initialized to all zero.
public Matrix( int rows, int cols ) throws ArithmeticException
{
this( rows, cols, 0.0 );
}
// Constructor - create a matrix of a given size, initialized to a value.
public Matrix( int rows, int cols, double value ) throws ArithmeticException
{
if ( rows <= 0 || cols <= 0 )
throw new ArithmeticException();
this.rows = rows;
this.cols = cols;
values = new double[rows][cols];
for ( int row = 0; row < rows; ++row )
for ( int col = 0; col < cols; ++col )
values[row][col] = value;
}
/// Constructor - create an identity matrix.
public Matrix( int size ) throws ArithmeticException
{
this( size, size );
for ( int i = 0; i < size; ++i )
values[i][i] = 1.0;
}
/// Constructor - copy a matrix.
public Matrix( Matrix o ) throws ArithmeticException
{
this( o.rows, o.cols );
for ( int row = 0; row < rows; ++row )
for ( int col = 0; col < cols; ++col )
values[row][col] = o.values[row][col];
}
/// Get the row count.
public int getRows()
{
return rows;
}
/// Get the column count.
public int getCols()
{
return cols;
}
/// Get an element.
public double get( int row, int col )
{
return values[row][col];
}
/// Set an element.
public void set( int row, int col, double value )
{
values[row][col] = value;
}
/// Equality test.
public boolean equals( Object o )
{
if ( o == null || ! ( o instanceof Matrix ))
return false;
Matrix m = (Matrix) o;
if ( m.rows != rows || m.cols != cols )
return false;
for ( int row = 0; row < rows; ++row )
for ( int col = 0; col < cols; ++col )
if ( m.values[row][col] != values[row][col] )
return false;
return true;
}
/// Compute a hash code for the matrix.
public int hashCode()
{
int h = 0;
for ( int row = 0; row < rows; ++row )
for ( int col = 0; col < cols; ++col )
{
Double d = new Double( values[row][col] );
h = h ^ d.hashCode();
}
return h;
}
/// Convert to a string.
public String toString()
{
return Acme.Utils.arrayToString( values );
}
/// Compute the sum of all the elements.
public double sum()
{
double s = 0.0;
for ( int row = 0; row < rows; ++row )
for ( int col = 0; col < cols; ++col )
s += values[row][col];
return s;
}
/// Compute the mean of all the elements.
public double mean()
{
return sum() / ( rows * cols );
}
/// Find the largest element.
public double max()
{
double m = values[0][0];
for ( int row = 0; row < rows; ++row )
for ( int col = 0; col < cols; ++col )
if ( values[row][col] > m )
m = values[row][col];
return m;
}
/// Find the smallest element.
public double min()
{
double m = values[0][0];
for ( int row = 0; row < rows; ++row )
for ( int col = 0; col < cols; ++col )
if ( values[row][col] < m )
m = values[row][col];
return m;
}
/// Swap rows in a matrix.
public void swapRows( int r1, int r2 )
{
double t;
for ( int col = 0; col < cols; ++col )
{
t = values[r1][col];
values[r1][col] = values[r2][col];
values[r2][col] = t;
}
}
/// Swap columns in a matrix.
public void swapCols( int c1, int c2 )
{
double t;
for ( int row = 0; row < rows; ++row )
{
t = values[row][c1];
values[row][c1] = values[row][c2];
values[row][c2] = t;
}
}
/// Transpose a matrix.
public static Matrix transpose( Matrix m )
{
Matrix result = new Matrix( m.cols, m.rows );
for ( int row = 0; row < m.rows; ++row )
for ( int col = 0; col < m.cols; ++col )
result.values[col][row] = m.values[row][col];
return result;
}
/// Add two matricies.
public static Matrix add( Matrix a, Matrix b ) throws ArithmeticException
{
if ( a.rows != b.rows || a.cols != b.cols )
throw new ArithmeticException();
Matrix result = new Matrix( a.rows, a.cols );
for ( int row = 0; row < a.rows; ++row )
for ( int col = 0; col < a.cols; ++col )
result.values[row][col] =
a.values[row][col] + b.values[row][col];
return result;
}
/// Subtract one matrix from another.
public static Matrix subtract( Matrix a, Matrix b ) throws ArithmeticException
{
if ( a.rows != b.rows || a.cols != b.cols )
throw new ArithmeticException();
Matrix result = new Matrix( a.rows, a.cols );
for ( int row = 0; row < a.rows; ++row )
for ( int col = 0; col < a.cols; ++col )
result.values[row][col] =
a.values[row][col] - b.values[row][col];
return result;
}
/// Multiply a matrix by a scalar.
public static Matrix multiply( Matrix a, double b )
{
Matrix result = new Matrix( a.rows, a.cols );
for ( int row = 0; row < a.rows; ++row )
for ( int col = 0; col < a.cols; ++col )
result.values[row][col] = a.values[row][col] * b;
return result;
}
/// Multiply a scalar by a matrix.
public static Matrix multiply( double a, Matrix b )
{
return Matrix.multiply( b, a );
}
/// Multiply two matricies.
public static Matrix multiply( Matrix a, Matrix b ) throws ArithmeticException
{
if ( a.cols != b.rows )
throw new ArithmeticException();
Matrix result = new Matrix( a.rows, b.cols );
for ( int row = 0; row < a.rows; ++row )
for ( int col = 0; col < b.cols; ++col )
{
double sum = 0.0;
for ( int i = 0; i < a.cols; ++i )
sum += a.values[row][i] * b.values[i][col];
result.values[row][col] = sum;
}
return result;
}
/// Solve ax=b using Gaussian elimination. The matrix a must be square,
// and b must be a vector with the same number of rows as a. Returns
// another vector of the same size as b.
public static Matrix solve( Matrix a, Matrix b ) throws ArithmeticException
{
int i, j, k;
double t;
if ( a.rows != a.cols || a.cols != b.rows || b.cols != 1 )
throw new ArithmeticException();
int n = a.rows;
a = new Matrix( a );
b = new Matrix( b );
Matrix x = new Matrix( n, 1 );
// Elimination with partial pivoting.
for ( i = 0; i < n; ++i )
{
// Find the largest pivot in a.
int max = i;
for ( j = i + 1; j < n; ++j )
if ( Math.abs( a.values[j][i] ) > Math.abs( a.values[max][i] ) )
max = j;
if ( a.values[max][i] == 0.0 )
throw new ArithmeticException();
// Exchange rows i and max in both a and b.
a.swapRows( i, max );
b.swapRows( i, max );
// And eliminate.
for ( j = i + 1; j < n; ++j )
{
t = a.values[j][i] / a.values[i][i];
for ( k = n - 1; k >= i; --k )
a.values[j][k] -= a.values[i][k] * t;
b.values[j][0] -= b.values[i][0] * t;
}
}
// Back-substitution.
for ( j = n - 1; j >= 0; --j )
{
t = 0.0;
for ( k = j + 1; k < n; ++k )
t += a.values[j][k] * x.values[k][0];
x.values[j][0] = ( b.values[j][0] - t ) / a.values[j][j];
}
return x;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -