private static double GetInfluence(SOMAttractionFunction attractionFunction, double distSquared, double searchRadius) { const double SIGMA = .28; // this gives peak negative at x=.5 (roughly), and near 0 at x=1 const double SIGMASQUARED = SIGMA * SIGMA; switch (attractionFunction) { case SOMAttractionFunction.Guassian_ORIG: // This is a guassian, but I wasn't scaling to search radius very well double twiceSearchRadiusSquared = 2d * (searchRadius * searchRadius); return(Math.Exp(-distSquared / twiceSearchRadiusSquared)); // this will reduce the learning rate as distance increases (guassian dropoff) case SOMAttractionFunction.Guassian: //https://en.wikipedia.org/wiki/Gaussian_function double percentSearchRadius1 = Math.Sqrt(distSquared) / searchRadius; percentSearchRadius1 *= 2; percentSearchRadius1 *= percentSearchRadius1; return(Math.Exp(-percentSearchRadius1)); case SOMAttractionFunction.MexicanHat: //https://en.wikipedia.org/wiki/Mexican_hat_wavelet double percentSearchRadius2 = Math.Sqrt(distSquared) / searchRadius; percentSearchRadius2 *= percentSearchRadius2; // it needs to be squared double left = (1 - (percentSearchRadius2 / SIGMASQUARED)); double right = percentSearchRadius2 / (2 * SIGMASQUARED); right = Math.Exp(-right); return(left * right); default: throw new ApplicationException("Unknown SOMAttractionFunction: " + attractionFunction.ToString()); } }
public SOMRules(int numNodes, int numIterations, double initialRadiusPercent, double learningRate, SOMAttractionFunction attractionFunction = SOMAttractionFunction.Guassian) { this.NumNodes = numNodes; this.NumIterations = numIterations; this.InitialRadiusPercent = initialRadiusPercent; this.LearningRate = learningRate; this.AttractionFunction = attractionFunction; }