#ifndef _inverse_n_
#define _inverse_n_


#include "./utils/vector.h"
#include "./utils/matrix.h"

#include "./numerics/inverse/inverse_gauss_jordan.h"
#include "./numerics/inverse/inverse_lu.h"

#include <omp.h>


namespace numerics{
	
	template <typename T>
   	void inplace_inverse(utils::Matrix<T>& A, std::string method = "Gauss-Jordan"){

		if (A.rows() != A.cols()) {
		    throw std::runtime_error("inplace_inverse: non-square matrix");
		}

   		if (method == "Gauss-Jordan"){
   			inverse_gj(A);
		}
		else if(method == "LU"){
			inplace_inverse_lu(A);
		}
		else{
			throw std::runtime_error("numerics::inplace_inverse(" + method + ") - Not implemented yet \r \nImplemented: 'Gauss-Jordan', 'LU'");
		}
	}



	template <typename T>
	utils::Matrix<T> inverse(utils::Matrix<T>& A, std::string method = "Gauss-Jordan"){
		utils::Matrix<T> B = A;
		inplace_inverse(B, method);
		return B;
	}

} // namespace numerics

#endif // _inverse_n_