"""
gauss_jordan(A::AbstractMatrix{T}) where T<:Number
Gaussian elimination, also known as row reduction, is an algorithm for solving systems of linear equations.
It consists of a sequence of operations performed on the corresponding matrix of coefficients.
This method can also be used to compute the rank of a matrix, the determinant of a square matrix, and the inverse of an invertible matrix.
https://en.wikipedia.org/wiki/Gaussian_elimination
# Examples/Tests
```julia
julia> M1 = [1 2 3; 4 5 6];
julia> M2 = [1 2 3; 4 8 12];
julia> @test gauss_jordan(M1) == [1 0 -1; 0 1 2] # Test Passed
julia> @test_throws AssertionError gauss_jordan(M2) # Test Passed - Thrown: AssertionError
```
# Contributed By:- [AugustoCL](https://github.com/AugustoCL)
"""
function gauss_jordan(A::AbstractMatrix{T}) where {T<:Number}
m, n = size(A)
if m == n
@assert determinant(A) ≠ 0.0 "Must insert a non-singular matrix"
else
@assert determinant(A[:, 1:(end-1)]) ≠ 0.0 "Must insert a non-singular matrix or a system matrix [A b]"
end
for i in axes(A, 1)
if A[i, i] == 0.0
for n in (i+1):m
if A[n, i] ≠ 0.0
L = copy(A[i, :])
A[i, :] = A[n, :]
A[n, :] = L
break
end
end
end
@. A[i, :] = A[i, :] ./ A[i, i]
for j in axes(A, 1)
if j ≠ i
@. A[j, :] = A[j, :] - A[i, :] * A[j, i]
end
end
end
return A
end
function gauss_jordan(A::AbstractMatrix{T}) where {T<:Integer}
return gauss_jordan(convert(Matrix{Float64}, A))
end