找回密码
 欢迎注册
查看: 11424|回复: 9

[求助] 数论变换里 的进制的选择和M有什么关系?

[复制链接]
发表于 2010-6-17 23:46:16 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?欢迎注册

×
最近用快速数论变换写了一个阶乘的算法. 发觉 选择太大的b进制会有可能发生错误. (10000!,用10,100,1000进制计算正确,10000进制就错误了.) 感觉上似乎是数据发生了溢出. 这个进制的选择和M有什么关系要求. 从变换结果看似乎要求 b^3 < M 实际上是什么的要求呢,真的不懂. (选择的M 是(15<<27) + 1,似乎是31位内最大的一个了.)
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2010-6-18 10:58:06 | 显示全部楼层
这个限制条件太宽了吧. 几乎达到 b^2 * N ^ 2. (b进制,N变换长度) 我见过有人发过 变换长度达 2^46,进制可达10^7(但不知道是不是同时可取到) 原话是这样的 "变换长度可达2^46(天文数字),进制可达1E7(1次可以算7位)" 其选取的M 是5000000000053*2^46+1.似乎是一个96bit左右的一个素数 但是他用的似乎是VB语言写的,不懂VB 我见过的似乎是一个上限是 k * b ^ 2 * N (k为一常数,b进制,N为变换长度,似乎和复数域的FFT误差分析很类似,但不敢肯定这个上限是否正确.) 我担心自己的思维进了死胡同,转不出来,于是上论坛问一下.
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2010-6-18 11:46:39 | 显示全部楼层
若数组A[0..L-1]表示被乘数,数组B[0..L-1]表示被乘数,则积数组可表示为C[0,L+L-2],C[k]= sum(A[i]*B[j], i+j=k)。 为了使用数论变换计算大数乘法,需要 1.对数组A做一次变换长度为2L的FNT 2.对数组B做一次变换长度为2L的FNT 3.计算T[i]=A[i]*B[i], i=0..2L-2. 4.对T做一次变换长度为2L的逆变换,结果存储与C。 因为C[i]的最大值约为 (r-1)*(r-1)*L,故M的值应该大于 r^2*L,r为进制 如果r的值较大,就需要做多次大数的模乘法,再应用中国剩余定理得最终的乘积。 在apfloat,r的值达到10^9,而3个M的值均小于2^32,为了计算很大的数的乘机,它使用3个不同的M,做了3次大数模乘法(为了做两个大数的乘法,需要做6次FNT正变换,3次FNT逆变换),最后应用CRT得到了最终的结果。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2010-6-19 01:44:40 | 显示全部楼层
这样啊. 我原来的猜想是k * b ^ 2 * N是这个,但是感觉上这个范围还是太大,(N通常较大) 而且我看过少部分变换结果,似乎都不会小于b^3,所以才这样想的(b^2肯定是错的,),而且看到最后结果都能被N整除,似乎这个N可以省略(但这个细想似乎没有道理). 对了,提到10^9,我想多问一下.在做这三次模乘法的时候,应该是直接就用10^9进制的了.(这应该不算是问题) 在做这三次模乘法后 是先各项进行CRT组合再进行进制修正,还是这3个乘积各自先修正再组合然后结果再修正一次.? (好像这个问题比较小白,在翻你们以前的帖子时想到的.) 我刚看apfloat的2.41版本.,可惜到现在里面的基本关系都还没弄清楚
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2010-6-19 02:13:34 | 显示全部楼层
刚找到一组三项式的素数: 1073741827:2^30+2^1+1 hex string:40000003 2147483647:2^31-2^1+1 hex string:7fffffff 1073741833:2^30+2^3+1 hex string:40000009 1073741857:2^30+2^5+1 hex string:40000021 2147483713:2^31+2^6+1 hex string:80000041 1073741953:2^30+2^7+1 hex string:40000081 2147483777:2^31+2^7+1 hex string:80000081 2147484161:2^31+2^9+1 hex string:80000201 2147483137:2^31-2^9+1 hex string:7ffffe01 1073750017:2^30+2^13+1 hex string:40002001 1073872897:2^30+2^17+1 hex string:40020001 2147352577:2^31-2^17+1 hex string:7ffe0001 1073479681:2^30-2^18+1 hex string:3ffc0001 1074266113:2^30+2^19+1 hex string:40080001 2146959361:2^31-2^19+1 hex string:7ff80001 4293918721:2^32-2^20+1 hex string:fff00001 2151677953:2^31+2^22+1 hex string:80400001 2130706433:2^31-2^24+1 hex string:7f000001 1107296257:2^30+2^25+1 hex string:42000001 2113929217:2^31-2^25+1 hex string:7e000001 2281701377:2^31+2^27+1 hex string:88000001 2013265921:2^31-2^27+1 hex string:78000001 3221225473:2^31+2^30+1 hex string:c0000001 3221225473:2^32-2^30+1 hex string:c0000001 find prime number :24 据说其二进制值0越多求模越快 但我粗测了下,发现差别不大,其中前面几个数明显稍慢
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2010-6-19 08:36:01 | 显示全部楼层
我并不认为 太小的模 有多大的用处 实用的数论变换,都是用一个很大的模做的 而中间的乘法,是用那些经过实践验证在小规模上 胜过数论变换和FFT傅里叶变换的算法的,像toom等算法 足够小的模会带来计算速度的降低的 我决的,怎么也要在10000位二进制以上的规模上 应用类FFT算法才比较合算,毕竟该类算法的预计算是比较繁琐的 至于模数的选择,我倾向于2^n + 1,因为足够简单
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2010-6-19 08:41:37 | 显示全部楼层
实践上应该是这么取舍的 超大规模,是浮点的傅里叶变换,大规模是FNT数论变换,然后中规模是Toom算法,小规模是Karatsuba乘法,极小的规模是硬乘。 这些算法,是从大到小的迭代调用关系,有一个统一的外壳根据规模自动选择
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2010-6-19 10:53:05 | 显示全部楼层
我自己写的程序 小的直接就硬乘. 稍大一点的就用用费马变换.(感觉规模小的时候乘法真的影响速度,可能给自己写的效率有关系) 然后就是分治. 1024位(10进制数)以上就用快速数论变换. 太大没有条件测试了,想进一步提速,就发生了这贴的问题. (现在还没有能力看明白CRT,CRT的原理倒基本看得明白什么意思.) 昨晚看到 Decimal 数据类型,如果是硬件能够支持,那就太恐怖(29位)了. 不过好像不是基本类型.
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2010-6-19 16:10:07 | 显示全部楼层
等把CRT的弄出来后按 无心人 的实现一下TOOM算法(这个没有写出来过,) 不过估计是一两个星期后的事了.
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2010-6-21 08:25:46 | 显示全部楼层
你说的费马变换是FNT么?那个比分治高级吧 不应该在你说的位置 ============================= Toom论坛有论文,有具体的实现算法 GMP实现了Toom-3,4,5,6算法 可以大大减少必须用FFT(整数的)的几率
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
您需要登录后才可以回帖 登录 | 欢迎注册

本版积分规则

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

GMT+8, 2024-11-22 00:20 , Processed in 0.027595 second(s), 16 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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