{"action":"created","issue":{"url":"https://api.github.com/repos/astropy/astropy/issues/3793","labels_url":"https://api.github.com/repos/astropy/astropy/issues/3793/labels{/name}","comments_url":"https://api.github.com/repos/astropy/astropy/issues/3793/comments","events_url":"https://api.github.com/repos/astropy/astropy/issues/3793/events","html_url":"https://github.com/astropy/astropy/pull/3793","id":79589918,"number":3793,"title":"Consider adding special \"arbitrary\" unit?","user":{"login":"embray","id":676149,"avatar_url":"https://avatars.githubusercontent.com/u/676149?v=3","gravatar_id":"","url":"https://api.github.com/users/embray","html_url":"https://github.com/embray","followers_url":"https://api.github.com/users/embray/followers","following_url":"https://api.github.com/users/embray/following{/other_user}","gists_url":"https://api.github.com/users/embray/gists{/gist_id}","starred_url":"https://api.github.com/users/embray/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/embray/subscriptions","organizations_url":"https://api.github.com/users/embray/orgs","repos_url":"https://api.github.com/users/embray/repos","events_url":"https://api.github.com/users/embray/events{/privacy}","received_events_url":"https://api.github.com/users/embray/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/astropy/astropy/labels/units","name":"units","color":"c7def8"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":23,"created_at":"2015-05-22T20:04:06Z","updated_at":"2015-06-15T18:34:17Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/astropy/astropy/pulls/3793","html_url":"https://github.com/astropy/astropy/pull/3793","diff_url":"https://github.com/astropy/astropy/pull/3793.diff","patch_url":"https://github.com/astropy/astropy/pull/3793.patch"},"body":"Something came up in working on models with units, that I thought might be useful.  Though if it's deemed too \"weird\" I could live without it (or perhaps this could be implemented just as a hack to use within the modeling package).\r\n\r\nThere are a couple of special cases in quantity arithmetic--namely the scalars `0.0` and `inf`, in that they may take \"arbitrary\" units (see [here](https://github.com/astropy/astropy/blob/44a166a104d72c2996cd18872a09f5759fc1bf86/astropy/units/quantity.py#L310)).  This allows expressions like the following:\r\n\r\n```python\r\nIn [3]: q = 1 * u.m\r\n\r\nIn [4]: q + 0\r\nOut[4]: <Quantity 1.0 m>\r\n```\r\n\r\nto be clear, this is only allowed at all with zero.  `q + 1` will raise an exception since you cannot add a quantity in meters to a dimensionless quantity (by default scalars get units of dimensionless_unscaled, *except* in the special case of zero and inf).  In fact, `q + 0` is different from `q + (0 * u.dimensionless_unscaled)`.  The latter is making it explicit that the zero we're adding must be a dimensionless quantity, and can't be added to meters.  This is a *good* design choice.\r\n\r\nHowever, it makes things a little inconvenient in how I'm trying to implement quantities in models.  What I would like to be able to do is when quantities are being used to evaluate a model, it is convenient to automatically convert all inputs to the model to `Quantity` objects (so that everything has a `.unit`).  In the spirit of how *most* `Quantity` arithmetic works, inputs without explicit quantities are automatically given units of `dimensionless_unscaled`.  However, I can't do this if the input is zero (or inf) because that actually gives different results than if the model were evaluated with the scalar `0.0`, with its ability to take arbitrary units.\r\n\r\nMaybe that's just something that should be rethought outright, though I think it would be confusing if models have different evaluation behavior from other ufuncs with respect to how they treat 0 when combining it with dimensionful quantities.\r\n\r\nSo I think it might be convenient to be able to create a Quantity whose value is either 0 or inf, and has a special unit called \"arbitrary\" that just implies the existing behavior of the bare 0/inf, as distinct from dimensionless_unscaled.  This would simplify a lot of code so I don't have to keep treating them as special cases."},"comment":{"url":"https://api.github.com/repos/astropy/astropy/issues/comments/112163435","html_url":"https://github.com/astropy/astropy/pull/3793#issuecomment-112163435","issue_url":"https://api.github.com/repos/astropy/astropy/issues/3793","id":112163435,"user":{"login":"mhvk","id":2789820,"avatar_url":"https://avatars.githubusercontent.com/u/2789820?v=3","gravatar_id":"","url":"https://api.github.com/users/mhvk","html_url":"https://github.com/mhvk","followers_url":"https://api.github.com/users/mhvk/followers","following_url":"https://api.github.com/users/mhvk/following{/other_user}","gists_url":"https://api.github.com/users/mhvk/gists{/gist_id}","starred_url":"https://api.github.com/users/mhvk/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mhvk/subscriptions","organizations_url":"https://api.github.com/users/mhvk/orgs","repos_url":"https://api.github.com/users/mhvk/repos","events_url":"https://api.github.com/users/mhvk/events{/privacy}","received_events_url":"https://api.github.com/users/mhvk/received_events","type":"User","site_admin":false},"created_at":"2015-06-15T18:34:17Z","updated_at":"2015-06-15T18:34:17Z","body":"@embray - `0 * Quantity(1.0, u.km)` should indeed have dimension `km` and thus not be allowed to be added to anything but lengths, but why should that determine what `0 * u.arbitrary * Quantity(1.0, u.km)` should do?\r\n\r\nFurther back to basics, I think it is obvious that `10 * (0. * u.arbitrary)` should not become dimensionless, since that would break commutativity, as it would be different from `(10 * 0) * u.abitrary`. Now we could let `(10.*u.dimensionless_unscaled) * (0. *u.arbitrary)` become dimensionless, though this is harder than my PR, since it is somewhat baked into `units` that any normal number is treated as if it were dimensionless. \r\n\r\nBut mostly I guess I don't quite see why we should generally enforce that something with arbitrary units can only hold 0, inf, or nan; that is not the usual definition at all. I do of course see that you want it in `models`, but I thought the main point was that you would just run `_can_have_arbitrary_units` once, and if it is true, you assign the parameter to a quantity with arbitrary units."}}