Esempio n. 1
0
def termination_check(matrix_A,matrix_B_s,matrix_B_w,show_time):
    t=take_time.TakeTime()

    mA   = matrix_A
    mB_s = matrix_B_s
    mB_w = matrix_B_w

    zvec = MX.mk_symbol_vector(mA.dimensions()[0],"z").transpose()
    t.print_tdiff("0",show_time)
    #########################################################
    # 1. compute JNF
    (mD,mP) = mA.jordan_form(QQbar,transformation=true)
    mPi = mP.inverse()

    t.print_tdiff("1",show_time)
    #########################################################
    # 2. find factors porresponding to entries in A in BPDQ
    sB_dims=mB_s.dimensions()
    wB_dims=mB_w.dimensions()
    A_dims=mA.dimensions()
    sB=MX.mk_symbol_matrix(sB_dims[0],sB_dims[1],"bs")
    wB=MX.mk_symbol_matrix(wB_dims[0],wB_dims[1],"bw")
    P=MX.mk_symbol_matrix(A_dims[0],A_dims[1],"p")
    D=MX.mk_symbol_matrix(A_dims[0],A_dims[1],"a")  # entries of this matrix must be sorted first when expanding
                                    # to make the algorithm work. Hence it is called "a"
    Q=MX.mk_symbol_matrix(A_dims[0],A_dims[1],"q")

    sBPDQ=matrix([])
    if sB.dimensions()[0] > 0:
        sBPDQ=(sB*P*D*Q).expand()           # .expand() is the same as .apply_map(expand)
    wBPDQ=matrix([])
    if wB.dimensions()[0] > 0:
        wBPDQ=(wB*P*D*Q).expand()
    # a matrix entry now has the form (apdq + apdq + apdq + ...), where each
    # a,p,d,q corresponds to one entry of the original matrices.
    #
    # split into operators and operands
    soBPDQ=map(lambda r: map (lambda c: formula_to_operands(c),r), MX.matrix_to_list(sBPDQ))
    woBPDQ=map(lambda r: map (lambda c: formula_to_operands(c),r), MX.matrix_to_list(wBPDQ))
    # Now we have a list representation of our matrix where each entry is split
    # into a tuple (operator,list of arguments).
    # Here we want to replace the symbolic values of matrix A by some abstract
    # representation of the Jordan matrix D to the power of some natural number
    soBPdQ=MX.replace_symbols_in_lmatrix(MX.matrix_to_list(D),MX.abstract_jordan_matrix_power(mD),soBPDQ)
    woBPdQ=MX.replace_symbols_in_lmatrix(MX.matrix_to_list(D),MX.abstract_jordan_matrix_power(mD),woBPDQ)
    # combine parts by same absolute eigenvalues and direction for every entry.
    # an entry.
    snBPdQ=MX.map_lmatrix(group_entry_summands_by_eigenvalue,soBPdQ)
    wnBPdQ=MX.map_lmatrix(group_entry_summands_by_eigenvalue,woBPdQ)
    # Entries now have the form (abs(a_0)(dir(a_0)pdq+dir(a_1)pdq+...)
    # + abs(a_2)(dir(a_2)pdq+dir(a_3)pdq+...) + ...).
    # Next the variables b p q are replaced by their values.
    snbPdQ=MX.replace_symbols_in_lmatrix(MX.matrix_to_list(sB),MX.matrix_to_list(mB_s),snBPdQ)
    snbpdQ=MX.replace_symbols_in_lmatrix(MX.matrix_to_list(P),MX.matrix_to_list(mP),snbPdQ)
    snbpdq=MX.replace_symbols_in_lmatrix(MX.matrix_to_list(Q),MX.matrix_to_list(mPi),snbpdQ)

    wnbPdQ=MX.replace_symbols_in_lmatrix(MX.matrix_to_list(wB),MX.matrix_to_list(mB_w),wnBPdQ)
    wnbpdQ=MX.replace_symbols_in_lmatrix(MX.matrix_to_list(P),MX.matrix_to_list(mP),wnbPdQ)
    wnbpdq=MX.replace_symbols_in_lmatrix(MX.matrix_to_list(Q),MX.matrix_to_list(mPi),wnbpdQ)

    t.print_tdiff("2",show_time)
    #########################################################
    # 3. build the index set and abstract conditions
    ind=sorted(list(set.union(abs_ev_index_set_from_abstract_lmatrix(snbpdq),
        abs_ev_index_set_from_abstract_lmatrix(wnbpdq))))
    s_abs_conds = mk_abstract_conds(snbpdq)
    w_abs_conds = mk_abstract_conds(wnbpdq)

    t.print_tdiff("3",show_time)
    #########################################################
    # 4. build index_z function  and conditions for each index and constraint
    index_z_k,index_cond_c_tuples = mk_index_z(s_abs_conds,w_abs_conds,ind,zvec)

    t.print_tdiff("4",show_time)
    #########################################################
    # 5. build positive eigenspace and constraints for vectors inside of it
    #pos_eigenspace = positive_eigenspace_of(mA)
    pos_eigenspace=positive_generalized_eigenspace_of(mA.change_ring(QQbar))
    in_space_conds = mk_in_space_conditions(pos_eigenspace,zvec)

    t.print_tdiff("5",show_time)
    #########################################################
    # 6. collect all variables and coefficients used
    c_vars=in_space_conds[1] # coefficients
    v_vars=in_space_conds[2] # variables (from zvec)
    allvars=in_space_conds[1]+in_space_conds[2]

    t.print_tdiff("6",show_time)
    #########################################################
    # 7. compute the maxial satisfying index for each of the k constraints
    max_indices = max_indices_cond(index_cond_c_tuples,zvec,in_space_conds)
    if max_indices == None:
        # when no index function can be found (= no nonterminating
        # susbspace is found = dimension of S_min is zero)
        t.print_tdiff("7.0",show_time)
        print "case 0: terminating"
        return "terminating"

    t.print_tdiff("7",show_time)
    #########################################################
    # 8. compute S_min
    S_min_conds=complex_space_conditions(s_abs_conds,w_abs_conds,ind,zvec,index_cond_c_tuples,max_indices,in_space_conds)
    S_min = SE.solution_to_space(S_min_conds[0][0],c_vars,v_vars)

    t.print_tdiff("8",show_time)
    #########################################################
    # 9. compute Q_min and R_min
    algebraic_base_extends = collect_QQ_extends(mD)
    Q_min=find_Q_min(S_min,algebraic_base_extends)
    R_min=VectorSpace(SR,Q_min.degree()).subspace_with_basis(Q_min.basis())

    t.print_tdiff("9",show_time)
    #########################################################
    # 10. decide termination
    if S_min.dimension() == Q_min.dimension():
        print "case 1: non-terminating"
        clean_up(allvars)
        t.print_tdiff("10.1",show_time)
        return "non-terminating"
    if Q_min.dimension() == 0:
        #########################################################
        # 10.2 test whether zero vector is non-terminating
        if terminates_on_zero(mB_s,mB_w):
            print "case 2: terminating"
            clean_up(allvars)
            t.print_tdiff("10.2",show_time)
            return "terminating"
        else:
            print "case 2: non-terminating"
            clean_up(allvars)
            t.print_tdiff("10.2",show_time)
            return "non-terminating"
    if 0 < Q_min.dimension() < S_min.dimension():
        #########################################################
        # 10.3 run termination_check onr educed program
        print "case 3: reduce"
        rA,valphas,lin_alpha=find_reduction_of_matrix(mA,Q_min)
        rB_s,rB_w=apply_reduction_on(mB_s, mB_w, valphas,lin_alpha)
        clean_up(allvars)
        t.print_tdiff("10.3",show_time)
        termination_check(rA,rB_s,rB_w)
Esempio n. 2
0
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)