# Sine 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: ``` /| / | / | c/ | / |a / | / _| /A____|_| b ``` *Sin(A)*, where *A* is the angle between side *b* and *c*, is the ratio *a* / *c*. The function can be defined in many other ways, for example it is the curve we get when tracking only one direction (e.g. horizontal) of a point moving alongside circle. It can also be defined as a solution to some [differential equations](differential_equation.md) etc. The graph of the sine function is following: ``` ^ sin(x) | 1_|_ | .--'''--. -1/2 pi | _.'' ''._ 3/2 pi .________|________.'________|________'|________|________.' --> x '._ | _.'|0 | |'._ | _.'| ''--___--'' _|_ 1/2 pi pi ''--___--'' 2 pi -1 | ``` **Why the fuck are there these [pi](pi.md) values on the x line???** Nubs often can't comprehend this. These pi values are values in **[radians](radian.md)**, units of measuring angles where *2 pi* is the full angle (360 degrees). In fact sine is sometimes shown with [degrees](degree.md) instead of radians (so imagine 90 degrees on the line where there is 1/2 pi etc.), but mathematicians prefer radians. **But why are there angles in the first place???** Why doesn't it go e.g. from 0 to 1 like all other nice functions? Well, it's because of the relation to geometry, remember the fucking triangle above... also if you define sine with a circle it all repeats after *2 pi*. Just draw some picture if you don't get it. 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 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). - [Derivative](derivative.md) of *sin(x)* is *cos(x)*, the [integral](integral.md) of *sin(x) dx* is *-cos(x)*. - By adding many differently shifted and scaled sine functions we can create basically any other function, see e.g. [cosine transform](cosine_transform.md). - *sin(x)^2 + cos(x)^2 = 1* Some values of the sine function are: | x (rad) | x (deg) | sin(x) | |----------|----------|--------------------| | 0 | 0 | 0 | | pi / 12 | 15 | ~0.259 | | pi / 6 | 30 | 0.5 | | pi / 4 | 45 | sqrt(2)/2 ~= 0.707 | | pi / 3 | 60 | sqrt(3)/2 ~= 0.866 | | pi / 2 | 90 | 1 | | 2 pi | 360 | 0 | ## Programming In programming languages sine is generally available in some math library, for example in [C](c.md) the function `sin` is in `math.h`. Spare yourself bugs, **always check if your sin function expects [radians](radian.md) or degrees!** There exists an **ugly engineering [approximation](approximation.md)** of sine that can be useful sometimes, it says that *sin(x) = x, for small x* Indeed, sine looks similar to a mere line near 0, but you can see it quickly diverges. 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 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. 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.).