# How do get SVD inverse

I formed my matrix $A$ from, A = random_matrix(QQ, 6, algorithm='echelonizable', rank=6, upper_bound=9), I then changed the ring to RDF (A.change_ring(RDF)) , I further obtain my SVD matrix (U, S, V = B.SVD()). How do i find the inverse of A using SVD

edit retag close merge delete

Sort by » oldest newest most voted

The documentation of random_matrix contains the information:

Random matrices with predictable echelon forms.  The
"algorithm='echelonizable'" keyword, along with a requested rank
("rank") and optional size control ("upper_bound") will return a
random matrix in echelon form.  When the base ring is "ZZ" or "QQ"
the result has integer entries, whose magnitudes can be limited by
the value of "upper_bound", and the echelon form of the matrix also
has integer entries.  Other exact rings may be also specified, but
there is no notion of controlling the size.  Square matrices of
full rank generated by this function always have determinant one,
and can be constructed with the "unimodular" keyword.


So the matrix A constructed above is a matrix with entries in $\mathbb Z$ (and base ring $\mathbb Q$) and determinant $$\det A = 1\ .$$ Since the inverse of $A$ is the "adjoint matrix", A.adjoint(), we have the information that the entries of $A^{-1}$ are integers. This information is important in the context of the question, since we get first and approximative inverse, having entries very closed to some integers, then we round.

In an explicit example:

This time i have got:

sage: A = random_matrix(QQ, 6, algorithm='echelonizable', rank=6, upper_bound=9)
sage: A

[ 1  0  2  2 -2  5]
[-1  0 -2 -3  3 -5]
[-1 -1  0 -4  5  5]
[ 0  1 -1  4 -5 -5]
[ 0  0  2  6 -5  5]
[ 1  1  0 -1 -1  1]


As promised:

sage: A.inverse() == A.adjoint()
True


but we do not print either one... Instead, let us associate:

sage: B = A.change_ring(RDF)
sage: U, S, V = B.SVD()


The matrices $U,V$ are orthogonal, so the transposed are the inverses:

sage: (U*U.transpose()).round()

[ 1.0 -0.0 -0.0  0.0  0.0 -0.0]
[-0.0  1.0  0.0 -0.0  0.0  0.0]
[-0.0  0.0  1.0  0.0 -0.0  0.0]
[ 0.0 -0.0  0.0  1.0 -0.0  0.0]
[ 0.0  0.0 -0.0 -0.0  1.0  0.0]
[-0.0  0.0  0.0  0.0  0.0  1.0]
sage: (V*V.transpose()).round()

[ 1.0 -0.0  0.0  0.0  0.0 -0.0]
[-0.0  1.0  0.0  0.0  0.0  0.0]
[ 0.0  0.0  1.0 -0.0 -0.0  0.0]
[ 0.0  0.0 -0.0  1.0 -0.0  0.0]
[ 0.0  0.0 -0.0 -0.0  1.0  0.0]
[-0.0  0.0  0.0  0.0  0.0  1.0]


The matrix $S$ contains on the diagonal the singular values, we can check for instance:

sage: B.singular_values()

[13.351058796439338,
11.46537265710543,
2.4430917321568475,
1.1384557335300527,
0.1717356340018411,
0.013676651355763396]
sage: S.round()

[13.0  0.0  0.0  0.0  0.0  0.0]
[ 0.0 11.0  0.0  0.0  0.0  0.0]
[ 0.0  0.0  2.0  0.0  0.0  0.0]
[ 0.0  0.0  0.0  1.0  0.0  0.0]
[ 0.0  0.0  0.0  0.0  0.0  0.0]
[ 0.0  0.0  0.0  0.0  0.0  0.0]


(No space to show $S$ here...) Inverting $S$ is easy. So we build the inverse of $B=USV'$, which is $VS^{-1}U'$. The entries of this matrix are

sage: C = V*S.inverse()*U.transpose()
sage: C
[-28.000000000000274 -17.000000000000092 -7.0000000000001155 -12.000000000000169   5.000000000000092   5.000000000000067]
[  -18.0000000000002  -7.000000000000057  -6.000000000000087 -10.000000000000128   6.000000000000075   5.000000000000055]
[ 28.000000000000302   17.00000000000011   6.000000000000119  11.000000000000178  -5.000000000000096  -5.000000000000072]
[-26.000000000000284 -14.000000000000098  -7.000000000000118 -12.000000000000174   6.000000000000098   5.000000000000072]
[-25.000000000000263 -13.000000000000085  -7.000000000000111 -12.000000000000163   6.000000000000092  5.0000000000000675]
[ -5.000000000000057 -3.0000000000000213  -1.000000000000022 -2.0000000000000333   1.000000000000018  1.0000000000000135]


and we round:

sage: C.round()

[-28.0 -17.0  -7.0 -12.0   5.0   5.0]
[-18.0  -7.0  -6.0 -10.0   6.0   5.0]
[ 28.0  17.0   6.0  11.0  -5.0  -5.0]
[-26.0 -14.0  -7.0 -12.0   6.0   5.0]
[-25.0 -13.0  -7.0 -12.0   6.0   5.0]
[ -5.0  -3.0  -1.0  -2.0   1.0   1.0]
sage: C.round().change_ring(ZZ)

[-28 -17  -7 -12   5   5]
[-18  -7  -6 -10   6   5]
[ 28  17   6  11  -5  -5]
[-26 -14  -7 -12   6   5]
[-25 -13  -7 -12   6   5]
[ -5  -3  -1  -2   1   1]
sage: C.round().change_ring(ZZ) == A.inverse()
True

more