SSブログ

光学薄膜設計ソフトの設計 その12「最適化ライブラリとのインターフェイス」 [考え中 - 光学薄膜設計]

こうやって進んでいるような気がするときは、やってて楽しいのでついつい時間を費やしてしまう。
昨日の続きで、以前考えた計算の構造をgslの最適化とちゃんとつながるかどうか。

ちょっと前考えたとき、光学薄膜オブジェクトは最適化の対象となる変数をオブジェクトとして取り出し、そこへのポインタを保持することにした。ある層の膜厚や屈折率はその層だけが単独で参照するだけだが、波長や入射角などすべての層が同じものを参照していなければならない。そういった構造とgslの最適化ライブラリからの呼ばれ方が矛盾しないかどうか。

ちょとまえに
  • 一つの層を表すオブジェクトのOTFLayer
  • それらの層をひとまとめにして膜構成として保持するOTFLayerComposition
  • OTFLayerCompositionとその他の条件を保持するOTFOpticalCharacteristics
を使うと言うことにした。OTFLayerは膜厚と屈折率のオブジェクトへのポインタを保持し、OTFLayerCompositionは基板および入射媒質の屈折率を保持し、OTFOpticalCharacteristicsは波長、入射角、偏光方向を保持する。

OTFLayerは単層のマトリクスを返すのがおもな仕事。OTFLayerCompositionは膜全体のマトリクス、あるいは前に書いたB、Cの値を返す。OTFOpticalCharacteristicsは反射率や透過率、それらの位相などを返す。

OTFLayerがマトリクスの値を計算するためには自分で持っていない波長や入射角を知る必要があるが、それは自分を保持しているOTFLayerCompositionに問い合わせることにする。OTFLayerComposition自信も波長などは持っていないのでさらに上のOTFOpticalCharacteristicsに問い合わせる。結構オーバーヘッドは大きいけどこれで波長の単一性は保証できる。計算効率は大切だけど、書いてるうちにわからなくなったりするので、単純さはさらに大切。

変数オブジェクトは変更があったら、それを参照しているオブジェクトに対して変更通知をすることにした。自分が保持しているオブジェクトから値の問い合わせを受けたとき、前回から変わってなければ(変更通知を受け取ってなければ)値を返すのではなく、変更が無い旨を知らせる。たとえばOTFOpticalCharacteristicsはOTFLayerCompositionから波長の問い合わせがあったとき、前回の問い合わせから変更が無ければ変更なし、と答える。OTFLayerCompositionはOTFLayerからの波長の問い合わせに対しては同じように変更なし、と答える。OTFLayerは自分に関係する変数すべてに変更が無ければ、前回計算したマトリクスをそのまま返す、ということにする。そうして一カ所でも変更のあるオブジェクトだけが値を更新する。かえって面倒かもしれないけど、とりあえずこうしておこう。

ここで新しいクラスを導入する。 メリット関数の一つの項を表すOTFTargetというのを作る。これは
  1. OTFOpticalCharacteristicsへのポインタを保持する
  2. 何を計算するか、とその目標値を保持する
  3. 計算の条件、例えば波長や入射角を保持する
  4. 重みを保持する
というようなもの。こいつの仕事はメリット関数の一つの項の値を計算することと、ある変数での微係数を計算すること。

何を計算するか、というのは反射率なのか、透過率なのか、位相なのか、などのこと。これはOTFOpticalCharacteristicsが計算可能なものでなければならない。簡単にするため、整数のenumとかではなく、OTFOpticalCharacteristicsのセレクタを直接持とう。そうすればif文やswitch文でふらずに直接OTFOpticalCharacteristicsオブジェクトにわたしてしまえばいい。OTFOpticalCharacteristicsが計算できるものが増えたときにOTFTargetそのものは変更せずにすむ。

計算できる内容はOTFOpticalCharacteristicsのメソッドとして定義されることになるけど、外とのインターフェイスのため、例えば反射率の計算のメソッドはなにか、あるいはあるメソッドは何をするのか、を実行時に調べられるような機能を持っておく必要がある。 そのために計算の内容を示す文字列の配列をOTFOpticalCharacteristicsのクラスが持ち、クラスメソッドを用意する。例えばこんな感じ。
+ (int)numberOfComputables;
+ (NSString *)descriptionOfComputableIndexAt:(int)n;
+ (SEL)computableForDescription:(NSString *)descr;
+ (NSString *)descriptionForComputable:(SEL)selector;
めんどうなのと名前が苦しそうだけど、OTFOpticalCharacteristicsの中だけで閉じられるのでつごうがいい。外からはこの文字列か、インデクスの整数で指定してセレクタを得る。

また目標値は範囲で指定できるようにする。目標値の範囲に入っていれば目標値との差は0と見なす。ある値以上やある値以下と言う場合も範囲の片方が無限大と言う設定にすればいい。しかし、これを使うと非線形最小2乗法が使えなくなるな。微係数が全部0でも動くのかなあ。動くわけないなあ。でも他の項が効いていれば微係数0にはならないだろうし。最適化が呼ばれたとき微係数全部が0なら最適化不要ということだし。どうしようか。とりあずまあ、いいか。

メリット関数全体はOTFMeritFunctionというオブジェクトにやらせよう。これは
  1. OTFTargetを保持する
  2. 変数を保持する
もので、gslの最適化ライブラリとのインターフェイスになる。gslから呼ばれたら
  1. 変数ベクトルから値を取り出して変数に設定する
  2. メリット関数とその微係数の値をOTFTargetから得て全部の和をとる
  3. 値をgslライブラリに返す
ということをやる。このやりとりはメソッドではなくCの関数呼び出しでできなければいけない。

ごちゃごちゃ書いてよくわからなくなってしまいそうなので、一区切りついたら整理する。このへんまでくるとつい実装に突入したくなるけど、それをぐっと我慢しよう。
nice!(0)  コメント(1)  トラックバック(0) 

nice! 0

コメント 1

Generic for cialis

沒有醫生的處方
cialis daily http://kawanboni.com/ Generic for cialis
by Generic for cialis (2018-04-14 02:51) 

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

トラックバック 0

献立04/21献立04/22 ブログトップ

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。