@@ -71,6 +71,10 @@ namespace MSSA {
7171 throw std::runtime_error (" expMSSA::wCorrKey: no such key" );
7272 }
7373
74+ if (nPC<2 ) {
75+ throw std::runtime_error (" expMSSA::wCorrKey: nPC must be >= 2 for a meaningful correlation" );
76+ }
77+
7478 // Get the number of components
7579 int ncomp = std::min<int >({numW, npc, nPC, static_cast <int >(PC.cols ())});
7680
@@ -97,29 +101,31 @@ namespace MSSA {
97101 else return numT - i + 1 ;
98102 };
99103
100- Eigen::MatrixXd ret = Eigen::MatrixXd::Zero (numW, numW);
101- for (int m=0 ; m<numW; m++) {
102- for (int n=m; n<numW; n++) {
104+ int rank = std::min<int >(nPC, numW);
105+
106+ Eigen::MatrixXd ret = Eigen::MatrixXd::Zero (rank, rank);
107+ for (int m=0 ; m<rank; m++) {
108+ for (int n=m; n<rank; n++) {
103109 for (int i=0 ; i<numT; i++) ret (m, n) += w (i) * R (i, m)*R (i, n);
104110 }
105111 }
106112
107113 // Normalize
108114 //
109- for (int m=0 ; m<numW ; m++) {
110- for (int n=m+1 ; n<numW ; n++) {
115+ for (int m=0 ; m<rank ; m++) {
116+ for (int n=m+1 ; n<rank ; n++) {
111117 if (ret (m, m)>0.0 and ret (n, n)>0.0 )
112118 ret (m, n) /= sqrt (ret (m, m)*ret (n, n));
113119 }
114120 }
115121
116122 // Unit diagonal
117123 //
118- for (int m=0 ; m<numW ; m++) ret (m, m) = 1.0 ;
124+ for (int m=0 ; m<rank ; m++) ret (m, m) = 1.0 ;
119125
120126 // Complete
121127 //
122- for (int m=0 ; m<numW ; m++) {
128+ for (int m=0 ; m<rank ; m++) {
123129 for (int n=0 ; n<m; n++) ret (m, n) = ret (n, m);
124130 }
125131
@@ -129,6 +135,10 @@ namespace MSSA {
129135
130136 Eigen::MatrixXd expMSSA::wCorrAll (int nPC)
131137 {
138+ if (nPC<2 ) {
139+ throw std::runtime_error (" expMSSA::wCorrAll: nPC must be >= 2 for a meaningful correlation" );
140+ }
141+
132142 // Get the number of components
133143 int ncomp = std::min<int >({numW, npc, nPC, static_cast <int >(PC.cols ())});
134144
@@ -153,10 +163,12 @@ namespace MSSA {
153163 else return numT - i + 1 ;
154164 };
155165
156- Eigen::MatrixXd ret = Eigen::MatrixXd::Zero (numW, numW);
166+ int rank = std::min<int >(nPC, numW);
167+
168+ Eigen::MatrixXd ret = Eigen::MatrixXd::Zero (rank, rank);
157169 for (auto R : RC) {
158- for (int m=0 ; m<numW ; m++) {
159- for (int n=m; n<numW ; n++) {
170+ for (int m=0 ; m<rank ; m++) {
171+ for (int n=m; n<rank ; n++) {
160172 for (int i=0 ; i<numT; i++)
161173 ret (m, n) += w (i) * R.second (i, m)*R.second (i, n);
162174 }
@@ -165,20 +177,20 @@ namespace MSSA {
165177
166178 // Normalize
167179 //
168- for (int m=0 ; m<numW ; m++) {
169- for (int n=m+1 ; n<numW ; n++) {
180+ for (int m=0 ; m<rank ; m++) {
181+ for (int n=m+1 ; n<rank ; n++) {
170182 if (ret (m, m)>0.0 and ret (n, n)>0.0 )
171183 ret (m, n) /= sqrt (ret (m, m)*ret (n, n));
172184 }
173185 }
174186
175187 // Unit diagonal
176188 //
177- for (int m=0 ; m<numW ; m++) ret (m, m) = 1.0 ;
189+ for (int m=0 ; m<rank ; m++) ret (m, m) = 1.0 ;
178190
179191 // Complete
180192 //
181- for (int m=0 ; m<numW ; m++) {
193+ for (int m=0 ; m<rank ; m++) {
182194 for (int n=0 ; n<m; n++) ret (m, n) = ret (n, m);
183195 }
184196
@@ -188,6 +200,10 @@ namespace MSSA {
188200 Eigen::MatrixXd expMSSA::wCorr
189201 (const std::string& name, const Key& key, int nPC)
190202 {
203+ if (nPC<2 ) {
204+ throw std::runtime_error (" expMSSA::wCorr: nPC must be >= 2 for a meaningful correlation" );
205+ }
206+
191207 int indx = coefDB.index (name);
192208 if (indx<0 ) {
193209 std::cout << " No such name <" << name << " >" << std::endl
0 commit comments