<   2017年 10月 ( 8 )   > この月の画像一覧

福井商業高校チアリーダー部

福井の高校のチアリーダー部が全米チアダンス選手権5連覇


入部してきた頃はほとんどが初心者。2年間で変貌する。本当に。

福井商業高校チアリーダー部 ありのままのJETS

顧問はダンスの経験がなく、プロのダンサー・振付師に月に1回生徒の指導を仰いだたとのこと。登美丘高校ダンス部といい、高校生の潜在能力の高さに驚かされる。しかし、指導のあり方についても考えさせられる事例だ。

エピローグ


追記

見落としていた動画の追加



[PR]
by tnomura9 | 2017-10-31 07:55 | ボーカロイド | Comments(0)

Haskell の Y コンビネータ

Yコンビネータの情報を探していたら Haskell でもできるという記事を見つけた。Haskell は型つきラムダ記法なので再帰関数はラムダ記法では定義できないはずだと不審に思ったが、次のように試してみた。

Prelude> let y x = x (y x)
Prelude> y (\f n -> if (n == 1) then 1 else (n * (f (n - 1)))) 5
120

...... 動いてしまった。

厳密には Y コンビネータ y の定義はラムダ記法ではないが、y x = x (y x) という動作をする高階関数の引数にラムダ記法の関数を与えると、第1引数にその関数自身がバインドされて再帰関数が定義できることが分かった。

Y コンビネータの威力が y x = x (y x) という不動点 (y x) で発揮されることが分かる。なぜそういうことが起きるのか考えてみた。

y x = x (y x)

なのでコンビネータ y は関数をひとつ引数に取る1変数関数だ。また、再帰関数を定義するときは x に上の階乗の例から分かるように関数と数値を引数に取る2変数関数を与える。そこで階乗を計算するための関数 g を g f x のように関数 f と整数 x を引数に取る2変数関数で表現してみる。すると、

y g = g (y g)

なので、(y g) を整数 3 に関数適用すると次のようになる。

(y g) 3 = (g (y g)) 3 = g (y g) 3

これは関数 g = \f n -> if n == 1 then 1 else n = n * (f (n - 1)) の f に (y g) がバインドされ、n に 3 がバインドされていることを示すので、

(y g) 3 = g (y g) 3 = 3 * ((y g) 2)

である。

同様に、(y g) 2 = 2 * ((y g) 1), (y g) 1 = 1

となるから、結局

(y g) 3 = g (y g) 3 = 3 * ((y g) 2) = 3 * 2 * ((y g) 1) = 3 * 2 * 1 = 6

と不動点 (y g) による再帰的計算が行われ 3 の階乗の 6 が計算される。つまり、高階関数 y が、

y x = x (y x)

のように不動点 (y x) を作り出す関数であれば、これを関数と整数の2つの引数をもつ2変数関数に関数適用すると、どのような再帰関数も作り出すことができることになる。この場合、どのような再帰関数を y コンビネータで定義しても、その(局所)関数名は (y x) という不動点になる。

Scheme で作った複雑な Y コンビネータも結局は y x = x (y x) という不動点を作り出す関数を定義したに過ぎない。Scheme の場合は Y コンビネータの定義もλ記法でできるので、型なしλ計算が再帰関数を記述できる根拠となる。しかし、Haskell でも y x = x (y x) のように y を定義するだけで、簡単に不動点を作り、無名再帰関数を記述できることが分かる。

追記

同じ発想で Scheme でもできないかと思ってやってみたが、スタックオーバーフローになってしまった。

y g = g (y g) = g (g (y g) = g (g (g (y g))) = ...

と永遠に β 変換をやり続けたためらしい。これを防ぐために前回の記事では Z コンビネータが使われていたようだが、これを y x = x (y x) の形にすることができなかった。β 変換の順序次第で無限ループになってしまうところが λ 計算の面白いところだ。真実はひとつではない?

[PR]
by tnomura9 | 2017-10-25 12:32 | ラッセルのパラドックス | Comments(0)

Y コンビネータの使い方

型なしラムダ計算の勉強のために Scheme をインストールした。

Linux : > sudo apt-get install mit-shceme
Mac : > brew install mit-scheme
Windows : Gaushe のインストーラをダウンロードした。(MIT Scheme が何故か動かなかった。)

型なしラムダ計算を学習しようと思ったのは、関数の自己適用がラッセルのパラドックスと関係があるのではないかと思ったからだ。ラムダ計算で関数の自己適用が現れるのは不動点コンビネータの Y コンビネータだ。ラムダ計算の教科書の説明では1ページくらいで解説してあるが、Scheme で実行しようとして躓いた。

そこでネット検索で、Y コンビネータで再帰的プログラムがかけることがわかった。再帰的プログラムの代表は階乗の計算だ。Scheme では次のように書ける。

1 ]=> (define (factorial n) (if (zero? n) 1 (* n (factorial (- n 1)))))

;Value: factorial

1 ]=> (factorial 5)

;Value: 120

しかしながら、これは自分自身を呼び出すのに関数名を必要としているので、ラムダ計算は使えない。

ところが、Y コンビネータを使うとラムダ計算でも再帰関数を定義できる。ラムダ計算の Y コンビネータは次のようになる。

Y = (λf . (λx . f (x x)) (λx . f (x x)))

何のことか分からないが、Scheme で記述した Y コンビネータは次のようになる。

1 ]=> (define yc (lambda (f) ((lambda (x) (f (lambda (n) ((x x) n)))) (lambda (x) (f (lambda (n) ((x x) n)))))))

;Value: yc

関数 (x x) に値を与えるための変数 n をλ記法で確保した以外はほぼ上のλ計算の Y コンビネータと同じものだ。Y コンビネータの一種で Z コンビネータというらしい。λ計算の Y コンビネータには任意の関数 g に関数適用することによって。

Y g = g (Y g)

となり、Y g が g の不動点になることがわかっている。とは言え、この Y でどうやって再帰関数を記述することができるのだろうか。

いろいろな解説をウェブで見たが、はっきりわからなかったのでこの記事を書いたわけだが、とにかく動くプログラムを作って動作させて見ることにした。Y コンビネータを使った階乗の関数は次のようになるが、実際に動作しているのが分かる。

1 ]=> (define fact (yc (lambda (f) (lambda (n) (if (zero? n) 1 (* n (f (- n 1))))))))

;Value: fact

1 ]=> (fact 5)

;Value: 120

そこで、階乗の計算を定義した部分を g とすると、上の定義は、

fact 5 = (Y g) 5 = g (Y g) 5

となるが、g(f, n) の引数 f に Yg がはいり、g の引数 n に5が入るので、

fact 5
= (g (Y g) 5)
= (if (zero? 5) 1 (* 5 ((Y g) 4)))
= 5 * ((Y g) 4)
= 5 * (g (Y g) 4)
= 5 * (if (zero? 4) 1 (* 4 ((Y g) 3)))
= 5 * 4 * ((Y g) 3)
...
= 5 * 4 * 3 * 2 * 1 * 1 = 120

と毎回関数 (Y g) が g の引数 f に入るので再帰関数の計算ができることになる。

要するに、λ記法で記述された関数に Y を関数適用すると第1引数を使ってその関数自身を利用するという、再帰的定義ができるのだ。無名関数であるλ記法で再帰的定義ができるという不思議な現象が起きてしまうが、このことによってλ記法はループのあるプログラムを作ることができるのが分かる。

Y コンビネータとは何かと考えるのは大変だが、Y コンビネータを使って再帰関数を定義する方法は意外に簡単だった。

[PR]
by tnomura9 | 2017-10-24 07:21 | ラッセルのパラドックス | Comments(0)

利尿薬でどうして血圧が下がらないのか

ある人に、心不全の患者さんに利尿薬が3種類も処方されているのに血圧は下がらないのかと尋ねられた。確かに利尿薬で体液は減るわけだから、血圧は下がってもいい。しかし、ひどく下がるときもあるが大抵はあまり血圧が下がるということはない。なぜなんだろう。

一般に血圧というのは動脈圧を指している。しかし、動脈が分岐して毛細血管になる頃には動脈圧はほとんど0になってしまう。つまり、血圧の影響は毛細血管までしか届かない。血液が毛細血管を抜けて静脈へ行く頃には、心臓の拍出による血圧の影響はなくなり、静脈の還流には心臓の影響はないに等しい。

すなわち、血液循環のシステムは動脈系のコンパートメントと静脈系のコンパートメントにはっきりわけられていると考えることができる。

したがって、利尿薬によって腎臓から失われた体液は動脈系のコンパートメントから失われるのか、静脈系のコンパートメントから失われるのかをはっきりしておく必要がある。

動脈血は腎臓の糸球体で濾過され、尿細管やヘンレのループで再吸収される。この際、再吸収された血液は腎静脈に戻っていき、動脈に戻ることはない。利尿薬によって腎臓から尿として体液が排出されたとしても、体液量が減るのは静脈系の循環血液量が減るのであって、動脈系の血液容量には変化がない。

血圧は動脈系の血液容量と動脈のコンプライアンスで決まるので、動脈系の血液容量の変化がなければ血圧は下がらないのだ。利尿薬を使っても血圧があまり下がらないのはそういう理由からだ。

それでは、どのようなときに血圧は下がるのだろうか。動脈の末梢血管が拡張して末梢血管抵抗が下がると、動脈全体の血液量が減少する。動脈のコンプライアンスが変化しなければ動脈の血液容量が減少するため血圧は下がってしまう。したがって、血圧を下降させるためには利尿剤で体液量を減少させることよりも末梢血管の抵抗を減らしたほうが効果的だ。

また、心拍出量が減少すれば動脈系のインとアウトのバランスから動脈の血液容量が減少し、これも降圧の要因となる。それでは、心拍出量が減少するのはどのようなときだろうか。それは、左房への肺からの血液の還流が減少する場合だ。肺への血液の供給は右室が行うので、右室の拍出量が、左室の心拍出量の鍵を握っていることになる。右室梗塞の時の治療抵抗性の低血圧はこの機序によっている。

右室の収縮力が機能している場合、右室からの拍出量は、右房への静脈還流量に依存している。そうして、右房への静脈還流量は大静脈と右房の圧較差、すなわち大静脈の静脈圧に依存する。さらに、大静脈の静脈圧は静脈系の血液容量と静脈系のコンプライアンスに依存することになる。

静脈のコンプライアンスは、動脈のコンプライアンスより遥かに大きいので、静脈系の血液容量の変化は、動脈に比べ静脈圧にあまり影響しない。すなわち、利尿薬で利尿を行っても、静脈圧の変化は動脈に比べ僅かなものになる。このため利尿薬による体液の減少は静脈圧の現象にあまり寄与せず、そのため右室の拍出量は減少せず、ひいては左室の心拍出量の減少にも繋がらず、血圧低下がみられない。

血圧は心拍出量と末梢血管抵抗と循環血液量に影響をうけるとしても、動脈系と静脈系に分けて考えなければ利尿剤の影響を予測できないことが分かる。

[PR]
by tnomura9 | 2017-10-23 22:10 | 考えるということ | Comments(0)

Darci Linne

2017年の America's Got Talent の優勝者

Darci Linne


すごい!!

ちなみに、準優勝は

Angelica Hale


天使!!


追記

準決勝で敗退したけれどこの子も素晴らしい。

Celine Tam


将来、美人になりそうだし、これからが楽しみだ。



3人の Golden Buzzers の動画もある。


[PR]
by tnomura9 | 2017-10-16 23:04 | ボーカロイド | Comments(0)

矛盾の無い集合論

素朴集合論にラッセルのパラドックスが発生するのは、集合と個体を同じレベルで論じたからだ。

領域という個体の数が N であるとき、その(部分)集合の数はは2の N 乗になるので、個体間の帰属関係で個体に集合を代表させようとしても圧倒的に数が不足する。領域の個体数を無限に増やしても、個体間の帰属関係を表す演算表は正方行列になるので、対角線論法とそれによるパラドックスを許してしまう。

集合を矛盾なく表現するためには、領域の個体とその集合は別の空間に分ける必要があるのだ。たとえば領域 D = {a, b, c} のときその領域における集合は、その部分集合の空間を S = {(), {a}, {b}, {c}, {a,b}, {a,c}, {b,c}, {a,b,c}} をすると S は D の要素からなる全ての集合を表すことができる。また、S は D における個体の集合の全ての演算について閉じている。このように、領域 D の個体とその集合を分けることで、ラッセルのパラドックスは全く発生しない。

しかし、この表現では集合の集合は表現できない。素朴集合論の個体も集合も個体として捉える方法は、集合の集合のような複雑な概念を統一的に表現することができる。上に述べた方法ではそれは不可能なような気がする。

そこで、S = {s0, s1, s2, ... , s8} ただし s0 = {}, S1 = {a}, ... とすると集合の集合 {{}, {a}} を表す集合の集合の空間 G = { {}, {s1}, {s2}, .... , {s1,s2}, .... } を考えることができる。この場合も G は領域 D の個体の集合の集合からなる空間を余すところなく表現できるので、ラッセルのパラドックスは発生しない。

新しい集合のデータ構造を考えるたびに新しい空間を作り出さなければならないが、ラッセルのパラドックスは発生しない。

これらはラッセルのタイプ理論と同じ考え方だ。ただし、タイプ理論では論理についての議論が複雑になりすぎたため、公理的集合論が採用された。しかし、素朴集合論の矛盾を解消するという意味では、公理的集合論よりも本質的に見える。

タイプ理論は複雑すぎて実用的に見えないが、個体の集まりである領域とその集合の空間を分ける考え方は、型付きラムダ計算とおなじだ。型付きラムダ計算は Haskell などの関数型プログラミング言語の基礎となっているが。こちらの方は十分実用的にプログラムを組むことができる。

乱暴な議論かもしれないが、型付きラムダ計算こそが矛盾を含まない集合論のモデルだと考えることができるのではないだろうか。もしかしたら、公理的集合論は型付きラムダ計算と同等なのかもしれない。


[PR]
by tnomura9 | 2017-10-15 23:36 | ラッセルのパラドックス | Comments(0)

なぜ素朴集合論は矛盾するのか

素朴集合論では集合は「ものの集まりというもの」であると考える。この考え方が便利なのはものの集まりである集合を1つのものと考えることによって、その集合を要素とする集合を考えることができることだ。また、集合を単なる個体と同列に置くことで、個体と集合からなる集合のようなものも簡単に考えることができる。

このことは、集合の要素として様々なレベルの集合を等しくとり得ることを意味するので、複雑な概念を簡潔に表現することができる。これは、個体や個体の集合や集合の集合などを同列のものとして取り扱うことができることによる、概念の操作の革命だ。数学に現れる複雑な概念の構造は集合の考え方を使うことで簡潔な表現を手に入れることになる。

しかし、物の集まりと集合としてのものの関係をどう表現したらいいだろうか、a, b, c というものがあったとしてそれを集合としてまとめた {a, b, c} という集合をひとつのものとして扱うとき、この集合という「もの」は a, b, c というものの集まりとは異なる。この区別が分かりやすいように {a, b, c} に A という名前をつけてみよう。すなわち、

A = {a, b, c}

とする。こうすると A と a, b, c の集まりの関係がはっきりしてくる。つまり、A は a, b, c の集まりそのものではないが、a, b, c の集まりを指し示す記号の役割を果たしている。素朴集合論ではこのような A と a, b, c を同列の対象として扱うから、A を要素とする {A} や {a, A} のような集合も作ることができる。

このように素朴集合論では個体も集合も集合の集合もおしなべてもの(対象)として扱うことができるからこれを区別せずに a, b, c, .... で表すことにする。このような対象の集まりを領域 D と呼ぶことにする。この領域 D ではたして集合はきちんと表現できるのだろうか。

このような領域 D にはどれが個体でどれが集合であるというような区別はない。しかし、個々の対象を取り上げたとき、そこには帰属関係という関係性がある。つまり、a という対象が b という対象をその要素とするとき(b が a に帰属しているとき)その関係を、

a ∋ b

で表すことができる。これはこの対象の集まりのどの2つの対象についても一方が他方に帰属するかどうかという関係を考えることができる。したがって、素朴集合の世界は、このように2つの対象の間に帰属関係が定義された対象のネットワークの全てと考えることができないだろうか。

このネットワークは2つの構成要素からできている。1つは対象の集まりであり、もう一つは対象と対象の帰属関係を表す評価関数 ψ(x, y) である。ψ(x, y) は2つの対象を引数とし、x が y を要素としていれば、すなわち x ∋ y なら1の値をとり、そうでなければ 0 の値をとる。ψ(x, y) は全ての対象間の帰属関係を表現できるので、このネットワークで全ての集合を表すことができそうに思える。

ところで、対象 a が集合のときその外延すなわち {b, c, d} という対象の集まりをどのようにして見つけることができるだろうか。それは評価関数 ψ(x, y) を使うことで簡単にできる。対象 x の外延を見つけるために全ての対象 a, b, c, ... に対して ψ(x, a), ψ(x, b), ... と評価関数の値を求めその数列を求める。その数列はたとえば 0, 1, 0, 0, 1, ... のようになっているかもしれない。x の外延はこの数列の値が 1 になっている要素を集めることで得ることができる。例えば上の数列の場合、x = {b, e, ... } である。

そこで、縦に対象をとり横にその対象が要素として含む可能性のある対象を並べ、各行列に評価関数 ψ(x, y) の値をおいた次のような正方行列を考える。

** a b c ...
a 0 1 0 ...
b 1 1 0 ...
c 0 0 1 ...

この正方行列の演算表は対象と対象の全ての帰属関係を記述している。そうして、この演算表の横の行の数列は、その行の対象に帰属する対象の集まり、すなわち外延を表していることが分かる。なぜなら、その数列の値が1になるような対象はすべてその行の対象に帰属しているからだ。

ところで、この演算表を見たときあれっと思う人は多いだろう。そのとおりでこれはカントールの定理に出てきた対角線論法の表と同じものだ。したがって、この演算表には致命的な欠陥がある。つまり、この演算表の対角線部分を反転させて作る数列 1 0 0 ... はある対象の集合を表しているが、この数列は上の演算表のどこにも現れない。なぜなら、演算表のどの行とも対角線部分で異なっているからだ。

このことは、素朴集合の世界の全てを対象とその帰属関係というネットワークで表すことはできないことを示している。つまり、全ての集合を対象とその帰属関係で表すことは不可能なのだ。対角線部分を逆転した数列がしめす集合は自分自身を要素として含まない集合の集合だが、そのような集合をこの演算表の上に表すことはできないのだ。

なぜこのようなことが起きるのか領域 D = {a, b, c} の場合を考えてみよう。領域 D の要素を集めた集合は次のように8個ある。

{}, {a}, {b}, {c}, {a,b}, {a,c}, {b,c}, {a,b,c}

この集合を全て対象 a, b, c だけで表すことは明らかに不可能だ。強いて帰属関係で表そうとすれば次のように対象を追加して演算表を作らなければならないが、これは正方行列にはならない。

** a b c
a 0 0 0
b 1 0 0
c 0 1 0
d 0 0 1
e 1 1 0
f 1 0 1
g 0 1 1
h 1 1 1

また、領域 D が無限集合であったとしても正方行列の演算表では全ての集合をあらわすことはできない。これを全ての集合は対象と帰属関係で表現できるとしたところが、素朴集合論にあらわれた矛盾の正体だったのだ。

ほとんどの数学的対象で集合は矛盾を起こさないように見える。この場合は数学では領域 D は実数などの集合であり、その要素の中には集合は含まれない。自分自身を要素として含まない集合の集合などは領域 D の要素には存在しないため矛盾が起きないのだろう。

追記

素朴集合論の世界を対象と対象間の帰属関係というネットワークでとらえようとしたところが素朴集合論の矛盾の原因だ。領域 D の対象の冪集合の要素(すなわち領域 D の部分集合)全てを領域 D の対象だけで代表させることは不可能なのに、それができると仮定するからだ。その仮定に立てば、領域 D の要素間の正方演算表で全ての領域 D の集合を表すことができなければならないが、そうではないので、対角線論法による矛盾が発生する。

領域 D の部分集合を表す記号を領域 D の内部に求めなければ、領域 D の部分集合全てを表す記号を考えることはできるので、矛盾は発生しない。たとえば、領域 D = {a, b, c} のときその部分集合を x = {}, y = {a}, z = {b} のように集合の空間 S = {x, y, z, ...} で捉えることにすると、領域 D の全ての集合を集合の空間 S で表現でき、領域 D の全ての部分集合間の演算は、S の上で完結している。数学で多用される集合で矛盾が見られないように思われるのは、数学の対象 では領域 D は実数などの集合でその要素に集合を含まないため、領域 D の部分集合の空間 S が領域 D とは独立しているからではないだろうか。

[PR]
by tnomura9 | 2017-10-08 09:11 | ラッセルのパラドックス | Comments(0)

理解のタイムラグ

『世界記憶力グランドマスターが教える脳にまかせる勉強法』池田義博著を読んだ。その中でも「3サイクル反復速習法」が独創的だったので今実行してみている。要するに1回の読書でベージを3回読み返しながら読み進めていく方法だが、その読み進め方が独特だ。1ページを読み終わって次のページに進む前に、そのページの一つ前のページから読み返すのだ。

今読んでいるページを読み終えたら、次のページに進む前に今読んでいるページの一つ前のページを読み返す。その後今読んでいるページをもう一度読み、それから、次のページに進むのだ。このサイクルを繰り返していくと、一回の読書で同じページを3回読むことになる。

面倒くさそうに見えるが、やってみるとそれほどでもない。速度が気になるなら、スキミングすればよい。実際にやってみると面白いことに気がついた。それは、次のページに移る前に今読んでいる一つ前のページを読むと内容がよく分かるのだ。それは繰り返しの3回目だからというだけでなく、書いてあることの構成や著者の意図が1回目に読んだときよりはるかによく見える。

そこで思いついたのは、3回目というタイムラグの間に、脳が1回目に読んだことを咀嚼して理解を深めているのではないかということだ。つまり一回目の読書では文字情報から内容を読み取るが、その内容を理解するために少しタイムラグが発生するのではないだろうか。さらに、文字情報の読み取りと同時に、意識には上らないが、意識下でそれを既存の記憶に関連付けて理解するという作業が行われているのではないだろうか。

どうやら、読書の際には文字情報から内容を読み取るという作業と、読み取った内容を既存の記憶と関連付けて理解するという2つの作業が同時進行的に行われており、読み取る作業とそれを理解する作業の間には少しのタイムラグがあるようなのだ。この理解する作業は意識下で行われているため読み取り作業の表面には現れないが、読み返す操作で意識に上らせることができる。この意識下の作業を読み返しで意識に上らせることで記憶の再定着ができるのだろう。

読み返しの操作は、ある程度細切れに行うのが有効だ。おそらく、本を3回通読してもこの分かったという感じはおこらないだろう。脳が新しい情報を処理するための適切な情報量があるに違いない。その情報の単位というのはどうも新書版1ページくらいのようだ。専門分野の教科書などは1ページの情報量が多く、読み返しの効果が薄れるような気がする。この場合は参考書の1ページ分を3等分して、それを新書の1ページとして取り扱うといいかもしれない。

この考えはノートの取り方にも応用できるのではないだろうか。参考書を読みながら丸写しするのではなく、前のページを読み返すときにノートに記入するのだ。あるいは脳が疲れなければ、前のページの内容を思い出して記入しても良い。いずれにせよ、意識的な読み取り作業に隠れている同時進行の意識下の理解の作業を有効活用することが大切だ。

[PR]
by tnomura9 | 2017-10-02 06:05 | 考えるということ | Comments(0)