Hatena::ブログ(Diary)

My Life as a Mock Quant このページをアンテナに追加 RSSフィード Twitter

2013-06-15

R markdown(knitr)パッケージのchunk optionまとめ

| 22:40 | R markdown(knitr)パッケージのchunk optionまとめを含むブックマーク

R markdownファイル(Rmd)にRのコード片(以下、chunk)を埋め込む際のオプションがたくさんあって覚えきれないから、よく使いそうなものだけでもまとめておきたい。ここで言うchunkってのはR markdownファイル中に記述することが出来る

```{r eval=FALSE, error=FALSE}
summary(cars)
```

というようなRのコード片の事で、そのオプションってのはこの例だと"eval"や"error"に該当。要するにOptions: Chunk options and package options | knitrの俺用まとめです。また別途、簡易リファレンスカード(英語・PDF)もあったので、これ読んでおけば大体いいかも。RPubsにも例が上がっていて、これを見るのも参考になる。

オプションデフォルト意味
evalTRUElogicalchunkを実際にRのコードとして評価するか否か
echoTRUElogical/numericchunkを出力として表示するか否か。echo=2:3等ともかけてこの場合2・3番目のコードのみ出力。逆にecho=-4だと4番目のコード以外出力
warningTRUElogicalchunkに対する警告を表示させるか否か
errorTRUElogicalchunkに対するエラーを表示させるか否か
promptFALSElogicalプロンプトの文字(例:>)を実行したコードの結果として追加するか否か
comment'##'character計算結果の頭につく文字
includeTRUElogicalchunk・実行結果を出力(通常、RStudio使ってるならHTML)に入れるか否か。これをFALSEにしてもRのコードは実行される点に注意。
messageTRUElogicalmessage関数の結果を表示させるか否か(パッケージ読み込む時に表示されるメッセージ等の事)
highlightTRUElogicalコードをシンタックスハイライトするか否か
tidyTRUElogical出力されるchunkをformatRパッケージのtidy.source()関数で整形するか否か
fig.width/height7numeric図のプロットのサイズ(単位:インチ)
results'markup'character結果の出力を(markup/asis/hide)の三択の文字列から選択。markup・asisはmark upした結果か生のRの結果かが違う。hideは結果を表示しない
cacheFALSElogical出力される計算結果をキャッシュするか否か

(俺が使うものを上に配置し、大体降順に整理)

SFINAE(Substitution Failure Is Not An Error)のメモ

| 21:34 | SFINAE(Substitution Failure Is Not An Error)のメモを含むブックマーク

関数オーバーロードを使用する際に、うまくコンパイルできないケースをエラーとするのではなく、オーバーロードの対象から自ずと外してしまうという技法((技法というよりもコンパイラとしてこのような動作となるか否かって話っぽい))。以下の例の場合はtest<int>とintでテンプレート引数を指定した際にはT::typeと引数を指定したケースが自ずとオーバーロード対象からはずれ、他方のtest関数がマッチングされエラーとはならない(代入エラーとはそれ自身はエラーではないというSFINAE原義)。

#include <iostream>
//適当なクラス
struct Hoge{typedef int type;};
//TとT::type型をそれぞれ引数とするtest関数
template<typename T>
void test(T){std::cout << "T" << std::endl;}
template<typename T>
void test(typename T::type){std::cout << "T::type" << std::endl;}

int main()
{
    test<Hoge>(0); //上(T::type)が呼ばれる
    test<int>(0);  //上(T)が呼ばれる
    return 0;
}

実行結果

T::type
T

Boost enable_ifのページにあった例

似たような例として参考にLINKを張ってあるBoostのenable_ifの例が良かったので、それを引用させていただく。以下のコードではnegate関数を二つ定義しているものの、templateを使って書いている方はint型に対してインスタンス化されないので、除去される(エラーにはならずただ除去される!)。

#include <iostream>
//二つのnegate関数(下の関数はインスタンス化されない)
int negate(int i) { return -i; }
template <class F>
typename F::result_type negate(const F& f) { return -f(); }

int main()
{
    int a = 10;
    int x = negate(a);
    return 0;
}

enable_ifを使ってやる

C++11から標準ライブラリ入りしたenable_ifを使ってSFINAEを作り出すのが常套手段。ただしここでenable_if関数は手元のVS2008にはない&勉強兼ねて自作した。

普通にdouble型とint型の

#include <iostream>
//自作is_int, is_double
template<class T>
struct is_int{static const bool value = false;};
template<>
struct is_int<int>{static const bool value = true;};
template<class T>
struct is_double{static const bool value = false;};
template<>
struct is_double<double>{static const bool value = true;};
//enable_if
template<bool Cond, class T = void>
struct enable_if{};
template<class T>
struct enable_if<true, T> { typedef T type; };
//
//
template<class T>
typename enable_if<is_int<T>::value, T>::type hoge(T t) 
{
    std::cout << "hoge: int\n";
    return t;
} 
template<class T>
typename enable_if<is_double<T>::value, T>::type hoge(T t) 
{
    std::cout << "hoge: double\n";
    return t;
}
 
int main()
{
    hoge(1.2);
    hoge(10);
    return 0;
}

参考

Substitution failure is not an error - Wikipedia, the free encyclopedia

enable_if - 1.53.0(1.2のBackgroundの箇所に記載あり)

std::enable_if - cppreference.com

2013-05-18

CIRモデルで金利の期間構造 by shiny

| 20:41 | CIRモデルで金利の期間構造 by shinyを含むブックマーク

金融工学でいうCIRモデルで表現される金利の期間構造の、モデルパラメーター依存性を見てみたくて、簡単なwebアプリケーションを作ってみた。

CIRモデルについてはリンク先を見て頂くとして、shinyについて簡単に捕捉しておくと、

という事です。

公式サイトはこちらで、日本語での解説記事・資料も

…と結構出ています。


作ったアプリケーションは2つのCIRモデルパラメーターによる金利の期間構造を描画するような簡単なもの。

もともとshiny自体が複雑なもの作るようには出来てないしね。

http://www.hatena.ne.jp/

このアプリケーション自体はShinyホスティングというβ版のサービス上で動いています*1

Shinyホスティングサービス自体は無料でこちらのLINKから登録する事が出来ます。


今回作成したアプリケーションのソースはgistに貼り付けてあります。

Interest rate term structure by CIR(Cox,Ingersoll,Ross)model


ちなみに既にR言語使いで、かつ、手元で既にshiny使ってる方なら

library(shiny)
runGist(5604103)

でこのアプリケーションをローカル環境で立ち上げる事ができます。

この辺のrunGist・runGithub・runUrl系の関数は便利だなぁ。

*1:いつ動かなくなるかもわかりませが…

2013-05-13

CRTP(Curiously Recurring Template Pattern)を使ってCloneable(Deep copy)を楽に書く方法を考えていた

| 19:17 | CRTP(Curiously Recurring Template Pattern)を使ってCloneable(Deep copy)を楽に書く方法を考えていたを含むブックマーク

問題

オブジェクトの深いコピーを作る時は、コピーコンストラクタを内部で呼び出してnewするようなclone関数を作成するのがセオリーだと思い、以下のように書くわけです。

#include <iostream>
//適当なクラス
class Hoge
{
public:
    Hoge* clone(){return new Hoge(*this);}
};
class Moge
{
public:
    Moge* clone(){return new Moge(*this);}
};

int main()
{
    Hoge x1;
    Moge y1;
    //クローンしたオブジェクト
    Hoge *x2 = x1.clone();
    Moge *y2 = y1.clone();
    delete x2;
    delete y2;
    return 0;
}

いちいち書くのが面倒くさい

ただ、上の書き方だとDeep copyさせたいクラスを追加するたびに、いちいちclone関数を各クラスに書かねばならず、面倒くさい。

また仮に「コピー可能クラス・インターフェイス」を作成、継承させてもこの問題は変わらなくて、しかも今の場合、本質的に関係ないと思ってるHoge・Mogeクラスが共にCloneableクラスのオブジェクトとして、格納可能になってしまうのはなんか気持ちが悪い。

一応、書くと以下のような感じか。

#include <iostream>
//適当なクラス
class Cloneable
{
public:
    virtual Cloneable* clone(){return new Cloneable(*this);}
};
class Hoge : public Cloneable
{
public:
    Hoge* clone(){return new Hoge(*this);}
};
class Moge : public Cloneable
{
public:
    Moge* clone(){return new Moge(*this);}
};

int main()
{
    Hoge x1;
    Moge y1;
    //クローンしたオブジェクト
    Hoge *x2 = x1.clone();
    Moge *y2 = y1.clone();
    //Cloneable *x3 = x1.clone();
    //Cloneable *y3 = y1.clone();
    //x3 = y3 が出来てしまう
    delete x2;
    delete y2;
    return 0;
}

この書き方は

とほぼ同じだと思う。

CRTPを使って対処してみる

ここでこのめんどくさい問題に対処するためにはCRTP(Curiously Recurring Template Pattern)を使うのがいいんじゃないかなと考えて書いてみたのが以下のコード。

継承先に何も書かなくてもcloneする事が出来てうれしいなと思うわけです。

もっと良いやり方があるのでしょうかね?

#include <iostream>
//適当なクラス
template <class T>
class Cloneable
{
public:
    T* clone(){return new T(static_cast<T&>(*this));}
};
class Hoge : public Cloneable<Hoge>
{};
class Moge : public Cloneable<Moge>
{};

int main()
{
    Hoge x1;
    Moge y1;
    //クローンしたオブジェクト
    Hoge *x2 = x1.clone();
    Moge *y2 = y1.clone();
    delete x2;
    delete y2;
    return 0;
}

いや、そもそも・・・

テンプレート関数一発書いておけばいいって話?どう使い分けるのが良いのだろうか。

よくわからなくなってきた。

#include <iostream>
//適当なクラス
template <class T>
T* clone(const T& x){return new T(x);}
class Hoge{};
class Moge{};

int main()
{
    Hoge x1;
    Moge y1;
    //クローンしたオブジェクト
    Hoge *x2 = clone(x1);
    Moge *y2 = clone(y1);
    delete x2;
    delete y2;
    return 0;
}

2013-05-01

zclipはfileプロトコルではなくhttpプロトコルでないと動かない

| 20:40 | zclipはfileプロトコルではなくhttpプロトコルでないと動かないを含むブックマーク

jQueryを使ったjavascriptクリップボードコピペプラグインzclipはfileプロトコルではなくhttpプロトコルでないと動かない、つまり作成したhtmlファイルを単にブラウザドラッグ&ドロップしてもだめで、サーバーアップロードしてhttpプロトコルを使ってアクセスしないとworkしない。

私が手元でテストする時はvisual studio for webを使ってIIS express経由で表示させるようにして動作をチェックした。

実際に動作チェックに使ったコードは以下。

<html>
<head>
</head>
<body>
    <script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
    <script type="text/javascript" src="http://www.steamdev.com/zclip/js/jquery.zclip.min.js"></script>
    <script>
        $(document).ready(function () {
            $('a#copy').zclip({
                path: 'http://www.steamdev.com/zclip/js/ZeroClipboard.swf',
                copy: $('div#description').text()
            });
        });
    </script>
    <a id='copy' href="#">Copy</a>
    <div id='description'>this seems awesome</div>
</body>
</html>

参考:stackoverflowでの該当スレッド

2013-04-24

「文字⇒数値」はatofでいいわ

| 21:40 | 「文字⇒数値」はatofでいいわを含むブックマーク

sstreamのstringstream使えばいいんだろうけど、こっちの方がタイプ量的に楽。

あとはboost::lexical_cast使えないちゃんの時のために。

#include <iostream>
#include <vector>
#include <algorithm>
//文字列⇒小数の変換ファンクタ
struct ToDouble{double operator()(std::string x){return ::atof(x.c_str());}};
//表示用のファンクタ
struct Show{void operator()(double x){std::cout << x << std::endl;}};

int main()
{
    //適当な数値文字列
    std::vector<std::string> x;
    x.push_back("10.13");
    x.push_back("-97.13");
    x.push_back("-5");
    x.push_back("123");
    //double型のベクターへ変換
    std::vector<double> y(x.size());
    std::transform(x.begin(), x.end(), y.begin(), ToDouble());
    //結果表示
    std::for_each(y.begin(), y.end(),Show());
    return 0;
}

結果(ちゃんと数値になってる)

10.13
-97.13
-5
123

egtraegtra 2013/04/27 02:59 たしかにこういう単純なのだとstringstream面倒ですよね。最近だと、std::string→doubleの変換を行うstof関数が用意されていることもあります。

teramonagiteramonagi 2013/04/27 07:00 本当だ!VS2010からいけるみたいですね、ありがとうございます。