2012-04-15 6 views
1

プログラムは2x2行列の負の要素の平均幾何平均を計算します。私は以下のこのプログラムでコードを理解しようとしています。なぜ著者が書いたものを書いたのですか?このコードは以下の作者がコードマトリックス内の行列の幾何平均値

#include <stdio.h> 
#include <math.h> 

#define ROWS 2 
#define COLS 2 
char * last_geom_err = NULL; 

float geometricMean(float * arr, int rows, int cols){ 
    float neg_mul = 1; 
    int neg_count = 0; 
    float arr_elem; 
    for (int i = 0; i < rows; i++) 
     for (int j = 0; j < cols; j++) 
      if((arr_elem = *(arr + i * cols + j)) < 0){ 
       neg_mul *= arr_elem; 
       neg_count++; 
      } 
    if (neg_count == 0){ 
     last_geom_err = "no negative elements in array"; 
     return 0; 
    } 
    if ((neg_count % 2 == 0) && (neg_mul < 0)){ 
     last_geom_err = "a negative number under the square root of even degree"; 
     return 0; 
    } 
    last_geom_err = NULL; 
    return pow(neg_mul, (float)neg_count); 
} 

int main(){ 
    float arr[ROWS][COLS] = { 
     1., -2., 
     -5., -6. 
    }; 
    printf("Array:\n"); 
    for(int i = 0; i < 2; i++){ 
     for(int j = 0; j < 2; j++) 
      printf("%5.2f ", arr[i][j]); 
     putchar('\n'); 
    } 
    float gm = geometricMean((float*)arr, ROWS, COLS); 
    if (last_geom_err != NULL) 
     printf("#Error of calculation: %s", last_geom_err); 
    else 
     printf("Geometric mean of negative elements of array = %5.2f", gm); 
    return 0; 
} 

なぜこの中であまりにも多くのポインタを書いたもの、それはハード を理解するために見つけるイムのでしょうか?

char * last_geom_err = NULL; 

    float geometricMean(float * arr, int rows, int cols){ 
     float neg_mul = 1; 
     int neg_count = 0; 
     float arr_elem; 
     for (int i = 0; i < rows; i++) 
      for (int j = 0; j < cols; j++) 
       if((arr_elem = *(arr + i * cols + j)) < 0){ 
        neg_mul *= arr_elem; 
        neg_count++; 
       } 
     if (neg_count == 0){ 
      last_geom_err = "no negative elements in array"; 
      return 0; 
     } 
     if ((neg_count % 2 == 0) && (neg_mul < 0)){ 
      last_geom_err = "a negative number under the square root of even degree"; 
      return 0; 
     } 
     last_geom_err = NULL; 
     return pow(neg_mul, (float)neg_count); 
    } 

及びこれ

float gm = geometricMean((float*)arr, ROWS, COLS); 
     if (last_geom_err != NULL) 
      printf("#Error of calculation: %s", last_geom_err); 
     else 
      printf("Geometric mean of negative elements of array = %5.2f", gm); 
     return 0 
+0

何、唯一の整数の指数に負の拠点を扱うので、はNaNを返すこと、しかし

return pow(neg_mul, 1.0/neg_count); 

のようになります特にあなたは理解していないのですか?基本的なC構文を理解していますか? –

+0

@ MarkByers、それは、行列がフラットなメモリ内表現でアクセスされる方法に関係していると思われます( '(float **)'から '(float *)'へのキャストに注意してください)。 – geekosaur

+0

@geekosaurあなたは正しいです。どこかでかなり混乱しています。 –

答えて

2

プログラムはそうでない2×2行列

における負の要素の平均幾何平均を算出します。最初に、通常geometric mean applies only to positive numbers.幾何平均の意味を負の数に拡張することができます。kの負の数は絶対値の幾何平均の負数ですが、負の値を含むセットの幾何平均正の数ははっきりしないはずです。幾何平均を拡張するもう一つの有意義な方法は、ホロモルフィーのドメインに対するホモモーフフィック関数としての拡張である(k > 1については、kのサブセットではない)。これには、前の拡張が枝の上の1つのブランチの値として含まれます。k

とにかく、幾何平均の計算には、与えられたプログラムではない形のk第1番目のルートが含まれています。さあ、コードを見てみましょう。

float geometricMean(float * arr, int rows, int cols){ 
    float neg_mul = 1; 
    int neg_count = 0; 

負の配列要素の積の初期化およびそのカウント。

float arr_elem; 
    for (int i = 0; i < rows; i++) 
     for (int j = 0; j < cols; j++) 

行列のメモリレイアウトはそうrow 0cols - 1にスロット0を占有

 -------------------------------------------- 
arr -> | row 0 | row 1 | row 2 | ... | row (rows-1) | 
     -------------------------------------------- 

ある、row 1は、一般に、row kスロット(k+1)*cols - 1からk*colsを占有し、スロットを2*cols - 1colsを占めます。したがって、arr + i*cols + jは、col jrow iに示します。

  if((arr_elem = *(arr + i * cols + j)) < 0){ 
       neg_mul *= arr_elem; 
       neg_count++; 
      } 

読む行列要素a[i][j]、それが負の場合、すべての負のエントリの製品にそれを掛けて、それを数えます。フラットなメモリレイアウトのため、for(k = 0; k < rows*cols; ++k)をループし、arr[k]にアクセスすることができます。

if (neg_count == 0){ 
     last_geom_err = "no negative elements in array"; 
     return 0; 
    } 

配列に負の要素がまったく含まれていない場合は、エラーメッセージを設定して戻ります。数字のない(幾何学的な)平均は意味を持たない。

if ((neg_count % 2 == 0) && (neg_mul < 0)){ 
     last_geom_err = "a negative number under the square root of even degree"; 
     return 0; 
    } 

負のエントリの数が偶数で負のエントリの値が負の場合は、エラーメッセージを設定して戻ります。

これはデッドコードです。負の数の偶数の積は常に正であり、浮動小数点演算(IEEE 754に準拠またはそれに十分近い)での唯一の注意点がありますが、完全に壊れていれば何かが起こる可能性があります。そうではありません。 (オーバーフロー無限大は、0と比較し、彼らが必要として、乗算に振る舞う、ここでの問題ではありません。)

last_geom_err = NULL; 
    return pow(neg_mul, (float)neg_count); 
} 

は最後に、何の例外的な状況が発生しないので、NULLにエラーメッセージを設定し、

を返します

(負の商品の商品)(負の商品の数)幾何平均の場合

、最後の行はneg_mul < 0場合powはそう

if (neg_mul < 0) { 
    return -pow(-neg_mul, 1.0/neg_count); 
} else { 
    return pow(neg_mul, 1.0/neg_count); 
} 
関連する問題