Skip to content
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

Models as components for CallableNumericalModel #251

Open
tBuLi opened this issue Jun 18, 2019 · 4 comments
Open

Models as components for CallableNumericalModel #251

tBuLi opened this issue Jun 18, 2019 · 4 comments

Comments

@tBuLi
Copy link
Owner

tBuLi commented Jun 18, 2019

Taking the example from #248, we realized that the syntax for CallableNumericalModel's could be improved a bit from

ode_model = ODEModel({D(y, x): a * y}, initial={x: 0.0, y: 1.0})
model_dict = {
    z: 2 * y + b,
    y: lambda x, a: ode_model(x=x, a=a).y,
}

to

ode_model = ODEModel({D(y, x): a * y}, initial={x: 0.0, y: 1.0})
model_dict = {
    z: 2 * y + b,
    y: ode_model
}

if we make CallableNumericalModel's aware of Ans objects to automate the unpacking. (ODEModel is used here for no particular reason, could be any model.) I think this looks a lot cleaner. However, this could potentially open a pandora's box I haven't thought about, but for now I think it's save.
An interesting extension would be tuple unpacking for multicomponent models:

ode_model = ODEModel({D(y1, x): a * y1, D(y2, x): a * y2}, initial={x: 0.0, y1: 1.0, y2: 0.0})
model_dict = {
    z: 2 * y1 + b,
    (y1, y2): ode_model
}
model = CallableNumericalModel(model_dict, connectivity_mapping={z: {y2, b}})

fit = Fit(model, x=xdata, z=zdata, y2=None)

where y2 is set to None so it is ignored in the optimization as usual. The general invariant here would be {ode_model.dependent_vars: ode_model}.

For general models this might not be a good idea because of the extra work involved for calculating jacobians etc, but for CallableNumericalModel this might in fact be a powerful addition.

@pckroon
Copy link
Collaborator

pckroon commented Jun 19, 2019

My only issue with this is that it makes it a little bit harder for users to create a CallableNumericalModel with a function that just returns a number. Unless you want the CallableNumericalModel to do the wrapping of the answer, but I see problems on the horizon there: you'll need to know the symbols, and only do it if the function doesn't return Ans objects already.

@tBuLi
Copy link
Owner Author

tBuLi commented Jun 19, 2019

Why is it harder for functions that only return a number? We can already do that now, right? Like,

{y: lambda x: x}

is valid input to CallableNumericalModel. What am I missing here.

@pckroon
Copy link
Collaborator

pckroon commented Jun 19, 2019

Maybe I'm missing something. I was under the impression you'd have to provide {y: lambda x: Ans(x=x)}

@tBuLi
Copy link
Owner Author

tBuLi commented Jun 19, 2019

Ah, I see what you mean. No, I'm not intending to always use the Ans object, that would indeed be worse. I'm just proposing that if a component is evaluated, and it happens to return an Ans object, than we realize what has happened (the component was one of our own models) and so we unpack it.

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

No branches or pull requests

2 participants