template<unsigned int N, unsigned int M, typename Scalar>
class mat
: boost::additive< mat<N,M,Scalar>
, boost::multiplicative2< mat<N,M,Scalar>, Scalar
, boost::equality_comparable< mat<N,M,Scalar>
> > >
{
public:
/*...*/
const vec<N,Scalar>& column(unsigned int j) const
{
assert(j < M);
return *(reinterpret_cast<const vec<N,Scalar>* >(&data[N*j]));
}
vec<N,Scalar>& column(unsigned int j)
{
assert(j < M);
return *(reinterpret_cast<vec<N,Scalar>* >(&data[N*j]));
}
/*...*/
private:
Scalar data[N*M]; // In column-major storage
};
template<unsigned int N, typename Scalar, bool cond>
class det
{
public:
/* Gaussian elimination for large matrices */
static Scalar compute(const mat<N,N,Scalar>& a)
{
mat<N,N,Scalar> copy = a; /* Is it ok to allocate this on the stack? */
Scalar factor = 1;
unsigned int i = 0;
unsigned int j = 0;
while(i < N && j < N)
{
cout << copy << endl;
unsigned int maxj = j;
for(unsigned int k = j+1; k < N; ++k)
{
if(std::abs(copy(i,k)) > std::abs(copy(i,maxj)))
maxj = k;
}
if(copy(i,maxj) != 0)
{
/* Swap columns j and maxj */
vec<N,Scalar> temp = copy.column(j);
copy.column(j) = copy.column(maxj);
copy.column(maxj) = temp;
cout << "Swapped " << copy << endl;
if(j != maxj)
factor = -factor * copy(i,j);
else
factor = factor * copy(i,j);
copy.column(j) /= copy(i,j); /* why doesn't this work?? (only copy(i,j) is being updated) */
// copy.column(j) = copy.column(j) / copy(i,j); /* this on the other hand works */
cout << "Divided " << copy << endl;
for(unsigned int k = j+1; k < N; ++k)
copy.column(k) -= copy(i,k) * copy.column(j);
++i;
}
else /* Early out */
{
cout << "Early out" << endl;
return 0;
}
++j;
}
return factor;
}
};