RobTillaart / FastTrig

Arduino library with interpolated lookup for sin() and cos()

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

fastTrig_optimize.ino - some points

brewmanz opened this issue · comments

in float getError(int i)

  • for (float f = i - 1; f < i + 1; f += 0.0001) will work better using int ii as loop counter from -10000 to +10000 and f = i + ii * 0.00001;. When i is at 84, the error difference between expected and actual of 84.0001 and 84.0002 is 'not trivial'. I'm too lazy to calculate it exactly, but floats are accurate to 24 bits (23 stored; 1 implicit) which is 1 in 16,777,216 i.e. potential rounding differences of c.0.000005. That might not seem much, but adding it 10,000 times gives a potential error of 0.05 - that's 500 clicks of 0.0001. Okay, that's extremely unlikely (drifting 50 clicks wouldn't surprise me), but there's no need to throw away accuracy.
  • For some reason, your loop includes i-1 but excludes i+1. This seems an oversight to me; IMO it should be symmetrical.
  • error += abs(sin(f / 180 * PI) - isin(f)); When tracking deviation errors, it's usual to use Least Squares i.e. it's better to have two errors of 2 than one of 3.

in int optimize()

  • for (int j = -1; j < 1; j++) + if (j == 0) continue; this loop only gets actioned for j = -1. I don't think that this is intended. Also the if (j == 0) continue; can be removed if you use for (int j = -1; j <= 1; j+=2)

in void test_isin_error_1(bool show)

  • I notice some delay(10); and can't work out why they're there. To ensure the Serial.print stuff has finished, use Serial.flush(); although I don't see any timing that might require that.
  • z += y; Again, I would use a Least Squares rather than simple sum of errors. Actually I would track both sum-of-error and sum-of-error-squared and calculate/display Std Dev.

in float getError(int i)

  • float loop, I know the potential problems with float loops, for the purpose of this test the values are still equidistant enough. In fact I considered to use 2000 random numbers in the interval, but that could cluster so that could create substantial bias.
  • excluding i+1 is because with the next 'degree' it will be tested. If I would include it it would have double weight.
  • deviation, this was easier to program and as the sin function is monotone continuous in the interval the linear interpolation in every interval is also continuous. Therefor no sudden peaks. Feel free to do a testrun to see if squared error would generate a different lookup table. And yes I already found that the step size / number of test points affect the table. This difference I saw was only 1 so a diff of 1 in 65535 which is at the edge of the accuracy that is feasible with 16 bit.

in int optimize()

  • for (j = -1 to +1) that is historical grown, in a first version I had j from -5 to 5 and had to skip 0. but learned quickly that that was overkill while using quite some time.
  • Good catch that +1 is missed, will fix that

in void test_isin_error_1(bool show)

  • delay(10) indeed to be sure data has been printed. As printing over serial is interrupt based a few of these interrupts may occur during the measurement. 10 millis delay is enough to flush 100 chars so it works well. Serial.flush() would also be good, maybe even better to understand the purpose.
  • deviation discussed above.

Got a new run of optimize doing -2 ..+2

current table

test_isin_error_1
ISIN 0-3600 calls:
max error: 0.00012007
avg error: 0.00002303

1145, 2289, 3435, 4572, 5716, 6853, 7989, 9125, 10255, 11385,
12508, 13631, 14745, 15859, 16963, 18067, 19165, 20253, 21342, 22417,
23489, 24553, 25610, 26659, 27703, 28731, 29755, 30773, 31777, 32772,
33756, 34734, 35697, 36649, 37594, 38523, 39445, 40350, 41247, 42131,
42998, 43856, 44701, 45528, 46344, 47147, 47931, 48708, 49461, 50205,
50933, 51646, 52342, 53022, 53686, 54334, 54969, 55579, 56180, 56760,
57322, 57866, 58394, 58908, 59399, 59871, 60327, 60768, 61184, 61584,
61969, 62330, 62677, 63000, 63304, 63593, 63858, 64108, 64334, 64545,
64731, 64903, 65049, 65177, 65289, 65377, 65449, 65501, 65527, 65535

test_isin_error_1
ISIN 0-3600 calls:
max error: 0.00010264
avg error: 0.00002059

so better, will be included next version

Thanx