1pub mod neuron;
9pub mod enecode;
10pub mod graph;
11pub mod doctest;
12pub mod population;
13pub mod api;
14pub mod agent_wrapper;
15
16use rand::prelude::*;
17use enecode::topology::TopologyGene;
18use enecode::NeuronType;
19use log::*;
20use std::collections::HashMap;
21use std::sync::Arc;
22use std::f32::consts::E;
23
24pub fn setup_logger() {
26 pretty_env_logger::try_init().ok();
27}
28
29
30pub fn rng_box(rng_seed: Option<u8>) -> Box<dyn RngCore> {
32 match rng_seed {
33 Some(seedu8) => {
34 let seed = [seedu8; 32];
35 Box::new(StdRng::from_seed(seed))
36 }
37 None => Box::new(rand::thread_rng())
38 }
39}
40
41pub fn hash_em(names: Vec<&str>, weights: Vec<f32>) -> HashMap<String, f32> {
43 let mut hm: HashMap<String, f32> = HashMap::new();
44 for (inn_number, weight) in names.iter().zip(weights.iter()) {
45 hm.insert(String::from(*inn_number), *weight);
46 }
47
48 hm
49}
50
51pub fn ez_input(names: Vec<&str>) -> Vec<String> {
53 names.iter().map(|&n| String::from(n)).collect()
54}
55
56pub fn sort_genes_by_neuron_type(input_topology_vector: Vec<TopologyGene>) -> Vec<TopologyGene> {
58 let mut topology_s: Vec<TopologyGene> = Vec::new();
59 let mut topology_hidden: Vec<TopologyGene> = Vec::new();
60 let mut topology_outputs: Vec<TopologyGene> = Vec::new();
61
62 for tg in input_topology_vector.into_iter() {
63
64 match tg.pin {
65 NeuronType::In => topology_s.push(tg),
66 NeuronType::Hidden => topology_hidden.push(tg),
67 NeuronType::Out => topology_outputs.push(tg),
68 };
69
70 }
71
72 topology_s.sort_by_key(|tg| tg.innovation_number.clone() );
73 topology_hidden.sort_by_key(|tg| tg.innovation_number.clone() );
74 topology_outputs.sort_by_key(|tg| tg.innovation_number.clone() );
75
76 topology_s.extend(topology_hidden.drain(..));
77 topology_s.extend(topology_outputs.drain(..));
78 topology_s
79
80}
81
82pub fn progenitor_code(innovation_number: &str) -> &str {
84 match innovation_number.find("-") {
85 Some(idx) => {
86 let(prog, _tail) = innovation_number.split_at(idx);
87 prog
88 }
89 None => innovation_number
90 }
91
92}
93
94pub fn increment_innovation_number(neuron_id: &str, daughter_ids: Vec<&str>) -> Arc<str> {
96 let progenitor_code: &str = progenitor_code(neuron_id);
101
102 let daughter_ids_progenitor: Vec<&str> = daughter_ids.iter().map(|x| *x)
103 .filter(|id| id.starts_with(progenitor_code))
104 .filter(|&id| id != progenitor_code).collect();
105
106 if daughter_ids_progenitor.len() == 0 {
108 format!("{}-0001", progenitor_code).into()
109 } else {
110 let largest_daughter_id = daughter_ids_progenitor.iter().max().unwrap();
112
113 if let Some(idx) = largest_daughter_id.rfind("-") {
114 let (previous_lineage, largest_daughter_number) = largest_daughter_id.split_at(idx);
115
116 let ldn: i32 = match largest_daughter_number[1..].parse() {
117 Ok(n) => n,
118 Err(_e) => panic!("Failed to parse string daughter number"),
119 };
120
121 let mut daughter_id = String::from(previous_lineage);
122 let daughter_innovation = format!("-{:0>4}", ldn + 1);
125 daughter_id.push_str(&daughter_innovation);
126
127 Arc::from(daughter_id)
128
129 } else {
130 debug!("Problem with parsing string largest_daughter_id {} while duplicating {}", largest_daughter_id, neuron_id);
131 panic!("Attempted to parse daughter innovation number but found invalid code");
132 }
133 }
134}
135
136pub fn sigmoid(z: &f32) -> f32 {
138 1.0 / (1.0 + E.powf(-z))
139}
140
141pub fn relu(z: &f32) -> f32 {
143 match *z > 0.0 {
144 true => *z,
145 false => 0.0,
146 }
147}
148
149#[cfg(test)]
150mod tests {
151 use super::*;
152
153 #[test]
154 fn test_progenitor_code() {
155 assert_eq!("a0", progenitor_code("a0"));
156 assert_eq!("a0", progenitor_code("a0-12345"));
157 assert_eq!("b00", progenitor_code("b00-12345"));
158 }
159
160 #[test]
161 fn test_increment_innovation_number() {
162 let innovation_number = String::from("a0");
163 let daughters = Vec::new();
164
165 let d1 = increment_innovation_number(&innovation_number, daughters);
166 assert_eq!(&*d1, "a0-0001");
167
168 let daughters2 = vec!["a0-0001", "a0-0002"];
169 let d2 = increment_innovation_number(&innovation_number, daughters2);
170 assert_eq!(&*d2, "a0-0003");
171
172 let innovation_number2 = String::from("a0-0001");
173
174 let daughters3 = vec!["a0-0002", "a0-0005", "B0-10000"];
175 let d3 = increment_innovation_number(&innovation_number2, daughters3);
176
177 assert_eq!(&*d3, "a0-0006");
178 }
179}