U統計量の分布     Last modified: May 15, 2002

 再帰呼び出しをすると簡単に書くことができても,時間がかかりすぎるのをどうにかしたい。そこで,時間と空間のトレードオフという常套手段をとります。

 以下のスクリプト(プログラム)は処理時間が短い代わりに,メモリをたくさん消費します。80?86系のマシンではつらいでしょうが,Mac だと軽いですね。
 n1, n2 が 20 以下の全ての場合の分布表が Macintosh Quadra 840AV で,結果をファイルに書き出すときは90 秒でできます。u_table.awk では,n1=n2=10 だけの分布表を求めるだけで 90 秒かかったわけですから大きな違いですね。

このスクリプトを実行すると,かなり大きなファイル(1.3MB)ができあがります。


# u-statistics2.awk

BEGIN {
   LIMIT = 20  # 上限値の設定
   for (n1 = 1; n1 <= LIMIT; n1++) {
       if (n1 >= 3) { # 不要なメモリを解放
           for (i = 0; i <= n1-2; i++) {
               for (j = 0; j <= i*(n1-2); j++) {
                   delete u[n1-2,i,j]
               }
           }
       }
       u[n1,0,0] = 1
       for (n2 = 1; n2 <= n1; n2++) {
           printf "\n\n n1 = %i   n2 = %i\n\n", n1, n2
           m1 = max(n1, n2-1)
           m2 = min(n1, n2-1)
           for (i = 0; i < m1*m2+1; i++) {
               u[n1,n2,i] = u[m1,m2,i]
           }
           m1 = max(n1-1, n2)
           m2 = min(n1-1, n2)
           num = m1*m2+1
           d_start = n1*n2-num+1
           for (i = 0; i < num; i++) {
               u[n1,n2,d_start+i] += u[m1,m2,i]
           }
           denom = 1/combination(n1+n2, n2)
           cum2 = 1
           cum1 = 0
           printf "%3s:%10s  %13s%13s%13s\n",
           "U", "度数", "確率", "累積1", "累積2"
           for (i = 0; i < n1*n2+1; i++) {
               x = u[n1,n2,i]
               y = x*denom
               cum1 += y
               printf "%3i:%10i  %13.10f%13.10f%13.10f\n",
               i, x, y, cum1, cum2
               cum2 -= y
           }
       }
   }
}

# n から m (n ≧ m ≧ 0 )を取り出す組合せを求める
# 使用例: x = combination(10, 5)

function combination(n, m,     i, c) 
{
   c = 1
   k = min(n, n-m)
   for (i = 1; i <= k; i++) {
       c *= (n-i+1)/i
   }
   return c
}

# x, y の大きい方を求める
# 使用例: x = max(10, 5)

function max(x, y)
{
   return (x > y) ? x : y
}

# x, y の小さい方を求める
# 使用例: x = min(10, 5)

function min(x, y)
{
   return (x < y) ? x : y
}


・ 直前のページへ戻る  ・ E-mail to Shigenobu AOKI