Esempio n. 1
0
def test_grad_log_likelihood(kernel, seed=42, eps=1.34e-7):
    np.random.seed(seed)
    x = np.sort(np.random.rand(100))
    yerr = np.random.uniform(0.1, 0.5, len(x))
    y = np.sin(x)

    if not terms.HAS_AUTOGRAD:
        gp = GP(kernel)
        gp.compute(x, yerr)
        with pytest.raises(ImportError):
            _, grad = gp.grad_log_likelihood(y)
        return

    for fit_mean in [True, False]:
        gp = GP(kernel, fit_mean=fit_mean)
        gp.compute(x, yerr)
        _, grad = gp.grad_log_likelihood(y)
        grad0 = np.empty_like(grad)

        v = gp.get_parameter_vector()
        for i, pval in enumerate(v):
            v[i] = pval + eps
            gp.set_parameter_vector(v)
            ll = gp.log_likelihood(y)

            v[i] = pval - eps
            gp.set_parameter_vector(v)
            ll -= gp.log_likelihood(y)

            grad0[i] = 0.5 * ll / eps
            v[i] = pval
        assert np.allclose(grad, grad0)
Esempio n. 2
0
def test_log_likelihood(method, seed=42):
    np.random.seed(seed)
    x = np.sort(np.random.rand(10))
    yerr = np.random.uniform(0.1, 0.5, len(x))
    y = np.sin(x)

    kernel = terms.RealTerm(0.1, 0.5)
    gp = GP(kernel, method=method)
    with pytest.raises(RuntimeError):
        gp.log_likelihood(y)

    for term in [(0.6, 0.7, 1.0)]:
        kernel += terms.ComplexTerm(*term)
        gp = GP(kernel, method=method)

        assert gp.computed is False

        with pytest.raises(ValueError):
            gp.compute(np.random.rand(len(x)), yerr)

        gp.compute(x, yerr)
        assert gp.computed is True
        assert gp.dirty is False

        ll = gp.log_likelihood(y)
        K = gp.get_matrix(include_diagonal=True)
        ll0 = -0.5 * np.dot(y, np.linalg.solve(K, y))
        ll0 -= 0.5 * np.linalg.slogdet(K)[1]
        ll0 -= 0.5 * len(x) * np.log(2*np.pi)
        assert np.allclose(ll, ll0)

    # Check that changing the parameters "un-computes" the likelihood.
    gp.set_parameter_vector(gp.get_parameter_vector())
    assert gp.dirty is True
    assert gp.computed is False

    # Check that changing the parameters changes the likelihood.
    gp.compute(x, yerr)
    ll1 = gp.log_likelihood(y)
    params = gp.get_parameter_vector()
    params[0] += 0.1
    gp.set_parameter_vector(params)
    gp.compute(x, yerr)
    ll2 = gp.log_likelihood(y)
    assert not np.allclose(ll1, ll2)

    gp[1] += 0.1
    assert gp.dirty is True
    gp.compute(x, yerr)
    ll3 = gp.log_likelihood(y)
    assert not np.allclose(ll2, ll3)
Esempio n. 3
0
def test_nyquist_singularity(method, seed=4220):
    np.random.seed(seed)

    kernel = terms.ComplexTerm(1.0, np.log(1e-6), np.log(1.0))
    gp = GP(kernel, method=method)

    # Samples are very close to Nyquist with f = 1.0
    ts = np.array([0.0, 0.5, 1.0, 1.5])
    ts[1] = ts[1] + 1e-9 * np.random.randn()
    ts[2] = ts[2] + 1e-8 * np.random.randn()
    ts[3] = ts[3] + 1e-7 * np.random.randn()

    yerr = np.random.uniform(low=0.1, high=0.2, size=len(ts))
    y = np.random.randn(len(ts))

    gp.compute(ts, yerr)
    llgp = gp.log_likelihood(y)

    K = gp.get_matrix(ts)
    K[np.diag_indices_from(K)] += yerr**2.0

    ll = (-0.5 * np.dot(y, np.linalg.solve(K, y)) -
          0.5 * np.linalg.slogdet(K)[1] - 0.5 * len(y) * np.log(2.0 * np.pi))

    assert np.allclose(ll, llgp)
Esempio n. 4
0
def test_predict(seed=42):
    np.random.seed(seed)
    x = np.linspace(1, 59, 300)
    t = np.sort(np.random.uniform(10, 50, 100))
    yerr = np.random.uniform(0.1, 0.5, len(t))
    y = np.sin(t)

    kernel = terms.RealTerm(0.1, 0.5)
    for term in [(0.6, 0.7, 1.0), (0.1, 0.05, 0.5, -0.1)]:
        kernel += terms.ComplexTerm(*term)
    gp = GP(kernel)

    gp.compute(t, yerr)
    K = gp.get_matrix(include_diagonal=True)
    Ks = gp.get_matrix(x, t)
    true_mu = np.dot(Ks, np.linalg.solve(K, y))
    true_cov = gp.get_matrix(x, x) - np.dot(Ks, np.linalg.solve(K, Ks.T))

    mu, cov = gp.predict(y, x)

    _, var = gp.predict(y, x, return_var=True)
    assert np.allclose(mu, true_mu)
    assert np.allclose(cov, true_cov)
    assert np.allclose(var, np.diag(true_cov))

    mu0, cov0 = gp.predict(y, t)
    mu, cov = gp.predict(y)
    assert np.allclose(mu0, mu)
    assert np.allclose(cov0, cov)
Esempio n. 5
0
    def __init__(self, x, y, n_bg_coef, wave_err=0.05, # MAGIC NUMBER: wavelength error hack
                 log_sigma0=0., log_rho0=np.log(10.), # initial params for GP
                 x_shift=None):

        self.x = np.array(x)
        self.y = np.array(y)

        if n_bg_coef >= 2:
            a_kw = dict([('a{}'.format(i),0.) for i in range(2,n_bg_coef)])

            # estimate background
            a_kw['a1'] = (y[-1]-y[0])/(x[-1]-x[0]) # slope
            a_kw['a0'] = y[-1] - a_kw['a1']*x[-1] # estimate constant term

        else:
            a_kw = dict(a0=np.mean([y[0], y[-1]]))

        # initialize model
        self.mean_model = MeanModel(n_bg_coef=n_bg_coef, **a_kw)
        self.kernel = terms.Matern32Term(log_sigma=log_sigma0, log_rho=log_rho0)

        # set up the gp
        self.gp = GP(self.kernel, mean=self.mean_model, fit_mean=True)
        self.gp.compute(x, yerr=wave_err)
        logger.debug("Initial log-likelihood: {0}"
                     .format(self.gp.log_likelihood(y)))

        if x_shift is None:
            self.x_shift = 0.
        else:
            self.x_shift = x_shift
Esempio n. 6
0
    def __init__(self, lpf, name: str = 'gp', noise_ids=None, fixed_hps=None):
        if not with_celerite:
            raise ImportError("CeleriteLogLikelihood requires celerite.")

        self.name = name
        self.lpf = lpf

        if fixed_hps is None:
            self.free = True
        else:
            self.hps = asarray(fixed_hps)
            self.free = False

        if lpf.lcids is None:
            raise ValueError('The LPF data needs to be initialised before initialising CeleriteLogLikelihood.')
        self.noise_ids = noise_ids if noise_ids is not None else unique(lpf.noise_ids)

        self.mask = m = zeros(lpf.lcids.size, bool)
        for lcid,nid in enumerate(lpf.noise_ids):
            if nid in self.noise_ids:
                m[lcid == lpf.lcids] = 1

        if m.sum() == lpf.lcids.size:
            self.times = lpf.timea
            self.fluxes = lpf.ofluxa
        else:
            self.times = lpf.timea[m]
            self.fluxes = lpf.ofluxa[m]

        self.gp = GP(Matern32Term(0, 0))

        if self.free:
            self.init_parameters()
        else:
            self.compute_gp(None, force=True, hps=self.hps)
Esempio n. 7
0
def Fit0_Jitter(x, y, yerr = None, verbose = True, doPlot = False, \
                    xpred = None):
    k = terms.Matern32Term(log_sigma=0.0, log_rho=0.0)
    if yerr is None:
        wn = np.median(abs(np.diff(y)))
    else:
        wn = np.median(yerr)
    k += terms.JitterTerm(log_sigma=np.log(wn))
    gp = GP(k, mean=1.0)
    gp.compute(x)
    HP_init = gp.get_parameter_vector()
    soln = minimize(NLL0, gp.get_parameter_vector(), jac=True, args=(gp, y))
    gp.set_parameter_vector(soln.x)
    if verbose:
        print 'Initial pars:', HP_init
        print 'Fitted pars:', soln.x
    if xpred is None:
        return soln.x
    mu, var = gp.predict(y, xpred, return_var=True)
    std = np.sqrt(var)
    if doPlot:
        plt.errorbar(x, y, yerr=yerr, fmt=".k", capsize=0)
        plt.plot(xpred, mu, 'C0')
        plt.fill_between(xpred,
                         mu + std,
                         mu - std,
                         color='C0',
                         alpha=0.4,
                         lw=0)
    return soln.x, mu, std
Esempio n. 8
0
def Fit0(x, y, yerr, verbose = True, doPlot = False, \
             xpred = None, HP_init = None):
    if HP_init is None:
        HP_init = np.zeros(2)
    k = terms.Matern32Term(log_sigma=HP_init[0], log_rho=HP_init[1])
    gp = GP(k, mean=1.0)
    gp.compute(x, yerr=yerr)
    soln = minimize(NLL0, HP_init, jac=True, args=(gp, y))
    gp.set_parameter_vector(soln.x)
    if verbose:
        print 'Initial pars:', HP_init
        print 'Fitted pars:', soln.x
    if xpred is None:
        return soln.x
    mu, var = gp.predict(y, xpred, return_var=True)
    std = np.sqrt(var)
    if doPlot:
        plt.errorbar(x, y, yerr=yerr, fmt=".k", capsize=0)
        plt.plot(xpred, mu, 'C0')
        plt.fill_between(xpred,
                         mu + std,
                         mu - std,
                         color='C0',
                         alpha=0.4,
                         lw=0)
    return soln.x, mu, std
Esempio n. 9
0
def Pred1_2D(par, x2d, y2d, y2derr, doPlot=True, x2dpred=None):
    K = x2d.shape[0]
    k = terms.Matern32Term(log_sigma=par[-2], log_rho=par[-1])
    gp = GP(k, mean=1.0)
    shifts = np.append(0, par[:K - 1])
    x1d = (x2d + shifts[:, None]).flatten()
    inds = np.argsort(x1d)
    y1d = y2d.flatten()
    y1derr = y2derr.flatten()
    gp.compute(x1d[inds], yerr=y1derr[inds])
    if x2dpred is None:
        x2dpred = np.copy(x2d)
    x2dpreds = (x2dpred + shifts[:, None])
    y2dpred = np.zeros_like(x2dpred)
    y2dprederr = np.zeros_like(x2dpred)
    for k in range(K):
        print 'Prediction for spectrum %d' % (k + 1)
        x1dpred = x2dpreds[k, :].flatten()
        indspred = np.argsort(x1dpred)
        mu, var = gp.predict(y1d[inds], x1dpred[indspred], return_var=True)
        std = np.sqrt(var)
        y2dpred[k, indspred] = mu
        y2dprederr[k, indspred] = std
    if doPlot:
        for i in range(K):
            plt.errorbar(x2d[i, :],
                         y2d[i, :] - i,
                         yerr=y2derr[i, :],
                         fmt=".k",
                         capsize=0,
                         alpha=0.5)
            plt.plot(x2dpred[i, :], y2dpred[i, :] - i, 'C0')
            plt.fill_between(x2dpred[i,:], y2dpred[i,:] + y2dprederr[i,:] - i, \
                                 y2dpred[i,:] - y2dprederr[i,:] - i, color = 'C0', alpha = 0.4, lw = 0)
    return x2dpred, y2dpred, y2dprederr
Esempio n. 10
0
    def __call__(self, rho: Optional[float] = 2., niter: int = 5):
        logger.info("Running Celerite Matern 3/2 detrending")

        time = self.ts.time.copy()
        flux = self.ts.flux.copy()
        mask = ones(time.size, bool)

        for i in range(niter):
            time_learn = time[mask]
            flux_learn = flux[mask]

            wn = mad_std(diff(flux_learn)) / sqrt(2)
            log_sigma = log(mad_std(flux_learn))
            log_rho = log(rho)

            kernel = Matern32Term(log_sigma, log_rho)
            gp = GP(kernel, mean=1.0)
            gp.compute(time_learn, yerr=wn)
            self.prediction = gp.predict(flux_learn, time, return_cov=False)
            mask &= ~sigma_clip(flux - self.prediction, sigma=3).mask

        residuals = flux - self.prediction
        self.mask = m = ~(sigma_clip(residuals, sigma_lower=inf,
                                     sigma_upper=4).mask)
        self.ts._data.update('celerite_m32', time[m],
                             (flux - self.prediction + 1)[m], self.ts.ferr[m])
    def __init__(self, lpf, name: str = 'gp', lcids=None, fixed_hps=None):
        if not with_celerite:
            raise ImportError("MultiCeleriteLogLikelihood requires celerite.")

        self.name = name
        self.lpf = lpf

        if fixed_hps is None:
            self.free = True
        else:
            self.hps = asarray(fixed_hps)
            self.free = False

        if lpf.lcids is None:
            raise ValueError(
                'The LPF data needs to be initialised before initialising CeleriteLogLikelihood.'
            )
        self.lcids = lcids if lcids is not None else unique(lpf.lcids)
        self.lcslices = [lpf.lcslices[i] for i in self.lcids]
        self.nlc = len(self.lcslices)

        self.times, self.fluxes, self.wns = [], [], []
        for i in self.lcids:
            self.times.append(lpf.times[i])
            self.fluxes.append(lpf.fluxes[i])
            self.wns.append(diff(lpf.fluxes[i]).std() / sqrt(2))

        self.gps = [GP(Matern32Term(0, 0)) for i in range(self.nlc)]

        if self.free:
            self.init_parameters()
        else:
            self.compute_gp(None, force=True, hps=self.hps)
Esempio n. 12
0
    def init_gp(self,
                log_sigma=None,
                log_rho=None,
                amp=None,
                x0=None,
                bg=None,
                bg_buffer=None,
                **kwargs):
        """
        **kwargs:
        """

        # Call the different get_init methods with the correct kwargs passed
        sig = inspect.signature(self.get_init)
        kw = OrderedDict()
        for k in list(sig.parameters.keys()):
            kw[k] = kwargs.pop(k, None)
        p0 = self.get_init(**kw)

        # Call the generic init method - all line models must have these params
        p0_generic = self.get_init_generic(amp=amp,
                                           x0=x0,
                                           bg=bg,
                                           bg_buffer=bg_buffer)
        for k, v in p0_generic.items():
            p0[k] = v

        # expand bg parameters
        bgs = p0.pop('bg_coef')
        for i in range(self.n_bg_coef):
            p0['bg{}'.format(i)] = bgs[i]

        # transform
        p0 = self.transform_pars(p0)

        # initialize model
        mean_model = self.MeanModel(n_bg_coef=self.n_bg_coef,
                                    absorp_emiss=self.absorp_emiss,
                                    **p0)

        p0_gp = self.get_init_gp(log_sigma=log_sigma, log_rho=log_rho)
        kernel = terms.Matern32Term(log_sigma=p0_gp['log_sigma'],
                                    log_rho=p0_gp['log_rho'])

        # set up the gp model
        self.gp = GP(kernel, mean=mean_model, fit_mean=True)

        if self._err is not None:
            self.gp.compute(self.x, self._err)
        else:
            self.gp.compute(self.x)

        init_params = self.gp.get_parameter_vector()
        init_ll = self.gp.log_likelihood(self.flux)
        logger.log(0, "Initial log-likelihood: {0}".format(init_ll))

        return init_params
Esempio n. 13
0
def gpSimFull(carmaTerm, SNR, duration, N, nLC=1):
    """Simulate full CARMA time series.

    Args:
        carmaTerm (object): celerite GP term.
        SNR (float): Signal to noise ratio defined as ratio between
            CARMA amplitude and the mode of the errors (simulated using
            log normal).
        duration (float): The duration of the simulated time series in days.
        N (int): The number of data points.
        nLC (int, optional): Number of light curves to simulate. Defaults to 1.

    Raises:
        RuntimeError: If the input CARMA term/model is not stable, thus cannot be
            solved by celerite.

    Returns:
        Arrays: t, y and yerr of the simulated light curves in numpy arrays.
            Note that errors have been added to y.
    """

    assert isinstance(
        carmaTerm,
        celerite.celerite.terms.Term), "carmaTerm must a celerite GP term"

    if (not isinstance(carmaTerm,
                       DRW_term)) and (carmaTerm._arroots.real > 0).any():
        raise RuntimeError(
            "The covariance matrix of the provided CARMA term is not positive definite!"
        )

    t = np.linspace(0, duration, N)
    noise = carmaTerm.get_rms_amp() / SNR
    yerr = np.random.lognormal(0, 0.25, N) * noise
    yerr = yerr[np.argsort(np.abs(yerr))]

    # init GP and solve matrix
    gp_sim = GP(carmaTerm)
    gp_sim.compute(t)

    # simulate, assign yerr based on y
    t = np.repeat(t[None, :], nLC, axis=0)
    y = gp_sim.sample(size=nLC)

    # format yerr making it heteroscedastic
    y_rank = y.argsort(axis=1).argsort(axis=1)
    yerr = np.repeat(yerr[None, :], nLC, axis=0)
    yerr = np.array(list(map(lambda x, y: x[y], yerr, y_rank)))
    yerr_sign = np.random.binomial(1, 0.5, yerr.shape)
    yerr_sign[yerr_sign < 1] = -1
    yerr = yerr * yerr_sign

    if nLC == 1:
        return t[0], y[0] + yerr[0], yerr[0]
    else:
        return t, y + yerr, yerr
Esempio n. 14
0
def Fit1(x2d, y2d, y2derr, par_in=None, verbose=True):
    K = x2d.shape[0]
    if par_in is None:
        par_in = np.zeros(K + 1)
    k = terms.Matern32Term(log_sigma=par_in[-2], log_rho=par_in[-1])
    gp = GP(k, mean=1.0)
    soln = minimize(NLL1, par_in, args=(gp, x2d, y2d, y2derr))
    if verbose:
        print 'Initial pars:', par_in
        print 'Fitted pars:', soln.x
    return soln.x
Esempio n. 15
0
def test_grad_log_likelihood(kernel, with_general, seed=42, eps=1.34e-7):
    np.random.seed(seed)
    x = np.sort(np.random.rand(100))
    yerr = np.random.uniform(0.1, 0.5, len(x))
    y = np.sin(x)

    if with_general:
        U = np.vander(x - np.mean(x), 4).T
        V = U * np.random.rand(4)[:, None]
        A = np.sum(U * V, axis=0) + 1e-8
    else:
        A = np.empty(0)
        U = np.empty((0, 0))
        V = np.empty((0, 0))

    if not terms.HAS_AUTOGRAD:
        gp = GP(kernel)
        gp.compute(x, yerr, A=A, U=U, V=V)
        with pytest.raises(ImportError):
            _, grad = gp.grad_log_likelihood(y)
        return

    for fit_mean in [True, False]:
        gp = GP(kernel, fit_mean=fit_mean)
        gp.compute(x, yerr, A=A, U=U, V=V)
        _, grad = gp.grad_log_likelihood(y)
        grad0 = np.empty_like(grad)

        v = gp.get_parameter_vector()
        for i, pval in enumerate(v):
            v[i] = pval + eps
            gp.set_parameter_vector(v)
            ll = gp.log_likelihood(y)

            v[i] = pval - eps
            gp.set_parameter_vector(v)
            ll -= gp.log_likelihood(y)

            grad0[i] = 0.5 * ll / eps
            v[i] = pval
        assert np.allclose(grad, grad0)
Esempio n. 16
0
def drw_fit(t, y, yerr, debug=False, user_bounds=None, n_iter=10):
    """
    Fit time series to DRW.

    Args:
        t (array(float)): Time stamps of the input time series (the default unit is day).
        y (array(float)): y values of the input time series.
        yerr (array(float)): Measurement errors for y values.
        debug (bool, optional): Turn on/off debug mode. Defaults to False.
        user_bounds (list, optional): Parameter boundaries for the optimizer.
            Defaults to None.
        n_iter (int, optional): Number of iterations to run the optimizer. Defaults to 10.

    Raises:
        celerite.solver.LinAlgError: For non-positive definite autocovariance matrices.

    Returns:
        array(float): Best-fit parameters
    """

    best_fit = np.empty(2)
    std = np.std(y)

    # init bounds for fitting
    if user_bounds is not None and (len(user_bounds) == 2):
        bounds = user_bounds
    else:
        bounds = [(-4, np.log(4 * std)), (-4, 10)]

    # re-position lc
    t = t - t[0]
    y = y - np.median(y)

    # initialize parameter and kernel
    kernel = DRW_term(*drw_log_param_init(std, max_tau=np.log(t[-1] / 8)))
    gp = GP(kernel, mean=0)
    gp.compute(t, yerr)

    best_fit_return = _min_opt(
        y,
        best_fit,
        gp,
        lambda: drw_log_param_init(std, size=n_iter, max_tau=np.log(t[-1] / 8)
                                   ),
        "param",
        debug,
        bounds,
        n_iter,
    )

    return best_fit_return
Esempio n. 17
0
def test_pickle(with_general, seed=42):
    solver = celerite.CholeskySolver()
    np.random.seed(seed)
    t = np.sort(np.random.rand(500))
    diag = np.random.uniform(0.1, 0.5, len(t))
    y = np.sin(t)

    if with_general:
        U = np.vander(t - np.mean(t), 4).T
        V = U * np.random.rand(4)[:, None]
        A = np.sum(U * V, axis=0) + 1e-8
    else:
        A = np.empty(0)
        U = np.empty((0, 0))
        V = np.empty((0, 0))

    alpha_real = np.array([1.3, 1.5])
    beta_real = np.array([0.5, 0.2])
    alpha_complex_real = np.array([1.0])
    alpha_complex_imag = np.array([0.1])
    beta_complex_real = np.array([1.0])
    beta_complex_imag = np.array([1.0])

    def compare(solver1, solver2):
        assert solver1.computed() == solver2.computed()
        if not solver1.computed():
            return
        assert np.allclose(solver1.log_determinant(),
                           solver2.log_determinant())
        assert np.allclose(solver1.dot_solve(y), solver2.dot_solve(y))

    s = pickle.dumps(solver, -1)
    solver2 = pickle.loads(s)
    compare(solver, solver2)

    solver.compute(0.0, alpha_real, beta_real, alpha_complex_real,
                   alpha_complex_imag, beta_complex_real, beta_complex_imag, A,
                   U, V, t, diag)
    solver2 = pickle.loads(pickle.dumps(solver, -1))
    compare(solver, solver2)

    # Test that models can be pickled too.
    kernel = terms.RealTerm(0.5, 0.1)
    kernel += terms.ComplexTerm(0.6, 0.7, 1.0)
    gp1 = GP(kernel)
    gp1.compute(t, diag)
    s = pickle.dumps(gp1, -1)
    gp2 = pickle.loads(s)
    assert np.allclose(gp1.log_likelihood(y), gp2.log_likelihood(y))
    def learn_gps(self):
        for lcid in tqdm(self.lcids, desc='Learning GPs', leave=False):
            kernel = Matern32Term(log(self.lpf.fluxes[lcid].std()), log(0.1))
            gp = GP(kernel, mean=0.0)
            gp.freeze_parameter('kernel:log_sigma')

            def nll(x):
                gp.set_parameter_vector(x)
                gp.compute(self.lpf.times[lcid], self.lpf.wn[lcid])
                return -gp.log_likelihood(self.lpf.fluxes[lcid] - 1.0)

            res = minimize(nll, [log(1.)])
            gp.set_parameter_vector(res.x)
            gp.compute(self.lpf.times[lcid], self.lpf.wn[lcid])
            self.gps.append(gp)
Esempio n. 19
0
def test_predict(method, seed=42):
    np.random.seed(seed)
    x = np.sort(np.random.rand(10))
    yerr = np.random.uniform(0.1, 0.5, len(x))
    y = np.sin(x)

    kernel = terms.RealTerm(0.1, 0.5)
    for term in [(0.6, 0.7, 1.0)]:
        kernel += terms.ComplexTerm(*term)
    gp = GP(kernel, method=method)
    gp.compute(x, yerr)

    mu0, cov0 = gp.predict(y, x)
    mu, cov = gp.predict(y)
    assert np.allclose(mu0, mu)
    assert np.allclose(cov0, cov)
Esempio n. 20
0
def test_build_gp(method, seed=42):
    kernel = terms.RealTerm(0.5, 0.1)
    kernel += terms.ComplexTerm(0.6, 0.7, 1.0)
    gp = GP(kernel, method=method)

    assert gp.vector_size == 5
    p = gp.get_parameter_vector()
    assert np.allclose(p, [0.5, 0.1, 0.6, 0.7, 1.0])

    gp.set_parameter_vector([0.5, 0.8, 0.6, 0.7, 2.0])
    p = gp.get_parameter_vector()
    assert np.allclose(p, [0.5, 0.8, 0.6, 0.7, 2.0])

    with pytest.raises(ValueError):
        gp.set_parameter_vector([0.5, 0.8, -0.6])

    with pytest.raises(ValueError):
        gp.set_parameter_vector("face1")
Esempio n. 21
0
def test_pickle(method, seed=42):
    solver = get_solver(method)
    np.random.seed(seed)
    t = np.sort(np.random.rand(500))
    diag = np.random.uniform(0.1, 0.5, len(t))
    y = np.sin(t)

    alpha_real = np.array([1.3, 1.5])
    beta_real = np.array([0.5, 0.2])
    alpha_complex_real = np.array([1.0])
    alpha_complex_imag = np.array([0.1])
    beta_complex_real = np.array([1.0])
    beta_complex_imag = np.array([1.0])

    def compare(solver1, solver2):
        assert solver1.computed() == solver2.computed()
        if not solver1.computed():
            return
        assert np.allclose(solver1.log_determinant(),
                           solver2.log_determinant())
        assert np.allclose(solver1.dot_solve(y),
                           solver2.dot_solve(y))

    s = pickle.dumps(solver, -1)
    solver2 = pickle.loads(s)
    compare(solver, solver2)

    if method != "sparse":
        solver.compute(
            alpha_real, beta_real, alpha_complex_real, alpha_complex_imag,
            beta_complex_real, beta_complex_imag, t, diag
        )
        solver2 = pickle.loads(pickle.dumps(solver, -1))
        compare(solver, solver2)

    # Test that models can be pickled too.
    kernel = terms.RealTerm(0.5, 0.1)
    kernel += terms.ComplexTerm(0.6, 0.7, 1.0)
    gp1 = GP(kernel, method=method)
    gp1.compute(t, diag)
    s = pickle.dumps(gp1, -1)
    gp2 = pickle.loads(s)
    assert np.allclose(gp1.log_likelihood(y), gp2.log_likelihood(y))
Esempio n. 22
0
    def __call__(self, period: Optional[float] = None):
        logger.info("Running Celerite")
        assert hasattr(
            self.ts, 'ls'), "Celerite step requires a prior Lomb-Scargle step"
        self.period = period if period is not None else self.ts.ls.period

        gp = GP(SHOTerm(log(self.ts.flux.var()), log(10),
                        log(2 * pi / self.period)),
                mean=1.)
        gp.freeze_parameter('kernel:log_omega0')
        gp.compute(self.ts.time, yerr=self.ts.ferr)

        def minfun(pv):
            gp.set_parameter_vector(pv)
            gp.compute(self.ts.time, yerr=self.ts.ferr)
            return -gp.log_likelihood(self.ts.flux)

        res = minimize(minfun,
                       gp.get_parameter_vector(),
                       jac=False,
                       method='powell')
        self.result = res
        self.parameters = res.x
        self.prediction = gp.predict(self.ts.flux, return_cov=False)
Esempio n. 23
0
plot_setup.setup()

# Set up the dimensions of the problem
N = 2**np.arange(6, 20)
times = np.empty((len(N), 3))
times[:] = np.nan

# Simulate a "dataset"
np.random.seed(42)
t = np.sort(np.random.rand(np.max(N)))
yerr = np.random.uniform(0.1, 0.2, len(t))
y = np.sin(t)

# Set up the GP model
kernel = terms.RealTerm(1.0, 0.1) + terms.ComplexTerm(0.1, 2.0, 1.6)
gp = GP(kernel)

for i, n in enumerate(N):
    times[i, 0] = benchmark("gp.compute(t[:{0}], yerr[:{0}])".format(n),
                            "from __main__ import gp, t, yerr")

    gp.compute(t[:n], yerr[:n])
    times[i, 1] = benchmark("gp.log_likelihood(y[:{0}])".format(n),
                            "from __main__ import gp, y")

    if n <= 4096:
        times[i, 2] = benchmark(
            """
C = gp.get_matrix(t[:{0}])
C[np.diag_indices_from(C)] += yerr[:{0}]**2
cho_factor(C)
Esempio n. 24
0
def gpSimFull(carmaTerm, SNR, duration, N, nLC=1, log_flux=True):
    """
    Simulate CARMA time series using uniform sampling.

    Args:
        carmaTerm (object): An EzTao CARMA kernel.
        SNR (float): Signal-to-noise defined as ratio between CARMA RMS amplitude and
            the median of the measurement errors (simulated using log normal).
        duration (float): The duration of the simulated time series (default in days).
        N (int): The number of data points in the simulated time series.
        nLC (int, optional): Number of time series to simulate. Defaults to 1.
        log_flux (bool): Whether the flux/y values are in astronomical magnitude.
            This argument affects how errors are assigned. Defaults to True.

    Raises:
        RuntimeError: If the input CARMA term/model is not stable, thus cannot be
            solved by celerite.

    Returns:
        (array(float), array(float), array(float)): Time stamps (default in day), y
        values and measurement errors of the simulated time series.
    """

    assert isinstance(
        carmaTerm,
        celerite.celerite.terms.Term), "carmaTerm must a celerite GP term"

    if (not isinstance(carmaTerm,
                       DRW_term)) and (carmaTerm._arroots.real > 0).any():
        raise RuntimeError(
            "The covariance matrix of the provided CARMA term is not positive definite!"
        )

    t = np.linspace(0, duration, N)
    noise = carmaTerm.get_rms_amp() / SNR
    yerr = np.random.lognormal(0, 0.25, N) * noise
    yerr = yerr[np.argsort(np.abs(yerr))]  # small->large

    # init GP and solve matrix
    gp_sim = GP(carmaTerm)
    gp_sim.compute(t)

    # simulate, assign yerr based on y
    t = np.repeat(t[None, :], nLC, axis=0)
    y = gp_sim.sample(size=nLC)

    # format yerr making it heteroscedastic
    yerr = np.repeat(yerr[None, :], nLC, axis=0)

    # if in mag, large value with large error; in flux, the opposite
    if log_flux:
        # ascending sort
        y_rank = y.argsort(axis=1).argsort(axis=1)
        yerr = np.array(list(map(lambda x, y: x[y], yerr, y_rank)))
    else:
        # descending sort
        y_rank = (-y).argsort(axis=1).argsort(axis=1)
        yerr = np.array(list(map(lambda x, y: x[y], yerr, y_rank)))

    if nLC == 1:
        return t[0], y[0], yerr[0]
    else:
        return t, y, yerr
Esempio n. 25
0
def mcmc(t,
         y,
         yerr,
         p,
         q,
         n_walkers=32,
         burn_in=500,
         n_samples=2000,
         init_param=None):
    """
    A simple wrapper to run quick MCMC using emcee.

    Args:
        t (array(float)): Time stamps of the input time series (the default unit is day).
        y (array(float)): y values of the input time series.
        yerr (array(float)): Measurement errors for y values.
        p (int): The p order of a CARMA(p, q) model.
        q (int): The q order of a CARMA(p, q) model.
        n_walkers (int, optional): Number of MCMC walkers. Defaults to 32.
        burn_in (int, optional): Number of burn in steps. Defaults to 500.
        n_samples (int, optional): Number of MCMC steps to run. Defaults to 2000.
        init_param (array(float), optional): The initial position for the MCMC walker. 
            Defaults to None.

    Returns:
        (object, array(float), array(float)): The emcee sampler object. The MCMC 
        flatchain (n_walkers*n_samplers, dim) and chain (n_walkers, n_samplers, dim) 
        in CARMA space if p > 2, otherwise empty.
    """
    assert p > q, "p order must be greater than q order."

    if init_param is not None and p <= 2:
        assert len(init_param) == int(
            p + q + 1
        ), "The initial parameters doesn't match the dimension of the CARMA model!"
    else:
        print("Searching for best-fit CARMA parameters...")
        init_param = carma_fit(t, y, yerr, p, q, n_iter=200)

    # set on param or fcoeff
    if p > 2:
        ll = lambda *args: -neg_fcoeff_ll(*args)
        init_sample = CARMA_term.carma2fcoeffs(np.log(init_param[:p]),
                                               np.log(init_param[p:]))
    else:
        ll = lambda *args: -neg_param_ll(*args)
        init_sample = init_param

    # create vectorized functions
    vec_fcoeff2carma = np.vectorize(
        CARMA_term.fcoeffs2carma,
        excluded=[
            1,
        ],
        signature="(n)->(m),(k)",
    )

    # reposition ts
    t = t - t[0]
    y = y - np.median(y)

    # init celerite kernel/GP
    kernel = CARMA_term(np.log(init_param[:p]), np.log(init_param[p:]))
    gp = GP(kernel, mean=0)
    gp.compute(t, yerr)

    # init sampler
    ndim = len(init_sample)
    sampler = emcee.EnsembleSampler(n_walkers, ndim, ll, args=[y, gp])

    print("Running burn-in...")
    p0 = np.log(init_sample) + 1e-8 * np.random.randn(n_walkers, ndim)
    p0, lp, _ = sampler.run_mcmc(p0, burn_in)

    print("Running production...")
    sampler.reset()
    sampler.run_mcmc(p0, n_samples)

    carma_flatchain = np.array([])
    carma_chain = np.array([])

    if p > 2:
        ar, ma = vec_fcoeff2carma(sampler.flatchain, p)
        carma = np.log(np.hstack((ar, ma)))
        carma_flatchain = carma
        carma_chain = carma.reshape((n_walkers, n_samples, ndim), order="F")

    return sampler, carma_flatchain, carma_chain
Esempio n. 26
0
def carma_fit(
    t,
    y,
    yerr,
    p,
    q,
    init_func=None,
    neg_lp_func=None,
    optimizer_func=None,
    n_opt=20,
    user_bounds=None,
    scipy_opt_kwargs={},
    scipy_opt_options={},
    debug=False,
):
    """
    Fit an arbitrary CARMA model

    The default settings are optimized for normalized LCs.

    Args:
        t (array(float)): Time stamps of the input time series (the default unit is day).
        y (array(float)): y values of the input time series.
        yerr (array(float)): Measurement errors for y values.
        p (int): The p order of a CARMA(p, q) model.
        q (int): The q order of a CARMA(p, q) model.
        init_func (object, optional): A user-provided function to generate initial
            guesses for the optimizer. Defaults to None.
        neg_lp_func (object, optional): A user-provided function to compute negative
            probability given an array of parameters, an array of time series values and
            a celerite GP instance. Defaults to None.
        optimizer_func (object, optional): A user-provided optimizer function.
            Defaults to None.
        n_opt (int, optional): Number of optimizers to run.
            Defaults to 20.
        user_bounds (array(float), optional): Parameter boundaries for the default
            optimizer. If p > 2, these are boundaries for the coefficients of the
            factored polynomial. Defaults to None.
        scipy_opt_kwargs (dict, optional): Keyword arguments for scipy.optimize.minimize.
            Defaults to {}.
        scipy_opt_options (dict, optional): "options" argument for scipy.optimize.minimize.
            Defaults to {}.
        debug (bool, optional): Turn on/off debug mode. Defaults to False.

    Raises:
        celerite.solver.LinAlgError: For non-positive definite autocovariance matrices.

    Returns:
        array(float): Best-fit parameters
    """
    # set core config
    dim = int(p + q + 1)
    mode = "fcoeff" if p > 2 else "param"

    # init bounds for fitting
    if user_bounds is not None and (len(user_bounds) == dim):
        bounds = user_bounds
    else:
        bounds = [(-15, 15)] * dim
        bounds[p:-1] = [(a[0] - 5, a[1] - 5) for a in bounds[p:-1]]
        bounds[-1] = (-15, 5)

    # re-position lc
    t = t - t[0]
    y = y - np.median(y)
    y_std = mad(y) * 1.4826
    y = y / y_std
    yerr = yerr / y_std

    # initialize parameter and kernel
    ARpars, MApars = sample_carma(p, q)
    kernel = CARMA_term(np.log(ARpars), np.log(MApars))
    gp = GP(kernel, mean=0)
    gp.compute(t, yerr)

    # determine/set init func
    if init_func is not None:
        init = init_func
    else:
        init = partial(carma_log_fcoeff_init, p, q)

    # determine/set negative log probability function
    if neg_lp_func is None:
        neg_lp = partial(neg_lp_flat, bounds=np.array(bounds), mode=mode)
    else:
        neg_lp = neg_lp_func

    # determine/set optimizer function
    if optimizer_func is None:
        scipy_opt_kwargs.update({"method": "L-BFGS-B", "bounds": bounds})
        opt = partial(
            scipy_opt,
            mode=mode,
            opt_kwargs=scipy_opt_kwargs,
            opt_options=scipy_opt_options,
            debug=debug,
        )
    else:
        opt = optimizer_func

    # get best-fit solution & adjust MA params (multiply by y_std)
    best_fit_return = opt(y, gp, init, neg_lp, n_opt)
    best_fit_return[p:] = best_fit_return[p:] * y_std

    return best_fit_return
Esempio n. 27
0
def dho_fit(
    t,
    y,
    yerr,
    init_func=None,
    neg_lp_func=None,
    optimizer_func=None,
    n_opt=20,
    user_bounds=None,
    scipy_opt_kwargs={},
    scipy_opt_options={},
    debug=False,
):
    """
    Fit DHO to time series

    The default settings are optimized for normalized LCs.

    Args:
        t (array(float)): Time stamps of the input time series (the default unit is day).
        y (array(float)): y values of the input time series.
        yerr (array(float)): Measurement errors for y values.
        init_func (object, optional): A user-provided function to generate initial
            guesses for the optimizer. Defaults to None.
        neg_lp_func (object, optional): A user-provided function to compute negative
            probability given an array of parameters, an array of time series values and
            a celerite GP instance. Defaults to None.
        optimizer_func (object, optional): A user-provided optimizer function.
            Defaults to None.
        n_opt (int, optional): Number of optimizers to run.. Defaults to 20.
        user_bounds (list, optional): Parameter boundaries for the default optimizer and
            the default flat prior. Defaults to None.
        scipy_opt_kwargs (dict, optional): Keyword arguments for scipy.optimize.minimize.
            Defaults to {}.
        scipy_opt_options (dict, optional): "options" argument for scipy.optimize.minimize.
            Defaults to {}.
        debug (bool, optional): Turn on/off debug mode. Defaults to False.

    Raises:
        celerite.solver.LinAlgError: For non-positive definite autocovariance matrices.

    Returns:
        array(float): Best-fit DHO parameters
    """

    # determine user defined boundaries if any
    if user_bounds is not None and (len(user_bounds) == 4):
        bounds = user_bounds
    else:
        bounds = [(-15, 15)] * 4
        bounds[2:] = [(a[0] - 8, a[1] - 8) for a in bounds[2:]]

    # re-position/normalize lc
    t = t - t[0]
    y = y - np.median(y)
    y_std = mad(y) * 1.4826
    y = y / y_std
    yerr = yerr / y_std

    # determine negative log probability function
    if neg_lp_func is None:
        neg_lp = partial(neg_lp_flat, bounds=np.array(bounds), mode="param")
    else:
        neg_lp = neg_lp_func

    # initialize parameter, kernel and GP
    kernel = DHO_term(*dho_log_param_init())
    gp = GP(kernel, mean=0)
    gp.compute(t, yerr)

    # determine initialize function
    if init_func is None:
        init = partial(dho_log_param_init)
    else:
        init = init_func

    # determine the optimizer function
    if optimizer_func is None:
        scipy_opt_kwargs.update({"method": "L-BFGS-B", "bounds": bounds})
        opt = partial(
            scipy_opt,
            mode="param",
            opt_kwargs=scipy_opt_kwargs,
            opt_options=scipy_opt_options,
            debug=debug,
        )
    else:
        opt = optimizer_func

    # get best-fit solution & adjust MA params (multiply by y_std)
    best_fit_return = opt(y, gp, init, neg_lp, n_opt)
    best_fit_return[2:] = best_fit_return[2:] * y_std

    return best_fit_return
Esempio n. 28
0
def drw_fit(
    t,
    y,
    yerr,
    init_func=None,
    neg_lp_func=None,
    optimizer_func=None,
    n_opt=10,
    user_bounds=None,
    scipy_opt_kwargs={},
    scipy_opt_options={},
    debug=False,
):
    """
    Fit DRW.

    Args:
        t (array(float)): Time stamps of the input time series (the default unit is day).
        y (array(float)): y values of the input time series.
        yerr (array(float)): Measurement errors for y values.
        init_func (object, optional): A user-provided function to generate initial
            guesses for the optimizer. Defaults to None.
        neg_lp_func (object, optional): A user-provided function to compute negative
            probability given an array of parameters, an array of time series values and
            a celerite GP instance. Defaults to None.
        optimizer_func (object, optional): A user-provided optimizer function.
            Defaults to None.
        n_opt (int, optional): Number of optimizers to run. Defaults to 10.
        user_bounds (list, optional): Parameter boundaries for the default optimizer.
            Defaults to None.
        scipy_opt_kwargs (dict, optional): Keyword arguments for scipy.optimize.minimize.
            Defaults to {}.
        scipy_opt_options (dict, optional): "options" argument for scipy.optimize.minimize.
            Defaults to {}.
        debug (bool, optional): Turn on/off debug mode. Defaults to False.

    Returns:
        array(float): Best-fit DRW parameters
    """
    # re-position lc; compute some stat
    t = t - t[0]
    y = y - np.median(y)
    std = np.std(y)
    min_dt = np.min(t[1:] - t[:-1])

    # init bounds for fitting
    if user_bounds is not None and (len(user_bounds) == 2):
        bounds = user_bounds
    else:
        bounds = [
            (np.log(std / 50), np.log(3 * std)),
            (np.log(min_dt / 5), np.log(t[-1])),
        ]

    # determine negative log probability function
    if neg_lp_func is None:
        neg_lp = partial(neg_lp_flat, bounds=np.array(bounds), mode="param")
    else:
        neg_lp = neg_lp_func

    # define ranges to generate initial guesses
    amp_range = [std / 50, 3 * std]
    log_tau_range = [np.log(min_dt / 5), np.log(t[-1] / 10)]

    # initialize parameter and kernel
    kernel = DRW_term(*drw_log_param_init(amp_range, log_tau_range))
    gp = GP(kernel, mean=0)
    gp.compute(t, yerr)

    # determine initialize function
    if init_func is None:
        init = partial(drw_log_param_init, amp_range, log_tau_range)
    else:
        init = init_func

    # determine optimizer function
    if optimizer_func is None:
        scipy_opt_kwargs.update({"method": "L-BFGS-B", "bounds": bounds})
        opt = partial(
            scipy_opt,
            mode="param",
            opt_kwargs=scipy_opt_kwargs,
            opt_options=scipy_opt_options,
            debug=debug,
        )
    else:
        opt = optimizer_func

    best_fit_return = opt(y, gp, init, neg_lp, n_opt)

    return best_fit_return
Esempio n. 29
0
def carma_fit(t,
              y,
              yerr,
              p,
              q,
              de=True,
              debug=False,
              mode="coeff",
              user_bounds=None,
              n_iter=10):
    """Fit time series to any CARMA model.

    Args:
        t (object): An array of time stamps in days.
        y (object): An array of y values.
        yerr (object): An array of the errors in y values.
        p (int): P order of a CARMA(p, q) model.
        q (int): Q order of a CARMA(p, q) model.
        de (bool, optional): Whether to use differential_evolution as the
            optimizer. Defaults to True.
        debug (bool, optional): Turn on/off debug mode. Defaults to False.
        mode (str, optional): Specify which space to sample, 'param' or 'coeff'.
            Defaults to 'coeff'.
        user_bounds (list, optional): Factorized polynomial coefficient boundaries
            for the optimizer. Defaults to None.
        n_iter (int, optional): Number of iterations to run the optimizer if de==False.
            Defaults to 10.

    Raises:
        celerite.solver.LinAlgError: For non-positive definite matrices.

    Returns:
        object: An array of best-fit CARMA parameters
    """
    dim = int(p + q + 1)
    best_fit = np.empty(dim)

    # init bounds for fitting
    if user_bounds is not None and (len(user_bounds) == dim):
        bounds = user_bounds
    elif p == 2 and q == 1:
        bounds = [(-10, 13), (-14, 7), (-10, 6), (-12, 3)]
    elif p == 2 and q == 0:
        bounds = [(-10, 16), (-14, 16), (-13, 15)]
    else:
        ARbounds = [(-6, 3)] * p
        MAbounds = [(-6, 1)] * (q + 1)
        bounds = ARbounds + MAbounds

    # re-position lc
    t = t - t[0]
    y = y - np.median(y)

    # initialize parameter and kernel
    ARpars, MApars = sample_carma(p, q)
    kernel = CARMA_term(np.log(ARpars), np.log(MApars))
    gp = GP(kernel, mean=np.median(y))
    gp.compute(t, yerr)

    if p > 2:
        mode = "coeff"

    if mode == "coeff":
        init_func = lambda: carma_log_fcoeff_init(dim)
    else:
        init_func = lambda: carma_log_param_init(dim)

    if de:
        best_fit_return = _de_opt(
            y,
            best_fit,
            gp,
            init_func,
            mode,
            debug,
            bounds,
        )
    else:
        best_fit_return = _min_opt(
            y,
            best_fit,
            gp,
            init_func,
            mode,
            debug,
            bounds,
            n_iter,
        )

    return best_fit_return
Esempio n. 30
0
def dho_fit(t, y, yerr, de=True, debug=False, user_bounds=None, n_iter=10):
    """Fix time series to a DHO model.

    Args:
        t (object): An array of time stamps in days.
        y (object): An array of y values.
        yerr (object): An array of the errors in y values.
        de (bool, optional): Whether to use differential_evolution as the
            optimizer. Defaults to True.
        debug (bool, optional): Turn on/off debug mode. Defaults to False.
        user_bounds (list, optional): Parameter boundaries for the optimizer.
            Defaults to None.
        n_iter (int, optional): Number of iterations to run the optimizer if de==False.
            Defaults to 10.


    Raises:
        celerite.solver.LinAlgError: For non-positive definite matrices.

    Returns:
        object: An array of best-fit parameters
    """
    best_fit = np.zeros(4)

    if user_bounds is not None and (len(user_bounds) == 4):
        bounds = user_bounds
    else:
        bounds = [(-10, 13), (-14, 7), (-10, 6), (-12, 3)]

    # re-position lc
    t = t - t[0]
    y = y - np.median(y)

    # initialize parameter, kernel and GP
    kernel = DHO_term(*dho_log_param_init())
    gp = GP(kernel, mean=np.mean(y))
    gp.compute(t, yerr)

    if de:
        best_fit_return = _de_opt(
            y,
            best_fit,
            gp,
            lambda: dho_log_param_init(),
            "param",
            debug,
            bounds,
        )
    else:
        best_fit_return = _min_opt(
            y,
            best_fit,
            gp,
            lambda: dho_log_param_init(),
            "param",
            debug,
            bounds,
            n_iter,
        )

    return best_fit_return