## row major/col major matrix

### row major/col major matrix

I'm writing a matrix class which can handle row major or
column major storage (and change dynamically).  Here's what
I've come up with:  (some details omitted)

enum orient { row_wise, col_wise };

class A_matrix {
public:
double ** values;
// implements storage in row major fashion
// storage is contiguous, but an array of pointers is
// used to point to each row

virtual orient get_orientation() = 0;
virtual double &operator() (int, int) = 0;

Quote:}

class my_rm_matrix : private A_matrix {
// constructors, etc..

double &operator() (int row, int col) { return values[row][col]; }
orient get_orient() { return row_wise; }

Quote:}

class my_cm_matrix : private A_matrix {
// constructors, etc...
//   to construct an M by N column major matrix
//   simply construct and N by M A_matrix

// switch indices since this is column major storage
double &operator() (int row, int col) { return values[col][row]; }
orient get_orient() { return col_wise; }

Quote:}

class gen_matrix {
private:
A_matrix *internals;
public:
// Constructors, destructor, etc...

// all other matrix operations for this class to be based
// on the following polymorphic access method
double &operator() (int row, int col) { return (*internals)(row,col); }

Quote:}

//-------------------------------------------------------
//-------------------------------------------------------

So here's my question(s).  In order to implement a couple of the
constructors for gen_matrix, I had to do a lot of casting, like so:

#include "h_mat.hpp"
//
//  GEN_MATRIX MEMEBER FUNCTIONS
//
// If you can't tell, I'm a C programmer diving into C++
//
gen_matrix::gen_matrix(const gen_matrix &gg) {
init(0,0);
if( gg.internals ) {
if( (gg.internals)->get_orient() == row_wise ) {
internals = (A_matrix *)
new my_rm_matrix( * ((my_rm_matrix *)gg.internals) );
}
else
internals = (A_matrix *)
new my_cm_matrix(*((my_cm_matrix *)gg.internals));
if (!internals) error(1);
}

Quote:}

//------------------------------------------------
void gen_matrix::init(int rs, int cs, orient st = row_wise) {
if ( rs && cs ) {
if (st == row_wise)
internals = (A_matrix *) new my_rm_matrix(rs,cs);
else
internals = (A_matrix *) new my_cm_matrix(rs,cs);
if (! internals) error(1);
}
else internals = NULL;
Quote:}

//-----------------------------------------------
//

Is this the way to do it?? It seems to work fine, but it doesn't look
very nice.  The thing is, I have standard copy-initializer constructors,

my_rm_matrix::my_rm_matrix(const my_rm_matrix &rm);
my_cm_matrix::my_cm_matrix(const my_cm_matrix &cm);

but not one with an  A_matrix & argument, since A_matrix is abstract.
I had hoped that something like

internals = new my_rm_matrix(gg.internals);

would work, but it doesn't match this up with the appropriate
copy initializer constructor.  And if I don't cast the result of
new back to an A_matrix *, the compiler complains about the private
inheritance of A_matrix in the my_?m_matrix classes.

Note: this is basically the first program I've written with
derived classes, polymorphism, etc...  I'm amazed that the whole
thing works, but it does.  I realize that accessing every element
of a matrix through 3 or 4 pointers isn't optimal, but I thought
it would be a useful exercise to write a matrix class which would
support either storage method and didn't require an if-then-else
for every access.

What I'm looking for is comments, suggestions, or whatever.

Kendall Bailey
PhD graduate student, NC State University
Dept of Mathematics

web:   http://www4.ncsu.edu/eos/users/k/krbailey/www/

[  Read the C++ FAQ: http://www.connobj.com/cpp/cppfaq.htm  ]
[  Moderation policy: http://www.connobj.com/cpp/guide.htm  ]

### row major/col major matrix

>I'm writing a matrix class which can handle row major or
>column major storage (and change dynamically).  Here's what
>I've come up with:  (some details omitted)

You should read "Scientific and Engineering C++" by Barton and
Nackman.

[  Read the C++ FAQ: http://www.connobj.com/cpp/cppfaq.htm  ]
[  Moderation policy: http://www.connobj.com/cpp/guide.htm  ]

Hello All,

Here is the row major initialization:

#define ASIZE 4096
long int A[ASIZE][ASIZE];

void main()
{
double Duration;
clock_t Start, Finish;

int nI,
nJ,
nN;

Start = clock();
for(nN = 0;nN < 100; nN++)
for(nI = 0;nI < ASIZE; nI++)             --Row major initialization
for(nJ = 0; nJ < ASIZE;nJ++)
A[nI][nJ];

Finish = clock();

Duration = (double)(Finish-Start)/CLOCKS_PER_SEC;

cout << "\tDuration = " << Duration << endl;

for column major just switch the above two for loops like so:
for(nJ = 0; nJ < ASIZE;nJ++)
for(nI = 0;nI < ASIZE; nI++)             --Column major initialization
A[nI][nJ];

Im working in Visual Studio 6.0 on Win NT 4.0 sp5

My question is this ..... why is the column major initialization every bit as fast as the Row major?
I expected the Row Major to blow the doors off of the column major.