#ifndef _matdiv_n_
#define _matdiv_n_


#include "./utils/matrix.h"
#include "./core/omp_config.h"


namespace numerics{

	template <typename T>
	utils::Matrix<T> matdiv(const utils::Matrix<T>& A, const utils::Vector<T>& b, std::string method){
        
        utils::Matrix<T> C = A;

        if (method == "row"){
            for (uint64_t i = 0; i < A.rows(); ++i){
                for (uint64_t j = 0; j < A.cols(); ++j){
                    C(i,j) /= b[j];
                }
            }
        }else if (method == "col"){
            for (uint64_t i = 0; i < A.rows(); ++i){
                for (uint64_t j = 0; j < A.cols(); ++j){
                    C(i,j) /= b[i];
                }
            }
        }else{
            throw std::runtime_error("matdiv: choose div by: 'row' or 'col'");
        }
        return C;
	}




    template <typename T>
    void inplace_matdiv(utils::Matrix<T>& A, const utils::Matrix<T>& B){
        
        const uint64_t rows = A.rows();
        const uint64_t cols = A.cols();

        if ((rows != B.rows()) || (cols != B.cols())){
            throw std::runtime_error("inplace_matdiv: rows and cols are not the same'");
        }

        for (uint64_t i = 0; i < rows; ++i){
            for (uint64_t j = 0; j < cols; ++j){
                A(i,j) /= B(i,j);
            }
        }
    }


    template <typename T>
    utils::Matrix<T> matdiv(const utils::Matrix<T>& A, const utils::Matrix<T>& B){
        
        const uint64_t rows = A.rows();
        const uint64_t cols = A.cols();

        if ((rows != B.rows()) || (cols != B.cols())){
            throw std::runtime_error("matdiv: choose div by: 'row' or 'col'");
        }

        utils::Matrix<T> C = A;

        inplace_matdiv(C, B);

        return C;
    }

    template <typename T>
    void inplace_matdiv(utils::Matrix<T>& A, const T b){
        
        const uint64_t rows = A.rows();
        const uint64_t cols = A.cols();


        for (uint64_t i = 0; i < rows; ++i){
            for (uint64_t j = 0; j < cols; ++j){
                A(i,j) /= b;
            }
        }
    }




} // namespace numerics

#endif // _matdiv_n_