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
00041 #include "infomax_ica.h"
00042
00046 InfomaxICA::InfomaxICA(){
00047
00048 }
00049
00050 InfomaxICA::InfomaxICA(double lambda, int b, double epsilon):
00051 lambda_(lambda),
00052 b_(b),
00053 epsilon_(epsilon){
00054
00055 }
00056
00061 void InfomaxICA::applyICA(const Matrix &dataset){
00062 double current_cos=DBL_MAX;
00063 w_.Init(b_,b_);
00064 data_.Init(dataset.n_rows(),dataset.n_cols());
00065 la::ScaleOverwrite(1.0,dataset,&data_);
00066 if (b_<data_.n_cols()){
00067 sphere(data_);
00068
00069 Matrix i1 = eye(data_.n_rows(),double(1));
00070 la::ScaleOverwrite(1.0,i1,&w_);
00071 while (epsilon_<=current_cos){
00072 Matrix w_prev;
00073 w_prev.Copy(w_);
00074 evaluateICA();
00075 current_cos = w_delta(w_prev,w_);
00076 }
00077 }
00078 else
00079 fprintf(stdout,"Window size must be less than number of instances.");
00080 }
00081
00085 void InfomaxICA::evaluateICA(){
00086 Matrix BI = eye(w_.n_rows(),double(b_));
00087
00088 Matrix icv = Matrix(w_.n_rows(),b_);
00089 Matrix icv2 = Matrix(w_.n_rows(),w_.n_cols());
00090 Matrix icv4 = Matrix(w_.n_rows(),w_.n_cols());
00091 for (index_t i=0;i<data_.n_cols();i+=b_){
00092 if (i+b_<data_.n_cols()){
00093 Matrix subm;
00094 data_.MakeColumnSlice(i,b_,&subm);
00095 la::MulExpert(1,false,w_,false,subm,0.0,&icv);
00096 la::Scale(double(-1.0),&icv);
00097 expM(icv);
00098 addOne(icv);
00099 invertVals(icv);
00100 la::Scale(-2.0,&icv);
00101 addOne(icv);
00102 la::MulExpert(1,false,icv,true,subm,0.0,&icv2);
00103 la::AddOverwrite(icv2,BI,&icv4);
00104 la::Scale(lambda_,&icv4);
00105 la::MulExpert(1,false,icv4,false,w_,0.0,&icv2);
00106 la::AddTo(w_.n_elements(),icv2.ptr(),w_.ptr());
00107 }
00108 }
00109 }
00110
00111
00115 void InfomaxICA::sphere(Matrix &data){
00116 Matrix sample_covariance = sampleCovariance(data);
00117 Matrix wz = sqrtm(sample_covariance);
00118 Matrix wz_inverse = Matrix(wz.n_rows(),wz.n_cols());
00119 Matrix data_sub_means = subMeans(data);
00120 if (la::InverseOverwrite(wz,&wz_inverse)){
00121 la::Scale(wz.n_cols()*wz.n_rows(),2.0,wz_inverse.ptr());
00122 la::MulOverwrite(wz_inverse,data_sub_means,&data);
00123 }
00124 }
00125
00126
00127 Matrix InfomaxICA::sampleCovariance(const Matrix &m){
00128 Matrix ttm = subMeans(m);
00129 Matrix wm = Matrix(m.n_cols(),m.n_rows());
00130 la::TransposeOverwrite(ttm,&wm);
00131
00132 Matrix twm = Matrix(ttm.n_rows(),ttm.n_rows());
00133 Matrix output = Matrix(ttm.n_rows(),ttm.n_rows());
00134 output.SetZero();
00135 Matrix tttm = Matrix(wm);
00136
00137 la::Scale(tttm.n_rows()*tttm.n_cols(),1/(double(ttm.n_cols())-1),tttm.ptr());
00138 la::MulTransAOverwrite(wm,tttm,&twm);
00139 la::AddOverwrite(twm.n_rows()*twm.n_cols(),twm.ptr(),twm.ptr(),output.ptr());
00140 la::Scale(output.n_rows()*output.n_cols(),double(0.5),output.ptr());
00141 return output;
00142 }
00143
00144 Matrix InfomaxICA::subMeans(const Matrix &m){
00145 Matrix output = Matrix(m);
00146 Vector row_means = rowMean(output);
00147 la::Scale(row_means.length(),-1.0,row_means.ptr());
00148 for (index_t j=0;j<output.n_cols();j++){
00149 la::AddTo(row_means.length(),row_means.ptr(),output.GetColumnPtr(j));
00150 }
00151 return output;
00152 }
00153
00157 Vector InfomaxICA::rowMean(const Matrix &m){
00158 Vector row_means;
00159 row_means.Init(m.n_rows());
00160 row_means.SetZero();
00161 for (index_t j=0;j<m.n_cols();j++){
00162 la::AddTo(row_means.length(),m.GetColumnPtr(j),row_means.ptr());
00163 }
00164 la::Scale(row_means.length(),1/double(m.n_cols()),row_means.ptr());
00165 return row_means;
00166 }
00167
00172 Matrix InfomaxICA::sqrtm(const Matrix &m){
00173 Matrix output = Matrix(m.n_rows(), m.n_cols());
00174 Matrix chol = Matrix(m);
00175 if (la::Cholesky(&chol)){
00176 Matrix u,vt;
00177 Vector s;
00178 la::TransposeSquare(&chol);
00179 if (la::SVDInit(chol,&s,&u,&vt)){
00180 Matrix S = Matrix(s.length(),s.length());
00181 Matrix tm1 = Matrix(u.n_rows(),S.n_cols());
00182 S.SetZero();
00183 S.SetDiagonal(s);
00184 la::MulExpert(1,false,u,false,S,0.0,&tm1);
00185 la::MulExpert(1,false,tm1,true,u,0.0,&output);
00186 }
00187 else
00188 fprintf(stderr,"infomaxICA sqrtm: SVD failed.\n");
00189 }
00190 else
00191 fprintf(stderr,"infomaxICA sqrtm: Cholesky decomposition failed.\n");
00192 return output;
00193 }
00194
00195
00196 double InfomaxICA::w_delta(const Matrix &w_prev, const Matrix &w_pres){
00197 Matrix temp;
00198 Vector delta_c;
00199 Vector delta_r;
00200 double delta_dot;
00201 la::SubInit(w_pres,w_prev,&temp);
00202 vectorize(temp,delta_r);
00203 vectorize(temp,delta_c);
00204 delta_dot = la::Dot(delta_r.length(),delta_r.ptr(),delta_c.ptr());
00205 fprintf(stderr,"w change=%f\n",delta_dot);
00206 return delta_dot;
00207 }
00208
00209
00210
00214 void InfomaxICA::expM(Matrix &m){
00215 for (index_t i=0;i<m.n_rows();i++){
00216 for (index_t j=0;j<m.n_cols();j++){
00217 m.set(i,j,exp(m.get(i,j)));
00218 }
00219 }
00220 }
00221
00225 void InfomaxICA::addOne(Matrix &m){
00226 for (index_t i=0;i<m.n_rows();i++){
00227 for (index_t j=0;j<m.n_cols();j++){
00228 m.set(i,j,m.get(i,j)+1);
00229 }
00230 }
00231 }
00232
00236 void InfomaxICA::invertVals(Matrix &m){
00237 for (index_t i=0;i<m.n_rows();i++){
00238 for (index_t j=0;j<m.n_cols();j++){
00239 m.set(i,j,1/m.get(i,j));
00240 }
00241 }
00242 }
00243
00247 Matrix InfomaxICA::eye(index_t dim, double diagVal){
00248 Matrix output;
00249 Vector *diag = new Vector();
00250 diag->Init(dim);
00251 diag->SetAll(diagVal);
00252 output.InitDiagonal(*diag);
00253 return output;
00254 }
00255
00259 void InfomaxICA::vectorize(const Matrix &m, Vector &v){
00260 index_t v_ind = 0;
00261 v.Init(m.n_rows()*m.n_cols());
00262 for (index_t i=0;i<m.n_rows();i++){
00263 for (index_t j=0;j<m.n_cols();j++){
00264 v[v_ind]=m.get(i,j);
00265 v_ind++;
00266 }
00267 }
00268
00269 }
00270
00274 void InfomaxICA::displayMatrix(const Matrix &m){
00275 fprintf(stdout,"\n");
00276 for (index_t i=0;i<m.n_rows();i++){
00277 for (index_t j=0;j<m.n_cols();j++){
00278 fprintf(stdout,"%f ",m.get(i,j));
00279 }
00280 fprintf(stdout,"\n");
00281 }
00282 }
00283
00287 void InfomaxICA::displayVector(const Vector &m){
00288 fprintf(stdout,"\n");
00289 for (index_t i=0;i<m.length();i++){
00290 fprintf(stdout,"%f ",m[i]);
00291 }
00292 fprintf(stdout,"\n");
00293 }
00294
00299 void InfomaxICA::getUnmixing(Matrix &w){
00300 w.Copy(w_);
00301 }
00302
00307 void InfomaxICA::getSources(const Matrix &dataset, Matrix &s){
00308 s.Init(dataset.n_rows(),dataset.n_cols());
00309 la::MulExpert(1.0,false,w_,false,dataset,0.0,&s);
00310 }
00311
00312 void InfomaxICA::setLambda(const double lambda){
00313 lambda_=lambda;
00314 }
00315
00316 void InfomaxICA::setB(const int b){
00317 b_=b;
00318 }
00319
00320 void InfomaxICA::setEpsilon(const double epsilon){
00321 epsilon_=epsilon;
00322 }