GenericMatrix.cpp 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. /**
  2. * @file GenericMatrix.cpp
  3. * @brief matrix interface for indirect matrix multiplications
  4. * @author Erik Rodner
  5. * @date 05/14/2009
  6. */
  7. #include "GenericMatrix.h"
  8. using namespace NICE;
  9. using namespace std;
  10. GMSparse::GMSparse ( const NICE::Matrix & A, double epsilon )
  11. {
  12. // derive a sparse matrix from a dense one
  13. m_rows = A.rows ();
  14. m_cols = A.cols ();
  15. for ( u_int i = 0; i < m_rows; i++ )
  16. for ( u_int j = 0; j < m_cols; j++ )
  17. if ( fabs ( A ( i, j ) ) > epsilon )
  18. this->A.insert ( this->A.begin (), NICE::triplet < int, int,
  19. double > ( i, j, A ( i, j ) ) );
  20. }
  21. void
  22. GMSparse::multiply ( NICE::Vector & y, const NICE::Vector & x ) const
  23. {
  24. if ( x.size() != m_cols )
  25. fthrow ( Exception, "GMSparse::multiply: vector and matrix size do not match!" );
  26. y.resize ( m_rows );
  27. y.set ( 0.0 );
  28. // perform sparse multiplication
  29. for ( vector < NICE::triplet < int, int, double > >::const_iterator k =
  30. this->A.begin (); k != this->A.end (); k++ )
  31. {
  32. int i = k->first;
  33. int j = k->second;
  34. double value = k->third; // = a_ij
  35. y[i] += value * x[j];
  36. }
  37. }
  38. GMCovariance::GMCovariance ( const NICE::Matrix *data )
  39. {
  40. this->data = data;
  41. }
  42. void
  43. GMCovariance::multiply ( NICE::Vector & y, const NICE::Vector & x ) const
  44. {
  45. if ( x.size() != data->rows() )
  46. fthrow ( Exception, "GMCovariance::multiply: vector and matrix size do not match!" );
  47. /*******************************************************************
  48. * d_k = data(:,k) vector k in the data set
  49. * f_k = d_k^T x
  50. * fSum = \sum_k f_k
  51. * In the following we use the following relationship
  52. * S = \sum_i d_i ( d_i - \mu )^T = \sum_i (d_i - \mu) (d_i - \mu)^T
  53. * Sx = \sum_i d_i ( f_i - fSum/N )
  54. * which seems to be very efficient
  55. * *****************************************************************/
  56. NICE::Vector f ( data->cols () );
  57. f.set ( 0.0 );
  58. double fSum = 0.0;
  59. for ( uint k = 0; k < data->cols (); k++ )
  60. {
  61. for ( uint d = 0; d < data->rows (); d++ )
  62. f[k] += ( *data ) ( d, k ) * x[d];
  63. fSum += f[k];
  64. }
  65. y.resize ( x.size () );
  66. y.set ( 0.0 );
  67. int N = data->cols ();
  68. for ( uint k = 0; k < data->cols (); k++ )
  69. for ( int l = 0; l < ( int ) y.size (); l++ )
  70. y[l] += ( f[k] - fSum / N ) * ( ( *data ) ( l, k ) );
  71. for ( int i = 0; i < ( int ) y.size (); i++ )
  72. y[i] /= N;
  73. }