无心人 发表于 2008-5-21 20:53:36

:)

麻烦你把那个PDF发上来

ssikkiss 发表于 2008-5-21 20:54:58

或者你在网上搜索Winograd WFTA也能找到相应的信息
在WFTA中,Winograd 为了计算FFT,把大N点FFT转化成小n的循环卷积问题,
而我们要做乘法,就是一个循环卷积问题
过去我们是用FFT来做的,也就是把循环卷积问题转化为FFT的计算
现在,如果我们对Winograd的那个"小n点快速卷及算法"弄懂了,就不必绕圈子了!

无心人 发表于 2008-5-21 21:12:20

:)

那个和FNT关系不大
那个算法是把高度复合数N点变换
分解成小n变换,高效的2-12点的变换

ssikkiss 发表于 2008-5-21 21:13:27

发了3次!发不了!太大了,9MB,

ssikkiss 发表于 2008-5-21 21:18:03

那个和FNT关系不大
那个算法是把高度复合数N点变换
分解成小n变换,高效的2-12点的变换
你说的这个是针对整个WFTA,而我说的是WFTA中Winograd提出的那个 小n点循环卷及算法

不知怎么发不上来文件,我把它用WINRAR分成了24分,还是发不上来
要么,留个email?

无心人 发表于 2008-5-21 21:19:44

yaojialin@126.com

ssikkiss 发表于 2008-5-21 21:20:16

这是用Z变换来计算卷及,不是与TAOCP上的一样么?

ssikkiss 发表于 2008-5-21 21:30:51

发了,你看看收到没有

无心人 发表于 2008-5-21 21:33:47

谢谢

ssikkiss 发表于 2010-7-2 21:47:47

本帖最后由 ssikkiss 于 2010-7-2 22:05 编辑

此题网上以有人做出。
我抄写了它的c++代码,编译出错,稍更改了下,可以通过,不过请自己加入main函数
const int NMax = 1<<22;
const int SomeMore = 600;
const int PolyTempMax = 1<<11;
#define NUMBERTYPE long
NUMBERTYPE * Global = new NUMBERTYPE;
long CountAdd;
long CountMul;
// Standard circular convolution
void CircConv(long N, NUMBERTYPE *X, NUMBERTYPE *H, NUMBERTYPE *Y) {
    long i, j;
    for (i = 0; i < N ;i++)
      Y = 0;
    for (i = 0; i < N ;i++)
      for (j = 0; j < N ;j++)
            if (i + j < N)
                Y += X * H;
            else
                Y += X * H;
}
void WriteResult(long N, NUMBERTYPE *X) {
    long i;
    long t=0;
    for (i = 0; i < N; i++) {
      t+=X;
      cout<<t%10;
      t/=10;
    }
    printf("\n");
}
void ModuloPlusMinus(long N, long X) {
    long i;
    NUMBERTYPE Temp;
    for (i = 0; i < N; i++) {
      Temp = Global;
      Global = Temp - Global;
      Global = Temp + Global;
    }
    CountAdd += N<<1;
}
void MulAddDiv(long N, long X1, long X2) {
    long i;
    NUMBERTYPE Temp;
    for (i = 0; i < N; i++) {
      Temp = Global;
      Global = (Temp + Global)>>1;
      Global = (-Temp + Global)>>1;
    }
    CountAdd += N<<1;
}
void PermutePolySub(long N, long K, long X, NUMBERTYPE * Y, long Z) {
    long i;
    long adr;
    long ex;
    for (i = 0; i < N; i++) {
      adr = (i + K +2 * N * N) % N;
      ex = ((i + K +2 * N * N) / N) & 1;
      if (ex == 0) {
            Global = Global - Y;
      } else {
            Global = -Global + Y;
      }
    }
    CountAdd +=N;
}

void PolyAdd(long N, long X, NUMBERTYPE * Y, long Z) {
    long i;
    for (i = 0; i < N; i++) {
      Global = Global + Y;
    }
    CountAdd +=N;
}

void PolySubPermute(long N, long K, long X, NUMBERTYPE * Y, long Z) {
    long i;
    long adr;
    long ex;

    for (i = 0; i < N; i++) {
      adr = (i + K + 2 * N * N) % N;
      ex = ((i + K + 2 * N * N) / N) & 1;
      if (ex == 0) {
            Global = Global - Y;
      } else {
            Global = Global + Y;
      }
    }
    CountAdd +=N;
}

void PolyAddPermute(long N, long K, long X, NUMBERTYPE * Y, long Z) {
    long i;
    long adr;
    long ex;

    for (i = 0; i < N; i++) {
      adr = (i + K + 2 * N * N) % N;
      ex = ((i + K + 2 * N * N) / N) & 1;
      if (ex == 0) {
            Global = Global + Y;
      } else {
            Global = Global - Y;
      }
    }
    CountAdd +=N;
}

void PolyTransNB(long N, long L2, long K, long X) {
    long i;
    long M;
    long m1;
    long P;
    long p1;
    long Q;
    long q1;
    long adr;
    NUMBERTYPE *Temp = new NUMBERTYPE;;
    M = (long)floor(0.5 + log(N) / log(2));
    P = 1;
    Q = N / 2;
    for (m1 = 0; m1 < M; m1++) {
      for (p1 = 0; p1 < P; p1++)
            for (q1 = 0; q1 < Q; q1++) {
                adr = q1 +p1 * (Q<<1);
                for (i = 0; i < L2; i++)
                  Temp = Global;
                PermutePolySub(L2, P * q1 * K, X + L2 * adr, Temp, X + L2 * (adr + Q));
                PolyAdd(L2, X + L2 * adr, Temp, X + L2 * adr);
            }
      P <<=1;
      Q >>=1;
    }
    delete []Temp;
}

void PolyTransBN(long N, long L2, long K, long X) {
    long i;
    long M;
    long m1;
    long P;
    long p1;
    long Q;
    long q1;
    long adr;
    NUMBERTYPE *Temp = new NUMBERTYPE;;

    M = (long)floor(0.5 + log(N) /log(2));
    P = N / 2;
    Q = 1;
    for (m1 = 0; m1 < M; m1++) {
      for (p1 = 0; p1 < P; p1++)
            for (q1 = 0; q1 < Q; q1++) {
                adr = q1 + 2 * p1 * Q;
                for (i = 0; i < L2; i++)
                  Temp = Global;
                PolySubPermute(L2, P * q1 * K,X+L2*adr,Temp,X+L2*(adr+Q));
                PolyAddPermute(L2, P * q1 * K,X + L2 * adr, Temp, X + L2 * adr);
            }
      P >>=1;
      Q <<=1;
    }
    delete []Temp;
}

void NegaConvolution(long N, long X, long H, long Y) {
    long i, k;
    long N2, N3, N4;
    long L1, L2;
    NUMBERTYPE Tp0, Tp1, Tp2;

    if (N==2) {
      Tp0= (Global + Global) * Global;
      Tp1=(Global + Global) * Global;
      Tp2=(Global - Global) * Global;

      CountMul +=3;
      Global = Tp0 - Tp1;
      Global = Tp0 - Tp2;

      CountAdd+=5;
    } else {
      N2=N<<1;
      N3=N2+N;
      N4=N2<<1;

      L2 = (long)floor(0.5 + sqrt(N));
      if (L2 * L2 != N)
            L2 = (long)floor(0.5 + sqrt(N2));
      L1 = N / L2;

      for (k=0;k<L1;k++)
            for (i=0;i<L2;i++) {
                Global=Global;
                Global=Global;
                Global=0;
                Global=0;
            }
      PolyTransNB(2 * L1, L2, L2 / L1, Y);
      PolyTransNB(2 * L1, L2, L2 / L1, Y + N2);
      for (k = 0; k < 2 * L1; k++)
            NegaConvolution(L2, Y + L2 * k, Y + N2 + L2 * k, Y + N4);
      PolyTransBN(2 * L1, L2, -(L2 / L1), Y);
      for (k = 0; k < L1; k++) {
            for (i = 1; i < L2; i++) {
                Global = (Global +
                                          Global) / (2 * L1);
            }
            Global = (Global - Global) / (2 * L1);
            CountAdd+=L2+1;
      }
    }
}


void CircConvolution(long N, long X, long H) {
    long M;
    long N2;
    long X1, X2;
    NUMBERTYPE Tp0, Tp1, Tp2;

    N2 = 2 * N;
    M = N / 2;
    do {
      ModuloPlusMinus(M, X);
      ModuloPlusMinus(M, H);
      NegaConvolution(M, X, H, N2);
      X += M;
      H += M;
      M /= 2;
    } while (M != 1);

    Tp0=(Global+Global)*Global;
    Tp2=(Global-Global);
    Tp1=Tp2*Global;
    Tp2=Tp2*Global;

    CountAdd +=5;
    CountMul +=3;
    Global = Tp0 - Tp1;
    Global = Tp0 - Tp2;
    M = 2;
    X1 = X - M;
    X2 = X;
    do {
      MulAddDiv(M, X1, X2);
      X2 -= M;
      M <<=1;
      X1 -= M;
    } while (M != N);
}

char* testmul(int e) {
    NUMBERTYPE* sequenceOne=new NUMBERTYPE;
    NUMBERTYPE* sequenceTwo=new NUMBERTYPE;
    NUMBERTYPE* resultFast=new NUMBERTYPE;
    NUMBERTYPE* resultSlow=new NUMBERTYPE;

    long N;
    long X,H;
    long i;

    N=2;
    N<<=e;
    for (i=0;i<N/2;i++) {
      sequenceOne=9;
      sequenceTwo=9;
    }

    for (i=N/2;i<N;i++) {
      sequenceOne=0;
      sequenceTwo=0;
    }

    cout<<N<<endl;




    X=0;
    H=N;
    Timer timer;
    timer.start();
    for (i = 0; i < N; i++) {
      Global = sequenceOne;
      Global = sequenceTwo;
    }
    CountAdd = 0;
    CountMul = 0;
    CircConvolution(N, X, H);
    timer.end();
    cout<<"test mul:耗时"<<timer.getSecond()<<"秒"<<endl;
//WriteResult(N, Global); // First part of Global contains the convolution
    printf("\n");


//CircConv(N, sequenceOne, sequenceTwo, resultSlow);
//WriteResult(N, resultSlow);
    cout<<"Additions:"<<CountAdd<<endl;
    cout<<"Multiplications:"<<CountMul<<endl;

        char* ret=(char*)malloc(sizeof(char)*(N+2));

        long t=0;
    for (i = 0; i < N; i++) {
      t+=Global;
                ret=t%10+'0';
      t/=10;
    }
        ret=0;

    return ret;
}




















页: 1 2 [3] 4
查看完整版本: 一个循环卷积的问题