@include "Data.tz" @use Abstract. @use Matrix. @use Vector. @use Genome. @use Mobile. Abstract : NeuralNetwork4 [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). parentAfitness(double). parentBfitness(double). meta-neuronCount(int). meta-connectionCount(int).#count of under-net connections meta-network(pointer). meta-nodes(object). meta-connections(object). meta-weights(object). + 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. if meta-connections: free meta-connections. if meta-weights: free meta-weights. if meta-nodes: free meta-nodes. if meta-network: free meta-network. super destroy. + to init: iterationStep = 1.0. timeConstant = 1.0. self disable-auto-free. + to init-with neuron-count theNetworkSize (int): n(int). i(int). j(int). val(double). 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. meta-connectionCount = ((neuronCount - 1) * (neuronCount - 1)). meta-neuronCount = (neuronCount + meta-connectionCount).#((neuronCount + meta-connectionCount) / 2) meta-network = neuralNetworkNew(meta-neuronCount). meta-nodes = new Vector. meta-nodes set-vector-pointer to neuralNetworkGetNeuronStateVector(meta-network) with-size meta-neuronCount. meta-weights = new Matrix2D. meta-weights set-matrix-pointer to neuralNetworkGetConnectionWeightMatrix(meta-network) x-size meta-neuronCount y-size meta-neuronCount. meta-connections = new Matrix2D. meta-connections set-matrix-pointer to neuralNetworkGetConnectionStructureMatrix(meta-network) x-size meta-neuronCount y-size meta-neuronCount. for i = 0, i < meta-neuronCount, i++:{ for j = 0, j < meta-neuronCount, j++:{ if i != j:{ val = random[2] - 1. meta-connections set-value to 1.0 at-x i at-y j. meta-weights set-value to val at-x i at-y j. } else: meta-connections set-value to 0.0 at-x i at-y j. } } #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 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. } } meta-neuronCount = gene get-meta-size. meta-network = neuralNetworkNew(meta-neuronCount). meta-nodes = new Vector. meta-nodes set-vector-pointer to neuralNetworkGetNeuronStateVector(meta-network) with-size meta-neuronCount. meta-weights = new Matrix2D. meta-weights set-matrix-pointer to neuralNetworkGetConnectionWeightMatrix(meta-network) x-size meta-neuronCount y-size meta-neuronCount. meta-connections = new Matrix2D. meta-connections set-matrix-pointer to neuralNetworkGetConnectionStructureMatrix(meta-network) x-size meta-neuronCount y-size meta-neuronCount. for m = 0, m < meta-neuronCount, m++:{ for o = 0, o < meta-neuronCount, o++:{ val = gene get-meta-val at-x o at-y m. meta-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 NeuralGenome2. rtn set-weights of-matrix weights of-size neuronCount. rtn set-meta-weights of-matrix meta-weights of-size meta-neuronCount. rtn set-homeland of homeland. return rtn. + to get-neuron-count: return neuronCount. + to get-iteration-step: return iterationStep. + to set-iteration-step to newTimeStep (float): iterationStep = newTimeStep. neuralNetworkSetTimeStep(network, newTimeStep). neuralNetworkSetTimeStep(meta-network, newTimeStep). + to get-time-constant: return timeConstant. + to set-time-constant to newTimeConstant (float): timeConstant = newTimeConstant. neuralNetworkSetTimeConstant(network, newTimeConstant). neuralNetworkSetTimeConstant(meta-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). neuralNetworkSetNeuronStateBounds(meta-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 perturb-neuron-state at index (int) to value (float): oldVal(float). newVal(float). oldVal = neuralNetworkGetNeuronState(network, index). newVal = oldVal + value. neuralNetworkSetNeuronState(network, index, newVal). + 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 get-meta-connection-weight-matrix: return meta-weights. + to set-connection-weight-matrix to val (double) at-x i (int) at-y m (int): if i != m:{ connections set-value to 1.0 at-x i at-y m. weights set-value to val at-x i at-y m. } + to set-meta-connection-weight-matrix to val (double) at-x i (int) at-y m (int): if i != m:{ meta-connections set-value to 1.0 at-x i at-y m. meta-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-meta-weight at-x x (int) at-y y (int): return (meta-weights get-value at-x x at-y y). + to perturb-weight to val(double) at-x x(int) at-y y (int): tempval(double). tempval = (weights get-value at-x x at-y y). tempval = tempval + val. weights set-value to tempval 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 n (int). m (int). o (int). val (double). oldval (double). neuralNetworkUpdateState(network). for n = 0, n < neuronCount, n++:{ val = neuralNetworkGetNeuronState(network, n). oldval = neuralNetworkGetNeuronState(meta-network, n). val = val + oldval. neuralNetworkSetNeuronState(meta-network, n, val). } neuralNetworkUpdateState(meta-network). for n = 0, n < neuronCount, n++:{ for m = 0, m < neuronCount, m++:{ if n != m:{ o = (meta-neuronCount - ((n * neuronCount) + m)). val = neuralNetworkGetNeuronState(meta-network, o). oldval = (weights get-value at-x n at-y m). val = val + oldval. if val > 1.0 : val = 1.0. if val < -1.0 : val = -1.0. weights set-value to val at-x n at-y m. } } } + 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). 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). 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 mutate-meta-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). for i=0, i < z, i++:{ n = random[meta-neuronCount]. m = random[meta-neuronCount]. val = random[2.0]- 1.0. if m != n:{ meta-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). 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". } } } } #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". } } } } #homeland = #newhomeland = (parent1 get-homeland). #newhomeland = "($newhomeland X $homeland)". #homeland = newhomeland. #die "The method \"crossover\" must be implemented in your GeneticAlgorithmIndividual subclass!". + to crossover-meta-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 [meta-neuronCount - 1]. m = random [meta-neuronCount - 1]. o = random [meta-neuronCount - 1 - n]. o = o + n. p = random [neuronCount - 1]. print "crossover point 1 $n - $m : point 2 $o - $p". for i=0, i < meta-neuronCount, i++:{ for r=0, r < meta-neuronCount, r++:{ if i!=r:{ if (i > n && i < o && r > m && r < p):{ val = parent1 get-meta-weight at-x i at-y r. #meta-connections set-value to 1.0 at-x i at-y r. meta-weights set-value to val at-x i at-y r. #print "parent 1 $i $r". } else:{ val = parent2 get-meta-weight at-x i at-y r. #meta-connections set-value to 1.0 at-x i at-y r. meta-weights set-value to val at-x i at-y r. #print "parent 2 2 2". } } } } + to crossover-meta-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. r (int). i (int). val(double). for i=0, i < meta-neuronCount, i++:{ for r=0, r < meta-neuronCount, r++:{ if i!=r:{ if random[2.0]>1:{ val = parent1 get-meta-weight at-x i at-y r. #meta-connections set-value to 1.0 at-x i at-y r. meta-weights set-value to val at-x i at-y r. #print "parent 1 $i $r". } else:{ val = parent2 get-meta-weight at-x i at-y r. #meta-connections set-value to 1.0 at-x i at-y r. meta-weights set-meta-value to val at-x i at-y r. #print "parent 2 2 2". } } } } + to get-copy: #XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXxxthis needs updated #n (int). m (int). i (int). val(double). rtn (object). rtn = new NeuralNetwork4. rtn init-with neuron-count neuronCount. for i=0, i