Skip to content

Commit ab76025

Browse files
committed
Allow for 0.0 bandwidth samplers pre-clamped and post-clamped
1 parent a946f2d commit ab76025

3 files changed

Lines changed: 104 additions & 75 deletions

File tree

src/genotype/multi_range.rs

Lines changed: 45 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -264,26 +264,8 @@ where
264264
MutationType::Range(_) => {
265265
// post-clamp
266266
let current_value = chromosome.genes[index];
267-
let delta = self.allele_bandwidth_samplers[index]
268-
.as_ref()
269-
.unwrap()
270-
.sample(rng);
271-
if rng.gen() {
272-
chromosome.genes[index] =
273-
T::clamped_add(current_value, delta, *self.allele_ranges[index].end());
274-
} else {
275-
chromosome.genes[index] =
276-
T::clamped_sub(current_value, delta, *self.allele_ranges[index].start());
277-
}
278-
}
279-
MutationType::RangeScaled(bandwidths) => {
280-
if self.current_scale_index >= bandwidths.len().saturating_sub(1) {
281-
// post-clamp
282-
let current_value = chromosome.genes[index];
283-
let delta = self.allele_bandwidth_samplers[index]
284-
.as_ref()
285-
.unwrap()
286-
.sample(rng);
267+
if let Some(sampler) = self.allele_bandwidth_samplers[index].as_ref() {
268+
let delta = sampler.sample(rng);
287269
if rng.gen() {
288270
chromosome.genes[index] =
289271
T::clamped_add(current_value, delta, *self.allele_ranges[index].end());
@@ -294,6 +276,28 @@ where
294276
*self.allele_ranges[index].start(),
295277
);
296278
}
279+
}
280+
}
281+
MutationType::RangeScaled(bandwidths) => {
282+
if self.current_scale_index >= bandwidths.len().saturating_sub(1) {
283+
// post-clamp
284+
let current_value = chromosome.genes[index];
285+
if let Some(sampler) = self.allele_bandwidth_samplers[index].as_ref() {
286+
let delta = sampler.sample(rng);
287+
if rng.gen() {
288+
chromosome.genes[index] = T::clamped_add(
289+
current_value,
290+
delta,
291+
*self.allele_ranges[index].end(),
292+
);
293+
} else {
294+
chromosome.genes[index] = T::clamped_sub(
295+
current_value,
296+
delta,
297+
*self.allele_ranges[index].start(),
298+
);
299+
}
300+
}
297301
} else {
298302
// pre-clamp
299303
let bandwidth = bandwidths[self.current_scale_index];
@@ -637,27 +641,28 @@ where
637641
population: &mut Population<T>,
638642
rng: &mut R,
639643
) {
640-
let allele_range_start = *self.allele_ranges[index].start();
641-
let allele_range_end = *self.allele_ranges[index].end();
642-
643-
let current_value = chromosome.genes[index];
644-
let delta = self.allele_bandwidth_samplers[index]
645-
.as_ref()
646-
.unwrap()
647-
.sample(rng);
648-
if allele_range_start < current_value {
649-
let mut new_chromosome = population.new_chromosome(chromosome);
650-
new_chromosome.genes[index] = T::clamped_sub(current_value, delta, allele_range_start);
651-
new_chromosome.reset_metadata(self.genes_hashing);
652-
population.chromosomes.push(new_chromosome);
653-
};
654-
if current_value < allele_range_end {
655-
let mut new_chromosome = population.new_chromosome(chromosome);
656-
new_chromosome.genes[index] = T::clamped_add(current_value, delta, allele_range_end);
657-
new_chromosome.reset_metadata(self.genes_hashing);
658-
population.chromosomes.push(new_chromosome);
659-
};
644+
if let Some(sampler) = self.allele_bandwidth_samplers[index].as_ref() {
645+
let delta = sampler.sample(rng);
646+
let allele_range_start = *self.allele_ranges[index].start();
647+
let allele_range_end = *self.allele_ranges[index].end();
648+
let current_value = chromosome.genes[index];
649+
if allele_range_start < current_value {
650+
let mut new_chromosome = population.new_chromosome(chromosome);
651+
new_chromosome.genes[index] =
652+
T::clamped_sub(current_value, delta, allele_range_start);
653+
new_chromosome.reset_metadata(self.genes_hashing);
654+
population.chromosomes.push(new_chromosome);
655+
};
656+
if current_value < allele_range_end {
657+
let mut new_chromosome = population.new_chromosome(chromosome);
658+
new_chromosome.genes[index] =
659+
T::clamped_add(current_value, delta, allele_range_end);
660+
new_chromosome.reset_metadata(self.genes_hashing);
661+
population.chromosomes.push(new_chromosome);
662+
};
663+
}
660664
}
665+
661666
fn fill_neighbouring_population_range_pre_clamp<R: Rng>(
662667
&self,
663668
index: usize,

src/genotype/range.rs

Lines changed: 40 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -180,27 +180,31 @@ where
180180
MutationType::Range(_) => {
181181
// post-clamp
182182
let current_value = chromosome.genes[index];
183-
let delta = self.allele_bandwidth_sampler.as_ref().unwrap().sample(rng);
184-
if rng.gen() {
185-
chromosome.genes[index] =
186-
T::clamped_add(current_value, delta, *self.allele_range.end());
187-
} else {
188-
chromosome.genes[index] =
189-
T::clamped_sub(current_value, delta, *self.allele_range.start());
190-
}
191-
}
192-
MutationType::RangeScaled(bandwidths) => {
193-
if self.current_scale_index >= bandwidths.len().saturating_sub(1) {
194-
// post-clamp
195-
let current_value = chromosome.genes[index];
196-
let delta = self.allele_bandwidth_sampler.as_ref().unwrap().sample(rng);
183+
if let Some(sampler) = self.allele_bandwidth_sampler.as_ref() {
184+
let delta = sampler.sample(rng);
197185
if rng.gen() {
198186
chromosome.genes[index] =
199187
T::clamped_add(current_value, delta, *self.allele_range.end());
200188
} else {
201189
chromosome.genes[index] =
202190
T::clamped_sub(current_value, delta, *self.allele_range.start());
203191
}
192+
}
193+
}
194+
MutationType::RangeScaled(bandwidths) => {
195+
if self.current_scale_index >= bandwidths.len().saturating_sub(1) {
196+
// post-clamp
197+
let current_value = chromosome.genes[index];
198+
if let Some(sampler) = self.allele_bandwidth_sampler.as_ref() {
199+
let delta = sampler.sample(rng);
200+
if rng.gen() {
201+
chromosome.genes[index] =
202+
T::clamped_add(current_value, delta, *self.allele_range.end());
203+
} else {
204+
chromosome.genes[index] =
205+
T::clamped_sub(current_value, delta, *self.allele_range.start());
206+
}
207+
}
204208
} else {
205209
// pre-clamp
206210
let bandwidth = bandwidths[self.current_scale_index];
@@ -534,27 +538,29 @@ where
534538
population: &mut Population<T>,
535539
rng: &mut R,
536540
) {
537-
let allele_range_start = *self.allele_range.start();
538-
let allele_range_end = *self.allele_range.end();
541+
if let Some(sampler) = self.allele_bandwidth_sampler.as_ref() {
542+
let allele_range_start = *self.allele_range.start();
543+
let allele_range_end = *self.allele_range.end();
539544

540-
(0..self.genes_size).for_each(|index| {
541-
let current_value = chromosome.genes[index];
542-
let delta = self.allele_bandwidth_sampler.as_ref().unwrap().sample(rng);
543-
if allele_range_start < current_value {
544-
let mut new_chromosome = population.new_chromosome(chromosome);
545-
new_chromosome.genes[index] =
546-
T::clamped_sub(current_value, delta, allele_range_start);
547-
new_chromosome.reset_metadata(self.genes_hashing);
548-
population.chromosomes.push(new_chromosome);
549-
};
550-
if current_value < allele_range_end {
551-
let mut new_chromosome = population.new_chromosome(chromosome);
552-
new_chromosome.genes[index] =
553-
T::clamped_add(current_value, delta, allele_range_end);
554-
new_chromosome.reset_metadata(self.genes_hashing);
555-
population.chromosomes.push(new_chromosome);
556-
};
557-
});
545+
(0..self.genes_size).for_each(|index| {
546+
let current_value = chromosome.genes[index];
547+
let delta = sampler.sample(rng);
548+
if allele_range_start < current_value {
549+
let mut new_chromosome = population.new_chromosome(chromosome);
550+
new_chromosome.genes[index] =
551+
T::clamped_sub(current_value, delta, allele_range_start);
552+
new_chromosome.reset_metadata(self.genes_hashing);
553+
population.chromosomes.push(new_chromosome);
554+
};
555+
if current_value < allele_range_end {
556+
let mut new_chromosome = population.new_chromosome(chromosome);
557+
new_chromosome.genes[index] =
558+
T::clamped_add(current_value, delta, allele_range_end);
559+
new_chromosome.reset_metadata(self.genes_hashing);
560+
population.chromosomes.push(new_chromosome);
561+
};
562+
});
563+
}
558564
}
559565
fn fill_neighbouring_population_range_pre_clamp<R: Rng>(
560566
&self,

tests/genotype/range_test.rs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,14 +129,32 @@ fn float_mutate_chromosome_single_range_scaled_on_edge() {
129129
let mut genotype = RangeGenotype::builder()
130130
.with_genes_size(3)
131131
.with_allele_range(0.0..=1.0)
132-
.with_mutation_type(MutationType::RangeScaled(vec![1.0, 0.1, 0.01]))
132+
.with_mutation_type(MutationType::RangeScaled(vec![1.0, 0.1, 0.0, 0.0]))
133133
.build()
134134
.unwrap();
135135

136136
let mut chromosome = build::chromosome(vec![1.0, 0.0, 1.0]);
137+
137138
assert!(genotype.increment_scale_index());
138139
assert_eq!(genotype.current_scale_index, 1);
140+
genotype.mutate_chromosome_genes(3, false, &mut chromosome, &mut rng);
141+
assert!(relative_chromosome_eq(
142+
inspect::chromosome(&chromosome),
143+
vec![0.970, 0.0, 0.904],
144+
0.001,
145+
));
146+
147+
assert!(genotype.increment_scale_index());
148+
assert_eq!(genotype.current_scale_index, 2);
149+
genotype.mutate_chromosome_genes(3, false, &mut chromosome, &mut rng);
150+
assert!(relative_chromosome_eq(
151+
inspect::chromosome(&chromosome),
152+
vec![0.970, 0.0, 0.904],
153+
0.001,
154+
));
139155

156+
assert!(genotype.increment_scale_index());
157+
assert_eq!(genotype.current_scale_index, 3);
140158
genotype.mutate_chromosome_genes(3, false, &mut chromosome, &mut rng);
141159
assert!(relative_chromosome_eq(
142160
inspect::chromosome(&chromosome),

0 commit comments

Comments
 (0)