updated niche/fastica

This commit is contained in:
tekhnofiend
2008-01-18 04:12:35 +00:00
parent 915c1afb92
commit 002f359382
2 changed files with 246 additions and 172 deletions
+49 -126
View File
@@ -23,85 +23,8 @@ namespace {
}
void RandVector(Vector &v) {
index_t d = v.length();
v.SetZero();
for(index_t i = 0; i+1 < d; i+=2) {
double a = drand48();
double b = drand48();
double first_term = sqrt(-2 * log(a));
double second_term = 2 * M_PI * b;
v[i] = first_term * cos(second_term);
v[i+1] = first_term * sin(second_term);
}
if((d % 2) == 1) {
v[d - 1] = sqrt(-2 * log(drand48())) * cos(2 * M_PI * drand48());
}
la::Scale(1/sqrt(la::Dot(v, v)), &v);
}
void Center(Matrix X, Matrix &X_centered) {
Vector col_vector_sum;
col_vector_sum.Init(X.n_rows());
col_vector_sum.SetZero();
index_t n = X.n_cols();
for(index_t i = 0; i < n; i++) {
Vector cur_col_vector;
X.MakeColumnVector(i, &cur_col_vector);
la::AddTo(cur_col_vector, &col_vector_sum);
}
la::Scale(1/(double) n, &col_vector_sum);
X_centered.CopyValues(X);
for(index_t i = 0; i < n; i++) {
Vector cur_col_vector;
X_centered.MakeColumnVector(i, &cur_col_vector);
la::SubFrom(col_vector_sum, &cur_col_vector);
}
}
void Whiten(Matrix X, Matrix &X_whitened, Matrix &whitening_matrix, Matrix &dewhitening_matrix) {
Matrix X_cov, D, D_inv, E;
Vector D_vector;
Scale(1 / (double) (X.n_cols() - 1),
MulTransBInit(&X, &X, &X_cov));
la::EigenvectorsInit(X_cov, &D_vector, &E);
E.set(0, 1, -E.get(0, 1));
E.set(1, 1, -E.get(1, 1));
index_t d = D_vector.length();
D.Init(d, d);
D.SetZero();
D_inv.Init(d, d);
D_inv.SetZero();
for(index_t i = 0; i < d; i++) {
double sqrt_val = sqrt(D_vector[i]);
D.set(i, i, sqrt_val);
D_inv.set(i, i, 1 / sqrt_val);
}
la::MulTransBInit(D_inv, E, &whitening_matrix);
la::MulInit(E, D, &dewhitening_matrix);
la::MulInit(whitening_matrix, X, &X_whitened);
}
void Orthogonalize(Matrix W_old, Matrix &W) {
@@ -157,11 +80,11 @@ namespace {
int FixedPointICA(Matrix X, Matrix whitening_matrix, Matrix dewhitening_matrix,
int approach, index_t num_of_IC, int g, int fine_tune,
double a1, double a2, double mu, bool stabilization,
double epsilon, index_t max_num_iterations,
index_t max_fine_tune, double sample_size,
Matrix* A, Matrix* W) {
int approach, index_t num_of_IC, int g, int fine_tune,
double a1, double a2, double mu, bool stabilization,
double epsilon, index_t max_num_iterations,
index_t max_fine_tune, double sample_size,
Matrix* A, Matrix* W) {
// ensure default values are passed into this function if the user doesn't care about certain parameters
@@ -258,11 +181,11 @@ namespace {
B.Init(d, num_of_IC);
/*
for(index_t i = 0; i < num_of_IC; i++) {
for(index_t i = 0; i < num_of_IC; i++) {
Vector b;
B.MakeColumnVector(i, &b);
RandVector(b);
}
}
*/
B.SetZero();
for(index_t i = 0; i < d; i++) {
@@ -393,12 +316,12 @@ namespace {
Scale(1 / (double) n,
AddTo(MulInit(&X, &hyp_tan, &temp1),
DotMultiplyOverwrite(MulInit(&col_vector,
MapOverwrite(&MinusArg,
n,
MatrixMapSum(&Square, 0, &hyp_tan, &sum)),
&temp2),
&B)));
DotMultiplyOverwrite(MulInit(&col_vector,
MapOverwrite(&MinusArg,
n,
MatrixMapSum(&Square, 0, &hyp_tan, &sum)),
&temp2),
&B)));
break;
@@ -453,12 +376,12 @@ namespace {
Scale(1 / (double) num_selected,
AddTo(MulInit(&X_sub, &hyp_tan, &temp1),
DotMultiplyOverwrite(MulInit(&col_vector,
MapOverwrite(&MinusArg,
num_selected,
MatrixMapSum(&Square, 0, &hyp_tan, &sum)),
&temp2),
&B)));
DotMultiplyOverwrite(MulInit(&col_vector,
MapOverwrite(&MinusArg,
num_selected,
MatrixMapSum(&Square, 0, &hyp_tan, &sum)),
&temp2),
&B)));
break;
@@ -607,11 +530,11 @@ namespace {
Scale(1 / (double) num_selected,
SubOverwrite(MulInit(&X_sub, &U, &temp1),
DotMultiplyOverwrite(&B,
MulInit(&col_vector,
Sum(&ex, &sum),
&temp2)),
&B));
DotMultiplyOverwrite(&B,
MulInit(&col_vector,
Sum(&ex, &sum),
&temp2)),
&B));
break;
@@ -660,8 +583,8 @@ namespace {
//D = diag(1 ./ (Beta + sum((Y_squared_a2 - 1) .* ex)))
VectorToDiag(MapOverwrite(&Inv,
0,
AddTo(&Beta_vector, &sum_vector)),
0,
AddTo(&Beta_vector, &sum_vector)),
&D);
//B = B + myy * B * (Y' * gauss - diag(Beta)) * D;
@@ -734,8 +657,8 @@ namespace {
Scale(1 / (double) num_selected,
MulInit(&X_sub,
MapOverwrite(&pow,
3,
MulTransAInit(&X_sub, &B, &temp1)),
3,
MulTransAInit(&X_sub, &B, &temp1)),
&temp2));
AddTo(&temp2,
@@ -784,10 +707,10 @@ namespace {
Scale(1 / (double) n,
MulOverwrite(&X,
MapOverwrite(&Square,
0,
MulTransAInit(&X, &B, &temp1)),
&B));
MapOverwrite(&Square,
0,
MulTransAInit(&X, &B, &temp1)),
&B));
break;
}
@@ -824,10 +747,10 @@ namespace {
Scale(1 / (double) num_selected,
MulOverwrite(&X_sub,
MapOverwrite(&Square,
0,
MulTransAInit(&X_sub, &B, &temp1)),
&B));
MapOverwrite(&Square,
0,
MulTransAInit(&X_sub, &B, &temp1)),
&B));
break;
}
@@ -1405,11 +1328,11 @@ namespace {
}
int FastICAMain(datanode *module) {
int FastICAMain(datanode *module, Matrix *W, Matrix *Y) {
const char *data = fx_param_str_req(NULL, "data");
Matrix X, X_centered, X_whitened, whitening_matrix, dewhitening_matrix, A, W;
Matrix X, X_centered, X_whitened, whitening_matrix, dewhitening_matrix, A;
data::Load(data, &X);
index_t d = X.n_rows(); // number of dimensions
@@ -1490,27 +1413,22 @@ int FastICAMain(datanode *module) {
fx_timer_start(NULL, "FastICA");
X_centered.Init(d, n);
Center(X, X_centered);
Center(X, &X_centered);
Whiten(X_centered, X_whitened, whitening_matrix, dewhitening_matrix);
WhitenUsingEig(X_centered, &X_whitened, &whitening_matrix, &dewhitening_matrix);
FixedPointICA(X_whitened, whitening_matrix, dewhitening_matrix, approach, num_of_IC, nonlinearity, fine_tune, a1, a2, mu, stabilization, epsilon, max_num_iterations, max_fine_tune, sample_size, &A, &W);
FixedPointICA(X_whitened, whitening_matrix, dewhitening_matrix, approach, num_of_IC, nonlinearity, fine_tune, a1, a2, mu, stabilization, epsilon, max_num_iterations, max_fine_tune, sample_size, &A, W);
W.PrintDebug("W");
W -> PrintDebug("W");
Matrix Y;
la::MulInit(W, X, &Y);
la::MulInit(*W, X, Y);
fx_timer_stop(NULL, "FastICA");
SaveCorrectly("unmixing_matrix.dat", W);
SaveCorrectly("indep_comps.dat", Y);
return SUCCESS_PASS;
}
@@ -1520,7 +1438,12 @@ int main(int argc, char *argv[]) {
srand48(time(0));
int ret_val = FastICAMain(fx_root);
Matrix W, Y;
int ret_val = FastICAMain(fx_root, &W, &Y);
SaveCorrectly("unmixing_matrix.dat", W);
SaveCorrectly("indep_comps.dat", Y);
fx_done();
+197 -46
View File
@@ -37,6 +37,15 @@ double ArgMinus(double x, double arg) {
return arg - x;
}
Matrix* DiagMatrixInit(index_t n, double value, Matrix *diag_matrix) {
diag_matrix -> Init(n, n);
diag_matrix -> SetZero();
for(index_t i = 0; i < n; i++) {
diag_matrix -> set(i, i, value);
}
return diag_matrix;
}
Matrix* ColVector(index_t n, double value, Matrix *col_vector) {
col_vector -> Init(n, 1);
@@ -490,68 +499,210 @@ void MakeSubMatrixByColumns(Vector column_indices, Matrix A, Matrix *A_sub) {
}
}
void Center(Matrix X, Matrix* X_centered) {
Vector col_vector_sum;
col_vector_sum.Init(X.n_rows());
col_vector_sum.SetZero();
index_t n = X.n_cols();
for(index_t i = 0; i < n; i++) {
Vector cur_col_vector;
X.MakeColumnVector(i, &cur_col_vector);
la::AddTo(cur_col_vector, &col_vector_sum);
}
la::Scale(1/(double) n, &col_vector_sum);
X_centered -> Copy(X);
for(index_t i = 0; i < n; i++) {
Vector cur_col_vector;
X_centered -> MakeColumnVector(i, &cur_col_vector);
la::SubFrom(col_vector_sum, &cur_col_vector);
}
}
void WhitenUsingSVD(Matrix X, Matrix* X_whitened, Matrix* whitening_matrix) {
Matrix cov_X, U, VT, inv_S_matrix, temp1;
Vector S_vector;
Scale(1 / (double) (X.n_cols() - 1),
MulTransBInit(&X, &X, &cov_X));
la::SVDInit(cov_X, &S_vector, &U, &VT);
index_t d = S_vector.length();
inv_S_matrix.Init(d, d);
inv_S_matrix.SetZero();
for(index_t i = 0; i < d; i++) {
double inv_sqrt_val = 1 / sqrt(S_vector[i]);
inv_S_matrix.set(i, i, inv_sqrt_val);
}
cov_X.PrintDebug("cov(X')");
U.PrintDebug("U");
VT.PrintDebug("VT");
inv_S_matrix.PrintDebug("S^-.5");
MulTransBInit(MulTransAInit(&VT, &inv_S_matrix, &temp1),
&U,
whitening_matrix);
MulInit(whitening_matrix, &X, X_whitened);
}
void WhitenUsingEig(Matrix X, Matrix* X_whitened, Matrix* whitening_matrix, Matrix* dewhitening_matrix) {
Matrix cov_X, D, D_inv, E;
Vector D_vector;
Scale(1 / (double) (X.n_cols() - 1),
MulTransBInit(&X, &X, &cov_X));
la::EigenvectorsInit(cov_X, &D_vector, &E);
//E.set(0, 1, -E.get(0, 1));
//E.set(1, 1, -E.get(1, 1));
index_t d = D_vector.length();
D.Init(d, d);
D.SetZero();
D_inv.Init(d, d);
D_inv.SetZero();
for(index_t i = 0; i < d; i++) {
double sqrt_val = sqrt(D_vector[i]);
D.set(i, i, sqrt_val);
D_inv.set(i, i, 1 / sqrt_val);
}
la::MulTransBInit(D_inv, E, whitening_matrix);
la::MulInit(E, D, dewhitening_matrix);
la::MulInit(*whitening_matrix, X, X_whitened);
}
void RandVector(Vector &v) {
index_t d = v.length();
v.SetZero();
for(index_t i = 0; i+1 < d; i+=2) {
double a = drand48();
double b = drand48();
double first_term = sqrt(-2 * log(a));
double second_term = 2 * M_PI * b;
v[i] = first_term * cos(second_term);
v[i+1] = first_term * sin(second_term);
}
if((d % 2) == 1) {
v[d - 1] = sqrt(-2 * log(drand48())) * cos(2 * M_PI * drand48());
}
la::Scale(1/sqrt(la::Dot(v, v)), &v);
}
Matrix* RandNormalInit(index_t d, index_t n, Matrix* A) {
double* A_elements = A -> ptr();
index_t num_elements = d * n;
for(index_t i = 0; i+1 < num_elements; i+=2) {
double a = drand48();
double b = drand48();
double first_term = sqrt(-2 * log(a));
double second_term = 2 * M_PI * b;
A_elements[i] = first_term * cos(second_term);
A_elements[i+1] = first_term * sin(second_term);
}
if((d % 2) == 1) {
A_elements[d - 1] = sqrt(-2 * log(drand48())) * cos(2 * M_PI * drand48());
}
return A;
}
/*
int main(int argc, char *argv[]) {*/
//fx_init(argc, argv);
/*
Matrix A, B, C, D, E, F;
//fx_init(argc, argv);
/*
Matrix A, B, C, D, E, F;
RandMatrix(5, 2, &A);
RandMatrix(2, 4, &B);
RandMatrix(5, 4, &C);
RandMatrix(7, 5, &D);
RandMatrix(7, 4, &E);
RandMatrix(7, 4, &F);
RandMatrix(5, 2, &A);
RandMatrix(2, 4, &B);
RandMatrix(5, 4, &C);
RandMatrix(7, 5, &D);
RandMatrix(7, 4, &E);
RandMatrix(7, 4, &F);
SaveCorrectly("A.dat", A);
SaveCorrectly("B.dat", B);
SaveCorrectly("C.dat", C);
SaveCorrectly("D.dat", D);
SaveCorrectly("E.dat", E);
SaveCorrectly("A.dat", A);
SaveCorrectly("B.dat", B);
SaveCorrectly("C.dat", C);
SaveCorrectly("D.dat", D);
SaveCorrectly("E.dat", E);
Matrix temp1, temp2, temp3, temp4, temp5;
Matrix temp1, temp2, temp3, temp4, temp5;
Vector sum_vector;
Matrix diag_matrix;
Vector sum_vector;
Matrix diag_matrix;
VectorToDiag(MatrixSum(DotMultiplyInit(MapOverwrite(&TimesTen, Sub(Mul(&D, Sub(Mul(&A, &B, &temp1), &C, &temp2), &temp3), &E, &temp4)), &F, &temp5), &sum_vector), &diag_matrix);
VectorToDiag(MatrixSum(DotMultiplyInit(MapOverwrite(&TimesTen, Sub(Mul(&D, Sub(Mul(&A, &B, &temp1), &C, &temp2), &temp3), &E, &temp4)), &F, &temp5), &sum_vector), &diag_matrix);
Vector diag_vector;
DiagToVector(&diag_matrix, &diag_vector);
Vector diag_vector;
DiagToVector(&diag_matrix, &diag_vector);
la::Scale(2, Scale(100, &diag_matrix));
la::Scale(2, Scale(100, &diag_matrix));
A.PrintDebug("A");
B.PrintDebug("B");
C.PrintDebug("C");
D.PrintDebug("D");
E.PrintDebug("E");
F.PrintDebug("F");
A.PrintDebug("A");
B.PrintDebug("B");
C.PrintDebug("C");
D.PrintDebug("D");
E.PrintDebug("E");
F.PrintDebug("F");
temp4.PrintDebug("temp4");
temp5.PrintDebug("temp5");
temp4.PrintDebug("temp4");
temp5.PrintDebug("temp5");
sum_vector.PrintDebug("sum(temp5)");
sum_vector.PrintDebug("sum(temp5)");
diag_matrix.PrintDebug("diag_matrix");
diag_vector.PrintDebug("diag_vector");
diag_matrix.PrintDebug("diag_matrix");
diag_vector.PrintDebug("diag_vector");
Matrix Z, sub_Z;
RandMatrix(4, 5, &Z);
Vector indices;
indices.Init(3);
indices[0] = 1;
indices[1] = 0;
indices[2] = 3;
MakeSubMatrixByColumns(indices, Z, &sub_Z);
Matrix Z, sub_Z;
RandMatrix(4, 5, &Z);
Vector indices;
indices.Init(3);
indices[0] = 1;
indices[1] = 0;
indices[2] = 3;
MakeSubMatrixByColumns(indices, Z, &sub_Z);
Z.PrintDebug("Z");
sub_Z.PrintDebug("sub_Z");
Z.PrintDebug("Z");
sub_Z.PrintDebug("sub_Z");
*/
*/
/*
index_t n = 10;
index_t d = 2;
@@ -568,8 +719,8 @@ void MakeSubMatrixByColumns(Vector column_indices, Matrix A, Matrix *A_sub) {
Matrix sum, temp1, temp2;
AddOverwrite(
Scale(1 / (double) n, MulInit(&X, &hyp_tan, &temp1)),
DotMultiplyOverwrite(MulInit(&ones, Scale(A1 / (double) n, MapOverwrite(&MinusArg, A1, Sum(MapOverwrite(&Square, 0, &hyp_tan), &sum))), &temp2), &B));
Scale(1 / (double) n, MulInit(&X, &hyp_tan, &temp1)),
DotMultiplyOverwrite(MulInit(&ones, Scale(A1 / (double) n, MapOverwrite(&MinusArg, A1, Sum(MapOverwrite(&Square, 0, &hyp_tan), &sum))), &temp2), &B));
B.PrintDebug("B");
@@ -581,5 +732,5 @@ void MakeSubMatrixByColumns(Vector column_indices, Matrix A, Matrix *A_sub) {
return 0;
}
}
*/