mixtureDST.cc

Go to the documentation of this file.
00001 /* MLPACK 0.2
00002  *
00003  * Copyright (c) 2008, 2009 Alexander Gray,
00004  *                          Garry Boyer,
00005  *                          Ryan Riegel,
00006  *                          Nikolaos Vasiloglou,
00007  *                          Dongryeol Lee,
00008  *                          Chip Mappus, 
00009  *                          Nishant Mehta,
00010  *                          Hua Ouyang,
00011  *                          Parikshit Ram,
00012  *                          Long Tran,
00013  *                          Wee Chin Wong
00014  *
00015  * Copyright (c) 2008, 2009 Georgia Institute of Technology
00016  *
00017  * This program is free software; you can redistribute it and/or
00018  * modify it under the terms of the GNU General Public License as
00019  * published by the Free Software Foundation; either version 2 of the
00020  * License, or (at your option) any later version.
00021  *
00022  * This program is distributed in the hope that it will be useful, but
00023  * WITHOUT ANY WARRANTY; without even the implied warranty of
00024  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00025  * General Public License for more details.
00026  *
00027  * You should have received a copy of the GNU General Public License
00028  * along with this program; if not, write to the Free Software
00029  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
00030  * 02110-1301, USA.
00031  */
00038 #include "fastlib/fastlib.h"
00039 #include "support.h"
00040 #include "mixtureDST.h"
00041 
00042 using namespace hmm_support;
00043 
00044 void MixtureGauss::Init(int K, int N) {
00045   means.Init();
00046   for (int i = 0; i < K; i++) {
00047     Vector v;
00048     RAND_NORMAL_01_INIT(N, &v);
00049     means.PushBackCopy(v);
00050   }
00051   
00052   covs.Init();
00053   for (int i = 0; i < means.size(); i++) {
00054     Matrix m;
00055     m.Init(N, N); m.SetZero();
00056     for (int j = 0; j < N; j++) m.ref(j, j) = 1.0;
00057     covs.PushBackCopy(m);
00058   }
00059 
00060   prior.Init(means.size());
00061   for (int i = 0; i < prior.length(); i++) prior[i] = 1.0/K;
00062 
00063   ACC_means.InitCopy(means);
00064   ACC_covs.InitCopy(covs);
00065   ACC_prior.Init(K);
00066   inv_covs.InitCopy(covs);
00067   det_covs.Init(covs.size());
00068   for (int i = 0; i < K; i++) {
00069     double det = la::Determinant(covs[i]);
00070     la::InverseOverwrite(covs[i], &inv_covs[i]);
00071     det_covs[i] = pow(2.0*math::PI, -N/2.0) * pow(det, -0.5);
00072   }
00073 }
00074 
00075 void MixtureGauss::Init(int K, const Matrix& data, const ArrayList<int>& labels) {
00076   means.Init();
00077   int N = data.n_rows();
00078   for (int i = 0; i < K; i++) {
00079     Vector v;
00080     v.Init(N);
00081     means.PushBackCopy(v);
00082   }
00083   
00084   covs.Init();
00085   for (int i = 0; i < means.size(); i++) {
00086     Matrix m;
00087     m.Init(N, N);
00088     covs.PushBackCopy(m);
00089   }
00090 
00091   prior.Init(means.size());
00092 
00093   ACC_means.InitCopy(means);
00094   ACC_covs.InitCopy(covs);
00095   ACC_prior.Init(K);
00096   inv_covs.InitCopy(covs);
00097   det_covs.Init(covs.size());
00098   start_accumulate();
00099   //printf("cols = %d rows = %d\n", data.n_cols(), data.n_rows()); 
00100   for (int i = 0; i < data.n_cols(); i++) {
00101     Vector v;
00102     data.MakeColumnVector(i, &v);
00103     //printf("%d\n", i);
00104     accumulate_cluster(labels[i], v);
00105   }
00106   end_accumulate_cluster();
00107 }
00108 
00109 void MixtureGauss::InitFromFile(const char* mean_fn, const char* covs_fn, const char* prior_fn) {
00110   Matrix meansmat;
00111   data::Load(mean_fn, &meansmat);
00112   mat2arrlst(meansmat, &means);
00113   int N = means[0].length();
00114   int K = means.size();
00115   if (covs_fn != NULL) {
00116     Matrix covsmat;
00117     data::Load(covs_fn, &covsmat);
00118     mat2arrlstmat(N, covsmat, &covs);
00119     DEBUG_ASSERT_MSG(K==covs.size(), "InitFromFile: sizes do not match !");
00120   }
00121   else {
00122     covs.Init();
00123     for (int i = 0; i < means.size(); i++) {
00124       Matrix m;
00125       m.Init(N, N); m.SetZero();
00126       for (int j = 0; j < N; j++) m.ref(j, j) = 1.0;
00127       covs.PushBackCopy(m);
00128     }
00129   }
00130   if (prior_fn != NULL) {
00131     Matrix priormat;
00132     data::Load(prior_fn, &priormat);
00133     DEBUG_ASSERT_MSG(K==priormat.n_cols(), "InitFromFile: sizes do not match !!");
00134     prior.Init(K);
00135     for (int i = 0; i < K; i++) prior[i] = priormat.get(0, i);
00136   }
00137   else {
00138     prior.Init(means.size());
00139     for (int i = 0; i < prior.length(); i++) prior[i] = 1.0/K;
00140   }
00141   
00142   ACC_means.InitCopy(means);
00143   ACC_covs.InitCopy(covs);
00144   ACC_prior.Init(K);
00145   inv_covs.InitCopy(covs);
00146   det_covs.Init(covs.size());
00147   for (int i = 0; i < K; i++) {
00148     double det = la::Determinant(covs[i]);
00149     la::InverseOverwrite(covs[i], &inv_covs[i]);
00150     det_covs[i] = pow(2.0*math::PI, -N/2.0) * pow(det, -0.5);
00151   }
00152 }
00153 
00154 void MixtureGauss::InitFromProfile(const ArrayList<Matrix>& matlst, int start, int N) {
00155   DEBUG_ASSERT(matlst[start].n_cols()==1);
00156   Vector tmp;
00157   matlst[start].MakeColumnVector(0, &tmp);
00158   prior.Copy(tmp);
00159 
00160   // DEBUG: print_vector(prior, "  prior = ");
00161 
00162   means.Init();
00163   covs.Init();
00164   int K = prior.length();
00165   for (int i = start+1; i < start+2*K+1; i+=2) {
00166     DEBUG_ASSERT(matlst[i].n_rows()==N && matlst[i].n_cols()==1);
00167     DEBUG_ASSERT(matlst[i+1].n_rows()==N && matlst[i+1].n_cols()==N);
00168     Vector m;
00169     matlst[i].MakeColumnVector(0, &m);
00170     means.PushBackCopy(m);
00171     covs.PushBackCopy(matlst[i+1]);    
00172   }
00173   ACC_means.InitCopy(means);
00174   ACC_covs.InitCopy(covs);
00175   ACC_prior.Init(K);
00176   inv_covs.InitCopy(covs);
00177   det_covs.Init(covs.size());
00178   for (int i = 0; i < K; i++) {
00179     double det = la::Determinant(covs[i]);
00180     la::InverseOverwrite(covs[i], &inv_covs[i]);
00181     det_covs[i] = pow(2.0*math::PI, -N/2.0) * pow(det, -0.5);
00182   }  
00183 }
00184 
00185 void MixtureGauss::print_mixture(const char* s) const {
00186   int K = means.size();
00187   printf("%s - Mixture (%d)\n", s, K);
00188   print_vector(prior, "  PRIOR");
00189   for (int i = 0; i < K; i++) {
00190     printf("  CLUSTER %d:\n", i);
00191     print_vector(means[i], "  MEANS");
00192     print_matrix(covs[i], "  COVS");
00193   }
00194 }
00195 
00196 void MixtureGauss::generate(Vector* v) const {
00197   int K = means.size();
00198   double r = RAND_UNIFORM_01();
00199   int cluster = K-1;
00200   double s = 0;
00201   for (int i = 0; i < K; i++) {
00202     s += prior[i];
00203     if (s >= r) {
00204       cluster = i;
00205       break;
00206     }
00207   }
00208   RAND_NORMAL_INIT(means[cluster], covs[cluster], v);
00209 }
00210 
00211 double MixtureGauss::getPDF(const Vector& v) const {
00212   int K = means.size();
00213   double s = 0;
00214   for (int i = 0; i < K; i++)
00215     s += getPDF(i, v);
00216   return s;
00217 }
00218 
00219 double MixtureGauss::getPDF(int cluster, const Vector& v) const {
00220   return prior[cluster]*NORMAL_DENSITY(v, means[cluster], inv_covs[cluster], det_covs[cluster]);
00221 }
Generated on Mon Jan 24 12:04:38 2011 for FASTlib by  doxygen 1.6.3