2018-05-17 14:01:02 +00:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <cgv/math/mat.h>
|
|
|
|
|
|
|
|
#include <cgv/math/up_tri_mat.h>
|
|
|
|
|
|
|
|
#include <limits>
|
|
|
|
#include <algorithm>
|
|
|
|
|
|
|
|
namespace cgv {
|
|
|
|
namespace math {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//compute a cholesky factorisation of a square positive definite matrix
|
|
|
|
//returns false if matrix is not positive definite
|
|
|
|
// further if a is symmetric then a == l*l^t
|
|
|
|
template<typename T>
|
|
|
|
bool chol(const mat<T> &a, low_tri_mat<T> &l)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
assert(a.is_square());
|
|
|
|
|
|
|
|
unsigned N = a.nrows();
|
|
|
|
|
|
|
|
l.resize(N);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for(unsigned i = 0; i < N;i++)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
for(unsigned j = i; j < N;j++)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
T sum= a(i, j);
|
|
|
|
|
|
|
|
for(int k = i - 1; k >= 0;k--)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
sum -= l(i, k) * l(j, k);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(i == j)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if(sum <= 0)
|
|
|
|
|
|
|
|
return false;//not positive definite
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
l(j, i) = sqrt(sum);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
l(j, i) = sum / l(i, i);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2018-05-17 13:50:03 +00:00
|
|
|
|
|
|
|
//returns true if A is positive definite otherwise false
|
|
|
|
template <typename T>
|
|
|
|
bool is_pos_def(const cgv::math::mat<T>& A)
|
|
|
|
{
|
|
|
|
low_tri_mat<T> G;
|
|
|
|
return chol(A,G);
|
2018-05-17 14:01:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|