如何规范化C中的矩阵?

时间:2016-02-14 14:10:45

标签: c matrix

如何规范矩阵?

假设我有一个2x3矩阵:
1 2 3
4 5 6 归一化矩阵将是:
1/sqrt(pow(2,2) + pow(3,2)) 2/sqrt(pow(2,2) + pow(3,2)) 3/sqrt(pow(2,2) + pow(3,2))
4/sqrt(pow(5,2) + pow(6,2)) 5/sqrt(pow(5,2) + pow(6,2)) 6/sqrt(pow(5,2) + pow(6,2))

这是我的示例代码:

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

int main(){  
    int rows, cols, rowCounter, colCounter, r, c;  
    int initial[100], inputMatrix[100][100], rowSum[100] = {0}, norm[100][100], square[100] = {0};


    printf("Enter size of a matrix\n");
    scanf("%d %d", &rows, &cols);
    printf("Enter matrix of size %dX%d\n", rows, cols);
    /* Input matrix */
    for(rowCounter = 0; rowCounter < rows; rowCounter++){
        for(colCounter = 0; colCounter < cols; colCounter++){
            scanf("%d", &inputMatrix[rowCounter][colCounter]);
        }
    }



    for(r = 0; r < rows; r++)  
       {  
           for(c = 1; c < cols; c++)  
           {  
               float a;  
               a == inputMatrix[r][c];  
                square[r] += pow(a, 2);  
           }  
           printf("%.2lf ", square[r]);  
       }  

        for(rowCounter = 0; rowCounter < rows; rowCounter++)  
       {  
           for(colCounter = 0; colCounter < cols; colCounter++)  
           {  
               norm[rowCounter][colCounter] == (inputMatrix[rowCounter][colCounter]) / sqrt(square[rowCounter]);  
           }  
       }  
       printf("\nNormalized Matrix:\n");  
       for(rowCounter = 0; rowCounter < rows; rowCounter++)  
       {  
           for(colCounter = 0; colCounter < cols; colCounter++)  
           {  
               printf("%.3lf ", norm[rowCounter][colCounter]);  
           }  
           printf("\n");  
       }  

        getch();  
        return 0;  
    }  

2 个答案:

答案 0 :(得分:3)

为什么在这里使用==

for(r = 0; r < rows; r++)  
   {  
       for(c = 1; c < cols; c++)  
       {  
           float a;  
           a == inputMatrix[r][c];   //look here
            square[r] += pow(a, 2);  
       }  

应该是:

for(r = 0; r < rows; r++)  
   {  
       for(c = 1; c < cols; c++)  
       {  
           float a;  
           a = inputMatrix[r][c];  
            square[r] += pow(a, 2);  
       }  

同样在这里:

norm[rowCounter][colCounter] == (inputMatrix[rowCounter][colCounter]) / sqrt(square[rowCounter]);

应该是:

norm[rowCounter][colCounter] = (inputMatrix[rowCounter][colCounter]) / sqrt(square[rowCounter]);

你应该小心:

int initial[100], inputMatrix[100][100], rowSum[100] = {0}, norm[100][100], square[100] = {0};

您确定对所有此声明使用int吗? 我认为您应该使用doublefloat,至少在其中一些中使用。

答案 1 :(得分:2)

您的代码中存在一些问题,我会尝试解决最重要的问题。

您的norm矩阵是一个int的二维数组inputMatrix,但您必须使用float或double数组才能正确存储结果并执行正确的计算。在C中如果除法的两个项都是整数类型,则执行整数除法(如:3/2 = 1,而不是1.5),这不是你需要的。

另一个错误是使用==代替=来执行分配。在C ==中是'等于'关系操作。

<强> 修改

由于@ chux 指出为asquare[]选择更准确的类型会更明智。使用long long int将(可能)防止数字溢出,以防矩阵的元素对于它们的方块而言太大或者它们的总和由int重新呈现。

请注意,如果您决定使用double而不是其他微妙的数值问题,则需要考虑由浮点类型表示的小数(和执行顺序)之和。因此,作为部分补救措施,您可以long doubledouble使用a(如果它在您的环境中的确比square更精确)。

编辑2

在问题和评论中,你说矩阵的每一行的第一个元素应该是“矩阵中的常量”,因此它不会参与代码和示例中的平方和你给了,但在这两个中它们都在下一个循环中更新。我不确定发生了什么,所以我纠正了我的代码以模仿你的行为。

以下是您的代码的工作更正版本:

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

int main() {  
    int rows, cols, r, c;  
    // you may think about dynamical allocation here
    int inputMatrix[100][100], rowSum[100] = {0};
    // it's better to use a type that can manage bigger numbers to avoid numeric overflow
    long long int a, square[100] = {0}; 
    // your starting matrix can be a matrix of int but the normalized one need to
    // contain floating point numbers
    double norm[100][100], k;

    printf("Enter size of a matrix\n");
    scanf("%d %d", &rows, &cols);
    printf("Enter matrix of size %dX%d\n", rows, cols);
    /* Input matrix */
    for ( r = 0; r < rows; r++) {
        for (c = 0; c < cols; c++) {
            scanf("%d", &inputMatrix[r][c]);
            //     ^^ if you are scanning integer numbers... 
        }
    }

    printf("\nrows: %d cols: %d elements:\n",rows,cols);  
    for( r = 0; r < rows; r++) {  
        for( c = 0; c < cols; c++) {  
            printf("%d ", inputMatrix[r][c]);
            // ...  ^^ you should print integer numbers
        }  
        printf("\n");  
    }  

    for (r = 0; r < rows; r++)  {  
        for (c = 1; c < cols; c++) {
        //      ^^^ I don't know why you skip this here
            a = inputMatrix[r][c];
            //^ You have to assign, not to compare!
            square[r] += a * a;
            //           ^^^^^ no need to call pow()
        }  
        printf("Sum of squares of row %d: %lld\n",r,square[r]);
        //             square contains int ^^
        // It would be nice and safer if you check here if square == 0 to avoid a
        // division by zero and probably detect bad input data
    }  

    for ( r = 0; r < rows; r++ ) {
        // It's far more efficient to precalculate this term, even if compilers
        // could be smart enough to do it for you. You may want to store those
        // values in an array of doubles instead of the (sum of) squares
        k = 1.0 / sqrt(square[r]);
        for( c = 0; c < cols; c++ ) {  
            norm[r][c] = k * inputMatrix[r][c] ;
            // again,  ^ assign not compare
        }  
    }

    // you can add the printf to the previous loop...
    printf("\nNormalized Matrix:\n");  
    for( r = 0; r < rows; r++) {  
        for( c = 0; c < cols; c++) {  
            printf("%.3lf ", norm[r][c]);
            //      ^^^^^ norm contains double 
        }  
        printf("\n");  
    }  

    return 0;  
}

我保留整数类型的输入矩阵,但最好也使用double。当我为原始矩阵添加了一个打印循环时,最终输出是:

rows: 2 cols: 3 elements:
1 2 3 
4 5 6 
Sum of squares of row 0: 13
Sum of squares of row 1: 61

Normalized Matrix:
0.277 0.555 0.832 
0.512 0.640 0.768