import java.util.Date;
import java.util.Random;
public class JZXC {
public static void main(String[] args){
System.out.println(new Date()); //打印系统时间
Matrix m1=new Matrix(10,10);
m1.randomInitMatrix(); //对矩阵m1进行随机数初始化
// m1.infoMatrix(); //打印矩阵m1的信息
Matrix m2=new Matrix(10,10);
m2.randomInitMatrix(); //对矩阵m2进行随机数初始化
// m2.infoMatrix(); //打印矩阵m2的信息
Matrix m3=m1.matrixmulti(m2); //m3为矩阵m1与m2相乘普通算法求得结果
// m3.infoMatrix(); //打印矩阵m3的信息
System.out.println(new Date()); //打印系统时间
//Strasson算法
Matrix m4=m1.Strassen(m1, m2); //矩阵m4为矩阵m1与m2的strassen算法求得矩阵
// m4.infoMatrix();
System.out.println(new Date()); //打印系统时间
}
}
class Matrix{
static int matrixNum=1; //当前矩阵数
boolean chgtoStranssen=false; //判断矩阵是否已经转换成stransson矩阵
int xNum; //二维数组的第一维
int yNum; //二维数组的第二维
int myMatrix[][]; //二维数组
private static Random rm=new Random(); //随机数产生器
Matrix(int xNum,int yNum){ //构造方法
this.xNum=xNum;
this.yNum=yNum;
myMatrix=new int[xNum][yNum];
}
public void randomInitMatrix(){ //矩阵随机数初始化方法
for(int i=0;i<xNum;i++){
for(int j=0;j<yNum;j++){
int y=rm.nextInt(20); //产生0-20以内的数
myMatrix[i][j]=y;
}
}
}
public void matrixInitMatrix(Matrix m){ //矩阵初始化矩阵
for(int i=0;i<m.xNum;i++){
for(int j=0;j<m.yNum;j++){
myMatrix[i][j]=m.myMatrix[i][j];
}
}
}
public Matrix matrixPlus(Matrix a){ //矩阵相加,矩阵相加
if(a.xNum!=this.xNum||a.yNum!=this.yNum){
System.out.println("矩阵维数不相符,无法相加");
System.exit(-1);
}
Matrix tmpMatrix=new Matrix(a.xNum,a.yNum);
for(int i=0;i<a.xNum;i++){
for(int j=0;j<a.yNum;j++){
tmpMatrix.myMatrix[i][j]=a.myMatrix[i][j]+this.myMatrix[i][j];
}
}
return tmpMatrix;
}
public Matrix matrixMinus(Matrix a){ //矩阵相减,减数为所传所矩阵
if(a.xNum!=this.xNum||a.yNum!=this.yNum){
System.out.println("矩阵维数不相符,无法相减");
System.exit(-1);
}
Matrix tmpMatrix=new Matrix(a.xNum,a.yNum);
for(int i=0;i<a.xNum;i++){
for(int j=0;j<a.yNum;j++){
tmpMatrix.myMatrix[i][j]=this.myMatrix[i][j]-a.myMatrix[i][j];
}
}
return tmpMatrix;
}
public Matrix matrixmulti(Matrix m){ //任意矩阵相乘算法
if(this.yNum!=m.xNum){
System.out.println("矩阵维数不相符,无法相乘");
System.exit(-1);
}
Matrix tmpMatrix=new Matrix(xNum,m.yNum);
for(int i=0;i<xNum;i++){
for(int j=0;j<m.yNum;j++){
tmpMatrix.myMatrix[i][j]=0;
for(int k=0;k<yNum;k++){
tmpMatrix.myMatrix[i][j]+=myMatrix[i][k]*m.myMatrix[k][j];
}
}
}
return tmpMatrix;
}
public Matrix Strassen(Matrix a,Matrix b){
Matrix m=new Matrix(a.xNum,b.yNum);
if(a.yNum!=b.xNum){
System.out.println("矩阵维数不相符,无法相乘");
System.exit(-1);
}
if(!this.chgtoStranssen){
m=new Matrix(a.xNum,b.yNum);
a=a.creMatrix(a);
b=b.creMatrix(b);
chgtoStranssen=true;
}
Matrix tmpMatrix=new Matrix(a.xNum,b.yNum);
int tmpX=a.xNum/2;
int tmpY=a.yNum/2;
Matrix ms[]=new Matrix[15];
for(int i=0;i<15;i++){
ms[i]=new Matrix(tmpX,tmpY);
}
if(tmpX>=2){
for(int i=0;i<tmpX;i++){ //矩阵左上角赋值
for(int j=0;j<tmpY;j++){
ms[7].myMatrix[i][j]=a.myMatrix[i][j];
ms[11].myMatrix[i][j]=b.myMatrix[i][j];
}
}
for(int i=0,h=0;i<tmpX;i++,h++){ //矩阵右上角赋值
for(int j=tmpY,k=0;j<a.yNum;j++,k++){
ms[8].myMatrix[h][k]=a.myMatrix[i][j];
ms[12].myMatrix[h][k]=b.myMatrix[i][j];
}
}
for(int i=tmpX,h=0;i<a.xNum;i++,h++){ //矩阵左下角赋值
for(int j=0,k=0;j<tmpY;j++,k++){
ms[9].myMatrix[h][k]=a.myMatrix[i][j];
ms[13].myMatrix[h][k]=b.myMatrix[i][j];
}
}
for(int i=tmpX,h=0;i<a.xNum;i++,h++){ //矩阵右下角赋值
for(int j=tmpY,k=0;j<a.yNum;j++,k++){
ms[10].myMatrix[h][k]=a.myMatrix[i][j];
ms[14].myMatrix[h][k]=b.myMatrix[i][j];
}
}
Strassen(ms[7].matrixPlus(ms[10]),ms[11].matrixPlus(ms[14]));
Strassen(ms[9].matrixPlus(ms[10]),ms[11]);
Strassen(ms[7],ms[12].matrixMinus(ms[14]));
Strassen(ms[10],ms[13].matrixMinus(ms[11]));
Strassen(ms[7].matrixPlus(ms[8]),ms[14]);
Strassen(ms[9].matrixMinus(ms[7]),ms[11].matrixPlus(ms[12]));
Strassen(ms[8].matrixMinus(ms[10]),ms[13].matrixPlus(ms[14]));
ms[0]=ms[7].matrixPlus(ms[10]).matrixmulti(ms[11].matrixPlus(ms[14]));
ms[1]=ms[9].matrixPlus(ms[10]).matrixmulti(ms[11]);
ms[2]=ms[7].matrixmulti(ms[12].matrixMinus(ms[14]));
ms[3]=ms[10].matrixmulti(ms[13].matrixMinus(ms[11]));
ms[4]=ms[7].matrixPlus(ms[8]).matrixmulti(ms[14]);
ms[5]=ms[9].matrixMinus(ms[7]).matrixmulti(ms[11].matrixPlus(ms[12]));
ms[6]=ms[8].matrixMinus(ms[10]).matrixmulti(ms[13].matrixPlus(ms[14]));
}
for(int i=0;i<tmpX;i++){ //矩阵左上角赋值
for(int j=0;j<tmpY;j++){
tmpMatrix.myMatrix[i][j]=ms[0].matrixPlus(ms[3]).matrixMinus(ms[4]).matrixPlus(ms[6]).myMatrix[i][j];
}
}
for(int i=0,h=0;i<tmpX;i++,h++){ //矩阵右上角赋值
for(int j=tmpY,k=0;j<a.yNum;j++,k++){
tmpMatrix.myMatrix[i][j]=ms[2].matrixPlus(ms[4]).myMatrix[h][k];
}
}
for(int i=tmpX,h=0;i<a.xNum;i++,h++){ //矩阵左下角赋值
for(int j=0,k=0;j<tmpY;j++,k++){
tmpMatrix.myMatrix[i][j]=ms[1].matrixPlus(ms[3]).myMatrix[h][k];
}
}
for(int i=tmpX,h=0;i<a.xNum;i++,h++){ //矩阵右下角赋值
for(int j=tmpY,k=0;j<a.yNum;j++,k++){
tmpMatrix.myMatrix[i][j]=ms[0].matrixPlus(ms[2]).matrixMinus(ms[1]).matrixPlus(ms[5]).myMatrix[h][k];
}
}
for(int i=0;i<m.xNum;i++){
for(int j=0;j<m.yNum;j++){
m.myMatrix[i][j]=tmpMatrix.myMatrix[i][j];
}
}
return m;
}
public Matrix creMatrix(Matrix a){ //将矩阵a转成2^n阶的矩阵
int tmpX=a.xNum;
int tmpY=a.yNum;
if(a.xNum<a.yNum){
while(Logarithm.log(a.yNum, 2)%1!=0){
a.yNum++;
}
a.xNum=a.yNum;
}
else{
while(Logarithm.log(a.xNum, 2)%1!=0){
a.xNum++;
}
a.yNum=a.xNum;
}
Matrix b=new Matrix(a.xNum,a.yNum);
for(int i=0;i<tmpX;i++){
for(int j=0;j<tmpY;j++){
b.myMatrix[i][j]=a.myMatrix[i][j];
}
}
for(int i=tmpX;i<a.xNum;i++){
for(int j=tmpY;j<a.yNum;j++){
b.myMatrix[i][j]=0;
}
}
return b;
}
public void infoMatrix(){ //打印矩阵信息
System.out.println("第"+matrixNum+"个矩阵:");
for(int i=0;i<xNum;i++){
for(int j=0;j<yNum;j++){
System.out.print(myMatrix[i][j]+" ");
}
System.out.println();
}
matrixNum+=1;
}
}
class Logarithm { //求底数的类
static public double log(double value, double base) {
return Math.log(value)/Math.log(base);
}
}