Skip to content
Snippets Groups Projects
Commit aa2d137d authored by Taddeus Kroes's avatar Taddeus Kroes
Browse files

Implemented standard radians.

parent be87484c
No related branches found
No related tags found
No related merge requests found
from ..node import OP_ADD, OP_MUL, OP_DIV, OP_POW, OP_NEG, OP_SIN, OP_COS
from ..node import OP_ADD, OP_MUL, OP_DIV, OP_POW, OP_NEG, OP_SIN, OP_COS, \
OP_TAN
from .groups import match_combine_groups
from .factors import match_expand
from .powers import match_add_exponents, match_subtract_exponents, \
......@@ -13,7 +14,7 @@ from .negation import match_negated_factor, match_negate_polynome, \
match_negated_division
from .sort import match_sort_multiplicants
from .goniometry import match_add_quadrants, match_negated_parameter, \
match_half_pi_subtraction
match_half_pi_subtraction, match_standard_radian
RULES = {
OP_ADD: [match_add_numerics, match_add_constant_fractions,
......@@ -28,6 +29,9 @@ RULES = {
match_remove_negative_exponent, match_exponent_to_root,
match_extend_exponent, match_constant_exponent],
OP_NEG: [match_negate_polynome],
OP_SIN: [match_negated_parameter, match_half_pi_subtraction],
OP_COS: [match_negated_parameter, match_half_pi_subtraction],
OP_SIN: [match_negated_parameter, match_half_pi_subtraction,
match_standard_radian],
OP_COS: [match_negated_parameter, match_half_pi_subtraction,
match_standard_radian],
OP_TAN: [match_standard_radian],
}
from .utils import is_fraction
from ..node import ExpressionNode as N, ExpressionLeaf as L, Scope, OP_ADD, \
OP_POW, OP_MUL, OP_SIN, OP_COS, OP_TAN, PI
OP_POW, OP_MUL, OP_DIV, OP_SIN, OP_COS, OP_TAN, PI, TYPE_OPERATOR
from ..possibilities import Possibility as P, MESSAGES
from ..translate import _
......@@ -102,9 +102,44 @@ def match_half_pi_subtraction(node):
return []
def is_pi_frac(node, denominator):
"""
Check if a node is a fraction of 1 multiplied with PI.
Example:
>>> print is_pi_frac(L(1) / 2 * L(PI), 2)
True
"""
if not node.is_op(OP_MUL):
return False
frac, pi = node
if not frac.is_op(OP_DIV) or not pi.is_leaf or pi.value != PI:
return False
n, d = frac
return n == 1 and d == denominator
def sqrt(value):
return N('sqrt', L(value))
l0, l1, sq2, sq3 = L(0), L(1), sqrt(2), sqrt(3)
half = l1 / 2
CONSTANTS = {
OP_SIN: [l0, half, half * sq2, half * sq3, l1],
OP_COS: [l1, half * sq3, half * sq2, half, l0],
OP_TAN: [l0, l1 / 3 * sq3, l1, sq3]
}
def match_standard_radian(node):
"""
Apply a direct constant calculation from the following table.
Apply a direct constant calculation from the constants table.
| 0 | pi / 6 | pi / 4 | pi / 3 | pi / 2
----+---+-----------+-----------+-----------+-------
......@@ -112,5 +147,29 @@ def match_standard_radian(node):
cos | 1 | sqrt(3)/2 | sqrt(2)/2 | 1/2 | 0
tan | 0 | sqrt(3)/3 | 1 | sqrt(3) | -
"""
# TODO: implement
pass
assert node.type == TYPE_OPERATOR and node.op in (OP_SIN, OP_COS, OP_TAN)
t = node[0]
if t == 0:
return [P(node, standard_radian, (node.op, 0))]
denoms = [6, 4, 3]
if node.op != OP_TAN:
denoms.append(2)
for i, denominator in enumerate(denoms):
if is_pi_frac(t, denominator):
return [P(node, standard_radian, (node.op, i + 1))]
return []
def standard_radian(root, args):
op, column = args
return CONSTANTS[op][column].clone()
MESSAGES[standard_radian] = _('Replace standard radian {0}.')
# vim: set fileencoding=utf-8 :
from src.rules.goniometry import match_add_quadrants, add_quadrants, \
match_negated_parameter, negated_sinus_parameter, \
negated_cosinus_parameter, sin, cos
from src.rules.goniometry import sin, cos, tan, match_add_quadrants, \
add_quadrants, match_negated_parameter, negated_sinus_parameter, \
negated_cosinus_parameter, match_standard_radian, standard_radian, \
is_pi_frac
from src.node import PI, OP_SIN, OP_COS, OP_TAN
from src.possibilities import Possibility as P
from tests.rulestestcase import RulesTestCase, tree
from src.rules import goniometry
import doctest
class TestRulesGoniometry(RulesTestCase):
def test_doctest(self):
self.assertEqual(doctest.testmod(m=goniometry)[0], 0)
def test_match_add_quadrants(self):
root = tree('sin t ^ 2 + cos t ^ 2')
possibilities = match_add_quadrants(root)
......@@ -35,3 +42,30 @@ class TestRulesGoniometry(RulesTestCase):
c = tree('cos -t')
t = c[0]
self.assertEqual(negated_cosinus_parameter(c, (t,)), cos(+t))
def test_is_pi_frac(self):
l1, pi = tree('1,' + PI)
self.assertTrue(is_pi_frac(l1 / 2 * pi, 2))
self.assertFalse(is_pi_frac(l1 / 2 * pi, 3))
self.assertFalse(is_pi_frac(l1 * pi, 3))
def test_match_standard_radian(self):
s, c, t = tree('sin(1 / 6 * pi), cos(1 / 2 * pi), tan(0)')
self.assertEqualPos(match_standard_radian(s), \
[P(s, standard_radian, (OP_SIN, 1))])
self.assertEqualPos(match_standard_radian(c), \
[P(c, standard_radian, (OP_COS, 4))])
self.assertEqualPos(match_standard_radian(t), \
[P(t, standard_radian, (OP_TAN, 0))])
def test_standard_radian(self):
l0, l1, sq3, pi6, pi4, pi2 = tree('0,1,sqrt(3),1/6*pi,1/4*pi,1/2*pi')
self.assertEqual(standard_radian(sin(pi6), (OP_SIN, 1)), l1 / 2)
self.assertEqual(standard_radian(sin(pi2), (OP_SIN, 4)), 1)
self.assertEqual(standard_radian(cos(l0), (OP_COS, 0)), 1)
self.assertEqual(standard_radian(tan(pi4), (OP_TAN, 3)), sq3)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment