照度分布計算その11 - Mathematicaとのインターフェイス [回折による照度分布計算]
回折によるレーザ照度の計算の続き。今週は横浜のうちに帰ってるけど、雨降りなのですることがない。あーめーが、ふーりまーす、あーめがーふーるー、とりあえずMathematicaをフロントエンドに使うことにしたのでそのインターフェイスSMathematicaIOクラスを作っておく。
と、こんなインターフェイス。
@interface SMathematicaIO : NSObject - (int)parse; - (int)writeBack:(NSDictionary *)result; @endインスタンス変数は、ない。これならObjective-CのクラスではなくてCの関数として実装した方がいいけど、まあ、どっちでもええわ。javaならクラスメソッドの集合として実装されるたぐいのもの。
Mathematicaの上から
In[1]:= RunThrough["./a.out", {lambda->0.633, apertureDiameter->5.0}]なんて入力するとa.outが起動され、その標準入力にRunThroughの第2引数が文字列に変換されて(この場合だと"{lambda -> 0.633, apertureDiameter -> 5.0}")渡される。
-parseは標準入力からこれを読み込んで、パラメータを設定する。こんなの
static NSString *nextToken(); static char buf[256]; static NSString *reals = @"-0123456789."; @implementation SMathematicaIO - (int)parse { static NSString *rule = @"->"; NSCharacterSet *numset = [NSCharacterSet characterSetWithCharactersInString:reals]; SParameters *par = [SParameters currentParameters]; NSString *str; NSCharacterSet *alnum = [NSCharacterSet alphanumericCharacterSet]; while ((str = nextToken()) != nil) { if ([str rangeOfCharacterFromSet:alnum].location != NSNotFound) { if ([str isEqualToString:kHelpString]) return kMathematicaNeedsHelp; if ([par querryFor:str] != nil) { NSString *r = nextToken(); if ((r != nil) && [r isEqualToString:rule]) { NSString *val = nextToken(); if ((val != nil) && ([val rangeOfCharacterFromSet:numset].location != NSNotFound)) { NSNumber *num = [NSNumber numberWithDouble: [val doubleValue]]; [par setValue:num for:str]; } else return kParseError; } else return kParseError; } } } return kProcessedSuccessfully; }おお、なんかいかにもプログラミングしてるみたい!これは、nextToken()という標準入力に入った文字列をトークンに分解する関数を呼んでwhileループを一回りしたら一つパラメータが設定される、というもの。
このnextToken()は、実はいんちきをした。こんなの。
static NSString *nextToken() { char *bp = buf; char *be; if (scanf(" %s", buf) > 0) { if (*bp == '{') bp ++; be = bp + strlen(bp) - 1; if ((*be == '}') || (*be == ',')) *be = '\0'; return [NSString stringWithCString:bp encoding:NSASCIIStringEncoding]; } else return nil; }禁断のscanf()を使った。formatに" %s"とするとisspace()がTRUE(スペース、タブ、改行など)で区切られたのを切り出す。RunThrough[]は式の間にスペースを必ず入れるのでそれを利用している。ただし、Listを表す括弧"{"、"}"やコンマの間にはスペースを入れないので、それを切り離す必要があるが、今回はどっちみち必要なくなるのであったら捨てることにした。やりかたはかっこわるい。RunThrough[]が作る文字列しか読まないと決めうちしてるのでこうしたけど、良い子はまねをしてはいけません。
書き出しはもっと簡単。
- (int)writeBack:(NSDictionary *)result { const char *buf = [[result mathematicaStyleDescription] cStringUsingEncoding:NSASCIIStringEncoding]; if (buf == NULL) return kParseError; printf(buf); return kProcessedSuccessfully; }結果として渡されたNSDictionaryに前回作ったmathematicaStyleDescriptionを投げて、それをCの文字列に変換して標準出力に書き出すだけ。NSDictionaryはMathematicaのRule(a->b)の形にするのでRunThrough[]がかえってきたときはMathematicaの上で評価してしまえばいい。
2008-06-22 11:30
nice!(0)
コメント(1)
トラックバック(0)
沒有醫生的處方
cialis 200 dollar savings card http://cialisvonline.com/ Cialis tablets australia
by Online cialis (2018-04-15 05:22)