Skip to content

Deprecate implicit obsdim keyword argument #429

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 15 commits into from
Jan 31, 2022
Merged

Deprecate implicit obsdim keyword argument #429

merged 15 commits into from
Jan 31, 2022

Conversation

devmotion
Copy link
Member

Lately, due to the discussions also in AbstractGPs, I thought a bit about our support of matrices and the obsdim keyword argument.

I realized that I like it that one can still call kernelmatrix etc. with matrices, even though internally we only work with RowVecs and ColVecs (fortunately 🙏). I think this might make it a bit easier for new users as they don't have to learn about ColVecs and RowVecs right away - and even to me sometimes it feels quite nice, e.g., if other parts and packages of my script don't work with, or don't even know about, ColVecs/RowVecs and the hence the most natural form of the data is a raw matrix with a clearly defined convention (rows or columns).

However, I also realized that I really don't like it that there is an implicit default obsdim since this makes code more difficult to read and reason about and could lead to misunderstandings and bugs. And any default choice is somewhat arbitrary and probably heavily biased by research area and personal preferences.

I think one can get both - matrices as arguments and no default convention - by deprecating the default implicit obsdim keyword argument and requiring users to state obsdim explicitly. A prominent example of another package that did this is Distances.jl.

The idea grew on me, and hence I put together this PR. It has to be updated once #427 is merged.

@codecov
Copy link

codecov bot commented Jan 27, 2022

Codecov Report

Merging #429 (455df6e) into master (f9bbd84) will increase coverage by 0.04%.
The diff coverage is 100.00%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #429      +/-   ##
==========================================
+ Coverage   93.09%   93.14%   +0.04%     
==========================================
  Files          52       52              
  Lines        1202     1210       +8     
==========================================
+ Hits         1119     1127       +8     
  Misses         83       83              
Impacted Files Coverage Δ
src/approximations/nystrom.jl 92.50% <100.00%> (ø)
src/matrix/kernelmatrix.jl 100.00% <100.00%> (ø)
src/matrix/kernelpdmat.jl 81.81% <100.00%> (ø)
src/utils.jl 91.13% <100.00%> (+0.99%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update f9bbd84...455df6e. Read the comment docs.

@theogf
Copy link
Member

theogf commented Jan 27, 2022

So the idea behind the deprecation is that defaultobs is now nothing and that it will trigger an warning but still work like before and we then make a new breaking release without this default?

@devmotion
Copy link
Member Author

Yes, exactly, currently it is just changing defaultobsdim to nothing, widening the type annotation, and adding a deprecation warning if obsdim=nothing. In an upcoming breaking release we would then remove defaultobsdim and change obsdim::Union{Int,Nothing}=defaultobsdim to just obsdim::Int, without default value.

@theogf
Copy link
Member

theogf commented Jan 28, 2022

Can you maybe comment or introduce what will be the behavior when the user will not provide obsdim (once the deprecations are removed)

@devmotion
Copy link
Member Author

The default behaviour would be:

julia> f(x; obsdim::Int) = size(x, obsdim)
f (generic function with 1 method)

julia> f(rand(3, 4))
ERROR: UndefKeywordError: keyword argument obsdim not assigned
Stacktrace:
 [1] f(x::Matrix{Float64})
   @ Main ./REPL[6]:1
 [2] top-level scope
   @ REPL[7]:1

julia> f(rand(3, 4); obsdim=nothing)
ERROR: TypeError: in keyword argument obsdim, expected Int64, got a value of type Nothing
Stacktrace:
 [1] top-level scope
   @ REPL[8]:1

julia> f(rand(3, 4); obsdim=1)
3

julia> f(rand(3, 4); obsdim=2)
4

If we are not happy with these messages, we could continue using nothing but throw an error in vec_of_vecs where in this PR a deprecation warning is shown.

@theogf
Copy link
Member

theogf commented Jan 28, 2022

Yes that's exactly what we discussed last time with @st--, @willtebbutt and @rossviljoen . We think that it should throw an error but with a extremely verbose explicative message

src/utils.jl Outdated

function vec_of_vecs(X::AbstractMatrix; obsdim::Union{Nothing,Int}=nothing)
_obsdim = deprecated_obsdim(obsdim)
@assert _obsdim ∈ (1, 2) "obsdim should be 1 or 2, see docs of kernelmatrix"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what was your reason to here use an @assert instead of an explicit if & throw(ArgumentError())?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That I didn't want to change the existing code 😄 I think it should throw an error but this seemed unrelated to the changes here.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since I prefer ArgumentError as well I changed it nevertheless.

@st--
Copy link
Member

st-- commented Jan 28, 2022

Looks great, thanks! Happy to have this merged into master.

@devmotion devmotion changed the title RFC: Deprecate implicit obsdim keyword argument Deprecate implicit obsdim keyword argument Jan 28, 2022
devmotion and others added 3 commits January 28, 2022 15:09
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
) false
@deprecate sampleindex(
X::AbstractMatrix, r::Real; obsdim::Union{Integer,Nothing}=defaultobs
) sampleindex(vec_of_vecs(X; obsdim=obsdim === nothing ? nothing : Int(obsdim)), r) false
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the benefit of the ternary ? : over just

Suggested change
) sampleindex(vec_of_vecs(X; obsdim=obsdim === nothing ? nothing : Int(obsdim)), r) false
) sampleindex(vec_of_vecs(X; obsdim=obsdim), r) false

?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is it because here it was Integer whereas vec_of_vecs requires more specific Int?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, exactly. The current deprecation is not correct since it does not handle non-Int Integers. It doesn't matter much since we're allowed to remove it any time but since I had to change it anyway I fixed it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants