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);
00158 Array< double > v(size);
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);
00166 v(j) += Shark::sqr(x.elem(i * size + j));
00167 }
00168
00169 for (j = 0; j < size; ++j) {
00170 m(j) /= x.dim(0);
00171 v(j) = Shark::max(0., v(j) / x.dim(0) - m(j) * m(j));
00172 }
00173
00174
00175 if (x.ndim() > 1)
00176 v.resize(x[ 0 ], true);
00177
00178 return v;
00179 }
00180
00181
00182
00183
00216 double angle(const Array< double >& x, const Array< double >& y)
00217 {
00218
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
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
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
00299
00300 m(j) /= x.dim(0);
00301 v(j) = v(j) / x.dim(0) - m(j) * m(j);
00302 }
00303
00304
00305 m.resize(x[ 0 ], true);
00306 v.resize(x[ 0 ], true);
00307 }
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
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
00332
00333
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
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
00352
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