Limba has no trigonometric functions

libmath on a specific embedded system does not have such features, as sin

and cos

due to the lack of the fp-operation module.

Is there any library around that exposes functions via look-up tables? I really don't need 100% reliable values.

+3


source to share


5 answers


Depending on the required speed and accuracy requirements, perhaps you could create the functions needed for a simple lookup table by writing a program to create the lookup table. Or use CORDIC .



+2


source


The best way for non-hardware floating point targets is probably to use the fixed point algorithm and CORDIC.



Anthony Williams fixed point math data library provides a complete analog of the standard math library for a data type fixed

that is typically around 5 times faster than soft floating point for the same purpose. It's a C ++ library, but as long as your compiler supports C ++, this shouldn't be a problem, even if the rest of your code doesn't use C ++ special features. For the most part, all you have to do for the port code to use this library is to replace math.h with fixed.hpp and replace the keywords with float

and double

with the type fixed

.

+2


source


If you don't have libraries for your system that provide sin / cos functions or in-memory lookup tables, you can create one very easily.

The following matlab function will give you a sin(x)

([0.2 * pi] range in 2 * pi / 100 increments) in a c-header myheader.h

:

step=2*pi/100;
x=[0:step:2*pi];
y=floor(0.5 * 65535 * sin(x));

fd=fopen('myheader.h','wt');
fprintf(fd,'int16_t y[%d]={%g',length(y),y(1));
fprintf(fd,',\n %.9g',y(2:end));
fprintf(fd,'};\n');
fclose(fd);

      


The header looks like this:

int16_t y[101]={0,
 2057,
 4107,
 6140,
 8149,
 10126,
 12063,
 13952,
 15786,
 17558,
 19260,
 20887,
 22431,
 23886,
 25248,
 26509,
 27667,
 28714,
 29649,
 30466,
 31164,
 31738,
 32187,
 32509,
 32703,
 32767,
 32703,
 32509,
 32187,
 31738,
 31164,
 30466,
 29649,
 28714,
 27667,
 26509,
 25248,
 23886,
 22431,
 20887,
 19260,
 17558,
 15786,
 13952,
 12063,
 10126,
 8149,
 6140,
 4107,
 2057,
 -0,
 -2057,
 -4107,
 -6140,
 -8149,
 -10126,
 -12063,
 -13952,
 -15786,
 -17558,
 -19260,
 -20887,
 -22431,
 -23886,
 -25248,
 -26509,
 -27667,
 -28714,
 -29649,
 -30466,
 -31164,
 -31738,
 -32187,
 -32509,
 -32703,
 -32768,
 -32703,
 -32509,
 -32187,
 -31738,
 -31164,
 -30466,
 -29649,
 -28714,
 -27667,
 -26509,
 -25248,
 -23886,
 -22431,
 -20887,
 -19260,
 -17558,
 -15786,
 -13952,
 -12063,
 -10126,
 -8149,
 -6140,
 -4107,
 -2057,
 -0};

      

+1


source


Jack Ganssle has an excellent article on Trigger Optimization for Embedded Systems:

http://www.ganssle.com/approx/approx.pdf

0


source


I don't think it makes sense to provide such a library as there are too many design and parameterization options compared to the difficulty of writing your own. I mean, none of them are very difficult, but cannot be provided as a solution for everyone.

  • parameters:

    • sin / cos argument == (unsigned) vs (signed)
    • short, int, float, fixed point
    • range: limited (mod pi, mod 2pi)
    • - the argument is radians, degrees, or whatever (e.g. 2pi == 65536 == 0)
  • meaning

    • float versus fixed point versus scaled integer
    • 1st quadrant only, full or extended range (no argument staging)
    • both sines and cosines, or just sine
  • demands

    • code size
    • data size
    • execution speed
      • "constant" vs.
      • many options are allowed.
    • accuracy
      • minimize minimum quadratic metric
      • minimize maximum error
      • minimize 1 - sin (x) ^ 2 - cos (x) ^ 2 error
  • Method

    • direct a = LUT [b]
    • mirroring depending on the quadrant: a = sign (b) * LUT [b ^ mirror (b)]; // conceptual formula
    • CORDIC
    • Polynomial of 3rd or 5th Taylor level
    • added (angular) precision using two LUT tables LUTA (x) = sin (x); LUTB (x) = sin (x / 256) and formula for sum of angles
0


source







All Articles