{"action":"created","issue":{"url":"https://api.github.com/repos/sympy/sympy/issues/15565","repository_url":"https://api.github.com/repos/sympy/sympy","labels_url":"https://api.github.com/repos/sympy/sympy/issues/15565/labels{/name}","comments_url":"https://api.github.com/repos/sympy/sympy/issues/15565/comments","events_url":"https://api.github.com/repos/sympy/sympy/issues/15565/events","html_url":"https://github.com/sympy/sympy/pull/15565","id":385576388,"node_id":"MDExOlB1bGxSZXF1ZXN0MjM0NTEzNTg2","number":15565,"title":"Make the substitution of symbols consistent with powers of symbols","user":{"login":"normalhuman","id":13082030,"node_id":"MDQ6VXNlcjEzMDgyMDMw","avatar_url":"https://avatars1.githubusercontent.com/u/13082030?v=4","gravatar_id":"","url":"https://api.github.com/users/normalhuman","html_url":"https://github.com/normalhuman","followers_url":"https://api.github.com/users/normalhuman/followers","following_url":"https://api.github.com/users/normalhuman/following{/other_user}","gists_url":"https://api.github.com/users/normalhuman/gists{/gist_id}","starred_url":"https://api.github.com/users/normalhuman/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/normalhuman/subscriptions","organizations_url":"https://api.github.com/users/normalhuman/orgs","repos_url":"https://api.github.com/users/normalhuman/repos","events_url":"https://api.github.com/users/normalhuman/events{/privacy}","received_events_url":"https://api.github.com/users/normalhuman/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":1,"created_at":"2018-11-29T05:30:48Z","updated_at":"2018-11-29T12:58:23Z","closed_at":null,"author_association":"CONTRIBUTOR","pull_request":{"url":"https://api.github.com/repos/sympy/sympy/pulls/15565","html_url":"https://github.com/sympy/sympy/pull/15565","diff_url":"https://github.com/sympy/sympy/pull/15565.diff","patch_url":"https://github.com/sympy/sympy/pull/15565.patch"},"body":"#### References to other Issues or PRs\r\n\r\nFixes #6976. Closes #4514 which was already fixed; removed XFAIL from its test\r\n\r\n#### Brief description of what is fixed or changed\r\n\r\nThe `subs` method now applies the same logic to symbols as to their powers, by calling `Pow._eval_subs`. Old behavior:\r\n```\r\n>>> (log(x)**2/x).subs(1/x, u)\r\nu*log(x)**2\r\n```\r\nNew behavior:\r\n```\r\n>>> (log(x)**2/x).subs(1/x, u)\r\nu*log(1/u)**2\r\n```\r\nThis uncovered some issues with `manualintegrate`: it is prone to infinite recursion, which was previously prevented by the failure of subs. This is corrected as well.\r\n\r\n#### Other comments\r\n\r\nThe integral of `log(x)**2/x` becomes `log(1/u)**2/u` after `subs(1/x, u)`, and then another substitution `subs(1/u, v)` is made, returning to the original form. This did not happen before only because `subs` did not succeed in replacing x.\r\n\r\nThe dictionary `_integral_cache` of manualintegrate was meant to prevent infinite recursion but it never worked because each substitution introduces a new dummy, and dummy variables are considered different. For the above example, this dictionary would look like\r\n```\r\n{(log(x)**2/x, x): None,\r\n(log(1/_u)**2/_u, _u): None,\r\n(log(_u)**2/_u, _u): None,\r\n(log(1/_u)**2/_u, _u): None, \r\n(log(_u)**2/_u, _u): None, \r\n(log(1/_u)**2/_u, _u): None, \r\n(log(_u)**2/_u, _u): None, \r\n(log(1/_u)**2/_u, _u): None}\r\n```\r\nThis is corrected now by using the same dummy in all cached integrands. The type of return value after cache hit was fixed; as written, it would throw errors if there was ever a cache hit.\r\n\r\nAnother issue that came up is that the manual integration of `(x+1)/x` tried substitution `u = 1/x` before partial fractions, which resulted in a suboptimal form of the integrand (now that the substitution was successful). A clause is added to prevent substitution in a rational function when it increases its degree.\r\n\r\nTwo of manualintegrate tests now return cosmetically different (slightly simpler) expressions due to earlier exit when hitting the cache. \r\n\r\n#### Release Notes\r\n\r\n<!-- Write the release notes for this release below. See\r\nhttps://github.com/sympy/sympy/wiki/Writing-Release-Notes for more information\r\non how to write release notes. The bot will check your release notes\r\nautomatically to see if they are formatted correctly. -->\r\n\r\n<!-- BEGIN RELEASE NOTES -->\r\n* core\r\n  * substitution of powers of symbols is applied to those symbols as well\r\n* integrals\r\n  * manual integration algorithm is prevented from making infinite circular substitutions\r\n<!-- END RELEASE NOTES -->\r\n"},"comment":{"url":"https://api.github.com/repos/sympy/sympy/issues/comments/442824447","html_url":"https://github.com/sympy/sympy/pull/15565#issuecomment-442824447","issue_url":"https://api.github.com/repos/sympy/sympy/issues/15565","id":442824447,"node_id":"MDEyOklzc3VlQ29tbWVudDQ0MjgyNDQ0Nw==","user":{"login":"smichr","id":90703,"node_id":"MDQ6VXNlcjkwNzAz","avatar_url":"https://avatars3.githubusercontent.com/u/90703?v=4","gravatar_id":"","url":"https://api.github.com/users/smichr","html_url":"https://github.com/smichr","followers_url":"https://api.github.com/users/smichr/followers","following_url":"https://api.github.com/users/smichr/following{/other_user}","gists_url":"https://api.github.com/users/smichr/gists{/gist_id}","starred_url":"https://api.github.com/users/smichr/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/smichr/subscriptions","organizations_url":"https://api.github.com/users/smichr/orgs","repos_url":"https://api.github.com/users/smichr/repos","events_url":"https://api.github.com/users/smichr/events{/privacy}","received_events_url":"https://api.github.com/users/smichr/received_events","type":"User","site_admin":false},"created_at":"2018-11-29T12:58:23Z","updated_at":"2018-11-29T12:58:23Z","author_association":"MEMBER","body":"+1"}}
{"actor":{"display_login":"smichr"}}