Lord Nikon
2006-04-28, 21:01:36
Hi,
liegt es daran, das ich den Winograd zu schlecht implementiert habe,
oder wieso ist bei einer 1000x1000 Matrix dieser Algorthmus viel schlechter?
Winograd
public Matrices Winograd_multiply(Matrices B)
{
Matrices Result=new Matrices(this.m,B.n);
final int end=this.n/2;
float value[]=new float[this.n];
float value2[]=new float[this.n];
float value3[][]=new float[this.m][this.n];
float result=0.0f;
int tmp;
int tmp2;
for(int i=0;i!=this.m;i++)
{ value[i]=0;
value2[i]=0;
for(int k=1;k<=end;k++)
{
tmp=(2*k)-2;
tmp2=(2*k)-1;
value[i]+=this.A[i][tmp]*this.A[i][tmp2];
value2[i]+=B.A[tmp2][i]*B.A[tmp][i];
}
}
for(int i=0;i!=this.m;i++)
for(int j=0;j!=this.n;j++)
{
value3[i][j]=value[i]+value2[j];
}
for(int i=0;i!=this.m;i++)
{
for(int j=0;j!=this.n;j++)
{
for(int k=1;k<=end;k++)
{
tmp=(2*k)-2;
tmp2=(2*k)-1;
result+=(this.A[i][tmp]+B.A[tmp2][j])*(this.A[i][tmp2]+B.A[tmp][j])-value3[i][j];
}
Result.insert(j,i,result);
result=0.0f;
}
}
return Result;
}
Standardalgorithmus:
private float get_sum(int am,int bn)
{
float value=0.0f;
for(int i=0;i<this.n;i++)
{
value+=this.A[am][i]*tmp.A[i][bn];
}
return value;
}
public Matrices multiply(Matrices B)
{
float value=0.0f;
tmp=B;
Matrices Result=new Matrices(this.m,B.n);
if(this.n==B.m)
{
for(int i=0;i!=this.m;i++)
{
for(int y=0;y!=B.n;y++)
{
value=this.get_sum(i,y);
Result.insert(y,i,value);
}
}
return Result;
}
else
{
return null;
}
}
Bei 3 Multiplikation von 1000x1000 braucht der Standardalgorithmus 54 Sekunden, während der Winograd Algorithmus174 Sekunden braucht.
Programmiersprache ist Java. In der Theorie sollte Winograd schneller sein,
oder?
liegt es daran, das ich den Winograd zu schlecht implementiert habe,
oder wieso ist bei einer 1000x1000 Matrix dieser Algorthmus viel schlechter?
Winograd
public Matrices Winograd_multiply(Matrices B)
{
Matrices Result=new Matrices(this.m,B.n);
final int end=this.n/2;
float value[]=new float[this.n];
float value2[]=new float[this.n];
float value3[][]=new float[this.m][this.n];
float result=0.0f;
int tmp;
int tmp2;
for(int i=0;i!=this.m;i++)
{ value[i]=0;
value2[i]=0;
for(int k=1;k<=end;k++)
{
tmp=(2*k)-2;
tmp2=(2*k)-1;
value[i]+=this.A[i][tmp]*this.A[i][tmp2];
value2[i]+=B.A[tmp2][i]*B.A[tmp][i];
}
}
for(int i=0;i!=this.m;i++)
for(int j=0;j!=this.n;j++)
{
value3[i][j]=value[i]+value2[j];
}
for(int i=0;i!=this.m;i++)
{
for(int j=0;j!=this.n;j++)
{
for(int k=1;k<=end;k++)
{
tmp=(2*k)-2;
tmp2=(2*k)-1;
result+=(this.A[i][tmp]+B.A[tmp2][j])*(this.A[i][tmp2]+B.A[tmp][j])-value3[i][j];
}
Result.insert(j,i,result);
result=0.0f;
}
}
return Result;
}
Standardalgorithmus:
private float get_sum(int am,int bn)
{
float value=0.0f;
for(int i=0;i<this.n;i++)
{
value+=this.A[am][i]*tmp.A[i][bn];
}
return value;
}
public Matrices multiply(Matrices B)
{
float value=0.0f;
tmp=B;
Matrices Result=new Matrices(this.m,B.n);
if(this.n==B.m)
{
for(int i=0;i!=this.m;i++)
{
for(int y=0;y!=B.n;y++)
{
value=this.get_sum(i,y);
Result.insert(y,i,value);
}
}
return Result;
}
else
{
return null;
}
}
Bei 3 Multiplikation von 1000x1000 braucht der Standardalgorithmus 54 Sekunden, während der Winograd Algorithmus174 Sekunden braucht.
Programmiersprache ist Java. In der Theorie sollte Winograd schneller sein,
oder?