dimanche 4 novembre 2018

Matrix and Vector Class

I have matrix class which works fine and it has no memory leaks and everything works fine. Now I decided to made the entries of elements of my matrix class generic using templates and another vector class which is nothing but same like matrix class having N rows and 1 column. I made my vector class also generic using template:

But I cannot perform arithmetic operations using operator overloading between matrix and vector object.

Matrix.h, Vector.h and main is given below:

****Matrix.h****

template <typename T>
class Matrix {
private:
    std::size_t row_;
    std::size_t col_;
    T* data;

public:

    Matrix() : row_{ 0 }, col_{ 0 }, data{ nullptr } {}
    Matrix(std::size_t rows, std::size_t cols, T initValue) :row_{ rows }, col_{ cols }, data{ nullptr }
    {
        /*if (rows == 0)
        {
            std::cout << std::endl;
        }
        else
        */
        data = new T[rows*cols];

        for (std::size_t i = 0; i < rows; ++i)
        {
            for (std::size_t j = 0; j < cols; ++j)
            {
                data[i*cols + j] = initValue;

            }
        }

    }

    ~Matrix()
    {

        delete[] data;

    }

    Matrix(const Matrix<T> &source)
    {
        this->data = nullptr;
        this->row_ = source.row_;
        this->col_ = source.col_;
        this->data = new T[source.row_*source.col_];
        for (std::size_t i = 0; i < source.row_; ++i)
        {
            for (std::size_t j = 0; j < source.col_; ++j)
            {
                this->data[i*this->col_ + j] = source.data[i*source.col_ + j];

            }
        }
    }
    Matrix<T>& operator=(const Matrix<T>& source)
    {
        if (this == &source)
        {
            return *this;
        }
        else
            delete[] this->data;
        //this->data = nullptr;
        this->row_ = source.row_;
        this->col_ = source.col_;
        this->data = new T[source.row_*source.col_];
        for (std::size_t i = 0; i < source.row_; ++i)
        {
            for (std::size_t j = 0; j < source.col_; ++j)
            {
                this->data[i*this->col_ + j] = source.data[i*source.col_ + j];
            }
        }
        return *this;
    }

    T& operator()(std::size_t i, std::size_t j)
    {
        return this->data[i*this->col_ + j];
    }

    const T& operator()(std::size_t i, std::size_t j) const
    {
        return this->data[i*this->col_ + j];
    }

    bool operator ==(const Matrix<T>& source) const
    {
        if (this == &source)
        {
            return true;
        }
        if (this->row_ != source.row_ && this->col_ != source.col_)
        {
            return false;
        }
        else if (this->row_ == source.row_ && this->col_ == source.col_)
        {
            for (std::size_t i = 0; i < source.row_; ++i)
            {
                for (std::size_t j = 0; j < source.col_; ++j)
                {
                    if (this->data[i*this->col_ + j] != source.data[i*source.col_ + j])
                    {
                        return false;
                    }
                }
            }

            return true;
        }
        return true;
    }

    bool operator !=(const Matrix<T>& source) const
    {
        if (this->row_ != source.row_ && this->col_ != source.col_)
        {
            return true;
        }
        else if (this->row_ == source.row_ && this->col_ == source.col_)
        {
            for (std::size_t i = 0; i < source.row_; ++i)
            {
                for (std::size_t j = 0; j < source.col_; ++j)
                {
                    if (this->data[i*this->col_ + j] != source.data[i*source.col_ + j])
                    {
                        return true;
                    }
                }
            }

            return false;
        }
        return true;
    }
    Matrix<T>& operator +=(const Matrix<T>& source)
    {

        for (std::size_t i = 0; i < source.row_; ++i)
        {
            for (std::size_t j = 0; j < source.col_; ++j)
            {
                this->data[i*this->col_ + j] = this->data[i*this->col_ + j] + source.data[i*source.col_ + j];
            }
        }
        return *this;
    }
    Matrix<T> operator +(const Matrix<T>& source) const
    {
        Matrix temp;
        temp.row_ = source.row_;
        temp.col_ = source.col_;
        temp.data = new T[source.row_*source.col_];
        for (std::size_t i = 0; i < source.row_; ++i)
        {
            for (std::size_t j = 0; j < source.col_; ++j)
            {
                temp.data[i*temp.col_ + j] = this->data[i*this->col_ + j] + source.data[i*source.col_ + j];
            }
        }
        return temp;
        delete[] temp.data;
    }

    Matrix<T>& operator -=(const Matrix<T>& source)
    {

        for (std::size_t i = 0; i < source.row_; ++i)
        {
            for (std::size_t j = 0; j < source.col_; ++j)
            {
                this->data[i*this->col_ + j] = this->data[i*this->col_ + j] - source.data[i*source.col_ + j];
            }
        }
        return *this;
    }
    Matrix<T> operator -(const Matrix<T>& source) const
    {
        Matrix<T> temp;
        temp.row_ = source.row_;
        temp.col_ = source.col_;
        temp.data = new T[source.row_*source.col_];
        for (std::size_t i = 0; i < source.row_; ++i)
        {
            for (std::size_t j = 0; j < source.col_; ++j)
            {
                temp.data[i*temp.col_ + j] = this->data[i*this->col_ + j] - source.data[i*source.col_ + j];
            }
        }
        return temp;
    }
    Matrix<T> &operator *=(const Matrix<T> & source)
    {
        T val1{ 0 };
        Matrix<T> temp;
        temp.data = new T[this->row_*source.col_];
        temp.row_ = this->row_;
        temp.col_ = source.col_;
        //assert("Size doesn't match!" && this->row_ == source.col_);

        for (std::size_t i = 0; i < this->row_; ++i)
        {
            for (std::size_t j = 0; j < source.col_; ++j)
            {
                val1 = 0;
                for (std::size_t k = 0; k < this->col_; ++k)
                {
                    val1 += this->data[i*this->col_ + k] * source.data[k*source.col_ + j];
                    temp.data[i*temp.col_ + j] = val1;
                }
            }
        }
        this->row_ = temp.row_;
        this->col_ = temp.col_;
        for (std::size_t i = 0; i < temp.row_; ++i)
        {
            for (std::size_t j = 0; j < temp.col_; ++j)
            {
                this->data[i*this->col_ + j] = temp.data[i*temp.col_ + j];
            }
        }


        return *this;

    }

    Matrix<T> operator *(const Matrix<T> &source) const
    {
        //assert("Size doesn't match!" && this->row_ == source.col_);
        Matrix <T>add;
        T val1;
        add.data = new T[this->row_*source.col_];
        add.row_ = this->row_;
        add.col_ = source.col_;

        //std::cout << "Detail of Matrix is given below:" << std::endl;
        //std::cout << "================================" << std::endl;
        for (std::size_t i = 0; i < this->row_; ++i)
        {
            for (std::size_t j = 0; j < source.col_; ++j)
            {
                val1 = 0;
                for (std::size_t k = 0; k < this->col_; ++k)
                {
                    val1 += this->data[i*this->col_ + k] * source.data[k*source.col_ + j];
                    add.data[i*add.col_ + j] = val1;
                }
            }
        }
        return add;
    }

    std::size_t rows() const
    {
        return this->row_;
    }
    std::size_t cols() const
    {
        return this->col_;
    }
    friend std::ostream& operator <<(std::ostream& out, const Matrix<T>& source)
    {

        for (std::size_t i = 0; i < source.row_; ++i)
        {
            if (i > 0) {
                std::cout << "\n";
            }
            for (std::size_t j = 0; j < source.col_; ++j)
            {
                out << source(i, j) << " ";
            }
        }
        return out;
    }
    friend std::istream& operator >>(std::istream& in, Matrix<T>& source)
    {
        for (std::size_t i = 0; i < source.row_; ++i)
        {
            for (std::size_t j = 0; j < source.col_; ++j)
            {
                in >> source(i, j) >> std::ws;

            }
        }
        return in;
    }

    Matrix<T> & inverseDiagonal()
    {
        assert("Square Matrix is accepted!" && this->row_ == this->col_);
        std::cout << "Inverse is given below:" << std::endl;
        for (std::size_t i = 0; i < this->row_; ++i)
        {
            for (std::size_t j = 0; j < this->col_; ++j)
            {
                if (i == j) {
                    this->operator()(i, j) = 1 / this->operator()(i, j);
                }
                else
                {
                    this->operator()(i, j) = 0;
                }
            }
        }
        return *this;
    }
};``

Vector.h

 template <typename U>
 class Vector {
 private:


std::size_t row_;
    U* data;

public:

    Vector() : row_{ 0 }, data{ nullptr } {}
    Vector(std::size_t rows)
    {
        row_ = rows;
        this->data = new U[rows];
    }
    Vector(std::size_t rows, U initValue) :row_{ rows }, data { nullptr }
    {
        /*if (rows == 0)
        {
            std::cout << std::endl;
        }
        else
        */
        data = new U[rows];

        for (std::size_t i = 0; i < rows; ++i)
        {

                data[i] = initValue;


        }

    }

    ~Vector()
    {

        delete[] data;

    }

    explicit Vector(const Vector &source)
    {
        this->data = nullptr;
        this->row_ = source.row_;
        this->data = new U[source.row_];
        for (std::size_t i = 0; i < source.row_; ++i)
        {

                this->data[i] = source.data[i];


        }
    }
    Vector<U>& operator=(const Vector<U>& source) 
    {
        if (this == &source)
        {
            return *this;
        }
        else
            delete[] this->data;
        //this->data = nullptr;
        this->row_ = source.row_;
        this->data = new U[source.row_];
        for (std::size_t i = 0; i < source.row_; ++i)
        {

                this->data[i] = source.data[i];

        }
        return *this;
    }

    auto & operator()(std::size_t i)
    {
        return this->data[i];
    }

    const auto & operator()(std::size_t i) const
    {
        return this->data[i];
    }

    bool operator ==(const Vector<U> & source) const
    {
        if (this == &source)
        {
            return true;
        }
        if (this->row_ != source.row_ )
        {
            return false;
        }
        else if (this->row_ == source.row_ )
        {
            for (std::size_t i = 0; i < source.row_; ++i)
            {

                    if (this->data[i] != source.data[i])
                    {
                        return false;
                    }

            }

            return true;
        }
        return true;
    }

    bool operator !=(const Vector<U> & source) const
    {
        if (this->row_ != source.row_ )
        {
            return true;
        }
        else if (this->row_ == source.row_ )
        {
            for (std::size_t i = 0; i < source.row_; ++i)
            {

                    if (this->data[i] != source.data[i])
                    {
                        return true;
                    }

            }

            return false;
        }
        return true;
    }
    Vector<U> & operator +=(const Vector<U> & source)
    {

        for (std::size_t i = 0; i < source.row_; ++i)
        {

                this->data[i] = this->data[i] + source.data[i];

        }
        return *this;
    }
    Vector<U> operator +(const Vector<U>& source) const
    {
        Vector<U> temp;
        temp.row_ = source.row_;

        temp.data = new U[source.row_];
        for (std::size_t i = 0; i < source.row_; ++i)
        {

                temp.data[i] = this->data[i] + source.data[i];

        }
        return temp;
        delete[] temp.data;
    }
    Vector<U> operator [] (std::size_t i)
    {
        return this->data[i];
    }

    Vector<U>& operator -=(const Vector<U>& source)
    {

        for (std::size_t i = 0; i < source.row_; ++i)
        {

                this->data[i] = this->data[i] - source.data[i];

        }
        return *this;
    }
    Vector<U> operator -(const Vector<U>& source) const
    {
        Vector<U> temp;
        temp.row_ = source.row_;
        temp.data = new  U[source.row_];
        for (std::size_t i = 0; i < source.row_; ++i)
        {

                temp.data[i] =this->data[i] - source.data[i];

        }
        return temp;
    }


    Vector<U> &operator *=(const Vector<U> & source)
    {
        double val1{ 0 };
        Vector<U> temp;
        temp.data = new U[this->row_];
        temp.row_ = this->row_;

        //assert("Size doesn't match!" && this->row_ == source.col_);

        for (std::size_t i = 0; i < this->row_; ++i)
        {
                val1 = 0;
                for (std::size_t k = 0; k < source.row_; ++k)
                {
                    val1 += this->data[i*this->row_ + k] * source.data[k*source.row_ + i];
                    temp.data[i*temp.row_+ k] = val1;
                }

        }
        this->row_ = temp.row_;

        for (std::size_t i = 0; i < temp.row_; ++i)
        {

            this->data[i] = temp.data[i];

        }


        return *this;

    }
    Vector<U> operator *(const Vector<U> &source) const
    {
        //assert("Size doesn't match!" && this->row_ == source.col_);
        Vector<U> add;
        U val1;
        add.data = new U[this->row_];
        add.row_ = this->row_;

        //std::cout << "Detail of Vector is given below:" << std::endl;
        //std::cout << "================================" << std::endl;
        for (std::size_t i = 0; i < this->row_; ++i)
        {

                val1 = 0.;
                val1 += this->data[i] * source.data[i];
                add.data[i] = val1;


        }
        return add;
    }

    std::size_t rows() const
    {
        return this->row_;
    }
    std::size_t size() const
    {
        return this->row_;
    }

    friend std::ostream& operator <<(std::ostream& out, const Vector<U>& source)
    {

        for (std::size_t i = 0; i < source.row_; ++i)
        {


                out << source(i) << " ";

        }
        return out;
    }
    friend std::istream& operator >>(std::istream& in, Vector<U>& source)
    {
        for (std::size_t i = 0; i < source.row_; ++i)
        {

                in >> source(i) >> std::ws;


        }
        return in;
    }

    double  l2Norm() const
    {
        //auto lambda = [&](double a, double b) {return a + b * b;};

        //std::cout << this->data << std::endl;
        //double l2 = std::accumulate(this->*data.std::begin(), this->data.std::end(), 0., lambda);

        double norm = 0.;
        for (std::size_t i = 0; i < row_; ++i)
             norm += this->data[i] * this->data[i];
        return sqrt(norm);

    }

};

main.cpp

int main()
{
    Matrix<double> A(5, 5, 50);
    Vector <double> b(5, 50);
    std::cout << "Matrix" << std::endl;
    std::cout << A << std::endl;
    std::cout << "Vector" << std::endl;
    std::cout << b << std::endl;
    std::cout << b - A << std::endl;
    system("Pause");
    return 0;
}

Error: error C2679: binary '-': no operator found which takes a right-hand operand of type 'Matrix' (or there is no acceptable conversion)

note: could be 'Vector Vector::operator -(const Vector &) const'

note: while trying to match the argument list '(Vector, Matrix)'

Aucun commentaire:

Enregistrer un commentaire