// 長方形の対角線の長さの標準偏差を求める class Diagonal { public static void main(String[] args) { double epsilon = 1e-10d; // 平方根の計算精度 // 長方形の幅と高さが与えられているものとする double widths[] = new double[] { 20, 18, 24, 31, 17 }; // 長方形の幅 double heights[] = new double[] { 4, 5, 7, 2, 3 }; // 長方形の高さ int size = widths.length; // 長方形の個数 double diagonalSum = 0; // 対角線長の合計を覚える変数 double diagonalSqrSum = 0; // 対角線長の2乗の合計を覚える変数 // 各長方形の対角線長と2乗値を計算しつつ合計を求める for (int i = 0; i < size; i=i+1) { // 三平方定理より、対角線長の2乗を計算 double diagonalSqr = widths[i]*widths[i] + heights[i]*heights[i]; // 対角線長の2乗の合計に加算 diagonalSqrSum = diagonalSqrSum + diagonalSqr; // ニュートン法によって diagonalSqrSum の平方根を求める double diagonal = diagonalSqr/2;// 平方根の推定値 double delta = diagonalSqr - diagonal*diagonal; // 誤差 while (epsilon < Math.abs(delta)) { // 誤差が大きい間改良を続ける diagonal = diagonal/2 + diagonalSqr/2/diagonal; // ニュートン法 delta = diagonalSqr - diagonal*diagonal; // 誤差を更新 }// ここまでが平方根計算 diagonalSum = diagonalSum + diagonal; // 対角線長の合計を更新 diagonalSqrSum = diagonalSqrSum + diagonalSqr; // 対角線長の2乗の合計 } double diagonalAve = diagonalSum/widths.length; // 対角線長の平均値 // 標準偏差の2乗値(公式より) double stdDevSqr = diagonalSqrSum/widths.length - diagonalAve*diagonalAve; // 標準偏差を平方根計算で求める double stdDev = stdDevSqr/2;// 推定値 double delta = stdDev*stdDev - stdDevSqr; // 誤差 while (epsilon < Math.abs(delta)) { // 誤差が大きい間、改良を続ける stdDev = stdDev/2 + stdDevSqr/2/stdDev; // ニュートン法 delta = stdDevSqr - stdDev*stdDev; // 誤差を更新 }//ここまでが平方根計算 System.out.println("対角線長の標準偏差は"+stdDev+"です。"); } }
Hidehiko Masuhara, November 2000