Skip to content

Commit a946f2d

Browse files
committed
fix issue where max_delta_up/down was 0.0 leading to empty range
1 parent 56aa7a1 commit a946f2d

3 files changed

Lines changed: 106 additions & 32 deletions

File tree

src/genotype/multi_range.rs

Lines changed: 42 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -204,11 +204,19 @@ where
204204
.iter()
205205
.map(|mutation_type| match &mutation_type {
206206
MutationType::Range(bandwidth) => {
207-
Some(Uniform::new_inclusive(T::smallest_increment(), bandwidth))
207+
if *bandwidth >= T::smallest_increment() {
208+
Some(Uniform::new_inclusive(T::smallest_increment(), bandwidth))
209+
} else {
210+
None
211+
}
208212
}
209213
MutationType::RangeScaled(bandwidths) => {
210214
let bandwidth = bandwidths.last().unwrap();
211-
Some(Uniform::new_inclusive(T::smallest_increment(), bandwidth))
215+
if *bandwidth >= T::smallest_increment() {
216+
Some(Uniform::new_inclusive(T::smallest_increment(), bandwidth))
217+
} else {
218+
None
219+
}
212220
}
213221
_ => None,
214222
})
@@ -300,13 +308,19 @@ where
300308
if rng.gen() {
301309
let max_delta_up = allele_range_end - current_value;
302310
let working_delta_up = T::min(bandwidth, max_delta_up);
303-
let delta = rng.gen_range(T::smallest_increment()..=working_delta_up);
304-
chromosome.genes[index] += delta; // no need to check again
311+
if working_delta_up >= T::smallest_increment() {
312+
let delta =
313+
rng.gen_range(T::smallest_increment()..=working_delta_up);
314+
chromosome.genes[index] += delta; // no need to check again
315+
}
305316
} else {
306317
let max_delta_down = current_value - allele_range_start;
307318
let working_delta_down = T::min(bandwidth, max_delta_down);
308-
let delta = rng.gen_range(T::smallest_increment()..=working_delta_down);
309-
chromosome.genes[index] -= delta; // no need to check again
319+
if working_delta_down >= T::smallest_increment() {
320+
let delta =
321+
rng.gen_range(T::smallest_increment()..=working_delta_down);
322+
chromosome.genes[index] -= delta; // no need to check again
323+
}
310324
}
311325
}
312326
}
@@ -660,19 +674,23 @@ where
660674
let mut new_chromosome = population.new_chromosome(chromosome);
661675
let max_delta_down = current_value - allele_range_start;
662676
let working_delta_down = T::min(bandwidth, max_delta_down);
663-
let delta = rng.gen_range(T::smallest_increment()..=working_delta_down);
664-
new_chromosome.genes[index] -= delta; // no need to check again
665-
new_chromosome.reset_metadata(self.genes_hashing);
666-
population.chromosomes.push(new_chromosome);
677+
if working_delta_down >= T::smallest_increment() {
678+
let delta = rng.gen_range(T::smallest_increment()..=working_delta_down);
679+
new_chromosome.genes[index] -= delta; // no need to check again
680+
new_chromosome.reset_metadata(self.genes_hashing);
681+
population.chromosomes.push(new_chromosome);
682+
}
667683
};
668684
if current_value < allele_range_end {
669685
let mut new_chromosome = population.new_chromosome(chromosome);
670686
let max_delta_up = allele_range_end - current_value;
671687
let working_delta_up = T::min(bandwidth, max_delta_up);
672-
let delta = rng.gen_range(T::smallest_increment()..=working_delta_up);
673-
new_chromosome.genes[index] += delta; // no need to check again
674-
new_chromosome.reset_metadata(self.genes_hashing);
675-
population.chromosomes.push(new_chromosome);
688+
if working_delta_up >= T::smallest_increment() {
689+
let delta = rng.gen_range(T::smallest_increment()..=working_delta_up);
690+
new_chromosome.genes[index] += delta; // no need to check again
691+
new_chromosome.reset_metadata(self.genes_hashing);
692+
population.chromosomes.push(new_chromosome);
693+
}
676694
};
677695
}
678696
fn fill_neighbouring_population_random<R: Rng>(
@@ -1000,11 +1018,19 @@ where
10001018
.iter()
10011019
.map(|mutation_type| match &mutation_type {
10021020
MutationType::Range(bandwidth) => {
1003-
Some(Uniform::new_inclusive(T::smallest_increment(), bandwidth))
1021+
if *bandwidth >= T::smallest_increment() {
1022+
Some(Uniform::new_inclusive(T::smallest_increment(), bandwidth))
1023+
} else {
1024+
None
1025+
}
10041026
}
10051027
MutationType::RangeScaled(bandwidths) => {
10061028
let bandwidth = bandwidths.last().unwrap();
1007-
Some(Uniform::new_inclusive(T::smallest_increment(), bandwidth))
1029+
if *bandwidth >= T::smallest_increment() {
1030+
Some(Uniform::new_inclusive(T::smallest_increment(), bandwidth))
1031+
} else {
1032+
None
1033+
}
10081034
}
10091035
_ => None,
10101036
})

src/genotype/range.rs

Lines changed: 42 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -120,11 +120,19 @@ where
120120
};
121121
let allele_bandwidth_sampler = match &mutation_type {
122122
MutationType::Range(bandwidth) => {
123-
Some(Uniform::new_inclusive(T::smallest_increment(), bandwidth))
123+
if *bandwidth >= T::smallest_increment() {
124+
Some(Uniform::new_inclusive(T::smallest_increment(), bandwidth))
125+
} else {
126+
None
127+
}
124128
}
125129
MutationType::RangeScaled(bandwidths) => {
126130
let bandwidth = bandwidths.last().unwrap();
127-
Some(Uniform::new_inclusive(T::smallest_increment(), bandwidth))
131+
if *bandwidth >= T::smallest_increment() {
132+
Some(Uniform::new_inclusive(T::smallest_increment(), bandwidth))
133+
} else {
134+
None
135+
}
128136
}
129137
_ => None,
130138
};
@@ -207,13 +215,19 @@ where
207215
if rng.gen() {
208216
let max_delta_up = allele_range_end - current_value;
209217
let working_delta_up = T::min(bandwidth, max_delta_up);
210-
let delta = rng.gen_range(T::smallest_increment()..=working_delta_up);
211-
chromosome.genes[index] += delta; // no need to check again
218+
if working_delta_up >= T::smallest_increment() {
219+
let delta =
220+
rng.gen_range(T::smallest_increment()..=working_delta_up);
221+
chromosome.genes[index] += delta; // no need to check again
222+
}
212223
} else {
213224
let max_delta_down = current_value - allele_range_start;
214225
let working_delta_down = T::min(bandwidth, max_delta_down);
215-
let delta = rng.gen_range(T::smallest_increment()..=working_delta_down);
216-
chromosome.genes[index] -= delta; // no need to check again
226+
if working_delta_down >= T::smallest_increment() {
227+
let delta =
228+
rng.gen_range(T::smallest_increment()..=working_delta_down);
229+
chromosome.genes[index] -= delta; // no need to check again
230+
}
217231
}
218232
}
219233
}
@@ -558,19 +572,23 @@ where
558572
let mut new_chromosome = population.new_chromosome(chromosome);
559573
let max_delta_down = current_value - allele_range_start;
560574
let working_delta_down = T::min(bandwidth, max_delta_down);
561-
let delta = rng.gen_range(T::smallest_increment()..=working_delta_down);
562-
new_chromosome.genes[index] -= delta; // no need to check again
563-
new_chromosome.reset_metadata(self.genes_hashing);
564-
population.chromosomes.push(new_chromosome);
575+
if working_delta_down >= T::smallest_increment() {
576+
let delta = rng.gen_range(T::smallest_increment()..=working_delta_down);
577+
new_chromosome.genes[index] -= delta; // no need to check again
578+
new_chromosome.reset_metadata(self.genes_hashing);
579+
population.chromosomes.push(new_chromosome);
580+
}
565581
};
566582
if current_value < allele_range_end {
567583
let mut new_chromosome = population.new_chromosome(chromosome);
568584
let max_delta_up = allele_range_end - current_value;
569585
let working_delta_up = T::min(bandwidth, max_delta_up);
570-
let delta = rng.gen_range(T::smallest_increment()..=working_delta_up);
571-
new_chromosome.genes[index] += delta; // no need to check again
572-
new_chromosome.reset_metadata(self.genes_hashing);
573-
population.chromosomes.push(new_chromosome);
586+
if working_delta_up >= T::smallest_increment() {
587+
let delta = rng.gen_range(T::smallest_increment()..=working_delta_up);
588+
new_chromosome.genes[index] += delta; // no need to check again
589+
new_chromosome.reset_metadata(self.genes_hashing);
590+
population.chromosomes.push(new_chromosome);
591+
}
574592
};
575593
});
576594
}
@@ -884,11 +902,19 @@ where
884902
};
885903
let allele_bandwidth_sampler = match &self.mutation_type {
886904
MutationType::Range(bandwidth) => {
887-
Some(Uniform::new_inclusive(T::smallest_increment(), bandwidth))
905+
if *bandwidth >= T::smallest_increment() {
906+
Some(Uniform::new_inclusive(T::smallest_increment(), bandwidth))
907+
} else {
908+
None
909+
}
888910
}
889911
MutationType::RangeScaled(bandwidths) => {
890912
let bandwidth = bandwidths.last().unwrap();
891-
Some(Uniform::new_inclusive(T::smallest_increment(), bandwidth))
913+
if *bandwidth >= T::smallest_increment() {
914+
Some(Uniform::new_inclusive(T::smallest_increment(), bandwidth))
915+
} else {
916+
None
917+
}
892918
}
893919
_ => None,
894920
};

tests/genotype/range_test.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,28 @@ fn float_mutate_chromosome_single_range_scaled() {
123123
));
124124
}
125125

126+
#[test]
127+
fn float_mutate_chromosome_single_range_scaled_on_edge() {
128+
let mut rng = SmallRng::seed_from_u64(1);
129+
let mut genotype = RangeGenotype::builder()
130+
.with_genes_size(3)
131+
.with_allele_range(0.0..=1.0)
132+
.with_mutation_type(MutationType::RangeScaled(vec![1.0, 0.1, 0.01]))
133+
.build()
134+
.unwrap();
135+
136+
let mut chromosome = build::chromosome(vec![1.0, 0.0, 1.0]);
137+
assert!(genotype.increment_scale_index());
138+
assert_eq!(genotype.current_scale_index, 1);
139+
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+
126148
#[test]
127149
fn float_mutate_chromosome_single_step() {
128150
let mut rng = SmallRng::seed_from_u64(0);

0 commit comments

Comments
 (0)