Closed auggiemarignier closed 11 months ago
It makes sense to have a general Parameterisation
class and inherit it with TransD1D
(or Voronoi1D
?) and OverComplete
. There will be common functionalities like plotting, and conversion to/from a model vector.
For OverComplete
, is it possible to think of it as a composition of two different kinds of parameterisations? Like Cosine1D
and Pixel1D
, and operator functions that can add them up. I don't remember the details of overcomplete tomography so not sure about the feasibility of this.
I'm thinking for a certain subclass of Parameterisation
, there are these ways to categorise them and we can implement with MixIn
classes:
All these utilities for Parameterisation
and its subclasses are going to sit inside cofi.utils
. You are right that they are in principle something we expect the users to define, so they don't really belong in CoFI's core. But they are here to save users' time to reinvent the wheels so we'd like to include them in a separate "utility" module.
These are just initial ideas. Thoughts?
I haven't heard of Mixin
before but a quick google makes it look interesting.
Ok so to use the parameterisation the user would do something like
from cofi.utils.parameterisation import Cosine2D
...
def obective(x,...):
...
return norm(data - ForwardModel(Cosine2D(x)))
I'm happy to start looking into implementing this because I can't really progress on my DCIP example without it
Looking a bit more into the utils
that are already implemented (e.g. LpNormRegularization
) we could follow a similar pattern. Regularisation gets integrated with BaseProblem.set_regularisation
, so we could create BaseProblem.set_parameterisation
which would then under the hood autoupdate the BaseProblem.forward
(and/or objective
, data_misfit
etc) to call forward(Parameterisation(model))
. Not sure how though.
Yes it would make sense to do this.
Alternatively, I was also thinking about something like:
my_parameterization = cofi.utils.OverComplete(*args)
my_initial_model = my_parameterization.to_model_vector()
my_problem = cofi.BaseProblem()
my_problem.set_initial_model(my_initial_model)
my_problem.set_forward(lambda m: my_fwd(my_parameterization(m)))
So that the users have more control and responsibility for handling parameterizations. In the end it's only a utility. There might be some points that I haven't thought of yet (especially with how we'll handle trans-d, but that's out of the scope for now) and I'm happy with either way for now.
I suggest we have a discussion on this in the All-hands meeting?
@jwhhh @fmagrini it looks like we both have a problem with integrating something that's parameterisation-specific into
cofi
. Here are a couple things to think about.cofi.utils._parameterisation
and in there we have different classes for different parameterisation, e.g. you can add aTransD1D
class and I'll add anOvercomplete
class? These should also perhaps be subclasses of a generalParameterisation
class to ensure consistent functionality.cofi
framework. Perhaps viaInversionOptions
.cofi
??