Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 1 addition & 5 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,21 +1,17 @@
name = "DiagHamInterface"
uuid = "2f27495d-c82b-46d5-b81b-1bb9aa58c4d5"
version = "1.1.0"
version = "1.1.1"
authors = ["Andreas Feuerpfeil <development@manybodylab.com>"]

[deps]
DelimitedFiles = "8bb1440f-4735-579b-a4ab-409b98df4dab"
Format = "1fa38f19-a742-5d3f-a2b9-30dd87b9d5f8"
Preferences = "21216c6a-2e73-6563-6e65-726566657250"
Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7"
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
ThreadSafeDicts = "4239201d-c60e-5e0a-9702-85d713665ba7"

[compat]
DelimitedFiles = "1"
Format = "1.3.7"
Preferences = "1.5.0"
Printf = "1"
SparseArrays = "1"
ThreadSafeDicts = "0.1.6"
julia = "1.10"
2 changes: 0 additions & 2 deletions src/DiagHamInterface.jl
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,8 @@ export write_to_txt
export write_matrix_elements

using DelimitedFiles
using Format
using SparseArrays
using Preferences
using ThreadSafeDicts

include("utility/backup.jl")
include("utility/diagham_path.jl")
Expand Down
60 changes: 23 additions & 37 deletions src/utility/numbers.jl
Original file line number Diff line number Diff line change
@@ -1,40 +1,26 @@
# Maps the format string (e.g. "%.5f") to the compiled formatter Function.
const LOCAL_FORMAT_CACHE = ThreadSafeDict{String, Function}()

"""
format_with_precision(x; atol=eps(float(T)), mode=:auto, maxdigits=20)
format_with_precision(x; atol=0.0, maxdigits=typemax(Int))

Format number `x` as a string with absolute precision `atol`.
Mode `:auto` uses `%f` for `[1e-3, 1e6)`, else `%e`. Use `:f` or `:e` to force format.
Format number `x` as a string with absolute precision `atol` and a maximum of
`maxdigits` significant digits.
Uses scientific notation for very small or large numbers.
"""
function format_with_precision(x::T; atol = eps(float(T)), mode::Symbol = :auto, maxdigits::Int = 20) where {T <: Real}
function format_with_precision(x::T; atol = 0.0, maxdigits::Int = typemax(Int)) where {T <: Real}
iszero(x) && return "0.0"
absx = abs(x)
abs_atol = abs(atol)

use_e = mode == :e || (mode == :auto && (absx < 1.0e-3 || absx >= 1.0e6))
if iszero(atol)
maxdigits == typemax(Int) && return string(x)
return string(round(x, sigdigits = maxdigits))
end

if use_e
exp10 = floor(Int, log10(absx))
log10_atol = log10(abs_atol)
p = ceil(Int, exp10 - log10_atol)
p = clamp(p, 0, maxdigits)
mag_x = floor(Int, log10(abs(x)))
mag_atol = floor(Int, log10(abs(atol)))

formatter = get_threadsafe_formatter("%.$(p)e")
return formatter(x)
else
p = ceil(Int, -log10(abs_atol))
p = clamp(p, 0, maxdigits)
required_sigdigits = max(1, mag_x - mag_atol + 1)
s = min(required_sigdigits, maxdigits)

formatter = get_threadsafe_formatter("%.$(p)f")
return formatter(x)
end
end

function get_threadsafe_formatter(fmtstr::String)
return get!(LOCAL_FORMAT_CACHE, fmtstr) do
Format.generate_formatter(fmtstr)
end
rounded_x = round(x, sigdigits = s)
return string(rounded_x)
end

read_number(V::Number) = V
Expand Down Expand Up @@ -64,18 +50,18 @@ function _read_number_bracket(V::AbstractString)
return ComplexF64(real, imag)
end

function write_number(V::Number; atol::Real = eps(real(float(V))))
return format_with_precision(V; atol = atol)
function write_number(V::Number; kwargs...)
return format_with_precision(V; kwargs...)
end

function write_number(V::Complex; atol::Real = eps(real(float(V))))
return string("(", format_with_precision(real(V); atol = atol), ",", format_with_precision(imag(V); atol = atol), ")")
function write_number(V::Complex; kwargs...)
return string("(", format_with_precision(real(V); kwargs...), ",", format_with_precision(imag(V); kwargs...), ")")
end

function write_number_space(V::Number; atol::Real = eps(real(float(V))))
return format_with_precision(V; atol = atol)
function write_number_space(V::Number; kwargs...)
return format_with_precision(V; kwargs...)
end

function write_number_space(V::Complex; atol::Real = eps(real(float(V))))
return "$(format_with_precision(real(V); atol = atol)) $(format_with_precision(imag(V); atol = atol))"
function write_number_space(V::Complex; kwargs...)
return "$(format_with_precision(real(V); kwargs...)) $(format_with_precision(imag(V); kwargs...))"
end
9 changes: 1 addition & 8 deletions test/test_basics.jl
Original file line number Diff line number Diff line change
Expand Up @@ -97,14 +97,7 @@ using Test
# Test normal range numbers
result = format_with_precision(1.5)
@test !occursin("e", result) && !occursin("E", result)

# Test with forced mode
result_e = format_with_precision(1.5; mode = :e)
@test occursin("e", result_e) || occursin("E", result_e)

result_f = format_with_precision(1.5; mode = :f)
@test !occursin("e", result_f) && !occursin("E", result_f)


# Test negative numbers
result_neg = format_with_precision(-1.5)
@test startswith(result_neg, "-")
Expand Down
Loading