存储编码,矩阵等之间的运算都是在伽罗华域(Galois Field,GF,有限域)上进行的,所以要实现底层的运算库,必须了解 GF 上的运算规则。
域:
一组元素的集合,以及在集合上的四则运算,构成一个域。其中加法和乘法必须满足交换、结合和分配的规律。加法和乘法具有封闭性,即加法和乘法结果仍然是域中的元素。域中必须有加法单位元和乘法单位元,且每一个元素都有对应的加法逆元和乘法逆元。但不要求域中的 0有乘法逆元。
有限域GF(p):
有限域GF(p)是一个很重要的域,其中p为素数。简单来说,GF(p)就是 mod p,因为一个数模p后,结果在[0, p-1]之间。对于元素a和b,那么(a+b) mod p和(a*b)mod p,其结果都是域中的元素。GF(p)里面的加法和乘法与一般的加法和乘法差不多,区别是结果需要mod p,以保证结果都是域中的元素。GF(p)的加法和乘法单位元分别是 0和1。GF(p)加法是(a+b) mod p,乘法是(a*b)mod p。
重点讲一下GF(2^n),特别是GF(2^8),因为8刚好是一个字节的比特数。前面说到, GF(p),p得是一个素数,才能保证集合中的所有元素都有加法和乘法逆元(0除外)。但我们却很希望0到255这256个数字也能组成一个域。因为很多领域需要用到。mod 256的余数范围就是0到255,但256不是素数。小于256的最大素数为251,所以很多人就直接把大于等于251的数截断为250。解决方法就是GF(p^n),其中p为素数。在这里我们只需令p为2,n为8,即GF(2^8)。
多项式运算:
要弄懂GF(2^n),要先明白多项式运算。这里的多项式和初中学的多项式运算有一些区别。虽然它们的表示形式都是这样的:f(x) = x^6 + x^ 4 + x^2 + x + 1。下面是它的一些特点:
1、多项式的系数只能是0或者1。当然对于GF(p^n),如果p等于3,那么系数是可以取:0, 1, 2的
2、合并同类项时,系数们进行异或操作,不是平常的加法操作。比如x^4 + x^4等于0*x^4。因为两个系数都为1,进行异或后等于0
3、无所谓的减法(减法就等于加法),或者负系数。所以,x^4 – x^4就等于x^4 + x^4。-x^3就是x^3。
看一些例子:
f(x) = x^6 + x^4 + x^2 + x + 1。g(x) = x^7 + x + 1。那么:
f(x) + g(x) = x^7 + x^6 + x^4+ x^2 + (1+1)x + (1+1)1 = x^7 + x^6 + x^4 + x^2。f(x) – g(x)等于f(x) + g(x)。
f(x) * g(x) =(x^13 + x^11 + x^9 + x^8 + x^7) + (x^7 + x^5 + x^3 + x^2 + x) + (x^6+ x^4 + x^2 + x + 1) = x^13 + x^11 + x^9 + x^8 + x^6 + x^5+ x^4+ x^3+1。
本原多项式:本源多项式不能表示为其他两个多项式相乘的乘积。
本源多项式模运算:
对于GF(2^3)来说指数小于3的多项式有8个,分别是0, 1, x, x+1, x^2, x^2+1, x^2 + x, x^2+x+1。其中一个本源多项式为x^3+x+1,前面8个多项式进行四则运算后 mod (x^3+x+1)的结果都是8个之中的某一个。对于GF(2^8),其中一个本源多项式为x^8 + x^4 + x^3 +x +1。对应地,小于8次的多项式有256个。
通过本原多项式生成元素:
我们设 q(x) 是在 GF(2^w) 上的一个本原多项式(最小多项式),则任意的 GF(2^w) 均可以由 GF(2^w)下的多项式x产生出。基本步骤是:
1、给定一个初始集合 {0,1,x}
2、将这个集合中的上一个元素,例如x ,乘以x如果得到的结果的度大于等于w,则再将结果 mod q(x)
3、直到集合有2^w个元素,此时最后一个元素乘以 x 再 mod q(x) 的值为 1
下面给出一个例子来说明,当 w=2 时,q(x)=x^2+x+1,对 GF(4),最开始的集合是 {0,1,x},这个集合的上一个元素是 x,乘以 x 得到 x^2,此时其度等于 w,所以 x^2%q(x)=x+1;此时集合更新为 {0,1,x,x+1};再将 上一个元素 x+1 乘以 x,得到 x^2+x,其度数也等于 2,所以 (x^2+x)%q(x)=1,此时可以结束这个过程,即 GF(4) 为 {0,1,x,x+1}。
通过上面说明,只需要找到对应 GF(2^w) 上的本源多项式 q(x) (运算遵循 GF(2)),则其即可通过 x 代换得到,可以对应表示成:
GF(2^w)=GF(2)[x]/q(x)
根据已有理论,根据不同 w ,对应本源多项式为:
在实际计算机中,都是使用二进制来运算,所以我们需要将 RS 码中的 GF(2^w) 中的元素都映射到二进制上来:s(x) 的元素 x^i 对应到二进制位的 i -th,例如上面的 GF(4) 中,依次对应的是 {00,01,10,11}。如下图给出 GF(16) 的例子:
通过上面系列对 GF(2^w) 的分析,对应其上的乘法可以转换成多项式相乘后再 mod q(x),问题得到了简化(多项式相乘时,各元素次数做的是加法)。因此,我们定义 RS 码上的元算时,先将二进制映射成多项式,再求模运算,再转换成二进制,这样一来,我们有两个映射表格 gflog(将二进制映射成多项式) 和 gfilog(对多项式进行运算,然后将结果转换成二进制),不同的 w 对应不同的表格,表格中的元素是 2^w?1 (0 单独存在,没有哪个的次方等于 0)。如下图给出了w=4 情况下的两个表格:
对应给出乘法和除法运算的例子:
7 * 9 = gfilog[gflog[7] + gflog[9]] = gfilog[10 + 14] = gfilog[9] = 10
13 / 11 = gfilog[gflog[13] - gflog[11]] = gfilog[13 - 7] = gfilog[6] = 12