JuliaGaussianProcesses / AbstractGPs.jl

Abstract types and methods for Gaussian Processes.
https://juliagaussianprocesses.github.io/AbstractGPs.jl/dev
Other
218 stars 20 forks source link

**BREAKING** improve structs & constructors #306

Open st-- opened 2 years ago

st-- commented 2 years ago

Happy for others to contribute to this branch.

Things that came to my mind: e.g. FiniteGP should check whether length(x) == size(Sigma, 1) == size(Sigma, 2).

willtebbutt commented 2 years ago

e.g. FiniteGP should check whether length(x) == size(Sigma, 1) == size(Sigma, 2).

This would be good. We should be it in an @non_differentiable function though, for AD's sake. (we already have the ChainRulesCore dep, so no harm done there)

codecov[bot] commented 2 years ago

Codecov Report

Merging #306 (ac78254) into master (0440ea6) will increase coverage by 0.27%. The diff coverage is 100.00%.

@@            Coverage Diff             @@
##           master     #306      +/-   ##
==========================================
+ Coverage   97.64%   97.91%   +0.27%     
==========================================
  Files          10       10              
  Lines         382      384       +2     
==========================================
+ Hits          373      376       +3     
+ Misses          9        8       -1     
Impacted Files Coverage Δ
src/finite_gp_projection.jl 100.00% <100.00%> (ø)
src/util/common_covmat_ops.jl 97.61% <0.00%> (+2.38%) :arrow_up:

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 0440ea6...ac78254. Read the comment docs.

st-- commented 2 years ago

I just checked and UniformScaling is supported and can be used at least with some methods (mean_and_var errors since diagind is not defined):

Could we not make that non-breaking by also having a constructor that converts the UniformScaling into an appropriately-sized ScalMat?

willtebbutt commented 2 years ago

@devmotion I'm still not entirely convinced by the UniformScaling argument. For me, it's still appropriate to consider it a bug, because if I ran the standard test_finitegp_primary_public_interface test suite on a FiniteGP with a UniformScaling in it, it would error, meaning that our "official" interface tests fail when you use a UniformScaling. Moreover, in the docs we explicitly say

Let f be an AbstractGP, x an AbstractVector representing a collection of inputs, and Σ a positive-definite matrix of size (length(x), length(x)). 

The docstring for FiniteGP is nearly as specific:

The finite-dimensional projection of the AbstractGP `f` at `x`. Assumed to be observed under
Gaussian noise with zero mean and covariance matrix `Σy`

although it should probably be tightened up, and docstrings added for the other outer constructors.

In short, our official documentation, to some degree the docstring for FiniteGP, and our official API tests indicate that Σy should be a matrix. To my mind, the fact that the implementations of a subset of the methods implemented on FiniteGPs happen to work correctly when a UniformScaling is provided is a coincidence, and not a sufficient reason to say that meaningfully support UniformScaling at present.

st-- commented 2 years ago

Could we not make that non-breaking by also having a constructor that converts the UniformScaling into an appropriately-sized ScalMat?

Looks like we can, @devmotion I added the example you gave as another test case and it's passing

devmotion commented 2 years ago

A constructor won't prevent breakage of downstream dispatches on UniformScaling. If we consider this a valid example (maybe there are others, it was just the first thing that came to my mind and worked for large parts of the API, ie users might not notice that it was unintended), then there is no way around making a breaking release.

devmotion commented 2 years ago

@willtebbutt I can definitely see your point. IMO it's an edge case and one could argue one way or the other. I don't think the use of UniformScaling is completely surprising since eg MvNormal happily accepts these as covariance matrices.

In general, I think the discussion just shows that it would be safer to make a breaking release. Not all matrix-like structures are of type AbstractMatrix, as eg UniformScaling and up until some time ago AbstractPDMat show. And I don't think there's a major issue for downstream packages and users with making a beeaking release: if they don't use non-AbstractMatrix types they can just update, and otherwise it's good we didn't break stuff.

willtebbutt commented 2 years ago

Okay. Let's try and tie this down in the next release though (more precise testing and documentation).

st-- commented 2 years ago

See https://github.com/JuliaGaussianProcesses/ApproximateGPs.jl/pull/126 for the required AD fix