SSブログ

照度分布計算その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の上で評価してしまえばいい。


nice!(0)  コメント(1)  トラックバック(0) 

nice! 0

コメント 1

Online cialis

沒有醫生的處方
cialis 200 dollar savings card http://cialisvonline.com/ Cialis tablets australia
by Online cialis (2018-04-15 05:22) 

コメントを書く

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

トラックバック 0

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