dDataMin - みる会図書館


検索対象: 月刊 C MAGAZINE 1990年6月号
5件見つかりました。

1. 月刊 C MAGAZINE 1990年6月号

や 8 を含むような平均律数の拡張は , 読みや ゴリズムと呼ぶことにします ) 。前述の例て によるスケールの作成は実用的とはいえず , すいものて、はありません。また , 参照値の は , このアルゴリズムにより , 0 , 5 , 10 , 今回は採用しません。 Dixon-KronmaI のア 中間の数値を読み取ることも難しいといえ 15 , 20 , 25 のスケールが選ばれることにな ルゴリズムと違った方法て、改良したほうが ます。 したがって , この拡張した平均律数 ります。 よいようて、す。 このアルゴリズムの欠点は , スケールの 改良 D ⅸ on - Kronm 引アルゴリズム 利用率が必ずしもよいとはいえない点にあ ります。間隔数 5 の場合て、は , スケールの利 用率は平均て、は約 63 % , 最悪て、 32 % 以下に なってしまいます。たとえば , 1.99 から 10.01 のデータについて間隔数 5 て、スケールを作成 するとき , 0 , 5 , 10 , 15 , 20 , 25 が選択さ れますが , このときのスケールの利用率は 32 % を少し越える程度にしかなりません。 スケールの利用率は入力とし , 与える間 隔の数 N を増やすことて、改良て、きます。しか しながら間隔を 20 へ増加させたところて、 , その利用率は平均ては 68 % , 最悪て、 38 % に しか改善されません。 このアルゴリズムて、スケールの利用率を 改善するもうひとつの方法は , 平均律数の 定義を拡張して , 基準とする数字を増やす ことてす。たとえば平均律数を 1 , 2 , 3 , 4 , 5 , 8 とその 10 のべき乗倍の数とすれば , き め細かなスケールが設定てき , スケールの 利用率が向上します。 この根本的な改良を行う前に もう一度 1 , 2 , 5 とその 10 のべき乗倍の数の平均律数 について考えてみましよう。すべて 10 の約 数の積て、あるのて、 , 10 のべき乗倍の数とそ の整数倍の数が参照値から外れないことが 保証されます。たとえば , 1 , 2 , 5 の平均律 数によるスケール作成て、は , 8 , 9 , 10 , 11 , 12 8 , 10 , 12 , 14 , 16 5 , 10 , 15 , 20 と , 10 とその整数倍を , 参照値として必ず 含んています。 前に述べた 3 と 8 を含む拡張した平均律数 によるスケールは , 3 と 8 が 10 の約数て、はな いのて , 参照値に 10 とその倍数を選ばない ことも起こり得ます。たとえば , 6 , 9 , 12 , 15 ( 10 を選んていない ) 6 , 8 , 16 , 24 ( 10 と 20 を選んていない ) などからわかるように List 1 : void scDixonKronmaI( dDataMin, dDataMax, nExactIntervals, pdScaIeMin, pdScaIeMax, pnActuaI ) 2 : ( 入力 ) データ最小値 * / 3 : double dDataMin; ( 入力 ) データ最大値 * / 4 : double dDataMax; ( 入力 ) 使用する間隔数の正確な数 * / 5 : i nt nExactIntervals; ( 出力 ) スケール最小値 * / 6 : double *pdScaIeMin; ( 出力 ) スケール最大値 7 : double *pdScaIeMax; ( 出力 ) 使用する間隔数 * / 8 : *pnActua に i nt double dIntervalSize; int i ! ndex : doub dPower0fTen; double dNiceNum; int n し oMult; nAdj し 0MuIt; int int n H i Mu は : nAdjHiMult; 17 : int 18 : nActua Ⅱ ntervals : int int nDiffIntervals; 20 : int nAdjIntervaIs : assert( dDataMin く dDataMax ) : assert( nExactIntervals 〉 = 2 ) : 22 : / * 取り得る最小の間隔のサイズ引 nterva 1 S i 2 e の計算 * / 23 : ( dDataMax ー dDataMin ) / nExactIntervals; 24 : dIntervalSize / * d I nterva 燔 i ze より大きいうちで最小の平均律数を計算 * / 25 : for( dNiceNum=scFirstNiceNum(dIntervalSize, &ilndex, &dPower0fTen) : 26 : dNiceNum く dIntervalSize; dNiceNum=scNextNiceNum(pdSet, SET-LEN, &ilndex, &dPowerOfTen)) 28 : 29 : 30 : 32 : 33 : 34 : 35 : 36 : 38 : 39 : 40 : 42 : 43 : 44 : 45 : 46 : 48 : 49 : 52 : 53 : 54 : 55 : 56 : 58 : 59 : 60 : 62 : 64 : 65 : 66 : 67 : 68 : } / * 求めた平均律数によりスケールを作成する * / scCalcExtLabeI (dDataMin,dDataMax, dNiceNum,&n し oMult,&nHiMult) : / * 入力された間隔数を超えるまで、新しい数値をもとにスケールを / * 再作成し続ける while( nHiMuIt -n し 0MuIt 〉 nExactIntervals ) { dNiceNum = scNextNiceNum(pdSet. SET_ し EN, &iIndex,&dPower0fTen) : scCalcExt し abel (dDataMin,dDataMax,dNiceNum, &nLOMult, &nHiMult) : / * データをカバーする間隔数の計算 * / nActualIntervals=nHiMult nLoMul t; / * 追加された間隔の基準を考慮して低い倍数と高い倍数を調整する / * センタリングのための調整 nDiffIntervals=nExactIntervals-nActualIntervals; nDiffIntervaIs / 2 : nAdjIntervaIs i f ( nD i ff lnterva 1 s & 1 ) { / * nDiffIntervaIs が奇数なら、外部へスケールを延ばす * / if( dDataMi n-n し oMult*dN iceNum く nHiMult*dN iceNum-dDataMax) { nAdjIntervaIs + + : nAdj し oMuIt = n し 0MuIt - nAdjIntervals; nAdjHiMuIt = nAdj し oMult 十 nExactIntervals; / * 負の数を含まないデータのとき負のスケールに調整されるのを避ける if( nAdj し oMuIt く 0 & & n し oMult > = 0 ) { nAdjLOMuIt = 0 : nAdjHiMult = nExactIntervals; / * 正の数を含まないデータのとき正のスケールに調整されるのを避ける if( nAdjHiMuIt > 0 & & nHiMuIt ← 0 ) { nAdjHiMuIt = 0 : nAdj し 0Mult = -nExactlntervals : / * スケールに関する出力値を計算する * / *pdScaleMin = nAdj し oMult * dNiceNum, *pdScaIeMax = nAdjHiMuIt * dNiceNum; *pnActuaI = nExactI ntervals : 平均律スケールの作成 31

2. 月刊 C MAGAZINE 1990年6月号

Lewa 「 t のアルゴリズム アレゴリズムの改良 Dixon-Kronmal のアルゴリズムが , 入力 として要求する間隔の数を正確に与えて , その間隔の数てスケーリングすることが , スケールの最適化を妨げるいちばんの要因 てあると考えられます。いいかげんな間隔 の数を指定すると , ムダな間隔をもっスケ ールが出力されることは誰て、も予想がっく と思います。例をあげれば , 間隔の数を 5 と して , 7 から 18 の範囲のデータのスケール作 成を考えると , Dixon-Kronmal のアルゴリ ズムは 0 , 5 , 10 , 15 , 20 , 25 のスケールを 出力しますが , これてはスケールの利用率 は 44 % しか得られません。 7 から 18 の範囲のデータに関して , ムダな 間隔を含まない平均律スケールを作成する ことは不可能てはありません。たとえば , 最小値と最大値と平均律数を与えることて , そのようなスケールが作成て、きます。これ は最小値以下てもっとも大きい平均律数の 倍数にあたる数と , 最大値以上てもっとも 小さい平均律数の倍数を求めて , スケール の最小値と最大値とし , その間に存在する 平均律数の倍数すべてを参照値とすること て実現されます。 ムダな間隔を排除することは , すなわち スケールの利用率を改善することて、あると もいえます。ムダな間隔をもたないように する唯一の方法は , 間隔の数に柔軟性をも たせて , 最適な値に適時変えてしまうこと て、す。 これから述べるアルゴリズムのすべてが , ムダな間隔を含まない平均律スケールを作 成する (List1) ものてす。しかし , それぞ れのアルゴリズムは , 使用する間隔数の調 整の仕方において異なったものて、す。とい っても , それぞれのアルゴリズムの主要な 働きは , ューザが指定した間隔数を満足さ せるような最適な平均律数を決定すること てあり , 同じものてす。 32 CMAGAZINE 19 6 Composin •+MeII-Tempered Liner 5 0 厄 5 34 : } List 33 : 32 : 31 : 30 : 29 : 28 : 26 : 25 : 24 : 23 : 22 : 20 : 18 : 17 : 14 : 8 : 5 : 2 : 1 : int 7 : double 6 : double int 4 : double 3 : doub 1 e VOid scLewart( dDataM i n, pdScaIeMi n, dDataMin; dDataMax; nApproxlntervals : *pdScaIeMin : *pdScaIeMax : *pnAc tua に dDataMax, nApproxlnterval s, pdScaIeMax, pnActual ) ( 出力 ) 間隔の数 ( 出力 ) スケールの最大値 ( 出力 ) スケールの最小値 ( 入力 ) 問隔の大まかな数 ( 入力 ) データ最大値 ( 入力 ) データ最小値 double int double double int int dIntervalSize; ilndex; dPower0fTen; dNiceNum : nLoMult; nHiMult; assert( dDataMi n く dDataMax ) : assert( nApproxIntervaIs 〉 = 2 ) : 取り得る最小の間隔のサイズの計算 (dDataMax-dDataMi n) /nApproxI nterval s : dlnterval Size / * 取り得る最小の数に近い平均律数をみつける / * 値はループをプレークしたときの値として得る * / for( dNiceNum=scFirstNiceNum( dIntervalSize, &ilndex, &dPowerOfTen ) : sqrt(pdSet[iIndex]*pdSet[iIndex + (]) * dPowerOfTen く dlntervaISize; dNiceNum = scNextN iceNum (pdSet, SET- し EN, &i lndex, &dPowerOfTen) ) / * 求めた平均律数でスケールを作成 * / scCalcExt し abel ( dDataMin, dDataMax, dNiceNum, &n し 0MuIt, &nHiMult ) : / * スケールに関する出力値の計算 * / = nHiMult ー n し oMult; *pdScaIeMax = nHiMuIt * dNiceNum; *pdScaleM in = n し OMult * dNiceNum; *pnÅctual wart のア丿レゴリズム もうひとつのアルゴリズムの改良版とし ているだけなのてす。 間隔 N を適当に少なくしたり , 増やしたりし を施しているわけて、はなくて , 与えられた す。しかし , このために特別変わった処理 ば , スケールの利用率が画期的に向上しま Lewart のアルゴリズム (List2) を用いれ なります。 通常 , N / から N / + 2 まて、の数と 結果として得られるスケールの間隔は , 求める も近い間隔数を作るような平均律数を 問隔数 N を与えたとき , 間隔 N にもっと ・データの最小値と最大値とおおまかな ムを提案しています。 C. W. Lewart は , 次のようなアルゴリズ ア丿レゴリズム と取大問隔数指定 て , ューザが必要とする間隔の最大値を指 定する方法 (List3) も考えられています。 のようなアルゴリズムが便利て、あるという 状況は , 数多く考えることがて、きます。 たとえば , 垂直座標を描くときのことを 考えてみましよう。はじめに , 描こうとす る垂直方向の長さは , 叶インチしか与えら れていなく , その間に座標軸とラベルを描 かなければならないとします。さらに , 参 照値のラベルはインチの高さのキャラクタ て、 , 上下に隣接するラベルとはインチの隙 間をもって描かれるとしましよう。この条 件て、は , スケールの間隔は最大て、 10 個しか とることがてきません ( ラベルをいくつ描く ことがて、きるかを考えれば , 10 のラベルの キャラクタの高さが 10 >< インチて , その 9 つの間隔が 9x インチ , 合わせて 4 亭インチ て、す ) 。このような条件て、は Lewart のアルゴ リズムは適用てきません。もし適用すると , 間隔数 10 を指定しても , 出力の間隔数は最 適値に 17 などを選ぶ可能性があるからてす。

3. 月刊 C MAGAZINE 1990年6月号

List5 るならば , スケールの最小値と最 大値にデータが乗っかっているよ うなグラフはかえって見にくい。 できれば余裕をもったスケールの 作成を行いたい ・スケールの最小値と最大値を固定 する必要がある状況も起こり得る。 たとえば , 最小値を 0 に固定する必 要があることが多い。バーセンテ ージを示す棒グラフでは , スケー ルの最小値を 0 にすれば , 30 % のデー タが 15 % のものの倍であることがわ かりやすくなる これらの特殊なケースて、は , アルゴ リズムを適用する前にデータの最小値 と最大値を適当に変えることて、対応す ることは可能てす。 文献 36 : / * 外部ラベルのスケールの計算 * / scCaIcE%tLabel( dDataMin, dDataMax, dNiceNum, pnLoMu は , pnHi Mult) 37 : void / * ( 入力 ) データの最小値 38 : double dDataMin; / * ( 入力 ) データの最大値 39 : double dDataMax; / * ( 入力 ) 平均律数 40 : double dNiceNum; / * ( 出力 ) スケール最小値の倍数 * / 41 : int *pn し oMult; / * ( 出力 ) スケール最大値の倍数 * / 42 : i nt *pnHiMult; 43 : { / * 小さい倍数の計算 * / *pnLOMuIt=(int)floor( dDataMin / dNiceNum ) : 45 : / * 数値のチェック * / 46 : if( (double) (*pn し oMult + 1) * dNiceNum ← dDataMin ) { (*pn し 0MuIt) 十十 : 48 : 49 : / * 大きい倍数の計算 * / 50 : ( int) cei 1 ( dDataMax/dN iceNum ) : *pnHiMult / * 数値のチェック * / 52 : if( (double) (*pnHiMult-l)*dNiceNum > ニ dDataMax ) { 53 : (*pnH iMult) ー 54 : 55 : 56 : } 57 : / * 内部ラベルのスケールの計算 * / scCaIcIntLabeI ( dDataMin, dDataMax, dNiceNum, pn し oMult, pnHiMult ) 58 : void 59 : double dDataMin; / * ( 入力 ) データ最小値 60 : double dDataMax; / * ( 入力 ) データ最大値 61 : double dNiceNum; / * ( 入力 ) 平均律数 62 : i nt / * ( 出力 ) 最小参照値の倍数 * / *pn し oMult; 63 : i nt / * ( 出力 ) 最大参照値の倍数 * / *pnHi Mult; 64 : { 65 : / * 小さい倍数の計算 * / 66 : *pn し oMult=(int)cei 1 (dDataMin/dNiceNum) : / * 数値のチェック * / if( (double) ( *pn し oMult-1 )*dNiceNum > = dDataMin ) { 68 : (*pn し OMuIt) ー 69 : / * 高い倍数の計算 * / *pnHiMult=(int) floor(dDataMax/dNiceNum ) : 73 : / * 数値のチェック * / if( (double)( *pnHiMult 十 1)*dNiceNum く = dDataMax ) { (*pnH iMult) + + : 75 : 76 : 78 : / * doub を整数のべき乗に変える 79 : / * Robert Sedgewick,Algorithms, 第 1 版 , pp. 46 ー 47 のものを適合させた * / 80 : static double scPower( dRoot, iExponent ) 81 : double dRoot; / * ( 入力 ) べき乗にするときの根 * / 82 : i nt / * ( 入力 ) 変換の根に対するべき数 * / iExponent; 84 : double dResult; 85 : / * 負の指数のために根を逆数にして正の指数を用いる * / 86 : if( iExponent く 0 ) { 87 : = 1.0 / dRoot; dRoot 88 : -iExponent; i Exponent 89 : / * 倍数の作る * / 90 : dResult ー while( iExponent ) { 92 : i f ( i Exponent & 1 ) { 93 : 94 : dResult * = dRoot; 95 : 96 : iExponent > 〉 = 1 : if( iExponent ) { 98 : dRoot * = dRoot: 99 : 100 : 101 : 102 : 103 : } 1. Dixon W. J. and R. A. Kronmal, $The Choice of Origin and ScaIe for Journal of the ACM 12 ( 2 ) : Graphs , 259 ー 261 , Apr. 1965. 2. Lewart , C. R. "Algorithms SCALEI , SCALE2 , and SCALE3 for Determina tion Of Scales on Computer ー Generated Plots , 〃 Communications of the ACM 16 ( 10 ) : 639 ー 640 , Oct. 1973. 3 . CIeveIand, WiIIiam S. Thr Ele ments 0f Graphing Data. Belmont, CaIif. : Wadsworth , 1985. 4 . Giammo, T . "A Mathematical Method for the Automatic Scaling 0f a Function, Journal of the ACM 11 ( 1 ) : 79 ー 83 , Jan. 1964. Tom Steppe 氏は , ミシガン州の Ann Arbor のソフトウェア工ンジニアて , Meta 囲外にデータを置くことを許して System 社て℃ ASE のワークベンチを開発し も , おもなデータのスケール作成 ています。 を優先する必要がある ・データをプロットすることを考え return( dResult ) : ケール作成に関するおもしろい考え方 があります。 ・大きく外れた値を少量しかもたな いデータについては , スケール範 平均律スケールの作成 35

4. 月刊 C MAGAZINE 1990年6月号

前に述べた例において , 間隔数 17 て、はラ ベルをすべて描けないことはいうまて、もあ りません。間隔数が 10 を越えないことを保 証するために , 入力する間隔の数を 5 くらい て、指定すれば , Lewart のアルゴリズムを使 用することも可能て、すが ( 間隔数 5 を指定す ると出力の間隔値は 9 を越えないことや , 6 を入力したときの出力の間隔値は 11 を越え なことは保証されている ) , 計算が厄介て、 , いい加減な感じを受けます。 この問題を解決する間隔の最大値を指定 て、きるアルゴリズムの例を示してみましよ ・データの最小値と最大値と問隔数の最 大値 N の入力値に対して , 問隔数が N 以 下でスケールの利用率が最大となるよ うな平均律数を求める ちょっと見ただけて、はうまく働いて , す べての場合に適用て、きるかのように思えま す。しかし , まれに , 入力した間隔数 N より かなり小さな間隔数を出力してしまうこと もあるのて、す。たとえば , 最大の間隔数を 10 と入力し , 0 から 15 まて、の範囲をとるテ タのスケールを作成するとき , このアル土 リズムて、はスケールの利用率を 100 % とする ことがて、きますが , このスケールは 0 , 5 , 10 , 15 と間隔数はわずか 3 となってしまうの て、す。 このアルゴリズムは非常にすばらしいス ケールの利用率を実現してくれますが , 小 さな間隔数を出力するおそれがあるのて、 , 使用て、きない場合もあるわけて、す。しかし , この欠点を修正したアルゴリズムて、も , 同 様の利用率を達成することがて、きます。そ のアルゴリズムは , 次のようにシンプルに 記述て、きます ( これを最大値間隔数指定アル ゴリズムと呼ぶことにします ) 。 ・データの最小値と最大値および間隔数 N を与えたとき , N を越えることのない 最大の間隔数をもたらすことのできる 平均律数を出力する 前に述べたアルゴリズムが N 以下の間隔数 て、 , スケールの利用率を最大とする平均律 ( 出力 ) 間隔数 38 : } 平均律スケールの作成 最大間隔数指定アルゴリズム List 1 : 2 : 5 : 8 : 13 : 15 : 16 : 17 : 19 : 20 : 21 : 22 : 24 : 25 : 26 : 28 : 29 : 30 : 31 : 32 : 33 : 34 : 36 : 37 : i nt 7 : doub I e 6 : doub 1 e i nt 4 : doub 1 e 3 : double VOid scMaxIntervaI ( dDataMin, dDataMax, nMaxIntervaIs, pdScaIeMin, pdScaleMax, pnActuaI ) dDataMin; dDataMax; nMaxI nterva ls; *pdScaleMin; *pdScaIeMax : *pnActual; ( 入力 ) データ最小値 ( 入力 ) データ最大値 ( 入力 ) 間隔数の最大値 ( 出力 ) スケールの最小値 ( 出力 ) スケールの最大値 dIntervalSize; i lndex : dPower0fTen; dNiceNum; n し oMult; nHiMult; assert( dDataMin く dDataMax ) : assert( nMaxIntervaIs > ニ 2 ) ; int int double double int double 取り得る最小の間隔のサイズの計算 (dDataMax-dDataMin) / nMaxIntervaIs; dIntervalSize / * dIntervaISize よりおおきい数で最小の平均律数を計算 for( dNiceNum=scFirstNiceNum(dIntervaISize, &ilndex, &dPower0fTen ) : dNiceNum く dIntervalSize; dNiceNum=scNextNiceNum(pdSet, SET-LEN, &ilndex, &dPowerOfTen) ) / * 求めた平均律数を用いてスケール作成 * / scCaIcExt し abel ( dDataMin, dDataMax. dNiceNum, &nLOMuIt, &nHiMuIt ) : / * 入力の間隔数を超えるまで求めた平均律数でスケール再作成 * / while( nHiMuIt-nLoMuIt 〉 nMaxIntervals ) { dNiceNum=scNextNiceNum(pdSet, SET_ し EN, &ilndex, &dPower0fTen ) : scCaIcExtLabeI (dDataMin. dDataMax, dNiceNum, &n し oMul,t, &nHiMult) : / * スケールに関する出力値の計算 * / = n H i Mu は一 n し oMu は : *pdScaIeMax = nHiMuIt * dNiceNum; *pdScaIeMin ニ nLOMuIt * dNiceNum; *pnActual 数を求めるのに対して , このアルゴリズム は N を越えることのない最大の間隔数をもた らす平均律数を求めています。 この最大間隔数指定アルゴリズムは , ス ケール利用率最大のアルゴリズムに近い良 質のスケールを得ることがて、きますが , さ らに間隔数が極端に小さくなってしまう欠 点を改善しています。たとえば , 前述の間 隔数の最大値 10 て、 , 0 から 15 まての範囲のデ ータに対して , このアルゴリズムてはスケ ールの利用率を数 % 犠牲にして , 0 , 2 , 4 , 6 , 8 , 10 , 1 , 2 , 14 , 16 のスケールを出力します。 間隔数の最大値を N と指定したときに のアルゴリズムて、は N / 2.5 以上の間隔数を確 保します。間隔数 5 の場合 , スケールの利用 率は平均て、 76 % , 最悪て 50 % 程度となりま す。 部ラベリング アレゴリズム , こまて、述べてきたアルゴリズムは , す べてスケールの最小値と最大値が参照値の 中に含まれているという仮定て、成り立って いました。多くの場合 , これは必要条件と なっています。しかし , この件に関してフ レキシプルに対応てきる内部ラベリング法 ( List4 ) を用いれば , つねにスケールの利用 率を 100 % にすることがてきます。 この方法ては , スケールの最小値と最大 値が平均律数て、なくてもかまわなくなり , 代わりにこれらがデータの最小値と最大値 そのものになります ( したがって , スケール の利用率は 100 % となります ) 。 さらに このスケールの最小値と最大値 の間の参照値 ( これは平均律数てなければな りません ) がラベリングされます。ここて少 33

5. 月刊 C MAGAZINE 1990年6月号

Com 05i れ WeII-Tempered れ e 「 5 ( 0 厄 5 なくともふたつの参照値がラベリングされ なければ , そのスケールは使いものになり ません。参照値ひとって、は , その参照値以 外の点の値を読み取ることがてきないから てす。内部ラベリング法においても , 間隔 のおおまかな数や間隔の数の最大値を指定 するようないろいろなアルゴリズムが考え られますが , 本稿て、は間隔数の最大値を指 定するアルゴリズムだけについて検討して みました。 さあなたの選択は スケールの作成に関する解析は , これま て、数多くの発表がなされてきました。それ ら発表の中て、は , 平均律スケールが数多く 作られ , 参照値として平均律数が使用され てきました。また , すべてのアルゴリズム が , データの最小値と最大値および間隔の 数に関する数値を入力する必要があるもの ばかりてすから , 使用するプログラムにお いて , ひとつのアルゴリズムを適時ほかの アルゴリズムに置き換えることも簡単にて、 きます。紹介したアルゴリズムのうち最適 なものを選択する指標は下記のようになり ます。 スケールの最小値と最大値を参照値と したいときは , 以下の ( 1 ) から ( 4 ) のう ちから選ぶ ( 1 ) 間隔の数を正確に指定したいとき は , 改良 Dixon ー K 「 onm のアルゴ リズム ( 2 ) おおまかな間隔の数を指定すると きは , Lewa 「 t のアルゴリズム ( 3 ) 間隔の最大値を指定するときは , 間隔数最大アルゴリズム ( 4 ) これら以外の条件では , 各自検討。 一方 , スケールの最大値と最小値 が参照値でなくてもかまわないと きは , 内部ラベリングアルゴリズ ムを選択 今回はふれることがてきませんて、し たが , これらのほかに , 次のようなス 内部ラベリングアルゴリズム List sclnternal ( dDataMin, dDataMax, nMaxIntervals, 1 : vo i d pdRefMin, pdRefMax, pnActual ) 2 : / * ( 入力 ) データ最小値 * / 3 : double dDataMin; / * ( 入力 ) データ最大値 * / 4 : double dDataMax; / * ( 入力 ) 間隔の最大値 * / nMaxIntervaIs; 5 : i nt / * ( 出力 ) 最小参照値 6 : double *pdRefMin; / * ( 出力 ) 最大参照値 7 : double *pdRefMax; / * ( 出力 ) 参照値間隔の数 * / 8 : i nt *pnActual; double dIntervalSize; i I ndex; int double dPower0fTen; 12 : double dNiceNum; 13 : nLoMult; 14 : int nH i Mul t : 15 : i nt assert( dDataMin く dDataMax ) : assert( nMaxIntervaIs > = 5 ) : 17 : / * 取り得る最小の間隔のサイズの計算 * / (dDataMax-dDataMin)/nMaxIntervaIs; dIntervalSize ー 20 : / * dInternalSize より大きいうちで最小の平均律数を計算する * / 21 : for( dNiceNum ー scFirstNiceNum( dIntervalSize. &ilndex, &dPowerOfTen ) : 22 : dNiceNum く dIntervaISize; 23 : dNiceNum = scNextNiceNum( PdSet, SET-LEN, &i lndex. &dPowerOfTen ) ) 24 : 25 : 26 : 28 : 29 : 30 : 31 : 32 : 33 : 34 : } / * 求めた平均律数によるスケール作成 * / scCalcIntLabeI ( dDataMin, dDataMax, dNiceNum, &nLOMult, &nHiMult ) : / * 参照値の最大値と最小値の計算 * / *pdRefMin=n し OMu It*dN i ceNum : *pdRefMax=nH iMu It*dN i ceNum : *pnActual=nHiMu lt-n し OMult : 各アルゴリズムで使用する関数 List 1 : / * 平均律数の初期値を計算する * / 2 : double scFirstNiceNum( dIntervalSize• pilndex• pdPowerOfTen ) / * ( 入力 ) 間隔のサイズ 3 : double dIntervalSize; / * ( 出力 ) 平均律数の基数配列インデックス * / 4 : i nt *pilndex; / * ( 出力 ) 平均律数をつくる 10 のべき乗の数 * / 5 : double *pdPower0fTen; 7 : int i Exponent: / * 10 のべき乗初期値 * / 8 : (int)floor( log10(dIntervalSize) ) : 9 : iExponent / * 数値のチェック * / 10 : *pdPower0fTen = scPower( 10.0. iExponent ) : if( *pdPower0fTen * 10.0 ← dIntervaISize ) { 12 : *pdPower0fTen * = 10.0 : 14 : / * 初期インデックスは常に 0 * / *piIndex=0; 16 : return ( *pdPower0fTen ) : 17 : 18 : } 19 : / * 平均律数の次の候補値計算 * / 20 : double scNextNiceNum( pdSet, nSet. p i lndex, pdPower0fTen ) / * ( 入力 ) 倍数のセット 21 : double *pdSet; / * ( 入力 ) セットの要素の数 22 : i nt nSet : / * ( 入出力 ) 平均律の基数配列のインデックス * / 23 : int *pilndex; / * ( 入出力 ) 平均律数の 10 のべき乗の数 24 : double *pdPower0fTen; / * 基数のインデックスを増やす * / 26 : (*pilndex) + 十 : / * 基数のインデックスが最大数を超えたなら 28 : / * インデックスを 0 にリセットし 10 のべき乗を増やす * / 29 : if( *pilndex > = nSet ) { 30 : *pilndex *pdPower0fTen * = 10.0 : 32 : return ( pdSet[*pi lndex] * *pdPower0fTen ) : 34 : 34 CMAGAZINE 19 6