-
-
Notifications
You must be signed in to change notification settings - Fork 2k
Description
GIven a model with scalar or array parameters, I would like to be able to easily make another model which has different parameter values (either scalar or array), while preserving other things (e.g. constraints, polynomial degree, etc). One can try the naive approach of making a copy of the model and then changing the parameters, but this doesn't always work:
Common imports
from astropy.modeling.models import Polynomial1D
import numpy as npScalar ▶️ Scalar
This case works fine:
poly = Polynomial1D(2, c0=1, c1=3, c2=5)
poly.c0.fixed = True
poly.c1.bounds = [0, 10]
poly2 = poly.copy()
poly2.c0=1.5
poly2.c1=3.2
poly2.c2 = 5.5Array ▶️ scalar
poly = Polynomial1D(2, c0=np.ones((10, 10)), c1=np.ones((10, 10)) * 3, c2=np.ones((10, 10)) * 5)
poly.c0.fixed = True
poly.c1.bounds = [0, 10]
poly2 = poly.copy()
poly2.c0=1.5
poly2.c1=3.2
poly2.c2 = 5.5This works ok because scalars are broadcastable to arrays. This is not ideal though as one temporarily has a copy of all the arrays in memory, and if the arrays are big it might be annoying.
Array ▶️ array
This does not work if the new array shape is not broadcastable to the old one:
poly = Polynomial1D(2, c0=np.ones((10, 10)), c1=np.ones((10, 10)) * 3, c2=np.ones((10, 10)) * 5)
poly.c0.fixed = True
poly.c1.bounds = [0, 10]
poly2 = poly.copy()
poly2.c0=np.arange(5)The error is:
InputParameterError: Value for parameter c0 does not match shape or size
expected by model ((5,), 5) vs ((10, 10), 100)
Scalar ▶️ Array
This does not work at all:
poly = Polynomial1D(2, c0=1, c1=3, c2=5)
poly.c0.fixed = True
poly.c1.bounds = [0, 10]
poly2 = poly.copy()
poly2.c0=np.arange(5)the error is:
InputParameterError: Value for parameter c0 does not match shape or size
expected by model ((5,), 5) vs ((1,), 1)
Possible solutions
One option would not be to check the dimensions whenever parameters are set, but to instead validate them at the point where the model is called - otherwise it is not possible to change the parameters to have a shape that is not broadcastable to the current one.
Another option would be to have a way to do e.g. poly.copy_with_new_parameters(c0=np.arange(5), ...) or similar, that is, do a copy but replace the parameter value with the ones provided in the method call.
I'm open to other ideas though!