Tuesday 21 December 2010

SOM 2D (Code Review)

First Try Code (Click To Show)


static void Som2d(){
Console.WriteLine("SOM 2-D");
//double[,] lSOM = new double[onx,onx];

Random rn = new Random ();
List<double[,]> wgh = new List<double[,]>();
for (int dn = 0; dn < datanum; dn++) {
double[,] tmp = new double[onx, ony];
for(int wx = 0; wx < onx; wx++){
for(int wy = 0; wy < ony; wy++){
tmp[wx, wy] = rn.NextDouble();
}
}
wgh.Add(tmp);
}
rn = null;

// run epoch
double ngrad = 0; // neighbor radius
double ilrrt = lrrt;
for(int ec = 0; ec < epch; ec++){
drawTextProgressBar (ec + 1, epch);
// loop output nodes
for(int ix = 0; ix < rnx; ix++){
for(int iy = 0; iy < rny; iy++){
// get BM node
double tmpd = 0;
double mdis = double.PositiveInfinity;
int mx = 0;
int my = 0;
for(int ox = 0; ox < onx; ox++){
for (int oy = 0; oy < ony; oy++) {
for(int it = 0; it < datanum; it++){
tmpd += (ggarray[it][ix, iy] - wgh[it][ox, oy]) *
(ggarray[it][ix, iy] - wgh[it][ox, oy]);
}

if(tmpd < mdis){
mdis = tmpd;
mx = ox;
my = oy;
}

tmpd = 0;
}
}

// set neighbor radius (mrad)
ngrad = mrad * Math.Exp(-(double)ec/timc);

for(int jx = 0; jx < onx; jx++){
for (int jy = 0; jy < ony; jy++) {
double dist2bmu = ((mx - jx) * (mx - jx)) + ((my - jy) * (my - jy));
double wsqr = ngrad * ngrad;
if(dist2bmu < wsqr){
dinf = Math.Exp(-dist2bmu/2*wsqr);
// adjust weight
for(int it = 0; it < datanum; it++){
wgh[it][jx, jy] += lrrt * dinf * (ggarray[it][ix, iy] - wgh[it][jx, jy]);
}
}
}
}
}
}

lrrt = ilrrt * Math.Exp (-(double)ec / epch);
}
Console.WriteLine ("DONE");

// render result
for (int it = 0; it < datanum; it++) {
Sizing sz = new Sizing ();
sz.Writeout (mx0, my0, mx1, my1, onx, ony, wgh[it], outf + it.ToString());
}
}



Revision Code, Using Output Node Index Value as Output (Click To Show)


static void som2dd ()
{
Console.WriteLine ("SOM 2-D");

double[] inpvector = new double[clnm];
for (int iv = 0; iv < clnm; iv++) {
inpvector[iv] = ( iv + 1 );
}

// run epoch
double ngrad = 0;
// neighbor radius
double ilrrt = lrrt;
for (int ec = 0; ec < epch; ec++) {
printTextProgressBar (ec + 1, epch);
for(int ipc = 0; ipc < clnm; ipc++){
// get BM node
double tmpd = 0;
double mdis = double.PositiveInfinity;
int mx = 0;
int my = 0;
for (int ox = 0; ox < rnx; ox++) {
for (int oy = 0; oy < rny; oy++) {

for (int it = 0; it < datanum; it++) {
tmpd += (inpvector[ipc] - ggarray[it][ox, oy]) * (inpvector[ipc] - ggarray[it][ox, oy]);
}

if (tmpd < mdis) {
mdis = tmpd;
mx = ox;
my = oy;
}

tmpd = 0;
}
}

// set neighbor radius (mrad)
ngrad = mrad * Math.Exp (-(double)ec / timc);

for (int jx = 0; jx < rnx; jx++) {
for (int jy = 0; jy < rny; jy++) {
double dist2bmu = ((mx - jx) * (mx - jx)) + ((my - jy) * (my - jy));
double wsqr = ngrad * ngrad;
if (dist2bmu < wsqr) {
dinf = Math.Exp (-dist2bmu / 2 * wsqr);
// adjust weight
for (int it = 0; it < datanum; it++) {
ggarray[it][jx, jy] += lrrt * dinf * (inpvector[ipc] - ggarray[it][jx, jy]);
}
}
}
}
lrrt = ilrrt * Math.Exp (-(double)ec / epch);
}
}

double[,] gout = new double[rnx, rny];
for (int jx = 0; jx < rnx; jx++) {
for (int jy = 0; jy < rny; jy++) {
double tmp = 0;
for (int i = 0; i < datanum; i++) {
tmp += ggarray[i][jx, jy];
}
gout[jx, jy] = (tmp / (double) datanum);
}
}

Sizing sz = new Sizing ();
sz.Writeout (mx0, my0, mx1, my1, rnx, rny, gout, outf);
Console.WriteLine ("DONE");
//printMinMaxValue(gout);
gout = null;
}

Thursday 16 December 2010