Advertisement
Guest User

Untitled

a guest
Jan 18th, 2020
76
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.67 KB | None | 0 0
  1. from fractions import Fraction
  2.  
  3. def gcd(x, y):
  4.     def gcd1(x, y):
  5.         if y == 0:
  6.             return x
  7.         return gcd1(y, x%y)
  8.     return gcd1(abs(x), abs(y))
  9.  
  10. def simplify(x, y):
  11.     g = gcd(x, y)
  12.     return Fraction(long(x/g), long(y/g))
  13.  
  14. def lcm(x, y):
  15.     return long(x*y/gcd(x,y))
  16.  
  17. def transform(m):
  18.     sum_list = list(map(sum, m))
  19.     bool_indices = list(map(lambda x: x == 0, sum_list))
  20.     indices = set([i for i, x in enumerate(bool_indices) if x])
  21.     new_m = []
  22.     for i in xrange(len(m)):
  23.         new_m.append(list(map(lambda x: Fraction(0, 1) if(sum_list[i] == 0) else simplify(x, sum_list[i]), m[i])))
  24.     transform_m = []
  25.     zeros_m = []
  26.     for i in xrange(len(new_m)):
  27.         if i not in indices:
  28.             transform_m.append(new_m[i])
  29.         else:
  30.             zeros_m.append(new_m[i])
  31.     transform_m.extend(zeros_m)
  32.     t_m = []
  33.     for i in xrange(len(transform_m)):
  34.         t_m.append([])
  35.         extend_m = []
  36.         for j in xrange(len(transform_m)):
  37.             if j not in indices:
  38.                 t_m[i].append(transform_m[i][j])
  39.             else:
  40.                 extend_m.append(transform_m[i][j])
  41.         t_m[i].extend(extend_m)
  42.     return [t_m, len(zeros_m)]
  43.  
  44. def copy(m):
  45.     c_m = []
  46.     for i in xrange(len(m)):
  47.         c_m.append([])
  48.         for j in xrange(len(m[i])):
  49.             c_m[i].append(Fraction(m[i][j].numerator, m[i][j].denominator))
  50.     return c_m
  51.  
  52. def gauss_elmination(initial, values):
  53.     m = copy(initial)
  54.     for i in xrange(len(m)):
  55.         index = -1
  56.         for j in xrange(i, len(m)):
  57.             if m[j][i].numerator != 0:
  58.                 index = j
  59.                 break
  60.         if index == -1:
  61.             raise ValueError('Gauss elimination failed!')
  62.         m[i], m[index] = m[index], m[j]
  63.         values[i], values[index] = values[index], values[i]
  64.         for j in xrange(i+1, len(m)):
  65.             if m[j][i].numerator == 0:
  66.                 continue
  67.             ratio = -m[j][i]/m[i][i]
  68.             for k in xrange(i, len(m)):
  69.                 m[j][k] += ratio * m[i][k]
  70.             values[j] += ratio * values[i]
  71.     res = [0 for i in xrange(len(m))]
  72.     for i in xrange(len(m)):
  73.         index = len(m) -1 -i
  74.         end = len(m) - 1
  75.         while end > index:
  76.             values[index] -= m[index][end] * res[end]
  77.             end -= 1
  78.         res[index] = values[index]/m[index][index]
  79.     return res
  80.  
  81. def transpose(m):
  82.     t_m = []
  83.     for i in xrange(len(m)):
  84.         for j in xrange(len(m)):
  85.             if i == 0:
  86.                 t_m.append([])
  87.             t_m[j].append(m[i][j])
  88.     return t_m
  89.  
  90. def inverse(m):
  91.     t_m = transpose(m)
  92.     m_inv = []
  93.     for i in xrange(len(t_m)):
  94.         values = [Fraction(int(i==j), 1) for j in xrange(len(m))]
  95.         m_inv.append(gauss_elmination(t_m, values))
  96.     return m_inv
  97.  
  98. def mult(m1, m2):
  99.     res = []
  100.     for i in xrange(len(m1)):
  101.         res.append([])
  102.         for j in xrange(len(m2[0])):
  103.             res[i].append(Fraction(0, 1))
  104.             for k in xrange(len(m1[0])):
  105.                 res[i][j] += m1[i][k] * m2[k][j]
  106.     return res
  107.  
  108. def split(m, lengthR):
  109.     lengthQ = len(m) - lengthR
  110.     Q = []
  111.     R = []
  112.     for i in xrange(lengthQ):
  113.         Q.append([int(i==j)-m[i][j] for j in xrange(lengthQ)])
  114.         R.append(m[i][lengthQ:])
  115.     return [Q, R]
  116.  
  117. def solution(m):
  118.     res = transform(m)
  119.     if res[1] == len(m):
  120.         return [1, 1]
  121.     Q, R = split(*res)
  122.     inv = inverse(Q)
  123.     res = mult(inv, R)
  124.     row = res[0]
  125.     l = 1
  126.     for item in row:
  127.         l = lcm(l, item.denominator)
  128.     res = list(map(lambda x: long(x.numerator*l/x.denominator), row))
  129.     res.append(l)
  130.     return res
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement