1use num_traits::Float;
4#[cfg(feature = "serde")]
5use serde::{Deserialize, Serialize};
6
7#[derive(Clone, Debug, PartialEq)]
11#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
12pub struct Bias<T> {
13 value: T,
14}
15
16impl<T: Float> Bias<T> {
17 pub fn new(value: T) -> Self {
19 Self { value }
20 }
21
22 pub fn value(&self) -> T {
24 self.value
25 }
26
27 pub fn mut_value(&mut self) -> &mut T {
29 &mut self.value
30 }
31}
32
33#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
35#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
36pub struct InputId(usize);
37
38impl InputId {
39 pub fn new(id: usize) -> Self {
41 Self(id)
42 }
43
44 pub fn as_usize(&self) -> usize {
46 self.0
47 }
48}
49
50#[derive(Clone, Debug, PartialEq)]
54#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
55pub struct Input<T> {
56 id: InputId,
58 weight: T,
59}
60
61impl<T: Float> Input<T> {
62 pub fn new(id: InputId, weight: T) -> Self {
65 Self { id, weight }
66 }
67
68 pub fn id(&self) -> InputId {
70 self.id
71 }
72
73 pub fn weight(&self) -> T {
75 self.weight
76 }
77
78 pub fn mut_weight(&mut self) -> &mut T {
80 &mut self.weight
81 }
82}
83
84#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
86#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
87pub struct NeuronId(usize);
88
89impl NeuronId {
90 pub fn new(id: usize) -> Self {
92 Self(id)
93 }
94
95 pub fn as_usize(&self) -> usize {
97 self.0
98 }
99}
100
101#[derive(Clone, Debug, PartialEq)]
105#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
106pub struct Neuron<T: Float> {
107 id: NeuronId,
109 num_inputs: usize,
111 weight: T,
115 #[cfg_attr(feature = "serde", serde(skip))]
118 #[cfg_attr(feature = "serde", serde(default = "Default::default"))]
119 current_value: Option<T>,
120 #[cfg_attr(feature = "serde", serde(skip))]
122 #[cfg_attr(feature = "serde", serde(default = "T::zero"))]
123 previous_value: T,
124}
125
126impl<T: Float> Neuron<T> {
127 pub fn new(id: NeuronId, num_inputs: usize, weight: T) -> Self {
129 Self {
130 id,
131 num_inputs,
132 weight,
133 current_value: None,
134 previous_value: T::zero(),
135 }
136 }
137
138 pub fn id(&self) -> NeuronId {
140 self.id
141 }
142
143 pub fn num_inputs(&self) -> usize {
145 self.num_inputs
146 }
147
148 pub(crate) fn set_num_inputs(&mut self, num_inputs: usize) {
150 self.num_inputs = num_inputs;
151 }
152
153 pub fn weight(&self) -> T {
155 self.weight
156 }
157
158 pub(crate) fn mut_weight(&mut self) -> &mut T {
160 &mut self.weight
161 }
162
163 pub(crate) fn current_value(&self) -> Option<T> {
164 self.current_value
165 }
166
167 pub(crate) fn set_current_value(&mut self, value: Option<T>) {
168 self.current_value = value;
169 }
170
171 pub fn previous_value(&self) -> T {
175 self.previous_value
176 }
177
178 pub(crate) fn mut_previous_value(&mut self) -> &mut T {
179 &mut self.previous_value
180 }
181}
182
183#[derive(Clone, Debug, PartialEq)]
188#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
189pub struct ForwardJumper<T> {
190 source_id: NeuronId,
192 weight: T,
195}
196
197impl<T: Float> ForwardJumper<T> {
198 pub fn new(source_id: NeuronId, weight: T) -> Self {
201 Self { source_id, weight }
202 }
203
204 pub fn source_id(&self) -> NeuronId {
206 self.source_id
207 }
208
209 pub fn weight(&self) -> T {
211 self.weight
212 }
213
214 pub fn mut_weight(&mut self) -> &mut T {
216 &mut self.weight
217 }
218}
219
220#[derive(Clone, Debug, PartialEq)]
225#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
226pub struct RecurrentJumper<T> {
227 source_id: NeuronId,
229 weight: T,
232}
233
234impl<T: Float> RecurrentJumper<T> {
235 pub fn new(source_id: NeuronId, weight: T) -> Self {
238 Self { source_id, weight }
239 }
240
241 pub fn source_id(&self) -> NeuronId {
243 self.source_id
244 }
245
246 pub fn weight(&self) -> T {
248 self.weight
249 }
250
251 pub fn mut_weight(&mut self) -> &mut T {
253 &mut self.weight
254 }
255}
256
257#[derive(Clone, Debug, PartialEq)]
260#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
261#[cfg_attr(feature = "serde", serde(tag = "kind"))]
262#[cfg_attr(feature = "serde", serde(rename_all = "lowercase"))]
263pub enum Gene<T: Float> {
264 Bias(Bias<T>),
266 Input(Input<T>),
268 Neuron(Neuron<T>),
270 ForwardJumper(ForwardJumper<T>),
272 RecurrentJumper(RecurrentJumper<T>),
274}
275
276impl<T: Float> Gene<T> {
277 pub fn weight(&self) -> T {
279 match self {
280 Self::Bias(bias) => bias.value(),
281 Self::Input(input) => input.weight(),
282 Self::Neuron(neuron) => neuron.weight(),
283 Self::ForwardJumper(forward) => forward.weight(),
284 Self::RecurrentJumper(recurrent) => recurrent.weight(),
285 }
286 }
287
288 pub(crate) fn mut_weight(&mut self) -> &mut T {
290 match self {
291 Self::Bias(bias) => bias.mut_value(),
292 Self::Input(input) => input.mut_weight(),
293 Self::Neuron(neuron) => neuron.mut_weight(),
294 Self::ForwardJumper(forward) => forward.mut_weight(),
295 Self::RecurrentJumper(recurrent) => recurrent.mut_weight(),
296 }
297 }
298
299 pub fn is_bias(&self) -> bool {
301 matches!(self, Self::Bias(_))
302 }
303
304 pub fn is_input(&self) -> bool {
306 matches!(self, Self::Input(_))
307 }
308
309 pub fn is_neuron(&self) -> bool {
311 matches!(self, Self::Neuron(_))
312 }
313
314 pub fn is_forward_jumper(&self) -> bool {
316 matches!(self, Self::ForwardJumper(_))
317 }
318
319 pub fn is_recurrent_jumper(&self) -> bool {
321 matches!(self, Self::RecurrentJumper(_))
322 }
323
324 pub fn as_bias(&self) -> Option<&Bias<T>> {
326 if let Self::Bias(bias) = self {
327 Some(bias)
328 } else {
329 None
330 }
331 }
332
333 pub fn as_input(&self) -> Option<&Input<T>> {
335 if let Self::Input(input) = self {
336 Some(input)
337 } else {
338 None
339 }
340 }
341
342 pub fn as_neuron(&self) -> Option<&Neuron<T>> {
344 if let Self::Neuron(neuron) = self {
345 Some(neuron)
346 } else {
347 None
348 }
349 }
350
351 pub fn as_forward_jumper(&self) -> Option<&ForwardJumper<T>> {
353 if let Self::ForwardJumper(forward) = self {
354 Some(forward)
355 } else {
356 None
357 }
358 }
359
360 pub fn as_recurrent_jumper(&self) -> Option<&RecurrentJumper<T>> {
362 if let Self::RecurrentJumper(recurrent) = self {
363 Some(recurrent)
364 } else {
365 None
366 }
367 }
368
369 pub(crate) fn as_mut_neuron(&mut self) -> Option<&mut Neuron<T>> {
371 if let Self::Neuron(neuron) = self {
372 Some(neuron)
373 } else {
374 None
375 }
376 }
377}
378
379impl<T: Float> From<Bias<T>> for Gene<T> {
380 fn from(bias: Bias<T>) -> Self {
381 Self::Bias(bias)
382 }
383}
384
385impl<T: Float> From<Input<T>> for Gene<T> {
386 fn from(input: Input<T>) -> Self {
387 Self::Input(input)
388 }
389}
390
391impl<T: Float> From<Neuron<T>> for Gene<T> {
392 fn from(neuron: Neuron<T>) -> Self {
393 Self::Neuron(neuron)
394 }
395}
396
397impl<T: Float> From<ForwardJumper<T>> for Gene<T> {
398 fn from(forward: ForwardJumper<T>) -> Self {
399 Self::ForwardJumper(forward)
400 }
401}
402
403impl<T: Float> From<RecurrentJumper<T>> for Gene<T> {
404 fn from(recurrent: RecurrentJumper<T>) -> Self {
405 Self::RecurrentJumper(recurrent)
406 }
407}
408
409#[derive(Clone, Debug, PartialEq)]
411pub enum NonNeuronGene<T> {
412 Bias(Bias<T>),
414 Input(Input<T>),
416 ForwardJumper(ForwardJumper<T>),
418 RecurrentJumper(RecurrentJumper<T>),
420}
421
422impl<T> From<Bias<T>> for NonNeuronGene<T> {
423 fn from(bias: Bias<T>) -> Self {
424 Self::Bias(bias)
425 }
426}
427
428impl<T> From<Input<T>> for NonNeuronGene<T> {
429 fn from(input: Input<T>) -> Self {
430 Self::Input(input)
431 }
432}
433
434impl<T> From<ForwardJumper<T>> for NonNeuronGene<T> {
435 fn from(forward: ForwardJumper<T>) -> Self {
436 Self::ForwardJumper(forward)
437 }
438}
439
440impl<T> From<RecurrentJumper<T>> for NonNeuronGene<T> {
441 fn from(recurrent: RecurrentJumper<T>) -> Self {
442 Self::RecurrentJumper(recurrent)
443 }
444}
445
446impl<T: Float> From<NonNeuronGene<T>> for Gene<T> {
447 fn from(gene: NonNeuronGene<T>) -> Self {
448 match gene {
449 NonNeuronGene::Bias(bias) => Self::Bias(bias),
450 NonNeuronGene::Input(input) => Self::Input(input),
451 NonNeuronGene::ForwardJumper(forward) => Self::ForwardJumper(forward),
452 NonNeuronGene::RecurrentJumper(recurrent) => Self::RecurrentJumper(recurrent),
453 }
454 }
455}