Я заранее прошу прощения, если это кажется более сложным, чем необходимо.Пытался сделать его более минимальным, чем этот, но тогда некоторые вопросы было сложнее сформулировать.Таким образом, это максимально близко к моей ситуации.У меня есть некоторые данные, которые я хочу дополнить функцией, аналогичной описанной ниже.Но при реализации подгонки pyMC3, как во втором разделе кода, я сталкиваюсь с ошибками, связанными с этими двумя вопросами.
# some constants and fixed things
rin = 1.
rout = 1000.
tmin = 10.
x = np.arange(0.1, 10, 0.2)
# parameters to be fitted
a = 4.0
b = 0.5
c = 10
# define r_struct, depends on b, but is one value
r_struct = 0.1**(1./b)
# nrad below, the number of radial points,
# depends on r_struct and the constant rout
# QUESTION 1 here
nrad = round(r_struct, -1) + round((rout - r_struct)/10., -1) * 2
# define the radial bins, logarithmically spaced
rbins = np.logspace(np.log10(rin), np.log10(rout), num=nrad+1, endpoint=True)
rad = 10**(( np.log10(rbins[1:]) + np.log10(rbins[:-1]))/2.)
t = rad**(-b)
# QUESTION 2 here
# t cannot go below tmin, so I do this
t[t < tmin] = tmin
# then I want to know where the limit of r_struct is here
iout = rad > r_struct
iin = rad <= r_struct
# depending on if rad is past r_struct or not
# I do two different things.
c1 = c_struct * (rad[iin]/50.)**(-1.*a)
taper = np.exp( -(rad[iout]/rad[iout][0])**(2.-a) )
c2 = c_taper * taper/taper[0]
tau = np.append(c1, c2)
y_true = J0( x[:, np.newaxis] * rad) * (t * (1.0 - np.exp(-1.*tau) ) )
y_true = y_true.sum(axis=1)
y_obs = y_true + np.random.normal(size=len(x))*50
y_error = np.ones_like(y_true)*0.1*y_true.max()
plt.errorbar(x,y_obs, yerr= y_error, color='r', marker='.', ls='None', label='Observed')
plt.plot(x,y_true, 'b', marker='None', ls='-', lw=1, label='True')
plt.xlabel('x'); plt.ylabel('y'); plt.legend()
OKтак что теперь я хочу вписать это в PyMC3.Я начал со следующего:
with pm.Model() as basic_model:
# parameters
a = pm.Uniform("a", 0, 10)
b = pm.Uniform("b", 0, 10)
c = pm.Uniform("c", 0,100)
r_struct = 0.1**(1./b)
nrad = round(r_struct, -1) + round((rout - r_struct)/10., -1) * 2
rbins = np.logspace(np.log10(rin), np.log10(rout), num=nrad+1, endpoint=True)
rad = 10**(( np.log10(rbins[1:]) + np.log10(rbins[:-1]))/2.)
t = rad**(-b)
t[t < tmin] = tmin
iout = rad > r_struct
iin = rad <= r_struct
c1 = c_struct * (rad[iin]/50.)**(-1.*a)
taper = np.exp( -(rad[iout]/rad[iout][0])**(2.-a) )
c2 = c_taper * taper/taper[0]
tau = np.append(c1, c2)
y_true = J0( x[:, np.newaxis] * rad) * (t * (1.0 - np.exp(-1.*tau) ) )
y_true = y_true.sum(axis=1)
func=pm.Deterministic('gauss',y_true)
y = pm.Normal('y', mu=func, tau=1.0/y_error**2, observed=y_obs)
trace = pm.sample(5000)
Однако это не удалось уже при первом вызове round ().См. Вопросы ниже.
ВОПРОС 1. "nrad" должно быть целым числом, это зависит от pymc3 перед "b" (через r_struct), как мне его округлитьи целое число при запуске PyMC3? Для справки я получаю эту ошибку:
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-11-fcf897a21b89> in <module>()
15 r_struct = 0.1**(1./b)
16
---> 17 nrad = round(r_struct, -1) + round((rout - r_struct)/10., -1) * 2
18 rbins = np.logspace(np.log10(rin), np.log10(rout), num=nrad+1, endpoint=True)
TypeError: type TensorVariable doesn't define __round__ method
ВОПРОС 2: Как выполнить сравнение с массивом, созданным с помощьюДо PyMC3? При сравнении не получается код.
---------------------------------------------------------------------------
AssertionError Traceback (most recent call last)
<ipython-input-12-7f77e70d147a> in <module>()
26 t = rad**(-b)
27
---> 28 t[t < tmin] = tmin
29 iout = rad > r_struct
30 iin = rad <= r_struct
Приветствуются любые предложения по разъяснению вопроса, включая заголовок!