relf / egobox

Efficient global optimization toolbox in Rust: bayesian optimization, mixture of gaussian processes, sampling methods

Home Page:https://joss.theoj.org/papers/10.21105/joss.04737

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

JOSS Review - Yuhan

YuhanLiin opened this issue · comments

I only have time to skim over the code and I have a few suggestions:

  • There's two main ways the code passes arrays as reference into functions: &ArrayBase<impl Data<Elem = F>, Ix> and &Array<F, Ix>. We should use only one way across all functions. I prefer the first way because it also allows ArrayView, so it's more flexible. The same applies to &mut ArrayBase<impl DataMut<Elem = F>, Ix> and &mut Array<F, Ix>.
  • There are some places where you have an inherent method called train() on model parameters. If you can put that functionality into a linfa::Fit impl, that would be preferred. Doing so allows for a tighter integration with linfa, and you also use Fit in other places in the code.
  • The function reduced_likelihood in gp/src/algorithms.rs mostly consists of cfg attributes to pick between BLAS and non-BLAS calls. It's cleaner to have two separate versions of the function for BLAS and non-BLAS. That way you only need two cfg attributes.

Thanks for your relevant suggestions, I will try to address them.

Regarding the first point I remember I was stopped from using &ArrayBase<impl Data<Elem = F>, Ix> everywhere when I started to use trait objects here . And I think it also explains the second point and why I have a train method beside the use of Fit.

I agree with your points but I do not know how to make them work with trait objects or if there is a way to implement the whole thing without trait objects (a mixture of expert has to handle different GP surrogates with fit/predict methods). If you have more detailed suggestions about a possible Rust implementation, I'll be happy to improve this design. PRs are welcome as well.

It makes sense for trait objects to prevent using ArrayBase<impl _> in trait methods, because generic params aren't object-safe. However you can still make the rest of the API generic and just call .view() on the array when passing it into the trait methods. I'm not sure how trait objects prevent using Fit.

The only alternative for trait objects I can think of is to use an enum, but that precludes external impls of Surrogate, which may be a dealbreaker.

Just to clarify, I meant that I cannot use Fit as a trait object hence needing another trait with a train method; otherwise, in #37, I applied your suggestions.

I've noticed you did not tick the third point, it was fixed previously with #34.

Got it