00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
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
00100 for (int i = 0; i < data.n_cols(); i++) {
00101 Vector v;
00102 data.MakeColumnVector(i, &v);
00103
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
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 }