LCOV - code coverage report
Current view: top level - include/xo/unit - scaled_unit.hpp (source / functions) Hit Total Coverage
Test: out3.info Lines: 22 22 100.0 %
Date: 1980-01-01 00:00:00 Functions: 2 2 100.0 %

          Line data    Source code
       1             : /** @file scaled_unit2.hpp
       2             :  *
       3             :  *  Author: Roland Conybeare
       4             :  **/
       5             : 
       6             : #pragma once
       7             : 
       8             : #include "natural_unit.hpp"
       9             : 
      10             : namespace xo {
      11             :     namespace qty {
      12             :         /** @class bpu2_array_rescale_result
      13             :          *  @brief Represents the product sqrt(outer_scale_sq) * outer_scale_exact * nat_unit
      14             :          **/
      15             :         template <typename Int>
      16             :         struct scaled_unit {
      17          22 :             constexpr scaled_unit(const natural_unit<Int> & nat_unit,
      18             :                                    ratio::ratio<Int> outer_scale_exact,
      19             :                                    double outer_scale_sq)
      20          22 :                 : natural_unit_{nat_unit},
      21          22 :                   outer_scale_exact_{outer_scale_exact},
      22          22 :                   outer_scale_sq_{outer_scale_sq}
      23             :                 {}
      24             : 
      25             :             constexpr scaled_unit reciprocal() const {
      26             :                 return scaled_unit(nu_reciprocal(natural_unit_,
      27             :                                                  outer_scale_exact_.reciprocal(),
      28             :                                                  1.0 / outer_scale_sq_));
      29             :             }
      30             : 
      31             :             natural_unit<Int> natural_unit_;
      32             :             ratio::ratio<Int> outer_scale_exact_;
      33             :             double outer_scale_sq_;
      34             :         };
      35             : 
      36             :         namespace detail {
      37             :             template <typename Int>
      38             :             constexpr auto make_unit_rescale_result(const natural_unit<Int> & bpuv) {
      39             :                 return scaled_unit<Int>(bpuv,
      40             :                                         ratio::ratio<Int>(1, 1),
      41             :                                         1.0);
      42             :             }
      43             :         }
      44             : 
      45             :         namespace su2 {
      46             :             constexpr auto nanogram = detail::make_unit_rescale_result<std::int64_t>(nu2::nanogram);
      47             :             constexpr auto microgram = detail::make_unit_rescale_result<std::int64_t>(nu2::microgram);
      48             :         }
      49             : 
      50             :         namespace detail {
      51             :             template <typename Int>
      52             :             constexpr
      53             :             detail::bpu2_rescale_result<Int>
      54             :             bpu2_product(const bpu<Int> & lhs_bpu,
      55             :                          const bpu<Int> & rhs_bpu)
      56             :             {
      57             :                 assert(lhs_bpu.native_dim() == rhs_bpu.native_dim());
      58             : 
      59             :                 bpu<Int> prod_bpu = lhs_bpu;
      60             :                 auto rr = bpu_product_inplace(&prod_bpu, rhs_bpu);
      61             : 
      62             :                 return bpu2_rescale_result<Int>(prod_bpu,
      63             :                                                 rr.outer_scale_exact_,
      64             :                                                 rr.outer_scale_sq_);
      65             :             }
      66             : 
      67             :             template <typename Int>
      68             :             constexpr
      69             :             scaled_unit<Int>
      70             :             nu_bpu_product(const natural_unit<Int> & lhs_bpu_array,
      71             :                            const bpu<Int> & rhs_bpu)
      72             :             {
      73             :                 natural_unit<Int> prod = lhs_bpu_array;
      74             :                 auto rr = nu_product_inplace(&prod, rhs_bpu);
      75             : 
      76             :                 return scaled_unit<Int>(prod,
      77             :                                         rr.outer_scale_exact_,
      78             :                                         rr.outer_scale_sq_);
      79             :             };
      80             : 
      81             :             template <typename Int>
      82             :             constexpr
      83             :             scaled_unit<Int>
      84           3 :             nu_product(const natural_unit<Int> & lhs_bpu_array,
      85             :                        const natural_unit<Int> & rhs_bpu_array)
      86             :             {
      87           3 :                 natural_unit<Int> prod = lhs_bpu_array;
      88             : 
      89             :                 /* accumulate product of scalefactors spun off by rescaling
      90             :                  * any basis-units in rhs_bpu_array that conflict with the same dimension
      91             :                  * in lh_bpu_array
      92             :                  */
      93           3 :                 auto sfr = (detail::outer_scalefactor_result<Int>
      94           3 :                             (scalefactor_ratio_type(1, 1) /*outer_scale_exact*/,
      95             :                              1.0 /*outer_scale_sq*/));
      96             : 
      97           6 :                 for (std::size_t i = 0; i < rhs_bpu_array.n_bpu(); ++i) {
      98           3 :                     auto sfr2 = nu_product_inplace(&prod, rhs_bpu_array[i]);
      99             : 
     100           3 :                     sfr.outer_scale_exact_ = sfr.outer_scale_exact_ * sfr2.outer_scale_exact_;
     101           3 :                     sfr.outer_scale_sq_ *= sfr2.outer_scale_sq_;
     102             :                 }
     103             : 
     104             :                 return scaled_unit<Int>(prod,
     105             :                                          sfr.outer_scale_exact_,
     106           3 :                                          sfr.outer_scale_sq_);
     107             :             }
     108             : 
     109             :             template <typename Int>
     110             :             constexpr
     111             :             scaled_unit<Int>
     112          19 :             nu_ratio(const natural_unit<Int> & nu_lhs,
     113             :                      const natural_unit<Int> & nu_rhs)
     114             :             {
     115          19 :                 natural_unit<Int> ratio = nu_lhs;
     116             : 
     117             :                 /* accumulate product of scalefactors spun off by rescaling
     118             :                  * any basis-units in rhs_bpu_array that conflict with the same dimension
     119             :                  * in lh_bpu_array
     120             :                  */
     121          19 :                 auto sfr = (detail::outer_scalefactor_result<Int>
     122          19 :                             (scalefactor_ratio_type(1, 1) /*outer_scale_exact*/,
     123             :                              1.0 /*outer_scale_sq*/));
     124             : 
     125          38 :                 for (std::size_t i = 0; i < nu_rhs.n_bpu(); ++i) {
     126          19 :                     auto sfr2 = nu_ratio_inplace(&ratio, nu_rhs[i]);
     127             : 
     128             :                     /* note: nu_ratio_inplace() reports multiplicative outer scaling factors,
     129             :                      *       so multiply is correct here
     130             :                      */
     131          19 :                     sfr.outer_scale_exact_ = sfr.outer_scale_exact_ * sfr2.outer_scale_exact_;
     132          19 :                     sfr.outer_scale_sq_ *= sfr2.outer_scale_sq_;
     133             :                 }
     134             : 
     135             :                 return scaled_unit<Int>(ratio,
     136             :                                         sfr.outer_scale_exact_,
     137          19 :                                         sfr.outer_scale_sq_);
     138             :             }
     139             :         }
     140             : 
     141             :         template <typename Int>
     142             :         inline constexpr scaled_unit<Int>
     143             :         operator* (const scaled_unit<Int> & x_unit,
     144             :                    const scaled_unit<Int> & y_unit)
     145             :         {
     146             :             auto rr = detail::nu_product(x_unit.natural_unit_,
     147             :                                          y_unit.natural_unit_);
     148             : 
     149             :             return (scaled_unit<Int>
     150             :                     (rr.natural_unit_,
     151             :                      rr.outer_scale_exact_ * x_unit.outer_scale_exact_ * y_unit.outer_scale_exact_,
     152             :                      rr.outer_scale_sq_ * x_unit.outer_scale_sq_ * y_unit.outer_scale_sq_));
     153             :         }
     154             : 
     155             :         template <typename Int>
     156             :         inline constexpr scaled_unit<Int>
     157             :         operator/ (const scaled_unit<Int> & x_unit,
     158             :                    const scaled_unit<Int> & y_unit)
     159             :         {
     160             :             auto rr = detail::nu_ratio(x_unit.natural_unit_,
     161             :                                        y_unit.natural_unit_);
     162             : 
     163             :             return (scaled_unit<Int>
     164             :                     (rr.natural_unit_,
     165             :                      rr.outer_scale_exact_ * x_unit.outer_scale_exact_ * y_unit.outer_scale_exact_,
     166             :                      rr.outer_scale_sq_ * x_unit.outer_scale_sq_ * y_unit.outer_scale_sq_));
     167             :         }
     168             :     } /*namespace qty*/
     169             : } /*namespace xo*/
     170             : 
     171             : /** end scaled_unit2.hpp **/

Generated by: LCOV version 1.0