⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 matrix.cs

📁 工程上可以直接使用的关于数值计算方法的原代码
💻 CS
📖 第 1 页 / 共 5 页
字号:
/*
 * 操作矩阵的类 Matrix
 * 
 * 周长发编制
 */

using System;

namespace CSharpAlgorithm.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 int Columns
		{
			get
			{
				return numColumns;
			}
		}

		/**
		 * 属性: 矩阵行数
		 */
		public int Rows
		{
			get
			{
				return numRows;
			}
		}

		/**
		 * 索引器: 访问矩阵元素
		 * @param row - 元素的行
		 * @param col - 元素的列
		 */
		public double this[int row, int col]
		{
			get
			{
				return elements[col + row * numColumns]; 
			}
			set
			{
				elements[col + row * numColumns] = value;
			}
		}

		/**
		 * 属性: Eps
		 */
		public double Eps
		{
			get
			{
				return eps;
			}
			set
			{
				eps = value;
			}
		}

		/**
		 * 基本构造函数
		 */
		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 value - 二维数组,存储矩阵各元素的值
		 */
		public Matrix(double[,] value)
		{
			numRows = value.GetLength(0);
			numColumns = value.GetLength(1);
			double[] data = new double[numRows * numColumns];
			int k = 0;
			for (int i=0; i<numRows; ++i)
			{
				for (int j=0; j<numColumns; ++j)
				{
					data[k++] = value[i, j]; 
				}
			}
			Init(numRows, numColumns);
			SetData(data);
		}

		/**
		 * 指定值构造函数
		 * 
		 * @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 bool, 成功返回true, 否则返回false
		 */
		public bool 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;
		}

		/**
		 * 重载 + 运算符
		 * 
		 * @return Matrix对象
		 */
		public static Matrix operator +(Matrix m1, Matrix m2)
		{
			return m1.Add(m2);
		}

		/**
		 * 重载 - 运算符
		 * 
		 * @return Matrix对象
		 */
		public static Matrix operator -(Matrix m1, Matrix m2)
		{
			return m1.Subtract(m2);
		}

		/**
		 * 重载 * 运算符
		 * 
		 * @return Matrix对象
		 */
		public static Matrix operator *(Matrix m1, Matrix m2)
		{
			return m1.Multiply(m2);
		}

		/**
		 * 重载 double[] 运算符
		 * 
		 * @return double[]对象
		 */
		public static implicit operator double[](Matrix m)
		{
			return m.elements;
		}

		/**
		 * 将方阵初始化为单位矩阵
		 * 
		 * @param nSize - 方阵行列数
		 * @return bool 型,初始化是否成功
		 */
		public bool 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 override string ToString() 
		{
			return ToString(",", true);
		}
	
		/**
		 * 将矩阵各元素的值转化为字符串
		 * 
		 * @param sDelim - 元素之间的分隔符
		 * @param bLineBreak - 行与行之间是否有回车换行符
		 * @return string 型,转换得到的字符串
		 */
		public string ToString(string sDelim, bool bLineBreak) 
		{
			string s="";

			for (int i=0; i<numRows; ++i)
			{
				for (int j=0; j<numColumns; ++j)
				{
					string ss = GetElement(i, j).ToString("F");
					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 = GetElement(nRow, j).ToString("F");
				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 = GetElement(i, nCol).ToString("F");
				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 bool 型,说明设置是否成功
		 */
		public bool 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 bool 型,两个矩阵相等则为true,否则为false
		 */
		public override bool Equals(object other) 
		{
			Matrix matrix = other as Matrix;
			if (matrix == null)
				return false;

			// 首先检查行列数是否相等
			if (numColumns != matrix.GetNumColumns() || numRows != matrix.GetNumRows())
				return false;

			for (int i=0; i<numRows; ++i)
			{
				for (int j=0; j<numColumns; ++j)
				{
					if (Math.Abs(GetElement(i, j) - matrix.GetElement(i, j)) > eps)
						return false;
				}
			}

			return true;
		}

		/**
		 * 因为重写了Equals,因此必须重写GetHashCode
		 * 
		 * @return int型,返回复数对象散列码
		 */
		public override int GetHashCode()
		{
			double sum = 0;
			for (int i=0; i<numRows; ++i)
			{
				for (int j=0; j<numColumns; ++j)
				{
					sum += Math.Abs(GetElement(i, j));
				}
			}
			return (int)Math.Sqrt(sum);
		}

		/**
		 * 实现矩阵的加法
		 * 
		 * @param other - 与指定矩阵相加的矩阵
		 * @return Matrix型,指定矩阵与other相加之和
		 * @如果矩阵的行/列数不匹配,则会抛出异常
		 */
		public Matrix Add(Matrix other) 
		{
			// 首先检查行列数是否相等
			if (numColumns != other.GetNumColumns() ||
				numRows != other.GetNumRows())
				throw new Exception("矩阵的行/列数不匹配。");

			// 构造结果矩阵
			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 result ;
		}

		/**
		 * 实现矩阵的减法
		 * 
		 * @param other - 与指定矩阵相减的矩阵
		 * @return Matrix型,指定矩阵与other相减之差
		 * @如果矩阵的行/列数不匹配,则会抛出异常
		 */
		public Matrix Subtract(Matrix other) 
		{
			if (numColumns != other.GetNumColumns() ||
				numRows != other.GetNumRows())
				throw new Exception("矩阵的行/列数不匹配。");

			// 构造结果矩阵
			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 result ;
		}

		/**
		 * 实现矩阵的数乘
		 * 
		 * @param value - 与指定矩阵相乘的实数

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -