Skip to content

Commit

Permalink
Fix macro hygiene in @constant, @derived_constant (missing `esc()…
Browse files Browse the repository at this point in the history
…`) (#36)

* Fix macro hygiene in constant definition macros

* Avoid hard-coding values of derived constants

* Fix argument names in `@derived_constant` docstring
  • Loading branch information
Socob authored Oct 7, 2024
1 parent 7d94def commit 72782d8
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 29 deletions.
49 changes: 26 additions & 23 deletions src/PhysicalConstants.jl
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,13 @@ _name(::PhysicalConstant{name,T,D,U}) where {name,T,D,U} = name

# Functions composing the building blocks of the macros

function _constant_preamble(name, sym, unit, def)
function _constant_preamble(name, sym, unit, val, def)
ename = esc(name)
qname = esc(Expr(:quote, name))
esym = esc(sym)
qsym = esc(Expr(:quote, sym))
eunit = esc(unit)
e_val = esc(val)
_bigconvert = isa(def,Symbol) ? quote
function _big(::PhysicalConstant{_name($ename),T,D,U}) where {T,D,U}
c = BigFloat()
Expand All @@ -45,25 +46,25 @@ function _constant_preamble(name, sym, unit, def)
end : quote
_big(::PhysicalConstant{_name($ename),T,D,U}) where {T,D,U} = $(esc(def))
end
return ename, qname, esym, qsym, eunit, _bigconvert
return ename, qname, esym, qsym, eunit, e_val, _bigconvert
end

function _constant_begin(qname, ename, esym, eunit, val, _bigconvert)
function _constant_begin(qname, ename, esym, eunit, e_val, _bigconvert)
quote
const $ename = PhysicalConstant{gensym($qname),Float64,dimension($eunit),typeof($eunit)}()
export $ename
const $esym = $ename

Base.float(::PhysicalConstant{_name($ename),T,D,U}) where {T,D,U} = $val * $eunit
Base.float(::PhysicalConstant{_name($ename),T,D,U}) where {T,D,U} = $e_val * $eunit
Base.float(FT::DataType, ::PhysicalConstant{_name($ename),T,D,U}) where {T,D,U} =
FT($val) * $eunit
FT($e_val) * $eunit
$_bigconvert
Base.big(x::PhysicalConstant{_name($ename),T,D,U}) where {T,D,U} = _big(x) * $eunit
Base.float(::Type{BigFloat}, x::PhysicalConstant{_name($ename),T,D,U}) where {T,D,U} = big(x)
end
end

function _constant_end(qname, ename, qsym, descr, val, reference, eunit)
function _constant_end(qname, ename, qsym, edescr, e_val, ereference, eunit)
quote
Measurements.measurement(::PhysicalConstant{_name($ename),T,D,U}) where {T,D,U} =
measurement(Float64, $ename)
Expand All @@ -73,13 +74,13 @@ function _constant_end(qname, ename, qsym, descr, val, reference, eunit)

function Base.show(io::IO, ::MIME"text/plain", x::PhysicalConstant{_name($ename),T,D,U}) where {T,D,U}
unc = uncertainty(ustrip(measurement($ename)))
println(io, $descr, " (", $qsym, ")")
println(io, $edescr, " (", $qsym, ")")
println(io, "Value = ", float($ename))
println(io, "Standard uncertainty = ",
iszero(unc) ? "(exact)" : unc * $eunit)
println(io, "Relative standard uncertainty = ",
iszero(unc) ? "(exact)" : round(unc / $val, sigdigits=2))
print(io, "Reference = ", $reference)
iszero(unc) ? "(exact)" : round(unc / $e_val, sigdigits=2))
print(io, "Reference = ", $ereference)
end

@assert isa(ustrip(float($ename)), Float64)
Expand Down Expand Up @@ -141,29 +142,31 @@ Reference = My lab notebook
```
"""
macro constant(name, sym, descr, val, def, unit, unc, bigunc, reference)
ename, qname, esym, qsym, eunit, _bigconvert = _constant_preamble(name, sym, unit, def)
ename, qname, esym, qsym, eunit, e_val, _bigconvert = _constant_preamble(name, sym, unit, val, def)
eunc = esc(unc)
ebigunc = esc(bigunc)
tag = Threads.atomic_add!(Measurements.tag_counter, UInt64(1))
quote
$(_constant_begin(qname, ename, esym, eunit, val, _bigconvert))
$(_constant_begin(qname, ename, esym, eunit, e_val, _bigconvert))

function Measurements.measurement(FT::DataType,
::PhysicalConstant{_name($ename),T,D,U}) where {T,D,U}
vl = FT($val)
vl = FT($e_val)
newder = Measurements.empty_der2(vl)
if iszero($unc)
return Measurement{FT}(vl, FT($unc), UInt64(0), newder) * $eunit
if iszero($eunc)
return Measurement{FT}(vl, FT($eunc), UInt64(0), newder) * $eunit
else
return Measurement{FT}(vl, FT($unc), $tag,
return Measurement{FT}(vl, FT($eunc), $tag,
Measurements.Derivatives(newder,
(vl, $unc, $tag)=>one(FT))) * $eunit
(vl, $eunc, $tag)=>one(FT))) * $eunit
end
end
function Measurements.measurement(::Type{BigFloat},
x::PhysicalConstant{_name($ename),T,D,U}) where {T,D,U}
vl = _big(x)
unc = BigFloat($bigunc)
unc = BigFloat($ebigunc)
newder = Measurements.empty_der2(vl)
if iszero($unc)
if iszero($eunc)
return Measurement{BigFloat}(vl, unc, UInt64(0), newder) * $eunit
else
return Measurement{BigFloat}(vl, unc, $tag,
Expand All @@ -172,12 +175,12 @@ macro constant(name, sym, descr, val, def, unit, unc, bigunc, reference)
end
end

$(_constant_end(qname, ename, qsym, esc(descr), val, reference, eunit))
$(_constant_end(qname, ename, qsym, esc(descr), e_val, esc(reference), eunit))
end
end

"""
@derived_constant(name, sym, descr, val, def, unit, unc, bigunc, reference) -> PhysicalConstant
@derived_constant(name, sym, descr, val, def, unit, measure64, measurebig, reference) -> PhysicalConstant
Macro to define a new [`PhysicalConstant`](@ref) derived from another existing `PhysicalConstant`.
Expand Down Expand Up @@ -221,9 +224,9 @@ Reference = My lab notebook
```
"""
macro derived_constant(name, sym, descr, val, def, unit, measure64, measurebig, reference)
ename, qname, esym, qsym, eunit, _bigconvert = _constant_preamble(name, sym, unit, def)
ename, qname, esym, qsym, eunit, e_val, _bigconvert = _constant_preamble(name, sym, unit, val, def)
quote
$(_constant_begin(qname, ename, esym, eunit, val, _bigconvert))
$(_constant_begin(qname, ename, esym, eunit, e_val, _bigconvert))

Measurements.measurement(::Type{Float64},
::PhysicalConstant{_name($ename),T,D,U}) where {T,D,U} =
Expand All @@ -235,7 +238,7 @@ macro derived_constant(name, sym, descr, val, def, unit, measure64, measurebig,
x::PhysicalConstant{_name($ename),T,D,U}) where {T,D,U} =
convert(Measurement{FT}, ustrip(measurement(x))) * $eunit

$(_constant_end(qname, ename, qsym, esc(descr), val, reference, eunit))
$(_constant_end(qname, ename, qsym, esc(descr), e_val, esc(reference), eunit))
end
end

Expand Down
3 changes: 2 additions & 1 deletion src/codata2014.jl
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ import PhysicalConstants: @constant, @derived_constant
J * s, 8.1e-42, 81/10_000_000_000_000_000_000_000_000_000_000_000_000_000_000,
"CODATA 2014")
@derived_constant(PlanckConstantOver2pi, ħ, "Planck constant over 2pi",
1.0545718001391127e-34, ustrip(big(h))/(2 * big(pi)), J * s,
convert(Float64, ustrip(big(h))/(2 * big(pi))),
ustrip(big(h))/(2 * big(pi)), J * s,
measurement(h)/2pi, measurement(BigFloat, h)/(2 * big(pi)), "CODATA 2014")
@constant(BoltzmannConstant, k_B, "Boltzmann constant", 1.380_648_52e-23,
BigFloat(138_064_852)/BigFloat(10_000_000_000_000_000_000_000_000_000_000), J * K^-1,
Expand Down
13 changes: 8 additions & 5 deletions src/codata2018.jl
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ _νx(T) = find_zero((_νf, _Dνf), T(_νx0), Roots.Newton())
6_626_070_15/1_000_000_000_000_000_000_000_000_000_000_000_000_000_000,
J * s, 0.0, BigFloat(0.0), "CODATA 2018")
@derived_constant(ReducedPlanckConstant, ħ, "Reduced Planck constant",
1.0545718176461565e-34, ustrip(big(h))/(2 * big(pi)), J * s,
convert(Float64, ustrip(big(h))/(2 * big(pi))),
ustrip(big(h))/(2 * big(pi)), J * s,
measurement(h)/2pi, measurement(BigFloat, h)/(2 * big(pi)), "CODATA 2018")
@constant(BoltzmannConstant, k_B, "Boltzmann constant", 1.380_649e-23,
BigFloat(1_380_649)/BigFloat(100_000_000_000_000_000_000_000_000_000), J * K^-1,
Expand Down Expand Up @@ -77,14 +78,16 @@ _νx(T) = find_zero((_νf, _Dνf), T(_νx0), Roots.Newton())
@constant(AvogadroConstant, N_A, "Avogadro constant", 6.022_140_76e23,
BigFloat(602_214_076_000_000_000_000_000), mol^-1,
0.0, BigFloat(0.0), "CODATA 2018")
@derived_constant(MolarGasConstant, R, "Molar gas constant", 8.314_462_618_153_24,
@derived_constant(MolarGasConstant, R, "Molar gas constant",
convert(Float64, ustrip(big(N_A) * big(k_B))),
ustrip(big(N_A) * big(k_B)), J * mol^-1 * K^-1,
measurement(N_A) * measurement(k_B),
measurement(BigFloat, N_A) * measurement(BigFloat, k_B), "CODATA 2018")
@constant(RydbergConstant, R_∞, "Rydberg constant", 10_973_731.568_160,
BigFloat(10_973_731_568_160)/BigFloat(1_000_000), m^-1,
2.1e-5, BigFloat(21)/BigFloat(1_000_000), "CODATA 2018")
@derived_constant(StefanBoltzmannConstant, σ, "Stefan-Boltzmann constant", 5.670_374_419_184_4294e-8,
@derived_constant(StefanBoltzmannConstant, σ, "Stefan-Boltzmann constant",
convert(Float64, ustrip(2 * big(pi)^5 * big(k_B)^4 / (15 * big(h)^3 * big(c_0)^2))),
ustrip(2 * big(pi) ^ 5 * big(k_B) ^ 4 / (15 * big(h) ^ 3 * big(c_0) ^ 2)), W * m^-2 * K^-4,
(2 * pi ^ 5 * measurement(k_B) ^ 4) / (15 * measurement(h) ^ 3 * measurement(c_0) ^ 2),
(2 * big(pi) ^ 5 * measurement(BigFloat, k_B) ^ 4) / (15 * measurement(BigFloat, h) ^ 3 * measurement(BigFloat, c_0) ^ 2),
Expand All @@ -95,13 +98,13 @@ _νx(T) = find_zero((_νf, _Dνf), T(_νx0), Roots.Newton())
BigFloat(60)/BigFloat(1000_000_000_000_000_000_000_000_000_000_000_000_000),
"CODATA 2018")
@derived_constant(WienWavelengthDisplacementLawConstant, b, "Wien wavelength displacement law constant",
2.897_771_955_185_1727e-3,
convert(Float64, ustrip(big(h) * big(c_0) / (_λx(BigFloat) * big(k_B)))),
ustrip(big(h) * big(c_0) / (_λx(BigFloat) * big(k_B))), m * K,
measurement(h) * measurement(c_0) / (_λx0 * measurement(k_B)),
measurement(BigFloat, h) * measurement(BigFloat, c_0) / (_λx(BigFloat) * measurement(BigFloat, k_B)),
"CODATA 2018")
@derived_constant(WienFrequencyDisplacementLawConstant, b′, "Wien frequency displacement law constant",
5.878_925_757_646_825e10,
convert(Float64, ustrip(_νx(BigFloat) * big(k_B) / big(h))),
ustrip(_νx(BigFloat) * big(k_B) / big(h)), Hz / K,
_νx0 * measurement(k_B) / measurement(h),
_νx(BigFloat) * measurement(BigFloat, k_B) / measurement(BigFloat, h), "CODATA 2018")
Expand Down

0 comments on commit 72782d8

Please sign in to comment.