オーダー
オーダーについて。適当に済ましていたので、おぼえがきします。アルゴリズムでも数学でも見ることがよくありますが、若干うろ覚えです。
定義
が のときオーダーである。
これを変形すると、 となることから、この定義は は より発散する速度が遅いということを意味しているのがわかります。この時 は で抑えられる、と言ったりするようです。
これに対し似た記法で、というものもあります。この時、以下が成り立ちます。
詳細な定義は省略しますが極限が0になることが違います。 は より発散する速度が、 の時より、十分遅いというイメージです。この時 は に比べ無視できる、と言ったりするようです。例えば、写像 が で全微分可能とは、
です。ここでは となっていて多少変化がありますが基本的に意味は変わっていません。つまり、 と は のノルムが十分小さいところでは限りなく等しいということが言えます。
アルゴリズムなどではよく、、 などと言ったりしますね。これらは「入力データ量 に対する実行時間は 」みたいな文脈だったと思います。これはつまり、
より、
この場合はアルゴリズムの実行時間が に比例する、ということですね。 なども同様です。
感想
わかったようなわかってないような微妙な気分です。当たり前のことを言っている気持ちにもなりました。
まあ少なくとも毎回ググらなくてよくなっただけ、進歩かと思います。
javascriptで実行時間を表示する
短いメモです。
console.time
、console.timeEnd
を使うとスクリプトの実行時間を表示することができます。
var loop = n => { console.time('timer'); for(i = 1; i <= n; i++) { for(j = 1; j <= n; j++) { console.log(`${i} x ${j} = ${i*j}`); } } console.timeEnd('timer'); }
引数で与えている文字列を使って、スタートとエンドを対応させます。
ここを参考にしました[JavaScript]使い分けるだけで今すぐデバッグ効率を上げる、consoleオブジェクトの関数 - Qiita。console
オブジェクトの関数がたくさん書かれています。
ReduxとExpressかElectronか
Reduxのチュートリアルを見終わったので、実際に手を動かしてみようと思い、リポジトリを作成してみました。中身はExample: Todo List | Reduxです。
express
とelectron
で動作確認ができます。
感想
写経しているとredux
に関して徐々にわかってきました。redux
は画面状態をStore
内のstate
オブジェクトとして持っていて、操作によって発行されるaction
オブジェクトとstate
をセットで、Reducer
に渡すことで、新たなstate
を取得します。
今回の登場人物は、
- Component(presentation, container)
- Action Creator
- Reducer & Store
処理の流れもこの順番です。
画面はコンポーネント(Component
)のツリー構造で表現されます。コンポーネントにはPresentation Component
とContainer Component
の二種類があり、Presentation Component
は構造を、Container Component
は状態を変化させる方法を定義します。単独で部品としても使えますが、Container Component
で定義した状態を変化させる関数を、react-redux
ライブラリに含まれるconnect
関数を使って、Presentation Component
に結びつけて使用したりもできます。また、このconnect
によってStore
とComponent
の結びつけも行なっているようです。(ちょっと調べないと、です)
また、コンポーネントのツリーの頂点にProvider
というreact-redux
ライブラリに含まれるコンポーネントを追加しているので、ここが状態をツリーの枝に伝える仕組みを提供しているのかもしれないです。
特定の動作に対して発行するAction
をAction Creator
で定義しておきます。これは最低限type
というプロパティを持ったオブジェクトを生成すれば問題ないようです。
Reducer
がStore
を定めているのだろうという認識で、この二つは同じ行に書いています。(実装的な視点、ですかね)Reducer
は古いstate
と、発行されたaction
を引数に新しいstate
を返します。redux
ライブラリのcreateStore
関数によってReducer
からStore
が生成されます。
いろいろ書きましたが、それぞれの部品はわかるものの、連結部分がわかりにくいという感想です。
知らなくてはいけないのはreact-redux
のProvider
、connect
によっていかにコンポーネントとStore
を結びつけているか、という部分ですかね。
Reduxの勉強3
引き続き、Reduxのレッスン動画を視聴した時のメモです。
- 21: ToDoアプリのリファクタリング。見た目と挙動を分けます。Main container componentからPresentational componentを分離しましょうというはなし。
- 22: container componentは振る舞いを定義するクラスとして作成した。
conponentDidMount
、conponentWillUnmont
メソッドを定義し、presentational componentは状態に対する見た目だけを定義する。のかな? - 23: Storeと結びついているコンポーネントは
forceUpdate
する?render
を全体のコンポーネントから分割したコンポーネントに行わせるように修正した。(しかしAddToDoコンポーネントにはrenderがないようだが)厳密にPresentationとContainerを分割する必要はないが、したほうがいいと言ったことを言っている気がする。。。
(だんだんきつくなってきました。。。)
- 24: StoreにアクセスするコンポーネントがContainerコンポーネントみたいだ。子のContainer ComponentにStoreを渡すために一旦storeをトップレベルの引数として渡す処理を書いた。
- 25:
Provider
を使うことでPresentation ComponentからStoreを取り除くことができるみたいだ。ContextによってContainer ComponentにStoreを渡すことができるようになった。Contextを使うにはchildContextTypesを指定しなければいけない。グローバルにアクセスできる感じか。ただしContextはあまり安定していないらしく、がっつり使っているのは良くないとのことです。 - 26:
Provider
はライブラリとして取得できるよ、という説明と記述方法でした。 - 27:
ReactRedux
ライブラリのconnect
メソッドを使うことでContainer Componentを作成することができる。最終的にどうなるか知れればいいかなという気分になってきました。 - 28, 29:
connect
メソッドを使って色々整理していきます。 - 30: ActionCreaterについて。
だいぶ聞き取れず、試すこともできず、停滞しています。 後日初めから、アプリを作成しつつ追っかけていこうと思います。。。
webpack、babel、React
Reactの環境構築です。できるだけ覚えることを減らしたいので、webpack
、babel
、react
を軸に必要最低限なものをインストールします。Node.js
の環境が整っている前提です。(npm
コマンドが使えればOKかと思います)
それぞれに関するメモです。
webpack
: jsxとかes6記法で書いたスクリプトとかをクライアント側に送るためにまとめるビルドツールという認識です。モジュール間の依存性を解決しつつビルドしてくれるそうです。チュートリアルやったらわかった気になれました。loader
というモジュールを追加することで、jsファイルだけでなくcssなどのまとめ方も指定できます。babel
: es6記法を一般的なブラウザで読めるようにコンパイルするもの。webpackでes6記法を含んだファイルをビルドする際に、エンジンとして使いました。インストールのみで特に何もしていないです。react
: jsのテンプレートエンジンです。jsxとして書くのが楽なので書くと、そのままではブラウザで動きません。なのでwebpackで普通のjsファイルにビルドさせます。
設定
パッケージファイルを作成し、必要なパッケージをインストールします。
npm init -y npm install webpack babel-loader babel-core babel-preset-es2015 babel-preset-react react react-dom --save-dev
次はwebpack
の設定です、設定ファイルを記述しない場合webpackにいろいろオプションを指定して実行することになりますので、ファイルwebpack.confing.js
を作成します。
webpack.config.js
module.exports = { entry: "./entry.js", output: { path: __dirname, filename: "bundle.js" }, module: { loaders: [ { test: /\.(js|jsx)$/, exclude: /node_modules/, loader: "babel", query: { presets: ['es2015', 'react'] } } ] } };
このファイルにwebpackコマンド実行時の設定をオブジェクトとして記述していきます。プロパティの説明をします。
entry
がビルドしたいスクリプトになります。この例ではentry.js
と設定しています。内部でrequire
とか呼び出ししているファイルは、webpackが勝手にまとめてくれます。output
には出力ファイルのパスと名前を記述します。ディレクトリ構造を考えていないので特にパスは指定してません。module
のloaders
という配列に、どのファイルをどのようにビルドするかの設定をオブジェクトで記述します。今回は一つだけです。test
にはどのファイルを対象にするかを正規表現で記述します。今回は拡張子がjs
またはjsx
のものを対象にします。exclude
には除外するもののパターンを記述します。loader
はビルドするエンジンを指定しているのだと思います。loader
に機能を追加するのがpreset
なんだろうか。presets
はes6記法とreactに関するものを指定しました。
次に、順番が前後していますが、entry.js
とReactのコンポーネントと動作確認用のindex.html
を作りましょう。
entry.js
window.onload = () => { require('./Hello.jsx'); }
Hello.jsx
const React = require('react'); const { render } = require('react-dom'); const Hello = React.createClass({ render: function() { return ( <div className="hello"> Hello, world! </div> ); } }); render( <Hello />, document.getElementById('root') );
index.html
<html> <head> <meta charset="utf-8"> </head> <body> <script type="text/javascript" src="bundle.js" charset="utf-8"></script> <div id="root"></div> </body> </html>
あとはコマンドを叩くだけです。
./node_modules/.bin/webpack
実行完了したらindex.html
をブラウザで確認してみてください。Reactっぽさはないですが、レンダリングされているのが確認できると思います。
必須ではないですがコマンドの実行はpackage.json
のscripts
に記述しちゃうと楽です。
package.json
{ "name": "webpack-tutorial", "version": "1.0.0", "description": "", "main": "bundle.js", "dependencies": { "webpack": "^1.13.1", "css-loader": "^0.23.1", "style-loader": "^0.13.1", "babel-core": "^6.10.4", "babel-loader": "^6.2.4", "babel-preset-es2015": "^6.9.0", "babel-preset-react": "^6.11.1", "react": "^15.2.0", "react-dom": "^15.2.0" }, "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "webpack": "webpack --progress --colors" }, "author": "", "license": "ISC" }
以下で起動できるようになります。
npm run webpack
以上です。コードはgithubに上げました。リポジトリ名がチュートリアルとなっていますが全然チュートリアルではないですが。。。
感想
ビルドツールのノリが少しわかりました。ビルドツールが自分にとって身近ではないのは、頻繁にビルドしないからに尽きるんでしょうね。
ともあれようやくReactが動いたので、Reduxのチュートリアルを試すことができます。
Reduxの勉強2
動画が30分で終わるかと思ったら30回あることに気がついて力尽きてしまったので、今日はその残りを見ていきます。
Webpackを使えるようになろうとか言っていましたが、いまの腰を据えて試せていないので停滞しています。残りの動画を放っておくとちょっと分かった気になっているので見なくなる可能性があります、こちらを優先させていただきます。
- 11: todos Reducerをテストファーストで書いた。actionにidがふってあるが、どこまでふったか、stateかどこかに数字を控えなければいけないのだろうか?(後の動画でグローバル変数として保持しているのがわかる)
- 12: todos Reducerに「ADD_TODO」だけではなく「TOGGLE_TODO」メソッド(case?すくなくともメソッドではない)を追加。副作用なくすためにしっかりテスト書かないとダメ。ちょっと性善説で悩む(でもみんな責任感あるし大丈夫かな)。
- 13: Reducerの分割。stateのリストを受け取るReducerの内部を、単一のstateを受け取るReducerに切り出す。どんどんReducer同士を結合させちゃえてきな英語を喋っていた気がする、この辺りは副作用のない関数であることが不安を取り去ってくれてますね。想定していないtypeのActionに関してはそのままstate返しましょう、という念押し。
- 14: Reducerの合成だが、ちょっと難しい。todosとは別のvisibilityFilter Reducerを追加し、それらを包含したtodoApp Reducerを作成。todoApp内部で、各Reducerへの振り分けを行なっているみたい。なんかStoreとReducerの関係性が曖昧になってきた。。。ActionをStoreに
dispatch
した際に、入れ子になったどのstateに対するActionか指定していないが、これは対象としていない方にundefinedが渡るからシカトしてOKということか?なんか違和感。 - 15: Reducerの合成は
combineReducers
を使うと楽と言っている。またes6の記法で定義した変数a, b, c
をobj = {a,b,c}
と書けばオブジェクトのkey valueが勝手に入るらしい。「object literal shorthand anotation」だそうです。 - 16:
combineReducers
の実装を書いて説明してくれる。reduce
で少し詰まった。多分、foldl
とかと同じでいいんですよね。配列の各要素を使って一つのものをどんどん作っていくイメージをしました。 - 17: Reactを使ってToDoの「ADD_TODO」機能のユーザインタフェースを作った。また、入力から出力までのReduxの(?)ライフサイクルを説明してくれているので、よくわからなくなったらこれを見るといいかも。
- 18: 「TOGGLE_TODO」機能をUIから使えるようにした。全体的に言えるのはどの関数も、基本的には全てのstateを総なめして一致したら処理を実行する感じみたいだ。
- 19: 「visibilityFilter」のUIを作成。画面側の機能とReducerは対応していないという当たり前のことに気がつく。filterをかける処理などは通常の関数で実装しているが、もし自分が作った時にその辺間違えそう。画面表示とstateの違いをちゃんと整理しておかないと危険ですね。
- 20: ToDoアプリのリファクタリング。Reactコンポーネントの分離について。分離の基準がよく理解できない。イベントハンドラのコールバック関数はどちらが持つべきか等。分離の途中で次回。
感想
本当は今日中に30まで見てしまって、手を動かす時間を取りたかったのですが、眠気が襲ってきてしまったのでこれで終了です。
動画の中で、コンポーネント内でinputの値を取得するために、react callback ref api
を使っていた。常識っぽいので知っておきたいです。
あと、markdownのlistはoffsetが効かないため困りました。今日は動画を11から見始めたので、
11. hogehoge 12. hogehoge ...
と書いていたのですが、画面上では
1. hogehoge 2. hogehoge ...
になってしまい、ちょっと面倒さを感じながら*
をかませて対応しました。
JavaScript...
ES6から、「Spread operater」というものが追加されました。「...」を記述することで、配列やオブジェクトを展開する事ができる演算子だそうです。 例えば、
var [x, ...xs] = [1,2,3,4,5,6,7,8,9]; console.log(x); //=> 1 console.log(xs); //=> [2, 3, 4, 5, 6, 7, 8, 9]
分割代入との合わせ技だと思いますが、このように余った部分を配列で受け取ってくれます。
可変長引数等で使えますね。
サンプルコードを書いてみました。 比較方法が数値しか対応していなくて残念ですが、比較の優先順位を可変長で受け取るソート関数を書いてみました。
function mySort(array, ...properties) { if(properties.length <= 0) return array; let comp = (a, b) => { let res = 0; for(i = 0; i < properties.length; i++){ let property = properties[i]; if(match = /^-(.*)$/g.exec(property)) property = match[1]; let sign = (match) ? -1 : 1; if(!(property in a)) throw new Error(`There is no property named ${property}`); res = sign * (a[property] - b[property]); if(res !== 0) break; } return res; } return [...array].sort(comp); } var objs = [ {id: 0, a:1, b:1, c:1, d:1}, {id: 1, a:1, b:1, c:1, d:2}, {id: 2, a:1, b:1, c:2, d:1}, {id: 3, a:1, b:1, c:2, d:2}, {id: 4, a:1, b:2, c:1, d:1}, {id: 5, a:1, b:2, c:1, d:2}, {id: 6, a:1, b:2, c:2, d:1}, {id: 7, a:1, b:2, c:2, d:2}, {id: 8, a:2, b:1, c:1, d:1}, {id: 9, a:2, b:1, c:1, d:2}, {id:10, a:2, b:1, c:2, d:1}, {id:11, a:2, b:1, c:2, d:2}, {id:12, a:2, b:2, c:1, d:1}, {id:13, a:2, b:2, c:1, d:2}, {id:14, a:2, b:2, c:2, d:1}, {id:15, a:2, b:2, c:2, d:2} ]; console.table( mySort(objs, '-a', 'b','c') );
配列への要素の追加も副作用なく簡単にかけます。
function mutableExclamate(list) { list.push('!'); return list; } function immutableExclamate(list) { return [...list, '!']; } args = ['y','a','y']; console.log(args); //=> ["y", "a", "y"] console.log(mutableExclamate(args)); //=> ["y", "a", "y", "!"] console.log(args); //=> ["y", "a", "y", "!"] args = ['y','a','y']; console.log(args); //=> ["y", "a", "y"] console.log(immutableExclamate(args)); //=> ["y", "a", "y", "!"] console.log(args); //=> ["y", "a", "y"]
そんなに想像力が働かないですね。 ただArray.prototypeを触らなければならない場面は減ると思います。
Reduxの勉強
Redux
ここを一通り読めばわかりそうだ!と思って読み始めたら、いきなりプレディクタブルステートコンテナとか言われてよく分かりません。
Redux is a predictable state container for JavaScript apps. Read Me | Redux
ステートは普通に状態でいいのだろうか?あまり知らないため、用語を使っていたらわけわからなくなると思いながら、とりあえず読み進めることにしました。
30分の動画があるためそれを見る。なんか10個くらいあるようです。(間違ってました、後述)
- ToDoアプリを用いて、画面の状態が一つのオブジェクト(State Tree)に対応していることの実演。
- State Treeはリードオンリーで、操作(type)とデータを持ったオブジェクト(Action)によって変更される。
- Pure FunctionとImpure Functionの違い。副作用がないこと(戻り値を返す以外の方法で出力を行わないことかな?)
- StateとActionを受け取り新しいStateを返すのがReducer、これはPure Functionになっている。だから同じStateとActionを入れれば同じStateが必ず得られることが保証される。(ちょっと英語怪しくなってきました...)
- 数字を増やしたり減らしたりするだけのCounter Reducerを例に、ReducerとTestの説明をしている。
expect(...).toEqual(...)
って感じで書いている。またReducerの実装上の注意など説明されていた(未定義なtypeのAction、stateのデフォルト値など) - Reduxの導入と、Storeのもつメソッドの説明。ReduxのcreateStoreメソッドによってReducerを引数にStoreというものが作られている。StoreはsubscribeメソッドによってViewの書き換えを行なったり、stateを保持しているようだ。StoreにActionをdispatchメソッドによって食べさせることで保持しているstateが更新されている。こいつは副作用を担っているっぽいです。
- createStoreの実装に関する説明。getState、dispatch、subscribeの三つを提供してくれるがこれらが何をしているかを説明してくれた。subscribeがあまりわからない...内部に持つlisteners配列を更新するが、filter処理はなにをしている?
- renderにはReactを使おう!その際はコールバックを渡すのがいいよ、という説明。おそらく先ほどのsubscribeのおかげでStoreが変更を反映してくれているんだろうという程度の理解。
- テストにdeepFreezeを使ってイミュータブルな処理をちゃんと書こうという話かな?es6の記法(配列
list
に対して...list
を使うことで中身を展開できる)をつかった小粋な書き方とか勉強になりました。 - 引き続きテストの話。
Object.assign
とes6...object
の記法の説明。自分の英語力だと3点リーダの記法がいいように聞こえたんだけどどうなんだ?
いまさら気がついたのですが、この動画30分ではなく30個の動画だったのですね...
30見ていると何も達成感がないのでとりあえずまとめとしてカウンターアプリを作ってみよう。
と思ったのですが、環境構築がうまくいかずに断念。webpackを勉強しないといけない。
感想
ビルドツールになぜか苦手意識があることが判明しました。なぜ嫌なのだろうか?webpackを調べつつ、Redux触っていきたいです、あわよくばElectronでアプリ作りたいです。
javascriptで波括弧を使ってconst値に分割代入
こんにちは。
クロスプラットフォームのデスクトップアプリがhtml、css、javascriptで作れてしまうフレームワーク「Electron」をちょっと触ってみようと思ったのですが、「Hello, world」する前に気になったことをメモします。 (Electronとはあまり関係ない内容になっています)
疑問
とりあえずElectronの環境を整えました。
mkdir myapp npm init -y cd myapp npm install electron-prebuilt --save-dev
あとは、Quick Start - Electronを参考に進めていきました。
ウィンドウを表示したり、閉じた時の挙動を制御するシステム系の設定をindex.js
(package.json
のmain
プロパティで指定したファイル)に記述するのですが、いざコピペしてやろうと思ってサイトの内容を読んでいるといきなり3行目に以下の記述を見かけました。
const electron = require('electron'); // Module to control application life. const {app} = electron; ...
const
は定数定義で、ES6から使えるらしい、ということは知っていたのですが、
この波括弧{app}
はなんなんだ?と思いました。
知らないと恥ずかしいのかもしれないので、いろいろ試してみました。
(以下ごちゃごちゃしています。結論はタイトルに書いてあります)
スコープ
とりあえずconst
は関係ない、スコープの問題だろうと当たりをつけて以下のコードをchromeのコンソールで実行しました。
{hoge} = {hoge:'hogehoge'}; console.log(hoge);
確かにこれでもhogehoge
がコンソールに出力されます。
const
がどうとかではなく、左辺に波括弧の中にオブジェクトのプロパティを記述すると、右辺のオブジェクトが持っているプロパティの値を取り出すことができるという動きです。
左辺の波括弧の中のhoge
が外側から参照できること、左辺のhoge
に右辺の値が入っていることについて考えなければと思い、javascriptのオブジェクトの代入に関して調べてみました。
javascriptにおいてはオブジェクト型の代入は参照渡しになる、ということを聞いてもしかすると、と考え以下のコードを試してみました。
obj1 = {p1:{c:1}}; p1 = obj1.p1; p1.cc = 2; console.info(obj1); console.info(p1); obj2 = {p2:{c:1}}; var {p2} = obj2; p2.cc = 2; console.info(obj2); console.info(p2);
二種類の方法を試したのですが違いはありませんでした。 もしかすると波括弧で囲えば値渡しになるとか考えたのですが、それは間違っていました。。。
感想
そもそもなんでこう書かれているかを探るために、Electronのドキュメントのgithubリポジトリをみてみました。
この記法に変更された時のプルリクエストを見ると、Destructing assignment
というコミットメッセージを発見しました!
ググってみると次のページが見つかります。
分割代入、という構文だったんですね、初めて知りました。
今日はここにたどり着くまでで消耗してしましました...
gnuplotとFFTW
勉強のため、gnuplot(gnuplot homepage)とc言語のFFTW(Fastest Fourier Transform in the West.)ライブラリの環境を作ってみます。
gnuplot
gnuplotはコマンドラインから使えるグラフィックユーティリティです。科学者や学生向けに数学の関数をヴィジュアル化する目的で作られました。
homebrewでインストールします。こちらを参考にしました。(gnuplotをHomebrewからインストールするときの手順)
$ brew install gnuplot --with-aquaterm
aquatermはGUIです。gnuplotの出力を表示するために、インストール時点でオプションを追加します。
インストール完了後gnuplot
コマンドで対話環境が起動します。まずはaquatermでsin(x)
を表示してみましょう。
gnuplot> set terminal aqua gnuplot> plot sin(x)
出力方式、出力先を設定することで、画像ファイルやhtmlのcanvasとして吐き出すことができます。
gnuplot> set terminal png gnuplot> set output 'sin_x.png' gnuplot> plot sin(x)
関数をデータとして吐き出したい場合は、
gnuplot> set table "gnuplot.sample" gnuplot> set yrange [0:1] gnuplot> set xrange [-5:5] gnuplot> plot exp(- x * x / 2) / sqrt(2 * pi) gnuplot> unset table
とすると、gnuplot.sample
ファイルに関数の値が書き込まれます。
# Curve 0 of 1, 100 points # Curve title: "exp(- x * x / 2) / sqrt(2 * pi)" # x y type -5 1.48672e-06 i -4.89899 2.45106e-06 i -4.79798 3.99989e-06 i -4.69697 6.46117e-06 i -4.59596 1.0331e-05 i -4.49495 1.6351e-05 i -4.39394 2.56161e-05 i -4.29293 3.97238e-05 i -4.19192 6.09759e-05 i -4.09091 9.26476e-05 i -3.9899 0.000139341 i -3.88889 0.00020744 i -3.78788 0.000305686 i -3.68687 0.00044589 i -3.58586 0.000643795 i -3.48485 0.000920105 i -3.38384 0.00130165 i -3.28283 0.00182273 i -3.18182 0.0025265 i -3.08081 0.00346644 i -2.9798 0.00470779 i -2.87879 0.00632878 i -2.77778 0.00842153 i -2.67677 0.0110926 i -2.57576 0.0144624 i -2.47475 0.0186646 i -2.37374 0.0238433 i -2.27273 0.0301496 i -2.17172 0.0377369 i -2.07071 0.0467541 i -1.9697 0.057338 i -1.86869 0.069604 i -1.76768 0.0836362 i -1.66667 0.0994771 i -1.56566 0.117117 i -1.46465 0.136486 i -1.36364 0.157443 i -1.26263 0.179775 i -1.16162 0.20319 i -1.06061 0.227324 i -0.959596 0.251742 i -0.858586 0.275953 i -0.757576 0.299423 i -0.656566 0.32159 i -0.555556 0.341892 i -0.454545 0.359787 i -0.353535 0.374774 i -0.252525 0.386423 i -0.151515 0.394389 i -0.0505051 0.398434 i 0.0505051 0.398434 i 0.151515 0.394389 i 0.252525 0.386423 i 0.353535 0.374774 i 0.454545 0.359787 i 0.555556 0.341892 i 0.656566 0.32159 i 0.757576 0.299423 i 0.858586 0.275953 i 0.959596 0.251742 i 1.06061 0.227324 i 1.16162 0.20319 i 1.26263 0.179775 i 1.36364 0.157443 i 1.46465 0.136486 i 1.56566 0.117117 i 1.66667 0.0994771 i 1.76768 0.0836362 i 1.86869 0.069604 i 1.9697 0.057338 i 2.07071 0.0467541 i 2.17172 0.0377369 i 2.27273 0.0301496 i 2.37374 0.0238433 i 2.47475 0.0186646 i 2.57576 0.0144624 i 2.67677 0.0110926 i 2.77778 0.00842153 i 2.87879 0.00632878 i 2.9798 0.00470779 i 3.08081 0.00346644 i 3.18182 0.0025265 i 3.28283 0.00182273 i 3.38384 0.00130165 i 3.48485 0.000920105 i 3.58586 0.000643795 i 3.68687 0.00044589 i 3.78788 0.000305686 i 3.88889 0.00020744 i 3.9899 0.000139341 i 4.09091 9.26476e-05 i 4.19192 6.09759e-05 i 4.29293 3.97238e-05 i 4.39394 2.56161e-05 i 4.49495 1.6351e-05 i 4.59596 1.0331e-05 i 4.69697 6.46117e-06 i 4.79798 3.99989e-06 i 4.89899 2.45106e-06 i 5 1.48672e-06 i
ここでは一列目がx軸、二列目がy軸になっています。三列目はちょっと謎...
このデータを使ってグラフを表示するのも簡単にできます。
gnuplot> plot "gnuplot.sample"
FFTW
FFTWは離散フーリエ変換を計算するためのc言語のライブラリです。変換する関数は次元、入力サイズ、実数or虚数別が選べます。
$ brew install fftw
FFTWには離散フーリエ変換を扱うための関数や複素数データ型が用意されています。
FFTW does not use a fixed algorithm for computing the transform, but instead it adapts the DFT algorithm to details of the underlying hardware in order to maximize performance.
FFTWでは入力データに対して、毎回決まった変換アルゴリズムを適応するのではなく、最適化した変換アルゴリズムを用いて離散フーリエ変換を行う仕組みになっています。そのため、変換実行前に「プラン」というものを作成します。複素一次元離散フーリエ変換のプランを作成する関数を見てみましょう。
fftw_plan fftw_plan_dft_1d(int n, fftw_complex *in, fftw_complex *out, int sign, unsigned flags);
fftw_plan_dft_1d
はfftw_plan
を戻り値にもつ関数です。引数として次のものをとります;
int n
: データサイズfftw_complex *in
:入力データ配列fftw_complex *out
:出力データ配列int sign
:フーリエ変換(-1)、逆フーリエ変換(+1)かの設定。定数が用意されています。unsigned flags
:通常はFFTW_ESTIMATE
をつかい、サイズが同じ変換を何回もし、初期化コスト(?)を気にしないならばFFTW_MEASURE
を使うみたいです。
感想
力が尽きてしまい、フーリエ変換前後のグラフを出力することは断念しました。sinをフーリエ変換して、一本だけ立つことを確認するとか、関数の和がどんどん短形関数に近づいていく様をみるとか、やりたいです。
フーリエ変換の練習(前半)
フーリエ変換について知識がないため、ちょっと勉強してみます。証明的なものを載せていますが、考え方を学ぶためのメモなため正確なことを知りたい場合参考書を当たってください。フーリエ変換の雰囲気がわからなくて困っている場合はちょっとは役に立つと思います。(私も同じ状況なので)
フーリエ変換は関数を周波数で分解した表示に変換できるものです。分解の際に現れる各項は連続関数と定数の積ですが、これらの無限の和を考えることで、不連続な関数に関しても分解が得られるということが面白と思いました。通信関係をはじめとして、広い範囲での応用がされています。
元となった理論は、フーリエ級数の研究なのかと思います。フーリエ級数は周期関数に関する表示を与えるものでしたが、フーリエ変換では周期を無限と考えることで、その対象を広げたところが違いです。
考え方の核は、周期を無限と考えることと、関数空間に対して基底による分解を与える感じでしょうか?一部フーリエ級数と変わらないですが。
前提条件としては、微分積分、線形代数(基底とかの話)、複素数(というかオイラーの公式)を知っていれば理解できそうです。
離散フーリエ変換など応用の方面でまだまだ研究されているようで2012年には従来の10倍の変換速度を誇るSFFTといったものも発表されたみたいですね。。。
ということで、数学の勉強方法ってどうするんだろう、としばらく悩んだのですが、ああ、証明を考えてみるのが一番理解できるな、と思い出しました。理解のためにまずはフーリエ級数を証明してみます。なので周期関数の空間について考えます。ちゃんとした参考書みないので記号は適当です、うまくいかなかったらすみません。
周期関数
周期 の関数の空間を と定義します。
内積は、 で定義します。(内積であることは積分の性質からいけるはず)
の基底が、1(定値関数)、、 になることを示せれば、任意の周期関数 は、
という形で表せることがわかります。
証明
前半
基底であることを示すには、一次独立と生成系であることを言わなければいけません。
まずは一次独立を示すために、それぞれの基底候補が直交していることを示します。
より がわかりました。 も同様です。
次に、 と と、 ですが、これはオイラーの公式を使うといけそうです(、 の積の公式を忘れてしまいました...)。
以下の等式が成立します。(記述が面倒なので、 とします。)
一方、
なので、
が成り立ちます。さらにの符号を変えた、 から、
よってこれを使うと、
つまり、、、 は直行することがわかります。
以上のことから、
に対して、、、 をそれぞれかけて積分したものを考えれば、
、 、 がわかります。
感想
ちょっと元気が無くなってしまい、今回は前半だけです。いろいろ抜けがあると思います、後半の生成系であることを示す方針は全然思いついてないです。ただ関数空間の条件に可積分が必要になりそうですね(多分仮定されてたはず)。
あと、はてなの環境では[tex: ... ]
の内部で&が使えないため等式を複数段並べる時とか面倒です。なにか方法があるのでしょうか?
Persistent
Persistentはデータベースアクセスインターフェースを提供するHaskellのパッケージで、DDL、DML、などを扱いやすい関数を備えています。
型安全と完結さ、明確な文法という原理に則って開発されていて、PostgreSQL、SQLite、 MySQL、MongoDBや実験的にRedisもサポートしているそうです。MySQLに関してはjoinをサポートしてい無いそうですが、Esqueletoライブラリによって補完されていると書かれています。また、データベースのマイグレーションも行ってくれるようです。(詳細)
データ構造
Persistentはデータベースの構造をどうやってHaskellで表現しているのでしょうか?対応表が載っていたので転記します。
SQL | Persistent |
---|---|
Datatypes(VARCHAR, INTEGER, etc) | PersistValue |
Column | PersistField |
Table | PersistEntity |
PersistValueはデータ型、PersistField、PersistEntityは型クラスになっています。
まずは、
- データ型
- テーブル定義
- マイグレーション
をHaskell内で記述する必要があるようです。
とりあえず
とりあえずサイトのサンプルを動かしてみます。
{-# LANGUAGE EmptyDataDecls #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE GADTs #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE QuasiQuotes #-} {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE TypeFamilies #-} import Database.Persist import Database.Persist.TH import Database.Persist.Sqlite import Control.Monad.IO.Class (liftIO) share [mkPersist sqlSettings, mkSave "entityDefs"] [persistLowerCase| User email String password String deriving Show |] main :: IO () main = runSqlite ":memory:" $ do runMigration $ migrate entityDefs $ entityDef (Nothing :: Maybe User) hogeId <- insert $ User "hoge@fuga.com" "piyo" hoge <- get hogeId liftIO $ print hoge
プラグマがよくわかってい無いため、なんとも言えませんが記述する部分はshare
の次の行のデータ型定義くらいで済んでるのではないかと思います。もしかしたらリレーションとか考えると複雑になるのかもしれませんが。
感想
途中で力が尽きてしまったので、次はいろいろいじりたい。なんだか中途半端なことが溜まっている気がする。
おまけ:Yesod
YesodはHaskellのWebフレームワークです。Haskellによる、型安全でRESTfulで高性能なWebアプリケーション開発の生産性を向上させる目的を掲げているそうです。
PersistentはYesodに組み込まれているそうです。HaskellのWebフレームワークとしてはかなり有名らしく、githubを見るとすでにバージョンは2.5
が出ていました。
pingを知ろう
こんにちは。
シンプルなものって素敵ですよね。自分が好きなものは包丁とまな板です。大工道具もなかなか素敵です。
本当のところはよくわかってないですが、今日はシンプルそうで、使いこなせるとカッコ良さそうな、ping
コマンドについてメモしました。(BSD)
ping(píŋ)とは?
まずはターミナルからman ping
を実行してマニュアルを確認します。
NAME ping -- send ICMP ECHO_REQUEST packets to network hosts
ICMPとはInternet Control Message Protocol
の略で、IP通信の制御や通信状態の調査などを行なうためのものです。
ECHO_REQUESTとは「エコー要求」と訳されていて、通信可能なら応答するよう要求するICMPのメッセージの一種です。
ping
はICMPでネットワークホストにエコー要求パケットを送るコマンド、
つまりネットワークを通して「大丈夫ですか?」と聞くコマンドということみたいです。
オプション
単純にping XXX.XXX.XXX.XXX
を実行すると、XXX.XXX.XXX.XXX
へパケットが送られ続けます。制御するオプションの一部をメモします。
オプション | 内容 |
---|---|
-c count |
count 回のパケット送信を行った後停止する |
-i wait |
パケット送信毎にwait 秒の間隔(interval?)待機する |
-t timeout |
timeout 秒過ぎたら停止する |
-W waittime |
応答がwaittime 秒過ぎたら画面表示しない(最終的には遅れた応答も統計情報として反映はする) |
パケットが見たい
-p pattern
というオプションでは送信するパケットの内容を変更できるようです。
しかしターミナルからはパケットの内容は見えないため(やり方があるのかもしれませんが)、確認できません......
それだとちょっと寂しいので、脱線してOS Xでパケットを見る方法をメモしておきます。
wireshark
ネットワークプロトコル解析ツールのwireshark
を使えばいいようです。オプションなしでhomebrewでインストールするとguiが無いようなので--with-qt
をつけてコマンドを打ちます。
brew install wireshark --with-qt
インストールの仕方が悪かったのか、うまく動きませんでしたが、sudo /usr/local/Cellar/wireshark/バージョン/bin/Wireshark
で直接起動したらいけました。
wi-fiを選択して、icmpでフィルタします。あとは試しにping -p ff 外部のIP
として見ると、icmpのrequestとreplyが交互に表示されました。
パケットの中身を見るとff
がたくさん並んでいて、-p
オプションも効いています!
感想
とりあえずパケットの中身が見れて満足です。これでping
のオプションも少しずつ理解を深めていけそうです。ネットワーク経路なども選択できるようで、その辺りを使いこなしていきたいです。
haskellのパッケージ管理ツールstack
haskellでservantを使いたくて色々調べていたら、サンプルとして上がっているものがことごとくstackというパッケージ管理ツールを想定したものでした。cabal-install
の代わりになるものっぽいです。
stackはhaskellプロジェクトの管理を簡単にしてくれるもので、依存関係の解決とか、テスト実行とか、ベンチマーク測定とか色々機能があるようです。あとGHCi起動時のモジュールのロードを勝手にしてくれるみたいです。
というわけでhaskellのパッケージ管理ツールstackを入れてみます。
参考
正直現在の環境をどうやって入れたか覚えてないのですが、確かhomebrewでcabal-install
とghc
をインストールした気がします。それらを全てアンインストールし、
brew install haskell-stack
を実行しました。
GHCiを使うために、
stack setup
を実行。
stack ghci
でGHCiが起動するようになりました。
runghc hoge.hg
、runhaskell hoge.hs
は
stack runghc hoge.hs
で実行できます。
感想
使えるからいいやではなく、何をしているかちゃんと理解しないといけないですね......
vimの移動コマンド
こんにちは。
よく使っているエディタ、vimについてメモします。
vimには便利な移動コマンドが沢山あって魅力的です、でもなかなか使いこなせていない感じがします。上下左右移動を覚えた後、さらに自由にファイルを編集するための移動コマンドを調べてみました。
基本的な移動
コマンド | 意味 |
---|---|
h |
左へ移動 |
j |
下へ移動 |
k |
上へ移動 |
l |
右へ移動 |
0 |
行左端へ移動 |
$ |
行右端へ移動 |
^ |
文頭へ移動 |
g_ |
文末へ移動 |
折り返された行での移動
基本的なコマンドに対してg
を頭につけると、折り返し時の移動が楽になります。
コマンド | 意味 |
---|---|
gj |
下へ移動 |
gk |
上へ移動 |
g0 |
画面左端へ移動 |
g$ |
画面右端へ移動 |
gm |
画面中央へ移動 |
例えばgj
、gk
は画面で見たままの上下移動になります。
また、g0
、gm
、g$
コマンドは画面上水平方向の位置へ移動します。
g
をつければ画面上で見たままの、上下左右移動、行頭、行末移動になると覚えておくといいと思います。
検索
コマンド | 意味 |
---|---|
f[char] |
カーソル位置から行末方向にある[char]の位置にカーソルを移動 |
t[char] |
カーソル位置から行末方向にある[char]の直前の位置にカーソルを移動 |
F[char] |
カーソル位置から行頭方向にある[char]の位置にカーソルを移動 |
T[char] |
カーソル位置から行頭方向にある[char]の直前の位置にカーソルを移動 |
; |
直近のf、t、F、Tをリピートします |
, |
直近のf、t、F、Tを逆方向にリピートします(つまりfaのあとの,はFa) |
次の行、次の文、次の段落
コマンド | 意味 |
---|---|
+ |
次の行の最初の文字に移動 |
- |
前の行の最初の文字に移動 |
) |
次の文へ移動(文はドットとスペース. で区切ります) |
( |
前の文へ移動 |
} |
次の段落へ移動 |
{ |
前の段落へ移動 |
感想
gif
作成時にタイプミスしないようにするのが大変でした。(作成にはttygif
を使いました。)
...ちょっと再生速度が速いみたいです。
検索で;
、,
を使いこなせば速度が上がるかと思います、,
は忘れがちなので気をつけます。
いずれ画面操作系のコマンド(配置、リサイズ等)についてもメモしておきたいです。