LaTeX 中物理常数的值

LaTeX 中物理常数的值

我想通过一些参考在我的 LaTeX 代码中使用物理常数的值。

据我了解,曼迪包似乎给出了物理常数的值,但我更喜欢物理包。我也考虑使用scipy.constants通过引用值pythontex 包。Pythontex 更好一些,但是它需要预|后编译。

你知道有什么包能以简单的方式给出物理常数的值吗?希望常数的数据集与 CODATA201{4..8} 相同。

答案1

虽然在很多情况下我认为这不是必要的,但既然你问了,我也想要这个。所以,我做了一些东西。

from scipy.constants import physical_constants as pc
import re
from math import ceil

filename = r'physical_constants.tex'
setup = r"""
\RequirePackage{etoolbox}
\RequirePackage{xparse}
\RequirePackage{siunitx}

\makeatletter

\def\physicalconstants@missingconstantmarker#1{%
    \ifx\@onlypreamble\@notprerr% only insert the marker when not in preamble
        {\textbf{??#1??}}%
    \fi
}
\def\physicalconstants@declare#1#2#3#4#5{% {name}{value}{unit}{uncertainty}
    \csdef{physicalconstants@#1@value}{#2}%
    \csdef{physicalconstants@#1@unit}{#3}%
    \csdef{physicalconstants@#1@uncertainty}{#4}%
    \csdef{physicalconstants@#1@uncertainvalue}{#5}%
}
\def\physicalconstants@blind@get#1#2{% {entry}{name}
    \csuse{physicalconstants@#2@#1}%
}
\def\physicalconstants@try#1{% {name}{subject}, gobbles subject if name is undefined
    \ifcsdef{physicalconstants@#1@value}{%
        \@firstofone
    }{%
        \GenericWarning{}{LaTeX Warning: I do not know the physical constant `#1'.}%
        \physicalconstants@missingconstantmarker{#1}%
        \@gobble
    }%
}
\def\physicalconstants@declarealias#1#2{% {new}{old}
    \physicalconstants@try{#2}{%
        \csdef{physicalconstants@#1@value}{\physicalconstants@blind@get{value}{#2}}%
        \csdef{physicalconstants@#1@unit}{\physicalconstants@blind@get{unit}{#2}}%
        \csdef{physicalconstants@#1@uncertainty}{\physicalconstants@blind@get{uncertainty}{#2}}%
        \csdef{physicalconstants@#1@uncertainvalue}{\physicalconstants@blind@get{uncertainvalue}{#2}}%
    }%
}
\def\physicalconstants@get#1#2{% {entry}{name}
    \physicalconstants@try{#2}{%
        \physicalconstants@blind@get{#1}{#2}%
    }%
}
\NewDocumentCommand\pcalias{}{% {new}{old}}
    \physicalconstants@declarealias
}
\NewDocumentCommand\pcget{}{% {entry}{name}
    \physicalconstants@get
}
\NewDocumentCommand\pcvalue{O{} m}{% [\num options]{name}
    \physicalconstants@try{#2}{%
        \num[#1]{\physicalconstants@blind@get{value}{#2}}%
    }%
}
\NewDocumentCommand\pcunit{O{} m}{% [\si options]{name}
    \physicalconstants@try{#2}{%
        \si[#1]{\physicalconstants@blind@get{unit}{#2}}%
    }%
}
\NewDocumentCommand\pcuncertainty{O{} m}{% [\num options]{name}
    \physicalconstants@try{#2}{%
        \num[#1]{\physicalconstants@blind@get{uncertainty}{#2}}%
    }%
}
\NewDocumentCommand\pcuncertainvalue{O{} m}{% [\num options]{name}
    \physicalconstants@try{#2}{%
        \num[#1]{\physicalconstants@blind@get{uncertainvalue}{#2}}%
    }%
}
\NewDocumentCommand\pc{O{} m}{% [\SI options]{name}
    \physicalconstants@try{#2}{%
        \SI[#1]{\physicalconstants@blind@get{value}{#2}}{\physicalconstants@blind@get{unit}{#2}}%
    }%
}
\NewDocumentCommand\pcu{O{} m}{% [\num options]{name}
    \physicalconstants@try{#2}{%
        \SI[#1]{\physicalconstants@blind@get{uncertainvalue}{#2}}{\physicalconstants@blind@get{unit}{#2}}%
    }%
}

"""
cleanup = r"""
\makeatother
"""

unit_map = {
    'A': r'\ampere',
    'C': r'\coulomb',
    'F': r'\farad',
    'GeV': r'\giga\electronvolt',
    'Hz': r'\hertz',
    'J': r'\joule',
    'K': r'\kelvin',
    'MHz': r'\mega\hertz',
    'MeV': r'\mega\electronvolt',
    'N': r'\newton',
    'Pa': r'\pascal',
    'S': r'\siemens',
    'T': r'\tesla',
    'V': r'\volt',
    'W': r'\watt',
    'Wb': r'\weber',
    'c': r'\clight',
    'eV': r'\electronvolt',
    'fm': r'\femto\meter',
    'kg': r'\kilogram',
    'm': r'\metre',
    'mol': r'\mole',
    'ohm': r'\ohm',
    's': r'\second',
    'sr': r'\steradian',
    'u': r'\atomicmassunit',
}
unit_regex = re.compile(r'\b([a-zA-Z]+)(?:\^(-?)(\d+))?\b')
number_regex = re.compile(r'([+-]?)(\d+)(\.?)(\d*)(e?)([+-]?\d*)')


def format_unit(unit_input):
    unit = ''
    for (base, sign, exp) in unit_regex.findall(unit_input):
        if sign:
            unit += r'\per'
        if exp == '1':
            pass
        elif exp == '2':
            unit += r'\square'
        elif exp == '3':
            unit += r'\cube'
        elif exp:
            unit += r'\raiseto{{{}}}'.format(exp)
        unit += unit_map[base]
    return unit
        
def format_uncertain_value(value_input, uncertainty_input):
    val_parts = number_regex.fullmatch(str(value_input)).groups()
    unc_parts = number_regex.fullmatch(str(uncertainty_input)).groups()
    unc_digits = unc_parts[1] + unc_parts[3]
    if int(unc_digits):
        val_exp = int(val_parts[5]) if val_parts[5] else 0
        unc_exp = int(unc_parts[5]) if unc_parts[5] else 0
        exp_discrepancy = ( (unc_exp - len(unc_parts[3]))
                           - (val_exp - len(val_parts[3])) )
        if exp_discrepancy < 0:
            # The uncertainty is too granular, we have to round.
            unc_digits = str(ceil(float('{}e{}'.format(unc_digits, exp_discrepancy))))
        else:
            # The uncertainty is missing some zeros at the end.
            unc_digits += '0' * exp_discrepancy
    else:
        unc_digits = '0'
    return '{0}{1}{2}{3}({6}){4}{5}'.format(*val_parts, unc_digits)

def main():
    with open(filename, 'w') as of:
        of.write(setup)
        for (name, entries) in pc.items():
            (value, unit, uncertainty) = entries
            of.write(r'\physicalconstants@declare{{{}}}{{{}}}{{{}}}{{{}}}{{{}}}'.format(
                            name,
                            value,
                            format_unit(unit),
                            uncertainty, 
                            format_uncertain_value(value, uncertainty))
                        + '\n')
        of.write(cleanup)
        
if __name__ == '__main__':
    main()

physical_constants.tex此 Python 脚本将创建包含 中的所有常量的文件scipy.constants.physical_constants。您可以\input将其放入您的序言中,并将其与所有常用siunitx功能一起使用。

\documentclass{article}

\usepackage[T1]{fontenc}
\usepackage[
    locale=DE,
    per-mode=fraction,
    quotient-mode=fraction,
    ]{siunitx}

\let\vectimes\times
\let\times\cdot

\input{physical_constants}

\pcalias{e}{elementary charge}
\pcalias{aSi}{lattice parameter of silicon}

\begin{document}

\pcvalue{aSi}

\pcunit{aSi}

\pcuncertainty{aSi}

\pcuncertainvalue{aSi}

\pc{aSi}

\pcu{aSi}

\pcu[separate-uncertainty]{aSi}

\pc{e}

\end{document}

MWE 输出


我没有对此进行过广泛的测试,也没有在设计上投入太多心思。请自行决定是否使用。当然,欢迎提供反馈和建议。如果我错了,并且这引起了很多兴趣,那么可能值得努力使其成为一个功能齐全的软件包。

相关内容