1use itertools::izip;
2
3use crate::tensor::R2lTensor;
4
5pub mod buffer;
7
8#[derive(Debug)]
10pub struct Memory<T> {
11 pub state: T,
13 pub next_state: T,
15 pub action: T,
17 pub reward: f32,
19 pub terminated: bool,
21 pub truncated: bool,
23}
24
25impl<T> Memory<T> {
26 pub fn is_done(&self) -> bool {
28 self.terminated || self.truncated
29 }
30}
31
32#[derive(Debug)]
33pub struct MultiMemory<T: R2lTensor> {
35 last_states: Vec<T>,
36 next_states: Vec<T>,
37 actions: Vec<T>,
38 rewards: Vec<f32>,
39 terminateds: Vec<bool>,
40 truncateds: Vec<bool>,
41}
42
43impl<T: R2lTensor> MultiMemory<T> {
44 #[must_use]
46 pub fn with_capacity(capacity: usize) -> Self {
47 Self {
48 last_states: Vec::with_capacity(capacity),
49 next_states: Vec::with_capacity(capacity),
50 actions: Vec::with_capacity(capacity),
51 rewards: Vec::with_capacity(capacity),
52 terminateds: Vec::with_capacity(capacity),
53 truncateds: Vec::with_capacity(capacity),
54 }
55 }
56
57 pub fn push_memory(&mut self, memory: Memory<T>) {
59 let Memory {
60 state,
61 next_state,
62 action,
63 reward,
64 terminated,
65 truncated,
66 } = memory;
67 self.last_states.push(state);
68 self.next_states.push(next_state);
69 self.actions.push(action);
70 self.rewards.push(reward);
71 self.terminateds.push(terminated);
72 self.truncateds.push(truncated);
73 }
74
75 pub fn next_states_mut(&mut self) -> &mut [T] {
77 &mut self.next_states
78 }
79
80 #[must_use]
82 pub fn into_stored_memories(self) -> Vec<Memory<T>> {
83 let mut memories = Vec::with_capacity(self.last_states.len());
84 let Self {
85 last_states: states,
86 next_states,
87 actions,
88 rewards,
89 terminateds,
90 truncateds,
91 } = self;
92 for (state, next_state, action, reward, terminated, truncated) in izip!(
93 states,
94 next_states,
95 actions,
96 rewards,
97 terminateds,
98 truncateds
99 ) {
100 memories.push(Memory {
101 state,
102 next_state,
103 action,
104 reward,
105 terminated,
106 truncated,
107 });
108 }
109 memories
110 }
111
112 pub fn into_memories(self, next_states: &[T]) -> Vec<Memory<T>> {
116 let mut memories = Vec::with_capacity(self.last_states.len());
117 let Self {
118 last_states: states,
119 next_states: _,
120 actions,
121 rewards,
122 terminateds,
123 truncateds,
124 } = self;
125 for (state, next_state, action, reward, terminated, truncated) in izip!(
126 states,
127 next_states,
128 actions,
129 rewards,
130 terminateds,
131 truncateds
132 ) {
133 memories.push(Memory {
134 state,
135 next_state: next_state.clone(),
136 action,
137 reward,
138 terminated,
139 truncated,
140 });
141 }
142 memories
143 }
144}
145
146pub trait TrajectoryBatch<T: R2lTensor> {
148 fn len(&self) -> usize;
150
151 fn is_empty(&self) -> bool;
153
154 fn states(&self) -> &[T];
156
157 fn next_states(&self) -> &[T];
159
160 fn actions(&self) -> &[T];
162
163 fn rewards(&self) -> &[f32];
165
166 fn terminated(&self) -> &[bool];
168
169 fn truncated(&self) -> &[bool];
171}