more matrix problems

• 03-04-2010
Aisthesis
more matrix problems
same template class as in the other thread, but i'll post the current prototypes first for orientation:

Code:

```template<typename T, int n> // n is the Matrix height/width class Matrix { private:         T** content;        // 2-dimensional array of T objects public:         // default constructor should use default T object if there is one         Matrix();         // creates uniform Matrix (all values = t)         Matrix(const T& t);         // construct a Matrix from an array         Matrix(const T arr[][n]);         // copy constructor         Matrix(const Matrix& m);         // destructor         ~Matrix();         // assignment         Matrix<T, n>& operator=(const Matrix<T, n>& m);         // 'at' function (indexing)         T at(const int i, const int j);         // basic matrix operations         // addition         Matrix<T, n> operator+(const Matrix<T, n>& m) const;         // scalar multiplication         friend Matrix<T, n> operator*(T t, const Matrix<T, n>& m);         //Matrix<T, n> scalar_mult(const T& t) const;         // other methods         void show(); };```
The 'at' function is my current problem. I'd obviously like to have a prototype of the form
T& at(const int i, const int j);
but I can't get it to work that way. Here's the definition:
Code:

```template<typename T, int n> T Matrix<T, n>::at(const int i, const int j) {         if (1 <= i && i <= n && 1 <= j && j <= n)                 return content[i - 1][j - 1];         else         {                 std::cout << "Invalid index!\n";                 return NULL;         } }```
Aside from whether or not the else part will even work, this stops working as soon as I change the return type to T& and then in the if part use return &content[i - 1][j - 1]; (I thought it was kind of nice to convert to standard matrix notation.

How do I get a reference here so that I can not only show what the value is but also use this function to assign values inside my matrix?
• 03-04-2010
Salem
Well if you're returning a reference, you can't return NULL.

My guess is you throw an exception instead.
Perhaps follow what std::vector.at() does when it has a problem.
• 03-04-2010
Aisthesis
fair enough, so something like this?
Code:

```// 'at' function: indexing using normal MATRIX notation (starting at row/col 1 not 0) template<typename T, int n> T Matrix<T, n>::at(const int i, const int j) throw(std::out_of_range) {         if (i < 1 || n < i || j < 1 || n < j)                 throw std::out_of_range("Matrix index out of range");         else                 return content[i - 1][j - 1]; }```
That still leaves the problem of returning a reference so that we can not only look at the value but also assign it-- and this doesn't work:
Code:

```template<typename T, int n> T& Matrix<T, n>::at(const int i, const int j) throw(std::out_of_range) {         if (i < 1 || n < i || j < 1 || n < j)                 throw std::out_of_range("Matrix index out of range");         else                 return &content[i - 1][j - 1]; }```
• 03-04-2010
laserlight
You do not need to change anything other than the return type when changing to return a reference. What you did is to change the return type to a reference type, but then you changed the return statement to return the address. Therefore, there is a type mismatch.
• 03-04-2010
GReaper
I'd want to see how you'll perform matrix multiplication with this class....
• 03-04-2010
GReaper
I prepare using 1D arrays for multiplication. They are, at my opinion, simpler.
• 03-04-2010
Aisthesis
I was thinking multiplication would be hard, too, but that turned out to work easily.
Code:

```template<typename T, int n> Matrix<T, n> Matrix<T, n>::operator*(const Matrix<T, n>& m) const {         T arr[n][n];         for (int i = 0; i < n; ++i)         {                 for (int j = 0; j < n; ++j)                 {                         arr[i][j] = 0;        // initialize before doing multiplication                         for (int k = 0; k < n; ++k)                         {                                 arr[i][j] += content[i][k] * m.content[k][j];                         }                 }         }         return Matrix<T, n>(arr); }```
Where i'm bogging down is with the recursive def of determinants (which also suffers from a clunky version of scalar multiplication). More on those later.

Weird that I could get matrix multiplication to work with no problem but that scalar multiplication is looking very ugly.

Also need to try laser's suggestion on at and see what happens (if i'm understanding it right).
• 03-04-2010
Aisthesis
right on again, laser. it at least compiled when i just changed the return types in prototype and definition to T&. Now i'll have to make sure it also allows me to make assignments.
• 03-04-2010
Aisthesis
assigment worked, too! tx!!
now just scalar multiplication and determinants (which i knew would be hard as i'm a recursion novice) left to go.
• 03-04-2010
Aisthesis
here's the current "at", just to close that one out for now:
Code:

```template<typename T, int n> T& Matrix<T, n>::at(const int i, const int j) throw(std::out_of_range) {         if (i < 1 || n < i || j < 1 || n < j)                 throw std::out_of_range("Matrix index out of range");         return content[i - 1][j - 1]; }```
• 03-05-2010
GReaper
Well, even if your class is correct, it's useless! Only 3x3 and 4x4 matrices are useful, for me, as i'm building a 3D maths library