# # # @include "Data.tz" @use Abstract. @use Matrix. @use Vector. @use Genome. @use Mobile. Abstract : NeuralNetwork3 [version 2.3] { % An experimental neural network class for different types of neural % networks whose goal is to provide efficient computation and the % ability to manipulate the parameters and connections using evolution + variables: network (pointer). nodes (object). inputNodes (object). outputNodes (object). weights (object). connections (object). neuronCount (int). inputNeuronCount (int). outputNeuronCount (int). iterationStep (float). timeConstant (float). stateBoundLower (float). stateBoundUpper (float). homeland (string). fitness(double). limbLengths (3 floats). + to destroy: if network: free network. if nodes: free nodes. if inputNodes: free inputNodes. if outputNodes: free outputNodes. if weights: free weights. if connections: free connections. super destroy. + to init: iterationStep = 1.0. timeConstant = 1.0. self disable-auto-free. + to init-with neuron-count theNetworkSize (int): n(int). network = neuralNetworkNew(theNetworkSize). neuronCount = theNetworkSize. #print "neuronCount $neuronCount". nodes = new Vector. nodes set-vector-pointer to neuralNetworkGetNeuronStateVector(network) with-size neuronCount. weights = new Matrix2D. weights set-matrix-pointer to neuralNetworkGetConnectionWeightMatrix(network) x-size neuronCount y-size neuronCount. connections = new Matrix2D. connections set-matrix-pointer to neuralNetworkGetConnectionStructureMatrix(network) x-size neuronCount y-size neuronCount. for n=0, n<3, n++: { limbLengths[n] = random[2.0] + 1. } #self add-dependency on nodes. #self add-dependency on inputNodes. #self add-dependency on outputNodes. #self add-dependency on weights. #self add-dependency on connections. return self. + to start-with-genome genome gene(object): n(int). m(int). o (int). val (double). neuronCount = gene get-size. network = neuralNetworkNew(neuronCount). nodes = new Vector. nodes set-vector-pointer to neuralNetworkGetNeuronStateVector(network) with-size neuronCount. weights = new Matrix2D. weights set-matrix-pointer to neuralNetworkGetConnectionWeightMatrix(network) x-size neuronCount y-size neuronCount. connections = new Matrix2D. connections set-matrix-pointer to neuralNetworkGetConnectionStructureMatrix(network) x-size neuronCount y-size neuronCount. for n =0 , n <3, n++ : { limbLengths[n] = (gene get-limb-length number n). } for m = 0, m < neuronCount, m++:{ for o = 0, o < neuronCount, o++:{ val = gene get-val at-x o at-y m. weights set-value to val at-x o at-y m. } } #self set-homeland of (gene get-homeland). #self add-dependency on nodes. #self add-dependency on inputNodes. #self add-dependency on outputNodes. #self add-dependency on weights. #self add-dependency on connections. - to get-network-pointer: return network. + to get-neuron-state-vector: return nodes. #+ to save-with-dialog: # self archive-as-xml file fileName (string). #show-dialog with-title title (string) with-message message (string) with-yes-button yesString (string) with-no-button noString (string) + section "Network Parameter Accessors": + to get-genome: rtn (object). n (int). rtn = new NeuralGenome. rtn set-weights of-matrix weights of-size neuronCount. for n=0, n < 3, n++:{ rtn set-limb-length number n to-val limbLengths[n]. } rtn set-homeland of homeland. return rtn. + to get-limb-length number n (int): return limbLengths[n]. + to get-neuron-count: return neuronCount. + to get-iteration-step: return iterationStep. + to set-iteration-step to newTimeStep (float): iterationStep = newTimeStep. neuralNetworkSetTimeStep(network, newTimeStep). + to get-time-constant: return timeConstant. + to set-time-constant to newTimeConstant (float): timeConstant = newTimeConstant. neuralNetworkSetTimeConstant(network, newTimeConstant). + to get-lower-saturation-boundry: return stateBoundLower. + to get-upper-saturation-boundry: return stateBoundUpper. + to set-saturation-bounds between lower (float) and upper (float): stateBoundLower = lower. stateBoundUpper = upper. neuralNetworkSetNeuronStateBounds(network, lower, upper). + section "Network State Variable and Vector Accessors": + to set-neuron-state at index (int) to value (float): neuralNetworkSetNeuronState(network, index, value). + to get-neuron-state at index (int): return neuralNetworkGetNeuronState(network, index). + to set-input-state-vector from first (int) to last (int): % returns a vector which contains the input nodes inputNodes = new Vector. inputNodes set-vector-pointer to neuralNetworkSetInputNeurons(network, first, (last - first)) with-size (last - first). inputNeuronCount = (last - first). return inputNodes. + to get-input-state-vector: % returns a vector which contains the input nodes return inputNodes. + to set-output-state-vector from first (int) to last (int): % returns a vector which contains the output nodes outputNodes = new Vector. outputNodes set-vector-pointer to neuralNetworkSetInputNeurons(network, first, (last - first)) with-size (last - first). outputNeuronCount = (last - first). return outputNodes. + to get-output-state-vector: % returns a vector which contains the output nodes return outputNodes. + to get-connection-structure-matrix: % returns a matrix of synaptic connections [0,1] return connections. + to apply-structure-to-weights: neuralNetworkApplyStructure(network). + to get-connection-weight-matrix: % returns a matrix of the synaptic strengths return weights. + to set-connection-weight-matrix to val (double) at-x i (int) at-y m (int): connections set-value to 1.0 at-x i at-y m. weights set-value to val at-x i at-y m. + to get-weight at-x x (int) at-y y (int): return (weights get-value at-x x at-y y). + to get-edge at-x x (int) at-y y (int): return (connections get-value at-x x at-y y). + to randomize-states between lowerBound = -1.0 (float) and upperBound = 1.0 (float): i (int). for i = 0, i < neuronCount, i++: nodes set-value to (lowerBound + random[(upperBound - lowerBound)]) at-x i. + to randomize-weights between lowerBound = -1.0 (float) and upperBound = 1.0 (float) with-autapses autapsesBool = 0 (int): i, j (int). for i = 0, i < neuronCount, i++: for j = 0, j < neuronCount, j++: if autapsesBool: { weights set-value to (lowerBound + random[(upperBound - lowerBound)]) at-x i at-y j. } else: { if i == j: weights set-value to 0.0 at-x i at-y j. else: weights set-value to (lowerBound + random[(upperBound - lowerBound)]) at-x i at-y j. } + to init-random-structure with-connectivity-percent thePercent = 0.5 (float) with-autapses autapsesBool = 0 (int): i, j (int). edge (int). for i = 0, i < neuronCount, i++: for j = 0, j < neuronCount, j++: if autapsesBool: { if random[1.0] < thePercent: edge = 1.0. else: edge = 0.0. connections set-value to edge at-x i at-y j. } else: { if i != j: { if random[1.0] < thePercent: edge = 1.0. else: edge = 0.0. connections set-value to edge at-x i at-y j. } else: connections set-value to 0.0 at-x i at-y j. } + to init-fully-connected-structure with-autapses autapsesBool = 0 (int): i, j (int). for i = 0, i < neuronCount, i++: for j = 0, j < neuronCount, j++: if autapsesBool: { connections set-value to 1.0 at-x i at-y j. } else: { if i != j: connections set-value to 1.0 at-x i at-y j. else: connections set-value to 0.0 at-x i at-y j. } + to update-state: % updates the network's state based on current state and % inputs neuralNetworkUpdateState(network). + to mutate: % Implement this method to mutate the genes of this object. This method % must be implemented by your subclass. n (int). m (int). i (int). val(double). n = random[2]. val = random[1] - 0.5. if ((limbLengths[n]+val) > 0.5):limbLengths[n] += val. if ((limbLengths[n]+val) <= 0.5):limbLengths[n] += |val|. for i=0, i < 50, i++:{ n = random[neuronCount]. m = random[neuronCount]. val = random[2.0]- 1.0. if m != n:{ weights set-value to val at-x n at-y m. } } #die "The method \"mutate\" must be implemented in your GeneticAlgorithmIndividual subclass!". + to mutate-connections connects z(int): % Implement this method to mutate the genes of this object. This method % must be implemented by your subclass. n (int). m (int). i (int). val(double). n = random[2]. val = random[1] - 0.5. if ((limbLengths[n]+val) > 0.5):limbLengths[n] += val. if ((limbLengths[n]+val) <= 0.5):limbLengths[n] += |val|. for i=0, i < z, i++:{ n = random[neuronCount]. m = random[neuronCount]. val = random[2.0]- 1.0. if m != n:{ weights set-value to val at-x n at-y m. } } + to randomize: % Implement this method to randomize the genes of this object. This method % must be implemented by your subclass. n (int). #val(double). for n=0, n<3, n++: { limbLengths[n] = random[2.0] + 1. } self init-random-structure with-connectivity-percent 0.5 with-autapses 0. self randomize-weights between -1.0 and 1.0 with-autapses 0. #die "The method \"randomize\" must be implemented in your GeneticAlgorithmIndividual subclass!". + to crossover-two-point from-parent-1 parent1 (object) from-parent-2 parent2 (object): % Implement this method to make this object become a crossover of parent1 % and parent2. This method must be implemented by your subclass if % crossover is enabled. # Make 2 point crossover # Ok here it is n (int). m (int). o (int). p (int). #q (int). r (int). i (int). val(double). newhomeland (string). n = random [neuronCount - 1]. m = random [neuronCount - 1]. o = random [neuronCount - 1 - n]. o = o + n. p = random [neuronCount - 1]. print "crossover point 1 $n - $m : point 2 $o - $p". for i=0, i < neuronCount, i++:{ for r=0, r < neuronCount, r++:{ if i!=r:{ #if random[2.0]>1:{ if (i > n && i < o && r > m && r < p):{ val = parent1 get-weight at-x i at-y r. #connections set-value to 1.0 at-x i at-y r. weights set-value to val at-x i at-y r. #print "parent 1 $i $r". } else:{ val = parent2 get-weight at-x i at-y r. #connections set-value to 1.0 at-x i at-y r. weights set-value to val at-x i at-y r. #print "parent 2 2 2". } } } } if (random[2.0] > 1.0) : { for i=0, i<3, i++:{ val = parent1 get-limb-length number i. limbLengths[i] = val. } } else:{ for i=0, i<3, i++:{ val = parent2 get-limb-length number i. limbLengths[i] = val. } } #homeland = #newhomeland = (parent1 get-homeland). #newhomeland = "($newhomeland X $homeland)". #homeland = newhomeland. #die "The method \"crossover\" must be implemented in your GeneticAlgorithmIndividual subclass!". + to crossover-omni-point from-parent-1 parent1 (object) from-parent-2 parent2 (object): % Implement this method to make this object become a crossover of parent1 % and parent2. This method must be implemented by your subclass if % crossover is enabled. n (int). m (int). o (int). p (int). #q (int). r (int). i (int). val(double). newhomeland (string). for i=0, i < neuronCount, i++:{ for r=0, r < neuronCount, r++:{ if i!=r:{ if random[2.0]>1:{ val = parent1 get-weight at-x i at-y r. #connections set-value to 1.0 at-x i at-y r. weights set-value to val at-x i at-y r. #print "parent 1 $i $r". } else:{ val = parent2 get-weight at-x i at-y r. #connections set-value to 1.0 at-x i at-y r. weights set-value to val at-x i at-y r. #print "parent 2 2 2". } } } } if (random[2.0] > 1.0) : { for i=0, i<3, i++:{ val = parent1 get-limb-length number i. limbLengths[i] = val. } } else:{ for i=0, i<3, i++:{ val = parent2 get-limb-length number i. limbLengths[i] = val. } } #homeland = #newhomeland = (parent1 get-homeland). #newhomeland = "($newhomeland X $homeland)". #homeland = newhomeland. #die "The method \"crossover\" must be implemented in your GeneticAlgorithmIndividual subclass!". + to get-copy: #n (int). m (int). i (int). val(double). rtn (object). rtn = new NeuralNetwork3. rtn init-with neuron-count neuronCount. for i=0, i