2017-08-04 12 views
5

astropy.modellingでModel.tied(またはParameter.tied)属性を使用しようとしていますが、動作が分からないようです。たとえば、2つのパラメータ、すなわちflux_0flux_1を持つ複合モデルを作成したいとしましょう。しかし、私はflux_0をフィッティングに使用したいだけです:flux_1は常に1 - flux_0の値を持ちます。 (。結局、私はflux_0 + flux_1 + ... + flux_n = 1ように、この機能を拡張する必要があります)astropy.modelingのパラメータを束縛する

私はモデルクラスを定義し、そのようなtied属性の「呼び出し可能」:その後、私はtied属性を検査

>>> 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',) 

。私の理解では、(脚注参照)、これは辞書でなければならないことであるが、そうではありません。

>>> 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 

私は辞書として、それを設定しようとすると、それが適切なParameterを更新しません:

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

しかし、複合型モデルクラスの代わりにバットからすぐにオブジェクトを作成しようとすると(これは最後にやりたいことではありません)、オブジェクトのtied属性は辞書です。残念ながら、この辞書を設定することは、まだ所望の効果を生成しません:

>>> 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> 

は、したがって、この例では、tied属性が正しい機能を保持していますが、パラメータのvalueはそれに応じて更新されません。

私はここで間違っていますか? tied属性を完全に誤解していますか?

(私は上記の例でAstropy 1.3.3でのPython 3.5.2を使用しています)


は脚注:

help(TwoModel)を実行すると、私は以下の情報を得る:

⁝ 
| 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

良い質問 - 私はあなたの質問に答えることができるはずですので、このコードのほとんどを書いています。私はその日に外出しようとしていますが、私はできるだけ早く元気に戻そうとします。残念なことに、複合モデルの制約を扱うIIRCはややこしいことがあります。 – Iguananaut

+1

私はあなたに今話すことの一つは、パラメータの値を手動で更新するときにモデルの制約が適用されるという誤解に陥っているように見えます。これはそうではありません。制約は、フィッティング時にモデルにフィットするときにのみ使用され、パラメータに制約を設定します。フィッティング制約の外は強制されません。私は前にこれを変えることを考えました、あなたが期待しているように動作するように。ある時点で問題が開いていましたが、今見つからないようです... – Iguananaut

+0

私はhttps://github.com/astropy/astropy/issues/2265でこれを参照しています。 – Iguananaut

答えて

0

以下の例は、astropyのドキュメントに記載されている例に似ています。

複合モデル= 2つの1次元ガウス関数の合計。

拘束:すべての3つの手段の和は常に1に等しくなければならない三つの1Dガウス関数 拘束のCompund_model =和astropyでmean_1 = 2 *平均_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) 

タイイングパラメータ。

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) 
関連する問題