Commit 9b96c5aa authored by Cianciosa, Mark's avatar Cianciosa, Mark
Browse files

Reduce cases like (a/b)^c*b^d and it's variants.

parent cfe9453a
Loading
Loading
Loading
Loading
+35 −0
Original line number Diff line number Diff line
@@ -1078,6 +1078,41 @@ namespace graph {
                }
            }

            auto lpd = divide_cast(this->left->get_power_base());
            if (lpd.get()) {
//  (a/b)^c*b^d -> a^c*b^(c-d)
                if (lpd->get_right()->is_power_base_match(this->right)) {
                    return pow(lpd->get_left(), this->left->get_power_exponent()) *
                           pow(this->right->get_power_base(),
                               this->right->get_power_exponent() -
                               this->left->get_power_exponent());
                }
//  (b/a)^c*b^d -> b^(c+d)/a^c
                if (lpd->get_left()->is_power_base_match(this->right)) {
                    return pow(this->right->get_power_base(),
                               this->right->get_power_exponent() +
                               this->left->get_power_exponent()) /
                           pow(lpd->get_right(), this->left->get_power_exponent());
                }
            }
            auto rpd = divide_cast(this->right->get_power_base());
            if (rpd.get()) {
//  b^d*(a/b)^c -> a^c*b^(c-d)
                if (rpd->get_right()->is_power_base_match(this->left)) {
                    return pow(rpd->get_left(), this->right->get_power_exponent()) *
                           pow(this->left->get_power_base(),
                               this->left->get_power_exponent() -
                               this->right->get_power_exponent());
                }
//  b^d*(b/a)^c -> b^(c+d)/a^c
                if (rpd->get_left()->is_power_base_match(this->left)) {
                    return pow(this->right->get_power_base(),
                               this->right->get_power_exponent() +
                               this->right->get_power_exponent()) /
                           pow(rpd->get_right(), this->right->get_power_exponent());
                }
            }

//  Exp(a)*Exp(b) -> Exp(a + b)
            auto le = exp_cast(this->left);
            auto re = exp_cast(this->right);
+15 −0
Original line number Diff line number Diff line
@@ -975,6 +975,21 @@ template<typename T> void test_multiply() {
    assert(graph::pow_cast(common_base_cast4->get_right()).get() &&
           "Expected power cast on the right.");

//  (a/b)^c*b^d -> a^c*b^(c-d)
    auto divide_pow = graph::pow(v2/v1, two)*graph::pow(v1, two);
    assert(divide_pow->is_power_base_match(v2) && "Expected the v2 variable.");
//  (b/a)^c*b^d -> b^(c+d)/a^c
    auto divide_pow2 = graph::pow(v1/v2, two)*graph::pow(v1, two);
    assert(graph::divide_cast(divide_pow2).get() &&
           "Expected a divide node.");
//  b^d*(a/b)^c -> a^c*b^(c-d)
    auto divide_pow3 = graph::pow(v1, two)*graph::pow(v2/v1, two);
    assert(divide_pow3->is_power_base_match(v2) && "Expected the v2 variable.");
//  b^d*(b/a)^c -> b^(c+d)/a^c
    auto divide_pow4 = graph::pow(v1, two)*graph::pow(v1/v2, two);
    assert(graph::divide_cast(divide_pow4).get() &&
           "Expected a divide node.");

//  Test node properties.
    assert(two_times_three->is_constant_like() && "Expected a constant.");
    assert(!two_times_three->is_all_variables() && "Did not expect a variable.");