{"action":"created","issue":{"url":"https://api.github.com/repos/tulip-control/polytope/issues/17","repository_url":"https://api.github.com/repos/tulip-control/polytope","labels_url":"https://api.github.com/repos/tulip-control/polytope/issues/17/labels{/name}","comments_url":"https://api.github.com/repos/tulip-control/polytope/issues/17/comments","events_url":"https://api.github.com/repos/tulip-control/polytope/issues/17/events","html_url":"https://github.com/tulip-control/polytope/issues/17","id":115554947,"number":17,"title":"Choosing between scipy and cvxopt solvers","user":{"login":"ajwagen","id":15052647,"avatar_url":"https://avatars3.githubusercontent.com/u/15052647?v=4","gravatar_id":"","url":"https://api.github.com/users/ajwagen","html_url":"https://github.com/ajwagen","followers_url":"https://api.github.com/users/ajwagen/followers","following_url":"https://api.github.com/users/ajwagen/following{/other_user}","gists_url":"https://api.github.com/users/ajwagen/gists{/gist_id}","starred_url":"https://api.github.com/users/ajwagen/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ajwagen/subscriptions","organizations_url":"https://api.github.com/users/ajwagen/orgs","repos_url":"https://api.github.com/users/ajwagen/repos","events_url":"https://api.github.com/users/ajwagen/events{/privacy}","received_events_url":"https://api.github.com/users/ajwagen/received_events","type":"User","site_admin":false},"labels":[{"id":88233485,"url":"https://api.github.com/repos/tulip-control/polytope/labels/enhancement","name":"enhancement","color":"84b6eb","default":true}],"state":"closed","locked":false,"assignee":{"login":"johnyf","id":3135273,"avatar_url":"https://avatars0.githubusercontent.com/u/3135273?v=4","gravatar_id":"","url":"https://api.github.com/users/johnyf","html_url":"https://github.com/johnyf","followers_url":"https://api.github.com/users/johnyf/followers","following_url":"https://api.github.com/users/johnyf/following{/other_user}","gists_url":"https://api.github.com/users/johnyf/gists{/gist_id}","starred_url":"https://api.github.com/users/johnyf/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/johnyf/subscriptions","organizations_url":"https://api.github.com/users/johnyf/orgs","repos_url":"https://api.github.com/users/johnyf/repos","events_url":"https://api.github.com/users/johnyf/events{/privacy}","received_events_url":"https://api.github.com/users/johnyf/received_events","type":"User","site_admin":false},"assignees":[{"login":"johnyf","id":3135273,"avatar_url":"https://avatars0.githubusercontent.com/u/3135273?v=4","gravatar_id":"","url":"https://api.github.com/users/johnyf","html_url":"https://github.com/johnyf","followers_url":"https://api.github.com/users/johnyf/followers","following_url":"https://api.github.com/users/johnyf/following{/other_user}","gists_url":"https://api.github.com/users/johnyf/gists{/gist_id}","starred_url":"https://api.github.com/users/johnyf/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/johnyf/subscriptions","organizations_url":"https://api.github.com/users/johnyf/orgs","repos_url":"https://api.github.com/users/johnyf/repos","events_url":"https://api.github.com/users/johnyf/events{/privacy}","received_events_url":"https://api.github.com/users/johnyf/received_events","type":"User","site_admin":false}],"milestone":{"url":"https://api.github.com/repos/tulip-control/polytope/milestones/4","html_url":"https://github.com/tulip-control/polytope/milestone/4","labels_url":"https://api.github.com/repos/tulip-control/polytope/milestones/4/labels","id":1481084,"number":4,"title":"0.2.1","description":"Bug fixes and minor improvements.","creator":{"login":"johnyf","id":3135273,"avatar_url":"https://avatars0.githubusercontent.com/u/3135273?v=4","gravatar_id":"","url":"https://api.github.com/users/johnyf","html_url":"https://github.com/johnyf","followers_url":"https://api.github.com/users/johnyf/followers","following_url":"https://api.github.com/users/johnyf/following{/other_user}","gists_url":"https://api.github.com/users/johnyf/gists{/gist_id}","starred_url":"https://api.github.com/users/johnyf/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/johnyf/subscriptions","organizations_url":"https://api.github.com/users/johnyf/orgs","repos_url":"https://api.github.com/users/johnyf/repos","events_url":"https://api.github.com/users/johnyf/events{/privacy}","received_events_url":"https://api.github.com/users/johnyf/received_events","type":"User","site_admin":false},"open_issues":0,"closed_issues":7,"state":"open","created_at":"2016-01-03T16:04:49Z","updated_at":"2017-10-07T06:11:06Z","due_on":null,"closed_at":null},"comments":4,"created_at":"2015-11-06T17:52:32Z","updated_at":"2017-10-09T23:23:37Z","closed_at":"2017-09-19T07:54:41Z","author_association":"CONTRIBUTOR","body":"When running the version of polytope in branch `scipysolver` (as of 524f4c59782ccc31ab776ddf605ead4cb3c6de5e) with both `scipy` and `cvxopt` installed, it may be beneficial to have the ability to easily choose which solver is to be used. Below is a possible implementation of this to go in `polytope.py`:\n\n``` python\ndef set_solver(solver):\n    if solver == 'scipy':\n        from scipy import optimize\n        global optimize\n        global lp_solver\n        lp_solver = 'scipy'\n    if solver == 'glpk':\n        try:\n            from cvxopt import matrix, solvers\n            import cvxopt.glpk\n            from .esp import esp\n            global matrix\n            global solvers\n            global esp\n            global lp_solver\n            lp_solver = 'glpk'\n            # Hide optimizer output\n            solvers.options['show_progress'] = False\n            solvers.options['LPX_K_MSGLEV'] = 0\n            solvers.options['msg_lev'] = 'GLP_MSG_OFF'\n        except:\n            raise Exception(\"unable to import cvxopt.glpk\")\n```\n\nChanging a global variable (`lp_solver`) may not be the best solution to switch between solvers but, given the current implementation, it is a relatively simple one. Are there any other thoughts on a safer or better way to implement this?\n"},"comment":{"url":"https://api.github.com/repos/tulip-control/polytope/issues/comments/335316011","html_url":"https://github.com/tulip-control/polytope/issues/17#issuecomment-335316011","issue_url":"https://api.github.com/repos/tulip-control/polytope/issues/17","id":335316011,"user":{"login":"johnyf","id":3135273,"avatar_url":"https://avatars0.githubusercontent.com/u/3135273?v=4","gravatar_id":"","url":"https://api.github.com/users/johnyf","html_url":"https://github.com/johnyf","followers_url":"https://api.github.com/users/johnyf/followers","following_url":"https://api.github.com/users/johnyf/following{/other_user}","gists_url":"https://api.github.com/users/johnyf/gists{/gist_id}","starred_url":"https://api.github.com/users/johnyf/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/johnyf/subscriptions","organizations_url":"https://api.github.com/users/johnyf/orgs","repos_url":"https://api.github.com/users/johnyf/repos","events_url":"https://api.github.com/users/johnyf/events{/privacy}","received_events_url":"https://api.github.com/users/johnyf/received_events","type":"User","site_admin":false},"created_at":"2017-10-09T23:23:37Z","updated_at":"2017-10-09T23:23:37Z","author_association":"OWNER","body":"Regarding the default choice, I commented [above](https://github.com/tulip-control/polytope/issues/17#issuecomment-330450784):\r\n\r\n> A global variable is present for this purpose anyway, in order to record what happened at import time. Reusing this variable is good enough.\r\n\r\nThis comment refers to the variable `lp_solver`:\r\n\r\nhttps://github.com/tulip-control/polytope/blob/f4c0cb4ce7bf60ad32d90e34770d4cefc2ce7af0/polytope/polytope.py#L87\r\n\r\nChanging this variable does change the default solver. However, the following corner case raises an error:\r\n\r\n1. install GLPK and `cvxopt.glpk`\r\n2. import `polytope`, so `lp_solver == 'glpk'`\r\n3. set the module variable `lp_solver = 'scipy'`\r\n4. call `polytope.lpsolve(..., solver='glpk')`\r\n\r\nThe error will be raised because the module now thinks that the best available solver is `scipy`, and that GLPK is unavailable, here:\r\n\r\nhttps://github.com/tulip-control/polytope/blob/f4c0cb4ce7bf60ad32d90e34770d4cefc2ce7af0/polytope/polytope.py#L2293\r\n\r\nSo changing `lp_solver` does change the package's default, but actually prevents direct calls to GLPK via `lpsolve`. There is no reason for this limitation. To avoid it, two separate module variables should be used:\r\n\r\n1. a hidden `set`-valued variable that records all solvers found installed at import time\r\n2. a visible variable that records the current default choice (e.g., `lp_solver`)\r\n\r\nSetting the default can remain as simple as it is now, with 2 choices, even when more solvers become available:\r\n\r\n1. if `scipy` is present but GLPK absent, choose `scipy` as default\r\n2. if `scipy` and GLPK are present, choose GLPK as default"}}
{"actor":{"display_login":"johnyf"}}