Shark Machine Learning Library
  • About Shark
  • Sourceforge
    • Project Summary
    • Downloads
    • Subversion Repository
  • Getting Started
  • Tutorials
  • FAQ
  • Main Modules
    • ReClaM
    • EALib
    • MOO-EALib
    • Fuzzy
  • Tools
    • Mixture
    • Array
    • Rng
    • LinAlg
    • FileUtil
  • Main Page
  • Classes

LinAlg.cpp

Go to the documentation of this file.
00001 //===========================================================================
00037 //======================================================================
00038 
00039 
00040 #include <cstdio>
00041 #include <cstdlib>
00042 #include <cmath>
00043 #include <SharkDefs.h>
00044 #include <Array/ArrayOp.h>
00045 #include <LinAlg/LinAlg.h>
00046 
00047 
00048 //===========================================================================
00103 Array< double > mean(const Array< double >& x)
00104 {
00105     SIZE_CHECK(x.ndim() > 1)
00106 
00107     Array< double > m(x[ 0 ]);
00108     for (unsigned i = 1; i < x.dim(0); ++i)
00109         m += x[ i ];
00110     m /= double(x.dim(0));
00111     return m;
00112 }
00113 
00114 
00115 
00116 //===========================================================================
00151 Array< double > variance(const Array< double >& x)
00152 {
00153     SIZE_CHECK(x.ndim() > 1 && x.dim(0) > 0)
00154 
00155     unsigned i, j;
00156     unsigned size = x.nelem() / x.dim(0);
00157     Array< double > m(size);   // vector of mean values.
00158     Array< double > v(size);   // vector of variance values
00159 
00160     m = 0.;
00161     v = 0.;
00162 
00163     for (i = 0; i < x.dim(0); ++i)
00164         for (j = 0; j < size; ++j) {
00165             m(j) += x.elem(i * size + j);// sum of elements in j's row
00166             v(j) += Shark::sqr(x.elem(i * size + j));//sum of squares od elements in j's row
00167         }
00168 
00169     for (j = 0; j < size; ++j) {
00170         m(j) /= x.dim(0);//normalize mean
00171         v(j)  = Shark::max(0., v(j) / x.dim(0) - m(j) * m(j));
00172     }
00173 
00174     // re-arrange variance array
00175     if (x.ndim() > 1)
00176         v.resize(x[ 0 ], true);//ensure v is a column vector
00177 
00178     return v;
00179 }
00180 
00181 
00182 
00183 //===========================================================================
00216 double angle(const Array< double >& x, const Array< double >& y)
00217 {
00218     //return scalar_product( x, y ) / sqrt( sumOfSqr( x ) * sumOfSqr( y ) );
00219 
00220     SIZE_CHECK(x.ndim() == 1 && x.samedim(y))
00221 
00222     double sumxx = 0;
00223     double sumyy = 0;
00224     double sumxy = 0;
00225 
00226     for (unsigned i = 0; i < x.nelem(); ++i) {
00227         sumxx += x(i) * x(i);
00228         sumyy += y(i) * y(i);
00229         sumxy += x(i) * y(i);
00230     }
00231 
00232     return (sumxx == 0 || sumyy == 0) ? 0. : sumxy / sqrt(sumxx * sumyy);
00233 }
00234 
00235 
00236 //===========================================================================
00270 void meanvar
00271 (
00272     const Array< double >& x,
00273     Array< double >&       m,
00274     Array< double >&       v
00275 )
00276 {
00277     SIZE_CHECK(x.ndim() > 1)
00278 
00279     unsigned i, j;
00280 
00281     // number of elements for each "row":
00282     unsigned size = x.nelem() / x.dim(0);
00283 
00284     m.resize(size, false);
00285     v.resize(size, false);
00286     m = 0.;
00287     v = 0.;
00288 
00289     for (i = 0; i < x.dim(0); ++i) {
00290         for (j = 0; j < size; ++j) {
00291             // Sum of elements of each "row":
00292             m(j) += x.elem(i * size + j);
00293             v(j) += Shark::sqr(x.elem(i * size + j));
00294         }
00295     }
00296 
00297     for (j = 0; j < size; ++j) {
00298         // Calculate mean value by dividing
00299         // by no. of "rows":
00300         m(j) /= x.dim(0);
00301         v(j)  = v(j) / x.dim(0) - m(j) * m(j);
00302     }
00303 
00304     // re-arrange arrays
00305     m.resize(x[ 0 ], true);
00306     v.resize(x[ 0 ], true);
00307 }
00308 
00309 /*
00310     /brief Calculates the mean and variance values of 1d-arrays p(x)
00311 
00312     calculates the first two moments of a discrete value array and
00313     his corresponding x-values
00314     /param pxA      1d array with functionvalues
00315     /param xA       1d array with corresponding x values
00316     /param mA       retunsvalue meanval
00317     /param vA       returnvalue variance
00318     /param startA   start of a calculation window
00319     /param endA     end of a calculation window
00320 */
00321 void meanvar
00322 (
00323     const Array< double >& pxA,
00324     const Array< double >& xA,
00325     double &mA,
00326     double &vA,
00327     const int startA,
00328     const int endA
00329 )
00330 {
00331 //  SIZE_CHECK( xA.ndim( ) != 1 )
00332 //  SIZE_CHECK( pxA.ndim( ) != xA.ndim( ) )
00333 //  SIZE_CHECK( pxA.nelem( ) != xA.nelem( ) )
00334 
00335     int size = pxA.nelem();
00336     int startL  = (startA < 0) ? 0 : startA;
00337     int endL    = (endA == -1) ? size : endA;
00338     if (startL == endL) {
00339         mA = startA;
00340         vA = 0;
00341     }
00342     double ew = 0;
00343     double sum = 0;
00344     int i;
00345     // calculate first moment
00346     for (i = startL; i < endL ;++i) {
00347         ew  += pxA.elem(i) * xA.elem(i);
00348         sum += pxA.elem(i);
00349     }
00350     mA = (ew == 0) ? 0 : ew / sum;
00351     // calculate variance
00352     // variance is the second central moment
00353     const int ii = 2;
00354     double vc = 0;
00355     for (i = startL; i < endL ;++i) {
00356         vc += pow((xA.elem(i) - mA), (double)ii) * pxA.elem(i);
00357     }
00358     vA = sqrt((vc == 0) ? 0 : vc / sum);
00359 
00360 }
00361 
00362 
00363 
00364 
00365 //===========================================================================
00408 double corrcoef(const Array< double >& x, const Array< double >& y)
00409 {
00410     SIZE_CHECK(x.ndim() == 1 && x.samedim(y))
00411 
00412     double sumxx = 0;
00413     double sumyy = 0;
00414     double sumxy = 0;
00415     double sumx  = 0;
00416     double sumy  = 0;
00417 
00418     if (x.nelem() > 0) {
00419         for (unsigned i = 0; i < x.nelem(); ++i) {
00420             sumxx += x(i) * x(i);
00421             sumyy += y(i) * y(i);
00422             sumxy += x(i) * y(i);
00423             sumx  += x(i);
00424             sumy  += y(i);
00425         }
00426 
00427         sumxx /= x.nelem();
00428         sumyy /= x.nelem();
00429         sumxy /= x.nelem();
00430         sumx  /= x.nelem();
00431         sumy  /= x.nelem();
00432 
00433         sumxx -= sumx * sumx;
00434         sumyy -= sumy * sumy;
00435         sumxy -= sumx * sumy;
00436     }
00437 
00438     return (sumxx == 0 || sumyy == 0) ? 0. : sumxy / sqrt(sumxx * sumyy);
00439 }
00440 
00441 
00442 
00443 //===========================================================================
00483 Array< double > corrcoef(const Array< double >& x)
00484 {
00485     SIZE_CHECK(x.ndim() > 1)
00486 
00487     unsigned i, j;
00488     Array< double > C(covariance(x));
00489 
00490     for (i = 0; i < C.dim(0); ++i)
00491         for (j = 0; j < i; ++j)
00492             if (C(i, i) == 0 || C(j, j) == 0)
00493                 C(i, j) = C(j, i) = 0;
00494             else
00495                 C(i, j) = C(j , i) = C(i, j) / sqrt(C(i, i) * C(j, j));
00496 
00497     for (i = 0; i < C.dim(0); ++i)
00498         C(i, i) = 1;
00499 
00500     return C;
00501 }
00502 
00503 
00504 //===========================================================================
00542 double covariance(const Array< double >& x, const Array< double >& y)
00543 {
00544     SIZE_CHECK(x.ndim() == 1 && x.samedim(y))
00545 
00546     double sumxy = 0;
00547     double sumx  = 0;
00548     double sumy  = 0;
00549 
00550     if (x.nelem() > 0) {
00551         for (unsigned i = 0; i < x.nelem(); ++i) {
00552             sumxy += x(i) * y(i);
00553             sumx  += x(i);
00554             sumy  += y(i);
00555         }
00556 
00557         sumxy /= x.nelem();
00558         sumx  /= x.nelem();
00559         sumy  /= x.nelem();
00560     }
00561 
00562     return sumxy - sumx * sumy;
00563 }
00564 
00565 //===========================================================================
00602 Array< double > covariance(const Array< double >& x)
00603 {
00604     SIZE_CHECK(x.ndim() == 2)
00605 
00606     unsigned num = x.dim(0);
00607     unsigned dim = x.dim(1);
00608 
00609     Array< double > mean(dim);
00610     Array< double > covar(dim, dim);
00611 
00612     mean  = 0.;
00613     covar = 0.;
00614 
00615     for (unsigned i = num; i--;) {
00616         mean  += x[ i ];
00617         covar += outerProduct(x[ i ], x[ i ]);
00618     }
00619 
00620     mean  /= double(num);
00621     covar /= double(num);
00622     covar -= outerProduct(mean, mean);
00623 
00624     return covar;
00625 }
00626 
00627 //===========================================================================
00641 void matMat(Array2D<double> &A, const Array2D<double> &B, const Array2D<double> &C) {
00642   unsigned i, j, k, n = B.dim(0), m = C.dim(1), l = C.dim(0);
00643   SIZE_CHECK( B.dim(1) == C.dim(0) );  
00644   A.resize(n, m, false);
00645   for(i=0; i<n; i++) {
00646     for(j=0; j<m; j++) {
00647       A(i,j)=B(i, 0) * C(0, j);
00648       for(k=1; k<l; k++) {
00649                 A(i,j)+=B(i, k) * C(k, j);
00650       }
00651     }
00652   }
00653 }
00654 
00655 //===========================================================================
00665 void matColVec(Array<double> &A, const Array2D<double> &B, const Array<double> &C)
00666 {
00667     SIZE_CHECK(B.ndim() == 2);
00668     SIZE_CHECK(C.ndim() == 1);
00669 
00670     unsigned int v, vc = B.dim(0);
00671     unsigned int h, hc = B.dim(1);
00672 
00673     SIZE_CHECK(C.dim(0) == hc);
00674     A.resize(vc, false);
00675 
00676     for (v=0; v<vc; v++)
00677     {
00678         double value = 0.0;
00679         for (h=0; h<hc; h++) value += B(v, h) * C(h);
00680         A(v) = value;
00681     }
00682 }
00683 
00684 //===========================================================================
00692 void matColVec(ArrayReference<double> A, const Array2D<double>& B, const ArrayReference<double> C)
00693 {
00694     SIZE_CHECK(B.ndim() == 2);
00695     SIZE_CHECK(C.ndim() == 1);
00696 
00697     unsigned int v, vc = B.dim(0);
00698     unsigned int h, hc = B.dim(1);
00699 
00700     SIZE_CHECK(C.dim(0) == hc);
00701     A.resize(vc, false);
00702 
00703     for (v=0; v<vc; v++)
00704     {
00705         double value = 0.0;
00706         for (h=0; h<hc; h++) value += B(v, h) * C(h);
00707         A(v) = value;
00708     }
00709 }
00710 
00711 //===========================================================================
00723 void matColVec(Array<double> &A, const Array2D<double> &B, const Array<double> &C, unsigned int index)
00724 {
00725     unsigned i, j, n, m;
00726     SIZE_CHECK( B.ndim() == 2 );
00727     SIZE_CHECK( C.ndim() == 2 );
00728     RANGE_CHECK(index < C.dim(1));
00729     SIZE_CHECK( B.dim(1) == C.dim(0) );
00730     n = B.dim(0);
00731     m = B.dim(1);
00732     A.resize(n, false);
00733     for(i=0; i<n; i++) {
00734         A(i)=B(i, 0) * C(0, index);
00735         for(j=1; j<m; j++) {
00736             A(i)+=B(i, j) * C(j, index);
00737         }
00738     }
00739 }
00740 
00741 //===========================================================================
00755 double vecMatVec(const Array<double> &A, const Array2D<double> &B, const Array<double> &C) {
00756   unsigned i, j, n, m;
00757   double sum =  0, help;
00758   SIZE_CHECK( A.ndim() == 1 );  
00759   SIZE_CHECK( B.ndim() == 2 );  
00760   SIZE_CHECK( C.ndim() == 1 );  
00761   SIZE_CHECK( B.dim(1) == C.dim(0) );  
00762   SIZE_CHECK( B.dim(0) == A.dim(0) );  
00763   n = B.dim(0);
00764   m = B.dim(1);  
00765 
00766   for(i=0; i<n; i++) {
00767     help=B(i, 0) * C(0);
00768     for(j=1; j<m; j++) {
00769     help+=B(i, j) * C(j);
00770     }
00771     sum+=A(i)*help;
00772   }
00773   return sum;
00774 }
00775 
00776 //===========================================================================
00789 double vecMatVec(const Array<double> &A, unsigned int i, const Array2D<double> &B, const Array<double> &C, unsigned int j) {
00790     unsigned a, c, n, m;
00791     double sum =  0, help;
00792     SIZE_CHECK( A.ndim() == 2 );
00793     SIZE_CHECK( B.ndim() == 2 );
00794     SIZE_CHECK( C.ndim() == 2 );
00795     RANGE_CHECK(i < A.dim(1));
00796     RANGE_CHECK(j < C.dim(1));
00797     SIZE_CHECK( B.dim(1) == C.dim(0) );
00798     SIZE_CHECK( B.dim(0) == A.dim(0) );
00799     n = B.dim(0);
00800     m = B.dim(1);
00801 
00802     for(a=0; a<n; a++) {
00803         help=B(a, 0) * C(0, j);
00804         for(c=1; c<m; c++) {
00805             help+=B(a, c) * C(c, j);
00806         }
00807         sum+=A(a, i)*help;
00808     }
00809     return sum;
00810 }
00811 
00812 //===========================================================================
00824 void invertSymm( Array2D<double> &I, const Array2D< double >& A) {
00825   SIZE_CHECK( A.ndim() == 2 );  
00826   SIZE_CHECK( A.dim(1) == A.dim(0) );  
00827 
00828   Array<double> lambda;
00829   Array2D<double> eigenVectors;
00830   unsigned n = A.dim(0);
00831   
00832   I.resize(A, false);
00833   lambda.resize(n, false);
00834   eigenVectors.resize(A, false);
00835   lambda = 0;
00836   eigenVectors = 0.;
00837   
00838   eigensymm(A, eigenVectors, lambda);
00839   I = 0.;
00840   
00841   for(unsigned i = 0; i < n; ++i) I(i,i) = 1./lambda(i);
00842 
00843   I = innerProduct(I , transpose(eigenVectors));
00844   I = innerProduct(eigenVectors , I);
00845 }
00846 
00847 
00848 //===========================================================================
00868 void CholeskyDecomposition(const Array2D< double >& M,
00869                                                      Array2D< double >& C) 
00870 {
00871     int i, j, k, m;
00872     double s;
00873     SIZE_CHECK(M.dim(0) == M.dim(1));
00874     
00875     m = M.dim(0);
00876     C.resize(m, m, false);
00877     for(j = 0; j < m; j++) {
00878         for(i = j; i < m; i++) {
00879             s = M(i, j);
00880             for(k = 0; k < j; k++) {
00881                 s -= C(i, k) * C(j, k);
00882             }
00883             if (i == j) {
00884                 C(i, j) = sqrt(s);
00885             }
00886             else {
00887                 C(i, j) = s/C(j , j);
00888                 C(j, i) = 0;
00889             }
00890         }
00891     }
00892 }
00893