use crate::ASK;
pub struct Amplitudes {
current: usize,
max: usize,
including: bool,
}
impl Amplitudes {
pub fn upto_including_energy(max_energy: usize, ask: &ASK) -> Amplitudes {
let max_amplitude = f64::floor(f64::sqrt(max_energy as f64)) as usize;
Amplitudes {
current: 1,
max: std::cmp::min(max_amplitude, ask.max_amplitude()),
including: true,
}
}
pub fn possible_from_trellis_node(
n: usize,
e: usize,
n_max: usize,
e_max: usize,
ask: &ASK,
) -> Amplitudes {
let next_local_max_energy = e_max - n_max + n + 1;
let remaining_energy = next_local_max_energy - e;
let max_amplitude = f64::floor(f64::sqrt(remaining_energy as f64)) as usize;
Amplitudes {
current: 1,
max: std::cmp::min(max_amplitude, ask.max_amplitude()),
including: true,
}
}
pub fn upto(max_amplitude: usize, ask: &ASK) -> Amplitudes {
Amplitudes {
current: 1,
max: std::cmp::min(max_amplitude, ask.max_amplitude() + 1),
including: false,
}
}
pub fn all_in(ask: &ASK) -> Amplitudes {
Amplitudes {
current: 1,
max: ask.max_amplitude(),
including: true,
}
}
}
impl Iterator for Amplitudes {
type Item = usize;
fn next(&mut self) -> Option<Self::Item> {
if self.current < self.max || (self.including && self.current == self.max) {
let return_amplitude = self.current;
self.current += 2;
Some(return_amplitude)
} else {
None
}
}
}
pub struct Energies {
current: usize,
max: usize,
including: bool,
}
impl Energies {
pub fn for_trellis_level(n: usize, n_max: usize, e_max: usize) -> Energies {
let local_max_energy = if e_max + n >= n_max {
e_max + n - n_max
} else {
0
};
Energies {
current: n,
max: local_max_energy,
including: true,
}
}
}
impl Iterator for Energies {
type Item = usize;
fn next(&mut self) -> Option<Self::Item> {
if self.current < self.max || (self.including && self.current == self.max) {
let return_energy = self.current;
self.current += 8;
Some(return_energy)
} else {
None
}
}
}