[ifcsoft] push by kyle.tha...@gmail.com - Fixed bug where if variance of a dimension was 0, SOM linear init woul... on 2011-06-01 21:50 GMT

1 view
Skip to first unread message

ifc...@googlecode.com

unread,
Jun 1, 2011, 5:51:49 PM6/1/11
to ifcsoft--a...@googlegroups.com
Revision: 31f610ed8559
Author: kthayer
Date: Wed Jun 1 14:49:51 2011
Log: Fixed bug where if variance of a dimension was 0, SOM linear init
would go into an infinite loop. This happens specifically when Matrix.eig()
is called on a matrix with a NaN or infinity. I remove all those
dimensions, find the eigen vectors on the rest of the dimensions and put
back in the average value for the missing dimensions.
http://code.google.com/p/ifcsoft/source/detail?r=31f610ed8559

Modified:
/src/ifcSoft/model/som/SOMInitFns.java

=======================================
--- /src/ifcSoft/model/som/SOMInitFns.java Wed May 25 09:13:13 2011
+++ /src/ifcSoft/model/som/SOMInitFns.java Wed Jun 1 14:49:51 2011
@@ -92,6 +92,60 @@
int dims = dataset.getDimensions();
Matrix m = findAutocorrelationMatrix(dataset);

+ //since the autocorrelation Matrix may have had divide by 0s (if std
deviation = 0)
+ //we need to remove all row/columns that have a NAN or infinity
+ m.print(8, 2);
+ boolean dimsValidity[] = new boolean[dims];
+ for(int i = 0; i < dims; i++){
+ dimsValidity[i] = false;
+ }
+ for(int i = 0; i < m.getRowDimension(); i++){
+ for(int j = 0; j < m.getColumnDimension(); j++){
+ if(!Double.isNaN(m.get(i, j)) && !Double.isInfinite(m.get(i, j)) ){
+ if(i != j){
+ dimsValidity[i] = true;
+ dimsValidity[j] = true;
+ }
+ }
+ }
+ }
+ boolean areAnyInvalid = false;
+ for(int i = 0; i < dims; i++){
+ if(!dimsValidity[i]){
+ areAnyInvalid = true;
+ }
+ }
+
+ if(areAnyInvalid){//if some dimensions are invalid we need to remove
them from the matrix
+ int numValid = 0;
+ for(int i = 0; i < dims; i++){
+ if(dimsValidity[i]){
+ numValid++;
+ }
+ }
+ int validDims[] = new int[numValid];
+ int validDimsI = 0;
+ for(int i = 0; i < dims; i++){
+ if(dimsValidity[i]){
+ validDims[validDimsI] = i;
+ validDimsI++;
+ }
+ }
+
+ //make a new matrix with just the valid dimensions and replace the old
matrix with it
+ Matrix newM = new Matrix(numValid,numValid);
+ for(int i = 0; i < numValid; i++){
+ for(int j = 0; j < numValid; j++){
+ newM.set(i, j, m.get(validDims[i], validDims[j]));
+ }
+ }
+
+ m = newM;
+ System.out.println("New matrix:");
+ m.print(8, 2);
+ }
+
+
EigenvalueDecomposition test = m.eig();
double eigenvals[] = test.getRealEigenvalues();
Matrix eigenvectors = test.getV();
@@ -110,10 +164,24 @@

double largestEigenV[] = new double[dims];
double secondLargestEigenV[] = new double[dims];
- for(int k = 0; k < dims; k++){ //the columns (second index) are the
eigen vectors
- largestEigenV[k] = eigenvectors.get(k, largestEigenIndex);
- secondLargestEigenV[k] = eigenvectors.get(k,
secondLargestEigenIndex);
- }
+ if(areAnyInvalid){
+ int validI = 0;
+ for(int k = 0; k < dims; k++){ //the columns (second index) are the
eigen vectors
+ if(dimsValidity[k]){
+ largestEigenV[k] = eigenvectors.get(validI, largestEigenIndex);
+ secondLargestEigenV[k] = eigenvectors.get(validI,
secondLargestEigenIndex);
+ validI++;
+ }else{
+ largestEigenV[k] = dataset.getMean(k);
+ secondLargestEigenV[k] = dataset.getMean(k);
+ }
+ }
+ }else{
+ for(int k = 0; k < dims; k++){ //the columns (second index) are the
eigen vectors
+ largestEigenV[k] = eigenvectors.get(k, largestEigenIndex);
+ secondLargestEigenV[k] = eigenvectors.get(k, secondLargestEigenIndex);
+ }
+ }

Random r = new Random();
int flipLargestEigen =1;

Reply all
Reply to author
Forward
0 new messages