{"action":"created","comment":{"url":"https://api.github.com/repos/ContinuumIO/dask/pulls/comments/31880525","id":31880525,"diff_hunk":"@@ -60,13 +62,53 @@ def test_tsqr_svd_irregular_blocks():\n     data = from_array(mat, chunks=(3, n), name='A')[1:]\n     mat2 = mat[1:, :]\n \n-    u, s, v = tsqr(data, compute_svd=True)\n+    u, s, vt = tsqr(data, compute_svd=True)\n     u = np.array(u)\n     s = np.array(s)\n-    v = np.array(v)\n+    vt = np.array(vt)\n+    usvt = np.dot(u, np.dot(np.diag(s), vt))\n+\n+    s_exact = np.linalg.svd(mat2)[1]\n \n-    assert np.allclose(mat2, np.dot(u, np.dot(np.diag(s), v)))  # accuracy check\n+    assert np.allclose(mat2, usvt)  # accuracy check\n     assert np.allclose(np.eye(n, n), np.dot(u.T, u))  # u must be orthonormal\n-    assert np.allclose(np.eye(n, n), np.dot(v.T, v))  # v must be orthonormal\n-    assert np.allclose(s, np.linalg.svd(mat2)[1])  # s must contain the singular\n-                                                   # values\n+    assert np.allclose(np.eye(n, n), np.dot(vt, vt.T))  # v must be orthonormal\n+    assert np.allclose(s, s_exact)  # s must contain the singular values\n+\n+\n+def test_svd_compressed():\n+    m, n = 30, 25\n+    r = 10\n+    mat1 = np.random.randn(m, r)\n+    mat2 = np.random.randn(r, n)\n+    mat = mat1.dot(mat2)\n+    data = from_array(mat, chunks=(10, 10), name='A')\n+\n+    n_iter = int(1e2)\n+    for i in range(n_iter):\n+        u, s, vt = svd_compressed(data, r)\n+        u = np.array(u)\n+        s = np.array(s)\n+        vt = np.array(vt)\n+        if i == 0:\n+            usvt = np.dot(u, np.dot(np.diag(s), vt))\n+        else:\n+            usvt += np.dot(u, np.dot(np.diag(s), vt))\n+    usvt /= n_iter\n+\n+    tol = 1e-1\n+    assert np.allclose(np.linalg.norm(mat - usvt),\n+                       np.linalg.norm(mat),\n+                       rtol=tol, atol=tol)  # average accuracy check\n+\n+    u, s, vt = svd_compressed(data, r)\n+    u = np.array(u)[:, :r]\n+    s = np.array(s)[:r]\n+    vt = np.array(vt)[:r, :]\n+\n+    s_exact = np.linalg.svd(mat)[1]\n+    s_exact = s_exact[:r]\n+\n+    assert np.allclose(np.eye(r, r), np.dot(u.T, u))  # u must be orthonormal\n+    assert np.allclose(np.eye(r, r), np.dot(vt, vt.T))  # v must be orthonormal\n+    assert np.allclose(s, s_exact)  # s must contain the singular values","path":"dask/array/tests/test_linalg.py","position":93,"original_position":93,"commit_id":"c983a3aa2a136f647021da4846138e6485d3449e","original_commit_id":"c983a3aa2a136f647021da4846138e6485d3449e","user":{"login":"marianotepper","id":8825420,"avatar_url":"https://avatars.githubusercontent.com/u/8825420?v=3","gravatar_id":"","url":"https://api.github.com/users/marianotepper","html_url":"https://github.com/marianotepper","followers_url":"https://api.github.com/users/marianotepper/followers","following_url":"https://api.github.com/users/marianotepper/following{/other_user}","gists_url":"https://api.github.com/users/marianotepper/gists{/gist_id}","starred_url":"https://api.github.com/users/marianotepper/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/marianotepper/subscriptions","organizations_url":"https://api.github.com/users/marianotepper/orgs","repos_url":"https://api.github.com/users/marianotepper/repos","events_url":"https://api.github.com/users/marianotepper/events{/privacy}","received_events_url":"https://api.github.com/users/marianotepper/received_events","type":"User","site_admin":false},"body":"In my experience, the singular values are correct. The right and left singular vectors, however, will be only correct in average.","created_at":"2015-06-07T20:58:44Z","updated_at":"2015-06-07T20:58:44Z","html_url":"https://github.com/ContinuumIO/dask/pull/280#discussion_r31880525","pull_request_url":"https://api.github.com/repos/ContinuumIO/dask/pulls/280","_links":{"self":{"href":"https://api.github.com/repos/ContinuumIO/dask/pulls/comments/31880525"},"html":{"href":"https://github.com/ContinuumIO/dask/pull/280#discussion_r31880525"},"pull_request":{"href":"https://api.github.com/repos/ContinuumIO/dask/pulls/280"}}},"pull_request":{"url":"https://api.github.com/repos/ContinuumIO/dask/pulls/280","id":37112954,"html_url":"https://github.com/ContinuumIO/dask/pull/280","diff_url":"https://github.com/ContinuumIO/dask/pull/280.diff","patch_url":"https://github.com/ContinuumIO/dask/pull/280.patch","issue_url":"https://api.github.com/repos/ContinuumIO/dask/issues/280","number":280,"state":"open","locked":false,"title":"Randomized/compressed SVD implementation","user":{"login":"marianotepper","id":8825420,"avatar_url":"https://avatars.githubusercontent.com/u/8825420?v=3","gravatar_id":"","url":"https://api.github.com/users/marianotepper","html_url":"https://github.com/marianotepper","followers_url":"https://api.github.com/users/marianotepper/followers","following_url":"https://api.github.com/users/marianotepper/following{/other_user}","gists_url":"https://api.github.com/users/marianotepper/gists{/gist_id}","starred_url":"https://api.github.com/users/marianotepper/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/marianotepper/subscriptions","organizations_url":"https://api.github.com/users/marianotepper/orgs","repos_url":"https://api.github.com/users/marianotepper/repos","events_url":"https://api.github.com/users/marianotepper/events{/privacy}","received_events_url":"https://api.github.com/users/marianotepper/received_events","type":"User","site_admin":false},"body":"- It provides an approximation of the true analytical SVD.\r\n- Using the subsampled Fourier or Hadamard transforms, instead of a Gaussian random matrix, would significantly improve the method's performance.\r\n- Should we create a function called 'thin_svd' that acts like the 'svd' function, providing a generic interface for alternative rank-k SVD implementations?","created_at":"2015-06-07T20:38:38Z","updated_at":"2015-06-07T20:58:44Z","closed_at":null,"merged_at":null,"merge_commit_sha":"a63f8f50eb22d839a26165d276964c4ea7187ea4","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/ContinuumIO/dask/pulls/280/commits","review_comments_url":"https://api.github.com/repos/ContinuumIO/dask/pulls/280/comments","review_comment_url":"https://api.github.com/repos/ContinuumIO/dask/pulls/comments{/number}","comments_url":"https://api.github.com/repos/ContinuumIO/dask/issues/280/comments","statuses_url":"https://api.github.com/repos/ContinuumIO/dask/statuses/c983a3aa2a136f647021da4846138e6485d3449e","head":{"label":"marianotepper:master","ref":"master","sha":"c983a3aa2a136f647021da4846138e6485d3449e","user":{"login":"marianotepper","id":8825420,"avatar_url":"https://avatars.githubusercontent.com/u/8825420?v=3","gravatar_id":"","url":"https://api.github.com/users/marianotepper","html_url":"https://github.com/marianotepper","followers_url":"https://api.github.com/users/marianotepper/followers","following_url":"https://api.github.com/users/marianotepper/following{/other_user}","gists_url":"https://api.github.com/users/marianotepper/gists{/gist_id}","starred_url":"https://api.github.com/users/marianotepper/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/marianotepper/subscriptions","organizations_url":"https://api.github.com/users/marianotepper/orgs","repos_url":"https://api.github.com/users/marianotepper/repos","events_url":"https://api.github.com/users/marianotepper/events{/privacy}","received_events_url":"https://api.github.com/users/marianotepper/received_events","type":"User","site_admin":false},"repo":{"id":30978934,"name":"dask","full_name":"marianotepper/dask","owner":{"login":"marianotepper","id":8825420,"avatar_url":"https://avatars.githubusercontent.com/u/8825420?v=3","gravatar_id":"","url":"https://api.github.com/users/marianotepper","html_url":"https://github.com/marianotepper","followers_url":"https://api.github.com/users/marianotepper/followers","following_url":"https://api.github.com/users/marianotepper/following{/other_user}","gists_url":"https://api.github.com/users/marianotepper/gists{/gist_id}","starred_url":"https://api.github.com/users/marianotepper/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/marianotepper/subscriptions","organizations_url":"https://api.github.com/users/marianotepper/orgs","repos_url":"https://api.github.com/users/marianotepper/repos","events_url":"https://api.github.com/users/marianotepper/events{/privacy}","received_events_url":"https://api.github.com/users/marianotepper/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/marianotepper/dask","description":"Minimal task scheduling abstraction","fork":true,"url":"https://api.github.com/repos/marianotepper/dask","forks_url":"https://api.github.com/repos/marianotepper/dask/forks","keys_url":"https://api.github.com/repos/marianotepper/dask/keys{/key_id}","collaborators_url":"https://api.github.com/repos/marianotepper/dask/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/marianotepper/dask/teams","hooks_url":"https://api.github.com/repos/marianotepper/dask/hooks","issue_events_url":"https://api.github.com/repos/marianotepper/dask/issues/events{/number}","events_url":"https://api.github.com/repos/marianotepper/dask/events","assignees_url":"https://api.github.com/repos/marianotepper/dask/assignees{/user}","branches_url":"https://api.github.com/repos/marianotepper/dask/branches{/branch}","tags_url":"https://api.github.com/repos/marianotepper/dask/tags","blobs_url":"https://api.github.com/repos/marianotepper/dask/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/marianotepper/dask/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/marianotepper/dask/git/refs{/sha}","trees_url":"https://api.github.com/repos/marianotepper/dask/git/trees{/sha}","statuses_url":"https://api.github.com/repos/marianotepper/dask/statuses/{sha}","languages_url":"https://api.github.com/repos/marianotepper/dask/languages","stargazers_url":"https://api.github.com/repos/marianotepper/dask/stargazers","contributors_url":"https://api.github.com/repos/marianotepper/dask/contributors","subscribers_url":"https://api.github.com/repos/marianotepper/dask/subscribers","subscription_url":"https://api.github.com/repos/marianotepper/dask/subscription","commits_url":"https://api.github.com/repos/marianotepper/dask/commits{/sha}","git_commits_url":"https://api.github.com/repos/marianotepper/dask/git/commits{/sha}","comments_url":"https://api.github.com/repos/marianotepper/dask/comments{/number}","issue_comment_url":"https://api.github.com/repos/marianotepper/dask/issues/comments{/number}","contents_url":"https://api.github.com/repos/marianotepper/dask/contents/{+path}","compare_url":"https://api.github.com/repos/marianotepper/dask/compare/{base}...{head}","merges_url":"https://api.github.com/repos/marianotepper/dask/merges","archive_url":"https://api.github.com/repos/marianotepper/dask/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/marianotepper/dask/downloads","issues_url":"https://api.github.com/repos/marianotepper/dask/issues{/number}","pulls_url":"https://api.github.com/repos/marianotepper/dask/pulls{/number}","milestones_url":"https://api.github.com/repos/marianotepper/dask/milestones{/number}","notifications_url":"https://api.github.com/repos/marianotepper/dask/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/marianotepper/dask/labels{/name}","releases_url":"https://api.github.com/repos/marianotepper/dask/releases{/id}","created_at":"2015-02-18T18:12:31Z","updated_at":"2015-03-27T16:56:48Z","pushed_at":"2015-06-07T20:27:55Z","git_url":"git://github.com/marianotepper/dask.git","ssh_url":"git@github.com:marianotepper/dask.git","clone_url":"https://github.com/marianotepper/dask.git","svn_url":"https://github.com/marianotepper/dask","homepage":"","size":1034,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"ContinuumIO:master","ref":"master","sha":"c6671db2a060c8ce73b9514539fd1ee81c91053c","user":{"login":"ContinuumIO","id":1158637,"avatar_url":"https://avatars.githubusercontent.com/u/1158637?v=3","gravatar_id":"","url":"https://api.github.com/users/ContinuumIO","html_url":"https://github.com/ContinuumIO","followers_url":"https://api.github.com/users/ContinuumIO/followers","following_url":"https://api.github.com/users/ContinuumIO/following{/other_user}","gists_url":"https://api.github.com/users/ContinuumIO/gists{/gist_id}","starred_url":"https://api.github.com/users/ContinuumIO/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ContinuumIO/subscriptions","organizations_url":"https://api.github.com/users/ContinuumIO/orgs","repos_url":"https://api.github.com/users/ContinuumIO/repos","events_url":"https://api.github.com/users/ContinuumIO/events{/privacy}","received_events_url":"https://api.github.com/users/ContinuumIO/received_events","type":"Organization","site_admin":false},"repo":{"id":28782747,"name":"dask","full_name":"ContinuumIO/dask","owner":{"login":"ContinuumIO","id":1158637,"avatar_url":"https://avatars.githubusercontent.com/u/1158637?v=3","gravatar_id":"","url":"https://api.github.com/users/ContinuumIO","html_url":"https://github.com/ContinuumIO","followers_url":"https://api.github.com/users/ContinuumIO/followers","following_url":"https://api.github.com/users/ContinuumIO/following{/other_user}","gists_url":"https://api.github.com/users/ContinuumIO/gists{/gist_id}","starred_url":"https://api.github.com/users/ContinuumIO/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ContinuumIO/subscriptions","organizations_url":"https://api.github.com/users/ContinuumIO/orgs","repos_url":"https://api.github.com/users/ContinuumIO/repos","events_url":"https://api.github.com/users/ContinuumIO/events{/privacy}","received_events_url":"https://api.github.com/users/ContinuumIO/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/ContinuumIO/dask","description":"Task scheduling and blocked algorithms for parallel processing","fork":false,"url":"https://api.github.com/repos/ContinuumIO/dask","forks_url":"https://api.github.com/repos/ContinuumIO/dask/forks","keys_url":"https://api.github.com/repos/ContinuumIO/dask/keys{/key_id}","collaborators_url":"https://api.github.com/repos/ContinuumIO/dask/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/ContinuumIO/dask/teams","hooks_url":"https://api.github.com/repos/ContinuumIO/dask/hooks","issue_events_url":"https://api.github.com/repos/ContinuumIO/dask/issues/events{/number}","events_url":"https://api.github.com/repos/ContinuumIO/dask/events","assignees_url":"https://api.github.com/repos/ContinuumIO/dask/assignees{/user}","branches_url":"https://api.github.com/repos/ContinuumIO/dask/branches{/branch}","tags_url":"https://api.github.com/repos/ContinuumIO/dask/tags","blobs_url":"https://api.github.com/repos/ContinuumIO/dask/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/ContinuumIO/dask/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/ContinuumIO/dask/git/refs{/sha}","trees_url":"https://api.github.com/repos/ContinuumIO/dask/git/trees{/sha}","statuses_url":"https://api.github.com/repos/ContinuumIO/dask/statuses/{sha}","languages_url":"https://api.github.com/repos/ContinuumIO/dask/languages","stargazers_url":"https://api.github.com/repos/ContinuumIO/dask/stargazers","contributors_url":"https://api.github.com/repos/ContinuumIO/dask/contributors","subscribers_url":"https://api.github.com/repos/ContinuumIO/dask/subscribers","subscription_url":"https://api.github.com/repos/ContinuumIO/dask/subscription","commits_url":"https://api.github.com/repos/ContinuumIO/dask/commits{/sha}","git_commits_url":"https://api.github.com/repos/ContinuumIO/dask/git/commits{/sha}","comments_url":"https://api.github.com/repos/ContinuumIO/dask/comments{/number}","issue_comment_url":"https://api.github.com/repos/ContinuumIO/dask/issues/comments{/number}","contents_url":"https://api.github.com/repos/ContinuumIO/dask/contents/{+path}","compare_url":"https://api.github.com/repos/ContinuumIO/dask/compare/{base}...{head}","merges_url":"https://api.github.com/repos/ContinuumIO/dask/merges","archive_url":"https://api.github.com/repos/ContinuumIO/dask/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/ContinuumIO/dask/downloads","issues_url":"https://api.github.com/repos/ContinuumIO/dask/issues{/number}","pulls_url":"https://api.github.com/repos/ContinuumIO/dask/pulls{/number}","milestones_url":"https://api.github.com/repos/ContinuumIO/dask/milestones{/number}","notifications_url":"https://api.github.com/repos/ContinuumIO/dask/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/ContinuumIO/dask/labels{/name}","releases_url":"https://api.github.com/repos/ContinuumIO/dask/releases{/id}","created_at":"2015-01-04T18:50:00Z","updated_at":"2015-06-07T16:50:58Z","pushed_at":"2015-06-07T20:38:38Z","git_url":"git://github.com/ContinuumIO/dask.git","ssh_url":"git@github.com:ContinuumIO/dask.git","clone_url":"https://github.com/ContinuumIO/dask.git","svn_url":"https://github.com/ContinuumIO/dask","homepage":"http://dask.pydata.org","size":8987,"stargazers_count":65,"watchers_count":65,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":20,"mirror_url":null,"open_issues_count":34,"forks":20,"open_issues":34,"watchers":65,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/ContinuumIO/dask/pulls/280"},"html":{"href":"https://github.com/ContinuumIO/dask/pull/280"},"issue":{"href":"https://api.github.com/repos/ContinuumIO/dask/issues/280"},"comments":{"href":"https://api.github.com/repos/ContinuumIO/dask/issues/280/comments"},"review_comments":{"href":"https://api.github.com/repos/ContinuumIO/dask/pulls/280/comments"},"review_comment":{"href":"https://api.github.com/repos/ContinuumIO/dask/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/ContinuumIO/dask/pulls/280/commits"},"statuses":{"href":"https://api.github.com/repos/ContinuumIO/dask/statuses/c983a3aa2a136f647021da4846138e6485d3449e"}}}}