@@ -10,7 +10,7 @@ struct LogQuantArray{T,N} <: AbstractArray{Unsigned,N}
1010end
1111
1212Base. size (QA:: LogQuantArray ) = size (QA. A)
13- Base. getindex (QA:: LogQuantArray ,i... ) = getindex (QA. A,i... )
13+ Base. getindex (QA:: LogQuantArray , i... ) = getindex (QA. A, i... )
1414Base. eltype (Q:: LogQuantArray{T,N} ) where {T,N} = T
1515
1616"""
@@ -21,7 +21,7 @@ Base.eltype(Q::LogQuantArray{T,N}) where {T,N} = T
2121"""
2222function minpos (A:: AbstractArray{T} ) where T
2323 o = zero (T)
24- mi = foldl ((x,y) -> y > o ? min (x,y) : x, A; init= typemax (T))
24+ mi = foldl ((x, y) -> y > o ? min (x, y) : x, A; init= typemax (T))
2525 mi == typemax (T) && return o
2626 return mi
2727end
@@ -39,7 +39,7 @@ Quantize elements of an array logarithmically into UInts with either round to ne
3939# Returns
4040- a LogQuantArray{T} with the quantised array and the minimum and maximum of the original range.
4141"""
42- function LogQuantization (
42+ function LogQuantization (
4343 :: Type{T} ,
4444 A:: AbstractArray ,
4545 round_nearest_in:: Symbol = :linspace
@@ -60,38 +60,86 @@ function LogQuantization(
6060 else
6161 # inverse log spacing
6262 # map min to 1 and max to ff..., reserve 0 for 0.
63- Δ⁻¹ = (2 ^ (sizeof (T)* 8 ) - 2 ) / (logmax- logmin)
64-
63+ Δ⁻¹ = (2 ^ (sizeof (T) * 8 ) - 2 ) / (logmax - logmin)
64+
6565 # shift to round-to-nearest in lin or log-space
6666 if round_nearest_in == :linspace
67- c = 1 / 2 - Δ⁻¹* log (mi* (exp (1 / Δ⁻¹)+ 1 ) / 2 )
67+ c = 1 / 2 - Δ⁻¹ * log (mi * (exp (1 / Δ⁻¹) + 1 ) / 2 )
6868 elseif round_nearest_in == :logspace
69- c = - logmin* Δ⁻¹
69+ c = - logmin * Δ⁻¹
7070 else
7171 throw (ArgumentError (" Round-to-nearest either :linspace or :logspace" ))
7272 end
7373 end
7474
7575 # preallocate output
76- Q = similar (A,T)
76+ Q = similar (A, T)
7777
7878 @inbounds for i in eachindex (A)
7979 # store 0 as 0x00...
8080 # store positive numbers via convert to logpacking as 0x1-0xff..
81- Q[i] = iszero (A[i]) ? zero (T) : convert (T,round (c + Δ⁻¹* log (Float64 (A[i]))))+ one (T)
81+ Q[i] = iszero (A[i]) ? zero (T) : convert (T, round (c + Δ⁻¹ * log (Float64 (A[i])))) + one (T)
82+ end
83+
84+ return LogQuantArray {T,ndims(Q)} (Q, Float64 (logmin), Float64 (logmax))
85+ end
86+
87+
88+
89+ """
90+ LogQuantArray(::Type{TUInt},A::AbstractArray{T,N};dims::Int) where {TUInt<:Unsigned,T,N}
91+ Logarithmic quantization independently for every element along dimension
92+ `dims` in array `A`.
93+
94+ # Returns
95+ - a Vector{LogQuantArray}.
96+ """
97+ function LogQuantArray (:: Type{TUInt} , A:: AbstractArray{T,N} ; dims:: Int ) where {TUInt<: Unsigned ,T,N}
98+ @assert dims <= N " Can't quantize a $N -dimensional array in dimension=$dims "
99+ n = size (A)[dims]
100+ L = Vector {LogQuantArray} (undef, n)
101+ t = [
102+ if j == dims
103+ 1
104+ else
105+ Colon ()
106+ end for j in 1 : N
107+ ]
108+ for i in 1 : n
109+ t[dims] = i
110+ L[i] = LogQuantization (TUInt, A[t... ])
82111 end
112+ return L
113+ end
83114
84- return LogQuantArray {T,ndims(Q)} (Q,Float64 (logmin),Float64 (logmax))
115+ function LogQuantArray {U} (
116+ A:: AbstractArray{T,N} ;
117+ dims:: Option{Int} = nothing
118+ ) where {U<: Unsigned ,T,N}
119+ isnothing (dims) ? LogQuantization (U,A) : LogQuantArray (U,A;dims= dims)
85120end
86121
87- # define for 8, 16, 24 and 32 bit uints
88- LogQuant8Array (A:: AbstractArray{T,N} ,rn:: Symbol = :linspace ) where {T,N} = LogQuantization (UInt8,A,rn)
89- LogQuant16Array (A:: AbstractArray{T,N} ,rn:: Symbol = :linspace ) where {T,N} = LogQuantization (UInt16,A,rn)
90- LogQuant24Array (A:: AbstractArray{T,N} ,rn:: Symbol = :linspace ) where {T,N} = LogQuantization (UInt24,A,rn)
91- LogQuant32Array (A:: AbstractArray{T,N} ,rn:: Symbol = :linspace ) where {T,N} = LogQuantization (UInt32,A,rn)
122+ # keep compatibility: shortcuts for unsigned integers of 8, 16, 24 and 32-bit
123+ function LogQuant8Array (A:: AbstractArray{T,N} , rn:: Symbol = :linspace ; dims:: Option{Int} = nothing ) where {T,N}
124+ isnothing (dims) ? LogQuantization (UInt8, A, rn) : LogQuantArray (UInt8, A; dims= dims)
125+ end
126+
127+ function LogQuant16Array (A:: AbstractArray{T,N} , rn:: Symbol = :linspace ; dims:: Option{Int} = nothing ) where {T,N}
128+ isnothing (dims) ? LogQuantization (UInt16, A, rn) : LogQuantArray (UInt16, A; dims= dims)
129+ end
130+
131+ function LogQuant24Array (A:: AbstractArray{T,N} , rn:: Symbol = :linspace ; dims:: Option{Int} = nothing ) where {T,N}
132+ isnothing (dims) ? LogQuantization (UInt24, A, rn) : LogQuantArray (UInt24, A; dims= dims)
133+ end
134+
135+ function LogQuant32Array (A:: AbstractArray{T,N} , rn:: Symbol = :linspace ; dims:: Option{Int} = nothing ) where {T,N}
136+ isnothing (dims) ? LogQuantization (UInt32, A, rn) : LogQuantArray (UInt32, A; dims= dims)
137+ end
138+
139+
92140
93141"""
94- Array{T}(n::Integer,Q::LogQuantArray) where {T<:AbstractFloat}
142+ Array{T}(n::Integer, Q::LogQuantArray) where {T<:AbstractFloat}
95143
96144De-quantise a LogQuantArray into floats.
97145
@@ -102,19 +150,19 @@ De-quantise a LogQuantArray into floats.
102150# Returns
103151- an array of type T with the de-quantised values.
104152"""
105- function Base. Array {T} (n:: Integer ,Q:: LogQuantArray ) where {T<: AbstractFloat }
153+ function Base. Array {T} (n:: Integer , Q:: LogQuantArray ) where {T<: AbstractFloat }
106154 Qlogmin = Q. min # log(min::Float64)
107155 Qlogmax = Q. max # log(max::Float64)
108156
109157 # spacing in logspace ::Float64
110- Δ = (Qlogmax- Qlogmin)/ (2 ^ n- 2 ) # -2 as 0x00.. is reserved for 0
158+ Δ = (Qlogmax - Qlogmin) / (2 ^ n - 2 ) # -2 as 0x00.. is reserved for 0
111159
112- A = similar (Q,T) # preallocate
160+ A = similar (Q, T) # preallocate
113161
114162 @inbounds for i in eachindex (A)
115163 # 0x0 is unpack as 0
116164 # exp in Float64 then convert to T at assignment =
117- A[i] = iszero (Q[i]) ? zero (T) : A[i] = exp (Qlogmin + (Q[i]- 1 ) * Δ)
165+ A[i] = iszero (Q[i]) ? zero (T) : A[i] = exp (Qlogmin + (Q[i] - 1 ) * Δ)
118166 end
119167
120168 return A
@@ -179,9 +227,9 @@ function Base.Array{T}(L::Vector{LogQuantArray}) where T
179227 n = length (L)
180228 s = size (L[1 ])
181229 t = axes (L[1 ])
182- A = Array {T,N+ 1} (undef,s... ,length (L))
230+ A = Array {T,N + 1} (undef, s... , length (L))
183231 for i in 1 : n
184- A[t... ,i] = Array {T} (L[i])
232+ A[t... , i] = Array {T} (L[i])
185233 end
186234 return A
187- end
235+ end
0 commit comments