B級科学者もどきの憂鬱

とある理系になりきれない奴のつれづれなる活動記

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

行列計算ライブラリEigenで固有値の計算

お久しぶりです。もうすぐ年明けですね。
もう何ヶ月も全然書いてなかったので、
次の更新はTIPSの話にしたかったのですが、
記事にできるほど進んでません!
というわけで今回は全然違うテーマです。

最近は数値シミュレーションを色々とやっています。
その過程で、行列計算にEigenというC++用ライブラリを導入しました。
色々見てる限り、結構速そうで導入も楽で使いやすそうです。

行列計算だけでなく、普通の配列を扱う計算で使っても、
アセンブラレベルで並列化したりしてくれるので、
普通にC++で書くより速いそうです。
これに関してはまだ確かめてませんけど。

導入は、公式サイトから圧縮ファイルをダウンロードし、
解凍して出来たファイルをインクルードパスに追加するだけです。
ヘッダファイルだけで出来ているので、コンパイル等は不要です。

例として、実数行列の固有値を求めるコードを書いてみます。

#include <stdio.h>
#include <Eigen/Dense>  // 固有値計算ルーチンの入ったインクルードファイル

int main() {
  Eigen::Matrix<double, 3, 3> A;  // 実数行列
  A << 1,2,3,4,5,6,7,8,9;  // Aの行列要素を代入

  Eigen::EigenSolver< Eigen::Matrix<double, 3, 3> > s(A);
  std::cout << "固有値\n" << s.eigenvalues() << std::endl;
  std::cout << "固有ベクトル\n" << s.eigenvectors() << std::endl;

  return 0;
}

EigenSolverが固有値を求めるテンプレートクラスで、
テンプレート引数に、求めたい行列の型名を入れて使います。
行列型の型名が割と長くなるので、typedef等で短い名前に置き換えた方が、
間違いが少なくなると思います。

複素行列の固有値を求めたい場合は、Aの型名の、
Eigen::Matrix<double, 3, 3>
doublestd::complex<double>に置き換えて、
(もちろん、EigenSolverのテンプレート引数も一緒に置き換えて)
Eigen::Matrix<std::complex<double>, 3, 3>
とすれば良い、だけではありません

これだけだと、EigenSolverのコンパイルに失敗します。
少なくとも、私が使った環境ではエラーになります。
(Eigen3.2.0、Visual Studio Express 2012 for Windows Desktop)
私は最初、これにハマって数十分悩みました。
というかこれが、今回の記事を書いた動機です。

解決法は、EigenSolverの代わりに、ComplexEigenSolverを使うことです。
これでエラーは出なくなります。

さらに詳しく知りたい方は、公式リファレンスを参照して下さい。
スポンサーサイト

最近の活動

書くほどの事が無かったので、
またまたこんなに空いてしまいました。
最近やってることを適当に書き連ねていきます。


図書館で、前々からやりたかった、
テンプレートメタプログラミングに関する資料を借りてきました。
目から鱗のテクニックが満載で、とても楽しいです。

ですが、やはり万人向けではないと思いました。
STLやBoostのようなライブラリの作成者のように、
パフォーマンスと柔軟性を極限まで追求する人向け、
という感じを受けました。知っていて損はないでしょうけど。


最近歌い手になった知り合いに頼まれて、
歌い手用のMIXをやることになりました。
音楽の素養は素人だし、センスに至っては素人以下の私に何故、
と思わなくもないですが、知人曰く「理系だろ?」とのこと。
理論に関して「だけ」は多少知ってるけどね……。

とりあえずやってみたら割とお気に召したようでした。
多分これからも参加することになると思います。


TIPSの開発は少しずつ進めています。
動作速度と品質のトレードオフを実現するために、
合成モードをいくつか用意する予定です。

爆速モード、それなりモード、高品質モードの三つです。
もしかしたら、それなりモードと高品質モードの間に
イイ感じモードが入るかもしれません。
ちなみに、モード名は今考えました。

爆速モードは、速度をひたすら優先します。
その分、精度が多少犠牲になり、フラグが色々無効になります。
高品質モードは、論文三つぐらいの内容を
全部詰め込んだ処理を行います。
その分、時間は結構かかります。

元々は、速度と品質のトレードオフを
シームレスに設定できるようにするつもりでしたが、
色々検討した結果、こういう形に落ち着きました。

実現できないというわけでは無いのですが、
現在検討中のアルゴリズムには、
連続的に設定できるパラメータがわずかしかないので、
無理に実装しても、あまり意味はないと思います。

あと、現行のTIPSでは、BREは扱えませんけど、
現在開発中の物では扱えるようになる予定です。
フォルマント修正系のフラグについては、
今までどおり扱えません。

やろうと思えば擬似的に扱えないこともないと思いますが、
多分誰も得しない&結構面倒なので、
熱烈な要望がない限りは実装しません。

現状はこんな感じです。
実装予定はあくまで予定なので、
これからまた変わっていくかもしれません。

resamplerは動くけどTIPSは動かない方へ

お久しぶりです。
最近、少し手を抜くことを覚えて、楽になったと思ったら、
それとは別にやることが増えて結局前と変わらないという
負の連鎖に頭痛がしますが私は元気です。
今回の記事は、たまにユーザーの方から報告のある、
TIPSエンジンが動かないという問い合わせに関してです。

先日、自分のノートPCの方でTIPSエンジンを使ってみたら、
最初、全く合成されませんでした。

そこで、UTAUのインストール先を、
Program Filesからマイドキュメントに移動したら、
ちゃんと動くようになりました。

どうやら、tips.exeには、Program Files等のフォルダに、
新しいファイルを作成する権限が無いようです。
なので、合成パラメータを格納するpmkファイルの作成に失敗し、
pmkファイルを用いる合成工程も失敗するようです。

そういえば、あの辺のフォルダって、
ファイルを作成するのにいちいち管理者権限が要りますよね。
まぁあれはあれで必要な機能だとは思いますが、
もう少し融通を利かせて欲しいものです。

通常のresamplerはどちらのフォルダでも動くのですが、
これは、UTAU本体と作者が同じだからでしょうかね。
この辺りはあまり良く分かりません。

というわけで、resamplerは動くけど、TIPSが動かない方は、
一度、UTAUの入ったフォルダごと、マイドキュメント等に
移動させると、移動させた方のUTAU上では、
TIPSも動くようになるかもしれません。

UTAUの作者以外の方が作ったエンジンも同じように動かない方は、
これで動くようになる可能性が高いです。
もちろんそれでも動かない可能性はありますが。

フォルダを丸ごと移動、というのをさせたくない方は、
ファイル作成権限を操作することで、回避可能です。
こちらのリンク先の画像を参照して下さい。
http://twitpic.com/durky9

この操作により、TIPSがpmkファイルを
作ることが出来るようになります。
作り終わったら、設定を元に戻しても構いません。


まとめです。

resamplerは動くけど、TIPSは動かない、という方は、
UTAUのインストール先が、ファイルの新規作成に管理者権限の
必要なフォルダかどうか、チェックしてみてください。
例えば、Program Files等です。他にも色々あります。

もし上記のチェックに当てはまったら、
次のいずれかの操作を行って下さい。

1.
ファイル新規作成に管理者権限の必要の無いフォルダ、
例えば、マイドキュメントなどに、
UTAUのインストールフォルダを変更するか、
UTAU.exeの入ったフォルダを、丸ごとそこにコピーする。

新しく作った方のUTAUを用いてTIPSエンジンを使ってみると、
もしかしたらちゃんと動く様になっているかもしれなせん。

2.
次のリンク先を参照して、ファイル作成権限を変更する。
http://twitpic.com/durky9
こちらのほうがより楽です。


これでも動かない方は、状況を出来るだけ具体的に、
例えば、何という音源の何の音で合成されない、
などをお知らせくだされば、なるべく調べるようにします。


5/20 追記
pmkファイルを作成してさえいれば、
UTAUがProgram Files等にあっても動くはずです。
なので、別の場所でpmkファイルだけ作っておくというのも手です。

勉強とか進捗とか

新年明けましておめでとうございます。
……というにはあまりに時期違いですが、
一応、2013年度最初の記事になりますね。

前回からだいぶ空いてしまいました。
時間自体はそれなりにありましたが、
単に、書くほどのネタが無かったせいです。
というわけで、近況とか適当に書いていきます。

年末年始休みの間に、TIPSエンジンのプログラムを進めました。
休みが終わる頃には、WAVEファイルの読み込み処理まで書きました。
……あれ? もしかして、ほぼ進んでない?

どんなWAVEファイルでも問題なく読めるようにとか考えて、
RIFFファイルの英文の仕様書とか無理して読んだり、
その他色々とめんどくさいことやってた結果がこれだよ!

とはいえ、仕様を詳細に調べ直さないといけない箇所は
多分ここぐらいのものだと思いますので、
以降のプログラムは割とすんなり進む……はずです。

そういえば、次のバージョンでは、パラメータ推定に使うFFTを、
自作ではなく、他のライブラリに置き換える事を考えています。
自作は自作でそれなりに利点はあるのですが、
他のライブラリに比べると、やはり速度がかなり劣るので。

最も速いと言われているのはFFTWですが、
導入が少々面倒なのと、GPLライセンスなので、
これを採用するかどうかは分かりません。

あと、信号処理関連の書籍をもう一度読み直して、
基礎固めをやったりしてます。
前に一回やった分野のはずなのに、
何故か新しい発見があるという謎。

その他、本業関連で英語力がもっと必要だと痛感して、
タイミングよく拾った新品同様の単語帳で、
久しぶりに英語の勉強もやったりしてます。
やばい、高校英語とか半分位忘れてる!

日本語の資料ではあまり突っ込んだ所まで
資料が無いことが多いので、これで英語の論文とか
まともに読めるようになればいいんですけどね。

#defineでシングルトン化

デザインパターンの中で、おそらく最もシンプルなのが、
シングルトンパターンでしょう。
他のパターンはあんまり知らないけど、
これだけは使えるという人も多いです。

このパターン、C++のプログラミング系のサイトで、
よくテンプレート化出来ないか取り上げられてますよね。

ただ、シングルトンパターンをテンプレートの継承で行う場合、
どうやってもコンストラクタがprotectedになり、
完全なシングルトンにすることが出来ません。
継承を使わなくとも、色々と問題点が多く、
シンプルな解は中々無いようです。

じゃあテンプレートじゃなくて、マクロでやればいいんじゃね?
と思って作ってみました。

#define SINGLETONIZE(ClassName) \
    private: \
        ClassName(); \
        ~ClassName(); \
        ClassName(const ClassName&); \
        ClassName& operator=(const ClassName&); \
    public: \
        static ClassName& GetInstance() { \
            static ClassName object; \
            return object; \
        }

とても簡単に出来ちゃいました。

シングルトンパターンを知っている人なら、
ほとんど説明はいらないと思いますが、
一応、使い方はこんな感じになります。
シングルトン化したいクラスを、Singleとします。

class Single {

    // メンバ色々……

    SINGLETONIZE(Single)

    // メンバ色々……

};

という風に、クラス宣言内に書けばOKです。

シングルトン化したいクラス名以外のものをマクロの引数に渡すと、
多分全ての場合でコンパイラがエラーを吐きますので、
マクロでよくある様々な障害とも無縁だと思います。

スレッドセーフな実装ではありませんので、
マルチスレッドでは直接使えませんが、
多少改変すれば出来るはずです。

こんなマクロを作っている人を案外見かけないのですが、
どうしてなのでしょうか?
あまりにも自明な解過ぎて載せる価値が無いという事か、
はたまた、マクロなんて邪道ってことなんでしょうかね。
何事も適材適所だと思いますが。

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。