Skip to content

Commit

Permalink
Fix bugs, convenient syntax
Browse files Browse the repository at this point in the history
  • Loading branch information
brendanjohnharris committed Nov 9, 2022
1 parent 6405539 commit 3391190
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 154 deletions.
4 changes: 2 additions & 2 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "Normalization"
uuid = "be38d6a3-8366-4a42-ad57-222272b5bbe7"
authors = ["brendanjohnharris <[email protected]>"]
version = "0.1.0"
version = "0.2.0"

[deps]
JuliennedArrays = "5cadff95-7770-533d-a838-a1bf817ee6e0"
Expand All @@ -10,4 +10,4 @@ Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"

[compat]
JuliennedArrays = "0.3.0"
julia = "1.6 - 1.7"
julia = "1.6 - 1.8"
16 changes: 11 additions & 5 deletions src/Normalization.jl
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,21 @@ export fit,
denormalize!,
denormalize,
nansafe,
@_Normalization,
ZScore,
RobustZScore,
MixedSigmoid,
Sigmoid,
RobustSigmoid,
MixedSigmoid,
MinMax

abstract type AbstractNormalization end
(𝒯::Type{<:AbstractNormalization})(dims) = 𝒯(;dims)
function (𝒯::Type{<:AbstractNormalization})(dims, p)
isnothing(p) || (all(x->x==p[1], length.(p)) && error("Inconsistent parameter dimensions"))
𝒯(;dims, p)
end
(T::AbstractNormalization)(dims) = dims == () || (T.dims = dims)
(T::AbstractNormalization)(;dims) = dims == () || (T.dims = dims)

macro _Normalization(name, 𝑝, 𝑓, 𝑓⁻¹)
:(mutable struct $(esc(name)) <: AbstractNormalization
Expand Down Expand Up @@ -68,18 +70,20 @@ _mixedNorm.(common_norms)
_nansafe(p) = x -> p(filter(!isnan, x))
nansafe!(T::AbstractNormalization) = (T.𝑝=_nansafe.(T.𝑝); ())
nansafe(T::AbstractNormalization) = (N = deepcopy(T); nansafe!(N); N)
nansafe(𝒯::Type{<:AbstractNormalization}; dims=nothing) = dims |> 𝒯 |> nansafe
nansafe(𝒯::Type{<:AbstractNormalization}; dims=nothing) = 𝒯(; dims) |> nansafe

Base.reshape(x::Number, dims...) = reshape([x], dims...)
function fit!(T::AbstractNormalization, X::AbstractArray; dims=())
T(dims)
T(;dims)
dims = isnothing(T.dims) ? (1:ndims(X)) : T.dims
psz = size(X) |> collect
psz[[dims...]] .= 1
T.p = reshape.(map.(T.𝑝, (JuliennedArrays.Slices(X, dims...),)), psz...)
end
fit(T::AbstractNormalization, X::AbstractArray; kw...)=(T=deepcopy(T); fit!(T, X; kw...); T)
fit(𝒯::Type{<:AbstractNormalization}, X::AbstractArray; dims=nothing) = (T = 𝒯(dims); fit!(T, X); T)
fit(𝒯::Type{<:AbstractNormalization}, X::AbstractArray; dims=nothing) = (T = 𝒯(; dims); fit!(T, X); T)

(𝒯::Type{<:AbstractNormalization})(X; dims=nothing) = fit(𝒯, X; dims)

function normalize!(X::AbstractArray, T::AbstractNormalization)
isnothing(T.p) && fit!(T, X)
Expand All @@ -89,6 +93,8 @@ NormUnion = Union{AbstractNormalization, Type{<:AbstractNormalization}}
normalize!(X::AbstractArray, 𝒯::NormUnion; dims=nothing) = normalize!(X, fit(𝒯, X; dims))
normalize(X::AbstractArray, T::NormUnion; kwargs...) = (Y=copy(X); normalize!(Y, T; kwargs...); Y)

(T::AbstractNormalization)(X) = normalize(X, T)

function denormalize!(X::AbstractArray, T::AbstractNormalization)
isnothing(T.p) && error("Cannot denormalize with an unfit normalization")
mapdims!(T.𝑓⁻¹, X, T.p...; T.dims)
Expand Down
149 changes: 2 additions & 147 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ end
# * ZScore a 2D array over the first dim.
T = fit(ZScore, X, dims=1)
Y = normalize(X, T)
N = ZScore(X; dims=1) # Alternate syntax
@test N(X) == Y
@test !isnothing(T.p)
@test length(T.p) == 2
@test length(T.p[1]) == length(T.p[2]) == size(X, 2)
Expand All @@ -39,153 +41,6 @@ end
@test X == Y
@test_nowarn denormalize!(Y, T)
@test Y _X

# X = copy(_X)
# t = fit(ZScoreTransform, X, dims=1, scale=false)
# Y = transform(t, X)
# @test length(t.mean) == 8
# @test isempty(t.scale)
# @test Y ≈ X .- mean(X, dims=1)
# @test reconstruct(t, Y) ≈ X
# @test transform!(t, X) === X
# @test isequal(X, Y)
# @test reconstruct!(t, Y) === Y
# @test Y ≈ _X

# X = copy(_X)
# t = fit(ZScoreTransform, X, dims=1)
# Y = transform(t, X)
# @test length(t.mean) == 8
# @test length(t.scale) == 8
# @test Y ≈ (X .- mean(X, dims=1)) ./ std(X, dims=1)
# @test reconstruct(t, Y) ≈ X
# @test Y ≈ standardize(ZScoreTransform, X, dims=1)
# @test transform!(t, X) === X
# @test isequal(X, Y)
# @test reconstruct!(t, Y) === Y
# @test Y ≈ _X

# X = copy(_X)
# t = fit(ZScoreTransform, X, dims=2)
# Y = transform(t, X)
# @test length(t.mean) == 5
# @test length(t.scale) == 5
# @test Y ≈ (X .- mean(X, dims=2)) ./ std(X, dims=2)
# @test reconstruct(t, Y) ≈ X
# @test Y ≈ standardize(ZScoreTransform, X, dims=2)
# @test transform!(t, X) === X
# @test isequal(X, Y)
# @test reconstruct!(t, Y) === Y
# @test Y ≈ _X

# X = copy(_X)
# t = fit(UnitRangeTransform, X, dims=1, unit=false)
# Y = transform(t, X)
# @test length(t.min) == 8
# @test length(t.scale) == 8
# @test Y ≈ X ./ (maximum(X, dims=1) .- minimum(X, dims=1))
# @test reconstruct(t, Y) ≈ X
# @test transform!(t, X) === X
# @test isequal(X, Y)
# @test reconstruct!(t, Y) === Y
# @test Y ≈ _X

# X = copy(_X)
# t = fit(UnitRangeTransform, X, dims=1)
# Y = transform(t, X)
# @test isa(t, AbstractDataTransform)
# @test length(t.min) == 8
# @test length(t.scale) == 8
# @test Y ≈ (X .- minimum(X, dims=1)) ./ (maximum(X, dims=1) .- minimum(X, dims=1))
# @test reconstruct(t, Y) ≈ X
# @test Y ≈ standardize(UnitRangeTransform, X, dims=1)
# @test transform!(t, X) === X
# @test isequal(X, Y)
# @test reconstruct!(t, Y) === Y
# @test Y ≈ _X

# X = copy(_X)
# t = fit(UnitRangeTransform, X, dims=2)
# Y = transform(t, X)
# @test isa(t, AbstractDataTransform)
# @test length(t.min) == 5
# @test length(t.scale) == 5
# @test Y ≈ (X .- minimum(X, dims=2)) ./ (maximum(X, dims=2) .- minimum(X, dims=2))
# @test reconstruct(t, Y) ≈ X
# @test transform!(t, X) === X
# @test isequal(X, Y)
# @test reconstruct!(t, Y) === Y
# @test Y ≈ _X

# # vector
# X = rand(10)
# _X = copy(X)

# t = fit(ZScoreTransform, X, dims=1, center=false, scale=false)
# Y = transform(t, X)
# @test transform(t, X) ≈ Y
# @test reconstruct(t, Y) ≈ X
# @test transform!(t, X) === X
# @test isequal(X, Y)
# @test reconstruct!(t, Y) === Y
# @test Y ≈ _X

# X = copy(_X)
# t = fit(ZScoreTransform, X, dims=1, center=false)
# Y = transform(t, X)
# @test Y ≈ X ./ std(X, dims=1)
# @test transform(t, X) ≈ Y
# @test reconstruct(t, Y) ≈ X
# @test transform!(t, X) === X
# @test isequal(X, Y)
# @test reconstruct!(t, Y) === Y
# @test Y ≈ _X

# X = copy(_X)
# t = fit(ZScoreTransform, X, dims=1, scale=false)
# Y = transform(t, X)
# @test Y ≈ X .- mean(X, dims=1)
# @test transform(t, X) ≈ Y
# @test reconstruct(t, Y) ≈ X
# @test transform!(t, X) === X
# @test isequal(X, Y)
# @test reconstruct!(t, Y) === Y
# @test Y ≈ _X

# X = copy(_X)
# t = fit(ZScoreTransform, X, dims=1)
# Y = transform(t, X)
# @test Y ≈ (X .- mean(X, dims=1)) ./ std(X, dims=1)
# @test transform(t, X) ≈ Y
# @test reconstruct(t, Y) ≈ X
# @test Y ≈ standardize(ZScoreTransform, X, dims=1)
# @test transform!(t, X) === X
# @test isequal(X, Y)
# @test reconstruct!(t, Y) === Y
# @test Y ≈ _X

# X = copy(_X)
# t = fit(UnitRangeTransform, X, dims=1)
# Y = transform(t, X)
# @test Y ≈ (X .- minimum(X, dims=1)) ./ (maximum(X, dims=1) .- minimum(X, dims=1))
# @test transform(t, X) ≈ Y
# @test reconstruct(t, Y) ≈ X
# @test transform!(t, X) === X
# @test isequal(X, Y)
# @test reconstruct!(t, Y) === Y
# @test Y ≈ _X

# X = copy(_X)
# t = fit(UnitRangeTransform, X, dims=1, unit=false)
# Y = transform(t, X)
# @test Y ≈ X ./ (maximum(X, dims=1) .- minimum(X, dims=1))
# @test transform(t, X) ≈ Y
# @test reconstruct(t, Y) ≈ X
# @test Y ≈ standardize(UnitRangeTransform, X, dims=1, unit=false)
# @test transform!(t, X) === X
# @test isequal(X, Y)
# @test reconstruct!(t, Y) === Y
# @test Y ≈ _X
end

@testset "3D normalization" begin
Expand Down

0 comments on commit 3391190

Please sign in to comment.