c中矩阵的几何平均数

问题描述:

该程序计算2×2矩阵中的负数元素的平均几何平均数,我试着理解下面这个程序中的代码,以及为什么作者写了他写的内容,可能有人向我解释什么?下面这段代码并即时发现很难理解 是作者在代码c中矩阵的几何平均数

#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

什么你明白不明白?你了解基本的C语法吗? – 2012-04-15 08:24:58

+0

@MarkByers,猜测它与矩阵在其展开的内存表示中的访问方式有关(注意将'(float **)'强制转换为'(float *)')。 – geekosaur 2012-04-15 08:26:56

+0

@geekosaur你是对的,那里我很困惑很多 – 2012-04-15 08:31:34

程序计算在一个2×2矩阵

它没有负性元件的平均几何平均值。首先,通常是geometric mean applies only to positive numbers.可以通过说负数的几何平均数是绝对值的几何平均值的负数来将定义扩展为负数,但包含负数的集的几何平均数正数应该是不清楚的。扩展几何平均值的另一种有意义的方法是作为全态函数的全纯函数的扩展(对于k > 1将不是ℂk的子集)。这将包括以前的扩展名为上述分支上的值ℝk

无论如何,几何平均值的计算将包括某种形式的k-根,该给定的程序不会。现在让我们看看代码。

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++) 

矩阵的存储器布局是

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

所以row 0占用时隙0至cols - 1row 1占据槽cols2*cols - 1,通常,row k占据槽k*cols(k+1)*cols - 1到。因此arr + i*cols + j指向row i中的col j

  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,尽管数学上它不是。 (溢出不在这里的问题,无穷比较0和乘法的行为,因为他们应该。)

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

最后,设置错误消息NULL,因为没有特殊情况发生,并返回

(负项目的产品)(负项目的数目)

对于几何平均值,最后一行应类似于

return pow(neg_mul, 1.0/neg_count); 
然而

,这将返回NaN的,如果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); 
}