Comments (7)
Here is where I am at as regards base_dimension
A base_dimension is a globally unique entity within an application.
exponents of base_dimensions can be combined in a set known as a dimension.
For convenience c++ classes representing unique base_dimensions must be totally ordered at compile time.
Alternatively you have to restrict a base_dimension to a particular system e.g Newtonian Physics or Quantum Physics etc
Ideally you can plug in a set of base dimensions ( which meets the necessary requirements) to the units 'engine' and it will just work.
For myself I would hope there would be a standard <units/si_base_dimensions> header included.
In previous discussions, there used to be requests for options where e.g apple,oranges, pears are base dimensions ( money is another frequent request, though arguably far from being a compile time constant).
Ideally it should be possible to unplug (say) physical base_dimensions and plug in apples and pears base_dimensions or even append apples and pears to physical base dimensions. Even though apples and pears base_dimensions might seem ridiculous, yet it helps to use as a test case to verify separation of concerns in the library. For example The SI system can then be verified as a plug in to the basic units engine rather than being a dependency
from mp-units.
Hi, thanks for the review of a new design :-) You raised a few interesting questions here and well, even though I designed and implemented all of this I am not sure if I know how to answer them ;-)
We always had base_dimension
in the design but for now, it was fixed to one bae unit (i.e. physical length was always measured in metres even when we simulated CGS dimensions). This metre symbol was hardcoded in the base_dimension
implementation and independent from metre
unit defined for a derived dimension. It bothered me a lot. Also up to now, every base_dimension
was repeated as a derived one (i.e. length = <exp<base_dim_length, 1>> and only this one was later used to composed real derived dimensions like area or velocity. New design solves all of those problems.
Right now a physical dimension is still identified by a unique text identifier (i.e. "length") that is the most important part of the ordering (BTW, I fixed a potential bug there based on your comment, thanks! :-) ), but additionally gets a base unit that is adopted in a specific system of units. So:
namespace units::si {
struct dim_length : base_dimension<"length", metre> {};
struct dim_mass : base_dimension<"mass", kilogram> {};
struct dim_time : base_dimension<"time", second> {};
struct dim_current : base_dimension<"current", ampere> {};
struct dim_temperature : base_dimension<"temperature", kelvin> {};
struct dim_substance : base_dimension<"substance", mole> {};
struct dim_luminous_intensity : base_dimension<"luminous intensity", candela> {};
}
namespace units::cgs {
using si::centimetre;
using si::gram;
using si::second;
struct dim_length : base_dimension<"length", centimetre> {};
struct dim_mass : base_dimension<"mass", gram> {};
using si::dim_time;
}
You ask "Is there a dependency of base_dimension on the particular system(s) in use as suggested here?". I think that the answer is no. Base dimensions do not depend on a system. They define one. A set of base dimensions for all system's base quantities yields a system of those base quantities.
They are not closed to this system. You can freely mix base dimensions from different systems to form one derived dimension (if one wishes so).
One more use case for this feature is not strictly connected to define a system of units but opens the doors to provide units that have the same dimensions but different units in the numerator and denominator like the Hubble parameter mentioned by Vincent Reverdy in https://wg21.link/p1930.
BTW, if you would like to discuss some stuff more interactively please reach me on Cpplang Slack. I really value your feedback. Thanks!
from mp-units.
@mpusz That is very helpful. Thankyou.
from mp-units.
I am wondering about the uses of template strings to uniquely identify base_dimension. 2 issues.
- If I am writing a pre c++2a library ( as I am), then I can't use them easily
- You cant reuse the name returned by the base_dimension in different quantity systems.
For uniquely identifying base_dimension, an alternative to string is a UUID
https://en.wikipedia.org/wiki/Universally_unique_identifier
No need to re-invent the wheel here either, since there are already some UUIDs assigned for(nearly) the purpose in the bluetooth specification, which are at least a standardised useful starting point to work from.
https://www.bluetooth.com/specifications/assigned-numbers/units/
The numbers used there are so called 'short form' UUIDs which stand in for the full length UUIDs where the number there is added to a reserved value.
One could reserve 'short form' UUIDs and require custom base_dimensions to use the full length UUID
from mp-units.
This is a library using c++20 features. Strings as NTTP is only one of many C++20 features used there and all of them will be the reason for your code to not compile on a pre C++20 compiler. Also, I do not care much about other strange quantity systems. If it is a physical "length" than just reuse it with the same name and a unit that is a base unit for length for this system of units (this exactly why base_dimension
was refactored in a new design). If the length base dimension is really strange and does not conform to a physical system meaning of it than just it what it is a "strange length" as its identifier ;-)
With the above, I do not think that introducing UUID to the C++ Standard Library is a good idea here.
from mp-units.
OK.
I have one other issue. I think this thing we are calling base_dimension, should be called base_quantity
See here in middle of the page. https://physics.nist.gov/cuu/Units/units.html
I renamed things in one branch of my library and I think it is much easier to read.
from mp-units.
I am really open to bikeshedding of names if needed, but in this particular case, I have a really strong opinion.
First of all, please note that I am fully aware of the official terms and definitions. If you do not have access to ISO 80000, you can find most of them in chapter 4.1 of my paper: https://wg21.link/p1935.
It is true that officially the SI specs define quantity (divided to a base and derived quantity) and "just" a dimension (no base or derived) that is a list of exponents. If I would like to follow exactly this nomenclature than:
- Length and all other SI base quantities would be handled by
base_quantity
class template - All derived quantities would be handled by
derived_quantity
class template - Both
derived_quantity
andbase_quantity
class templates would have nearly the same interface (and this is the biggest and the most complicated class of the library) - Users would need to be aware when to instantiate a
derived_quantity
and when to instantiate abase_quantity
(also in a generic code)
However, please note that ISO 80000, even in the official definitions chapter, often mentions dimensions of base quantities which clearly states that base quantities also have their own dimensions ;-). For example, the definition of dimension looks as follows:
expression of the dependence of a quantity on the base quantities of a system of quantities as a product of powers of factors corresponding to the base quantities, omitting any numerical factor. A power of a factor is the factor raised to an exponent. Each factor is the dimension of a base quantity.
Above clearly states that base quantities have their own dimensions that then are used to form exponents of a "dimension" (in our case derived_dimension
). Also in the same derived dimension definition, there is a table that iterates all "symbols for dimensions" of "base quantities" (i.e. L
for length). which clearly states that dimensions of base quantities have unique identifiers.
This is why I believe that in this particular case we are really OK with our design. From the implementation point of view I have to know which factor of a derived dimension definition is a base quantity and which is a derived one because if I get a derived one from the user than I have to unpack it to a list of base quantities. This is why we need to have two strong types in the design:
base_dimension
derived_dimension
As you know both have also different properties (i.e. base_dimension
need a unique and sortable identifiers which is an implementation detail that ISO 80000 does not bother much about ;-) ).
I also believe that it is much easier for the user to have only one quantity
abstraction that handles both base and derived quantities. Splitting this would complicate writing generic code a lot.
from mp-units.
Related Issues (20)
- Should `quantity_point_like_traits` work on raw values?
- Consider using two types instead of values for the template parameters of the `reference` type HOT 1
- Bikeshedding `force_in(Unit)` HOT 10
- Change `mp-units/2.1.0` to `mp-units/2.0.0` in Conan installation steps? HOT 2
- Add support for easier math expressions in `mp-units/math.h` HOT 17
- Should we allow deriving from system entities? HOT 1
- No 2.1.0 in Conan center HOT 3
- ice_point definition is (very very slightly) incorrect
- Do we really need ASCII-only text output? HOT 13
- Text input support
- formatting/printing vector of quantities results in compile time error HOT 3
- Bazel build system support HOT 3
- Should conversions from the raw numerical value to a dimensionless quantity with a unit one be allowed? HOT 26
- Is mp-units targeting freestanding implementations HOT 6
- Provide `wchar_t` support for text output
- Effectively global unit names like 'm' are problematic HOT 35
- compilation time and how to improve it HOT 17
- Can't compile with localization disabled HOT 1
- Can't compile with exceptions disabled HOT 1
- Linker error with base units for "numerical_value_in()" HOT 4
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from mp-units.