You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Allow non-scalar power for quantities, when dimensionless? #4764
A possible fix would be easy. Just replace this line by:
if function is np.power and result_unit != dimensionless_unscaled:
That would at least don't trigger the validation if the unit is u.m / u.m (same unit as numerator and denominator) but would still fail for u.m / u.cm (only equivalent units as numerator and denominator).
The problem boils down to:
a = np.array([2, 2, 2, 2]) * u.Unit('cm/cm')
a.unit is u.dimensionless_unscaled # False
a.unit == u.dimensionless_unscaled # True
But I don't know if that's performance-critical and I haven't checked the tests. I could do so if you want and there are no objections.
This may be part of a solution, but I'm fairly sure it would leave the unit as cm/cm, which I don't think is what we would want, so at the very least it needs to be something like
if function is np.power:
if result_unit == dimensionless_unscaled
result_unit = dimensionless_unscaled
else:
...
But it may be good to think of a method that gets units of u.m/u.cm work too. For that, I think we'd like to keep the present behaviour that, say (2*(u.m/u.cm))**3 yields 8 m3 / cm3, but if it is raised to an array or an irrational number, it would turn to dimensionless. So, I think the solution might be to keep the if statement as is, but further down one would do something like:
try:
p = validate_power(p)
except ValueError as exc:
# Array power; may be OK for dimensionless input.
try:
converters[0] = get_converter(units[0], dimensionless_unscaled)
except:
raise exc
I do wonder, though, if that isn't better done in validate_power itself...
Activity
pllim commentedon Apr 8, 2016
Given that
ais already effectively unitless, I am surprised that the behavior is inconsistent. Sounds like a bug to me.cdeil commentedon Apr 11, 2016
I agree this looks like a bug, or at least it's confusing / inconvenient.
Does anyone know what the proper fix would be?
Are there general performance concerns applying it (too many checks for quantity operations)?
pllim commentedon Apr 11, 2016
c/c @mhvk
MSeifert04 commentedon Apr 11, 2016
A possible fix would be easy. Just replace this line by:
That would at least don't trigger the validation if the unit is
u.m / u.m(same unit as numerator and denominator) but would still fail foru.m / u.cm(only equivalent units as numerator and denominator).The problem boils down to:
But I don't know if that's performance-critical and I haven't checked the tests. I could do so if you want and there are no objections.
pllim commentedon Apr 11, 2016
@MSeifert04 , that looks promising. Please submit a PR, thanks. 😃
mhvk commentedon Apr 11, 2016
This may be part of a solution, but I'm fairly sure it would leave the unit as
cm/cm, which I don't think is what we would want, so at the very least it needs to be something likeBut it may be good to think of a method that gets units of
u.m/u.cmwork too. For that, I think we'd like to keep the present behaviour that, say(2*(u.m/u.cm))**3yields8 m3 / cm3, but if it is raised to an array or an irrational number, it would turn to dimensionless. So, I think the solution might be to keep the if statement as is, but further down one would do something like:I do wonder, though, if that isn't better done in
validate_poweritself...MSeifert04 commentedon Apr 11, 2016
@mhvk But wouldn't that be inconsistent?
add,subtractalso keep the unit of the first operand without any attempt of decomposition.mhvk commentedon Apr 11, 2016
It would actually be similar for dimensionless:
i.e., a conversion to dimensionless is done if that is the only way to make the operation succeed.
But let's move the discussion to #4770...
MSeifert04 commentedon Apr 11, 2016
@mhvk In that case it's an operation with a NOT quantity. I've also noticed this and was investigating where that came from.
But just try:
a - 2. * u.dimensionless_unscaled. And you'll have a result-unit.