trig.rs

7.8 kB · rust · 297 lines

1#![allow(clippy::excessive_precision)]23/// The number of samples in one full turn.4pub const N: usize = 256;56/// One full turn of sine, sampled N times.7pub const SINE: [f32; 256] = [8    0.0f32,9    0.024541229009628296f32,10    0.049067676067352295f32,11    0.0735645666718483f32,12    0.0980171412229538f32,13    0.12241067737340927f32,14    0.1467304676771164f32,15    0.1709618866443634f32,16    0.19509032368659973f32,17    0.21910123527050018f32,18    0.24298018217086792f32,19    0.2667127549648285f32,20    0.290284663438797f32,21    0.3136817514896393f32,22    0.3368898630142212f32,23    0.3598950505256653f32,24    0.3826834261417389f32,25    0.40524131059646606f32,26    0.4275550842285156f32,27    0.4496113359928131f32,28    0.4713967442512512f32,29    0.49289819598197937f32,30    0.5141027569770813f32,31    0.5349976420402527f32,32    0.5555702447891235f32,33    0.5758081674575806f32,34    0.5956993103027344f32,35    0.6152315735816956f32,36    0.6343932747840881f32,37    0.6531728506088257f32,38    0.6715589761734009f32,39    0.6895405650138855f32,40    0.7071067690849304f32,41    0.7242470979690552f32,42    0.7409511208534241f32,43    0.7572088241577148f32,44    0.7730104327201843f32,45    0.7883464097976685f32,46    0.803207516670227f32,47    0.8175848126411438f32,48    0.8314695954322815f32,49    0.8448535799980164f32,50    0.8577286005020142f32,51    0.8700869679450989f32,52    0.8819212913513184f32,53    0.89322429895401f32,54    0.903989315032959f32,55    0.91420978307724f32,56    0.9238795042037964f32,57    0.9329928159713745f32,58    0.9415440559387207f32,59    0.949528157711029f32,60    0.9569403529167175f32,61    0.9637760519981384f32,62    0.9700312614440918f32,63    0.9757021069526672f32,64    0.9807852506637573f32,65    0.9852776527404785f32,66    0.9891765117645264f32,67    0.9924795627593994f32,68    0.9951847195625305f32,69    0.9972904324531555f32,70    0.9987954497337341f32,71    0.99969881772995f32,72    1.0f32,73    0.99969881772995f32,74    0.9987954497337341f32,75    0.9972904324531555f32,76    0.9951847195625305f32,77    0.9924795627593994f32,78    0.9891765117645264f32,79    0.9852776527404785f32,80    0.9807852506637573f32,81    0.9757021069526672f32,82    0.9700312614440918f32,83    0.9637760519981384f32,84    0.9569403529167175f32,85    0.949528157711029f32,86    0.9415440559387207f32,87    0.9329928159713745f32,88    0.9238795042037964f32,89    0.91420978307724f32,90    0.903989315032959f32,91    0.89322429895401f32,92    0.8819212913513184f32,93    0.8700869679450989f32,94    0.8577286005020142f32,95    0.8448535799980164f32,96    0.8314695954322815f32,97    0.8175848126411438f32,98    0.803207516670227f32,99    0.7883464097976685f32,100    0.7730104327201843f32,101    0.7572088241577148f32,102    0.7409511208534241f32,103    0.7242470979690552f32,104    0.7071067690849304f32,105    0.6895405650138855f32,106    0.6715589761734009f32,107    0.6531728506088257f32,108    0.6343932747840881f32,109    0.6152315735816956f32,110    0.5956993103027344f32,111    0.5758081674575806f32,112    0.5555702447891235f32,113    0.5349976420402527f32,114    0.5141027569770813f32,115    0.49289819598197937f32,116    0.4713967442512512f32,117    0.4496113359928131f32,118    0.4275550842285156f32,119    0.40524131059646606f32,120    0.3826834261417389f32,121    0.3598950505256653f32,122    0.3368898630142212f32,123    0.3136817514896393f32,124    0.290284663438797f32,125    0.2667127549648285f32,126    0.24298018217086792f32,127    0.21910123527050018f32,128    0.19509032368659973f32,129    0.1709618866443634f32,130    0.1467304676771164f32,131    0.12241067737340927f32,132    0.0980171412229538f32,133    0.0735645666718483f32,134    0.049067676067352295f32,135    0.024541229009628296f32,136    1.2246468525851679e-16f32,137    -0.024541229009628296f32,138    -0.049067676067352295f32,139    -0.0735645666718483f32,140    -0.0980171412229538f32,141    -0.12241067737340927f32,142    -0.1467304676771164f32,143    -0.1709618866443634f32,144    -0.19509032368659973f32,145    -0.21910123527050018f32,146    -0.24298018217086792f32,147    -0.2667127549648285f32,148    -0.290284663438797f32,149    -0.3136817514896393f32,150    -0.3368898630142212f32,151    -0.3598950505256653f32,152    -0.3826834261417389f32,153    -0.40524131059646606f32,154    -0.4275550842285156f32,155    -0.4496113359928131f32,156    -0.4713967442512512f32,157    -0.49289819598197937f32,158    -0.5141027569770813f32,159    -0.5349976420402527f32,160    -0.5555702447891235f32,161    -0.5758081674575806f32,162    -0.5956993103027344f32,163    -0.6152315735816956f32,164    -0.6343932747840881f32,165    -0.6531728506088257f32,166    -0.6715589761734009f32,167    -0.6895405650138855f32,168    -0.7071067690849304f32,169    -0.7242470979690552f32,170    -0.7409511208534241f32,171    -0.7572088241577148f32,172    -0.7730104327201843f32,173    -0.7883464097976685f32,174    -0.803207516670227f32,175    -0.8175848126411438f32,176    -0.8314695954322815f32,177    -0.8448535799980164f32,178    -0.8577286005020142f32,179    -0.8700869679450989f32,180    -0.8819212913513184f32,181    -0.89322429895401f32,182    -0.903989315032959f32,183    -0.91420978307724f32,184    -0.9238795042037964f32,185    -0.9329928159713745f32,186    -0.9415440559387207f32,187    -0.949528157711029f32,188    -0.9569403529167175f32,189    -0.9637760519981384f32,190    -0.9700312614440918f32,191    -0.9757021069526672f32,192    -0.9807852506637573f32,193    -0.9852776527404785f32,194    -0.9891765117645264f32,195    -0.9924795627593994f32,196    -0.9951847195625305f32,197    -0.9972904324531555f32,198    -0.9987954497337341f32,199    -0.99969881772995f32,200    -1.0f32,201    -0.99969881772995f32,202    -0.9987954497337341f32,203    -0.9972904324531555f32,204    -0.9951847195625305f32,205    -0.9924795627593994f32,206    -0.9891765117645264f32,207    -0.9852776527404785f32,208    -0.9807852506637573f32,209    -0.9757021069526672f32,210    -0.9700312614440918f32,211    -0.9637760519981384f32,212    -0.9569403529167175f32,213    -0.949528157711029f32,214    -0.9415440559387207f32,215    -0.9329928159713745f32,216    -0.9238795042037964f32,217    -0.91420978307724f32,218    -0.903989315032959f32,219    -0.89322429895401f32,220    -0.8819212913513184f32,221    -0.8700869679450989f32,222    -0.8577286005020142f32,223    -0.8448535799980164f32,224    -0.8314695954322815f32,225    -0.8175848126411438f32,226    -0.803207516670227f32,227    -0.7883464097976685f32,228    -0.7730104327201843f32,229    -0.7572088241577148f32,230    -0.7409511208534241f32,231    -0.7242470979690552f32,232    -0.7071067690849304f32,233    -0.6895405650138855f32,234    -0.6715589761734009f32,235    -0.6531728506088257f32,236    -0.6343932747840881f32,237    -0.6152315735816956f32,238    -0.5956993103027344f32,239    -0.5758081674575806f32,240    -0.5555702447891235f32,241    -0.5349976420402527f32,242    -0.5141027569770813f32,243    -0.49289819598197937f32,244    -0.4713967442512512f32,245    -0.4496113359928131f32,246    -0.4275550842285156f32,247    -0.40524131059646606f32,248    -0.3826834261417389f32,249    -0.3598950505256653f32,250    -0.3368898630142212f32,251    -0.3136817514896393f32,252    -0.290284663438797f32,253    -0.2667127549648285f32,254    -0.24298018217086792f32,255    -0.21910123527050018f32,256    -0.19509032368659973f32,257    -0.1709618866443634f32,258    -0.1467304676771164f32,259    -0.12241067737340927f32,260    -0.0980171412229538f32,261    -0.0735645666718483f32,262    -0.049067676067352295f32,263    -0.024541229009628296f32,264];265266/// Returns the sine at a sample index, wrapping past a full turn.267#[inline]268pub fn sin_idx(i: usize) -> f32 {269    SINE[i % N]270}271272/// Returns the cosine at a sample index by a quarter-turn shift of the sine table.273#[inline]274pub fn cos_idx(i: usize) -> f32 {275    SINE[(i + N / 4) % N]276}277278#[cfg(test)]279mod tests {280    use super::*;281282    #[test]283    fn quarter_turns_are_exact() {284        assert_eq!((cos_idx(0), sin_idx(0)), (1.0, 0.0));285        assert_eq!(sin_idx(N / 4), 1.0);286        assert!(cos_idx(N / 4).abs() < 1e-6);287        assert!(sin_idx(N / 2).abs() < 1e-6);288        assert_eq!(sin_idx(3 * N / 4), -1.0);289    }290291    #[test]292    fn stride_divides_every_count() {293        for &count in &[1usize, 2, 4, 8, 16, 32, 64, 128] {294            assert_eq!(N % count, 0, "N must divide count {count}");295        }296    }297}