diff --git a/CHANGELOG.md b/CHANGELOG.md index 2a1a59a..8e5d085 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,15 +6,22 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). +## [0.3.3] - 2025-03-23 +- fix #28, prevent promotion of constants to double. Kudos to Harrison3000 +- replace M_PI by a const float _PI_ to prevent promotion. +- update examples +- update readme.md (minor) +- minor edits + + ## [0.3.3] - 2023-11-02 - update readme.md - update keywords.txt - update changelog.md - ## [0.3.2] - 2022-12-20 - fix changelog -- fix #25 change reference parameters to pointer +- fix #25 change reference parameters to pointer - isincos(float f, float \*si, float \*co) - isincos256(uint32_t v, int \*si, int \*co); - fix examples @@ -35,9 +42,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ---- ## [0.2.1] - 2022-12-05 -- add atanFast(x) => faster and less accurate than atan(). +- add atanFast(x) => faster and less accurate than atan(). Input range (-1..1) is fastest. -- add atan2Fast(y, x) => faster and less accurate. +- add atan2Fast(y, x) => faster and less accurate. calls atanFast() + offset. - add example to measure performance atanFast - update readme.md @@ -60,11 +67,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - no functional changes ## [0.1.10] - 2022-04-15 -- fix #12 +- fix #12 - split .h in .h and .cpp Needed in case of more complex projects. -## [0.1.9] - 2021-12-18 -- update Arduino-CI, badges, +## [0.1.9] - 2021-12-18 +- update Arduino-CI, badges, - update library.json - minor edits @@ -83,14 +90,14 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - new table - added iasin() and iacos() -In (0.1.4) an error was found in the optimize algorithm, so for 0.1.5 -it was ran again and accuracy improved for **isin()** and **icos()**. -However **itan()** lost a (smaller) bit. +In (0.1.4) an error was found in the optimize algorithm, so for 0.1.5 +it was ran again and accuracy improved for **isin()** and **icos()**. +However **itan()** lost a (smaller) bit. The gain outweighs the loss and so new table is kept. Performance has not changed. -An initial version of a reverse lookup for **iasin(val)** and **iacos(val)** +An initial version of a reverse lookup for **iasin(val)** and **iacos(val)** is added, as it uses the same **isintable16\[\]** interpolation table. There is no **atan()** or **atan2()** replacement. @@ -101,8 +108,8 @@ There is no **atan()** or **atan2()** replacement. - cleanup - examples -The library (0.1.4) provides an **itan()** which improved accuracy -upon the (0.1.3) version and performance for the ESP32. +The library (0.1.4) provides an **itan()** which improved accuracy +upon the (0.1.3) version and performance for the ESP32. Performance on AVR (UNO) is still an issue, accuracy is OK. @@ -126,7 +133,7 @@ _eons passed_ - added interpolation ## [0.1.01] - 2011-08-18 -- improved tables a bit +- improved tables a bit - changed param to float ## [0.1.00] - 2011-08-18 diff --git a/FastTrig.cpp b/FastTrig.cpp index 39db4cd..e020167 100644 --- a/FastTrig.cpp +++ b/FastTrig.cpp @@ -1,7 +1,7 @@ // // FILE: FastTrig.cpp // AUTHOR: Rob Tillaart -// VERSION: 0.3.3 +// VERSION: 0.3.4 // PURPOSE: Arduino library for a faster approximation of sin() and cos() // DATE: 2011-08-18 // URL: https://github.com/RobTillaart/FastTrig @@ -11,6 +11,10 @@ #include "FastTrig.h" +const float _PI_ = 3.14159265; +const float _PI_DIV_2_ = _PI_ / 2; + + // 91 x 2 bytes ==> 182 bytes // use 65535.0 as divider uint16_t sinTable16[] = { @@ -45,7 +49,7 @@ uint16_t sinTable16[] = { */ -// use 255.0 as divider +// use 255.0 as divider uint8_t sinTable8[] = { 0, 4, 9, 13, 18, 22, 27, 31, 35, 40, 44, 49, 53, 57, 62, 66, 70, 75, 79, 83, 87, @@ -62,8 +66,8 @@ uint8_t sinTable8[] = { /////////////////////////////////////////////////////// // -// GONIO INT EXPERIMENTAL -// works with only whole degrees. +// GONIO INT EXPERIMENTAL +// works with only whole degrees. // int isin256(uint32_t v) { @@ -174,7 +178,7 @@ float isin(float f) } } - // float value improves ~4% on avg error for ~60 bytes. + // float value improves ~4% on average error for ~60 bytes. uint16_t value = sinTable16[y]; // interpolate if needed @@ -182,7 +186,7 @@ float isin(float f) { value = value + ((sinTable16[y + 1] - value) / 8 * remain) / 32; // == * remain / 256 } - float g = value * 0.0000152590219; // = / 65535.0 + float g = value * 0.0000152590219f; // = / 65535.0 if (negative) return -g; return g; } @@ -235,7 +239,7 @@ void isincos(float f, float *si, float *co) cneg = !cneg; } - // float value improves ~4% on avg error for ~60 bytes. + // float value improves ~4% on average error for ~60 bytes. // SIN uint16_t value = sinTable16[y]; // interpolate if needed @@ -243,7 +247,7 @@ void isincos(float f, float *si, float *co) { value = value + ((sinTable16[y + 1] - value) / 8 * remain) / 32; // == * remain / 256 } - *si = value * 0.0000152590219; // = / 65535.0 + *si = value * 0.0000152590219f; // = / 65535.0 if (sneg) *si = - *si; // COS @@ -254,7 +258,7 @@ void isincos(float f, float *si, float *co) remain = 256 - remain; value = value + ((sinTable16[90-y] - value) / 8 * remain) / 32; // == * remain / 256 } - *co = value * 0.0000152590219; // = / 65535.0 + *co = value * 0.0000152590219f; // = / 65535.0 if (cneg) *co = - *co; } @@ -382,8 +386,8 @@ float iatan(float f) float atanFast(float x) { // remove two test will limit the input range but makes it even faster. - if ( x > 1) return ( M_PI / 2) - atanHelper(1.0 / x); - if ( x < -1) return (-M_PI / 2) - atanHelper(1.0 / x); + if ( x > 1) return (_PI_DIV_2_) - atanHelper(1.0 / x); + if ( x < -1) return (-_PI_DIV_2_) - atanHelper(1.0 / x); return atanHelper(x); } @@ -391,10 +395,10 @@ float atanFast(float x) inline float atanHelper(float x) { float x2 = x * x; - return (((0.079331 * x2) - 0.288679) * x2 + 0.995354) * x; + return (((0.079331f * x2) - 0.288679f) * x2 + 0.995354f) * x; // an even more accurate alternative, less fast - // return ((((-0.0389929 * x2) + 0.1462766) * x2 - 0.3211819) * x2 + 0.9992150) * x; + // return ((((-0.0389929f * x2) + 0.1462766f) * x2 - 0.3211819f) * x2 + 0.9992150f) * x; } @@ -407,21 +411,21 @@ float atan2Fast(float y, float x) { if (y >= 0) { - if (fabs(y) >= fabs(x)) return M_PI / 2 - atanFast(x / y); + if (fabs(y) >= fabs(x)) return _PI_DIV_2_ - atanFast(x / y); return atanFast(y / x); } - if (fabs(y) >= fabs(x)) return -M_PI / 2 - atanFast(x / y); + if (fabs(y) >= fabs(x)) return -_PI_DIV_2_ - atanFast(x / y); return atanFast(y / x); } else { if (y >= 0) { - if (fabs(y) >= fabs(x)) return M_PI / 2 - atanFast(x / y); - return M_PI + atanFast(y / x); + if (fabs(y) >= fabs(x)) return _PI_DIV_2_ - atanFast(x / y); + return _PI_ + atanFast(y / x); } - if (fabs(y) >= fabs(x)) return -M_PI / 2 - atanFast(x / y); - return -M_PI + atanFast(y / x); + if (fabs(y) >= fabs(x)) return -_PI_DIV_2_ - atanFast(x / y); + return -_PI_ + atanFast(y / x); } } @@ -429,7 +433,7 @@ float atan2Fast(float y, float x) /////////////////////////////////////////////////////// // // HYPOT -// related but not strict gonio. +// related but not strict goniometry. // // hypotFast() formula for faster hypot() at the price of accuracy // experimental! @@ -442,7 +446,7 @@ float hypotFast(float x, float y) a = fabs(y); b = fabs(x); } - float z = 0.917981 * (b + a / 2); + float z = 0.917981f * (b + a / 2); if (z > b) return z; return b; } diff --git a/FastTrig.h b/FastTrig.h index bd887d4..af9597a 100644 --- a/FastTrig.h +++ b/FastTrig.h @@ -2,7 +2,7 @@ // // FILE: FastTrig.h // AUTHOR: Rob Tillaart -// VERSION: 0.3.3 +// VERSION: 0.3.4 // PURPOSE: Arduino library for a faster approximation of sin() and cos() // DATE: 2011-08-18 // URL: https://github.com/RobTillaart/FastTrig @@ -18,7 +18,8 @@ #endif -#define FAST_TRIG_LIB_VERSION (F("0.3.3")) +#define FAST_TRIG_LIB_VERSION (F("0.3.4")) + #ifdef __cplusplus extern "C" @@ -74,7 +75,7 @@ float atan2Fast(float y, float x); /////////////////////////////////////////////////////// // // HYPOT -// related but not strict gonio. +// related but not strict goniometry. // // hypotFast() formula for faster hypot() at the price of accuracy // experimental! diff --git a/LICENSE b/LICENSE index 09c29af..35dd82b 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2011-2024 Rob Tillaart +Copyright (c) 2011-2025 Rob Tillaart Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 95850cb..3325eef 100644 --- a/README.md +++ b/README.md @@ -47,6 +47,12 @@ Of course this introduces an error but the error is small and performance is sti quite fast (which was the goal). +### Related + +- https://github.com/RobTillaart/fast_math +- https://github.com/RobTillaart?tab=repositories&q=math + + ## Interface ```cpp @@ -54,7 +60,7 @@ quite fast (which was the goal). ``` -#### Lookup tables +### Lookup tables The lookup tables are optimized (sketch provided) to minimize the error when using the interpolation, this implies that the points in the table might not be optimal when you use only whole degrees. @@ -71,10 +77,10 @@ however it is great to use in a LEDstrip or motor movements when less accuracy i Although the tables can be written to, it is advised not to do so. -*OK, the optimize example does a write to improve the table to minimize errors* +_OK, the optimize example does a write to improve the table to minimize errors_ -#### atan, atan2 +### atan, atan2 Since version 0.2.1 two functions are added: - **float atanFast(float f)** input range -1 .. 1 is faster. @@ -89,7 +95,7 @@ Use **fastTrig_atan_performance.ino** to check the gain on your board. Price is that the values are less accurate, but the difference is < 0.001. -#### isin256, icos256, isincos256 +### isin256, icos256, isincos256 Version 0.3.0 added these experimental functions: @@ -102,7 +108,7 @@ returns both the sin(v)\*256 and the cos(v)\*256 of the same angle. Faster than both individual calls together. -#### isincos +### isincos Version 0.3.0 added this experimental function: @@ -113,7 +119,7 @@ There is a minor difference between the value of the **float co** compared to ** This need some investigation ( truncating ?) -#### hypotFast +### hypotFast Strictly **hypot()** is no gonio function but it is often used for calculating length in polar coordinates. @@ -367,6 +373,7 @@ See examples #### Should +- clean example headers (consistency) - write more tests to verify values. - test performance on more platforms. - investigate the difference between **isincos()** and **icos()**. diff --git a/examples/fastTrig_atan_performance/fastTrig_atan_performance.ino b/examples/fastTrig_atan_performance/fastTrig_atan_performance.ino index 1ff31fb..3aebb63 100644 --- a/examples/fastTrig_atan_performance/fastTrig_atan_performance.ino +++ b/examples/fastTrig_atan_performance/fastTrig_atan_performance.ino @@ -1,7 +1,7 @@ // FILE: fastTrig_atan_performance.ino // AUTHOR: Rob Tillaart // DATE: 2022-12-05 -// PURPOSE: performance and accuracy measurement +// PURPOSE: performance and accuracy measurement // URL: https://github.com/RobTillaart/FastTrig @@ -18,12 +18,16 @@ void setup() { Serial.begin(115200); while (!Serial); + Serial.println(); Serial.println(__FILE__); + Serial.println("FAST_TRIG_LIB_VERSION: "); + Serial.println(FAST_TRIG_LIB_VERSION); + Serial.println(); delay(10); x = random(100); y = x + random(100); - + start = micros(); angle = atan(x / y); stop = micros(); @@ -40,7 +44,7 @@ void setup() Serial.println(angle, 4); Serial.println(stop - start); delay(10); - + start = micros(); angle = atan2(y, x); stop = micros(); @@ -56,7 +60,7 @@ void setup() Serial.println(angle, 4); Serial.println(stop - start); delay(10); - + Serial.println("\natan2Fast comparison"); for (float x = -100; x <= 100; x++) { @@ -86,16 +90,16 @@ void setup() float zin(float x) { float x2 = x * x; - // return ((((-0.004392476*x2 + 0.079487663) * x2) -0.645920978) * x2 + 1.570794852) * x; - return (((0.0727102 * x2) - 0.6432292) * x2 + 1.5706268) * x; + // return ((((-0.004392476f*x2 + 0.079487663f) * x2) -0.645920978f) * x2 + 1.570794852f) * x; + return (((0.0727102f * x2) - 0.6432292f) * x2 + 1.5706268f) * x; } float atanA(float x) { float x2 = x * x; - return (((0.079331 * x2) - 0.288679) * x2 + 0.995354) * x; - // return ((((-0.0389929 * x2) + 0.1462766) * x2 - 0.3211819) * x2 + 0.9992150) * x; + return (((0.079331f * x2) - 0.288679f) * x2 + 0.995354f) * x; + // return ((((-0.0389929f * x2) + 0.1462766f) * x2 - 0.3211819f) * x2 + 0.9992150f) * x; } @@ -150,4 +154,6 @@ void loop() { } -// -- END OF FILE -- + +// -- END OF FILE -- + diff --git a/examples/fastTrig_atan_performance/performance_0.3.3.txt b/examples/fastTrig_atan_performance/performance_0.3.3.txt new file mode 100644 index 0000000..0cdc07e --- /dev/null +++ b/examples/fastTrig_atan_performance/performance_0.3.3.txt @@ -0,0 +1,29 @@ +IDE: 1.8.19 +BOARD: Arduino UNO + + +fastTrig_atan_performance.ino +FAST_TRIG_LIB_VERSION: +0.3.3 + + +atan +0.1250 +0.1244 +184 + +atanFast +0.1239 +96 + +atan2 +1.4464 +196 + +atan2Fast +1.4469 +124 + +atan2Fast comparison +done + diff --git a/examples/fastTrig_atan_performance/performance_0.3.4.txt b/examples/fastTrig_atan_performance/performance_0.3.4.txt new file mode 100644 index 0000000..b96a45e --- /dev/null +++ b/examples/fastTrig_atan_performance/performance_0.3.4.txt @@ -0,0 +1,28 @@ +IDE: 1.8.19 +BOARD: Arduino UNO + + +fastTrig_atan_performance.ino +FAST_TRIG_LIB_VERSION: +0.3.4 + + +atan +0.1250 +0.1244 +184 + +atanFast +0.1239 +96 + +atan2 +1.4464 +196 + +atan2Fast +1.4469 +124 + +atan2Fast comparison +done diff --git a/examples/fastTrig_generate_tables/fastTrig_generate_tables.ino b/examples/fastTrig_generate_tables/fastTrig_generate_tables.ino index c156c13..668b694 100644 --- a/examples/fastTrig_generate_tables/fastTrig_generate_tables.ino +++ b/examples/fastTrig_generate_tables/fastTrig_generate_tables.ino @@ -1,39 +1,45 @@ // // FILE: fastTrig_generate_tables.ino // AUTHOR: Rob Tillaart -// PURPOSE: generate look up tables for gonio functions (and others) +// PURPOSE: generate look up tables for goniometry functions (and others) // these are not optimized for interpolation. // DATE: 2020-09-08 +// URL: https://github.com/RobTillaart/FastTrig - -// TODO -// tables might have some trouble at "max values" CHECK +// TODO +// tables might have some trouble at "max values" CHECK #include "Arduino.h" +#include "FastTrig.h" void setup() { Serial.begin(115200); + while (!Serial); + Serial.println(); Serial.println(__FILE__); + Serial.println("FAST_TRIG_LIB_VERSION: "); + Serial.println(FAST_TRIG_LIB_VERSION); + Serial.println(); - // generate any # bits you want. - generate_bit_sin(32); // works is possible - generate_bit_sin(24); // TODO is this better than 16 bit? - generate_bit_sin(20); // for serious math 1 digit better than 16 bit. - generate_bit_sin(16); // for serious math - generate_bit_sin(12); // for 12 bit DAC - generate_bit_sin(10); // for 10 bit DAC - generate_bit_sin(8); // for LED + // generate any # bits you want. + generate_bit_sin(32); // works is possible + generate_bit_sin(24); // TODO is this better than 16 bit? + generate_bit_sin(20); // for serious math 1 digit better than 16 bit. + generate_bit_sin(16); // for serious math + generate_bit_sin(12); // for 12 bit DAC + generate_bit_sin(10); // for 10 bit DAC + generate_bit_sin(8); // for LED - // for LED - // need to patch datatype in output, - // TODO: pack 2 values in one byte ==> would ~half the array size. - generate_bit_sin(4); // interpolating makes no sense + // for LED + // need to patch data type in output, + // TODO: pack 2 values in one byte ==> would ~half the array size. + generate_bit_sin(4); // interpolating makes no sense - generate_bit_cos(16); // note the fasttrig reuses the isin table. + generate_bit_cos(16); // note the fastTrig reuses the isin table. generate_bit_cos(8); generate_bit_tan(16); @@ -150,5 +156,5 @@ void generate_bit_tan(int t) } -// -- END OF FILE -- +// -- END OF FILE -- diff --git a/examples/fastTrig_hypot_accuracy/fastTrig_hypot_accuracy.ino b/examples/fastTrig_hypot_accuracy/fastTrig_hypot_accuracy.ino index cac9338..d4e6b55 100644 --- a/examples/fastTrig_hypot_accuracy/fastTrig_hypot_accuracy.ino +++ b/examples/fastTrig_hypot_accuracy/fastTrig_hypot_accuracy.ino @@ -1,7 +1,7 @@ // FILE: fastTrig_hypot_accuracy.ino // AUTHOR: Rob Tillaart // DATE: 2022-12-05 -// PURPOSE: performance and accuracy measurement +// PURPOSE: performance and accuracy measurement // URL: https://github.com/RobTillaart/FastTrig @@ -18,7 +18,11 @@ void setup() { Serial.begin(115200); while (!Serial); + Serial.println(); Serial.println(__FILE__); + Serial.println("FAST_TRIG_LIB_VERSION: "); + Serial.println(FAST_TRIG_LIB_VERSION); + Serial.println(); delay(10); @@ -53,4 +57,6 @@ void loop() { } -// -- END OF FILE -- + +// -- END OF FILE -- + diff --git a/examples/fastTrig_hypot_performance/fastTrig_hypot_performance.ino b/examples/fastTrig_hypot_performance/fastTrig_hypot_performance.ino index 21ddfe9..ad0ccd6 100644 --- a/examples/fastTrig_hypot_performance/fastTrig_hypot_performance.ino +++ b/examples/fastTrig_hypot_performance/fastTrig_hypot_performance.ino @@ -1,7 +1,7 @@ // FILE: fastTrig_hypot_performance.ino // AUTHOR: Rob Tillaart // DATE: 2022-12-05 -// PURPOSE: performance and accuracy measurement +// PURPOSE: performance and accuracy measurement // URL: https://github.com/RobTillaart/FastTrig @@ -18,7 +18,11 @@ void setup() { Serial.begin(115200); while (!Serial); + Serial.println(); Serial.println(__FILE__); + Serial.println("FAST_TRIG_LIB_VERSION: "); + Serial.println(FAST_TRIG_LIB_VERSION); + Serial.println(); delay(10); x = random(100); @@ -27,12 +31,12 @@ void setup() Serial.println(x); Serial.println(y); delay(10); - + ////////////////////////////////////////// Serial.println("\nPERFORMANCE"); Serial.println("ALGORITHM\tVALUE\t\tTIME"); delay(10); - + start = micros(); for (int i = 0; i < 1000; i++) length = sqrt(x * x + y * y); @@ -73,4 +77,6 @@ void loop() { } -// -- END OF FILE -- + +// -- END OF FILE -- + diff --git a/examples/fastTrig_isincos/fastTrig_isincos.ino b/examples/fastTrig_isincos/fastTrig_isincos.ino index df9c7b5..f43237b 100644 --- a/examples/fastTrig_isincos/fastTrig_isincos.ino +++ b/examples/fastTrig_isincos/fastTrig_isincos.ino @@ -2,19 +2,27 @@ // AUTHOR: Rob Tillaart // DATE: 2022-12-09 // PURPOSE: R&D +// URL: https://github.com/RobTillaart/FastTrig + #include "Arduino.h" #include "FastTrig.h" + uint32_t start, stop; volatile float x; volatile int y; + void setup() { Serial.begin(115200); while (!Serial); + Serial.println(); Serial.println(__FILE__); + Serial.println("FAST_TRIG_LIB_VERSION: "); + Serial.println(FAST_TRIG_LIB_VERSION); + Serial.println(); delay(10); start = micros(); @@ -155,4 +163,5 @@ void loop() } -// -- END OF FILE -- +// -- END OF FILE -- + diff --git a/examples/fatTrig_isincos256/fatTrig_isincos256.ino b/examples/fastTrig_isincos256/fastTrig_isincos256.ino similarity index 93% rename from examples/fatTrig_isincos256/fatTrig_isincos256.ino rename to examples/fastTrig_isincos256/fastTrig_isincos256.ino index 285fa3b..7ef73c0 100644 --- a/examples/fatTrig_isincos256/fatTrig_isincos256.ino +++ b/examples/fastTrig_isincos256/fastTrig_isincos256.ino @@ -2,19 +2,27 @@ // AUTHOR: Rob Tillaart // DATE: 2022-12-09 // PURPOSE: R&D +// URL: https://github.com/RobTillaart/FastTrig + #include "Arduino.h" #include "FastTrig.h" + uint32_t start, stop; volatile float x; volatile int y; + void setup() { Serial.begin(115200); while (!Serial); + Serial.println(); Serial.println(__FILE__); + Serial.println("FAST_TRIG_LIB_VERSION: "); + Serial.println(FAST_TRIG_LIB_VERSION); + Serial.println(); delay(10); start = micros(); @@ -167,4 +175,5 @@ void loop() } -// -- END OF FILE -- +// -- END OF FILE -- + diff --git a/examples/fastTrig_optimize/fastTrig_optimize.ino b/examples/fastTrig_optimize/fastTrig_optimize.ino index 6567e29..9cb6db0 100644 --- a/examples/fastTrig_optimize/fastTrig_optimize.ino +++ b/examples/fastTrig_optimize/fastTrig_optimize.ino @@ -3,10 +3,10 @@ // AUTHOR: Rob Tillaart // PURPOSE: sketch to optimize the table for interpolation // DATE: 2020-09-06 +// URL: https://github.com/RobTillaart/FastTrig -// WARNING TAKES A LOT OF TIME ON 16 MHz - -// TODO make a python script for this ? +// WARNING TAKES A LOT OF TIME ON 16 MHz +// TODO make a python script for this ? #include "FastTrig.h" @@ -15,9 +15,9 @@ float getError(int i) { float error = 0; - for (float f = i - 1; f < i + 1; f += 0.0001) // get error due to interpolation around point i . + for (float f = i - 1; f < i + 1; f += 0.0001) // get error due to interpolation around point i . { - error += abs(sin(f / 180 * PI) - isin(f)); // sum up the error (all errors are traded equal + error += abs(sin(f / 180 * PI) - isin(f)); // sum up the error (all errors are traded equal } return error; } @@ -26,10 +26,14 @@ float getError(int i) void setup() { Serial.begin(115200); + while (!Serial); Serial.println(); + Serial.println(__FILE__); + Serial.println("FAST_TRIG_LIB_VERSION: "); + Serial.println(FAST_TRIG_LIB_VERSION); Serial.println(); - // print the table + // print the table for (int i = 0; i <= 90; i++) { Serial.print(sinTable16[i]); @@ -41,7 +45,7 @@ void setup() test_isin_error_1(false); Serial.println(); - while(optimize()); // prints a new table as long as it is better. + while(optimize()); // prints a new table as long as it is better. Serial.println("\n\ndone..."); } @@ -50,18 +54,18 @@ void setup() int optimize() { int rv = 0; - for (int i = 1; i < 90; i++) // for every angle + for (int i = 1; i < 90; i++) // for every angle { int t = sinTable16[i]; int idx = 0; - float minError = getError(i); // what is the current error + float minError = getError(i); // what is the current error bool flag = false; - for (int j = -2; j <= 2; j++) // try if adjacent numbers in table give less error. + for (int j = -2; j <= 2; j++) // try if adjacent numbers in table give less error. { if (j == 0) continue; sinTable16[i] = t + j; float e = getError(i); - if (e < minError) // if less than we can update the table. + if (e < minError) // if less than we can update the table. { idx = j; minError = e; @@ -69,7 +73,7 @@ int optimize() flag = true; } } - if (flag) Serial.print('*'); // comment if you do not want see changes. + if (flag) Serial.print('*'); // comment if you do not want see changes. sinTable16[i] = t + idx; Serial.print(sinTable16[i]); Serial.print(", "); @@ -126,5 +130,5 @@ void loop() } -// -- END OF FILE -- +// -- END OF FILE -- diff --git a/examples/fatTrig_playground/fatTrig_playground.ino b/examples/fastTrig_playground/fastTrig_playground.ino similarity index 83% rename from examples/fatTrig_playground/fatTrig_playground.ino rename to examples/fastTrig_playground/fastTrig_playground.ino index f82f237..09d4ffe 100644 --- a/examples/fatTrig_playground/fatTrig_playground.ino +++ b/examples/fastTrig_playground/fastTrig_playground.ino @@ -3,26 +3,27 @@ // AUTHOR: Rob Tillaart // PURPOSE: playground to play with tables. // DATE: 2020-09-08 +// URL: https://github.com/RobTillaart/FastTrig -// NOTES +// NOTES // -// 16 bits is less accurate than 24 bits but still has 5-6 digits OK -// storage needs 2 bytes per value ==> 182 bytes +// 16 bits is less accurate than 24 bits but still has 5-6 digits OK +// storage needs 2 bytes per value ==> 182 bytes // -// 24 bits is as accurate as sin() itself. -// accuracy wise on par with sin() function (as expected) -// storage needs 4 bytes per value ==> 364 bytes -// performance on par with 16 bit +// 24 bits is as accurate as sin() itself. +// accuracy wise on par with sin() function (as expected) +// storage needs 4 bytes per value ==> 364 bytes +// performance on par with 16 bit // -// 20 bits is one digit better than 16 bit -// storage needs 4 bytes per value ==> 364 bytes -// performance on par with 16 bit +// 20 bits is one digit better than 16 bit +// storage needs 4 bytes per value ==> 364 bytes +// performance on par with 16 bit // -// 32 bits makes less sense as float have only 23 bit mantisse -// maybe to approx. doubles. +// 32 bits makes less sense as float have only 23 bit mantissa +// maybe to approx. doubles. // -// TODO questions -// Q: 24 bit per degree or 16 bit per half degree? Same storage +// TODO questions +// Q: 24 bit per degree or 16 bit per half degree? Same storage // // @@ -76,7 +77,10 @@ uint16_t sinTable16[] = { void setup() { Serial.begin(115200); + while (!Serial); + Serial.println(); Serial.println(__FILE__); + Serial.println(); test_accuracy(); test_performance(); @@ -95,7 +99,7 @@ void test_accuracy() float a = sin(i * (PI / 180)); float b = (1.0 * sinTable16[i]) / 65535; float c = (1.0 * sinTable20[i]) / 1048575; - // float c = (1.0 * sinTable24[i]) / 16777215; + // float c = (1.0 * sinTable24[i]) / 16777215; Serial.print(a, 8); Serial.print('\t'); Serial.print(abs(a - b), 8); @@ -168,5 +172,4 @@ void loop() } -// -- END OF FILE -- - +// -- END OF FILE -- diff --git a/examples/fastTrig_plot/fastTrig_plot.ino b/examples/fastTrig_plot/fastTrig_plot.ino index 2138912..71ce034 100644 --- a/examples/fastTrig_plot/fastTrig_plot.ino +++ b/examples/fastTrig_plot/fastTrig_plot.ino @@ -3,9 +3,10 @@ // AUTHOR: Rob Tillaart // PURPOSE: testing the fastTrigonio functions // DATE: 2020-09-07 +// URL: https://github.com/RobTillaart/FastTrig -// sketch to visualy compare tan(x) and itan(x) -// use IDE.plotter to view. +// sketch to visually compare tan(x) and itan(x) +// use IDE.plotter to view. #include "FastTrig.h" @@ -18,8 +19,14 @@ int i; void setup() { Serial.begin(115200); + while (!Serial); + Serial.println(); + Serial.println(__FILE__); + Serial.println("FAST_TRIG_LIB_VERSION: "); + Serial.println(FAST_TRIG_LIB_VERSION); + Serial.println(); - // clean plotter buffer + // clean plotter buffer for (int i = 0; i < 500; i++) { Serial.print(0); @@ -68,5 +75,5 @@ void loop() } -// -- END OF FILE -- +// -- END OF FILE -- diff --git a/examples/fastTrig_test1/fastTrig_test1.ino b/examples/fastTrig_test1/fastTrig_test1.ino index 5faa3e6..91e5d8b 100644 --- a/examples/fastTrig_test1/fastTrig_test1.ino +++ b/examples/fastTrig_test1/fastTrig_test1.ino @@ -4,7 +4,7 @@ // PURPOSE: testing the fastTrigonio functions // DATE: 2020-08-30 // (c) : MIT -// +// URL: https://github.com/RobTillaart/FastTrig #include "FastTrig.h" @@ -18,7 +18,12 @@ int i; void setup() { Serial.begin(115200); - Serial.println("start"); + while (!Serial); + Serial.println(); + Serial.println(__FILE__); + Serial.println("FAST_TRIG_LIB_VERSION: "); + Serial.println(FAST_TRIG_LIB_VERSION); + Serial.println(); test_hw_support(); @@ -27,7 +32,7 @@ void setup() test_sin_cos_tan(720); test_isin_icos_itan(720); - test_isin_error_1(false); // parameter true gives a more info + test_isin_error_1(false); // parameter true gives a more info test_icos_error_1(false); test_itan_error_1(false); @@ -35,7 +40,7 @@ void setup() } -bool test_hw_support() // to be elaborated +bool test_hw_support() // to be elaborated { Serial.println(__FUNCTION__); int n = random(350); @@ -141,7 +146,7 @@ void test_isin_error_1(bool show) float b = isin(i * 0.1); float y = abs(a - b); z += y; - if (a > 0) zz += y / a; // not 100% correct but almost. + if (a > 0) zz += y / a; // not 100% correct but almost. if (mx < y) { mx = y; @@ -199,7 +204,7 @@ void test_icos_error_1(bool show) float b = icos(i * 0.1); float y = abs(a - b); z += y; - if (a > 0) zz += y / a; // not 100% correct but almost. + if (a > 0) zz += y / a; // not 100% correct but almost. if (mx < y) { mx = y; @@ -256,9 +261,9 @@ void test_itan_error_1(bool show) if ((i + 900 ) % 1800 == 0) continue; float a = tan(i * 0.1 * PI / 180); float b = itan(i * 0.1); - float y = abs(a - b); // abs error - rel error ~ 1% + float y = abs(a - b); // absolute error - relative error ~ 1% z += y; - if (a > 0) zz += y / a; // not 100% correct but almost. + if (a > 0) zz += y / a; // not 100% correct but almost. if (mx < y) { mx = y; @@ -307,4 +312,5 @@ void loop() } -// -- END OF FILE -- +// -- END OF FILE -- + diff --git a/examples/fastTrig_test1/performance_0.3.4.txt b/examples/fastTrig_test1/performance_0.3.4.txt new file mode 100644 index 0000000..38e84f7 --- /dev/null +++ b/examples/fastTrig_test1/performance_0.3.4.txt @@ -0,0 +1,57 @@ +IDE: 1.8.19 +BOARD: Arduino UNO + +fastTrig_test1.ino +FAST_TRIG_LIB_VERSION: +0.3.4 + +test_hw_support +176 +44 +0.21 + +test_sin_cos_tan +SIN COS TAN 360 calls - offset: 0 +120.42 120.28 147.64 + + +test_isin_icos_itan +ISIN ICOS ITAN 360 calls - offset: 0 +44.19 51.34 112.69 + + +test_sin_cos_tan +SIN COS TAN 360 calls - offset: 720 +124.19 123.96 151.39 + + +test_isin_icos_itan +ISIN ICOS ITAN 360 calls - offset: 720 +84.93 91.36 134.70 + + +test_isin_error_1 +ISIN 0-3600 calls: +max abs error: 0.00011572 +avg abs error: 0.00003061 +max rel error: 0.02955145 +avg rel error: 0.00036519 + + +test_icos_error_1 +ICOS 0-3600 calls: +max abs error: 0.00011519 +avg abs error: 0.00002528 +max rel error: 0.02949960 +avg rel error: 0.00034869 + + +test_itan_error_1 +ITAN 0-3600 calls: +max abs error: 0.72760009 +avg abs error: 0.00641527 +max rel error: 0.00144703 +avg rel error: 0.00037889 + + +done... \ No newline at end of file diff --git a/examples/fastTrig_test2/fastTrig_test2.ino b/examples/fastTrig_test2/fastTrig_test2.ino index 8106a34..8c32d2f 100644 --- a/examples/fastTrig_test2/fastTrig_test2.ino +++ b/examples/fastTrig_test2/fastTrig_test2.ino @@ -4,7 +4,7 @@ // PURPOSE: testing the itan functions // DATE: 2021-08-10 // (c) : MIT - +// URL: https://github.com/RobTillaart/FastTrig #include "FastTrig.h" @@ -18,7 +18,12 @@ int i; void setup() { Serial.begin(115200); - Serial.println("start"); + while (!Serial); + Serial.println(); + Serial.println(__FILE__); + Serial.println("FAST_TRIG_LIB_VERSION: "); + Serial.println(FAST_TRIG_LIB_VERSION); + Serial.println(); test_tan(0); test_itan_error_1(false); @@ -73,9 +78,9 @@ void test_itan_error_1(bool show) if (((i + 900 ) % 1800) == 0) continue; float a = tan(i * 0.1 * PI / 180); float b = itan(i * 0.1); - float y = abs(a - b); // abs error - rel error ~ 1% + float y = abs(a - b); // absolute error - relative error ~ 1% z += y; - if (a > 0) zz += y / a; // not 100% correct but almost. + if (a > 0) zz += y / a; // not 100% correct but almost. if (mx < y) mx = y; if (show) { @@ -121,5 +126,5 @@ void loop() } -// -- END OF FILE -- +// -- END OF FILE -- diff --git a/examples/fastTrig_test_arc/fastTrig_test_arc.ino b/examples/fastTrig_test_arc/fastTrig_test_arc.ino index 83265cf..5ad22f8 100644 --- a/examples/fastTrig_test_arc/fastTrig_test_arc.ino +++ b/examples/fastTrig_test_arc/fastTrig_test_arc.ino @@ -4,7 +4,7 @@ // VERSION: 0.1.1 // PURPOSE: testing the fastTrigonio functions // DATE: 2020-09-09 - +// URL: https://github.com/RobTillaart/FastTrig #include "FastTrig.h" @@ -19,16 +19,21 @@ float f; void setup() { Serial.begin(115200); + while (!Serial); + Serial.println(); Serial.println(__FILE__); + Serial.println("FAST_TRIG_LIB_VERSION: "); + Serial.println(FAST_TRIG_LIB_VERSION); + Serial.println(); test_arcsin_arccos_arctan(); test_i_arcsin_i_arccos_i_arctan(); - test_i_arcsin_error_1(true); // parameter true gives a more info + test_i_arcsin_error_1(true); // parameter true gives a more info test_i_arccos_error_1(true); - // NOT IMPLEMENTED - //test_i_arctan_error_1(true); + // NOT IMPLEMENTED + // test_i_arctan_error_1(true); Serial.println("done...\n"); } @@ -124,7 +129,7 @@ void test_i_arcsin_error_1(bool show) float b = iasin(f); float y = abs(a - b); z += y; - if (a > 0) zz += y / a; // not 100% correct but almost. + if (a > 0) zz += y / a; // not 100% correct but almost. if (mx < y) { mx = y; @@ -182,7 +187,7 @@ void test_i_arccos_error_1(bool show) float b = iacos(f); float y = abs(a - b); z += y; - if (a > 0) zz += y / a; // not 100% correct but almost. + if (a > 0) zz += y / a; // not 100% correct but almost. if (mx < y) { mx = y; @@ -239,9 +244,9 @@ void test_i_arctan_error_1(bool show) if (f == 0) continue; float a = atan(f) * 180 / PI; float b = iatan(f); - float y = abs(a - b); // abs error - rel error ~ 1% + float y = abs(a - b); // absolute error - relative error ~ 1% z += y; - if (a > 0) zz += y / a; // not 100% correct but almost. + if (a > 0) zz += y / a; // not 100% correct but almost. if (mx < y) { mx = y; @@ -290,5 +295,5 @@ void loop() } -// -- END OF FILE -- +// -- END OF FILE -- diff --git a/library.json b/library.json index 3ace928..4295d86 100644 --- a/library.json +++ b/library.json @@ -15,7 +15,7 @@ "type": "git", "url": "https://github.com/RobTillaart/FastTrig" }, - "version": "0.3.3", + "version": "0.3.4", "license": "MIT", "frameworks": "*", "platforms": "*", diff --git a/library.properties b/library.properties index 614f0aa..6cb75e3 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=FastTrig -version=0.3.3 +version=0.3.4 author=Rob Tillaart maintainer=Rob Tillaart sentence=Arduino library with interpolated lookup for sin(), cos(), tan(), atan2() and more.