Replies: 8 comments 2 replies
-
Systems are there to map units to base dimensions. in SI: length -> meter What you are displaying wannot be achieved in practice since you can have combination of tour constants that can be reduced to the same results. That's why we are using base units. |
Beta Was this translation helpful? Give feedback.
-
As long as the constants/units are appropriately chosen, I think there should be a unique mapping to express any quantity in terms of those constants/units. It won't work for any arbitrary choice, of course -- they need to be complete (same number as the number of dimensions you're replacing) and independent. For example, say I want to replace the SI base units (meter, second) with (meter, c) instead -- c being the speed of light. If I want to express a quantity with dimensions [length]n[time]p in terms of (meter, c) then the only way to do it is as a multiple of mn+p c-p. So there's a unique mapping. You could just as well use [speed] as a base dimension instead of [time], and you could use "c" as your unit for speed. I understand if it's not worth doing in the implementation, but I do think it should in principle be possible. I'm pretty sure you could cast it as a matrix problem, so that the invertibility of the matrix determines whether you've chosen a "good" set of constants/units or not. |
Beta Was this translation helpful? Give feedback.
-
In case this is useful to anyone else, I wrote a function for this. I don't know that it's super efficient or handles all the edge cases appropriately, but it seems to work well enough for my purposes. It sets up a matrix equation to figure out the appropriate units to convert to, and then it uses numpy's pseudo-inverse function pinv to solve it. The tricky part is dealing with cases where the matrix ends up being non-square but there's nevertheless a unique solution (E.g., converting 1 m to {ft, hr}). Essentially, in these cases if you do the row reduction by hand, you'll end up with rows/columns of zeros that can be eliminated to turn it into a square matrix. Numerically that's a bit of a pain, so pseudo-inverse has the advantage of just always giving you a solution.
So as long as you've chosen your set of units well, it should work fine.
Some example conversions (I defined G = gravitational_constant for convenience): |
Beta Was this translation helpful? Give feedback.
-
Very nice implementation. 👍 I changed it a little such that
There might still be some redudancy in the sets, though.
|
Beta Was this translation helpful? Give feedback.
-
Ah. It currently works in SI units only ..., which does not meet aim of this issue |
Beta Was this translation helpful? Give feedback.
-
Could the same or similar algorithm be used to transform compound units in contexts? For example, currently we can use the |
Beta Was this translation helpful? Give feedback.
-
@jules-ch is right, right now systems are constrained to change the base units (not the base dimensions). Pint is very flexible. Everything (I mean everything) is specified in the definitions file. So right now, using the current Pint, you can write your own definition file in which the base dimensions are different and use it. Implementing a feature for systems that can change the base dimensions will require more work, but is also possible. |
Beta Was this translation helpful? Give feedback.
-
@hgrecco Sorry, I'm not sure I quite understand -- it's certainly possible now to have a system with the speed of light instead of time, for instance: import pint
ureg = pint.UnitRegistry()
SI_with_c = ureg.get_system("SI_with_c")
SI_with_c.base_units = {"second": {"meter": 1.0, "c": -1.0}}
ureg.default_system = "SI_with_c"
print((1 * ureg.metres / ureg.seconds).to_base_units())
# 3.3356409519815204e-09 <Unit('c')>
print((1 * ureg.seconds).to_base_units())
# 299792458.0 <Unit('meter / c')> Or do you mean automatically working out the base units conversion dict from a set of units? |
Beta Was this translation helpful? Give feedback.
-
Hi, I'm wondering if it's possible to define base units with different dimensions than the standard SI ones? Maybe I've misunderstood, but it seems like the
@system
definition approach complains if you try to define something like "eV" as a base unit (I got the error 'The new base must be a root dimension if not discarded unit is specified.')In some contexts of my work, it would be more convenient to use hbar, eV, and nm as base units in place of m, kg, s. You can always map any combination of (m, kg, s) into a combination of (hbar, eV, nm), so it would be nice if there was some simple function to do that.
To give a more concrete example, if you use Planck units as currently defined in the default unit definitions, then
Q_(4e8, 'm/s').to_base_units()
gets displayed as1.334... planck_length/planck_time
. Personally, I think it could be much nicer if the base units in the Planck unit system were actually 'c, gravitational_constant, hbar, k_C, k', so thatQ_(4e8, 'm/s').to_base_units()
would display as1.334... c
, andQ_(1, 'planck_length').to_base_units()
would display as1 hbar ** 0.5 * G ** 0.5 / c ** 1.5
.I'm sure I can write some conversion function to do this manually, but I wonder if there's already a convenient way to do it from within pint? If not using base units, even something like
my_quantity.to({'hbar', 'eV', 'nm'})
would be useful, where the argument is a set rather than a dictionary, and the to() function determines the appropriate exponents (if there's a valid conversion). Maybe that exists and I missed it?Regardless, thanks for all the work you've put into the package!
Beta Was this translation helpful? Give feedback.
All reactions