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

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

[复制链接]
 楼主| 发表于 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-11-22 00:38 , Processed in 0.030739 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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