0
#include<iostream>
using namespace std;


void transpose(const int input[2][3], int (&output)[3][2]){
    for(int i=0; i<2; ++i) {
        for(int j=0; j<3 ; ++j) {
            output [j][i] = input [i][j];
        }
    }
}

void printMultiArray(const int multi[2][3], const int len){
    for (int row=0; row<2; row++){
        for (int col=0; col<3; col++){
            cout << multi[row][col] << " " ;
        }                               
        cout << endl;                           
    }                                               
}   


int main(){

    int multi[2][3] = {{1, 2, 3}, {7, 8, 9}};
    int empty[3][2];


    printMultiArray(multi, 6);
    cout << "... space line ..." << endl;

    transpose(multi, empty);
    printMultiArray(empty, 6);


    return 0;
}

I have the above code to tranpose a 2x3 array... but it does not compile and fails with:

6-3-transposeArray.cpp: In function ‘int main()’:
6-3-transposeArray.cpp:33: error: cannot convert ‘int (*)[2]’ to ‘const int (*)[3]’ for argument ‘1’ to ‘void printMultiArray(const int (*)[3], int)’

I am not sure what the problem is though. It seems to be complaining about the 1st arg to transpose() but printMultiArray() seems to have no problem with the array being passed in the same manner.

Secondly is there a more generic way to implement this? (e.g. a generic func that could take in 2x3, 2x4 and 2x5 arrays and return the transpose of each)

Bit of a basic question but Any help appreciated :)

mbbxedh2
  • 137
  • 1
  • 2
  • 11
  • Any reason you are not using `std::vector< std::vector<> >` or something similar? Also the simplest way to transpose is to invert `(i,j)`: http://stackoverflow.com/questions/16737298/what-is-the-fastest-way-to-transpose-a-matrix-in-c – Shafik Yaghmour Jul 16 '13 at 16:09
  • You really, *really*, ***really*** don't want to save second order tensors like this. This is a job for a nicely designed class (which could use `std::vector` for interior memory purposes). If you don't know about classes yet, read a book. – Zeta Jul 16 '13 at 16:10
  • Is Boost uBlas an option? See this [question](http://stackoverflow.com/questions/4097153/how-to-transpose-matrix-using-ublas). – dwxw Jul 16 '13 at 16:13

3 Answers3

3

It seems to be complaining about the 1st arg to transpose()

No, the error clearly says the problem is with the first argument to printMultiArray. You're passing a 3x2 array, and the function is hard-coded for a 2x3 array.

Secondly is there a more generic way to implement this?

Yes; you can use integer template parameters to specify the dimensions:

template <size_t N, size_t M>
void transpose(const int (&input)[N][M], int (&output)[M][N]) {
    for (size_t i = 0; i < N; ++i) {
        for (size_t j = 0; j < M; ++j) {
            output[j][i] = input[i][j];
        }
    }
}

The correct template specialisation can be deduced from the function arguments:

transpose(multi, empty); // Automatically selects N=2, M=3.

Similarly, you can implement a generic printMultiArray to fix your error.

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
0

Create a class that contains a vector. In the constructor pass the x and y size of the matrix, and resize the vector to x * y. Create get/set functions (or operator []) which take the x, y coordinate the user wishes to access. Also have a "transposed" bool flag in the class. If the flag is true, swap x and y, and then return vec[x + y * sizex]. Now transposing the array does not need any copying. Just flip the flag.

Neil Kirk
  • 21,327
  • 9
  • 53
  • 91
0

You could implement these using std::vectors and it would be much more readable and manageable.

BUT if you want something that is generic I would use Eigen. If you insist on implementing yourself and you want something generic I would build a class that does this for you. I won't go too much into the design but it could be something like

newMat = oldMat.Transpose()

where newMat and oldMat are of a MyMatrix class that you implement

sedavidw
  • 11,116
  • 13
  • 61
  • 95