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
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
# 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 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))