def mk_in_space_conditions(space,var_vector): # print "mk_in_space_conditions" # print space # print var_vector basis_matrix = space.matrix().transpose().apply_map(lambda x:QQbar(x).radical_expression()) vec_len,coeff_count = basis_matrix.dimensions() coeffs = MX.mk_symbol_vector(coeff_count,'c'); # print "mk_in_space_condition:", coeff_count, coeffs, vec_len # print basis_matrix #for i in range(coeff_count): # assume(coeffs[0][i],'rational') if coeff_count == 0: # if the space is empty return ([0 != 0],coeffs.list(),var_vector.list()) lhs1 = MX.linear_combination_of(coeffs,basis_matrix).list() lhs2 = var_vector.list() # print "lhs2",lhs2 # print "lhs1",lhs1 conds=map(lambda tup: tup[0] - tup[1] == 0,zip(lhs1,lhs2)) return (conds,coeffs.list(),var_vector.list())
def find_reduction_of_matrix(matrix,subspace): def gen_vars(d): alphas=[] betas=[] for i in range(d): alphas.append(var("a_"+str(i),latex_name="\\alpha_"+str(i))) betas.append(var("b_"+str(i),latex_name="\\beta_"+str(i))) return (alphas,betas) subspace_basis=subspace.matrix().transpose() dims=subspace_basis.dimensions() alphas,betas = gen_vars(dims[1]) # generate variables for each columns alpha_lin=MX.linear_combination_of(vector(alphas),subspace_basis) beta_lin=MX.linear_combination_of(vector(betas),subspace_basis) # print "find_reduction_of_matrix" # print "- matrix:" # print matrix # print "- subspace:" # print subspace # print "- alpha_lin:" # print alpha_lin # print "- beta_lin:" # print beta_lin #deprecated code # nbetas = (matrix * alpha_lin).list() # print "- nbetas:" # print nbetas vec_lhs = matrix * alpha_lin vec_rhs = beta_lin conditions=[] for r in range(dims[0]): conditions.append(vec_lhs[r] - vec_rhs[r] == 0) # print conditions sol_dict=solve(conditions,betas,solution_dict=True)[0] nbetas=map(lambda x:x.substitute(sol_dict),betas) # print "- nbetas:" # print nbetas red_mx_s=MX.mk_symbol_matrix(dims[1],dims[1],"A") # reduced symbolic matrix # print "- red_mx_s:" # print red_mx_s red_mx_vars=red_mx_s.list() lhs = red_mx_s * vector(alphas) rhs = nbetas conditions=map(lambda i: lhs[i] - rhs[i] == 0,range(dims[1])) # print "- conditions" # print conditions sol_dict=solve(conditions,red_mx_vars,solution_dict=True)[0] # print "- sol_dict" # print sol_dict allvars=set.union(*map(lambda x:set(x.variables()),sol_dict.values())) # print "- allvars" # print allvars fvars=allvars.difference(set(alphas)) # print "- fvars" # print fvars var_dict= dict(zip(fvars,[1]*len(fvars)) + zip(alphas,[1]*len(alphas))) # print "- var_dict" # print var_dict nsol_dict= dict(map(lambda x:(x[0],x[1].substitute(var_dict)),sol_dict.items())) # print "- nsol_dict" # print nsol_dict # print nsol_dict red_mx_n= red_mx_s.apply_map(lambda x:x.substitute(nsol_dict)) # print "end" return (red_mx_n,alphas,alpha_lin)
def find_Q_min(S_min,space_exts): def solve_for_one_nonzero_variable(conditions,vars): conds=[] for var in vars: conds.append(conditions+[var != 0]) #print conds solutions=SE.solve_ext(conds,*vars) return solutions def gen_vars(col_count,exts): vardict=dict() vars=[] for c in range(col_count): vardict[c]=dict() for e_id in range(len(exts)): v=var("v_c"+str(c)+"_e"+str(e_id)) vardict[c][exts[e_id]]=v vars.append(v) assume(v,'rational') return vardict,vars def solution_to_coefficients(solution,vardict,vars): idict=dict() for eq in solution: for v in vars: if eq.operator() == operator.eq: if eq.lhs() == v: idict[v]=eq.rhs() if eq.rhs() == v: idict[v]=eq.lhs() if eq.operator() == operator.ne: if (eq.lhs() == v and eq.rhs() == 0) or (eq.rhs() == v and eq.lhs() == 0): idict[v] = SR(1) idict = dict(map(lambda x:(x[0],x[1].substitute(idict)),idict.items())) # maybe mor than one subtitution step is needed coeffs=[] for c in vardict.keys(): coeff=0 for ext in vardict[c].keys(): v = vardict[c][ext] if not idict.has_key(v): idict[v]=0 coeff = coeff + idict[v]*ext.radical_expression() coeffs.append(coeff) # print "idict",idict return coeffs S_min_matrix = S_min.matrix().transpose() dims = S_min_matrix.dimensions() vecs = S_min_matrix.columns() exts = map(abs,[AA(1)]+space_exts) # it does not suffice to take the space extension of S_min # print exts conditions=[] vardict,vars=gen_vars(dims[1],exts) for r in range(dims[0]): #print "row", S_min_matrix.row(r) d=dict() for c in range(dims[1]): for e_id in range(len(exts)): num_part=QQbar(S_min_matrix[r,c])*exts[e_id] nf_gens=QQbar(num_part).as_number_field_element()[2].im_gens() # print "np:",vardict[c][exts[e_id]],num_part,nf_gens signf=1 if QQbar(num_part) < 0: signf = -1 for gen in nf_gens: #v=var("v_c"+str(c)+"_e"+str(e_id)) v=vardict[c][exts[e_id]] k=abs(gen) # only use positive extensions as key if d.has_key(k): d[k].append(signf*v) else: d[k] = [signf*v] # print "d:",d for ext in d.keys(): #print ext,ext != 1 if ext != 1: conditions.append(sum(d[ext]) == 0) # print "basic conditions", conditions # print vardict # print vars solutions= solve_for_one_nonzero_variable(conditions,vars) # find as many possible solutions to get all vectors of Q_min # print solutions # reduce to real solutions not containing 0 != 0 solutions= SE.solve_ext(solutions,vars) # print solutions forget() # forget that the variables are rational coeffs=map(lambda s: solution_to_coefficients(s,vardict,vars),solutions) # print "coeffs",coeffs vecs=map(lambda v:MX.linear_combination_of(vector(v),S_min_matrix),coeffs) # print vecs V=VectorSpace(QQ,S_min.degree()) Q_min=V.span(vecs) return Q_min