예제 #1
0
    def PlotCurvesConstrained(self, constrained):
        # plots sums of data curves up to each order we're interested in, subject to some
        # constraint
        if constrained:
            trunc_gp_sym = gm.TruncationGP(kernel = self.kernel, ref=1, ratio = self.ratio, \
                            disp = 0, df = np.inf, scale = 1, optimizer = None)
            # fits GP given constraints
            trunc_gp_sym.fit(self.X[::10], self.yn_constrained[::10], orders = self.orders_array, \
                             dX = np.array([[0], [1]]), dy = np.array([0, 0]))

            fig, axes = plt.subplots( math.ceil(self.n_orders / 2), 2, sharex = True, \
                                     sharey = True, figsize = (5, 8) )
            for i, n in enumerate(self.orders_array):
                # Again, only consider the truncation errors for this plot
                _, std_sym = trunc_gp_sym.predict(self.X, order = n, return_std = True, \
                                    kind = 'trunc')

                for j in range(i, self.n_orders):
                    ax = axes.ravel()[j]
                    ax.plot(self.x,
                            self.yn_constrained[:, i],
                            zorder=i - 5,
                            c=self.colors[i])
                    ax.fill_between(self.x, self.yn_constrained[:, i] + 2 * std_sym, \
                                    self.yn_constrained[:, i] - 2 * std_sym, zorder = i-5, \
                                    facecolor = self.light_colors[i], edgecolor = self.colors[i], \
                                    lw = edgewidth)
                ax = axes.ravel()[i]
                ax.axhline(0, 0, 1, ls='--', lw=0.5, c=softblack, zorder=0)
                ax.set_xticks([])
                ax.set_yticks([])

            fig.tight_layout(h_pad=0.3, w_pad=0.3)
        else:
            return 0
예제 #2
0
    def PlotPointwiseFit(self, mask, expensive=True, constrained=False):
        # plots sums of data curves up to each order we're interested in. If the system is
        # inexpensive, we plot the full sum for each x-value; if the system is expensive, we
        # plot the full sum of the curves when fit a subset of x-values

        # By setting disp=0 and df=inf, no updating of hyperparameters occurs
        # The priors become Dirac delta functions at mu=center and cbar=scale
        # But this assumption could be relaxed, if desired
        trunc_gp = gm.TruncationGP(kernel = self.kernel, ref = self.ref, ratio = self.ratio, \
                                   disp = 0, df = np.inf, scale = 1, optimizer = None)
        # Still only fit on a subset of all data to update mu and cbar!
        # We must beware of numerical issues of using data that are "too close"
        trunc_gp.fit(self.X[mask], self.data[mask], orders=self.orders_array)

        fig, axes = plt.subplots(math.ceil(self.n_orders / 2), 2, sharex = True, sharey = True, \
                                 figsize = (5, 8))

        for i, n in enumerate(self.orders_array):
            if expensive:
                # Only get the uncertainty due to truncation (kind='trunc')
                pred_exp, std_trunc_exp = trunc_gp.predict(self.X, order = n, \
                                                               return_std = True)

                for j in range(i, self.n_orders):
                    ax = axes.ravel()[j]
                    ax.plot(self.x, pred_exp, zorder=i - 5, c=self.colors[i])
                    ax.plot(self.x[mask], self.data[mask, i], ls = '', c = self.colors[i], \
                            marker = 'o', zorder = i-5)
                    ax.fill_between(self.x, pred_exp + 2 * std_trunc_exp, \
                                    pred_exp - 2 * std_trunc_exp, zorder = i-5, \
                                    facecolor = self.light_colors[i], edgecolor = self.colors[i], \
                                    lw = edgewidth)
                ax = axes.ravel()[i]
                ax.set_xticks([])
                ax.set_yticks([])
                ax.set_ylim(-15, 37)
            else:
                # Only get the uncertainty due to truncation (kind='trunc')
                _, std_trunc = trunc_gp.predict(self.X,
                                                order=n,
                                                return_std=True,
                                                kind='trunc')

                for j in range(i, self.n_orders):
                    ax = axes.ravel()[j]
                    ax.plot(self.x,
                            self.data[:, i],
                            zorder=i - 5,
                            c=self.colors[i])
                    ax.fill_between(self.x, self.data[:, i] + 2 * std_trunc, \
                                    self.data[:, i] - 2 * std_trunc, zorder = i-5, \
                                    facecolor = self.light_colors[i], edgecolor = self.colors[i], \
                                    lw = edgewidth)
                ax = axes.ravel()[i]
                ax.set_xticks([])
                ax.set_yticks([])
                ax.set_ylim(-15, 37)

        fig.tight_layout(h_pad=0.3, w_pad=0.3)
예제 #3
0
    def PlotCredibleIntervals(self):
        # plots credible intervals ("weather plot") for each order we're interested in

        try:
            # kernel for fit
            self.kernel_fit = RBF(length_scale = self.ls) + \
                                WhiteKernel(noise_level = self.nugget, noise_level_bounds = 'fixed')

            # truncation GP
            self.gp_trunc = gm.TruncationGP(kernel = self.kernel_fit, ref = self.ref, \
                        ratio = self.ratio, center = self.center, disp = self.disp, \
                        df = self.df, scale = self.scale)
            self.gp_trunc.fit(self.X[self.x_train_mask], y = self.data[self.x_train_mask], \
                        orders = self.orders_array)

            # extracts truncation error for each x-value
            self.norm_trunc_cov = self.gp_trunc.cov(self.X[self.x_valid_mask],
                                                    start=0,
                                                    end=0)
            self.norm_residuals = (self.data_true[self.x_valid_mask, None] - \
                                   self.data[self.x_valid_mask]) / \
                    (self.ratio**(self.orders_array+1) / np.sqrt(1 - self.ratio**2))
            self.gr_dgn_trunc = gm.GraphicalDiagnostic(self.norm_residuals, \
                            mean = np.zeros(self.x[self.x_valid_mask].shape[0]), \
                            cov = self.norm_trunc_cov, colors = self.colors, gray = gray, \
                            black = softblack)

            fig, ax = plt.subplots(figsize=(3.4, 3.2))

            # plots the curves
            for i, n in enumerate(self.orders_array):
                norm_residuals_alt = self.data_true[self.x_valid_mask] - \
                                            self.data[self.x_valid_mask][:,i]
                norm_trunc_cov_alt = self.gp_trunc.cov(
                    self.X[self.x_valid_mask], start=n + 1)
                gr_dgn_trunc_alt = gm.GraphicalDiagnostic(
                    norm_residuals_alt, mean = np.zeros(self.x[self.x_valid_mask].shape[0]), \
                    cov = norm_trunc_cov_alt, colors = [self.colors[i]], gray = gray, black = softblack)
                gr_dgn_trunc_alt.credible_interval(
                    np.linspace(1e-5, 1, 100),
                    band_perc=[0.68, 0.95],
                    ax=ax,
                    title=None,
                    xlabel=r'Credible Interval ($100\alpha\%$)',
                    ylabel=r'Empirical Coverage ($\%$)')
            ax.set_xticks([0, 0.2, 0.4, 0.6, 0.8, 1])
            ax.set_xticklabels([0, 20, 40, 60, 80, 100])
            ax.set_yticks([0, 0.2, 0.4, 0.6, 0.8, 1])
            ax.set_yticklabels([0, 20, 40, 60, 80, 100])
            fig.tight_layout()

        except:
            print(
                "The credible intervals could not be calculated at one or more orders."
            )
예제 #4
0
    def PlotPosteriorPDF(self, posteriorgrid):
        # plots the posterior PDF for the ratio and correlation length of the fit GP

        try:
            # kernel for fit
            self.kernel_fit = RBF(length_scale = self.ls) + \
                                WhiteKernel(noise_level = self.nugget, noise_level_bounds = 'fixed')

            # fits the GP at the mask
            self.gp_trunc = gm.TruncationGP(kernel = self.kernel_fit, ref = self.ref, \
                        ratio = self.ratio, center = self.center, disp = self.disp, \
                        df = self.df, scale = self.scale)
            self.gp_trunc.fit(self.X[self.x_train_mask], y = self.data[self.x_train_mask], \
                        orders = self.orders_array)

            # reads the posterior grid points to the class
            self.posteriorgrid = posteriorgrid
            self.ls_vals = self.posteriorgrid.x_vals
            self.ratio_vals = self.posteriorgrid.y_vals

            # Compute the log likelihood for values on this grid.
            self.ls_ratio_loglike = np.array([[
                self.gp_trunc.log_marginal_likelihood(theta = [ls_,], ratio = ratio_val) \
                for ls_ in np.log(self.ls_vals)]
                for ratio_val in self.ratio_vals])

            # Makes sure that the values don't get too big or too small
            self.ls_ratio_like = np.exp(self.ls_ratio_loglike -
                                        np.max(self.ls_ratio_loglike))

            # Now compute the marginal distributions
            self.ratio_like = np.trapz(self.ls_ratio_like,
                                       x=self.ls_vals,
                                       axis=-1)
            self.ls_like = np.trapz(self.ls_ratio_like,
                                    x=self.ratio_vals,
                                    axis=0)

            # Normalize them
            self.ratio_like /= np.trapz(self.ratio_like,
                                        x=self.ratio_vals,
                                        axis=0)
            self.ls_like /= np.trapz(self.ls_like, x=self.ls_vals, axis=0)

            with plt.rc_context({
                    "text.usetex": True,
                    "text.latex.preview": True
            }):
                #             with plt.rc_context({"text.usetex": True}):
                cmap_name = 'Blues'
                cmap = mpl.cm.get_cmap(cmap_name)

                # Setup axes
                fig, ax_joint, ax_marg_x, ax_marg_y = joint_plot(ratio=5,
                                                                 height=3.4)

                # Plot contour
                ax_joint.contour(self.ls_vals,
                                 self.ratio_vals,
                                 self.ls_ratio_like,
                                 levels=[
                                     np.exp(-0.5 * r**2)
                                     for r in np.arange(9, 0, -0.5)
                                 ] + [0.999],
                                 cmap=cmap_name,
                                 vmin=-0.05,
                                 vmax=0.8,
                                 zorder=1)

                # Now plot the marginal distributions
                ax_marg_y.plot(self.ratio_like,
                               self.ratio_vals,
                               c=cmap(0.8),
                               lw=1)
                ax_marg_y.fill_betweenx(self.ratio_vals,
                                        np.zeros_like(self.ratio_like),
                                        self.ratio_like,
                                        facecolor=cmap(0.2),
                                        lw=1)
                ax_marg_x.plot(self.ls_vals, self.ls_like, c=cmap(0.8), lw=1)
                ax_marg_x.fill_between(self.ls_vals,
                                       np.zeros_like(self.ls_vals),
                                       self.ls_like,
                                       facecolor=cmap(0.2),
                                       lw=1)

                # Formatting
                ax_joint.set_xlabel(r'$\ell$')
                ax_joint.set_ylabel(r'$Q$')
                ax_joint.axvline(self.ls, 0, 1, c=gray, lw=1, zorder=0)
                ax_joint.axhline(self.ratio, 0, 1, c=gray, lw=1, zorder=0)
                ax_joint.margins(x=0, y=0.)
                ax_joint.set_xlim(0.05, 0.35)
                ax_joint.set_xticks([0.1, 0.2, 0.3])
                ax_joint.set_xticks([0.15, 0.25], minor=True)
                ax_joint.set_yticks([0.4, 0.5, 0.6])
                ax_joint.set_yticks([0.35, 0.45, 0.55, 0.65], minor=True)
                ax_marg_x.set_ylim(bottom=0)
                ax_marg_y.set_xlim(left=0)
                ax_joint.text(0.95, 0.95, r'pr$(\ell, Q \,|\, \vec{\mathbf{y}}_k)$', ha='right', \
                              va='top', transform = ax_joint.transAxes, bbox = text_bbox)
                plt.show()
        except:
            print(
                "The posterior probability distribution could not be calculated."
            )
예제 #5
0
    def PlotTruncations(self):
        # plots the data summed to each order we're interested in

        try:
            # kernel for fit
            self.kernel_fit = RBF(length_scale = self.ls) + \
                                WhiteKernel(noise_level = self.nugget, noise_level_bounds = 'fixed')

            # fits truncation GP to data given a mask
            self.gp_trunc = gm.TruncationGP(kernel = self.kernel_fit, ref = self.ref, \
                        ratio = self.ratio, center = self.center, disp = self.disp, \
                        df = self.df, scale = self.scale)
            self.gp_trunc.fit(self.X[self.x_train_mask], y = self.data[self.x_train_mask], \
                        orders = self.orders_array)

            # extracts truncation error for each x-value
            self.norm_trunc_cov = self.gp_trunc.cov(self.X[self.x_valid_mask],
                                                    start=0,
                                                    end=0)
            self.norm_residuals = (self.data_true[self.x_valid_mask, None] - \
                                   self.data[self.x_valid_mask]) / \
                    (self.ratio**(self.orders_array+1) / np.sqrt(1 - self.ratio**2))
            self.gr_dgn_trunc = gm.GraphicalDiagnostic(self.norm_residuals, \
                            mean = np.zeros(self.x[self.x_valid_mask].shape[0]), \
                            cov = self.norm_trunc_cov, colors = self.colors, gray = gray, \
                            black = softblack)

            fig, axes = plt.subplots(math.ceil(self.n_orders / 2), 2, sharex = True, sharey = True, \
                figsize = (3.9, 3.2))

            # plots curves with error
            for i, n in enumerate(self.orders_array):
                _, std_trunc = self.gp_trunc.predict(self.X, order = n, return_std = True, \
                                    kind = 'trunc')

                for j in range(i, self.n_orders):
                    ax = axes.ravel()[j]
                    ax.plot(self.x,
                            self.data[:, i],
                            zorder=i - 5,
                            c=self.colors[i])
                    ax.fill_between(self.x, self.data[:, i] + 2 * std_trunc, \
                                    self.data[:, i] - 2 * std_trunc, zorder = i-5, \
                                    facecolor = self.light_colors[i], edgecolor = self.colors[i], \
                                    lw = edgewidth)
                ax = axes.ravel()[i]
                ax.plot(self.x, self.data_true, color=softblack, lw=1, ls='--')
                ax.set_xticks([0.25, 0.5, 0.75])
                ax.set_xticks(self.x[self.x_valid_mask], minor=True)
                ax.set_xticklabels([0.25, 0.5, 0.75])
                ax.set_yticks([0, 10, 20])
                ax.set_yticks([-10, 0, 10, 20, 30])
                ax.set_ylim(-15, 37)

            axes[1, 0].set_xlabel(r'$x$')
            axes[1, 1].set_xlabel(r'$x$')
            fig.tight_layout(h_pad=0.3, w_pad=0.3)

        except:
            print(
                "The truncation error curves could not be calculated at one or more orders."
            )