Как мне округлить и сделать сравнение с предыдущими параметрами PyMC3 в модели? - PullRequest
0 голосов
/ 17 октября 2018

Я заранее прошу прощения, если это кажется более сложным, чем необходимо.Пытался сделать его более минимальным, чем этот, но тогда некоторые вопросы было сложнее сформулировать.Таким образом, это максимально близко к моей ситуации.У меня есть некоторые данные, которые я хочу дополнить функцией, аналогичной описанной ниже.Но при реализации подгонки 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()

enter image description here

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

Приветствуются любые предложения по разъяснению вопроса, включая заголовок!

...