'use strict'; // genome structure // { // genes: gene[] // n_input, n_internal, n_output // } import { validate_genome, parse_genome, mut_gene_source, mut_gene_sink, mut_gene_weight, mut_genome_expand, mut_genome_contract, mut_genome_insert, mut_genome_delete, } from './genome'; test('genome validation', () => { expect(validate_genome({ n_input: 0, n_internal: 1, n_output: 0, genes: [[0, 0, 1.0]], })).toBe(true); expect(validate_genome({ n_input: 2, n_internal: 0, n_output: 1, genes: [[0, 2, 1]], })).toBe(true); expect(validate_genome({ n_input: 2, n_internal: 0, n_output: 1, genes: [[2, 0, 1]], })).toBe(false); expect(validate_genome({ n_input: 2, n_internal: 0, n_output: 1, genes: [[2, 2, 1]], })).toBe(false); expect(validate_genome({ n_input: 2, n_internal: 1, n_output: 1, genes: [[3, 2, 1]], })).toBe(false); }); test('parse a genome into a neural net', () => { const n = parse_genome({ n_input: 1, n_internal: 1, n_output: 1, genes: [ [0, 1, 1], [1, 1, 1], [1, 2, 1] ] }); expect(n.input_count).toBe(1); expect(n.output_count).toBe(1); expect(n.compute([2], [-1])).toEqual([ [ Math.tanh( Math.tanh( 2-1 ) ) ], [ Math.tanh( 2-1 ) ], ]); }); test('mutate gene source', () => { const n_input = 3; const n_internal = 4; const n_output = 5; expect(mut_gene_source( n_input, n_internal, n_output, [0, 4, 0], 0.0 )).toEqual([0, 4, 0]); expect(mut_gene_source( n_input, n_internal, n_output, [0, 4, 0], 1.0 )).toEqual([1, 4, 0]); expect(mut_gene_source( n_input, n_internal, n_output, [6, 4, 0], 0.0 )).toEqual([5, 4, 0]); expect(mut_gene_source( n_input, n_internal, n_output, [6, 4, 0], 1.0 )).toEqual([6, 4, 0]); }); test('mutate gene sink', () => { const n_input = 3; const n_internal = 4; const n_output = 5; expect(mut_gene_sink( n_input, n_internal, n_output, [0, 7, 0], 0.0 )).toEqual([0, 7, 0]); expect(mut_gene_sink( n_input, n_internal, n_output, [0, 7, 0], 1.0 )).toEqual([0, 8, 0]); expect(mut_gene_sink( n_input, n_internal, n_output, [6, 11, 0], 0.0 )).toEqual([6, 10, 0]); expect(mut_gene_sink( n_input, n_internal, n_output, [6, 11, 0], 1.0 )).toEqual([6, 11, 0]); }); test('mutate gene weight', () => { const weight_max = 4.0; expect(mut_gene_weight( weight_max, [0, 0, 1], 0.0 )).toEqual([0, 0, (2 - 4)/3]); expect(mut_gene_weight( weight_max, [0, 0, -4], 1.0 )).toEqual([0, 0, (-8 + 4)/3]); expect(mut_gene_weight( weight_max, [0, 0, 3], 0.5 )).toEqual([0, 0, (6+0)/3]); }); test('expand genome', () => { const n_input = 1; const n_internal = 3; const n_output = 1; const genome = { n_input, n_internal, n_output, genes: [ [0, 1, 0], [1, 2, 0], [2, 3, 0], [3, 4, 0], ], }; expect(mut_genome_expand(genome, 0.0)).toEqual({ n_input, n_internal: n_internal+1, n_output, genes: [ [0, 2, 0], [2, 3, 0], [3, 4, 0], [4, 5, 0], ], }); expect(mut_genome_expand(genome, 0.5)).toEqual({ n_input, n_internal: n_internal+1, n_output, genes: [ [0, 1, 0], [1, 3, 0], [3, 4, 0], [4, 5, 0], ], }); expect(mut_genome_expand(genome, 0.99)).toEqual({ n_input, n_internal: n_internal+1, n_output, genes: [ [0, 1, 0], [1, 2, 0], [2, 4, 0], [4, 5, 0], ], }); }); test('contract genome', () => { const n_input = 1; const n_internal = 3; const n_output = 1; const genome = { n_input, n_internal, n_output, genes: [ [0, 1, 0], [1, 2, 1], [2, 3, 2], [3, 4, 3], ], }; expect(mut_genome_contract(genome, 0.0)).toEqual({ n_input, n_internal: n_internal-1, n_output, genes: [ [0, 1, 0], [0, 1, 1], [1, 2, 2], [2, 3, 3], ], }); expect(mut_genome_contract(genome, 0.5)).toEqual({ n_input, n_internal: n_internal-1, n_output, genes: [ [0, 1, 0], [1, 2, 1], [1, 2, 2], [2, 3, 3], ], }); expect(mut_genome_contract(genome, 0.99)).toEqual({ n_input, n_internal: n_internal-1, n_output, genes: [ [0, 1, 0], [1, 2, 1], [2, 3, 2], [2, 3, 3], ], }); }); test('insert new genes', () => { const n_input = 1; const n_internal = 2; const n_output = 1; const weight_max = 4; expect(mut_genome_insert({ n_input, n_internal, n_output, genes: [] }, weight_max, 0, 0.5, 0)).toEqual({ n_input, n_internal, n_output, genes: [[0, 2, -4]] }); expect(mut_genome_insert({ n_input, n_internal, n_output, genes: [[0, 2, -4]] }, weight_max, 0.99, 0, 1)).toEqual({ n_input, n_internal, n_output, genes: [[0, 2, -4], [2, 1, 4]] }); }); test('remove genes', () => { const n_input = 0; const n_output = 0; const n_internal = 3; const genome = { n_input, n_internal, n_output, genes: [[0, 1, 0], [1, 2, 0]], }; expect(mut_genome_delete(genome, 0.0)).toEqual({ n_input, n_internal, n_output, genes: [[1, 2, 0]], }); expect(mut_genome_delete(genome, 0.99)).toEqual({ n_input, n_internal, n_output, genes: [[0, 1, 0]], }); });