Пример #1
0
    def _model_setup(self):
        with self._model:
            # COSMOLOGY


            omega_m = pm.Uniform("OmegaM", lower=0, upper=1.)

            # dark energy EOS
            w = pm.Normal("w", mu=-1, sd=1)

            # My custom distance mod. function to enable
            # ADVI and HMC smapling.

            dm = distmod_w_flat(omega_m, self._h0, w, self._zcmb)

            # PHILIPS PARAMETERS

            # M0 is the location parameter for the distribution
            # sys_scat is the scale parameter for the M0 distribution
            # rather than "unexpalined variance"
            M0 = pm.Normal("M0", mu=-19.3, sd=2.)
            sys_scat = pm.HalfCauchy('sys_scat', beta=2.5)  # Gelman recommendation for variance parameter
            M_true = pm.Normal('M_true', M0, sys_scat, shape=self._n_SN)

            # following Rubin's Unity model... best idea? not sure
            taninv_alpha = pm.Uniform("taninv_alpha", lower=-.2, upper=.3)
            taninv_beta = pm.Uniform("taninv_beta", lower=-1.4, upper=1.4)

            # Transform variables
            alpha = pm.Deterministic('alpha', T.tan(taninv_alpha))
            beta = pm.Deterministic('beta', T.tan(taninv_beta))

            # Again using Rubin's Unity model.
            # After discussion with Rubin, the idea is that
            # these parameters are ideally sampled from a Gaussian,
            # but we know they are not entirely correct. So instead,
            # the Cauchy is less informative around the mean, while
            # still having informative tails.

            xm = pm.Cauchy('xm', alpha=0, beta=1)
            cm = pm.Cauchy('cm', alpha=0, beta=1)

            Rx_log = pm.Uniform('Rx_log', lower=-0.5, upper=0.5)
            Rc_log = pm.Uniform('Rc_log', lower=-1.5, upper=1.5)

            # Transformed variables
            Rx = pm.Deterministic("Rx", T.pow(10., Rx_log))
            Rc = pm.Deterministic("Rc", T.pow(10., Rc_log))

            x_true = pm.Normal('x_true', mu=xm, sd=Rx, shape=self._n_SN)
            c_true = pm.Normal('c_true', mu=cm, sd=Rc, shape=self._n_SN)

            # Do the correction
            mb = pm.Deterministic("mb", M_true + dm - alpha * x_true + beta * c_true)

            # Likelihood and measurement error

            obsc = pm.Normal("obsc", mu=c_true, sd=self._dcolor, observed=self._color)
            obsx = pm.Normal("obsx", mu=x_true, sd=self._dx1, observed=self._x1)
            obsm = pm.Normal("obsm", mu=mb, sd=self._dmb_obs, observed=self._mb_obs)
Пример #2
0
def sky_position(period, t0, e, omega, incl, t, **kwargs):
    # Shorthands
    n = 2.0 * np.pi / period
    cos_omega = tt.cos(omega)
    sin_omega = tt.sin(omega)

    # Find the reference time that puts the center of transit at t0
    E0 = 2.0 * tt.atan2(
        tt.sqrt(1.0 - e) * cos_omega,
        tt.sqrt(1.0 + e) * (1.0 + sin_omega))
    tref = t0 - (E0 - e * tt.sin(E0)) / n

    # Solve Kepler's equation for the true anomaly
    M = (t - tref) * n
    kepler = KeplerOp(**kwargs)
    E = kepler(M, e + tt.zeros_like(M))
    f = 2.0 * tt.atan2(
        tt.sqrt(1.0 + e) * tt.tan(0.5 * E),
        tt.sqrt(1.0 - e) + tt.zeros_like(E))

    # Rotate into sky coordinates
    cf = tt.cos(f)
    sf = tt.sin(f)
    swpf = sin_omega * cf + cos_omega * sf
    cwpf = cos_omega * cf - sin_omega * sf

    # Star / planet distance
    r = (1.0 - e**2) / (1 + e * cf)

    return tt.stack(
        [-r * cwpf, -r * swpf * tt.cos(incl), r * swpf * tt.sin(incl)])
 def build_model(self, name='normal_model'):
     # Define Stochastic variables
     with pm.Model(name=name) as self.model:
         # Global mean pitch angle
         self.mu_phi = pm.Uniform('mu_phi', lower=0, upper=90)
         self.sigma_phi = pm.InverseGamma('sigma_phi',
                                          alpha=2,
                                          beta=15,
                                          testval=8)
         self.sigma_gal = pm.InverseGamma('sigma_gal',
                                          alpha=2,
                                          beta=15,
                                          testval=8)
         # define a mean galaxy pitch angle
         self.phi_gal = pm.TruncatedNormal(
             'phi_gal',
             mu=self.mu_phi,
             sd=self.sigma_phi,
             lower=0,
             upper=90,
             shape=len(self.galaxies),
         )
         # draw arm pitch angles centred around this mean
         self.phi_arm = pm.TruncatedNormal(
             'phi_arm',
             mu=self.phi_gal[self.gal_arm_map],
             sd=self.sigma_gal,
             lower=0,
             upper=90,
             shape=len(self.gal_arm_map),
         )
         # convert to a gradient for a linear fit
         self.b = tt.tan(np.pi / 180 * self.phi_arm)
         # arm offset parameter
         self.c = pm.Cauchy('c',
                            alpha=0,
                            beta=10,
                            shape=self.n_arms,
                            testval=np.tile(0, self.n_arms))
         # radial noise
         self.sigma_r = pm.InverseGamma('sigma_r', alpha=2, beta=0.5)
         r = pm.Deterministic(
             'r',
             tt.exp(self.b[self.point_arm_map] * self.data['theta'] +
                    self.c[self.point_arm_map]))
         # likelihood function
         self.likelihood = pm.Normal(
             'Likelihood',
             mu=r,
             sigma=self.sigma_r,
             observed=self.data['r'],
         )
    def build_model(self, name=''):
        # Define Stochastic variables
        with pm.Model(name=name) as self.model:
            # Global mean pitch angle
            self.phi_gal = pm.Uniform('phi_gal',
                                      lower=0,
                                      upper=90,
                                      shape=len(self.galaxies))
            # note we don't model inter-galaxy dispersion here
            # intra-galaxy dispersion
            self.sigma_gal = pm.InverseGamma('sigma_gal',
                                             alpha=2,
                                             beta=20,
                                             testval=5)
            # arm offset parameter
            self.c = pm.Cauchy('c',
                               alpha=0,
                               beta=10,
                               shape=self.n_arms,
                               testval=np.tile(0, self.n_arms))

            # radial noise
            self.sigma_r = pm.InverseGamma('sigma_r', alpha=2, beta=0.5)

            # define prior for Student T degrees of freedom
            # self.nu = pm.Uniform('nu', lower=1, upper=100)

            # Define Dependent variables
            self.phi_arm = pm.TruncatedNormal(
                'phi_arm',
                mu=self.phi_gal[self.gal_arm_map],
                sd=self.sigma_gal,
                lower=0,
                upper=90,
                shape=self.n_arms)

            # convert to a gradient for a linear fit
            self.b = tt.tan(np.pi / 180 * self.phi_arm)
            r = pm.Deterministic(
                'r',
                tt.exp(self.b[self.data['arm_index'].values] *
                       self.data['theta'] +
                       self.c[self.data['arm_index'].values]))

            # likelihood function
            self.likelihood = pm.StudentT(
                'Likelihood',
                mu=r,
                sigma=self.sigma_r,
                nu=1,  #self.nu,
                observed=self.data['r'],
            )
Пример #5
0
def hierarchial(subject_id=20902040):
    X_all = np.concatenate([
        np.stack(((arm.t * arm.chirality), arm.R, arm.point_weights,
                  np.tile(arm_no, len(arm.R))),
                 axis=1)
        for arm_no, arm in enumerate(get_arms(subject_id, err=False))
    ])
    # remove values with zero weight
    X = X_all[X_all.T[2] > 0]

    t, R, point_weights = X.T[:3]
    # get an arm index
    enc = OrdinalEncoder(dtype=np.int32)
    arm_idx = enc.fit_transform(X[:, [3]]).T[0]

    n_unique_arms = len(np.unique(arm_idx))

    with pm.Model() as hierarchical_model:
        print('Defining model')
        mu_psi = pm.Uniform('mu_psi', lower=0, upper=80, testval=15.0)
        sigma_psi = pm.HalfCauchy('sigma_psi', beta=1)
        psi_offset = pm.Normal('psi_offset', mu=0, sd=1)
        psi = pm.Deterministic('psi', mu_psi + sigma_psi * psi_offset)
        psi_radians = psi * np.pi / 180

        a = pm.Uniform('a', lower=0, upper=200, testval=1, shape=n_unique_arms)

        # define our equation for mu_r
        r_est = (a[arm_idx] / 100 * tt.exp(tt.tan(psi_radians) * t))

        # define our expected error on r here we assume this sigma is the
        # same for all galaxies (not necessarily true)
        base_sigma = pm.HalfCauchy('sigma', beta=5, testval=0.02)
        sigma_y = theano.shared(np.asarray(np.sqrt(point_weights),
                                           dtype=theano.config.floatX),
                                name='sigma_y')
        sigmas = base_sigma / sigma_y

        # define our likelihood function
        pm.Normal('R_like', mu=r_est, sd=sigmas, observed=R)

    with hierarchical_model:
        trace = pm.sample(2000, tune=1000, cores=2)

    pm.traceplot(trace)
    plt.gcf().set_size_inches(6, 15)
    pm.plots.pairplot(trace, varnames=['mu_psi', 'sigma_psi', 'sigma'])
    plt.gcf().set_size_inches(10, 10)
    pm.plots.plot_posterior(trace, kde_plot=True)
    plt.gcf().set_size_inches(10, 10)
    plt.show()
Пример #6
0
    def build_model(self, name=''):
        # Define Stochastic variables
        with pm.Model(name=name) as self.model:
            # Global mean pitch angle
            self.phi_gal = pm.Uniform('phi_gal',
                                      lower=0,
                                      upper=90,
                                      shape=len(self.galaxies))
            # note we don't model inter-galaxy dispersion here
            # intra-galaxy dispersion
            self.sigma_gal = pm.InverseGamma('sigma_gal',
                                             alpha=2,
                                             beta=20,
                                             testval=5)
            # arm offset parameter
            self.c = pm.Cauchy('c',
                               alpha=0,
                               beta=10,
                               shape=self.n_arms,
                               testval=np.tile(0, self.n_arms))

            # radial noise
            self.sigma_r = pm.InverseGamma('sigma_r', alpha=2, beta=0.5)

            # ----- Define Dependent variables -----

            # Phi arm is drawn from a truncated normal centred on phi_gal with
            # spread sigma_gal
            gal_idx = self.gal_arm_map.astype('int32')
            self.phi_arm = pm.TruncatedNormal('phi_arm',
                                              mu=self.phi_gal[gal_idx],
                                              sd=self.sigma_gal,
                                              lower=0,
                                              upper=90,
                                              shape=self.n_arms)

            # transform to gradient for fitting
            self.b = tt.tan(np.pi / 180 * self.phi_arm)

            # r = exp(theta * tan(phi) + c)
            # do not track this as it uses a lot of memory
            arm_idx = self.data['arm_index'].values.astype('int32')
            r = tt.exp(self.b[arm_idx] * self.data['theta'] + self.c[arm_idx])

            # likelihood function (assume likelihood here)
            self.likelihood = pm.Normal(
                'Likelihood',
                mu=r,
                sigma=self.sigma_r,
                observed=self.data['r'],
            )
Пример #7
0
    def get_rvmodels(self, t, name=None):
        K = tt.exp(tt.stack([p.logK for p in self.planets]))
        n = tt.stack([p.n for p in self.planets])
        t0 = tt.stack([p.t0 for p in self.planets])
        e = tt.stack([p.eccen for p in self.planets])
        cosw = tt.stack([p.omegavec[0] for p in self.planets])
        sinw = tt.stack([p.omegavec[1] for p in self.planets])

        mean_anom = n * (t[:, None] - t0)
        eccen_arg = e + tt.zeros_like(mean_anom)
        eccen_anom = self.kepler(mean_anom, eccen_arg)
        f = 2 * tt.arctan2(
            tt.sqrt(1 + e) * tt.tan(0.5 * eccen_anom),
            tt.sqrt(1 - e) + tt.zeros_like(eccen_anom))
        return pm.Deterministic(
            join_names(self.name, name, "rvmodels"),
            K * (cosw * (tt.cos(f) + e) - sinw * tt.sin(f)))
Пример #8
0
    def construct_likelihood(self):
        pm.Deterministic('gradient', tt.tan(self.model['angle']))
        pm.Deterministic(
            'intercept',
            self.model['displacement'] / tt.cos(self.model['angle']))

        if self.data_covariances is not None:
            pm.Potential(
                'like',
                likelihood(self.model['angle'], self.model['displacement'],
                           self.model['ln_variance'], self.z, self.s))
        else:
            sigma = tt.exp(self.model['ln_variance'])**0.5
            pm.Normal('like',
                      mu=self.relation(self.z[:, 0]),
                      sd=sigma,
                      observed=self.z[:, 1],
                      shape=len(self.data))
Пример #9
0
def get_logsp_trace_from_arms(arms, nsamples=3000):
    X = np.concatenate([
        np.stack(((arm.t * arm.chirality), arm.R, arm.point_weights,
                  np.tile(i, len(arm.R))),
                 axis=1) for i, arm in enumerate(arms)
    ])
    pw_mask = X[:, 2] > 0
    t = X[:, 0][pw_mask]
    R = X[:, 1][pw_mask]
    weights = X[:, 2][pw_mask]

    pa, sigma_pa = arms[0].get_parent().get_pitch_angle(arms)

    with pm.Model() as model:
        # psi has a uniform prior over all reasonable values (-80, 80)
        # not -90 to 90 to avoid infinities / overflows
        psi = pm.Uniform('psi', lower=0, upper=80, testval=pa)
        psi_radians = psi * np.pi / 180

        # model a as a uniform, which we scale later so our varibles have
        # similar magnitude
        a = pm.Uniform('a', lower=0, upper=200, testval=1, shape=len(arms))
        a_arr = tt.concatenate(
            [tt.tile(a[i], len(arms[i].t)) for i in range(len(arms))])[pw_mask]

        # define our equation for mu_r
        mu_r = a_arr / 100 * tt.exp(tt.tan(psi_radians) * t)

        # define our expected error on r (different to error on psi)
        base_sigma = pm.HalfCauchy('sigma', beta=5, testval=0.02)
        sigma_y = theano.shared(np.asarray(np.sqrt(weights),
                                           dtype=theano.config.floatX),
                                name='sigma_y')
        sigmas = base_sigma / sigma_y
        # define our likelihood function
        likelihood = pm.Normal('R', mu=mu_r, sd=sigmas, observed=R)
        # run the sampler

    with model:
        trace = pm.sample(nsamples, tune=1500, cores=2)

    return trace
Пример #10
0
def model(inp):
    """
        MODEL 1:
        fc1 = T.dot(inp, weight1) ** np.sqrt(2)
        fc2 = T.tan(T.dot(fc1, weight2))
        fc3 = T.dot(fc2, weight3)
    """
    """
        MODEL 2:
        This model is particularly interesting because of the piecewise nature of the non-linearity (max). This results in fragments or shards in the end fractal.

        fc1 = T.maximum(T.dot(inp, weight1) ** np.sqrt(2), 0)
        fc2 = T.maximum(T.tan(T.dot(fc1, weight2)), 0)
        fc3 = T.dot(fc2, weight3)
    """
    """
        MODEL 3:
    """

    fc1 = T.dot(T.minimum(inp, 0), weight1)**np.sqrt(2)
    fc2 = T.tan(T.dot(fc1, weight2))
    fc3 = T.dot(fc2, weight3)

    return fc3
Пример #11
0
 def B(self, alpha, beta):
     return (1 / alpha) * T.arctan(beta * T.tan(self.pi * alpha / 2))
Пример #12
0
 def B(self, alpha, beta):
     return (1/alpha)*T.arctan(beta*T.tan(self.pi*alpha/2))
Пример #13
0
 def UNSQUASH(self, unit_box_sample):
     """ Perform the unboxing operation symbolically (see .unsquash). """
     
     return tns.tan(np.pi * (unit_box_sample - 0.5))
Пример #14
0
t = np.linspace(0, 10, 2)
x = np.random.uniform(0, 10, 50)
y = x * true_params[0] + true_params[1]
y_obs = y + np.exp(true_params[-1]) * np.random.randn(N)

plt.plot(x, y_obs, ".k", label="observations")
plt.plot(t, true_params[0] * t + true_params[1], label="truth")
plt.xlabel("x")
plt.ylabel("y")
plt.legend(fontsize=14)

import pymc3 as pm
import theano.tensor as tt

with pm.Model() as model:
    logs = pm.Uniform("logs", lower=-10, upper=10)
    alphaperp = pm.Uniform("alphaperp", lower=-10, upper=10)
    theta = pm.Uniform("theta", -2 * np.pi, 2 * np.pi, testval=0.0)

    # alpha_perp = alpha * cos(theta)
    alpha = pm.Deterministic("alpha", alphaperp / tt.cos(theta))

    # beta = tan(theta)
    beta = pm.Deterministic("beta", tt.tan(theta))

    # The observation model
    mu = alpha * x + beta
    pm.Normal("obs", mu=mu, sd=tt.exp(logs), observed=y_obs)

    trace = pm.sample(draws=2000, tune=2000)
Пример #15
0
n_times = 100
#n_times = len(df["X"].unique()) #時間の数
basic_model = Model()

#subtensorの使い方↓
#http://deeplearning.net/software/theano/library/tensor/basic.html

with basic_model: 
    #事前分布
    #コーシー分布は逆関数法にて乱数生成
    s_mu =  HalfNormal('s_mu', sd=1) #コーシー分布の分散
    s_Y =  HalfNormal('s_Y', sd=1) #観測誤差
    mu_0 = Normal('mu_0',mu=0, sd=1)  #初期状態
    x = Uniform("x" ,lower=-math.pi/2,upper=math.pi/2, shape=n_times-1)
    
    #Cauchyの誤差process
    c = tt.dot(s_mu,tt.tan(x))
    
    #状態process
    mu = tt.zeros((n_times))
    mu = tt.set_subtensor(mu[0], mu_0)
    for i in range(n_times-1):
        mu = tt.set_subtensor(mu[i+1], mu[i]+c[i])

    #likelihood
    Y_obs = Normal('Y_obs', mu=mu, sd=s_Y, observed=Y)    
    
    #サンプリング 
    trace = sample(1000,n_init=5000)
    summary(trace)
Пример #16
0
def tan(x):
  return T.tan(x)
Пример #17
0
    def _model_setup(self):
        with self._model:
            # COSMOLOGY


            omega_m = pm.Uniform("OmegaM", lower=0., upper=1.)
            omega_k = pm.Uniform("Omegak", lower=-1., upper=1.)

            # My custom distance mod. function to enable
            # ADVI and HMC sampling.



            #  We are going to have to break this into
            #  four likelihoods

            dm_0 = distmod_constant_curve(omega_m, omega_k, self._h0, self._zcmb_survey[0])
            dm_1 = distmod_constant_curve(omega_m, omega_k, self._h0, self._zcmb_survey[1])
            dm_2 = distmod_constant_curve(omega_m, omega_k, self._h0, self._zcmb_survey[2])
            dm_3 = distmod_constant_curve(omega_m, omega_k, self._h0, self._zcmb_survey[3])

            # PHILIPS PARAMETERS

            # M0 is the location parameter for the distribution
            # sys_scat is the scale parameter for the M0 distribution
            # rather than "unexpalined variance"
            M0 = pm.Uniform("M0", lower=-20., upper=-18.)
            sys_scat = pm.HalfCauchy('sys_scat', beta=2.5)  # Gelman recommendation for variance parameter

            M_true_0 = pm.Normal('M_true_0', M0, sys_scat, shape=self._n_SN_survey[0])
            M_true_1 = pm.Normal('M_true_1', M0, sys_scat, shape=self._n_SN_survey[1])
            M_true_2 = pm.Normal('M_true_2', M0, sys_scat, shape=self._n_SN_survey[2])
            M_true_3 = pm.Normal('M_true_3', M0, sys_scat, shape=self._n_SN_survey[3])

            # following Rubin's Unity model... best idea? not sure
            taninv_alpha = pm.Uniform("taninv_alpha", lower=-.2, upper=.3)
            taninv_beta = pm.Uniform("taninv_beta", lower=-1.4, upper=1.4)

            # Transform variables
            alpha = pm.Deterministic('alpha', T.tan(taninv_alpha))
            beta = pm.Deterministic('beta', T.tan(taninv_beta))

            # Again using Rubin's Unity model.
            # After discussion with Rubin, the idea is that
            # these parameters are ideally sampled from a Gaussian,
            # but we know they are not entirely correct. So instead,
            # the Cauchy is less informative around the mean, while
            # still having informative tails.

            xm = pm.Cauchy('xm', alpha=0, beta=1)

            cm = pm.Cauchy('cm', alpha=0, beta=1, shape=4)

            s = pm.Uniform('s', lower=-2, upper=2, shape=4)

            c_shift_0 = cm[0] + s[0] * self._zcmb_survey[0]
            c_shift_1 = cm[1] + s[1] * self._zcmb_survey[1]
            c_shift_2 = cm[2] + s[2] * self._zcmb_survey[2]
            c_shift_3 = cm[3] + s[3] * self._zcmb_survey[3]

            Rx_log = pm.Uniform('Rx_log', lower=-0.5, upper=0.5)
            Rc_log = pm.Uniform('Rc_log', lower=-1.5, upper=1.5, shape=4)

            # Transformed variables
            Rx = pm.Deterministic("Rx", T.pow(10., Rx_log))

            Rc = pm.Deterministic("Rc", T.pow(10., Rc_log))

            x_true_0 = pm.Normal('x_true_0', mu=xm, sd=Rx, shape=self._n_SN_survey[0])
            c_true_0 = pm.Normal('c_true_0', mu=c_shift_0, sd=Rc[0], shape=self._n_SN_survey[0])
            x_true_1 = pm.Normal('x_true_1', mu=xm, sd=Rx, shape=self._n_SN_survey[1])
            c_true_1 = pm.Normal('c_true_1', mu=c_shift_1, sd=Rc[1], shape=self._n_SN_survey[1])
            x_true_2 = pm.Normal('x_true_2', mu=xm, sd=Rx, shape=self._n_SN_survey[2])
            c_true_2 = pm.Normal('c_true_2', mu=c_shift_2, sd=Rc[2], shape=self._n_SN_survey[2])
            x_true_3 = pm.Normal('x_true_3', mu=xm, sd=Rx, shape=self._n_SN_survey[3])
            c_true_3 = pm.Normal('c_true_3', mu=c_shift_3, sd=Rc[3], shape=self._n_SN_survey[3])

            # Do the correction
            mb_0 = pm.Deterministic("mb_0", M_true_0 + dm_0 - alpha * x_true_0 + beta * c_true_0)
            mb_1 = pm.Deterministic("mb_1", M_true_1 + dm_1 - alpha * x_true_1 + beta * c_true_1)
            mb_2 = pm.Deterministic("mb_2", M_true_2 + dm_2 - alpha * x_true_2 + beta * c_true_2)
            mb_3 = pm.Deterministic("mb_3", M_true_3 + dm_3 - alpha * x_true_3 + beta * c_true_3)

            # Likelihood and measurement error

            obsc_0 = pm.Normal("obsc_0", mu=c_true_0, sd=self._dcolor_survey[0], observed=self._color_survey[0])
            obsx_0 = pm.Normal("obsx_0", mu=x_true_0, sd=self._dx1_survey[0], observed=self._x1_survey[0])
            obsm_0 = pm.Normal("obsm_0", mu=mb_0, sd=self._dmbObs_survey[0], observed=self._mbObs_survey[0])

            obsc_1 = pm.Normal("obsc_1", mu=c_true_1, sd=self._dcolor_survey[1], observed=self._color_survey[1])
            obsx_1 = pm.Normal("obsx_1", mu=x_true_1, sd=self._dx1_survey[1], observed=self._x1_survey[1])
            obsm_1 = pm.Normal("obsm_1", mu=mb_1, sd=self._dmbObs_survey[1], observed=self._mbObs_survey[1])

            obsc_2 = pm.Normal("obsc_2", mu=c_true_2, sd=self._dcolor_survey[2], observed=self._color_survey[2])
            obsx_2 = pm.Normal("obsx_2", mu=x_true_2, sd=self._dx1_survey[2], observed=self._x1_survey[2])
            obsm_2 = pm.Normal("obsm_2", mu=mb_2, sd=self._dmbObs_survey[2], observed=self._mbObs_survey[2])

            obsc_3 = pm.Normal("obsc_3", mu=c_true_3, sd=self._dcolor_survey[3], observed=self._color_survey[3])
            obsx_3 = pm.Normal("obsx_3", mu=x_true_3, sd=self._dx1_survey[3], observed=self._x1_survey[3])
            obsm_3 = pm.Normal("obsm_3", mu=mb_3, sd=self._dmbObs_survey[3], observed=self._mbObs_survey[3])
Пример #18
0
def reflected_phase_curve(phases, omega, g, a_rp, return_q=True):
    """
    Reflected light phase curve for a homogeneous sphere by
    Heng, Morris & Kitzmann (2021).

    Parameters
    ----------
    phases : `~np.ndarray`
        Orbital phases of each observation defined on (0, 1)
    omega : tensor-like
        Single-scattering albedo as defined in
    g : tensor-like
        Scattering asymmetry factor, ranges from (-1, 1).
    a_rp : float, tensor-like
        Semimajor axis scaled by the planetary radius

    Returns
    -------
    flux_ratio_ppm : tensor-like
        Flux ratio between the reflected planetary flux and the stellar flux in
        units of ppm.
    A_g : tensor-like
        Geometric albedo derived for the planet given {omega, g}.
    q : tensor-like
        Integral phase function
    """
    # Convert orbital phase on (0, 1) to "alpha" on (0, np.pi)
    alpha = (2 * np.pi * phases - np.pi).astype(floatX)
    abs_alpha = np.abs(alpha).astype(floatX)
    alpha_sort_order = np.argsort(alpha)
    sin_abs_sort_alpha = np.sin(abs_alpha[alpha_sort_order]).astype(floatX)
    sort_alpha = alpha[alpha_sort_order].astype(floatX)

    gamma = tt.sqrt(1 - omega)
    eps = (1 - gamma) / (1 + gamma)

    # Equation 34 for Henyey-Greestein
    P_star = (1 - g**2) / (1 + g**2 + 2 * g * tt.cos(alpha))**1.5
    # Equation 36
    P_0 = (1 - g) / (1 + g)**2

    # Equation 10:
    Rho_S = P_star - 1 + 0.25 * ((1 + eps) * (2 - eps))**2
    Rho_S_0 = P_0 - 1 + 0.25 * ((1 + eps) * (2 - eps))**2
    Rho_L = 0.5 * eps * (2 - eps) * (1 + eps)**2
    Rho_C = eps**2 * (1 + eps)**2

    alpha_plus = tt.sin(abs_alpha / 2) + tt.cos(abs_alpha / 2)
    alpha_minus = tt.sin(abs_alpha / 2) - tt.cos(abs_alpha / 2)

    # Equation 11:
    Psi_0 = tt.log((1 + alpha_minus) * (alpha_plus - 1) / (1 + alpha_plus) /
                   (1 - alpha_minus))
    Psi_S = 1 - 0.5 * (tt.cos(abs_alpha / 2) -
                       1.0 / tt.cos(abs_alpha / 2)) * Psi_0
    Psi_L = (tt.sin(abs_alpha) +
             (np.pi - abs_alpha) * tt.cos(abs_alpha)) / np.pi
    Psi_C = (-1 + 5 / 3 * tt.cos(abs_alpha / 2)**2 -
             0.5 * tt.tan(abs_alpha / 2) * tt.sin(abs_alpha / 2)**3 * Psi_0)

    # Equation 8:
    A_g = omega / 8 * (P_0 - 1) + eps / 2 + eps**2 / 6 + eps**3 / 24

    # Equation 9:
    Psi = ((12 * Rho_S * Psi_S + 16 * Rho_L * Psi_L + 9 * Rho_C * Psi_C) /
           (12 * Rho_S_0 + 16 * Rho_L + 6 * Rho_C))

    flux_ratio_ppm = 1e6 * (a_rp**-2 * A_g * Psi)

    if return_q:
        q = _integral_phase_function(Psi, sin_abs_sort_alpha, sort_alpha,
                                     alpha_sort_order)

        return flux_ratio_ppm, A_g, q
    else:
        return flux_ratio_ppm, A_g
Пример #19
0
def run_simultaneous_hierarchial(recalculate=False,
                                 sample_size=None,
                                 max_ngals=None,
                                 outfolder='hierarchical-model'):
    enc = OrdinalEncoder(dtype=np.int32)
    sid_list = pd.read_csv('lib/subject-id-list.csv').values.T[0]

    if os.path.isfile('Xall.npy') and not recalculate:
        X_all = np.load('Xall.npy')
    else:
        X_all = make_X_all(sid_list)
        np.save('Xall.npy', X_all)

    # remove all points with weight of zero (or less..?)
    all_gal_idx, all_arm_idx = enc.fit_transform(X_all[:, [3, 4]]).T
    if max_ngals is not None and max_ngals <= all_gal_idx.max():
        gals = np.random.choice(np.arange(all_gal_idx.max() + 1),
                                max_ngals,
                                replace=False)
    else:
        gals = np.arange(len(all_gal_idx.max() + 1))
    X_masked = X_all[(X_all.T[2] > 0) & np.isin(all_gal_idx, gals)]
    sample = np.random.choice(len(X_masked), size=sample_size,
                              replace=False) if sample_size else np.arange(
                                  len(X_masked))
    X = X_masked[sample]

    t, R, point_weights = X.T[:3]
    # encode categorical variables into an index
    enc = OrdinalEncoder(dtype=np.int32)
    gal_idx, arm_idx = enc.fit_transform(X[:, [3, 4]]).T
    n_gals = len(np.unique(gal_idx))
    n_unique_arms = len(np.unique(arm_idx))

    print('{} galaxies, {} spiral arms, {} points'.format(
        n_gals, n_unique_arms, len(X)))

    with pm.Model() as hierarchical_model:
        print('Defining model')
        # Hyperpriors (informative for now)
        mu_psi = pm.Uniform('mu_psi', lower=0, upper=80, testval=15)
        # sigma_psi = pm.Gamma('sigma_psi', alpha=2, beta=10)
        sigma_psi = pm.HalfCauchy('sigma_psi', beta=1)
        psi_offset = pm.Normal('psi_offset', mu=0, sd=1, shape=n_gals)
        psi = pm.Deterministic('psi', mu_psi + sigma_psi * psi_offset)
        psi_radians = psi * np.pi / 180

        a = pm.Uniform('a', lower=0, upper=200, testval=1, shape=n_unique_arms)

        # define our equation for mu_r
        r_est = (a[arm_idx] / 100 * tt.exp(tt.tan(psi_radians[gal_idx]) * t))

        # define our expected error on r here we assume this sigma is the
        # same for all galaxies (not necessarily true)
        base_sigma = pm.HalfCauchy('sigma', beta=1, testval=0.02)
        sigma_y = theano.shared(np.asarray(np.sqrt(point_weights),
                                           dtype=theano.config.floatX),
                                name='sigma_y')
        sigmas = base_sigma / sigma_y

        # define our likelihood function
        likelihood = pm.Normal('R_like', mu=r_est, sd=sigmas, observed=R)

    with hierarchical_model:
        trace = pm.sample(2000, tune=1000, cores=2, target_accept=0.95)
    if outfolder is not None:
        traces_dir = os.path.join('uniform-traces', outfolder)
    try:
        os.mkdir(traces_dir)
    except FileExistsError:
        shutil.rmtree(traces_dir)
    pm.save_trace(trace, directory=traces_dir, overwrite=True)
    pm.traceplot(trace, varnames=['mu_psi', 'sigma_psi', 'sigma'])
    plt.show()
Пример #20
0
def reflected_phase_curve_inhomogeneous(phases,
                                        omega_0,
                                        omega_prime,
                                        x1,
                                        x2,
                                        A_g,
                                        a_rp,
                                        return_q=True):
    """
    Reflected light phase curve for an inhomogeneous sphere by
    Heng, Morris & Kitzmann (2021), with inspiration from Hu et al. (2015).

    Parameters
    ----------
    phases : `~np.ndarray`
        Orbital phases of each observation defined on (0, 1)
    omega_0 : tensor-like
        Single-scattering albedo of the less reflective region.
        Defined on (0, 1).
    omega_prime : tensor-like
        Additional single-scattering albedo of the more reflective region,
        such that the single-scattering albedo of the reflective region is
        ``omega_0 + omega_prime``. Defined on (0, ``1-omega_0``).
    x1 : tensor-like
        Start longitude of the darker region [radians] on (-pi/2, pi/2)
    x2 : tensor-like
        Stop longitude of the darker region [radians] on (-pi/2, pi/2)
    a_rp : float, tensor-like
        Semimajor axis scaled by the planetary radius

    Returns
    -------
    flux_ratio_ppm : tensor-like
        Flux ratio between the reflected planetary flux and the stellar flux
        in units of ppm.
    g : tensor-like
        Scattering asymmetry factor on (-1, 1)
    q : tensor-like
        Integral phase function
    """

    g = _g_from_ag(A_g, omega_0, omega_prime, x1, x2)

    # Redefine alpha to be on (-pi, pi)
    alpha = (2 * np.pi * phases - np.pi).astype(floatX)
    abs_alpha = np.abs(alpha).astype(floatX)

    # Equation 34 for Henyey-Greestein
    P_star = (1 - g**2) / (1 + g**2 + 2 * g * tt.cos(abs_alpha))**1.5
    # Equation 36
    P_0 = (1 - g) / (1 + g)**2

    Rho_S, Rho_S_0, Rho_L, Rho_C = rho(omega_0, P_0, P_star)

    Rho_S_prime, Rho_S_0_prime, Rho_L_prime, Rho_C_prime = rho(
        omega_prime, P_0, P_star)

    alpha_plus = tt.sin(abs_alpha / 2) + tt.cos(abs_alpha / 2)
    alpha_minus = tt.sin(abs_alpha / 2) - tt.cos(abs_alpha / 2)

    # Equation 11:
    Psi_0 = tt.log((1 + alpha_minus) * (alpha_plus - 1) / (1 + alpha_plus) /
                   (1 - alpha_minus))

    Psi_S = 1 - 0.5 * (tt.cos(abs_alpha / 2) -
                       1.0 / tt.cos(abs_alpha / 2)) * Psi_0
    Psi_L = (tt.sin(abs_alpha) +
             (np.pi - abs_alpha) * tt.cos(abs_alpha)) / np.pi
    Psi_C = (-1 + 5 / 3 * tt.cos(abs_alpha / 2)**2 -
             0.5 * tt.tan(abs_alpha / 2) * tt.sin(abs_alpha / 2)**3 * Psi_0)

    # Table 1:
    condition_a = (-np.pi / 2 <= alpha - np.pi / 2)
    condition_0 = ((alpha - np.pi / 2 <= np.pi / 2) & (np.pi / 2 <= alpha + x1)
                   & (alpha + x1 <= alpha + x2))
    condition_1 = ((alpha - np.pi / 2 <= alpha + x1) &
                   (alpha + x1 <= np.pi / 2) & (np.pi / 2 <= alpha + x2))
    condition_2 = ((alpha - np.pi / 2 <= alpha + x1) &
                   (alpha + x1 <= alpha + x2) & (alpha + x2 <= np.pi / 2))

    condition_b = (alpha + np.pi / 2 <= np.pi / 2)
    condition_3 = ((alpha + x1 <= alpha + x2) & (alpha + x2 <= -np.pi / 2) &
                   (-np.pi / 2 <= alpha + np.pi / 2))
    condition_4 = ((alpha + x1 <= -np.pi / 2) & (-np.pi / 2 <= alpha + x2) &
                   (alpha + x2 <= alpha + np.pi / 2))
    condition_5 = ((-np.pi / 2 <= alpha + x1) & (alpha + x1 <= alpha + x2) &
                   (alpha + x2 <= alpha + np.pi / 2))

    integration_angles = [
        [alpha - np.pi / 2, np.pi / 2], [alpha - np.pi / 2, alpha + x1],
        [alpha - np.pi / 2, alpha + x1, alpha + x2, np.pi / 2],
        [-np.pi / 2, alpha + np.pi / 2], [alpha + x2, alpha + np.pi / 2],
        [-np.pi / 2, alpha + x1, alpha + x2, alpha + np.pi / 2]
    ]

    conditions = [
        condition_a & condition_0,
        condition_a & condition_1,
        condition_a & condition_2,
        condition_b & condition_3,
        condition_b & condition_4,
        condition_b & condition_5,
    ]

    Psi_S_prime = 0
    Psi_L_prime = 0
    Psi_C_prime = 0

    for condition_i, angle_i in zip(conditions, integration_angles):
        for i, phi_i in enumerate(angle_i):
            sign = (-1)**(i + 1)
            I_phi_S, I_phi_L, I_phi_C = I(alpha, phi_i)
            Psi_S_prime += tt.switch(condition_i, sign * I_phi_S, 0)
            Psi_L_prime += tt.switch(condition_i, sign * I_phi_L, 0)
            Psi_C_prime += tt.switch(condition_i, sign * I_phi_C, 0)

    # Compute everything for alpha=0
    angles_alpha0 = [-np.pi / 2, x1, x2, np.pi / 2]
    Psi_S_prime_alpha0 = 0
    Psi_L_prime_alpha0 = 0
    Psi_C_prime_alpha0 = 0
    for i, phi_i in enumerate(angles_alpha0):
        sign = (-1)**(i + 1)
        I_phi_S_alpha0, I_phi_L_alpha0, I_phi_C_alpha0 = I(0, phi_i)

        Psi_S_prime_alpha0 += sign * I_phi_S_alpha0
        Psi_L_prime_alpha0 += sign * I_phi_L_alpha0
        Psi_C_prime_alpha0 += sign * I_phi_C_alpha0

    # P_star_alpha0 = (1 - g ** 2) / (1 + g ** 2 + 2 * g * 1) ** 1.5

    # Rho_S_alpha0, Rho_S_0_alpha0, Rho_L_alpha0, Rho_C_alpha0 = rho(omega_0, P_0,
    #                                                                P_star_alpha0)
    #
    # Rho_S_prime_alpha0, Rho_S_0_prime_alpha0, Rho_L_prime_alpha0, Rho_C_prime_alpha0 = rho(
    #     omega_prime, P_0, P_star_alpha0
    # )

    # # Equation 11:
    # Psi_S_alpha0 = 1
    # Psi_L_alpha0 = 1
    # Psi_C_alpha0 = (-1 + 5 / 3)

    # # Equation 37
    # F_S_alpha0 = np.pi / 16 * (omega_0 * Rho_S_alpha0 * Psi_S_alpha0 +
    #                            omega_prime * Rho_S_prime_alpha0 *
    #                            Psi_S_prime_alpha0)
    # F_L_alpha0 = np.pi / 12 * (omega_0 * Rho_L_alpha0 * Psi_L_alpha0 +
    #                            omega_prime * Rho_L_prime_alpha0 *
    #                            Psi_L_prime_alpha0)
    # F_C_alpha0 = 3 * np.pi / 64 * (omega_0 * Rho_C_alpha0 * Psi_C_alpha0 +
    #                                omega_prime * Rho_C_prime_alpha0 *
    #                                Psi_C_prime_alpha0)

    # Equation 37
    F_S = np.pi / 16 * (omega_0 * Rho_S * Psi_S +
                        omega_prime * Rho_S_prime * Psi_S_prime)
    F_L = np.pi / 12 * (omega_0 * Rho_L * Psi_L +
                        omega_prime * Rho_L_prime * Psi_L_prime)
    F_C = 3 * np.pi / 64 * (omega_0 * Rho_C * Psi_C +
                            omega_prime * Rho_C_prime * Psi_C_prime)

    sobolev_fluxes = F_S + F_L + F_C
    F_max = tt.max(sobolev_fluxes)

    Psi = sobolev_fluxes / F_max

    flux_ratio_ppm = 1e6 * a_rp**-2 * Psi * A_g

    if return_q:
        alpha_sort_order = np.argsort(alpha)
        sin_abs_sort_alpha = np.sin(abs_alpha[alpha_sort_order]).astype(floatX)
        sort_alpha = alpha[alpha_sort_order].astype(floatX)

        q = _integral_phase_function(Psi, sin_abs_sort_alpha, sort_alpha,
                                     alpha_sort_order)

        # F_0 = F_S_alpha0 + F_L_alpha0 + F_C_alpha0

        return flux_ratio_ppm, g, q
    else:
        return flux_ratio_ppm, g
Пример #21
0
 def do_some_ops(x):
     tdb_trace(tt.tan(x), 'tan(x)')
     return {'cos': tt.cos(x), 'sin': tt.sin(x), 'exp': tt.exp(x), 'log': tt.log(x)}
Пример #22
0
 def S(self, alpha, beta):
     inner = 1 + (beta**2) * (T.tan(self.pi * alpha / 2)**2)
     S = inner**(1 / (2 * alpha))
     return S
    # we want this:
    # arm_pa = pm.TruncatedNormal(
    #     'arm_pa',
    #     mu=gal_pa_mu, sd=gal_pa_sd,
    #     lower=0.1, upper=60,
    #     shape=n_arms,
    # )
    # Specified in a non-centred way:
    arm_pa_mu_offset = pm.Normal('arm_pa_mu_offset', mu=0, sd=1, shape=n_arms)
    arm_pa = pm.Deterministic('arm_pa',
                              gal_pa_mu + gal_pa_sd * arm_pa_mu_offset)
    pm.Potential('arm_pa_mu_bound',
                 (tt.switch(tt.all(arm_pa > 0.1), 0, -np.inf) +
                  tt.switch(tt.all(arm_pa < 70), 0, -np.inf)))

    arm_b = pm.Deterministic('b', tt.tan(np.pi / 180 * arm_pa))
    arm_r = tt.exp(arm_b[arm_idx] * T + arm_c[arm_idx])
    # prevent r from being very large
    pm.Potential('arm_r_bound', tt.switch(tt.all(arm_r < 1E4), 0, -np.inf))
    likelihood = pm.Normal('L', mu=arm_r, sigma=sigma, observed=R)

# it's important we now check the model specification, namely do we have any
# problems with logp being undefined?
with model:
    print(model.check_test_point())

with model:
    trace = pm.sample(500,
                      tune=500,
                      target_accept=0.95,
                      init='advi+adapt_diag')
Пример #24
0
 def S(self, alpha, beta):
     inner = 1+(beta**2)*(T.tan(self.pi*alpha/2)**2)
     S = inner**(1/(2*alpha))
     return S