Revision history [back]

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 = VS.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


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 = VS.inverse()U.transpose()
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





 Copyright Sage, 2010. Some rights reserved under creative commons license. Content on this site is licensed under a Creative Commons Attribution Share Alike 3.0 license. about | faq | help | privacy policy | terms of service Powered by Askbot version 0.7.59 Please note: Askbot requires javascript to work properly, please enable javascript in your browser, here is how //IE fix to hide the red margin var noscript = document.getElementsByTagName('noscript')[0]; noscript.style.padding = '0px'; noscript.style.backgroundColor = 'transparent'; askbot['urls']['mark_read_message'] = '/s/messages/markread/'; askbot['urls']['get_tags_by_wildcard'] = '/s/get-tags-by-wildcard/'; askbot['urls']['get_tag_list'] = '/s/get-tag-list/'; askbot['urls']['follow_user'] = '/followit/follow/user/{{userId}}/'; askbot['urls']['unfollow_user'] = '/followit/unfollow/user/{{userId}}/'; askbot['urls']['user_signin'] = '/account/signin/'; askbot['urls']['getEditor'] = '/s/get-editor/'; askbot['urls']['apiGetQuestions'] = '/s/api/get_questions/'; askbot['urls']['ask'] = '/questions/ask/'; askbot['urls']['questions'] = '/questions/'; askbot['settings']['groupsEnabled'] = false; askbot['settings']['static_url'] = '/m/'; askbot['settings']['minSearchWordLength'] = 4; askbot['settings']['mathjaxEnabled'] = true; askbot['settings']['sharingSuffixText'] = ''; askbot['settings']['errorPlacement'] = 'after-label'; askbot['data']['maxCommentLength'] = 800; askbot['settings']['editorType'] = 'markdown'; askbot['settings']['commentsEditorType'] = 'rich\u002Dtext'; askbot['messages']['askYourQuestion'] = 'Ask Your Question'; askbot['messages']['acceptOwnAnswer'] = 'accept or unaccept your own answer'; askbot['messages']['followQuestions'] = 'follow questions'; askbot['settings']['allowedUploadFileTypes'] = [ "jpg", "jpeg", "gif", "bmp", "png", "tiff" ]; askbot['data']['haveFlashNotifications'] = true; askbot['data']['activeTab'] = 'questions'; askbot['settings']['csrfCookieName'] = 'asksage_csrf'; askbot['data']['searchUrl'] = ''; /*<![CDATA[*/ $('.mceStatusbar').remove();//a hack to remove the tinyMCE status bar$(document).ready(function(){ // focus input on the search bar endcomment var activeTab = askbot['data']['activeTab']; if (inArray(activeTab, ['users', 'questions', 'tags', 'badges'])) { var searchInput = $('#keywords'); } else if (activeTab === 'ask') { var searchInput =$('#id_title'); } else { var searchInput = undefined; animateHashes(); } var wasScrolled = $('#scroll-mem').val(); if (searchInput && !wasScrolled) { searchInput.focus(); putCursorAtEnd(searchInput); } var haveFullTextSearchTab = inArray(activeTab, ['questions', 'badges', 'ask']); var haveUserProfilePage =$('body').hasClass('user-profile-page'); if ((haveUserProfilePage || haveFullTextSearchTab) && searchInput && searchInput.length) { var search = new FullTextSearch(); askbot['controllers'] = askbot['controllers'] || {}; askbot['controllers']['fullTextSearch'] = search; search.setSearchUrl(askbot['data']['searchUrl']); if (activeTab === 'ask') { search.setAskButtonEnabled(false); } search.decorate(searchInput); } else if (activeTab === 'tags') { var search = new TagSearch(); search.decorate(searchInput); } if (askbot['data']['userIsAdminOrMod']) { $('body').addClass('admin'); } if (askbot['settings']['groupsEnabled']) { askbot['urls']['add_group'] = "/s/add-group/"; var group_dropdown = new GroupDropdown();$('.groups-dropdown').append(group_dropdown.getElement()); } var userRep = $('#userToolsNav .reputation'); if (userRep.length) { var showPermsTrigger = new ShowPermsTrigger(); showPermsTrigger.decorate(userRep); } }); if (askbot['data']['haveFlashNotifications']) {$('#validate_email_alert').click(function(){notify.close(true)}) notify.show(); } var langNav = $('.lang-nav'); if (langNav.length) { var nav = new LangNav(); nav.decorate(langNav); } /*]]>*/ if (typeof MathJax != 'undefined') { MathJax.Hub.Config({ extensions: ["tex2jax.js"], jax: ["input/TeX","output/HTML-CSS"], tex2jax: {inlineMath: [["$","$"],["\$","\$"]]} }); } else { console.log('Could not load MathJax'); } //todo - take this out into .js file$(document).ready(function(){ $('div.revision div[id^=rev-header-]').bind('click', function(){ var revId = this.id.substr(11); toggleRev(revId); }); lanai.highlightSyntax(); }); function toggleRev(id) { var arrow =$("#rev-arrow-" + id); var visible = arrow.attr("src").indexOf("hide") > -1; if (visible) { var image_path = '/m/default/media/images/expander-arrow-show.gif?v=19'; } else { var image_path = '/m/default/media/images/expander-arrow-hide.gif?v=19'; } image_path = image_path + "?v=19"; arrow.attr("src", image_path); \$("#rev-body-" + id).slideToggle("fast"); } for (url_name in askbot['urls']){ askbot['urls'][url_name] = cleanUrl(askbot['urls'][url_name]); }