Ask Your Question
1

How do get SVD inverse

asked 2018-02-07 21:16:06 +0100

snesnezzy gravatar image

updated 2018-02-09 03:09:11 +0100

calc314 gravatar image

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 flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted
0

answered 2018-02-09 04:40:18 +0100

dan_fulea gravatar image

updated 2018-02-09 04:42:37 +0100

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
edit flag offensive delete link more

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower

Stats

Asked: 2018-02-07 21:16:06 +0100

Seen: 456 times

Last updated: Feb 09 '18