28 #ifndef __TERRALIB_COMMON_INTERNAL_MATRIXUTILS_H
29 #define __TERRALIB_COMMON_INTERNAL_MATRIXUTILS_H
38 #include <boost/numeric/ublas/io.hpp>
39 #include <boost/numeric/ublas/lu.hpp>
40 #include <boost/numeric/ublas/matrix.hpp>
41 #include <boost/numeric/ublas/triangular.hpp>
42 #include <boost/numeric/ublas/vector.hpp>
43 #include <boost/numeric/ublas/vector_proxy.hpp>
60 if( ( inputMatrix.size1() == 0 ) || ( inputMatrix.size2() == 0 ) )
66 boost::numeric::ublas::matrix<T>
A( inputMatrix );
68 const unsigned int size1 =
static_cast<unsigned int>(
A.size1());
70 boost::numeric::ublas::permutation_matrix<std::size_t> pm( size1 );
72 if( boost::numeric::ublas::lu_factorize(
A, pm ) != 0.0 )
80 for (
unsigned int pmi = 0; pmi < size1; ++pmi)
81 if ( pmi != pm( pmi ) )
86 for(
unsigned int i = 0 ; i < size1 ; i++ )
87 determinant *=
A(i,i);
89 determinant = determinant * pmSign;
99 if( ( inputMatrix.size1() == 0 ) || ( inputMatrix.size2() == 0 ) )
106 boost::numeric::ublas::matrix<T>
A( inputMatrix );
108 const unsigned int size1 =
A.size1();
110 boost::numeric::ublas::permutation_matrix<std::size_t> pm( size1 );
112 if( boost::numeric::ublas::lu_factorize(
A, pm ) != 0.0 )
119 for (
unsigned int pmi = 0; pmi < size1; ++pmi)
120 if ( pmi != pm( pmi ) )
125 for(
unsigned int i = 0 ; i < size1 ; i++ )
126 determinant *=
A(i,i);
128 determinant = determinant * pmSign;
144 boost::numeric::ublas::matrix<T>& outputMatrix)
146 assert( inputMatrix.size1() == inputMatrix.size2() );
149 boost::numeric::ublas::matrix<T>
A( inputMatrix );
152 boost::numeric::ublas::permutation_matrix<std::size_t> pm(
A.size1() );
155 if( boost::numeric::ublas::lu_factorize(
A, pm ) != 0 )
162 outputMatrix = boost::numeric::ublas::identity_matrix<T>(
A.size1() );
167 boost::numeric::ublas::lu_substitute(
A, pm, outputMatrix );
192 boost::numeric::ublas::matrix<T>& outputMatrix)
194 if( inputMatrix.size1() > inputMatrix.size2() )
196 boost::numeric::ublas::matrix<T> trans( boost::numeric::ublas::trans(
199 boost::numeric::ublas::matrix<T> aux1( boost::numeric::ublas::prod( trans,
202 boost::numeric::ublas::matrix<T> aux1Inv;
206 outputMatrix = boost::numeric::ublas::prod( aux1Inv, trans );
214 else if( inputMatrix.size1() < inputMatrix.size2() )
216 boost::numeric::ublas::matrix<T> trans( boost::numeric::ublas::trans(
219 boost::numeric::ublas::matrix<T> aux1( boost::numeric::ublas::prod(
220 inputMatrix, trans ) );
222 boost::numeric::ublas::matrix<T> aux1Inv;
226 outputMatrix = boost::numeric::ublas::prod( trans, aux1Inv );
250 bool EigenVectors(
const boost::numeric::ublas::matrix<T>& inputMatrix, boost::numeric::ublas::matrix<T> &eigenVectorsMatrix, boost::numeric::ublas::matrix<T> &eigenValuesMatrix)
257 int dim = (int)inputMatrix.size1();
266 double range, fdim, anorm, anrmx,
268 sinx, cosx, sinx2, cosx2,
274 eigenVectorsMatrix.resize(dim, dim);
275 eigenVectorsMatrix.clear();
276 for (i = 0; i < dim; i++)
277 eigenVectorsMatrix(i, i) = 1.0;
279 int fat = (dim * dim + dim) / 2;
283 cov =
new double[fat];
284 e_vec =
new double[dim * dim];
285 e_val =
new double[fat];
287 if( cov == NULL || e_vec == NULL || e_val == NULL )
291 for (i = 0; i < dim; i++)
292 for (j = 0; j <= i; j++)
293 cov[k++] = inputMatrix(i, j);
295 for (i = 0; i < ((dim * dim + dim) / 2); i++)
299 for (i = 0; i < dim; i++)
302 for (j = 0; j < dim; j++)
314 for (j = 0; j < dim; j++)
316 for (i = 0; i <= j; i++)
319 ia = i + (j * j + j) / 2;
320 anorm = anorm + e_val[ia] * e_val[ia];
326 anorm = 1.414 * sqrt((
double)anorm);
327 anrmx = anorm * range / fdim;
350 mq = (m * m + m) / 2;
351 lq = (l * l + l) / 2;
354 if (fabs((
double)(e_val[lm])) >= thr)
360 x = 0.5 * (e_val[ll] - e_val[mm]);
361 z = e_val[lm] * e_val[lm] + x * x;
362 y = - e_val[lm] / sqrt((
double)(z));
367 z = sqrt( (
double)(1.0 - y * y) );
368 sinx = y / sqrt( (
double)(2.0 * (1.0 + z)) );
371 cosx = sqrt( (
double)(1.0 - sinx2) );
379 for (i = 0; i < dim; i++)
381 iq = (i * i + i) / 2;
396 x = e_val[il] * cosx - e_val[im] * sinx;
397 e_val[im] = e_val[il] * sinx + e_val[im] * cosx;
405 x = e_vec[ilr] * cosx - e_vec[imr] * sinx;
406 e_vec[imr] = e_vec[ilr] * sinx + e_vec[imr] * cosx;
410 x = 2.0 * e_val[lm] * sincs;
411 y = e_val[ll] * cosx2 + e_val[mm] * sinx2 - x;
412 x = e_val[ll] * sinx2 + e_val[mm] * cosx2 + x;
414 e_val[lm] = (e_val[ll] - e_val[mm]) * sincs + e_val[lm] * (cosx2 - sinx2);
444 for (i = 0; i < dim; i++)
447 ll = i + (i * i + i) / 2;
450 for (j = i; j < dim; j++)
453 mm = j + (j * j + j) / 2;
455 if (e_val[ll] < e_val[mm])
458 e_val[ll] = e_val[mm];
461 for (k = 0; k < dim; k++)
466 e_vec[ilr] = e_vec[imr];
474 eigenValuesMatrix.resize(dim, 1);
475 eigenValuesMatrix.clear();
477 for (i = 0; i < dim; i++)
478 for (j = 0; j < dim; j++)
479 eigenVectorsMatrix(j, i) = e_vec[k++];
480 for (i = 0; i < dim; i++)
481 eigenValuesMatrix(i, 0) = e_val[(i * (i + 1)) / 2 + i];
bool GetDeterminantComplex(const boost::numeric::ublas::matrix< T > &inputMatrix, T &determinant)
bool GetInverseMatrix(const boost::numeric::ublas::matrix< T > &inputMatrix, boost::numeric::ublas::matrix< T > &outputMatrix)
Matrix inversion.
bool GetPseudoInverseMatrix(const boost::numeric::ublas::matrix< T > &inputMatrix, boost::numeric::ublas::matrix< T > &outputMatrix)
Pseudo matrix inversion.
bool EigenVectors(const boost::numeric::ublas::matrix< T > &inputMatrix, boost::numeric::ublas::matrix< T > &eigenVectorsMatrix, boost::numeric::ublas::matrix< T > &eigenValuesMatrix)
Computes the eigenvectors of a given matrix.
bool GetDeterminant(const boost::numeric::ublas::matrix< T > &inputMatrix, T &determinant)
Get the Matrix determinant value.
Proxy configuration file for TerraView (see terraview_config.h).