[units] Creating specific unit quantities
In the Boost Unit documentation there are examples on creating quantities using a dimension. There doesn't seem to be any documentation on using a specific type of dimension as a quantity. Is it possible to create a quantity with a specific type of dimension value? using namespace boost::units; using namespace boost::units::si; quantity<length> L = 2.0*meters; //Is it possible to have meters instead of length as a quantity? quantity<???> L = 2.0 * meters; Ryan
On Tue, Mar 1, 2011 at 10:19 PM, Ryan <mccorywork@gmail.com> wrote:
Is it possible to create a quantity with a specific type of dimension value?
With some digging I've found that it's possible.
using namespace boost::units; using namespace boost::units::si;
quantity<length> L = 2.0*meters;
//Is it possible to have meters instead of length as a quantity? quantity<???> L = 2.0 * meters;
quantity<meter_base_unit::unit_type> L = 2.0 * meters; This quantity though doesn't naturally allow addition with quantity<length>. quantity<length> L = 2.0 * meters; quantity<meter_base_unit::unit_type> M = 3.0 * meters; quantity<length> N = L + M; This doesn't compile. The error is "Failed to specialize function template 'add_typeof_helpter'". If I explicit cast M to quantity<length> the code compiles. The si::length is the meter. So why is this occuring? Ryan
On Tue, Mar 1, 2011 at 10:19 PM, Ryan <mccorywork@gmail.com> wrote: Is it possible to create a quantity with a specific type of dimension value? With some digging I've found that it's possible.
using namespace boost::units; using namespace boost::units::si;
quantity<length> L = 2.0*meters;
//Is it possible to have meters instead of length as a quantity? quantity<???> L = 2.0 * meters;
quantity<meter_base_unit::unit_type> L = 2.0 * meters;
This quantity though doesn't naturally allow addition with quantity<length>.
quantity<length> L = 2.0 * meters; quantity<meter_base_unit::unit_type> M = 3.0 * meters;
quantity<length> N = L + M;
This doesn't compile. The error is "Failed to specialize function template 'add_typeof_helpter'". If I explicit cast M to quantity<length> the code compiles. The si::length is the meter. So why is this occuring?
I don't really understand what you're trying to accomplish. You might want to have a look at the "Why can't I construct a quantity directly from the value type?" section in the FAQ. That explains why "si::length" and "meters" are different things...basically, "meters" is an instance of si::length. Matthias
On Thu, Mar 3, 2011 at 12:02 PM, Matthias Schabel <boost@schabel-family.org>wrote:
I don't really understand what you're trying to accomplish.
I'm trying to add two quantities together. One quantity was created using the si system and the other was created directly.
That explains why "si::length" and "meters" are different things...basically, "meters" is an instance of si::length.
quantity<si::length> L = 2.0 * meters; I thought what this meant was a quantity value was being creating with the si::length dimension. The unit of measurement for si::length is the meter and therefore the value 2.0 is being stored as 2.0 meters. I thought this was confirmed when the display of the quantity value showed "2 m". If this isn't what is occurring could you shed some light on this? Ryan
On Thu, Mar 3, 2011 at 12:02 PM, Matthias Schabel <boost@schabel-family.org> wrote: I don't really understand what you're trying to accomplish.
I'm trying to add two quantities together. One quantity was created using the si system and the other was created directly.
Maybe http://www.boost.org/doc/libs/1_46_0/doc/html/boost_units/Quantities.html#bo...
I thought what this meant was a quantity value was being creating with the si::length dimension. The unit of measurement for si::length is the meter and therefore the value 2.0 is being stored as 2.0 meters. I thought this was confirmed when the display of the quantity value showed "2 m". If this isn't what is occurring could you shed some light on this?
quantity<si::length> is shorthand for quantity<si::length,double>. si::length is type representing a length in the SI system, so it encapsulates both the dimensionality of length and the specific measure of length.
On Thu, Mar 3, 2011 at 2:38 PM, Matthias Schabel <boost@schabel-family.org>wrote:
Maybe http://www.boost.org/doc/libs/1_46_0/doc/html/boost_units/Quantities.html#bo...
"implicit conversion between quantity<Unit1,Y> and quantity<Unit2,Z> is
allowed if Unit1 reduces to exactly the same combination of base units as Unit2 and if Y and Z are convertible." Doesn't si::length reduce to the base unit "si::meter_base_unit:unit_type"? If it doesn't what is the base unit of si::length?
quantity<si::length> is shorthand for quantity<si::length,double>. si::length is type representing a length in the SI system, so it encapsulates both the dimensionality of length and the specific measure of length.
I understand that si::length is a dimension. A value in a dimension has to have a particular unit of measurement. In the case of length a value can be either meters, kilometers, nanometers, centimeters, etc. The chosen unit of measurement for si::length is meters. Shouldn't I be able to create quantity of the si systems length (which is in meters) and a quantity of type meters and have them work together? Ryan
On Thu, Mar 3, 2011 at 2:38 PM, Matthias Schabel <boost@schabel-family.org> wrote:
Maybe http://www.boost.org/doc/libs/1_46_0/doc/html/boost_units/Quantities.html#bo...
"implicit conversion between quantity<Unit1,Y> and quantity<Unit2,Z> is allowed if Unit1 reduces to exactly the same combination of base units as Unit2 and if Y and Z are convertible."
Doesn't si::length reduce to the base unit "si::meter_base_unit:unit_type"? If it doesn't what is the base unit of si::length?
base_units and base_dimensions represent the "basis vectors" for units/unit systems, so no. If you look in boost/units/systems/si/length.hpp you can see that si::length is unit<length_dimension,si::system>. I'm still uclear on what you're trying to accomplish. Why don't you give a code snippet that does what you want to do? Matthias
On Thu, Mar 3, 2011 at 4:58 PM, Matthias Schabel <boost@schabel-family.org>wrote:
Why don't you give a code snippet that does what you want to do?
using namespace boost::units; class Test { public: void setX(quantity<si::length> const& x) { m_X = x; } private: quantity<si::length> m_X; }; int main(int, char const *[]) { typedef boost::units::us::foot_base::unit_type foot_unit; static const foot_unit foot; Test a; quantity<si::length> first (1.0 * si::meter); quantity<foot_unit> second(1.0 * foot); quantity<boost::units::si::meter_base_unit::unit_type> third (1.0 * si::meter); a.setX(first); a.setX(second); a.setX(third); return 0; }
On Thu, Mar 3, 2011 at 4:58 PM, Matthias Schabel <boost@schabel-family.org> wrote:
Why don't you give a code snippet that does what you want to do?
using namespace boost::units;
class Test { public: void setX(quantity<si::length> const& x) { m_X = x; } private: quantity<si::length> m_X; };
int main(int, char const *[]) {
typedef boost::units::us::foot_base::unit_type foot_unit; static const foot_unit foot;
Test a;
quantity<si::length> first (1.0 * si::meter); quantity<foot_unit> second(1.0 * foot); quantity<boost::units::si::meter_base_unit::unit_type> third (1.0 * si::meter);
a.setX(first); a.setX(second); a.setX(third);
return 0; }
#include <boost/units/quantity.hpp> #include <boost/units/systems/si.hpp> #include <boost/units/base_units/us/foot.hpp> using namespace boost::units; class Test { public: // takes any unit of length template<class System> void setX(quantity<unit<length_dimension,System> > const& x) { // explicit conversion to si::length = meters m_X = quantity<si::length>(x); } private: quantity<si::length> m_X; }; int main(int, char const *[]) { typedef boost::units::us::foot_base_unit::unit_type foot_unit; static const foot_unit foot; Test a; quantity<si::length> first (1.0 * si::meter); quantity<foot_unit> second(1.0 * foot); quantity<boost::units::si::meter_base_unit::unit_type> third (1.0 * si::meter); a.setX(first); a.setX(second); a.setX(third); return 0; }
On Mon, Mar 7, 2011 at 5:35 PM, Matthias Schabel <boost@schabel-family.org>wrote:
// takes any unit of length template<class System> void setX(quantity<unit<length_dimension,System> > const& x) { // explicit conversion to si::length = meters m_X = quantity<si::length>(x); }
Is the following set of statements correct. si::length has a length_dimension and is part of the si::system. boost::units::si:: meter_base_unit::unit_type has a length_dimension and is part of the si::system. boost::units::us::foot_base_unit::unit_type has a length_dimension and is part of the us system. Since an explicit conversion is needed I definitely don't understand the differences between the following three statements. I've included examples to show my limited understanding. implicit conversion of quantity<Unit,Y> to quantity<Unit,Z> is allowed if Yand Z are implicitly convertible. quantity<si::length, int> to quantity<si::length, double> explicit conversion between quantity<Unit1,Y> and quantity<Unit2,Z> is allowed if Unit1 and Unit2 have the same dimensions and if Y and Z are implicitly convertible. quantity<us::foot_base_unit::unit_type, int> to quantity<si::length, double> Both have the same length dimension. implicit conversion between quantity<Unit1,Y> and quantity<Unit2,Z> is allowed if Unit1 reduces to exactly the same combination of base units as Unit2 and if Y and Z are convertible. I'm not sure on the example for this one. Ryan
Is the following set of statements correct. si::length has a length_dimension and is part of the si::system.
Yes
boost::units::si::meter_base_unit::unit_type has a length_dimension and is part of the si::system.
No - it has length_dimension and is a part of its own system made up of meter_base_unit only.
boost::units::us::foot_base_unit::unit_type has a length_dimension and is part of the us system.
No - it has length_dimension and is a part of its own system made up of foot base_unit only
Since an explicit conversion is needed I definitely don't understand the differences between the following three statements. I've included examples to show my limited understanding.
implicit conversion of quantity<Unit,Y> to quantity<Unit,Z> is allowed if Y and Z are implicitly convertible.
quantity<si::length, int> to quantity<si::length, double>
Yes
explicit conversion between quantity<Unit1,Y> and quantity<Unit2,Z> is allowed if Unit1 and Unit2 have the same dimensions and if Y and Z are implicitly convertible.
quantity<us::foot_base_unit::unit_type, int> to quantity<si::length, double> Both have the same length dimension.
Yes
implicit conversion between quantity<Unit1,Y> and quantity<Unit2,Z> is allowed if Unit1 reduces to exactly the same combination of base units as Unit2 and if Y and Z are convertible.
You should look at how systems are defined, for example in <boost/units/base_unit.hpp> and <boost/units/systems/si/base.hpp>. Essentially, if you create a unit from a base_unit, the resulting unit exists in a system of its own containing only that base_unit. The reason for this is that multiple systems can share some of the same base_units : both SI and CGS have seconds as the base unit of time. Thus, if you didn't propagate information about the system, it would be possible to "forget" what system you were operating in. In general, when using Boost.Units you should assume that any conversions between units must be explicit. Matthias
On Mon, Mar 7, 2011 at 5:35 PM, Matthias Schabel <boost@schabel-family.org>wrote:
#include <boost/units/quantity.hpp> #include <boost/units/systems/si.hpp> #include <boost/units/base_units/us/foot.hpp>
using namespace boost::units;
class Test { public: // takes any unit of length template<class System> void setX(quantity<unit<length_dimension,System> > const& x) { // explicit conversion to si::length = meters m_X = quantity<si::length>(x); } private: quantity<si::length> m_X; };
void setY(quantity<unit<???, System> > const& y) { m_Y = quantity<si::dimensionless>(y); } I would like to be able to accept any systems dimensionless quantity. Since dimensionless isn't a physical system I obviously didn't find a tag I could use like length_dimension. What should I do here? Ryan
void setY(quantity<unit<???, System> > const& y) { m_Y = quantity<si::dimensionless>(y); }
I would like to be able to accept any systems dimensionless quantity. Since dimensionless isn't a physical system I obviously didn't find a tag I could use like length_dimension. What should I do here?
I'm getting the feeling that you're not trying very hard here... Look in the <boost/units> directory and you will find three headers : dimensionless_type.hpp, dimensionless_unit.hpp, and dimensionless_quantity.hpp, giving you a variety of options : template<class System,class Y> void setA(quantity<unit<dimensionless_type,System>,Y>&) { } template<class System,class Y> void setB(quantity<typename dimensionless_unit<System>::type,Y>&) { } template<class System,class Y> void setC(typename dimensionless_quantity<System,Y>::type&) { } Matthias
On Wed, Mar 16, 2011 at 6:13 PM, Matthias Schabel <boost@schabel-family.org>wrote:
Look in the <boost/units> directory and you will find three headers : dimensionless_type.hpp, dimensionless_unit.hpp, and dimensionless_quantity.hpp, giving you a variety of options :
Thank you for your help. Ryan
participants (2)
-
Matthias Schabel
-
Ryan