# Determinant

This topic is 3409 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hi, I am trying to write a member function for a matrix class to compute the determinant, the code is as follows:
t matrix::determinant()
{
if(rows != cols);
//throw DimensionMismatchException

if(rows == 1)
return mat[0][0];
else
{
t det = 0;
for(int i = 0; i < cols; i++)
{
det += (t)pow(-1,i) * mat[0] * this.deleteRowCol(0,i).determinant();
}
return det;
}
}

the expansion by minors for an nxm matrix. The matrix class is a template defined as follows:
template<int rows, int cols, typename t>
class matrix

When I try to compile this, I get it still trying to compile a matrix with size 0x0 which creates a compile error. Why is this happening even with the check if(rows == 1)? Thanks, Max

##### Share on other sites
Both branches get generated. If statements are code, not template metacode.

First, write a square matrix class (well you can avoid this, but it makes things easier). (A square matrix being a class templated on one integer size parameter, plus t. It inherits a generic n x n matrix, and forwards constructors onto it. Note that as POD, you can do layout based binary casting safely!). Write a function that takes a generic matrix, and either returns a square matrix or throws.

Write a row removal function that takes a square matrix, and returns a square matrix one smaller.

Then write a template determinate function that takes a square matrix.

Specialize the 1x1 matrix version to simply return the value in the matrix.

Then your non-specialized determinate function reads like your else clause. There is no need to check for rows==1, as that is handled by the specialization.

You can do this without creating the square matrix class, but it can make things easier. :)

...

Actually...
template<int size, typename T>struct determinateHelper {  T operator()( Matrix<size, size, T> const& src ) const {    // the non-size=1 case  }};template<typename T>struct determinateHelper<1, T> {  T operator()( Matrix<1, 1, T> const& src ) const {    // the size=1 case  }};template<int size, typename T>T determinate( Matrix<size,size,T> const& src ) {  return determinateHelper<size, T>()(src);}

Now you do compile-time checking on the Matrix passed in. If you pass in a Matrix that isn't square, you fail to compile. :) (This can cause issues down the road).

You can allow for non-square matrix options via:
template< typename Matrix, typename T>T determinate( Matrix const& src ) {  throw you_suck();  return T();}

which is an override that will match less than the square matrix, I think (or maybe it won't work, hmm).

##### Share on other sites
Besides the problem with templates, I should mention that that method to compute the determinant is actually pretty slow: The running time is O(n!).

A much better procedure is to use Gaussian elimination and multiply the elements in the diagonal: The running time is O(n^3).

##### Share on other sites
Quote:
 Original post by alvaroBesides the problem with templates, I should mention that that method to compute the determinant is actually pretty slow: The running time is O(n!).A much better procedure is to use Gaussian elimination and multiply the elements in the diagonal: The running time is O(n^3).

I always figured that algorithm would run slower but i never bothered to analyze it, i'll switch to that way, converting it to a triangular matrix and using the diagonals correct?

1. 1
Rutin
19
2. 2
3. 3
JoeJ
15
4. 4
5. 5

• 21
• 19
• 11
• 13
• 17
• ### Forum Statistics

• Total Topics
631697
• Total Posts
3001764
×