Currently I am working on a code that computes the following equation with two matrices, X and Y, to return the value of matrix W.
W = (XT * X)^-1 * XT * Y
Input Matrix train:
4
10
3.000000,1.000000,1180.000000,1955.000000,221900.000000
3.000000,2.250000,2570.000000,1951.000000,538000.000000
2.000000,1.000000,770.000000,1933.000000,180000.000000
4.000000,3.000000,1960.000000,1965.000000,604000.000000
3.000000,2.000000,1680.000000,1987.000000,510000.000000
4.000000,4.500000,5420.000000,2001.000000,1230000.000000
3.000000,2.250000,1715.000000,1995.000000,257500.000000
3.000000,1.500000,1060.000000,1963.000000,291850.000000
3.000000,1.000000,1780.000000,1960.000000,229500.000000
3.000000,2.500000,1890.000000,2003.000000,323000.000000
Input Matrix test:
3
3.000000,2.500000,3560.000000,1965.000000
2.000000,1.000000,1160.000000,1942.000000
3.000000,1.000000,1430.000000,1927.000000
Result Matrix:
716559
194430
323391
My code returns the proper values for the testcases with the exception of matrices over the size of 1000. I know this is because the size is not dynamically allocated, but I am not sure what the best approach to doing this in my code would be:
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char* argv[]){
if(argc < 3){
printf("error.");
return 0;
}
FILE *fptrain = fopen(argv[1], "r");
if(fptrain == NULL)
{
printf("error.");
return 0;
}
int row, col, i, j;
fscanf(fptrain, "%d", &col);
col = col+1;
fscanf(fptrain, "%d", &row);
char ch;
//creates the original X and Y matrix
double trainX[row][col];
double trainY[row][1];
for(i=0; i<row; i++)
{
trainX[i][0] = 1.000000;
for(j=1; j<col; j++)
{
fscanf(fptrain, "%lf%c", &trainX[i][j], &ch);
}
fscanf(fptrain, "%lf%c", &trainY[i][0], &ch);
}
//creates the X transposed matrix
double trainXtrans[col][row];
for(i=0; i<row; i++)
{
for(j=0; j<col; j++)
{
trainXtrans[j][i] = trainX[i][j];
}
}
//multiplies X and X transposed
double trainXtemp[row][row];
int s;
double num=0;
for(i=0; i<col; i++)
{
for(j=0; j<col; j++)
{
for(s=0; s<row; s++)
{
num = num + trainX[s][j]*trainXtrans[i][s];
}
trainXtemp[i][j] = num;
num = 0;
}
}
//finds the identity matrix of X times X transposed
double trainXinden[col][col*2];
for(i=0; i<col; i++)
{
for(j=0; j<col; j++)
{
trainXinden[i][j] = trainXtemp[i][j];
}
for(j=col; j<col*2; j++)
{
if(j==i+col)
{
trainXinden[i][j] = 1.000000;
}
else{
trainXinden[i][j] = 0.000000;
}
}
}
//finds the inverse of X times X transposed through Gauss Jordan Elimination
int k;
double divscalar;
for(i=0; i<col; i++)
{
divscalar = trainXinden[i][i];
for(j=0; j<col*2; j++)
{
if(trainXinden[i][j] != 0)
{
trainXinden[i][j] = trainXinden[i][j]/divscalar;
}
}
for(k=0; k<col; k++)
{
if(i!=k)
{
double subscalar = trainXinden[k][i];
for(j=0; j<col*2; j++)
{
trainXinden[k][j] = trainXinden[k][j] - subscalar*trainXinden[i][j];
}
}
}
}
double trainXinverse[row][row];
for(i=0; i<row; i++)
{
for(j=0; j<col; j++)
{
trainXinverse[i][j] = trainXinden[i][j+col];
}
}
double trainXinvXt[col][row];
for(i=0; i<col; i++)
{
for(j=0; j<row; j++)
{
for(s=0; s<col; s++)
{
num = num + trainXinverse[i][s]*trainXtrans[s][j];
}
trainXinvXt[i][j] = num;
num = 0;
}
}
//multiples (trainXinvXt) by Y
double weight[row][1];
for(i=0; i<col; i++)
{
for(s=0; s<row; s++)
{
weight[i][0] += trainXinvXt[i][s]*trainY[s][0];
}
}
FILE *fptest = fopen(argv[2], "r");
if(fptest == NULL)
{
printf("error.");
return 0;
}
int testrows;
fscanf(fptest, "%d", &testrows);
//creates the test file matrix
double testM[testrows][col];
for(i=0; i<testrows; i++)
{
testM[i][0] = 1.000000;
for(j=1; j<col; j++)
{
fscanf(fptest, "%lf%c", &testM[i][j], &ch);
}
}
double prices[testrows][1];
for(i=0; i<testrows; i++)
{
for(s=0; s<col; s++)
{
num = num + testM[i][s]*weight[s][0];
}
prices[i][0] = num;
num = 0;
}
for(i=0; i<testrows; i++)
{
printf("%0.0lf", prices[i][0]);
printf("\n");
}
return 0;
}
When I use malloc on each matrix, for some reason it appears that it is not allowing me to create the augmented matrix or perform my gauss-jordan reduction, which is ruining my final answer.
The best approach to allocate memory to a multi-dimensional array (taking e.g. of 2D array, since you are using matrix in your program):
int(*matrix)[col] = malloc (sizeof(int[row][col]));
If you want to write a function for it then:
void* allocMatrix (int row, int col)
{
return malloc (sizeof(int[row][col]));
}
If you are not familiar with this approach of allocating memory dynamically to a multi-dimensional array then read this (very nicely explained by Lundin).
In your program, you are having the matrix of type double, so the allocMatrix() will be -
void* allocMatrix (int row, int col)
{
return malloc (sizeof(double[row][col]));
}
and in main(), you need to make following changes to create matrix dynamically -
double (*trainX)[col] = allocMatrix (row, col);
Do same changes for other matrices also and make sure to free() the dynamically allocated memory to matrices at appropriate places in your program.
Just for the knowledge purpose, this practice of allocating memory to the multi-dimensional array has been followed commonly, though it's not the best.
Related
I have to read the number of rows and columns of a matrix from a txt file also its elements. the first row is the number of rows and columns followed by its numbers. For example this is a matrix with 2 rows and 3 columns containing 123 456 and a matrix with 3 rows and 2 columns.
2 3
1 2 3
4 5 6.
3 2
1 2
3 4
5 6
What I have to do is to read two matrix from the same text file and multiply them. I'm encountering some unknown problem.
When I write my code to test whether the matrix is populated correctly. I only get the first matrix printed and then the program stopped. Output: 1 2 3
4 5 6
Here's the part of the code. Thanks in advance.
int main(){
int **mat1,**mat2,**result;
int row1,col1,row2,col2;
int i,j,k;
FILE *file;
char fname[100];
printf("enter file name\n");
scanf("%s", &fname);
file=fopen(fname, "r");
fscanf(file, "%d %d", &row1,&col1);//row of first matrix
mat1=malloc(row1 * col1 * sizeof(int*));//create memory for first matrix
//reading data for first matrix
for(i=0; i<row1; i++)
{
for(j=0; j<col1; j++)
{
fscanf(file, "%d", &mat1[i][j]);
}
}
for(i=0; i<row1; i++)
{
for(j=0; j<col1; j++)
{
printf("%d\t",mat1[i][j]);
}
printf("\n");
}
fscanf(file,"%d %d", &row2, &col2);//row of second matrix
mat2=malloc(row2 * col2 * sizeof(int*));//create memory for second matrix
//reading data for second matrix
for(i=0; i<row2; i++)
{
for(j=0; j<col2; j++)
{
fscanf(file,"%d",&mat2[i][j]);
}
}
for(i=0; i<row2; i++) //check mat2
{
for(j=0; j<col2; j++)
{
printf("%d\t",mat2[i][j]);
}
printf("\n");
}
I think I fixed the problem, but I had to do quite a bit of debugging due to lots of segfaults, so I'll put the answer to the original question at the top and defer all the things I had to debug to the bottom.
fscanf(file, "%*[.]"); //this is to read the period in the file
fscanf(file,"%d %d", &row2, &col2);//row of second matrix
mat2=malloc(row2 * col2 * sizeof(int*));//create memory for second matrix
By adding that one line of code, it started working for me, but it only started working due to the debugging below.
Since the number of calls to malloc did not represent the number of nested ararys that were indexed, I had to change the declaration of the matrices, the way they were populated, and they way they are referenced.
int *mat1,*mat2;
This declaration is to make the next edits work.
//reading data for first matrix
for(i=0; i<row1; i++)
{
for(j=0; j<col1; j++)
{
fscanf(file, "%d", &(mat1[i*col1 + j]));
}
}
for(i=0; i<row1; i++)
{
for(j=0; j<col1; j++)
{
printf("%d\t",mat1[i*col1 + j]);
}
printf("\n");
}
And of course, for the second matrix;
//reading data for second matrix
for(i=0; i<row2; i++)
{
for(j=0; j<col2; j++)
{
fscanf(file,"%d",&(mat2[i*col2 + j]));
}
}
for(i=0; i<row2; i++) //check mat2
{
for(j=0; j<col2; j++)
{
printf("%d\t",(mat2[i*col2 + j]));
}
printf("\n");
}
Please keep in mind that if you are going to be referencing an array inside of an an array, then you need to malloc space for another array in each slot of the original array. I chose the unintuitive approach to matrix arithmetic, but the code can be augmented to easily allow for double array indexing to be used.
You have some problem with allocating a 2D arrays:
For example:
mat1=malloc(row1 * col1 * sizeof(int*));//create memory for first matrix
it should be
mat1=(int**)malloc(row1 * sizeof(int*));//create memory for first matrix
Then should allocate each row in mat1 in for loop with before scanf each cell in a matrix
for (i = 0; i < row1; i++)
{
mat1[i] = malloc(col1 * sizeof(int));
for (j = 0; j < col1; j++)
{
fscanf(file, "%d", &mat1[i][j]);
}
}
Then, do similar stuff for mat2
Here is my solution that based on original problem:
#include <stdio.h>
#include <stdlib.h>
int main() {
int **mat1, **mat2, **result;
int row1, col1, row2, col2;
int i, j, k;
FILE *file;
char fname[100];
printf("enter file name\n");
scanf("%s", &fname);
file = fopen(fname, "r");
fscanf(file, "%d %d", &row1, &col1);//row of first matrix
mat1 = (int **)malloc(row1 * sizeof(int*));//create memory for first matrix
//reading data for first matrix
for (i = 0; i < row1; i++)
{
mat1[i] = malloc(col1 * sizeof(int));
for (j = 0; j < col1; j++)
{
fscanf(file, "%d", &mat1[i][j]);
}
}
for (i = 0; i < row1; i++)
{
for (j = 0; j < col1; j++)
{
printf("%d\t", mat1[i][j]);
}
printf("\n");
}
fscanf(file, "%d %d", &row2, &col2);//row of second matrix
mat2 = (int **)malloc(row2 * sizeof(int*));//create memory for second matrix
//reading data for second matrix
for (i = 0; i < row2; i++)
{
mat2[i] = malloc(col2 * sizeof(int));
for (j = 0; j < col2; j++)
{
fscanf(file, "%d", &mat2[i][j]);
}
}
for (i = 0; i < row2; i++) //check mat2
{
for (j = 0; j < col2; j++)
{
printf("%d\t", mat2[i][j]);
}
printf("\n");
}
fclose(file);
return 0;
}
I am currently working on a code that calculates the following equation:
W = (XT * X)^-1 * XT * Y
with XT being the transpose of X and ^-1 the inverse of the product XT*X.
To do this, I am passing a text file with a matrix to the program, and then performing operations on it to obtain the proper matrix formats to use in the equation. Although the code works some times, there are instances when I will run the code and receive the proper answer, but others when a random number will be produced.
For example, when using the matrix [first integer = columns-1, second integer = rows]:
4
4
4.000000,3.000000,2.000000,3.000000,200.000000
5.000000,2.000000,1.000000,7.000000,300.000000
1.000000,4.000000,2.000000,1.000000,500.000000
8.000000,8.000000,9.000000,3.000000,200.000000
it will produce an answer for XT * (XT * X)^-1 as:
0.497617 -0.166646 0.061712 -0.137570
-61.086998 -0.258283 -0.340935 -0.064228
0.186411 -0.083895 0.285920 -0.082587
-0.722773 0.207515 -0.009408 0.238550
-0.579552 0.345476 0.154362 0.055048
and the numbers will not remain the same through each test run. It does this with this result matrix multiplied by Y [the last column in the original matrix] as well. Below is a sample of the code I have written thus far:
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char* argv[]){
if(argc < 2){
printf("error.");
return 0;
}
FILE *fptrain = fopen(argv[1], "r");
int row, col, i, j;
fscanf(fptrain, "%d", &col);
col = col+1;
fscanf(fptrain, "%d", &row);
char ch;
//creates the original X and Y matrix
float trainX[row][col];
float trainY[row][1];
for(i=0; i<row; i++)
{
trainX[i][0] = 1.000000;
for(j=1; j<col; j++)
{
fscanf(fptrain, "%f%c", &trainX[i][j], &ch);
}
fscanf(fptrain, "%f%c", &trainY[i][0], &ch);
}
//creates the X transposed matrix
float trainXtrans[col][row];
for(i=0; i<row; i++)
{
for(j=0; j<col; j++)
{
trainXtrans[j][i] = trainX[i][j];
}
}
//multiplies X and X transposed
float trainXtemp[row][row];
int s;
int num=0;
for(i=0; i<row; i++)
{
for(j=0; j<row; j++)
{
for(s=0; s<col; s++)
{
num = num + trainX[i][s]*trainXtrans[s][j];
}
trainXtemp[i][j] = num;
num =0;
}
}
//finds the identity matrix of X times X transposed
float trainXinden[row][row*2];
for(i=0; i<row; i++)
{
for(j=0; j<row; j++)
{
trainXinden[i][j] = trainXtemp[i][j];
}
for(j=row; j<row*2; j++)
{
if(j==i+row)
{
trainXinden[i][j] = 1;
}
else{
trainXinden[i][j] = 0;
}
}
}
//finds the inverse of X times X transposed through Gauss Jordan Elimination
int k;
float divscalar;
for(i=0; i<row; i++)
{
divscalar = trainXinden[i][i];
for(j=0; j<row*2; j++)
{
trainXinden[i][j] = trainXinden[i][j]/divscalar;
}
for(k=0; k<row; k++)
{
if(i!=k)
{
float subscalar = trainXinden[k][i];
for(j=0; j<row*2; j++)
{
trainXinden[k][j] = trainXinden[k][j] - subscalar*trainXinden[i][j];
}
}
}
}
//copies over the result of gauss jordan elimination
float trainXinverse[row][row];
for(i=0; i<row; i++)
{
for(j=0; j<row; j++)
{
trainXinverse[i][j] = trainXinden[i][j+row];
}
}
//multiplies (X times X transpose) inverse by (X transposed)
float trainXinvXt[col][row];
for(i=0; i<col; i++)
{
for(j=0; j<row; j++)
{
for(s=0; s<row; s++)
{
trainXinvXt[i][j] += trainXtrans[i][s]*trainXinverse[s][j];
}
}
}
//multiples (trainXinvXt) by Y
float weight[row][1];
for(i=0; i<col; i++)
{
for(s=0; s<col-1; s++)
{
weight[i][0] += trainXinvXt[i][s]*trainY[s][0];
}
}
return 0;
}
is this perhaps a memory issue or is my Gauss-Jordan Elimination method throwing something off?
There are two 2D arrays and r and c are their row and column, i and j are used for integer variables.
Transpose of matrix is running well till the value r and c are entered.
#include <stdio.h>
int main() {
// your code goes here
int a[50][50], b[50][50], i, j, r, c;
printf("Enter the value of R and c");
scanf("%d%d", &r, &c);
for(i = 0; i < r; i++)
{
for(j = 0; j < c; j++)
{
scanf("%d", &a[i][j]);
}
}
for(i = 0; i < r; i++)
{
for(j = 0; j < c; j++)
{
b[i][j] = a[i][j];
}
}
for(i = 0; i < r; i++)
{
for(j = 0; j < c; j++)
{
printf("%d\n", b[i][j]);
}
printf("\n");
}
return 0;
}
You are not "transposing" the matrix. You are simply copying one array to another. To transpose a matrix, you need to convert rows to columns:
for(i=0;i<r;i++)
{
for(j=0;j<c;j++)
{
b[j][i]=a[i][j];
}
}
and reverse c and r in the loop condition when printing:
for(i=0;i<c;i++)
{
for(j=0;j<r;j++)
{
printf("%d\n",b[i][j]);
}
printf("\n");
}
Note that your arrays are capable of handling 50x50. So you need to ensure the input values of r and c don't exceed these limits.
Your code is
#include <stdio.h>
int main() {
// your code goes here
int a[50][50], b[50][50], i, j, r, c;
printf("Enter the value of R and c\n");
scanf("%d%d", &r, &c);
for(i=0;i<r;i++)
{
for(j=0;j<c;j++)
{
scanf("%d",&a[i][j]);
}
}
for(i=0;i<r;i++)
{
for(j=0;j<c;j++)
{
printf("%3d",a[i][j]);
}
printf("\n");
}
printf("\n");
for(i = 0; i < c; i++)
{
for(j = 0; j < r; j++)
{
printf("%3d", a[j][i]);
}
printf("\n");
}
return 0;
}
There is segmentation fault in case 5 of this program(transpose) this segmentation fault occurs only when the input row is greater than that of the input column. Hopefully this is due to the reason I have not allocated the memory accordingly.
b= (int**)malloc(r*sizeof(int*));
for(i=0; i<c; i++)
{
b[i] = (int*)malloc(sizeof(int));
}
And if I am doing it accordingly like this:
b= (int**)malloc(c*sizeof(int*));
for(i=0; i<r; i++)
{
b[i] = (int*)malloc(sizeof(int));
}
there still is seg. fault and this time it is not producing correct output for matrix of any order.
Here is my full code :
#include<stdio.h>
#include<stdlib.h>
int** inputmatrix(int **a,int r, int c)
{
int i, j;
a = (int**)malloc(r*sizeof(int));
for(i=0; i<c; i++)
{
a[i] = (int*)malloc(sizeof(int));
}
printf("\n Input the Elements of the Matrix :");
for(i=0; i<r; i++)
{
for(j=0; j<c; j++)
{
scanf("%d",&a[i][j]);
}
}
return a;
}
void showmatrix(int** a, int r, int c)
{
int i, j;
for(i=0; i<r; i++)
{
printf("\n");
for(j=0; j<c; j++)
{
printf(" %d",a[i][j]);
}
}
}
int** add(int **a, int **b, int r, int c)
{
int i,j;
for(i=0; i<r; i++)
{
for(j=0; j<c; j++)
{
a[i][j] = a[i][j]+b[i][j];
}
}
return a;
}
int** multiplication(int** a, int **b, int r1, int c1, int c2)
{
int **c,i,j,k;
c = (int**)malloc(r1*sizeof(int*));
for(i=0; i<c2; i++)
{
c[i] = (int*)malloc(sizeof(int));
}
for(i=0; i<r1; i++)
{
for(j=0; j<c2; j++)
{
c[i][j] = 0;
for(k=0; k<c1; k++)
{
c[i][j] = c[i][j] + a[i][k]*b[k][j];
}
}
}
return c;
}
int minval(int **a, int r, int c)
{
int i, min;
min = a[r][0];
for(i=0; i<c; ++i)
{
if(a[r][i]<min)
{
min = a[r][i];
}
}
return min;
}
int maxval(int **a, int r, int c)
{
int i, max;
max = a[0][c];
for(i=0; i<r; ++i)
{
if(a[i][c] > max )
{
max = a[i][c];
}
}
return max;
}
void saddlepoint(int **a, int r, int c)
{
int i, j, rpos, cpos, flag = 0,sp;
for(i=0; i<r; ++i)
{
for(j=0; j<c; ++j)
{
if(a[i][j] == minval(a, i, c) && a[i][j] == maxval(a, r, j))
{
sp = a[i][j];
flag = 1;
rpos = i;
cpos = j;
}
}
}
if(flag == 1)
{
printf("\n The Saddle point of the Matrix is found at position (%d,%d) value is %d ", rpos, cpos,sp);
}
else
{
printf("\n There is no saddle point in the Matrix ");
}
}
int magicsquare(int **a, int r, int c)
{
int i, j, row_sum, col_sum, d1, d2, flag = 0;
if(r==c)
{
for(i =0 ;i<r; i++) // for digonals
{
d1 = d1 + a[i][i];
d2 = d2 + a[i][r-i-1];
}
for(i=0; i<r; i++)
{
row_sum = 0;
for(j=0; j<c; j++)
{
row_sum = row_sum + a[i][j];
}
if(row_sum == d1)
flag = 1;
else
break;
}
for(i=0; i<r; i++)
{
col_sum = 0;
for(j=0; j<c; j++)
{
col_sum = col_sum + a[j][i];
}
if(col_sum == d1)
flag =1;
else
break;
}
}
else
{
printf("\n This Matrix is not a Magic Square ");
}
return flag;
}
int** transpose(int **a, int r, int c)
{
int i, j, **b;
b= (int**)malloc(c*sizeof(int*));
for(i=0; i<r; i++)
{
b[i] = (int*)malloc(sizeof(int));
}
for(i =0; i<r; i++)
{
for(j=0; j<c; j++)
{
b[j][i] = a[i][j];
}
}
return b;
}
int main()
{
int **a, **b,r1,c1,r2,c2, i,j,ch,f;
int **c;
printf("\n enter your choice : \n1.Addition \n2.Multiplication \n3.Saddle Point \n4. Magic Square \n5.Transpose\n");
scanf("%d",&ch);
printf("\n enter the oder of matrix A :");
scanf("%d%d",&r1,&c1);
a = inputmatrix(a,r1,c1);
switch(ch)
{
case 1:
printf("\n enter the oder of matrix B :");
scanf("%d%d",&r2,&c2);
if(r1==r2 && c1==c2)
{
b = inputmatrix(b,r2,c2);
a = add(a,b,r1,c1);
printf("\n the result of the addition of matrices is :");
for(i=0; i<r1; i++)
{
printf("\n");
for(j=0;j<c1; j++)
{
printf("%d\t",a[i][j]);
}
}
}
else
{
printf("\n these matrices can't be added ");
}
break;
case 2 :
printf("\n Enter the Order of Matrix B :");
scanf("%d%d",&r2,&c2);
b = inputmatrix(b,r2,c2);
if(c1 == r2)
{
c = multiplication(a, b, r1, c1, r2);
for(i=0; i<r1; i++)
{
printf("\n");
for(j=0; j<c2; j++)
{
printf("%d\t",c[i][j]);
}
}
}
else
{
printf("\n Sorry, These Matrices Can't be Multiplied ");
}
break;
case 3 :
printf("\n The Matrix you Entered is :");
for(i=0; i<r1; i++)
{
printf("\n");
for(j=0; j<c1; j++)
{
printf(" %d",a[i][j]);
}
}
saddlepoint(a,r1,c1);
break;
case 4 :
printf("\n The Matrix you Entered is :");
for(i=0; i<r1; i++)
{
printf("\n");
for(j=0; j<c1; j++)
{
printf(" %d",a[i][j]);
}
}
int f = magicsquare(a, r1, c1);
if(f==1)
printf("\n This Matrix is a Magic Square ");
else
printf("\n This Matrix is not a Magic Square ");
break;
case 5 :
printf("\n The Matrix you enter is :");
showmatrix(a,r1,c1);
b = transpose(a,r1,c1);
printf("\n the transpose of the entered matrix is :");
for(i=0; i<c1; i++)
{
printf("\n");
for(j=0; j<r1; j++)
{
printf(" %d",b[i][j]);
}
}
break;
default : printf("\n Sorry, This is a Wrong Choice ");
}
return 0;
}
A few Output cases are also below:
case 1:
enter your choice :
1.Addition
2.Multiplication
3.Saddle Point
4. Magic Square
5.Transpose
5
enter the oder of matrix A :3
2
Input the Elements of the Matrix :1
2
3
4
5
Segmentation fault (core dumped)
case 2:
enter your choice:
1.Addition
2.Multiplication
3.Saddle Point
4. Magic Square
5.Transpose
5
enter the oder of matrix A :2
3
Input the Elements of the Matrix :1
2
3
4
5
6
The Matrix you enter is :
1 2 3
4 5 6
the transpose of the entered matrix is :
1 4
2 5
3 6
And there is some problem in the multiplication function also, there also right matrix is not being displayed.
b= (int**)malloc(r*sizeof(int*));
This allocates an array of r int* elements.
for(i=0; i<c; i++)
This goes over the first c elements of this array. If c>r, then
b[i] = (int*)malloc(sizeof(int));
the behaviour of the line above is undefined. If c<=r, it is well-defined but not very useful, as it allocates one element for each matrix row. It probably becomes broken later, when you try to access elements past the first column.
To allocate a matrix with r rows and c columns you probably want to do this:
b = malloc(r * sizeof(int*)); /* allocate `r` rows */
for(i = 0; i < r; i++) /* for each of the `r` rows */
b[i] = malloc (c * sizeof(int)); /* allocate `c` columns */
There is mistake in the declaration of the arrays using malloc.
When you wish to declare a 2-D array of 'r' rows and 'c' columns, the statements should be something like
int **arr=malloc(r*sizeof(int *));
for(i=0;i<r;i++)
arr[i]=malloc(c*sizeof(int));
This will eliminate the segmentation fault.
The first statement declares an array of 'r' integer pointers.
The for loop executes 'r' times since you have to initialize each of the 'r' pointers declared by the previous statement.
The statement inside the for loop declares an integer array of length 'c' to store 'c' elements of each row.
Moreover, it initializes each of the pointers of the array 'arr' with the addresses of these rows(in correct order of-course).
Thus we get 'r' rows of 'c' elements each and hence an (r x c) matrix.
Greeting,
Somebody can find, why write out these program segmenation fault, when I take in the all inputs?
I don't find where is the problem, or where should be modify my code
And I would like to get the results?
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
void inMatrix(int n, double **matrix)
{
int j, i;
for (i = 0; i < n; i++)
{
for (j= 0; j < n; j++)
{
scanf("%lf", &matrix[i][j]);
}
}
}
void inVector(double *vektor, int n)
{
int k;
for (k = 0; k < n; k++)
{
scanf("%lf", &vektor[k]);
}
}
void outVector(double *vektor, int n)
{
int k;
for (k = 0; k < n; k++)
{
printf("%.8lf ", vektor[k]);
}
}
void lup(int n, double **A, double **b, int v)
{
int *Permutation = (int*)malloc(sizeof(int)*n);
int i,j;
int k;
double *max = (double*) malloc (sizeof(double)*n);
int m=0, p=0;
int tmp=0, tmp2=0;
int t=0, isSingular=0;
double largestElement=0.0;
double *helpVector = (double*) malloc (sizeof(double)*n);
double *helpVectorA = (double*) malloc (sizeof(double)*n);
double *helpVectorB = (double*) malloc (sizeof(double)*n);
// for(i=0;i<n;i++)
// {
// for(j=0;j<n;j++)
// {
// A[i][j]=D[i][j];
// }
// }
for(i=0; i<n; i++)
Permutation[i]=i;
for(m=0; m<n-1; m++)
{
for(i=m; i<n; i++)
{
max[i]=fabs(A[i][m]);
}
for(i=m; i<n; i++)
{
if(max[i]>largestElement)
{
largestElement=max[i];
p=i;
}
}
for(i=0; i<n; i++)
{
helpVectorA[i]=A[m][i];
helpVectorB[i]=A[p][i];
}
for(i=0; i<n; i++)
{
A[m][i]=helpVectorB[i];
A[p][i]=helpVectorA[i];
}
tmp=Permutation[m];
tmp2=Permutation[p];
Permutation[m]=tmp2;
Permutation[p]=tmp;
if(fabs(A[m][m])>0.00000000000000001)
{
for(i=m+1; i<n; i++)
{
A[i][m]=A[i][m]/A[m][m];
for(j=m+1; j<n; j++)
{
A[i][j]=A[i][j]-A[i][m]*A[m][j];
}
}
}
if(fabs(A[m][m])<0.00000000001)
{
printf("szingularis\n");
isSingular=1;
break;
}
for(i=0; i<n; i++) max[i]=-1;
largestElement=0.0;
p=m+1;
}
if(isSingular==0)
{
if(fabs(A[n-1][n-1])<0.00000000001)
{
printf("szingularis\n");
isSingular=1;
}
}
if(isSingular==0)
{
for(k=0; k<v;k++)
{
for(i=0; i<n; i++)
{
t=Permutation[i];
helpVector[i]=b[k][t];
}
for(i=0; i<n; i++)
{
b[i][k]=helpVector[i];
}
for(i=1; i<n; i++)
{
for(j=0; j<i; j++)
{
b[k][i]-=A[i][j]*b[k][j];
}
}
for(i=n-1; i>=0; i--)
{
for(j=i+1; j<n; j++)
{
b[k][i]-=A[i][j]*b[k][j];
}
b[k][i]=b[k][i]/A[i][i];
}
}
for(i=0; i<n; i++)
{
printf("%.8lf ", b[k][i]);
}
printf("\n");
}
}
int main()
{
int k, v,n;
int j;
double **A;
double **C;
// read dimension of matrix and value
scanf("%d", &n);
//matrix
A = (double **) calloc(n, sizeof ( double*));
// matrix to store the vectors
C = (double **) calloc(n, sizeof(double *));
while(n!=0)
{
for (k = 0; k < n; k++)
{
A[k] = (double *) calloc(n, sizeof ( double));
}
inMatrix(n, A);
scanf("%d", &v);
for(k=0;k<v;k++)
{
C[k] = (double *) calloc(n, sizeof ( double));
}
for(k=0; k<v;k++)
{
for(j=0;j<n;j++)
{
scanf("%lf", &C[k][j]);
}
}
//print out result
for(k=0;k<v;k++)
{
for(j=0;j<v;j++)
{
lup(n,A,C,v);
}
}
}
return 0;
}
In main, you have
/* ... */
C = (double **) calloc(n, sizeof(double *));
n elements
while(n!=0)
{
for (k = 0; k < n; k++)
{
A[k] = (double *) calloc(n, sizeof ( double));
}
inMatrix(n, A);
scanf("%d", &v);
for(k=0;k<v;k++)
v? Where did it come from? Do you perhaps mean n
Remember C was allocated space for n elements, even before v was set.
{
C[k] = (double *) calloc(n, sizeof ( double));
}
/* ... */
Your indentation and use of whitespace could improve a bit too.
In function lup, at line 157 (in the second "if(isSingular==0)" block) you wrote
printf("%.8lf ", b[k][i]);
this line is written in a for-loop iterating on i, while k has a leftover value from the last loop. The break condition of that loop was that k = v (the size of C, A.K.A "b" from the line of code above).
So, basically, you wrote:
printf("%.8lf", b[MaxIndexOfB+1][i];
And that's probably the stinker you're looking for.
Two notes. First, I've been .Net man for too long, so I might be missing something completely trivial here, In that case, sorry.
Second, when you want people to read your code (like when posting it for help), it's imperative to use more meaningful names, or something to improve code readability, but if you're not going to do this, at least avoid confusing stuff like passing variable named "C" into parameter named "b" if it's avoidable.
Checkout this tutorial. It teaches you how to find segfaults using GDB.