{"action":"created","comment":{"url":"https://api.github.com/repos/tBuLi/symfit/pulls/comments/234951784","pull_request_review_id":176702098,"id":234951784,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDIzNDk1MTc4NA==","diff_hunk":"@@ -133,23 +170,98 @@ def _init_from_dict(self, model_dict):\n \n         :param model_dict: dict of (dependent_var, expression) pairs.\n         \"\"\"\n-        sort_func = lambda symbol: str(symbol)\n-        self.model_dict = OrderedDict(sorted(model_dict.items(), key=lambda i: sort_func(i[0])))\n-        self.dependent_vars = sorted(model_dict.keys(), key=sort_func)\n+        sort_func = lambda symbol: symbol.name\n+        self.model_dict = OrderedDict(sorted(model_dict.items(),\n+                                             key=lambda i: sort_func(i[0])))\n+        # Everything at the bottom of the toposort is independent, at the top\n+        # dependent, and the rest interdependent.\n+        ordered = list(toposort(self.connectivity_mapping))\n+        independent = ordered.pop(0)\n+        self.dependent_vars = sorted(ordered.pop(-1), key=sort_func)\n+        self.interdependent_vars = sorted(\n+            [item for items in ordered for item in items],\n+            key=sort_func\n+        )\n+        # `independent` contains both params and vars, needs to be separated\n+        self.params = sorted(\n+            [s for s in independent if isinstance(s, Parameter)],","path":"symfit/core/fit.py","position":98,"original_position":98,"commit_id":"c753dc92fd5b0fb8853b6aa0f3a0274c93f41401","original_commit_id":"c753dc92fd5b0fb8853b6aa0f3a0274c93f41401","user":{"login":"tBuLi","id":2188968,"node_id":"MDQ6VXNlcjIxODg5Njg=","avatar_url":"https://avatars2.githubusercontent.com/u/2188968?v=4","gravatar_id":"","url":"https://api.github.com/users/tBuLi","html_url":"https://github.com/tBuLi","followers_url":"https://api.github.com/users/tBuLi/followers","following_url":"https://api.github.com/users/tBuLi/following{/other_user}","gists_url":"https://api.github.com/users/tBuLi/gists{/gist_id}","starred_url":"https://api.github.com/users/tBuLi/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tBuLi/subscriptions","organizations_url":"https://api.github.com/users/tBuLi/orgs","repos_url":"https://api.github.com/users/tBuLi/repos","events_url":"https://api.github.com/users/tBuLi/events{/privacy}","received_events_url":"https://api.github.com/users/tBuLi/received_events","type":"User","site_admin":false},"body":"Has been abandoned for now :P. It is not useful when it comes to sorting out the interdependence because it only deals with one `Expr` at a time, and since the Parameters are already present at the lowest level of the toposort it makes more sense to just take them from there.","created_at":"2018-11-20T10:43:33Z","updated_at":"2018-11-20T10:43:33Z","html_url":"https://github.com/tBuLi/symfit/pull/201#discussion_r234951784","pull_request_url":"https://api.github.com/repos/tBuLi/symfit/pulls/201","author_association":"OWNER","_links":{"self":{"href":"https://api.github.com/repos/tBuLi/symfit/pulls/comments/234951784"},"html":{"href":"https://github.com/tBuLi/symfit/pull/201#discussion_r234951784"},"pull_request":{"href":"https://api.github.com/repos/tBuLi/symfit/pulls/201"}},"in_reply_to_id":234649421},"pull_request":{"url":"https://api.github.com/repos/tBuLi/symfit/pulls/201","id":231790044,"node_id":"MDExOlB1bGxSZXF1ZXN0MjMxNzkwMDQ0","html_url":"https://github.com/tBuLi/symfit/pull/201","diff_url":"https://github.com/tBuLi/symfit/pull/201.diff","patch_url":"https://github.com/tBuLi/symfit/pull/201.patch","issue_url":"https://api.github.com/repos/tBuLi/symfit/issues/201","number":201,"state":"open","locked":false,"title":"Matrix compatibility and interdependent components","user":{"login":"tBuLi","id":2188968,"node_id":"MDQ6VXNlcjIxODg5Njg=","avatar_url":"https://avatars2.githubusercontent.com/u/2188968?v=4","gravatar_id":"","url":"https://api.github.com/users/tBuLi","html_url":"https://github.com/tBuLi","followers_url":"https://api.github.com/users/tBuLi/followers","following_url":"https://api.github.com/users/tBuLi/following{/other_user}","gists_url":"https://api.github.com/users/tBuLi/gists{/gist_id}","starred_url":"https://api.github.com/users/tBuLi/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tBuLi/subscriptions","organizations_url":"https://api.github.com/users/tBuLi/orgs","repos_url":"https://api.github.com/users/tBuLi/repos","events_url":"https://api.github.com/users/tBuLi/events{/privacy}","received_events_url":"https://api.github.com/users/tBuLi/received_events","type":"User","site_admin":false},"body":"This PR makes two big new changes: support for `sympy.MatrixExpr` as variables and as an indirect consequence it also adds component interdependence.\r\n\r\nConsider e.g.\r\n```python\r\na, b = parameters('a, b')\r\nx, y, z = variables('x, y, z')\r\nmodel_dict = {\r\n    y: a**3 * x + b**2,\r\n    z: y**2 + a * b\r\n}\r\n```\r\n\r\nThis could be a great asset when `y` is expensive to compute and used multiple times. In such a model, `y` is no longer a dependent variable, but rather an interdependent one.\r\n\r\nThe big challenge here was how to calculate the Jacobian and Hessian for such a model, since also there we would like `D(z, a)` to be a function of `D(y, a)`:\r\n```python\r\n{D(y, a): 3 * a**2 * x,\r\n D(y, b): 2 * b,\r\n D(z, a): b + 2 * y * D(y, a),\r\n D(z, b): a + 2 * y * D(y, b),\r\n}\r\n```\r\n\r\nThis PR so far addresses:\r\n\r\n- [x] Introduce separate functions for building a model to represent the jacobian, hessian and least-squares.\r\n- [x] Models now have an attribute `self.jacobian_model` and `self.hessian_model`, which are models to represent those quantities. `self.eval_[...]` calls the respective model and properly arranges the output. (The models just have a set of component representing the jacobian and hessian, so they need to be ordered properly.)\r\n- [x] In addition to the previous point, evaluating models is now based purely on calling the `eval_components`, `eval_jacobian`, and `eval_hessian`. Unless changed by a subclass, `eval_components` calls `numerical_components`. The other two simply call `self.jacobian_model` or `self.hessian_model`.\r\n- [x] All models now have an important new property: `connectivity_mapping`. This indicates for every component on which variables and parameters it depends. This is used in code generation when lambdifying symbolic expressions, such that every component is no longer assumed to depend on all independent variables and parameters, but is just provided with those it needs.\r\n\r\n   For `BaseNumericalModel` subclasses such a `connectivity_mapping` should be provided, although the old syntax is also still supported.\r\n- [x] Based on `connectivity_mapping`, a topological sort can be performed to find the right evaluation order of the components. This is stored in `ordered_symbols`. This added a dependency to the very lightweight package `toposort`.\r\n- [x] In order to properly perform the chain rule we need to turn all variables into functions before calculating derivatives. To this end, there is now 'vars_as_functions' to provide a simple mapping between the two, and `function_dict`, which is equivalent to `model_dict` except that all variables have been turned into `Function` objects and the sorting is based on `ordered_symbols`, not alphabetical.\r\n- [x] Removed a lot of commented out fossilized code which stemmed from a different era.\r\n- [x] Constraints have been massively simplified, getting ever closer to the goal of eliminating them completely.\r\n- [ ] Fixed #84, printing vector models in a more recognizable way. We could still consider printing the `function_dict` instead though.\r\n- [ ] Move models to a separate file.","created_at":"2018-11-18T13:58:45Z","updated_at":"2018-11-20T10:43:33Z","closed_at":null,"merged_at":null,"merge_commit_sha":"75369be3fa2adcb7b21643f64ff326b971b84a55","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/tBuLi/symfit/pulls/201/commits","review_comments_url":"https://api.github.com/repos/tBuLi/symfit/pulls/201/comments","review_comment_url":"https://api.github.com/repos/tBuLi/symfit/pulls/comments{/number}","comments_url":"https://api.github.com/repos/tBuLi/symfit/issues/201/comments","statuses_url":"https://api.github.com/repos/tBuLi/symfit/statuses/c753dc92fd5b0fb8853b6aa0f3a0274c93f41401","head":{"label":"tBuLi:sympy_matrix_compatibility","ref":"sympy_matrix_compatibility","sha":"c753dc92fd5b0fb8853b6aa0f3a0274c93f41401","user":{"login":"tBuLi","id":2188968,"node_id":"MDQ6VXNlcjIxODg5Njg=","avatar_url":"https://avatars2.githubusercontent.com/u/2188968?v=4","gravatar_id":"","url":"https://api.github.com/users/tBuLi","html_url":"https://github.com/tBuLi","followers_url":"https://api.github.com/users/tBuLi/followers","following_url":"https://api.github.com/users/tBuLi/following{/other_user}","gists_url":"https://api.github.com/users/tBuLi/gists{/gist_id}","starred_url":"https://api.github.com/users/tBuLi/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tBuLi/subscriptions","organizations_url":"https://api.github.com/users/tBuLi/orgs","repos_url":"https://api.github.com/users/tBuLi/repos","events_url":"https://api.github.com/users/tBuLi/events{/privacy}","received_events_url":"https://api.github.com/users/tBuLi/received_events","type":"User","site_admin":false},"repo":{"id":24005390,"node_id":"MDEwOlJlcG9zaXRvcnkyNDAwNTM5MA==","name":"symfit","full_name":"tBuLi/symfit","private":false,"owner":{"login":"tBuLi","id":2188968,"node_id":"MDQ6VXNlcjIxODg5Njg=","avatar_url":"https://avatars2.githubusercontent.com/u/2188968?v=4","gravatar_id":"","url":"https://api.github.com/users/tBuLi","html_url":"https://github.com/tBuLi","followers_url":"https://api.github.com/users/tBuLi/followers","following_url":"https://api.github.com/users/tBuLi/following{/other_user}","gists_url":"https://api.github.com/users/tBuLi/gists{/gist_id}","starred_url":"https://api.github.com/users/tBuLi/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tBuLi/subscriptions","organizations_url":"https://api.github.com/users/tBuLi/orgs","repos_url":"https://api.github.com/users/tBuLi/repos","events_url":"https://api.github.com/users/tBuLi/events{/privacy}","received_events_url":"https://api.github.com/users/tBuLi/received_events","type":"User","site_admin":false},"html_url":"https://github.com/tBuLi/symfit","description":"Symbolic Fitting; fitting as it should be.","fork":false,"url":"https://api.github.com/repos/tBuLi/symfit","forks_url":"https://api.github.com/repos/tBuLi/symfit/forks","keys_url":"https://api.github.com/repos/tBuLi/symfit/keys{/key_id}","collaborators_url":"https://api.github.com/repos/tBuLi/symfit/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/tBuLi/symfit/teams","hooks_url":"https://api.github.com/repos/tBuLi/symfit/hooks","issue_events_url":"https://api.github.com/repos/tBuLi/symfit/issues/events{/number}","events_url":"https://api.github.com/repos/tBuLi/symfit/events","assignees_url":"https://api.github.com/repos/tBuLi/symfit/assignees{/user}","branches_url":"https://api.github.com/repos/tBuLi/symfit/branches{/branch}","tags_url":"https://api.github.com/repos/tBuLi/symfit/tags","blobs_url":"https://api.github.com/repos/tBuLi/symfit/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/tBuLi/symfit/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/tBuLi/symfit/git/refs{/sha}","trees_url":"https://api.github.com/repos/tBuLi/symfit/git/trees{/sha}","statuses_url":"https://api.github.com/repos/tBuLi/symfit/statuses/{sha}","languages_url":"https://api.github.com/repos/tBuLi/symfit/languages","stargazers_url":"https://api.github.com/repos/tBuLi/symfit/stargazers","contributors_url":"https://api.github.com/repos/tBuLi/symfit/contributors","subscribers_url":"https://api.github.com/repos/tBuLi/symfit/subscribers","subscription_url":"https://api.github.com/repos/tBuLi/symfit/subscription","commits_url":"https://api.github.com/repos/tBuLi/symfit/commits{/sha}","git_commits_url":"https://api.github.com/repos/tBuLi/symfit/git/commits{/sha}","comments_url":"https://api.github.com/repos/tBuLi/symfit/comments{/number}","issue_comment_url":"https://api.github.com/repos/tBuLi/symfit/issues/comments{/number}","contents_url":"https://api.github.com/repos/tBuLi/symfit/contents/{+path}","compare_url":"https://api.github.com/repos/tBuLi/symfit/compare/{base}...{head}","merges_url":"https://api.github.com/repos/tBuLi/symfit/merges","archive_url":"https://api.github.com/repos/tBuLi/symfit/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/tBuLi/symfit/downloads","issues_url":"https://api.github.com/repos/tBuLi/symfit/issues{/number}","pulls_url":"https://api.github.com/repos/tBuLi/symfit/pulls{/number}","milestones_url":"https://api.github.com/repos/tBuLi/symfit/milestones{/number}","notifications_url":"https://api.github.com/repos/tBuLi/symfit/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/tBuLi/symfit/labels{/name}","releases_url":"https://api.github.com/repos/tBuLi/symfit/releases{/id}","deployments_url":"https://api.github.com/repos/tBuLi/symfit/deployments","created_at":"2014-09-13T20:48:28Z","updated_at":"2018-11-19T18:31:35Z","pushed_at":"2018-11-19T13:55:27Z","git_url":"git://github.com/tBuLi/symfit.git","ssh_url":"git@github.com:tBuLi/symfit.git","clone_url":"https://github.com/tBuLi/symfit.git","svn_url":"https://github.com/tBuLi/symfit","homepage":"http://symfit.readthedocs.org","size":2572,"stargazers_count":31,"watchers_count":31,"language":"Python","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":8,"mirror_url":null,"archived":false,"open_issues_count":34,"license":{"key":"gpl-2.0","name":"GNU General Public License v2.0","spdx_id":"GPL-2.0","url":"https://api.github.com/licenses/gpl-2.0","node_id":"MDc6TGljZW5zZTg="},"forks":8,"open_issues":34,"watchers":31,"default_branch":"master"}},"base":{"label":"tBuLi:master","ref":"master","sha":"fcf8c17b5682144657d4410cfdce9e08cbbcd4e7","user":{"login":"tBuLi","id":2188968,"node_id":"MDQ6VXNlcjIxODg5Njg=","avatar_url":"https://avatars2.githubusercontent.com/u/2188968?v=4","gravatar_id":"","url":"https://api.github.com/users/tBuLi","html_url":"https://github.com/tBuLi","followers_url":"https://api.github.com/users/tBuLi/followers","following_url":"https://api.github.com/users/tBuLi/following{/other_user}","gists_url":"https://api.github.com/users/tBuLi/gists{/gist_id}","starred_url":"https://api.github.com/users/tBuLi/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tBuLi/subscriptions","organizations_url":"https://api.github.com/users/tBuLi/orgs","repos_url":"https://api.github.com/users/tBuLi/repos","events_url":"https://api.github.com/users/tBuLi/events{/privacy}","received_events_url":"https://api.github.com/users/tBuLi/received_events","type":"User","site_admin":false},"repo":{"id":24005390,"node_id":"MDEwOlJlcG9zaXRvcnkyNDAwNTM5MA==","name":"symfit","full_name":"tBuLi/symfit","private":false,"owner":{"login":"tBuLi","id":2188968,"node_id":"MDQ6VXNlcjIxODg5Njg=","avatar_url":"https://avatars2.githubusercontent.com/u/2188968?v=4","gravatar_id":"","url":"https://api.github.com/users/tBuLi","html_url":"https://github.com/tBuLi","followers_url":"https://api.github.com/users/tBuLi/followers","following_url":"https://api.github.com/users/tBuLi/following{/other_user}","gists_url":"https://api.github.com/users/tBuLi/gists{/gist_id}","starred_url":"https://api.github.com/users/tBuLi/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tBuLi/subscriptions","organizations_url":"https://api.github.com/users/tBuLi/orgs","repos_url":"https://api.github.com/users/tBuLi/repos","events_url":"https://api.github.com/users/tBuLi/events{/privacy}","received_events_url":"https://api.github.com/users/tBuLi/received_events","type":"User","site_admin":false},"html_url":"https://github.com/tBuLi/symfit","description":"Symbolic Fitting; fitting as it should be.","fork":false,"url":"https://api.github.com/repos/tBuLi/symfit","forks_url":"https://api.github.com/repos/tBuLi/symfit/forks","keys_url":"https://api.github.com/repos/tBuLi/symfit/keys{/key_id}","collaborators_url":"https://api.github.com/repos/tBuLi/symfit/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/tBuLi/symfit/teams","hooks_url":"https://api.github.com/repos/tBuLi/symfit/hooks","issue_events_url":"https://api.github.com/repos/tBuLi/symfit/issues/events{/number}","events_url":"https://api.github.com/repos/tBuLi/symfit/events","assignees_url":"https://api.github.com/repos/tBuLi/symfit/assignees{/user}","branches_url":"https://api.github.com/repos/tBuLi/symfit/branches{/branch}","tags_url":"https://api.github.com/repos/tBuLi/symfit/tags","blobs_url":"https://api.github.com/repos/tBuLi/symfit/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/tBuLi/symfit/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/tBuLi/symfit/git/refs{/sha}","trees_url":"https://api.github.com/repos/tBuLi/symfit/git/trees{/sha}","statuses_url":"https://api.github.com/repos/tBuLi/symfit/statuses/{sha}","languages_url":"https://api.github.com/repos/tBuLi/symfit/languages","stargazers_url":"https://api.github.com/repos/tBuLi/symfit/stargazers","contributors_url":"https://api.github.com/repos/tBuLi/symfit/contributors","subscribers_url":"https://api.github.com/repos/tBuLi/symfit/subscribers","subscription_url":"https://api.github.com/repos/tBuLi/symfit/subscription","commits_url":"https://api.github.com/repos/tBuLi/symfit/commits{/sha}","git_commits_url":"https://api.github.com/repos/tBuLi/symfit/git/commits{/sha}","comments_url":"https://api.github.com/repos/tBuLi/symfit/comments{/number}","issue_comment_url":"https://api.github.com/repos/tBuLi/symfit/issues/comments{/number}","contents_url":"https://api.github.com/repos/tBuLi/symfit/contents/{+path}","compare_url":"https://api.github.com/repos/tBuLi/symfit/compare/{base}...{head}","merges_url":"https://api.github.com/repos/tBuLi/symfit/merges","archive_url":"https://api.github.com/repos/tBuLi/symfit/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/tBuLi/symfit/downloads","issues_url":"https://api.github.com/repos/tBuLi/symfit/issues{/number}","pulls_url":"https://api.github.com/repos/tBuLi/symfit/pulls{/number}","milestones_url":"https://api.github.com/repos/tBuLi/symfit/milestones{/number}","notifications_url":"https://api.github.com/repos/tBuLi/symfit/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/tBuLi/symfit/labels{/name}","releases_url":"https://api.github.com/repos/tBuLi/symfit/releases{/id}","deployments_url":"https://api.github.com/repos/tBuLi/symfit/deployments","created_at":"2014-09-13T20:48:28Z","updated_at":"2018-11-19T18:31:35Z","pushed_at":"2018-11-19T13:55:27Z","git_url":"git://github.com/tBuLi/symfit.git","ssh_url":"git@github.com:tBuLi/symfit.git","clone_url":"https://github.com/tBuLi/symfit.git","svn_url":"https://github.com/tBuLi/symfit","homepage":"http://symfit.readthedocs.org","size":2572,"stargazers_count":31,"watchers_count":31,"language":"Python","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":8,"mirror_url":null,"archived":false,"open_issues_count":34,"license":{"key":"gpl-2.0","name":"GNU General Public License v2.0","spdx_id":"GPL-2.0","url":"https://api.github.com/licenses/gpl-2.0","node_id":"MDc6TGljZW5zZTg="},"forks":8,"open_issues":34,"watchers":31,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/tBuLi/symfit/pulls/201"},"html":{"href":"https://github.com/tBuLi/symfit/pull/201"},"issue":{"href":"https://api.github.com/repos/tBuLi/symfit/issues/201"},"comments":{"href":"https://api.github.com/repos/tBuLi/symfit/issues/201/comments"},"review_comments":{"href":"https://api.github.com/repos/tBuLi/symfit/pulls/201/comments"},"review_comment":{"href":"https://api.github.com/repos/tBuLi/symfit/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/tBuLi/symfit/pulls/201/commits"},"statuses":{"href":"https://api.github.com/repos/tBuLi/symfit/statuses/c753dc92fd5b0fb8853b6aa0f3a0274c93f41401"}},"author_association":"OWNER"}}
{"actor":{"display_login":"tBuLi"}}