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");
    }


}

      

+3


source to share


2 answers


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

    x width

    ).

    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.

+2


source


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;

      

0


source







All Articles