Difficulty creating Matrix class

I've been trying to debug this matrix class for more than a day now. I'm not experienced with C++ and I'm sure I've made some careless error.

Header:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
                                                                                                                                                                      
#ifndef MATRICIES_MATRIX_H
#define MATRICIES_MATRIX_H

#include <iostream>
#include <initializer_list>
#include <cstdlib>

typedef unsigned int uint;
typedef initializer_list<initializer_list<double>> i_list;

using namespace std;
namespace Matricies{
  class Matrix {

  public:
    size_t rows;
    size_t cols;

    double ** x;

    Matrix(size_t rows, size_t cols);                 // constructor (all elements initialized to 0)                                                                                                        
    Matrix(const i_list & list);                  // constructor (using initializer list)                                                                                                                   

    Matrix(const Matrix & m);                     // copy constructor                                                                                                                                       
    ~Matrix();                                    // destructor                                                                                                                                             

    Matrix add(double s) const;                   // add scalar to this matrix                                                                                                                              
    Matrix add(const Matrix & m) const;           // add this matrix and another matrix                                                                                                                     

    Matrix subtract(double s) const;              // subtract scalar from this matrix                                                                                                                       
    Matrix subtract(const Matrix & m) const;      // subtract another matrix from this matrix                                                                                                               

    Matrix multiply(double s) const;              // multiply this matrix by a scaler                                                                                                                       
    Matrix multiply(const Matrix & m) const;      // multiply this matrix by another matrix                                                                                                                 

    Matrix divide(double s) const;                // divide this matrix by a scaler                                                                                                                         
    Matrix t() const;                             // transpose of this matrix                                                                                                                               

    const uint numRows() const;                   // returns the number of rows                                                                                                                             
    const uint numCols() const;                   // returns the number of cols                                                                                                                             

    double & at(uint row, uint col);              // get/set element at row,col                                                                                                                             
    const double & at (uint row, uint col) const; // get element at row,col (when using a const object)                                                                                                     

  }; //Matrix             



Body:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include "Matrix.h"

using cs1730::Matrix;

Matrix::Matrix(size_t rows, size_t cols){
  this->rows = rows;               // constructor (all elements initialized to 0)                                                                                                                           
  this->cols = cols;
  this->x = new double[cols][cols];
  for(uint i=0; i<cols; ++i)
    for(uint j=0; j<rows; ++j)
      x[i][j] = 0;
}
Matrix::Matrix(const i_list & list){                  // constructor (using initializer list)                                                                                                               
  //keep track of indices                                                                                                                                                                                   
  //get size of list                                                                                                                                                                                        
  //get size of l                                                                                                                                                                                           
  //conditionally allocate space                                                                                                                                                                            
  this->cols = list.size(0);
  this->rows = list.size(1);
  this->x = new double [cols][rows];
  auto list = list.begin();
  for(int i=0; i<cols; ++i)
    for(int j=0; j<rows; ++j)
      x[i][j] = list[i][j];
}

Matrix::Matrix(const Matrix & m){                     // copy constructor                                                                                                                                   
  this->rows = m.rows;
  this->cols = m.cols;
  this->x = new double [cols][rows];
  for(size_t i=0; i<rows; ++i)
    for(size_t j=0; j<cols; ++j)
      x[i][j] = m.at(i,j);
}

Matrix::~Matrix(){                                    // destructor                                                                                                                                         
  delete [] this-> x;
}

Matrix::Matrix add(double s) const{                   // add scalar to this matrix                                                                                                                          
  Matrix ret (*this);
  for(int i=0; i<this.rows; i++)
    for(int j=0; j<this.cols; j++)
      ret.at(i,j) += s;
  return ret;
}
Matrix::Matrix add(const Matrix & m) const{           // add this matrix and another matrix                                                                                                                 
  Matrix ret (*this);
  for(int i=0; i<this.rows; i++)
    for(int j=0; j<this.cols; j++)
      ret.at(i,j) += m.at(i,j);
  return ret;
}
Matrix::Matrix subtract(double s) const{              // subtract scalar from this matrix                                                                                                                   
  Matrix ret (*this);
  for(int i=0; i<this.rows; i++)
    for(int j=0; j<this.cols; j++)
      ret.at(i,j) -= s;
  return ret;
}


Here are some of the errors that have been keeping me up:


For some reason c++ can't read #include <initializer_list>
1
2
3
Matrix.h:10: error: expected initializer before ‘<’ token
Matrix.h:36: error: ISO C++ forbids declaration of ‘i_list’ with no type
Matrix.h:36: error: expected ‘,’ or ‘...’ before ‘&’ token


 
Matrix.cpp:8: error: ‘cols’ cannot appear in a constant-expression


How am I supposed to access the Matrix calling the function? And what would the technical name for the Matrix calling the function be?
 
Matrix.cpp:43: error: invalid use of ‘this’ in non-member function
Last edited on
The error about initializer_list is complaining because initializer_list is in the std namespace. std::initializer_list.
As for the other error, it's not this., it's this->.

Also, minor note on terminology: you can only debug a program that actually runs. Fixing compiler errors is not debugging.
> Matrix.cpp:8: error: ‘cols’ cannot appear in a constant-expression

this->x = new double[cols][cols]; // line 8

The error is because in C++, the size of an array must be a constant known at compile time.


> I'm not experienced with C++

Favour std::vector<double> over dynamically allocated C-style arrays.
https://cal-linux.com/tutorials/vectors.html
Valid advice that even experienced palookas could benefit from.

Makes programming much easier; for instance:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include <iostream>
#include <vector>

struct matrix
{
    matrix( std::size_t nrows, std::size_t ncols, double v = 0 )
        : data( nrows, std::vector<double>( ncols, v ) ) {}

    matrix( std::initializer_list< std::initializer_list<double> > ilist )
        : data( ilist.begin(), ilist.end() )
    {
        std::size_t max_cols = 0 ;
        for( const auto& row : data ) max_cols = std::max( max_cols, row.size() ) ;
        for( auto& row : data ) row.resize( max_cols ) ;
    }

    std::size_t num_rows() const { return data.size() ; }
    std::size_t num_cols() const { return data.empty() ? 0 : data[0].size() ; }

    matrix& operator+= ( double value )
    {
        for( auto& row : data ) for( double& v : row ) v += value ;
        return *this ;
    }

    // etc.

    auto& operator[] ( std::size_t row ) { return data[row] ; }
    const auto& operator[] ( std::size_t row ) const { return data[row] ; }

    // etc.

    private: std::vector< std::vector<double> > data ;
};

matrix operator+ ( matrix m, double d ) { return m += d ; }
matrix operator+ ( double d, const matrix& m ) { return m + d ; }
// etc.

int main()
{
    matrix mtx { { 1.0, 2.0, 3.0 }, { 4.0, 5.0, 6.0, 7.0 }, { 8.0, 9.0 } } ;

    for( std::size_t i = 0 ; i < mtx.num_rows() ; ++i )
    {
        for( std::size_t j = 0 ; j < mtx.num_cols() ; ++j )
            std::cout << std::fixed << mtx[i][j] << ' ' ;
        std::cout << '\n' ;
    }

    std::cout << '\n' ;
    mtx = 100 + mtx ;

    for( std::size_t i = 0 ; i < mtx.num_rows() ; ++i )
    {
        for( std::size_t j = 0 ; j < mtx.num_cols() ; ++j )
            std::cout << std::fixed << mtx[i][j] << ' ' ;
        std::cout << '\n' ;
    }
}

http://coliru.stacked-crooked.com/a/406383d1526a214e
Problem solved, thank you
Topic archived. No new replies allowed.