AccumulateJFAStat.cpp

Go to the documentation of this file.
00001 /*
00002 This file is part of LIA_RAL which is a set of software based on ALIZE
00003 toolkit for speaker recognition. ALIZE toolkit is required to use LIA_RAL.
00004 
00005 LIA_RAL project is a development project was initiated by the computer
00006 science laboratory of Avignon / France (Laboratoire Informatique d'Avignon -
00007 LIA) [http://lia.univ-avignon.fr <http://lia.univ-avignon.fr/>]. Then it
00008 was supported by two national projects of the French Research Ministry:
00009         - TECHNOLANGUE program [http://www.technolangue.net]
00010         - MISTRAL program [http://mistral.univ-avignon.fr]
00011 
00012 LIA_RAL is free software: you can redistribute it and/or modify
00013 it under the terms of the GNU Lesser General Public License as
00014 published by the Free Software Foundation, either version 3 of
00015 the License, or any later version.
00016 
00017 LIA_RAL is distributed in the hope that it will be useful,
00018 but WITHOUT ANY WARRANTY; without even the implied warranty of
00019 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00020 GNU Lesser General Public License for more details.
00021 
00022 You should have received a copy of the GNU Lesser General Public
00023 License along with LIA_RAL.
00024 If not, see [http://www.gnu.org/licenses/].
00025 
00026 The LIA team as well as the LIA_RAL project team wants to highlight the
00027 limits of voice authentication in a forensic context.
00028 The "Person Authentification by Voice: A Need of Caution" paper
00029 proposes a good overview of this point (cf. "Person
00030 Authentification by Voice: A Need of Caution", Bonastre J.F.,
00031 Bimbot F., Boe L.J., Campbell J.P., Douglas D.A., Magrin-
00032 chagnolleau I., Eurospeech 2003, Genova].
00033 The conclusion of the paper of the paper is proposed bellow:
00034 [Currently, it is not possible to completely determine whether the
00035 similarity between two recordings is due to the speaker or to other
00036 factors, especially when: (a) the speaker does not cooperate, (b) there
00037 is no control over recording equipment, (c) recording conditions are not
00038 known, (d) one does not know whether the voice was disguised and, to a
00039 lesser extent, (e) the linguistic content of the message is not
00040 controlled. Caution and judgment must be exercised when applying speaker
00041 recognition techniques, whether human or automatic, to account for these
00042 uncontrolled factors. Under more constrained or calibrated situations,
00043 or as an aid for investigative purposes, judicious application of these
00044 techniques may be suitable, provided they are not considered as infallible.
00045 At the present time, there is no scientific process that enables one to
00046 uniquely characterize a persones voice or to identify with absolute
00047 certainty an individual from his or her voice.]
00048 
00049 Copyright (C) 2004-2010
00050 Laboratoire d'informatique d'Avignon [http://lia.univ-avignon.fr]
00051 LIA_RAL admin [alize@univ-avignon.fr]
00052 Jean-Francois Bonastre [jean-francois.bonastre@univ-avignon.fr]
00053 */
00054 
00055 #if !defined(ALIZE_JFAAcc_cpp)
00056 #define ALIZE_JFAAcc_cpp
00057 
00058 #if defined(_WIN32)
00059   #include <cfloat> // for _isnan()
00060   #define ISNAN(x) _isnan(x)
00061   #define ISINF(x) (!_finite(x))
00062 #elif defined(linux) || defined(__linux) || defined(__CYGWIN__) || defined(__APPLE__)
00063   #define ISNAN(x) isnan(x)
00064   #define ISINF(x) isinf(x)
00065 #else
00066   #error "Unsupported OS\n"
00067 #endif
00068 
00069 #include<AccumulateJFAStat.h>
00070 #include<iostream>
00071 #include<fstream>
00072 #include<cstdio>
00073 #include<cassert>
00074 #include<cmath>
00075 #include "SuperVectors.h"
00076 #include "RealVector.h"
00077 #include <liatools.h>
00078 #include <limits>
00079 #ifdef THREAD
00080 #include <pthread.h>
00081 #endif
00082 
00083 
00084 using namespace alize;
00085 using namespace std;
00086 
00087 
00088 //***************************************************************//
00089 //                      Constructeurs et Destructeurs                            //
00090 //***************************************************************//
00091 
00092 
00093 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
00094 JFAAcc::JFAAcc(String & featFilename,Config & config)
00095         :_ms(config),_ss(config){ // constructor for a single file
00096 
00097         XLine& tmpLine = XLine::create();
00098         tmpLine.addElement(featFilename);
00099 
00100         XList jfaNdx;
00101         jfaNdx.addLine()=tmpLine;
00102 
00103 //      XList jfaNdx(featFilename,config);
00104         _init(jfaNdx,config);
00105 
00106 }
00107 
00108 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
00109 JFAAcc::JFAAcc(XList & ndx,Config & config)
00110         :_ms(config),_ss(config){ // constructor
00111         _init(ndx,config);
00112 }
00113 
00114 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
00115 JFAAcc::~JFAAcc(){
00116         _vEvT.deleteAllObjects();
00117         _uEuT.deleteAllObjects();
00118         _vuEvuT.deleteAllObjects();
00119         _l_spk_inv.deleteAllObjects();
00120         _l_sess_inv.deleteAllObjects();
00121         _l_yx_inv.deleteAllObjects();
00122         _Aev.deleteAllObjects();
00123         _Aec.deleteAllObjects();
00124 }
00125 
00126 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
00127 String JFAAcc::getClassName() const{    return "JFAAcc";}
00128 
00129 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
00130 void JFAAcc::_init(XList &ndx, Config &config){
00131 
00133         _fileList=ndx;
00134         _ndxTable=JFATranslate(ndx);
00135 
00137         MixtureGD& UBM = _ms.loadMixtureGD(config.getParam("inputWorldFilename"));
00138 
00139         _vectSize = UBM.getVectSize();
00140         _n_distrib = UBM.getDistribCount();
00141         _svSize = _vectSize*_n_distrib;
00142 
00143         _rankEV=1;
00144         if(config.existsParam("eigenVoiceNumber"))
00145                 _rankEV=config.getParam("eigenVoiceNumber").toULong();
00146         _rankEC=1;
00147         if(config.existsParam("eigenChannelNumber"))
00148                 _rankEC=config.getParam("eigenChannelNumber").toULong();
00149         
00151         _n_speakers=_fileList.getLineCount();
00152         _n_sessions=_fileList.getAllElements().getElementCount();
00153         
00154         _ubm_means.setSize(_svSize);
00155         _ubm_invvar.setSize(_svSize);
00156 
00158         for(unsigned long i=0;i<_n_distrib;i++){
00159                 DistribGD & dis=UBM.getDistrib(i);
00160                 DoubleVector & c=dis.getCovInvVect();
00161                 DoubleVector & m=dis.getMeanVect();
00162                 for(unsigned long j=0;j<_vectSize;j++){
00163                         _ubm_means[i*_vectSize+j]=m[j];
00164                         _ubm_invvar[i*_vectSize+j]=c[j];
00165                 }
00166         }
00167 
00169         _matN= Matrix<double>(_n_speakers, _n_distrib);
00170         _N_h= Matrix<double>(_n_sessions, _n_distrib);
00171         _F_X= Matrix<double>(_n_speakers, _n_distrib*_vectSize);
00172         _F_X_h= Matrix<double>(_n_sessions, _n_distrib*_vectSize);
00173         _matN.setAllValues(0.0);
00174         _N_h.setAllValues(0.0);
00175         _F_X.setAllValues(0.0);
00176         _F_X_h.setAllValues(0.0);
00177         
00179         _cN= Matrix<double>(_n_speakers, _n_distrib);
00180         _cN_h= Matrix<double>(_n_sessions, _n_distrib);
00181         _cF_X= Matrix<double>(_n_speakers, _n_distrib*_vectSize);
00182         _cF_X_h= Matrix<double>(_n_sessions, _n_distrib*_vectSize);
00183         _cN.setAllValues(0.0);
00184         _cN_h.setAllValues(0.0);
00185         _cF_X.setAllValues(0.0);
00186         _cF_X_h.setAllValues(0.0);
00187         
00189         _D.setSize(_svSize);
00190         _D.setAllValues(0.0);
00191         
00192         _V.setDimensions(_rankEV, _svSize);
00193         _V.setAllValues(0.0);
00194         
00195         _matU.setDimensions(_rankEC, _svSize);
00196         _matU.setAllValues(0.0);
00197         
00198         _VU.setDimensions(_rankEV + _rankEC, _svSize);
00199         _VU.setAllValues(0.0);
00200         
00201         _Z.setDimensions(_n_speakers, _svSize);
00202         _Z.setAllValues(0.0);
00203         
00204         _Y.setDimensions(_n_speakers, _rankEV);
00205         _Y.setAllValues(0.0);
00206         
00207         _matX.setDimensions(_n_sessions, _rankEC);
00208         _matX.setAllValues(0.0);
00209         
00210         _YX.setDimensions(_n_speakers, _rankEV + _rankEC);
00211         _YX.setAllValues(0.0);
00212         
00214         for(unsigned long s =0; s<_n_distrib; s++){
00215                 _vEvT.addObject(*new DoubleSquareMatrix(_rankEV));
00216                 _vEvT[s].setAllValues(0.0);
00217         }
00218         for(unsigned long s =0; s<_n_distrib; s++){
00219                 _uEuT.addObject(*new DoubleSquareMatrix(_rankEC));
00220                 _uEuT[s].setAllValues(0.0);
00221         }
00222         for(unsigned long s =0; s<_n_distrib; s++){
00223                 _vuEvuT.addObject(*new DoubleSquareMatrix(_rankEV + _rankEC));
00224                 _vuEvuT[s].setAllValues(0.0);
00225         }
00226 
00228         for(unsigned long spk =0; spk<_n_speakers; spk++){
00229                 _l_spk_inv.addObject(*new DoubleSquareMatrix(_rankEV));
00230                 _l_spk_inv[spk].setAllValues(0.0);
00231         }
00232         
00234         for(unsigned long sess =0; sess<_n_sessions; sess++){
00235                 _l_sess_inv.addObject(*new DoubleSquareMatrix(_rankEC));
00236                 _l_sess_inv[sess].setAllValues(0.0);
00237         }
00238 
00240         for(unsigned long spk =0; spk<_n_speakers; spk++){
00241                 _l_yx_inv.addObject(*new DoubleSquareMatrix(_rankEV + _rankEC));
00242                 _l_yx_inv[spk].setAllValues(0.0);
00243         }
00244         
00246         for(unsigned long spk =0; spk<_n_distrib; spk++){
00247                 _Aev.addObject(*new DoubleSquareMatrix(_rankEV));
00248                 _Aev[spk].setAllValues(0.0);
00249         }
00250         _Cev.setDimensions(_rankEV,_svSize);
00251         _Cev.setAllValues(0.0);
00252 
00254         for(unsigned long spk =0; spk<_n_distrib; spk++){
00255                 _Aec.addObject(*new DoubleSquareMatrix(_rankEC));
00256                 _Aec[spk].setAllValues(0.0);
00257         }
00258         _Cec.setDimensions(_rankEC,_svSize);
00259         _Cec.setAllValues(0.0);
00260         
00261 }
00262 
00263 
00264 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
00265 void JFAAcc::computeAndAccumulateJFAStat(Config& config){
00266         
00267         //STILL TO IMPLEMENT A THREADED VERSION OF THIS FUNCTION
00268         
00269 //      #ifdef THREAD          
00270 //      if (config.existsParam("numThread") && config.getParam("numThread").toLong() >0){
00271 //              computeAndAccumulateJFAStatThreaded(config);                            //accumulate stats
00272 //      }
00273 //      else    computeAndAccumulateJFAStatUnThreaded(config);                  //unthreaded version
00274 //      #else
00275                 computeAndAccumulateJFAStatUnThreaded(config);                  //accumute stats
00276 //      #endif
00277 }
00278 
00279 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
00280 void JFAAcc::computeAndAccumulateJFAStatUnThreaded(Config& config){
00281 
00282         MixtureGD& UBM = _ms.getMixtureGD(0);
00283         MixtureGDStat &acc=_ss.createAndStoreMixtureStat(UBM);
00284 
00286         FeatureServer fs;
00287         XLine allFiles=_fileList.getAllElements();
00288         fs.init(config, allFiles);
00289         
00291         SegServer segmentsServer;
00292         LabelServer labelServer;
00293         initializeClusters(allFiles,segmentsServer,labelServer,config);
00294         
00295         verifyClusterFile(segmentsServer,fs,config);
00296         unsigned long codeSelectedFrame=labelServer.getLabelIndexByString(config.getParam("labelSelectedFrames"));
00297 
00298         SegCluster& selectedSegments=segmentsServer.getCluster(codeSelectedFrame);
00299         acc.resetOcc();
00300         Seg *seg; 
00301         selectedSegments.rewind();
00302 
00304         double *n_h, *n, *f_x_h, *f_x;  
00305         n_h=_N_h.getArray(); n=_matN.getArray(); f_x_h=_F_X_h.getArray();f_x=_F_X.getArray();
00306         
00307         String currentSource="";unsigned long loc=0;unsigned long session=0;
00308         while((seg=selectedSegments.getSeg())!=NULL){
00309 
00310                 unsigned long begin=seg->begin()+fs.getFirstFeatureIndexOfASource(seg->sourceName());                           
00311 
00312                 JFATranslate ndxTable=JFATranslate(_fileList);
00313                 
00314                 if (currentSource!=seg->sourceName()) {
00315                         currentSource=seg->sourceName();
00316                         loc=ndxTable.locNb(currentSource);
00317                         session=ndxTable.sessionNb(currentSource);
00318                         if (verboseLevel >= 1)cout << "Processing file["<<currentSource<<"]"<< endl;    
00319                 }
00320 
00321                 fs.seekFeature(begin);
00322                 Feature f;
00323 
00324                 for (unsigned long idxFrame=0;idxFrame<seg->length();idxFrame++){
00325                         fs.readFeature(f);
00326                         acc.computeAndAccumulateOcc(f);
00327                         DoubleVector aPost=acc.getOccVect();
00328                         double *ff=f.getDataVector();
00329 
00330                         for(unsigned long k=0;k<_n_distrib;k++) {
00331 
00332                                 n_h[session*_n_distrib+k]+=aPost[k];
00333                                 n[loc*_n_distrib+k]   +=aPost[k];
00334 
00335                                 for (unsigned long i=0;i<_vectSize;i++) {
00336                                         f_x_h[session*_svSize+(k*_vectSize+i)]+=aPost[k]*ff[i];
00337                                         f_x[loc*_svSize+(k*_vectSize+i)]   +=aPost[k]*ff[i];
00338                                 }
00339                         }
00340                 }
00341         }       
00342 }
00343 
00344 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
00345 void JFAAcc::computeAndAccumulateJFAStat(FeatureServer &fs,Config & config){
00346         SegServer segmentsServer;
00347         LabelServer labelServer;
00348         initializeClusters(_fileList,segmentsServer,labelServer,config);
00349         verifyClusterFile(segmentsServer,fs,config);
00350         unsigned long codeSelectedFrame=labelServer.getLabelIndexByString(config.getParam("labelSelectedFrames"));
00351         SegCluster& selectedSegments=segmentsServer.getCluster(codeSelectedFrame); 
00352         this->computeAndAccumulateJFAStat(selectedSegments,fs,config);
00353 };
00354 
00355 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
00356 void JFAAcc::computeAndAccumulateJFAStat(SegCluster &selectedSegments,FeatureServer &fs,Config & config){
00357 
00358         MixtureGD& UBM = _ms.getMixtureGD(0);
00359         MixtureGDStat &acc=_ss.createAndStoreMixtureStat(UBM);
00360 
00362         double *n_h, *n, *f_x_h, *f_x;  
00363         n_h=_N_h.getArray(); n=_matN.getArray(); f_x_h=_F_X_h.getArray();f_x=_F_X.getArray();
00364         
00366         Seg *seg; 
00367         selectedSegments.rewind();
00368         
00369         String currentSource="";unsigned long loc=0;unsigned long session=0;
00370         while((seg=selectedSegments.getSeg())!=NULL){
00371 
00372                 unsigned long begin=seg->begin()+fs.getFirstFeatureIndexOfASource(seg->sourceName());                           
00373 
00374                 JFATranslate ndxTable=JFATranslate(_fileList);
00375                 
00376                 if (currentSource!=seg->sourceName()) {
00377                         currentSource=seg->sourceName();
00378                         loc=ndxTable.locNb(currentSource);
00379                         session=ndxTable.sessionNb(currentSource);
00380                         if (verboseLevel >= 1)cout << "Processing file["<<currentSource<<"]"<< endl;    
00381                 }
00382 
00383                 fs.seekFeature(begin);
00384                 Feature f;
00385 
00386                 for (unsigned long idxFrame=0;idxFrame<seg->length();idxFrame++){
00387 
00388                         fs.readFeature(f);
00389                         acc.computeAndAccumulateOcc(f);
00390                         DoubleVector aPost=acc.getOccVect();
00391                         double *ff=f.getDataVector();
00392 
00393                         for(unsigned long k=0;k<_n_distrib;k++) {
00394 
00395                                 n_h[session*_n_distrib+k]+=aPost[k];
00396                                 n[loc*_n_distrib+k]   +=aPost[k];
00397 
00398                                 for (unsigned long i=0;i<_vectSize;i++) {
00399                                         f_x_h[session*_svSize+(k*_vectSize+i)]+=aPost[k]*ff[i];
00400                                         f_x[loc*_svSize+(k*_vectSize+i)]   +=aPost[k]*ff[i];
00401                                 }
00402                         }
00403                 }
00404         }       
00405 }
00406 
00407 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
00408 void JFAAcc::resetAcc(){
00409         _F_X.setAllValues(0.0); 
00410         _F_X_h.setAllValues(0.0);       
00411         _N_h.setAllValues(0.0);
00412         _matN.setAllValues(0.0);        
00413         if (verboseLevel >= 1) cout << "# JFA Accumulators reset" << endl;
00414 }
00415 
00416 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
00417 void JFAAcc::resetTmpAcc(){
00418         
00419         _Cev.setAllValues(0.0);
00420         _Cec.setAllValues(0.0);
00421         
00423         for(unsigned long s =0; s<_n_distrib; s++){
00424                 _vEvT[s].setAllValues(0.0);
00425                 _uEuT[s].setAllValues(0.0);
00426                 
00427                 _Aev[s].setAllValues(0.0);
00428                 _Aec[s].setAllValues(0.0);
00429         }
00430 
00432         for(unsigned long spk =0; spk<_n_speakers; spk++){
00433                 _l_spk_inv[spk].setAllValues(0.0);
00434         }
00435         for(unsigned long session =0; session<_n_speakers; session++){
00436                 _l_sess_inv[session].setAllValues(0.0);
00437         }
00438 }
00439 
00440 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
00441 void JFAAcc::loadEV(const String& evFilename, Config& config){  
00442         String filename = config.getParam("matrixFilesPath") + evFilename +  config.getParam("saveMatrixFilesExtension");
00443         _V.load (filename, config);
00444         _rankEV=_V.rows();
00445 
00446         if(_rankEV != config.getParam("eigenVoiceNumber").toLong()){
00447                 throw Exception("Incorrect dimension of EigenVoice Matrix",__FILE__,__LINE__);
00448         }
00449 
00450         cout << "(AccumulateJFAStat) Init EV matrix from "<< filename <<"  for EigenVoices Matrix: "<<", rank: ["<<_V.rows() << "] sv size: [" << _V.cols() <<"]"<<endl;
00451 }
00452 
00453 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
00454 void JFAAcc::loadEV(Matrix<double> & V, Config& config){
00455         _rankEV=V.rows();
00456         _V=V;
00457 
00458         if(_rankEV != config.getParam("eigenVoiceNumber").toLong()){
00459                 throw Exception("Incorrect dimension of EigenVoice Matrix",__FILE__,__LINE__);
00460         }
00461 
00462 }
00463 
00464 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
00465 void JFAAcc::loadEC(const String& ecFilename, Config& config){  
00466         String filename = config.getParam("matrixFilesPath") + ecFilename +  config.getParam("saveMatrixFilesExtension");
00467         _matU.load (filename, config);
00468         _rankEC=_matU.rows();
00469 
00470         if(_rankEC != config.getParam("eigenChannelNumber").toLong()){
00471                 throw Exception("Incorrect dimension of EigenChannel Matrix",__FILE__,__LINE__);
00472         }
00473 
00474         cout << "(AccumulateJFAStat) Init EC matrix from "<< filename <<"  for EigenChannel Matrix: "<<", rank: ["<<_matU.rows() << "] sv size: [" << _matU.cols() <<"]"<<endl;
00475 }
00476 
00477 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
00478 void JFAAcc::loadEC(Matrix<double> & U, Config& config){
00479         _rankEC=U.rows();
00480         _matU=U;
00481 
00482         if(_rankEC != config.getParam("eigenChannelNumber").toLong()){
00483                 throw Exception("Incorrect dimension of EigenChannel Matrix",__FILE__,__LINE__);
00484         }
00485 }
00486 
00487 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
00488 void JFAAcc::loadD(const String& dFilename, Config& config){    
00489         String filename = config.getParam("matrixFilesPath") + dFilename +  config.getParam("saveMatrixFilesExtension");
00490         
00491         Matrix<double> D(filename, config);
00492         double *d = D.getArray();
00493         
00494         if( (D.rows() != 1) || ( D.cols() != _svSize ) ){
00495                 throw Exception("Incorrect dimension of D Matrix",__FILE__,__LINE__);
00496         }
00497         
00498         else{
00499                 for(unsigned long i=0; i<_svSize; i++){
00500                         _D[i] = d[i];
00501                 }
00502         }
00503         cout << "(AccumulateJFAStat) Init D from "<< filename <<"  for EigenChannel Matrix: "<<endl;
00504 }
00505 
00506 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
00507 void JFAAcc::loadD(DoubleVector & D){
00508         _D=D;
00509 
00510         if(_D.size() != _svSize ){
00511                 throw Exception("Incorrect dimension of D Matrix",__FILE__,__LINE__);
00512         }
00513 }
00514 
00515 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
00516 void JFAAcc::loadN(Config& config){
00517         String filname=config.getParam("matrixFilesPath") + config.getParam("nullOrderStatSpeaker") + config.getParam("loadMatrixFilesExtension");
00518         _matN.load (filname, config);
00519 
00520         if((_matN.rows() != _fileList.getLineCount()) || (_matN.cols() != _n_distrib)){
00521                 throw Exception("Incorrect dimension of N Matrix",__FILE__,__LINE__);
00522         }
00523         cout<<"(AccumulateJFAStat) ---------load statistics N [ "<<_matN.rows()<<" ] [ "<<_matN.cols()<<" ]"<<endl;
00524 }
00525 
00526 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
00527 void JFAAcc::loadN_h(Config& config){
00528         String filname=config.getParam("matrixFilesPath") + config.getParam("nullOrderStatSession") + config.getParam("loadMatrixFilesExtension");
00529         _N_h.load (filname, config);
00530 
00531 
00532         if((_N_h.rows() != _fileList.getAllElements().getElementCount()) || (_N_h.cols() != _n_distrib)){
00533                 throw Exception("Incorrect dimension of N_h Matrix",__FILE__,__LINE__);
00534         }
00535         cout<<"(AccumulateJFAStat) ---------load statistics N_h [ "<<_N_h.rows()<<" ] [ "<<_N_h.cols()<<" ]"<<endl;
00536 }
00537 
00538 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
00539 void JFAAcc::loadF_X(Config& config){
00540         String filname=config.getParam("matrixFilesPath") + config.getParam("firstOrderStatSpeaker") + config.getParam("loadMatrixFilesExtension");
00541         _F_X.load (filname, config);
00542 
00543         if((_F_X.rows() != _fileList.getLineCount()) || (_F_X.cols() != _svSize)){
00544                 throw Exception("Incorrect dimension of F_X Matrix",__FILE__,__LINE__);
00545         }
00546         cout<<"(AccumulateJFAStat) ---------load statistics F_X [ "<<_F_X.rows()<<" ] [ "<<_F_X.cols()<<" ]"<<endl;
00547 }
00548 
00549 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
00550 void JFAAcc::loadF_X_h(Config& config){
00551         String filname=config.getParam("matrixFilesPath") + config.getParam("firstOrderStatSession") + config.getParam("loadMatrixFilesExtension");
00552         _F_X_h.load (filname, config);
00553 
00554         if((_F_X_h.rows() != _fileList.getAllElements().getElementCount()) || (_F_X_h.cols() != _svSize)){
00555                 throw Exception("Incorrect dimension of F_X_h Matrix",__FILE__,__LINE__);
00556         }
00557         cout<<"(AccumulateJFAStat) ---------load statistics F_X_h [ "<<_F_X_h.rows()<<" ] [ "<<_F_X_h.cols()<<" ]"<<endl;
00558 }
00559 
00560 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
00561 void JFAAcc::initEV(Config& config){            
00562                 _rankEV=config.getParam("eigenVoiceNumber").toULong();
00563                 _V.setDimensions(_rankEV,_svSize);
00564 //              srand48(_svSize*_rankEV);
00565 //              _V.randomInit();
00566 
00567                 //Initialise with a normal distribution random process
00568                 double norm=0;
00569                 for(unsigned long k=0; k<_svSize; k++){
00570                         norm += _ubm_invvar[k];
00571                 }
00572 
00573                 boxMullerGeneratorInit();
00574                 for(unsigned long i=0; i<_V.rows(); i++){
00575                         for(unsigned long j=0; j<_V.cols(); j++){
00576                                 double val = boxMullerGenerator(0.0, 1.0);
00577                                 while((ISNAN(val)) || (ISINF(val))){
00578                                         val = boxMullerGenerator(0.0, 1.0);
00579                                 }
00580                                 _V(i,j) = val * norm * 0.001;
00581                         }
00582                 }
00583                 if (verboseLevel >=1) cout << "(AccumulateJFAStat) Random Init for EigenVoices Matrix with Box-Muller method "<<", rank: ["<<_V.rows() << "] sv size: [" << _V.cols() <<"]"<<endl;
00584 }
00585 
00586 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
00587 void JFAAcc::initEC(Config& config){            
00588                 _rankEC=config.getParam("eigenChannelNumber").toULong();
00589                 _matU.setDimensions(_rankEC,_svSize);
00590 //              srand48(_svSize*_rankEC);
00591 //              _matU.randomInit();
00592 
00593                 //Initialise with a normal distribution random process
00594                 double norm=0;
00595                 for(unsigned long k=0; k<_svSize; k++){
00596                         norm += _ubm_invvar[k];
00597                 }
00598 
00599                 boxMullerGeneratorInit();
00600                 for(unsigned long i=0; i<_matU.rows(); i++){
00601                         for(unsigned long j=0; j<_matU.cols(); j++){
00602                                 double val = boxMullerGenerator(0.0, 1.0);
00603                                 while((ISNAN(val)) || (ISINF(val))){
00604                                         val = boxMullerGenerator(0.0, 1.0);
00605                                 }
00606                                 _matU(i,j) = val * norm * 0.001;
00607                         }
00608                 }
00609                 cout << "(AccumulateJFAStat) Random Init for EigenChannel Matrix: "<<", rank: ["<<_matU.rows() << "] sv size: [" << _matU.cols() <<"]"<<endl;
00610 }
00611 
00612 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
00613 void JFAAcc::initD(Config& config){                     
00614                 Matrix<double> D;
00615                 D.setDimensions(1,_svSize);
00616 
00617                 //Initialise with the MAP value
00618                 for(unsigned long i=0; i<_svSize; i++){
00619                         _D[i] = sqrt(1.0/(_ubm_invvar[i]*config.getParam("regulationFactor").toDouble()));
00620                 }
00621 
00622                 cout<< "(AccumulateJFAStat) Random Init for D Matrix:  sv size: [" << _D.size() <<"]"<<endl;
00623 }
00624 
00625 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
00626 void JFAAcc::initVU(){
00627 
00628         _VU.concatCols(_V,_matU);
00629 }
00630 
00631 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
00632 void JFAAcc::saveV(const String& filename, Config& config){
00633         String vName = config.getParam("matrixFilesPath") + filename +  config.getParam("saveMatrixFilesExtension");
00634         _V.save(vName, config);
00635 }
00636 
00637 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
00638 void JFAAcc::saveU(const String& filename, Config& config){
00639         String uName = config.getParam("matrixFilesPath") + filename +  config.getParam("saveMatrixFilesExtension");
00640         _matU.save(uName, config);
00641 }
00642 
00643 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
00644 void JFAAcc::saveD(const String& filename, Config& config){
00645         String dName = config.getParam("matrixFilesPath") + filename +  config.getParam("saveMatrixFilesExtension");
00646         Matrix<double> D;
00647         D.setDimensions(1,_svSize);
00648         for(unsigned long i=0; i<_svSize; i++){
00649                 D(0,i) = _D[i];
00650         }
00651         D.save(dName, config);
00652 }
00653 
00654 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
00655 void JFAAcc::estimateVEVT(Config &config){
00656         
00657         #ifdef THREAD          
00658         if (config.existsParam("numThread") && config.getParam("numThread").toLong() >0)        estimateVEVTThreaded(config.getParam("numThread").toLong());
00659         else estimateVEVTUnThreaded();
00660         #else
00661         estimateVEVTUnThreaded();
00662         #endif
00663 }
00664 
00665 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
00666 void JFAAcc::estimateVEVTUnThreaded(){  
00667         if (verboseLevel >= 1) cout << "(AccumulateJFAStat) compute V * Sigma-1 * V "<<endl;
00668 
00669         for(unsigned long d=0; d<_n_distrib; d++){
00670 
00671                 Matrix<double>ssV= _V.crop(0,d*_vectSize, _rankEV,_vectSize);
00672 
00674                 double *vEvT, *v, *E;
00675                 vEvT= _vEvT[d].getArray();
00676                 v= ssV.getArray();
00677                 E= _ubm_invvar.getArray();
00678 
00679                 for(unsigned long i = 0; i<_rankEV; i++){
00680                         for(unsigned long j = 0; j<=i; j++){
00681                                 for(unsigned long k=0; k<_vectSize;k++){
00682                                         vEvT[i*_rankEV+j] += v[i*_vectSize+k] * E[d*_vectSize+k] * v[j*_vectSize+k];
00683                                 }
00684                         }
00685                 }
00686                 
00687                 for(unsigned long i=0;i<_rankEV;i++){
00688                 for(unsigned long j=i+1;j<_rankEV;j++) {
00689                                 vEvT[i*_rankEV+j] = vEvT[j*_rankEV+i];
00690                         }
00691                 }
00692         }
00693 }
00694 
00695 #ifdef THREAD
00696 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
00697 //                              Data strucutre of thread
00698 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
00699 struct VEVthread_data{
00700 
00701         double *V;
00702         double *ubm_invvar;
00703         unsigned long disBottom;
00704         unsigned long disUp;    
00705         unsigned long rankEV;
00706         unsigned long svSize;
00707         unsigned long vectSize;
00708         RefVector <DoubleSquareMatrix>* vevT;
00709 };
00710 
00711 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
00712 //                              Thread Routine
00713 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
00714 void *VEVthread(void *threadarg) {
00715         struct VEVthread_data *my_data;
00716         my_data = (struct VEVthread_data *) threadarg;
00717         
00718         double *v = my_data->V;
00719         unsigned long disBottom = my_data->disBottom;   
00720         unsigned long disUp = my_data->disUp;
00721         double *E=my_data->ubm_invvar;
00722         unsigned long _rankEV=my_data->rankEV;
00723         unsigned long _svSize=my_data->svSize;
00724         unsigned long _vectSize=my_data->vectSize;
00725 
00726         for (unsigned long d=disBottom;d <disUp;d++){
00727                 
00728                 DoubleSquareMatrix &vEvT=(*(my_data->vevT))[d];
00729                 vEvT.setAllValues(0.0);
00730                 double *vevt = vEvT.getArray();
00731                 
00732                 for(unsigned long i = 0; i<_rankEV; i++){
00733                         for(unsigned long j = 0; j<=i; j++){
00734                                 for(unsigned long k=0; k<_vectSize;k++){
00735                                         vevt[i*_rankEV+j] += v[(i*_svSize)+(d*_vectSize)+k] * E[d*_vectSize+k] * v[(j*_svSize)+(d*_vectSize)+k];
00736                                 }
00737                         }
00738                 }       
00739 
00740                 for(unsigned long i=0;i<_rankEV;i++){
00741                         for(unsigned long j=i+1;j<_rankEV;j++) {
00742                                 vevt[i*_rankEV+j]=vevt[j*_rankEV+i];
00743                         }
00744                 }
00745         }
00746         pthread_exit((void*) 0);
00747         return (void*)0 ;
00748 }
00749 
00750 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
00751 void JFAAcc::estimateVEVTThreaded(unsigned long NUM_THREADS){
00752         
00753         if (verboseLevel >=1) cout << "(AccumulateJFAStat) Compute vEvT Threaded"<<endl;
00754         if (NUM_THREADS==0) throw Exception("Num threads can not be 0",__FILE__,__LINE__);
00755         
00756         double *V=_V.getArray();
00757         double *ubm_invvar=_ubm_invvar.getArray();
00758         
00759         int rc, status;
00760         if (NUM_THREADS > _n_distrib) NUM_THREADS=_n_distrib;
00761         
00762         struct VEVthread_data *thread_data_array = new VEVthread_data[NUM_THREADS];
00763         pthread_t *threads = new pthread_t[NUM_THREADS];
00764 
00765         pthread_attr_t attr;
00766         pthread_attr_init(&attr);
00767         pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
00768         unsigned long offset=_n_distrib/NUM_THREADS;
00769         
00770         unsigned long disBottom = 0;
00771         unsigned long disUp=0;
00772         unsigned long re=_n_distrib - NUM_THREADS*offset;
00773         
00774         //Create threads : one per distribution as a maximum
00775         for(unsigned long t=0; t<NUM_THREADS; t++){
00776         
00777                 disUp = disBottom +offset;
00778                 if(t<re) disUp +=1;
00779 
00780                 thread_data_array[t].V=V;
00781                 thread_data_array[t].ubm_invvar=ubm_invvar;
00782                 thread_data_array[t].disBottom=disBottom;
00783                 thread_data_array[t].disUp=disUp;
00784                 thread_data_array[t].rankEV=_rankEV;
00785                 thread_data_array[t].svSize=_svSize;
00786                 thread_data_array[t].vectSize=_vectSize;
00787                 thread_data_array[t].vevT=&(_vEvT);
00788 
00789                 if (verboseLevel > 1) cout<<"(AccumulateJFAStat) Creating thread n["<< t<< "] for distributions["<<disBottom<<"-->"<<disUp<<"]"<<endl;
00790                 rc = pthread_create(&threads[t], &attr, VEVthread, (void *)&thread_data_array[t]);
00791                 if (rc) throw Exception("ERROR; return code from pthread_create() is ",__FILE__,rc);
00792                 
00793                 disBottom = disUp;
00794         }
00795         
00796         pthread_attr_destroy(&attr);
00797         for(unsigned long t=0; t<NUM_THREADS; t++) {
00798                 rc = pthread_join(threads[t], (void **)&status);
00799                 if (rc)  throw Exception("ERROR; return code from pthread_join() is ",__FILE__,rc);
00800                 if (verboseLevel >1) cout <<"(AccumulateJFAStat) Completed join with thread ["<<t<<"] status["<<status<<"]"<<endl;
00801         }
00802 
00803         free(thread_data_array);
00804         free(threads);
00805 
00806         if (verboseLevel >= 1) cout << "(AccumulateJFAStat) Done " << endl;
00807 }
00808 #endif
00809 
00810 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
00811 void JFAAcc::estimateUEUT(Config &config){
00812         #ifdef THREAD          
00813         if (config.existsParam("numThread") && config.getParam("numThread").toLong() >0)        estimateUEUTThreaded(config.getParam("numThread").toLong());
00814         else estimateUEUTUnThreaded();
00815         #else
00816         estimateUEUTUnThreaded();
00817         #endif
00818 }
00819 
00820 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
00821 void JFAAcc::estimateUEUTUnThreaded(){  
00822         if (verboseLevel >= 1) cout << "(AccumulateJFAStat) compute U * Sigma-1 * U "<<endl;
00823 
00824         for(unsigned long d=0; d<_n_distrib; d++){
00825 
00826                 Matrix<double>ssU= _matU.crop(0,d*_vectSize, _rankEC,_vectSize);
00827 
00829                 double *uEuT, *u, *E;
00830                 uEuT= _uEuT[d].getArray();
00831                 u= ssU.getArray();
00832                 E= _ubm_invvar.getArray();
00833                 
00834                 for(unsigned long i = 0; i<_rankEC; i++){
00835                         for(unsigned long j = 0; j<=i; j++){
00836                                 for(unsigned long k=0; k<_vectSize;k++){
00837                                         uEuT[i*_rankEC+j] += u[i*_vectSize+k] * E[d*_vectSize+k] * u[j*_vectSize+k];
00838                                 }
00839                         }
00840                 }
00841                 for(unsigned long i=0;i<_rankEC;i++){
00842                         for(unsigned long j=i+1;j<_rankEC;j++) {
00843                                 uEuT[i*_rankEC+j] = uEuT[j*_rankEC+i];
00844                         }
00845                 }
00846         }
00847 }
00848 
00849 #ifdef THREAD
00850 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
00851 //                              Data strucutre of thread
00852 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
00853 struct UEUthread_data{
00854 
00855         double *U;
00856         double *ubm_invvar;
00857         unsigned long disBottom;
00858         unsigned long disUp;    
00859         unsigned long rankEC;
00860         unsigned long svSize;
00861         unsigned long vectSize;
00862         RefVector <DoubleSquareMatrix>* ueuT;
00863         unsigned long nT;
00864 };
00865 
00866 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
00867 //                              Thread Routine
00868 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
00869 void *UEUthread(void *threadarg) {
00870         struct UEUthread_data *my_data;
00871         my_data = (struct UEUthread_data *) threadarg;
00872         
00873         double *u = my_data->U;
00874         unsigned long disBottom = my_data->disBottom;   
00875         unsigned long disUp = my_data->disUp;
00876         double *E=my_data->ubm_invvar;
00877         unsigned long _rankEC=my_data->rankEC;
00878         unsigned long _svSize=my_data->svSize;
00879         unsigned long _vectSize=my_data->vectSize;
00880 
00881         for (unsigned long d=disBottom;d <disUp;d++){
00882                 
00883                 DoubleSquareMatrix &uEuT=(*(my_data->ueuT))[d];
00884                 uEuT.setAllValues(0.0);
00885                 double *ueut = uEuT.getArray();
00886                 
00887                 for(unsigned long i = 0; i<_rankEC; i++){
00888                         for(unsigned long j = 0; j<=i; j++){
00889                                 for(unsigned long k=0; k<_vectSize;k++){
00890                                         ueut[i*_rankEC+j] += u[(i*_svSize)+(d*_vectSize)+k] * E[d*_vectSize+k] * u[(j*_svSize)+(d*_vectSize)+k];
00891                                 }
00892                         }
00893                 }
00894                 for(unsigned long i=0;i<_rankEC;i++){
00895                         for(unsigned long j=i+1;j<_rankEC;j++) {
00896                                 ueut[i*_rankEC+j] = ueut[j*_rankEC+i];
00897                         }
00898                 }
00899         }
00900         pthread_exit((void*) 0);
00901         return (void*)0 ;
00902 }
00903 
00904 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
00905 void JFAAcc::estimateUEUTThreaded(unsigned long NUM_THREADS){
00906         
00907         if (verboseLevel >=1) cout << "(AccumulateJFAStat) Compute uEuT Threaded"<<endl;
00908         if (NUM_THREADS==0) throw Exception("Num threads can not be 0",__FILE__,__LINE__);
00909         
00910         double *U=_matU.getArray();
00911         double *ubm_invvar=_ubm_invvar.getArray();
00912         
00913         int rc, status;
00914         if (NUM_THREADS > _n_distrib) NUM_THREADS=_n_distrib;
00915         
00916         //struct UEUthread_data thread_data_array[NUM_THREADS];
00917         struct UEUthread_data *thread_data_array = new UEUthread_data[NUM_THREADS];
00918 
00919         //pthread_t threads[NUM_THREADS];
00920          pthread_t *threads = new pthread_t[NUM_THREADS];
00921 
00922         pthread_attr_t attr;
00923         pthread_attr_init(&attr);
00924         pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
00925         unsigned long offset=_n_distrib/NUM_THREADS;
00926         
00927         unsigned long disBottom = 0;
00928         unsigned long disUp=0;
00929         unsigned long re=_n_distrib - NUM_THREADS*offset;
00930 
00931         //Create threads
00932         for(unsigned long t=0; t<NUM_THREADS; t++){
00933         
00934                 disUp = disBottom +offset;
00935                 if(t<re) disUp +=1;
00936                 
00937                 thread_data_array[t].U=U;
00938                 thread_data_array[t].ubm_invvar=ubm_invvar;
00939                 thread_data_array[t].disBottom=disBottom;
00940                 thread_data_array[t].disUp=disUp;
00941                 thread_data_array[t].rankEC=_rankEC;
00942                 thread_data_array[t].svSize=_svSize;
00943                 thread_data_array[t].vectSize=_vectSize;
00944                 thread_data_array[t].ueuT=&(_uEuT);
00945                 thread_data_array[t].nT=t;
00946 
00947                 if (verboseLevel >1) cout<<"(AccumulateJFAStat) Creating thread n["<< t<< "] for distributions["<<disBottom<<"-->"<<disUp<<"]"<<endl;
00948                 rc = pthread_create(&threads[t], &attr, UEUthread, (void *)&thread_data_array[t]);
00949                 if (rc) throw Exception("ERROR; return code from pthread_create() is ",__FILE__,rc);
00950                 
00951                 disBottom = disUp;
00952         }
00953         
00954         pthread_attr_destroy(&attr);
00955         for(unsigned long t=0; t<NUM_THREADS; t++) {
00956                 rc = pthread_join(threads[t], (void **)&status);
00957                 if (rc)  throw Exception("ERROR; return code from pthread_join() is ",__FILE__,rc);
00958                 if (verboseLevel >1) cout <<"(AccumulateJFAStat) Completed join with thread ["<<t<<"] status["<<status<<"]"<<endl;
00959         }
00960 
00961         free(thread_data_array);
00962         free(threads);
00963 
00964         if (verboseLevel >= 1) cout << "(AccumulateJFAStat) Done " << endl;
00965 }
00966 #endif
00967 
00968 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
00969 void JFAAcc::estimateVUEVUT(Config &config){
00970         
00971         #ifdef THREAD          
00972         if (config.existsParam("numThread") && config.getParam("numThread").toLong() >0)        estimateVUEVUTThreaded(config.getParam("numThread").toLong());
00973         else estimateVUEVUTUnThreaded();
00974         #else
00975         estimateVUEVUTUnThreaded();
00976         #endif
00977 }
00978 
00979 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
00980 void JFAAcc::estimateVUEVUTUnThreaded(){        
00981         if (verboseLevel >= 1) cout << "(AccumulateJFAStat) compute VU * Sigma-1 * VU "<<endl;
00982 
00983         for(unsigned long d=0; d<_n_distrib; d++){
00984 
00985                 Matrix<double>ssVU= _VU.crop(0,d*_vectSize, _rankEV + _rankEC,_vectSize);
00986 
00988                 double *vuEvuT, *vu, *E;
00989                 vuEvuT= _vuEvuT[d].getArray();
00990                 vu= ssVU.getArray();
00991                 E= _ubm_invvar.getArray();
00992 
00993                 for(unsigned long i = 0; i<_rankEV + _rankEC; i++){
00994                         for(unsigned long j = 0; j<=i; j++){
00995                                 for(unsigned long k=0; k<_vectSize;k++)
00996                                         vuEvuT[i*(_rankEV + _rankEC)+j] += vu[i*_vectSize+k] * E[d*_vectSize+k] * vu[j*_vectSize+k];
00997                         }
00998                 }
00999                 for(unsigned long i=0;i<_rankEV + _rankEC;i++){
01000                         for(unsigned long j=i+1;j<_rankEV + _rankEC;j++) {
01001                                 vuEvuT[i*(_rankEV + _rankEC)+j] = vuEvuT[j*(_rankEV + _rankEC)+i];
01002                         }
01003                 }
01004         }
01005 }
01006 
01007 #ifdef THREAD
01008 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
01009 //                              Data strucutre of thread
01010 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
01011 struct VUEVUthread_data{
01012 
01013         double *VU;
01014         double *ubm_invvar;
01015         unsigned long disBottom;
01016         unsigned long disUp;    
01017         unsigned long rankECV;
01018         unsigned long svSize;
01019         unsigned long vectSize;
01020         RefVector <DoubleSquareMatrix>* vuevuT;
01021 };
01022 
01023 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
01024 //                              Thread Routine
01025 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
01026 void *VUEVUthread(void *threadarg) {
01027         struct VUEVUthread_data *my_data;
01028         my_data = (struct VUEVUthread_data *) threadarg;
01029         
01030         double *vu = my_data->VU;
01031         unsigned long disBottom = my_data->disBottom;   
01032         unsigned long disUp = my_data->disUp;
01033         double *E=my_data->ubm_invvar;
01034         unsigned long _rankECV=my_data->rankECV;
01035         unsigned long _svSize=my_data->svSize;
01036         unsigned long _vectSize=my_data->vectSize;
01037 
01038         for (unsigned long d=disBottom;d <disUp;d++){
01039                 
01040                 DoubleSquareMatrix &vuEvuT=(*(my_data->vuevuT))[d];
01041                 vuEvuT.setAllValues(0.0);
01042                 double *vuevut = vuEvuT.getArray();
01043 
01044                 for(unsigned long i = 0; i<_rankECV; i++){
01045                         for(unsigned long j = 0; j<=i; j++){
01046                                 for(unsigned long k=0; k<_vectSize;k++){
01047                                         vuevut[i*_rankECV+j] += vu[(i*_svSize)+(d*_vectSize)+k] * E[d*_vectSize+k] * vu[(j*_svSize)+(d*_vectSize)+k];
01048                                 }
01049                         }
01050                 }
01051                 for(unsigned long i=0;i<_rankECV;i++){
01052                         for(unsigned long j=i+1;j<_rankECV;j++) {
01053                                 vuevut[i*_rankECV+j]=vuevut[j*_rankECV+i];
01054                         }
01055                 }
01056 
01057         }
01058         pthread_exit((void*) 0);
01059         return (void*)0 ;
01060 }
01061 
01062 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
01063 void JFAAcc::estimateVUEVUTThreaded(unsigned long NUM_THREADS){
01064         
01065         if (verboseLevel >=1) cout << "(AccumulateJFAStat) Compute vuEvuT Threaded"<<endl;
01066         if (NUM_THREADS==0) throw Exception("Num threads can not be 0",__FILE__,__LINE__);
01067         
01068         double *VU=_VU.getArray();
01069         double *ubm_invvar=_ubm_invvar.getArray();
01070         
01071         int rc, status;
01072         if (NUM_THREADS > _n_distrib) NUM_THREADS=_n_distrib;
01073         
01074         struct VUEVUthread_data *thread_data_array = new VUEVUthread_data[NUM_THREADS];
01075         pthread_t *threads = new pthread_t[NUM_THREADS];
01076 
01077         pthread_attr_t attr;
01078         pthread_attr_init(&attr);
01079         pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
01080         unsigned long offset=_n_distrib/NUM_THREADS;
01081         
01082         unsigned long disBottom = 0;
01083         unsigned long disUp=0;
01084         unsigned long re=_n_distrib - NUM_THREADS*offset;
01085 
01086         //Create threads
01087         for(unsigned long t=0; t<NUM_THREADS; t++){
01088         
01089                 disUp = disBottom +offset;
01090                 if(t<re) disUp +=1;
01091                 
01092                 thread_data_array[t].VU=VU;
01093                 thread_data_array[t].ubm_invvar=ubm_invvar;
01094                 thread_data_array[t].disBottom=disBottom;
01095                 thread_data_array[t].disUp=disUp;
01096                 thread_data_array[t].rankECV=_rankEC+_rankEV;
01097                 thread_data_array[t].svSize=_svSize;
01098                 thread_data_array[t].vectSize=_vectSize;
01099                 thread_data_array[t].vuevuT=&(_vuEvuT);
01100 
01101                 if (verboseLevel >1) cout<<"(AccumulateJFAStat) Creating thread n["<< t<< "] for distributions["<<disBottom<<"-->"<<disUp<<"]"<<endl;
01102                 rc = pthread_create(&threads[t], &attr, VUEVUthread, (void *)&thread_data_array[t]);
01103                 if (rc) throw Exception("ERROR; return code from pthread_create() is ",__FILE__,rc);
01104                 
01105                 disBottom = disUp;
01106         }
01107         
01108         pthread_attr_destroy(&attr);
01109         for(unsigned long t=0; t<NUM_THREADS; t++) {
01110                 rc = pthread_join(threads[t], (void **)&status);
01111                 if (rc)  throw Exception("ERROR; return code from pthread_join() is ",__FILE__,rc);
01112                 if (verboseLevel >1) cout <<"(AccumulateJFAStat) Completed join with thread ["<<t<<"] status["<<status<<"]"<<endl;
01113         }
01114 
01115         free(thread_data_array);
01116         free(threads);
01117 
01118         if (verboseLevel >= 1) cout << "(AccumulateJFAStat) Done " << endl;
01119 }
01120 #endif
01121 
01122 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
01123 void  JFAAcc::getVY(DoubleVector &vy, String &file){            
01124         vy.setAllValues(0.0);   
01125         
01126         double *v, *y; y=_Y.getArray(); v=_V.getArray();
01127 
01128         unsigned long idx=_ndxTable.locNb(file);
01129         for (unsigned long i=0;i<_svSize;i++){
01130                 for (unsigned long j=0;j<_rankEV;j++){
01131                         vy[i] += v[j*_svSize + i] * y[idx*_rankEV + j ];
01132                 }
01133         }       
01134 }
01135 
01136 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
01137 void  JFAAcc::getVY(DoubleVector &vy, unsigned long spk) {              
01138         vy.setAllValues(0.0);
01139         
01140         double *v, *y; y=_Y.getArray(); v=_V.getArray();
01141         for (unsigned long i=0;i<_svSize;i++){
01142                 for (unsigned long j=0;j<_rankEV;j++){
01143                         vy[i] += v[j*_svSize + i] * y[spk*_rankEV + j ];
01144                 }
01145         }
01146 }
01147 
01148 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
01149 void  JFAAcc::getVUYX(DoubleVector &vuyx, String &file){
01150         vuyx.setAllValues(0.0);
01151         
01152         double *vu, *yx; vu=_VU.getArray(); yx=_YX.getArray();
01153         
01154         unsigned long idx=_ndxTable.locNb(file);
01155         for (unsigned long i=0;i<_svSize;i++){
01156                 for (unsigned long j=0;j<_rankEC + _rankEV;j++) {
01157                         vuyx[i] += vu[j*_svSize + i] * yx[idx*(_rankEC + _rankEV)+j];
01158                 }
01159         }
01160 }
01161 
01162 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
01163 void  JFAAcc::getVUYX(DoubleVector &vuyx, unsigned long spk) {
01164         vuyx.setAllValues(0.0);
01165         
01166         double *vu, *yx; vu=_VU.getArray(); yx=_YX.getArray();
01167         
01168         for (unsigned long i=0;i<_svSize;i++){
01169                 for (unsigned long j=0;j<_rankEC + _rankEV;j++){
01170                         vuyx[i] += vu[j*_svSize + i] * yx[spk*(_rankEC + _rankEV)+j];
01171                 }
01172         }
01173 }
01174 
01175 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
01176 void  JFAAcc::getDZ(DoubleVector &dz, unsigned long spk) {      
01177         dz.setAllValues(0.0);   
01178         double *z=_Z.getArray();
01179         for (unsigned long i=0;i<_svSize;i++){
01180                 dz[i] = _D[i] * z[spk*_svSize +i];
01181         }
01182 };
01183 
01184 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
01185 void  JFAAcc::getUX(DoubleVector &ux, unsigned long ses) {              
01186         ux.setAllValues(0.0);
01187 
01188         ux.setAllValues(0.0);
01189         double *u, *x;
01190         u=_matU.getArray(); x=_matX.getArray();
01191 
01192         for (unsigned long i=0;i<_svSize;i++){
01193                 for (unsigned long j=0;j<_rankEC;j++){
01194                         ux[i] = _matU(j,i)*_matX(ses,j);
01195                 }
01196         }
01197 }
01198 
01199 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
01200 void JFAAcc::getUX(DoubleVector &ux, String& file){
01201         
01202         ux.setAllValues(0.0);   
01203         double *u, *x;
01204         u=_matU.getArray(); x=_matX.getArray();
01205 
01206         unsigned long idx=_ndxTable.sessionNb(file);
01207         
01208         for (unsigned long i=0;i<_svSize;i++){
01209                 for (unsigned long j=0;j<_rankEC;j++) {
01210                         ux[i]+=_matU(j,i)*_matX(idx,j);
01211                 }
01212         }
01213 }
01214 
01215 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
01216 void JFAAcc::getVYplusDZ(DoubleVector & VYplusDZ, String & file){
01217         VYplusDZ.setAllValues(0.0);
01218         DoubleVector VY(_svSize,_svSize);
01219         getVY(VY,file);
01220         
01221         double *vy, *vyplusdz, *z;
01222         vy=VY.getArray(); vyplusdz=VYplusDZ.getArray(); z=_Z.getArray();
01223         
01224         unsigned long spk=_ndxTable.locNb(file);                
01225         for (unsigned long i=0;i<_svSize;i++){
01226                 vyplusdz[i] = vy[i] + _D[i] * z[spk*_svSize+i];
01227         }
01228 }
01229 
01230 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
01231 void JFAAcc::getVYplusDZ(DoubleVector &VYplusDZ, unsigned long spk){
01232         VYplusDZ.setAllValues(0.0);
01233         DoubleVector VY(_svSize,_svSize);
01234         getVY(VY,spk);
01235         
01236         double *vy, *vyplusdz, *z;
01237         vy=VY.getArray(); vyplusdz=VYplusDZ.getArray(); z=_Z.getArray();
01238         
01239         for (unsigned long i=0;i<_svSize;i++){
01240                 vyplusdz[i] = vy[i] + _D[i] * z[spk*_svSize+i];
01241         }
01242 }
01243 
01244 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
01245 // Compute supervector of client M_s_h=M+DZ_s
01246 void JFAAcc::getMplusDZ(DoubleVector &Sp, String& file){
01247         Sp.setAllValues(0.0);
01248         
01249         unsigned long spk=_ndxTable.locNb(file);                
01250         for (unsigned long i=0;i<_svSize;i++)
01251                 Sp[i]=_ubm_means[i]+_D[i]*_Z(spk,i);
01252         
01253 }
01254 
01255 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
01256 // Compute supervector of client M_s_h=M+DZ_s
01257 void JFAAcc::getMplusDZ(DoubleVector &Sp, unsigned long spk){
01258         Sp.setAllValues(0.0);
01259         
01260         for (unsigned long i=0;i<_svSize;i++)
01261                 Sp[i]=_ubm_means[i]+_D[i]*_Z(spk,i);
01262 }
01263 
01264 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
01265 // Compute supervector of client M_s_h=M+ VY_s
01266 void JFAAcc::getMplusVY(DoubleVector &Sp, String& file){
01267         Sp.setAllValues(0.0);
01268         DoubleVector vy(_svSize,_svSize);
01269         getVY(vy,file);         
01270         for (unsigned long i=0;i<_svSize;i++){
01271                 Sp[i] = _ubm_means[i] + vy[i];
01272         }
01273 }
01274 
01275 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
01276 // Compute supervector of client M_s_h=M+ VY_s
01277 void JFAAcc::getMplusVY(DoubleVector &Sp, unsigned long spk){
01278         Sp.setAllValues(0.0);
01279         DoubleVector vy(_svSize,_svSize);
01280         getVY(vy,spk);
01281         for (unsigned long i=0;i<_svSize;i++){
01282                 Sp[i]=_ubm_means[i] + vy[i];
01283         }
01284 }
01285 
01286 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
01287 // Compute supervector of client M_s_h=M+ UX
01288 void JFAAcc::getMplusUX(DoubleVector &Sp, String& file){
01289         Sp.setAllValues(0.0);
01290         DoubleVector ux(_svSize,_svSize);
01291         getUX(ux,file);         
01292         for (unsigned long i=0;i<_svSize;i++){
01293                 Sp[i] = _ubm_means[i] + ux[i];
01294         }
01295 }
01296 
01297 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
01298 // Compute supervector of client M_s_h=M+ UX
01299 void JFAAcc::getMplusUX(DoubleVector &Sp, unsigned long session){
01300         Sp.setAllValues(0.0);
01301         DoubleVector ux(_svSize,_svSize);
01302         getUX(ux,session);
01303         for (unsigned long i=0;i<_svSize;i++){
01304                 Sp[i]=_ubm_means[i] + ux[i];
01305         }
01306 }
01307 
01308 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
01309 // Compute supervector of client M_s_h=M+ VY_s + DZ_s
01310 void JFAAcc::getMplusVYplusDZ(DoubleVector &Sp, String& file){
01311         Sp.setAllValues(0.0);
01312         
01313         DoubleVector vy(_svSize,_svSize);
01314         getVY(vy,file); 
01315         unsigned long spk=_ndxTable.locNb(file);                
01316         for (unsigned long i=0;i<_svSize;i++){
01317                 Sp[i] = _ubm_means[i] + vy[i] +_D[i]*_Z(spk,i);
01318         }
01319 }
01320 
01321 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
01322 // Compute supervector of client M_s_h=M+ VY_s + DZ_s
01323 void JFAAcc::getMplusVYplusDZ(DoubleVector &Sp, unsigned long spk){
01324         Sp.setAllValues(0.0);
01325         DoubleVector vy(_svSize,_svSize);
01326 
01327         getVY(vy,spk);
01328         for (unsigned long i=0;i<_svSize;i++){
01329                 Sp[i]=_ubm_means[i] + vy[i] +_D[i]*_Z(spk,i);
01330         }
01331 }
01332 
01333 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
01334 // Compute supervector of client M_s_h=M+ VUY_sX
01335 void JFAAcc::getMplusVUYX(DoubleVector &Sp, String& file){
01336         Sp.setAllValues(0.0);
01337         DoubleVector vuyx(_svSize,_svSize);
01338         getVUYX(vuyx,file);             
01339         for (unsigned long i=0;i<_svSize;i++){
01340                 Sp[i] = _ubm_means[i] + vuyx[i];
01341         }
01342 }
01343 
01344 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
01345 // Compute supervector of client M_s_h=M+ VUY_sX
01346 void JFAAcc::getMplusVUYX(DoubleVector &Sp, unsigned long spk){
01347         Sp.setAllValues(0.0);
01348         DoubleVector vuyx(_svSize,_svSize);
01349         this->getVUYX(vuyx,spk);
01350         
01351         for (unsigned long i=0;i<_svSize;i++){
01352                 Sp[i]=_ubm_means[i] + vuyx[i];
01353         }
01354 }
01355 
01356 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
01357 void JFAAcc::estimateAndInverseL_EV(Config& config){
01358         
01359         #ifdef THREAD          
01360         if (config.existsParam("numThread") && config.getParam("numThread").toLong() >0)        estimateAndInverseLThreaded_EV(config.getParam("numThread").toLong());
01361         else estimateAndInverseLUnThreaded_EV();
01362         #else
01363         estimateAndInverseLUnThreaded_EV();
01364         #endif
01365 }
01366 
01367 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
01368 void JFAAcc::estimateAndInverseLUnThreaded_EV(){
01369         
01370         if (verboseLevel >= 1) cout << "(AccumulateJFAStat) Compute and Inverse L Matrix for EigenVoices "<<endl;
01371         
01372         DoubleSquareMatrix L(_rankEV);
01373 
01374         for(unsigned long spk=0; spk<_n_speakers; spk++){       
01375                 L.setAllValues(0.0);
01376                 for(unsigned long i=0; i<_rankEV; i++){ L(i,i)=1.0;}
01377                 
01378                 double *l, *n;
01379                 l=L.getArray();  n=_matN.getArray();
01380 
01381                 for(unsigned long dis=0; dis<_n_distrib;dis++){
01382                         double *vevt=_vEvT[dis].getArray();
01383                         for(unsigned long i=0; i<_rankEV; i++){
01384                                 for(unsigned long j=0; j<=i; j++){
01385                                         l[i*_rankEV+j] =+ l[i*_rankEV+j] + vevt[i*_rankEV+j]*n[spk*_n_distrib+dis];
01386                                 }
01387                         }
01388                 }
01389                 //As L is symetric, copy the second half of coefficients
01390                 for(unsigned long i=0;i<_rankEV;i++){
01391                         for(unsigned long j=i+1;j<_rankEV;j++) {
01392                                 l[i*_rankEV+j] = l[j*_rankEV+i];
01393                         }
01394                 }
01395                 
01396                 //Inverse L and stock it in _l_spk_inv[spk]
01397                 L.invert(_l_spk_inv[spk]);
01398         }
01399 }
01400 
01401 #ifdef THREAD
01402 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
01403 //                              Data strucutre of thread
01404 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
01405 struct LVthread_data{
01406 
01407         double *N;
01408         unsigned long spkBottom;
01409         unsigned long spkUp;    
01410         unsigned long rankEV;
01411         unsigned long n_distrib;
01412         unsigned long nt;
01413         RefVector <DoubleSquareMatrix>* vevT;
01414         RefVector <DoubleSquareMatrix>* linv;
01415 };
01416 
01417 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
01418 //                              Thread Routine
01419 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
01420 void *LVthread(void *threadarg) {
01421         struct LVthread_data *my_data;
01422         my_data = (struct LVthread_data *) threadarg;
01423 
01424         double *n = my_data->N;
01425         unsigned long spkBottom = my_data->spkBottom;   
01426         unsigned long spkUp = my_data->spkUp;
01427         unsigned long _rankEV=my_data->rankEV;
01428         unsigned long _n_distrib=my_data->n_distrib;
01429 
01430         for(unsigned long spk=spkBottom; spk<spkUp; spk++){
01431         
01432                 DoubleSquareMatrix L(_rankEV);  
01433                 L.setAllValues(0.0);    
01434                 double *l=L.getArray();
01435                 for(unsigned long i=0; i<_rankEV; i++){ l[i*_rankEV+i]=1.0;}
01436 
01437                 for(unsigned long d=0; d<_n_distrib;d++){
01438                         DoubleSquareMatrix &vEvT=(*(my_data->vevT))[d];
01439                         double *vevt = vEvT.getArray();
01440                         for(unsigned long i=0; i<_rankEV; i++){
01441                                 for(unsigned long j=0; j<=i; j++){
01442                                         l[i*_rankEV+j] =+ l[i*_rankEV+j] + vevt[i*_rankEV+j]*n[spk*_n_distrib+d];
01443                                 }
01444                         }
01445                         
01446                 }
01447                 //As L is symetric, copy the second half of coefficients
01448                 for(unsigned long i=0;i<_rankEV;i++){
01449                         for(unsigned long j=i+1;j<_rankEV;j++) {
01450                                 l[i*_rankEV+j] = l[j*_rankEV+i];
01451                         }
01452                 }
01453 
01454                 DoubleSquareMatrix &linv=(*(my_data->linv))[spk];               
01455                 //Inverse L and stock it in _l_spk_inv[spk]
01456                 L.invert(linv);
01457         }
01458         pthread_exit((void*) 0);
01459         return (void*)0 ;
01460 }
01461 
01462 
01463 
01464 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
01465 void JFAAcc::estimateAndInverseLThreaded_EV(unsigned long NUM_THREADS){
01466         
01467         if (verboseLevel >= 1) cout << "(AccumulateJFAStat) Compute and Inverse L Matrix for EigenVoices Threaded"<<endl;
01468         if (NUM_THREADS==0) throw Exception("Num threads can not be 0",__FILE__,__LINE__);
01469 
01470         int rc, status;
01471         if (NUM_THREADS > _n_speakers) NUM_THREADS=_n_speakers;
01472 
01473         struct LVthread_data *thread_data_array = new LVthread_data[NUM_THREADS];
01474         pthread_t *threads = new pthread_t[NUM_THREADS];
01475 
01476         pthread_attr_t attr;
01477         pthread_attr_init(&attr);
01478         pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
01479         unsigned long offset=_n_speakers/NUM_THREADS;
01480         
01481         double *N=_matN.getArray(); 
01482         
01483         unsigned long spkBottom = 0;
01484         unsigned long spkUp=0;
01485         unsigned long re=_n_speakers - NUM_THREADS*offset;
01486         
01487         //Create threads
01488         for(unsigned long t=0; t<NUM_THREADS; t++){
01489         
01490                 spkUp = spkBottom +offset;
01491                 if(t<re) spkUp +=1;
01492 
01493                 thread_data_array[t].N=N;
01494                 thread_data_array[t].spkBottom=spkBottom;
01495                 thread_data_array[t].spkUp=spkUp;
01496                 thread_data_array[t].rankEV=_rankEV;
01497                 thread_data_array[t].n_distrib=_n_distrib;
01498                 thread_data_array[t].vevT=&(_vEvT);
01499                 thread_data_array[t].linv=&(_l_spk_inv);
01500                 thread_data_array[t].nt=t;
01501 
01502                 if (verboseLevel>1) cout<<"(AccumulateJFAStat) Creating thread n["<< t<< "] for speakers["<<spkBottom<<"-->"<<spkUp-1<<"]"<<endl;
01503                 rc = pthread_create(&threads[t], &attr, LVthread, (void *)&thread_data_array[t]);
01504                 if (rc) throw Exception("ERROR; return code from pthread_create() is ",__FILE__,rc);
01505                 
01506                 spkBottom = spkUp;
01507         }
01508         
01509         pthread_attr_destroy(&attr);
01510         for(unsigned long t=0; t<NUM_THREADS; t++) {
01511                 rc = pthread_join(threads[t], (void **)&status);
01512                 if (rc)  throw Exception("ERROR; return code from pthread_join() is ",__FILE__,rc);
01513                 if (verboseLevel >1) cout <<"(AccumulateJFAStat) Completed join with thread ["<<t<<"] status["<<status<<"]"<<endl;
01514         }
01515 
01516         free(thread_data_array);
01517         free(threads);
01518 
01519         if (verboseLevel >= 1) cout << "(AccumulateJFAStat) Done " << endl;
01520         
01521 }
01522 #endif
01523 
01524 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
01525 void JFAAcc::estimateAndInverseL_EC(Config& config){
01526 
01527         #ifdef THREAD    
01528         if (config.existsParam("numThread") && config.getParam("numThread").toLong() >0)        estimateAndInverseLThreaded_EC(config.getParam("numThread").toLong());
01529         else estimateAndInverseLUnThreaded_EC();
01530         #else
01531         estimateAndInverseLUnThreaded_EC();
01532         #endif
01533 }
01534 
01535 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
01536 void JFAAcc::estimateAndInverseLUnThreaded_EC(){
01537 
01538         if (verboseLevel >= 1) cout << "(AccumulateJFAStat) Compute and Inverse L Matrix for EigenChannel "<<endl;
01539 
01540         DoubleSquareMatrix L(_rankEC);
01541 
01542         for(unsigned long sess=0; sess<_n_sessions; sess++){
01543 
01544                 L.setAllValues(0.0);
01545                 for(unsigned long i=0; i<_rankEC; i++){ L(i,i)=1.0;}
01546 
01547                 double *l, *n_h;
01548                 l=L.getArray();  n_h=_N_h.getArray();
01549 
01550                 for(unsigned long dis=0; dis<_n_distrib;dis++){
01551                         double *ueut=_uEuT[dis].getArray();
01552                         
01553                         for(unsigned long i=0; i<_rankEC; i++){
01554                                 for(unsigned long j=0; j<=i; j++){
01555                                         l[i*_rankEC+j] =+ l[i*_rankEC+j] + ueut[i*_rankEC+j]*n_h[sess*_n_distrib+dis];
01556                                 }
01557                         }
01558                 }
01559                 //Copy the second half of the symetric matrix
01560                 for(unsigned long i=0;i<_rankEC;i++){
01561                         for(unsigned long j=i+1;j<_rankEC;j++) {
01562                                 l[i*_rankEC+j] = l[j*_rankEC+i];
01563                         }
01564                 }
01565         
01566                 //Inverse L and stock in  _l_sess_inv[spk]
01567                 L.invert(_l_sess_inv[sess]);
01568         }
01569 }
01570 
01571 #ifdef THREAD
01572 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
01573 //                              Data strucutre of thread
01574 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
01575 struct LUthread_data{
01576 
01577         double *N_h;
01578         unsigned long sessBottom;
01579         unsigned long sessUp;   
01580         unsigned long rankEC;
01581         unsigned long n_distrib;
01582         RefVector <DoubleSquareMatrix>* ueuT;
01583         RefVector <DoubleSquareMatrix>* linv;
01584 };
01585 
01586 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
01587 //                              Thread Routine
01588 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
01589 void *LUthread(void *threadarg) {
01590         struct LUthread_data *my_data;
01591         my_data = (struct LUthread_data *) threadarg;
01592 
01593         double *n_h = my_data->N_h;
01594         unsigned long sessBottom = my_data->sessBottom; 
01595         unsigned long sessUp = my_data->sessUp;
01596         unsigned long _rankEC=my_data->rankEC;
01597         unsigned long _n_distrib=my_data->n_distrib;
01598 
01599         for(unsigned long session=sessBottom; session<sessUp; session++){
01600         
01601                 DoubleSquareMatrix L(_rankEC);  
01602                 L.setAllValues(0.0);    
01603                 double *l=L.getArray();
01604                 for(unsigned long i=0; i<_rankEC; i++){ l[i*_rankEC+i]=1.0;}
01605 
01606                 for(unsigned long d=0; d<_n_distrib;d++){
01607                         DoubleSquareMatrix &uEuT=(*(my_data->ueuT))[d];
01608                         double *ueut = uEuT.getArray();
01609                         
01610                         for(unsigned long i=0; i<_rankEC; i++){
01611                                 for(unsigned long j=0; j<=i; j++){
01612                                         l[i*_rankEC+j] =+ l[i*_rankEC+j] + ueut[i*_rankEC+j]*n_h[session*_n_distrib+d];
01613                                 }
01614                         }
01615                         
01616                 }
01617                 //As L is symetric, copy the second half of coefficients
01618                 for(unsigned long i=0;i<_rankEC;i++){
01619                         for(unsigned long j=i+1;j<_rankEC;j++) {
01620                                 l[i*_rankEC+j] = l[j*_rankEC+i];
01621                         }
01622                 }
01623                 
01624                 DoubleSquareMatrix &linv=(*(my_data->linv))[session];           
01625                 //Inverse L and stock it in _l_sess_inv[spk]
01626                 L.invert(linv);
01627         }
01628         pthread_exit((void*) 0);
01629         return (void*)0 ;
01630 }
01631 
01632 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
01633 void JFAAcc::estimateAndInverseLThreaded_EC(unsigned long NUM_THREADS){
01634         
01635         if (verboseLevel >= 1) cout << "(AccumulateJFAStat) Compute and Inverse L Matrix for EigenChannel Threaded"<<endl;
01636         if (NUM_THREADS==0) throw Exception("Num threads can not be 0",__FILE__,__LINE__);
01637 
01638         int rc, status;
01639         if (NUM_THREADS > _n_distrib) NUM_THREADS=_n_distrib;
01640 
01641         struct LUthread_data *thread_data_array = new LUthread_data[NUM_THREADS];
01642         pthread_t *threads = new pthread_t[NUM_THREADS];
01643 
01644         pthread_attr_t attr;
01645         pthread_attr_init(&attr);
01646         pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
01647         unsigned long offset=_n_sessions/NUM_THREADS;
01648         double *N_h=_N_h.getArray(); 
01649         
01650         unsigned long sessBottom = 0;
01651         unsigned long sessUp=0;
01652         unsigned long re=_n_sessions - NUM_THREADS*offset;
01653         
01654         //Create threads
01655         for(unsigned long t=0; t<NUM_THREADS; t++){
01656                 sessUp = sessBottom +offset;
01657                 if(t<re) sessUp +=1;
01658 
01659                 thread_data_array[t].N_h=N_h;
01660                 thread_data_array[t].sessBottom=sessBottom;
01661                 thread_data_array[t].sessUp=sessUp;
01662                 thread_data_array[t].rankEC=_rankEC;
01663                 thread_data_array[t].n_distrib=_n_distrib;
01664                 thread_data_array[t].ueuT=&(_uEuT);
01665                 thread_data_array[t].linv=&(_l_sess_inv);
01666 
01667                 if (verboseLevel >1) cout<<"(AccumulateJFAStat) Creating thread n["<< t<< "] for sessions ["<<sessBottom<<"-->"<<sessUp<<"]"<<endl;
01668                 rc = pthread_create(&threads[t], &attr, LUthread, (void *)&thread_data_array[t]);
01669                 if (rc) throw Exception("ERROR; return code from pthread_create() is ",__FILE__,rc);
01670                 
01671                 sessBottom = sessUp;
01672         }
01673         
01674         pthread_attr_destroy(&attr);
01675         for(unsigned long t=0; t<NUM_THREADS; t++) {
01676                 rc = pthread_join(threads[t], (void **)&status);
01677                 if (rc)  throw Exception("ERROR; return code from pthread_join() is ",__FILE__,rc);
01678                 if (verboseLevel >1) cout <<"(AccumulateJFAStat) Completed join with thread ["<<t<<"] status["<<status<<"]"<<endl;
01679         }
01680 
01681         free(thread_data_array);
01682         free(threads);
01683 
01684         if (verboseLevel >= 1) cout << "(AccumulateJFAStat) Done " << endl;
01685 }
01686 #endif
01687 
01688 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
01689 void JFAAcc::estimateAndInverseL_VU(Config& config){
01690 
01691         #ifdef THREAD          
01692         if (config.existsParam("numThread") && config.getParam("numThread").toLong() >0)        estimateAndInverseLThreaded_VU(config.getParam("numThread").toLong());
01693         else estimateAndInverseLUnThreaded_VU();
01694         #else
01695         estimateAndInverseLUnThreaded_VU();
01696         #endif
01697 }
01698 
01699 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
01700 void JFAAcc::estimateAndInverseLUnThreaded_VU(){
01701         
01702         if (verboseLevel >= 1) cout << "(AccumulateJFAStat) Compute and Inverse L Matrix for training "<<endl;
01703         
01704         DoubleSquareMatrix L(_rankEV + _rankEC);
01705 
01706         for(unsigned long spk=0; spk<_n_speakers; spk++){       
01707                 L.setAllValues(0.0);
01708                 for(unsigned long i=0; i<_rankEV + _rankEC; i++){       L(i,i)=1.0;}
01709 
01710                 double *l, *n;
01711                 l=L.getArray();  n=_matN.getArray();
01712 
01713                 for(unsigned long dis=0; dis<_n_distrib;dis++){
01714                         double *vuevut=_vuEvuT[dis].getArray();
01715                         
01716                         for(unsigned long i=0; i<_rankEV + _rankEC; i++){
01717                                 for(unsigned long j=0; j<=i; j++){
01718                                         l[i*(_rankEV + _rankEC)+j] =+ l[i*(_rankEV + _rankEC)+j] + vuevut[i*(_rankEV + _rankEC)+j]*n[spk*_n_distrib+dis];
01719                                 }
01720                         }
01721                 }
01722                 //Copy the second half of the symetric matrix
01723                 for(unsigned long i=0;i<(_rankEV + _rankEC);i++){
01724                         for(unsigned long j=i+1;j<(_rankEV + _rankEC);j++) {
01725                                 l[i*(_rankEV + _rankEC)+j] = l[j*(_rankEV + _rankEC)+i];
01726                         }
01727                 }
01728 
01729                 //Inverse L and stock in _l_sess_inv[spk]
01730                 L.invert(_l_yx_inv[spk]);
01731         }
01732 }
01733 
01734 #ifdef THREAD
01735 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
01736 //                              Data strucutre of thread
01737 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
01738 struct LVUthread_data{
01739 
01740         double *N;
01741         unsigned long spkBottom;
01742         unsigned long spkUp;    
01743         unsigned long rankEVC;
01744         unsigned long n_distrib;
01745         unsigned long nt;
01746         RefVector <DoubleSquareMatrix>* vuevuT;
01747         RefVector <DoubleSquareMatrix>* linv;
01748 };
01749 
01750 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
01751 //                              Thread Routine
01752 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
01753 void *LVUthread(void *threadarg) {
01754         struct LVUthread_data *my_data;
01755         my_data = (struct LVUthread_data *) threadarg;
01756 
01757         double *n = my_data->N;
01758         unsigned long spkBottom = my_data->spkBottom;   
01759         unsigned long spkUp = my_data->spkUp;
01760         unsigned long _rankEVC=my_data->rankEVC;
01761         unsigned long _n_distrib=my_data->n_distrib;
01762 
01763         for(unsigned long spk=spkBottom; spk<spkUp; spk++){
01764         
01765                 DoubleSquareMatrix L(_rankEVC);
01766                 L.setAllValues(0.0);    
01767                 double *l=L.getArray();
01768                 for(unsigned long i=0; i<_rankEVC; i++){        l[i*_rankEVC+i]=1.0;}
01769 
01770                 for(unsigned long d=0; d<_n_distrib;d++){
01771                         DoubleSquareMatrix &vuEvuT=(*(my_data->vuevuT))[d];
01772                         double *vuevut = vuEvuT.getArray();
01773                         
01774                         for(unsigned long i=0; i<_rankEVC; i++){
01775                                 for(unsigned long j=0; j<=i; j++){
01776                                         l[i*_rankEVC+j] =+ l[i*_rankEVC+j] + vuevut[i*_rankEVC+j]*n[spk*_n_distrib+d];
01777                                 }
01778                         }
01779                         
01780                 }
01781                 //As L is symetric, copy the second half of coefficients
01782                 for(unsigned long i=0;i<_rankEVC;i++){
01783                         for(unsigned long j=i+1;j<_rankEVC;j++) {
01784                                 l[i*_rankEVC+j] = l[j*_rankEVC+i];
01785                         }
01786                 }
01787 
01788                 DoubleSquareMatrix &linv=(*(my_data->linv))[spk];               
01789                 //Inverse L and stock it in _l_yx_inv[spk]
01790                 L.invert(linv);
01791         }
01792         pthread_exit((void*) 0);
01793         return (void*)0 ;
01794 }
01795 
01796 
01797 
01798 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
01799 void JFAAcc::estimateAndInverseLThreaded_VU(unsigned long NUM_THREADS){
01800         
01801         if (verboseLevel >= 1) cout << "(AccumulateJFAStat) Compute and Inverse L Matrix for Training Threaded"<<endl;
01802         if (NUM_THREADS==0) throw Exception("Num threads can not be 0",__FILE__,__LINE__);
01803 
01804         int rc, status;
01805         if (NUM_THREADS > _n_speakers) NUM_THREADS=_n_speakers;
01806 
01807         struct LVUthread_data *thread_data_array = new LVUthread_data[NUM_THREADS];
01808         pthread_t *threads = new pthread_t[NUM_THREADS];
01809 
01810 
01811         pthread_attr_t attr;
01812         pthread_attr_init(&attr);
01813         pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
01814         unsigned long offset=_n_speakers/NUM_THREADS;
01815         
01816         double *N=_matN.getArray(); 
01817         
01818         unsigned long spkBottom = 0;
01819         unsigned long spkUp=0;
01820         unsigned long re=_n_speakers - NUM_THREADS*offset;
01821         
01822         //Create threads
01823         for(unsigned long t=0; t<NUM_THREADS; t++){
01824                 spkUp = spkBottom +offset;
01825                 if(t<re) spkUp +=1;
01826 
01827                 thread_data_array[t].N=N;
01828                 thread_data_array[t].spkBottom=spkBottom;
01829                 thread_data_array[t].spkUp=spkUp;
01830                 thread_data_array[t].rankEVC=_rankEV + _rankEC;
01831                 thread_data_array[t].n_distrib=_n_distrib;
01832                 thread_data_array[t].vuevuT=&(_vuEvuT);
01833                 thread_data_array[t].linv=&(_l_yx_inv);
01834 
01835                 if (verboseLevel >1) cout<<"(AccumulateJFAStat) Creating thread n["<< t<< "] for speakers["<<spkBottom<<"-->"<<spkUp-1<<"]"<<endl;
01836                 rc = pthread_create(&threads[t], &attr, LVUthread, (void *)&thread_data_array[t]);
01837                 if (rc) throw Exception("ERROR; return code from pthread_create() is ",__FILE__,rc);
01838                 
01839                 spkBottom = spkUp;
01840         }
01841         
01842         pthread_attr_destroy(&attr);
01843         for(unsigned long t=0; t<NUM_THREADS; t++) {
01844                 rc = pthread_join(threads[t], (void **)&status);
01845                 if (rc)  throw Exception("ERROR; return code from pthread_join() is ",__FILE__,rc);
01846                 if (verboseLevel>1) cout <<"(AccumulateJFAStat) Completed join with thread ["<<t<<"] status["<<status<<"]"<<endl;
01847         }
01848         if (verboseLevel >= 1) cout << "(AccumulateJFAStat) Done " << endl;
01849 
01850         free(thread_data_array);
01851         free(threads);
01852 
01853 }
01854 #endif
01855 
01856 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
01857 void JFAAcc::estimateYandV(Config& config){
01858         #ifdef THREAD          
01859         if (config.existsParam("numThread") && config.getParam("numThread").toLong() >0)        estimateYandVThreaded(config.getParam("numThread").toLong());
01860         else estimateYandVUnThreaded();
01861         #else
01862         estimateYandVUnThreaded();
01863         #endif
01864 }
01865 
01866 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
01867 void JFAAcc::estimateYandVUnThreaded(){ //estimate Y for all speakers and V
01868         
01869         if (verboseLevel >=1) cout << "(AccumulateJFAStat) Compute Y  and V Estimate "<<endl;
01870         _Y.setAllValues(0.0);
01871         Matrix<double> AUX(_n_speakers,_rankEV);
01872         AUX.setAllValues(0.0);
01873         
01874         double *y, *v, *f_x, *aux, *invVar, *n, *c;
01875         y=_Y.getArray(); v=_V.getArray(); f_x=_F_X.getArray(); aux=AUX.getArray(); invVar=_ubm_invvar.getArray(); n=_matN.getArray(); c=_Cev.getArray();
01876 
01877         //For each speaker
01878         for(unsigned long spk=0; spk<_n_speakers; spk++){
01879                 double *invl = _l_spk_inv[spk].getArray();
01880 
01881                 for(unsigned long i=0;i<_rankEV;i++){
01882                         for(unsigned long k=0;k<_svSize;k++) {
01883                                 aux[spk*_rankEV+i] += f_x[spk*_svSize+k] * invVar[k] * v[i*_svSize+k];
01884                         }
01885                 }
01886                 
01887                 //multiplication by invL
01888                 for(unsigned long i=0; i<_rankEV;i++){
01889                         for(unsigned long k=0; k<_rankEV; k++){
01890                                 y[spk*_rankEV+i] += aux[spk*_rankEV+k] * invl[i*_rankEV+k];
01891                         }
01892                 }
01893 
01894                 for(unsigned long i=0;i<_rankEV;i++){
01895                         for(unsigned long j=0;j<_rankEV;j++){
01896                                         invl[i*_rankEV+j] += y[spk*_rankEV+i]*y[spk*_rankEV+j];
01897                         }
01898                 }
01899 
01900                 for(unsigned long dis = 0; dis<_n_distrib;dis++){
01901                         for(unsigned long i=0;i<_rankEV;i++){
01902                                 for(unsigned long j = 0;j<_rankEV;j++){
01903                                         _Aev[dis](i,j) += invl[i*_rankEV+j] * n[spk*_n_distrib+dis];
01904 
01905                                 }
01906                         }
01907                 }
01908 
01909                 for(unsigned long i=0;i<_rankEV;i++){
01910                         for(unsigned long j=0;j<_svSize;j++){
01911                                         c[i*_svSize+j] += y[spk*_rankEV+i] * f_x[spk*_svSize+j];
01912                         }
01913                 }
01914         }
01915 }
01916 
01917 #ifdef THREAD
01918 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
01919 //                              Data strucutre of thread
01920 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
01921 struct estimateYandVthread_data{
01922         double *AUX;
01923         double *Y;
01924         double *V;
01925         double *F_X;
01926         double *ubm_invvar;
01927         unsigned long spkBottom;
01928         unsigned long spkUp;    
01929         unsigned long rankEV;
01930         unsigned long svSize;
01931         unsigned long n_distrib;
01932         unsigned long nt;
01933         RefVector <DoubleSquareMatrix>* linv;
01934 };
01935 
01936 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
01937 //                              Thread Routine
01938 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
01939 
01940 void *estimateYandVthread(void *threadarg) {
01941         
01942         struct estimateYandVthread_data *my_data;
01943         my_data = (struct estimateYandVthread_data *) threadarg;
01944 
01945         double *v = my_data->V;
01946         double *y = my_data->Y;
01947         double *f_x = my_data->F_X;
01948         double *aux = my_data->AUX;
01949         double *ubm_invvar = my_data->ubm_invvar;
01950         unsigned long spkBottom = my_data->spkBottom;   
01951         unsigned long spkUp = my_data->spkUp;
01952         unsigned long _rankEV=my_data->rankEV;
01953         unsigned long _svSize=my_data->svSize;
01954         
01955         //For each session
01956         for(unsigned long spk= spkBottom; spk<spkUp; spk++){
01957 
01958                 DoubleSquareMatrix &linv=(*(my_data->linv))[spk];
01959                 double *invl = linv.getArray();
01960 
01961                 for(unsigned long i=0;i<_rankEV;i++){
01962                         for(unsigned long k=0;k<_svSize;k++) {
01963                                 aux[spk*_rankEV+i] += f_x[spk*_svSize+k] * ubm_invvar[k] * v[i*_svSize+k];
01964                         }
01965                 }
01966                 
01967                 //multiplication by invL
01968                 for(unsigned long i=0; i<_rankEV;i++){
01969                         for(unsigned long k=0; k<_rankEV; k++){
01970                                 y[spk*_rankEV+i] += aux[spk*_rankEV+k] * invl[i*_rankEV+k];
01971                         }
01972                 }
01973         }
01974         pthread_exit((void*) 0);
01975         return (void*)0 ;
01976 }
01977 
01978 
01979 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
01980 void JFAAcc::estimateYandVThreaded(unsigned long NUM_THREADS){
01981 
01982         if (verboseLevel >= 1) cout << "(AccumulateJFAStat) Estimate Y and V for each session Threaded"<<endl;
01983         if (NUM_THREADS==0) throw Exception("Num threads can not be 0",__FILE__,__LINE__);
01984 
01985         int rc, status;
01986         if (NUM_THREADS > _n_speakers) NUM_THREADS=_n_speakers;
01987 
01988         struct estimateYandVthread_data *thread_data_array = new estimateYandVthread_data[NUM_THREADS];
01989         pthread_t *threads = new pthread_t[NUM_THREADS];
01990 
01991         pthread_attr_t attr;
01992         pthread_attr_init(&attr);
01993         pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
01994         unsigned long offset=_n_speakers/NUM_THREADS;
01995 
01996         _Y.setAllValues(0.0);
01997         Matrix<double> AUX(_n_speakers,_rankEV);
01998         AUX.setAllValues(0.0);
01999         
02000         double *y, *f_x, *n, *c;
02001         y=_Y.getArray(); f_x=_F_X.getArray(); n=_matN.getArray(); c=_Cev.getArray();
02002         
02003         double *V =_V.getArray();
02004         double *Y =_Y.getArray();
02005         double *F_X =_F_X.getArray();
02006         double *aux = AUX.getArray(); 
02007         double *ubm_invvar=_ubm_invvar.getArray();
02008 
02009         unsigned long spkBottom = 0;
02010         unsigned long spkUp=0;
02011         unsigned long re=_n_speakers - NUM_THREADS*offset;
02012         
02013         //Create threads
02014         for(unsigned long t=0; t<NUM_THREADS; t++){
02015                 spkUp = spkBottom +offset;
02016                 if(t<re) spkUp +=1;
02017 
02018                 thread_data_array[t].V=V;
02019                 thread_data_array[t].Y=Y;
02020                 thread_data_array[t].F_X=F_X;
02021                 thread_data_array[t].AUX=aux;
02022                 thread_data_array[t].ubm_invvar=ubm_invvar;
02023                 thread_data_array[t].spkBottom=spkBottom;
02024                 thread_data_array[t].spkUp=spkUp;
02025                 thread_data_array[t].rankEV=_rankEV;
02026                 thread_data_array[t].svSize=_svSize;
02027                 thread_data_array[t].linv=&(_l_spk_inv);
02028 
02029                 if (verboseLevel >1) cout<<"(AccumulateJFAStat) Creating thread n [ "<< t<< " ] for speakers[ "<<spkBottom<<" --> "<<spkUp-1<<" ]"<<endl;
02030                 rc = pthread_create(&threads[t], &attr, estimateYandVthread, (void *)&thread_data_array[t]);
02031                 if (rc) throw Exception("ERROR; return code from pthread_create() is ",__FILE__,rc);
02032                 
02033                 spkBottom = spkUp;
02034         }
02035         
02036         pthread_attr_destroy(&attr);
02037         for(unsigned long t=0; t<NUM_THREADS; t++) {
02038                 rc = pthread_join(threads[t], (void **)&status);
02039                 if (rc)  throw Exception("ERROR; return code from pthread_join() is ",__FILE__,rc);
02040                 if (verboseLevel>1) cout <<"(AccumulateJFAStat) Completed join with thread ["<<t<<"] status["<<status<<"]"<<endl;
02041         }
02042         
02043         free(thread_data_array);
02044         free(threads);
02045         
02046         for(unsigned long spk=0; spk<_n_speakers; spk++){
02047                 double *invl = _l_spk_inv[spk].getArray();
02048                 
02049                 for(unsigned long i=0;i<_rankEV;i++){
02050                         for(unsigned long j=0;j<_rankEV;j++){
02051                                         invl[i*_rankEV+j] += y[spk*_rankEV+i]*y[spk*_rankEV+j];
02052                         }
02053                 }
02054 
02055                 for(unsigned long dis = 0; dis<_n_distrib;dis++){
02056                         for(unsigned long i=0;i<_rankEV;i++){
02057                                 for(unsigned long j = 0;j<_rankEV;j++){
02058                                         _Aev[dis](i,j) += invl[i*_rankEV+j] * n[spk*_n_distrib+dis];
02059 
02060                                 }
02061                         }
02062                 }
02063 
02064                 for(unsigned long i=0;i<_rankEV;i++){
02065                         for(unsigned long j=0;j<_svSize;j++){
02066                                         c[i*_svSize+j] += y[spk*_rankEV+i] * f_x[spk*_svSize+j];
02067                         }
02068                 }
02069         }
02070         if (verboseLevel >= 1) cout << "(AccumulateJFAStat) Done " << endl;
02071 }
02072 #endif
02073 
02074 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
02075 void JFAAcc::estimateY(Config& config){
02076         #ifdef THREAD          
02077         if (config.existsParam("numThread") && config.getParam("numThread").toLong() >0)        estimateYThreaded(config.getParam("numThread").toLong());
02078         else estimateYUnThreaded();
02079         #else
02080         estimateYUnThreaded();
02081         #endif
02082 }
02083 
02084 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
02085 void JFAAcc::estimateYUnThreaded(){     //estimate Y for all speakers
02086         
02087         if (verboseLevel>=1) cout << "(AccumulateJFAStat) Compute Y  Estimate "<<endl;
02088         _Y.setAllValues(0.0);
02089         Matrix<double> AUX(_n_speakers,_rankEV);
02090         AUX.setAllValues(0.0);
02091         
02092         double *y, *v, *f_x, *aux, *invVar;
02093         y=_Y.getArray(); v=_V.getArray(); f_x=_F_X.getArray(); aux=AUX.getArray(); invVar=_ubm_invvar.getArray();
02094 
02095         //For each speaker
02096         for(unsigned long spk=0; spk<_n_speakers; spk++){
02097 
02098                 double *invl = _l_spk_inv[spk].getArray();
02099 
02100                 for(unsigned long i=0;i<_rankEV;i++){
02101                         for(unsigned long k=0;k<_svSize;k++) {
02102                                 aux[spk*_rankEV+i] += f_x[spk*_svSize+k] * invVar[k] * v[i*_svSize+k];
02103                         }
02104                 }
02105                 
02106                 //multiplication by invL
02107                 for(unsigned long i=0; i<_rankEV;i++){
02108                         for(unsigned long k=0; k<_rankEV; k++){
02109                                 y[spk*_rankEV+i] += aux[spk*_rankEV+k] * invl[i*_rankEV+k];
02110                         }
02111                 }
02112         }
02113 }
02114 
02115 #ifdef THREAD
02116 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
02117 //                              Data strucutre of thread
02118 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
02119 struct estimateYthread_data{
02120         double *AUX;
02121         double *Y;
02122         double *V;
02123         double *F_X;
02124         double *ubm_invvar;
02125         unsigned long spkBottom;
02126         unsigned long spkUp;    
02127         unsigned long rankEV;
02128         unsigned long svSize;
02129         unsigned long n_distrib;
02130         unsigned long nt;
02131         RefVector <DoubleSquareMatrix>* linv;
02132 };
02133 
02134 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
02135 //                              Thread Routine
02136 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
02137 void *estimateYthread(void *threadarg) {
02138         
02139         struct estimateYthread_data *my_data;
02140         my_data = (struct estimateYthread_data *) threadarg;
02141 
02142         double *v = my_data->V;
02143         double *y = my_data->Y;
02144         double *f_x = my_data->F_X;
02145         double *aux = my_data->AUX;
02146         double *ubm_invvar = my_data->ubm_invvar;
02147         unsigned long spkBottom = my_data->spkBottom;   
02148         unsigned long spkUp = my_data->spkUp;
02149         unsigned long _rankEV=my_data->rankEV;
02150         unsigned long _svSize=my_data->svSize;
02151         
02152         //For each session
02153         for(unsigned long spk= spkBottom; spk<spkUp; spk++){
02154 
02155                 DoubleSquareMatrix &linv=(*(my_data->linv))[spk];
02156                 double *invl = linv.getArray();
02157 
02158                 for(unsigned long i=0;i<_rankEV;i++){
02159                         for(unsigned long k=0;k<_svSize;k++) {
02160                                 aux[spk*_rankEV+i] += f_x[spk*_svSize+k] * ubm_invvar[k] * v[i*_svSize+k];
02161                         }
02162                 }
02163                 
02164                 //multiplication by invL
02165                 for(unsigned long i=0; i<_rankEV;i++){
02166                         for(unsigned long k=0; k<_rankEV; k++){
02167                                 y[spk*_rankEV+i] += aux[spk*_rankEV+k] * invl[i*_rankEV+k];
02168                         }
02169                 }
02170         }
02171         pthread_exit((void*) 0);
02172         return (void*)0 ;
02173 }
02174 
02175 
02176 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
02177 void JFAAcc::estimateYThreaded(unsigned long NUM_THREADS){
02178 
02179         if (verboseLevel >= 1) cout << "(AccumulateJFAStat) Estimate Y for each speaker Threaded"<<endl;
02180         if (NUM_THREADS==0) throw Exception("Num threads can not be 0",__FILE__,__LINE__);
02181 
02182         int rc, status;
02183         if (NUM_THREADS > _n_speakers) NUM_THREADS=_n_speakers;
02184 
02185         struct estimateYthread_data *thread_data_array = new estimateYthread_data[NUM_THREADS];
02186         pthread_t *threads = new pthread_t[NUM_THREADS];
02187 
02188         pthread_attr_t attr;
02189         pthread_attr_init(&attr);
02190         pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
02191         unsigned long offset=_n_speakers/NUM_THREADS;
02192 
02193         _Y.setAllValues(0.0);
02194         Matrix<double> AUX(_n_speakers,_rankEV);
02195         AUX.setAllValues(0.0);
02196         
02197         double *y, *f_x, *c;
02198         y=_Y.getArray(); f_x=_F_X.getArray(); c=_Cev.getArray();
02199         
02200         double *V =_V.getArray();
02201         double *Y =_Y.getArray();
02202         double *F_X =_F_X.getArray();
02203         double *aux = AUX.getArray(); 
02204         double *ubm_invvar=_ubm_invvar.getArray();
02205 
02206         unsigned long spkBottom = 0;
02207         unsigned long spkUp=0;
02208         unsigned long re=_n_speakers - NUM_THREADS*offset;
02209         
02210         //Create threads
02211         for(unsigned long t=0; t<NUM_THREADS; t++){
02212                 spkUp = spkBottom +offset;
02213                 if(t<re) spkUp +=1;
02214 
02215                 thread_data_array[t].V=V;
02216                 thread_data_array[t].Y=Y;
02217                 thread_data_array[t].F_X=F_X;
02218                 thread_data_array[t].AUX=aux;
02219                 thread_data_array[t].ubm_invvar=ubm_invvar;
02220                 thread_data_array[t].spkBottom=spkBottom;
02221                 thread_data_array[t].spkUp=spkUp;
02222                 thread_data_array[t].rankEV=_rankEV;
02223                 thread_data_array[t].svSize=_svSize;
02224                 thread_data_array[t].linv=&(_l_spk_inv);
02225 
02226                 if (verboseLevel>1) cout<<"(AccumulateJFAStat) Creating thread n [ "<< t<< " ] for speakers[ "<<spkBottom<<" --> "<<spkUp-1<<" ]"<<endl;
02227                 rc = pthread_create(&threads[t], &attr, estimateYandVthread, (void *)&thread_data_array[t]);
02228                 if (rc) throw Exception("ERROR; return code from pthread_create() is ",__FILE__,rc);
02229                 
02230                 spkBottom = spkUp;
02231         }
02232         
02233         pthread_attr_destroy(&attr);
02234         for(unsigned long t=0; t<NUM_THREADS; t++) {
02235                 rc = pthread_join(threads[t], (void **)&status);
02236                 if (rc)  throw Exception("ERROR; return code from pthread_join() is ",__FILE__,rc);
02237                 if (verboseLevel>1) cout <<"(AccumulateJFAStat) Completed join with thread ["<<t<<"] status["<<status<<"]"<<endl;
02238         }
02239 
02240         free(thread_data_array);
02241         free(threads);
02242 
02243         if (verboseLevel >= 1) cout << "(AccumulateJFAStat) Done " << endl;
02244 }
02245 #endif
02246 
02247 //----------------------------------------------------------------------------------------------------------------------------------------------------------
02248 void JFAAcc::estimateXandU(Config &config){
02249         #ifdef THREAD          
02250         if (config.existsParam("numThread") && config.getParam("numThread").toLong() >0)        estimateXandUThreaded(config.getParam("numThread").toLong());
02251         else estimateXandUUnThreaded();
02252         #else
02253         estimateXandUUnThreaded();
02254         #endif
02255 }
02256 
02257 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
02258 void JFAAcc::estimateXandUUnThreaded(){ //estimate X for all sessions and U
02259         
02260         if (verboseLevel>=1) cout << "(AccumulateJFAStat) Compute X  andU Estimate "<<endl;
02261         _matX.setAllValues(0.0);
02262         Matrix<double> AUX(_n_sessions,_rankEC);
02263         AUX.setAllValues(0.0);
02264         
02265         double *x, *u, *f_x_h, *aux, *invVar, *n_h, *c;
02266         x=_matX.getArray(); u=_matU.getArray(); f_x_h=_F_X_h.getArray(); aux=AUX.getArray(); invVar=_ubm_invvar.getArray(); n_h=_N_h.getArray(); c=_Cec.getArray();
02267 
02268         //For each session
02269         for(unsigned long session=0; session<_n_sessions; session++){
02270 
02271                 double *invl = _l_sess_inv[session].getArray();
02272 
02273                 for(unsigned long i=0;i<_rankEC;i++){
02274                         for(unsigned long k=0;k<_svSize;k++) {
02275                                 aux[session*_rankEC+i] += f_x_h[session*_svSize+k] * invVar[k] * u[i*_svSize+k];
02276                         }
02277                 }
02278                 
02279                 //multiplication by invL
02280                 for(unsigned long i=0; i<_rankEC;i++){
02281                         for(unsigned long k=0; k<_rankEC; k++){
02282                                 x[session*_rankEC+i] += aux[session*_rankEC+k] * invl[i*_rankEC+k];
02283                         }
02284                 }
02285 
02286                 for(unsigned long i=0;i<_rankEC;i++){
02287                         for(unsigned long j=0;j<_rankEC;j++){
02288                                         invl[i*_rankEC+j] += x[session*_rankEC+i]*x[session*_rankEC+j];
02289                         }
02290                 }
02291 
02292                 for(unsigned long dis = 0; dis<_n_distrib;dis++){
02293                         for(unsigned long i=0;i<_rankEC;i++){
02294                                 for(unsigned long j = 0;j<_rankEC;j++){
02295                                         _Aec[dis](i,j) += invl[i*_rankEC+j] * n_h[session*_n_distrib+dis];
02296 
02297                                 }
02298                         }
02299                 }
02300 
02301                 for(unsigned long i=0;i<_rankEC;i++){
02302                         for(unsigned long j=0;j<_svSize;j++){
02303                                         c[i*_svSize+j] += x[session*_rankEC+i] * f_x_h[session*_svSize+j];
02304                         }
02305                 }
02306         }
02307 }
02308 
02309 #ifdef THREAD
02310 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
02311 //                              Data strucutre of thread
02312 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
02313 struct estimateXandUthread_data{
02314         double *U;
02315         double *X;
02316         double *F_X_h;
02317         double *AUX;
02318         double *ubm_invvar;
02319         unsigned long sessBottom;
02320         unsigned long sessUp;   
02321         unsigned long rankEC;
02322         unsigned long svSize;
02323         unsigned long nt;
02324         RefVector <DoubleSquareMatrix>* linv;
02325 };
02326 
02327 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
02328 //                              Thread Routine
02329 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
02330 void *estimateXandUthread(void *threadarg) {
02331         
02332         struct estimateXandUthread_data *my_data;
02333         my_data = (struct estimateXandUthread_data *) threadarg;
02334 
02335         double *u = my_data->U;
02336         double *x = my_data->X;
02337         double *f_x_h = my_data->F_X_h;
02338         double *aux = my_data->AUX;
02339         double *ubm_invvar = my_data->ubm_invvar;
02340         unsigned long sessBottom = my_data->sessBottom; 
02341         unsigned long sessUp = my_data->sessUp;
02342         unsigned long _rankEC=my_data->rankEC;
02343         unsigned long _svSize=my_data->svSize;
02344         
02345         //For each session
02346         for(unsigned long session= sessBottom; session<sessUp; session++){
02347 
02348                 DoubleSquareMatrix &linv=(*(my_data->linv))[session];
02349                 double *invl = linv.getArray();
02350 
02351                 for(unsigned long i=0;i<_rankEC;i++){
02352                         for(unsigned long k=0;k<_svSize;k++) {
02353                                 aux[session*_rankEC+i] += f_x_h[session*_svSize+k] * ubm_invvar[k] * u[i*_svSize+k];
02354                         }
02355                 }
02356                 
02357                 //multiplication by invL
02358                 for(unsigned long i=0; i<_rankEC;i++){
02359                         for(unsigned long k=0; k<_rankEC; k++){
02360                                 x[session*_rankEC+i] += aux[session*_rankEC+k] * invl[i*_rankEC+k];
02361                         }
02362                 }
02363         }
02364         pthread_exit((void*) 0);
02365         return (void*)0 ;
02366 }
02367 
02368 
02369 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
02370 void JFAAcc::estimateXandUThreaded(unsigned long NUM_THREADS){
02371 
02372         if (verboseLevel >= 1) cout << "(AccumulateJFAStat) Estimate X and U for each session Threaded"<<endl;
02373         if (NUM_THREADS==0) throw Exception("Num threads can not be 0",__FILE__,__LINE__);
02374 
02375         int rc, status;
02376         if (NUM_THREADS > _n_sessions) NUM_THREADS=_n_sessions;
02377 
02378         struct estimateXandUthread_data *thread_data_array = new estimateXandUthread_data[NUM_THREADS];
02379         pthread_t *threads = new pthread_t[NUM_THREADS];
02380 
02381         pthread_attr_t attr;
02382         pthread_attr_init(&attr);
02383         pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
02384         unsigned long offset=_n_sessions/NUM_THREADS;
02385 
02386         _matX.setAllValues(0.0);
02387         Matrix<double> AUX(_n_sessions,_rankEC);
02388         AUX.setAllValues(0.0);
02389         
02390         double *x, *f_x_h, *n_h, *c;
02391         x=_matX.getArray(); f_x_h=_F_X_h.getArray(); n_h=_N_h.getArray(); c=_Cec.getArray();
02392         
02393         double *U =_matU.getArray();
02394         double *X =_matX.getArray();
02395         double *F_X_h =_F_X_h.getArray();
02396         double *aux = AUX.getArray(); 
02397         double *ubm_invvar=_ubm_invvar.getArray();
02398 
02399         unsigned long sessBottom = 0;
02400         unsigned long sessUp=0;
02401         unsigned long re=_n_sessions - NUM_THREADS*offset;
02402         
02403         //Create threads
02404         for(unsigned long t=0; t<NUM_THREADS; t++){
02405                 sessUp = sessBottom +offset;
02406                 if(t<re) sessUp +=1;
02407 
02408                 thread_data_array[t].U=U;
02409                 thread_data_array[t].X=X;
02410                 thread_data_array[t].F_X_h=F_X_h;
02411                 thread_data_array[t].AUX=aux;
02412                 thread_data_array[t].ubm_invvar=ubm_invvar;
02413                 thread_data_array[t].sessBottom=sessBottom;
02414                 thread_data_array[t].sessUp=sessUp;
02415                 thread_data_array[t].rankEC=_rankEC;
02416                 thread_data_array[t].svSize=_svSize;
02417                 thread_data_array[t].linv=&(_l_sess_inv);
02418 
02419                 if (verboseLevel>1) cout<<"(AccumulateJFAStat) Creating thread n["<< t<< "] for speakers["<<sessBottom<<"-->"<<sessUp-1<<"]"<<endl;
02420                 rc = pthread_create(&threads[t], &attr, estimateXandUthread, (void *)&thread_data_array[t]);
02421                 if (rc) throw Exception("ERROR; return code from pthread_create() is ",__FILE__,rc);
02422                 
02423                 sessBottom = sessUp;
02424         }
02425         
02426         pthread_attr_destroy(&attr);
02427         for(unsigned long t=0; t<NUM_THREADS; t++) {
02428                 rc = pthread_join(threads[t], (void **)&status);
02429                 if (rc)  throw Exception("ERROR; return code from pthread_join() is ",__FILE__,rc);
02430                 if (verboseLevel>1) cout <<"(AccumulateJFAStat) Completed join with thread ["<<t<<"] status["<<status<<"]"<<endl;
02431         }
02432 
02433         free(thread_data_array);
02434         free(threads);
02435         
02436         
02437         //For each session
02438         for(unsigned long session=0; session<_n_sessions; session++){
02439                 
02440                 double *invl = _l_sess_inv[session].getArray();
02441 
02442                 for(unsigned long i=0;i<_rankEC;i++){
02443                         for(unsigned long j=0;j<_rankEC;j++){
02444                                         invl[i*_rankEC+j] += x[session*_rankEC+i]*x[session*_rankEC+j];
02445                         }
02446                 }
02447 
02448                 for(unsigned long dis = 0; dis<_n_distrib;dis++){
02449                         for(unsigned long i=0;i<_rankEC;i++){
02450                                 for(unsigned long j = 0;j<_rankEC;j++){
02451                                         _Aec[dis](i,j) += invl[i*_rankEC+j] * n_h[session*_n_distrib+dis];
02452 
02453                                 }
02454                         }
02455                 }
02456 
02457                 for(unsigned long i=0;i<_rankEC;i++){
02458                         for(unsigned long j=0;j<_svSize;j++){
02459                                         c[i*_svSize+j] += x[session*_rankEC+i] * f_x_h[session*_svSize+j];
02460                         }
02461                 }
02462         }
02463 
02464         if (verboseLevel >= 1) cout << "(AccumulateJFAStat) Done " << endl;
02465 }
02466 #endif
02467 
02468 
02469 //----------------------------------------------------------------------------------------------------------------------------------------------------------
02470 void JFAAcc::estimateX(Config &config){
02471         #ifdef THREAD    
02472         if (config.existsParam("numThread") && config.getParam("numThread").toLong() >0)        estimateXThreaded(config.getParam("numThread").toLong());
02473         else estimateXUnThreaded();
02474         #else
02475         estimateXUnThreaded();
02476         #endif
02477 }
02478 
02479 //----------------------------------------------------------------------------------------------------------------------------------------------------------
02480 void JFAAcc::estimateXUnThreaded(){     //estimate X for all speakers
02481 
02482         if (verboseLevel>=1) cout << "(AccumulateJFAStat) Compute X Estimate "<<endl;
02483         _matX.setAllValues(0.0);
02484         Matrix<double> AUX(_n_sessions,_rankEC);
02485         AUX.setAllValues(0.0);
02486 
02487         double *x, *u, *f_x_h, *aux, *invVar;
02488         x=_matX.getArray(); u=_matU.getArray(); f_x_h=_F_X_h.getArray(); aux=AUX.getArray(); invVar=_ubm_invvar.getArray();
02489 
02490         //For each session
02491         for(unsigned long session=0; session<_n_sessions; session++){
02492 
02493                 double *invl = _l_sess_inv[session].getArray();
02494 
02495                 for(unsigned long i=0;i<_rankEC;i++){
02496                         for(unsigned long k=0;k<_svSize;k++) {
02497                                 aux[session*_rankEC+i] += f_x_h[session*_svSize+k] * invVar[k] * u[i*_svSize+k];
02498                         }
02499                 }
02500         
02501                 //multiplication by invL
02502                 for(unsigned long i=0; i<_rankEC;i++){
02503                         for(unsigned long k=0; k<_rankEC; k++){
02504                                 x[session*_rankEC+i] += aux[session*_rankEC+k] * invl[i*_rankEC+k];
02505                         }
02506                 }
02507         }
02508 }
02509 
02510 #ifdef THREAD
02511 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
02512 //                              Data strucutre of thread
02513 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
02514 struct estimateXthread_data{
02515         double *U;
02516         double *X;
02517         double *F_X_h;
02518         double *AUX;
02519         double *ubm_invvar;
02520         unsigned long sessBottom;
02521         unsigned long sessUp;   
02522         unsigned long rankEC;
02523         unsigned long svSize;
02524         unsigned long nt;
02525         RefVector <DoubleSquareMatrix>* linv;
02526 };
02527 
02528 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
02529 //                              Thread Routine
02530 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
02531 void *estimateXthread(void *threadarg) {
02532         
02533         struct estimateXthread_data *my_data;
02534         my_data = (struct estimateXthread_data *) threadarg;
02535 
02536         double *u = my_data->U;
02537         double *x = my_data->X;
02538         double *f_x_h = my_data->F_X_h;
02539         double *aux = my_data->AUX;
02540         double *ubm_invvar = my_data->ubm_invvar;
02541         unsigned long sessBottom = my_data->sessBottom; 
02542         unsigned long sessUp = my_data->sessUp;
02543         unsigned long _rankEC=my_data->rankEC;
02544         unsigned long _svSize=my_data->svSize;
02545         
02546         //For each session
02547         for(unsigned long session= sessBottom; session<sessUp; session++){
02548 
02549                 DoubleSquareMatrix &linv=(*(my_data->linv))[session];
02550                 double *invl = linv.getArray();
02551 
02552                 for(unsigned long i=0;i<_rankEC;i++){
02553                         for(unsigned long k=0;k<_svSize;k++) {
02554                                 aux[session*_rankEC+i] += f_x_h[session*_svSize+k] * ubm_invvar[k] * u[i*_svSize+k];
02555                         }
02556                 }
02557                 
02558                 //multiplication by invL
02559                 for(unsigned long i=0; i<_rankEC;i++){
02560                         for(unsigned long k=0; k<_rankEC; k++){
02561                                 x[session*_rankEC+i] += aux[session*_rankEC+k] * invl[i*_rankEC+k];
02562                         }
02563                 }
02564         }
02565         pthread_exit((void*) 0);
02566         return (void*)0 ;
02567 }
02568 
02569 
02570 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
02571 void JFAAcc::estimateXThreaded(unsigned long NUM_THREADS){
02572 
02573         if (verboseLevel >= 1) cout << "(AccumulateJFAStat) Estimate X for each session Threaded"<<endl;
02574         if (NUM_THREADS==0) throw Exception("Num threads can not be 0",__FILE__,__LINE__);
02575 
02576         int rc, status;
02577         if (NUM_THREADS > _n_sessions) NUM_THREADS=_n_sessions;
02578 
02579         struct estimateXthread_data *thread_data_array = new estimateXthread_data[NUM_THREADS];
02580         pthread_t *threads = new pthread_t[NUM_THREADS];
02581 
02582         pthread_attr_t attr;
02583         pthread_attr_init(&attr);
02584         pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
02585         unsigned long offset=_n_sessions/NUM_THREADS;
02586         
02587         Matrix<double> AUX(_n_sessions,_rankEC);
02588         AUX.setAllValues(0.0);
02589         
02590         double *U =_matU.getArray();
02591         double *X =_matX.getArray();
02592         double *F_X_h =_F_X_h.getArray();
02593         double *aux = AUX.getArray(); 
02594         double *ubm_invvar=_ubm_invvar.getArray();
02595 
02596         unsigned long sessBottom = 0;
02597         unsigned long sessUp=0;
02598         unsigned long re=_n_sessions - NUM_THREADS*offset;
02599         
02600         //Create threads
02601         for(unsigned long t=0; t<NUM_THREADS; t++){
02602                 sessUp = sessBottom +offset;
02603                 if(t<re) sessUp +=1;
02604 
02605                 thread_data_array[t].U=U;
02606                 thread_data_array[t].X=X;
02607                 thread_data_array[t].F_X_h=F_X_h;
02608                 thread_data_array[t].AUX=aux;
02609                 thread_data_array[t].ubm_invvar=ubm_invvar;
02610                 thread_data_array[t].sessBottom=sessBottom;
02611                 thread_data_array[t].sessUp=sessUp;
02612                 thread_data_array[t].rankEC=_rankEC;
02613                 thread_data_array[t].svSize=_svSize;
02614                 thread_data_array[t].linv=&(_l_sess_inv);
02615 
02616                 if (verboseLevel>1) cout<<"(AccumulateJFAStat) Creating thread n["<< t<< "] for speakers["<<sessBottom<<"-->"<<sessUp-1<<"]"<<endl;
02617                 rc = pthread_create(&threads[t], &attr, estimateXthread, (void *)&thread_data_array[t]);
02618                 if (rc) throw Exception("ERROR; return code from pthread_create() is ",__FILE__,rc);
02619                 
02620                 sessBottom = sessUp;
02621         }
02622         
02623         pthread_attr_destroy(&attr);
02624         for(unsigned long t=0; t<NUM_THREADS; t++) {
02625                 rc = pthread_join(threads[t], (void **)&status);
02626                 if (rc)  throw Exception("ERROR; return code from pthread_join() is ",__FILE__,rc);
02627                 if (verboseLevel>1) cout <<"(AccumulateJFAStat) Completed join with thread ["<<t<<"] status["<<status<<"]"<<endl;
02628         }
02629 
02630         free(thread_data_array);
02631         free(threads);
02632 
02633         if (verboseLevel >= 1) cout << "(AccumulateJFAStat) Done " << endl;
02634 
02635 }
02636 #endif
02637 
02638 
02639 //******************************************
02640 // AJOUT POUR LE LFA VERSION DRISS
02641 //******************************************
02642 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
02643 void JFAAcc::estimateU(){       //estimate X for all sessions and U
02644         
02645         if (verboseLevel>=1) cout << "(AccumulateJFAStat) Compute U Estimate "<<endl;
02646 //      _matX.setAllValues(0.0);
02647         Matrix<double> AUX(_n_sessions,_rankEC);
02648         AUX.setAllValues(0.0);
02649         
02650         double *x, *u, *f_x_h, /* *aux,*/ *invVar, *n_h, *c;
02651         x=_matX.getArray(); u=_matU.getArray(); f_x_h=_F_X_h.getArray();  invVar=_ubm_invvar.getArray(); n_h=_N_h.getArray(); c=_Cec.getArray();
02652         //aux=AUX.getArray();
02653 
02654         //For each session
02655         for(unsigned long session=0; session<_n_sessions; session++){
02656 
02657                 double *invl = _l_sess_inv[session].getArray();
02658 
02659 //              for(unsigned long i=0;i<_rankEC;i++){
02660 //                      for(unsigned long k=0;k<_svSize;k++) {
02661 //                              aux[session*_rankEC+i] += f_x_h[session*_svSize+k] * invVar[k] * u[i*_svSize+k];
02662 //                      }
02663 //              }
02664                 
02665 //              //multiplication by invL
02666 //              for(unsigned long i=0; i<_rankEC;i++){
02667 //                      for(unsigned long k=0; k<_rankEC; k++){
02668 //                              x[session*_rankEC+i] += aux[session*_rankEC+k] * invl[i*_rankEC+k];
02669 //                      }
02670 //              }
02671 
02672                 for(unsigned long i=0;i<_rankEC;i++){
02673                         for(unsigned long j=0;j<_rankEC;j++){
02674                                         invl[i*_rankEC+j] += x[session*_rankEC+i]*x[session*_rankEC+j];
02675                         }
02676                 }
02677 
02678                 for(unsigned long dis = 0; dis<_n_distrib;dis++){
02679                         for(unsigned long i=0;i<_rankEC;i++){
02680                                 for(unsigned long j = 0;j<_rankEC;j++){
02681                                         _Aec[dis](i,j) += invl[i*_rankEC+j] * n_h[session*_n_distrib+dis];
02682 
02683                                 }
02684                         }
02685                 }
02686 
02687                 for(unsigned long i=0;i<_rankEC;i++){
02688                         for(unsigned long j=0;j<_svSize;j++){
02689                                         c[i*_svSize+j] += x[session*_rankEC+i] * f_x_h[session*_svSize+j];
02690                         }
02691                 }
02692         }
02693 }
02694 //******************************************
02695 // FIN D'AJOUT POUR LE LFA VERSION DRISS
02696 //******************************************
02697 
02698 
02699 
02700 
02701 
02702 
02703 
02704 
02705 
02706 
02707 
02708 
02709 
02710 
02711 
02712 
02713 
02714 
02715 
02716 //----------------------------------------------------------------------------------------------------------------------------------------------------------
02717 void JFAAcc::estimateZandD(){   //estimate Z and D
02718         
02719         if (verboseLevel>=1) cout << "(AccumulateJFAStat) Compute Z and D Estimate "<<endl;
02720         _Z.setAllValues(0.0);
02721         
02722         DoubleVector aux1(_svSize, _svSize), aux2(_svSize, _svSize);
02723         aux1.setAllValues(0.0); aux2.setAllValues(0.0);
02724         
02725         double *f_x, *n, *z;
02726         f_x=_F_X.getArray(); n=_matN.getArray(); z=_Z.getArray();
02727 
02728         for(unsigned long spk=0; spk<_n_speakers;spk++){
02729                 
02730                 DoubleVector L(_svSize, _svSize);
02731                 L.setAllValues(0.0);
02732                 
02733                 for(unsigned long i=0; i<_n_distrib; i++){
02734                         for(unsigned long j=0; j<_vectSize; j++){
02735                                 L[i*_vectSize+j] = 1 + _matN(spk,i) * _ubm_invvar[i*_vectSize+j] * _D[i*_vectSize+j] * _D[i*_vectSize+j];
02736                                 _Z(spk,i*_vectSize+j) = _F_X(spk,i*_vectSize+j) * _ubm_invvar[i*_vectSize+j] * _D[i*_vectSize+j] / L[i*_vectSize+j];
02737                         }
02738                 }
02739 
02740                 for(unsigned long i=0;i<_n_distrib;i++){
02741                         for(unsigned long j=0;j<_vectSize;j++){
02742                                 aux1[i * _vectSize +j] += ( 1 / L[i*_vectSize + j] + _Z(spk,i*_vectSize +j) * _Z(spk,i*_vectSize +j) ) * _matN(spk, i);
02743                                 aux2[i*_vectSize+j] += _Z(spk,i*_vectSize +j) * _F_X(spk,i*_vectSize+j);
02744                                 
02745                         }
02746                 }
02747         }
02748         
02749         for(unsigned long i=0;i<_svSize;i++){
02750                 _D[i] = aux2[i] / aux1[i];
02751         }
02752 }
02753 
02754 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
02755 void JFAAcc::estimateYX(){      //estimate X and Y at the same time for all speakers
02756 
02757         if (verboseLevel>=1) cout << "(AccumulateJFAStat) Compute Y and X  Estimate "<<endl;
02758 
02759         _YX.setAllValues(0.0);
02760         Matrix<double> AUX(_n_speakers,_rankEV + _rankEC);
02761         AUX.setAllValues(0.0);
02762         
02763         double *yx, *vu, *f_x, *aux, *invVar;
02764         yx=_YX.getArray(); vu=_VU.getArray(); f_x=_F_X.getArray(); aux=AUX.getArray(); invVar=_ubm_invvar.getArray();
02765 
02766         //For each speaker
02767         for(unsigned long spk=0; spk<_n_speakers; spk++){
02768 
02769                 double *invl = _l_yx_inv[spk].getArray();
02770 
02771                 for(unsigned long i=0;i<_rankEV + _rankEC ;i++){
02772                         for(unsigned long k=0;k<_svSize;k++) {
02773                                 aux[spk*(_rankEV + _rankEC)+i] += f_x[spk*_svSize+k] * invVar[k] * vu[i*_svSize+k];
02774                         }
02775                 }
02776                 
02777                 //multiplication by invL
02778                 for(unsigned long i=0; i<_rankEV + _rankEC;i++){
02779                         for(unsigned long k=0; k<_rankEV + _rankEC; k++){
02780                                 yx[spk*(_rankEV + _rankEC)+i] += aux[spk*(_rankEV + _rankEC)+k] * invl[i*(_rankEV + _rankEC)+k];
02781                         }
02782                 }
02783         }
02784 }
02785 
02786 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
02787 void JFAAcc::estimateZ(){       //estimate Z for all speakers during the training phase
02788         
02789         if (verboseLevel>=1) cout << "(AccumulateJFAStat) Compute Z Estimate during the training phase "<<endl;
02790         _Z.setAllValues(0.0);
02791         
02792         DoubleVector aux1(_svSize, _svSize), aux2(_svSize, _svSize);
02793         aux1.setAllValues(0.0); aux2.setAllValues(0.0);
02794         DoubleVector L(_svSize, _svSize);
02795 
02796         double *z, *n, *f_x;
02797         z=_Z.getArray(); n=_matN.getArray(); f_x=_F_X.getArray();
02798         
02799         for(unsigned long spk=0; spk<_n_speakers;spk++){
02800 
02801                 L.setAllValues(0.0);
02802                 
02803                 for(unsigned long i=0; i<_n_distrib; i++){
02804                         for(unsigned long j=0; j<_vectSize; j++){
02805                                 L[i*_vectSize+j] = 1 + _matN(spk,i) * _ubm_invvar[i*_vectSize+j] * _D[i*_vectSize+j] * _D[i*_vectSize+j];
02806                                 _Z(spk,i*_vectSize+j) = _F_X(spk,i*_vectSize+j) * _ubm_invvar[i*_vectSize+j] * _D[i*_vectSize+j] / L[i*_vectSize+j];
02807                         }
02808                 }
02809         }
02810 }
02811 
02812 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
02813 void JFAAcc::estimateZMAP(unsigned long tau){   //estimate Z for all speakers during the training phase
02814         
02815         if (verboseLevel>=1) cout << "(AccumulateJFAStat) Compute Z MAP estimate during the training phase "<<endl;
02816         _Z.setAllValues(0.0);
02817         
02818         DoubleVector aux1(_svSize, _svSize), aux2(_svSize, _svSize);
02819         aux1.setAllValues(0.0); aux2.setAllValues(0.0);
02820 
02821         double *z, *n, *f_x;
02822         z=_Z.getArray(); n=_matN.getArray(); f_x=_F_X.getArray();
02823         
02824         for(unsigned long spk=0; spk<_n_speakers;spk++){
02825                 for(unsigned long i=0; i<_n_distrib; i++){
02826                         for(unsigned long j=0; j<_vectSize; j++){
02827                                 _Z(spk,i*_vectSize+j) = (tau/(tau + _matN(spk,i))) * _D[i*_vectSize+j] * _ubm_invvar[i*_vectSize+j] * _F_X(spk,i*_vectSize+j);
02828 
02829                         }
02830                 }
02831         }
02832 }
02833 
02834 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
02835 void JFAAcc::updateVestimate(){
02836 
02837         Matrix<double> tmpC; tmpC.setDimensions(_rankEV, _svSize); tmpC.setAllValues(0.0);
02838         
02839         for(unsigned long d=0;d<_n_distrib;d++){
02840                 DoubleSquareMatrix invA;
02841                 invA.setSize(_rankEV);
02842                 _Aev[d].invert(invA);
02843                 
02844                 double *tmpc, * inva, *cev;
02845                 tmpc=tmpC.getArray(); inva=invA.getArray(); cev=_Cev.getArray();
02846                 
02847                 for(unsigned long i=0; i<_rankEV;i++){
02848                         for(unsigned long j=0; j<_vectSize;j++){
02849                                 for(unsigned long k=0; k<_rankEV;k++){
02850                                         tmpC(i,d*_vectSize+j) += invA(i,k) *  _Cev(k,d*_vectSize+j);
02851                                 }
02852                         }
02853                 }
02854         }
02855         _Cev=tmpC;
02856         _V=_Cev;
02857 }
02858 
02859 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
02860 void JFAAcc::updateUestimate(){
02861 
02862         Matrix<double> tmpC; tmpC.setDimensions(_rankEC, _svSize); tmpC.setAllValues(0.0);
02863         for(unsigned long d=0;d<_n_distrib;d++){
02864                 DoubleSquareMatrix invA;
02865                 invA.setSize(_rankEC);
02866                 _Aec[d].invert(invA);
02867 
02868                 double *tmpc, * inva, *cec;
02869                 tmpc=tmpC.getArray(); inva=invA.getArray(); cec=_Cec.getArray();
02870                 
02871                 for(unsigned long i=0; i<_rankEC;i++){
02872                         for(unsigned long j=0; j<_vectSize;j++){
02873                                 for(unsigned long k=0; k<_rankEC;k++){
02874                                         tmpC(i,d*_vectSize+j) += invA(i,k) *  _Cec(k,d*_vectSize+j);
02875                                 }
02876                         }
02877                 }
02878         }
02879         _Cec=tmpC;
02880         _matU=_Cec;
02881 }
02882 
02883 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
02884 XList& JFAAcc::getXList(){
02885         return(_fileList);
02886 }
02887 
02888 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
02889 unsigned long JFAAcc::getNSpeakers(){
02890         return(_n_speakers);
02891 }
02892 
02893 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
02894 unsigned long JFAAcc::getNSessions(){
02895         return(_n_sessions);
02896 }
02897 
02898 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
02899 unsigned long JFAAcc::getNDistrib(){
02900         return(_n_distrib);
02901 }
02902 
02903 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
02904 unsigned long JFAAcc::getVectSize(){
02905         return(_vectSize);
02906 }
02907 
02908 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
02909 unsigned long JFAAcc::getSvSize(){
02910         return(_svSize);
02911 }
02912 
02913 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
02914 unsigned long JFAAcc::getRankEV(){
02915         return(_rankEV);
02916 }
02917 
02918 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
02919 unsigned long JFAAcc::getRankEC(){
02920         return(_rankEC);
02921 }
02922 
02923 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
02924 DoubleVector& JFAAcc::getUbmMeans(){
02925         return(_ubm_means);
02926 }
02927 
02928 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
02929 DoubleVector& JFAAcc::getUbmInvVar(){
02930         return(_ubm_invvar);
02931 }
02932 
02933 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
02934 Matrix<double> JFAAcc::getV(){
02935         return(_V);
02936 }
02937 
02938 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
02939 Matrix<double> JFAAcc::getU(){
02940         return(_matU);
02941 }
02942 
02943 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
02944 DoubleVector JFAAcc::getD(){
02945         return(_D);
02946 }
02947 
02948 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
02949 Matrix<double> JFAAcc::getVU(){
02950         return(_VU);
02951 }
02952 
02953 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
02954 Matrix<double> JFAAcc::getY(){
02955         return(_Y);
02956 }
02957 
02958 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
02959 Matrix<double> JFAAcc::getX(){
02960         return(_matX);
02961 }
02962 
02963 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
02964 Matrix<double> JFAAcc::getZ(){
02965         return(_Z);
02966 }
02967 
02968 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
02969 Matrix<double> JFAAcc::getYX(){
02970         return(_YX);
02971 }
02972 
02973 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
02974 Matrix <double>& JFAAcc::getN() {
02975         return _matN;
02976 }       
02977         
02978 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
02979 Matrix <double>& JFAAcc::getN_h() {
02980         return _N_h;
02981 }
02982         
02983 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
02984 Matrix <double>& JFAAcc::getF_X() {
02985         return _F_X;
02986 }       
02987         
02988 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
02989 Matrix <double>& JFAAcc::getF_X_h() {
02990         return _F_X_h;
02991 }
02992 
02993 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
02994 void JFAAcc::splitYX(){
02995         _Y= _YX.crop(0,0, _n_speakers, _rankEV);
02996         _matX= _YX.crop(0,_rankEV, _n_speakers, _rankEC);
02997 }
02998 
02999 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
03000 void JFAAcc::storeAccs(){ // save JFA state in temporary variables
03001                 _cF_X=_F_X;
03002                 _cF_X_h=_F_X_h;
03003                 _cN_h=_N_h; 
03004                 _cN=_matN;
03005                 if (verboseLevel>=1) cout << "(AccumulateJFAStat) JFA Accs states stored" << endl;
03006 }
03007 
03008 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
03009 void JFAAcc::restoreAccs() {    // Restore Accumulators in temporary variables
03010         _matN=_cN;
03011         _N_h=_cN_h;     
03012         _F_X=_cF_X;
03013         _F_X_h=_cF_X_h;
03014         if (verboseLevel>=1) cout << "(AccumulateJFAStat) JFA Accs states restored" << endl;                    
03015 }
03016         
03017 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
03018 void JFAAcc::substractMplusDZ(Config & config){
03019         #ifdef THREAD          
03020         if (config.existsParam("numThread") && config.getParam("numThread").toLong() >0)        substractMplusDZThreaded(config.getParam("numThread").toLong());
03021         else substractMplusDZUnThreaded();
03022         #else
03023         substractMplusDZUnThreaded();
03024         #endif
03025 }
03026 
03027 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
03028 void JFAAcc::substractMplusDZUnThreaded(){
03029         
03030         if (verboseLevel >= 1) cout <<"(AccumulateJFAStat) Compute and Substract Speaker FA Stats M + DZ " << endl;     
03031 
03032         double *F_X = _F_X.getArray();
03033         
03034         for(unsigned long spk=0; spk<_n_speakers; spk++){
03035                 //Compute M+DZ for the current speaker
03036                 DoubleVector MplusDZ; MplusDZ.setSize(_svSize); MplusDZ.setAllValues(0.0);
03037                 double *mplusdz=MplusDZ.getArray();
03038                 this->getMplusDZ(MplusDZ,spk);
03039 
03040                 double *n=_matN.getArray();
03041                 
03042                 //Substract M+DZ
03043                 for(unsigned long i=0; i<_n_distrib; i++){
03044                         for(unsigned long j = 0; j< _vectSize;j++){
03045                                 F_X[spk*_svSize+i*_vectSize+j] -= mplusdz[i*_vectSize+j]*n[spk*_n_distrib+i];
03046                         }
03047                 }
03048         }
03049 }
03050 
03051 
03052 #ifdef THREAD
03053 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
03054 //                              Data strucutre of thread
03055 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
03056 struct S_MplusDZthread_data{
03057         double *N;
03058         double *F_X;
03059         double *D;
03060         double *Z;
03061         double *ubm_means;
03062         unsigned long spkBottom;
03063         unsigned long spkUp;    
03064         unsigned long vectSize;
03065         unsigned long svSize;
03066         unsigned long n_distrib;
03067         unsigned long nt;
03068 };
03069 
03070 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
03071 //                              Thread Routine
03072 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
03073 void *S_MplusDZthread(void *threadarg) {
03074         struct S_MplusDZthread_data *my_data;
03075         my_data = (struct S_MplusDZthread_data *) threadarg;
03076 
03077         double *n = my_data->N;
03078         double *f_x = my_data->F_X;
03079         double *d = my_data->D;
03080         double *z = my_data->Z;
03081         double *ubm_means = my_data->ubm_means;
03082         unsigned long spkBottom = my_data->spkBottom;   
03083         unsigned long spkUp = my_data->spkUp;
03084         unsigned long _vectSize=my_data->vectSize;
03085         unsigned long _svSize=my_data->svSize;
03086         unsigned long _n_distrib=my_data->n_distrib;
03087 
03088         for(unsigned long spk=spkBottom; spk<spkUp; spk++){
03089                 //Compute M+DZ for the current speaker
03090                 DoubleVector MplusDZ; MplusDZ.setSize(_svSize); MplusDZ.setAllValues(0.0);
03091                 for (unsigned long i=0;i<_svSize;i++){
03092                         MplusDZ[i]=ubm_means[i]+d[i] * z[spk*_svSize+i];
03093                 }
03094 
03095                 //Substract M+DZ
03096                 for(unsigned long i=0; i<_n_distrib; i++){
03097                         for(unsigned long j = 0; j< _vectSize;j++){
03098                                 f_x[spk*_svSize+i*_vectSize+j] -= MplusDZ[i*_vectSize+j]*n[spk*_n_distrib+i];
03099                         }
03100                 }
03101         }
03102         pthread_exit((void*) 0);
03103         return (void*)0 ;
03104 }
03105 
03106 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
03107 void JFAAcc::substractMplusDZThreaded(unsigned long NUM_THREADS){
03108         
03109         if (verboseLevel >= 1) cout <<"(AccumulateJFAStat) Compute and Substract Speaker FA Stats M + DZ Threaded" << endl;
03110         if (NUM_THREADS==0) throw Exception("Num threads can not be 0",__FILE__,__LINE__);
03111 
03112         int rc, status;
03113         if (NUM_THREADS > _n_speakers) NUM_THREADS=_n_speakers;
03114 
03115         struct S_MplusDZthread_data *thread_data_array = new S_MplusDZthread_data[NUM_THREADS];
03116         pthread_t *threads = new pthread_t[NUM_THREADS];
03117 
03118         pthread_attr_t attr;
03119         pthread_attr_init(&attr);
03120         pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
03121         unsigned long offset=_n_speakers/NUM_THREADS;
03122         
03123         double *N=_matN.getArray(); 
03124         double *F_X=_F_X.getArray();
03125         double *D=_D.getArray();
03126         double *Z=_Z.getArray();
03127         double *ubm_means=_ubm_means.getArray();
03128         unsigned long spkBottom = 0;
03129         unsigned long spkUp=0;
03130         unsigned long re=_n_speakers - NUM_THREADS*offset;
03131         
03132         //Create threads
03133         for(unsigned long t=0; t<NUM_THREADS; t++){
03134                 spkUp = spkBottom +offset;
03135                 if(t<re) spkUp +=1;
03136 
03137                 thread_data_array[t].N=N;
03138                 thread_data_array[t].F_X=F_X;
03139                 thread_data_array[t].D=D;
03140                 thread_data_array[t].Z=Z;
03141                 thread_data_array[t].ubm_means=ubm_means;
03142                 thread_data_array[t].spkBottom=spkBottom;
03143                 thread_data_array[t].spkUp=spkUp;
03144                 thread_data_array[t].vectSize=_vectSize;
03145                 thread_data_array[t].svSize=_svSize;
03146                 thread_data_array[t].n_distrib=_n_distrib;
03147 
03148                 if (verboseLevel>1) cout<<"(AccumulateJFAStat) Creating thread n["<< t<< "] for speakers ["<<spkBottom<<"-->"<<spkUp-1<<"]"<<endl;
03149                 rc = pthread_create(&threads[t], &attr, S_MplusDZthread, (void *)&thread_data_array[t]);
03150                 if (rc) throw Exception("ERROR; return code from pthread_create() is ",__FILE__,rc);
03151                 
03152                 spkBottom = spkUp;
03153         }
03154         
03155         pthread_attr_destroy(&attr);
03156         for(unsigned long t=0; t<NUM_THREADS; t++) {
03157                 rc = pthread_join(threads[t], (void **)&status);
03158                 if (rc)  throw Exception("ERROR; return code from pthread_join() is ",__FILE__,rc);
03159                 if (verboseLevel>1) cout <<"(AccumulateJFAStat) Completed join with thread ["<<t<<"] status["<<status<<"]"<<endl;
03160         }
03161 
03162         free(thread_data_array);
03163         free(threads);
03164 
03165         if (verboseLevel >= 1) cout << "(AccumulateJFAStat) Done " << endl;
03166 }
03167 
03168 #endif
03169 
03170 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
03171 void JFAAcc::substractMplusDZByChannel(){
03172         
03173         if (verboseLevel >= 1) cout <<"(AccumulateJFAStat) Compute and Substract Speaker FA Stats M + DZ " << endl;     
03174 
03175         double *F_X_h = _F_X_h.getArray();
03176         double *N_h = _N_h.getArray();
03177 
03178         XLine *pline; String *pFile; _fileList.rewind();
03179 
03180         unsigned long spk =0;
03181         unsigned long sess=0;
03182 
03183         while((pline=_fileList.getLine())!=NULL) {
03184 
03185                 DoubleVector MplusDZ; MplusDZ.setSize(_svSize); MplusDZ.setAllValues(0.0);
03186                 double *mplusdz=MplusDZ.getArray();
03187 
03188                 while((pFile=pline->getElement())!=NULL) {
03189 
03190                 this->getMplusDZ(MplusDZ,spk);
03191 
03192                         for(unsigned long k=0;k<_n_distrib;k++) 
03193                                 for (unsigned long i=0;i<_vectSize;i++) 
03194                                         F_X_h[sess*_svSize+(k*_vectSize+i)]-= N_h[sess*_n_distrib+k]*MplusDZ[i+k*_vectSize];
03195                         sess++;
03196                 }
03197                 spk++;
03198         }
03199 }
03200 
03201 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
03202 void JFAAcc::substractMplusVY(Config &config){
03203         #ifdef THREAD          
03204         if (config.existsParam("numThread") && config.getParam("numThread").toLong() >0)        substractMplusVYThreaded(config.getParam("numThread").toLong());
03205         else substractMplusVYUnThreaded();
03206         #else
03207         substractMplusVYUnThreaded();
03208         #endif
03209 }
03210 
03211 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
03212 void JFAAcc::substractMplusVYUnThreaded(){
03213         
03214         if (verboseLevel >= 1) cout <<"(AccumulateJFAStat) Compute and Substract Speaker FA Stats M + VY" << endl;      
03215 
03216         double *f_x = _F_X.getArray();
03217         
03218         for(unsigned long spk=0; spk<_n_speakers; spk++){
03219                 //compute M+VY for the current speaker
03220                 DoubleVector MplusVY; MplusVY.setSize(_svSize); MplusVY.setAllValues(0.0);
03221                 double *mplusvy=MplusVY.getArray();
03222                 this->getMplusVY(MplusVY,spk);
03223                 double *n=_matN.getArray();
03224 
03225                 //substract M+VY
03226                 for(unsigned long i=0; i<_n_distrib; i++){
03227                         for(unsigned long j = 0; j< _vectSize;j++){
03228                                 f_x[spk*_svSize+i*_vectSize+j] -= mplusvy[i*_vectSize+j]*n[spk*_n_distrib+i];
03229                         }
03230                 }
03231         }
03232 }
03233 
03234 #ifdef THREAD
03235 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
03236 //                              Data strucutre of thread
03237 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
03238 struct S_MplusVYthread_data{
03239         double *N;
03240         double *F_X;
03241         double *V;
03242         double *Y;
03243         double *ubm_means;
03244         unsigned long spkBottom;
03245         unsigned long spkUp;    
03246         unsigned long vectSize;
03247         unsigned long svSize;
03248         unsigned long n_distrib;
03249         unsigned long rankEV;
03250         unsigned long nt;
03251 };
03252 
03253 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
03254 //                              Thread Routine
03255 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
03256 void *S_MplusVYthread(void *threadarg) {
03257         
03258         struct S_MplusVYthread_data *my_data;
03259         my_data = (struct S_MplusVYthread_data *) threadarg;
03260 
03261         double *n = my_data->N;
03262         double *f_x = my_data->F_X;
03263         double *v = my_data->V;
03264         double *y = my_data->Y;
03265         double *ubm_means = my_data->ubm_means;
03266         unsigned long spkBottom = my_data->spkBottom;   
03267         unsigned long spkUp = my_data->spkUp;
03268         unsigned long _vectSize=my_data->vectSize;
03269         unsigned long _svSize=my_data->svSize;
03270         unsigned long _n_distrib=my_data->n_distrib;
03271         unsigned long _rankEV=my_data->rankEV;
03272 
03273         DoubleVector MplusVY;MplusVY.setSize(_svSize);
03274         double* mplusvy=MplusVY.getArray();     
03275 
03276         for(unsigned long spk=spkBottom; spk<spkUp;spk++){
03277 
03278                 //compute M+VY for the current speaker
03279                 MplusVY.setAllValues(0.0);
03280 
03281                 //Calcul de mplusvy
03282                 for (unsigned long i=0;i<_svSize;i++){
03283                         for (unsigned long j=0;j<_rankEV;j++){
03284                                 mplusvy[i] += v[j*_svSize + i] * y[spk*_rankEV + j ];
03285                         }
03286                         //Ajout de M
03287                         mplusvy[i] += ubm_means[i];
03288                 }
03289                 //substract M+VY
03290                 for(unsigned long i=0; i<_n_distrib; i++){
03291                         for(unsigned long j = 0; j< _vectSize;j++){
03292                                 f_x[spk*_svSize+i*_vectSize+j] -= mplusvy[i*_vectSize+j]*n[spk*_n_distrib+i];
03293                         }
03294                 }
03295         }
03296         pthread_exit((void*) 0);
03297         return (void*)0 ;
03298 }
03299 
03300 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
03301 void JFAAcc::substractMplusVYThreaded(unsigned long NUM_THREADS){
03302         
03303         if (verboseLevel >= 1) cout <<"(AccumulateJFAStat) Compute and Substract Speaker FA Stats M + VY Threaded" << endl;
03304         if (NUM_THREADS==0) throw Exception("Num threads can not be 0",__FILE__,__LINE__);
03305 
03306         int rc, status;
03307         if (NUM_THREADS > _n_speakers) NUM_THREADS=_n_speakers;
03308 
03309         struct S_MplusVYthread_data *thread_data_array = new S_MplusVYthread_data[NUM_THREADS];
03310         pthread_t *threads = new pthread_t[NUM_THREADS];
03311 
03312         pthread_attr_t attr;
03313         pthread_attr_init(&attr);
03314         pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
03315         unsigned long offset=_n_speakers/NUM_THREADS;
03316         
03317         double *N=_matN.getArray(); 
03318         double *F_X=_F_X.getArray();
03319         double *V=_V.getArray();
03320         double *Y=_Y.getArray();
03321         double *ubm_means = _ubm_means.getArray();
03322         unsigned long spkBottom = 0;
03323         unsigned long spkUp=0;
03324         unsigned long re=_n_speakers - NUM_THREADS*offset;
03325         
03326         //Create threads
03327         for(unsigned long t=0; t<NUM_THREADS; t++){
03328                 spkUp = spkBottom +offset;
03329                 if(t<re) spkUp +=1;
03330 
03331                 thread_data_array[t].N=N;
03332                 thread_data_array[t].F_X=F_X;
03333                 thread_data_array[t].V=V;
03334                 thread_data_array[t].Y=Y;
03335                 thread_data_array[t].ubm_means=ubm_means;
03336                 thread_data_array[t].spkBottom=spkBottom;
03337                 thread_data_array[t].spkUp=spkUp;
03338                 thread_data_array[t].vectSize=_vectSize;
03339                 thread_data_array[t].svSize=_svSize;
03340                 thread_data_array[t].n_distrib=_n_distrib;
03341                 thread_data_array[t].rankEV=_rankEV;
03342 
03343                 if (verboseLevel>1) cout<<"(AccumulateJFAStat) Creating thread n["<< t<< "] for speakers ["<<spkBottom<<"-->"<<spkUp-1<<"]"<<endl;
03344                 rc = pthread_create(&threads[t], &attr, S_MplusVYthread, (void *)&thread_data_array[t]);
03345                 if (rc) throw Exception("ERROR; return code from pthread_create() is ",__FILE__,rc);
03346                 
03347                 spkBottom = spkUp;
03348         }
03349         
03350         pthread_attr_destroy(&attr);
03351         for(unsigned long t=0; t<NUM_THREADS; t++) {
03352                 rc = pthread_join(threads[t], (void **)&status);
03353                 if (rc)  throw Exception("ERROR; return code from pthread_join() is ",__FILE__,rc);
03354                 if (verboseLevel>1) cout <<"(AccumulateJFAStat) Completed join with thread ["<<t<<"] status["<<status<<"]"<<endl;
03355         }
03356 
03357         free(thread_data_array);
03358         free(threads);
03359 
03360         if (verboseLevel >= 1) cout << "(AccumulateJFAStat) Done " << endl;
03361 }
03362 
03363 #endif
03364 
03365 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
03366 void JFAAcc::substractUX(Config &config){
03367         #ifdef THREAD          
03368         if (config.existsParam("numThread") && config.getParam("numThread").toLong() >0)        substractUXThreaded(config.getParam("numThread").toLong());
03369         else substractUXUnThreaded();
03370         #else
03371         substractUXUnThreaded();
03372         #endif
03373 }
03374         
03375 //-----------------------------------------------------------------------------------------------------------------------------------------------------------   
03376 void JFAAcc::substractUXUnThreaded(){
03377 
03378         if (verboseLevel >= 1) cout <<"(AccumulateJFAStat) Compute and Substract Speaker FA Stats UX " << endl;
03379 
03380         unsigned long spk=0;
03381         unsigned long session=0; 
03382         XLine *pline; String *pFile; 
03383         _fileList.rewind();
03384 
03385         DoubleVector UX;UX.setSize(_svSize); UX.setAllValues(0.0);
03386         double* ux=UX.getArray();       
03387         double *f_x = _F_X.getArray();
03388         double *n_h=_N_h.getArray(); 
03389 
03390         while((pline=_fileList.getLine())!=NULL) {              
03391                 while((pFile=pline->getElement())!=NULL) {      
03392                         this->getUX(UX,*pFile);
03393 
03394                         for(unsigned long k=0;k<_n_distrib;k++)
03395                                 for (unsigned long i=0;i<_vectSize;i++)
03396                                         f_x[spk*_svSize+k*_vectSize+i] -= n_h[session*_n_distrib+k]*ux[i+k*_vectSize];
03397                         session++;
03398                 }
03399                 spk++;
03400         }
03401 }
03402 
03403 #ifdef THREAD
03404 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
03405 //                              Data strucutre of thread
03406 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
03407 struct S_UXthread_data{
03408         double *N_h;
03409         double *F_X;
03410         double *U;
03411         double *X;
03412         RefVector<DoubleVector>* sessIdx;
03413         unsigned long spkBottom;
03414         unsigned long spkUp;    
03415         unsigned long vectSize;
03416         unsigned long svSize;
03417         unsigned long n_distrib;
03418         unsigned long rankEC;
03419         unsigned long nt;
03420 };
03421 
03422 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
03423 //                              Thread Routine
03424 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
03425 void *S_UXthread(void *threadarg) {
03426         struct S_UXthread_data *my_data;
03427         my_data = (struct S_UXthread_data *) threadarg;
03428 
03429         double *n_h = my_data->N_h;
03430         double *f_x = my_data->F_X;
03431         double *u = my_data->U;
03432         double *x = my_data->X;
03433         unsigned long spkBottom = my_data->spkBottom;   
03434         unsigned long spkUp = my_data->spkUp;
03435         unsigned long _vectSize=my_data->vectSize;
03436         unsigned long _svSize=my_data->svSize;
03437         unsigned long _n_distrib=my_data->n_distrib;
03438         unsigned long _rankEC=my_data->rankEC;
03439 
03440 
03441         DoubleVector UX;UX.setSize(_svSize);
03442         double* ux=UX.getArray();       
03443 
03444         for(unsigned long spk=spkBottom; spk<spkUp;spk++){
03445 
03446                 DoubleVector &sessIdx =(*(my_data->sessIdx))[spk];
03447 
03448                 for(unsigned long sess=0; sess<sessIdx.size(); sess++){
03449 
03450                         //getUX
03451                         UX.setAllValues(0.0);
03452                         unsigned long idx = (unsigned long)sessIdx[sess];
03453 
03454                         for (unsigned long i=0;i<_svSize;i++){
03455                                 for (unsigned long j=0;j<_rankEC;j++) {
03456                                         ux[i]+=u[j*_svSize+i]*x[idx*_rankEC+j];
03457                                 }
03458                         }
03459                         //
03460                         for(unsigned long k=0;k<_n_distrib;k++){
03461                                 for (unsigned long i=0;i<_vectSize;i++){
03462                                         f_x[spk*_svSize+k*_vectSize+i] -= n_h[idx*_n_distrib+k]*ux[i+k*_vectSize];
03463                                 }
03464                         }
03465                 }
03466         }
03467         pthread_exit((void*) 0);
03468         return (void*)0 ;
03469 }
03470 
03471 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
03472 void JFAAcc::substractUXThreaded(unsigned long NUM_THREADS){
03473         
03474         if (verboseLevel >= 1) cout <<"(AccumulateJFAStat) Compute and Substract Channel JFA Stats UX Threaded" << endl;
03475         if (NUM_THREADS==0) throw Exception("Num threads can not be 0",__FILE__,__LINE__);
03476 
03477         int rc, status;
03478         if (NUM_THREADS > _n_speakers) NUM_THREADS=_n_speakers;
03479 
03480         struct S_UXthread_data *thread_data_array = new S_UXthread_data[NUM_THREADS];
03481         pthread_t *threads = new pthread_t[NUM_THREADS];
03482 
03483         pthread_attr_t attr;
03484         pthread_attr_init(&attr);
03485         pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
03486         unsigned long offset=_n_speakers/NUM_THREADS;
03487         
03488         double *N_h=_N_h.getArray(); 
03489         double *F_X=_F_X.getArray();
03490         double *U=_matU.getArray();
03491         double *X=_matX.getArray();
03492 
03493         RefVector<DoubleVector> sessIdx(_n_speakers);
03494         DoubleVector tmpSessIdx(0);
03495 
03496         for(unsigned long i=0; i<_n_speakers; i++){
03497                 sessIdx.addObject(*new DoubleVector(tmpSessIdx));
03498         }
03499 
03500         _fileList.rewind(); XLine *pline; String *pfile;
03501         unsigned long tmpS=0;
03502         unsigned long tmpSpk =0;
03503         while((pline=_fileList.getLine()) != NULL){
03504                 while((pfile=pline->getElement())!=NULL){
03505                         sessIdx[tmpSpk].addValue(tmpS);
03506                         tmpS++;
03507                 }
03508                 tmpSpk++;
03509         }
03510 
03511         unsigned long spkBottom = 0;
03512         unsigned long spkUp=0;
03513         unsigned long re=_n_speakers - NUM_THREADS*offset;
03514         
03515         //Create threads
03516         for(unsigned long t=0; t<NUM_THREADS; t++){
03517                 spkUp = spkBottom +offset;
03518                 if(t<re) spkUp +=1;
03519 
03520                 thread_data_array[t].N_h=N_h;
03521                 thread_data_array[t].F_X=F_X;
03522                 thread_data_array[t].U=U;
03523                 thread_data_array[t].X=X;
03524                 thread_data_array[t].sessIdx=&(sessIdx);
03525 
03526 
03527                 thread_data_array[t].spkBottom=spkBottom;
03528                 thread_data_array[t].spkUp=spkUp;
03529                 thread_data_array[t].vectSize=_vectSize;
03530                 thread_data_array[t].svSize=_svSize;
03531                 thread_data_array[t].n_distrib=_n_distrib;
03532                 thread_data_array[t].rankEC=_rankEC;
03533 
03534                 if (verboseLevel>1) cout<<"(AccumulateJFAStat) Creating thread n["<< t<< "] for speakers ["<<spkBottom<<"-->"<<spkUp-1<<"]"<<endl;
03535                 rc = pthread_create(&threads[t], &attr, S_UXthread, (void *)&thread_data_array[t]);
03536                 if (rc) throw Exception("ERROR; return code from pthread_create() is ",__FILE__,rc);
03537                 
03538                 spkBottom = spkUp;
03539         }
03540 
03541 
03542         pthread_attr_destroy(&attr);
03543         for(unsigned long t=0; t<NUM_THREADS; t++) {
03544                 rc = pthread_join(threads[t], (void **)&status);
03545                 if (rc)  throw Exception("ERROR; return code from pthread_join() is ",__FILE__,rc);
03546                 if (verboseLevel>1) cout <<"(AccumulateJFAStat) Completed join with thread ["<<t<<"] status["<<status<<"]"<<endl;
03547         }
03548 
03549         free(thread_data_array);
03550         free(threads);
03551 
03552         sessIdx.deleteAllObjects();
03553 
03554         if (verboseLevel >= 1) cout << "(AccumulateJFAStat) Done " << endl;
03555 }
03556 
03557 #endif
03558 
03559 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
03560 void JFAAcc::substractMplusUX(){
03561 
03562         if (verboseLevel >= 1) cout <<"(AccumulateJFAStat) Compute and Substract Speaker FA Stats UX " << endl;
03563 
03564         unsigned long spk=0;
03565         unsigned long session=0; 
03566         XLine *pline; String *pFile; 
03567         _fileList.rewind();
03568 
03569         DoubleVector MplusUX;MplusUX.setSize(_svSize); MplusUX.setAllValues(0.0);
03570         double* mplusux=MplusUX.getArray();     
03571         double *f_x = _F_X.getArray();
03572         double *n_h=_N_h.getArray(); 
03573 
03574         while((pline=_fileList.getLine())!=NULL) {              
03575                 while((pFile=pline->getElement())!=NULL) {      
03576                         this->getMplusUX(MplusUX,*pFile);                       
03577 
03578                         for(unsigned long k=0;k<_n_distrib;k++){
03579                                 for (unsigned long i=0;i<_vectSize;i++){
03580                                         f_x[spk*_svSize+k*_vectSize+i] -= n_h[session*_n_distrib+k] *  mplusux[i+k*_vectSize];
03581                                 }
03582                         }
03583                         session++;
03584                 }
03585                 spk++;
03586         }
03587 }
03588 
03589 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
03590 void JFAAcc::substractMplusVUYX(){
03591         
03592         if (verboseLevel >= 1) cout <<"(AccumulateJFAStat) Compute and Substract Speaker FA Stats M + VUYX" << endl;    
03593 
03594         double *f_x = _F_X.getArray();
03595 
03596         for(unsigned long spk=0; spk<_n_speakers; spk++){
03597                 //compute M+VUYX for the current speaker
03598                 DoubleVector MplusVUYX; MplusVUYX.setSize(_svSize); MplusVUYX.setAllValues(0.0);
03599                 double *mplusvuyx=MplusVUYX.getArray();
03600                 this->getMplusVUYX(MplusVUYX,spk);
03601 
03602                 double *n=_matN.getArray();
03603                 
03604                 //substract M+VUYX
03605                 for(unsigned long i=0; i<_n_distrib; i++){
03606                         for(unsigned long j = 0; j< _vectSize;j++){
03607                                 f_x[spk*_svSize+i*_vectSize+j] -= mplusvuyx[i*_vectSize+j]*n[spk*_n_distrib+i];
03608                         }
03609                 }
03610         }
03611 }
03612 
03613 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
03614 void JFAAcc::substractMplusVYplusDZ(Config &config){
03615         #ifdef THREAD          
03616         if (config.existsParam("numThread") && config.getParam("numThread").toLong() >0)        substractMplusVYplusDZThreaded(config.getParam("numThread").toLong());
03617         else substractMplusVYplusDZUnThreaded();
03618         #else
03619         substractMplusVYplusDZUnThreaded();
03620         #endif
03621 }
03622 
03623 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
03624 void JFAAcc::substractMplusVYplusDZUnThreaded(){
03625         
03626         if (verboseLevel >= 1) cout <<"(AccumulateJFAStat) Compute and Substract Speaker FA Stats M + VY + DZ unthreaded" << endl;      
03627 
03628         DoubleVector MplusVYplusDZ(_svSize,_svSize);
03629         MplusVYplusDZ.setAllValues(0.0); 
03630         double *m_vy_dz=MplusVYplusDZ.getArray();  
03631         
03632         // Compute Occupations and Statistics
03633         unsigned long spk=0; 
03634         unsigned long session=0;                
03635         XLine *pline; String *pFile; _fileList.rewind();
03636 
03637         double *n_h=_N_h.getArray(); 
03638         double *f_x_h=_F_X_h.getArray();
03639 
03640 
03641         while((pline=_fileList.getLine())!=NULL) {
03642 
03643                 this->getMplusVYplusDZ(MplusVYplusDZ,spk);
03644                 while((pFile=pline->getElement())!=NULL) {
03645                         for(unsigned long k=0;k<_n_distrib;k++){
03646                                 for (unsigned long i=0;i<_vectSize;i++){ 
03647                                         f_x_h[session*_svSize+k*_vectSize+i] -= n_h[session*_n_distrib+k]*m_vy_dz[i+k*_vectSize];
03648                                 }
03649                         }                       
03650                         session++;
03651                 }
03652                 spk++;
03653         }
03654 }
03655 
03656 #ifdef THREAD
03657 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
03658 //                              Data strucutre of thread
03659 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
03660 struct S_MplusVYplusDZthread_data{
03661         double *N_h;
03662         double *F_X_h;
03663         double *V;
03664         double *Y;
03665         double *D;
03666         double *Z;
03667         double *ubm_means;
03668         RefVector<DoubleVector>* sessIdx;
03669 
03670         unsigned long spkBottom;
03671         unsigned long spkUp;    
03672         unsigned long vectSize;
03673         unsigned long svSize;
03674         unsigned long n_distrib;
03675         unsigned long rankEV;
03676         unsigned long nt;
03677 };
03678 
03679 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
03680 //                              Thread Routine
03681 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
03682 void *S_MplusVYplusDZthread(void *threadarg) {
03683         struct S_MplusVYplusDZthread_data *my_data;
03684         my_data = (struct S_MplusVYplusDZthread_data *) threadarg;
03685 
03686         double *n_h = my_data->N_h;
03687         double *f_x_h = my_data->F_X_h;
03688         double *v = my_data->V;
03689         double *y = my_data->Y;
03690         double *d = my_data->D;
03691         double *z = my_data->Z;
03692         double *ubm_means = my_data->ubm_means;
03693         unsigned long spkBottom = my_data->spkBottom;   
03694         unsigned long spkUp = my_data->spkUp;
03695         unsigned long _vectSize=my_data->vectSize;
03696         unsigned long _svSize=my_data->svSize;
03697         unsigned long _n_distrib=my_data->n_distrib;
03698         unsigned long _rankEV=my_data->rankEV;
03699 
03700         DoubleVector Sp;Sp.setSize(_svSize);
03701         double* sp=Sp.getArray();
03702         
03703         for(unsigned long spk=spkBottom; spk<spkUp;spk++){
03704 
03705 
03706                 DoubleVector &sessIdx =(*(my_data->sessIdx))[spk];
03707 
03708                 for(unsigned long sess=0; sess<sessIdx.size(); sess++){
03709 
03710                         unsigned long idx = (unsigned long)sessIdx[sess];
03711 
03712                         Sp.setAllValues(0.0);
03713                         
03714                         //getMplusVYplusDZ
03715                         for (unsigned long i=0;i<_svSize;i++){
03716 
03717                                 //getVY
03718                                 for (unsigned long j=0;j<_rankEV;j++){
03719                                         sp[i] += v[j*_svSize + i] * y[spk*_rankEV + j ];
03720                                 }
03721 
03722                                 //add DZ
03723                                 sp[i] +=ubm_means[i] + d[i]*z[spk*_svSize+i];
03724                         }
03725 
03726                         for(unsigned long k=0;k<_n_distrib;k++){
03727                                 for (unsigned long i=0;i<_vectSize;i++){ 
03728                                         f_x_h[idx*_svSize+k*_vectSize+i] -= n_h[idx*_n_distrib+k]*sp[i+k*_vectSize];
03729                                 }
03730                         }
03731                 }
03732         }
03733         pthread_exit((void*) 0);
03734         return (void*)0 ;
03735 }
03736 
03737 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
03738 void JFAAcc::substractMplusVYplusDZThreaded(unsigned long NUM_THREADS){
03739         
03740         if (verboseLevel >= 1) cout <<"(AccumulateJFAStat) Compute and Substract Speaker FA Stats M + VY + DZ Threaded" << endl;
03741         if (NUM_THREADS==0) throw Exception("Num threads can not be 0",__FILE__,__LINE__);
03742 
03743         int rc, status;
03744         if (NUM_THREADS > _n_speakers) NUM_THREADS=_n_speakers;
03745 
03746         struct S_MplusVYplusDZthread_data *thread_data_array = new S_MplusVYplusDZthread_data[NUM_THREADS];
03747         pthread_t *threads = new pthread_t[NUM_THREADS];
03748 
03749         pthread_attr_t attr;
03750         pthread_attr_init(&attr);
03751         pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
03752         unsigned long offset=_n_speakers/NUM_THREADS;
03753         
03754         double *N_h=_N_h.getArray(); 
03755         double *F_X_h=_F_X_h.getArray();
03756         double *V=_V.getArray();
03757         double *Y=_Y.getArray();
03758         double *D=_D.getArray();
03759         double *Z=_Z.getArray();
03760         double *ubm_means=_ubm_means.getArray();
03761 
03762         RefVector<DoubleVector> sessIdx(_n_speakers);
03763         DoubleVector tmpSessIdx(0);
03764 
03765         for(unsigned long i=0; i<_n_speakers; i++){
03766                 sessIdx.addObject(*new DoubleVector(tmpSessIdx));
03767         }
03768 
03769         _fileList.rewind(); XLine *pline; String *pfile;
03770         unsigned long tmpS=0;
03771         unsigned long tmpSpk =0;
03772         while((pline=_fileList.getLine()) != NULL){
03773                 while((pfile=pline->getElement())!=NULL){
03774                         sessIdx[tmpSpk].addValue(tmpS);
03775                         tmpS++;
03776                 }
03777                 tmpSpk++;
03778         }
03779 
03780         unsigned long spkBottom = 0;
03781         unsigned long spkUp=0;
03782         unsigned long re=_n_speakers - NUM_THREADS*offset;
03783         
03784         //Create threads
03785         for(unsigned long t=0; t<NUM_THREADS; t++){
03786                 spkUp = spkBottom +offset;
03787                 if(t<re) spkUp +=1;
03788 
03789                 thread_data_array[t].N_h=N_h;
03790                 thread_data_array[t].F_X_h=F_X_h;
03791                 thread_data_array[t].V=V;
03792                 thread_data_array[t].Y=Y;
03793                 thread_data_array[t].D=D;
03794                 thread_data_array[t].Z=Z;
03795                 thread_data_array[t].ubm_means=ubm_means;
03796                 thread_data_array[t].sessIdx=&(sessIdx);
03797 
03798                 thread_data_array[t].spkBottom=spkBottom;
03799                 thread_data_array[t].spkUp=spkUp;
03800                 thread_data_array[t].vectSize=_vectSize;
03801                 thread_data_array[t].svSize=_svSize;
03802                 thread_data_array[t].n_distrib=_n_distrib;
03803                 thread_data_array[t].rankEV=_rankEV;
03804 
03805                 if (verboseLevel>1) cout<<"(AccumulateJFAStat) Creating thread n["<< t<< "] for speakers [ "<<spkBottom<<" --> "<<spkUp-1<<" ]"<<endl;
03806                 rc = pthread_create(&threads[t], &attr, S_MplusVYplusDZthread, (void *)&thread_data_array[t]);
03807                 if (rc) throw Exception("ERROR; return code from pthread_create() is ",__FILE__,rc);
03808                 
03809                 spkBottom = spkUp;
03810         }
03811         
03812         pthread_attr_destroy(&attr);
03813         for(unsigned long t=0; t<NUM_THREADS; t++) {
03814                 rc = pthread_join(threads[t], (void **)&status);
03815                 if (rc)  throw Exception("ERROR; return code from pthread_join() is ",__FILE__,rc);
03816                 if (verboseLevel>1) cout <<"(AccumulateJFAStat) Completed join with thread ["<<t<<"] status["<<status<<"]"<<endl;
03817         }
03818 
03819         free(thread_data_array);
03820         free(threads);
03821 
03822         sessIdx.deleteAllObjects();
03823 
03824         if (verboseLevel >= 1) cout << "(AccumulateJFAStat) Done " << endl;
03825 }
03826 
03827 #endif
03828 
03829 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
03831 void JFAAcc::getSpeakerModel(MixtureGD &mixture, String& file){
03832         
03833         DoubleVector Sp, MplusVYplusDZ, UX;
03834         Sp.setSize(_svSize); Sp.setAllValues(0.0);
03835         MplusVYplusDZ.setSize(_svSize);
03836         UX.setSize(_svSize);
03837         
03838         this->getMplusVYplusDZ(MplusVYplusDZ, file);
03839         this->getUX(UX, file);
03840         
03841         for(unsigned long i=0; i<_svSize; i++){
03842                 Sp[i] = MplusVYplusDZ[i]+UX[i];
03843         }
03844         svToModel(Sp,mixture);
03845 }
03846 
03847 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
03849 void JFAAcc::normalizeFeatures(SegCluster &selectedSegments,FeatureServer &fs,Config & config){
03850         
03851         if (verbose) cout << "(AccumulateJFAStat) Normalize Features" << endl;  
03852         //MixtureGD & clientMixture=_ms.getMixtureGD(1);                                                // copy the UBM mixture
03853         MixtureGD & world=_ms.getMixtureGD(0);
03854 
03855         MixtureGD & clientMixture=_ms.duplicateMixture (_ms.getMixtureGD(0), DUPL_DISTRIB);
03856         
03857         RealVector <double> ux; ux.setSize(_svSize);                                            //vecteur utilise pour calculers Ux
03858         double *_ux=ux.getArray();
03859         
03860         bool topGauss = false;
03861         if(config.existsParam("topGauss"))      topGauss = config.getParam("topGauss").toBool();
03862 
03863         Seg *seg;                                                                                                       // current selectd segment
03864         selectedSegments.rewind();
03865         String currentSource="";
03866         while((seg=selectedSegments.getSeg())!=NULL){
03867                 unsigned long begin=seg->begin()+fs.getFirstFeatureIndexOfASource(seg->sourceName()); 
03868                 if (currentSource!=seg->sourceName()) {
03869                         currentSource=seg->sourceName();
03870                         this->getUX(ux,currentSource);
03871                         this->getSpeakerModel(clientMixture,currentSource);                     //model contenant M_s_h=M+Vy + Dz+Ux
03872                         if (verbose)cout << "Processing speaker["<<currentSource<<"]"<< endl;   
03873                 }
03874 
03875                 fs.seekFeature(begin);
03876                 Feature f;
03877 
03878                 if (!topGauss) {
03879                         for (unsigned long idxFrame=0;idxFrame<seg->length();idxFrame++){
03880                                 fs.readFeature(f,0);
03881                                 double *ff=f.getDataVector();                           
03882                                 double sum=0.0;
03883                                 DoubleVector P;
03884                                 P.setSize(_n_distrib);
03885                                 double *Prob=P.getArray();
03886 
03887                                 //Compute occupation of the current frame on each distribution of the UBM
03888                                 for(unsigned long k=0;k<_n_distrib;k++) {
03889                                         Prob[k]=clientMixture.weight(k)*clientMixture.getDistrib(k).computeLK(f);
03890 //                                      Prob[k]=world.weight(k)* world.getDistrib(k).computeLK(f);
03891                                         sum+=Prob[k];
03892                                 }
03893                                 for(unsigned long k=0;k<_n_distrib;k++){
03894                                         Prob[k]/=sum;
03895                                 }
03896 
03897                                 //Substract the channel from the feature
03898                                 for(unsigned long k=0;k<_n_distrib;k++) {
03899                                         for (unsigned long i=0;i<_vectSize;i++) 
03900                                                 ff[i]-= Prob[k]*_ux[k*_vectSize+i];                             //Soustrait les statistiques du canal
03901                                         }
03902                                 fs.writeFeature(f);
03903                         }       
03904                 }
03905                 else {
03906                         throw Exception("no topgauss yet",__FILE__,__LINE__);
03907                 }
03908         }
03909         
03910         _ms.deleteMixture(clientMixture);
03911         _ms.deleteUnusedDistribs();
03912         
03913 };      
03914 
03915 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
03916 void JFAAcc::substractUXfromFeatures(FeatureServer &fs,Config &config){
03917         SegServer segmentsServer;
03918         LabelServer labelServer;
03919         initializeClusters(_fileList,segmentsServer,labelServer,config);
03920         verifyClusterFile(segmentsServer,fs,config);
03921         unsigned long codeSelectedFrame=labelServer.getLabelIndexByString(config.getParam("labelSelectedFrames"));
03922         SegCluster& selectedSegments=segmentsServer.getCluster(codeSelectedFrame);  
03923         normalizeFeatures(selectedSegments,fs,config);
03924 };
03925 
03926 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
03928 void JFAAcc::saveAccs(Config &config) {
03929 
03930         String fxName, fxhName, nName, nhName;
03931         fxName = "F_X.mat"; fxhName = "F_X_h.mat"; nName = "N.mat"; nhName = "N_h.mat";
03932         if(config.existsParam("nullOrderStatSpeaker"))  nName = config.getParam("matrixFilesPath") + config.getParam("nullOrderStatSpeaker")+config.getParam("saveMatrixFilesExtension");
03933         if(config.existsParam("nullOrderStatSession"))  nhName = config.getParam("matrixFilesPath") + config.getParam("nullOrderStatSession")+config.getParam("saveMatrixFilesExtension");
03934         if(config.existsParam("firstOrderStatSpeaker")) fxName = config.getParam("matrixFilesPath") + config.getParam("firstOrderStatSpeaker")+config.getParam("saveMatrixFilesExtension");
03935         if(config.existsParam("firstOrderStatSession")) fxhName = config.getParam("matrixFilesPath") + config.getParam("firstOrderStatSession")+config.getParam("saveMatrixFilesExtension");
03936 
03937         _F_X.save(fxName,config);
03938         _F_X_h.save(fxhName,config);
03939         _N_h.save(nhName,config); 
03940         _matN.save(nName,config);
03941         if (verboseLevel>=1) cout << "(AccumulateJFAStat) FA Accs states saved" << endl;
03942 }
03943 
03944 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
03945 double JFAAcc::getLLK(SegCluster &selectedSegments,MixtureGD &model,FeatureServer&fs,Config & config){
03946 
03947         if (verboseLevel >= 1) cout << "(FactorAnalysisStat) Compute Likelihood" << endl;
03948         double llk=0.0;
03949 
03950         MixtureGDStat &acc=_ss.createAndStoreMixtureStat(model);                
03951         Seg *seg;        
03952         selectedSegments.rewind();
03953 
03954         while((seg=selectedSegments.getSeg())!=NULL){                                   
03955                 unsigned long begin=seg->begin()+fs.getFirstFeatureIndexOfASource(seg->sourceName()); 
03956                 fs.seekFeature(begin);
03957                 Feature f;
03958                 for (unsigned long idxFrame=0;idxFrame<seg->length();idxFrame++){
03959                         fs.readFeature(f); 
03960                         acc.computeAndAccumulateLLK(f,1.0,TOP_DISTRIBS_NO_ACTION);
03961                 }               
03962         }
03963 
03964         llk= acc.getMeanLLK();
03965         _ss.deleteMixtureStat(acc);
03966 
03967 return llk;
03968 };
03969 
03970 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
03971 void JFAAcc::verifyEMLK(Config& config){
03972 
03973         XList ndx(_fileList);
03974         XLine *pline; String *pFile; ndx.rewind();
03975 
03976         double total=0.0;
03977         unsigned long maxLLKcomputed=1;
03978         maxLLKcomputed=config.getParam("computeLLK").toLong();  
03979 
03980         unsigned long cnt=0;
03981         while((pline=ndx.getLine())!=NULL && cnt < maxLLKcomputed) { 
03982                 while((pFile=pline->getElement())!=NULL && cnt < maxLLKcomputed) {
03983 
03985                         MixtureServer ms(config);
03986                         MixtureGD &model=ms.loadMixtureGD(config.getParam("inputWorldFilename"));
03987                         this->getSpeakerModel(model,*pFile);
03988                         
03990                         FeatureServer fs(config,*pFile);
03991                         SegServer segmentsServer;
03992                         LabelServer labelServer;
03993                         initializeClusters(*pFile,segmentsServer,labelServer,config);
03994                         verifyClusterFile(segmentsServer,fs,config);
03995                         unsigned long codeSelectedFrame=labelServer.getLabelIndexByString(config.getParam("labelSelectedFrames"));
03996                         SegCluster& selectedSegments=segmentsServer.getCluster(codeSelectedFrame);  
03997                         double llk=this->getLLK(selectedSegments,model,fs,config); 
03998                         if (verbose) cout << "(EigenVoice) LLK["<<*pFile<<"]="<<llk<<endl;
03999                         cnt++;
04000                         total+=llk;
04001                 }
04002         }
04003         if (verboseLevel >=1) cout << "*** (Verify LLK) Total LLK="<<total<<" ***"<<endl;
04004 }
04005 
04006 
04007 #endif