標高+1m

Don't be rational.

次元ベース宇宙の性質と勉強会のお知らせ

f:id:ympbyc:20150506120157g:plain

よく忘れるのでメモ。

任意のn次元空間Aからn+m次元図形aを観測できるとき、aが存在するn+m次元空間は必ずそのうちのn本の軸をAと共有している。

例えば、理想的な4次元空間(xyzw空間)に於いて、観測装置がxyz空間にあって、3次元立体がxyw空間にあるとき、この立体はxy平面に張り付いた体積0の2次元断面として観測されるはずだけど、z方向の厚みを素粒子一粒分すら持てないため光学的な観測は不可能。

重力はこういう風にはみ出てるんじゃないかっていうのがvacuum energyとかunified field theoryとかひも理論とかグラビトンの話につながる。証明が難しいけど論理的にはとても自然。

話は変わって、なんとなく勉強会というかビアバッシュでも開きたいなと思ってます。幾何学 ∪ 理論物理学 ∪ 計算機科学みたいなテーマで、ビール片手に語り合う会に興味がある方はぜひtwitterで教えてください。 Minori Yamashita (@ympbyc) | Twitter

数人でも興味ある方がいれば会場とビール確保してatndだかcompassだかなんだかで募集かけます。

Brian Greeneが最高

I wanna be a part of the pathway towards truth. I don't care what that truth is. I just wanna help to find it. And if string theory is wrong, get rid of it!

考えてることも科学に対する姿勢も話し方も大好き。World Science Festivalのディスカッション全部めちゃくちゃ面白いのでおすすめ。

日本語訳ついてるのだとこれとか

www.ted.com

それから、これはひも理論関係ないけどe8の話面白い。

www.ted.com

やっぱり理論物理学って面白い。

高次元立方体を描く

f:id:ympbyc:20150412222058p:plain

先日の記事で触れたように、次元数の軸が、どれかの次元の軸についての方程式になっていた場合どんな挙動になるのかの実験のためにn次元単位立体を描画するプログラムを書いています。プログラマだと実験の道具を自分の指先でちょちょいと作れてとても便利。

今日の夕方にJSFiddleで暇つぶしに書いていたら、n次元(0含む)の立方体の辺を描画するものが呆気ないほど簡単にできてしまいました。

超立方体 - Wikipedia
正八胞体 - Wikipedia

5次元立方体のワイヤフレーム。コード末尾の方のstatedが次元数(軸の数)。"Edit in JSFiddle"から、この数値を変えたりして実験できます。

gistはココ: gist: Draw n-dimentional cube on canvas.

あくまでスクリプト的なコードで、効率などは無視していますが、わりかしシンプルに表現できました。

仕組みとしては、

  1. x軸の角度と、y軸の角度をパラメータとして受け取って、この2軸が作る角度を等分割して残りの軸を割り当てる。
  2. 次元軸の置換(permutation)について、 これと {0: 1, 1: 1, ..., n: 1}ベクタplotVertexを呼ぶ。
  3. plotVertexは座標ベクタを舐めて、各スカラーxについて半径xの円周と軸の交点に向けて辺を描画する。この交点を保存しておいて、次の辺のスタート地点とする。

という、定規とコンパスを使う時と全く同じ仕組みになっています。

出来上がった図形は、立体を2次元に投影するときに、互いに直角ではない角度を直角であると錯覚するのと全く同じように、全ての角度が直角であると錯覚して見る必要があります。

以下ギャラリーです。辺の重なりの奥-手前関係は考慮していないので注意。

2次元立方体 2-cube

f:id:ympbyc:20150412231031p:plain

3次元立方体 3-cube

f:id:ympbyc:20150412235728p:plain

4次元立方体 4-cube

f:id:ympbyc:20150412235756p:plain f:id:ympbyc:20150412235819p:plain

5次元立方体 5-cube

f:id:ympbyc:20150412235834p:plain f:id:ympbyc:20150412235845p:plain

6次元立方体 6-cube

f:id:ympbyc:20150412235947p:plain f:id:ympbyc:20150412235955p:plain f:id:ympbyc:20150413000007p:plain

7次元立方体 7-cube

f:id:ympbyc:20150413000042p:plain

8次元立方体 8-cube

f:id:ympbyc:20150413000503p:plain

9次元立方体 9-cube

f:id:ympbyc:20150413000523p:plain

ちゃんと各頂点に次元数本の辺が集まっているのが確認できます。

次元が増えるにつれて赤くなっていくのは、色を設定し忘れた軸方向の線が、デフォルトの赤で引かれているからです。

暇を見つけて改良していきます。任意の軸についての回転を実装すればだいぶ把握しやすくなりそう。

編集履歴

Apr 18 2015

  • もっとうまいやり方を思いついたのでコードを修正しました。美しくなったけどネストした再帰のせいで重くなった。

Apr 19 2015

  • コードを修正して、軸を、等分割位置から0.1τずらすようにしました。ちょうど重なって繋がっているように見えていた線分がうまいことズレて見れるようになった。

  • 任意の軸方向にスケールできるようにしました。

f:id:ympbyc:20150420101117g:plain

関連記事

ympbyc.hatenablog.com

高次元宇宙に移行する

n個の要素を持った配列、n次元ベクトルで表された座標を考える。 *1 n次元ベクトルを与えられた時には、普通n次元空間について考えるけれど、このベクトルをよく見ると、もう一本暗黙の軸があるように見えてくる。ベクトルの要素数の軸だ。ベクトルに詳しくない僕が知っているベクトルの要素数自然数(n)個っていう離散的な値しか取らないけれど、これも軸にできることは間違い無いと思う。

f:id:ympbyc:20150409051145p:plain 3トーラスの表面のxyz座標を計算したいけどなかなか上手くいかない図

数学を全然知らないのに幾何にハマってしまった。ベクトルも集合も高校数学のそれも触りのところしか覚えてないからやり直す必要がある。

というわけでこのテキストで書くことの数学的裏付けを取ることが今の僕には出来ないし、これらはほぼ*2確実に既に数学の言葉で研究されてることなので、このテキストに意味があるのかはよくわからない。「どうやら幾何学ってめちゃくちゃ面白そうだぞ」っていう今の僕の想いが伝わればそれでいいです。

次元を潰す

いきなり高次元の話に入るとわけわからないと思うのでこの章で4次元の物体について考えてウォームアップしよう。

僕らの視覚が認識する空間次元は3つだけだ。4次元の物体を"視る"には、3次元空間に4次元の物体をエンコードするか、空間ではない次元(色とか)を使う必要がある。

時間軸を使って、3次元空間に4次元物体を通過させて、断面のアニメーションを得るっていうのと、立体射影については他所をあたってもらうとして*3、ここでは次元を潰すという操作を考えたい。

次元を潰すというのはなにも難しいことじゃなくて、特に平坦に潰すのは簡単にできる。例えば、3次元の球*4を紙に書くときは、円周を書いて、それに陰影をつけて表現する。これは、x,y,zのどれかの軸を0に押しつぶして、はみ出た次元を色にエンコードするという操作だ。

変わった潰し方もある。例えば、冒頭の画像のように、トーラスの表面に巻きついている糸のz軸をxy平面に垂直に潰すと各頂点が円周から垂直なギザギザの曲線ができる。ところが、平面に垂直に潰すのではなく、円周に沿って撫でるように潰すこともできて、こうすると円周上の点を決める中心角θに、トーラスの経線上の点を決める中心角θ'が加算されて、花丸のような曲線になる。

f:id:ympbyc:20150409063419p:plain θ' = 8θ (0≦θ≦τ)のトーラスをxy平面に潰した図

こういった操作を時間軸に対して行うとなかなか面白い。例えばGPS地上絵 [GPS Drawings]は時間軸をxy平面に潰し込んで、高さzを無視したものだ。

逆に潰された時間軸をほどいてみる。紙(xy平面)にペンで円が描いてあるとき、これを空いているz軸に沿って時間方向に引き伸ばすと、缶のような円筒の下が螺旋状にずれたような形状ができる。螺旋部分はペン先を円周に沿って回している時間。

f:id:ympbyc:20150409122126p:plain

今までの話は平坦に潰すという話だった。平坦じゃない潰し方が投影で、3DCGとか遠近法を使った絵とかは、xyの2次元平面に3次元物体を潰すときに、消失点を設定して、消失点へ集まる軸にz軸を対応づける。これによって錯視的に平面の絵を立体に見せることができる。

同じことが4次元物体でもできるんじゃないかと思って、3次元モニタがあれば4次元の物体を錯視的に表示できると思ったけれど、網膜が2次元球面である制約を受けるような気もしていてまだわからない。

僕らの体も、見えているのが3次元断面なだけで、少なくともこれに加えて時間方向への拡がりはあるわけだし、さらに高次元にはみ出していてもなんにもおかしくはない。

次元軸

ここから本題。2年前くらいからよく高次元の世界について考えているんだけど、高次元の存在になる、というか、高次元の存在としての自覚と視覚を獲得する方法が検討もつかなかった。これはさっき風呂に入っていて思いついた生焼けのアイディア。

(1次元, 2次元, 3次元,   4次元,  ... n次元)

ていうn個の要素を持った配列、n次元ベクトルで表された座標を考える。 *5 n次元ベクトルを与えられた時には、普通n次元空間について考えるけれど、このベクトルをよく見ると、もう一本暗黙の軸があるように見えてくる。ベクトルの要素数の軸だ。ベクトルに詳しくない僕が知っているベクトルの要素数自然数(n)個っていう離散的な値しか取らないけれど、これも軸にできることは間違い無いと思う。

この軸方向に移動すると、次元が増減する。この軸を仮にdimentionのdで d軸 と呼ぶことにする。

ここまでで「高次元に行く方法」というぼんやりしていて怪しかった言葉が、「さあ、ではどうやってd軸の値を変化させようか」という数学の言葉になった。

で、その方法について。n本の軸のどれか一つでもdに関する方程式に変数として含まれていれば、つまり、

vars = {d ∝ p | p ∈ {x,y,z,...}}
vars ≠ ∅

*6 であるなら、その軸方向に運動すればdの増減が見込める。

僕らは、僕らの意志で自由に空間の3次元内を移動できて、さらに意志に無関係に時間方向に移動している、もしこの4軸のどれかが係数がいくら小さくても変数として含まれてさえいれば、つまり{x,y,z,t} ∩ vars ≠ ∅なら、十分な距離だけこの軸方向に移動すれば、高次元に到達できるはずなんだ。もしこの3+1本の軸のどれもdに関する方程式に登場せず、かつvarsが空でない場合は、脳の多次元構造とリンクを確立する方法を探るしかない。

f:id:ympbyc:20150409063932p:plain

(define (vec . xs)
  (take xs (car xs)))

(vec 2 0 0 0 0 0 0 0)   ;;=> (2 0)
(vec 5 0 0 0 0 0 0 0)   ;;=> (5 0 0 0 0)

ベクトルの要素数が要素に依存する例 - dがxに比例している

あぶれた次元や足りない次元がどうエンコードされるのかは考えないといけない。

追記: 宇宙の曲率との関係について

ある軸方向への移動が他の軸方向への移動を作り出すっていう現象を想像しづらいのは、軸が全て直線で構成されるユークリッド空間で考えているから。僕らがユークリッド空間にいるときは、x軸と平行に歩くと見えない力でy方向に吸い寄せられていくなんてことは起きない。

でも僕らがいるのは地球で、地球は球という多様体だ。多様体は、局所的にはユークリッド空間を"貼り付ける"ことができるけれど、大局的に見るとこれが破綻する図形のこと。球やトーラスは多様体の典型例だ。地球の表面を西に移動し続けると、僕らの視点では北を正面に見て左方向に直線的に進んでいるように見える。でも宇宙からこの移動体を観察すると、実際には緯線に沿った円の軌道をなぞるように進んでいることがわかる。つまりローカル座標系でのx方向への移動がグローバル座標系でのy方向への移動も同時に作り出しているわけだ。

f:id:ympbyc:20150413030019p:plain f:id:ympbyc:20150413030352p:plain

俺はx方向に移動していたと思ったらy方向にも移動していた。な… 何を言っているのか わからねーと思うが…

これと同じことが宇宙規模で起きるのが曲率のある宇宙で、閉じた宇宙、開いた宇宙、平らな宇宙っていうのはこの話なんだ。*7

つまり、3+1時空の軸のどれかが次元方向に曲がっているとしたら、ある日突然体の一部が高次元方向に"持ち上がり"始めるってことも、逆に3軸宇宙に潰され始めるってことも、数学的に充分考えられる。

追記終わり

ちょっと今は言葉がまとまっていなくて説明できないけど、d軸ってフラクタルの繰り返しの方向か、それによく似た性質の軸なんじゃないかという直感がある。こんど書きたいと思っているn-トーラスを3次元に潰す話もこれに関係ある気がする。 ref: フラクタル次元 - Wikipedia

今日のところは以上です。次回は銀河とトーラスについて書きます。

ツッコミ待ってます。

*1:点次元の0次元は0要素ベクタなので座標には含まれない

*2:絶対なんだけど知らないことを絶対とは言えない

*3:こことか: http://www.dimensions-math.org/Dim_CH2_JP.htm

*4:表面から内側として3次元

*5:点次元の0次元は0要素ベクタなので座標には含まれない

*6:∝を使ったけど別に比例じゃなくていい。こういうときに使う記号を知らなかった。教えてほしい

*7:閉じている宇宙は球やトーラスのトポロジーで、開いた宇宙は鞍形のようなトポロジー、平らな宇宙はユークリッド空間という理解。トポロジーは現在勉強中。

次元とそのエンコーディング

次元て言葉の意味を勘違いしてた。

0次元では点、1次元では線、2次元では面、3次元では立体、4次元で物体、5次元で並行宇宙が表現できるとかっていう時空的な次元について考えることが多かったけど、次元はもっと身近なところにあった。

情報の次元

次元ていうのはある情報に含まれる変数の数だ。つまり1つの変数を持った情報は1次元だし、3つの変数を持った情報は3次元だ。

たとえばrgb(r, g, b)これはr軸、g軸、b軸の3軸の空間に並べることができる。rgba(r, g, b, a)なら4本の軸が必要だ。

僕らの脳が瞬間瞬間に処理しているのは空間の三次元だけじゃなくて、他にも圧縮された次元がいくつもある。例えば目から得られる情報には、xyz空間の立体情報の他に、色がある。色は周波数や光量等の多次元情報が1次元程度に圧縮されて知性に届く。

音も面白い。演奏っていうのは、少なくとも楽器の数だけある情報の次元を時間軸,周波数軸,振幅軸の3次元に編み込む行為だ。

脳が一瞬中に処理している情報の次元数を数えてみると、パッと思いつくだけでもこれだけある

  • x,y,zで3
  • 音が2
  • 色が1
  • 温度が1
  • 湿度が1
  • 匂いが1
  • 触覚、痛覚が1
  • 味覚が4

さらにこのスナップショットが連なった記憶の次元がある

これを上から順にx,y,z,v,p,c,t,h,s,q,u0-u3,tとする。

僕らはこの15+次元の情報を目とか耳とか舌とかの感覚器官にマップしているけど、マッピングがこうである必然性はない。現生生物の目はx,y,z方向を向いているけど、進化の過程では例えばv,p,c空間を視ていた生物がいたかもしれない。現生生物の数倍の数の感覚器官を持っていたものの、生存に必要無いとして切り捨てられた情報次元もあるはずだ。

こんなに情報次元が多いのに、相対論的宇宙が世界を空間3次元+時間1次元として扱っているのは、これらの情報次元は全て素粒子の配置にエンコードできるという信念に基づいているからなんだと思う。これはひも理論も同じ。

位相幾何学のしっぽ

例えば2次元平面を考える。この平面に描いた長方形の周上の点は(x,y)で表すので十分だが、円を描いたとして、円周の点を表す時はx,yよりも半径と角度、つまり緯度、経度の方が扱いやすい。

3次元空間に置かれた球の表面の座標は、x,y,zの3次元情報よりも、lat,longの2次元情報の方が有用。球の表面が2次元ていうのはこういう意味。

4次元球の表面は3次元 www.kyoto-su.ac.jp

最近会社の創立10周年パーティーに向けて3Dのインタラクティブアニメーション作ってて、カメラにトーラスの内側を回らせたりしてて、位相幾何学って面白そうだっていうことはわかった。僕は数学を体系立てて学ぶのがどうしようもなく下手なんだけど、数学の表面を撫でるようなプログラミングは楽しい。三角関数とか行列もプログラム書いて初めてわかった。

とかの結果が視覚的に見える計算がお気に入り。うまくいくとパズルが解けたみたいで楽しい。

標高+1m

あらすじ

高度18000kmは、人々の熱狂と、世界各地で約20時の空に向けて撃たれた大量の花火で幕を開けた。旧単位2020年、つまり高度17706kmに転軸した太陽系が初めて迎える新メガメートル紀だ。それが旧単位を恣意的に翻訳した値にすぎないと鼻で笑っていた人も、8.765km前には興奮を隠すことをやめていた。俺は久々の休高度をストーンとオンパでもキメて穏やかに過ごしたかったが、0時の通りの馬鹿騒ぎと、20時からの炸裂音はマンション22時の俺の部屋まで容赦なく響いてきていた。俺は観念してペーパーを口に放り込みオンパのジョイントを数本巻いて、0時を目指した。

うわー難しい。時空酔いしそう。今度仕切り直す。

関数型UIプログラミング

Pasta(deprecated)とかkakahiakaとかcastorocaudaっていうのを2012年くらいからぽつぽつ作ってて、その時に考えていたこと。多分Fluxも同じことを考えてて思いついたんだと思ってる。あと継続ベースのWAF( Seasideとかkahuaとか )とも通じる部分がある。*1

狭義の関数型プログラミングには値と関数しかない*2ので状態が持てない。つまり入力から一意に出力が決まるプログラムしか書けない。つまりアプリケーション自体が一つの関数である必要が有る。

こういうアプリケーションの典型例としては、対話式でない単純なシェルスクリプトがある。完全にステートレスな(裏にDBがあったりしない)Webサーバの各エンドポイントとかも当てはまる。

$ echo hello
hello

このパラダイムで対話的UI(例えばWebフロントエンド)を作るには、シェルの役割を果たすフレームワークがあれば、プログラマは純粋関数を書くだけで良い。つまりフレームワークの責務は、

  1. ユーザの入力(マウスクリック、キープレスなど)の度に適切な関数を適切な引数で呼ぶことと、
  2. この関数の返り値を利用してUIをアップデートすること。

実はこれだけでは不十分で、フロントエンドアプリケーションは状態を持つ必要が有ることが多い。ここでいう状態は、アプリケーションのライフサイクルを通じて、刻々と変わっていく変数の集合。例えば記事一覧と記事詳細を扱うアプリケーションなら、記事データの配列と、現在選択中の記事IDなどが該当する。

そこで先の架空のフレームワークに一つインディレクションを加えて、

  1. ユーザの入力がある度に適切な関数を適切な引数で呼ぶ
  2. この関数は現在の状態と1から渡ってきた引数を受け取り、新しい状態を返す
  3. 新しい状態から新しいUIを組み立てて表示する

こうする。

アプリケーション全体を見ると、状態からUIへの純粋関数を、繰り返し状態を変えながら呼び出している構図が出来上がる。

理論的にはこれでいいんだけど、3は安直にやるとページ全体が書きかわることになってSPAの意味がなくなる。そこでWebFUIcastorocaudaReactでは、プログラマには状態から仮想DOMっていうツリー状のデータを生成する関数を書かせて、これを前回の仮想DOMと突っつき合わせて差分を計算して、差分のみを描画するっていう戦略を採っている。

;;わざと冗長な書き方をしている

;;アプリの状態を保持するref
(def state (atom {:articles [{:id "xxx" :title "yyy" :text "zzz"}]
                  :selected nil}))

;;3
(defn render-all [state]
  [:div [:h1 "ブログ"]
        [:div#articles
         (map (fn [atcl]
                  [:div [:h2.article-title 
                         {:data-id (:id atcl)} 
                         (:title atcl)]
                   (when (= (:selected state) (:id atcl))
                         [:p (:text atcl)]))
              (:articles state))])

(def vdom (atom (render-all @state)))

;;1 & 2
;;記事のタイトルをクリックされたら記事idを設定する
(.addEventListener 
   (.querySelector js/document "#articles")
   "click"
   (fn [e]
     (let [id (.getAttribute (.-target e) "id")
           st (swap! state assoc :selected id)]
          (swap! vdom render-diff (render-all st)))))

仮想DOMが無いと、状態からUIを生成する部分を純粋関数として書くのは難しくなるけど、うまくやれば、状態からUIが一意に決まるという性質は残せる。

Pasta(deprecated)とkakahiakaは、仮想DOMを持たない実装で、つまりDOMの上でなくても使える。ミュータブルなオブジェクトで表現されたUIの世界の上に純粋関数としてのアプリケーションを構築するためのものって言えるとこまで汎用化してある。

どうやっているかっていうと、差分を出す部分を1段階早くしていて、2のアプリ関数は新しい状態を返す代わりに現在の状態への差分を返すようにしている。で、3は状態の変更をオブザーブしていて、新しい状態と古い状態を渡されるからそれを使って命令的に描画をする。

var K = window.kakahiaka;

//アプリの状態を保持するref
var app = K.app({
  articles: [{id: "xxx", title: "yyy", text: "zzz"}],
  selected: null
});

//3
K.watch_transition(app, "selected", function (state, old_state) {
  $('.article[data-id=' + old_state.selected + '] p').hide();
  $('.article[data-id=' + state.selected + '] p').show();
});

//2
var selectArticle = K.deftransition(function (state, id) {
  return {selected: id};  //トランジションは状態と引数を受け取って差分を返す純粋関数
});

//1
$("#articles").on("click", ".article-title", function () {
  selectArticle(app, $(this).data("id"));  //トランジションの起動
});

これだと、純粋関数として書けるのは2だけなんだけど、アプリケーション自体が純粋関数としての性質を持つのは変わらなくて、状態の保存->復元とか、undo,redoとかバグレポートに添付された状態の読み込みとかしたら勝手にUIも復元されるようになるので便利。

htmlは全く汚れないし、jsでhtmlを生成するわけでもないのでhtmlコーダとフロントエンドエンジニアの分業が楽。逆に一人で両方やるなら仮想DOMとかどんどん使うと良い。

まとめ

アプリケーション全体を眺めたときに、

  • イベントが起きるたびに状態を更新する純粋関数が起動される
  • 差分描画の仕組みがある
  • 状態からUIが一意に決まる

こういう構造(まあ要するにFluxとかREPL)になっていると幸せっすよ。っていうのと、

  • FluxにはMVCがどうとかじゃなくてこういう道筋でも至れるんだぜってことと、

  • プログラムの一部が純粋関数型でなくてもそんなに気に病まなくてもいいかもね

ってことが言いたかった。


以前の記事:

kakahiakaとは - 標高+1m

*1:この記事ではわかりやすさのために関数を「呼ぶ」と表記している箇所があります

*2:もっと狭義だと関数しかない