row major/col major matrix

row major/col major matrix

Post by krbai.. » Fri, 05 Apr 1996 04:00:00



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.

Thanks in advance,

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

Post by Kevin Cli » Sun, 07 Apr 1996 04:00:00



>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  ]


 
 
 

1. Row Major versus Column Major Initialization

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.

Can someone provide an answer?

Rance

2. Big hard drive

3. How to sort a 2D vector by rows and cols?

4. MS-WORD 6.0.1 SDK Kit Exp.

5. Rows and cols

6. Configuring Logon Points

7. How to go trough a grid without changing the col and row properties

8. BOOK: EXPERT SYSTEMS APPLICATIONS

9. Major problem with Win2000 and threads

10. Major doubts regarding File System Drivers

11. Ndis major version

12. Windows 95 DUN - Major SMM PROBLEM

13. limit for major version of type library ?