/*我所设计的矩阵类包含以下功能:(不只是加法功能和转置功能)
 * 1.三种普通构造方法以及一种复制构造方法
 * 2.矩阵的加法、减法、数乘、求负以及矩阵乘法的运算
 * 3.矩阵的转置
 * 4.矩阵的三种判断:矩阵是否同型、矩阵是否相等以及矩阵是否为方阵
 * 5.计算矩阵的迹、矩阵中所有元素的和以及矩阵的乘方
 * 6.获取矩阵的行数和列数
 * 7.输出矩阵相关的所有信息
 * 8.获取行列数确定的单位矩阵的静态方法                                                      
 */
public class Basematrix
{
	private double[][] matrix;//用二维数组存储矩阵,数据成员声明为私有保证封装性和安全性
	private int column,row;//分别声明矩阵的行数和列数
	
	//声明了三种普通构造方法和一种复制构造方法
	public Basematrix() {}//默认构造方法,只是为了方便创建一个矩阵对象
	public Basematrix(int column,int row)//以行数和列数为参数的构造方法,确定矩阵的类型但是还不填充元素
	{
		this.column=column;
		this.row=row;
		this.matrix=new double[column][row];//此处容易出错,尽管只给出行数和列数,但是也应该对作为引用类型的数据成员matrix进行创建
	}
	public Basematrix(double [][]matrix)//以一个二维数组作为参数的构造方法,由二维数组的相关性质便可以确定矩阵的行数和列数
	{
		this.column=matrix.length;
		this.row=matrix[0].length;
		this.matrix=new double[column][row];
		for(int i=0;i<column;i++)
		{
			for(int j=0;j<row;j++)
				this.matrix[i][j]=matrix[i][j];
		}
	}
	public Basematrix(Basematrix Matrix)//复制构造函数
	{
		this.column=Matrix.column;
		this.row=Matrix.row;
		this.matrix=new double[column][row];//不直接使用this.matrix=Matrix.matrix是为了实现深复制
		for(int i=0;i<column;i++)
		{
			for(int j=0;j<row;j++)
				this.matrix[i][j]=matrix[i][j];
		}
	}
	
	//声明了矩阵的加法、减法、数乘和乘法运算
	public Basematrix add(Basematrix Matrix)//矩阵的加法运算
	{
		Basematrix temp=new Basematrix(column,row);//两个矩阵是同型矩阵时,对应位置的元素相加
		for(int i=0;i<column;i++)
		{
			for(int j=0;j<row;j++)
			{
				temp.matrix[i][j]=this.matrix[i][j]+Matrix.matrix[i][j];
			}
		}
		return temp;
	}
	public Basematrix substract(Basematrix Matrix)//矩阵的减法运算,与加法运算类似
	{
		if(!this.SameKind(Matrix))
		{
			System.out.println("You can't substract two kinds of matrix");
			return (new Basematrix(1,1));
		}
		Basematrix temp=new Basematrix(column,row);
		for(int i=0;i<column;i++)
		{
			for(int j=0;j<row;j++)
				temp.matrix[i][j]=this.matrix[i][j]-Matrix.matrix[i][j];
		}
		return temp;
	}
	public Basematrix multiple(double n)//矩阵的数乘运算,每个元素分别数乘即可
	{
		Basematrix temp=new Basematrix(this.matrix);
		for(int i=0;i<column;i++)
		{
			for(int j=0;j<row;j++)
				temp.matrix[i][j]*=n;
		}
		return temp;
	}
	public Basematrix multiple(Basematrix Matrix)//矩阵的乘法运算,是矩阵运算中较为复杂的运算,使用了方法重载
	{
		if(this.row!=Matrix.column)//判断两个矩阵是否能进行乘法运算
		{
			System.out.println("You can't mutiple these two kinds of matrixs");
			return (new Basematrix(1,1));
		}
		Basematrix temp=new Basematrix(this.column,Matrix.row);//能进行乘法运算时,执行下列语句
		for(int i=0;i<temp.column;i++)
		{
			for(int j=0;j<temp.row;j++)
			{
				double sum=0;
				for(int k=0;k<this.row;k++)
					sum+=(this.matrix[i][k]*Matrix.matrix[k][j]);
				temp.matrix[i][j]=sum;//通过上述算法计算每一个元素的值
			}
		}
		return temp;
	}
	//声明了求负矩阵的方法
	public Basematrix negative()
	{
		Basematrix temp=new Basematrix(this.matrix);
		for(int i=0;i<column;i++)
		{
			for(int j=0;j<row;j++)
				temp.matrix[i][j]=-this.matrix[i][j];
		}
		return temp;
	}
	
	//声明了矩阵的转置方法
	public Basematrix reverse()
	{
		Basematrix temp=new Basematrix(row,column);//新建一个行数与列数与原矩阵相反的矩阵
		for(int i=0;i<column;i++)
		{
			for(int j=0;j<row;j++)
				temp.matrix[j][i]=this.matrix[i][j];//填充新矩阵中的元素
		}
		return temp;
	}
	
	//声明了判断矩阵同型、矩阵相等和是否为方阵的方法,返回值均为boolean类型
	public boolean SameKind(Basematrix Matrix)//判断两个矩阵是否同型
	{
		if(this.column==Matrix.column&&this.row==Matrix.row)
			return true;
		else
			return false;
	}
	public boolean equal(Basematrix Matrix)//判断两个矩阵是否相等
	{
		if(!this.SameKind(Matrix))//矩阵相等的前提条件是两个矩阵同型
			return false;
		for(int i=0;i<column;i++)
		{
			for(int j=0;j<row;j++)
				if(this.matrix[i][j]!=Matrix.matrix[i][j])
					return false;
		}
		return true;
	}
	public boolean phalanx()//判断矩阵是否为方阵
	{
		if(column==row)
			return true;
		else
			return false;
	}
	
	//声明了计算矩阵的迹和所有元素之和的方法
	public double trail()//计算矩阵的迹
	{
		if(!phalanx())//矩阵有迹的前提是矩阵是一个方阵
		{
			System.out.println("Not a phalanx!");
			return 0;
		}
		else//对角线上的元素相加
		{
			double Trail=0;
			for(int i=0;i<column;i++)
				Trail+=this.matrix[i][i];
			return Trail;
		}
	}
	public double sum()//计算矩阵中所有元素的和
	{
		double Sum=0;
		for(int i=0;i<column;i++)
		{
			for(int j=0;j<row;j++)
				Sum+=this.matrix[i][j];
		}
		return Sum;
	}
	public Basematrix pow(int n)//计算矩阵的乘方
	{
		if(!this.phalanx())//首先判断矩阵是否是方阵
		{
			System.out.println("You can't calculate the pow of a non-phalanx!");
			return (new Basematrix(1,1));
		}
		Basematrix temp=Basematrix.unit(this.column);
		for(int i=1;i<=n;i++)//通过循环方式多次矩阵相乘的方法来计算乘方
			temp=temp.multiple(this);
		return temp;
	}
	
	//获取行列数确定的单位矩阵的方法,由于该方法不属于类中的某一个对象,因此设置为静态方法
	public static Basematrix unit(int n)
	{
		Basematrix unit=new Basematrix(n,n);
		for(int i=0;i<unit.column;i++)
			unit.matrix[i][i]=1;
		return unit;
	}
	
	//声明了矩阵的两个对外公有接口,分别获取行数和列数
	public int getColumn() {return column;}
	public int getRow() {return row;}
	
	//声明了获取矩阵所有信息并输出的方法
	public void show()
	{
		//首先输出行数和列数
		System.out.println("This is a matrix with "+column+" columns and "+row+" rows.");
		System.out.println("The elements of the matrix:");
		for(int i=0;i<column;i++)
		{
			for(int j=0;j<row;j++)
				System.out.printf("%5.2f", matrix[i][j]);//以格式化方法输出矩阵中每一个元素的值
			System.out.println("");
		}
	}
}