Update
This commit is contained in:
parent
f7e0fb4b27
commit
556653d6e4
28 changed files with 190 additions and 41 deletions
41
sin.md
41
sin.md
|
@ -2,8 +2,6 @@
|
|||
|
||||
Sine, abbreviated *sin*, is a [trigonometric](trigonometry.md) [function](function.md) that simply said models a smooth oscillation, it is one of the most important and basic functions in geometry, [mathematics](math.md) and [physics](physics.md), and of course in [programming](programming.md). Along with [cosine](cos.md), [tangent](tan.md) and [cotangent](cot.md) it belongs to a group of functions that can be defined by ratios of sides of a right triangle depending on one of the angles in it (hence *trigonometric* -- "triangle measuring"). If some measurement looks like sine function, we say it is *harmonic*. This is very common in nature and technology, e.g. a weight on a spring goes up and down by this function, [alternating current](ac.md) voltage has the sine shape (because it is generated by a circular motion) etc.
|
||||
|
||||
|
||||
|
||||
The function is most commonly defined using a right triangle as follows. Consider the following triangle:
|
||||
|
||||
```
|
||||
|
@ -39,7 +37,7 @@ The graph of the sine function is following:
|
|||
Some additional facts and properties regarding the sine functions are:
|
||||
|
||||
- The domain are all [real numbers](real_number.md), the [codomain](codomain.md) are real numbers in interval <-1,1> (including both bounds).
|
||||
- It is an [odd function](odd_function.md) (-sin(x) = sin(-x)).
|
||||
- It is an [odd function](odd_function.md) (*-sin(x) = sin(-x)*).
|
||||
- It is periodic, with a period of 2 [pi](pi.md).
|
||||
- Sine is just shifted [cosine](cos.md), i.e. *sin(x) = cos(x - 1/2 pi)*
|
||||
- Its inverse function is [arcus sine](asin.md), abbreviated *asin*, also written as *sin^-1* -- this function tells you what argument you need to give to sin to get a specific result number. It's actually an inverse of only part of the sine function because the whole sine function can't be inverted, it isn't [bijective](bijection.md).
|
||||
|
@ -74,6 +72,39 @@ Indeed, sine looks similar to a mere line near 0, but you can see it quickly div
|
|||
|
||||
When implementing your own `sin` function, consider what you expect from it.
|
||||
|
||||
If you want a small, fast and perhaps integer only `sin` function (the one we'd prefer in [LRS](lrs.md)) that doesn't need extreme accuracy, consider using a **[look up table](lut.md)**. You simply precompute the values of the sine function into a static table in memory and the function just retrieves them when called -- this is super fast. Note that you can save a lot of space by **only storing sine values between 0 and 1/2 pi**, the remaining parts of the function are just different transformation of this part. You can further save space and/or make the function work with [floats](float.md) by further [interpolating](interpolation.md) (e.g. just linearly) between the stored values, for example if `sin(3.45)` is called and you only have values stored for `sin(3.4)` and `sin(3.5)`, you simply average them.
|
||||
If you want a small, fast and perhaps integer only `sin` function (the one we'd prefer in [LRS](lrs.md)) that doesn't need extreme accuracy, consider using a **[look up table](lut.md)**. You simply precompute the values of the sine function into a static table in memory and the function just retrieves them when called -- this is super fast. Note that you can save a lot of space by **only storing sine values between 0 and 1/2 pi**, the remaining parts of the function are just different transformations of this part. You can further save space and/or make the function work with [floats](float.md) by further [interpolating](interpolation.md) (even just linearly) between the stored values, for example if `sin(3.45)` is called and you only have values stored for `sin(3.4)` and `sin(3.5)`, you simply average them.
|
||||
|
||||
Another approach is to use [Taylor series](taylor_series.md) to approximate sine with a [polynomial](polynomial.md) to whatever precision we need (this is used in calculators etc.).
|
||||
If you don't need extreme speed there exist nice sine [approximation](approximation.md), e.g. the extremely accurate **Bhaskara I's approximation** (angle in radians): *sin(x) ~= (16 * x * (pi - x)) / (5 * pi^2 - 4 * x * (pi - x))*. (This formula is actually more elegant for cosine, so it may be even better to consider using that.) Here is a [C](c.md) [fixed point](fixed_point.md) implementation:
|
||||
|
||||
```
|
||||
#define UNIT 1024
|
||||
#define PI ((int) (UNIT * 3.14159265))
|
||||
|
||||
/* Integer sine using Bhaskara's approx. Returns a number
|
||||
in <-UNIT, UNIT> interval. Argument is in radians * UNIT. */
|
||||
|
||||
int sinInt(int x)
|
||||
{
|
||||
int sign = 1;
|
||||
|
||||
if (x < 0) // odd function
|
||||
{
|
||||
x *= -1;
|
||||
sign = -1;
|
||||
}
|
||||
|
||||
x %= 2 * PI;
|
||||
|
||||
if (x > PI)
|
||||
{
|
||||
x -= PI;
|
||||
sign *= -1;
|
||||
}
|
||||
|
||||
int tmp = PI - x;
|
||||
|
||||
return sign * (16 * x * tmp) / ((5 * PI * PI - 4 * x * tmp) / UNIT);
|
||||
}
|
||||
```
|
||||
|
||||
Another approach is to use [Taylor series](taylor_series.md) to approximate sine with a [polynomial](polynomial.md) to whatever precision we need (this is used e.g. in calculators etc.).
|
Loading…
Add table
Add a link
Reference in a new issue