def _calcMatrixTrans(calc, tS, tT, lS, lT): """ See `calcMatrixTrans()` for the main documentation. This is the lower-level function which is wrapped through `persistent_cache`. This makes the cache more flexible about different parameters `R` to `calcMatrixTrans()`. """ try: ms = calc.calcMatrixTrans(tS, tT, lS, lT) except Exception: print (calc.params, calc.curlS, tS, tT, lS, lT) raise # Each matrix is for a zeta**i factor, where zeta is the n-th root of unity. # And n = calc.matrixCountTrans. assert len(ms) == calc.matrixCountTrans order = len(ms) K = CyclotomicField(order) zeta = K.gen() Kcoords = zeta.coordinates_in_terms_of_powers() assert len(K.power_basis()) == K.degree() new_ms = [matrix(QQ, ms[0].nrows(), ms[0].ncols()) for i in range(K.degree())] for l in range(order): coords = Kcoords(zeta**l) for i,m in enumerate(coords): new_ms[i] += ms[l] * m ms = new_ms denom = calc.matrixRowDenomTrans denom, ms = reduceNRow(denom=denom, mats=ms) return denom, order, ms
def toCyclPowerBase(M, order): """ Let's K = CyclotomicField(order). INPUT: - `M` -- A matrix over the cyclomotic field `K`. - `order` -- The order of `K`, the cyclomotic field. OUTPUT: - A list of matrices `ms` in power base where every matrix is a factor to `zeta**i` where `zeta = K.gen()` and `len(ms) == K.degree()`. """ K = CyclotomicField(order) zeta = K.gen() Kcoords = zeta.coordinates_in_terms_of_powers() assert len(K.power_basis()) == K.degree() ms = [matrix(QQ,M.nrows(),M.ncols()) for i in range(K.degree())] for y in range(M.nrows()): for x in range(M.ncols()): try: v_ = M[y,x] v = K(v_) coords = Kcoords(v) except TypeError: print "type of {1} ({2}) is not valid in Cyclomotic field of order {0}".format(order, M[y,x], type(M[y,x])) raise assert len(coords) == K.degree() for i in range(K.degree()): ms[i][y,x] = coords[i] return ms