def test_fraction_in_division(self): root, expected = tree('(1 / a * b) / c, b / (ac)') self.assertEqual( fraction_in_division(root, (True, Scope(root[0]), root[0][0])), expected) root, expected = tree('c / (1 / a * b), (ac) / b') self.assertEqual( fraction_in_division(root, (False, Scope(root[1]), root[1][0])), expected) root, expected = tree('c / (-(1 / a) * b), (ac) / ((-1)b)') self.assertEqual( fraction_in_division(root, (False, Scope(root[1]), root[1][0])), expected) root, expected = tree('c / ((-1) / a * b), (ac) / ((-1)b)') self.assertEqual( fraction_in_division(root, (False, Scope(root[1]), root[1][0])), expected) root, expected = tree('c / (1 / (-a) * b), ((-a)c) / b') self.assertEqual( fraction_in_division(root, (False, Scope(root[1]), root[1][0])), expected)
def test_match_add_logarithms(self): root = tree('log a + ln b') self.assertEqualPos(match_add_logarithms(root), []) # log(ab) is not desired if ab is not reduceable root = tree('log a + log b') self.assertEqualPos(match_add_logarithms(root), []) log_a, log_b = root = tree('log 2 + log 3') self.assertEqualPos(match_add_logarithms(root), [P(root, add_logarithms, (Scope(root), log_a, log_b))]) log_a, log_b = root = tree('-log 2 - log 3') self.assertEqualPos(match_add_logarithms(root), [P(root, expand_negations, (Scope(root), log_a, log_b))]) # log(2 / 3) is not desired because 2 / 3 cannot be reduced log_a, log_b = root = tree('log 2 - log 3') self.assertEqualPos(match_add_logarithms(root), []) log_a, log_b = root = tree('log 4 - log 2') self.assertEqualPos(match_add_logarithms(root), [P(root, subtract_logarithms, (Scope(root), log_a, log_b))]) log_a, log_b = root = tree('-log 2 + log 4') self.assertEqualPos(match_add_logarithms(root), [P(root, subtract_logarithms, (Scope(root), log_b, log_a))])
def test_negated_factor(self): a, b = root = tree('a * -b') self.assertEqual(negated_factor(root, (Scope(root), b)), -(a * +b)) (a, b), c = root = tree('a * (-b) * -c') self.assertEqual(negated_factor(root, (Scope(root), b)), -(a * +b * c)) self.assertEqual(negated_factor(root, (Scope(root), c)), -(a * b * +c))
def test_find_possibilities_sort(self): (ab, cd), e = root = tree('(a + b)(c + d)e') self.assertEqualPos(find_possibilities(root), [ P(root, expand_single, (Scope(root), cd, e)), P(root, expand_single, (Scope(root), ab, e)), P(root, expand_double, (Scope(root), ab, cd)) ])
def test_add_quadrants(self): s, c = root = tree('sin(t) ^ 2 + cos(t) ^ 2') self.assertEqual(add_quadrants(root, (Scope(root), s, c)), 1) root, expect = tree('cos(t) ^ 2 + a + sin(t) ^ 2, a + 1') (c, a), s = root self.assertEqual(add_quadrants(root, (Scope(root), s, c)), expect)
def test_match_multiply_one(self): l1, x = root = tree('1x') self.assertEqual(match_multiply_numerics(root), [P(root, multiply_one, (Scope(root), l1))]) (x, l1), x = root = tree('x * 1x') self.assertEqual(match_multiply_numerics(root), [P(root, multiply_one, (Scope(root), l1))])
def test_sum_rule_integral(self): ((f, g), h), x = root = tree('int (2x + 3x + 4x) dx') self.assertEqual(sum_rule_integral(root, (Scope(root[0]), f)), tree('int 2x dx + int (3x + 4x) dx')) self.assertEqual(sum_rule_integral(root, (Scope(root[0]), g)), tree('int 3x dx + int (2x + 4x) dx')) self.assertEqual(sum_rule_integral(root, (Scope(root[0]), h)), tree('int 4x dx + int (2x + 3x) dx'))
def test_multiply_fractions(self): (a, b), (c, d) = ab, cd = root = tree('a / b * (c / d)') self.assertEqual(multiply_fractions(root, (Scope(root), ab, cd)), a * c / (b * d)) (ab, e), cd = root = tree('a / b * e * (c / d)') self.assertEqual(multiply_fractions(root, (Scope(root), ab, cd)), a * c / (b * d) * e)
def test_match_add_exponents_multiple_identifiers(self): a, b, p, q = tree('a,b,p,q') ((a0, b0), a1), b1 = root = a**p * b**p * a**q * b**q possibilities = match_add_exponents(root) self.assertEqualPos(possibilities, [ P(root, add_exponents, (Scope(root), a0, a1, a, p, q)), P(root, add_exponents, (Scope(root), b0, b1, b, p, q)) ])
def test_match_const_deriv_multiplication(self): root = tree('d/dx 2x') l2, x = root[0] self.assertEqualPos(match_const_deriv_multiplication(root), [P(root, const_deriv_multiplication, (Scope(root[0]), l2, x))]) (x, y), x = root = tree('d/dx xy') self.assertEqualPos(match_const_deriv_multiplication(root), [P(root, const_deriv_multiplication, (Scope(root[0]), y, x))])
def test_match_combine_groups_n_const(self): ((l2, a0), (l3, a1)), (l4, a2) = (m0, m1), m2 = root = tree('2a+3a+4a') possibilities = match_combine_groups(root) self.assertEqualPos(possibilities, [ P(root, combine_groups, (Scope(root), l2, a0, m0, l3, a1, m1)), P(root, combine_groups, (Scope(root), l2, a0, m0, l4, a2, m2)), P(root, combine_groups, (Scope(root), l3, a1, m1, l4, a2, m2)) ])
def test_subtract_logarithms(self): root, expect = tree('log(a) - log(b), log(a / b)') loga, logb = root self.assertEqual(subtract_logarithms(root, (Scope(root), loga, logb)), expect) root, expect = tree('-log(a) + log(b), log(b / a)') loga, logb = root self.assertEqual(subtract_logarithms(root, (Scope(root), logb, loga)), expect)
def test_match_add_numerics(self): l1, l2 = root = tree('1 + 2') possibilities = match_add_numerics(root) self.assertEqualPos(possibilities, [P(root, add_numerics, (Scope(root), l1, l2))]) (l1, b), l2 = root = tree('1 + b + 2') possibilities = match_add_numerics(root) self.assertEqualPos(possibilities, [P(root, add_numerics, (Scope(root), l1, l2))])
def test_sum_rule(self): root = tree('(x ^ 2 + x)\'') x2, x = f = root[0] self.assertEqual(sum_rule(root, (Scope(f), x2)), der(x2) + der(x)) self.assertEqual(sum_rule(root, (Scope(f), x)), der(x) + der(x2)) root = tree('(x ^ 2 + 3 + x)\'') (x2, l3), x = f = root[0] self.assertEqual(sum_rule(root, (Scope(f), x2)), der(x2) + der(l3 + x)) self.assertEqual(sum_rule(root, (Scope(f), x)), der(x) + der(x2 + l3))
def test_match_add_exponents_ternary(self): a, p, q, r = tree('a,p,q,r') (n0, n1), n2 = root = a**p * a**q * a**r possibilities = match_add_exponents(root) self.assertEqualPos(possibilities, [ P(root, add_exponents, (Scope(root), n0, n1, a, p, q)), P(root, add_exponents, (Scope(root), n0, n2, a, p, r)), P(root, add_exponents, (Scope(root), n1, n2, a, q, r)) ])
def test_expand_single(self): root, expect = tree('a(b + c), ab + ac') a, bc = root self.assertEqualNodes(expand_single(root, (Scope(root), a, bc)), expect) root, expect = tree('a(b+c)d, a(bd + cd)') (a, bc), d = root self.assertEqualNodes(expand_single(root, (Scope(root), bc, d)), expect)
def test_match_sum_product_rule_sum(self): root = tree('d/dx (x ^ 2 + x)') x2, x = f = root[0] self.assertEqualPos(match_sum_product_rule(root), [P(root, sum_rule, (Scope(f), x2)), P(root, sum_rule, (Scope(f), x))]) root = tree('d/dx (x ^ 2 + 3 + x)') self.assertEqualPos(match_sum_product_rule(root), [P(root, sum_rule, (Scope(root[0]), x2)), P(root, sum_rule, (Scope(root[0]), x))])
def test_match_negated_factor(self): a, b = root = tree('a * -b') self.assertEqualPos(match_negated_factor(root), [P(root, negated_factor, (Scope(root), b))]) (a, b), c = root = tree('a * (-b) * -c') scope = Scope(root) self.assertEqualPos(match_negated_factor(root), [ P(root, negated_factor, (scope, b)), P(root, negated_factor, (scope, c)) ])
def test_match_sum_rule_integral(self): (f, g), x = root = tree('int (2x + 3x) dx') self.assertEqualPos(match_sum_rule_integral(root), [P(root, sum_rule_integral, (Scope(root[0]), f))]) ((f, g), h), x = root = tree('int (2x + 3x + 4x) dx') self.assertEqualPos(match_sum_rule_integral(root), [ P(root, sum_rule_integral, (Scope(root[0]), f)), P(root, sum_rule_integral, (Scope(root[0]), g)), P(root, sum_rule_integral, (Scope(root[0]), h)) ])
def test_factor_out_abs_term(self): root, expect = tree('|abc|, |a||bc|') (((a, b), c), ) = (abc, ) = root self.assertEqual(factor_out_abs_term(root, (Scope(abc), a)), expect) root, expect = tree('|abc|, |b||ac|') (((a, b), c), ) = (abc, ) = root self.assertEqual(factor_out_abs_term(root, (Scope(abc), b)), expect) root, expect = tree('-|abc|, -|a||bc|') (((a, b), c), ) = (abc, ) = root self.assertEqual(factor_out_abs_term(root, (Scope(abc), a)), expect)
def test_expand_double(self): (a, b), (c, d) = ab, cd = tree('a + b,c + d') root, expect = tree('(a + b)(c + d), ac + ad + bc + bd') ab, cd = root self.assertEqualNodes(expand_double(root, (Scope(root), ab, cd)), expect) root, expect = tree('a(a + b)b(c + d)c, a(ac + ad + bc + bd)bc') (((a, ab), b), cd), c = root self.assertEqualNodes(expand_double(root, (Scope(root), ab, cd)), expect)
def test_match_reduce_sqrt_mult(self): ((l2, x), ) = root = tree('sqrt(2x)') self.assertEqualPos(match_reduce_sqrt(root), [ P(root, extract_sqrt_multiplicant, (Scope(root[0]), l2)), P(root, extract_sqrt_multiplicant, (Scope(root[0]), x)) ]) (((l2, x), y), ) = root = tree('sqrt(2xy)') self.assertEqualPos(match_reduce_sqrt(root), [ P(root, extract_sqrt_multiplicant, (Scope(root[0]), l2)), P(root, extract_sqrt_multiplicant, (Scope(root[0]), x)), P(root, extract_sqrt_multiplicant, (Scope(root[0]), y)) ])
def test_match_factor_out_abs_term_mult(self): ((a, b), ) = (ab, ) = root = tree('|ab|') self.assertEqualPos(match_factor_out_abs_term(root), [ P(root, factor_out_abs_term, (Scope(ab), a)), P(root, factor_out_abs_term, (Scope(ab), b)) ]) (((a, b), c), ) = (abc, ) = root = tree('|abc|') self.assertEqualPos(match_factor_out_abs_term(root), [ P(root, factor_out_abs_term, (Scope(abc), a)), P(root, factor_out_abs_term, (Scope(abc), b)), P(root, factor_out_abs_term, (Scope(abc), c)) ])
def test_match_expand(self): a, bc, d = tree('a,b + c,d') b, c = bc root = a * bc self.assertEqualPos(match_expand(root), [P(root, expand_single, (Scope(root), a, bc))]) root = bc * a self.assertEqualPos(match_expand(root), [P(root, expand_single, (Scope(root), bc, a))]) root = a * bc * d self.assertEqualPos(match_expand(root), [ P(root, expand_single, (Scope(root), a, bc)), P(root, expand_single, (Scope(root), bc, d)) ]) ab, cd = root = (a + b) * (c + d) self.assertEqualPos(match_expand(root), [P(root, expand_double, (Scope(root), ab, cd))]) (ab, cd), e = root = tree('(a + b)(c + d)e') self.assertEqualPos(match_expand(root), [ P(root, expand_double, (Scope(root), ab, cd)), P(root, expand_single, (Scope(root), cd, e)), P(root, expand_single, (Scope(root), ab, e)) ])
def test_extract_fraction_terms_leaf(self): root, expect = tree('(ba) / a, a / a * b / 1') n, d = root self.assertEqual( extract_fraction_terms(root, (Scope(n), Scope(N(OP_MUL, d)), n[1], d)), expect) root, expect = tree('a / (ab), a / a * 1 / b') n, d = root self.assertEqual( extract_fraction_terms(root, (Scope(N(OP_MUL, n)), Scope(d), n, d[0])), expect)
def test_multiply_numerics(self): a, b, i2, i3, i6, f2, f3, f6 = tree('a,b,2,3,6,2.0,3.0,6.0') i3, i2 = root = tree('3 * 2') self.assertEqual(multiply_numerics(root, (Scope(root), i3, i2)), 6) f3, i2 = root = tree('3.0 * 2') self.assertEqual(multiply_numerics(root, (Scope(root), f3, i2)), 6.0) i3, f2 = root = tree('3 * 2.0') self.assertEqual(multiply_numerics(root, (Scope(root), i3, f2)), 6.0) f3, f2 = root = tree('3.0 * 2.0') self.assertEqual(multiply_numerics(root, (Scope(root), f3, f2)), 6.0) ((a, i3), i2), b = root = tree('a * 3 * 2 * b') self.assertEqualNodes(multiply_numerics(root, (Scope(root), i3, i2)), a * 6 * b)
def test_match_factor_in_multiplicant(self): (l2, log_3) = root = tree('2log(3)') self.assertEqualPos(match_factor_in_multiplicant(root), [P(root, factor_in_multiplicant, (Scope(root), l2, log_3))]) (l2, log_3), l4 = root = tree('2log(3)4') self.assertEqualPos(match_factor_in_multiplicant(root), [P(root, factor_in_multiplicant, (Scope(root), l2, log_3)), P(root, factor_in_multiplicant, (Scope(root), l4, log_3))]) root = tree('2log(a)') self.assertEqualPos(match_factor_in_multiplicant(root), []) root = tree('alog(3)') self.assertEqualPos(match_factor_in_multiplicant(root), [])
def test_combine_groups_simple(self): root, l1 = tree('a + a,1') a0, a1 = root self.assertEqualNodes( combine_groups(root, (Scope(root), l1, a0, a0, l1, a1, a1)), (l1 + 1) * a0)
def test_match_combine_groups_two_const(self): ((l2, a0), b), (l3, a1) = (m0, b), m1 = root = tree('2a + b + 3a') possibilities = match_combine_groups(root) self.assertEqualPos( possibilities, [P(root, combine_groups, (Scope(root), l2, a0, m0, l3, a1, m1))])
def test_combine_groups_nary(self): root, l1 = tree('ab + b + ba,1') abb, ba = root ab, b = abb self.assertEqualNodes( combine_groups(root, (Scope(root), l1, ab, ab, l1, ba, ba)), (l1 + 1) * ab + b)