# Calculating the determinant of a matrix

I am working on a library (in my spare time) that I hope to open source soon. One of the elements in the library is a method for calculating the determinant of a given input matrix. For this, I have created a sub-project called "LUDecomposition" because I will use LU Decomposition in order to calculate the Determinant.

Now, my best approach was:

1. Have a class "LUDecomposition" which calculates the LU Decomposition of an input signal

2. Have another class "Determinant" which uses the `LUDecomposition` for the calculate and then returns this.

Currently, it is contained in one file, and, "Determinant" is inheriting from "LUDecompostion" but it does not look right, since, the relationship makes no sense. `LUDecomposition` -> `CAN BE/IS A` `Determinant`

But I cannot see any other option other than having a method inside the "LU Decomposition" and returning it from there. BUT the only problem is that, what if I did not want the users of the library/interface to know how the determinant is calculated?

``````#include <iostream>
#include <vector>

typedef std::vector<double> Vector;

namespace LUDecomposition {

class LUDecompostion {

public:

LUDecompostion();

template<typename Inverse>
LUDecompostion(Inverse begin, Inverse end)
: matrix_input(begin, end)
{
const size_t matrix_size = matrix_input.size();

this->upper.resize(matrix_size, std::vector<double>(matrix_size));
this->lower.resize(matrix_size, std::vector<double>(matrix_size));
Solve();

}

void Solve();

std::vector<Vector> getUpper();
std::vector<Vector> getLower();

protected:

std::vector<Vector> matrix_input;
std::vector<Vector> upper;
std::vector<Vector> lower;

};

/*
Class Determinant

*/

class Determinant : public LUDecomposition {

public:

Determinant();

template<typename Inverse>
Determinant(Inverse begin, Inverse end)
:   matrix_input(begin, end)
{
/*
TO DO
TO DO
TO DO
*/

}

};
}
``````

EDIT:

``````namespace LUP
{

class LUPDecomposition {

public:

LUPDecomposition()
{

}

string getLower()
{
return "This is the lower matrix";
}

string getUpper()
{
return "This is the upper matrix";
}

protected:

std::vector<double> data;

};

LUPDecomposition FactorMatrix()
{
return LUPDecomposition();

}
}
``````

First, there is nothing wrong with your inheritance, although I would avoid naming the class `Determinant`; I would probably use `LUP::Determinant` and if compatibility with other objects is requested implement a `IDeterminant` interface (but in this specific case seems overkill). This is because your determinant is not a generic determinant but a specific implementation on top of a factorization. And I see no problem from having your determinant object reduced to the factorization it was computed from. There might be space and performance concerns though (if I need just the determinant why store everything else?).

With the namespace, I'd rather have a `Decomposition` namespace with `LUP` factorization, `Cholesky` factorization, `QR` factorization and so on. And note that you probably plan to do `LUP` not `LU` factorization so that should also be reflected.

Now, back to the factorizations, you probably do not want to have the `solve` which is the algorithm and the result which represents the data in the same object. For this you can:

• Use generic functions and break inheritance and object dependencies

Can be implemented with functions or functor objects but the API should be something like:

``````LUP::Decomposition decomposition = LUP::FactorMatrix(matrix.begin(), matrix.end());
auto determinant = LUP::ComputeDeterminant(decomposition);
``````

where

`LUP::FactorMatrix` factors the matrix and returns the LU (or LUP) decomposition; this could be just a simple function (with template iterators)

`LUP::Decomposition` (or LU) contains the lower and upper triangular matrix and, if needed, the permutation matrix

`LUP::ComputeDeterminant` can be used on a various of inputs, and in this case an overload that works with a decomposition will return the matrix determinant. You can have it in a more generic namespace with an overload for LUP decomposition.

The advantage is that you can easily decide what data you store and you can also add other operations such as:

``````LUP::Decomposition decomposition = LUP::FactorMatrix(matrix.begin(), matrix.end());
if (LUP::ComputeDeterminant(decomposition) > 5) //whatever
auto matrix = LUP::ComputeMatrixInverse(decomposition);
``````

• Dependency injection is easy as long as you keep the interfaces compatible. You can have two `Solve` methods that behave differently (iterative?) but returns the same type of object so the process is the same.
• Thank you so much for your detailed answer. Just a quick question: Should the `LUP::FactorMatrix` be a static member that returns an object of `LUDecomposition` almost like a global object/singleton? Mar 18, 2015 at 8:30