Author Topic: Faster trig functions: tables and interpolation  (Read 3563 times)

0 Members and 1 Guest are viewing this topic.

Offline STxAxTIC

  • Library Staff
  • Forum Resident
  • Posts: 1091
  • he lives
    • View Profile
Faster trig functions: tables and interpolation
« on: January 26, 2020, 09:02:44 pm »
I had to make good on what I was lecturing bplus about (even if the recent plasma program is speedier)...

So I create two things:

1) Trig tables, strictly 360 degrees. These are lightning fast, like by an order of 10 compared to the native trig functions.

Of course, sometimes you want fractional degrees, which brings me to the next thing:

2) Two functions, InterSin and InterCos - and these can completely (maybe need to convert them to radians first) replace the native SIN and COS. Without any optimization, they are 5% to 10% faster as-is pasted below. The reason they are quick is trigonometric interpolation. Fractional angles are inspired by a first-order approximation using the derivative.

Below is the whole package. Tables, functions, testing, etc. Enjoy. (By that I mean optimize away - I bet these functions can be made faster.)

Code: QB64: [Select]
  1. ' Constants.
  2. CONST PI = 3.141592654
  3. CONST PI2 = 2 * PI
  4. CONST PI180 = PI / 180
  5.  
  6. ' Define trig tables.
  7. DIM SHARED SinTable(0 TO 359) AS SINGLE
  8. DIM SHARED CosTable(0 TO 359) AS SINGLE
  9.  
  10. ' Create trig tables in degrees.
  11. FOR k = 0 TO 359 STEP 1
  12.     SinTable(k) = SIN(_D2R(k))
  13.     CosTable(k) = COS(_D2R(k))
  14.  
  15. '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  16. ' Accuracy and testing section (optional)
  17. '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  18.  
  19. ' Speed test native SIN and COS.
  20. t = TIMER
  21. FOR k = 1 TO 10 ^ 7
  22.     a = SIN(3)
  23.     b = COS(3)
  24. PRINT "Native:": PRINT TIMER - t: PRINT
  25.  
  26. ' Speed test table SIN and COS (integer arguments only).
  27. t = TIMER
  28. FOR k = 1 TO 10 ^ 7
  29.     a = SinTable(3)
  30.     b = CosTable(3)
  31. PRINT "Table only:": PRINT TIMER - t: PRINT
  32.  
  33. ' Speed test interpolated SIN and COS (any argument).
  34. t = TIMER
  35. FOR k = 1 TO 10 ^ 7
  36.     a = InterSin(3)
  37.     b = InterCos(3)
  38. PRINT "Interpolated:": PRINT TIMER - t: PRINT
  39.  
  40. ' Error test table at standard intervals:
  41. es = 0
  42. ec = 0
  43. FOR k = 0 TO 359 STEP 1
  44.     es = es + (SIN(_D2R(k)) - SinTable(k)) ^ 2
  45.     ec = ec + (COS(_D2R(k)) - CosTable(k)) ^ 2
  46. PRINT "Total error in table:": PRINT es: PRINT ec: PRINT
  47.  
  48. ' Error test table at smaller intervals:
  49. es = 0
  50. ec = 0
  51. FOR k = 0 TO 359 STEP .1
  52.     es = es + (SIN(_D2R(k)) - InterSin(k)) ^ 2
  53.     ec = ec + (COS(_D2R(k)) - InterCos(k)) ^ 2
  54. PRINT "Total error in interpolated functions:": PRINT es: PRINT ec: PRINT
  55.  
  56. ' Exampe:
  57. PRINT "Example use:"
  58. PRINT InterSin(25)
  59. PRINT InterCos(25)
  60.  
  61.  
  62. '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  63. ' Functions
  64. '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  65.  
  66. FUNCTION InterSin (arg AS SINGLE)
  67.     z = INT(arg)
  68.     x = arg - z
  69.     IF (x = 0) THEN
  70.         InterSin = SinTable(z)
  71.     ELSE
  72.         InterSin = SinTable(z) + x * (PI180) * CosTable(z)
  73.     END IF
  74.  
  75. FUNCTION InterCos (arg AS SINGLE)
  76.     z = INT(arg)
  77.     x = arg - z
  78.     IF (x = 0) THEN
  79.         InterCos = CosTable(z)
  80.     ELSE
  81.         InterCos = CosTable(z) - x * (PI180) * SinTable(z)
  82.     END IF
  83.  
« Last Edit: January 26, 2020, 09:18:17 pm by STxAxTIC »
You're not done when it works, you're done when it's right.

Offline david_uwi

  • Newbie
  • Posts: 71
    • View Profile
Re: Faster trig functions: tables and interpolation
« Reply #1 on: February 04, 2020, 02:08:57 pm »
Back when computers were slow this was the standard method to do trig functions (look-up tables).
I still use them these days when using 8-bit microprocessors with the added advantage that the lookup table can be written to program memory (plenty of that) rather than stored in RAM (not much of that).
There are still some legacy statements in BASIC that do this like CONST (program memory is being used rather than RAM).
As I've mentioned it let me give a plug to GCBasic a QB compatible programming language for microprocessors.