Because I really needed sparse operations, I recoded the right_kernel
function as follows (I need the output basis). I realize after reading
your code that these two are actually equivalent - you use functions
dealing with pivots while I directly fetch them from the matrix (I did
not know the existence of these functions).

def right_kernel_basis(m):
    field=m.base_ring()
    lead_positions=[]

    row_vector_space=VectorSpace(m.base_ring(), m.ncols(),
sparse=True)
    m_ech=m.echelon_form()

    additional_columns=[]
    last_j = -1

    last_row=-1
    for i in xrange(m_ech.nrows()):
        nz_pos = m_ech.row(i).nonzero_positions()
        if len(nz_pos)==0:
            last_row=i
            break

        j = nz_pos[0]
        lead_positions.append(j)
        assert j>last_j # echelon form
        assert m_ech[i][j] == 1

        if last_j >= 0:
            additional_columns += range(last_j+1, j)

        last_j = j

    if last_row<0:
        last_row = m_ech.nrows()

    ker_vectors=[]
    for j in additional_columns + range(last_j+1, m_ech.ncols()):
        col = m_ech.column(j)
        v = row_vector_space(0)
        v[j] = 1
        for i in col.nonzero_positions():
            v[lead_positions[i]] = -col[i]
        assert m*v == 0
        ker_vectors.append(v)

    assert len(ker_vectors) + last_row == m.ncols()

    if len(ker_vectors)==0:
        return []

    mret = Matrix(field, ker_vectors, sparse=True).transpose()
    assert mret.rank() == len(ker_vectors)

    assert m*mret == 0

    return ker_vectors


--~--~---------~--~----~------------~-------~--~----~
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/sage-support
URL: http://www.sagemath.org
-~----------~----~----~----~------~----~------~--~---

Reply via email to