サポート単位と数量¶
注釈
ここで提供されている機能は最近追加されたものです。何か問題があったら、迷わずにいてください issue tracker それがそうです。
♪the astropy.modeling
ソフトウェアパッケージ部分は、モデルパラメータ、モデル、およびチューブの間の単位および数の使用をサポートする。現在、一部の内蔵モデルしかありません(例えば Gaussian1D
)ユニットをサポートしますが、これは将来的にすべての適切なモデルに拡張されます。
パラメータを数量に設定する¶
モデルはいいです Quantity
パラメータの対象とする::
>>> from astropy import units as u
>>> from astropy.modeling.models import Gaussian1D
>>> g1 = Gaussian1D(mean=3 * u.m, stddev=2 * u.cm, amplitude=3 * u.Jy)
次いで、パラメータにアクセスすると、値および単位を含むParameterオブジェクトが返される:
>>> g1.mean
Parameter('mean', value=3.0, unit=m)
そして、パラメータの各属性にアクセスすることができる:
>>> g1.mean.name
'mean'
>>> g1.mean.value
3.0
>>> g1.mean.unit
Unit("m")
パラメータが数量に初期化された場合、常に数量に設定されるべきであるが、単位は初期単位と互換性がある必要はない。
>>> g1.mean = 3 * u.s
>>> g1
<Gaussian1D(amplitude=3. Jy, mean=3. s, stddev=2. cm)>
単位ではなくパラメータ値を変更するためには,Value属性を設定するだけでよい:
>>> g1.mean.value = 2
>>> g1
<Gaussian1D(amplitude=3. Jy, mean=2. s, stddev=2. cm)>
最初に数に設定したパラメータをスカラーに設定することは機能しないが,ユーザは値のみを変更して単位を保持したいのか,単位を除去したいのか:
>>> g1.mean = 2
Traceback (most recent call last):
...
UnitsError : The 'mean' parameter should be given as a Quantity because it
was originally initialized as a Quantity
一方、先に定義された単位なしパラメータのために単位を有する量を指定する場合、これは明確であるので、これは可能である。
>>> g2 = Gaussian1D(mean=3)
>>> g2.mean = 3 * u.m
言い換えれば,単位をパラメータに付加すると,意味が明確でないため,それらを削除することはできない.
数量評価モデル¶
評価中に、数をモデルに渡すことができる:
>>> g3 = Gaussian1D(mean=3 * u.m, stddev=5 * u.cm)
>>> g3(2.9 * u.m)
<Quantity 0.1353352832366122>
>>> g3(2.9 * u.s)
Traceback (most recent call last):
...
UnitsError : Units of input 'x', s (time), could not be converted to
required input units of m (length)
この場合,平均値と標準偏差には単位があるため,評価過程で伝達される値にも単位が必要となる.
>>> g3(3)
Traceback (most recent call last):
...
UnitsError : Units of input 'x', (dimensionless), could not be converted to
required input units of m (length)
等価物.¶
等価性は、特に留意されたい。例えば、周波数空間において定義されるガウスは、波長空間において定義されるガウスではない。したがって、私たちは等価項をパラメータ自体に付加することを許さない。代わりに,入力データをパラメータ空間に変換する方法をとり,いずれの等価性も評価時にデータ(パラメータではなく)に適用すべきである.
ガウスの波長空間のモデルを考えてみましょう
>>> g4 = Gaussian1D(mean=3 * u.micron, stddev=1 * u.micron, amplitude=3 * u.Jy)
デフォルトの場合、伝達頻度は機能しません:
>>> g4(1e2 * u.THz)
Traceback (most recent call last):
...
UnitsError : Units of input 'x', THz (frequency), could not be converted to
required input units of micron (length)
しかし、等価辞書をEvalvaliesパラメータに渡すことができます(これは、いくつかのモデルが複数の入力を含むことができるので、辞書である必要があります)。
>>> g4(110 * u.THz, equivalencies={'x': u.spectral()})
<Quantity 2.888986819525229 Jy>
辞書のキーワードは入力された名称であるべきであり,以下のようになる.
>>> g4.inputs
('x',)
INPUT_UNITS_EQUALALITIES属性を使用して、入力パラメータのデフォルト等価値を設定することもできます:
>>> g4.input_units_equivalencies = {'x': u.spectral()}
>>> g4(110 * u.THz)
<Quantity 2.888986819525229 Jy>
単位付きモデルをデータにフィッティングする¶
モデルが単位を用いてフィッティングを行うことをサポートしていれば,単位を用いたモデルと使用単位のデータのフィッティングはシームレスであるはずである.これを示すために、まず合成データを生成します。
import numpy as np
from astropy import units as u
import matplotlib.pyplot as plt
x = np.linspace(1, 5, 30) * u.micron
y = np.exp(-0.5 * (x - 2.5 * u.micron)**2 / (200 * u.nm)**2) * u.mJy
plt.plot(x, y, 'ko')
plt.xlabel('Wavelength (microns)')
plt.ylabel('Flux density (mJy)')
そして部品の初期推定を定義し何の単位も使わずにフィッティングします
from astropy.modeling import models, fitting
g5 = models.Gaussian1D(mean=3 * u.micron, stddev=1 * u.micron, amplitude=1 * u.Jy)
fitter = fitting.LevMarLSQFitter()
g5_fit = fitter(g5, x, y)
plt.plot(x, y, 'ko')
plt.plot(x, g5_fit(x), 'r-')
plt.xlabel('Wavelength (microns)')
plt.ylabel('Flux density (mJy)')
等価性フィッティング¶
データはパラメータのデータと同等ではないが,等価で変換できる場合を考える.この場合、等価物は、上記の評価例に示すように、辞書によって伝達されることができる。
g6 = models.Gaussian1D(mean=110 * u.THz, stddev=10 * u.THz, amplitude=1 * u.Jy)
g6_fit = fitter(g6, x, y, equivalencies={'x': u.spectral()})
plt.plot(x, g6_fit(x, equivalencies={'x': u.spectral()}), 'b-')
plt.xlabel('Wavelength (microns)')
plt.ylabel('Flux density (mJy)')
この場合、周波数空間(青色)におけるガウスは、波長空間(赤色)におけるガウスではないので、フィッティング(青色)はやや悪い。前述したように、追加のパラメータをFitterに渡すことを避けるために、INPUT_UNITS_EQUALILEATIONSをモデル自体に設定することもできます:
g6.input_units_equivalencies = {'x': u.spectral()}
g6_fit = fitter(g6, x, y)
セルレスモデルにおけるユニットのサポート¶
多項式のようなモデルもあり,本質的に単位には適用できない.その代わりに coerce_units()
無単位モデルを含む入力単位および戻り単位を無単位モデルに追加する方法を提供する UnitsMapping
それがそうです。内部では,入力がモデルに渡される前に単位が剥離され,単位が結果に付加される. return_units
指定されています。この方法は、新しい複合モデルを返す:
>>> from astropy.modeling import models
>>> from astropy import units as u
>>> model = models.Polynomial1D(1, c0=1, c1=2)
>>> new_model = model.coerce_units(input_units={'x': u.Hz}, return_units={'y': u.s},
... input_units_equivalencies={'x':u.spectral()})
>>> new_model(10 * u.Hz)
<Quantity 21. s>