ある意味、自然数(Natural Number)や整数(Integer Number)が何か規定する等差数列(arithmetic progression)あるいは算術数列(arithmetic sequence)の定義(definition)こそが数理計算(mathematical computing)の出発点といえましょう。
等差数列(arithmetic progression)あるいは算術数列(arithmetic sequence)の定義(definition)は以下。
- 与えられた区間(interval)において「隣接する項が公差(common difference=共通の差)を持つ数列(sequence of numbers with common difference)」の事で、計算上の初項(Initial term)をa[1] 、公差をdとすれば、n番目の項a[n]はa[n]=a[1]+(n-1)dとなり一般にa[m]=a[m]+(n-m)dと書く。この記述を一般項(general term)という。
この表現を用いると、例えば以下の単調数列(monotonic sequence)は自明の場合(torivial case)としてそれぞれこの様に表現(explession)される。
- 自然数(Natural)N[n]={1,2,3…,1+(n-1)*1}…区間1~無限大Inf、初項1、公差1、一般項1+(n-1)*1
- 整数(Integer)Z[n]={0-(n-1)*1,…,-3,-2,-1,0,1,2,3,…1+(n-1)*1}…区間無限小-Inf~0~無限大Inf、初項0、公差±1、一般項0±(n-1)*1
- 偶数(Even)[n]={-2n,…-6,-4,-2,0,2,4,6,…2n}…区間無限小-Inf~0~無限大Inf、初項0、公差±1、一般項0±(n-1)*2
- 奇数(Odd)[n]={2n-1,…-5,-3,-1,1,3,5,…2n+1}…区間無限小-Inf~0~無限大Inf、初項0、公差±1、一般項0±(n-1)*1
自然数の様に片側の端点(end point)のみが無限大Infもしくは無限小-Infに開き(open)、もう片側が閉じた(closed)半開区間(semi-open interval)で仕切られた算術数列を片側無限算術数列(one-sided infinite arithmetic sequence)、整数や偶数や奇数の様に無限大Infと無限小-Infに挟まれた開区間(open interval)で仕切られた算術数列を両側無限算術数列(Two-sided infinite arithmetic sequence)と呼ぶ。その振る舞いは公差dに符号の向き(Sign direction)に依って定まる。
- dの符号が正(plus)ならば、その数列の項(term)は増加数列(increasing sequence)を構成し無限大Infに発散(divergence)する。
- dの符号が負(minus)ならば、その数列の項(term)は減少数列(decreasing sequence)を構成し無限小-Infに発散(divergence)する。
ちなみに両側とも閉じて有限個の項しか持たない閉区間(closed interval)の算術数列は有限算術数列(Finite arithmetic sequence)と呼ばれ、初等数学でいうところの等差数列は概ねこれを指す。有限算術数列の和は算術級数 (arithmetic series) と言う。
ところで コンピューター言語は原則として無限大Infや無限小-Infを直接は扱えません(例外的に扱う場合も、概ね図示は困難)。そこでここでは数直線(Number Line)上の-5~0~5近辺を区間(Interval)としての実装を試みる事にします。
自然数(Natural)N[n]={1,2,3…,1+(n-1)*1}…数列(sequence)a[m]の順番(Order)=係数(coefficient)mはこれによって与えられる。従ってこの範囲では順番と係数が一致する。
統計言語Rによる「1から5を範囲とする自然数」表現
#代数ライブラリYACASを用いた表現。
library(Ryacas)
yacas("Table(n,n,1,5,1)")
Yacas vector:
[1] 1 2 3 4 5
#標準搭載関数seqを用いた表現
c0<-seq(1,5,by=1)
c0
[1] 1 2 3 4 5
表の出力
library(xtable)
N0<- data.frame(Order=c0, Value=c0)
print(xtable(N0),type="html")
Order | Value | |
---|---|---|
1 | 1.00 | 1.00 |
2 | 2.00 | 2.00 |
3 | 3.00 | 3.00 |
4 | 4.00 | 4.00 |
5 | 5.00 | 5.00 |
グラフの出力
plot(N0$Order,N0$Value,type="b",main="Natural Number",xlab="Order",ylab="Value")
整数(Integer)Z[n]={0-(n-1)*1,…,-3,-2,-1,0,1,2,3,…1+(n-1)*1}(ただしnは0以上の整数)…0や負数の導入によって順番と係数が一致しなくなる。
統計言語Rによる「-5から5を範囲とする整数」表現
#代数ライブラリYACASを用いた表現。
library(Ryacas)
yacas("Table(n,n,-5,5,1)")
Yacas vector:
[1] -5 -4 -3 -2 -1 0 1 2 3 4 5#標準搭載関数seqを用いた表現
c0<-seq(-5,5,by=1)
c0
[1] -5 -4 -3 -2 -1 0 1 2 3 4 5
表の出力
library(xtable)
Z0<- data.frame(Coefficient=c0, Value=c0)
print(xtable(Z0),type="html")
Coefficient | Value | |
---|---|---|
1 | -5.00 | -5.00 |
2 | -4.00 | -4.00 |
3 | -3.00 | -3.00 |
4 | -2.00 | -2.00 |
5 | -1.00 | -1.00 |
6 | 0.00 | 0.00 |
7 | 1.00 | 1.00 |
8 | 2.00 | 2.00 |
9 | 3.00 | 3.00 |
10 | 4.00 | 4.00 |
11 | 5.00 | 5.00 |
グラフの出力
plot(Z0$Coefficient,Z0$Value,type="b",main="Integer Number",xlab="Coefficient",ylab="Value")
abline(h = 0,col=c(200,200,200))
abline(v = 0,col=c(200,200,200))
偶数(Even)[n]={-2n,…-6,-4,-2,0,2,4,6,…2n}…「-5~0~5近辺」なる曖昧表現を用いたのはこのケースを想定したから。「細けぇ事はいいんだよ」?
統計言語Rによる「-6から6を範囲とする偶数」表現
#代数ライブラリYACASを用いた表現。
library(Ryacas)
yacas("Table(n,n,-6,6,2)")
Yacas vector:
[1] -6 -4 -2 0 2 4 6
#標準搭載関数seqを用いた表現
c0<-seq(-6,6,by=2)
c0
[1] -6 -4 -2 0 2 4 6
表の出力
library(xtable)
Even0<- data.frame(Coefficient=c0, Value=c0)
print(xtable(Even0),type="html")
Coefficient | Value | |
---|---|---|
1 | -6.00 | -6.00 |
2 | -4.00 | -4.00 |
3 | -2.00 | -2.00 |
4 | 0.00 | 0.00 |
5 | 2.00 | 2.00 |
6 | 4.00 | 4.00 |
7 | 6.00 | 6.00 |
グラフの出力
plot(Even0$Coefficient,Even0$Value,type="b",main="Even Number",xlab="Coefficient",ylab="Value")
abline(h = 0,col=c(200,200,200))
abline(v = 0,col=c(200,200,200))
奇数(odd)[n]={2n-1,…-5,-3,-1,1,3,5,…2n+1}…偶数(even number)の一般項2nに対し、奇数(odd number)の一般項は2n±1という関係。
統計言語Rによる「-5から5を範囲とする奇数」表現
#代数ライブラリYACASを用いた表現。
library(Ryacas)
yacas("Table(n,n,-5,5,2)")
Yacas vector:
[1] -5 -3 -1 1 3 5
#標準搭載関数seqを用いた表現
c0<-seq(-5,5,by=2)
c0
[1] -5 -3 -1 1 3 5
表の出力
library(xtable)
Odd0<- data.frame(Coefficient=c0, Value=c0)
print(xtable(Odd0),type="html")
Coefficient | Value | |
---|---|---|
1 | -5.00 | -5.00 |
2 | -3.00 | -3.00 |
3 | -1.00 | -1.00 |
4 | 1.00 | 1.00 |
5 | 3.00 | 3.00 |
6 | 5.00 | 5.00 |
グラフの出力
plot(Odd0$Coefficient,Odd0$Value,type="b",main="Odd Number",xlab="Coefficient",ylab="Value")
abline(h = 0,col=c(200,200,200))
abline(v = 0,col=c(200,200,200))
統計言語Rによる「公差dの符号が正(plus)ならば、その数列の項(term)は増加数列(increasing sequence)を構成し無限大Infに発散(divergence)する」の実装例。
#上の例は全てこれに該当するが、とりあえず実数のそれを再利用。
c0<-seq(-5,5,by=1)
PD0<- data.frame(Coefficient=c0, Value=c0)
plot(PD0$Coefficient,PD0$Value,type="l",main="Divergence to Inf",xlab="Coefficient",ylab="Value")
abline(h = 0,col=c(200,200,200))
abline(v = 0,col=c(200,200,200))
統計言語Rによる「公差dの符号が負(minus)ならば、その数列の項(term)は減少数列(decreasing sequence)を構成し無限小-Infに発散(divergence)する」の実装例。
但し書き
統計言語Rの標準関数Seq(St(始点),Ed(終点),by=Def(公差))には以下の制約がある。
- Def(公差)の値がマイナスを取れない。
- Def(公差)=0がエラーとならないのはSt(始点)=Ed(終点)の場合のみ。
従って与えられた条件をそのままの形では実装出来ない。
代替実装例
cx<-c(-5:5)
cy<-c(5:-5)
ND0<- data.frame(Coefficient=cx, Value=cy)
plot(ND0$Coefficient,ND0$Value,type="l",main="Divergence to -Inf",xlab="Coefficient",ylab="Value")
abline(h = 0,col=c(200,200,200))
abline(v = 0,col=c(200,200,200))
統計言語Rによる「有限算術数列(Finite arithmetic sequence)の総和(sum)としての算術級数 (arithmetic series) と算術平均(arithmetic mean)」の実装例
考え方
まず有限算術数列(Finite arithmetic sequence)の総和(sum)S(1~n)[係数n]=初項a+a[1]+a[2]+a[3]…a[n]における公差dを巡る計算順序を入れ替えて以下の式を構成。
- 式A…S(1~n)[n]=a+(a+1*d)+(a+2*d)+(a+3*d)…(a+(n-1)*d)
- 式B…S(1~n)[n]=a[n]+(a[n]-1*d)+(a+2*d)+(a+3*d)…(a+(n-1)*d)
この2式を両辺で項ごとに足し合わせる。
- 左辺は2*S(1~n)[n]
- 右辺は各項で公差dを含む成分がすべて相殺されて初項a[1]と末項a[n]の和だけが残り、これがn項続く。
- 従って答えは2*S[n] = n*(a[1] + a[n])となる。
両辺を 2 で割ればS[n]=n(a[1]+a[n])/2=n(2*a[1]+(n-1)d)/2となる。
この種の式は欧州だとピサのレオナルド(一般にはフィボナッチとして知られる)が記した「算盤の書("Liber Abaci"; 1202年, ch. II.12)」に初出。
- よく聞かれる伝承としてカール・フリードリヒ・ガウス(独Johann Carl Friedrich Gauß/羅Carolus Fridericus Gauss、1777年~1855年)がこの式を再発見した話がある。彼が3年生のときに、教師J. G. Bütnerが生徒たちに1から100までの合計を求めさせたところ、彼は即座に答(5050)を出したため、Bütner と助手のMartin Bartelsがいたく驚いたというものである。
そして等差級数の算術平均(arithmetic mean)S[n]/nは自明的に (a[1] + a[n])/2となる。499年に、インド数学・天文学古典期の傑物数学・天文学者アーリヤバタ(Aryabhatiya、476年~?)も現存するインド数学最古の文献「アーリヤバティーヤ」の中でこのような方法を与えている。
統計言語Rによる実装例
#有限算術数列c0(n=1~100)の生成
c0=c(1:100)
c0
[1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
[39] 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
[77] 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
#係数nの確認
length(c0)
[1] 100#初項a[1]の確認
c0[1]
[1] 1#末項a[n]の確認
c0[length(c0)]
[1] 100#総和(sum)の計算(公差1のケース)
c0[length(c0)]*(2*c0[1]+(length(c0)-1)*1)/2
[1] 5050
100*(2*1+(100-1)*1)/2
[1] 5050
100*101/2
[1] 5050
#sum関数による答え合わせ
sum(c0)
[1] 5050
#算術平均(arithmetic mean)S[n]/nの計算(c0[1]+c0[length(c0)])/2
[1] 50.5
#mean関数による答え合わせ
mean(c0)
[1] 50.5
とりあえず以下続報…
【個人的メモ】この投稿の執筆に際して参照した数学・コンピューター言語系サイト