Fast Sine & Cosine lookup tables

Share your advanced PureBasic knowledge/code with the community.
dell_jockey
Enthusiast
Enthusiast
Posts: 767
Joined: Sat Jan 24, 2004 6:56 pm

Fast Sine & Cosine lookup tables

Post by dell_jockey »

The following snippet is something I include to be able to get fast SIN & COS value estimates. Depending on the number of steps around the unity circle you choose to have, you can end up with an accuracy of at least six decimal places, which is good enough for most of my applications.

In this setup, I've traded memory for speed. I could have just pre-computed one SIN quadrant and derive all other quadrants as well as COS from that. Instead I choose to create tables for both, for the entire unity circle.

Please note the credit in the header.

enjoy!

Code: Select all

; ---------------------------------------------------
;              SIN-COS-tables.pbi
; ---------------------------------------------------
; precomputed global SIN/COS lookup tables are
; referenced by macros to reduce function call
; overhead and avoid trig conversion calculations
; - fSIN ( degrees )    ; fast sine
; - fCOS ( degrees )    ; fast cosine
; ---------------------------------------------------
; based on Kaeru Gaman's following PureBoard entry:
; http://www.purebasic.fr/german/viewtopic.php?t=5884
; ---------------------------------------------------

Global _Trig_Resolution_.w = 16384   ; steps around unity circle, needs
                                     ; to be a power of 2, i.e.
                                     ; 512, 1024, 2048, 4096, 8192, ...
                                     ; the larger this value, the larger
                                     ; the tables become, but one also
                                     ; gets more precision
                                     
Global _Resolution_minus_One_.w = _Trig_Resolution_.w - 1                                     

Global Dim SinTable.f(_Resolution_minus_One_.w)
Global Dim CosTable.f(_Resolution_minus_One_.w)

Global Angle_to_Index.f = ( _Trig_Resolution_ / 360.0 )

_Trig_Res_halved_.w = _Trig_Resolution_.w >> 1              ; populate tables
For n = 0 To _Resolution_minus_One_.w                        
    SinTable(n) = Sin( (#PI / _Trig_Res_halved_.w) * n )
    CosTable(n) = Cos( (#PI / _Trig_Res_halved_.w) * n )
Next 

Macro fSIN( degrees )
  SinTable( Int((Angle_to_Index.f * degrees) + 0.5 ) & (_Resolution_minus_One_.w) )
EndMacro

Macro fCOS( degrees )
  CosTable( Int((Angle_to_Index.f * degrees) + 0.5 ) & (_Resolution_minus_One_.w) )
EndMacro


; ------------------------------------------
; Usage
; ------------------------------------------
; set __UsageDefined__ to #True to test this
; file standalone
; ------------------------------------------
Define.b __UsageDefined__ = #True  
If __UsageDefined__
  For i = 0 To 359 Step 15
    Debug( "SIN(" + Str(i)+") = " + StrD( fSIN( i ), 6) )
    Debug( "COS(" + Str(i)+") = " + StrD( fCOS( i ), 6) ) 
  Next
EndIf
Last edited by dell_jockey on Sun Feb 24, 2008 11:31 am, edited 1 time in total.
cheers,
dell_jockey
________
http://blog.forex-trading-ideas.com
Tranquil
Addict
Addict
Posts: 952
Joined: Mon Apr 28, 2003 2:22 pm
Location: Europe

Post by Tranquil »

Nice code. Will try to speed up our FFT a bit using SIN/COS look-up tables soon. :)

Thanks for posting.
Tranquil
Post Reply