Logo coherent WaveBurst  
Library Reference Guide
Logo
regression.cc
Go to the documentation of this file.
1 /*
2 # Copyright (C) 2019 Sergey Klimenko, Vaibhav Tiwari
3 #
4 # This program is free software: you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License as published by
6 # the Free Software Foundation, either version 3 of the License, or
7 # (at your option) any later version.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License
15 # along with this program. If not, see <https://www.gnu.org/licenses/>.
16 */
17 
18 
19 //---------------------------------------------------
20 // WAT class for regression analysis
21 // S. Klimenko, University of Florida
22 //---------------------------------------------------
23 
24 #include <time.h>
25 #include <iostream>
26 #include <stdexcept>
27 #include "regression.hh"
28 #include "Biorthogonal.hh"
29 #include "SymmArray.hh"
30 #include "WDM.hh"
31 
32 ClassImp(regression) // used by THtml doc
33 
34 regression::regression() : Edge(0.), pOUT(false)
35 {
36 //
37 // Default constructor
38 //
39 
40  this->clear();
41 }
42 
43 regression::regression(WSeries<double> &in, char* ch, double fL, double fH)
44 {
45 //
46 // Constructor from WSeries, add target channel
47 //
48 // in: TF transform of target
49 // ch: channel name
50 // fL, fH: low and high frequency
51 //
52 // It calls the add function
53 //
54 
55  this->add(in,ch,fL,fH);
56 }
57 
59  Edge(0.), pOUT(false)
60 {
61 //
62 // Copy constructor
63 //
64 
65  *this = value;
66 }
67 
69 {
70 //
71 // Copy constructor using operator
72 //
73 
74  std::cout<<"I am =\n";
75  this->chList = value.chList; // TF data: 0 - target, >0 - withess
76  this->FILTER = value.FILTER; // total Wiener filter
77  this->chName = value.chName; // channel names
78  this->chMask = value.chMask; // vectors of selected/rejected (1/0) layers
79  this->matrix = value.matrix; // symmetric matrix
80  this->vCROSS = value.vCROSS; // cross-correlation vector
81  this->vEIGEN = value.vEIGEN; // eigenvaue vector
82  this->target = value.target; // target time series
83  this->rnoise = value.rnoise; // regressed out noise
84  this->WNoise = value.WNoise; // Wavelet series for regressed out noise
85  this->Edge = value.Edge; // boundary buffer
86  this->pOUT = value.pOUT; // printout flag
87 
88  return *this;
89 }
90 
91 size_t regression::add(WSeries<double> &in, char* ch, double fL, double fH) {
92 //
93 // clear and add target channel to the regression list
94 //
95 // in: target channel, time-frequency series
96 // ch: name - channel name
97 // fL, fH: - fL <-- frequency band --> fH. If fL>=fH - set boundaries from input in
98 //
99 // return value: number of channels in the regression list
100 //
101 
102  this->clear();
103  size_t I = in.maxLayer();
104  wavearray<int> mask(I+1); mask=0;
106  ww = in;
107  ww.setlow(fL>=fH ? in.getlow() : fL);
108  ww.sethigh(fL>=fH ? in.gethigh() : fH);
109 
110  for(size_t i=1; i<I; i++) {
111  if(ww.frequency(i)<=ww.gethigh() && ww.frequency(i)>=ww.getlow())
112  mask.data[i] = 1;
113  }
114 
115  this->chList.push_back(ww);
116  this->chName.push_back(ch);
117  this->chMask.push_back(mask);
118  ww.Inverse();
119  this->target = ww;
120  return chList.size();
121 }
122 
123 size_t regression::add(wavearray<double> &in, char* ch, double fL, double fH) {
124 //
125 // add witness channel to the regression list
126 //
127 // in: witness time series
128 // ch: channel name, if ch name is the same as witness, build LPE filter
129 // fL, fH: fL <-- frequency band --> fH
130 //
131 // return value: number of channels in the regression list
132 //
133 
134  if(!chList.size()) {
135  std::cout<<"regression::add() ERROR: add target first\n";
136  exit(1);
137  }
138  if(chList.size()>1 && strcmp(this->chName[0],this->chName[1])==0) {
139  std::cout<<"regression::add() ERROR: second witness channel can not be added to LPEF\n";
140  exit(1);
141  }
142  in -= in.mean();
143  if(in.rms()==0.) {
144  std::cout<<"regression::add() warning: empty witness channel.\n";
145  return 0;
146  }
147  double rate = chList[0].rate();
148  size_t size = chList[0].size();
149  int n = in.rate()>rate ? int(in.rate())%int(rate) : int(rate)%int(in.rate());
150  int m = in.rate()>rate ? int(in.rate()/rate) : -int(rate/in.rate());
151  int l = int(log(fabs(m))/log(2.)+0.1);
152 
153  if(n || abs(m)!=int(pow(2.,l)+0.1)) {
154  std::cout<<"regression::add() ERROR: incompatible target and witness channels\n";
155  exit(1);
156  }
157 
158  Biorthogonal<double> Bio(512);
159  WSeries<double> ws(Bio);
161  WDM<double>* wdm = (WDM<double>*)this->chList[0].pWavelet->Clone();
162 
163  if(m==1) { // copy witness
164  ts = in;
165  }
166  else if(m>0) { // downsample witness
167  ws.Forward(in,l);
168  ws.getLayer(ts,0);
169  }
170  else { // upsample witness
171  ws.resize(abs(m)*in.size());
172  ws.rate(abs(m)*in.rate());
173  ws.Forward(l); ws=0.;
174  ws.putLayer(in,0);
175  ws.Inverse(); ts = ws;
176  }
177  ws.Forward(ts,*wdm);
178 
179  if(ws.rate()!=rate || ws.size() != size) {
180  std::cout<<"regression::add() ERROR: incompatible target and witness channels\n";
181  exit(1);
182  }
183 
184  ws.setlow(fL>=fH ? 0. : fL);
185  ws.sethigh(fL>=fH ? ws.rate()/2. : fH);
186 
187  size_t I = ws.maxLayer()+1;
188  wavearray<int> mask(I); mask=0;
189 
190  for(size_t i=0; i<I; i++) {
191  if(ws.frequency(i)<=ws.gethigh() && ws.frequency(i)>=ws.getlow())
192  mask.data[i] = 1;
193  //ws.getLayer(ts,i);
194  //if (ws.frequency(i)>500 && ws.frequency(i)<540) std::cout << ws.frequency(i) << " " << ts.mean() << " " << ts.rms() << endl;
195  //if (ts.rms()==0) mask.data[i]=0;
196  }
197 
198  this->chList.push_back(ws);
199  this->chName.push_back(ch);
200  this->chMask.push_back(mask);
201 
202  delete wdm;
203 
204  return chList.size();
205 }
206 
207 size_t regression::add(int n, int m, char* ch) {
208 //
209 // construct witness channel from 2 channels and add
210 //
211 // n, m channel indeces in chList
212 // ch: channel name
213 //
214 // return value: number of channels in the regression list
215 //
216 
217 
218  if(chList.size()>1 && strcmp(this->chName[0],this->chName[1])==0) {
219  std::cout<<"regression::add() ERROR: second witness channel can not be added to LPEF\n";
220  exit(1);
221  }
222  if(n>=(int)chList.size() || m>=(int)chList.size()) {
223  std::cout<<"regression::add() WARNING: can't construct witness channel.\n";
224  return chList.size();
225  }
226 
227  WSeries<double> wsn = this->chList[n];
228  WSeries<double> wsm = this->chList[m];
229  wavearray<int>* pMn = &(this->chMask[n]);
230  wavearray<int>* pMm = &(this->chMask[m]);
232  WDM<double>* wdm = (WDM<double>*)this->chList[0].pWavelet->Clone();
233 
234  size_t I = wsn.maxLayer()+1;
236  wavearray<int> mask(I); mask=0;
237 
238  for(size_t i=0; i<I; i++) {
239  if(!(pMn->data[i])) {
240  wsn.getLayer(wa,i); wa = 0;
241  wsn.putLayer(wa,i);
242  }
243  if(!(pMm->data[i])) {
244  wsm.getLayer(wa,i); wa = 0;
245  wsm.putLayer(wa,i);
246  }
247  if(!(pMn->data[i])) continue;
248  for(size_t j=0; j<I; j++) {
249  if(!(pMm->data[j])) continue;
250  if(i+j < I-1) mask.data[i+j] = 1;
251  if(i>j) mask.data[i-j] = 1;
252  if(i<j) mask.data[j-i] = 1;
253  }
254  }
255 
256  wsn.setlow(chList[0].getlow());
257  wsn.sethigh(chList[0].gethigh());
258  for(size_t i=0; i<I; i++) {
259  if(wsn.frequency(i)>wsn.gethigh() || wsn.frequency(i)<wsn.getlow())
260  mask.data[i] = 0;
261  }
262 
263  wsn.Inverse();
264  wsm.Inverse();
265  wsm *= wsn; ts = wsm; ts -= ts.mean();
266  wsn.Forward(ts, *wdm);
267  this->chList.push_back(wsn);
268  this->chName.push_back(ch);
269  this->chMask.push_back(mask);
270 
271  delete wdm;
272 
273  return chList.size();
274 }
275 
276 size_t regression::setFilter(size_t K) {
277 //
278 // set Wiener filter structure
279 //
280 // K: half-size length of a unit filter: each witness layer has filter 2(2*k+1) long
281 //
282 // return value: total number of witness layers
283 //
284 // FILTER.filter[0] is not used
285 //
286 
287  size_t i,j;
288  size_t I = this->chList[0].maxLayer();
289  size_t count = 0;
290  wavearray<int>* pT = &(this->chMask[0]);
291  wavearray<int>* pW;
292  vectorD f; f.resize(2*K+1);
293 
294  this->FILTER.clear(); std::vector<Wiener>().swap(FILTER);
295  this->matrix.clear(); std::vector<TMatrixDSym>().swap(matrix);
296  this->vCROSS.clear(); std::vector< wavearray<double> >().swap(vCROSS);
297  this->vEIGEN.clear(); std::vector< wavearray<double> >().swap(vEIGEN);
298 
299  this->kSIZE = K;
300  for(i=1; i<I; i++) {
301  if(!pT->data[i]) continue; // check target mask
302 
303  Wiener WF;
304 
305  for(j=0; j<chList.size(); j++) {
306  pW = &(this->chMask[j]);
307  if(!pW->data[i]) continue; // check witness mask
308  WF.channel.push_back(j);
309  WF.layer.push_back(i);
310  WF.norm.push_back(1.);
311  WF.filter00.push_back(f);
312  WF.filter90.push_back(f);
313  if(j) count++;
314  }
315  if(WF.channel.size()>1) this->FILTER.push_back(WF);
316  else pT->data[i] = 0; // mask target layer
317  }
318  return count;
319 }
320 
321 void regression::mask(int n, double flow, double fhigh) {
322 //
323 // mask (set to 0) Mask vector
324 //
325 // n: channel index
326 // flow, high: low and high frequency bounds
327 //
328 
329  int* pM = this->chMask[n].data;
330  WSeries<double>* pW = &(this->chList[n]);
331  size_t I = pW->maxLayer()+1;
332  for(size_t i=0; i<I; i++) {
333  if((pW->frequency(i)<fhigh && pW->frequency(i)>flow) || fhigh<=flow)
334  pM[i] = 0;
335  }
336 
337 }
338 
339 void regression::unmask(int n, double flow, double fhigh) {
340 //
341 // unmask (set to 1) Mask vector
342 //
343 // n: channel index
344 // flow, high: low and high frequency bounds
345 //
346 
347  int* pM = this->chMask[n].data;
348  WSeries<double>* pW = &(this->chList[n]);
349  size_t I = pW->maxLayer()+1;
350  for(size_t i=0; i<I; i++) {
351  if((pW->frequency(i)<fhigh && pW->frequency(i)>flow) || fhigh<=flow)
352  pM[i] = 1;
353  }
354 
355 }
356 
358 //
359 // extract eigenvalues
360 //
361 // n: channel index. If -1 return all eigenvalues
362 //
363 // return wavearray: eigen-values
364 //
365 
367  size_t I = this->vEIGEN.size();
368  if(n<(int)I && n>=0) return vEIGEN[n];
369  for(size_t i=0; i<I; i++) E.append(this->vEIGEN[i]);
370  return E;
371 }
372 
373 wavearray<double> regression::getFILTER(char c, int nT, int nW) {
374 //
375 // extract filter for target index nT and witness nW
376 //
377 // c: 'f' or 'F' - extract 0-phase or 90-phase filter
378 // 'n' or 'N' - extract 0-phase or 90-phase norm
379 // 'a' or 'A' - extract 0-phase - 90-phase asymmetry
380 // nT: target index. If <0, return full vector
381 // nW: witness index
382 //
383 // return wavearray: filter values
384 //
385 
386  wavearray<double> OUT;
387  int N = int(this->FILTER.size());
388  int i,I,j,J;
389 
390  if(nT>=0 && nT<N) {i=nT; I=nT+1;}
391  else {i=0; I=N;}
392 
393  for(int n=i ;n<I;n++) {
394  int M = int(this->FILTER[n].filter00.size());
395 
396  if(nW>0 && nW<M) {j=nW; J=nW+1;}
397  else {j=1; J=M;}
398 
399  for(int m=j; m<J; m++) {
400  int K = int(this->FILTER[n].filter00[m].size());
401  wavearray<double> e(K);
402  wavearray<double> E(K);
403 
404  for(int k=0; k<K; k++) {
405  e.data[k] = this->FILTER[n].filter00[m][k];
406  E.data[k] = this->FILTER[n].filter90[m][k];
407  }
408 
409  if(c=='a') {
410  double re = e.rms();
411  double RE = E.rms();
412  OUT.append((re*re-RE*RE)/(re*re+RE*RE));
413  }
414  else if(c=='n') OUT.append(e.rms());
415  else if(c=='N') OUT.append(E.rms());
416  else {
417  if(c!='F') OUT.append(e);
418  if(c!='f') OUT.append(E);
419  }
420  }
421  }
422  return OUT;
423 }
424 
425 void regression::setMatrix(double edge, double f) {
426 //
427 // set system of linear equations: M * F = V
428 // M = matrix array, V = vector of free coefficients, F = filters
429 //
430 // edge: boundary interval in seconds excluded from training
431 // 1-f: tail fraction to be removed during training
432 //
433 
434  int i,j,n,m,nn,mm,N;
435  int I = this->FILTER.size(); // number of target layers
436  int K = (int)this->kSIZE; // unit filter half-size
437  int K2 = 2*K;
438  int K4 = 2*(2*K+1);
439  int k,ii,jj,kk;
440  int sIZe,sTEp,k00n,k90n,k00m,k90m;
441 
442  double FLTR = !strcmp(this->chName[0],this->chName[1]) ? 0. : 1.; // LPEF : Wiener
443  double fm = fabs(f);
444 
445  double fraction, rms;
446  WSeries<double>* pTFn;
447  WSeries<double>* pTFm;
451  std::slice s00n,s90n;
452  std::slice s00m,s90m;
453  Wiener* pW;
454  SymmArray<double> acf(K2);
455  SymmArray<double> ccf(K2);
456 
457  this->Edge = edge;
458  this->target.edge(edge);
459  for(i=0; i<(int)this->chList.size(); i++) { // loop on channels
460  this->chList[i].edge(edge); // set edge
461  }
462  if(!I) {std::cout<<"regression::nothing to clean.\n"; return;}
463 
464  this->matrix.clear(); std::vector<TMatrixDSym>().swap(matrix);
465  this->vCROSS.clear(); std::vector< wavearray<double> >().swap(vCROSS);
466  this->vEIGEN.clear(); std::vector< wavearray<double> >().swap(vEIGEN);
467 
468  for(i=0; i<I; i++) { // loop on target layers
469  pW = &FILTER[i];
470  N = pW->layer.size();
471  TMatrixDSym MS((N-1)*K4);
472  wavearray<double> VC((N-1)*K4);
473 
474  pTFm = &(this->chList[0]); // target
475  s00m = pTFm->pWavelet->getSlice(pW->layer[0]);
476  s90m = pTFm->pWavelet->getSlice(-pW->layer[0]);
477  k00m = s00m.start();
478  k90m = s90m.start();
479  sIZe = s00m.size(); // # of samples in a layer
480  sTEp = s00m.stride(); // layer stide
481 
482  for(n=0; n<N; n++) { // normalization & cross-vector
483  pTFn = &(this->chList[pW->channel[n]]);
484 
485  // normalize target & witness channels
486 
487  pTFn->getLayer(qq,pW->layer[n]);
488  pTFn->getLayer(ww,pW->layer[n]);
489  pTFn->getLayer(WW,-pW->layer[n]);
490 
491  for(j=0; j<(int)ww.size(); j++) {
492  qq.data[j] = ww.data[j]*ww.data[j]+WW.data[j]*WW.data[j];
493  }
494  rms = sqrt(qq.mean(fm));
495  pW->norm[n] = rms;
496 // std::cout<<i<<" "<<rms<<std::endl;
497  if(!n) continue; // skip target
498 
499  // calculate target-witness cross-vector
500 
501  s00n = pTFn->pWavelet->getSlice(pW->layer[n]);
502  s90n = pTFn->pWavelet->getSlice(-pW->layer[n]);
503  k00n = s00n.start();
504  k90n = s90n.start();
505 
506  for(k=-K; k<=K; k++) {
507 
508  if(k<0) { // n-channel is shifted
509  k00n = s00n.start();
510  k90n = s90n.start();
511  k00m = s00m.start()-k*sTEp;
512  k90m = s90m.start()-k*sTEp;
513  }
514  else { // m-channel is shifted
515  k00n = s00n.start()+k*sTEp;
516  k90n = s90n.start()+k*sTEp;
517  k00m = s00m.start();
518  k90m = s90m.start();
519  }
520  for(j=K; j<sIZe-K; j++) {
521  jj = j*sTEp;
522  ww.data[j] = pTFn->data[k00n+jj]*pTFm->data[k00m+jj];
523  ww.data[j]+= pTFn->data[k90n+jj]*pTFm->data[k90m+jj];
524  WW.data[j] = pTFm->data[k90m+jj]*pTFn->data[k00n+jj];
525  WW.data[j]-= pTFm->data[k00m+jj]*pTFn->data[k90n+jj];
526  }
527 
528  kk = (n-1)*K4+K+k;
529  VC.data[kk] = ww.mean(fm)/pW->norm[0]/pW->norm[n]; // Chx+Ch'x'
530  VC.data[kk+K4/2] = WW.mean(fm)/pW->norm[0]/pW->norm[n]; // Ch'x-Chx'
531  if(k==0) {VC.data[kk] *= FLTR; VC.data[kk+K4/2] *= FLTR;} // handle LPE filter
532 // printf("%f ",VC.data[kk+0*K4/2]);
533  }
534 // std::cout<<std::endl;
535  }
536  ww=0.; WW=0.;
537 
538  for(n=1; n<N; n++) { // loop on witness channels
539  nn = (n-1)*K4+K; // index of ZERO element of ii block
540  pTFn = &(this->chList[pW->channel[n]]); // witness channel i
541  s00n = pTFn->pWavelet->getSlice(pW->layer[n]);
542  s90n = pTFn->pWavelet->getSlice(-pW->layer[n]);
543  k00n = s00n.start();
544  k90n = s90n.start();
545  sIZe = s00n.size();
546  sTEp = s00n.stride();
547 
548  for(m=n; m<N; m++) {
549  mm = (m-1)*K4+K; // index of ZERO element of jj block
550  pTFm = &(this->chList[pW->channel[m]]); // witness channel j
551  s00m = pTFm->pWavelet->getSlice(pW->layer[m]);
552  s90m = pTFm->pWavelet->getSlice(-pW->layer[m]);
553  k00m = s00m.start();
554  k90m = s90m.start();
555 
556 // printf("n/m=%2d/%2d %d %d %d %d\n",n,m,sIZe,sTEp,(int)s00n.start(),(int)s90n.start());
557 
558  for(k=-K2; k<=K2; k++) {
559 
560  if(k<0) {
561  k00n = s00n.start();
562  k90n = s90n.start();
563  k00m = s00m.start()-k*sTEp;
564  k90m = s90m.start()-k*sTEp;
565  }
566  else {
567  k00n = s00n.start()+k*sTEp;
568  k90n = s90n.start()+k*sTEp;
569  k00m = s00m.start();
570  k90m = s90m.start();
571  }
572 
573  for(j=K2; j<sIZe-K2; j++) {
574  jj = j*sTEp;
575  ww.data[j] = pTFn->data[k00n+jj]*pTFm->data[k00m+jj];
576  ww.data[j]+= pTFn->data[k90n+jj]*pTFm->data[k90m+jj];
577  WW.data[j] = pTFm->data[k00m+jj]*pTFn->data[k90n+jj];
578  WW.data[j]-= pTFm->data[k90m+jj]*pTFn->data[k00n+jj];
579  }
580 
581  acf[k] = ww.mean(fm)/pW->norm[n]/pW->norm[m]; // "auto" function
582  ccf[k] = WW.mean(fm)/pW->norm[n]/pW->norm[m]; // "cros" function
583 
584 // printf("%f ",acf[k]);
585  }
586 // std::cout<<"\n";
587 
588  for(ii=-K; ii<=K; ii++) { // fill in matrix
589  for(jj=-K; jj<=K; jj++) {
590  MS[nn+ii][mm+jj] = (ii==0 || jj==0) ? acf[ii-jj]*FLTR : acf[ii-jj];
591  MS[mm+jj][nn+ii] = (ii==0 || jj==0) ? acf[ii-jj]*FLTR : acf[ii-jj];
592  MS[nn+ii][mm+jj+K4/2] = (ii==0 || jj==0) ? ccf[ii-jj]*FLTR : ccf[ii-jj];
593  MS[mm+jj+K4/2][nn+ii] = (ii==0 || jj==0) ? ccf[ii-jj]*FLTR : ccf[ii-jj];
594  MS[nn+ii+K4/2][mm+jj] = (ii==0 || jj==0) ? -ccf[ii-jj]*FLTR :-ccf[ii-jj];
595  MS[mm+jj][nn+ii+K4/2] = (ii==0 || jj==0) ? -ccf[ii-jj]*FLTR :-ccf[ii-jj];
596  MS[nn+ii+K4/2][mm+jj+K4/2] = (ii==0 || jj==0) ? acf[ii-jj]*FLTR : acf[ii-jj];
597  MS[mm+jj+K4/2][nn+ii+K4/2] = (ii==0 || jj==0) ? acf[ii-jj]*FLTR : acf[ii-jj];
598  }
599  }
600  }
601  }
602  // for(int i=0;i<VC.size();i++)
603  // std::cout<<VC[i]<<std::endl;
604  // MS.Print();
605  this->matrix.push_back(MS);
606  this->vCROSS.push_back(VC);
607  }
608 }
609 
610 void regression::solve(double th, int nE, char c) {
611 //
612 // solve for eigenvalues and calculate Wiener filters
613 //
614 // th: eigenvalue threshold. If <0, than in units of max eigenvalue
615 // nE: number of selected eigenvalues (minimum is 4)
616 // c: regulator h=mild, s=soft, h=hard
617 //
618 
619  int i, j, k;
620  int nA = this->FILTER.size();
621  int nR = this->matrix.size();
622  int nC = this->vCROSS.size();
623  int ne;
624 
625  if(!nA) {std::cout<<"regression::nothing to clean.\n"; return;}
626  if (nA!=nR || nA!=nC || nA==0) {
627  std::cout << "Error, filter not initialized\n"; exit(1);
628  }
629 
630  int K = (int) this->kSIZE;
631  int K4=2*(2*K+1);
632  double temp;
633 
634  this->vEIGEN.clear(); std::vector< wavearray<double> >().swap(vEIGEN);
635 
636  for (i=0; i<nA; i++) { //loop on wavelet layers
637  int J = FILTER[i].layer.size()-1; //number of witness channels
638  ne = nE<=0 ? K4*J : nE-1;
639  if(ne>=K4*J) ne = K4*J-1;
640  if(ne<1) ne = 1;
641 
642  wavearray<double> lambda(K4*J); //inverse of regulators
643  TMatrixDSym R(this->matrix[i]);
644  wavearray<double>* pC = &(this->vCROSS[i]);
645  TMatrixDSymEigen QP(R);
646  TVectorD eigenval(QP.GetEigenValues());
647  TMatrixD eigenvec(QP.GetEigenVectors());
648 
649  //select threshold
650  double last = 0.;
651  double TH = th<0. ? -th*eigenval[0] : th+1.e-12;
652  int nlast = -1;
653  for(j=0; j<K4*J; j++) {
654  lambda.data[j] = eigenval[j];
655  if(eigenval[j]>=TH) nlast++;
656  if(j<K4*J-1)
657  if(eigenval[j+1]>eigenval[j])
658  std::cout<<eigenval[j]<<" "<<eigenval[j+1]<<endl;
659  }
660  if(nlast<1) nlast = 1;
661 
662  this->vEIGEN.push_back(lambda);
663  if(nlast>ne) nlast = ne;
664  lambda = 0.;
665 
666  //std::cout<<i<<" "<<J<<" "<<TH<<" "<<nlast<<" "<<K<<" "<<eigenval[nlast]<<std::endl;
667 
668  switch(c) { //regulators
669  case 'h':
670  last = 0.;
671  break;
672  case 's':
673  last = eigenval[nlast]>0. ? 1./eigenval[nlast] : 0.;
674  break;
675  case 'm':
676  last = 1./eigenval[0];
677  break;
678  }
679  for(j=0;j<=nlast;j++) lambda[j] = eigenval[j]>0. ? 1./eigenval[j] : 0.;
680  for(j=nlast+1;j<K4*J;j++) lambda[j] = last;
681 
682  //calculte filters
683  wavearray<double> vv(K4*J); // lambda * eigenvector * cross vector
684  wavearray<double> aa(K4*J); // eigenvector^T * lambda * eigenvector * cross vector
685 
686  for(j=0;j<K4*J;j++) {
687  temp=0.0;
688  for(k=0;k<K4*J;k++) temp += eigenvec[k][j]*pC->data[k];
689  vv.data[j]=temp*lambda.data[j];
690  }
691 
692  for(j=0;j<K4*J;j++) {
693  temp=0.0;
694  for(k=0;k<K4*J;k++) temp += eigenvec[j][k]*vv.data[k];
695  aa.data[j]=temp;
696  }
697 
698  //save filters coefficients
699  for (j=0; j<J; j++) {
700  for(k=0;k<=2*K;k++) {
701  FILTER[i].filter00[j+1][k] = aa.data[j*K4+k];
702  FILTER[i].filter90[j+1][k] = aa[j*K4+k+K4/2];
703  }
704  }
705  }
706 }
707 
708 
709 void regression::apply(double threshold, char c) {
710 //
711 // apply filter to target channel and produce noise TS
712 //
713 // threshold: filter is not applied if regressed noise rms < threshold
714 // mask channels with rms<threshold, if c='m' or c='M'.
715 // mask changes configuration of witness channels
716 // c: 'n' or 'N' - either 0-phase or 90-phase noise
717 // 'a' - (0-phase + 90-phase)/2 noise, standard RMS threshold
718 // 'A' - (0-phase + 90-phase)/2 noise, differential RMS threshold
719 // 'm' - (0-phase + 90-phase)/2 noise, mask, standard RMS threshold
720 // 'M' - (0-phase + 90-phase)/2 noise, mask, differential RMS threshold
721 //
722 
723  int n,m;
724  int nA = this->FILTER.size();
725  int nR = this->matrix.size();
726  int nC = this->vCROSS.size();
727 
728  if(!nA) {std::cout<<"regression::nothing to clean.\n"; return;}
729  if (nA!=nR || nA!=nC || nA==0) {
730  std::cout << "Error, filter is not initialized\n"; exit(1);
731  }
732 
733  int K = (int) this->kSIZE;
734  int N = this->FILTER.size(); // number of target layers
735 
736  wavearray<double> tmp(N); tmp=0.; //RANK
737  int L = this->chList.size(); //RANK
738  for(n=0; n<L; n++) this->vrank.push_back(tmp); //RANK
739 
744  WSeries<double>* pT;
745  Wiener* pF;
746 
747  double sum, SUM;
748  WSeries<double> wnoise(this->chList[0]);
749  WSeries<double> WNOISE(this->chList[0]);
750  wnoise=0; WNOISE=0.;
751 
752  for(n=0; n<N; n++) { // loop on target layers
753  std::vector< wavearray<double> > wno;
754  std::vector< wavearray<double> > WNO;
755  _apply_(n,wno,WNO);
756 
757  pF = &FILTER[n]; // pointer to Weiner structure
758  pT = &(this->chList[0]); // pointer to target WS
759  pT->getLayer(ww,pF->layer[0]); // get target 00 data
760  pT->getLayer(WW,-pF->layer[0]); // get target 90 data
761  ww = 0.; WW = 0.; // zero total noise arrays
762 
763  double freq = pT->frequency(pF->layer[0]); //RANK
764  vfreq.append(freq); //RANK
765 
766  int KK = int(ww.rate()*this->Edge); // calculate # of edge samples
767  if(KK<K) KK = K; KK++;
768  std::slice S(KK,ww.size()-2*KK,1); // slice for RMS calculation
769 
770  double trms = wno[0].rms(S);
771  double TRMS = WNO[0].rms(S);
772  int M = pF->layer.size(); // number of witness channels + 1
773 
774  for(m=1; m<M; m++) { // loop over witnwss channels
775  int j = (int)pF->channel[m]; // witness channel index
776  int* pM = this->chMask[j].data; // poiner to j's mask
777 
778  if(c=='A' || c=='M') {
779  qq=wno[0]; qq-=wno[m]; // channel j subtracted
780  QQ=WNO[0]; QQ-=WNO[m]; // channel j subtracted
781  sum = qq.rms(S);
782  SUM = QQ.rms(S);
783  sum = trms*trms-sum*sum;
784  SUM = TRMS*TRMS-SUM*SUM;
785  }
786  else {
787  sum = pow(wno[m].rms(S),2); // rms 00
788  SUM = pow(WNO[m].rms(S),2); // rms 90
789  }
790  if(sum<0.) sum = 0.;
791  if(SUM<0.) SUM = 0.;
792 
793  this->vrank[j].data[n] = sum+SUM; //RANK
794  this->vrank[0].data[n] += sum+SUM; //RANK
795 
796  if(sum+SUM < threshold*threshold) {
797  if(c=='m' || c=='M') pM[pF->layer[m]] = 0;
798  continue;
799  }
800  ww += wno[m]; WW += WNO[m];
801  //std::cout << "RMS: M: " << m << " " << wno[m].rms(S) << " " << WNO[m].rms(S) << std::endl;
802  }
803  if(c=='A' || c=='M') this->vrank[0].data[n] = trms*trms+TRMS*TRMS; //RANK
804  //std::cout << "RMS: N: " << n << " " << ww.rms() << " " << WW.rms() << std::endl;
805  ww *= pF->norm[0];
806  WW *= pF->norm[0];
807  //std::cout << "RMS: N: " << n << " " << ww.rms() << " " << WW.rms() << " " << pF->norm[0] << std::endl;
808  wnoise.putLayer(ww,pF->layer[0]);
809  wnoise.putLayer(WW,-pF->layer[0]);
810  }
811  WNOISE = wnoise;
812  this->WNoise = wnoise;
813  wnoise.Inverse();
814  WNOISE.Inverse(-2);
815 
816  if(c=='n') this->rnoise = wnoise;
817  else if(c=='N') this->rnoise = WNOISE;
818  else{
819  this->rnoise = wnoise;
820  this->rnoise += WNOISE;
821  this->rnoise *= 0.5;
822  }
823 }
824 
825 wavearray<double> regression::rank(int nbins, double fL, double fH) {
826 //
827 // get RMS for predicted noise (per layer/bin) for all witness channels
828 // (including masked)
829 //
830 // nbins: number of loudest frequency layers to calculate rms/layer.
831 // nbins=0 - take all layers
832 // if positive, return standard RMS
833 // if negative, return differential RMS
834 // fL, fH: frequency range: low, high
835 //
836 // return wavearray: rank values
837 //
838 
839  int n,m;
840  int nA = this->FILTER.size();
841  int nR = this->matrix.size();
842  int nC = this->vCROSS.size();
843 
844  if(!nA) {
845  std::cout<<"regression::nothing to clean.\n";
846  return wavearray<double>();
847  }
848  if (nA!=nR || nA!=nC) {
849  std::cout << "Error, filter not initialized\n"; exit(1);
850  }
851 
852  int N = this->FILTER.size(); // number of target layers
853  int L = this->chList.size();
854 
855  wavearray<double> tmp(N); tmp=0.;
856  wavearray<double> rms(L); rms=0.;
857  std::vector< wavearray<double> > vrms;
858  for(n=0; n<L; n++) { // loop on channels
859  vrms.push_back(tmp);
860  int tsize=this->vfreq.size();
861  for (int i=0; i<tsize; i++) {
862  double freq = vfreq.data[i];
863  if(fL<fH && (freq>fH || freq<fL)) continue;
864  vrms[n].data[i]=vrank[n].data[i];
865  }
866  }
867 
868  for(n=0; n<L; n++) { // loop on channels
869  vrms[n].waveSort();
870  nA = 0;
871  for(m=N-1; m>=N-abs(nbins); m--) { // loop over loud layers
872  rms.data[n] += vrms[n].data[m];
873  if(vrms[n].data[m]>0.) nA++;
874  }
875  if(nA) rms.data[n] /= nA;
876  rms.data[n] = sqrt(rms.data[n]);
877  }
878  return rms;
879 }
880 
882  std::vector< wavearray<double> > &wno,
883  std::vector< wavearray<double> > &WNO)
884 {
885 //
886 // internal regression apply function
887 //
888 
889  int m,k,i;
894  WSeries<double>* pT;
895  WSeries<double>* pW;
896  Wiener* pF;
897  std::vector<double> *ff, *FF;
898  double val, VAL;
899 
900  pF = &FILTER[n]; // pointer to Weiner structure
901  pT = &(this->chList[0]); // pointer to target WS
902  pT->getLayer(ww,pF->layer[0]); // get target 00 data
903  pT->getLayer(WW,-pF->layer[0]); // get target 90 data
904 
905  ww = 0.; WW = 0.; // zero total noise arrays
906  wno.clear();
907  WNO.clear();
908  wno.push_back(ww);
909  WNO.push_back(WW);
910 
911  int K = (int) this->kSIZE;
912  int M = pF->layer.size(); // number of witness channels + 1
913  for(m=1; m<M; m++) { // loop over witnwss channels
914  int j = (int)pF->channel[m]; // witness channel index
915  pW = &(this->chList[j]); // pointer to witness WS
916  pW->getLayer(qq,pF->layer[m]); // get witness 00 data
917  pW->getLayer(QQ,-pF->layer[m]); // get witness 90 data
918  ff = &(pF->filter00[m]); // get 00 filter pointer
919  FF = &(pF->filter90[m]); // get 90 filter pointer
920  wavearray<double> nn(qq.size()); // array for witness prediction data
921  wavearray<double> NN(qq.size()); // array for witness prediction data
922  nn.rate(qq.rate());
923  NN.rate(QQ.rate());
924  qq *= 1./pF->norm[m];
925  QQ *= 1./pF->norm[m];
926 
927  for(i=0; i<(int)qq.size(); i++) {
928  val = VAL = 0.;
929  if(i>=K && i<int(qq.size())-K) {
930  for(k=-K; k<=K; k++) {
931  val += (*ff)[k+K]*qq.data[i+k] - (*FF)[k+K]*QQ.data[i+k];
932  VAL += (*FF)[k+K]*qq.data[i+k] + (*ff)[k+K]*QQ.data[i+k];
933  }
934  }
935  nn.data[i] = val;
936  NN.data[i] = VAL;
937  wno[0].data[i] += val;
938  WNO[0].data[i] += VAL;
939  }
940  wno.push_back(nn);
941  WNO.push_back(NN);
942  }
943 }
944 
945 
946 
947 
948 
void sethigh(double f)
Definition: wseries.hh:132
size_t append(const wavearray< DataType_t > &)
Definition: wavearray.cc:793
virtual void resize(unsigned int)
Definition: wseries.cc:901
double getlow() const
Definition: wseries.hh:129
void setMatrix(double edge=0., double f=1.)
Definition: regression.cc:425
double M
Definition: DrawEBHH.C:13
par [0] value
void _apply_(int n, std::vector< wavearray< double > > &w, std::vector< wavearray< double > > &W)
Definition: regression.cc:881
virtual void rate(double r)
Definition: wavearray.hh:141
wavearray< double > target
Definition: regression.hh:185
virtual void edge(double s)
Definition: wavearray.hh:143
int n
Definition: cwb_net.C:28
TMatrixTSym< double > TMatrixDSym
Definition: regression.hh:38
WDM< double > wdm(nLAYERS, nLAYERS, 6, 10)
void setlow(double f)
Definition: wseries.hh:125
std::vector< wavearray< double > > vCROSS
Definition: regression.hh:183
Long_t size
int m
Definition: cwb_net.C:28
size_t add(WSeries< double > &target, char *name, double fL=0., double fH=0.)
Definition: regression.cc:91
int j
Definition: cwb_net.C:28
i drho i
double gethigh() const
Definition: wseries.hh:136
std::vector< double > vectorD
Definition: network.hh:51
wc clear()
#define N
cout<< "SNR "<< xsnr<< endl;wavearray< double > f
Definition: ComputeSNR.C:75
std::vector< wavearray< double > > vEIGEN
Definition: regression.hh:184
std::vector< Wiener > FILTER
Definition: regression.hh:181
std::vector< WSeries< double > > chList
Definition: regression.hh:178
virtual double rms()
Definition: wavearray.cc:1206
char val[20]
virtual size_t size() const
Definition: wavearray.hh:145
wavearray< double > rank(int nbins=0, double fL=0., double fH=0.)
Definition: regression.cc:825
wavearray< double > freq
Definition: Regression_H1.C:79
size_t size() const
Definition: wslice.hh:89
std::vector< vectorD > filter00
Definition: regression.hh:45
size_t start() const
Definition: wslice.hh:85
i() int(T_cor *100))
size_t stride() const
Definition: wslice.hh:93
bool log
Definition: WaveMDC.C:41
double fhigh
double * tmp
Definition: testWDM_5.C:31
void apply(double threshold=0., char c='a')
Definition: regression.cc:709
int getLayer(wavearray< DataType_t > &w, double n)
param: n - layer number
Definition: wseries.cc:193
int l
std::vector< TMatrixDSym > matrix
Definition: regression.hh:182
std::vector< wavearray< int > > chMask
Definition: regression.hh:180
int k
void solve(double th, int nE=0, char c='s')
Definition: regression.cc:610
std::vector< int > channel
Definition: regression.hh:42
wavearray< double > vfreq
Definition: regression.hh:189
std::vector< vectorD > filter90
Definition: regression.hh:46
size_t setFilter(size_t)
Definition: regression.cc:276
wavearray< double > getVEIGEN(int n=-1)
Definition: regression.cc:357
double e
double Edge
Definition: regression.hh:175
WSeries< double > ww
Definition: Regression_H1.C:33
size_t kSIZE
Definition: regression.hh:174
void clear()
Definition: regression.hh:160
std::vector< int > layer
Definition: regression.hh:43
double flow
std::vector< char * > chName
Definition: regression.hh:179
WSeries< double > WNoise
Definition: regression.hh:187
ifstream in
virtual std::slice getSlice(const double)
Definition: WaveDWT.cc:129
std::vector< double > norm
Definition: regression.hh:44
wavearray< double > ts(N)
#define SUM
Definition: FrDisplay.cc:130
virtual double mean() const
Definition: wavearray.cc:1071
double fabs(const Complex &x)
Definition: numpy.cc:55
wavearray< double > getFILTER(char c='a', int nT=-1, int nW=-1)
Definition: regression.cc:373
void Forward(int n=-1)
param: wavelet - n is number of steps (-1 means full decomposition)
Definition: wseries.cc:246
void unmask(int n, double flow=0., double fhigh=0.)
Definition: regression.cc:339
Meyer< double > S(1024, 2)
void mask(int n, double flow=0., double fhigh=0.)
Definition: regression.cc:321
DataType_t * data
Definition: wavearray.hh:319
std::vector< wavearray< double > > vrank
Definition: regression.hh:188
WaveDWT< DataType_t > * pWavelet
Definition: wseries.hh:456
regression & operator=(const regression &)
Definition: regression.cc:68
wavearray< double > rnoise
Definition: regression.hh:186
void Inverse(int n=-1)
param: n - number of steps (-1 means full reconstruction)
Definition: wseries.cc:291
void putLayer(wavearray< DataType_t > &, double n)
param: n - layer number
Definition: wseries.cc:219
double frequency(int l)
Definition: wseries.cc:117
int maxLayer()
Definition: wseries.hh:139
exit(0)