1use std::fmt;
4
5use crate::closed_form::{
6 Body, Bound, ClosedForm, Edge, Excitation, Fold, IndexId, ModalBank, Mode, Part, Rational,
7 Series, Unary, Var,
8};
9use crate::complex::{C64, canonical};
10use crate::env::NodeId;
11use crate::lanes::Lanes;
12use crate::run::Mirror;
13use crate::spectral_sum::atom::{Singular, SpectralAtom};
14use crate::spectral_sum::{Lane, SpectralSum};
15use crate::table::TABLE_VERSION;
16
17#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
20pub struct Hash(pub u64, pub u64);
21
22impl fmt::Display for Hash {
23 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
24 write!(f, "{:016x}{:016x}", self.0, self.1)
25 }
26}
27
28pub fn hash_spectral_sum(n: &SpectralSum) -> Hash {
29 hash_spectral_sum_under(n, TABLE_VERSION)
30}
31
32pub fn hash_closed_form(t: &ClosedForm) -> Hash {
33 hash_closed_form_under(t, TABLE_VERSION)
34}
35
36pub fn hash_spectral_sum_under(n: &SpectralSum, table_version: u64) -> Hash {
39 let mut s = Sink::new(0x01, table_version);
40 s.var(n.var);
41 s.u64(n.lanes.len() as u64);
42 for lane in &n.lanes {
43 s.lane(lane);
44 }
45 s.finish()
46}
47
48pub fn hash_closed_form_under(t: &ClosedForm, table_version: u64) -> Hash {
49 let mut s = Sink::new(0x02, table_version);
50 s.var(t.var);
51 s.formula(&t.body);
52 s.finish()
53}
54
55pub fn hash_closed_form_with(t: &ClosedForm, node: &mut dyn FnMut(NodeId) -> Hash) -> Hash {
58 let mut s = Sink::new(0x04, TABLE_VERSION);
59 s.node = Some(node);
60 s.var(t.var);
61 s.formula(&t.body);
62 s.finish()
63}
64
65pub fn draw(seed: u64, step: i64) -> f64 {
67 mix(mix(seed ^ DRAWN) ^ step as u64) as f64 / u64::MAX as f64
68}
69
70const DRAWN: u64 = 0x9e37_79b9_7f4a_7c15;
71
72pub fn draw_nearest(seed: u64, key: f64) -> Option<f64> {
74 let step = key.round_ties_even();
75 let held = step >= i64::MIN as f64 && step < i64::MAX as f64;
76 held.then(|| draw(seed, step as i64))
77}
78
79struct Sink<'a> {
80 lanes: Lanes<0>,
81 node: Option<&'a mut dyn FnMut(NodeId) -> Hash>,
82 bound: Vec<IndexId>,
85}
86
87impl<'a> Sink<'a> {
88 fn new(tag: u8, table_version: u64) -> Sink<'a> {
89 let mut s = Sink {
90 lanes: Lanes::default(),
91 node: None,
92 bound: Vec::new(),
93 };
94 s.byte(tag);
95 s.u64(table_version);
96 s
97 }
98
99 fn byte(&mut self, b: u8) {
100 self.lanes.word(u64::from(b));
101 }
102
103 fn u64(&mut self, v: u64) {
104 for b in v.to_le_bytes() {
105 self.byte(b);
106 }
107 }
108
109 fn i64(&mut self, v: i64) {
110 self.u64(v as u64);
111 }
112
113 fn f64(&mut self, v: f64) {
114 self.u64(canonical(v));
115 }
116
117 fn c64(&mut self, v: C64) {
118 let (re, im) = v.bits();
119 self.u64(re);
120 self.u64(im);
121 }
122
123 fn var(&mut self, v: Var) {
124 self.byte(match v {
125 Var::T => 0,
126 Var::F => 1,
127 });
128 }
129
130 fn edge(&mut self, e: Edge) {
131 match e {
132 Edge::NegInf => self.byte(0),
133 Edge::At(bits) => {
134 self.byte(1);
135 self.u64(bits);
136 }
137 Edge::PosInf => self.byte(2),
138 }
139 }
140
141 fn lane(&mut self, lane: &Lane) {
142 self.u64(lane.atoms.len() as u64);
143 for a in &lane.atoms {
144 self.atom(a);
145 }
146 self.u64(lane.series.len() as u64);
147 for s in &lane.series {
148 self.series(s);
149 }
150 self.u64(lane.modal.len() as u64);
151 for m in &lane.modal {
152 self.modal(m);
153 }
154 }
155
156 fn atom(&mut self, a: &SpectralAtom) {
158 self.c64(a.c);
159 self.u64(u64::from(a.poly.degree));
160 self.f64(a.poly.at);
161 match a.exp {
162 None => self.byte(0),
163 Some(e) => {
164 self.byte(1);
165 self.f64(e.sigma);
166 self.f64(e.omega);
167 }
168 }
169 match a.gauss {
170 None => self.byte(0),
171 Some(g) => {
172 self.byte(1);
173 self.f64(g.a);
174 self.f64(g.mu);
175 }
176 }
177 match a.ind {
178 None => self.byte(0),
179 Some(i) => {
180 self.byte(1);
181 self.edge(i.l);
182 self.edge(i.r);
183 }
184 }
185 match a.pole {
186 None => self.byte(0),
187 Some(p) => {
188 self.byte(1);
189 self.c64(p.at);
190 self.u64(u64::from(p.order));
191 self.byte(u8::from(p.pv));
192 }
193 }
194 match a.sing {
195 Singular::Regular => self.byte(0),
196 Singular::Delta { at, order } => {
197 self.byte(1);
198 self.f64(at);
199 self.u64(u64::from(order));
200 }
201 }
202 }
203
204 fn series(&mut self, s: &Series) {
205 self.i64(s.lo);
206 match s.hi {
207 Bound::Finite(n) => {
208 self.byte(0);
209 self.i64(n);
210 }
211 Bound::Infinite => self.byte(1),
212 }
213 self.bound.push(s.index);
214 self.formula(&s.term.body);
215 self.bound.pop();
216 }
217
218 fn amps(&mut self, amps: &[C64]) {
219 self.u64(amps.len() as u64);
220 for a in amps {
221 self.c64(*a);
222 }
223 }
224
225 fn modal(&mut self, m: &ModalBank) {
226 self.u64(m.modes.len() as u64);
227 for Mode {
228 omega,
229 tau,
230 amp,
231 phase,
232 } in &m.modes
233 {
234 self.f64(*omega);
235 self.f64(*tau);
236 self.f64(*amp);
237 self.f64(*phase);
238 }
239 match m.excite {
240 Excitation::HammerPulse { f0, t0, contact } => {
241 self.byte(0);
242 self.f64(f0);
243 self.f64(t0);
244 self.f64(contact);
245 }
246 Excitation::Impulse { t0 } => {
247 self.byte(1);
248 self.f64(t0);
249 }
250 }
251 }
252
253 fn parts(&mut self, parts: &[Part]) {
254 self.u64(parts.len() as u64);
255 for p in parts {
256 self.formula(&p.body);
257 }
258 }
259
260 fn rational(&mut self, r: &Rational) {
261 self.u64(r.zeros.len() as u64);
262 for z in &r.zeros {
263 self.c64(*z);
264 }
265 self.u64(r.poles.len() as u64);
266 for p in &r.poles {
267 self.c64(*p);
268 }
269 self.c64(r.gain);
270 }
271
272 fn formula(&mut self, f: &Body) {
273 match f {
274 Body::Const(c) => {
275 self.byte(0x10);
276 self.c64(*c);
277 }
278 Body::Line => self.byte(0x11),
279 Body::Index(i) => {
280 let depth = self.bound.iter().rev().position(|b| b == i);
281 self.byte(0x12);
282 self.u64(depth.expect("an index inside the series binding it") as u64);
283 }
284 Body::Param(p) => {
285 self.byte(0x13);
286 self.u64(u64::from(p.0));
287 }
288 Body::Node(n) => {
289 self.byte(0x14);
290 match self.node.as_mut().map(|named| named(*n)) {
291 Some(held) => {
292 self.u64(held.0);
293 self.u64(held.1);
294 }
295 None => self.u64(u64::from(n.0)),
296 }
297 }
298 Body::Add(parts) => {
299 self.byte(0x15);
300 self.parts(parts);
301 }
302 Body::Mul(parts) => {
303 self.byte(0x16);
304 self.parts(parts);
305 }
306 Body::Div(a, b) => {
307 self.byte(0x17);
308 self.formula(&a.body);
309 self.formula(&b.body);
310 }
311 Body::Pow(base, n) => {
312 self.byte(0x18);
313 self.formula(&base.body);
314 self.i64(i64::from(*n));
315 }
316 Body::Apply(op, arg) => {
317 self.byte(0x19);
318 self.byte(unary_tag(*op));
319 self.formula(&arg.body);
320 }
321 Body::Fold(op, args) => {
322 self.byte(0x1a);
323 self.byte(match op {
324 Fold::Max => 0,
325 Fold::Min => 1,
326 Fold::Mod => 2,
327 });
328 self.parts(args);
329 }
330 Body::Delta { at, order } => {
331 self.byte(0x1b);
332 self.formula(&at.body);
333 self.u64(u64::from(*order));
334 }
335 Body::Pv(at) => {
336 self.byte(0x1c);
337 self.formula(&at.body);
338 }
339 Body::Warp { at, of } => {
340 self.byte(0x27);
341 self.formula(&at.body);
342 self.formula(&of.body);
343 }
344 Body::Shift { by, of } => {
345 self.byte(0x1d);
346 self.f64(*by);
347 self.formula(&of.body);
348 }
349 Body::Deriv { order, of } => {
350 self.byte(0x1e);
351 self.u64(u64::from(*order));
352 self.formula(&of.body);
353 }
354 Body::Crop {
355 of,
356 l,
357 r,
358 rise,
359 fall,
360 } => {
361 self.byte(0x1f);
362 self.formula(&of.body);
363 self.edge(*l);
364 self.edge(*r);
365 self.f64(*rise);
366 self.f64(*fall);
367 }
368 Body::Join(parts) => {
369 self.byte(0x21);
370 self.parts(parts);
371 }
372 Body::Channel(of, k) => {
373 self.byte(0x22);
374 self.formula(&of.body);
375 self.byte(*k);
376 }
377 Body::Rational(r) => {
378 self.byte(0x23);
379 self.rational(r);
380 }
381 Body::Series(s) => {
382 self.byte(0x24);
383 self.series(s);
384 }
385 Body::Modal(m) => {
386 self.byte(0x25);
387 self.modal(m);
388 }
389 Body::Run(run) => {
390 self.byte(0x28);
391 self.f64(run.offset);
392 self.f64(run.step);
393 self.i64(run.first);
394 self.amps(&run.amps);
395 match &run.mirror {
396 Mirror::None => self.byte(0),
397 Mirror::Conjugate => self.byte(1),
398 Mirror::Held(amps) => {
399 self.byte(2);
400 self.amps(amps);
401 }
402 }
403 }
404 Body::Keyed { seed, of } => {
405 self.byte(0x26);
406 self.u64(*seed);
407 self.formula(&of.body);
408 }
409 }
410 }
411
412 fn finish(&self) -> Hash {
414 let Hash(a, b) = self.lanes.finish();
415 Hash(mix(a), mix(b))
416 }
417}
418
419fn unary_tag(op: Unary) -> u8 {
420 match op {
421 Unary::Sin => 0,
422 Unary::Cos => 1,
423 Unary::Exp => 2,
424 Unary::Tanh => 3,
425 Unary::Sat => 4,
426 Unary::Abs => 5,
427 Unary::Log => 6,
428 Unary::Sqrt => 7,
429 Unary::Step => 8,
430 }
431}
432
433fn mix(mut z: u64) -> u64 {
434 z = (z ^ (z >> 30)).wrapping_mul(0xbf58_476d_1ce4_e5b9);
435 z = (z ^ (z >> 27)).wrapping_mul(0x94d0_49bb_1331_11eb);
436 z ^ (z >> 31)
437}