From 131daf1bd2f188da492238b4269d22eec89efdb0 Mon Sep 17 00:00:00 2001 From: Phillip Alday Date: Fri, 2 Jul 2021 10:50:19 -0500 Subject: [PATCH 1/8] simplify string_mime --- test/runtests.jl | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/test/runtests.jl b/test/runtests.jl index edc94b4..50e96c2 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -4,12 +4,7 @@ using StatsBase using Statistics using Test -function string_mime(mime, x) - io = IOBuffer() - show(io, mime, x) - seekstart(io) - return read(io, String) -end +string_mime(mime, x) = sprint(show, mime, x) @testset "StandardizedPredictors.jl" begin include("centering.jl") From 14f1edf221baab0b79cbb0f66eb9dde932a1637b Mon Sep 17 00:00:00 2001 From: Phillip Alday Date: Fri, 2 Jul 2021 10:51:33 -0500 Subject: [PATCH 2/8] better inplace eltype preservation info --- src/centering.jl | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/centering.jl b/src/centering.jl index fe5d210..b1760fa 100644 --- a/src/centering.jl +++ b/src/centering.jl @@ -20,15 +20,20 @@ center!(x) = center!(mean, x) center!(f::Function, x) = center!(x, f(skipmissing(x))) function center!(x, y) + try + y = convert(eltype(x), y) + catch e + if e isa InexactError + throw(ArgumentError("Subtracting the center $(y) changes the eltype of "* + "the array. Promote to $(typeof(y)) first.")) + else + rethrow(e) + end + end x .-= y return x end -function center!(x::AbstractVector{<:Integer}) - throw(ArgumentError("Demeaning an array of integers changes its type to " * - "floating point. Promote to float first.")) -end - """ struct Center @@ -169,4 +174,3 @@ StatsModels.width(t::CenteredTerm) = StatsModels.width(t.term) # don't generate schema entries for terms which are already centered StatsModels.needs_schema(::CenteredTerm) = false StatsModels.termsyms(t::CenteredTerm) = StatsModels.termsyms(t.term) - From 2e2fdb3a15380e72770a0b5a1d4523134fa6ee5e Mon Sep 17 00:00:00 2001 From: Phillip Alday Date: Fri, 2 Jul 2021 10:51:49 -0500 Subject: [PATCH 3/8] tests --- test/centering.jl | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/test/centering.jl b/test/centering.jl index 2e836b7..7e87325 100644 --- a/test/centering.jl +++ b/test/centering.jl @@ -3,7 +3,7 @@ data = (x=collect(1:10), y=rand(10) .+ 3, z=Symbol.(repeat('a':'e', 2))) - + @testset "Automatic centering" begin xc = concrete_term(term(:x), data, Center()) @test xc isa CenteredTerm @@ -54,13 +54,35 @@ xc22 = center(x, 2) @test xc2.center == xc22.center == 2 + @testset "centering vectors" begin + x = collect(1:5) + y = x .+ 5.0 + xc = x .- 3 + + @test center(x) == xc + @test center(y) == xc + @test center(maximum, x) == (x .- 5) + @test all(center(y, x) .== 5) + + y2 = copy(y) + @test center!(y2) == xc + @test all(y2 .!= y) + @test y2 == xc + + # this is int on int so you can modify in place + @test center!(maximum, copy(x)) == (x .- 5) + # this converts exactly to int, so you can do it in place + center!(mean, copy(x)) == center(mean, x) + @test_throws ArgumentError center!(mean, [1, 2]) + @test_throws ArgumentError center!([1, 2]) + end end @testset "plays nicely with formula" begin f = @formula(0 ~ x * y) sch = schema(f, data) - + sch_c = schema(f, data, Dict(:x => Center(), :y => Center(2))) ff_c = apply_schema(f, sch_c) @@ -98,7 +120,7 @@ end # @testset "utilities" begin - + # end From f20d9cb9bfcc0d9f326936c12ab7bd08b4771c9f Mon Sep 17 00:00:00 2001 From: Phillip Alday Date: Fri, 2 Jul 2021 11:01:47 -0500 Subject: [PATCH 4/8] the other branch of convert errors --- test/centering.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/test/centering.jl b/test/centering.jl index 7e87325..4e35b35 100644 --- a/test/centering.jl +++ b/test/centering.jl @@ -75,6 +75,7 @@ center!(mean, copy(x)) == center(mean, x) @test_throws ArgumentError center!(mean, [1, 2]) @test_throws ArgumentError center!([1, 2]) + @test_throws MethodError center!(x -> 1, ["a","b"]) end end From ec19bdf62d6ffba35ef28ed6a57996f2950b414b Mon Sep 17 00:00:00 2001 From: Phillip Alday Date: Fri, 2 Jul 2021 11:05:22 -0500 Subject: [PATCH 5/8] be more thorough --- src/centering.jl | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/centering.jl b/src/centering.jl index b1760fa..3a82ace 100644 --- a/src/centering.jl +++ b/src/centering.jl @@ -22,10 +22,14 @@ center!(f::Function, x) = center!(x, f(skipmissing(x))) function center!(x, y) try y = convert(eltype(x), y) + # verify that we also don't hit problems during substraction + # I can't think of any common number type that isn't closed under + # subtraction, but maybe somebody has created a PositiveInt type + convert(eltype(x), first(x) - y) catch e if e isa InexactError throw(ArgumentError("Subtracting the center $(y) changes the eltype of "* - "the array. Promote to $(typeof(y)) first.")) + "the array. Promote to $(typeof(first(x) - y)) first.")) else rethrow(e) end From 91b302a6431e49b68a6bf96e84f44649a1f544f9 Mon Sep 17 00:00:00 2001 From: Phillip Alday Date: Fri, 2 Jul 2021 11:16:37 -0500 Subject: [PATCH 6/8] can we hit 100%? --- test/centering.jl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/centering.jl b/test/centering.jl index 4e35b35..cc5187e 100644 --- a/test/centering.jl +++ b/test/centering.jl @@ -32,6 +32,7 @@ sch = schema(data, Dict(:x => Center(), :y => Center(2))) xc = sch[term(:x)] @test xc isa CenteredTerm + @test !StatsModels.needs_schema(xc) @test xc.center == mean(data.x) yc = sch[term(:y)] @@ -101,6 +102,7 @@ @testset "printing" begin xc = concrete_term(term(:x), data, Center()) + @test StatsModels.termsyms(xc) == Set([:x]) @test "$(xc)" == "$(xc.term)" @test string_mime(MIME("text/plain"), xc) == "x(centered: 5.5)" @test coefnames(xc) == "x(centered: 5.5)" From 6da7e3458790e47b1a48c49c0330d3144f1dd5ec Mon Sep 17 00:00:00 2001 From: Phillip Alday Date: Fri, 2 Jul 2021 18:22:19 +0200 Subject: [PATCH 7/8] Update centering.jl --- src/centering.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/centering.jl b/src/centering.jl index 3a82ace..71fa1bb 100644 --- a/src/centering.jl +++ b/src/centering.jl @@ -28,7 +28,7 @@ function center!(x, y) convert(eltype(x), first(x) - y) catch e if e isa InexactError - throw(ArgumentError("Subtracting the center $(y) changes the eltype of "* + throw(ArgumentError("Subtracting the center $(y) changes the eltype of " * "the array. Promote to $(typeof(first(x) - y)) first.")) else rethrow(e) From 2a0d9c3ae869f0d4225f2a60925746892e082a8b Mon Sep 17 00:00:00 2001 From: Phillip Alday Date: Fri, 2 Jul 2021 18:22:58 +0200 Subject: [PATCH 8/8] Update centering.jl --- test/centering.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/centering.jl b/test/centering.jl index cc5187e..8951d09 100644 --- a/test/centering.jl +++ b/test/centering.jl @@ -76,7 +76,7 @@ center!(mean, copy(x)) == center(mean, x) @test_throws ArgumentError center!(mean, [1, 2]) @test_throws ArgumentError center!([1, 2]) - @test_throws MethodError center!(x -> 1, ["a","b"]) + @test_throws MethodError center!(v -> 1, ["a","b"]) end end