diff --git a/include/xo/unit/basis_unit.hpp b/include/xo/unit/basis_unit.hpp index cd0b2a02..37281553 100644 --- a/include/xo/unit/basis_unit.hpp +++ b/include/xo/unit/basis_unit.hpp @@ -4,7 +4,7 @@ #include "ratio_util.hpp" namespace xo { - namespace obs { + namespace unit { /** @class basis_unit * * @brief A dimensionless multiple with natively-specified (i.e. at compile-time) dimension @@ -56,9 +56,9 @@ namespace xo { template constexpr auto native_unit_abbrev_v = native_unit_abbrev_helper::value; - // ----- scaled_native_unit_abbrev_helper ----- - namespace units { + // ----- scaled_native_unit_abbrev_helper ----- + /* Require: InnerScale is ratio type; InnerScale >= 1 */ template struct scaled_native_unit_abbrev; @@ -80,7 +80,7 @@ namespace xo { template constexpr auto scaled_native_unit_abbrev_v = scaled_native_unit_abbrev::value; } - } /*namespace obs*/ + } /*namespace unit*/ } /*namespace xo*/ /** end basis_unit.hpp **/ diff --git a/include/xo/unit/dim_util.hpp b/include/xo/unit/dim_util.hpp index 222f9c9e..ad2f3496 100644 --- a/include/xo/unit/dim_util.hpp +++ b/include/xo/unit/dim_util.hpp @@ -2,10 +2,11 @@ #pragma once + #include "stringliteral.hpp" namespace xo { - namespace obs { + namespace unit { enum class dim { /** weight. native unit = 1 gram **/ mass, @@ -52,8 +53,7 @@ namespace xo { template constexpr auto native_unit_for_v = native_unit_for::value; - } /*namespace obs*/ + } /*namespace unit*/ } /*namespace xo*/ - /* end dim_util.hpp */ diff --git a/include/xo/unit/dimension_concept.hpp b/include/xo/unit/dimension_concept.hpp index c1514e40..6277b621 100644 --- a/include/xo/unit/dimension_concept.hpp +++ b/include/xo/unit/dimension_concept.hpp @@ -3,10 +3,9 @@ #pragma once #include "native_bpu_concept.hpp" -//#include namespace xo { - namespace obs { + namespace unit { /** checks most non-empty BPU (basis power unit) node types; * cannot check BpuList::rest_type, because concept definition * can't (as of c++23) be recursive. @@ -83,7 +82,7 @@ namespace xo { && (ratio_concept && bpu_list_concept && bpu_list_concept); - } /*namespace obs*/ + } /*namespace unit*/ } /*namespace xo*/ /* end dimension_concept.hpp */ diff --git a/include/xo/unit/dimension_impl.hpp b/include/xo/unit/dimension_impl.hpp index 7a8e7aff..d51c655c 100644 --- a/include/xo/unit/dimension_impl.hpp +++ b/include/xo/unit/dimension_impl.hpp @@ -17,7 +17,7 @@ namespace xo { * - bpu_list -> bpu_node */ - namespace obs { + namespace unit { // ----- lookup_bpu ----- /** @@ -510,7 +510,7 @@ namespace xo { template using canonical_t = canonical_impl::dim_type; - } /*namespace obs*/ + } /*namespace unit*/ } /*namespace xo*/ /* end dimension_impl.hpp */ diff --git a/include/xo/unit/native_bpu.hpp b/include/xo/unit/native_bpu.hpp index a3e716a0..44e1a54d 100644 --- a/include/xo/unit/native_bpu.hpp +++ b/include/xo/unit/native_bpu.hpp @@ -7,7 +7,7 @@ #include namespace xo { - namespace obs { + namespace unit { // ----- native_bpu ----- /** @class native_bpu @@ -253,7 +253,7 @@ namespace xo { _p_type /*Power*/ >; }; - } /*namespace obs*/ + } /*namespace unit*/ } /*namespace xo*/ /* end native_bpu.hpp */ diff --git a/include/xo/unit/native_bpu_concept.hpp b/include/xo/unit/native_bpu_concept.hpp index 776e18bf..f72c60ca 100644 --- a/include/xo/unit/native_bpu_concept.hpp +++ b/include/xo/unit/native_bpu_concept.hpp @@ -7,7 +7,7 @@ #include namespace xo { - namespace obs { + namespace unit { /** * e.g. see native_bpu> * @@ -35,8 +35,7 @@ namespace xo { && (std::is_signed_v)) // && std::copyable ; - } /*namespace obs*/ + } /*namespace unit*/ } /*namespace xo*/ - /* end native_bpu_concept.hpp */ diff --git a/include/xo/unit/quantity.hpp b/include/xo/unit/quantity.hpp index 286a9e16..adb6cf80 100644 --- a/include/xo/unit/quantity.hpp +++ b/include/xo/unit/quantity.hpp @@ -8,7 +8,7 @@ //#include "xo/indentlog/scope.hpp" namespace xo { - namespace obs { + namespace unit { /** @class promoter * * Aux class assister for quantity::promote() @@ -35,7 +35,7 @@ namespace xo { * - Repr * Repr -> Repr * - Repr / Repr -> Repr **/ - template //, typename RequiredDimensionType = Unit> + template class quantity { public: using unit_type = Unit; @@ -415,7 +415,7 @@ namespace xo { }; template - inline auto kilograms(Repr x) -> quantity { + inline auto kilograms(Repr x) -> quantity { return quantity::promote(x); }; @@ -495,7 +495,7 @@ namespace xo { return quantity::promote(x); } } /*namespace qty*/ - } /*namespace obs*/ + } /*namespace unit*/ } /*namespace xo*/ /* end quantity.hpp */ diff --git a/include/xo/unit/quantity_concept.hpp b/include/xo/unit/quantity_concept.hpp index 963a0246..09d33446 100644 --- a/include/xo/unit/quantity_concept.hpp +++ b/include/xo/unit/quantity_concept.hpp @@ -5,7 +5,7 @@ #include namespace xo { - namespace obs { + namespace unit { template concept quantity_concept = requires(Quantity qty, typename Quantity::repr_type repr) { @@ -17,5 +17,5 @@ namespace xo { { Quantity::unit_quantity() } -> std::same_as; { Quantity::promote(repr) } -> std::same_as; }; - } /*namespace obs*/ + } /*namespace unit*/ } /*namespace xo*/ diff --git a/include/xo/unit/ratio_concept.hpp b/include/xo/unit/ratio_concept.hpp index 3308b1f1..ecfeb4bf 100644 --- a/include/xo/unit/ratio_concept.hpp +++ b/include/xo/unit/ratio_concept.hpp @@ -5,9 +5,9 @@ #include namespace xo { - namespace obs { + namespace unit { template concept ratio_concept = (std::is_signed_v && std::is_signed_v); - } /*namespace obs*/ + } /*namespace unit*/ } /*namespace xo*/ diff --git a/include/xo/unit/ratio_util.hpp b/include/xo/unit/ratio_util.hpp index 7695db3d..1d7e3199 100644 --- a/include/xo/unit/ratio_util.hpp +++ b/include/xo/unit/ratio_util.hpp @@ -8,7 +8,7 @@ #include namespace xo { - namespace obs { + namespace unit { // ----- ratio_floor ----- template @@ -236,7 +236,7 @@ namespace xo { return exponent2str_aux().value; }; - } /*namespace obs*/ + } /*namespace unit*/ } /*namespace xo*/ /* end ratio_util.hpp */ diff --git a/include/xo/unit/stringliteral.hpp b/include/xo/unit/stringliteral.hpp index c6bc6243..b3e68fe8 100644 --- a/include/xo/unit/stringliteral.hpp +++ b/include/xo/unit/stringliteral.hpp @@ -8,7 +8,7 @@ #include namespace xo { - namespace obs { + namespace unit { // ----- stringliteral ----- @@ -164,7 +164,7 @@ namespace xo { static constexpr auto value = stringliteral_concat("-", _suffix.value_); }; - } /*namespace obs*/ + } /*namespace unit*/ } /*namespace xo*/ /* end stringliteral.hpp */ diff --git a/include/xo/unit/unit.hpp b/include/xo/unit/unit.hpp index d081077e..b8b8c1b9 100644 --- a/include/xo/unit/unit.hpp +++ b/include/xo/unit/unit.hpp @@ -1,11 +1,11 @@ -/* @file dimension.hpp */ +/* @file unit.hpp */ #pragma once #include "dimension_impl.hpp" namespace xo { - namespace obs { + namespace unit { // ----- wrap_unit ----- template @@ -26,6 +26,7 @@ namespace xo { // ----- normalize_unit ----- + /* like Unit, but with scalefactor 1 */ template struct normalize_unit { static_assert(unit_concept); @@ -239,7 +240,7 @@ namespace xo { using milligram = wrap_unit< std::ratio<1>, bpu_node< bpu> > >; + std::ratio<1, 1000>> > >; template <> struct scaled_native_unit_abbrev> { @@ -248,10 +249,10 @@ namespace xo { using gram = wrap_unit< std::ratio<1>, bpu_node< bpu> > >; + std::ratio<1>> > >; using kilogram = wrap_unit< std::ratio<1>, bpu_node< bpu> > >; + std::ratio<1000>> > >; template <> struct scaled_native_unit_abbrev> { @@ -385,10 +386,8 @@ namespace xo { using price = wrap_unit< std::ratio<1>, bpu_node< bpu> > >; - } - - } /*namespace obs*/ + } /*namespace units*/ + } /*namespace unit*/ } /*namespace xo*/ - -/* end dimension.hpp */ +/* end unit.hpp */ diff --git a/utest/quantity.test.cpp b/utest/quantity.test.cpp index 8274012c..352ca2c5 100644 --- a/utest/quantity.test.cpp +++ b/utest/quantity.test.cpp @@ -9,31 +9,32 @@ #include namespace xo { - using xo::obs::quantity; + using xo::unit::quantity; - using xo::obs::qty::milliseconds; - using xo::obs::qty::seconds; - using xo::obs::qty::minutes; - using xo::obs::qty::volatility30d; - using xo::obs::qty::volatility250d; + using xo::unit::qty::kilograms; + using xo::unit::qty::milliseconds; + using xo::unit::qty::seconds; + using xo::unit::qty::minutes; + using xo::unit::qty::volatility30d; + using xo::unit::qty::volatility250d; - using xo::obs::unit_find_bpu_t; - using xo::obs::unit_conversion_factor_t; - using xo::obs::unit_cartesian_product_t; - using xo::obs::unit_cartesian_product; - using xo::obs::unit_invert_t; - using xo::obs::unit_abbrev_v; - using xo::obs::same_dimension_v; - using xo::obs::dim; + using xo::unit::unit_find_bpu_t; + using xo::unit::unit_conversion_factor_t; + using xo::unit::unit_cartesian_product_t; + using xo::unit::unit_cartesian_product; + using xo::unit::unit_invert_t; + using xo::unit::unit_abbrev_v; + using xo::unit::same_dimension_v; + using xo::unit::dim; - using xo::obs::from_ratio; - using xo::obs::stringliteral_from_ratio; - using xo::obs::ratio2str_aux; - using xo::obs::cstr_from_ratio; + using xo::unit::from_ratio; + using xo::unit::stringliteral_from_ratio; + using xo::unit::ratio2str_aux; + using xo::unit::cstr_from_ratio; using xo::reflect::Reflect; - namespace units = xo::obs::units; + namespace units = xo::unit::units; namespace ut { /* use 'testcase' snippet to add test cases here */ @@ -626,7 +627,7 @@ namespace xo { //auto rng = xo::rng::xoshiro256ss(seed); - scope log(XO_DEBUG2(c_debug_flag, "TEST_CASE.mult2")); + scope log(XO_DEBUG2(c_debug_flag, "TEST_CASE.div4")); //log && log("(A)", xtag("foo", foo)); auto q1 = volatility250d(0.2); @@ -647,6 +648,41 @@ namespace xo { CHECK(r == Approx(0.692820323).epsilon(1e-6)); } /*TEST_CASE(div4)*/ + + TEST_CASE("muldiv5", "[quantity]") { + constexpr bool c_debug_flag = true; + + // can get bits from /dev/random by uncommenting the 2nd line below + //uint64_t seed = xxx; + //rng::Seed seed; + + //auto rng = xo::rng::xoshiro256ss(seed); + + scope log(XO_DEBUG2(c_debug_flag, "TEST_CASE.muldiv5")); + //log && log("(A)", xtag("foo", foo)); + + auto t = milliseconds(10); + auto m = kilograms(2.5); + + auto a = m / (t * t); + + /* 0.1/sqrt(30dy) ~ 0.288675/sqrt(250dy), + * so q1/q2 ~ 0.6928 + */ + + log && log(XTAG(m), XTAG(t), xtag("a=m.t^-2", a)); + + /* verify dimensions of result + sticky units */ + CHECK(strcmp(t.unit_cstr(), "ms") == 0); + CHECK(strcmp(m.unit_cstr(), "kg") == 0); + CHECK(strcmp(a.unit_cstr(), "kg.ms^-2") == 0); + + CHECK(a.scale() == 0.025); + + /* verify scale of result */ + //CHECK(r == Approx(0.692820323).epsilon(1e-6)); + + } /*TEST_CASE(div4)*/ } /*namespace ut*/ } /*namespace xo*/ diff --git a/utest/unit.test.cpp b/utest/unit.test.cpp index bccc5d47..d3ea40bf 100644 --- a/utest/unit.test.cpp +++ b/utest/unit.test.cpp @@ -14,33 +14,33 @@ namespace xo { using xo::reflect::Reflect; - using xo::obs::dim; - using xo::obs::native_unit_abbrev_v; - using xo::obs::units::scaled_native_unit_abbrev_v; - //using xo::obs::native_dim_abbrev; - using xo::obs::stringliteral_compare; - using xo::obs::literal_size_v; - using xo::obs::stringliteral_from_digit; - using xo::obs::stringliteral_from_int_v; - using xo::obs::stringliteral; + using xo::unit::dim; + using xo::unit::native_unit_abbrev_v; + using xo::unit::units::scaled_native_unit_abbrev_v; + //using xo::unit::native_dim_abbrev; + using xo::unit::stringliteral_compare; + using xo::unit::literal_size_v; + using xo::unit::stringliteral_from_digit; + using xo::unit::stringliteral_from_int_v; + using xo::unit::stringliteral; #ifndef __clang__ - using xo::obs::stringliteral_concat; - using xo::obs::stringliteral_from_ratio; - using xo::obs::bpu_assemble_abbrev_helper; - using xo::obs::bpu_assemble_abbrev; + using xo::unit::stringliteral_concat; + using xo::unit::stringliteral_from_ratio; + using xo::unit::bpu_assemble_abbrev_helper; + using xo::unit::bpu_assemble_abbrev; #endif - using xo::obs::bpu_node; - using xo::obs::wrap_unit; - using xo::obs::unit_abbrev_v; - //using xo::obs::dim_abbrev_v; - using xo::obs::di_cartesian_product; - using xo::obs::di_cartesian_product1; - using xo::obs::unit_cartesian_product_t; - using xo::obs::bpu_cartesian_product; - using xo::obs::bpu_cartesian_product_helper; - using xo::obs::unit_invert_t; - using xo::obs::units::gram; - using xo::obs::units::second; + using xo::unit::bpu_node; + using xo::unit::wrap_unit; + using xo::unit::unit_abbrev_v; + //using xo::unit::dim_abbrev_v; + using xo::unit::di_cartesian_product; + using xo::unit::di_cartesian_product1; + using xo::unit::unit_cartesian_product_t; + using xo::unit::bpu_cartesian_product; + using xo::unit::bpu_cartesian_product_helper; + using xo::unit::unit_invert_t; + using xo::unit::units::gram; + using xo::unit::units::second; using xo::print::ccs; template @@ -180,74 +180,74 @@ namespace xo { scope log(XO_DEBUG2(c_debug_flag, "TEST_CASE.dimension")); //log && log("(A)", xtag("foo", foo)); - using t1 = obs::bpu>; + using t1 = unit::bpu>; - static_assert(t1::c_native_dim == obs::dim::currency); + static_assert(t1::c_native_dim == unit::dim::currency); static_assert(t1::power_type::num == 1); static_assert(t1::power_type::den == 1); - using t2 = obs::bpu, std::ratio<-1,2>>; + using t2 = unit::bpu, std::ratio<-1,2>>; - static_assert(t2::c_native_dim == obs::dim::time); + static_assert(t2::c_native_dim == unit::dim::time); static_assert(t2::power_type::num == -1); static_assert(t2::power_type::den == 2); using dim1 = wrap_unit, bpu_node>; using d1 = dim1::dim_type; /* ccy */ REQUIRE(unused_same()); - REQUIRE(unused_same::power_unit_type, t1>()); + REQUIRE(unused_same::power_unit_type, t1>()); #ifdef NOT_USING - static_assert(obs::lo_basis_elt_of::c_lo_basis == t1::c_basis); + static_assert(unit::lo_basis_elt_of::c_lo_basis == t1::c_basis); #endif - static_assert(obs::native_lo_bwp_of::bwp_type::c_index == 0); - static_assert(obs::native_lo_bwp_of::bwp_type::c_basis == obs::dim::currency); + static_assert(unit::native_lo_bwp_of::bwp_type::c_index == 0); + static_assert(unit::native_lo_bwp_of::bwp_type::c_basis == unit::dim::currency); using dim2 = wrap_unit, bpu_node>; using d2 = dim2::dim_type; /* t^(-1/2) */ REQUIRE(unused_same()); - REQUIRE(unused_same::power_unit_type, t2>()); - static_assert(obs::native_lo_bwp_of::bwp_type::c_index == 0); - static_assert(obs::native_lo_bwp_of::bwp_type::c_basis == obs::dim::time); + REQUIRE(unused_same::power_unit_type, t2>()); + static_assert(unit::native_lo_bwp_of::bwp_type::c_index == 0); + static_assert(unit::native_lo_bwp_of::bwp_type::c_basis == unit::dim::time); using dim3 = wrap_unit, bpu_node>>; using d3 = dim3::dim_type; /* ccy.t^(-1/2) */ - REQUIRE(unused_same::power_unit_type, t1>()); + REQUIRE(unused_same::power_unit_type, t1>()); { - using type = obs::lookup_bpu::power_unit_type; - //std::cerr << "obs::power_unit_of::power_unit_type" << xtag("type", reflect::type_name()) << std::endl; + using type = unit::lookup_bpu::power_unit_type; + //std::cerr << "unit::power_unit_of::power_unit_type" << xtag("type", reflect::type_name()) << std::endl; REQUIRE(unused_same()); } #ifdef NOT_USING - static_assert(obs::lo_basis_elt_of::c_lo_basis == t2::c_basis); + static_assert(unit::lo_basis_elt_of::c_lo_basis == t2::c_basis); #endif /* lowest is in pos 1, beacuse t2=time before t1=currency */ - static_assert(obs::native_lo_bwp_of::bwp_type::c_index == 1); + static_assert(unit::native_lo_bwp_of::bwp_type::c_index == 1); - static_assert(unused_same::dim_type, d2>()); - //using type = obs::without_elt::dim_type; - //std::cerr << "obs::without_elt::dim_type" << xtag("type", reflect::type_name()) << std::endl; - static_assert(unused_same::dim_type, d1>()); + static_assert(unused_same::dim_type, d2>()); + //using type = unit::without_elt::dim_type; + //std::cerr << "unit::without_elt::dim_type" << xtag("type", reflect::type_name()) << std::endl; + static_assert(unused_same::dim_type, d1>()); using d3b = wrap_unit, bpu_node>>::dim_type; /* t^(-1/2).ccy */ - //using d3b = obs::dimension_impl>; /* t^(-1/2).ccy */ - REQUIRE(unused_same::power_unit_type, t2>()); - REQUIRE(unused_same::power_unit_type, t1>()); + //using d3b = unit::dimension_impl>; /* t^(-1/2).ccy */ + REQUIRE(unused_same::power_unit_type, t2>()); + REQUIRE(unused_same::power_unit_type, t1>()); /* lowest is in pos 0 */ - static_assert(obs::native_lo_bwp_of::bwp_type::c_index == 0); + static_assert(unit::native_lo_bwp_of::bwp_type::c_index == 0); - static_assert(unused_same::dim_type, d1>()); - static_assert(unused_same::dim_type, d2>()); + static_assert(unused_same::dim_type, d1>()); + static_assert(unused_same::dim_type, d2>()); - static_assert(unused_same, obs::canonical_t>()); + static_assert(unused_same, unit::canonical_t>()); log && log(xtag("d1.abbrev", unit_abbrev_v.c_str())); log && log(xtag("d2.abbrev", unit_abbrev_v.c_str()));