diff --git a/src/ColorVectorSpace.jl b/src/ColorVectorSpace.jl index e5b640d..adb2fa0 100644 --- a/src/ColorVectorSpace.jl +++ b/src/ColorVectorSpace.jl @@ -205,7 +205,15 @@ copy(c::MathTypes) = c (-)(c::MathTypes) = mapc(-, c) (-)(c::MathTypes{Bool}) = c abs(c::MathTypes) = mapc(abs, c) -norm(c::MathTypes, p::Real=2) = (cc = channels(c); norm(cc, p)/(p == 0 ? length(cc) : length(cc)^(1/p))) +function norm(c::MathTypes, p::Real=2) # FIXME: make the return types consistent + cc = acc.(channels(c)) + l = norm(cc, p) + c isa AbstractGray && return l / (p == 0 ? 1 : 1.0) + n = length(cc) + p == 2 && return l / sqrt(n) + p == 0 && return l / n # n::Int + l / n^(1/p) +end (⊙)(a::C, b::C) where {C<:MathTypes} = _mapc(rettype(*, a, b), _mul, a, b) (⋅)(a::C, b::C) where {C<:MathTypes} = throw(MethodError(dot, (a, b))) (⊗)(a::C, b::C) where {C<:MathTypes} = throw(MethodError(tensor, (a, b))) diff --git a/test/runtests.jl b/test/runtests.jl index 6497176..a149f89 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -149,6 +149,7 @@ ColorTypes.comp2(c::RGBA32) = alpha(c) @test norm(cf) == norm(cf, 2) == norm(gray(cf)) @test norm(cf, 1) == norm(gray(cf), 1) @test norm(cf, Inf) == norm(gray(cf), Inf) + @test norm(Gray(0.004N0f8)) ≈ Float32(0.004N0f8) # issue #183 @test @inferred(abs(cf)) === Gray(0.1f0) cu = Gray{N0f8}(0.1) @test @inferred(2*cu) === cu*2 === Gray(2*gray(cu)) @@ -443,6 +444,7 @@ ColorTypes.comp2(c::RGBA32) = alpha(c) @test abs2(cv) ≈ norm(cv)^2 @test_throws MethodError sum(abs2, RGB(0.1,0.2,0.3)) @test norm(RGB(0.1,0.2,0.3)) ≈ sqrt(0.14)/sqrt(3) + @test norm(RGB(0.004N0f8)) ≈ Float32(0.004N0f8) # issue #183 acu = RGB{N0f8}[cu] acf = RGB{Float32}[cf] @@ -812,8 +814,9 @@ ColorTypes.comp2(c::RGBA32) = alpha(c) x = 0.4 g = Gray(x) c = RGB(g) - for p in (0, 1, 2, Inf) + @testset "$p-norm equivalence" for p in (0, 1, 2, Inf) @test norm(x, p) == norm(g, p) ≈ norm(c, p) + @test (p == 0 ? 1.0 : NaN) === norm(Gray(NaN), p) === norm(RGB(NaN), p) end @test dot(x, x) == dot(g, g) ≈ dot(c, c) @test abs2(x) ≈ abs2(g) ≈ abs2(c)