Arrays-Matrices-Addition-C++

Started by
4 comments, last by senelebe 18 years ago
Well, still struggling with arrays, I can't seem to escape them. I wanted to find a good practice for using vectors, so I turned to linear algebra. Much to my dismay I realize vectors don't really do multidimensional. So, back to the arrays, gotta have multidimensional storage... I get my first matrix program up and running, variable sized matrix creation and inverting (with labels!). Works like a charm. Phase 2: adding, subtracting two matrices. Whoa there buddy! I've been floundering for hours now. It seems as though passing arrays, adding arrays and returning arrays is quite the complex get up! Apparently functions cannot return an array, who knew? No problem, I'll just create a pointer to an int, pass that back right? HAHAHA! no. Seems you cannot add two arrays to a pointer, nor can you add two arrays to another array to a pointer, nor can you add two pointers! Yes all pretty basic stuff I suspect.


#include "stdafx.h"
using namespace std;

const int UBOUND = 10;
typedef int matrix[UBOUND][UBOUND];
const int* addMatrix(matrix a1, matrix a2, int iUbound);

int main()
{
//....blah blah code
}

const int* addMatrix(matrix a1, matrix a2, int iUbound)
{
    const int* pa;
    matrix a3;
    for(int i = 0; i < iUbound; i++)
    {
       for(int x = 0; x < iUbound; x++)
       {
            a3[x] = a1[x] + a2[x];
            // const int a3[x] = a1[x] + a2[x]; thought maybe this, hah
            // const int *a3... knew that wouldn't work...
            // matrix a3 = ... non constant...
            // const matrix a3 = ....illegal definition....

            pa = a3;
       }
    }return pa;
}

Looking at it, I just knew this was going to work... hahaha..it didn't. While I realize I'm above my head at the moment, this is where the learning brought me today. As you can tell, my brain is fried atm, and just thought I'd share my adventures in C++. Hope everyone enjoys. Back to vectors tommorow even if they are one dimensional. I love C++.
Advertisement
You do not need physically multidimensional arrays. You can treat a single-dimensional array as a multidimensional one (and it is often better to do it that way). Consider:
int array[width * height];  // set element at [0,0] to 5;  array[0 * width + 0] = 5;    // set element at [1,4] to 10:  array[4 * width + 1] = 10;  // thus, in general:  // set element at [x,y] to n:  array[y * width + x] = n;


Every "width" elements of the array constitutes a single row of the "matrix." Thus (using 0-based indexing, of course), the 0th element of the 1st row is "width" elements into the array. The 0th element of the second row is 2 * "width" elements into the array. The 5th element of the second row is (2 * "width") + 5 elements in (the 2 * width gets you to the 0th element of the second row, then you move 5 elements in).

This will work with std::vector as well, so use that and not raw pointers. Better yet, wrap the matrix in a class and hide the accessing behind a member function:
class matrix{  public:    matrix(int width,int height)    : mVec(width * height),mWidth(width),mHeight(height)    {    }      // use operator() for indexing    int& operator(int x,int y)    {      return mVec[y * mWidth + x];    }  private:    std::vector< int > mVec;  // actual data    int                mWidth;    int                mHeight;}


This allows you to do:
matrix  m(5,5);  m(2,3) = 10;  std::cout << m(2,3) << std::endl;  // prints 10


You can extend this class to overload operators such as addition, use templates to allow multiple underlying types (int, float, whatever) or specify matrix size at compile time instead of run time.

And before you ask, you can set up a way to use the old m[x][y] syntax, if you really, really want. But you generally shouldn't, for a number of reasons.
Quote:Original post by senelebe
*** Source Snippet Removed ***
You are asking for all sorts of trouble there :-) Here are a couple of random suggestions:

1. If what you're interested in is the functionality, use a pre-existing linear algebra library. Otherwise...
2. Create a matrix class rather than using a typedef...
3. Use std::vector<> for the internal storage...
4. Expose two-dimensional array access via class methods.

If this is for game math (transformations and the like) rather than general linear algebra, you'll probably want to take a more specialized approach.

There are some specific issues with your code that it would be a good idea to understand and learn about, but I'm guessing that by the time I hit the 'reply' button there will already be a few posts addressing said issues :-)
Boost::multi_array. Really.
That is an excellent suggestion; I tend to forget about multi_array since I don't often need to use it.
First let me thank everyone for their input. I played around with the vector class a bit, it was great. I also looked into Boost. While I'm sure many will scoff, it gets under my skin if I cannot figure something out. Keep in mind this is all just practice. While I'm sure it's type unsafe and not well managed I did get it to work, and that made my night. Anyways...

#include "stdafx.h"using namespace std;const int UBOUND = 10;typedef int (*ptrMatrix)[UBOUND];typedef int matrix[UBOUND][UBOUND];ptrMatrix addMatrix(int a1[][UBOUND], int a2[][UBOUND], int iUBound);int main(){    matrix a;    matrix b;    for(int i = 0; i < UBOUND; i++)    {	for(int j = 0; j < UBOUND; j++)        {	     a[j] = i * i;	     b[j] = j * j;	}    }    int z = 0;    ptrMatrix ptrC = addMatrix(a, b, UBOUND);    for(int i = 0; i < UBOUND; i++)    {             for(int j = 0; j < UBOUND; j++)	 {                ++z;	     cout << "Record : " << z << ", Row: " << i << ", Col: "                     << j << ", Value: " << ptrC[j] << '\n';                                      	 }    }return 0;}ptrMatrix addMatrix(int a1[][UBOUND], int a2[][UBOUND], int iUBound){    ptrMatrix ptrA;    for(int i = 0; i < iUBound; i++)    {       for(int x = 0; x < iUBound; x++)       {            a1[x] = a1[x] + a2[x];	       }    }	ptrA = a1;	return ptrA;}


I'm sure it'd be better in a class or better with vectors or with boost... I don't know oop well enough to design the classes, I don't know vector well enough and there's something invigorating about running through f7/f5/f11 until you figure it out. It's the joy of tinkering. Given the VERY few resources I found (count 0) on returning multidimensional array pointers from functions... I don't feel too bad about it.

This topic is closed to new replies.

Advertisement