1
+ /*
2
+ COS_TABLE generated with:
3
+
4
+ #! /usr/bin/env python3
5
+ import math
6
+ print("const COS_TABLE: [u8; 256] = [", end="")
7
+ for i in range(256):
8
+ if i % 16 == 0:
9
+ print("\n", end="")
10
+ print("{:03}, ".format(int(255.0 * math.cos( ((3.14159265359 / 2.0) / 256) * float(i) ))), end="")
11
+ print("];")
12
+ */
13
+ /// One quarter of a cosine wave. The other four quarters are generated through symmetry.
14
+ const COS_TABLE : [ u8 ; 256 ] = [
15
+ 255 , 254 , 254 , 254 , 254 , 254 , 254 , 254 , 254 , 254 , 254 , 254 , 254 , 254 , 254 , 253 ,
16
+ 253 , 253 , 253 , 253 , 253 , 252 , 252 , 252 , 252 , 252 , 251 , 251 , 251 , 250 , 250 , 250 ,
17
+ 250 , 249 , 249 , 249 , 248 , 248 , 248 , 247 , 247 , 246 , 246 , 246 , 245 , 245 , 244 , 244 ,
18
+ 244 , 243 , 243 , 242 , 242 , 241 , 241 , 240 , 240 , 239 , 239 , 238 , 237 , 237 , 236 , 236 ,
19
+ 235 , 234 , 234 , 233 , 233 , 232 , 231 , 231 , 230 , 229 , 229 , 228 , 227 , 227 , 226 , 225 ,
20
+ 224 , 224 , 223 , 222 , 221 , 221 , 220 , 219 , 218 , 217 , 217 , 216 , 215 , 214 , 213 , 212 ,
21
+ 212 , 211 , 210 , 209 , 208 , 207 , 206 , 205 , 204 , 203 , 202 , 201 , 201 , 200 , 199 , 198 ,
22
+ 197 , 196 , 195 , 194 , 193 , 192 , 191 , 189 , 188 , 187 , 186 , 185 , 184 , 183 , 182 , 181 ,
23
+ 180 , 179 , 178 , 176 , 175 , 174 , 173 , 172 , 171 , 170 , 168 , 167 , 166 , 165 , 164 , 162 ,
24
+ 161 , 160 , 159 , 158 , 156 , 155 , 154 , 153 , 151 , 150 , 149 , 148 , 146 , 145 , 144 , 142 ,
25
+ 141 , 140 , 139 , 137 , 136 , 135 , 133 , 132 , 131 , 129 , 128 , 127 , 125 , 124 , 122 , 121 ,
26
+ 120 , 118 , 117 , 116 , 114 , 113 , 111 , 110 , 109 , 107 , 106 , 104 , 103 , 101 , 100 , 099 ,
27
+ 097 , 096 , 094 , 093 , 091 , 090 , 088 , 087 , 085 , 084 , 082 , 081 , 079 , 078 , 077 , 075 ,
28
+ 074 , 072 , 071 , 069 , 068 , 066 , 064 , 063 , 061 , 060 , 058 , 057 , 055 , 054 , 052 , 051 ,
29
+ 049 , 048 , 046 , 045 , 043 , 042 , 040 , 038 , 037 , 035 , 034 , 032 , 031 , 029 , 028 , 026 ,
30
+ 024 , 023 , 021 , 020 , 018 , 017 , 015 , 014 , 012 , 010 , 009 , 007 , 006 , 004 , 003 , 001 ,
31
+ ] ;
32
+
33
+ use std:: f32:: consts:: PI ;
34
+ enum Quadrant {
35
+ FirstNormNorm ,
36
+ SecondReverseInvert ,
37
+ ThirdNormInvert ,
38
+ FourthReverseNorm ,
39
+ }
40
+ /// LUT-based cosine computation. Has an `8-bit` resolution. Used to coarsely compute
41
+ /// a cosine without relying on `std` functions. The concerns driving this implementation are:
42
+ ///
43
+ /// - code size
44
+ /// - xous-core issue #285 and https://github.com/rust-lang/rust/issues/105734
45
+ ///
46
+ /// The issue above means any attempt to use `cos` (or any transcendental function) from
47
+ /// Rust math library leads to a link time error. Until Rust can fix this regression we have
48
+ /// to implement our own cosine function, or use `thin` LTO which adds about 7% to the size
49
+ /// of the kernel, making it by far the single largest contributing factor to kernel bloat.
50
+
51
+ pub fn cos ( a : f32 ) -> f32 {
52
+ let pos = a % ( 2.0 * PI ) ;
53
+ let q = if pos < ( PI / 2.0 ) {
54
+ Quadrant :: FirstNormNorm
55
+ } else if pos < ( PI ) {
56
+ Quadrant :: SecondReverseInvert
57
+ } else if pos < ( 3.0 * PI / 2.0 ) {
58
+ Quadrant :: ThirdNormInvert
59
+ } else {
60
+ Quadrant :: FourthReverseNorm
61
+ } ;
62
+ let idx = ( 256.0 * ( a % ( PI / 2.0 ) ) / ( PI / 2.0 ) ) as usize ;
63
+ match q {
64
+ Quadrant :: FirstNormNorm => {
65
+ ( COS_TABLE [ idx] as f32 ) / 255.0
66
+ } ,
67
+ Quadrant :: SecondReverseInvert => {
68
+ ( COS_TABLE [ 255 -idx] as f32 ) / -255.0
69
+ } ,
70
+ Quadrant :: ThirdNormInvert => {
71
+ ( COS_TABLE [ idx] as f32 ) / -255.0
72
+ } ,
73
+ Quadrant :: FourthReverseNorm => {
74
+ ( COS_TABLE [ 255 -idx] as f32 ) / 255.0
75
+ }
76
+ }
77
+ }
0 commit comments