日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > python >内容正文

python

python 有限域函数库_有限域(4)——程序实现有限域的运算

發(fā)布時(shí)間:2023/12/10 python 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python 有限域函数库_有限域(4)——程序实现有限域的运算 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

版權(quán)申明:本文為博主窗戶(Colin Cai)原創(chuàng),歡迎轉(zhuǎn)帖。如要轉(zhuǎn)貼,必須注明原文網(wǎng)址

http://www.cnblogs.com/Colin-Cai/p/9652019.html

作者:窗戶

QQ/微信:6679072

E-mail:6679072@qq.com

前一章,我們知道了使用素域的多項(xiàng)式環(huán)的商環(huán)構(gòu)造任意的有限域的方法。這一章里,我們就用程序?qū)崿F(xiàn)任意有限域里的運(yùn)算。

我在這里還是同第一章一樣,選擇用Scheme來(lái)描述。

數(shù)據(jù)表示

首先,我們需要的一個(gè)參數(shù)就是域的特征,記為?p

根據(jù)上章分析,我們還需要一個(gè)不可分多項(xiàng)式,稱(chēng)為生成多項(xiàng)式,記為 poly

上一章還有一個(gè)重要結(jié)論是,如果poly的次數(shù)是n, 那么所有的次數(shù)小于n的多項(xiàng)式共計(jì)pn個(gè),分別屬于不同的商集,除此之外并無(wú)其他商集,那么也就對(duì)應(yīng)著最后的域的元。

所以,我們這里就以這pn個(gè)小于n次的多項(xiàng)式來(lái)代表該域的所有元,這種表示是合理的。

現(xiàn)在,我們來(lái)考慮不可分多項(xiàng)式以及域里每個(gè)元的計(jì)法:

我們用一個(gè)長(zhǎng)度為n+1的list來(lái)記錄生成多項(xiàng)式poly就可以了(n次多項(xiàng)式一共n+1個(gè)系數(shù)),這個(gè)list的第0項(xiàng)、第1項(xiàng)、...第n-1項(xiàng)、第n項(xiàng)分別對(duì)應(yīng)著poly的n次系數(shù)、n-1次系數(shù)、...1次系數(shù)、0次系數(shù)(常數(shù)項(xiàng))。比如,特征2素域下的3次不可分多項(xiàng)式 x3+x+1,記作(1? 0 1 1)。

而對(duì)于每個(gè)域里的元,我們也用上述的寫(xiě)法來(lái)記,只是,我們把這個(gè)多項(xiàng)式補(bǔ)齊成n-1次,沒(méi)有的項(xiàng)系數(shù)都為0,比如在2特征、生成多項(xiàng)式x3+x+1的域下,元[x+1]記為(0 1 1),也就是一個(gè)域下所有的元,記錄成list都是生成多項(xiàng)式的次數(shù)這么長(zhǎng)。

函數(shù)定義

我們?cè)賮?lái)定義函數(shù)接口,我們就這樣去表示有限域里的加減乘除:

(add poly p a b) 代表p特征、生成多項(xiàng)式為poly時(shí),a+b

(sub poly p a b) 代表p特征、生成多項(xiàng)式為poly時(shí),a-b

(mul poly p a b) 代表p特征、生成多項(xiàng)式為poly時(shí),a*b

(div poly p a b) 代表p特征、生成多項(xiàng)式為poly時(shí),a/b

當(dāng)然,除法涉及到求逆,

(inv poly p a) 代表p特征、生成多項(xiàng)式為poly時(shí),a的逆

程序設(shè)計(jì)

有了上述準(zhǔn)備,再來(lái)看第一章的素域里的加減乘除:

;加法

(define (addp p a b)

(if (>= (+ a b) p) (- (+a b) p)

(+a b)

)

)

;減法

(define (subp p a b)

(addp p a (if (zero? b) 0 (-p b)))

)

;乘法

(define (mulp p a b)

(remainder (*a b) p)

)

;求逆

(define (invp p a)

(define (pow n a b)

(cond

((zero?n) a)

((zero? (remainder n 2)) (pow (quotient n 2) a (mulp p b b)))

(else (pow (quotient n 2) (mulp p a b) (mulp p b b)))

)

)

(pow (- p 2) 1a)

)

;除法

(define (divp p a b)

(mulp p a (invp p b))

)

加法和減法很容易做,一個(gè)map,對(duì)應(yīng)的都是相同次數(shù)的項(xiàng)的系數(shù),然后做合并同類(lèi)項(xiàng)即可。

(define (addp p a b)

(if (>= (+ a b) p) (- (+a b) p)

(+a b)

)

)

(define (subp p a b)

(addp p a (if (zero? b) 0 (-p b)))

)

而對(duì)于inv求逆來(lái)說(shuō),因?yàn)閜n階域里,除0之外的所有的元乘法構(gòu)成一個(gè)群,所以任何一個(gè)元的pn-1 次冪就是自己的逆元。

(define (inv poly p a)

(define (pow poly p a n)

(if (zero?n)

(append (make-list (- (length a) 1) 0) '(1)) ;指數(shù)為0的時(shí)候就是1元

(mul poly p a (pow poly p a (- n 1))) ;否則就是a和a的n-1次冪的乘積

)

)

(define (pow-n p n)

(if (zero? n) 1 ;指數(shù)為0的時(shí)候就是1(* p (pow-n p (- n 1))) ;否則就是p和p的n-1次冪的乘積

)

)

(pow poly p a (- (pow-n p (length a)) 2))

)

于是,除法也就順理成章:

(define (div poly p a b)

(mul poly p a (inv poly p b))

)

當(dāng)然,上面的求冪算法是個(gè)效率很差的算法。我們可以改個(gè)對(duì)數(shù)級(jí)的算法,此處不多解釋。理論依據(jù)我之前的文章《RSA簡(jiǎn)介(二)——模冪算法》

于是我們效率高的求逆如下:

(define (inv poly p a)

(define (pow poly p a n)

(define (pow2 n r x)

(cond

((zero?n) r)

((zero? (remainder n 2)) (pow2 (quotient n 2) r (mul poly p x x)))

(else (pow2 (quotient n 2) (mul poly p r x) (mul poly p x x)))

)

)(pow2 n (append (make-list(- (length a) 1) 0) '(1)) a)

)

(define (pow-n p n)

(define (pow2 n r x)

(cond

((zero?n) r)

((zero? (remainder n 2)) (pow2 (quotient n 2) r (*x x)))

(else (pow2 (quotient n 2) (* r x) (*x x)))

)

)

(pow2 n1p)

)

(pow poly p a (- (pow-n p (length a)) 2))

)

關(guān)鍵是乘法,做起來(lái)有些難,對(duì)lisp沒(méi)有太多基礎(chǔ)且不習(xí)慣函數(shù)式編程的人可能很難寫(xiě)出來(lái)。

兩個(gè)元的乘法結(jié)果應(yīng)該是其多項(xiàng)式乘法然后對(duì)生成多項(xiàng)式做帶余除法得到的余數(shù)。

從而,可以先構(gòu)造兩個(gè)函數(shù),一個(gè)函數(shù)是多項(xiàng)式乘法:

(define (poly-mul p a b)

(map (lambda (x) (remainder x p))

(cdr

(foldr

(lambda (x y)

(cons

(+ 1(car y))

(map+(append (make-list (- (length b) (car y) 1) 0) (map (lambda (c) (* c x)) a) (make-list (car y) 0))

(cdr y)

)

)

)

(make-list (+ (length a) (length b)) 0)

b

)

)

)

)

一個(gè)用迭代實(shí)現(xiàn)的帶余除法,如下

(define (division a b)

(define (division-iter a b b_len times)

(cond

((zero? times) a)

(else

(division-iter

(append

(map

(lambda (x y) (modulo (- x (* y (divp p (car a) (car b)))) p))

(cdr (take a b_len))

(cdr b)

)

(drop a b_len)

)

b

b_len

(- times 1)

)

)

)

)

(division-iter a b (length b) (- (length a) (length b) -1))

)

有了上述基礎(chǔ),就可以構(gòu)造乘法,乘法就是

(define (mul poly p a b)

(division

(poly-mul p a b)

poly

)

)

多項(xiàng)式乘法poly-mul的實(shí)現(xiàn)中用到了foldr算子,這個(gè)算子并不是定義在Scheme任何標(biāo)準(zhǔn)中的,獨(dú)屬于racket。不過(guò)這個(gè)算子實(shí)際上就是著名的SICP里的accumulate算子,我也一直很奇怪如此重要的算子為什么不在標(biāo)準(zhǔn)中體現(xiàn)。以下是這個(gè)算子的定義。

(define (foldr op init lst)

(if (null?lst) init

(op (car lst) (foldr op init (cdr lst)))

)

)

測(cè)試

以上,域的加減乘除都有了。

我們可以測(cè)試一下,階最小的不是素域的有限域是4階,特征為2。

特征2素域下的不可分2次多項(xiàng)式只有一個(gè),x2+x+1

(define poly '(1 1 1)) ;生成多項(xiàng)式

(define p 2) ;特征

(define (list-all)

(define (sub1 x)

(foldr (lambda (m n) (if (zero? (apply * n)) (cons m n) (cons (- 1 m) n))) '() x)

)

(define (func2 x y)

(let*((a (car x))

(b (cdr x))

(asum (apply+a))

(bsum (apply+b))

)

(cond

((zero? (+asum bsum)) (cons x y))

((zero?bsum) (func2 (cons (sub1 a) (sub1 b)) (cons x y)))

(else(func2 (cons a (sub1 b)) (cons x y)))

)

)

)

(let ((m (make-list (- (length poly) 1) (- p 1))))

(func2 (cons m m)'())

)

)

(for-each

(lambda (x) (display (string-append

(format"~a+~a=~a ~a-~a=~a ~a*~a=~a"(car x)

(cdr x)

(add p (car x) (cdr x))

(car x)

(cdr x)

(sub p (car x) (cdr x))

(car x)

(cdr x)

(mul poly p (car x) (cdr x))

)

(if (zero? ( foldr + 0(cdr x)))"\n"(format"~a/~a=~a\n"(car x)

(cdr x)

(div poly p (car x) (cdr x))

)

)

)

)

)

(list-all)

)

上面測(cè)試代碼中poly和p可以任意改,這里只以4階域?yàn)闇y(cè)試對(duì)象。

以上運(yùn)行結(jié)果如下:

(0 0)+(0 0)=(0 0) (0 0)-(0 0)=(0 0) (0 0)*(0 0)=(0 0)

(0 0)+(0 1)=(0 1) (0 0)-(0 1)=(0 1) (0 0)*(0 1)=(0 0) (0 0)/(0 1)=(0 0)

(0 0)+(1 0)=(1 0) (0 0)-(1 0)=(1 0) (0 0)*(1 0)=(0 0) (0 0)/(1 0)=(0 0)

(0 0)+(1 1)=(1 1) (0 0)-(1 1)=(1 1) (0 0)*(1 1)=(0 0) (0 0)/(1 1)=(0 0)

(0 1)+(0 0)=(0 1) (0 1)-(0 0)=(0 1) (0 1)*(0 0)=(0 0)

(0 1)+(0 1)=(0 0) (0 1)-(0 1)=(0 0) (0 1)*(0 1)=(0 1) (0 1)/(0 1)=(0 1)

(0 1)+(1 0)=(1 1) (0 1)-(1 0)=(1 1) (0 1)*(1 0)=(1 0) (0 1)/(1 0)=(1 1)

(0 1)+(1 1)=(1 0) (0 1)-(1 1)=(1 0) (0 1)*(1 1)=(1 1) (0 1)/(1 1)=(1 0)

(1 0)+(0 0)=(1 0) (1 0)-(0 0)=(1 0) (1 0)*(0 0)=(0 0)

(1 0)+(0 1)=(1 1) (1 0)-(0 1)=(1 1) (1 0)*(0 1)=(1 0) (1 0)/(0 1)=(1 0)

(1 0)+(1 0)=(0 0) (1 0)-(1 0)=(0 0) (1 0)*(1 0)=(1 1) (1 0)/(1 0)=(0 1)

(1 0)+(1 1)=(0 1) (1 0)-(1 1)=(0 1) (1 0)*(1 1)=(0 1) (1 0)/(1 1)=(1 1)

(1 1)+(0 0)=(1 1) (1 1)-(0 0)=(1 1) (1 1)*(0 0)=(0 0)

(1 1)+(0 1)=(1 0) (1 1)-(0 1)=(1 0) (1 1)*(0 1)=(1 1) (1 1)/(0 1)=(1 1)

(1 1)+(1 0)=(0 1) (1 1)-(1 0)=(0 1) (1 1)*(1 0)=(0 1) (1 1)/(1 0)=(1 0)

(1 1)+(1 1)=(0 0) (1 1)-(1 1)=(0 0) (1 1)*(1 1)=(1 0) (1 1)/(1 1)=(0 1)

總結(jié)

以上是生活随笔為你收集整理的python 有限域函数库_有限域(4)——程序实现有限域的运算的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。