找回密码
 欢迎注册
楼主: 无心人

[讨论] 一个循环卷积的问题

[复制链接]
 楼主| 发表于 2008-5-21 20:53:36 | 显示全部楼层


麻烦你把那个PDF发上来
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 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点的变换
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2008-5-21 21:13:27 | 显示全部楼层
发了3次!发不了!太大了,9MB,
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2008-5-21 21:18:03 | 显示全部楼层
那个和FNT关系不大
那个算法是把高度复合数N点变换
分解成小n变换,高效的2-12点的变换

你说的这个是针对整个WFTA,而我说的是WFTA中Winograd提出的那个 小n点循环卷及算法

不知怎么发不上来文件,我把它用WINRAR分成了24分,还是发不上来
要么,留个email?
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2008-5-21 21:19:44 | 显示全部楼层
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2008-5-21 21:20:16 | 显示全部楼层
这是用Z变换来计算卷及,不是与TAOCP上的一样么?
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2008-5-21 21:30:51 | 显示全部楼层
发了,你看看收到没有
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2008-5-21 21:33:47 | 显示全部楼层
谢谢
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2010-7-2 21:47:47 | 显示全部楼层
本帖最后由 ssikkiss 于 2010-7-2 22:05 编辑

此题网上以有人做出。
我抄写了它的c++代码,编译出错,稍更改了下,可以通过,不过请自己加入main函数

  1. const int NMax = 1<<22;
  2. const int SomeMore = 600;
  3. const int PolyTempMax = 1<<11;
  4. #define NUMBERTYPE long
  5. NUMBERTYPE * Global = new NUMBERTYPE[4*NMax + SomeMore];
  6. long CountAdd;
  7. long CountMul;
  8. // Standard circular convolution
  9. void CircConv(long N, NUMBERTYPE *X, NUMBERTYPE *H, NUMBERTYPE *Y) {
  10.     long i, j;
  11.     for (i = 0; i < N ;i++)
  12.         Y[i] = 0;
  13.     for (i = 0; i < N ;i++)
  14.         for (j = 0; j < N ;j++)
  15.             if (i + j < N)
  16.                 Y[i + j] += X[j] * H[i];
  17.             else
  18.                 Y[i + j - N] += X[j] * H[i];
  19. }
  20. void WriteResult(long N, NUMBERTYPE *X) {
  21.     long i;
  22.     long t=0;
  23.     for (i = 0; i < N; i++) {
  24.         t+=X[i];
  25.         cout<<t%10;
  26.         t/=10;
  27.     }
  28.     printf("\n");
  29. }
  30. void ModuloPlusMinus(long N, long X) {
  31.     long i;
  32.     NUMBERTYPE Temp;
  33.     for (i = 0; i < N; i++) {
  34.         Temp = Global[X + i];
  35.         Global[X + i] = Temp - Global[X + i + N];
  36.         Global[X + i + N] = Temp + Global[X + i + N];
  37.     }
  38.     CountAdd += N<<1;
  39. }
  40. void MulAddDiv(long N, long X1, long X2) {
  41.     long i;
  42.     NUMBERTYPE Temp;
  43.     for (i = 0; i < N; i++) {
  44.         Temp = Global[X1 + i];
  45.         Global[X1 + i] = (Temp + Global[X2 + i])>>1;
  46.         Global[X1 + i + N] = (-Temp + Global[X2 + i])>>1;
  47.     }
  48.     CountAdd += N<<1;
  49. }
  50. void PermutePolySub(long N, long K, long X, NUMBERTYPE * Y, long Z) {
  51.     long i;
  52.     long adr;
  53.     long ex;
  54.     for (i = 0; i < N; i++) {
  55.         adr = (i + K +  2 * N * N) % N;
  56.         ex = ((i + K +  2 * N * N) / N) & 1;
  57.         if (ex == 0) {
  58.             Global[Z + adr] = Global[X + i] - Y[i];
  59.         } else {
  60.             Global[Z + adr] = -Global[X + i] + Y[i];
  61.         }
  62.     }
  63.     CountAdd +=N;
  64. }

  65. void PolyAdd(long N, long X, NUMBERTYPE * Y, long Z) {
  66.     long i;
  67.     for (i = 0; i < N; i++) {
  68.         Global[Z + i] = Global[X + i] + Y[i];
  69.     }
  70.     CountAdd +=N;
  71. }

  72. void PolySubPermute(long N, long K, long X, NUMBERTYPE * Y, long Z) {
  73.     long i;
  74.     long adr;
  75.     long ex;

  76.     for (i = 0; i < N; i++) {
  77.         adr = (i + K + 2 * N * N) % N;
  78.         ex = ((i + K + 2 * N * N) / N) & 1;
  79.         if (ex == 0) {
  80.             Global[Z + adr] = Global[X + adr] - Y[i];
  81.         } else {
  82.             Global[Z + adr] = Global[X + adr] + Y[i];
  83.         }
  84.     }
  85.     CountAdd +=N;
  86. }

  87. void PolyAddPermute(long N, long K, long X, NUMBERTYPE * Y, long Z) {
  88.     long i;
  89.     long adr;
  90.     long ex;

  91.     for (i = 0; i < N; i++) {
  92.         adr = (i + K + 2 * N * N) % N;
  93.         ex = ((i + K + 2 * N * N) / N) & 1;
  94.         if (ex == 0) {
  95.             Global[Z + adr] = Global[X + adr] + Y[i];
  96.         } else {
  97.             Global[Z + adr] = Global[X + adr] - Y[i];
  98.         }
  99.     }
  100.     CountAdd +=N;
  101. }

  102. void PolyTransNB(long N, long L2, long K, long X) {
  103.     long i;
  104.     long M;
  105.     long m1;
  106.     long P;
  107.     long p1;
  108.     long Q;
  109.     long q1;
  110.     long adr;
  111.     NUMBERTYPE *Temp = new NUMBERTYPE[PolyTempMax];;
  112.     M = (long)floor(0.5 + log(N) / log(2));
  113.     P = 1;
  114.     Q = N / 2;
  115.     for (m1 = 0; m1 < M; m1++) {
  116.         for (p1 = 0; p1 < P; p1++)
  117.             for (q1 = 0; q1 < Q; q1++) {
  118.                 adr = q1 +  p1 * (Q<<1);
  119.                 for (i = 0; i < L2; i++)
  120.                     Temp[i] = Global[X + L2 * (adr +Q) + i];
  121.                 PermutePolySub(L2, P * q1 * K, X + L2 * adr, Temp, X + L2 * (adr + Q));
  122.                 PolyAdd(L2, X + L2 * adr, Temp, X + L2 * adr);
  123.             }
  124.         P <<=1;
  125.         Q >>=1;
  126.     }
  127.     delete []Temp;
  128. }

  129. void PolyTransBN(long N, long L2, long K, long X) {
  130.     long i;
  131.     long M;
  132.     long m1;
  133.     long P;
  134.     long p1;
  135.     long Q;
  136.     long q1;
  137.     long adr;
  138.     NUMBERTYPE *Temp = new NUMBERTYPE[PolyTempMax];;

  139.     M = (long)floor(0.5 + log(N) /log(2));
  140.     P = N / 2;
  141.     Q = 1;
  142.     for (m1 = 0; m1 < M; m1++) {
  143.         for (p1 = 0; p1 < P; p1++)
  144.             for (q1 = 0; q1 < Q; q1++) {
  145.                 adr = q1 + 2 * p1 * Q;
  146.                 for (i = 0; i < L2; i++)
  147.                     Temp[i] = Global[X + L2 * (adr+Q)+i];
  148.                 PolySubPermute(L2, P * q1 * K,X+L2*adr,Temp,X+L2*(adr+Q));
  149.                 PolyAddPermute(L2, P * q1 * K,X + L2 * adr, Temp, X + L2 * adr);
  150.             }
  151.         P >>=1;
  152.         Q <<=1;
  153.     }
  154.     delete []Temp;
  155. }

  156. void NegaConvolution(long N, long X, long H, long Y) {
  157.     long i, k;
  158.     long N2, N3, N4;
  159.     long L1, L2;
  160.     NUMBERTYPE Tp0, Tp1, Tp2;

  161.     if (N==2) {
  162.         Tp0= (Global[X] + Global[X + 1]) * Global[H];
  163.         Tp1=(Global[H] + Global[H + 1]) * Global[X + 1];
  164.         Tp2=(Global[H] - Global[H + 1]) * Global[X];

  165.         CountMul +=3;
  166.         Global[X] = Tp0 - Tp1;
  167.         Global[X+1] = Tp0 - Tp2;

  168.         CountAdd+=5;
  169.     } else {
  170.         N2=N<<1;
  171.         N3=N2+N;
  172.         N4=N2<<1;

  173.         L2 = (long)floor(0.5 + sqrt(N));
  174.         if (L2 * L2 != N)
  175.             L2 = (long)floor(0.5 + sqrt(N2));
  176.         L1 = N / L2;

  177.         for (k=0;k<L1;k++)
  178.             for (i=0;i<L2;i++) {
  179.                 Global[Y+L2*k+i]=Global[X + L1 * i + k];
  180.                 Global[Y+N2+L2*k+i]=Global[H + L1 * i + k];
  181.                 Global[Y+N+L2*k+i]=0;
  182.                 Global[Y+N3+L2*k+i]=0;
  183.             }
  184.         PolyTransNB(2 * L1, L2, L2 / L1, Y);
  185.         PolyTransNB(2 * L1, L2, L2 / L1, Y + N2);
  186.         for (k = 0; k < 2 * L1; k++)
  187.             NegaConvolution(L2, Y + L2 * k, Y + N2 + L2 * k, Y + N4);
  188.         PolyTransBN(2 * L1, L2, -(L2 / L1), Y);
  189.         for (k = 0; k < L1; k++) {
  190.             for (i = 1; i < L2; i++) {
  191.                 Global[X + L1 * i + k] = (Global[Y + L2 * k + i] +
  192.                                           Global[Y + N + L2 * k + (i - 1)]) / (2 * L1);
  193.             }
  194.             Global[X + k] = (Global[Y + L2 * k] - Global[Y + N + L2 * k + L2 - 1]) / (2 * L1);
  195.             CountAdd+=L2+1;
  196.         }
  197.     }
  198. }


  199. void CircConvolution(long N, long X, long H) {
  200.     long M;
  201.     long N2;
  202.     long X1, X2;
  203.     NUMBERTYPE Tp0, Tp1, Tp2;

  204.     N2 = 2 * N;
  205.     M = N / 2;
  206.     do {
  207.         ModuloPlusMinus(M, X);
  208.         ModuloPlusMinus(M, H);
  209.         NegaConvolution(M, X, H, N2);
  210.         X += M;
  211.         H += M;
  212.         M /= 2;
  213.     } while (M != 1);

  214.     Tp0=(Global[X]+Global[X+1])*Global[H];
  215.     Tp2=(Global[H]-Global[H+1]);
  216.     Tp1=Tp2*Global[X+1];
  217.     Tp2=Tp2*Global[X];

  218.     CountAdd +=5;
  219.     CountMul +=3;
  220.     Global[X] = Tp0 - Tp1;
  221.     Global[X+1] = Tp0 - Tp2;
  222.     M = 2;
  223.     X1 = X - M;
  224.     X2 = X;
  225.     do {
  226.         MulAddDiv(M, X1, X2);
  227.         X2 -= M;
  228.         M <<=1;
  229.         X1 -= M;
  230.     } while (M != N);
  231. }

  232. char* testmul(int e) {
  233.     NUMBERTYPE* sequenceOne=new NUMBERTYPE[NMax];
  234.     NUMBERTYPE* sequenceTwo=new NUMBERTYPE[NMax];
  235.     NUMBERTYPE* resultFast=new NUMBERTYPE[NMax];
  236.     NUMBERTYPE* resultSlow=new NUMBERTYPE[NMax];

  237.     long N;
  238.     long X,H;
  239.     long i;

  240.     N=2;
  241.     N<<=e;
  242.     for (i=0;i<N/2;i++) {
  243.         sequenceOne[i]=9;
  244.         sequenceTwo[i]=9;
  245.     }

  246.     for (i=N/2;i<N;i++) {
  247.         sequenceOne[i]=0;
  248.         sequenceTwo[i]=0;
  249.     }

  250.     cout<<N<<endl;




  251.     X=0;
  252.     H=N;
  253.     Timer timer;
  254.     timer.start();
  255.     for (i = 0; i < N; i++) {
  256.         Global[X + i] = sequenceOne[i];
  257.         Global[H + i] = sequenceTwo[i];
  258.     }
  259.     CountAdd = 0;
  260.     CountMul = 0;
  261.     CircConvolution(N, X, H);
  262.     timer.end();
  263.     cout<<"test mul:耗时"<<timer.getSecond()<<"秒"<<endl;
  264. //WriteResult(N, Global); // First part of Global contains the convolution
  265.     printf("\n");


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

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

  271.         long t=0;
  272.     for (i = 0; i < N; i++) {
  273.         t+=Global[i];
  274.                 ret[i]=t%10+'0';
  275.         t/=10;
  276.     }
  277.         ret[i++]=0;

  278.     return ret;
  279. }




















复制代码
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
您需要登录后才可以回帖 登录 | 欢迎注册

本版积分规则

小黑屋|手机版|数学研发网 ( 苏ICP备07505100号 )

GMT+8, 2024-4-28 22:39 , Processed in 0.063583 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表