TransWikia.com

Store values in their SI units

TeX - LaTeX Asked on May 17, 2021

So I have to do a bunch of calculations with both imperial and metric units. What I am looking for is a way to store values in their SI form

  • Just an idea was to define storeval{name}{quantity}{unit} in such a way that it is easy to
    retrieve names quantity and unit. Any syntax along the way of unit{name},value{name},unitSI{name} and valueSI{name} would be great.
    Examples. Let storeval{boatspeed}{25}{kts} (knots) then value{boatspeed}=25,unit{boatspeed}=kts, unitSI{boatspeed}=m/s and unitSI{boatspeed}=12.8611.
  • As a bonus it would be nice to do some simple calculations with these units.
    For instance if storeval{boatspeed}{25}{kts} and storeval{distanceShore}{3}{nmi}
    I am interested in storing both the value and unit in metric (SI units) for distanceShore/boatspeed in a new variable in storeval.

Attempt

documentclass{article}
usepackage{xparse}
usepackage{siunitx}


ExplSyntaxOn

NewDocumentCommand{setfpvar}{mm}
 {
  fp_zero_new:c { nebu_var_#1_fp }
  fp_set:cn { nebu_var_#1_fp } { #2 }
 }

NewExpandableDocumentCommand{fv}{m}
 {
  fp_use:c { nebu_var_#1_fp }
 }

% make an internal function available to the user
cs_set_eq:NN fpeval fp_eval:n

msg_new:nnn
  { switchcase }
  { no-match }
  { There~is~no~entry~`#1'~in~the~switch~statement! }

NewDocumentCommand switchcase { m m }
  {
    str_case:nnF { #1 } { #2 } { msg_error:nnn { switchcase } { no-match } { #1 } }
  }
  
cs_set_eq:NN IfEmptyTF tl_if_blank:nTF

NewDocumentCommand{impIIsi}{m G{}}{
    IfEmptyTF{#2}%
            {unitIIsi{#1}}%
            {valueIIsi{#1}{#2}}%
}

NewExpandableDocumentCommand{valueIIsi}{m m}{
  switchcase{#2}%
  {
    % Distances
    {cm}{fpeval{#1/1000}} % centimeters
    {m}{#1}
    {km}{fpeval{1000*#1}} % kilometers
    {feet}{fpeval{0.3048*#1}}
    {ft}{fpeval{0.3048*#1}}
    {mi}{fpeval{1609*#1}} % english miles
    {M}{fpeval{1852*#1}}  % nautical miles
    {NM}{fpeval{1852*#1}} % nautical miles
    {nmi}{fpeval{1852*#1}} % nautical miles
    {au}{fpeval{149597870700*#1}} % astronomical unit
    %
    % Time
    {s}{#1} % 
    {sec}{#1} % 
    {d}{fpeval{86400*#1}}
    {day}{fpeval{86400*#1}}
    {min}{fpeval{3600*#1}} % minute
    {h}{fpeval{3600*#1}} % hour
    %
    % Weight
    {Da}{fpeval{1.66053906660*10^(−27)*#1}}
    {t}{fpeval{10^(3)*#1}} % tonne
    {lb}{fpeval{0.45359237*#1}}
    {slug}{fpeval{14.59390*#1}}
    %
    % Temperature
    {celcius}{fpeval{#1+273}}
    {C}{fpeval{#1+273}}
    {farenheit}{fpeval{(#1-32)*(5/9)+273}}
    {F}{fpeval{(#1-32)*(5/9)+273}}
  }%
}

NewExpandableDocumentCommand{unitIIsi}{m}{
  switchcase{#1}%
  {
    {cm}{m}
    {m}{m}
    {km}{m}
    {mi}{m}
    {M}{m}
    {NM}{m}
    {nmi}{m}
  }%
}

ExplSyntaxOff

DeclareSIUnitlbf{lbf}

begin{document}

setfpvar{boatlength}{5} % Saves the value 0.87 nautical miles in meters

setfpvar{boatweightLBF}{1}
setfpvar{boatweight}{%
  fv{boatweightLBF}*valueIIsi{1}{ft}*valueIIsi{1}{lb}/valueIIsi{1}{s}^2
}
setfpvar{boatArea}{%
  (valueIIsi{100}{ft})^2
}
setfpvar{pressureOnWater}{%
  fv{boatweight}/fv{boatArea}
}

The weight of the boat is 
SI{fv{boatweightLBF}}{lbf} or SI{fv{boatweight}}{newton}

end{document}

One Answer

Take a look at this framework.

documentclass{article}
usepackage{xparse}
usepackage{expl3}

ExplSyntaxOn

% functions to do numerical conversion
cs_set:cpn {uconv_func_ft_m} #1 {
    fp_eval:n {#1 / 3.2808}
}

cs_set:cpn {uconv_func_km/s_m/s} #1 {
    fp_eval:n {#1 / 3.6}
}

prop_new:N g_uconv_var_prop

% conversion between non-SI units to SI
prop_new:N g_uconv_unit_to_si_prop
prop_gset_from_keyval:Nn g_uconv_unit_to_si_prop {
    ft=m,
    km/s=m/s
}

newcommand{storeval}[3]{
    prop_gput:Nnn g_uconv_var_prop {#1} {{#2}{#3}}
}

tl_new:N l_uconv_tmpa_tl
tl_new:N l_uconv_tmpb_tl
tl_new:N l_uconv_tmpc_tl
tl_new:N l_uconv_tmpd_tl
tl_new:N l_uconv_tmpe_tl
tl_new:N l_uconv_tmpf_tl
tl_new:N l_uconv_tmpg_tl
tl_new:N l_uconv_unit_si_tl

newcommand{getval}[1]{
    prop_get:NnNTF g_uconv_var_prop {#1} l_uconv_tmpa_tl {
        tl_item:Nn l_uconv_tmpa_tl {1}
    } {
        GenericError{}{unable~to ~fetch~variable~#1}{}{}
    }
}

newcommand{getunit}[1]{
    prop_get:NnNTF g_uconv_var_prop {#1} l_uconv_tmpa_tl {
        tl_item:Nn l_uconv_tmpa_tl {2}
    } {
        GenericError{}{unable~to ~fetch~variable~#1}{}{}
    }
}

cs_set:Npn uconv_fetch_unit_si:n #1 {
    prop_get:NnNF g_uconv_unit_to_si_prop {#1} l_uconv_unit_si_tl {
        % if the unit to SI conversion cannot be found
        % assume the unit itself is already SI
        tl_set:Nn l_uconv_unit_si_tl {#1}
    }
}

newcommand{getunitSI}[1]{
    prop_get:NnNTF g_uconv_var_prop {#1} l_uconv_tmpa_tl {
        tl_set:Nx l_uconv_tmpb_tl {tl_item:Nn l_uconv_tmpa_tl {2}}
        exp_args:NV uconv_fetch_unit_si:n l_uconv_tmpb_tl
        tl_use:N l_uconv_unit_si_tl
    } {
        GenericError{}{unable~to~fetch~variable~#1}{}{}
    }
}

newcommand{getvalSI}[1]{
    prop_get:NnNTF g_uconv_var_prop {#1} l_uconv_tmpd_tl {
        tl_set:Nx l_uconv_tmpe_tl {tl_item:Nn l_uconv_tmpd_tl {1}}
        tl_set:Nx l_uconv_tmpf_tl {tl_item:Nn l_uconv_tmpd_tl {2}}
        exp_args:NV uconv_fetch_unit_si:n l_uconv_tmpf_tl
        tl_if_eq:NNTF l_uconv_tmpf_tl l_uconv_unit_si_tl {
            % do not convert if both are the same
            tl_use:N l_uconv_tmpe_tl
        } {
            cs_if_exist:cTF {uconv_func_ l_uconv_tmpf_tl _l_uconv_unit_si_tl} {
                use:c {uconv_func_ l_uconv_tmpf_tl _l_uconv_unit_si_tl} l_uconv_tmpe_tl
            } {
                GenericError{}{conversion~from~l_uconv_tmpf_tl ~to~l_uconv_unit_si_tl~does~not~exist}{}{}
            } 
        }
    } {
        GenericError{}{unable~to ~fetch~variable~#1}{}{}
    }
}

ExplSyntaxOff


begin{document}

storeval{boatlength}{5}{ft}
storeval{boatspeed}{3.5}{km/s}

getval{boatspeed}getunit{boatspeed}

getval{boatlength}getunit{boatlength}

getvalSI{boatlength}getunitSI{boatlength}

getvalSI{boatspeed}getunitSI{boatspeed}


end{document}

Answered by Alan Xiang on May 17, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP