● 名前のついてない関数(純関数) … 引数が#1, #2,... と書かれる計算 &
→ 一回しか使わないような関数をわざわざ定義しなくても使えるようにした
Syntax Sugar の一つ.
→ 単純な関数に対しては積極的に使った方がプログラムが読みやすくなる.
→ 実行速度が速くなる,というメリットもあるらしい.
→ 最後に & をつけるのを忘れずに.
→ #1 は # と省略して書いてもよい.
次の例のように使う.
In[1]:= a = {1, 4, 9, 16, 25, 36, 49, 64, 81, 100} In[2]:= a // N[Sin[#]] & ← Map[N[Sin[#]]&, a] とこの場合は同じ. Out[2]= {0.841471, -0.756802, 0.412118, -0.287903, -0.132352, -0.991779, -0.953753, 0.920026, -0.629888, -0.506366} In[3]:= NS[x_] := N[Sin[x]] ← 純関数を使わない場合は,こうして新たに関数を定義してから, In[4]:= a // NS ← 使うということになる. Out[4]= {0.841471, -0.756802, 0.412118, -0.287903, -0.132352, -0.991779, -0.953753, 0.920026, -0.629888, -0.506366} ← もちろん Out[2] と同じになる.
■ 双平方
2つの1以上の整数の平方(= 二乗)の和である整数を双平方であるという.
では,双平方な数について何かわかることはないか調べてみよう.
まずは一番簡単な,12 + m2 (m=1,2,... ) という形のものから調べてみよう.
In[1]:= Ds[n_,m_] := n^2 + m^2 In[2]:= a = Table[Ds[1, n], {n, 1, 20}] Out[2]= {2, 5, 10, 17, 26, 37, 50, 65, 82, 101, 122, 145, 170, 197, 226, 257, 290, 325, 362, 401}
数学の世界では,
整数についてまずチェックすべき性質は素数との関係である
ということになっているので(^-^;),
● 素数かどうかの判定 … PrimeQ[数]
を使って素数なものを抜き出してみると次のようになる.
In[3]:= Select[a, PrimeQ] Out[3]= {2, 5, 17, 37, 101, 197, 257, 401}
さらに数学の世界では,
整数について素数性の次にチェックすべき性質は「何か整数で割ってみたときの振る舞い」
ということにもなっているので,
12 + m2 を 2,3,4,5,6,7,8,... で割ってみて様子を見てみよう.
● 整数の割り算の答え … Quotient[a, b]
→ a ÷ b = c 余り d という時の c である
という命令と以前紹介した Mod を使って,
In[4]:= QM[x_, n_] := {x, Quotient[x,n], Mod[x,n]} In[5]:= QM[21,5] Out[5]= {21,4,1} ← 要するに,21 ÷ 5 = 4 余り 1 の 21と右辺 が出てくる.
という関数を定義しておいて,2 で割った場合,3 で割った場合 … とやってみよう.
素数であるところにはそう記してある.
In[6]:= Map[QM[#, 2]& , a] //TableForm ← 2 で割った場合. 純関数を用いていることに注意. Out[6]//TableForm= 2 1 0 ← 素数 5 2 1 ← 素数 10 5 0 17 8 1 ← 素数 26 13 0 37 18 1 ← 素数 50 25 0 65 32 1 82 41 0 101 50 1 ← 素数 122 61 0 145 72 1 170 85 0 197 98 1 ← 素数 226 113 0 257 128 1 ← 素数 290 145 0 325 162 1 362 181 0 401 200 1 ← 素数 In[7]:= Map[QM[#, 3]& , a] //TableForm ← 3 で割った場合 Out[7]//TableForm= 2 0 2 ← 素数 5 1 2 ← 素数 10 3 1 17 5 2 ← 素数 26 8 2 37 12 1 ← 素数 50 16 2 65 21 2 82 27 1 101 33 2 ← 素数 122 40 2 145 48 1 170 56 2 197 65 2 ← 素数 226 75 1 257 85 2 ← 素数 290 96 2 325 108 1 362 120 2 401 133 2 ← 素数 In[8]:= Map[QM[#, 4]& , a] //TableForm ← 4 で割った場合 Out[8]//TableForm= 2 0 2 ← 素数 5 1 1 ← 素数 10 2 2 17 4 1 ← 素数 26 6 2 37 9 1 ← 素数 50 12 2 65 16 1 82 20 2 101 25 1 ← 素数 122 30 2 145 36 1 170 42 2 197 49 1 ← 素数 226 56 2 257 64 1 ← 素数 290 72 2 325 81 1 362 90 2 401 100 1 ← 素数 In[9]:= Map[QM[#, 5]& , a] //TableForm ← 5 で割った場合 Out[9]//TableForm= 2 0 2 ← 素数 5 1 0 ← 素数 10 2 0 17 3 2 ← 素数 26 5 1 37 7 2 ← 素数 50 10 0 65 13 0 82 16 2 101 20 1 ← 素数 122 24 2 145 29 0 170 34 0 197 39 2 ← 素数 226 45 1 257 51 2 ← 素数 290 58 0 325 65 0 362 72 2 401 80 1 ← 素数
となり,次のような仮説をたてると正否はどうなるかというと…
■ 仮説1 双平方数は 2 で割って余り 1 ならば素数 ⇒ 正しくない
■ 仮説2 双平方数は 素数ならば 2 で割って余り 1 ⇒ 2 を除いて正しい?
■ 仮説3 双平方数は 3 で割って余り ほげほげ ならば素数 ⇒ 正しくない
■ 仮説4 双平方数は 素数ならば 3 で割って余り ほげほげ ⇒ 正しくない
■ 仮説5 双平方数は 4 で割って余り ほげほげ ならば素数 ⇒ 正しくない
■ 仮説6 双平方数は 素数ならば 4 で割って余り 1 ⇒ 2 を除いて正しい?
■ 仮説7 双平方数は 5 で割って余り ほげほげ ならば素数 ⇒ 正しくない
■ 仮説8 双平方数は 素数ならば 5 で割って余り ほげほげ ⇒ 正しくない
となる(ただし,ここでは双平方数は 12 + m2 の形だけを考えている).
□ レポート課題 1
同様に,12+m2 の形の双平方数を 6,7,8 で割ったときの仮説を考え,その正否を調べよ.
仮説2 は,2以外は素数は奇数,ということから「当たり前」なのでいいとして(つまり,双平方数かどうかに関係ない),
仮説6 は「新しい発見」である.
そこで,仮説6をきちんと書いてみよう.
■ 仮説9 双平方数かつ素数は 4 で割って 1余る.
□ レポート課題 2
仮説9 が一般の双平方数(n2+m2 の形)に対して成り立つかどうか Mathematica で調べよ.
さて,仮説9 の形の「逆」の形の仮説は提案できないか調べてみよう.
● 論理演算 … !(Not), &&(And), ||(Or)
→ !式 は式の否定,式1 && 式2 は 式1と式2の論理積,式1 || 式2 は論理和を返す.
T で True, F で False を表すとして,論理演算を表で表すと次のようになる.
式 | !式 |
---|---|
T | F |
F | T |
式2 \ 式1 | T | F |
---|---|---|
T | T | F |
F | F | F |
式2 \ 式1 | T | F |
---|---|---|
T | T | T |
F | T | F |
与えられた整数が双平方数かどうかチェックする関数 DsQ を上の論理演算を使って最初に以下のように作っておいて,
In[10]:= DsQ[n_] := Module[{Answer, i, R}, i = 1; Answer = False; While[(!Answer) && (i <= Sqrt[Quotient[n, 2]]), R = Sqrt[n - i^2]; Answer = IntegerQ[R] && Positive[R]; i++; ]; Return[Answer] ] In[11]:= Table[{n, DsQ[n]}, {n, 1, 20}] // TableForm ← 20 まで DsQ が正しく動くかどうかチェック. Out[11]//TableForm= 1 False 2 True 3 False 4 False 5 True 6 False 7 False 8 True 9 False 10 True 11 False 12 False 13 True 14 False 15 False 16 False 17 True 18 True 19 False 20 True
まず,4 で割って 1 余る普通の整数は双平方かどうかみてみる.
In[12]:= b = Table[4*n+1, {n,0,19}] ← 4 で割って 1 余る数を小さい順に20個作っている Out[12]= {1, 5, 9, 13, 17, 21, 25, 29, 33, 37, 41, 45, 49, 53, 57, 61, 65, 69, 73, 77} In[13]:= Map[DsQ, b] Out[13]= {False, True, False, True, True, False, True, True, False, True, True, True, False, True, False, True, True, False, True, False}
… どうもそうとは限らないようだ.
では,4 で割って 1 余る素数は双平方かどうかを次にみてみよう.
In[14]:= c = Select[b, PrimeQ] ← 4で割って1余る数の中で素数なものを抜き出している Out[14]= {5, 13, 17, 29, 37, 41, 53, 61, 73} In[15]:= Map[DsQ, c] Out[15]= {True, True, True, True, True, True, True, True, True}
正しいように見える.よって,以下の仮説が提案できるだろう.
■ 仮説10 4で割って1余る素数は双平方である.
□ レポート課題 3
p に対して p = a2 + b2 となる a, b (1以上の整数)の組を求める関数を
Mathematica で作り, 100個程度の 4 で割って 1余る素数 p に対して計算してみよ.
この仮説と仮説9,さらに 2 が素数かつ双平方であることを併せて考えると,結局次の仮説にたどり着く.
■ 仮説11 (フェルマー-オイラーの定理) 素数 p が4で割って1余る or p=2 ⇔ 素数 p は双平方.
□ レポート課題 4
仮説 11 を数学的に証明せよ.
→知識がないと難しいと思われる… と思ったが,
→数学セミナー(日本評論社) 2000.09 の p.3--5
に通常の証明とは異なる非常に分かりやすい証明が載っている.
数学を知らなくても理解できる.
この証明を思いつくのはほとんど不可能だが…