Skip to content

Commit 080aa44

Browse files
author
Martin D. Weinberg
committed
A preliminary implementation of partition covariance
1 parent 9e8faf2 commit 080aa44

4 files changed

Lines changed: 185 additions & 3 deletions

File tree

expui/BiorthBasis.H

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,15 @@ namespace BasisClasses
9696
RowMatrixXd varray;
9797
//@}
9898

99+
//! Coefficient variance computation enabled
100+
bool pcavar = false;
101+
102+
//@{
103+
//! Sample counts and masses for covariance computation
104+
Eigen::VectorXi sampleCounts;
105+
Eigen::VectorXd sampleMasses;
106+
//@}
107+
99108
public:
100109

101110
//! Constructor from YAML node
@@ -213,6 +222,23 @@ namespace BasisClasses
213222

214223
return varray;
215224
}
225+
226+
//! Return a vector of tuples of basis functions and the
227+
//! covariance matrix for subsamples of particles
228+
using CoefCovarType = std::tuple<Eigen::VectorXd, Eigen::MatrixXd>;
229+
virtual std::vector<std::vector<CoefCovarType>>
230+
getCoefCovariance()
231+
{
232+
throw std::runtime_error("BiorthBasis::getCoefCovariance: Not implemented for this basis");
233+
}
234+
235+
//! Get sample counts for the covariance computation
236+
virtual std::tuple<Eigen::VectorXi, Eigen::VectorXd>
237+
getCovarSamples()
238+
{
239+
return std::make_tuple(sampleCounts, sampleMasses);
240+
}
241+
216242
};
217243

218244
/**
@@ -308,6 +334,16 @@ namespace BasisClasses
308334
virtual void computeAccel(double x, double y, double z,
309335
Eigen::Ref<Eigen::Vector3d> vstore);
310336

337+
//@{
338+
//! Covariance structures. First index is T, second is harmonic
339+
//! (l,m).
340+
std::vector<std::vector<Eigen::VectorXd>> meanV;
341+
std::vector<std::vector<Eigen::MatrixXd>> covrV;
342+
void init_covariance();
343+
void zero_covariance();
344+
int sampT = 100;
345+
//@}
346+
311347
public:
312348

313349
//! Constructor from YAML node
@@ -363,6 +399,10 @@ namespace BasisClasses
363399
return ret;
364400
}
365401

402+
//! Return a vector of tuples of basis functions and the
403+
//! covariance matrix for subsamples of particles
404+
std::vector<std::vector<CoefCovarType>>
405+
getCoefCovariance();
366406
};
367407

368408
/**
@@ -920,6 +960,19 @@ namespace BasisClasses
920960
return ret;
921961
}
922962

963+
//! Return a vector of tuples of basis functions and the
964+
//! covariance matrix for subsamples of particles
965+
std::vector<std::vector<CoefCovarType>>
966+
getCoefCovariance()
967+
{
968+
return sl->getCoefCovariance();
969+
}
970+
971+
std::tuple<Eigen::VectorXi, Eigen::VectorXd>
972+
getCovarSamples()
973+
{
974+
return sl->getCovarSamples();
975+
}
923976
};
924977

925978
/**

expui/BiorthBasis.cc

Lines changed: 85 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ namespace BasisClasses
2626
"pcavtk",
2727
"pcaeof",
2828
"subsamp",
29+
"sampT",
2930
"snr",
3031
"samplesz",
3132
"vtkfreq",
@@ -262,6 +263,8 @@ namespace BasisClasses
262263
if (conf["EVEN_L"]) EVEN_L = conf["EVEN_L"].as<bool>();
263264
if (conf["EVEN_M"]) EVEN_M = conf["EVEN_M"].as<bool>();
264265
if (conf["M0_ONLY"]) M0_only = conf["M0_ONLY"].as<bool>();
266+
if (conf["pcavar"]) pcavar = conf["pcavar"].as<bool>();
267+
if (conf["sampT"]) sampT = conf["sampT"].as<int>();
265268
}
266269
catch (YAML::Exception & error) {
267270
if (myid==0) std::cout << "Error parsing parameter stanza for <"
@@ -312,11 +315,39 @@ namespace BasisClasses
312315

313316
used = 0;
314317

318+
// Initialize covariance
319+
//
320+
if (pcavar) init_covariance();
321+
315322
// Set spherical coordindates
316323
//
317324
coordinates = Coord::Spherical;
318325
}
319326

327+
void Spherical::init_covariance()
328+
{
329+
if (pcavar) {
330+
meanV.resize(sampT);
331+
for (auto& v : meanV) v.resize(nmax);
332+
covrV.resize(sampT);
333+
for (auto& v : covrV) v.resize(nmax);
334+
sampleCounts.resize(sampT);
335+
sampleMasses.resize(sampT);
336+
zero_covariance();
337+
}
338+
}
339+
340+
void Spherical::zero_covariance()
341+
{
342+
for (int T=0; T<sampT; T++) {
343+
for (auto& v : meanV[T]) v.setZero();
344+
for (auto& v : covrV[T]) v.setZero();
345+
}
346+
347+
sampleCounts.setZero();
348+
sampleMasses.setZero();
349+
}
350+
320351
void SphericalSL::initialize()
321352
{
322353

@@ -409,6 +440,7 @@ namespace BasisClasses
409440
if (expcoef.rows()>0 && expcoef.cols()>0) expcoef.setZero();
410441
totalMass = 0.0;
411442
used = 0;
443+
if (pcavar) zero_covariance();
412444
}
413445

414446

@@ -535,6 +567,14 @@ namespace BasisClasses
535567

536568
legendre_R(lmax, costh, legs[tid]);
537569

570+
// Sample index for pcavar
571+
int T = 0;
572+
if (pcavar) {
573+
T = used % sampT;
574+
sampleCounts(T) += 1;
575+
sampleMasses(T) += mass;
576+
}
577+
538578
// L loop
539579
for (int l=0, loffset=0; l<=lmax; loffset+=(2*l+1), l++) {
540580

@@ -549,6 +589,16 @@ namespace BasisClasses
549589
for (int n=0; n<nmax; n++) {
550590
fac4 = potd[tid](l, n)*fac;
551591
expcoef(loffset+moffset, n) += fac4 * norm * mass;
592+
593+
if (pcavar) {
594+
for (int n=0; n<nmax; n++) {
595+
meanV[T][l](n) += fac4 * norm * mass;
596+
for (int o=0; o<nmax; o++)
597+
covrV[T][l](n, o) += fac4 * norm *
598+
fac * potd[tid](l, o) * norm * mass;
599+
}
600+
}
601+
552602
}
553603

554604
moffset++;
@@ -561,6 +611,15 @@ namespace BasisClasses
561611
fac4 = potd[tid](l, n);
562612
expcoef(loffset+moffset , n) += fac1 * fac4 * norm * mass;
563613
expcoef(loffset+moffset+1, n) += fac2 * fac4 * norm * mass;
614+
615+
if (pcavar) {
616+
for (int n=0; n<nmax; n++) {
617+
meanV[T][l](n) += fac * fac4 * norm * mass;
618+
for (int o=0; o<nmax; o++)
619+
covrV[T][l](n, o) += fac * fac4 * norm *
620+
fac * potd[tid](l, o) * norm * mass;
621+
}
622+
}
564623
}
565624

566625
moffset+=2;
@@ -902,6 +961,28 @@ namespace BasisClasses
902961
return ret;
903962
}
904963

964+
965+
/** Return a vector of tuples of basis functions and the covariance
966+
matrix for subsamples of particles */
967+
std::vector<std::vector<BiorthBasis::CoefCovarType>>
968+
Spherical::getCoefCovariance()
969+
{
970+
std::vector<std::vector<BiorthBasis::CoefCovarType>> ret;
971+
if (pcavar) {
972+
ret.resize(sampT);
973+
for (int T=0; T<sampT; T++) {
974+
int ltot = (lmax+1)*(lmax+2)/2;
975+
ret[T].resize(ltot);
976+
for (int l=0; l<ltot; l++) {
977+
std::get<0>(ret[T][l]) = meanV[T][l];
978+
std::get<1>(ret[T][l]) = covrV[T][l];
979+
}
980+
}
981+
}
982+
983+
return ret;
984+
}
985+
905986

906987
#define MINEPS 1.0e-10
907988

@@ -1350,9 +1431,9 @@ namespace BasisClasses
13501431

13511432
if (conf["aratio" ]) aratio = conf["aratio" ].as<double>();
13521433
if (conf["hratio" ]) hratio = conf["hratio" ].as<double>();
1353-
if (conf["dweight" ]) dweight = conf["dweight" ].as<double>();
1354-
if (conf["Mfac" ]) Mfac = conf["Mfac" ].as<double>();
1355-
if (conf["HERNA" ]) HERNA = conf["HERNA" ].as<double>();
1434+
if (conf["dweight" ]) dweight = conf["dweight" ].as<double>();
1435+
if (conf["Mfac" ]) Mfac = conf["Mfac" ].as<double>();
1436+
if (conf["HERNA" ]) HERNA = conf["HERNA" ].as<double>();
13561437
if (conf["rwidth" ]) rwidth = conf["rwidth" ].as<double>();
13571438
if (conf["ashift" ]) ashift = conf["ashift" ].as<double>();
13581439
if (conf["rfactor" ]) rfactor = conf["rfactor" ].as<double>();
@@ -1362,6 +1443,7 @@ namespace BasisClasses
13621443
if (conf["dtype" ]) dtype = conf["dtype" ].as<std::string>();
13631444
if (conf["vflag" ]) vflag = conf["vflag" ].as<int>();
13641445
if (conf["pyname" ]) pyname = conf["pyname" ].as<std::string>();
1446+
if (conf["pcavar"] ) pcavar = conf["pcavar" ].as<bool>();
13651447

13661448
// Deprecation warning
13671449
if (conf["density" ]) {

exputil/EmpCylSL.cc

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4812,6 +4812,44 @@ void EmpCylSL::pca_hall(bool compute, bool subsamp)
48124812
}
48134813

48144814

4815+
/** Return a vector of tuples of basis functions and the
4816+
covariance matrix for subsamples of particles */
4817+
std::vector<std::vector<EmpCylSL::CoefCovarType>>
4818+
EmpCylSL::getCoefCovariance()
4819+
{
4820+
std::vector<std::vector<std::tuple<Eigen::VectorXd, Eigen::MatrixXd>>> ret;
4821+
4822+
if (PCAVAR) {
4823+
ret.resize(sampT);
4824+
for (unsigned T=0; T<sampT; T++) {
4825+
ret[T].resize(MMAX+1);
4826+
for (int M=0; M<=MMAX; M++) {
4827+
std::get<0>(ret[T][M]) = covV[0][T][M];
4828+
std::get<1>(ret[T][M]) = covM[0][T][M];
4829+
}
4830+
}
4831+
}
4832+
4833+
return ret;
4834+
}
4835+
4836+
std::tuple<Eigen::VectorXi, Eigen::VectorXd>
4837+
EmpCylSL::getCovarSamples()
4838+
{
4839+
std::tuple<Eigen::VectorXi, Eigen::VectorXd> ret;
4840+
4841+
if (PCAVAR) {
4842+
std::get<0>(ret).resize(sampT);
4843+
std::get<1>(ret).resize(sampT);
4844+
for (int T=0; T<sampT; T++) {
4845+
std::get<0>(ret)(T) = numbT[T];
4846+
std::get<1>(ret)(T) = massT[T];
4847+
}
4848+
}
4849+
4850+
return ret;
4851+
}
4852+
48154853
void EmpCylSL::get_trimmed
48164854
(double snr,
48174855
std::vector<Eigen::VectorXd>& ac_cos, std::vector<Eigen::VectorXd>& ac_sin,

include/EmpCylSL.H

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -930,6 +930,15 @@ public:
930930
//! Check orthogonality for basis (pyEXP style)
931931
std::vector<Eigen::MatrixXd> orthoCheck();
932932

933+
//! Return a vector of tuples of basis functions and the
934+
//! covariance matrix for subsamples of particles
935+
using CoefCovarType = std::tuple<Eigen::VectorXd, Eigen::MatrixXd>;
936+
std::vector<std::vector<CoefCovarType>> getCoefCovariance();
937+
938+
//! Covariance statistics
939+
std::tuple<Eigen::VectorXi, Eigen::VectorXd> getCovarSamples();
940+
941+
933942
#if HAVE_LIBCUDA==1
934943
cudaMappingConstants getCudaMappingConstants();
935944

0 commit comments

Comments
 (0)