In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

Self Organizing Map - Arrange 2D Array

Just input many random Data..

Reference - 
http://www.tylerstreeter.net/projects/self-organizing-maps/
http://www.jjguy.com/som/
/**
 * Copyright greentec ( http://wonderfl.net/user/greentec )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/dZsw
 */

// forked from greentec's Self Organizing Map
package {
    import com.bit101.components.Label;
    import com.bit101.components.PushButton;
    import flash.display.Shape;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    
    public class FlashTest extends Sprite {
        
        public var outputNeuronWidthNum:int = 20;
        public var outputNeuronHeightNum:int = 20;
        public var outputNeuronNum:int = outputNeuronWidthNum * outputNeuronHeightNum;
        public var inputNeuronNum:int = 10000;
        
        public var _bitmap:Bitmap;
        public var _bitmapData:BitmapData;
        
        public var inputLayer:Layer;
        public var outputLayer:Layer;
        
        public var startLearningRate:Number = 0.05;
        public var learningRate:Number = 0.05;
        public var oneFrameIter:int = 30;
        public var iterMax:int = inputNeuronNum / oneFrameIter - 1;
        public var iter:int = -1;
        
        
        public var screenWidthHalf:int = 465 / 2;
        public var screenHeightHalf:int = 465 / 2;
        //public var startRadius:Number = 465;
        //public var radius:Number = 465;
        public var startRadius:Number = (outputNeuronWidthNum + outputNeuronWidthNum) / 2;
        public var radius:Number = startRadius;
        
        public var proceedNumLabel:Label;
        public var resetButton:PushButton;
        
        public var lineShape:Shape = new Shape();
        public var dotShape:Shape = new Shape();
        
        public var timeConstant:Number = iterMax / Math.log(startRadius); 

        public function FlashTest() {
            // write as3 code here..
            
            stage.scaleMode = "noScale";
            
            _bitmapData = new BitmapData(465, 465, false, 0x292929);
            _bitmap = new Bitmap(_bitmapData);
            addChild(_bitmap);
            
            var i:int;
            var neuron:Neuron;
            
            inputLayer = new Layer();
            for (i = 0; i < inputNeuronNum; i += 1)
            {
                neuron = new Neuron(2);
                inputLayer.neurons.push(neuron);
            }
            
            outputLayer = new Layer();
            
            for (i = 0; i < outputNeuronNum; i += 1)
            {
                neuron = new Neuron(2);
                outputLayer.neurons.push(neuron);
            }
            
            proceedNumLabel = new Label(this, 10, 10, "Proceed #");
            resetButton = new PushButton(this, 10, 465 - 30, "Reset", onReset);
            
            addEventListener(Event.ENTER_FRAME, onLoop);
        }
        
        private function onReset(e:Event):void
        {
            var i:int;
            if (hasEventListener(Event.ENTER_FRAME) == true)
            {
                removeEventListener(Event.ENTER_FRAME, onLoop);
            }
            
            var neuron:Neuron;
            
            for (i = 0; i < inputNeuronNum; i += 1)
            {
                neuron = inputLayer.neurons[i];
                neuron.resetW(2);
            }
            
            for (i = 0; i < outputNeuronNum; i += 1)
            {
                neuron = outputLayer.neurons[i];
                neuron.resetW(2);
            }
            
            iter = 0;
            learningRate = startLearningRate;
            radius = startRadius;
            
            if (hasEventListener(Event.ENTER_FRAME) == false)
            {
                addEventListener(Event.ENTER_FRAME, onLoop);
            }
        }
        
        private function onLoop(e:Event):void
        {
            var i:int;
            var j:int;
            var input:Neuron;
            var neuron:Neuron;
            var bmuNumber:Number;
            var bmuIndex:int;
            var dx:int;
            var dy:int;
            var v:Number;
            var N:Number;
            var dist:Number;
            var influence:Number;
            var bmuNeuron:Neuron;
            
            iter += 1;
            
            if (iter <= iterMax)
            {
                for (i = 0; i < oneFrameIter; i += 1)
                {
                    input = inputLayer.neurons[iter * oneFrameIter + i];
                    bmuNumber = 99999;
                    
                    for (j = 0; j < outputNeuronNum; j += 1)
                    {
                        neuron = outputLayer.neurons[j];
                        neuron.redDist = input.w[0] - neuron.w[0];
                        neuron.greenDist = input.w[1] - neuron.w[1];
                        neuron.euclideanDist = Math.sqrt(neuron.redDist * neuron.redDist + neuron.greenDist * neuron.greenDist);
                        
                        if (bmuNumber > neuron.euclideanDist)
                        {
                            bmuNumber = neuron.euclideanDist;
                            bmuIndex = j;
                        }
                    }
                    
                    bmuNeuron = outputLayer.neurons[bmuIndex];
                    //trace(bmuIndex, bmuNeuron, bmuNeuron.w[0], bmuNeuron.w[1]);
                    //var num:int = 0;
                    for (j = 0; j < outputNeuronNum; j += 1)
                    {
                        if (j != bmuIndex)
                        {
                            neuron = outputLayer.neurons[j];
                            
                            
                            dx = (bmuIndex % outputNeuronWidthNum) - (j % outputNeuronWidthNum);
                            dx = (dx ^ dx >> 31) - (dx >> 31); // == MAth.abs(dx)
                            dy = int(bmuIndex / outputNeuronWidthNum) - int(j / outputNeuronWidthNum);
                            dy = (dy ^ dy >> 31) - (dy >> 31);
                            //dist = Math.sqrt(dx * dx + dy * dy);
                            dist = dx + dy;
                            
                            if (dist < radius)
                            {
                                influence = Math.exp(( -1 * Math.sqrt(dist)) / (2 * radius * iter));
                                neuron.w[0] += learningRate * influence * neuron.redDist;
                                neuron.w[1] += learningRate * influence * neuron.greenDist;
                                //trace(neuron.w[0], neuron.w[1]);
                                //num += 1;
                            }
                        }
                        //neuron.w[0] = neuron.w[0] > 1 ? 1 : (neuron.w[0] < -1 ? -1 : neuron.w[0]);
                        //neuron.w[1] = neuron.w[1] > 1 ? 1 : (neuron.w[1] < -1 ? -1 : neuron.w[1]);
                        
                        //v = (dx + dy) / 18;
                        //N = Math.exp( -v);
                        
                        //neuron.w[0] += learningRate * N * neuron.redDist;
                        //neuron.w[1] += learningRate * N * neuron.greenDist;
                    }
                    //trace(num);
                    //trace(bmuNeuron.w[0], bmuNeuron.w[1]);
                }
                
                drawNodes(i-1, bmuIndex);
                
                learningRate = startLearningRate * Math.exp( -iter / timeConstant); 
                radius = startRadius * Math.exp( -iter / timeConstant);
                
                proceedNumLabel.text = "Proceed #" + String(iter) + "/" + String(iterMax);
            }
            else
            {
                if (hasEventListener(Event.ENTER_FRAME) == true)
                {
                    removeEventListener(Event.ENTER_FRAME, onLoop);
                }
            }
        }
        
        private function drawNodes(inputIndex:int, bmuIndex:int):void
        {
            _bitmapData.fillRect(_bitmapData.rect, 0x292929);
            
            lineShape.graphics.clear();
            dotShape.graphics.clear();
            
            
            //var randIndex:int = Math.random() * oneFrameIter + iter * oneFrameIter;
            var input:Neuron;
            input = inputLayer.neurons[inputIndex + iter * oneFrameIter];
            dotShape.graphics.lineStyle(0, 0xff00ff);
            dotShape.graphics.drawCircle((input.w[0] + 1) * screenWidthHalf, (input.w[1] + 1) * screenHeightHalf, 5);
            
            var neuron:Neuron;
            var endNeuron:Neuron; // for line drawing
            
            dotShape.graphics.lineStyle(0, 0xdddddd);
            lineShape.graphics.lineStyle(0, 0xdddddd);
            
            var i:int;
            var dx:int;
            var dy:int;
            var dist:int;
            
            for (i = 0; i < outputNeuronNum; i += 1)
            {
                neuron = outputLayer.neurons[i];
                
                dx = (bmuIndex % outputNeuronWidthNum) - (i % outputNeuronWidthNum);
                dx = (dx ^ dx >> 31) - (dx >> 31);
                dy = int(bmuIndex / outputNeuronWidthNum) - int(i / outputNeuronWidthNum);
                dy = (dy ^ dy >> 31) - (dy >> 31);
                dist = dx + dy;
                
                if (dist < radius)
                {
                    dotShape.graphics.lineStyle(0, 0xffff00);
                    dotShape.graphics.beginFill(0xffff00);
                }
                else
                {
                    dotShape.graphics.lineStyle(0, 0xdddddd);
                    dotShape.graphics.beginFill(0x808080);
                }
                
                dotShape.graphics.drawCircle((neuron.w[0] + 1) * screenWidthHalf, (neuron.w[1] + 1) * screenHeightHalf, 5);
                dotShape.graphics.endFill();
                
                
                if ( (i % outputNeuronWidthNum) < outputNeuronWidthNum - 1)
                {
                    endNeuron = outputLayer.neurons[i + 1];
                    lineShape.graphics.moveTo((neuron.w[0] + 1) * screenWidthHalf, (neuron.w[1] + 1) * screenHeightHalf);
                    lineShape.graphics.lineTo((endNeuron.w[0] + 1) * screenWidthHalf, (endNeuron.w[1] + 1) * screenHeightHalf);
                }
                
                if ( int(i / outputNeuronWidthNum) < outputNeuronHeightNum - 1)
                {
                    endNeuron = outputLayer.neurons[i + outputNeuronWidthNum];
                    lineShape.graphics.moveTo((neuron.w[0] + 1) * screenWidthHalf, (neuron.w[1] + 1) * screenHeightHalf);
                    lineShape.graphics.lineTo((endNeuron.w[0] + 1) * screenWidthHalf, (endNeuron.w[1] + 1) * screenHeightHalf);
                }
            }
            
            _bitmapData.draw(lineShape);
            _bitmapData.draw(dotShape);
        }
    }
}

Class
{
    /**
     * ...
     * @author ypc
     */
    class Neuron
    {
        public var w:Object;
        public var input:Number;
        public var output:Number;
        public var euclideanDist:Number;
        public var redDist:Number;
        public var greenDist:Number;
        public var blueDist:Number;
        
        public function Neuron(n:int)
        {
            this.w = new Object();
           
            
            if (n > 0)
            {
                var i:int;
                
                for (i = 0; i < n; i += 1)
                {
                    this.w[i] = Math.random() * 2 - 1;
                    
                }
            }
        }
        
        public function resetW(n:int):void
        {
            var i:int;
            
            for (i = 0; i < n; i += 1)
            {
                this.w[i] = Math.random() * 2 - 1;
                
            }
        }
        
    }

}

Class
{
    /**
     * ...
     * @author ypc
     */
    class Layer 
    {
        public var neurons:Array;
        
        public function Layer() 
        {
            this.neurons = [];
        }
        
    }

}