sysprog21 / mado

A window system for resource-constrained devices
MIT License
39 stars 14 forks source link

Replace sine table with 5th order approximation #27

Closed ndsl7109256 closed 2 months ago

ndsl7109256 commented 3 months ago

The previous implementation used the pre-calculated fixed-point arithmetic table for sine values, which added over 2 KiB to the code size.

To solve this issue, I implemented the 5th order polynomial approximation for sine, which reduced the code size from 2556 bytes to 494 bytes (by about 80%) while maintaining acceptable error (RMS error is 8.866 observed with 0-90 degrees, 0-1024 in fixed-point representation)

Original code size with sine table.

$ size .libtwin.a/src/trig.c.o
   text    data     bss     dec     hex filename
   2556       0       0    2556     9fc .libtwin.a/src/trig.c.o

Code size after using 5th order approximation

$ size .libtwin.a/src/trig.c.o
   text    data     bss     dec     hex filename
   494        0       0    494      1ee .libtwin.a/src/trig.c.o

I initially tried a 3rd order approximation, but the error was slightly large, causing the drawn circle to appear not perfectly round. Below is some analysis.

image
RMS Error Comparing with Sine table (valued from 0-65536, observed with 0-90 degrees, 0-1024 in fixed-point representation) 3rd approximation 5th approximation
RMS 878.000907 8.8665040

image

ref: https://www.nullhardware.com/blog/fixed-point-sine-and-cosine-for-embedded-systems/ https://hackmd.io/@rickywu0421/FinalProject#透過-3rd-order-sine-approximation-模擬-RSSI

jserv commented 3 months ago

glibc implementation of sincos:

jouae commented 3 months ago

@ndsl7109256 Hey! You do a great job!

Here is a suggestion make your report getting better.

When mentioning RMS or MSE, be sure to include the number of observations.

ndsl7109256 commented 2 months ago

Enhancement: Implement CORDIC algorithm for tan calculation

Currently, the twin_tan function uses division, which may be computationally expensive. A potential improvement would be to implement the CORDIC algorithm for calculating tan. This would avoid the use of the divider and potentially improve performance.

References: https://github.com/Max-Gulda/Cordic-Math/blob/main/lib/cordicMath/src/cordic-math.c#L290-L332 https://hackmd.io/@sysprog/linux-intdiv

jserv commented 2 months ago

Thank @ndsl7109256 for contributing!