How to transfer a matrix to C? - mistake
I am trying to write a function to transpose matrices.
parameters of this function:
-
matrix for transposition
-
the output matrix, which is empty.
The problem is that I can transpose some matrices, but some others fail, like the one I give in my example. What for? how can i solve it?
code:
int main (void)
{
//this works well
/* double array[3][2] = {{1,2},{3,4},{5,6}};
height = 3;
width = 2;
*/
//this input doesn't work
double array[2][3] = {{1,2,3},{4,5,6}};
height = 2;
width = 3;
int heightOutput = width; //2
int widthOutput = height; //3
double **output;
output = malloc(widthOutput * sizeof(double *)); //rows from 1
for (i = 0; i < widthOutput; i++)
{
output[i] = malloc(heightOutput * sizeof(double)); //columns
}
transposeMatrix(&array[0][0], height,width, &output[0][0], heightOutput, widthOutput);
printf("\n");
printf("\noutput matrix\n");
for(i=0;i<heightOutput;i++)
{
for(j=0;j<widthOutput;j++)
{
printf("%f\t",output[i][j]);
}
printf("\n");
}
}
void transposeMatrix(double* array2, int height, int width, double * output, int height2, int width2)
{
double workaround[3][3] ={0};
double result;
int i,j;
printf("input matrix:\n");
for(i=0;i<height;i++)
{
for(j=0;j<width;j++)
{
printf("%f\t",(*((array2+i*width)+j)));
}
printf("\n");
}
printf("\n");
for(i=0;i<width2;i++)
{
for(j=0;j<height2;j++)
{
result = (*((array2+i*width)+j));
workaround[i][j] = result;
}
}
for(i=0;i<width2;i++)
{
for(j=0;j<height2;j++)
{
*((output+j*3)+i) = workaround[i][j];
printf("%f\t",(*((output+j*3)+i)));
}
printf("\n");
}
}
source to share
The main problem is that you are confusing with matrix sizes.
-
When you fill the matrix
workaround
, your loop should be like this, since the size of the original matrix is ββ(height
xwidth
).for(i=0;i<width;i++) { for(j=0;j<height;j++) { result = (*((array2+i*width)+j)); workaround[i][j] = result; } }
-
When transferring a matrix
for(i=0;i<height2;i++) { for(j=0;j<width2;j++) { *((output+i*width2)+j) = workaround[j][i]; printf("%f\t",(*((output+i*width2)+j))); } }
-
In memory allocation you got the wrong sizes too, it should be
output = malloc(heightOutput * sizeof(double *)); //rows from 1 for (i = 0; i < heightOutput; i++) { output[i] = malloc(widthOutput * sizeof(double)); //columns }
With these changes, your program will run without errors, but the output will still be erroneous.
input matrix: 1.000000 2.000000 3.000000 4.000000 5.000000 6.000000 1.000000 2.000000 3.000000 4.000000 5.000000 6.000000 output matrix 1.000000 4.000000 5.000000 0.000000 0.000000 0.000000
-
The last problem is in passing arguments. You are allocating memory dynamically, pointers to strings first
output = malloc(heightOutput * sizeof(double *)); //rows from 1
With this you got an array of pointers
* -> NULL * -> NULL * -> NULL
and with a loop you assign values ββto them
for (i = 0; i < heightOutput; i++) { output[i] = malloc(widthOutput * sizeof(double)); //columns } * -> [e00, e01] * -> [e10, e11] * -> [e20, e21]
But there is no guarantee that they will be distributed one by one, but you are working with
output
as with linear allocated data. To work with this correctly, you need to pass in a double pointer.void transposeMatrix(double* array2, int height, int width, double ** output, int height2, int width2) { ... for(i=0;i<width2;i++) { for(j=0;j<height2;j++) { output[j][i] = workaround[i][j]; printf("%f\t",output[j][i]); } printf("\n"); } }
If you want to allocate linear memory, do as follows
output = malloc(heightOutput * widthOutput * sizeof(double));
But it all looks pretty complicated to me, it just looks like
void transposeMatrix(double* src, double* dst, int n, int m)
{
int i, j;
for(i = 0; i < n; ++i)
for(j = 0; j < m; ++j)
dst[j * n + i] = src[i * m + j];
}
int main(void)
{
double array[2][3] = {{1,2,3},{4,5,6}};
int height = 2;
int width = 3;
int i, j;
double *output = malloc(height * width * sizeof(double));
printf("input matrix\n");
for(i=0;i<height;i++)
{
for(j=0;j<width;j++)
{
printf("%f\t",array[i][j]);
}
printf("\n");
}
transposeMatrix(&array[0][0], output, height,width);
printf("output matrix\n");
for(i=0;i<width;i++)
{
for(j=0;j<height;j++)
{
printf("%f\t",output[i*height + j]);
}
printf("\n");
}
}
Edit: To answer your comment: let's say we have a 4 * 5 matrix
| a00 a01 a02 a03 a04 |
| a10 a11 a12 a13 a14 |
| a20 a21 a22 a23 a24 |
| a30 a31 a32 a33 a34 |
In memory allocated with
// n = 4, m = 5
double* A = malloc(n * m * sizeof(double));
it will look like
| a00 a01 a02 a03 a04 a10 a11 a12 a13 a14 a20 a21 a22 a23 a24 a30 a31 a32 a33 a34 |
So to get a let say (2, 3) element, we need to skip 2 * 5 elements (these are two lines of 5 elements) and 3 elements from the beginning of the third row, so - 13 elements to skip in the array, And to generalize for a matrix m * n to get element (i, j) we need to skip (i * m) + j elements in the array.
source to share
include stdio.h
include conio.h
include string.h
include stdlib.h
int main(){
int i,j,n,t=0,a[100][100],k,l,b=0;
printf(" n="); // you write the number or rows and columns or the matrix
scanf("%d",&n);
for(i=1;i<=n;i++){ //you write the elements of the matrix
for(j=1;j<=n;j++){
printf("a[%d][%d]=",i,j);
scanf("%d",&a[i][j]);
}
}
printf("\n");
for(i=1;i<=n;i++){ //you can see you original matrix
for(j=1;j<=n;j++){
printf("%d ",a[i][j]);
}
printf("\n");
}
printf("\n -\n");
for (i=2; i<=n; i++) { //now we transpose the original matrix
for (j=1; j < i; j++) {
t = a[i][j];
a[i][j] = a[j][i];
a[j][i] = t;
printf("\n da \n");
}
}
// now we can see the transposition of the matrix
// and compare it with the first
printf("\n \n ");
for(i=1;i<=n;i++){
for(j=1;j<=n;j++){
printf("%d ",a[i][j]);
}
printf("\n");
}
printf("\n \n");
system("PAUSE");
return 0;
source to share