Loading graph_framework/arithmetic.hpp +35 −0 Original line number Diff line number Diff line Loading @@ -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); Loading graph_tests/arithmetic_test.cpp +15 −0 Original line number Diff line number Diff line Loading @@ -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."); Loading Loading
graph_framework/arithmetic.hpp +35 −0 Original line number Diff line number Diff line Loading @@ -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); Loading
graph_tests/arithmetic_test.cpp +15 −0 Original line number Diff line number Diff line Loading @@ -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."); Loading