一般

KCSで行われた一般的な事柄

習うよりググれ

これはKCS AdventCalendar2019 5日目の記事です

←4日目 | 6日目→

 

こんにちは、Google信者なのにiPad Proを愛用している、1年のFastriver(@fastriver_org)です。最近私も人に教える機会が増えてきたのですが、初学者が何かを勉強していくに当たって手に入れるべきスキルの一つを紹介していこうと思います。

“””検索力”””です。

話題としては全ての分野に通ずると考えていますが、以下ではプログラミングを一例として話します。適宜何かに置き換えて読んでみてください。

「検索力」is 何

プログラミングにおいて、暗記は特に必要ありません。英単語のテストは一言一句覚えなければならないですが、コードを書くのに全ての関数名を覚えている意味はないです(断言)。大切となってくるのはコードを書きたいときに「その機能が存在することを知っている」ことです。機能の存在を認知していなければ思考に入ることすらできませんが、存在さえ知っていれば後はどうにかして書き方を調べるだけになります。そして、そこから目的のコードに辿り着くことができる力、これこそが「検索力」であります。検索力を高めることによって、暗記をすることなく(=自分の脳の限界に達することなく)知識の輪を広げることができるわけです。

では目的にいち早くたどり着くにはどうすればよいでしょうか?

1.人に聞く

もし、あなたの周りにその分野の強者つよつよがいた場合はこの手段が使えます。検索力が高くない場合はこの方法が最速であることが多いです。周りの方はソースコードを見ただけで魔法のように答えを示してくれるでしょう。

問題点

あなたは聞いた人の時間を奪っています。講習などで教えてもらっている場合は良いですが、いつまでもそばに人がいるわけではありません。また、検索力を高めていくと他の方法のほうが速くなります(聞かれた人もググってることが多い)。

そこで、一人ぼっちでも調べることができるツールが存在します。

2.Google検索(Yahoo!も許す)(BingはNG)

evolving_google_identity_2x1.jpg

(引用元: https://design.google/library/evolving-google-identity/)

皆さん「Google検索」を知っているでしょうか?

知らない人が多いかもしれませんが、なんと真ん中の白四角の部分に言葉を入力するだけで、それに関連したWebサイトや写真、動画などをネット上から検索してくれるサービスなんです!!!

昨今「Google検索はゴミ」「オワコン」などの風潮も流れていますが、適切な使い方をすれば現在でも非常に有用なツールです。活用していきましょう。

使い方1: そのままコピペ

コードを書いていてRuntime Errorが出たときなどに、英語が読めないどうすれば解決できるのか分からないときにはエラーメッセージをそのままコピペして検索すると、同じ悩みを持つ人とその解決策を持つ人を見つけられることが多いです(Stack OverflowとかGitHub Issueとかが引っかかる)。注意点としては、コピペするエラーメッセージの中に自分で定義した変数名などが入っていると全文一致の確率が下がってしまうということです。そこはうまく工夫しましょう。

使い方2: AND検索乱れ撃ち

検索において最も重要なのは検索ワードです。しかし往々にして、検索したいものは分かるが名前がわからない/検索したいものが何なのか分からない という状況が生まれます。例えば

 

Untitled

この右下のボタンを知りたいと思った時にも名前(Floating Action Button)を知らなければ困ってしまいます。このような時には記憶に存在する関連したワードをAND検索していくと辿り着くことができる可能性があります。見つからなくてもN回くらいワードを変えてやり直してみましょう。

Annotation 2019-11-28 141944割とすぐ見つかった

逆に言えば、固有の名前を知っていれば検索の速度はかなりあがります。多く使う機能などは検索で引っかかりやすい名前などを覚えておくと便利です。

使い方3: 検索演算子

Google検索は検索ワードをひたすら並べるAND検索だけでなく、豊富な演算子での検索が可能です。詳しくはリンク先を見てください。

ウェブ検索の精度を高める – Google 検索 ヘルプ
https://support.google.com/websearch/answer/2466433?hl=ja

 

Google検索を使いこなすための便利な29のテクニック

https://blog.hubspot.jp/update-how-to-search-in-google-x-advanced-google-search-tips-0-0

 

この中で僕がよく使うものを軽く紹介します。

・NOT検索

「C#のLINQについて調べたいのにアイドルグループが引っかかる…」などの時には特定のワードを除外するNOT検索が使えます。「LINQ -アイドル」のように除外したいワードにハイフンをつけるだけです。

・filetype:

ネットに転がっているのはWebページだけではありません。冊子などはPDFで公開されていることが多いですが、特定のファイル形式のみを検索したいときは「[検索ワード] filetype:pdf」とするとPDFのみが引っかかります。

使い方4: 多言語検索

ネット上の日本語の記事というのは、ほんの一握りでしかありません。海外で開発された技術などではなおさら外国語での記事が圧倒的に多いです。

https://www.forbes.com/sites/niallmccarthy/2018/07/27/how-languages-used-online-compare-to-real-life-infographic/#4e586c952c7c 日本語記事は全ページの3.8%しかカバーしていない

日本語で見つからない場合は、英語ないしはその技術の母国語で検索しましょう。その言語のワードのみの羅列だけでも大体フィルタリングされて結果が出ますが、検索画面の 設定 > 言語(Languages) から検索言語を変えることもできます(この場合全ての表記が変わるので注意)。

Annotation 2019-12-02 140651

Google翻訳を使うのも良いです。しかし多分原文のほうが読みやすいと思います…

使い方5: 期間指定検索

インターネットの記事は日々更新されていきます。ソフトウェアもアップデートがかかっていきますが、「昔の特定のものだけ」「最新バージョンだけ」調べたいということもしばしばおこります。そのときは検索対象の期間指定をすると目的により近い検索結果を得られます。

Annotation 2019-11-29 091802

しかし、如何にインターネットの情報が更新されているといっても、誰かが記事を書かなければ検索には出てこないので、最先端の情報などは探しにくいです(事件を起こせばものの数時間で検索汚染は始まるが…)。そこで、リアルタイムな情報に最適なソーシャルメディアがあります。

3.Twitter

みんな大好き青い鳥です。

Tweet自体は140字以内なので情報量としては少ないですが、分野の有力者の呟きや、勉強会の様子などを見ると最最新な情報を手に入れることができます。Twitterでコミュニティを形成している所も少なくないので、チェックないしは参加すると割と有益です(僕もXamarinをやるときに #JXUG さんによくお世話になってました)。

アカウントを持っていない人(作れ)や、多少細かい検索がしたい人はYahoo!リアルタイム検索(https://search.yahoo.co.jp/realtime)もおすすめです(ユーザー名を検索結果から除外してくれたりするらしい)。

あとTwitterにも一応検索演算子はあるらしいです。

https://developer.twitter.com/en/docs/tweets/search/guides/standard-operators

4. 公式ドキュメントを読む

これが真理です。真面目な開発元であれば公式ドキュメントを読むだけでほとんどが解決されます。慣れないうちはQiitaとかに落ちている誰かが噛み砕いてくれた記事でも良いですが、ググって公式が引っかかったら積極的にこっちを見るようにしましょう。OSSであればGitHubのREADMEかIssueに大切なことが上がっているので参照するとよいと思います。

公式ではなくとも自分がある程度信用できるサイトを予め知っておく(低質なサイトを除去する)ことも大切です。検索結果を吟味することで精度もぐっとあがります。

5.自分で書く

ネットの海をいくら彷徨っても見つからない?それは非常にラッキーなことですよ。もし解決策を貴方が見つけられれば唯一の情報源になれるんです!!ということで解決したらコミュニティへの貢献、そして同じ悩みを持つ人々(未来の自分を含む)のために記事を投稿しましょう。既に解決策が載っているものであっても、環境など異なる場合有用なので、積極的に投稿していきましょう(流石に丸写しで動いた程度だと意味ない気はするが)。

この項の詳細については、こちらで書いてあるので良ければ一読をお願いします(ロ技研ADCもよろしくね!)。

おまけ1: おすすめ拡張機能(Chrome)

Chromium以外はお帰りください。

uBlock Origin

有名広告ブロックアドオン。かなり精度が良い。サイト毎に有効/無効を設定できる。低俗な広告による精神攻撃を防げる。

検索の利便性のためには多少の犠牲は必要なのだ(Googleは広告で生きてる会社なのでブロックするのは程々にしようね!)

ゴシップサイトブロッカー

特定のドメインを検索結果から消す。c●deday.meなどのコピペ機械翻訳QAサイト、●エンジニア塾のような信頼性の低いサイトなどを踏むことによる精神攻撃を防げる。

便利。

おまけ2: 情報の信頼性について

以下は割と主観的な主張なので読み飛ばしてもいいです。

 

上は主に、目的となる情報への到達手段についての話でした。しかし、辿り着いた情報が必ずしも信頼できるとは限りません。幸いにもプログラミング界隈については信用できる情報が多く(騙す必要もあまりないし、実行すればすぐ分かる)、惑わされることはほとんどありません(バージョン違いなどでそのままだと動かないことはよくある)。ただインターネット上には間違った情報/意図的に人を騙そうとした情報が無数に存在します。その辺りのフィルタリングについて少しお話します。

1. 伝聞調・2次ソース以下は信用に値しない

よく検索に引っかかるのが、「今回、〇〇が☓☓と報道していました」や、他のサイトからそのまま文章を引っ張ってきた記事です。あくまで伝聞調であるためそのサイト/会社自身が情報ソースへの責任をあまり持っていない印象です。例え有名新聞社でも個人ブログでも2次ソース以下である場合は1次ソースを確認しましょう。面倒ならその話題は話半分に留めておくべきです。

2. 中身を読め

見出しは話題によってはただの煽りなので、本文を読みましょう。

 

とりあえずはそんなところです。

←4日目 | 6日目→

「Twinkle Stars」の修辞学的考察【前編】

この記事は、KCS AdventCalendar2019 3日目の記事です。

←2日目 4日目→

 

こんにちは。KCS音楽班のRinjuです。この記事では、「映画スター☆トゥインクルプリキュア 星のうたに想いをこめて」の挿入歌および主題歌である「Twinkle Stars」(作詞:大森祥子さん、作曲・編曲:高木洋さん)を修辞学的に考察します。音楽理論の話はしないので、音楽班以外の人にとっても面白く読んでもらえるのではないでしょうか。よろしくお願いします。

まずは題材曲を紹介します。

Twinkle Stars(TVED ver.)

余談ですが、イントロとアウトロをED用に作り、重要なメロディを抜くことで、映画で観るまでは普通の曲(言うまでもなく良い曲)に聴こえるようにしているのがスゴイと思います。

本記事で扱うのは上記Short ver.ではなくフルver.なので、この記事を読んで気になった人は音源を買うか、僕からCDを借りるかしてください。

原理

物語と音楽の繋がりと言えば、古きに目を向ければ古代ギリシャの劇(ドラーマ)まで遡れるのではないでしょうか。僕はそこら辺は未履修なので、現在履修中のバロック音楽(オペラ)の理屈で以って当該曲を考察します。しかしながら、「Twinkle Stars」作曲者の高木洋氏は音楽大学出身で、「ルパンレンジャーVSパトレンジャー」OPにて対位法による作曲を披露している(対位法はバロック時代に発達した作曲法です)ので、この仕方で得られる考察はまあまあ的を射ている可能性がなくもなくもなくもないかなと思います。

注目したいのは、「フィグーラ(音楽的修辞)」です。フィグーラとは、表現したいことを伝えるために用いられる特別な音の使い方を意味します。死を表現するときには音を下降させ、気持ちの悲痛さを伝えるために敢えて不協和音を鳴らす、といったことです。

なお、本記事で扱うフィグーラはバロック音楽に見られるそれと必ずしも同一ではなく、あくまでその考え方に当てはまる事柄をまとめたものです。バロックのフィグーラに興味がありましたら、一般教養科目の音楽を履修してください。先生の名前は、こういう場で言っていいかわからないので、リアルで聞かれたら答えます。また、この記事に書かれている内容は完全に僕の主張であって、今回の考察が見当違いだったとしてもそれは僕が勉強不足なだけということをここにことわっておきます。

以上をまとめると、「Twinkle Stars」に使われているフィグーラを発見し考察するのが、本記事の主題です。

 1.構成

「Twinkle Stars」は映画の内容に従った曲構成をしています。

まず、「Twinkle Stars」が劇中で歌われるに至る物語を書きます。

星の子ユーマは、成長して星になる生き物です。終盤、敵の強烈な悪意を受けて、ユーマは黒く禍々しい星になってしまいました。プリキュア(ひかる:キュアスター、ララ:キュアミルキー)はユーマを救うために、星の中に入っていきます。

星は、ユーマがひかる、ララ、フワ(妖精キャラ)と一緒に見たものの記憶で出来ていました。二人は星から雷を受けて、変身が解け、星のコアに落ちていきます。

海の中で、以前ユーマが混乱したときに「ながれぼしのうた」(劇中に登場するきらきら星に似た童謡)を歌ってあげたら落ち着いたことを思い出したララは、同じように「ながれぼしのうた」を歌います。ひかるがそれに続くと、どこからかユーマの声が聞こえてきました。二人は歌い続けます。そうして「Twinkle Stars」が始まります。

CD音源を聴くと、「Twinkle Stars」が、この曲が歌われた文脈までも内包していることに気が付きます。つまり、「Twinkle Stars」は「ながれぼしのうた」が歌われるところから始まります。

以降、物語に応じた曲展開・メロディが見られます。

構成をまとめます。

「ながれぼしのうた」(ハ長調(:C)→ニ長調(:D))

「Twinkle Stars」1番(ヘ長調(:F)→変ロ長調(Bb)→ト長調(:G))

「Twinkle Stars」2番(ト長調(:G))

「Twinkle Stars」Cメロ、Dメロ、Eメロ(ト長調) ※ラスサビはない(!)

この構成は、物語によって説明されます。1番ではひかるとララが変身し、2番ではユーマがプリキュアに気付き、その後は星の生まれ変わりを描いています。詳しくは以降で説明します。

作曲法はフィルムスコアリング(映像が先にあって音を付ける手法)ではありませんが、田中裕太監督、脚本の田中仁氏の考えに基づいて高木洋氏が映画と同時進行で作られたそうですので[1][2]、物語との結びつきの強さには説得力があります。

2.主旋律に散りばめられた律動

ベートーベンはバロックの作曲家ではありませんが、「運命」のダダダダーン!が、運命が扉を叩く音だというのはよく知られた話だと思います。

それに似た話をします。

ここに心音のリズムとでも呼ぶべきリズムがあります。

心音を模したリズム

図1 心音のリズム1

※図1はNotionというソフトウェアで作りました。今日初めて使ったので左端の謎休符コンボとか右端の黄色い長方形とかは是非温かい目でスルーしてください。

ド・クン、ド・クン…というリズムです。図1では、「ド」を弱拍に、「クン」を強拍に置く形で書いています。

これが用いられている曲としては、高取ヒデアキさん作曲「Alright! ハートキャッチプリキュア!」、Revoさん作曲「心臓を捧げよ!」が挙げられます(いずれもサビ)。

Alright! ハートキャッチプリキュア!(2:53~)

心臓を捧げよ!(5:32~)

TVの方のスター☆トゥインクルプリキュアでもこのリズムは登場しています。プルンスの推し・マオの歌「コズミック☆ミステリー☆ガール」(渡辺剛さん作曲)です。「盗んだハートは大切なコレクション」等と言った箇所です。恋して胸がドキドキ、ということでしょうか。

さて、Twinkle Starsのサビではこの心音のリズムが用いられています。

高木洋氏本人が書いた楽譜は、サビ冒頭のみ映画コメント色紙にて確認できました[3]ので、図2ではそれに基づいて楽譜を書きました。

心音を模したリズム

Twinkle Stars「わたしたちは星」

図2 Twinkle Starsに見られる心音のリズム1

煩雑さを避けるために約2小節分だけ書いていますが、この後は繰り返しなので結局心音のリズムが続きます。楽譜で確認しなくても、歌ってみればそれが同じリズムだとわかると思います。

次に、心音のリズムを1.5拍後ろにずらします。

心音のリズム2

図3 心音のリズム2

クン、ドクン、ドクン…という感じですね。これはTwinkle Stars Aメロ、「「わくわく」はどこから来るの? ときめく想いが連れてくる」の箇所等で部分的に使われています。初めに置いた「Twinkle Stars」の動画で、キュアスターが胸の高鳴りをジェスチャーで表現しながら「わくわく」と歌っているのがわかると思います。

さらに、心音のリズム1を0.5拍前にずらします。

心音のリズム3 (2)

図4 心音のリズム3

ド(強拍)クン(弱拍)、ドクン、…という感じです。

これはTwinkle Stars Cメロの「遥かなプレゼント きみとの記憶が 未来で希望、力になる」等の箇所で部分的に用いられています。

このように、Twinkle Starsには心音のリズムが散りばめられています。

ユーマというキャラクターは、「星もまた生き物である」ことを体現しています。星と「わたしたち」を結ぶモチーフとして、命を表現しようとして心音を用いたのだと僕は考えています。また、ユーマたちは劇中で地球の秘境巡りをしますが、その中には地球の心臓であるところのコアに繋がるヤスール火山もあります[4]。脚本の田中仁氏は、美しい大自然を巡る中であえて危険な火山を選んだことについて、

マグマの下には地球のコアがある。ユーマ自身も実は星のコアなので「同じ属性のものが直接触れ合える場所」という意味も込めてセッティングしました。[5]

と述べています。「ながれぼしのうた」を歌う前にひかるとララが落ちていくのはまさに星のコア(ヤスール火山の記憶)でした。そうして、Twinkle Starsが歌われたのは星の中心にあるオルゴールでした[6]。それが歌われる物語的意味から考えても、またそれが歌われる場所から考えても、Twinkle Starsで心音のリズムを使うのは最適で、最高に物語に寄り添った選択だったと思います。

これは感想ですが、星と「わたしたち」が同じだという歌で、断定形の歌詞が多い中で、Cメロの「きみも同じだといいな」が祈るような言い方なのが泣ける。ユーマとはいつかは会えるのだろうけれどユーマが「今」どう感じているかは想像して、そうだといいなと思うしかないんですね。でもその気持ちは弱くなくて、そうだよねって信じている。メロディで「同じだ」歌詞で「同じだといいな」って…………

次回予告

この曲については、現状あと4つ扱うべき事項があるんですが……。今回のように楽譜を作る必要があるのはあと1つだけなので、後編に回しても労力的には問題ないと思います。

「Twinkle Stars」には、フルにはあるがTV ED版にはない音色があります(実は映像にもあります)。フルにだけ入っている音を抽出してLINEに投げてみました。具体的には、TV ED版の位相を逆にして、ノイズキャンセルの要領でフルからTV ED版と同じ音を消して再生した動画を送りました。その際の反応がこちらです。

Reaction

日吉代表supercellくんは、いったい何が「「言葉」でなく「心」で理解できた!」のか? 続きは12月6日(金)のアドベントカレンダーにて。乞うご期待!

参考文献

[1]コミックナタリー 映画「スタプリ」ユーマの声を担当したのは…田中裕太監督らが制作秘話明かす

[2]アニメージュ スター☆トゥインクルプリキュア特別増刊号46ページ

[3]Twitter_映画スター☆トゥインクルプリキュア

[4]「映画スター☆トゥインクルプリキュア 星のうたに想いをこめて」パンフレット

[5]アニメージュ スター☆トゥインクルプリキュア特別増刊号47ページ

[6]アニメージュ スター☆トゥインクルプリキュア特別増刊号42ページ

←2日目 4日目→

一年を振り返る

これはKCS AdventCalendar2019 2日目の記事です。”2日目”の記事です。

 

こんにちは、2019年の日吉代表のsupercellです。さて、今年も色々と限界な一年でしたね。ということで、この記事では一年を振り返っていきたいと思います!!!!!

 

4月

  • 新歓でKCSちゃんのショーを披露。新歓担当、手伝ってくださった先輩方に圧倒的感謝。
  • 技術書典6に参加。某先輩には大変お世話になりました。また、風邪をひきながらも命を燃やして参加した某、途中から参加してくれた某に圧倒的感謝。

D4E71fzUIAAuNyM

  • web班、Unity班、AI班、DTM班、(Blender班)に分かれ活動開始。Unity班、AI班はAICの活動の一環として活動。
  • ソファ、デスクトップ、椅子、机、スピーカーを買い替えることに。

5月

  • 新歓合宿を実施、湯河原へ。多くの一年生が参加してくれたので圧倒的感謝。
  • DMMLT会を開催。開催してくださった先輩とDMMの方々に圧倒的感謝。

6月

  • 中間試験・・・

7月

  • 期末試験・・・

8月

  • 第二回総会実施。
  • 技術交流会実施。私は不参加でした、申し訳ありません。

9月

  • 夏合宿を実施。去年と同じく土善旅館へ。やはり開発には最適な環境だった。参加者には圧倒的感謝。
  • ついにデスクトップを買おうと動き出す。
  • Wi-Fiを止められる。(え?)

10月

  • ルーターはだめで有線でしか利用できなかったため、Wi-Fiを契約しようという流れに。
  • 限 界 矢 上 祭。展示しようと頑張ってくれた方々に圧倒的感謝。特に矢上祭担当に圧倒的感謝。
  • M3に参加。DTM班の方々に圧倒的感謝。

EH2hW1UUcAAilh7

11月

  • ルーターが届く。Wi-Fiが復活。会計担当には感謝しかありません。
  • 三田祭に参加。一年生が積極的に展示に参加してくれて圧倒的感謝。例によって三田祭担当にお世話になりました。EJ3U9kZU8AII8dNEJ3U9rMUcAE5s-d

 

以上が振り返りとなります。案外書いてみるとあっけないですね。急遽この記事を書くことになり低クオリティですが見てくださった読者の皆様に圧倒的感謝。また、サークル活動に関わってくださった方々に感謝します。

 

1日目 3日目

KCS × DMM.com 合同LTレポート

こんにちは.mo-takusanです.

今回は先日DMM.comさんとコラボして開催したLT会についてまとめたいと思います.
当日の様子のみが気になる方は「会の様子」まで飛んでいただければと思います.

投稿遅くなり申し訳ありません...

※(追記)
DMM.comさんの方でも記事が公開されたのでリンクを貼っておきます!
https://inside.dmm.com/entry/2019/05/22/kcs-dmm-lt

事の発端

今回のイベントは2月の中旬ごろDMM.comさんの会社にお邪魔させて頂いたことがきっかけでした.
DMM.comさんが度々外部との合同LT会をされているとのことで,KCSともLT会をして頂けないかとお尋ねしたところ快く引き受けてくださいました!
学生のみで活動していると知見が限られてきてしまうので本当にありがたい企画でした.特に昨年までのKCSは比較的内に籠りがちだったので外部活動もしたかったのです.また時期的にも新入生へのアピールになるかと思い企画させて頂きました.

DMMさんは↓のような会場をお持ちで頑張れば100人も入れるそうです!

イベントの目的

ということで,KCS側としては次のような目的をもってLT会に参加させて頂きました.

普段の活動では得られない知見

前述のように学生のみの活動では中々得られない知見が沢山あります.特に大規模な開発や設計などは個人では中々学ぶことはできないでしょう.一人で開発するときに保守性とかあまり気にしませんよね(一部を除く).

新入生に向けたPR

これも前述のように,時期的に新入生への良いアピールするには持って来いの企画でした.やはり大学の技術サークルとなると,将来を多少は考えて入部する人も多いので,こうした活動は毎年開催し,将来につながるようなサークルにしたいものです.

現場の方と触れあうことによるモチベーション向上

これは現役生に向けたものです.上で述べたように入部する際には将来について多少なりとも考えている人が多いと思いますが,入部して技術を学ぶことでどのように活かせるのかは想像がついていないと思います.そこで,実際に現場で活躍されている方とお話しすることで自分がやっている活動がどのように実を結ぶのか見え,やる気にもつながると考えました.

アウトプットの機会を増やす

これはKCSの技術向上のために建てた目的です.一昨年,昨年にかけてKCSはほとんどLT会を開催せず,アウトプットの機会はほとんど三田祭に限られていました.さらに三田祭は比較的受けの良いゲームなどに限られてくるため,結局一部の人しか参加できないような状況になっていました.そうなるとKCSの活動を通して技術力が向上するのではなく,それぞれがインターンなどに勝手に参加することで個人的に技術力が向上していく,という構図になってしまいます.この構図はサークルとしては明らかに不健全だったので今年は打開するぞ,という気持ちでした.

当日のタイムテーブル

当日のタイムテーブルに関してもDMM.comさんから提示して頂きました.

時間 内容
18:20~18:30 諭吉像前集合
18:36~19:07 移動(日吉駅発,六本木一丁目駅着)
19:30~19:35 乾杯
19:35~19:45 LT① DMM WEBエンジニア
19:45~19:55 LT② DMM アプリエンジニア
19:55~20:05 LT③ DMM ゲームエンジニア
20:05~20:15 LT④ DMM AIエンジニア
20:15~20:20 休憩
20:20~20:30 LT⑤ KCS 新歓パフォーマンス2019報告 
20:30~20:40 LT⑥ KCS 機械学習初歩
20:40~20:50 LT⑦ KCS Penmarkについて
20:50~21:00 LT⑧ KCS ZFSを使おう
21:00~22:00 懇親会

会の様子

当日はこんな感じで順番に次々と発表をしていく形でした.DMMの方々はさすがに発表に慣れた様子で聴講者を引き付けるのが本当に上手いなと感じました.大規模開発のお話やサービスの裏側のお話等非常に興味深い内容でした.
KCS側は2年生を中心にして発表をしてもらいました.緊張した様子でしたが,内容は面白かったです.(最近後輩の意欲と技術力本当にすごい…!)詳しくはLT資料を下に載せているのでご覧ください.

47580

懇親会の様子です.ピザとオードブルごちそうさまでした!

47580

47580

Twitterハッシュタグで盛り上がる

発表中は「#kcs_dmm」のハッシュタグを用いてそれぞれつぶやきながら聞きました.各々の感想を言い合いながら聴講できたので,より参加している感を味わえました.
以下にモーメントとして内容をまとめたのでご参考までにどうぞ.

LT資料

KCSメンバーの資料については公開できそうなのでここに載せておきます.

反省点

概ね会はうまくいきましたがいくつか反省点があったのでここに纏めておきます.

  • 登壇者を張り切って募集しすぎた
  • 新入生歓迎会で全く宣伝できなかった
  • LT時間を交代込みであることを伝えるべきであった

一つ目は単に僕が声をかけすぎたためです.今回は枠が少なかった上に時間もかつかつだったので人数はぴったりになるように声をかけるべきでした.
二つ目は結構致命的でした.新入生に向けたPRとは何だったのか….新歓期間はそもそも僕が参加できなかったので,せめてTwitterで告知しておくべきでした.
三つ目は時間がないのは初めから分かっていたのでそのように伝えるべきでした.

謝辞今後の期待

DMM.comさん,会場から懇親から準備から何から何まで用意をして頂き誠に有難うございました.おかげさまで大変有意義な時間を過ごすことができました.
KCSの活動は比較的春学期に集中する傾向にあり,秋学期以降もわちゃわちゃした活動をしていきたいので9~10月くらいにまた企画したいと思いますので是非参加お願いします!

RadeonRaysを使ってみた2:Instancing編

前回の記事:RadeonRaysを使ってみた

 

どうも,チョコです.OBになりました.

前回は,手軽にレイトレ―シングができるRadeonRays(以下RR)というライブラリを紹介しました.そこで,同じオブジェクト(玉としましょう)をたくさんシーンに入れようとすると,オブジェクトを複製しなければなりませんでした.メモリに不親切ですね.

さて,RRのAPIを見ると,このようなものがありますね.

どうやら,同じオブジェクトを重複に使用できるんですね.使用例を探してみましょう.

 

うん,ない.

 

マジで.RRを使ったサンプルレンダラーのBaikalのコードですら,CreateInstanceをヒットしなかった(あったら教えてください).

仕方ないですね.この2行のコメントを元に実装してみましょう.

とりあえず,玉を2つ書くコードを考えましょう.まず,玉のShapeを作って,APIに渡します.次に,CreateInstanceはShapeを複製してそうなので,このShapeを渡します.出てきたものを少しOffsetを与えてAPIに渡します.

これを前回のようにレンダーすると...

Screenshot (571)

おおお,玉が2つになりましたね.いいですね.

が,これはよく見るとおかしいですね.

Screenshot (571) - Copy

反射が足りないですね.

...

とりあえず,玉の表面位置を色にしてみましょう.

Screenshot (572)

なるほど.Instanceになっていると,位置は元のオブジェクトのままですね.つまり自分で変換しろと.

さて,変換するにはInstanceIDが必要ですが,RRが提供しているIntersectionの構造体を見てみましょう.

なるほど.すべて解けましたね.確認のため,この値を(2で割って)色にしてみましょう.

Screenshot (573)

当たりですね.では,すべてのオブジェクトの変換行列をkernelに渡しましょう.

そして,CLのほうで:

これで実行してみましょう.

Screenshot (576)

いいですね.ちゃんと反射するようになりましたね.

これで終わりなので,確認のために100コの玉で例の画像を作ってみましょう.

Screenshot (577)

(フルサイズで見ましょう)

きれいですね.では.

情報(工学)科の授業は教養ですらないという話 – 慶應義塾大学編

この記事はKCS Advent Calendar 25日目の記事です。

こんにちは、mt_caretです。最終日です。1お疲れ様でした。

情報科の授業は教養に過ぎないという話 – 東京工業大学附属科学技術高校編 — yosida95

自分がまだ高校生の時にこのブログ記事が大変話題になり、この記事や派生記事が大変印象に残りました。自分もついに学部3年になり、研究室も決まったので、そろそろ自分の大学や情報(工学)科に関する所感を述べます。不満だけ述べても生産的でないので、どうすれば良くなると思うかについても少し言及します。

TL;DR

  • カリキュラムが合わなかった(特に専門講義はかなり期待はずれだった)
  • 体系的な、幅広い範囲の情報科学教育(i.e. 教養)を期待しないほうがよい
  • 独学できる人ならSFCは悪くないのではないか

=> 進学先を間違えた

自分について

まずは軽く自己紹介をしようと思います。慶應義塾大学理工学部情報工学科に所属しています。

中学・高校ではロボコンや情報セキュリティに取り組んでおり、 CombGigを始めとする、CombConfと同じテーマの勉強会を開いたりしていました。その過程で、自分がやっていることはものづくりを趣味でやる範囲を出ていないことを痛感し、興味のない科目を学ぶことを強制されることなく、体系的に情報科学の様々な分野を学びたいと思い、大学に大変期待をしていました。

入学まで

興味のない分野の勉強に上手く打ち込むことができず入試に落ち、慶應義塾大学に進むことに。経済学部・環境情報学部・理工学部の3つに受かったため、情報科学を一番学べそうな理工学部に入ることにしました。

学門制 | 慶應義塾大学理工学部

ようこそ、学びの庭への 入口 [学門]へ! – 慶應義塾大学理工学部

慶應義塾大学には学門という概念があり、理工学部の入試の時点で学門1~5のどれかに入り、学部2年に進むタイミングで成績ベースで学科振り分けがされます。自分は情報工学科の定員が最も多い学門5を選びました。

B1

この学門制度にはいくつな不思議な点があります。

例えば、学門関係なく理工学部生は全員「基礎教育科目」という名目で数学・物理・化学や自然科学実験という物理と化学に関する実験を行う科目を履修することが強いられています。成績が悪いと希望しない学科に配属される可能性があるため、必死に取り組む必要があります。これが自分にとって予想以上に苦痛で、何故やる必要があるのか理解できないまま、情報科学を学ぶ権利を得るために、高校の時と同じように情報科学と一切関係のない分野の勉強や課題に取り組んでいました。

また、学門に関するサイトに

入学後、自分の興味や関心に応じて徐々に学びたい分野を絞っていき、2年進級時に所属する学科を決定します。

とありますが、自分の入学後、自分の興味や関心に応じて徐々に学びたい分野を絞っていった結果進みたい学科の枠が自分の学門に無い場合、「学門越え」が必要になりますが、理工学部全体で1学年1000人居る中許可されのは数人程度なので非常に難しいです

余談ですが、情報科学を学んだりプログラミング言語を学んだりする講義は理工学部の 1年の時は普通の選択科目としては用意されていません。例えば経済学部にはあるようだという話は聞いています。

B2

なんとか情報工学科に配属され、おお喜びです。これでやっと情報科学が学べるぞ!と思いきや、薄々感じていた違和感がより強く現れます。情報技術の話が通じる人が周りにいません。講義でもプログラミングはおろかパソコンを触ったことのない人を想定して進み、いくつかの講義を除き全て紙に鉛筆で進みます。

2年の時はC言語を学びます。2同期の多くはプログラミングをしたことがないため初めて学ぶプログラミング言語となりますが、3 純粋に文法と簡単な演習問題をやるだけなので、例えばポインタを理解していなくてもなんとかなりそうな感じでした。

コンピュータグラフィックスを専門とされている先生がアルゴリズムの講義を教え、4 ところどころテクニカルタームを誤用なさったり、最も実の有る講義と感じたラムダ計算とアルゴリズムのための離散数学の講義はそれぞれ文学部と数理科学科の先生によるものだったりと全体的に教員不足を感じました。アルゴリズムと言語処理系が専門の情報工学科の先生が欲しかったです。

また、講義を受けるための必修科目(prerequisites)、という概念がなくどの講義も事前知識を仮定されてないためか、例えばフーリエ変換やOSI参照モデルを別々の講義で複数回やり、カリキュラムの構成に違和感がありました。

B3

Cを1年かけて学んだ(?)次はJavaを学びます。5

3年の前期の後半は香港の企業でのインターンシップをやっていたため、限られた数の講義しか受けることができていませんが、3年になると4年の講義を履修することができることもあり、履修した範囲では流石に2年の講義と比べてもう少し深い内容になっている気がします。

しかし、米大などでは Captstone course6として位置付けられているコンパイラやOSの講義が後期週1コマに詰め込まれており、例えば計算理論の講義でDFAをゆっくり学ぶのと並列してコンパイラの講義でレキサ・パーサの文脈でDFAを軽く教わるといったような状況になり、やはりカリキュラムの構成が微妙だと感じました。

また、計算理論の講義ではAutomata Theory, Languages, and Computationをテキストとして進めますが、学生には難しいということでチューリングマシンの章まではやりません。なので、チューリングマシンを扱わず情報工学科の学位を得ることができます。余談ですが、同じ理工学部の数理科学科ではチューリングマシンまで含めて学ぶ計算理論の講義があるそうです。

こういったものを経て現在に至ります。研究室配属に関しても様々な話がありますが、話の本筋である情報科学教育から外れますので割愛します。

不満

  • 講義1つ1つが軽く、深いレベルの理解につながるような手を動かす課題を出す講義が非常に少ない
  • カリキュラム全体に統一感が無く、情報科学の中でも通信に偏っている
  • 同期に情報技術に取り組んできた人がとても少ない

良い点

  • G Suite・Google Drive無制限・Office 365あたりの福利厚生

結論

結論としては、

講義を通しては体系的な学習はできず、学部3年間は結構大きい機会損失だった

という風に考えています。カリキュラムについて良く調べ、事前に本質を見抜くべきでした。

申し送り

機会損失を減らす方向で、自分みたいな人に向けて書きます。

慶應義塾大学理工学部の受験を考えている人向け

  • 情報科学を学びたいなら、数理科学科がオススメです
  • 独学ができるなら、情報工学科と比べ必修科目が少なく自由時間が多い7 環境情報学部は悪くない選択肢だと思います

理工学部1年向け

  • 環境情報学部への転学部は比較的簡単らしい
  • KCSやロボット技術研究会といったサークルに入ったりし、探しに行くと大変優秀な人は一定数いる

情報工学科n年向け

  • ご愁傷さまです
  • n = 1くらいなら1年+αは埋没費用としてあきらめて大学の再受験は選択肢の1つだと思います
  • 過去n年は埋没費用として諦めて、残りのの4-n年の学費で学位を購入する気持ちで取り組みましょう。
    • ちゃんと取り組むと機会損失が増えるので講義・課題は最低限の手間を掛けて後は独学をがんばりましょう
  • 外の世界を見ましょう
    • 勉強会での発表は良い経験になります
    • インターンはよい経験になるだけではなく、職にも繋がります

免責

なお、このブログエントリを真に受けた事によって生じた利益や不利益について私はもちろんあなたの周囲の誰も責任を取りません。 自分の進路における決定はすべて自分の責任の下に行なわれるべきです。 しかし、無責任な周囲による無責任な意見を積極的に聞いて自分自身で咀嚼した方がお得です。 あなたは自身が想像している以上に視野狭窄です。 周囲の意見を聞くことで、自分だけでは考えつかなかった選択肢がいくつも出現して裏ステージへ進める可能性が高まります。
私自身がひどい視野狭窄に陥っている可能性が高いので、周囲の意見を聞こうという自戒です。 よろしければ、このエントリや私の考え方についてご意見や反論などをください。
(情報科の授業は教養に過ぎないという話 – 東京工業大学附属科学技術高校編 — yosida95より)

完全にこれです。是非意見・反論をください。

謝辞

事前に読み、フィードバックを送ってくれた皆さん、ありがとうございました。


  1. 遅刻しました。ごめんなさい。

  2. サンプルコードの文法が間違っているためそのままではコンパイルが通らないことが多々あったことが印象に残っています。また、課題の出力フォーマットが曖昧な上に手動で採点が行われているため、提出されたコードは目視で確認し採点する時がある、といったようなことをTAの方から聞いた記憶があります。既存のオンラインジャッジでもよいので、(可能であればオンラインの)自動的な採点システムが欲しかったです。

  3. C自体情報科学をやる上で必須だと思いますが、初めて学ぶ上でつまづきやすい、本質的でない部分が多いような気がしてなりません。SchemeやPythonあたりでSICPをやるぐらいが丁度よいかなと思いました。

  4. 線形探索に一時間半の講義を丸々掛けていたのが印象に残っています。

  5. E.W.Dijkstra Archive: To the Budget Council (concerning Haskell)
    余談ですが、環境情報学部ではプログラミングの講義として上級者向けにHaskellを学ぶ選択肢があるようです。

  6. こういった講義の存在は日本の大学では聞いたことがありません。東大のCPU実験あたりが該当するのでしょうか?

  7. 諸説あるようです。

Marloコンペ用の強化学習環境をサーバーに立てた話(おまけ:Google ColabでDQN)

はじめに

こんにちは、syuntoku14です。現在カリフォルニアでスマブラしてます。イカちゃん強いね。

 

スマブラのせいで時間がなくなってしまったので、本記事ではDavisで作成した無についてしゃべります。

 

皆さんMarloコンペというのをご存知ですか?OpenAIが主催しているMinecraft環境での強化学習の大会で、入賞するとカナダに行けたりするすごいやつです(もう終わっちゃいましたが、来年もあると思います)。

 

MarloコンペのチームにDavisで参加し、私は環境構築を担当したわけなんですが、この環境構築が鬼めんどくさかったのでスクリプト化しました。

 

一応公式ページにインストール方法などは書いてあるんですが、Minecraft環境非常に不親切で、ウィンドウがある環境でないと動きません。このままではGoogle Cloudなどクラウド上で学習させることが出来ません。困りましたね。

 

 やったこと

 

xvfbを使って仮想ウィンドウを作成し、Marloを走らせました。が、これだけではなぜか動かなかったので(OpenGL周りが原因?)、最終的に公式が配布しているDockerファイルを弄くり、中にあるlaunchClient.shをxvfb付きで実行したら動きました。

 

最終的に出来上がったDocker imageがこれです:

 

以下のコマンドで任意のポートにつなげて実行できます。

 

“`
docker run -it –rm -p [number of port]:10000 syuntoku/marlo_client
“`

 

ここまで自力で頑張ったあとで、これDocker Hubに既に存在していることに気がついてしまいました。圧倒的車輪の再発明だったんですね(悲しいね)。まあDockerについての知識が微妙についたので良いんじゃないでしょうか。

 

あとはこれをdocker-composeと–scaleオプションで並列化させて実行するだけです。(スクリプトにしました)

 

クラウド上で利用するにはDockerやCUDA、Anacondaのインストールもやらないといけないので、これもスクリプトにしました。

 

できたもの

Github:

https://github.com/syuntoku14/marlo_headless

使い方は一応READMEに書いてあります。

 

手順:
1. AWSでもGoogle Cloudでも何でも良いが、Ubuntu18.04環境を立ちあげる。
2. Jupyterの設定も勝手にしするので(ポート5000)、各クラウドのブラウザから5000番ポートを開けとく
2. 中でgit clone https://github.com/syuntoku14/marlo_headless.git
3. . ./marlo_headless/install/gcp/install.bash
4. . ./marlo_headless/docker/launch_multi_client.sh [number of environment]

 

私はVimmerなので、Jupyter-notebookのvim extensionをセットアップするスクリプトなども別でついてます。

 

肝心の学習ですが、まだやっていないです(無能)。学習させたらまた記事を書きます。おちまい。

 

おまけ

 

Courseraの課題でDQNを実装してGoogle Colab上で動かしました。

 

Gist:

 

先ほど紹介したMarlo用のスクリプトはついでにgym環境もインストールするので、上記のgistを参考にして適当にやればGoogle Cloudで簡単にAtariの学習も出来ます。やったね。

 

Algebraic Effects for Rust

Algebraic Effects for Rust

この記事はKCS Advent Calender 18日目の記事です!
Algebraic Effectsが最近話題ですね!自分は普段Rustというプログラミング言語を使っているのですが,残念ながら(?)Algebraic Effectsの言語レベルサポートはありません.無ければ作るとも言いますし,AEをサポートするライブラリを作ってみたので紹介します.

Algebraic Effectsとは?

自分も良く分かりません.教えてください.

「継続がとれる例外」らしいですね.

どうやって実装したの?

びしょ〜じょさんの記事によると,コルーチンを使うとAEの実装ができるようです.ちょうどRustにはasync/awaitサポートのためにコルーチンが今年入ったので,それを使えば実装できそうですね.詳しい実装方法は次のコミケ(30日日曜日です!)の冊子にこれから書く書いたのでそちらを参考にしてください!

はじめてのAlgebraic Effects

以下で登場するコードはhttps://github.com/pandaman64/hello-effからもダウンロードすることができます.

まずはRustを入手します.新しい機能を利用しているので(特にunsized_locals)最新のNightlyビルドが必要です.

$ rustup update
$ rustup toolchain install nightly

それが済んだら新しいプロジェクトを作りましょう.

$ cargo new hello-eff
$ cd hello-eff

Cargo.tomlのdependenciesに次の行を追加します.まだcrates.ioにはアップロードしていないのでGitHubのURLを書いています.

eff = { git = "https://github.com/pandaman64/effective-rust.git" }

それではmain.rsを下のように書いていきましょう.

#![feature(generators)]

use eff::*;

struct Hello;
impl Effect for Hello {
    type Output = String;
}

struct World;
impl Effect for World {
    type Output = String;
}

fn main() {
    let with_effect = eff! {
        let hello = perform!(Hello);
        let world = perform!(World);

        format!("{} {}!", hello, world);
    };

    run(with_effect, |x| println!("{}", x), handler! {
        H @ Hello[_] => {
            resume!("Hello".into());
        },
        W @ World[_] => {
            resume!("World".into());
        }
    });
}

これをcargo runで実行すると

Hello, World!

と表示されることでしょう.

これは一体何が起きているのでしょうか.
コードを一行一行見ていきましょう.

#![feature(generators)]

これは,このモジュールではジェネレータを使うという宣言です.ジェネレータとはコルーチンのRustでの名称です.Rustでは実験的な機能は明示的にオプトインしなければ使うことができません(feature gateと呼びます).このライブラリはジェネレータをフルに活用しているので,この宣言が必要です.

use eff::*;

次の行はライブラリのインポートです.自分が書いたAEライブラリはeffという名前で公開されているので,eff::*と書くことによって後ろのeff!handlehandler!といった関数・マクロをインポートします.

さて,この後に続くのがエフェクトの宣言です.

struct Hello;
impl Effect for Hello {
    type Output = String;
}

ここでは,Helloという名のエフェクトを宣言しています.effではエフェクトの宣言はEffectトレイトを実装することで行います.Effectトレイトの実装にはOutput型を指定する必要があり,Outputはこのエフェクトが解決したときにどの型の値になるかに相当します.

Worldの方も同様にエフェクトの宣言がされています.

それでは,main()の中を見ていきましょう.まずは以下の部分です.

let with_effect = eff! {
    let hello = perform!(Hello);
    let world = perform!(World);

    format!("{} {}!", hello, world);
};

ここでは,eff!マクロを使ってエフェクト付きの計算を定義しています.注意してほしいのは,この時点ではまだeff!内部の計算は実行されていないということです.eff!の中では,perform!を使ってエフェクトを発動することができます.perform!式の結果は上で紹介したEffectトレイトのOutput型となります.
今回の場合はどちらもStringですね.perform!によって取得した値はformatの行のように自由に使うことができます.

eff!で定義したエフェクト付きの計算はrun関数によって実行することができます.

run(with_effect, |x| println!("{}", x), handler! {
    H @ Hello[_] => {
        resume!("Hello".into());
    },
    W @ World[_] => {
        resume!("World".into());
    }
});

run関数は
1. エフェクト付き計算
2. value handler
3. effect handler

の3つを引数にとります.1のエフェクト付き計算は上で紹介したeff!マクロで作った値です.2のvalue handlerはeff!マクロ内の最終的な計算結果を受け取ってあれこれする関数です.今回は|x| println!("{}", x)と標準出力にプリントしてますが,そのままの値が欲しい場合は|x| xとすれば良いでしょう.3のeffect handlerにエフェクトに応じて処理を行うコードを記述します.

effect handlerはhandler!マクロにハンドラを並べることで定義します.一つ一つのハンドラは

ユニークな識別子 @ エフェクトの型 [ パターン ] => 式

という文法で記述します.ハンドラを複数書くときは,カンマで区切って書きます(実装をサボっているので末尾カンマは許容されません).

エフェクトの型によってこのハンドラがどのエフェクトをハンドルするのかを指定し,ハンドルした結果がとなります.perform!に渡されたエフェクトはパターンによって束縛されます.今回の例ではHelloWorldといったエフェクトの型が重要で,値自体は不要なので_パターンによって捨てています.ユニークな識別子は実装上の都合(Rustのマクロは識別子を生成できない)で必要です.handler!内でユニークになるよう名前をつけてください.

さて,ハンドル結果のについて見ていきましょう.ここには任意の式を書くことができますが,その中でも特別に扱われるのがresume!マクロです.resume!(式)はエフェクトの発動時点(perform!の時点)から処理を再開します.このとき,perform!の結果はresume!に渡した引数に評価されます.ですので,resume!に渡す式は対応するエフェクトのOutput型の値でなければいけません.これによって,例えば実装の分離ができることでしょう.

ハンドラ内でresume!を行わない場合は,ハンドラの式の結果がrun関数の結果となります.これを使えば,例外のような大域脱出が実装できます.

また,effライブラリはハンドラのexhaustiveness checkを行います.つまり,ハンドラがエフェクト全てを網羅しているかをチェックします.試しに上のコードからWorldのハンドラを削除するとコンパイルエラーとなることでしょう(マクロの内部でエラーが発生するのでエラー自体は読んでも意味が分からないと思います...).

引数をとるエフェクト

エフェクトは引数をとることができます.どうするのかというと,Effectトレイトを実装する型にフィールドを加えるだけです.上のサンプルに下のエフェクト型を追加しましょう.

struct Ask {
    prompt: String
}
impl Effect for Ask {
    type Output = String;
}

次に,eff!部分を下のように置き換えます.Worldエフェクトの代わりにAskエフェクトをperform!するようにしました.

let with_effect = eff! {
    let hello = perform!(Hello);
    let name = perform!(Ask {
        prompt: "What's your name?".into()
    });

    format!("{} {}!", hello, name)
};

さて,扱うエフェクトの型が変わったのでハンドラも書き換えなければいけません.ここでは次のようにしました.

use std::io::{stdin, stdout, Write};
let stdin = stdin();
run(with_effect, |x| println!("{}", x), handler! {
    H @ Hello[_] => {
        resume!("Hello".into());
    },
    A @ Ask[Ask { prompt }] => {
        print!("{} ", prompt);
        stdout().flush().unwrap();

        let mut name = String::new();
        match stdin.read_line(&mut name) {
            Ok(_) => resume!(name.trim().into()),
            Err(_) => eprintln!("failed to read"),
        }
    }
});

Worldのハンドラの代わりにAskのハンドラが追加されています.Askハンドラではpromptをエフェクトから取り出した後(ここで構造体パターンが使われていることに注意),それを表示しユーザからの入力を待ちます.入力が成功した場合には,resume!によって処理を戻します(trimは末尾の改行文字を除くためです).失敗した場合にはfailed to readと標準エラーに出力して終了します.こっそりstdinをハンドラ外の環境から引っ張ってきているのにも注目してください.

error: recursion limit reached while expanding the macro

というエラーが出た場合には#![recursion_limit="128"]という行を先頭に追加してください.

制約

  • ジェネリックなハンドラ.実装上の都合でジェネリックなハンドラが宣言できません.特に不便な点は,ハンドラで参照をとることができません(参照のライフタイムが宣言できないため).
  • その他にもライフタイムの不必要な'static制約がいくつかあります.困ったときはとりあえず参照を使うのをやめてください.
    eff!のネスト.実装のアイデアはあるのでもう少しお待ちください.
  • エフェクトのうち一部だけハンドルするハンドラ.exhaustivenessとこれを両立する実装を考えているところです.型レベル黒魔術が必要かも?

以上,Rust向けAlgebraic Effectsライブラリeffの紹介でした.自分自身良くわからないままやっているので,もっと良くなるところもあると思います.質問・意見等々ある人はhttps://github.com/pandaman64/effective-rustにIssueを立てるかTwitterで@__pandaman64__までぜひメンションを飛ばしてください!

再度の宣伝ですが,KCSはC95の二日目(30日)に同人誌を頒布予定です!
自分もそちらにこのライブラリの仕組みを解説する記事を寄稿しているのでぜひそちらもご覧ください.

ZFSはいいぞ

この記事はKCS Advent Calender 17日目の記事です。

はじめに

初めまして。J科4年の @kumassy_ です。けんきうしつのサーバーの面倒を見ています。

概要

ハードディスクにはたくさんのファイルが保存されているかと思いますが、ハードディスク上にファイルを格納するための仕組みをファイルシステムといいます。世の中にはext4やxfsなどいろいろなファイルシステムがありますが、ZFSというファイルシステムがとてもよさそうだったので紹介します。

ZFSのいいところ

  • ファイルシステムにRAID機能が組み込まれている
  • 使うコマンドが2つで管理が簡単
  • スナップショットがとれる
  • パーティションの容量が動的に拡張されるため、事前にパーティションのサイズを指定しなくてよい

実際に使ってみた

CentOS7.5にハードディスクを4枚さしてRAID-Z1(RAID-5相当)を組んでみました。1枚は/と/boot用で、残りの3枚をZFSで管理します。


# ストレージプールの作成
# LVMでいうVolume Groupのようなもの
$ sudo zpool create tank raidz1 sdb sdc sdd
$ zpool list
NAME SIZE ALLOC FREE EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT
tank 16.2T 1.55M 16.2T - 0% 0% 1.00x ONLINE -

# データセット(パーティションのようなもの)の作成
# 作成すると自動的にマウントされる
$ sudo zfs create tank/storage
$ sudo zfs create tank/home
$ zfs list
NAME USED AVAIL REFER MOUNTPOINT
tank 730K 10.5T 139K /tank
tank/home 128K 10.5T 128K /tank/home
tank/storage 128K 10.5T 128K /tank/storage

# マウントポイントの変更
$ sudo zfs set mountpoint=/storage tank/storage
$ sudo zfs set mountpoint=/home tank/home

とても簡単!!データセットを作ると自動的にマウントされるので、/etc/fstabの設定すらいらないです!!!!!!

さいごに

ZFSはいいぞ。

他にもスナップショットの作成やsend/receiveによるバックアップなど試したい機能がいろいろありますが、このあたりの資料を参考にしてみてください。

  • https://chibiegg.gitbooks.io/how-to-zfs/content/index.html
  • https://qiita.com/pitekusu/items/d5e9b0e4f5c06f8f76e3
  • https://pthree.org/2012/12/17/zfs-administration-part-x-creating-filesystems/

5次元回転&投影行列

5次元空間上の座標を回転させ、更に2次元平面上に投影するという行列を以前計算しましたのでその結果を掲載致します。

数値計算ソフトに頼めば一瞬で算出してくれそうではありますが、自分は手計算で押し切ったので一種のネタとして見ていただければと思います。

式は『Gamemaker』という日本ではマイナーな2Dゲーム制作に特化した開発ソフトに準拠した(GML言語)記述となっていますが何となく読めると思います。

x,y:最終的な2次元上の座標 / global.rr : 倍率 / a~j : 10個の各回転軸に対応した回転角 / xx,yy,zz,ww,vv : 元の5次元座標 / xxx,yyy : 2次元上の中心座標 / global.p : v軸上の投影視点座標 / global.q : w軸上の投影視点座標 / global.r : z軸上の投影視点座標 (global.p,q,r → ∞ で平行投影)(degtorad() : 度数法→弧度法変換)

x = xxx + global.rr((( cos(degtorad(a))cos(degtorad(c))cos(degtorad(e))cos(degtorad(g)) + sin(degtorad(b))sin(degtorad(c))sin(degtorad(e))cos(degtorad(g)) )xx
+ ( -cos(degtorad(a))cos(degtorad(c))cos(degtorad(e))sin(degtorad(g))sin(degtorad(h)) – sin(degtorad(b))sin(degtorad(c))sin(degtorad(e))sin(degtorad(g))sin(degtorad(h)) – sin(degtorad(a))cos(degtorad(d))cos(degtorad(e))cos(degtorad(h)) – cos(degtorad(b))sin(degtorad(d))sin(degtorad(e))cos(degtorad(h)) )yy
+ ( -cos(degtorad(a))
cos(degtorad(c))cos(degtorad(e))sin(degtorad(g))cos(degtorad(h))sin(degtorad(i)) – sin(degtorad(b))sin(degtorad(c))sin(degtorad(e))sin(degtorad(g))cos(degtorad(h))sin(degtorad(i)) + sin(degtorad(a))cos(degtorad(d))cos(degtorad(e))sin(degtorad(h))sin(degtorad(i)) + cos(degtorad(b))sin(degtorad(d))sin(degtorad(e))sin(degtorad(h))sin(degtorad(i)) + sin(degtorad(a))sin(degtorad(d))cos(degtorad(e))cos(degtorad(i)) – cos(degtorad(b))cos(degtorad(d))sin(degtorad(e))cos(degtorad(i)) )zz
+ ( -cos(degtorad(a))cos(degtorad(c))cos(degtorad(e))sin(degtorad(g))cos(degtorad(h))cos(degtorad(i))sin(degtorad(j)) – sin(degtorad(b))sin(degtorad(c))sin(degtorad(e))sin(degtorad(g))cos(degtorad(h))cos(degtorad(i))sin(degtorad(j)) + sin(degtorad(a))cos(degtorad(d))cos(degtorad(e))sin(degtorad(h))cos(degtorad(i))sin(degtorad(j)) + cos(degtorad(b))sin(degtorad(d))sin(degtorad(e))sin(degtorad(h))cos(degtorad(i))sin(degtorad(j)) – sin(degtorad(a))sin(degtorad(d))cos(degtorad(e))sin(degtorad(i))sin(degtorad(j)) + cos(degtorad(b))cos(degtorad(d))sin(degtorad(e))sin(degtorad(i))sin(degtorad(j)) – cos(degtorad(a))sin(degtorad(c))cos(degtorad(e))cos(degtorad(j)) + sin(degtorad(b))cos(degtorad(c))sin(degtorad(e))cos(degtorad(j)) )ww
+ ( -cos(degtorad(a))
cos(degtorad(c))cos(degtorad(e))sin(degtorad(g))cos(degtorad(h))cos(degtorad(i))cos(degtorad(j)) – sin(degtorad(b))sin(degtorad(c))sin(degtorad(e))sin(degtorad(g))cos(degtorad(h))cos(degtorad(i))cos(degtorad(j)) + sin(degtorad(a))cos(degtorad(d))cos(degtorad(e))sin(degtorad(h))cos(degtorad(i))cos(degtorad(j)) + cos(degtorad(b))sin(degtorad(d))sin(degtorad(e))sin(degtorad(h))cos(degtorad(i))cos(degtorad(j)) – sin(degtorad(a))sin(degtorad(d))cos(degtorad(e))sin(degtorad(i))cos(degtorad(j)) + cos(degtorad(b))cos(degtorad(d))sin(degtorad(e))sin(degtorad(i))cos(degtorad(j)) + cos(degtorad(a))sin(degtorad(c))cos(degtorad(e))sin(degtorad(j)) – sin(degtorad(b))cos(degtorad(c))sin(degtorad(e))sin(degtorad(j)) )vv)
/((global.p – (( sin(degtorad(g)) )xx
+ ( cos(degtorad(g))
sin(degtorad(h)) )yy
+ ( cos(degtorad(g))
cos(degtorad(h))sin(degtorad(i)) )zz
+ ( cos(degtorad(g))cos(degtorad(h))cos(degtorad(i))sin(degtorad(j)) )ww
+ ( cos(degtorad(g))cos(degtorad(h))cos(degtorad(i))cos(degtorad(j)) )vv))(global.q – ( (( sin(degtorad(a))cos(degtorad(c))sin(degtorad(f))cos(degtorad(g)) + cos(degtorad(b))sin(degtorad(c))cos(degtorad(f))cos(degtorad(g)) )xx
+ ( -sin(degtorad(a))cos(degtorad(c))sin(degtorad(f))sin(degtorad(g))sin(degtorad(h)) – cos(degtorad(b))sin(degtorad(c))cos(degtorad(f))sin(degtorad(g))sin(degtorad(h)) + cos(degtorad(a))cos(degtorad(d))sin(degtorad(f))cos(degtorad(h)) + sin(degtorad(b))sin(degtorad(d))cos(degtorad(f))cos(degtorad(h)) )yy
+ ( -sin(degtorad(a))
cos(degtorad(c))sin(degtorad(f))sin(degtorad(g))cos(degtorad(h))sin(degtorad(i)) – cos(degtorad(b))sin(degtorad(c))cos(degtorad(f))sin(degtorad(g))cos(degtorad(h))sin(degtorad(i)) – cos(degtorad(a))cos(degtorad(d))sin(degtorad(f))sin(degtorad(h))sin(degtorad(i)) – sin(degtorad(b))sin(degtorad(d))cos(degtorad(f))sin(degtorad(h))sin(degtorad(i)) – cos(degtorad(a))sin(degtorad(d))sin(degtorad(f))cos(degtorad(i)) + sin(degtorad(b))cos(degtorad(d))cos(degtorad(f))cos(degtorad(i)) )zz
+ ( -sin(degtorad(a))cos(degtorad(c))sin(degtorad(f))sin(degtorad(g))cos(degtorad(h))cos(degtorad(i))sin(degtorad(j)) – cos(degtorad(b))sin(degtorad(c))cos(degtorad(f))sin(degtorad(g))cos(degtorad(h))cos(degtorad(i))sin(degtorad(j)) – cos(degtorad(a))cos(degtorad(d))sin(degtorad(f))sin(degtorad(h))cos(degtorad(i))sin(degtorad(j)) – sin(degtorad(b))sin(degtorad(d))cos(degtorad(f))sin(degtorad(h))cos(degtorad(i))sin(degtorad(j)) + cos(degtorad(a))sin(degtorad(d))sin(degtorad(f))sin(degtorad(i))sin(degtorad(j)) – sin(degtorad(b))cos(degtorad(d))cos(degtorad(f))sin(degtorad(i))sin(degtorad(j)) – sin(degtorad(a))sin(degtorad(c))sin(degtorad(f))cos(degtorad(j)) + cos(degtorad(b))cos(degtorad(c))cos(degtorad(f))cos(degtorad(j)) )ww
+ ( -sin(degtorad(a))
cos(degtorad(c))sin(degtorad(f))sin(degtorad(g))cos(degtorad(h))cos(degtorad(i))cos(degtorad(j)) – cos(degtorad(b))sin(degtorad(c))cos(degtorad(f))sin(degtorad(g))cos(degtorad(h))cos(degtorad(i))cos(degtorad(j)) – cos(degtorad(a))cos(degtorad(d))sin(degtorad(f))sin(degtorad(h))cos(degtorad(i))cos(degtorad(j)) – sin(degtorad(b))sin(degtorad(d))cos(degtorad(f))sin(degtorad(h))cos(degtorad(i))cos(degtorad(j)) + cos(degtorad(a))sin(degtorad(d))sin(degtorad(f))sin(degtorad(i))cos(degtorad(j)) – sin(degtorad(b))cos(degtorad(d))cos(degtorad(f))sin(degtorad(i))cos(degtorad(j)) + sin(degtorad(a))sin(degtorad(c))sin(degtorad(f))sin(degtorad(j)) – cos(degtorad(b))cos(degtorad(c))cos(degtorad(f))sin(degtorad(j)) )vv)
/(global.p – (( sin(degtorad(g)) )xx
+ ( cos(degtorad(g))
sin(degtorad(h)) )yy
+ ( cos(degtorad(g))
cos(degtorad(h))sin(degtorad(i)) )zz
+ ( cos(degtorad(g))cos(degtorad(h))cos(degtorad(i))sin(degtorad(j)) )ww
+ ( cos(degtorad(g))cos(degtorad(h))cos(degtorad(i))cos(degtorad(j)) )vv)
)))(global.r-((( cos(degtorad(a))cos(degtorad(c))sin(degtorad(e))cos(degtorad(g)) – sin(degtorad(b))sin(degtorad(c))cos(degtorad(e))cos(degtorad(g)) )xx
+ ( -cos(degtorad(a))cos(degtorad(c))sin(degtorad(e))sin(degtorad(g))sin(degtorad(h)) + sin(degtorad(b))sin(degtorad(c))cos(degtorad(e))sin(degtorad(g))sin(degtorad(h)) – sin(degtorad(a))cos(degtorad(d))sin(degtorad(e))cos(degtorad(h)) + cos(degtorad(b))sin(degtorad(d))cos(degtorad(e))cos(degtorad(h)) )yy
+ ( -cos(degtorad(a))
cos(degtorad(c))sin(degtorad(e))sin(degtorad(g))cos(degtorad(h))sin(degtorad(i)) + sin(degtorad(b))sin(degtorad(c))cos(degtorad(e))sin(degtorad(g))cos(degtorad(h))sin(degtorad(i)) + sin(degtorad(a))cos(degtorad(d))sin(degtorad(e))sin(degtorad(h))sin(degtorad(i)) – cos(degtorad(b))sin(degtorad(d))cos(degtorad(e))sin(degtorad(h))sin(degtorad(i)) + sin(degtorad(a))sin(degtorad(d))sin(degtorad(e))cos(degtorad(i)) + cos(degtorad(b))cos(degtorad(d))cos(degtorad(e))cos(degtorad(i)) )zz
+ ( -cos(degtorad(a))cos(degtorad(c))sin(degtorad(e))sin(degtorad(g))cos(degtorad(h))cos(degtorad(i))sin(degtorad(j)) + sin(degtorad(b))sin(degtorad(c))cos(degtorad(e))sin(degtorad(g))cos(degtorad(h))cos(degtorad(i))sin(degtorad(j)) + sin(degtorad(a))cos(degtorad(d))sin(degtorad(e))sin(degtorad(h))cos(degtorad(i))sin(degtorad(j)) – cos(degtorad(b))sin(degtorad(d))cos(degtorad(e))sin(degtorad(h))cos(degtorad(i))sin(degtorad(j)) – sin(degtorad(a))sin(degtorad(d))sin(degtorad(e))sin(degtorad(i))sin(degtorad(j)) – cos(degtorad(b))cos(degtorad(d))cos(degtorad(e))sin(degtorad(i))sin(degtorad(j)) – cos(degtorad(a))sin(degtorad(c))sin(degtorad(e))cos(degtorad(j)) – sin(degtorad(b))cos(degtorad(c))cos(degtorad(e))cos(degtorad(j)) )ww
+ ( -cos(degtorad(a))
cos(degtorad(c))sin(degtorad(e))sin(degtorad(g))cos(degtorad(h))cos(degtorad(i))cos(degtorad(j)) + sin(degtorad(b))sin(degtorad(c))cos(degtorad(e))sin(degtorad(g))cos(degtorad(h))cos(degtorad(i))cos(degtorad(j)) + sin(degtorad(a))cos(degtorad(d))sin(degtorad(e))sin(degtorad(h))cos(degtorad(i))cos(degtorad(j)) – cos(degtorad(b))sin(degtorad(d))cos(degtorad(e))sin(degtorad(h))cos(degtorad(i))cos(degtorad(j)) – sin(degtorad(a))sin(degtorad(d))sin(degtorad(e))sin(degtorad(i))cos(degtorad(j)) – cos(degtorad(b))cos(degtorad(d))cos(degtorad(e))sin(degtorad(i))cos(degtorad(j)) + cos(degtorad(a))sin(degtorad(c))sin(degtorad(e))sin(degtorad(j)) + sin(degtorad(b))cos(degtorad(c))cos(degtorad(e))sin(degtorad(j)) )vv)
/((global.p – (( sin(degtorad(g)) )xx
+ ( cos(degtorad(g))
sin(degtorad(h)) )yy
+ ( cos(degtorad(g))
cos(degtorad(h))sin(degtorad(i)) )zz
+ ( cos(degtorad(g))cos(degtorad(h))cos(degtorad(i))sin(degtorad(j)) )ww
+ ( cos(degtorad(g))cos(degtorad(h))cos(degtorad(i))cos(degtorad(j)) )vv)
)(global.q – ((( sin(degtorad(a))cos(degtorad(c))sin(degtorad(f))cos(degtorad(g)) + cos(degtorad(b))sin(degtorad(c))cos(degtorad(f))cos(degtorad(g)) )xx
+ ( -sin(degtorad(a))cos(degtorad(c))sin(degtorad(f))sin(degtorad(g))sin(degtorad(h)) – cos(degtorad(b))sin(degtorad(c))cos(degtorad(f))sin(degtorad(g))sin(degtorad(h)) + cos(degtorad(a))cos(degtorad(d))sin(degtorad(f))cos(degtorad(h)) + sin(degtorad(b))sin(degtorad(d))cos(degtorad(f))cos(degtorad(h)) )yy
+ ( -sin(degtorad(a))
cos(degtorad(c))sin(degtorad(f))sin(degtorad(g))cos(degtorad(h))sin(degtorad(i)) – cos(degtorad(b))sin(degtorad(c))cos(degtorad(f))sin(degtorad(g))cos(degtorad(h))sin(degtorad(i)) – cos(degtorad(a))cos(degtorad(d))sin(degtorad(f))sin(degtorad(h))sin(degtorad(i)) – sin(degtorad(b))sin(degtorad(d))cos(degtorad(f))sin(degtorad(h))sin(degtorad(i)) – cos(degtorad(a))sin(degtorad(d))sin(degtorad(f))cos(degtorad(i)) + sin(degtorad(b))cos(degtorad(d))cos(degtorad(f))cos(degtorad(i)) )zz
+ ( -sin(degtorad(a))cos(degtorad(c))sin(degtorad(f))sin(degtorad(g))cos(degtorad(h))cos(degtorad(i))sin(degtorad(j)) – cos(degtorad(b))sin(degtorad(c))cos(degtorad(f))sin(degtorad(g))cos(degtorad(h))cos(degtorad(i))sin(degtorad(j)) – cos(degtorad(a))cos(degtorad(d))sin(degtorad(f))sin(degtorad(h))cos(degtorad(i))sin(degtorad(j)) – sin(degtorad(b))sin(degtorad(d))cos(degtorad(f))sin(degtorad(h))cos(degtorad(i))sin(degtorad(j)) + cos(degtorad(a))sin(degtorad(d))sin(degtorad(f))sin(degtorad(i))sin(degtorad(j)) – sin(degtorad(b))cos(degtorad(d))cos(degtorad(f))sin(degtorad(i))sin(degtorad(j)) – sin(degtorad(a))sin(degtorad(c))sin(degtorad(f))cos(degtorad(j)) + cos(degtorad(b))cos(degtorad(c))cos(degtorad(f))cos(degtorad(j)) )ww
+ ( -sin(degtorad(a))
cos(degtorad(c))sin(degtorad(f))sin(degtorad(g))cos(degtorad(h))cos(degtorad(i))cos(degtorad(j)) – cos(degtorad(b))sin(degtorad(c))cos(degtorad(f))sin(degtorad(g))cos(degtorad(h))cos(degtorad(i))cos(degtorad(j)) – cos(degtorad(a))cos(degtorad(d))sin(degtorad(f))sin(degtorad(h))cos(degtorad(i))cos(degtorad(j)) – sin(degtorad(b))sin(degtorad(d))cos(degtorad(f))sin(degtorad(h))cos(degtorad(i))cos(degtorad(j)) + cos(degtorad(a))sin(degtorad(d))sin(degtorad(f))sin(degtorad(i))cos(degtorad(j)) – sin(degtorad(b))cos(degtorad(d))cos(degtorad(f))sin(degtorad(i))cos(degtorad(j)) + sin(degtorad(a))sin(degtorad(c))sin(degtorad(f))sin(degtorad(j)) – cos(degtorad(b))cos(degtorad(c))cos(degtorad(f))sin(degtorad(j)) )vv)
/(global.p – (( sin(degtorad(g)) )xx
+ ( cos(degtorad(g))
sin(degtorad(h)) )yy
+ ( cos(degtorad(g))
cos(degtorad(h))sin(degtorad(i)) )zz
+ ( cos(degtorad(g))cos(degtorad(h))cos(degtorad(i))sin(degtorad(j)) )ww
+ ( cos(degtorad(g))cos(degtorad(h))cos(degtorad(i))cos(degtorad(j)) )vv)
))))))))

y = yyy + global.rr((( sin(degtorad(a))cos(degtorad(c))cos(degtorad(f))cos(degtorad(g)) – cos(degtorad(b))sin(degtorad(c))sin(degtorad(f))cos(degtorad(g)) )xx /
+ ( -sin(degtorad(a))cos(degtorad(c))cos(degtorad(f))sin(degtorad(g))sin(degtorad(h)) + cos(degtorad(b))sin(degtorad(c))sin(degtorad(f))sin(degtorad(g))sin(degtorad(h)) + cos(degtorad(a))cos(degtorad(d))cos(degtorad(f))cos(degtorad(h)) – sin(degtorad(b))sin(degtorad(d))sin(degtorad(f))cos(degtorad(h)) )yy
+ ( -sin(degtorad(a))
cos(degtorad(c))cos(degtorad(f))sin(degtorad(g))cos(degtorad(h))sin(degtorad(i)) + cos(degtorad(b))sin(degtorad(c))sin(degtorad(f))sin(degtorad(g))cos(degtorad(h))sin(degtorad(i)) – cos(degtorad(a))cos(degtorad(d))cos(degtorad(f))sin(degtorad(h))sin(degtorad(i)) + sin(degtorad(b))sin(degtorad(d))sin(degtorad(f))sin(degtorad(h))sin(degtorad(i)) – cos(degtorad(a))sin(degtorad(d))cos(degtorad(f))cos(degtorad(i)) – sin(degtorad(b))cos(degtorad(d))sin(degtorad(f))cos(degtorad(i)) )zz
+ ( -sin(degtorad(a))cos(degtorad(c))cos(degtorad(f))sin(degtorad(g))cos(degtorad(h))cos(degtorad(i))sin(degtorad(j)) + cos(degtorad(b))sin(degtorad(c))sin(degtorad(f))sin(degtorad(g))cos(degtorad(h))cos(degtorad(i))sin(degtorad(j)) – cos(degtorad(a))cos(degtorad(d))cos(degtorad(f))sin(degtorad(h))cos(degtorad(i))sin(degtorad(j)) + sin(degtorad(b))sin(degtorad(d))sin(degtorad(f))sin(degtorad(h))cos(degtorad(i))sin(degtorad(j)) + cos(degtorad(a))sin(degtorad(d))cos(degtorad(f))sin(degtorad(i))sin(degtorad(j)) + sin(degtorad(b))cos(degtorad(d))sin(degtorad(f))sin(degtorad(i))sin(degtorad(j)) – sin(degtorad(a))sin(degtorad(c))cos(degtorad(f))cos(degtorad(j)) – cos(degtorad(b))cos(degtorad(c))sin(degtorad(f))cos(degtorad(j)) )ww
+ ( -sin(degtorad(a))
cos(degtorad(c))cos(degtorad(f))sin(degtorad(g))cos(degtorad(h))cos(degtorad(i))cos(degtorad(j)) + cos(degtorad(b))sin(degtorad(c))sin(degtorad(f))sin(degtorad(g))cos(degtorad(h))cos(degtorad(i))cos(degtorad(j)) – cos(degtorad(a))cos(degtorad(d))cos(degtorad(f))sin(degtorad(h))cos(degtorad(i))cos(degtorad(j)) + sin(degtorad(b))sin(degtorad(d))sin(degtorad(f))sin(degtorad(h))cos(degtorad(i))cos(degtorad(j)) + cos(degtorad(a))sin(degtorad(d))cos(degtorad(f))sin(degtorad(i))cos(degtorad(j)) + sin(degtorad(b))cos(degtorad(d))sin(degtorad(f))sin(degtorad(i))cos(degtorad(j)) + sin(degtorad(a))sin(degtorad(c))cos(degtorad(f))sin(degtorad(j)) + cos(degtorad(b))cos(degtorad(c))sin(degtorad(f))sin(degtorad(j)) )vv)
/((global.p – (( sin(degtorad(g)) )xx
+ ( cos(degtorad(g))
sin(degtorad(h)) )yy
+ ( cos(degtorad(g))
cos(degtorad(h))sin(degtorad(i)) )zz
+ ( cos(degtorad(g))cos(degtorad(h))cos(degtorad(i))sin(degtorad(j)) )ww
+ ( cos(degtorad(g))cos(degtorad(h))cos(degtorad(i))cos(degtorad(j)) )vv))(global.q – ( (( sin(degtorad(a))cos(degtorad(c))sin(degtorad(f))cos(degtorad(g)) + cos(degtorad(b))sin(degtorad(c))cos(degtorad(f))cos(degtorad(g)) )xx
+ ( -sin(degtorad(a))cos(degtorad(c))sin(degtorad(f))sin(degtorad(g))sin(degtorad(h)) – cos(degtorad(b))sin(degtorad(c))cos(degtorad(f))sin(degtorad(g))sin(degtorad(h)) + cos(degtorad(a))cos(degtorad(d))sin(degtorad(f))cos(degtorad(h)) + sin(degtorad(b))sin(degtorad(d))cos(degtorad(f))cos(degtorad(h)) )yy
+ ( -sin(degtorad(a))
cos(degtorad(c))sin(degtorad(f))sin(degtorad(g))cos(degtorad(h))sin(degtorad(i)) – cos(degtorad(b))sin(degtorad(c))cos(degtorad(f))sin(degtorad(g))cos(degtorad(h))sin(degtorad(i)) – cos(degtorad(a))cos(degtorad(d))sin(degtorad(f))sin(degtorad(h))sin(degtorad(i)) – sin(degtorad(b))sin(degtorad(d))cos(degtorad(f))sin(degtorad(h))sin(degtorad(i)) – cos(degtorad(a))sin(degtorad(d))sin(degtorad(f))cos(degtorad(i)) + sin(degtorad(b))cos(degtorad(d))cos(degtorad(f))cos(degtorad(i)) )zz
+ ( -sin(degtorad(a))cos(degtorad(c))sin(degtorad(f))sin(degtorad(g))cos(degtorad(h))cos(degtorad(i))sin(degtorad(j)) – cos(degtorad(b))sin(degtorad(c))cos(degtorad(f))sin(degtorad(g))cos(degtorad(h))cos(degtorad(i))sin(degtorad(j)) – cos(degtorad(a))cos(degtorad(d))sin(degtorad(f))sin(degtorad(h))cos(degtorad(i))sin(degtorad(j)) – sin(degtorad(b))sin(degtorad(d))cos(degtorad(f))sin(degtorad(h))cos(degtorad(i))sin(degtorad(j)) + cos(degtorad(a))sin(degtorad(d))sin(degtorad(f))sin(degtorad(i))sin(degtorad(j)) – sin(degtorad(b))cos(degtorad(d))cos(degtorad(f))sin(degtorad(i))sin(degtorad(j)) – sin(degtorad(a))sin(degtorad(c))sin(degtorad(f))cos(degtorad(j)) + cos(degtorad(b))cos(degtorad(c))cos(degtorad(f))cos(degtorad(j)) )ww
+ ( -sin(degtorad(a))
cos(degtorad(c))sin(degtorad(f))sin(degtorad(g))cos(degtorad(h))cos(degtorad(i))cos(degtorad(j)) – cos(degtorad(b))sin(degtorad(c))cos(degtorad(f))sin(degtorad(g))cos(degtorad(h))cos(degtorad(i))cos(degtorad(j)) – cos(degtorad(a))cos(degtorad(d))sin(degtorad(f))sin(degtorad(h))cos(degtorad(i))cos(degtorad(j)) – sin(degtorad(b))sin(degtorad(d))cos(degtorad(f))sin(degtorad(h))cos(degtorad(i))cos(degtorad(j)) + cos(degtorad(a))sin(degtorad(d))sin(degtorad(f))sin(degtorad(i))cos(degtorad(j)) – sin(degtorad(b))cos(degtorad(d))cos(degtorad(f))sin(degtorad(i))cos(degtorad(j)) + sin(degtorad(a))sin(degtorad(c))sin(degtorad(f))sin(degtorad(j)) – cos(degtorad(b))cos(degtorad(c))cos(degtorad(f))sin(degtorad(j)) )vv)
/(global.p – (( sin(degtorad(g)) )xx
+ ( cos(degtorad(g))
sin(degtorad(h)) )yy
+ ( cos(degtorad(g))
cos(degtorad(h))sin(degtorad(i)) )zz
+ ( cos(degtorad(g))cos(degtorad(h))cos(degtorad(i))sin(degtorad(j)) )ww
+ ( cos(degtorad(g))cos(degtorad(h))cos(degtorad(i))cos(degtorad(j)) )vv)
)))(global.r-((( cos(degtorad(a))cos(degtorad(c))sin(degtorad(e))cos(degtorad(g)) – sin(degtorad(b))sin(degtorad(c))cos(degtorad(e))cos(degtorad(g)) )xx
+ ( -cos(degtorad(a))cos(degtorad(c))sin(degtorad(e))sin(degtorad(g))sin(degtorad(h)) + sin(degtorad(b))sin(degtorad(c))cos(degtorad(e))sin(degtorad(g))sin(degtorad(h)) – sin(degtorad(a))cos(degtorad(d))sin(degtorad(e))cos(degtorad(h)) + cos(degtorad(b))sin(degtorad(d))cos(degtorad(e))cos(degtorad(h)) )yy
+ ( -cos(degtorad(a))
cos(degtorad(c))sin(degtorad(e))sin(degtorad(g))cos(degtorad(h))sin(degtorad(i)) + sin(degtorad(b))sin(degtorad(c))cos(degtorad(e))sin(degtorad(g))cos(degtorad(h))sin(degtorad(i)) + sin(degtorad(a))cos(degtorad(d))sin(degtorad(e))sin(degtorad(h))sin(degtorad(i)) – cos(degtorad(b))sin(degtorad(d))cos(degtorad(e))sin(degtorad(h))sin(degtorad(i)) + sin(degtorad(a))sin(degtorad(d))sin(degtorad(e))cos(degtorad(i)) + cos(degtorad(b))cos(degtorad(d))cos(degtorad(e))cos(degtorad(i)) )zz
+ ( -cos(degtorad(a))cos(degtorad(c))sin(degtorad(e))sin(degtorad(g))cos(degtorad(h))cos(degtorad(i))sin(degtorad(j)) + sin(degtorad(b))sin(degtorad(c))cos(degtorad(e))sin(degtorad(g))cos(degtorad(h))cos(degtorad(i))sin(degtorad(j)) + sin(degtorad(a))cos(degtorad(d))sin(degtorad(e))sin(degtorad(h))cos(degtorad(i))sin(degtorad(j)) – cos(degtorad(b))sin(degtorad(d))cos(degtorad(e))sin(degtorad(h))cos(degtorad(i))sin(degtorad(j)) – sin(degtorad(a))sin(degtorad(d))sin(degtorad(e))sin(degtorad(i))sin(degtorad(j)) – cos(degtorad(b))cos(degtorad(d))cos(degtorad(e))sin(degtorad(i))sin(degtorad(j)) – cos(degtorad(a))sin(degtorad(c))sin(degtorad(e))cos(degtorad(j)) – sin(degtorad(b))cos(degtorad(c))cos(degtorad(e))cos(degtorad(j)) )ww
+ ( -cos(degtorad(a))
cos(degtorad(c))sin(degtorad(e))sin(degtorad(g))cos(degtorad(h))cos(degtorad(i))cos(degtorad(j)) + sin(degtorad(b))sin(degtorad(c))cos(degtorad(e))sin(degtorad(g))cos(degtorad(h))cos(degtorad(i))cos(degtorad(j)) + sin(degtorad(a))cos(degtorad(d))sin(degtorad(e))sin(degtorad(h))cos(degtorad(i))cos(degtorad(j)) – cos(degtorad(b))sin(degtorad(d))cos(degtorad(e))sin(degtorad(h))cos(degtorad(i))cos(degtorad(j)) – sin(degtorad(a))sin(degtorad(d))sin(degtorad(e))sin(degtorad(i))cos(degtorad(j)) – cos(degtorad(b))cos(degtorad(d))cos(degtorad(e))sin(degtorad(i))cos(degtorad(j)) + cos(degtorad(a))sin(degtorad(c))sin(degtorad(e))sin(degtorad(j)) + sin(degtorad(b))cos(degtorad(c))cos(degtorad(e))sin(degtorad(j)) )vv)
/((global.p – (( sin(degtorad(g)) )xx
+ ( cos(degtorad(g))
sin(degtorad(h)) )yy
+ ( cos(degtorad(g))
cos(degtorad(h))sin(degtorad(i)) )zz
+ ( cos(degtorad(g))cos(degtorad(h))cos(degtorad(i))sin(degtorad(j)) )ww
+ ( cos(degtorad(g))cos(degtorad(h))cos(degtorad(i))cos(degtorad(j)) )vv)
)(global.q – ((( sin(degtorad(a))cos(degtorad(c))sin(degtorad(f))cos(degtorad(g)) + cos(degtorad(b))sin(degtorad(c))cos(degtorad(f))cos(degtorad(g)) )xx
+ ( -sin(degtorad(a))cos(degtorad(c))sin(degtorad(f))sin(degtorad(g))sin(degtorad(h)) – cos(degtorad(b))sin(degtorad(c))cos(degtorad(f))sin(degtorad(g))sin(degtorad(h)) + cos(degtorad(a))cos(degtorad(d))sin(degtorad(f))cos(degtorad(h)) + sin(degtorad(b))sin(degtorad(d))cos(degtorad(f))cos(degtorad(h)) )yy
+ ( -sin(degtorad(a))
cos(degtorad(c))sin(degtorad(f))sin(degtorad(g))cos(degtorad(h))sin(degtorad(i)) – cos(degtorad(b))sin(degtorad(c))cos(degtorad(f))sin(degtorad(g))cos(degtorad(h))sin(degtorad(i)) – cos(degtorad(a))cos(degtorad(d))sin(degtorad(f))sin(degtorad(h))sin(degtorad(i)) – sin(degtorad(b))sin(degtorad(d))cos(degtorad(f))sin(degtorad(h))sin(degtorad(i)) – cos(degtorad(a))sin(degtorad(d))sin(degtorad(f))cos(degtorad(i)) + sin(degtorad(b))cos(degtorad(d))cos(degtorad(f))cos(degtorad(i)) )zz
+ ( -sin(degtorad(a))cos(degtorad(c))sin(degtorad(f))sin(degtorad(g))cos(degtorad(h))cos(degtorad(i))sin(degtorad(j)) – cos(degtorad(b))sin(degtorad(c))cos(degtorad(f))sin(degtorad(g))cos(degtorad(h))cos(degtorad(i))sin(degtorad(j)) – cos(degtorad(a))cos(degtorad(d))sin(degtorad(f))sin(degtorad(h))cos(degtorad(i))sin(degtorad(j)) – sin(degtorad(b))sin(degtorad(d))cos(degtorad(f))sin(degtorad(h))cos(degtorad(i))sin(degtorad(j)) + cos(degtorad(a))sin(degtorad(d))sin(degtorad(f))sin(degtorad(i))sin(degtorad(j)) – sin(degtorad(b))cos(degtorad(d))cos(degtorad(f))sin(degtorad(i))sin(degtorad(j)) – sin(degtorad(a))sin(degtorad(c))sin(degtorad(f))cos(degtorad(j)) + cos(degtorad(b))cos(degtorad(c))cos(degtorad(f))cos(degtorad(j)) )ww
+ ( -sin(degtorad(a))
cos(degtorad(c))sin(degtorad(f))sin(degtorad(g))cos(degtorad(h))cos(degtorad(i))cos(degtorad(j)) – cos(degtorad(b))sin(degtorad(c))cos(degtorad(f))sin(degtorad(g))cos(degtorad(h))cos(degtorad(i))cos(degtorad(j)) – cos(degtorad(a))cos(degtorad(d))sin(degtorad(f))sin(degtorad(h))cos(degtorad(i))cos(degtorad(j)) – sin(degtorad(b))sin(degtorad(d))cos(degtorad(f))sin(degtorad(h))cos(degtorad(i))cos(degtorad(j)) + cos(degtorad(a))sin(degtorad(d))sin(degtorad(f))sin(degtorad(i))cos(degtorad(j)) – sin(degtorad(b))cos(degtorad(d))cos(degtorad(f))sin(degtorad(i))cos(degtorad(j)) + sin(degtorad(a))sin(degtorad(c))sin(degtorad(f))sin(degtorad(j)) – cos(degtorad(b))cos(degtorad(c))cos(degtorad(f))sin(degtorad(j)) )vv)
/(global.p – (( sin(degtorad(g)) )xx
+ ( cos(degtorad(g))
sin(degtorad(h)) )yy
+ ( cos(degtorad(g))
cos(degtorad(h))sin(degtorad(i)) )zz
+ ( cos(degtorad(g))cos(degtorad(h))cos(degtorad(i))sin(degtorad(j)) )ww
+ ( cos(degtorad(g))cos(degtorad(h))cos(degtorad(i))cos(degtorad(j)) )vv)
))))))))

自分自身は上記のコードで実装に成功しましたが、急いで整理したので一部ミスが有りましたら申し訳ありません。