如何规范矩阵?
假设我有一个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;
}
答案 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
吗?
我认为您应该使用double
或float
,至少在其中一些中使用。
答案 1 :(得分:2)
您的代码中存在一些问题,我会尝试解决最重要的问题。
您的norm
矩阵是一个int的二维数组inputMatrix
,但您必须使用float或double数组才能正确存储结果并执行正确的计算。在C中如果除法的两个项都是整数类型,则执行整数除法(如:3/2 = 1,而不是1.5),这不是你需要的。
另一个错误是使用==
代替=
来执行分配。在C ==
中是'等于'关系操作。
<强> 修改 强>
由于@ chux 指出为a
和square[]
选择更准确的类型会更明智。使用long long int
将(可能)防止数字溢出,以防矩阵的元素对于它们的方块而言太大或者它们的总和由int
重新呈现。
请注意,如果您决定使用double而不是其他微妙的数值问题,则需要考虑由浮点类型表示的小数(和执行顺序)之和。因此,作为部分补救措施,您可以long double
和double
使用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