{"action":"opened","issue":{"url":"https://api.github.com/repos/HIPS/autograd/issues/254","repository_url":"https://api.github.com/repos/HIPS/autograd","labels_url":"https://api.github.com/repos/HIPS/autograd/issues/254/labels{/name}","comments_url":"https://api.github.com/repos/HIPS/autograd/issues/254/comments","events_url":"https://api.github.com/repos/HIPS/autograd/issues/254/events","html_url":"https://github.com/HIPS/autograd/issues/254","id":239680290,"number":254,"title":"Optimization performance worse with jacobian","user":{"login":"poliquin","id":360123,"avatar_url":"https://avatars2.githubusercontent.com/u/360123?v=3","gravatar_id":"","url":"https://api.github.com/users/poliquin","html_url":"https://github.com/poliquin","followers_url":"https://api.github.com/users/poliquin/followers","following_url":"https://api.github.com/users/poliquin/following{/other_user}","gists_url":"https://api.github.com/users/poliquin/gists{/gist_id}","starred_url":"https://api.github.com/users/poliquin/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/poliquin/subscriptions","organizations_url":"https://api.github.com/users/poliquin/orgs","repos_url":"https://api.github.com/users/poliquin/repos","events_url":"https://api.github.com/users/poliquin/events{/privacy}","received_events_url":"https://api.github.com/users/poliquin/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":0,"created_at":"2017-06-30T05:24:30Z","updated_at":"2017-06-30T05:24:30Z","closed_at":null,"body":"I am finding that the performance of `scipy.optimize` is worse when supplied with jacobian functions from autograd than without any function (i.e. using numerical differentiation).\r\n\r\nHere is a small example:\r\n\r\n```python\r\n\r\nfrom timeit import timeit\r\nimport autograd.numpy as np\r\nfrom autograd import jacobian\r\nfrom scipy import optimize\r\n\r\ndef test(x):\r\n    return np.sin(x)**2\r\n\r\ndef df(x):\r\n    return np.diag(2 * np.sin(x) * np.cos(x))\r\n\r\njac_test = jacobian(test)\r\n\r\n\r\ndef approx_j(x0, func, eps, *args):\r\n    \"\"\"Numerical jacobian.\"\"\"\r\n    f0 = func(*((x0, ) + args))\r\n    jac = np.zeros([len(x0), len(f0)])\r\n    dx = np.zeros(len(x0))\r\n    for i in range(len(x0)):\r\n        dx[i] = eps\r\n        jac[i] = (func(*((x0 + dx, ) + args)) - f0) / eps\r\n        dx[i] = 0.0\r\n    return jac.transpose()\r\n\r\n\r\n# confirm jacobian\r\nassert np.all(np.isclose(\r\n    jac_test(np.zeros(4)),\r\n    approx_j(np.zeros(4), test, 1e-8)\r\n))\r\nassert np.all(np.isclose(\r\n    df(np.zeros(4)),\r\n    approx_j(np.zeros(4), test, 1e-8)\r\n))\r\n\r\n# find root with and without jacobian\r\ns1 = optimize.root(\r\n    test, np.ones(4), method='hybr'\r\n)\r\ns2 = optimize.root(\r\n    test, np.ones(4), method='hybr', jac=jac_test\r\n)\r\ns3 = optimize.root(\r\n    test, np.ones(4), method='hybr', jac=df\r\n)\r\n\r\n# confirm same solution\r\nassert np.all(np.isclose(s1.x, s2.x))\r\nassert np.all(np.isclose(s1.x, s3.x))\r\n# using jacobian should require fewer function evaluations\r\nassert s2.nfev <= s1.nfev\r\nassert s3.nfev <= s1.nfev\r\n\r\n# timeit\r\ncmd = \"\"\"\r\noptimize.root(\r\n    test, np.ones(4), method='hybr'{}\r\n)\r\n\"\"\"\r\nprint(\r\n    'Without jacobian:',\r\n    timeit(cmd.format(''), globals=globals(), number=1000)\r\n)\r\nprint(\r\n    'With autograd jacobian:',\r\n    timeit(cmd.format(', jac=jac_test'), globals=globals(), number=1000)\r\n)\r\nprint(\r\n    'With analytical jacobian:',\r\n    timeit(cmd.format(', jac=df'), globals=globals(), number=1000)\r\n)\r\n```\r\n\r\nThe timings on my machine are:\r\n```\r\nWithout jacobian: 3.3757270729984157\r\nWith autograd jacobian: 4.7805181160219945\r\nWith analytical jacobian: 2.185655075998511\r\n```\r\n\r\nIs there a good rule of thumb for when supplying an autograd jacobian will improve `scipy.optimize` performance?\r\n\r\nThe above example is trivial, but my real application consists of solving more complicated fixed point problems and I get much slower performance using autograd than with numerical differentiation."}}
{"actor":{"display_login":"poliquin"}}