Strassen 算法矩阵乘法_IT随笔_百度空间

// Strassen.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <vector>
using namespace std;
const int BFSZ = 20;
char fbuff[BFSZ];

template <class T>
T ** create(int n){
T ** mat = new T*[n];
for (int i=0;i<n;i++){
   mat[i] = new T[n];
}
return mat;
}
template <class T>
void clear(T ** mat ,int n){
if (mat){
   for (int i=0;i<n;i++){
    delete [] mat[i];
   }
   delete [] mat;
}
}
template <class T>
void cp(T ** mat ,T ** src,int ax,int ay ,int bx,int by,int dem ){
int n = 1<<dem;
for (int i=0;i<n;i++){
   for (int j=0;j<n;j++){
    mat[ax+i][ay+j]=src[bx+i][by+j];
   }
}
}
template <class T>
T ** add(T ** A, T ** B ,int ax,int ay ,int bx,int by,int dem,bool issub=false){
int n = 1<<dem;
T ** ret = create<T>(n);
for (int i=0;i<n;i++){
   for (int j=0;j<n;j++){
    if (issub){
     ret[i][j]=A[ax+i][ay+j]-B[bx+i][by+j];
    }else{
     ret[i][j]=A[ax+i][ay+j]+B[bx+i][by+j];
    }
   }
}
return ret;
}
template <class T>
T ** mul(T ** A, T ** B ,int ax,int ay ,int bx,int by,int dem ){
T ** ret = create<T>(1<<dem);
if (dem==0){
   ret[0][0]=A[ax][ay]*B[bx][by];
}else{
   int subsz = 1<<(dem-1);
   T ** t1 = add(A,A,ax,ay,(ax+subsz),(ay+subsz),dem-1);
   T ** t2 = add(B,B,bx,by,(bx+subsz),(by+subsz),dem-1);
   T ** m[8];
   m[1] = mul(t1,t2,0,0,0,0,dem-1);
   clear(t1,subsz);
   clear(t2,subsz);
   t1 = add(A,A,(ax+subsz),ay,(ax+subsz),(ay+subsz),dem-1);
   m[2] = mul(t1,B,0,0,0,0,dem-1);
   clear(t1,subsz);
   t1 = add(B,B,bx,by+subsz,bx+subsz,by+subsz,dem-1,true);
   m[3] = mul(A,t1,ax,ay,0,0,dem-1);

   clear(t1,subsz);
   t1 = add(B,B,bx+subsz,by,bx,by,dem-1,true);
   m[4] = mul(A,t1,ax+subsz,ay+subsz,0,0,dem-1);

   clear(t1,subsz);
   t1 = add(A,A,ax,ay,ax,ay+subsz,dem-1);
   m[5] = mul(t1,B,0,0,bx+subsz,by+subsz,dem-1);


   clear(t1,subsz);
   t1 = add(A,A,ax+subsz,ay,ax,ay,dem-1,true);
   t2=add(B,B,bx,by,bx,by+subsz,dem-1);
   m[6] = mul(t1,t2,0,0,0,0,dem-1);

   clear(t1,subsz);
   clear(t2,subsz);

   t1 = add(A,A,ax,ay+subsz,ax+subsz,ay+subsz,dem-1,true);
   t2 = add(B,B,bx+subsz,by,bx+subsz,by+subsz,dem-1);
   m[7] = mul(t1,t2,0,0,0,0,dem-1);

   T ** c[4];

   c[0] = add(add( add(m[1],m[4],0,0,0,0,dem-1),m[5],0,0,0,0,dem-1,true),m[7],0,0,0,0,dem-1);
   c[1] = add(m[3],m[5],0,0,0,0,dem-1);
   c[2]= add(m[2],m[4],0,0,0,0,dem-1);
   c[3] = add(add( add(m[1],m[2],0,0,0,0,dem-1,true),m[3],0,0,0,0,dem-1),m[6],0,0,0,0,dem-1);

   cp(ret,c[0],0,0,0,0,dem-1);
   cp(ret,c[1],0,subsz,0,0,dem-1);
   cp(ret,c[2],subsz,0,0,0,dem-1);
   cp(ret,c[3],subsz,subsz,0,0,dem-1);

   for (int i=1;i<8;i++){ //没用 0
    clear(m[i],subsz);
   }
   for (int i=0;i<4;i++){
    clear(c[i],subsz);
   }
}
return ret;
}
template <class T>
void init(T ** mat , int n){
for (int i=0;i<n;i++){
   for (int j=0;j<n;j++){
    cin>>mat[i][j];
   }
}
}
template <class T>
void show(T ** mat , int n){
cout<<n<<endl;
for (int i=0;i<n;i++){
   cout<<mat[i][0];
   for (int j=1;j<n;j++){
    cout<<" "<<mat[i][j];
   }
   cout<<endl;
}
}

int dem;
void work();
int _tmain(int argc, _TCHAR* argv[])
{
int cas=1;
for (int i=0;i<cas;i++){
   sprintf(fbuff,"%d.in",i);
   freopen(fbuff,"r",stdin);
   sprintf(fbuff,"%d.out",i);
   freopen(fbuff,"w",stdout);
   work();
}
return 0;
}

void work(){
scanf("%d",&dem);
int n=1<<dem;
int ** A = create<int>(n);
init<int>(A ,n);
int ** B = create<int>(n);
init<int>(B , n);
int ** C = mul<int>(A,B,0,0,0,0,dem);
//int ** C = add<int>(A,B,0,0,0,0,dem);
show<int>(C,n);
}



郑重声明:资讯 【Strassen 算法矩阵乘法_IT随笔_百度空间】由 发布,版权归原作者及其所在单位,其原创性以及文中陈述文字和内容未经(企业库qiyeku.com)证实,请读者仅作参考,并请自行核实相关内容。若本文有侵犯到您的版权, 请你提供相关证明及申请并与我们联系(qiyeku # qq.com)或【在线投诉】,我们审核后将会尽快处理。
—— 相关资讯 ——