#include "Matrix.h"

Matrix::Matrix(){
  //Do Nothing;
}

Matrix::Matrix(int row, int column, vector <double> coefficient){
  this->row = row;
  this->column = column;
  this->coefficient = coefficient;
}

void Matrix::setMatrix(int row, int column, vector<double> coefficient){
  this->row = row;
  this->column = column;
  this->coefficient = coefficient;
}

vector<double> Matrix::getCoefficient() const {
  return this->coefficient;
}

int Matrix::getRow() const {
  return this->row;
}

int Matrix::getColumn() const {
  return this->column;
}

void Matrix::operator()(){
  auto it = this->coefficient.begin();
  for(int i=0; i<this->row; i++){
    for(int j=0; j<this->column; j++){
      cout << fixed << setprecision(2) << setw(8) << *it++;
    }
    cout << endl;
  }
}

bool Matrix::isAddable(const Matrix& matrix){
  if(this->row == matrix.getRow() && this->column == matrix.getColumn())
    return true;
  return false;
}

bool Matrix::isSubstractable(const Matrix& matrix){
  if(this->row == matrix.getRow() && this->column == matrix.getColumn())
    return true;
  return false;
}

bool Matrix::isMultipliable(const Matrix& matrix){
  if(this->column == matrix.getRow())
    return true;
  return false;
}

Matrix Matrix::operator+(const Matrix& matrix){
  Matrix res;
  vector <double> result;
  //transform(this->coefficient.begin(), this->coefficient.end(), matrix.coefficient.begin(), result.begin(), ::plus<int>());
  auto it1 = this->coefficient.begin();
  auto it2 = matrix.coefficient.begin();
  for( ;it1 != this->coefficient.end(); it1++, it2++){
    double num = *it1 + *it2;
    result.push_back(num);
  }
  res.setMatrix(this->row, this->column, result);
  return res;
}

Matrix Matrix::operator-(const Matrix& matrix){
  Matrix res;
  vector <double> result;
  auto it1 = this->coefficient.begin();
  auto it2 = matrix.coefficient.begin();
  for( ;it1 != this->coefficient.end(); it1++, it2++){
    double num = *it1 - *it2;
    result.push_back(num);
  }
  res.setMatrix(this->row, this->column, result);
  return res;
}

Matrix Matrix::operator*(const Matrix& matrix){
  Matrix res;
  vector <double> result;
  auto it1 = this->coefficient.begin();
  auto it2 = matrix.coefficient.begin();
  for(int i=0; i<this->row; i++){
    for(int j=0; j<matrix.column; j++){
      double sum = 0;
      for(int k=0; k<this->column; k++){
        sum += *(it1 + i*this->column+k) * *(it2 + k*matrix.column+j);
      }
      result.push_back(sum);
    }
  }
  res.setMatrix(this->row, matrix.column, result);
  return res;
}