2

I want to get into neural networks and that's why I want to write my own C++ matrix class. The problem is that I'm also pretty new to C++ and to keep things simple, I want to use a std::vector instead of an 2D-Array. At the moment my class looks something like

class Matrix {

private:

    std::vector<std::vector<float>> data_;

public:

    Matrix(const int& rows, const int& columns);
};

I know that a std::vector is a bit of overhead but I want to keep that overhead as small as possible with shrinking the vector only to the exact size needed:

Matrix::Matrix(const int &rows, const int &columns) {
    this->data_ = std::vector<std::vector<float>>{};
    this->data_.resize(rows);
    for (auto col : this->data_) {
        col.resize(columns);
    }

}

My question is: Does this shrinking work the way I intended or is there a better way to do it?

Thanks alot!

Christophe
  • 68,716
  • 7
  • 72
  • 138
Warsakul
  • 25
  • 2
  • *I want to get into neural networks and that's why I want to write my own C++ matrix class.* Why not use one that already exists? (Also if I were to write one I would use a vector not vector>, translating a 2D index to a 1D index is fairly simple math) – Borgleader May 05 '19 at 20:16
  • Because I want to understand how exactly they work. Even if my implementation will not be perfect (and it won't be :P) I want to learn how everything works. – Warsakul May 05 '19 at 20:18
  • I've already thought about using a 1 dimensional vector and translating the indices. Thank you for that tip! – Warsakul May 05 '19 at 20:19

1 Answers1

2

Shrinking means making smaller. Given the context of the constructor, I think you mean enlarging.

Your solution is not completely ok, since your for-loop resizes a copy of the vectors that you wanted to resize.

Less important, but worth to be mentioned: In addition, you make an unnecessary copy of an empty vector to initialize data_. In fact, when you enter the constructor's body, all the members are already constructed. Finally, it's not necessary either to use this-> to access members, unless there would be an ambiguity with a parameter name:

Matrix::Matrix(const int &rows, const int &columns) {
    data_.resize(rows);
    for (auto& col : data_) {   // note the & to resize the vector in the vector 
        col.resize(columns);
    }
}

Addendum:

You can also provide explicit parameters for the constructors of the members:

Matrix::Matrix(const int &rows, const int &columns) : data_(rows) {
    for (auto& col : data_) {
        col.resize(columns);
    }
}

If you like concision, you could even go for:

Matrix::Matrix(const int &rows, const int &columns) : data_(rows, vector<float>(columns)) {
}
Christophe
  • 68,716
  • 7
  • 72
  • 138