すごく便利!ブロック構文を使って式を得る
アプリ内でたくさんの式を扱うとするよ。
これは「赤ちゃんの成長グラフ」で使う近似式なんだけど、これをどういう風にアプリ内に持っておけばいいんだろう?って思ってさ。
最初はクラスメソッド(クラス名を'ApproxEquation'ってしとくよ)にしてこんな感じにしてたんだよ。
条件としては性別や身長or体重とか、何歳から何歳までに使える式だとかまあそういうのがいくつもあるんだ。
呼び出し元でそういう条件全てとxxを指定してコールするんだけど、値をまとめて欲しい時があるんだよ。
近似式なので近似曲線を描こうとすると、表示する範囲内でxxを100分割して少しずつ大きくしていくxxに応じたyyを得る、とかまあそんなのね。よくあるでしょ。
これを実装しようと
条件判定を何回もするのってなんか無駄じゃない?
結構な計算量になるからなんとか高速化したいと思っていろいろ調べたらさ、ブロック構文で実現できるみたいなんだ。
要は式を取ってくるってこと。
するとさっきの呼び出し元は先に式を得てるからループ内で条件判定する必要がないことになるんだ。
Approximationってのは次のように定義されるブロック変数だ。
式自体を定義して、条件に応じて必要な式を返すクラスメソッドはこんな感じになる。
yy = -34.9456869602161078*pow(xx,0) +110.1711990130272056*pow(xx,1) -42.2603582000001268*pow(xx,2) +8.8934314905976777*pow(xx,3) -1.0504024065048447*pow(xx,4) +0.0697635676738542*pow(xx,5) -0.0024233376396043*pow(xx,6) +0.0000341459080453*pow(xx,7);↑こんな感じのがたくさんあるんだ。
これは「赤ちゃんの成長グラフ」で使う近似式なんだけど、これをどういう風にアプリ内に持っておけばいいんだろう?って思ってさ。
最初はクラスメソッド(クラス名を'ApproxEquation'ってしとくよ)にしてこんな感じにしてたんだよ。
+(double)getYforX:(double)xx option1:(int)option1 option2:(int)option2 … { double yy; if (option1 == 0) { if (option2 == 0) { switch(option3) { //略 return yy; }↑かなりざっくりだけど、いろんな条件で式を場合分けする必要があるんだよ。
条件としては性別や身長or体重とか、何歳から何歳までに使える式だとかまあそういうのがいくつもあるんだ。
呼び出し元でそういう条件全てとxxを指定してコールするんだけど、値をまとめて欲しい時があるんだよ。
近似式なので近似曲線を描こうとすると、表示する範囲内でxxを100分割して少しずつ大きくしていくxxに応じたyyを得る、とかまあそんなのね。よくあるでしょ。
これを実装しようと
for (int ii=0;ii < 100;ii++) { double xx = offsetX + ii*unitX; double yy = [ApproxEquation getYforX:xx option1:MALE option2:HEIGHT … //配列に入れていくとか }こんな感じに記述すると、毎回呼び出し先でいくつも条件判定をしてから計算されることになるよね。
条件判定を何回もするのってなんか無駄じゃない?
結構な計算量になるからなんとか高速化したいと思っていろいろ調べたらさ、ブロック構文で実現できるみたいなんだ。
要は式を取ってくるってこと。
するとさっきの呼び出し元は先に式を得てるからループ内で条件判定する必要がないことになるんだ。
{ Approximation approximation = [ApproxEquation getEquationOption1:MALE option2:HEIGHT … for (int ii=0;ii < 100;ii++) { double xx = offsetX + ii*unitX; double yy = approximation(xx); //配列に入れていくとか } }↑ああ、なんかすっきりするよね!
Approximationってのは次のように定義されるブロック変数だ。
typedef double (^Approximation)(double xx);↑'Approximation'って変数名でdouble xxをもらってdoubleの値を返すってことだよね。
式自体を定義して、条件に応じて必要な式を返すクラスメソッドはこんな感じになる。
+(Approximation) getEquationOption1:(int)option1 option2:(int)option2 … { Approximation approximation; if (option1 == 0) { if (option2 == 0) { switch(option3) { //略 approximation = ^(double xx) { return -34.9456869602161078*pow(xx,0) +110.1711990130272056*pow(xx,1) -42.2603582000001268*pow(xx,2) +8.8934314905976777*pow(xx,3) -1.0504024065048447*pow(xx,4) +0.0697635676738542*pow(xx,5) -0.0024233376396043*pow(xx,6) +0.0000341459080453*pow(xx,7); }; //略 return approximation; }↑こんな構成で式を返す。便利だねえ!
スポンサーサイト