use itertools::izip;
use crate::tensor::R2lTensor;
pub mod buffer;
#[derive(Debug)]
pub struct Memory<T> {
pub state: T,
pub next_state: T,
pub action: T,
pub reward: f32,
pub terminated: bool,
pub truncated: bool,
}
impl<T> Memory<T> {
pub fn is_done(&self) -> bool {
self.terminated || self.truncated
}
}
#[derive(Debug)]
pub struct MultiMemory<T: R2lTensor> {
last_states: Vec<T>,
next_states: Vec<T>,
actions: Vec<T>,
rewards: Vec<f32>,
terminateds: Vec<bool>,
truncateds: Vec<bool>,
}
impl<T: R2lTensor> MultiMemory<T> {
#[must_use]
pub fn with_capacity(capacity: usize) -> Self {
Self {
last_states: Vec::with_capacity(capacity),
next_states: Vec::with_capacity(capacity),
actions: Vec::with_capacity(capacity),
rewards: Vec::with_capacity(capacity),
terminateds: Vec::with_capacity(capacity),
truncateds: Vec::with_capacity(capacity),
}
}
pub fn push_memory(&mut self, memory: Memory<T>) {
let Memory {
state,
next_state,
action,
reward,
terminated,
truncated,
} = memory;
self.last_states.push(state);
self.next_states.push(next_state);
self.actions.push(action);
self.rewards.push(reward);
self.terminateds.push(terminated);
self.truncateds.push(truncated);
}
pub fn next_states_mut(&mut self) -> &mut [T] {
&mut self.next_states
}
#[must_use]
pub fn into_stored_memories(self) -> Vec<Memory<T>> {
let mut memories = Vec::with_capacity(self.last_states.len());
let Self {
last_states: states,
next_states,
actions,
rewards,
terminateds,
truncateds,
} = self;
for (state, next_state, action, reward, terminated, truncated) in izip!(
states,
next_states,
actions,
rewards,
terminateds,
truncateds
) {
memories.push(Memory {
state,
next_state,
action,
reward,
terminated,
truncated,
});
}
memories
}
pub fn into_memories(self, next_states: &[T]) -> Vec<Memory<T>> {
let mut memories = Vec::with_capacity(self.last_states.len());
let Self {
last_states: states,
next_states: _,
actions,
rewards,
terminateds,
truncateds,
} = self;
for (state, next_state, action, reward, terminated, truncated) in izip!(
states,
next_states,
actions,
rewards,
terminateds,
truncateds
) {
memories.push(Memory {
state,
next_state: next_state.clone(),
action,
reward,
terminated,
truncated,
});
}
memories
}
}
pub trait TrajectoryBatch<T: R2lTensor> {
fn len(&self) -> usize;
fn is_empty(&self) -> bool;
fn states(&self) -> &[T];
fn next_states(&self) -> &[T];
fn actions(&self) -> &[T];
fn rewards(&self) -> &[f32];
fn terminated(&self) -> &[bool];
fn truncated(&self) -> &[bool];
}