Listをやろう

1から10の和
Geogebraで関数型プログラミングにとりくむ
[b][size=150][b][size=150]このワークシートは[url=https://www.geogebra.org/m/twxxx3yq]Math by Code[/url]の一部です。[br][/size][/b][br]<プログラミングってなんだっけ?>[br][/size][/b][br]プログラミングといえば、[br]計算などの記号・数値の操作をして、[br]問題を解決したりするための計画書を作ることだね。[br][br]詳しい話は省きますが、[br][color=#38761d][size=200][b]プログラミングには3つの側面がある[/b][/size][/color][br]といわれているね。[br]さて、何でしょう?[br][br]順番にやる「[color=#0000ff][b][size=100][size=150]順次[/size][/size][/b][/color]」、[br]同じようなことをくり返す「[size=150][color=#0000ff][b]反復[/b][/color][/size]」、[br]条件をつけて枝分かれする「[b][size=150][color=#0000ff]分岐[/color][/size][/b]」。[br][br]やりたいことを1行1行書き並べえて、上から順に実行するのが順次だね。[br]for文やwhile文を使って条件をつけて同じようなことを繰り返すのが反復だ。[br]分岐は、変数の値の範囲などで、次にどうするかを変えるのが分岐だ。[br][br]また、[br]同じようなことを何回もかくのも無駄だから、[color=#0000ff][b][size=150]変数と関数[/size][/b][/color]を用意して、記述を短くするのも便利だ。[br][br]プログラミングを建築としたら、堅牢で柔軟でエコなものが求められるだろう。[br][br]変数に対する手続きの流れを構造化するためにいろんな思想や言語やツールが次々に登場しているね。[br][br]現実の情報の流れにそってデータと処理の「型」を作り、それをデータとつなぐ「[color=#0000ff][b][size=150]オブジェクト指向[/size][/b][/color]」。[br]関数を数学の定義に近づけようとする「[size=150][b][color=#0000ff]宣言型、関数型[/color][/b][/size]」プログラミングの研究。[br]データ処理が表に対するものと考える行列・表・データベースの編集・探索のための「[color=#0000ff][b][size=150]パッケージ[/size][/b][/color]」。[br]AI、機械学習の研究開発、組み込み、Web、バックエンド、モバイルなど用途別の「[color=#0000ff][b][size=150]サービス[/size][/b][/color]」。[br]。。。などがある。[br][br][u][b][size=150][color=#38761d]質問:あなたが関数型プログラミングについて知っていることや用語を伝えてください。[br][/color][/size][/b][/u]
[b][size=150]<手続き型 VS 宣言型>[br][/size][/b][br][b][color=#38761d][size=200]200行5列の[br]200人の5科目(国、数、英、理、社)の得点表があるとしましょう。[br]これから200人分の平均点を出したい。[br][/size][/color][/b][br]1人目の得点は[br]国+数+英+理+社で出して、第6列(C6)に記入し、第7列(C7)にも書こう。[br]そして、2人目も同じように第6列(C6)を書く。第7列(C7)には上の行の7列目(C7)+この行の6列目(C6)。[br]こんな感じでやると、7列目(C7)には、どんどん、6列目(C6)が足されていく。[br]そして、200行7列目(C7)には200人分の5科目合計点の合計が入る。[br]最後に201行目にC7÷200を計算して書く。[br][br]これが、「[color=#0000ff][b][size=150]手続き型[/size][/b][/color]」だね。[br]juliaは手続き的にも関数型でも対応できるし、[br]添字が1スタートでgeogebraと同じだし、[br]記述がpythonに似ているので基本juliaで書いてみよう。[br][br][br][IN]julia[br]0点から100点までの200行5列の表データdataを適当に作る。[br]#データ作成***************************************[br][color=#0000ff][br]data=rand(0:100,200,5)[br][/color][br]#手続き的***************************************[br][color=#0000ff][br]C7 = 0[br]for hito in 1:200[br] C6 = 0[br] for kamoku in 1:5[br] C6 = C6 + data[hito, kamoku][br] end[br] C7 = C7 + C6[br]end[br]C7/200[br][/color][br]#***************************************[br][br]juliaは添え字が1開始で終了までの範囲をかくだけだから、初心者でも使いやすい。[br][br]しかし、他の言語はちがう。[br]範囲指定は繰り返しの書き方はC言語由来のスタート、増分、終了という書き方が[br]主流なので慣れが必要だ。しかも、今人気のpythonでさえも、添え字が0スタートだ。[br]「[color=#0000ff][b][size=150]フローチャートのパラダイム・流儀[/size][/b][/color]」に慣れるのにはよいでしょう。[br][br]しかし、この程度の課題なら、エクセルとかの表アプリがあれば、そんな苦労は不要だ。[br]エクセルを使った人ならわかるだろうけど[br]6列目に=Σ(1行目の5列の範囲指定)という関数をかき、それを200行までコピーする。[br]2001行目6列目に=Ave(6列目の1行から200行の範囲指定)という関数を書けば、計算式も不要だ。[br]そして、7列目という加算の繰り返し結果の順次記入という手間がいらないね。[br][br]このように、[color=#0000ff][b][size=150]順次や繰り返しというプログラミングのパラダイムを減らし、[br]数学的に(つまり、宣言的、内包的に)かける[/size][/b][/color]と、簡単だしわかりやすいね。[br][br]たとえば、6列目(L)は数データのリストになるね。[br]これを内包的にかいてみよう。[br] sum は、 hito番目のdataのすべての列のデータxの合計だ。[br]6列目(L)は、hitoが1から200番までいるときのsumの列だ。[br]あとは、平均=6列の合計÷6列の行数[br]=sum(L)÷size(L)のようにかける。[br][color=#980000](※size関数はプログラミング言語によってちがうので注意しよう)[br][/color]julia[br]#内包的***************************************[br][br][color=#0000ff]L= [ sum( [ x for x in data[hito, : ] ] ) for hito in 1:200 ] [br][br]sum(L)/length(L)[br][/color][br]#***************************************[br]つまり、[math]\sum_{hito=1}^{200}\sum_{i=1}^5data\left(hito,i\right)\div200[/math] と同じ書き方だ。[br]数学そのものの書き方だね。[br]ただ、2重のΣ計算の範囲をforのあとに記述しているだけだとわかるね。
では、geogebraで宣言型にかいてみよう
[size=150][b]<ウォーミングアップ>[/b][/size][br][br]手続き型でも宣言型でも、for条件が入れ子になっていることがわかるね。[br]そこで、もっと簡単な1重のfor条件をgeogebraでやってみよう。[br][br]1から10までの和をjuliaでかく。[br][color=#0000ff][IN][br]#======================[br]lst=[n for n in 1:10][br]sumlst=sum(lst)[br]#======================[br][OUT][br]55[br][/color][br][color=#cc0000]ワークシートにgeogebraアプリを作成したかったら、[br]最下行の「+要素の追加ボタン」を押して作成を選びます。[br]次に適当にたとえば、図形や関数を選びましょう。メニューバーの右上の3本線「三」マークを押し、[br]プルダウンメニューから表示を選べます。その真中あたりの「表示」を押して[br]チェックボックスの「数式」にチェックを入れましょう。[br]そうすると、数式、geogebraコードが表示されます。[br][br][/color][color=#38761d]関数コマンドは[url=https://geogebra.github.io/docs/manual/ja/]geobebraの日本語マニュアルページ[/url]を辞書代わりに使ってみましょう。[br][/color][br]geogebraではxは座標として解釈される予約語なので、変数は基本nなどにしよう。
1から10の和
さあ、この調子で2重のΣ計算を、geobebraを使って宣言型でかいてみよう。[br][br][color=#0000ff]200人分のデータの生成には、[br]data=Sequence(Sequence(RandomBetween(0,100),kamoku,1,5),hito,1,200)[br][br]200人分の5科目の合計点リストは、[br]L=Sequence(Sum(data(hito,k),k,1,5),hito,1,200)[br][br]平均点の計算は、[br]((Sum(L))/(Length(L)))[/color]
200人の平均点を宣言型で求めよう

メルセンヌさんの素数

[size=150][b][size=150]このワークシートは[url=https://www.geogebra.org/m/twxxx3yq]Math by Code[/url]の一部です。[br][/size][br]<メルセンヌ素数ってなんだっけ?>[br][br][/b]1644年にフランスのメルセンヌさんが、「M(n)=2[sup]n[/sup]-1型のn<=257の素数は11個だ」[br]と[color=#9900ff]予想[/color]しました。(n=2,3,5,7,13,17,19,31[color=#ff0000],67,[/color]127,[color=#ff0000]257[/color])[br]そこから、この型の素数をメルセンヌ素数と呼ばれるようになったようです。[br]1876年にリュカ(Lucas)さんが、127以下のメルセンヌ素数Mnは[br]n=2,3,5,7,13,17,19,31までは同じですが、[br]n=[color=#0000ff]61,89,107[/color],127になることを証明したそうです。[br]1952年以降、その続きがn=[color=#0000ff]512,607,1279,2203[/color],..........と発見が続いています。[br][br]メルセンヌ型素数は、mが素数であることは必要条件。[br]なぜなら、mが合成数だと2[sup]m[/sup]-1も合成数になるから。[br]このことは整式の分解で説明がつく。[br][b]mは素数であることが必要になる。しかし、十分とは限らないので要注意。[br]実際に調べてみよう。[br]juliaで素数判定関数を作る。[br]次に、juliaで2から31までの素数リストMを作る。[br]Mの要素mに対して2[sup]m[/sup]-1が素数になるものをfilterで取り出そう。[br]<参考>[br](・[b][color=#0000ff]素数リスト[/color][/b]の作り方、[color=#0000ff][b]素数判定[/b][/color]については[url=https://www.geogebra.org/m/jxmueqdt]こちら、[br][/url] ・リストに[color=#0000ff][b]filterをかける方法[/b][/color]については[url=https://www.geogebra.org/m/vre8rh6h]こちら[/url])[br][br][br][/b][color=#0000ff][IN]julia[br][/color][/size][color=#0000ff]#======================[br][/color]function isPrime(n)[br] lim = Int(round(n^0.5))[br] for num in 2:lim[br] if BigInt(n) % BigInt(num) ==0 [br] return false[br] end [br] end[br] return true[br]end[br]M=filter(n->length(filter( m -> n % m==0,1:n))==2, 2:31)[br]Ms=filter(m->isPrime(2^m-1),M)[br]println(M)[br]println(Ms)[br][color=#0000ff]#======================[/color][OUT][br][2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31][br][2, 3, 5, 7, 13, 17, 19, 31][br][br]このように少し調べただけでも[br]2[sup]m[/sup]-1が素数になる素数mを限定できたね。[br][br]geogebraでも試してみよう。[br]Juliaと同じロジックで、ほぼ同じような記述で調べることができる。
メルセンヌ素数判定法
<リュカ数>[br]Mp=2^p-1[br]Spは漸化式で、S[sub]0[/sub]=4, S[sub]k[/sub]=S[sub]k-1[/sub][sup]2[/sup]-2.[br][br]p番めのメルセンヌ数をMp,リュカ数をSpとする。[br][color=#0000ff][b][size=200]S[sub]p-2[/sub]がM[sub]p[/sub]で割り切れるときに、Mpは素数になる[br][/size][/b][/color]ことが必要十分条件だ。[br]Spは2乗して2をひくことを繰り返すので、急激に桁が大きくなると予想されるね。[br]それでも多桁なのでJuliaで多桁用にBigInt()でかこってリュカ数(Lucas)を作ってみよう[br][color=#0000ff]#Julia[br][/color][color=#0000ff]#[IN][br][/color][color=#0000ff]#====================[br][/color]#リュカ数を作る[br]Lucas=BigInt(4^2-2)[br]S=[Lucas][br]for i in 1:8[br] Lucas=BigInt(Lucas^2-2)[br] push!(S,Lucas)[br]end[br]println(S)[br][color=#0000ff]#====================[br][OUT][br][/color]BigInt[14, 194, 37634, 1416317954, 2005956546822746114, 4023861667741036022825635656102100994, 16191462721115671781777559070120513664958590125499158514329308740975788034, 262163465049278514526059369557563039213647877559524545911906005349555773831236935015956281848933426999307982418664943276943901608919396607297585154, 68729682406644277238837486231747530924247154108646671752192618583088487405790957964732883069102561043436779663935595172042357306594916344606074564712868078287608055203024658359439017580883910978666185875717415541084494926500475167381168505927378181899753839260609452265365274850901879881203714][br][br]<リュカ・レーマーテスト>[br]S[sub]p-2[/sub]がMpの倍数であることがMpはメルセンヌ素数であることの必要十分条件だった。[br] S=[14, 194, 37634, 1416317954, 2005956546822746114][br]M=[1,3,7,15,31,63,.....][br]S1 % M3=14 / 7=2だから、M3=7は素数[br]S2 % M4=194 % 15 !==0だから、M4は素数ではない。[br]S3 % M5= 37634 / 31 =1214だから、M5は素数。[br]こうして、2つ番号ちがいのリュカ数列をメルセンヌ数列で割り切れると[br]素数と判定できる。割り切れるかどうかは、剰余が0になるかどうかだから、[color=#0000ff][b][u]Spそのものではなく、SpをMpで割った剰余で代用[/u][/b][/color]して、[br]けたの爆発を防止しよう。[br][color=#0000ff]#Julia[br][/color][color=#0000ff]#[IN][br][/color][color=#0000ff]#====================[/color][br]target=127[br]M=[][br]for x in 3:target[br] push!(M,BigInt(2)^x - 1)[br]end[br]#println(M)[br]function LucaModM(x)[br] #x番目のメルセンヌ数を法とした剰余でリュカ数列を作る。[br] res=4^2-2[br] for i in 2:x[br] res = BigInt(res^2-2) % BigInt(M[x])[br] end[br] return res[br]end[br]for n in 3:target-2[br] if LucaModM(n)==0[br] println("M",n+2,"=2^",n+2,"-1=",M[n]," is Prime")[br] end[br]end[color=#0000ff]#====================[/color][br][color=#0000ff][OUT][br]M5=2^5-1=31 is Prime[br]M7=2^7-1=127 is Prime[br]M13=2^13-1=8191 is Prime[br]M17=2^17-1=131071 is Prime[br]M19=2^19-1=524287 is Prime[br]M31=2^31-1=2147483647 is Prime[br]M61=2^61-1=2305843009213693951 is Prime[br]M89=2^89-1=618970019642690137449562111 is Prime[br]M107=2^107-1=162259276829213363391578010288127 is Prime[br]M127=2^127-1=170141183460469231731687303715884105727 is Prime[/color][br][br][br]

≡はmagic

1.≡という魔法
[b]このワークシートは[url=https://www.geogebra.org/m/twxxx3yq]Math by Code[/url]の一部です。[br][/b][br][br]整数が偶数と奇数のどちらかのクラスに分けられるというのは便利な考え方です。[br]偶数もたんさんあるし、奇数もたくさんある。[br]でも、偶数は0、奇数は1で代表すると、とても楽になります。[br]それが合同の発想です。[br][br][b][size=150]<合同式>[/size][/b][br]偶数、奇数は2で割った余りによる分類でした。[br]4で割った余りは0,1,2,3の4種類のどれかなので、[br]それでクラス分けしましょう。[br]aを4で割った余りとbで割った余りが等しいとき、合同式「[color=#0000ff][b][size=150]a≡b(mod 4)」と書きます。[br]aとbのクラスは同じとも言えますね。[br][/size][/b][/color][b][color=#0000ff](pを[color=#0000ff][b]法p[/b][/color]とか、モジュラスpとか、pで割ったときとか、mod pとか読みます。[color=#0000ff][b]bは剰余。[/b][/color])[br]この≡記号は=よりも線が1本増えただけで、ほぼ等式の性質が使えます。[br][/color][/b]くわしく見ていきましょう。[br][br][br][b][size=150](一般化しよう)[br][/size][/b][color=#0000ff][b][size=150]a-b≡0(mod p)[/size][/b][/color]とかくと、a-bはpの倍数だ。pはa-bを割り切る(divide)[br][b]p|a-b[/b]ともかけるし、[b](a-b)=pk[/b]ともかけるでしょう。[br][color=#9900ff]実は、これがもともとの合同式の定義でした。[br][/color]整数x,y,zに対してz|(x-y)が成り立つとき、x≡y(mod z)とかき、[br]zを法として、xとyは[b]合同[/b]だという。この式を[b]合同式[/b]と呼ぶ。[br]合同式には3つの性質があり、合同は、同値関係だとわかるね。[br]性質1(反射)x≡x(mod n)[br]性質2(対称)x≡y(mod n)⇒y≡x(mod n)[br]性質3(推移)x≡y(mod n) ∧ y≡z(mod n) ⇒ x≡z(mod n)[br][br]法則(加減乗)2つの合同式の左辺どうし、右辺どうしの和差積は合同だ。[br]   [br][br]
互除法
ABG法
ウィルソンの確認
2.≡と=を比べる
[b]≡は=と同じように、等式の性質が使えることが多い。[br][br][size=150][color=#0000ff][u]質問:≡と=の同じところ、ちがうとこを調べてみよう。[br][/u][/color][br][/size][/b]移項したり、両辺に同じ数をたしたり、ひいたりできるだけでなく、[br]両辺同じ数をかけたり、[br]左辺どうしの積と右辺同士の積を結ぶことができる。[br]また、平方根も整数の範囲で求めることができる。[br]また、負の値はmod のpを加えて正の値にすることができます。これはmod の意味から明らか。[br](例)[br]x≡1(mod7)ならば、2x≡2(mod7)[br]x≡2(mod 7)ならば、7x≡14≡0(mod 7)[br]x-1≡0(mod 7) ならば、x≡1(mod 7)[br]x+6≡1(mod 7) ならば、x≡-5≡-5+7≡ 2(mod 7)[br]x[sup]2[/sup]≡4 (mod 7) ならば、x≡±2≡2, -2+7≡ 2,5(mod 7)[br]・13≡4, 13[sup]2[/sup]≡16≡7≡-2, 13[sup]3[/sup]≡-2・4=-8≡1(mod 9)だから、[br] 13[sup]10000[/sup]≡(13[sup]3[/sup])[sup]3333[/sup]・13≡1・4=4(mod 9)[br][br][br][b][size=150]<法と剰余の関係>[br][/size][/b]ただし、[color=#0000ff][b]等式とちがう部分もある。とくに、割り算だ[/b][/color]。[br][b]x≡1(mod8)[/b]なら、x={1,9,17,25,.....} だから、剰余と法が互いに素なら[color=#0000ff][b]x≡1(mod2, mod4)[/b][/color]となる。[br][b]x≡4(mod 8)[/b]なら、x={4,12,20,28,....} だから、1以外の剰余と法の最大公約数d=4で約すと、[br] x/4={1,3,5,7,....}だから、[b][color=#0000ff]x/4≡4/4(mod 8/4)≡1(mod 2)[br][/color][/b][br][b]x≡6(mod 8)[/b]なら、x={6,14,22,30,....} だから、1以外の剰余と法の公約数d=2で約すと、[br] x/2={3,7,11,15,....}だから、[color=#0000ff][b]x/2≡6/2(mod 8/2)≡3(mod 4)[/b][/color][br][br][b][size=150]<合同方程式を解いてみよう>[br][/size][/b]・1次方程式[b][color=#0000ff][size=150]ax≡b(mod p) [br][/size][/color][/b]ax - b = np となるnがある。[br][b]ax + np =b[/b] という、積和の形に直せるね。 [br][br][b][color=#0000ff][size=150]ma≡mb(mod n) [/size][/color]mがnの倍数でないとき、 両辺をmで割って約せる。しかし、法については注意![br][/b] 法nもmの倍数、n=mcなら、法もmで約せる。a≡b( mod n/m) [br] そうでないとき(nとmが互いに素なら)法はそのままだ。a≡b (mod n)[br] [color=#0000ff][b][size=150]一般に、G(m,n)=dとすると、a≡b( mod n/d)[br][/size][/b][/color][br][color=#0000ff][b](例1)「4x≡3(mod 19)」の解は? x ≡15[br][/b][/color]両辺を5倍する。20x≡(19+1)x≡ x ≡15(mod 19) [br](別解) 3-19=-16。[br]右辺-19で、4x≡-16(mod 19) 両辺を4で約す。x≡-4≡-4+19≡15。[br][color=#0000ff][b](例2)「4x≡16(mod 28)」の解は? x ≡ 4 (mod 7)[br][/b][/color]係数の最大公約数d=4だから、[br]4x/4≡16/4(mod 28/4) x≡4(mod 7)[br]x≡4, 4+7, 4 +7+7, 4 + 7+7+7 ( mod 28)[br]x ≡ 4 , 11, 18, 25(mod 28)[br][b][color=#0000ff](例3)「18x≡8(mod 14)」の解は? x≡2 ,9 (mod 7)[br][/color][/b]剰余と法の最大公約数d=2だから、[br]18x/2≡8/2(mod 14/2) 9x≡4(mod 7) [br]4≡4+7+7=18(mod 7)から、9x≡18(mod 7) x≡2(mod 7)[br]x≡2, 2+7 (mod 7)から、x≡2,9(mod 14)。 [br](別解)[color=#0000ff][b][size=150]ax≡b(mod p)を言い換える。[br]ax-py=bの解はax-py=G(a,p)のb/G(a,p)倍。[br]この倍数が整数のときは解がある。[br] [/size][/b][/color]18・4ー14・5=G(18,14)=2だから、8/2=4倍する。[br]x=4・4=16, y=5・4=20。[br][b]18[/b]・16=[b]14[/b]・20 + [b]8[/b]となる。[br]だから、18・16≡8(mod 14) x=16≡2(mod 14)。[br]他の解は14/2=7を加えて、x=2+7=9(mod 14)[br][b][color=#0000ff](例4)「35x≡105(mod 225)」の解は? x≡3(mod 45)[br][/color][/b]両辺は35の倍数になっている。[br]35 と225 の最大公約数は5だから、[br]35x/35≡105/35(mod 225/5) [br]x≡3(mod 45)[br]x ≡ 3 , 48, 93, 138, 183 (mod 225)[br][color=#0000ff][b](例5)「893x≡266(mod 2432)」の解は? x≡1106,1234, 1362,........, (mod 2432)[br]G(266,2432)=38[br]G(893,2432)=19[br]893x-2432y=266の解は893x-2432y=G(893,2432)=19の266/19=14倍。[br]「ユークリッドの互除法の逆算」(ABG計算)によって、x,yの特殊解は求められるね。[br](ABG計算の説明は省略。)[br][/b][/color]893・79ー2432・29=19だから、14倍する。[br]x=79・14=1106 y=29・14=406。[br][b]893[/b]・1106 = [b]2432[/b]・406+[b]266[/b]となる。[br]だから、893・1106≡266(mod 2432) [br] x≡1106(mod 2432)。[br][b]2432/19=128を1106に加えていく。[br][/b]pythonの対話モードで調べよう。[br]>>> y=1106[br]>>> for i in range(19):[br]... print(y)[br]... y=y+128[br]... y=y%2432[br]を実行する。[br]異なる解はx=1106+128k(mod 2432)=[br]1106[br]1234[br]1362[br]1490[br]1618[br]1746[br]1874[br]2002[br]2130[br]2258[br]2386[br]82[br]210[br]338[br]466[br]594[br]722[br]850[br]978[br][br][b][color=#0000ff](例6)6x≡15(mod 514)[b]の解は?なし[/b][br][/color][/b]6x-15は必ず奇数。法の514は偶数。[br]偶数が割り切る奇数はないので、6x-15≡0(mod 514)の解はない。[br][br]・2次方程式[br][color=#0000ff][b](例7)x[sup]2[/sup]+2x≡0(mod 7)[b]の解は? x ≡ 0, 5 (mod 7)[/b][br][/b][/color]左辺の因数分解で、x[sup]2[/sup]+2x≡x(x+2)≡0(mod 7)から、x≡0, -2≡0,5(mod 7)[br][color=#0000ff][b](例8)x[sup]2[/sup]+2x-1≡0(mod 7)[b]の解は?x≡ 2, 3 (mod 7)[/b][br][/b][/color]左辺-7して因数分解すると、x[sup]2[/sup]+2x-8=(x-2)(x+4)≡0(mod 7)から、x≡2, -4≡2,3(mod 7)[br][b][color=#0000ff](例9)x[sup]2[/sup]≡3(mod 10)[b]の解は?なし[/b][/color][/b][br]x(mod 10)={0,1,2,3,4,5,6,7,8,9}に対して、x[sup]2[/sup](mod 10)={0,1,4,9,6,5,6,9,4,1}から、剰余が3と合同に[br]ならない。だから、解なし。[br][br][color=#0000ff][b]このように、1次合同方程式でも解の数は1つとは限らない。[br]また、1次でも2次でも合同方程式は解なしもありうるね。[br][/b][/color][br][br]
3.「ウィルソンの定理」で≡記号に親しもう
[color=#0000ff][b][size=150]質問:pが素数のときに[br][br][size=200](p-1)! + 1 ≡ 0 (mod p)[br][/size][br]という[u]ウィルソンの定理[/u]というものがあります。[br]≡式の考えを使ってなぜそうなるかを考えてみよう。[br][/size][/b][/color][b][size=150](例)[/size][/b][br]p=2,3,5,7,11のとき、[br](2-1)!+1= 1!+1 =2≡0(mod 2)[br](3-1)!+1= 2!+1 =3≡0(mod 3)[br](5-1)!+1= 4!+1 =25≡0(mod 5)[br](7-1)!+1= 6!+1 =721≡0(mod 7)[br](11-1)!+1= 10!+1 =3628801=329891*11≡0(mod 11)[br][br][b][size=150](mod7で実験しよう)[/size][/b][br](7-1)!=(7-1)*5*4*3*2*1=(7-1)*(5*3)*(4*2)*1[br]≡(7-1)*1*1*1=7-1(mod 7)[br]だから、(7-1)!+1≡7-1+1=7≡0(mod 7)です。[br]7-1以下の1以上の整数は、単位元が1です。[br]剰余どうしの積が1になるペアは逆元といいますが、[br]同じ数が別のペアと逆元になることはありません。[br]1つの数には1つだけ逆元があります。[br]5*3=15≡1(mod 7)[br]4*2=8≡1(mod 7)[br]ただし、特殊なケースが2つあります。[br]1と6です。[br]1*1≡1(mod 7)[br]6*6=(7-1)*(7-1)≡(-1)*(-1)≡1(mod 7)です。[br]だから、7-1=6個の要素のうち、1と6だけは自分が逆元なので、そのままのこる。[br]のこりの6-2=4要素は4/2=2組の1ができるので、かけ算で1となり消える。[br]だから、[color=#0000ff][b]ウィルソンの定理は( )!がはずれる定理[/b][/color]と覚えられます。[br][br][b][size=150](一般化してみよう)[/size][/b][br]7を一般の素数pにしたときも同じ論法です。 [br][b][size=150][color=#0000ff](p-1)!=[/color][/size][/b](p-1)*(p-2)*..........*2*1 ( p-1個の偶数個の積)[br]=(p-1)*1* 1*1*......*1 ( 両端以外の(p-1-2)/2個の逆元ペアが1と合同。)[br][b][size=150][color=#0000ff]≡p-1 (mod p)[/color][/size][/b][br]だから、(p-1)!+1≡p-1+1=p≡0 (mod p) [br]ただし、p=3のときは、(3-1)!=(3-1)*1なので、両端だけで( )!が外れます。[br]また、p=2のときは、(2-1)!=1=2-1だから、先頭の2-1だけそのまま( )!が外れます。

zipで関数とグラフ

1.関数に式は必要か?
[color=#0000ff][b][size=150][b]このワークシートは[url=https://www.geogebra.org/m/twxxx3yq]Math by Code[/url]の一部です。[br][/b][br][br]関数は集合Xの要素xから集合Yの要素yへの対応づけだ。[br][/size][/b][/color]対応がつけばよいだけなのに、対応を式に表すことができると考えてしまいがちだ。[br]f :: X→Y[br]f (x) = expr(x)[br]中学数学で学んだ1次関数、2次関数のイメージが強いためか、[br]関数というと、[color=#0000ff][b]y=xの式という、計算操作のイメージ[/b][/color]がつきまつ。[br][br]しかし、結果としてのグラフイメージで関数を俯瞰してみよう。[br]すると、[color=#0000ff][b]関数はXとYの直積空間(X-Y座標平面)の要素の点(x,y)のあつまり、部分集合[/b][/color]という風にとらえることもできる。[br][br]y=2xという関数は、この関数を満たす点と考えると、順序対、タプル(x,y)のリスト[br]と考えることもできるね。[br]連続量に近いイメージがほしければ、xの範囲を細かく区切ると良い。[br][color=#0000ff]#[IN]julia[br]#============================[br]F=[(x,2*x) for x in 1:10][br]G=[(x,2*x) for x in 1:0.001:10][br]#============================[br][/color][OUT][br]10-element Vector{Tuple{Int64, Int64}}:[br] (1, 2)[br] (2, 4)[br] (3, 6)[br] (4, 8)[br] (5, 10)[br] (6, 12)[br] (7, 14)[br] (8, 16)[br] (9, 18)[br] (10, 20)[br][OUT][br]91-element Vector{Tuple{Float64, Float64}}:[br] (1.0, 2.0)[br] (1.1, 2.2)[br] (1.2, 2.4)[br] (1.3, 2.6)[br] (1.4, 2.8)[br] (1.5, 3.0)[br] (1.6, 3.2)[br] (1.7, 3.4)[br] (1.8, 3.6)[br] (1.9, 3.8)[br] (2.0, 4.0)[br] (2.1, 4.2)[br] (2.2, 4.4)[br] ⋮[br] (8.9, 17.8)[br] (9.0, 18.0)[br] (9.1, 18.2)[br] (9.2, 18.4)[br] (9.3, 18.6)[br] (9.4, 18.8)[br] (9.5, 19.0)[br] (9.6, 19.2)[br] (9.7, 19.4)[br] (9.8, 19.6)[br] (9.9, 19.8)[br] (10.0, 20.0)[br][br]すると、1対1にこだわらなければ、xの剰余を対応させたり、[br][color=#0000ff]xの値と無関係に乱数を作ってzipで順序対(タプル)を作ったり[/color]と[br]関数は自由だ。[br][br][color=#0000ff][b][size=200]zipを使うと、関数も作れるし、グラフもすぐかけるね。[br][/size][/b][br]#[IN]julia[br]#============================[br]H=[(x,x % 3) for x in 1:10][br][/color][color=#0000ff]#============================[br][OUT][br]10-element Vector{Tuple{Int64, Int64}}:[br] (1, 1)[br] (2, 2)[br] (3, 0)[br] (4, 1)[br] (5, 2)[br] (6, 0)[br] (7, 1)[br] (8, 2)[br] (9, 0)[br] (10, 1)[br]#[IN]julia[br]#============================[br]xs=Vector(1:10)[br]ys=rand(10)[br]z=[(x,y) for (x,y) in zip(xs,ys)][/color][br]#============================[br][OUT][br]10-element Vector{Tuple{Int64, Float64}}:[br] (1, 0.20169081026514768)[br] (2, 0.17422295843712776)[br] (3, 0.25178803264424066)[br] (4, 0.5264239612886585)[br] (5, 0.4820281573212978)[br] (6, 0.23582173409057716)[br] (7, 0.06452661349364275)[br] (8, 0.6707651637338825)[br] (9, 0.3189198173371426)[br] (10, 0.4016041332227487)[br][br][b][br][/b]
関数と順序対
mod関数 の視覚化
2.暗号解読は逆関数?
[b][size=150]<シーザー暗号とは>[br][/size][/b]シーザー[color=#9900ff][b]暗号[Cipher][/b][/color]というものがある。[br][br]これって、ルールは単純で、[br]文字xに対して、文字コードy=f(x)を対応させる。[br]f(x)は数値だから、それに定数sを足す。[br]そして、文字コードsに対する文字をf-1(x)で求めたものをzとしよう。[br]これが暗号化関数Cだ。[br][br]これを、入力した文字列Xの文字xすべて対してzを求めて出力したものが文字列Zとなる。[br]つまり、暗号化はC :: X→Zとかけるね。[br][br]とうことは暗号解読はその逆関数C[sup]-1[/sup] ::Z→Xとかくことができるはずだ。[br][br][b][size=150]<暗号化と復号化を比べると>[br][/size][/b]それでは、暗号を作る関数Cと暗号を解読(復号)する逆関数C[sup]-1[/sup]を作ってみようか?。[br]しかし、この発想には無駄がある。[br][br]暗号化のときに、文字コードを+sしているとしたら、[br]復号化のときは、文字コードをーsすればよいだけだ。[br]だったら、[b]暗号と復号の両方に使える関数Ci[/b]を作った方がよいことがわかるね。[br]シフト数をshift 、入力文字をxとすると[br][br][color=#0000ff][b][size=150]コード化::Char→Int   x -> y = codepoint(x)[br]シフト:: Int →Int y -> z = y + shift[br]デコード化:: Int→Char z -> d=Char(z)[br][/size][/b][/color][br]この3ステップを合成した関数がCiになるね。[br][br][b]<実装しよう>[br][/b][color=#0000ff]#julia[br]#============================[br]Int(codepoint('A'))[br]#============================[br][/color][OUT][br]65[br][color=#0000ff]#============================[br]Char(65)[br]#============================[br][/color][OUT][br]'A': [br]このように、コード化とデコード化はできることがわかる。[br]英数字、つまり、アスキー文字に限った暗号だとすると、[br]コード番号にshiftを加算してずらそう。[br]ただ、たすのではなく、Aが0番になるようにして、[br]からshiftをたして、それでも65を超えた番号は[br]振り出しのAから順にぐるぐる回るようにしたい。[br][color=#0000ff]#julia[br]#============================[br]Ci(shift::Int, x::Char)::Char = Char((Int(codepoint(x)) - 65 + shift) % 65 + 65)[br]Ci(0,'A'),Ci(1,'A'),Ci(2,'A'),Ci(3,'A')[br]#============================[br][/color][OUT][br]('A', 'B', 'C', 'D')[br][br]では、もっと先の文字も含めて、暗号と復号がうまくいくことを確認しよう。[br][color=#0000ff]#julia[br]#============================[br]Target = "ABCDE PQRSTU abcde,.xyz";[br][br]println(Target)[br]Ciphered=join([Ci(5,x) for x in Target] )[br]println(Ciphered)[br]Recovered=join([Ci(-5,x) for x in Ciphered] )[br]println(Recovered)[br][/color][color=#0000ff]#============================[br][/color][OUT][br]ABCDE PQRSTU abcde,.xyz[br]FGHIJ%UVWXYZ%fghij13}~[br]ABCDE PQRSTU abcde,.xyz[br][color=#0000ff][br]#julia[br]#============================[br]Target = "THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG";[br][br]println(Target)[br]Ciphered=join([Ci(5,x) for x in Target] )[br]println(Ciphered)[br]Recovered=join([Ci(-5,x) for x in Ciphered] )[br]println(Recovered)[br][/color][color=#0000ff]#============================[br][/color][OUT][br]THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG[br]YMJ%VZNHP%GWT\S%KT]%OZRUX%T[JW%YMJ%QF_^%ITL[br]THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG[br]

Graphをやろう

点と線でできた図をデータにしてみる。
[b][size=150]このワークシートは[url=https://www.geogebra.org/m/twxxx3yq]Math by Code[/url]の一部です。[br][br]<図形を使うことで処理が見やすくなる>[br][/size][/b]グラフは頂点の集まりVとそれらをいくつか結ぶ線分(辺)の集まりEでできている。[br][br][color=#38761d][b][u][size=150][size=200]頂点がnodeか vertexかpointだ。[br]辺がedgeかsegmentだ。[br][/size][/size][/u][/b][/color][br]辺の情報を与えれば、頂点の隣接状態の図としてのグラフはかける。[br]特に指定しなければ、点の位置は任意になる。[br][br]pythonでグラフを使うためにパッケージがいろいろ必要になる。[br]昔からnetworkxとかgraphvizが有名だね。[br](juliaでは典型的なグラフ用パッケージがあるかどうか不明なのでpythonとnetworkでコードをかく。)[br][color=#ff00ff]#======================[br]pip install scipy[br]pip install networkx[br]pip install [/color][color=#ff00ff]matplotlib[br][/color][color=#0000ff]#======================[br]import networkx as nx[br]G =nx.Graph()[br]G.add_edge(1,2)[br]G.add_edge(2,3)[br]G.add_edge(2,4)[br]nx.draw_networkx(G)[br]#======================[br][/color][OUT][br][br][color=#0000ff]#geogebra[br][/color][b][size=150][color=#38761d]グラフ用のパッケージがないので、[br]座標Nodesをランダムに4個発生させる。[br]その座標を引用して、点の番号NumTを打つ。[br][/color][/size][/b][color=#0000ff]Nodes=Sequence((RandomBetween(1,20),RandomBetween(1,20)),k,1,4)[br]NumT=Sequence(Text(k,Element(Nodes,k)),k,1,4)[br][br][/color][color=#38761d][size=150][b]描画のスピードは気にせず、4個の総当たりで辺のリストAllComiを作り、非表示にする。[br]データ作成上、リストが2層になってしまったので、辺のリストをフラットなCsにする。[br][/b][/size][/color][color=#0000ff]AllCombi=Sequence(Sequence(Segment(Element(Nodes,i),Element(Nodes,j)),j,i+1,4),i,1,3)[br]Cs=Flatten(AllCombi)[br][br][/color][color=#38761d][b][size=150]ランダムに連結すると辺が3本できないおそれがあるので辺をシャッフルして前から3本選ぶ。[br][/size][/b][/color][color=#0000ff]Take(Shuffle(Cs),1,3)[br][br][/color]
4点グラフ
4頂点3辺グラフ
[b][size=150]<ランダムに頂点を連結してみる>[br][br][/size][/b]randomにm辺できるまで、n頂点を適当に結ぶ。[br]辺の集合edge_setに2頂点の組を, [color=#0000ff][b]隣接行列[/b][/color]graph_dataに2頂点の連結情報を1に[br]セットしよう。これが[color=#0000ff][b]グラフを適当につくる関数generate_G(n,m)[/b][/color]だ。[br][br][[color=#0000ff]IN]Python[br]#================================================[br]import random[br][br]def generate_G(n, m):[br] graph_data = [[0] * n for i in range(n)][br] edge_set = set()[br] while len(edge_set) < m:[br] i, j = random.sample(range(n), 2)[br] if i > j: i, j = j, i[br] edge_set.add((i, j))[br] graph_data[i][j] = graph_data[j][i] = 1[br] return graph_data, edge_set[br][br][/color][color=#0000ff]random.seed(6)[br]node_num = 16[br]edge_num = 20[br]figGraph, edgeSet = generate_G(node_num, edge_num)[br][br]edgeSet[br][/color]figGraph[br]#================================================[br][OUT][br]{(0, 2),[br] (0, 4),[br] (0, 8),[br] (1, 9),[br] (2, 5),[br] (2, 7),[br] (2, 13),[br] (3, 12),[br] (3, 15),[br] (5, 11),[br] (5, 13),[br] (6, 8),[br] (6, 11),[br] (6, 13),[br] (7, 8),[br] (7, 11),[br] (8, 10),[br] (12, 13),[br] (12, 15),[br] (13, 14)}[br][br]geogebraの場合は、上記とほぼ同じでできます。[br]3本の頂点の選び方は、4C3=6本の辺をすべて引いてしまい。その順番をシャッフルしから前から3本[br]選びましたね。[br]これが16本になっても同じロジックで16C2=120本引いておき、その順番をシャッフルしてから20本選んだものだけを表示するという方法です。
16頂点20辺のグラフ

自然対数とオイラー

1.オイラー以前の対数の存在
[b][size=150][b][code][/code]このワークシートは[url=https://www.geogebra.org/m/twxxx3yq]Math by Code[/url]の一部です。[br][/b][/size][/b][br][b][size=150]<対数の意義と法則>[/size][br][/b]底がaのとき、[br][br]指数関数[size=150]y=a[sup]x[/sup]をpow(a,x)[/size]とかくと、[br]対数関数は[size=150]x=pow[sup]-1[/sup](a,y)[/size]となり、[size=150]pow[sup]-1[/sup]をlogと[/size]かく。[br]指数xを対数、正の数yを真数という。[br][br]・指数関数:対数x→真数y(xは全実数、[u]値域yは正数[/u])[br]・対数関数:真数y→対数x([u]定義域yは正数[/u]、xは全実数)[br][color=#0000ff][b][size=150]a(底)をy(真数)という結果にするための指数x(対数)を取り出せる。[br][/size][/b][/color]それが対数関数です。[b][size=150]対数の法則は、指数法則の裏返し。[br][/size][/b][br]・対数の定義から、[color=#0000ff][b]log[sub]a[/sub]a[sup]N[/sup]=N[/b][/color]はあきらか。1[size=150][b]=log[/b][sub]a[/sub][b]a[/b]、[/size][color=#0000ff][b][size=150]0=log[sub]a[/sub]1[/size][/b][/color][br]・指数の積の法則から、[b][color=#0000ff]log[sub]a[/sub]MN=log[sub]a[/sub]M+log[sub]a[/sub]N(2数の積の対数は分解した対数の和)[/color][/b][br]・指数の積の法則から、[color=#0000ff][b]log[sub]a[/sub]M/N=log[sub]a[/sub]M-log[sub]a[/sub]N(2数の商の対数は分解した対数の差)[/b][/color][br]・積の対数が対数の和分解できたことを繰り返すと、[b][color=#0000ff]log[sub]a[/sub]M[sup]k[/sup]=klog[sub]a[/sub]M(k乗の対数は対数のk倍)[/color][/b][br] これから、[math]\frac{log_aA}{log_aB}=\frac{log_aB^k}{log_aB}=\frac{klog_2B}{log_aB}=k=log_BB^k=log_BA[/math] これを逆にたどって、[math]log_BA=\frac{log_aA}{log_aB}[/math][br][br][b][size=150]<常用対数表を作る苦労>[/size][/b][br]底が10の対数を[color=#0000ff]常用対数[/color]といいます。計算の結果が表になっています。[br][color=#0000ff][b][size=150](常用)対数表[/size][/b][/color]です。真数から対数がすぐに出せるのです。[br]昔は関数電卓とかプログラミング環境がなかったから、とても重宝されたでしょう。[br]対数という言葉は17世紀はじめにネイピアが使い、その後ブリッグズ、メルカトル、ニュートンらが平方根を大量に反復計算したり、無限級数(無限の数列和)などを使って平方根を計算したり、双曲線での積分を使うなどして、[b][color=#0000ff]工夫し、苦労して計算されたものが対数表[/color][/b]だ。[br][br]その後オイラーさんなどが級数展開という再表現をすることで飛躍的に簡単に計算できるようになった。[br][br][size=150][u][color=#9900ff][b]質問:[/b][/color][color=#9900ff][b]12.3*45600*31400000/2.72=6474864705882.353を[br] 常用対数表を使うとどんな工夫ができますか。[br][/b][/color][/u][/size]  X=12.3×45600×31400000÷2.72[br]大きい数のかけ算をするときに対数表の数で10の指数におきかえてたし算する。[br]・1より大きい数Xは1以上10未満の3桁数Mを使って、浮動小数点表示X=M×10[sup]N[/sup]におきかえる。[br]  12.3=1.23×10[sup]1[/sup][br]  45600=4.56×10[sup]4[/sup][br]  31400000=3.14×10[sup]7[/sup][br]  2.72=2.72×10[sup]0[/sup][br]・log[sub]10[/sub]X=log[sub]10[/sub](M×10[sup]N[/sup])=log[sub]10[/sub]M+log[sub]10[/sub]10[sup]N[/sup]=log[sub]10[/sub]M + N [br] logA*B*C/D=logA+logB+logC-logD[br] Mは対数表にあるので、表をみてlog[sub]10[/sub]Mは転記して、Nをたします。[br] log[sub]10[/sub](1.23×10[sup]1[/sup])=0.0899+1, [br] log[sub]10[/sub](4.56×10[sup]4[/sup])=0.6590+4, [br] log[sub]10[/sub](3.14×10[sup]7[/sup])=0.4969+7,[br] log[sub]10[/sub](2.72×10[sup]0[/sup])=0.4346+0[br] log[sub]10[/sub]X[sub]=0.0899+1 +0.6590+4 +0.4969+7 - 0.4346[/sub][br] 1.0899+4.659+7.4969 -0.4346=12.8112[br] 0.8112を対数表から逆読みして、6.4の行の8と7の間、log[sub]10[/sub]6.475=0.8112。[br] 12.8112=0.8112+12= log[sub]10[/sub]6.475+12=log[sub]10[/sub]6.475×10[sup]12[/sup][br] 結局、10[sup]12.8112[/sup]=6.475×10[sup]12 [/sup][br] これで、10の12乗のオーダーで上3桁数が647であることがわかる。[br]
2.自然対数
[size=150][size=150]<底がeの自然対数>[br][/size][size=100]オイラー数(ネイピア数)e=2.718281828459...を底にすると、[br](e[sup]x[/sup])の微分=e[sup]x[/sup]のため、[br]微分積分などの数式計算が簡単になります。[br]そのため、常用対数は数値計算向きでしたが、自然対数は数式計算でよく使われます。[br]また、e[sup]iπ[/sup]=-1のオイラー等式のように、eは関数や数をつなぐときに登場します。[br][/size][b][br]<自然対数の底eの近似値>[br][/b][size=100]f(x)=e[sup]x[/sup]とするとき、[br]f(x)のマクローリン級数を利用してeの近似値を求めてみよう。[br]f[sup](k)[/sup](x)=e[sup]x[/sup]だから、f[sup](k)[/sup](0)=1。x=1とおくと、[br][size=150]e[sup]x[/sup]=1 +x +x[sup]2[/sup]/2! +x3/3! +....... +xn/n![/size]+.......[br]1[br]1/1=1[br]1/2!=1/2=0.5[br][size=150]1/3!=0.5/3=0.16666666666666666[br]1/4!=0.16666666666666666/4=0.04166666666666666[br]1/5!=0.04166666666666666/5=0.008333333333333331[br]1/6!=0.00833333333333333/6=0.001388888888888888[br][/size]1/7!=0.001388888888888888/7=0.00019841269841269831/8!=0.0001984126984126983/8=0.0000248015873015872[br]から、[br]e=f(1)=1+1+1/2!+1/3!+1/4!+1/5!+1/6!+1/7!+1/8![br] =1+1+0.5+0.16666666666666666+0.04166666666666666+0.008333333333333331[br]+0.001388888888888888+0.0001984126984126983+0.0000248015873015872[br]=2.71827876984127[br][/size][/size][br]オイラーはマクローリン展開を使わず、二項定理を使って級数展開することで、無限大・無限小の考え方を使って、同じ[size=150]e[sup]x[/sup]=1 +x +x[sup]2[/sup]/2! +x3/3! +....... +xn/n![/size]+.......に到達して、近似値を得ている。[br][br]さて、プログラミング言語などでは、[br]底がeの指数関数 [color=#0000ff][b]y=e[sup]x[/sup]を y=EXP(x)[/b][/color]とかくことが多い。[br]底がeの対数関数 [color=#0000ff][b]y=log[sub]e[/sub]xを y=LN(x)=Log(x)[/b][/color]とかくことが多く、[color=#0000ff]自然対数[/color]。[br][br][color=#9900ff][b][size=150][u]質問:言語によって、log[sub]10[/sub]5、log[sub]2[/sub]5と、ln5の表記・記述がちがいます。どんな傾向がありますか。[br][/u][/size][/b][/color][br][color=#0000ff][b]Python, juliaでは自然対数がデフォルトですが、geogebraでは常用対数がデフォルトです。[br]教育用の言語なのか、開発用の言語なのかのちがいでしょう。[br][/b][/color][br]・juliaではbase=Bとすると、[br]対数関数は、log(B, x)と、logB(x)という2種類があります。[br]base=eのときは、指定なしでlog(x)とかきます。[br]面白いのは、logをexpにして、exp(B,x),expB(x)という指数関数があり、exp(x)はB=eのときです。[br][br]・pythonではimport mathか、from math import 関数名をしてから、使いましょう。[br][br]・geogebraでは常用対数がデフォルトのようでlog(5)と入力すると、log[sub]10[/sub](5)に変換されてしまいます。[br]ほかに、log2, log10のように、底の指定自体が名前になっている関数があるのは、他の言語と同様です。[br]自然対数lnを使いたければ、底がeの指数関数を使い、E=exp(1)として、E=e[sup]1[/sup]=2.71828...を得て、[br]log(E,x)とすれば自然対数関数として使えますね。
いろんなlog
3.自然対数から常用対数を計算する
[b][size=150]<無限大・無限小>[br][size=100]二項定理[/size](1+x)n=ΣnCr x[sup]r[/sup][/size][/b]のnを実数に拡張したn!により定義されたnCrの拡張版F(n,r)=n!/(n-r)!r![br]によって、[b][color=#0000ff]一般二項定理[size=150](1+x)n=ΣF(n,r) x[sup]r [/sup][/size][/color][sup][/sup][/b]をニュートンらは使っていた。[br]オイラーは無限小・無限大という考えと一般2項展開を使って、[br]対数関数ln(x)を級数展開した。[br]ただし、ln(x)ではなく[b][color=#0000ff]ln(1+x)[/color][/b]だったので注意しよう。[br][br]・「かなり小さいωでe[sup]ω[/sup]=1+ωとなるかどうか」を実験してみる。[br]ωという量でe[sup]ω[/sup]=1+ωとなるならば、(e[sup]ω[/sup]ー1)/ω=1となるだろう。[br][br][color=#9900ff][b][u][size=150]質問:ωを小さくして[sup]ω[/sup]=1+ωとなるかどうかをしらべるにはどうしたらよいでしょうか。[br][/size][/u][/b][/color][br]ω=1/10^k (k=5...14)のとき、[br](e^ω-1)/ωを順に計算して=約1になるかを調べよう。[br][color=#0000ff][IN]python[br]##################################################[br][/color][color=#0000ff]from math import exp[br]e=exp(1)[br]omegas=[1/10**x for x in range(5,15)][br]print(omegas)[br]for omega in omegas:[br] print((e**omega-1)/omega)[br][/color][OUT][br][1e-05, 1e-06, 1e-07, 1e-08, 1e-09, 1e-10, 1e-11, 1e-12, 1e-13, 1e-14][br]1.000005000006965[br]1.0000004999621837[br]1.0000000494336803[br]0.999999993922529[br]1.000000082740371[br]1.000000082740371[br]1.000000082740371[br]1.000088900582341[br]0.9992007221626409[br]0.9992007221626409[br]ちょうど1にはならないが、なりそうそう。[br]無限小のωならなるかもしれないので、仮定してみよう。[br]無限小ωという量で指数表現でe[sup]ω[/sup]=1+ωとなるなら、対数表現で、ln(1+ω)=ωとなるね。[br][br]・十分大きいjに対してjω=jln(1+ω)=ln(1+ω)[sup]j[/sup]>1となる。[br] どんなxでもx=(1+ω)[sup]j[/sup]-1となるjがとれる。[br][br][size=150][color=#9900ff][u][b]質問:どんなxでも[/b][/u][/color][color=#9900ff][u][b]x=(1+ω)[sup]j[/sup]-1となるjがとれそうな感じをつかむにはどうしますか。[br][/b][/u][/color][/size][br]小さめのωに対して、大きいjを動かして、x=(1+ω)[sup]j[/sup]-1の値が連続的に変わりそうなことを確かめよう。[br]たとえば、[br]ω=0.001=1/10**2として、[br]js=[101,.....,999]とする。[br]jo = j*ω[br]lj = ln((1+ω)**j)[br]とすると、joとljはかなり近い。[br]x=(1+ω)**j-1は単調に増加してくれるならば、[br]逆にxを指定して、jを決めることができるという[br]感じがつかめでしょう。[br][br][color=#0000ff][IN]Python[br]##################################################[br]from math import log as ln[br]ω=1/10**2[br]js=[x for x in range(10**2+1,10**3)][br]for j in js:[br] jo=j*ω[br] lj=ln((1+ω)**j)[br] x=(1+ω)**j-1[br] print(jo,lj,x)[br][/color][br][OUT][br]1.01 1.0049834161699773 1.7318619677157439[br]1.02 1.0149337470231454 1.7591805873929012[br]1.03 1.0248840778763135 1.7867723932668302[br]1.04 1.0348344087294816 1.8146401171994988[br]1.05 1.0447847395826495 1.8427865183714935[br]1.06 1.0547350704358178 1.8712143835552086[br]1.07 1.0646854012889857 1.8999265273907606[br]1.08 1.0746357321421538 1.9289257926646681[br]1.09 1.0845860629953221 1.9582150505913152[br].........[br].......[br].........[br].......[br]9.88 9.830926882930074 18599.186432989674[br]9.89 9.840877213783243 18785.188297319568[br]9.9 9.850827544636411 18973.050180292765[br]9.91 9.860777875489578 19162.790682095692[br]9.92 9.870728206342747 19354.42858891665[br]9.93 9.880678537195916 19547.982874805817[br]9.94 9.890628868049083 19743.472703553874[br]9.950000000000001 9.900579198902252 19940.917430589416[br]9.96 9.910529529755419 20140.33660489531[br]9.97 9.920479860608587 20341.74997094426[br]9.98 9.930430191461756 20545.177470653703[br]9.99 9.940380522314923 20750.639245360242[br][br]よさそうな結果だね。
・それでは、[br] どんなxでもx=(1+ω)[sup]j[/sup]-1となるjがとれると仮定しよう。[br] こらから、1+x=(1+ω)[sup]j[/sup]=(e[sup]ω[/sup])[sup]j[/sup]=e[sup]jω[/sup]。ln(1+x)=jω。[br] また、逆算して、ω=(1+x)[sup]1/j[/sup]-1となる。[br]そこで、[color=#0000ff][b]一般二項定理[/b][/color]を使うと、[br]ln(1+x)=jω=j((1+ω)[sup]1/j[/sup]-1)[br]=j(1+(1/j)x+(1/j)(1/j-1)/2!x[sup]2[/sup]+(1/j)(1/j-1)(1/j-2)/3!x[sup]3[/sup]+.........) - j[br]=x - (j-1)/2jx[sup]2[/sup] + (j-1)(2j-1)/(2!j3j)x[sup]3[/sup]- (j-1)(2j-1)(3j-1)/(2j3j4j)x[sup]4[/sup]+.........) - j[br]jが無限大なら、(j-1)/2j=1/2,(2j-1)/3j=2/3,(3j-1)/4j=3/4,...となり、[br]jを使った係数はxの指数と同じ数以外が相殺されて消える。[br]だから、[math]ln\left(1+x\right)=x-\frac{x^2}{2}+\frac{x^3}{3}-\frac{x^4}{4}.......[/math].[br]x=-xとおくと、[sup][/sup][math]ln\left(1-x\right)=-x-\frac{x^2}{2}-\frac{x^3}{3}-\frac{x^4}{4}-.......[/math].[br]これから、[math]p\left(x\right)=ln\frac{1+x}{1-x}=ln\left(1+x\right)-ln\left(1-x\right)=2\left(x+\frac{x^3}{3}+\frac{x^5}{5}+......\right)[/math][br][br]これを公式として利用すると、[br]p(1/3)=ln(1+1/3)/(1-1/3)[br]=ln2=2(1/3+(1/3)[sup]3[/sup]/3+(1/3)[sup]5[/sup]/5+....)=0.69313...,[br]p(1/9)=ln(1+1/9)/(1-1/9)[br]=ln(5/4)=2(1/9+(1/9)[sup]3[/sup]/3+(1/9)[sup]5[/sup]/5+....)=0.22314...[br]ln5=ln(5/4×(2^2))=ln(5/4)+2ln2=0.22314+2(0.69313)=1.60941。[br]ln10=ln2+ln5=0.69313+1.60941=2.30254[br]log[sub]10[/sub](5)=ln5/ln10=1.60941/2.30254=0.69897。[br][color=#0000ff][b]このように自然対数を計算して、底の変換公式で常用対数を求めることができる。[/b][/color]

あみだくじたちは「群」になれるのか?

あみだくじを作ろう!
あみだくじをつないでも、あみだくじ。
123はどう動く?
[b]このワークシートは[url=https://www.geogebra.org/m/twxxx3yq]Math by Code[/url]の一部です。[br][/b][br][br][b][size=150]<たて線3本アミダ>[br][/size][/b][color=#0000ff][b]「群」group[/b][/color]というのは、ただの群れとか集まりというものではなく、ルールに適合する群れだ。[br]2項演算(2つのoperandに対する演算operator)を集まりに対して定めたとき、[br]・2項演算がそのグループの要素にとどまる。はみ出さない調和のとれた動き。閉じている。[b]closure[/b][br]・結合法則が成り立つ。abc=a(bc)=(ab)c。みんな仲良くくっつける。[b]associative[br][/b]・1つの単位元・零元(何もしない元[b]identity[/b])がある。停止も運動の1種。[br]・どの要素にも逆元・反元(演算をもどす元)がペアで存在する[b]inversible[/b]。逆の動きも仲間だ。[br]これらがOKならば、何でも「群」と言える。[br][br]アミダは群になるだどうか?[br]まず、たて線が3本で調べてみよう。
1.3本アミダ
あみだくじのように線をひいて、位置を変えることを[b]置換[/b]という。[br]番号を入れ替える操作をしているとも言えるね。[br]タテ線に乗っかって下にきた場所に上の番号がかいてある。[br]だから、下の番号だけ書き出すと、123,231,312,132,213,321となり[br]123の3つの番号の順列数3!=6通りの入れ替えがすべてできていることがわかるね。[br][b][size=150][br]<1段目の3つの置換>[br][/size][/b](1段目の左図)[br]この置換はヨコ線が0本だから、何もしない。だから、これが単位元、0元だね。何もしないのも置換。[br]あみだくじでヨコ線を1本ひくと、隣接要素の交換を表す。2要素の交換のことを[b]互換[/b]という。[br]1段目の3本アミダはヨコ線が0か2本なので互換数が偶数。偶数の互換なので[b]偶置換[/b]とよぼう。[br]2段目の3つはヨコ線が1か3本なので[b]奇置換[/b]とよぼう。[br]1と2をつなぐヨコ線は互換を引き起こす。これを、(12)とかこう。[br]2と3をつなぐヨコ線は(23)とかこう。3と1をつなぐヨコ線は(31)とかこう。[br][b][size=150][color=#0000ff]合成関数g*f(x)がxに対してfが先で、gを次にすることを表した。[br][/color][/size][/b](1段目の中図)[br]このアミダは、上に(12)、下に(23)なので、この合成は右先左後の表記で、(23)*(12)となる。[br]1→2の終点2が、2→3の始点2とつながり、1→2→3の移動がおきて1→3となる。[br]左から1番は左から3番の位置にたどりつき、2→1、3→2の行き先変更は合成されない。[br] [math]\left(\begin{matrix}1,2,3\\\downarrow,\downarrow,\downarrow\\3,1,2\end{matrix}\right)[/math] とかくと、番号の動きが見やすいね。途中の↓を省略してよい。 [math]\left(\begin{matrix}1,2,3\\3,1,2\end{matrix}\right)[/math] [br](1段目の右図)[br]このアミダは、上に(23)、下に(12)、なので、この合成操作の表記は(12)*(23)となる。[br]3→2の終点2が、2→1の始点2とつながり、3→2→1の移動がおきて3→1となる。[br]1→2、2→3の行き先変更は合成されない。[br] [math]\left(\begin{matrix}1,2,3\\\downarrow,\downarrow,\downarrow\\2,3,1\end{matrix}\right)[/math] だから、 [math]\left(\begin{matrix}1,2,3\\2,3,1\end{matrix}\right)[/math]
2.あみだくじは互換か巡回置換であらわせる
1段目の右図の置換[br]これは、おもしろいね。[br]1→2, 2→3, 3→1の順繰りにサイクリックに1つずつずらしているように見える。[br]だから、これを1サイクルを順に(1,2,3)とかき、[b][color=#0000ff]巡回置換[cyclic permutation][br][/color][/b]という名前がついている。直訳しただけの日本語ですなあ。[br]まあ、[color=#0000ff][b]順ぐり置き換え、くるっと回す[/b][/color]でもいいのだけれど、世間の常識の言葉を使っておこう。[br][br]1段目の中図は、さっき見た巡回置換に直せないだろうか?[br]1→3, 3→2, 2→1 と数字の大小はきれいではないが巡回しているね。(1,3,2)とかけるね。[br][br][b][size=150]<2段目の左、中、右の図>[/size][/b][br]では2段目を左からみよう。[br]1個目は(23)の互換だ。[br]2個目は(12)の互換だ。[br]3個目はヨコ線は上から順に(12)、(23)、(12)だ。合成互換の書き方では(12)*(23)*(12)。[br]1は(12)で1→2となり、次の(23)で2→3となるから、2でつなぐと、1→3。[br]2は(12)で2→1となり、最後の(12)で1→2となるから、1をつなぐと、2→2でもとにもどる。[br]3は(23)で3→2となり、最後の(12)で2→1となるから、2をつなぐと、3→1。[br]だから、2は変わらず、互換(13)と同じになるね。[br]
3.アミダをつなぐ
[b][size=150]<たてにつなぐのが演算>[br]アミダを区別しやすくするために、名前をつけよう。[/size][/b][br]1段目は偶置換で、左からe =( ), r=(1,3,2), s= (1,2,3) 。[br]2段目は奇置換で、左からa=(23),b=(12),c=(13)。[br][br]ではこの6要素を九九の表のようにたてとよこにならべよう。[br]6つ要素どうしの演算結果をかいて表をうめることをイメージしてみよう。[br][br]よこに、x={e, r, s, a, b, c}と並べたとき、たてに、y={e, r, s, a, b, c}と並べてうめてみる。[br]1行目は e*x=x={e, r, s, a, b, c}とそのまま並べるだけ。[br]2行目はr*x = {r*e, r*r, r*a, r*b,r*c}となるね。[br][br]たとえば、r*aはa=(23)の下にr=(1,3,2)をつなぐことになるね。
一番下の番号が321の順になったので、あみだくじでは2段目の最後、つまりcと同じになる。[br]aで2→3、rで3→2となるから、3をつなぐと2→2となるなどして、(13)になることがわかるね。[br]だから、r*a=cだ。[br]群の九九表のようなものを群表を呼んだりするけど、群表をかかなくても、[br][b][color=#0000ff]2つのあみだくじをたてにつなげば、1,2,3の番号が入れ替わるだけなので、その演算結果は[br]6つの要素のどれかと同じになるしかない[/color][/b]。[br]つまり、閉じていることと結合法則は明白なので、これは調べなくても大丈夫だね。[br][br]・単位元、つまり、なにもしない置換、ヨコ線のないのが、[color=#0000ff][b]eであり、1つしかない[/b][/color]からOK.[br]・では逆元をしらべよう。[br]同じ互換を繰り返すともとに戻るから a*a=e, b*b=e, c*c=eとなるね。[br]3要素の巡回置換は3回くりかえすともとにもどるから、r*r*r=e, s*s*s=eだ。[br]rを2回するとsになり、r*r=s。同じようにして、s*s=r。[br]xの逆元(反元)をx[sup]-1[/sup]とかくと、[b][size=150][color=#0000ff]a[sup]-1[/sup]=a, b[sup]-1[/sup]=b, c[sup]-1[/sup]=c, r[sup]-1[/sup]=s, s[sup]-1[/sup]=r, [/color][/size][/b]e[sup]-1[/sup]=eとなるね。[br][color=#0000ff][b]6つの置換にすべて逆が1つずつある[/b][/color]ので、逆元もクリアした。[br][br]3本アミダを上下につなぐことをあみだくじの演算とすると、[br]この演算で、アミダは群になっていることがわかったね。[br][br]群のコトバでは、[b][color=#0000ff]3本アミダをS3={e, s, r, a, b, c}を、[/color][/b][color=#0000ff][b]たてにつなぐことを演算*[/b][/color]とすると、[br]3本アミダ[b]群は<S3, * >[/b]とかくことができるね。
[color=#9900ff][u][b][size=150]質問:3本アミダ群<S3、*>の群表をコードで作成するにはどうしたらよいでしょう。[br][/size][/b][/u][/color][br]・巡回置換は(a b c ... z)は働きとしては、辞書{a:b, b:c, ...., z:a}になる。これが[b][color=#0000ff]ami2dic関数[/color][/b]。[br] あみだのリストごと、辞書のリストにして返す[b][color=#0000ff]amis2dics[/color][/b]関数もあると便利だね。[br]・あみだaの行先を出す[b][color=#0000ff]ami_go関数[/color][/b]は、aにないキーkの行先はkのままにする。[br]・あみだの連結は[color=#0000ff][b]conL(a,b)[/b][/color]関数で、aの行先をキーにしてbの行先にいく連結辞書を作ります。[br] conR(a,b)関数はbの行先をキーにしてaの行先にいく連結辞書を作ります。[br][br]辞書がそのまま返されても視認性が悪いので、巡回置換に名前をつけて識別しやすくしよう。[br]すべての置換Sと名前をタプルにして返す[color=#0000ff][b]rotdic(S)[/b][/color]関数によって、[br]要素の名前、集合に含まれる要素の名前、演算結果の要素の名前を返すために、[br]関数、[color=#0000ff][b]name(a)、[/b][/color][color=#0000ff][b]names(H)、aH[/b][/color][b][color=#0000ff](a,H)、Ha(H,a)を作ります。[/color][/b][br][br]これだけ、準備しておけば、群表を作ることはできます。[br]タイトルをつけるために、[b]naming(S)をprintします。[br][/b]そのあと、上につけるアミダをitemとして、name(item)、amiSetR(S,item)をprintすると、[br]右にかける要素ごとに、Sがどうなるかをリスト表示できます。[br]このitemをSの要素から順に選んで実行すれば、群表ができますね。[br][color=#0000ff]#[IN]Python==================================================[br][/color][b]#巡回リストamiを辞書にする。(例)a=[1,2,3] → dic={1:2,2:3,3:1}[br]def ami2dic(ami):[br][/b] return dict(zip(ami , ami[1:] + [ami[0]]))[br][b]def amis2dics(amis):[br][/b] return [dict(zip(ami , ami[1:] + [ami[0]])) for ami in amis][br][b]# kの辞書dic_aによる行先を返す。辞書にないなら行先はk。[br]def ami_go(k,dic_a):[br][/b] return dic_a[k] if k in dic_a.keys() else k[br][b]#あみだの辞書a,bの連結をする。[br]def conL(a,b):#a,bの順に演算する。[br][/b] keys = list(set(list(a.keys()) + list(b.keys())))[br] dic ={key:ami_go(ami_go(key,a),b) for key in keys if key !=ami_go(ami_go(key,a),b)}[br] if len(dic)==0:[br] dic={1:1}[br] return dic[br][b]def conR(a,b):#b,aの順に演算する。[br][/b] return conL(b,a)[br][b]#アミダを、(辞書,名)のタプルのリストにする。[br]def rotdic(S,SN):[br][/b] dic=[ami2dic(x) for x in S][br] return list(zip(dic,SN))[br][b]# あみだ辞書dic_aを名で返す。[br]def name(dic_a):[br][/b] global Nlist[br] return [item[1] for item in Nlist if item[0]==dic_a][0][br][b]# あみだ辞書集dicsを名のリストで返す。[br]def names(dics):[br][/b] global Nlist[br] return [item[1] for item in Nlist for b in dics if item[0]==b][br][b]# あみだ辞書の集合Hと辞書aを演算した結果リストを返す。[br]def Ha(H,a):[br][/b] global Nlist[br] res=[][br] for b in H:[br] res +=[item[1] for item in Nlist if item[0]==conR(b,a)][br] return res[br][b]def aH(a,H):[br][/b] global Nlist[br] res=[][br] for b in H:[br] res +=[item[1] for item in Nlist if item[0]==conR(a,b)][br] return res[br][b]#==================================以上が基本関数====================[br]#群表を作ろう。[br]def maketable():[br][/b] global Nlist[br] G = [x[0] for x in Nlist][br] print("*",names(G))[br] for item in G:[br] print(name(item),aH(item,G))[br] return True[br][b]e=[1][br]s=[1,2,3][br]r=[1,3,2][br]b=[1,2][br]c=[1,3][br]a=[2,3][br]S=[e,r,s,a,b,c][br]SN=["e","r","s","a","b","c"][br]Nlist=rotdic(S,SN)[br]#=================================以上が今回の前準備==================[br]maketable()[br]#================================================================[br][/b][OUT][br][color=#0000ff][b]* ['e', 'r', 's', 'a', 'b', 'c'][br]e ['e', 'r', 's', 'a', 'b', 'c'][br]r ['r', 's', 'e', 'c', 'a', 'b'][br]s ['s', 'e', 'r', 'b', 'c', 'a'][br]a ['a', 'b', 'c', 'e', 'r', 's'][br]b ['b', 'c', 'a', 's', 'e', 'r'][br]c ['c', 'a', 'b', 'r', 's', 'e'][/b][/color][br]
++記号の演習
[size=150][b]<数学の抽象化は概念化と切り離せない>[br][/b][/size][br]数学の抽象化は概念化、[br]つまり「用語と記号」の「約束」の世界だ。[br]群の「約束記号と用語」になれるために、[color=#0000ff][b]群の例[/b][/color]を記号・用語で確認する演習をしたい人はどうぞ。[br][b][size=150]<2項演算*>[/size][/b][br]2要素x,y∈Sに対する2項演算の結果を中置型でx*yとかくことが多い。四則演算+,-,×,÷なども[br]もちろん2項演算だ。群は集合の要素に対する2項演算について条件を満たすものにつけたラベルだ。[br]集合S上の2項演算はxとyの対に対して値zを返す写像fとみることができる。[br][b][color=#0000ff]x,yの順序対は(x,y)[/color]とかき、これを要素とするのは[color=#0000ff]直積[Direct Product]集合S×S[/color]だ。[br][/b]だから、2項演算*のことを[br][b][color=#0000ff]f:S×S→S ; (x,y)→f(x,y)[/color]と表記すると、f(x,y)=x*yということになるね。[br][size=150]<群のようなものと群>[br][/size][/b]「[color=#0000ff]集合[/color]」は、入る要素が内包的か外延的な定義などにより決まるもので、空集合∅も集合。[br]「[color=#0000ff]亜群[/color]」は、2項演算で閉じている集合。[br]「[color=#0000ff]半群[/color]」([color=#0000ff]semigroup[/color])は、閉じているのと[b]結合[associative[[/b]法則が言える集合。[br]「[color=#0000ff]単位的半群,モノイド[/color]」([color=#0000ff]monoid[/color])は、閉じていて結合法則が言えて、[b]単位元eが1つだけ[/b]ある集合。[br]「[b]群」(group[/b])は閉じていて、結合法則が言えて、単位元が唯一あり、[br] さらに、xの逆元inverse xが1つずつある集合。単位元しかない群、単位群{e}も群だね。e*e=e。[br][color=#0000ff]「アーベル群、可換群」[/color]は、群Gの任意の要素についてxy=yxが成り立つもの。[br]「群の位数」は、群Gの要素数で、#Gとか|G|とかく。[br]「要素の位数」は、群Gの要素gがg*n=eとなる最小のnをgの位数という。ord(g)=nとかく。[br][br]N10={1,2,3,4,5,6,7,8,9,10}とするとき、次の集合はどれか?[br]([color=#9900ff]例[/color])a*b=最大公約数(a,b)を求める演算*とすると、(N10,*)は[b]半群[/b]。[br] なぜなら、最大公約数はどれをさきに結合しても同じになるので、結合法則は成り立つ。[br]しかし、a*e=aとなる単位元eがあるとしたらすべての数の最小公倍数だから、そんなものはない。[br]([color=#9900ff]例[/color])a*b=min(a,b)とすると、(N10,*)は[b]モノイド[/b]。[br] なぜなら、minはどのからさきに調べても最後は同じ1つが返るから、結合法則は成り立つ。[br]また、min(x,10)=x,  min(10,10)=10となる。だから10が単位元だからモノイド。どのxについてもmin(x,y)=10となるyは存在するとは限らないから、必ずしも逆元はないので群になれない。[br]([color=#9900ff]例[/color])G={X |X=[math]\left(\begin{matrix}a,b\\-b,a\\\end{matrix}\right)[/math] , a[sup]2[/sup]+b[sup]2[/sup]>0, a,b∈R} で(G,・)は群といえる。・は行列の積。[br] 行列の積は一般に交換法則は成り立つとは限らないが、結合法則は成り立つから、半群。[br] X・E=XとなるEはa=1,b=0とすると、E∈Gだから、単位元は1つだけあり、単位的半群。[br] X・Y=EとなるYがどんなXにも1つずつあるか?det(X)=k=a[sup]2[/sup]+b[sup]2[/sup]>0だから、逆行列が決まる。[br] [math]X^{-1}=\frac{1}{a^2+b^2}\left(\begin{matrix}a,-b\\b,a\\\end{matrix}\right)[/math] [br]位数について[br](例)#S3=3!=6。|S3|=6。[br](例)あみだくじの演算*はつなぐことだった。[br] a*a=e, b*b=e, c*c=e、つまり、a[sup]2[/sup]=b[sup]2[/sup]=c[sup]2[/sup]=eだから、a,b,cの位数は2。[br]  r*r*r=e, s*s*s=e、つまり、r[sup]3[/sup]=s[sup]3[/sup]=eだから、r,sの位数は3。

多項式は整数のようなもの?

多項式の割り算とGCD
1.多項式も整数も環だ
[b][size=150][b]このワークシートは[url=https://www.geogebra.org/m/twxxx3yq]Math by Code[/url]の一部です。[br][/b][/size][/b][br][b][size=150]<整数は環だ。>[br][/size][/b]整数の集まりをZとかこう。[br]2項演算+について、[b][u]<Z、+>は群[/u][/b]だったね。[br]・閉性。a,b∈Zならa+b∈Z。[br]・ゼロ、[b][color=#0000ff]ゼロ元[/color][/b]は0∈Z[br]・+算は結合法則が成り立つ。[br][b]・x∈Zの[color=#0000ff]反数、反元[/color]は1つのだけ -x∈Zがある。[br][/b] (+算は交換法則が成り立つ。)[br][br]2項演算×について、[b][u]<Z、×>は逆元の存在以外OKだから、可換なモノイドと言えるね[/u]。[/b][br]・閉性。a,b∈Zならa×b∈Z。[br]・イチ、[color=#0000ff]イチ元[/color]は1∈Z[br]・×算は結合法則が成り立つ。[br] (×算は交換法則が成り立つ。)[br][b][b](Z∋[/b]x≠0の逆数、逆元1/xは∉Z。[color=#0000ff]逆元のあるxのことを単数、単元という。整数では1,-1)[br][/color][br]+、×についての分配法則が成り立つ。[br][/b]a,b,c∈Zなら(a+b)×c=a×c+b×c[br]整数は加法群・乗法群を分配法則でつなぎ、[b]乗法の逆元の存在には穴がある。[br][/b]穴の空いた2群のつながりだから?[b]<Z,+,×>[/b]を[b]環(Ring)と呼ぶのか?[br][/b]でも、指輪のリングではなく、ボクシングのリング・土俵、領域・区域という意味のRingらしい。[br]環は交換法則は標準ではないけれど、たいていが可換環だ。むしろ、非可換環の方がまれかもしれない。[br]だから、環は定義上は可換である必要はないが、たいてい可換なので可換環とはあえて呼ばないようだ。[br]
整数は無定義に語ったけど、[br]n次の[b]多項式K[X[/b]]は、係数の集合をKとしたときのXの最高次数がnの項の和の式とする。[br]Kが整数ZならZ[X], Kが実数ならR[X]、一般にf[X]のようにかく。[br][b][color=#0000ff]f[X]=Σa[sub]n[/sub]X[sup]n[/sup][/color][/b]と書ける。(an≠0)[br][br][b][size=150]<多項式も環だ>[br][/size]実数係数のR[X][/b]を簡単にZと書いてみよう。[br]□2項演算+について、[b]<Z、+>は群[/b]だ。[br]・閉性。a,b∈Zならa+b∈Z。[br]・ゼロ元は定数項の式0∈Z[br]・+算は結合法則が成り立つ。[br][b]・x∈Zの半元は1つのだけ -x∈Zがある。[br][/b](+算は交換法則が成り立つ。)[br][br]□2項演算×について、[b]<Z、×>は逆元の存在以外がOKだ。[br]可換なモノイドだね。[/b][br]・閉性。a,b∈Zならa×b∈Z。[br]・イチ元は定数項の式1∈Z[br]・×算は結合法則が成り立つ。[br](×算は交換法則が成り立つ。)[br][b]([b]Z∋[/b]x≠0の逆元1/xは分数式∉Z。単元は0以外の定数)[br][br]□+、×についての分配法則が成り立つ。[br][/b]a,b,c∈Zなら(a+b)×c=a×c+b×c[br][br]多項式R[X]をZと名前を変えても、同じように[b]環(Ring)になることがわかったね[/b]。[br]
2.環から整域へ
[b][size=150]<環の用語を確認しよう>[br][/size][/b][br]環の性質は整数の計算の一般化とも言える。[br]整数、整数計算がもっている面白い性質といえば、何でしょうか?[br][br]倍数、約数の数列を作ったり、最大公約数、最小公倍数[br]さらには素数を見つけたりしたね。[br][br]最小公倍数のもとは、最大公約数だった。[br]そして、最大公約数は連除法もあったけど、ユークリッドの互除法という、割り算の繰り返しから求められた。その根拠は、[b]割り算の余りは割る数よりも小さい正の数[/b]だった。[br][br]この「割り算の原理」が多項式でも成り立つと、[br]多項式にも約数、倍数、GCM,LSM,素数を生み出せるかもしれないね。。。。。。[br][br]環の世界の特殊が整数だということなので、用語を整数から環に言い換えをしておこう。[br]構造的には整数でも環でも同じ意味になりますね。[br][br]整数では約数、倍数というのがあった。これを筆頭に、[br][b]約数、倍数、単数(1,-1)、素数、公約数、最大公約数、互いに素は最大公約数が1、公倍数[br][/b]数を元に変えます。[br][b][color=#0000ff]約元、倍元、単元、素元、公約元、最大公約元、互いに素は最大公約元が単元、公倍元。[br][/color]素数がその数と単数しか約数がない数だった。[br][color=#0000ff]素元はその数と単元しか約元がない要素になるね。[br][br][/color][/b]では、これを多項式の世界に移すとどうなるだろうか。[br]約元は因数分解の[b]因数[/b]だね。[br][b]単元[/b]は0でない数、0以外の定数は、多項式にとってはイチとして見るということだね。[br]素数は[b]既約多項式[/b]。その係数の世界で因数が定数かその式自身しかないということだね。[br]公約元は[b]共通因数[/b]だ。これはよく使っていたでしょう。[br][br][b][size=150]<普通の整数らしい環が整域>[/size][/b][br]y≠0のyに対してx*y=0となるxを[b][color=#0000ff]零因子(ゼロ因子)[/color][/b]と呼ぶけれど、[br]整数環の世界ではx=0しかないけれど、集合や演算が変わればゼロ以外のゼロ因子がありうるね。[br][b]整数以外の環の世界ではx≠0でも、y≠0に対してx*y=0になることがある。[br][/b]<Z6,+,×>整数のmod 6での剰余の環={0,1,2,3,4,5}の演算では、[br]2×3=0、4×3=0。[br]1×0=0、5×0=0。[br]だから、[br]0はもちろん、ゼロ因子。[br]2,3,4はゼロ以外のゼロ因子だね。[br]1,5はゼロ因子ではない。[br]普通の整数からすると、2×3=0、4×3=0は変な計算ができてしまう環だ。[br][b][color=#0000ff][size=150]普通の整数らしく、[u]ゼロ以外のゼロ因子がない環、変な計算がない環を「整域」[/u]という。[br][/size][/color][/b]環の定義には、「ゼロ以外のゼロ因子がないものとする」という条件がないために[br]環の一般定義を変えずに、整数らしい環を、環の特殊として「整域」というネーミングにしたという[br]流れだと思われる。[br]・整域のよさは計算が変でないということだけではない。[b][color=#0000ff]整域なら、[u]簡約法則[/u]が使える[/color][/b]。[br]たとえば、a*x=b*xのとき、x≠0なら、a=bとカンタンな式に直してよい。[br]それは、0=a*x-b*x=(a-b)*xと変形すると、0以外のゼロ因子がない環、整域なら、[br](a-b)=0のみ、a=bと断言できるというわけだ。[br][br][b][size=150]<体と整域の関係>[/size][/b][br]体は環のうち乗法の逆元があるもの、だから、環の特殊の1つと言える。[br]すると、環という一般の中に2つの特殊(体と整域)があるということになるね。[br][br]では、体と整域の関係はどうなるのだろうか?[br]a,b,xが体の要素だとしよう。[br]a*x=b*xで、x≠0ならば、xの逆元x-1が存在する。だから、a*x*x-1=b*x*x-1で、a=bとなる。[br]体では、簡約法則が使える。[br]y=a-bとおくとき、x*y=x*(a-b)=0としよう。x≠0ならば、x-1が存在するから、y=0となるので、[br]ゼロでないゼロ因子が存在できない。つまり「[b][color=#0000ff]体ならば整域[/color][/b]」となる。[br]体は整域よりもさらに特殊なもの[br]ということがわかる。[br][br]つまり、[br][b][size=200]環>整域>体とだんだんと絞り込まれてきたね。[br][br][/size][/b]逆から見てみると、体(field)が、選ばれた者たちが戦ったり、集ったりできる競技場で、[br]そこに入れない者たちでも対戦したり、つながったりできるのが環(リング)ということか。[br][br]条件を複数クリアした正方形から見たら、長方形もひし形もずっこけているけど、ちゃんと平行四辺形[br]というワクに収まっているのと何か似ている気がするね。
3.整域からユークリッド整域へ
[b][size=150]<ユークリッド整域は中道?を行く>[br][/size][/b][br][b][color=#0000ff]ユークリッドの整域[/color][/b]は、[br]ユークリッドの互除法と[br]不定方程式AX+BY=C(CはA,Bの最大公約元Dの倍元)の解法の[br]前提となる[br][color=#0000ff][b][size=150]整除原理「A,B.Q,Rが整域に属するとき、[br]AをBで割った商がQで余りがRのとき、A=BQ+R(Rが正でBより小さい)」[br][/size][/b][/color][b]が成り立つ整域[/b]を特にネーミングしたものだ。[br][br]定義上は例えば、こうなる。[br][b][color=#0000ff][size=150]整除原理の一般化した定義[br][/size][/color][/b] 整域<A,+,×>の[b][color=#0000ff]各元xに非負整数を対応させる高さ関数H(x)があるものをユークリッド整域[/color][/b]という。[br] ・H(x)=0の核は[b]x=0に限る[/b]。[br] ・非ゼロのx,y∈AでH(xy)>=H(x)。「=」は[b]yが単元に限る[/b]。[br] ・どの非ゼロのx∈Aとどのy∈Aに対しても、q,r∈Aがあり、[b]y=qx+r で、0<=H(r)<H(x)[/b][br][br]係数の集合を、体R、体C、体Qにすれば、余りRをわる式Bより次数を低いもので求めることができる。[br]ただし、整除原理が成り立っても、逆元の存在は何ら保証しないから、ユークリッド整域は体になれるとは限らない。[br]つまり、[br]整域と体の間にユークリッド整域があるということだね。[br]整域を体にまで狭めなくても、整除原理が成り立てば、最大公約元もたぶん素元分解も一意的にもっていけるから、それで、[b]ユークリッド整域の存在価値[/b]は高いと予想されるでしょう。[br][br][color=#0000ff][b][size=200]環>整域>ユークリッド整域>体だね。[br][/size][/b][/color]
4.整式の素元分解
[b][size=150]<素元分解の一意性>[/size][/b][br]整数世界の素数は、多項式世界では既約多項式だった。[br]整数が素数の積に一意的に分解できるということは[br]多項式が既約多項式の積に一意的に分解できるということに対応するでしょう。[br][br][b][color=#0000ff][size=150]多項式K[X]がユークリッド整域となるため、[br]元xに対する非負整数、高さ関数H(x):=xの次数+1[br][/size][/color][/b]と定めてみよう。[br]通常の定数の高さは1,1次式の高さは2、0の高さだけ0。[br]次数を変えない、高さを変えないイチの働きをする多項式は定数。[br]多項式を多項式で割ると、割る数より次数が低い余りが決まる。[br][color=#0000ff](例)[br][/color]たとえば、f=x+1,g=x+2, h=x[sup]2[/sup]+3x+2, i=x[sup]2[/sup]+2x+1 としよう。[br]単元の高さは1, f,gの高さは2, h,i の高さは3になる。[br]h=f* g, i= f*f から、h, i の公約元、1, f 。(マイナスの場合は略す。 )[br]最大公約元G=fになる。[br]また、f, gは互いに素。[br]fとiの最小公倍元L= h*i/G=f*g*f*f/f=f*f*fの3次式となり、高さは4になる。[br]1次式を1つかけるたびに次数が1あがり、高さが1増える。[br]だから、高さHが次数+1という定義は常識にあうね。[br][br]さらに、[br]素元pとpの倍元でないxとは互いに素だ。互いに素は、最大公約元が単元、高さ1だ。[br]公倍元は最小公倍元Lの倍元だ。公倍元のうち、最小公倍元の高さHが最小の高さである。[br]公約元は最大公約元Gの約元だ。公約元のうち、最大公約元の高さHが最大の高さだ。[br]多項式の公約元は、共通因数だった。[br]a,bの最大公約元Gと最小公倍元Lの間には、ab=eGLが成り立つ。(eはある単元)[br][color=#0000ff]多項式の積商にとって[/color][b]単元倍[/b][color=#0000ff]は些末な違いだから気にしない。[br][/color][b]K[X]のKがZのときは、Zを正の整数に限り、一般に[color=#0000ff]モニックな(最高次の係数が1)[/color]の多項式に限定する[/b][color=#0000ff]とよいね。[br][b]ユークリッド整域では、a,bが互いに素でbcがaの倍元なら、cはaの倍元になる。[br][/b][/color][color=#0000ff](理由)[br][/color]a,bが互いに素なら、Gが単元eというこで、ab=eLとなり、L=abe'[br]bcがaの倍元なら、a,bの倍元だから、bc=kL=abe'k[br]整域だからbで簡約すると、c=ae'kとなり、cはaの倍元となる。[br][color=#0000ff][br]これから、0でも単元でもないどんな元も素元の積で表せる。[br][/color]・整除原理から、単元でない元なら、どの元も素元になるまで割って行くことができる。[br]・素元の積がAとBの2通りになった場合、Aの1素元pについてみると、A=Bはpの倍元だから、[br] Bの素元のどれかがpの倍元か単元倍になる。A、Bのともに素元pで割る。この作業を繰り返せば、[br] A、Bのともに単元の積になる。[br][color=#0000ff]だから、順序と単元倍の差をのぞくと、それは1通りになる。[br][/color](ただし、これは、存在証明のアルゴリズムであり、構成するアルゴリズムではない。)[br][b][color=#0000ff][size=200]つまり、ユークリッド整域で素元分解は一意的だ。[br][/size][/color][/b][br][color=#9900ff][b][size=150]質問:2つ整数係数の多項式の割り算の商と余りを求めるコードはどうすれば作れますか。[br][/size][/b][/color][br]割り算の関数に適当に名前をつけます。割る方の式はモニックとします。[br]モニックで、高さが2以上でなければ計算せずにメッセージを出すようにします。[br]たとえば、divf(A,B)関数として、A,B,そしてA÷Bの商Q、余りZを返すものとしましょう。[br][br]係数分離法、組立除法の考え方で多項式を係数のリストとして[br]データ化します。すると、最高次の係数がリストの0番目になります。[br]A÷Bのうち、割り算に関係する部分だけX=A,Y=Bとします。[br][b][color=#0000ff]Bの高さ、つまりリストBの長さをh=len(B)[/color]とします。[br][/b]多項式の最大係数が同じなるように、商をたてますから、q=X[0]//Y[0]です。[br]引き算は先頭次[リストのi=0]での係数の差0になりますから、[b]Z=X-Y*qの計算の次数は[リストのi+1番目]から[/b]にします。[br]引き算をするときに、[b]Yの最後の次の位が必要になるので0を補ってから[/b]引き算します。[br]最後の引き算は、Yの最後までだから、[b]範囲をhではなくh-1にして[/b]おきましょう。[br]また、0を立てたあとに、[b]Xの方がサイズが小さくなるときのため、Xに0を補ってから[/b]引き算します。[br][color=#ff0000][b](※なお、pythonの基本ですが、i in range(h)の範囲は0以上h未満になります。もし、h=3なら、[br]iは0,1,2の3個の数を動きますね。)[/b][/color][br]pop()は補った[0]をけずるための行です。[br]動作確認のために商を立てるごとに余りZを出力しています。[br]その都度のZを次のXとしてX=Zで更新し、YはずっとBのままです。[br][br][IN]Python======================================[br]#多項式の割り算[br]def divf(A, B):[br] h=len(B)[br] X=A[br] Y=B[br] cnt=0[br] Q=[][br] if len(B)<2 or B[0]!=1:[br] print("割る式はモニックで1次式以上にしてください。")[br] return A,B,[],[][br] while cnt<=len(A)-h:[br] q=X[0]//Y[0][br] Q.append(q)[br][b] print(f"{X}-{Y}×({q})",end="")[br][/b] if len(X)> h:[br][b] Y +=[0][br][/b] Z=[X[i+1]-Y[i+1]*q for i in range(h)][br][b] Y.pop()[br][/b] elif len(X)==h :[br] Z=[X[i+1]-Y[i+1]*q for i in range(h-1)][br] else:[br][b] X +=[0][br][/b] Z=[X[i+1]-Y[i+1]*q for i in range(h-1)][br][b] X.pop()[br][/b] X=Z[br][b] print(f"={X}")[br][/b] cnt +=1[br] return A,B,Q,Z[br][br]A,B,Q,R = divf([1,2,0,5],[1,-1,4])[br]print(f"{A}={B}×{Q} + {R}")[br]print()[br]A,B,Q,R = divf([-2,0,0,0,0,0],[1,0,-1])[br]print(f"{A}={B}×{Q} + {R}")[br]print()[br]A,B,Q,R = divf([1,2],[1,1])[br]print(f"{A}={B}×{Q} + {R}")[br]print()[br]A,B,Q,R = divf([1,2,1],[3,3])[br]print(f"{A}={B}×{Q} + {R}")[br][br]A,B,Q,R = divf([1,2,1],[3])[br]print(f"{A}={B}×{Q} + {R}")[br]A,B,Q,R = divf([1,2,1],[0])[br]print(f"{A}={B}×{Q} + {R}")[br]A,B,Q,R = divf([1,2,1],[1,1])[br]print(f"{A}={B}×{Q} + {R}")[br]print()#==========================================[br][color=#0000ff][OUT][br][1, 2, 0, 5]-[1, -1, 4]×(1)=[3, -4, 5][br][3, -4, 5]-[1, -1, 4]×(3)=[-1, -7][br][1, 2, 0, 5]=[1, -1, 4]×[1, 3] + [-1, -7][br][br][-2, 0, 0, 0, 0, 0]-[1, 0, -1]×(-2)=[0, -2, 0][br][0, -2, 0]-[1, 0, -1]×(0)=[-2, 0][br][-2, 0]-[1, 0, -1]×(-2)=[0, -2][br][0, -2]-[1, 0, -1]×(0)=[-2, 0][br][-2, 0, 0, 0, 0, 0]=[1, 0, -1]×[-2, 0, -2, 0] + [-2, 0][br][br][1, 2]-[1, 1]×(1)=[1][br][1, 2]=[1, 1]×[1] + [1][br][br]割る式はモニックで1次式以上にしてください。[br][1, 2, 1]=[3, 3]×[] + [][br]割る式はモニックで1次式以上にしてください。[br][1, 2, 1]=[3]×[] + [][br]割る式はモニックで1次式以上にしてください。[br][1, 2, 1]=[0]×[] + [][br][1, 2, 1]-[1, 1]×(1)=[1, 1][br][1, 1]-[1, 1]×(1)=[0][br][1, 2, 1]=[1, 1]×[1, 1] + [0][/color][br]
[size=150][size=100]ユークリッドの互除法を使うと最大公約数を求めることができましたね。[br]A,Bから[size=150]X=A,Y=Bとし、[/size][もし、Y>0ならQ=X/Y, R=X-Y*Q、[size=150]X=Y,Y=R[/size] ]を繰り返すと、[br]最後の直前のYつまり、Xが最大公約数になるというアルゴリズムが互除法でした。[br][/size][b][br][color=#9900ff][u]質問:2つ整数係数の多項式の最大公約元を求めるコードはどうすれば作れますか。[br][/u][/color][/b][/size][br]ユークリッドの互除法のアルゴリズムの割り算部分を整数から多項式に置き換えましょう。[br]Y>0というのはY=RをしたあとのYのことだから、割り算の余りの式Rの係数がすべて0以外です。[br]なので、係数の2乗和が正の間は、割り算を繰りかえしましょう。[br]ただし、せっかく、Yをモニックにしても、割った余りRがモニックでないと、Y=Rで代入したあとの[br]計算がうまく進みません。そこで、Yがモニックにならなくなったらモニックにする処理を先頭にして[br]おきましょう。[br][IN]Python[br]#============[br]def sqsum(L):[br] return sum([x**2 for x in L])[br]def eucld(A,B):[br] (X,Y) = (B,A) if len(A)0:[br] if Y[0]!=1:[br] print(f"Y={Y} => ",end="")[br] toOne=Y[0][br] Y=[x//toOne for x in Y] [br] print(Y)[br] A,B,Q,R=divf(X,Y)[br] X=Y[br] Y=R[br] return X[br][br]print(eucld([1,2,1],[1,1]))[br]print(eucld([1,2,1],[2,2]))[br]A=[1,2,-1,-2][br]B=[1,-2,-1,2][br]print(eucld(A,B))[br]#=============[br][OUT][br][1, 2, -1, -2]-[1, -2, -1, 2]×(1)=[4, 0, -4][br]Y=[4, 0, -4]==>[1, 0, -1][br][1, -2, -1, 2]-[1, 0, -1]×(1)=[-2, 0, 2][br][-2, 0, 2]-[1, 0, -1]×(-2)=[0, 0][br][1, 0, -1][br]
[IN]python[br]#===============[br]A=[1,0,1,1,1][br]B=[1,0,1][br]print(eucld(A,B))[br][OUT][br]#==========================[br][1, 0, 1, 1, 1]-[1, 0, 1]×(1)=[0, 0, 1][br][0, 0, 1]-[1, 0, 1]×(0)=[0, 1][br][0, 1]-[1, 0, 1]×(0)=[1, 0][br][1, 0, 1]-[1, 0]×(1)=[0, 1][br][0, 1]-[1, 0]×(0)=[1][br]割る式はモニックで1次式以上にしてください。[br][1][br]互いに素になった。
[color=#9900ff][b][u][size=150]質問:geogebraで多項式の割り算や最大公約元を求めるにはどうしたらよいでしょうか。[br][/size][/u][/b][/color][br][b]数式のビューで、[br][/b]Division( <割られる多項式>, <割る多項式> )2つの多項式の除算の商と余りを与える.[br][code]Division(x^2 + 3 x + 1, x - 1)[/code] 出力: [i]{x + 4, 5}[/i].[br][br][b]CASビューで、[br][/b]GCD( <多項式>, <多項式> )2つの多項式の最大公約数を計算する.[br][code]GCD(x^2 + 4 x + 4, x^2 - x - 6)[/code] 出力: [i]x + 2[/i].[br][br]が使えます。[br]これを使ってみよう。[br][br][url=https://geogebra.github.io/docs/manual/ja/commands/%E4%BB%A3%E6%95%B0/]geogebraの代数コマンド[/url]には、整式の約数まで出せたり、複素数の範囲で因数分解できたりと[br]スゴイです。geobebraの技術力は素晴らしい!
多項式の割り算とGCD

体の仲間をふやそう

1.群と環の仲間の増やし方
[b][size=150]このワークシートは[url=https://www.geogebra.org/m/twxxx3yq]Math by Code[/url]の一部です。[br][/size][/b][br]同じ要素に+と×があり、+は群で×はモノイドになる集合が環だった。[br]そして、[b][color=#0000ff]環の×算で、非ゼロなら単元じゃなくてもどれでも逆元があるものが体[/color][/b]だったね。[br][br]つまり、+も×も可換群で分配法則が成り立つものだという言い方もできる。[br](例)有理数体Q、実数体R、複素数体C[br](例)Fp=(Z/(p),+,×) 素数pを法とする剰余類の体[br](例)Zp=(Z, +(mod p) ,×(mod p)) 素数pに対する剰余計算をする整数全体[br]体はK(Körper), F(Fields)などの頭文字K,Fを使ったりします。[br][br]図形は点の集合だ。[br]群、環、体は何かの集合だ。[br][br]図形を切ったりつけたりしても同じ仲間でいられることがある。[br]たとえば、長方形はたてに切り分けても長方形のままで、それを横に切り分けても長方形のままで、。。[br]のように、仲間を増やしていける。[br]大きさをそろえて並べることで、大きな長方形が作れたりするね。[br]群、環、体でも、同じ大きさに着目して、切ったり、つないだりするイメージで仲間を増やせるだろう。[br][br][b][size=150]<群の仲間の増やし方>[br][/size][/b][br]群Gの仲間を増やすにはどうしたか思い出してみよう。[br][br]・[b]切り分ける増やし方[/b][br]自分自身と単位元のような自明なもの以外にも[b]部分群[/b]というものが作れることがあったね。[br][b]群の入れ子だ[/b]。[br]そして、部分群が正規なとき、(gN=Ngとなる群N、同じ型が分散せずに1つに入っている群N)とき、[b]G▷N[/b]と書き、Nを[b][color=#0000ff]正規部分群[/color][/b]と呼んだ。[br]たとえば、G={e, (1 2 3), (1 3 2), (1 2),(1 3),(1 2)}=S3のとき、(a b c)型が1つの収まる[br]N={e, (1 2 3),(1 3 2)}は位数も|G|=6の約数で、gN=Ngとなり、G/Nをすると、Nが加算の剰余0,残りT={(1 2),(1 3),(2 3)}が剰余1に対応する。G/NはZ2={0,1}、つまり、Z/2Zと同型になった。[br]つまり、GをNで割って、整数の割り算による剰余系と同じように、[b]剰余群、商群[/b]が作れたね。[br]一般に、GからHへの準同型写像fがあるとき、fの核KerfがNの役割になり、[b]G/Kerf とimfを同型に[/b]できた。[br]群によってはこの割り算による分解が連続できる複雑なしくみをもつものがあったね。[br][b]分解できるものは正規列[/b]が作れた。[br]Dn▷Cn▷1(二面体群、巡回群、単位群)[br] S3▷D3▷1(対称群、二面体群、単位群)[br] S4▷A4▷V4▷1(対称群、交代群、クラインの4元群、単位群)[br][br]一方で、[b]正規列がない単純な群[/b]があった。[br]5次の交代群(5次の対称群の半分)A5が単純群であることから、5次以上の[b]交代群Anも単純群[/b]であることが、数学的帰納法で証明できるということも学んだね。[br][br]・[b]くっつける増やし方[/b][br]群を成分のようにして、2つ並べる、[br]つまり、[b]群の直積[/b]というやり方でも新しく群が作れたね。[br]たとえば、x∈Z2とy∈Z3を並べた(x,y)は、(0,0)に1ずつたすと2×3=6回たして初めてもとにもどり、[br]巡回群C6と同型な群が作れた。[br]また、有限アーベル群の構造定理という便利なものがあったね。[br]今の直積とは逆に、位数に着目して、直積に分解できるというやつだった。[br][b]位数が素数pのべきの可換群は、巡回群の直積による群と同型[/b]になるというものだった。[br]たとえば、位数p4の可換群は次の5種類がありえた。[br]Cp[sup]4[/sup], Cp[sup]3[/sup]×Cp, Cp[sup]2[/sup]×Cp[sup]2[/sup],Cp[sup]2[/sup]×Cp×Cp,Cp×Cp×Cp×Cp[br][br]
[b][size=150]<環の仲間の増やし方>[/size][/b][br][b]・くっつける増やし方[/b][br][color=#0000ff]係数Kを使ったpの多項式の集合を[size=150]K[p][/size][/color]で表現した。[br][b]環Kにpを添付して拡大した環[/b]のことだったね。[br]R[√2]=a√2+b(a,b∈R)は環Zに√2を添付した環。[br]Z[[math]\sqrt[3]{2}[/math]]=a[math]\sqrt[3]{2}[/math] [sup]2[/sup]+b [math]\sqrt[3]{2}[/math] +c (a,b,c ∈Z)は環Zに [math]\sqrt[3]{2}[/math] を添付した環。[br]ガウス整数Z[i]は環Zにiを添付した環。[br]アイゼンシュタイン整数Z[ω]は環Zにωを添付した環だね。[br][br]環に要素pを追加することで、[b]線形空間(ベクトル)[/b]として要素をおく[b]次元[/b]、成分数が増えただけで、係数はもとの環のものが使えている。だから、群と群の直積と似ている。+算はまさに直積と同様。×算では、成分をまたがる計算も出てくるが、環のルールから外れることはない。[br]R={x+ [math]\sqrt[3]{2}[/math] y| x,y∈Z }は、一見2次元で成分が収まるように見えても、×算で、 [math]\sqrt[3]{2}[/math] の2乗の成分が必要になるから、次元が足りないので、環になれない。[br]このように環の添付拡大では、[b]線形空間の次元の発想[/b]も大切になったね。[br][br][b]・切り分ける増やし方[/b][br]環も群と同じように、割り算で環が増やせた。[br]群の正規部分群と同じように、[b]環の[color=#0000ff]イデアル[/color][/b]でわると[b]剰余環、商環[/b]ができた。[br]<Z[i]/(1+i),+,☓>={[0],[1]}も商環。ガウス格子点の2色ぬりわけ。[br]<Z[ω]/(1-ω),+,☓>={[-1],[0],[1]}も商環。アイゼンシュタイン格子点の3色ぬりわけ。[br]<Z[x]/(1+x[sup]2[/sup]),+,☓>= Z[i] も商環。整数係数の多項式がax+b (g(x)∈Z[x], a,b∈Z)に分類されたね。[br][br]わるのが[color=#0000ff][b]素元[/b]のイデアル[/color]で、環が[b]ユークリッド整域[/b]なら、環が体に格上げされた。[br]Z[x]はユークリッド整域で、x+1は素元だから、Z[X]/(x+1)は体。[br]Z[i]はユークリッド整域で、7は素元だから、Z[i]/(7)は体。[br]Z[ω]はユークリッド整域で、2は素元だから、Z[ω]/(2)は体。[br]Zはユークリッド整域で、3は素元だから、F3=Z/(3)は体。[br]
2.体の仲間の増やし方
[b][size=150]<体の入れ子>[br][/size][/b]体Lの部分集合Kが体であるとき、L/Kとかき、LがKの[b]拡大体[/b]、KがLの[b]部分体[/b]といいます。[br]L/Kが体の拡大なら、LはK上のベクトル空間とみることができてその次元d=[L:K]とかき、dをLのK上の拡大次数といいます。L/Kのd次拡大です。dが有限なら有限次拡大といい、dが無限大なら無限次拡大という。[br][br]3つの体K,M,Lがあり、L/M, M/Kのとき、サンドイッチの真ん中部分の[b]体MをL/Kの中間体[/b]といいます。[br]Mが2点L,Kの中点という感じの言葉遣いですね。[br]体の拡大[math]K\subset M\subset L[/math] に対して、拡大次数[L:K]=[L:M]×[M:K]が成り立つ。[br][color=#0000ff](例)[/color][br][math]\mathbb{C}[/math]/[math]\mathbb{R}[/math], [math]\mathbb{R}[/math]/[math]\mathbb{Q}[/math] だから、[math]\mathbb{R}[/math]は[math]\mathbb{C}[/math]/[math]\mathbb{Q}[/math] の中間体です。[br][br][b][size=150]<くっつける増やし方>[br][/size]・要素の添付による拡大[/b][br]有理数体[math]\mathbb{Q}[/math] にそれに属さない要素√2を添付した体を[math]\mathbb{Q}[/math] (√2)とかく。[br]2つのイメージがあるでしょう。[br][math]\mathbb{Q}[/math]の要素と要素√2の和・差・積・商どれをやっても収まる体。[br][math]\mathbb{Q}[/math]の拡大で√2も含む最小の体。[br][br]でも、結果的には環の拡大と同様な記法、係数[math]\mathbb{Q}[/math]を使った[b]√2の多項式の集合[/b][math]\mathbb{Q}[/math] [√2]と同じです。[br]添付する要素が1つの拡大を[b]単純拡大[/b]という。[br][br][color=#0000ff](例)[br][/color]K= [math]\mathbb{Q}[/math] (√2)=[math]\mathbb{Q}[/math] [√2]={a+b√2 | a,b∈Q}は体。[br]Kが環であることは省略。[br]×算のイチ元は1=1+0√2∈K[br]x=a+b√2≠0∈Kに対して[br]逆元x-1=は1/(a+b√2)=(a-b√2)/(a[sup]2[/sup]-2b[sup]2[/sup])=a/(a[sup]2[/sup]-2b[sup]2[/sup]) +(-b/(a[sup]2[/sup]-2b[sup]2[/sup]))√2より、[br]√2の多項式とみたときの係数は∈Qだから、x-1∈Kになる。[br][color=#0000ff](例)[/color][br]F= [math]\mathbb{Q}[/math] (i)=[math]\mathbb{Q}[/math] [i]={a+bi | a,b∈Q}は体。[br]Fが環であることは省略。[br]x算のイチ元は1=1+0i∈F[br]x=a+bi≠0∈Fのとき。(つまり、a=b=0ではない。)[br]xの逆元x-1=1/a+bi=(a-bi)/(a[sup]2[/sup]+b[sup]2[/sup])=a/(a[sup]2[/sup]+b[sup]2[/sup])+(-b/(a[sup]2[/sup]+b[sup]2[/sup]))i∈Fになる。
[b][size=150]<多項式に連動する増やし方>[br]L/Kが体の有限次拡大でa∈Lとする。[br][/size][/b]f(x)∈K[x]で、f(a)=0となるものがあれば[b]aはK上代数的、短く言うと、[color=#0000ff]K代数[/color][br]([/b]ないならaはK上超越的、K超越という。)[br]・aがK代数で、f(x)がモニックなとき、[br] f(x)はg(a)=0を満たす0でないg(x)∈K[x]の中で最小次数の多項式で、[b][color=#0000ff]最小多項式[/color][/b]という。[br] 言い換えると、[b]f(x)はK上既約、短く言うと、[color=#0000ff]K既約[/color][/b]だ。[br] また、g(a)=0となるg(x)∈K[x]はf(x)の倍数とも言える。[br]・aがK代数なら[color=#0000ff][b]K[a]=K(a)[/b][/color]だ。[b][color=#0000ff]最小多項式f(x)の次数がd(=degf(x))[/color][/b]ならば、dはaのK上の次数で、[br] K[a]はK上のベクトル空間としてd次元である。拡大次数[b][color=#0000ff][K(a):K]=d[/color][/b]。[br]・Lのすべての元xがK代数ならL/Kを[b]代数拡大[/b]といい、それ以外を[b]超越拡大[/b]という。[br][color=#0000ff]・[/color][b]L/Kが有限次拡大なら代数拡大[/b][color=#0000ff]。[br][/color][b]・特に、aがK代数なら単純拡大K(a)=K[a]は代数拡大。[br]つまり、K代数なaをKに添付すれば、K(a)のどの元xもK代数、つまり、代数拡大ができる。[br][/b][color=#0000ff](例)[/color][br]a=[b]√2[/b]∉Qが、Q[x]の多項式で、f(a)=a[sup]2[/sup]-2=0となるものがある。f(x)=x[sup]2[/sup]-2が[b]Q上既約、最小多項式[/b]で2次。[br]aはQ上の代数方程式の解だから、[b]aはQ上代数的[/b]。[br]だから、単純拡大Q(√2)=Q[√2]は代数拡大、[Q(√2):Q]=2で、Q(√2)={a+b√2 | a,b∈Q}。[br]代数拡大ということは、Q(√2)のどの元x=a+b√2もf(x)=0の解となるQ上の方程式があることになる。[br][color=#0000ff](例)[/color][br]b=[b]i[/b]∉Qが、Q[x]の多項式で、f(b)=b[sup]2[/sup]+1=0となるものがある。f(x)=x[sup]2[/sup]+1がQ上既約、最小多項式で2次。[br]bはQ上の代数方程式の解だから、bはQ上代数的。[Q(i):Q]=2で、Q(i)={a+bi | a,b∈Q}[br]c=[b]π[/b]∉Qは、Q[x]の多項式で、f(c)=0となるものがない。cは[b]Q上超越的[/b]。[br][color=#0000ff](例)[/color][br]a=[b]√2+√3[/b]のQ上の最小多項式f(x)を求める。[br]f(x)はQ上既約で、g(a)=0となるg(x)の因数でもある。(a-√2)[sup]2[/sup]=3だから、a[sup]2[/sup]-2√2a=1。[br]a[sup]2[/sup]-1=2√2aとして、両辺2乗する。a[sup]4[/sup]-2a[sup]2[/sup]+1=8a[sup]2[/sup]。aは[b]f(x)=x[sup]4[/sup]-10x[sup]2[/sup]+1[/b]の解。[br]f(x)を1次×3次、2次×2次と因数分解できたと仮定して係数比較しても整合性のある因数はないことが[br]確認される(計算略)。だから、f(x)は[b]Q上既約で、最小多項式[/b]だね。[br]f(x)の次数は4だから、拡大次数[Q(√2+√3):Q]=4だね。[br]Q(a)=Q[a]={p+qa+ra[sup]2[/sup]+sa[sup]3[/sup]|p,q,r,s∈Q}[br][color=#0000ff](例)[/color][br]a=[math]\sqrt[3]{2}[/math] のQ上の最小多項式f(x)を求める。[br]f(x)が既約になればよい。a[sup]3[/sup]=2だから、f(x)=x[sup]3[/sup]-2。f(x)が1次×2次と分解できるとして、-2の約数をf(x)[br]に入れても0にならない。だから、Q上既約。f(x)の次数は3次だから、拡大次数[Q(a):Q]=3だね。[br]Q(a)=Q[a]={p+qa+ra[sup]2[/sup]|p,q,r∈Q}
[b][size=150]<切り分ける増やし方がくっつける増やし方になる>[br][/size][/b][br]・写像f:環V→環W; x →f(y) とするとき、[br] f(x+y)=f(x)+f(y), f(x×y)=f(x)×f(y),f(イチv)=イチw[br] が成り立つとき、fは準同型写像といったね。[br]・環と同じように、体Kの積、和、イチを保存すれば、準同型写像といい、全単射なら同型写像といい、[br] K自身への写像なら[color=#0000ff][b]体Kの自己同型写像[/b][/color]といい、[b][color=#0000ff]AutK[/color][/b]と書いたりする。[br]・aのK上の最小多項式f(x)で、K[x]を割った商環はK(a)と同型になる。これを[b]商体[/b]という。[br] [size=200][size=150][color=#0000ff][b]K[x]/f(x)[/b][/color][math]\cong[/math][color=#0000ff][b]K(a)[/b][/color][/size][/size][br] ユークリッド整域Zを素元pで割った商環が剰余系の体Fpと同型な商体になったことに類似しているね。[br][b] つまり、要素をくっつけて作る拡大体が、最小多項式で割った[color=#0000ff]商体[/color]とぴったり重なるということだね。[br][/b][color=#0000ff](例)[/color][br]p=[math]\sqrt[3]{2}[/math]のとき、体の同型写像h:Q[X]/(x[sup]3[/sup]-2) ->Q[[math]\sqrt[3]{2}[/math]] ; ax[sup]2[/sup]+bx+c→a[math]\sqrt[3]{2}[/math] [sup]2[/sup]+ b[math]\sqrt[3]{2}[/math] +c[br]p=√2のとき、体の同型写像h:Q[X]/(x[sup]2[/sup]-2) ->Q[√2] ; ax+b→a√2+b[br]p=i のとき、体の同型写像h:R[X]/(x[sup]2[/sup]+1) ->R[i] ; ax+b→a i +b ([b][color=#0000ff]複素数体と同型![/color][/b])[br][br]まあ、x[sup]2[/sup]+1の商環を考えるということは、核で割ると同等なので、x[sup]2[/sup]+1=0で割ると同じ働きになっているいうことだね。[br][br][color=#9900ff][u][b][size=150]質問:体の同型写像の見える化をコードでやるにはどうしたらよいでしょうか。[br][/size][/b][/u][/color][br]最小多項式f(x)の次元をdとすると、[br]係数体Kに対する多項式環K[X]/f(x)の商体の拡大次元もdになります。[br]だから、xのd次曲線h(x)で視覚化できます。[br]また、最小多項式=0の解をpとすると、h(p)の値がK[p]の要素として数値化できます。[br]だから、h(x)の係数を変化させることで、連動性が生まれるでしょう。
体の同型写像を感じよう

Information