c中矩阵的几何平均数

时间:2012-04-15 08:23:25

标签: c

该程序计算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

1 个答案:

答案 0 :(得分:2)

  

程序计算2x2矩阵中负元素的平均几何平均值

没有。首先,通常geometric mean applies only to positive numbers.一个人可以通过说k负数的几何平均值是绝对值的几何平均值的负数,以一种有意义的方式将定义扩展到负数。但是包含负数和正数的集合的几何平均值应该是不清楚的。扩展几何平均值的另一种有意义的方法是将其作为全纯函数域的全纯函数的扩展(其中k > 1不是ℂ k 的子集)。这将包括前一个分支作为一个分支上的值,高于ℝ&lt; 0 ķ

无论如何,几何平均数的计算将包括某种形式的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 - 1的广告位,row 1占用广告位cols2*cols - 1,通常row k占用广告位{ {1}}到k*cols。因此(k+1)*cols - 1指向arr + i*cols + j中的col j

row 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;
    }

如果否定条目的数量是偶数且负条目的乘积为负数,请设置错误消息并返回。

请注意,这是死代码。偶数负数的乘积总是正的,并且浮点运算中唯一的警告(IEEE 754符合或足够接近;如果完全破坏,任何事情都可能发生)是下溢,产品可能会变为0,尽管数学上它不是。 (溢出在这里不是问题,无穷大比较为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); } ,因为没有发生异常情况并返回

  

(否定条目的产品)(否定条目的数量)

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

NULL

但是,如果 return pow(neg_mul, 1.0/neg_count); ,那将返回NaN,因为neg_mul < 0仅处理整数指数的负基数,所以

pow