/*
* 操作矩阵的类 Matrix
*
* 周长发编制
*/
package javaalgorithm.algorithm;
/**
* 操作矩阵的类 Matrix
* @author 周长发
* @version 1.0
*/
public class Matrix
{
private int numColumns = 0; // 矩阵列数
private int numRows = 0; // 矩阵行数
private double eps = 0.0; // 缺省精度
private double[] elements = null; // 矩阵数据缓冲区
/**
* 基本构造函数
*/
public Matrix()
{
numColumns = 1;
numRows = 1;
init(numRows, numColumns);
}
/**
* 指定行列构造函数
*
* @param nRows - 指定的矩阵行数
* @param nCols - 指定的矩阵列数
*/
public Matrix(int nRows, int nCols)
{
numRows = nRows;
numColumns = nCols;
init(numRows, numColumns);
}
/**
* 指定值构造函数
*
* @param nRows - 指定的矩阵行数
* @param nCols - 指定的矩阵列数
* @param value - 一维数组,长度为nRows*nCols,存储矩阵各元素的值
*/
public Matrix(int nRows, int nCols, double[] value)
{
numRows = nRows;
numColumns = nCols;
init(numRows, numColumns);
setData(value);
}
/**
* 方阵构造函数
*
* @param nSize - 方阵行列数
*/
public Matrix(int nSize)
{
numRows = nSize;
numColumns = nSize;
init(nSize, nSize);
}
/**
* 方阵构造函数
*
* @param nSize - 方阵行列数
* @param value - 一维数组,长度为nRows*nRows,存储方阵各元素的值
*/
public Matrix(int nSize, double[] value)
{
numRows = nSize;
numColumns = nSize;
init(nSize, nSize);
setData(value);
}
/**
* 拷贝构造函数
*
* @param other - 源矩阵
*/
public Matrix( Matrix other)
{
numColumns = other.getNumColumns();
numRows = other.getNumRows();
init(numRows, numColumns);
setData(other.elements);
}
/**
* 初始化函数
*
* @param nRows - 指定的矩阵行数
* @param nCols - 指定的矩阵列数
* @return boolean, 成功返回true, 否则返回false
*/
public boolean init(int nRows, int nCols)
{
numRows = nRows;
numColumns = nCols;
int nSize = nCols*nRows;
if (nSize < 0)
return false;
// 分配内存
elements = new double[nSize];
return true;
}
/**
* 设置矩阵运算的精度
*
* @param newEps - 新的精度值
*/
public void setEps(double newEps)
{
eps = newEps;
}
/**
* 取矩阵的精度值
*
* @return double型,矩阵的精度值
*/
public double getEps()
{
return eps;
}
/**
* 将方阵初始化为单位矩阵
*
* @param nSize - 方阵行列数
* @return boolean 型,初始化是否成功
*/
public boolean makeUnitMatrix(int nSize)
{
if (! init(nSize, nSize))
return false;
for (int i=0; i<nSize; ++i)
for (int j=0; j<nSize; ++j)
if (i == j)
setElement(i, j, 1);
return true;
}
/**
* 将矩阵各元素的值转化为字符串, 元素之间的分隔符为",", 行与行之间有回车换行符
* @return String 型,转换得到的字符串
*/
public String toString()
{
return toString(",", true);
}
/**
* 将矩阵各元素的值转化为字符串
*
* @param sDelim - 元素之间的分隔符
* @param bLineBreak - 行与行之间是否有回车换行符
* @return String 型,转换得到的字符串
*/
public String toString(String sDelim, boolean bLineBreak)
{
String s="";
for (int i=0; i<numRows; ++i)
{
for (int j=0; j<numColumns; ++j)
{
String ss = new Float(getElement(i, j)).toString();
s += ss;
if (bLineBreak)
{
if (j != numColumns-1)
s += sDelim;
}
else
{
if (i != numRows-1 || j != numColumns-1)
s += sDelim;
}
}
if (bLineBreak)
if (i != numRows-1)
s += "\r\n";
}
return s;
}
/**
* 将矩阵指定行中各元素的值转化为字符串
*
* @param nRow - 指定的矩阵行,nRow = 0表示第一行
* @param sDelim - 元素之间的分隔符
* @return String 型,转换得到的字符串
*/
public String toStringRow(int nRow, String sDelim)
{
String s = "";
if (nRow >= numRows)
return s;
for (int j=0; j<numColumns; ++j)
{
String ss = new Float(getElement(nRow, j)).toString();
s += ss;
if (j != numColumns-1)
s += sDelim;
}
return s;
}
/**
* 将矩阵指定列中各元素的值转化为字符串
*
* @param nCol - 指定的矩阵行,nCol = 0表示第一列
* @param sDelim - 元素之间的分隔符
* @return String 型,转换得到的字符串
*/
public String toStringCol(int nCol, String sDelim /*= " "*/)
{
String s = "";
if (nCol >= numColumns)
return s;
for (int i=0; i<numRows; ++i)
{
String ss = new Float(getElement(i, nCol)).toString();
s += ss;
if (i != numRows-1)
s += sDelim;
}
return s;
}
/**
* 设置矩阵各元素的值
*
* @param value - 一维数组,长度为numColumns*numRows,存储
* 矩阵各元素的值
*/
public void setData(double[] value)
{
elements = (double[])value.clone();
}
/**
* 设置指定元素的值
*
* @param nRow - 元素的行
* @param nCol - 元素的列
* @param value - 指定元素的值
* @return boolean 型,说明设置是否成功
*/
public boolean setElement(int nRow, int nCol, double value)
{
if (nCol < 0 || nCol >= numColumns || nRow < 0 || nRow >= numRows)
return false; // array bounds error
elements[nCol + nRow * numColumns] = value;
return true;
}
/**
* 获取指定元素的值
*
* @param nRow - 元素的行
* @param nCol - 元素的列
* @return double 型,指定元素的值
*/
public double getElement(int nRow, int nCol)
{
return elements[nCol + nRow * numColumns] ;
}
/**
* 获取矩阵的列数
*
* @return int 型,矩阵的列数
*/
public int getNumColumns()
{
return numColumns;
}
/**
* 获取矩阵的行数
* @return int 型,矩阵的行数
*/
public int getNumRows()
{
return numRows;
}
/**
* 获取矩阵的数据
*
* @return double型数组,指向矩阵各元素的数据缓冲区
*/
public double[] getData()
{
return elements;
}
/**
* 获取指定行的向量
*
* @param nRow - 向量所在的行
* @param pVector - 指向向量中各元素的缓冲区
* @return int 型,向量中元素的个数,即矩阵的列数
*/
public int getRowVector(int nRow, double[] pVector)
{
for (int j=0; j<numColumns; ++j)
pVector[j] = getElement(nRow, j);
return numColumns;
}
/**
* 获取指定列的向量
*
* @param nCol - 向量所在的列
* @param pVector - 指向向量中各元素的缓冲区
* @return int 型,向量中元素的个数,即矩阵的行数
*/
public int getColVector(int nCol, double[] pVector)
{
for (int i=0; i<numRows; ++i)
pVector[i] = getElement(i, nCol);
return numRows;
}
/**
* 给矩阵赋值
*
* @param other - 用于给矩阵赋值的源矩阵
* @return Matrix型,阵与other相等
*/
public Matrix setValue(Matrix other)
{
if (other != this)
{
init(other.getNumRows(), other.getNumColumns());
setData(other.elements);
}
// finally return a reference to ourselves
return this ;
}
/**
* 判断矩阵否相等
*
* @param other - 用于比较的矩阵
* @return boolean 型,两个矩阵相等则为true,否则为false
*/
public boolean equal(Matrix other)
{
// 首先检查行列数是否相等
if (numColumns != other.getNumColumns() || numRows != other.getNumRows())
return false;
for (int i=0; i<numRows; ++i)
{
for (int j=0; j<numColumns; ++j)
{
if (Math.abs(getElement(i, j) - other.getElement(i, j)) > eps)
return false;
}
}
return true;
}
/**
* 实现矩阵的加法
*
* @param other - 与指定矩阵相加的矩阵
* @return Matrix型,指定矩阵与other相加之和
*/
public Matrix add(Matrix other)
{
// 首先检查行列数是否相等
if (numColumns != other.getNumColumns() ||
numRows != other.getNumRows())
return null;
// 构造结果矩阵
Matrix result = new Matrix(this) ; // 拷贝构造
// 矩阵加法
for (int i = 0 ; i < numRows ; ++i)
{
for (int j = 0 ; j < numColumns; ++j)
result.setElement(i, j, result.getElement(i, j) + other.getElement(i, j)) ;
}
return