From 717f0e46d950060f2147f022f65b7e44e72cfdd8 Mon Sep 17 00:00:00 2001 From: Chris O <46587501+ChrisO345@users.noreply.github.com> Date: Fri, 21 Oct 2022 20:03:57 +1300 Subject: [PATCH] Maclaurin series approximation of sin (#7451) * added maclaurin_sin.py function * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * added type hints and fixed line overflows * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * removed incompatable type examples * Update maths/maclaurin_sin.py Co-authored-by: Caeden Perelli-Harris * changed error details * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * fixed grammatical errors * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * improved function accuracy and added test case * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Update maths/maclaurin_sin.py Co-authored-by: Christian Clauss * removed redundant return * fixed pytest * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Caeden Perelli-Harris Co-authored-by: Christian Clauss --- maths/maclaurin_sin.py | 64 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 maths/maclaurin_sin.py diff --git a/maths/maclaurin_sin.py b/maths/maclaurin_sin.py new file mode 100644 index 000000000..3c27ccf63 --- /dev/null +++ b/maths/maclaurin_sin.py @@ -0,0 +1,64 @@ +""" +https://en.wikipedia.org/wiki/Taylor_series#Trigonometric_functions +""" +from math import factorial, pi + + +def maclaurin_sin(theta: float, accuracy: int = 30) -> float: + """ + Finds the maclaurin approximation of sin + + :param theta: the angle to which sin is found + :param accuracy: the degree of accuracy wanted minimum ~ 1.5 theta + :return: the value of sine in radians + + + >>> from math import isclose, sin + >>> all(isclose(maclaurin_sin(x, 50), sin(x)) for x in range(-25, 25)) + True + >>> maclaurin_sin(10) + -0.544021110889369 + >>> maclaurin_sin(-10) + 0.5440211108893703 + >>> maclaurin_sin(10, 15) + -0.5440211108893689 + >>> maclaurin_sin(-10, 15) + 0.5440211108893703 + >>> maclaurin_sin("10") + Traceback (most recent call last): + ... + ValueError: maclaurin_sin() requires either an int or float for theta + >>> maclaurin_sin(10, -30) + Traceback (most recent call last): + ... + ValueError: maclaurin_sin() requires a positive int for accuracy + >>> maclaurin_sin(10, 30.5) + Traceback (most recent call last): + ... + ValueError: maclaurin_sin() requires a positive int for accuracy + >>> maclaurin_sin(10, "30") + Traceback (most recent call last): + ... + ValueError: maclaurin_sin() requires a positive int for accuracy + """ + + if not isinstance(theta, (int, float)): + raise ValueError("maclaurin_sin() requires either an int or float for theta") + + if not isinstance(accuracy, int) or accuracy <= 0: + raise ValueError("maclaurin_sin() requires a positive int for accuracy") + + theta = float(theta) + div = theta // (2 * pi) + theta -= 2 * div * pi + return sum( + (((-1) ** r) * ((theta ** (2 * r + 1)) / factorial(2 * r + 1))) + for r in range(accuracy) + ) + + +if __name__ == "__main__": + print(maclaurin_sin(10)) + print(maclaurin_sin(-10)) + print(maclaurin_sin(10, 15)) + print(maclaurin_sin(-10, 15))