{"action":"created","comment":{"url":"https://api.github.com/repos/scipy/scipy/pulls/comments/199964122","pull_request_review_id":134183535,"id":199964122,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDE5OTk2NDEyMg==","diff_hunk":"@@ -1460,3 +1461,109 @@ def __getitem__(self, indexer):\n                [ 0.57735027,  0.57735027, -0.57735027,  0.        ]])\n         \"\"\"\n         return self.__class__(self._quat[indexer], normalized=True)\n+\n+    @classmethod\n+    def match_vectors(cls, a, b, weights=None, normalized=False):\n+        \"\"\"Estimate the rotation to match two sets of vectors.\n+\n+        Find a rotation between frames A and B which best matches a set of unit\n+        vectors `a` and `b` observed in these frames. The following loss\n+        function is minimized to solve for the direction cosine matrix\n+        :math:`C`:\n+\n+        .. math::\n+\n+            L(C) = \\\\frac{1}{2} \\\\sum_{i = 1}^{n} w_i \\\\lVert \\\\mathbf{a}_i -\n+            C \\\\mathbf{b}_i \\\\rVert^2 ,\n+\n+        where :math:`w_i`'s are the `weights` corresponding to each vector.\n+\n+        The rotation is estimated using Markley's SVD method [1]_.\n+\n+        Parameters\n+        ----------\n+        a : array_like, shape (N, 3)\n+            Vectors expressed in initial frame A. Result of applying an\n+            arbitrary rotation to `b`. Each `a[i]` corresponds to a vector.\n+        b : array_like, shape (N, 3)\n+            Vectors expressed in another frame B. Shape must match `a`. Each\n+            `b[i]` corresponds to a vector.\n+        weights : None or array_like, 1D\n+            Coefficients describing the relative importance of the vectors in\n+            `a`. Number of values in `weights` must match number of vectors\n+            specified in `a` and `b`. `weights` are normalized before matching\n+            vectors. If None, then all values in `weights` are assumed to be\n+            equal. Default is None.\n+        normalized : boolean, optional\n+            If True, assume input vectors `a` and `b` to have unit norm. If\n+            False, normalize `a` and `b` before estimating rotation. Default\n+            is False.\n+\n+        Returns\n+        -------\n+        estimated_rotation : `Rotation` instance\n+            Best estimate of the rotation that transforms `b` to `a`.\n+        covariance_matrix : `numpy.ndarray`, shape (3, 3)\n+            Covariance matrix of the three component error vector of the Euler\n+            angles describing the `estimated_rotation`.\n+\n+        References\n+        ----------\n+        .. [1] F. Landis Markley,\n+                “Attitude determination using vector observations: a fast\n+                optimal matrix algorithm,” Journal of Astronautical Sciences,\n+                Vol. 41, No.2, 1993, pp. 261-280.\n+        \"\"\"\n+        outvecs = np.asarray(a)","path":"scipy/spatial/transform/rotation.py","position":65,"original_position":65,"commit_id":"1037c38c5c78f7aadc2ab738c26ee97c9531d271","original_commit_id":"1037c38c5c78f7aadc2ab738c26ee97c9531d271","user":{"login":"nmayorov","id":7074023,"node_id":"MDQ6VXNlcjcwNzQwMjM=","avatar_url":"https://avatars0.githubusercontent.com/u/7074023?v=4","gravatar_id":"","url":"https://api.github.com/users/nmayorov","html_url":"https://github.com/nmayorov","followers_url":"https://api.github.com/users/nmayorov/followers","following_url":"https://api.github.com/users/nmayorov/following{/other_user}","gists_url":"https://api.github.com/users/nmayorov/gists{/gist_id}","starred_url":"https://api.github.com/users/nmayorov/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nmayorov/subscriptions","organizations_url":"https://api.github.com/users/nmayorov/orgs","repos_url":"https://api.github.com/users/nmayorov/repos","events_url":"https://api.github.com/users/nmayorov/events{/privacy}","received_events_url":"https://api.github.com/users/nmayorov/received_events","type":"User","site_admin":false},"body":"Maybe keep names as `a` and `b`?","created_at":"2018-07-03T22:11:13Z","updated_at":"2018-07-03T22:52:10Z","html_url":"https://github.com/scipy/scipy/pull/8997#discussion_r199964122","pull_request_url":"https://api.github.com/repos/scipy/scipy/pulls/8997","author_association":"CONTRIBUTOR","_links":{"self":{"href":"https://api.github.com/repos/scipy/scipy/pulls/comments/199964122"},"html":{"href":"https://github.com/scipy/scipy/pull/8997#discussion_r199964122"},"pull_request":{"href":"https://api.github.com/repos/scipy/scipy/pulls/8997"}}},"pull_request":{"url":"https://api.github.com/repos/scipy/scipy/pulls/8997","id":198868196,"node_id":"MDExOlB1bGxSZXF1ZXN0MTk4ODY4MTk2","html_url":"https://github.com/scipy/scipy/pull/8997","diff_url":"https://github.com/scipy/scipy/pull/8997.diff","patch_url":"https://github.com/scipy/scipy/pull/8997.patch","issue_url":"https://api.github.com/repos/scipy/scipy/issues/8997","number":8997,"state":"open","locked":false,"title":"WIP / ENH: spatial.transform.Rotation.match_vectors","user":{"login":"adbugger","id":15844796,"node_id":"MDQ6VXNlcjE1ODQ0Nzk2","avatar_url":"https://avatars1.githubusercontent.com/u/15844796?v=4","gravatar_id":"","url":"https://api.github.com/users/adbugger","html_url":"https://github.com/adbugger","followers_url":"https://api.github.com/users/adbugger/followers","following_url":"https://api.github.com/users/adbugger/following{/other_user}","gists_url":"https://api.github.com/users/adbugger/gists{/gist_id}","starred_url":"https://api.github.com/users/adbugger/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/adbugger/subscriptions","organizations_url":"https://api.github.com/users/adbugger/orgs","repos_url":"https://api.github.com/users/adbugger/repos","events_url":"https://api.github.com/users/adbugger/events{/privacy}","received_events_url":"https://api.github.com/users/adbugger/received_events","type":"User","site_admin":false},"body":"Estimating a rotation between two frames using vector measurements in the two frames.\r\n\r\n@nmayorov I've done some changes to the code. Now we're normalizing the `weights` to have unit sum. This allows us to return the full covariance matrix as it is equal to the `sensitivity_matrix`. Do take a look and tell me if the math is sound.","created_at":"2018-07-03T07:07:27Z","updated_at":"2018-07-03T22:52:11Z","closed_at":null,"merged_at":null,"merge_commit_sha":"745d00f38a3b403eb7f3a79364c562ef56ab384b","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/scipy/scipy/pulls/8997/commits","review_comments_url":"https://api.github.com/repos/scipy/scipy/pulls/8997/comments","review_comment_url":"https://api.github.com/repos/scipy/scipy/pulls/comments{/number}","comments_url":"https://api.github.com/repos/scipy/scipy/issues/8997/comments","statuses_url":"https://api.github.com/repos/scipy/scipy/statuses/1037c38c5c78f7aadc2ab738c26ee97c9531d271","head":{"label":"adbugger:rotation_match_vectors","ref":"rotation_match_vectors","sha":"1037c38c5c78f7aadc2ab738c26ee97c9531d271","user":{"login":"adbugger","id":15844796,"node_id":"MDQ6VXNlcjE1ODQ0Nzk2","avatar_url":"https://avatars1.githubusercontent.com/u/15844796?v=4","gravatar_id":"","url":"https://api.github.com/users/adbugger","html_url":"https://github.com/adbugger","followers_url":"https://api.github.com/users/adbugger/followers","following_url":"https://api.github.com/users/adbugger/following{/other_user}","gists_url":"https://api.github.com/users/adbugger/gists{/gist_id}","starred_url":"https://api.github.com/users/adbugger/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/adbugger/subscriptions","organizations_url":"https://api.github.com/users/adbugger/orgs","repos_url":"https://api.github.com/users/adbugger/repos","events_url":"https://api.github.com/users/adbugger/events{/privacy}","received_events_url":"https://api.github.com/users/adbugger/received_events","type":"User","site_admin":false},"repo":{"id":121636791,"node_id":"MDEwOlJlcG9zaXRvcnkxMjE2MzY3OTE=","name":"scipy","full_name":"adbugger/scipy","owner":{"login":"adbugger","id":15844796,"node_id":"MDQ6VXNlcjE1ODQ0Nzk2","avatar_url":"https://avatars1.githubusercontent.com/u/15844796?v=4","gravatar_id":"","url":"https://api.github.com/users/adbugger","html_url":"https://github.com/adbugger","followers_url":"https://api.github.com/users/adbugger/followers","following_url":"https://api.github.com/users/adbugger/following{/other_user}","gists_url":"https://api.github.com/users/adbugger/gists{/gist_id}","starred_url":"https://api.github.com/users/adbugger/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/adbugger/subscriptions","organizations_url":"https://api.github.com/users/adbugger/orgs","repos_url":"https://api.github.com/users/adbugger/repos","events_url":"https://api.github.com/users/adbugger/events{/privacy}","received_events_url":"https://api.github.com/users/adbugger/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/adbugger/scipy","description":"Scipy library main repository","fork":true,"url":"https://api.github.com/repos/adbugger/scipy","forks_url":"https://api.github.com/repos/adbugger/scipy/forks","keys_url":"https://api.github.com/repos/adbugger/scipy/keys{/key_id}","collaborators_url":"https://api.github.com/repos/adbugger/scipy/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/adbugger/scipy/teams","hooks_url":"https://api.github.com/repos/adbugger/scipy/hooks","issue_events_url":"https://api.github.com/repos/adbugger/scipy/issues/events{/number}","events_url":"https://api.github.com/repos/adbugger/scipy/events","assignees_url":"https://api.github.com/repos/adbugger/scipy/assignees{/user}","branches_url":"https://api.github.com/repos/adbugger/scipy/branches{/branch}","tags_url":"https://api.github.com/repos/adbugger/scipy/tags","blobs_url":"https://api.github.com/repos/adbugger/scipy/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/adbugger/scipy/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/adbugger/scipy/git/refs{/sha}","trees_url":"https://api.github.com/repos/adbugger/scipy/git/trees{/sha}","statuses_url":"https://api.github.com/repos/adbugger/scipy/statuses/{sha}","languages_url":"https://api.github.com/repos/adbugger/scipy/languages","stargazers_url":"https://api.github.com/repos/adbugger/scipy/stargazers","contributors_url":"https://api.github.com/repos/adbugger/scipy/contributors","subscribers_url":"https://api.github.com/repos/adbugger/scipy/subscribers","subscription_url":"https://api.github.com/repos/adbugger/scipy/subscription","commits_url":"https://api.github.com/repos/adbugger/scipy/commits{/sha}","git_commits_url":"https://api.github.com/repos/adbugger/scipy/git/commits{/sha}","comments_url":"https://api.github.com/repos/adbugger/scipy/comments{/number}","issue_comment_url":"https://api.github.com/repos/adbugger/scipy/issues/comments{/number}","contents_url":"https://api.github.com/repos/adbugger/scipy/contents/{+path}","compare_url":"https://api.github.com/repos/adbugger/scipy/compare/{base}...{head}","merges_url":"https://api.github.com/repos/adbugger/scipy/merges","archive_url":"https://api.github.com/repos/adbugger/scipy/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/adbugger/scipy/downloads","issues_url":"https://api.github.com/repos/adbugger/scipy/issues{/number}","pulls_url":"https://api.github.com/repos/adbugger/scipy/pulls{/number}","milestones_url":"https://api.github.com/repos/adbugger/scipy/milestones{/number}","notifications_url":"https://api.github.com/repos/adbugger/scipy/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/adbugger/scipy/labels{/name}","releases_url":"https://api.github.com/repos/adbugger/scipy/releases{/id}","deployments_url":"https://api.github.com/repos/adbugger/scipy/deployments","created_at":"2018-02-15T14:07:00Z","updated_at":"2018-07-02T05:03:49Z","pushed_at":"2018-07-03T07:01:07Z","git_url":"git://github.com/adbugger/scipy.git","ssh_url":"git@github.com:adbugger/scipy.git","clone_url":"https://github.com/adbugger/scipy.git","svn_url":"https://github.com/adbugger/scipy","homepage":"http://scipy.org/scipylib/","size":79039,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1,"mirror_url":null,"archived":false,"open_issues_count":0,"license":{"key":"other","name":"Other","spdx_id":null,"url":null,"node_id":"MDc6TGljZW5zZTA="},"forks":1,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"scipy:master","ref":"master","sha":"c61e36fd955477df32ee165cdbba6121f057ee4b","user":{"login":"scipy","id":288277,"node_id":"MDEyOk9yZ2FuaXphdGlvbjI4ODI3Nw==","avatar_url":"https://avatars2.githubusercontent.com/u/288277?v=4","gravatar_id":"","url":"https://api.github.com/users/scipy","html_url":"https://github.com/scipy","followers_url":"https://api.github.com/users/scipy/followers","following_url":"https://api.github.com/users/scipy/following{/other_user}","gists_url":"https://api.github.com/users/scipy/gists{/gist_id}","starred_url":"https://api.github.com/users/scipy/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/scipy/subscriptions","organizations_url":"https://api.github.com/users/scipy/orgs","repos_url":"https://api.github.com/users/scipy/repos","events_url":"https://api.github.com/users/scipy/events{/privacy}","received_events_url":"https://api.github.com/users/scipy/received_events","type":"Organization","site_admin":false},"repo":{"id":1460385,"node_id":"MDEwOlJlcG9zaXRvcnkxNDYwMzg1","name":"scipy","full_name":"scipy/scipy","owner":{"login":"scipy","id":288277,"node_id":"MDEyOk9yZ2FuaXphdGlvbjI4ODI3Nw==","avatar_url":"https://avatars2.githubusercontent.com/u/288277?v=4","gravatar_id":"","url":"https://api.github.com/users/scipy","html_url":"https://github.com/scipy","followers_url":"https://api.github.com/users/scipy/followers","following_url":"https://api.github.com/users/scipy/following{/other_user}","gists_url":"https://api.github.com/users/scipy/gists{/gist_id}","starred_url":"https://api.github.com/users/scipy/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/scipy/subscriptions","organizations_url":"https://api.github.com/users/scipy/orgs","repos_url":"https://api.github.com/users/scipy/repos","events_url":"https://api.github.com/users/scipy/events{/privacy}","received_events_url":"https://api.github.com/users/scipy/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/scipy/scipy","description":"Scipy library main repository","fork":false,"url":"https://api.github.com/repos/scipy/scipy","forks_url":"https://api.github.com/repos/scipy/scipy/forks","keys_url":"https://api.github.com/repos/scipy/scipy/keys{/key_id}","collaborators_url":"https://api.github.com/repos/scipy/scipy/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/scipy/scipy/teams","hooks_url":"https://api.github.com/repos/scipy/scipy/hooks","issue_events_url":"https://api.github.com/repos/scipy/scipy/issues/events{/number}","events_url":"https://api.github.com/repos/scipy/scipy/events","assignees_url":"https://api.github.com/repos/scipy/scipy/assignees{/user}","branches_url":"https://api.github.com/repos/scipy/scipy/branches{/branch}","tags_url":"https://api.github.com/repos/scipy/scipy/tags","blobs_url":"https://api.github.com/repos/scipy/scipy/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/scipy/scipy/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/scipy/scipy/git/refs{/sha}","trees_url":"https://api.github.com/repos/scipy/scipy/git/trees{/sha}","statuses_url":"https://api.github.com/repos/scipy/scipy/statuses/{sha}","languages_url":"https://api.github.com/repos/scipy/scipy/languages","stargazers_url":"https://api.github.com/repos/scipy/scipy/stargazers","contributors_url":"https://api.github.com/repos/scipy/scipy/contributors","subscribers_url":"https://api.github.com/repos/scipy/scipy/subscribers","subscription_url":"https://api.github.com/repos/scipy/scipy/subscription","commits_url":"https://api.github.com/repos/scipy/scipy/commits{/sha}","git_commits_url":"https://api.github.com/repos/scipy/scipy/git/commits{/sha}","comments_url":"https://api.github.com/repos/scipy/scipy/comments{/number}","issue_comment_url":"https://api.github.com/repos/scipy/scipy/issues/comments{/number}","contents_url":"https://api.github.com/repos/scipy/scipy/contents/{+path}","compare_url":"https://api.github.com/repos/scipy/scipy/compare/{base}...{head}","merges_url":"https://api.github.com/repos/scipy/scipy/merges","archive_url":"https://api.github.com/repos/scipy/scipy/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/scipy/scipy/downloads","issues_url":"https://api.github.com/repos/scipy/scipy/issues{/number}","pulls_url":"https://api.github.com/repos/scipy/scipy/pulls{/number}","milestones_url":"https://api.github.com/repos/scipy/scipy/milestones{/number}","notifications_url":"https://api.github.com/repos/scipy/scipy/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/scipy/scipy/labels{/name}","releases_url":"https://api.github.com/repos/scipy/scipy/releases{/id}","deployments_url":"https://api.github.com/repos/scipy/scipy/deployments","created_at":"2011-03-09T18:52:03Z","updated_at":"2018-07-03T19:57:20Z","pushed_at":"2018-07-03T07:07:28Z","git_url":"git://github.com/scipy/scipy.git","ssh_url":"git@github.com:scipy/scipy.git","clone_url":"https://github.com/scipy/scipy.git","svn_url":"https://github.com/scipy/scipy","homepage":"https://scipy.org/scipylib/","size":80983,"stargazers_count":4605,"watchers_count":4605,"language":"Python","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":2387,"mirror_url":null,"archived":false,"open_issues_count":1263,"license":{"key":"other","name":"Other","spdx_id":null,"url":null,"node_id":"MDc6TGljZW5zZTA="},"forks":2387,"open_issues":1263,"watchers":4605,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/scipy/scipy/pulls/8997"},"html":{"href":"https://github.com/scipy/scipy/pull/8997"},"issue":{"href":"https://api.github.com/repos/scipy/scipy/issues/8997"},"comments":{"href":"https://api.github.com/repos/scipy/scipy/issues/8997/comments"},"review_comments":{"href":"https://api.github.com/repos/scipy/scipy/pulls/8997/comments"},"review_comment":{"href":"https://api.github.com/repos/scipy/scipy/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/scipy/scipy/pulls/8997/commits"},"statuses":{"href":"https://api.github.com/repos/scipy/scipy/statuses/1037c38c5c78f7aadc2ab738c26ee97c9531d271"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"nmayorov"}}