[英]I can't understand this Horner's rule implementation in extended fields GF(p^n)
我正在尝试从github上的此(旧)实现中了解Shamir的秘密共享方案的实现 ,并且在扩展字段GF(p ^ n)中的Horner规则方面遇到了麻烦:
void horner(int n, mpz_t y, const mpz_t x, const mpz_t coeff[])
{
int i;
mpz_set(y, x);
for(i = n - 1; i; i--) {
field_add(y, y, coeff[i]);
field_mult(y, y, x);
}
field_add(y, y, coeff[0]);
}
为什么add
放在第一位,然后才mult
? 算法是什么? 为什么不这样:
mpz_set(y,coeff[n-1]);
for(i = n - 2; i!=-1; i--) {
field_mult(y, y, x);
field_add(y,y,coeff[i]);
}
用普通的加法和乘法符号翻译此horner
函数,我们得到:
y = x; // mpz_set(y, x);
for(i = n - 1; i; i--) {
y = y + coeff[i]; // field_add(y, y, coeff[i]);
y = y * x // field_mult(y, y, x);
}
y = y + coeff[0] // field_add(y, y, coeff[0]);
您可以看到它不计算任何多项式,但是它是Horner算法计算单项多项式的变体。
现在您的建议:
y = coeff[n-1]; // mpz_set(y,coeff[n-1]);
for(i = n - 2; i!=-1; i--) {
y = y * x; // field_mult(y, y, x);
y = y + coeff[i]; // field_add(y,y,coeff[i]);
}
如果要将所有操作都包含在循环体内,则可以。 毕竟,这只是分解一系列交替指令的两种方法:
operation value of y loop iteration
add-mult loop mult-add loop
x initialization n-1
add x + coeff[n-1] n-1 n-1
mult (x + coeff[n-1]) * x n-1 n-2
add (x + coeff[n-1]) * x + coeff[n-2] n-2 n-2
mult ((x + coeff[n-1]) * x + coeff[n-2]) * x n-2 n-3
...etc...
但是,您需要将y
显式初始化为值1
(这是隐式coeff[n]
),以便您可以通过乘以x
开头并获得正确的最高阶项。
y = 1; // mpz_set(y,1);
for(i = n - 1; i!=-1; i--) { // NOTICE n - 1 NOT n - 2
y = y * x; // field_mult(y, y, x);
y = y + coeff[i]; // field_add(y,y,coeff[i]);
}
您可以算出您现在再执行一次乘法,并且乘以1 * x
。 在有限域上,这通常是通过对数和对数表来完成的,因此您最好避免这种无用的乘法,尤其是在要大量评估多项式的情况下。
TL; DR:这种Horner算法的编写方式将最后的加法和第一个乘法放在循环体之外。 由于最高阶系数为1
因此该乘法被完全删除。
需要说明的是:保留了最高阶项,但是它是x^n
而不是1 * x^n
。 您可以保留一个乘法来获得完全相同的结果。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.