def get_common_fact(expr):
    if is_sum(expr):
        sumlen = len(expr) - 1
        div = get_mult(expr[1])
        for i in range(1, sumlen):
            if div == 1:
                break
            div = gcd(div, get_mult(expr[i + 1]))
        return div
    elif is_radical(expr):
        return abs(expr[4])
    elif type(expr) == int:
        return abs(expr)
    elif type(expr) == tuple:
        return get_common_fact(expr[0])
def esimplify(expr):
    if type(expr) != tuple:
        raise RuntimeError(
            "Only fractions can be simplified with esimplify().")
    ans = None  # this line indicates that the variable ans is used after the conditionals but only defined inside them.
    if type(expr[0]) == int:
        div = gcd(*expr)
        ans = (expr[0] // div, expr[1] // div)
    elif is_radical(expr[0]):
        div = gcd(expr[0][4], expr[1])
        expr[0][4] //= div
        ans = (expr[0], expr[1] // div)
    elif is_sum(expr[0]):
        div = get_common_fact(expr[0])
        div = gcd(div, expr[1])
        if div == 1:
            return expr
        ans_num = edivout(expr[0], div)
        ans_denom = expr[1] // div
        ans = (ans_num, ans_denom)
    if ans[1] == 1:
        return ans[0]
    else:
        return ans
Esempio n. 3
0
def juggling(d, ar=None):
    '''
    src: 
    https://stackoverflow.com/questions/23321216/rotating-an-array-using-juggling-algorithm
    '''
    l = len(ar)
    g = gcd(d, l)
    for i in xrange(g):
        prev = i
        t = ar[i]
        walk = (i + d) % l
        while walk != i:
            ar[prev] = ar[walk]
            prev = walk
            walk = (walk + d) % l
        ar[(walk - d) % l] = t
Esempio n. 4
0
# import custom.my_math # this works

print("Module path patching...")
# alter pathes to be able to load custom module
import math
custom_module_path = os.path.join(os.getcwd(), "custom")
# os.path.abspath(os.path.dirname(__file__))
module_pathes.insert(0, custom_module_path)

import my_math
print("Python: D'oh, now I see my_math...")

print(" 9 / 5 to upper =", my_math.div_ceil(9, 5))

from my_math import sqrt
from math import sqrt

print("(my_math, math) Sqrt: ", sqrt(9))

from my_math import sqrt

print("(my_math, math, my_math) Sqrt: ", sqrt(9))

from my_math import gcd

print("gcd(21, 14) == ", gcd(21, 14))

# As your can see -- last import "wins" in case of name clashing.
# NB: if you try to rename my_math module to math to completely full python
#     if wouldn't work, since looks like math is one of buildins modules
 def simplify(self):
     g = gcd(self.n, self.d)
     self.n //= g
     self.d //= g
 def simplify(self):
     g = gcd(self.n, self.d)
     self.n //= g
     self.d //= g
Esempio n. 7
0
# import custom.my_math # this works

print("Module path patching...")
# alter pathes to be able to load custom module
import math
custom_module_path = os.path.join(os.getcwd(), "custom")
# os.path.abspath(os.path.dirname(__file__))
module_pathes.insert(0, custom_module_path)

import my_math
print("Python: D'oh, now I see my_math...")

print(" 9 / 5 to upper =", my_math.div_ceil(9, 5))

from my_math import sqrt
from math import sqrt

print("(my_math, math) Sqrt: ", sqrt(9))

from my_math import sqrt

print("(my_math, math, my_math) Sqrt: ", sqrt(9))

from my_math import gcd

print("gcd(21, 14) == ", gcd(21, 14))

# As your can see -- last import "wins" in case of name clashing.
# NB: if you try to rename my_math module to math to completely full python
#     if wouldn't work, since looks like math is one of buildins modules
def etimes(e1, e2):
    if type(e1) == int:
        if e1 == 0:
            return 0
        elif e1 == 1:
            return e2
    if type(e2) == int:
        if e2 == 0:
            return 0
        elif e2 == 1:
            return e1

    if type(e1) == int:
        if type(e2) == int:
            return e1 * e2
        if type(e2) == tuple:
            div = gcd(e1, e2[1])
            mult = e1 // div
            ans = (etimes(mult, e2[0]), e2[1] // div)
            if ans[1] == 1:
                return ans[0]
            else:
                return ans
        if is_sum(e2):
            terms = e2[1:]
            ans_terms = [etimes(e1, term) for term in terms]
            ans = ['+'] + ans_terms
            ans = remove_nested_sums(ans)
            return ans
        if is_radical(e2):
            if e1 >= 0:
                # this whole if statement should be commented out for the 23rd roots of unity
                if type(e2[3]) == tuple:
                    if gcd(e1, e2[3][1]) > 1:
                        degree = e2[1]
                        which = e2[2]
                        radicand = e2[3]
                        rad_mult = e2[4]
                        mult = e1**degree
                        div = gcd(mult, radicand[1])
                        num = etimes(mult, radicand[0])
                        effective_num = mult // div
                        lpd = largest_power_divisor(effective_num, degree)
                        num = edivout(num, lpd**degree)
                        radicand = esimplify((num, radicand[1]))
                        rad_mult *= lpd
                        return ['r', degree, which, radicand, rad_mult]
                ans = copy(e2)
                ans[4] *= e1
                return ans
            else:
                degree = e2[1]
                ans = copy(e2)
                if degree == 2:
                    ans[2] = (ans[2] + 1) % 2
                    return etimes(-e1, ans)
                else:
                    ans[3] = etimes(-1, ans[3])
                    # make sure the right nth root is picked
                    root_found = False
                    for i in range(degree):
                        if not float_equal(-expr_to_float(e2),
                                           expr_to_float(ans)):
                            ans[2] = (ans[2] + 1) % degree
                        else:
                            root_found = True
                            break
                    if not root_found:
                        print(
                            "Warning: e1 * e2 == {} and ans^{} == {}, but cannot find right root to make -e2 == ans."
                            .format(
                                expr_to_float(e1) * expr_to_float(e2), degree,
                                expr_to_float(ans[3])))
                    return etimes(-e1, ans)
                # I'm sure this code is all really nice but there's a way more convenient way to do it I just wasn't thinking of
                '''degree = e2[1]
                init_term = copy(e2)
                init_term[4] *= -e1
                ans_terms = [copy(init_term) for i in range(1, degree)]
                i = 1
                for term in ans_terms:
                    term[2] = (term[2] + i) % degree
                    i += 1
                if len(ans_terms) == 1:
                    return ans_terms[0]
                return ['+'] + ans_terms'''
    if type(e1) == tuple:
        if type(e2) == int:
            div = gcd(e2, e1[1])
            mult = e2 // div
            ans = (etimes(mult, e1[0]), e1[1] // div)
            if ans[1] == 1:
                return ans[0]
            else:
                return ans
        if type(e2) == tuple:
            ans = (etimes(e1[0], e2[0]), e1[1] * e2[1])
            ans = esimplify(ans)
            return ans
        if is_radical(e2):
            ans_num = etimes(e1[0], e2)
            ans = (ans_num, e1[1])
            ans = esimplify(ans)
            return ans
    if is_sum(e1):
        if type(e2) == int:
            terms = e1[1:]
            ans_terms = [etimes(term, e2) for term in terms]
            ans = ['+'] + ans_terms
            ans = remove_nested_sums(ans)
            return ans
        if type(e2) == tuple:
            ans_num = etimes(e1, e2[0])
            ans = (ans_num, e2[1])
            ans = esimplify(ans)
            return ans
        if is_sum(e2):
            terms = e1[1:]
            ans_terms = [etimes(term, e2) for term in terms]
            ans = esumlist(ans_terms)
            return ans
        if is_radical(e2):
            terms = e1[1:]
            ans_terms = [etimes(term, e2) for term in terms]
            ans = esumlist(ans_terms)
            return ans
    if is_radical(e1):
        if type(e2) == int:
            return etimes(e2, e1)
        if is_sum(e2):
            terms = e2[1:]
            ans_terms = [etimes(e1, term) for term in terms]
            ans = esumlist(ans_terms)
            return ans
        if is_radical(e2):
            if e1[1] == e2[1]:
                degree = e1[1]
                ans_radicand = etimes(e1[3], e2[3])
                ans = eroot(ans_radicand, degree)
                ans = etimes(ans, e1[4] * e2[4])
                '''if not float_equal(expr_to_float(e1) * expr_to_float(e2), expr_to_float(ans)):
                    print("Warning: e1 * e2 == {} while ans == {}. Maybe the wrong root was picked.".format(expr_to_float(e1) * expr_to_float(e2), expr_to_float(ans)))'''
                if is_radical(ans):
                    for i in range(degree):
                        ans[2] = i
                        if float_equal(
                                expr_to_float(e1) * expr_to_float(e2),
                                expr_to_float(ans)):
                            return ans
                    raise RuntimeError(
                        "Unable to resolve expression. etimes({}, {})".format(
                            e1, e2))
                elif degree == 2:
                    if float_equal(
                            expr_to_float(e1) * expr_to_float(e2),
                            expr_to_float(ans)):
                        return ans
                    ans = etimes(ans, -1)
                    if float_equal(
                            expr_to_float(e1) * expr_to_float(e2),
                            expr_to_float(ans)):
                        return ans
                    raise RuntimeError(
                        "Unable to resolve expression. etimes({}, {})".format(
                            e1, e2))
                else:
                    raise RuntimeError(
                        "Multiplication of two nth roots resulting in a rational value times nth root of unity is currently only implemented for n == 2"
                    )
            elif e1[1] > e2[1]:
                degree = e1[1]
                mult = e1[4]
                radicand = etimes(e1[3], epower(e2, degree))
                # to do: ans = eroot(radicand, degree) and multiply by mult
                ans = ['r', degree, 0, radicand, mult]
                for i in range(degree):
                    ans[2] = i
                    if float_equal(
                            expr_to_float(e1) * expr_to_float(e2),
                            expr_to_float(ans)):
                        return ans
                print("supposed value of ans: {}".format(ans))
                raise RuntimeError(
                    "Unable to resolve expression. etimes({}, {})".format(
                        e1, e2))
            else:
                return etimes(e2, e1)

    raise RuntimeError("Not implemented yet. etimes({}, {})".format(e1, e2))