/*
* Copyright 2004-2010 Information & Software Engineering Group (188/1)
* Institute of Software Technology and Interactive Systems
* Vienna University of Technology, Austria
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.ifs.tuwien.ac.at/dm/somtoolbox/license.html
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package at.tuwien.ifs.somtoolbox.layers.initialisation;
import java.io.FileNotFoundException;
import at.tuwien.ifs.somtoolbox.apps.initEval.EvaluationMain;
import at.tuwien.ifs.somtoolbox.input.SOMLibFileFormatException;
import at.tuwien.ifs.somtoolbox.input.SOMLibFormatInputReader;
import at.tuwien.ifs.somtoolbox.layers.Layer;
import at.tuwien.ifs.somtoolbox.layers.Unit;
/**
* @author Stefan Bischof
* @author Leo Sklenitzka
* @version $Id: SOMInitializer.java 3893 2010-11-03 13:57:47Z mayer $
*/
public class SOMInitializer implements LayerInitializer {
private Layer layer;
private int xSize;
private int ySize;
private int zSize;
private double[][][][] data;
private int initzsize;
private int initysize;
private int initxsize;
public SOMInitializer(Layer layer, int xSize, int ySize, int zSize) {
this.layer = layer;
this.xSize = xSize;
this.ySize = ySize;
this.zSize = zSize;
}
/**
*
*/
@Override
public Unit[][][] initialize() {
Unit[][][] units = new Unit[xSize][ySize][zSize];
try {
read();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SOMLibFileFormatException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
for (int k = 0; k < zSize; k++) {
double[] a = asdf(k, initzsize, zSize);
int z1 = (int) a[0];
int z2 = (int) a[1];
double w1_z = a[2];
double w2_z = a[3];
// suche zwei z-koordinaten-kandidaten z1, z2
// sowie zwei gewichte (summe = 1)
for (int j = 0; j < ySize; j++) {
a = asdf(j, initysize, ySize);
int y1 = (int) a[0];
int y2 = (int) a[1];
double w1_y = a[2];
double w2_y = a[3];
// suche zwei y-koordinaten-kandidaten y1, y2
// sowie zwei gewichte (summe = 1)
for (int i = 0; i < xSize; i++) {
a = asdf(i, initxsize, xSize);
int x1 = (int) a[0];
int x2 = (int) a[1];
double w1_x = a[2];
double w2_x = a[3];
// suche zwei x-koordinaten-kandidaten x1, x2
// sowie zwei gewichte (summe = 1)
// => 8 koordinaten aka. Units
double[][] vectors = null;
vectors = new double[][] {
// initSOM.getUnit(x1, y1, z1).getFeatureWeights(),
// initSOM.getUnit(x1, y1, z2).getFeatureWeights(),
// initSOM.getUnit(x1, y2, z1).getFeatureWeights(),
// initSOM.getUnit(x1, y2, z2).getFeatureWeights(),
// initSOM.getUnit(x2, y1, z1).getFeatureWeights(),
// initSOM.getUnit(x2, y1, z2).getFeatureWeights(),
// initSOM.getUnit(x2, y2, z1).getFeatureWeights(),
// initSOM.getUnit(x2, y2, z2).getFeatureWeights()
data[x1][y1][z1], data[x1][y1][z2], data[x1][y2][z1], data[x1][y2][z2], data[x2][y1][z1],
data[x2][y1][z2], data[x2][y2][z1], data[x2][y2][z2]
};
// => 8 gewichte
double[] weights = new double[] { w1_z * w1_y * w1_x, w2_z * w1_y * w1_x, w1_z * w2_y * w1_x,
w2_z * w2_y * w1_x, w1_z * w1_y * w2_x, w2_z * w1_y * w2_x, w1_z * w2_y * w2_x,
w2_z * w2_y * w2_x };
// vectorMean aufrufen und aktuelle Unit damit initialisieren
double[] newfeaturevector = vectorMean(vectors, weights);
units[i][j][k] = new Unit(layer, i, j, k, newfeaturevector);
}
}
}
return units;
}
/** Read weights from an already trained SOM */
private void read() throws FileNotFoundException, SOMLibFileFormatException {
String datasetname = EvaluationMain.getDatasetName();
String path = "data/" + datasetname + "/output-" + datasetname + "/" + datasetname;
SOMLibFormatInputReader r = new SOMLibFormatInputReader(path + ".wgt.gz", path + ".unit.gz", path + ".map");
data = r.getVectors();
initzsize = r.getZSize();
initysize = r.getYSize();
initxsize = r.getXSize();
}
/**
* Calculates a weighted mean of vectors. Prone to numerical error: floating point arithmetics ...
*
* @param vectors an array of double vectors
* @param weights weights for a weighted mean calculation
* @return a mean vector
*/
protected static double[] vectorMean(double[][] vectors, double[] weights) throws IllegalArgumentException {
int numVectors = vectors.length;
int dimVectors = vectors[0].length;
// if(v1.length != v2.length) {
// throw new IllegalArgumentException("Unequal vector dimensionality");
// }
if (weights.length < numVectors) {
throw new IllegalArgumentException("To few mean weights");
}
double[] means = new double[dimVectors];
for (int i = 0; i < means.length; i++) {
double mean = 0.0;
for (int j = 0; j < numVectors; j++) {
mean += vectors[j][i] * weights[j];
}
means[i] = mean;
}
return means;
}
private static double[] asdf(double k, double zinitsize, double zsize) {
if (zsize <= 1) {
return new double[] { 0.0, 0.0, 0.5, 0.5 };
}
double k0 = k * (zinitsize - 1) / (zsize - 1);
double z1 = java.lang.Math.floor(k0);
double z2 = java.lang.Math.ceil(k0);
double weight1_z = k0 - z1;
double weight2_z = z2 - k0;
// System.out.println("k:" + k +
// ", k0:"+k0+" ("+z1+","+z2+"), ("+weight1_z+","+weight2_z+")");
return new double[] { z1, z2, weight1_z, weight2_z };
}
/** Test method for testing the other methods */
public static void main(String[] args) {
// double[][] vectors = new double[][] {
// {1.0,4.0},
// {2.0,5.0},
// {3.0,6.0},
// {4.0,7.0}
// };
// double[] weights = new double[] {0.25,0.25,0.25,0.25};
// System.out.println(java.util.Arrays.toString(vectorMean(vectors, weights
// )));
// double zsize = 10.0;
// double zinitsize = 5.0;
// for (int k = 0; k < zsize; k++) {
// double k0 = (k * (zinitsize - 1)) / (zsize - 1);
// double a[] = asdf(k, zinitsize, zsize);
// double z1 = a[0];
// double z2 = a[1];
// double weight1_z = a[2];
// double weight2_z = a[3];
//
// }
}
}