mirror of
https://github.com/RobTillaart/Arduino.git
synced 2024-10-03 18:09:02 -04:00
0.3.0 FastTrig
This commit is contained in:
parent
8a2f0e7b16
commit
725673b5d9
@ -6,6 +6,16 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
|
||||
and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
|
||||
## [0.3.0] - 2012-12-11
|
||||
- add isin256(), icos256() and isincos256() => integer math only version
|
||||
- add isincos(float f, float &si, float &co) => calculate sin and cos simultaneously.
|
||||
- fix rounding bug when mirroring 90° for remainder.
|
||||
- add examples.
|
||||
- update documentation.
|
||||
- update library.properties.
|
||||
|
||||
----
|
||||
|
||||
## [0.2.1] - 2022-12-05
|
||||
- add atanFast(x) => faster and less accurate than atan().
|
||||
Input range (-1..1) is fastest.
|
||||
@ -15,7 +25,6 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
- update readme.md
|
||||
- update keywords.txt
|
||||
|
||||
|
||||
## [0.2.0] - 2022-12-02
|
||||
- merged PR #16 for ESP_IDF support
|
||||
- added <stdint.h>
|
||||
|
@ -1,7 +1,7 @@
|
||||
//
|
||||
// FILE: FastTrig.cpp
|
||||
// AUTHOR: Rob Tillaart
|
||||
// VERSION: 0.2.1
|
||||
// VERSION: 0.3.0
|
||||
// PURPOSE: Arduino library for a faster approximation of sin() and cos()
|
||||
// DATE: 2011-08-18
|
||||
// URL: https://github.com/RobTillaart/FastTrig
|
||||
@ -60,6 +60,78 @@ uint8_t sinTable8[] = {
|
||||
};
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// GONIO INT EXPERIMENTAL
|
||||
// works with only whole degrees.
|
||||
//
|
||||
int isin256(uint32_t v)
|
||||
{
|
||||
bool negative = false;
|
||||
|
||||
long whole = v;
|
||||
|
||||
if (whole >= 360) whole %= 360;
|
||||
|
||||
int y = whole; // 16 bit math is faster than 32 bit
|
||||
|
||||
if (y >= 180)
|
||||
{
|
||||
y -= 180;
|
||||
negative = true;
|
||||
}
|
||||
|
||||
if (y >= 90)
|
||||
{
|
||||
y = 180 - y;
|
||||
}
|
||||
|
||||
int g = sinTable16[y] >> 8;
|
||||
if (negative) return -g;
|
||||
return g;
|
||||
}
|
||||
|
||||
|
||||
int icos256(uint32_t v)
|
||||
{
|
||||
return isin256(v + 90);
|
||||
}
|
||||
|
||||
|
||||
void isincos256(uint32_t v, int &si, int &co)
|
||||
{
|
||||
bool sneg = false;
|
||||
bool cneg = false;
|
||||
|
||||
long whole = v;
|
||||
|
||||
if (whole >= 360)
|
||||
{
|
||||
whole %= 360;
|
||||
}
|
||||
|
||||
int y = whole; // 16 bit math is faster than 32 bit
|
||||
|
||||
if (y >= 180)
|
||||
{
|
||||
y -= 180;
|
||||
sneg = !sneg;
|
||||
cneg = !cneg;
|
||||
}
|
||||
|
||||
if (y >= 90)
|
||||
{
|
||||
y = 180 - y;
|
||||
cneg = !cneg;
|
||||
}
|
||||
|
||||
si = sinTable16[y] >> 8;
|
||||
co = sinTable16[90-y] >> 8;
|
||||
if (sneg) si = -si;
|
||||
if (cneg) co = -co;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// GONIO LOOKUP
|
||||
@ -76,7 +148,13 @@ float isin(float f)
|
||||
long whole = f;
|
||||
uint8_t remain = (f - whole) * 256;
|
||||
|
||||
if (whole >= 360) whole %= 360;
|
||||
if (whole >= 360)
|
||||
{
|
||||
whole %= 360;
|
||||
// possible faster for 360-720
|
||||
// if (whole >= 720) whole %= 360;
|
||||
// else whole -= 360;
|
||||
}
|
||||
|
||||
int y = whole; // 16 bit math is faster than 32 bit
|
||||
|
||||
@ -91,7 +169,7 @@ float isin(float f)
|
||||
y = 180 - y;
|
||||
if (remain != 0)
|
||||
{
|
||||
remain = 255 - remain;
|
||||
remain = 256 - remain;
|
||||
y--;
|
||||
}
|
||||
}
|
||||
@ -117,6 +195,87 @@ float icos(float x)
|
||||
}
|
||||
|
||||
|
||||
void isincos(float f, float &si, float &co)
|
||||
{
|
||||
bool sneg = (f < 0);
|
||||
bool cneg = false;
|
||||
if (sneg)
|
||||
{
|
||||
f = -f;
|
||||
}
|
||||
|
||||
long whole = f;
|
||||
uint8_t remain = (f - whole) * 256;
|
||||
|
||||
if (whole >= 360)
|
||||
{
|
||||
whole %= 360;
|
||||
// possible faster for 360-720
|
||||
// if (whole >= 720) whole %= 360;
|
||||
// else whole -= 360;
|
||||
}
|
||||
|
||||
int y = whole; // 16 bit math is faster than 32 bit
|
||||
|
||||
if (y >= 180)
|
||||
{
|
||||
y -= 180;
|
||||
sneg = !sneg;
|
||||
cneg = !cneg;
|
||||
}
|
||||
|
||||
if (y >= 90)
|
||||
{
|
||||
y = 180 - y;
|
||||
if (remain != 0)
|
||||
{
|
||||
remain = - remain;
|
||||
y--;
|
||||
}
|
||||
cneg = !cneg;
|
||||
}
|
||||
|
||||
// float value improves ~4% on avg error for ~60 bytes.
|
||||
// SIN
|
||||
uint16_t value = sinTable16[y];
|
||||
// interpolate if needed
|
||||
if (remain > 0)
|
||||
{
|
||||
value = value + ((sinTable16[y + 1] - value) / 8 * remain) / 32; // == * remain / 256
|
||||
}
|
||||
si = value * 0.0000152590219; // = / 65535.0
|
||||
if (sneg) si = -si;
|
||||
|
||||
// COS
|
||||
value = sinTable16[90-y];
|
||||
if (remain > 0)
|
||||
{
|
||||
value = sinTable16[89-y];
|
||||
remain = 256 - remain;
|
||||
value = value + ((sinTable16[90-y] - value) / 8 * remain) / 32; // == * remain / 256
|
||||
}
|
||||
co = value * 0.0000152590219; // = / 65535.0
|
||||
if (cneg) co = -co;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////
|
||||
//
|
||||
// TAN
|
||||
//
|
||||
// tan() should be done with isincos()
|
||||
// as icos() is less accurate => tan() less accurate.
|
||||
/*
|
||||
float itan(float f)
|
||||
{
|
||||
float x, y;
|
||||
isincos(f,x,y);
|
||||
if (y != 0) return x/y;
|
||||
return NAN;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
float itan(float f)
|
||||
{
|
||||
// reference
|
||||
@ -267,5 +426,5 @@ float atan2Fast(float y, float x)
|
||||
}
|
||||
|
||||
|
||||
|
||||
// -- END OF FILE --
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
//
|
||||
// FILE: FastTrig.h
|
||||
// AUTHOR: Rob Tillaart
|
||||
// VERSION: 0.2.1
|
||||
// VERSION: 0.3.0
|
||||
// PURPOSE: Arduino library for a faster approximation of sin() and cos()
|
||||
// DATE: 2011-08-18
|
||||
// URL: https://github.com/RobTillaart/FastTrig
|
||||
@ -18,7 +18,7 @@
|
||||
#endif
|
||||
|
||||
|
||||
#define FAST_TRIG_LIB_VERSION (F("0.2.1"))
|
||||
#define FAST_TRIG_LIB_VERSION (F("0.3.0"))
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
@ -29,6 +29,17 @@ extern uint16_t sinTable16[];
|
||||
extern uint8_t sinTable8[];
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// GONIO INT EXPERIMENTAL
|
||||
//
|
||||
int isin256(uint32_t v);
|
||||
int icos256(uint32_t v);
|
||||
|
||||
// calculate both in one call.
|
||||
void isincos256(uint32_t v, int &si, int &co);
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// GONIO LOOKUP
|
||||
@ -37,6 +48,10 @@ float isin(float f);
|
||||
|
||||
float icos(float x);
|
||||
|
||||
// calculate both in one call.
|
||||
void isincos(float v, float &si, float &co);
|
||||
|
||||
|
||||
float itan(float f);
|
||||
|
||||
// 0 returns NAN but we have a icot(x) cotangent.
|
||||
|
@ -15,6 +15,11 @@ Arduino library with interpolated lookup for sin() and cos(). Trades speed for a
|
||||
|
||||
**Warning: The library trades speed for accuracy so use at own risk**
|
||||
|
||||
So please, verify the performance and accuracy to see if they meet
|
||||
the requirements of your project.
|
||||
|
||||
----
|
||||
|
||||
The library provides one lookup table that is used for
|
||||
**isin(degrees)** and **icos(degrees)** and **itan(degrees)**.
|
||||
This lookup table is optimized for interpolation so the values for whole degrees are not optimal.
|
||||
@ -28,11 +33,15 @@ Similar to ```cos(x) == sin(x + PI)``` it is also true that ```icos(x) == isin(x
|
||||
so **icos()** can use the very same lookup table at the cost of a single addition.
|
||||
In fact it uses ```icos(x) == isin(x - 270)``` as that performs better, due to the folding.
|
||||
|
||||
The **i** in the names stands for **int** and **interpolated** as the core is using integer math and lookup table of 91 uint16_t = 182 bytes.
|
||||
The **i** in the names stands for **int** and **interpolated** as the core is
|
||||
using integer math and lookup table of 91 uint16_t = 182 bytes.
|
||||
By folding and mirroring the whole 360 degrees and beyond can be handled.
|
||||
When **isin(x)** is called and ```x == int(x)``` then the library will not interpolate and this will improve performance.
|
||||
When x is not a whole number the library will linear interpolate between **isin(int(x))** and **isin(int(x+1))**.
|
||||
Of course this introduces an error but it is quite fast (which was the goal).
|
||||
When **isin(float x)** is called and ```x == int(x)``` then the library will not interpolate.
|
||||
This will improve performance even more.
|
||||
When x is not a whole number the library will linear interpolate
|
||||
between **isin(int(x))** and **isin(int(x+1))**.
|
||||
Of course this introduces an error but the error is small and performance is still
|
||||
quite fast (which was the goal).
|
||||
|
||||
|
||||
#### Lookup tables
|
||||
@ -70,6 +79,30 @@ 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
|
||||
|
||||
Version 0.3.0 added these experimental functions:
|
||||
|
||||
- **int isin256(uint32_t v)** accepts only positive angles in degrees.
|
||||
Returns the sin(v)\*256 to keep all math integer (shift 8 later to correct value)
|
||||
- **int icos256(uint32_t v)** accepts only positive angles in degrees.
|
||||
Returns the cos(v)\*256 to keep all math integer (shift 8 later to correct value)
|
||||
- **int isincos256(uint32_t v, int &si, int &co)** accepts only positive angles in degrees.
|
||||
returns both the sin(v)\*256 and the cos(v)\*256 of the same angle.
|
||||
Faster than both individual calls together.
|
||||
|
||||
|
||||
#### isincos
|
||||
|
||||
Version 0.3.0 added this experimental function:
|
||||
|
||||
- **float isincos(float f, float &si, float &co)** accepts any angle in degrees.
|
||||
returns both the sin(v) and the cos(v) of the same angle.
|
||||
Faster than both individual calls, see example.
|
||||
There is a minor difference between the value of the **float co** compared to **icos()**.
|
||||
This need some investigation ( truncating ?)
|
||||
|
||||
|
||||
## Performance isin icos itan
|
||||
|
||||
time in us - calls 0 - 360 step 1 degree and calls 720 - 1080 (lib version 0.1.5)
|
||||
@ -98,7 +131,8 @@ and needs to be normalized ( expensive modulo on AVR ). It is worth noting that
|
||||
original **sin()** **cos()** and **tan()** only have a small overhead for
|
||||
values outside the 0..360 range.
|
||||
|
||||
Please, verify the performance to see if it meets your requirements.
|
||||
Please, verify the performance and accuracy to see if they meet
|
||||
the requirements of your project.
|
||||
|
||||
|
||||
## Accuracy isin icos itan
|
||||
@ -166,7 +200,6 @@ ESP32 calls -1 ..+1 step 0.001 degree
|
||||
- **iatan()** is **Not** Implemented
|
||||
|
||||
|
||||
|
||||
UNO calls -1 ..+1 step 0.001 degree
|
||||
|
||||
| function | max abs error | avg abs error | max rel error | avg rel error |
|
||||
@ -185,7 +218,7 @@ Please, verify the accuracy to see if it meets your requirements.
|
||||
|
||||
## Performance atanFast, atan2Fast
|
||||
|
||||
Times in microseconds (first measurement)
|
||||
Indicative times in microseconds (first measurements)
|
||||
|
||||
| function | atan | atanF | atan2 | atan2F | factor | notes |
|
||||
|:----------:|:------:|:-------:|:-------:|:--------:|:--------:|:--------|
|
||||
@ -193,18 +226,80 @@ Times in microseconds (first measurement)
|
||||
| UNO | 220 | 124 | 212 | 128 | ~1.6 |
|
||||
| ESP32 | 50 | 15 | 44 | 13 | ~3.3 |
|
||||
|
||||
The range
|
||||
The range of the second UNO is beyond the -1..1 range
|
||||
|
||||
Additional measurements are welcome.
|
||||
(use performance sketch)
|
||||
|
||||
To be elaborated.
|
||||
|
||||
|
||||
## Accuracy atanFast, atan2Fast
|
||||
|
||||
The atan2Fast() uses atanFast() so the accuracy for both is the same.
|
||||
The test sketch indicates a maximum error is smaller than 0.001.
|
||||
|
||||
To be elaborated
|
||||
To be elaborated.
|
||||
|
||||
|
||||
## Performance isincos()
|
||||
|
||||
**isincos()** calculates sin(f) and cos(f) in one call.
|
||||
|
||||
1000 calls in microseconds.
|
||||
|
||||
| function | UNO 16 | ESP32 240 |
|
||||
|:------------|:--------:|:-----------:|
|
||||
| sin | 122872 | 10926 |
|
||||
| isin | 70704 | 1086 |
|
||||
| cos | 122636 | 10853 |
|
||||
| icos | 66588 | 1151 |
|
||||
| isin + icos | 148368 | 2248 |
|
||||
| isincos | 103788 | 1909 |
|
||||
|
||||
Note the isincos() is faster than the original
|
||||
sin() or cos() while being pretty accurate.
|
||||
|
||||
|
||||
## Accuracy isincos()
|
||||
|
||||
As the basic algorithm is very similar to isin() the accuracy is the same.
|
||||
|
||||
|
||||
## Performance isin256 icos256 isincos256
|
||||
|
||||
**isin256()**, **icos256()** and **isincos256()** calculates the sin\*256 etc.
|
||||
These functions all return an integer value.
|
||||
There is no floating point math in there so it performs a bit better.
|
||||
At some moment you must correct this factor of 256 with a division or a shift 8.
|
||||
|
||||
|
||||
1000 calls in microseconds. Based upon **fastTrig_isincos256.ino**
|
||||
|
||||
Note to test and compare, the values were multiplied by 100 and shifted by 8.
|
||||
|
||||
| function | UNO 16 | ESP32 240 |
|
||||
|:------------------|:--------:|:-----------:|
|
||||
| sin | 131260 | 11364 |
|
||||
| isin | 79044 | 1119 |
|
||||
| isin256 | 28284 | 255 |
|
||||
| cos | 131008 | 11298 |
|
||||
| icos | 74928 | 1190 |
|
||||
| icos256 | 31704 | 289 |
|
||||
| isin256 + icos256 | 58352 | 478 |
|
||||
| isincos256 | 32300 | 339 |
|
||||
|
||||
Note the **Ixxx256()** series functions are Fast.
|
||||
The price is accuracy but might still be OK for many projects.
|
||||
|
||||
|
||||
## Accuracy isin256 icos256 isincos256
|
||||
|
||||
The **Ixxx256()** only accept whole degrees.
|
||||
Therefore the values come directly from the lookup tables. no interpolation.
|
||||
The error is less than 2% (first measurements.
|
||||
|
||||
**To be quantified**
|
||||
|
||||
|
||||
## versions
|
||||
@ -219,5 +314,23 @@ See examples
|
||||
|
||||
## Future
|
||||
|
||||
- How to improve the accuracy of the whole degrees, as now the table is optimized for interpolation.
|
||||
- sinc(x) = sin(x)/x function.?
|
||||
#### Must
|
||||
- improve documentation
|
||||
- verify math (tables etc) again.
|
||||
- write test sketches that output the tables for documentation :)
|
||||
|
||||
#### Should
|
||||
- write more tests to verify values.
|
||||
- test performance on more platforms.
|
||||
- investigate the difference between **isincos()** and **icos()**.
|
||||
- investigate **itan256()**
|
||||
- itan256(0) = 0 itan256(1) = 4 itan256(2) = 9 so there will be big steps...
|
||||
- max abs error should be 0.5 or less, it might have its uses.
|
||||
|
||||
#### Could
|
||||
- How to improve the accuracy of the whole degrees,
|
||||
- now the table is optimized for interpolation.
|
||||
- add **sinc(x)** = **sin(x)/x** function.?
|
||||
- **ixxx256()** functions need another lookup table?
|
||||
- separate .h file?
|
||||
|
||||
|
@ -0,0 +1,136 @@
|
||||
// FILE: isincos.ino
|
||||
// AUTHOR: Rob Tillaart
|
||||
// DATE: 2022-12-09
|
||||
// PURPOSE: R&D
|
||||
|
||||
#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(__FILE__);
|
||||
delay(10);
|
||||
|
||||
start = micros();
|
||||
for (uint32_t r = 0; r < 1000; r++)
|
||||
{
|
||||
x = sin(r);
|
||||
}
|
||||
stop = micros();
|
||||
Serial.print("SIN: \t\t");
|
||||
Serial.println(stop - start);
|
||||
delay(10);
|
||||
|
||||
|
||||
start = micros();
|
||||
for (uint32_t r = 0; r < 1000; r++)
|
||||
{
|
||||
x = isin(r);
|
||||
}
|
||||
stop = micros();
|
||||
Serial.print("ISIN: \t\t");
|
||||
Serial.println(stop - start);
|
||||
delay(10);
|
||||
|
||||
start = micros();
|
||||
for (uint32_t r = 0; r < 1000; r++)
|
||||
{
|
||||
x = cos(r);
|
||||
}
|
||||
stop = micros();
|
||||
Serial.print("COS: \t\t");
|
||||
Serial.println(stop - start);
|
||||
delay(10);
|
||||
|
||||
|
||||
start = micros();
|
||||
for (uint32_t r = 0; r < 1000; r++)
|
||||
{
|
||||
x = icos(r);
|
||||
}
|
||||
stop = micros();
|
||||
Serial.print("ICOS: \t\t");
|
||||
Serial.println(stop - start);
|
||||
delay(10);
|
||||
|
||||
for (uint32_t r = 0; r <= 360; r++)
|
||||
{
|
||||
x = cos(r * PI / 180.0);
|
||||
y = icos(r);
|
||||
if (abs(x - y) >= 1)
|
||||
{
|
||||
Serial.print(r);
|
||||
Serial.print('\t');
|
||||
Serial.print(x);
|
||||
Serial.print('\t');
|
||||
Serial.print(float(y));
|
||||
Serial.println();
|
||||
}
|
||||
}
|
||||
Serial.println();
|
||||
delay(100);
|
||||
|
||||
volatile float sum = 0;
|
||||
start = micros();
|
||||
for (uint32_t r = 0; r < 1000; r++)
|
||||
{
|
||||
sum += isin(r) + icos(r);
|
||||
}
|
||||
stop = micros();
|
||||
Serial.print("ISIN + ICOS: \t");
|
||||
Serial.println(stop - start);
|
||||
Serial.println(sum);
|
||||
delay(10);
|
||||
|
||||
sum = 0;
|
||||
start = micros();
|
||||
for (uint32_t r = 0; r < 1000; r++)
|
||||
{
|
||||
float p, q;
|
||||
isincos(r, p, q);
|
||||
sum += p + q;
|
||||
}
|
||||
stop = micros();
|
||||
Serial.print("ISINCOS: \t");
|
||||
Serial.println(stop - start);
|
||||
Serial.println(sum);
|
||||
delay(10);
|
||||
|
||||
|
||||
for (uint32_t r = 0; r < 100; r++)
|
||||
{
|
||||
float p, q, s, t;
|
||||
isincos(r*0.1, p, q);
|
||||
s = isin(r*0.1);
|
||||
t = icos(r*0.1);
|
||||
if ((abs(p-s) > 0.0001) || (abs(q-t) > 0.0001))
|
||||
{
|
||||
Serial.print(r);
|
||||
Serial.print("\t");
|
||||
Serial.print(s, 6);
|
||||
Serial.print("\t");
|
||||
Serial.print(p, 6);
|
||||
Serial.print("\t");
|
||||
Serial.print(t, 6);
|
||||
Serial.print("\t");
|
||||
Serial.print(q, 6);
|
||||
Serial.println();
|
||||
}
|
||||
}
|
||||
delay(10);
|
||||
|
||||
Serial.println("\ndone...");
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// -- END OF FILE --
|
@ -0,0 +1,51 @@
|
||||
start
|
||||
test_hw_support
|
||||
172
|
||||
40
|
||||
0.21
|
||||
|
||||
test_sin_cos_tan
|
||||
SIN COS TAN 360 calls - offset: 0
|
||||
120.42 120.29 147.66
|
||||
|
||||
|
||||
test_isin_icos_itan
|
||||
ISIN ICOS ITAN 360 calls - offset: 0
|
||||
44.21 51.33 112.71
|
||||
|
||||
|
||||
test_sin_cos_tan
|
||||
SIN COS TAN 360 calls - offset: 720
|
||||
124.19 123.98 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.00010270
|
||||
avg abs error: 0.00002059
|
||||
max rel error: 0.02955145
|
||||
avg rel error: 0.00035171
|
||||
|
||||
|
||||
test_icos_error_1
|
||||
ICOS 0-3600 calls:
|
||||
max abs error: 0.00010264
|
||||
avg abs error: 0.00002032
|
||||
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...
|
@ -0,0 +1,157 @@
|
||||
// FILE: fastTrig_isincos256.ino
|
||||
// AUTHOR: Rob Tillaart
|
||||
// DATE: 2022-12-09
|
||||
// PURPOSE: R&D
|
||||
|
||||
#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(__FILE__);
|
||||
delay(10);
|
||||
|
||||
start = micros();
|
||||
for (uint32_t r = 0; r < 1000; r++)
|
||||
{
|
||||
x = (100 * sin(r));
|
||||
}
|
||||
stop = micros();
|
||||
Serial.print("SIN: \t\t");
|
||||
Serial.println(stop - start);
|
||||
delay(10);
|
||||
|
||||
|
||||
start = micros();
|
||||
for (uint32_t r = 0; r < 1000; r++)
|
||||
{
|
||||
x = (100 * isin(r));
|
||||
}
|
||||
stop = micros();
|
||||
Serial.print("ISIN: \t\t");
|
||||
Serial.println(stop - start);
|
||||
delay(10);
|
||||
|
||||
start = micros();
|
||||
for (uint32_t r = 0; r < 1000; r++)
|
||||
{
|
||||
y = (100 * isin256(r)) >> 8;
|
||||
}
|
||||
stop = micros();
|
||||
Serial.print("ISIN256: \t");
|
||||
Serial.println(stop - start);
|
||||
Serial.println();
|
||||
delay(10);
|
||||
|
||||
|
||||
start = micros();
|
||||
for (uint32_t r = 0; r < 1000; r++)
|
||||
{
|
||||
x = (100 * cos(r));
|
||||
}
|
||||
stop = micros();
|
||||
Serial.print("COS: \t\t");
|
||||
Serial.println(stop - start);
|
||||
delay(10);
|
||||
|
||||
|
||||
start = micros();
|
||||
for (uint32_t r = 0; r < 1000; r++)
|
||||
{
|
||||
x = (100 * icos(r));
|
||||
}
|
||||
stop = micros();
|
||||
Serial.print("ICOS: \t\t");
|
||||
Serial.println(stop - start);
|
||||
delay(10);
|
||||
|
||||
start = micros();
|
||||
for (uint32_t r = 0; r < 1000; r++)
|
||||
{
|
||||
y = (100 * icos256(r)) >> 8;
|
||||
}
|
||||
stop = micros();
|
||||
Serial.print("ICOS256: \t");
|
||||
Serial.println(stop - start);
|
||||
Serial.println();
|
||||
delay(10);
|
||||
|
||||
for (uint32_t r = 0; r <= 360; r++)
|
||||
{
|
||||
x = (100 * cos(r * PI / 180.0));
|
||||
y = (100 * icos256(r)) >> 8;
|
||||
if (abs(x - y) >= 1)
|
||||
{
|
||||
Serial.print(r);
|
||||
Serial.print('\t');
|
||||
Serial.print(x);
|
||||
Serial.print('\t');
|
||||
Serial.print(float(y));
|
||||
Serial.println();
|
||||
}
|
||||
}
|
||||
Serial.println();
|
||||
delay(100);
|
||||
|
||||
volatile int sum = 0;
|
||||
start = micros();
|
||||
for (uint32_t r = 0; r < 1000; r++)
|
||||
{
|
||||
sum += isin256(r) + icos256(r);
|
||||
}
|
||||
stop = micros();
|
||||
Serial.print("S C 256: \t");
|
||||
Serial.println(stop - start);
|
||||
delay(10);
|
||||
|
||||
|
||||
start = micros();
|
||||
for (uint32_t r = 0; r < 1000; r++)
|
||||
{
|
||||
int p, q;
|
||||
isincos256(r, p, q);
|
||||
sum += p + q;
|
||||
}
|
||||
stop = micros();
|
||||
Serial.print("ISINCOS256: \t");
|
||||
Serial.println(stop - start);
|
||||
delay(10);
|
||||
|
||||
|
||||
for (uint32_t r = 0; r < 1000; r++)
|
||||
{
|
||||
int p, q, s, t;
|
||||
isincos256(r, p, q);
|
||||
s = isin256(r);
|
||||
t = icos256(r);
|
||||
if (p != s || q != t)
|
||||
{
|
||||
Serial.print(r);
|
||||
Serial.print("\t");
|
||||
Serial.print(s);
|
||||
Serial.print("\t");
|
||||
Serial.print(p);
|
||||
Serial.print("\t");
|
||||
Serial.print(t);
|
||||
Serial.print("\t");
|
||||
Serial.print(q);
|
||||
Serial.println();
|
||||
}
|
||||
}
|
||||
delay(10);
|
||||
|
||||
Serial.println("\ndone...");
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// -- END OF FILE --
|
@ -5,6 +5,8 @@
|
||||
# Methods and Functions (KEYWORD2)
|
||||
isin KEYWORD2
|
||||
icos KEYWORD2
|
||||
isincos KEYWORD2
|
||||
|
||||
itan KEYWORD2
|
||||
icot KEYWORD2
|
||||
|
||||
@ -14,6 +16,10 @@ iacos KEYWORD2
|
||||
atanFast KEYWORD2
|
||||
atan2Fast KEYWORD2
|
||||
|
||||
isin256 KEYWORD2
|
||||
icos256 KEYWORD2
|
||||
isincos256 KEYWORD2
|
||||
|
||||
|
||||
# Instances (KEYWORD2)
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "FastTrig",
|
||||
"keywords": "sin, cos, tan, isin, icos, itan, icot, fast",
|
||||
"description": "Arduino library with interpolated lookup for sin() cos() tan(). Trades speed for accuracy. Check readme for details.",
|
||||
"keywords": "sin, cos, tan, isin, icos, itan, icot, fast, isincos",
|
||||
"description": "Arduino library with interpolated lookup for sin(), cos(), tan(), atan2() and more. Trades speed for accuracy. Check readme.md for details.",
|
||||
"authors":
|
||||
[
|
||||
{
|
||||
@ -15,7 +15,7 @@
|
||||
"type": "git",
|
||||
"url": "https://github.com/RobTillaart/FastTrig"
|
||||
},
|
||||
"version": "0.2.1",
|
||||
"version": "0.3.0",
|
||||
"license": "MIT",
|
||||
"frameworks": "*",
|
||||
"platforms": "*",
|
||||
|
@ -1,9 +1,9 @@
|
||||
name=FastTrig
|
||||
version=0.2.1
|
||||
author=Rob Tillaart <rob.tillaart@gmail.com><pete.thompson@yahoo.com>
|
||||
version=0.3.0
|
||||
author=Rob Tillaart <rob.tillaart@gmail.com>
|
||||
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
|
||||
sentence=Arduino library with interpolated lookup for sin() and cos()
|
||||
paragraph=Trades speed for accuracy. Check readme for details.
|
||||
sentence=Arduino library with interpolated lookup for sin(), cos(), tan(), atan2() and more.
|
||||
paragraph=Trades speed for accuracy. Check readme.md for details.
|
||||
category=Data Processing
|
||||
url=https://github.com/RobTillaart/FastTrig
|
||||
architectures=*
|
||||
|
Loading…
Reference in New Issue
Block a user