2017-08-04 13 views
5

Tôi đang cố gắng sử dụng thuộc tính Model.tied (hoặc Parameter.tied) trong astropy.modelling, nhưng dường như không thể hiểu cách hoạt động của nó. Ví dụ: giả sử tôi muốn tạo mô hình kết hợp với hai tham số: flux_0flux_1. Tuy nhiên, tôi chỉ muốn flux_0 được sử dụng trong phù hợp: flux_1 phải luôn mang giá trị 1 - flux_0. (Cuối cùng, tôi cần phải mở rộng chức năng này để flux_0 + flux_1 + ... + flux_n = 1.)Các thông số lấy mẫu trong astropy.modeling

tôi định nghĩa một lớp mô hình và một "callable" cho thuộc tính tied như vậy:

>>> from astropy.modeling import Fittable1DModel, Parameter 
>>> 
>>> class MyModel(Fittable1DModel): 
...  flux = Parameter() 
...  @staticmethod 
...  def evaluate(x, flux): 
...   return flux 
... 
>>> def tie_fluxes(model): 
...  flux_1 = 1 - model.flux_0 
...  return flux_1 
... 
>>> TwoModel = MyModel + MyModel 
>>> 
>>> TwoModel 
<class '__main__.CompoundModel0'> 
Name: CompoundModel0 
Inputs: ('x',) 
Outputs: ('y',) 
Fittable parameters: ('flux_0', 'flux_1') 
Expression: [0] + [1] 
Components: 
    [0]: <class '__main__.MyModel'> 
    Name: MyModel 
    Inputs: ('x',) 
    Outputs: ('y',) 
    Fittable parameters: ('flux',) 

    [1]: <class '__main__.MyModel'> 
    Name: MyModel 
    Inputs: ('x',) 
    Outputs: ('y',) 
    Fittable parameters: ('flux',) 

Sau đó, tôi kiểm tra thuộc tính tied. Theo tôi hiểu rằng đây phải là một từ điển (xem chú thích), nhưng nó không phải là:

>>> TwoModel.tied 
<property object at 0x109523958> 
>>> 
>>> TwoModel.tied['flux_1'] = tie_fluxes 
Traceback (most recent call last): 
File "<stdin>", line 1, in <module> 
TypeError: 'property' object does not support item assignment 

Nếu tôi cố gắng thiết lập nó như một cuốn từ điển, nó không cập nhật phù hợp Parameter:

>>> TwoModel.tied = {'flux_1': tie_fluxes} 
>>> 
>>> TwoModel.flux_1.tied 
False 

Nhưng khi tôi cố gắng tạo một đối tượng ngay trên con dơi thay vì một lớp mô hình phức hợp (đây không phải là những gì tôi muốn làm cuối cùng), thuộc tính tied của đối tượng là một từ điển. Thật không may, thiết lập từ điển này vẫn không tạo ra hiệu quả mong muốn:

>>> TwoSetModel = MyModel(0.2) + MyModel(0.3) 
>>> 
>>> TwoSetModel 
<CompoundModel1(flux_0=0.2, flux_1=0.3)> 
>>> 
>>> TwoSetModel.tied 
{'flux_1': False, 'flux_0': False} 
>>> 
>>> TwoSetModel.tied['flux_1'] = tie_fluxes 
>>> 
>>> TwoSetModel 
<CompoundModel1(flux_0=0.2, flux_1=0.3)> 
>>> 
>>> TwoSetModel.flux_1.tied 
<function tie_fluxes at 0x102987730> 

Vì vậy, trong ví dụ này, các thuộc tính tied không giữ chức năng chính xác, nhưng của value tham số không cập nhật cho phù hợp.

Tôi đang làm gì sai ở đây? Tôi có hoàn toàn hiểu nhầm thuộc tính tied không?

(Tôi đang sử dụng Python 3.5.2 với Astropy 1.3.3 trong các ví dụ trên)


Footnote:

Chạy help(TwoModel), tôi nhận được thông tin sau:

⁝ 
| tied : dict, optional 
|  Dictionary ``{parameter_name: callable}`` of parameters which are 
|  linked to some other parameter. The dictionary values are callables 
|  providing the linking relationship. 
| 
|  Alternatively the `~astropy.modeling.Parameter.tied` property of a 
|  parameter may be used to set the ``tied`` constraint on individual 
|  parameters. 
⁝ 
| Examples 
| -------- 
| >>> from astropy.modeling import models 
| >>> def tie_center(model): 
| ...   mean = 50 * model.stddev 
| ...   return mean 
| >>> tied_parameters = {'mean': tie_center} 
| 
| Specify that ``'mean'`` is a tied parameter in one of two ways: 
| 
| >>> g1 = models.Gaussian1D(amplitude=10, mean=5, stddev=.3, 
| ...      tied=tied_parameters) 
| 
| or 
| 
| >>> g1 = models.Gaussian1D(amplitude=10, mean=5, stddev=.3) 
| >>> g1.mean.tied 
| False 
| >>> g1.mean.tied = tie_center 
| >>> g1.mean.tied 
| <function tie_center at 0x...> 
⁝ 
+0

Câu hỏi hay - Tôi đã viết hầu hết mã này để tôi có thể trả lời câu hỏi của bạn. Tôi sắp đi ra ngoài trong ngày nhưng tôi sẽ cố gắng để lấy lại càng sớm càng tốt. IIRC đối phó với các ràng buộc với các mô hình hợp chất vẫn có thể là một chút khó khăn, không may. – Iguananaut

+1

Một điều tôi có thể cho bạn biết bây giờ - bạn dường như rơi vào một quan niệm sai lầm phổ biến rằng các ràng buộc mô hình được áp dụng khi cập nhật thủ công các giá trị của tham số. Đây không phải là trường hợp.Các ràng buộc là * chỉ * được sử dụng bởi fitters khi lắp các mô hình, để thiết lập các ràng buộc trên các tham số. Bên ngoài các ràng buộc phù hợp không được thực thi. Tôi đã xem xét việc thay đổi điều này trước đây, để nó hoạt động theo cách bạn mong đợi. Đã có một vấn đề mở cho rằng tại một thời điểm nhưng tôi dường như không thể tìm thấy nó bây giờ ... – Iguananaut

+0

Tôi nghĩ rằng https://github.com/astropy/astropy/issues/2265 làm cho một số tài liệu tham khảo này. – Iguananaut

Trả lời

0

Ví dụ dưới đây tương tự như ví dụ trong tài liệu hướng dẫn.

Mẫu hợp chất = Tổng của hai hàm 1 gaussian.

Constrain: mean_1 = 2 * mean_0

import numpy as np 
import matplotlib.pyplot as plt 
from astropy.modeling import models, fitting 


def tie_center(model): 
    mean = 2* model.mean_0 
    return mean 

tied_parameters = {'mean_1': tie_center} 
np.random.seed(42) 
g1 = models.Gaussian1D(2, 0.4, 0.3) 
g2 = models.Gaussian1D(2.5, 0.2, 0.2) 
TwoGaussians = (models.Gaussian1D + 
models.Gaussian1D).rename('TwoGaussians') 
x = np.linspace(-1, 1, 200) 
y = g1(x) + g2(x) + np.random.normal(0., 0.2, x.shape) 

gg_init = TwoGaussians(amplitude_0=1.4, mean_0=1.2, stddev_0=0.1,\ 
amplitude_1=1.0,stddev_1=0.2, tied=tied_parameters) 
fitter = fitting.SLSQPLSQFitter() 
gg_fit = fitter(gg_init, x, y) 


plt.figure(figsize=(8,5)) 
plt.plot(x, y, 'ko') 
plt.plot(x, gg_fit(x)) 
plt.xlabel('Position') 
plt.ylabel('Flux') 
plt.show() 
print(gg_fit.mean_0,gg_fit.mean_1) 

thông số Ràng buộc trong astropy khi Compund_model = tổng của ba Hàm Gauss 1D Constrain: Sum của cả ba phương tiện nên luôn bằng một.

def tie_center(model): 
    mean = 1-(model.mean_0+ model.mean_1) 
    return mean 
tied_parameters = {'mean_2': tie_center} 

np.random.seed(42) 
g1 = models.Gaussian1D(2, 0.4, 0.3) 
g2 = models.Gaussian1D(2.5, 0.2, 0.2) 
g3 = models.Gaussian1D(1.5, 0.4, 0.1) 
ThreeGaussians = (models.Gaussian1D + models.Gaussian1D + 
models.Gaussian1D).rename('ThreeGaussians') 
x = np.linspace(-1, 1, 200) 
y = g1(x) + g2(x) + g3(x) + np.random.normal(0., 0.2, x.shape) 

gg_init = ThreeGaussians(amplitude_0=1.4, mean_0=0.3, stddev_0=0.1, 
amplitude_1=1.0, mean_1=0.3,stddev_1=0.2, \ 
amplitude_2=1.5,stddev_2=0.1,tied=tied_parameters) 
fitter = fitting.SLSQPLSQFitter() 
gg_fit = fitter(gg_init, x, y) 
plt.figure(figsize=(8,5)) 
plt.plot(x, y, 'ko') 
plt.plot(x, gg_fit(x)) 
plt.xlabel('Position') 
plt.ylabel('Flux') 
plt.show() 
print(gg_fit.mean_0,gg_fit.mean_1, gg_fit.mean_2) 
Các vấn đề liên quan