diff --git a/miscmaths.cc b/miscmaths.cc index e48ae7e9c3f155bbf2e57ab955b39b1d51c9e340..2913b5f04e718a2f1b1f408e7a032f3abea2305a 100644 --- a/miscmaths.cc +++ b/miscmaths.cc @@ -1732,6 +1732,29 @@ ReturnMatrix sum(const Matrix& mat, const int dim) return res; } +ReturnMatrix mean(const Matrix& mat, const RowVector& weights, const int dim) //weights are considered to be in the "direction" of dim and normalised to sum 1 +{ + Matrix res; + if (dim == 1){ + res = zeros(1,mat.Ncols()); + for (int mc=1; mc<=mat.Ncols(); mc++) { + for (int mr=1; mr<=mat.Nrows(); mr++) { + res(1,mc) += weights(mr)*mat(mr,mc); + } + } + } + else{ + res = zeros(mat.Nrows(),1); + for (int mr=1; mr<=mat.Nrows(); mr++) { + for (int mc=1; mc<=mat.Ncols(); mc++) { + res(mr,1) += weights(mc)*mat(mr,mc); + } + } + } + res.Release(); + return res; +} + ReturnMatrix mean(const Matrix& mat, const int dim) { Matrix res; @@ -1758,6 +1781,7 @@ ReturnMatrix mean(const Matrix& mat, const int dim) return res; } + ReturnMatrix var(const Matrix& mat, const int dim) { Matrix res, matmean; @@ -2038,7 +2062,7 @@ ReturnMatrix remmean(const Matrix& mat, const int dim) return res; } -/* ReturnMatrix cov(const Matrix& mat, const int norm) +ReturnMatrix oldcov(const Matrix& mat, const int norm) { SymmetricMatrix res; Matrix tmp; @@ -2052,27 +2076,95 @@ ReturnMatrix remmean(const Matrix& mat, const int dim) res.Release(); return res; } -*/ -ReturnMatrix cov(const Matrix& mat, const int norm) -{ +ReturnMatrix cov(const Matrix& data, const bool sampleCovariance, int econ) +{ + //This assumes vectors are stored using column order in data SymmetricMatrix res; - res << ones(mat.Ncols(),mat.Ncols()); + res << zeros(data.Ncols(),data.Ncols()); + Matrix meanM(mean(data)); + int N=data.Nrows(); + if (sampleCovariance && N>1) + N--; + if ( econ < 1 ) + econ=data.Nrows(); + for(int startRow=1; startRow <= data.Nrows(); startRow+=econ) { + Matrix suba=data.SubMatrix(startRow,Min(startRow+econ-1,data.Nrows()),1,data.Ncols()); + for (int row=1; row <= suba.Nrows(); row++) + suba.Row(row)-=meanM; + res << res + suba.t()*suba/N; + } + res.Release(); + return res; +} - Matrix meanM; - int N; - meanM = mean(mat); - if (norm == 1) {N = mat.Nrows();} - else {N = mat.Nrows()-1;} - for (int ctr=1; ctr <= mat.Nrows(); ctr++) - res << res + (mat.Row(ctr) - meanM ).t() * (mat.Row(ctr) - meanM); - res = res/N; +ReturnMatrix cov_r(const Matrix& data, const bool sampleCovariance, int econ) +{ + //This assumes vectors are stored using row order in data + SymmetricMatrix res; + res << zeros(data.Nrows(),data.Nrows()); + Matrix meanM(mean(data,2)); + int N=data.Ncols(); + if (sampleCovariance && N>1) + N--; + if ( econ < 1 ) + econ=data.Ncols(); + for(int startCol=1; startCol <= data.Ncols(); startCol+=econ) { + Matrix suba=data.SubMatrix(1,data.Nrows(),startCol,Min(startCol+econ-1,data.Ncols())); + for (int col=1; col <= suba.Ncols(); col++) + suba.Column(col)-=meanM; + res << res + suba*suba.t()/N; + } res.Release(); return res; } -ReturnMatrix corrcoef(const Matrix& mat, const int norm) +ReturnMatrix cov_r(const Matrix& data, const Matrix& weights2, int econ) +{ + //This assumes vectors are stored using row order in data, weights are a single "row". No bool flag as biased vs unbiased isn't relevant here + RowVector weights=((weights2/weights2.Sum()).AsRow()); + SymmetricMatrix res; + res << zeros(data.Nrows(),data.Nrows()); + Matrix meanM(mean(data,weights,2)); + + int N=1-weights.SumSquare();//As weights.Sum() is equal to 1 + + if ( econ < 1 ) + econ=data.Ncols(); + for(int startCol=1; startCol <= data.Ncols(); startCol+=econ) { + Matrix suba=data.SubMatrix(1,data.Nrows(),startCol,Min(startCol+econ-1,data.Ncols())); + for (int col=1; col <= suba.Ncols(); col++) { + suba.Column(col)-=meanM; + suba.Column(col)*=sqrt(weights(startCol+col-1)); + } + res << res + suba*suba.t()/N; + } + write_ascii_matrix("data.mat",data); + write_ascii_matrix("weights.mat",weights); + write_ascii_matrix("nonorm",cov_r(data,false)); + write_ascii_matrix("old.mat",res); + //res.Release(); + Matrix Data2=data; + for(int ctr=1; ctr <= data.Ncols(); ctr++) + Data2.Column(ctr)*=weights(ctr); + + + + Matrix res2 = oldcov(Data2.t(),1); + res << res2; + write_ascii_matrix("new.mat",res); + exit(1); + + + + return res; +} + + + + +ReturnMatrix corrcoef(const Matrix& mat, const bool norm) { SymmetricMatrix res; res = cov(mat,norm); diff --git a/miscmaths.h b/miscmaths.h index 02fa63fa363a1159996dc1907ecba64e034efdc3..23ebfc3f1d4618d7fd7486a36db734785950e266 100644 --- a/miscmaths.h +++ b/miscmaths.h @@ -232,6 +232,7 @@ namespace MISCMATHS { void pow_econ(Matrix& mat, const double exp); ReturnMatrix sum(const Matrix& mat, const int dim = 1); ReturnMatrix mean(const Matrix& mat, const int dim = 1); + ReturnMatrix mean(const Matrix& mat, const RowVector& weights, const int dim=1); ReturnMatrix var(const Matrix& mat, const int dim = 1); ReturnMatrix max(const Matrix& mat); ReturnMatrix max(const Matrix& mat,ColumnVector& index); @@ -256,8 +257,14 @@ namespace MISCMATHS { ReturnMatrix remmean(const Matrix& mat, const int dim = 1); ReturnMatrix stdev(const Matrix& mat, const int dim = 1); - ReturnMatrix cov(const Matrix& mat, const int norm = 0); - ReturnMatrix corrcoef(const Matrix& mat, const int norm = 0); + ReturnMatrix cov(const Matrix& mat, const bool sampleCovariance = false, const int econ=20000); + ReturnMatrix cov_r(const Matrix& mat, const bool sampleCovariance = false, const int econ=20000); + ReturnMatrix cov_r(const Matrix& data, const Matrix& weights, int econ=20000); + + + + ReturnMatrix oldcov(const Matrix& mat, const bool norm = false); + ReturnMatrix corrcoef(const Matrix& mat, const bool norm = false); void symm_orth(Matrix &Mat); void powerspectrum(const Matrix &Mat1, Matrix &Result, bool useLog); void element_mod_n(Matrix& Mat,double n); //represent each element in modulo n (useful for wrapping phases (n=2*M_PI))