Exemple #1
0
def test_HistoryMatching_select_expectations():
    "test the select_expectations method of HistoryMatching"

    # correct functionality

    expectations = (np.array([2., 10.]), np.array([0.,
                                                   0.]), np.array([[1., 2.]]))
    hm = HistoryMatching(obs=[1., 1.], expectations=expectations)

    expectations_new = hm._select_expectations()

    for a, b in zip(expectations, expectations_new):
        assert_allclose(a, b)

    gp = GaussianProcess(np.reshape(np.linspace(0., 1.), (-1, 1)),
                         np.linspace(0., 1.))
    np.random.seed(57483)
    gp.learn_hyperparameters()
    coords = np.array([[0.1], [1.]])
    obs = [1., 0.01]
    expectations = gp.predict(coords)

    hm = HistoryMatching(gp=gp, obs=obs, coords=coords)

    expectations_new = hm._select_expectations()

    for a, b in zip(expectations, expectations_new):
        assert_allclose(a, b)

    # ncoords somehow not set

    hm.ncoords = None
    with pytest.raises(ValueError):
        hm._select_expectations()

    # both coords and expectations set

    hm = HistoryMatching(gp=gp,
                         obs=obs,
                         coords=coords,
                         expectations=expectations)

    with pytest.raises(ValueError):
        hm._select_expectations()

    # if no expectations provided, fails

    hm = HistoryMatching(obs=obs)

    with pytest.raises(ValueError):
        hm._select_expectations()
Exemple #2
0
def test_HistoryMatching_get_implausibility():
    "test the get_implausibility method of HistoryMatching"

    # correct functionality

    expectations = (np.array([2., 10.]), np.array([0.,
                                                   0.]), np.array([[1., 2.]]))
    hm = HistoryMatching(obs=[1., 1.], expectations=expectations)
    I = hm.get_implausibility()

    assert_allclose(I, [1., 9.])
    assert_allclose(hm.I, [1., 9.])

    I = hm.get_implausibility(1.)

    assert_allclose(I, [1. / np.sqrt(2.), 9. / np.sqrt(2.)])
    assert_allclose(hm.I, [1. / np.sqrt(2.), 9. / np.sqrt(2.)])

    gp = GaussianProcess(np.reshape(np.linspace(0., 1.), (-1, 1)),
                         np.linspace(0., 1.))
    np.random.seed(57483)
    gp.learn_hyperparameters()
    coords = np.array([[0.1], [1.]])
    obs = [1., 0.01]
    mean, unc, _ = gp.predict(coords)
    I_exp = np.abs(mean - obs[0]) / np.sqrt(unc + obs[1])

    hm = HistoryMatching(gp=gp, obs=obs, coords=coords)
    I = hm.get_implausibility()

    assert_allclose(I, I_exp)
    assert_allclose(hm.I, I_exp)

    # no observations

    hm = HistoryMatching(expectations=expectations)

    with pytest.raises(ValueError):
        hm.get_implausibility()

    # negative variance for model discrepancy

    hm = HistoryMatching(obs=[1., 1.], expectations=expectations)

    with pytest.raises(AssertionError):
        hm.get_implausibility(-1.)
def demo_1D():
    # Create a gaussian process
    x_training = np.array([
        [0.],
        [10.],
        [20.],
        [30.],
        [43.],
        [50.]
    ])

    y_training = get_y_simulated_1D(x_training)

    gp = GaussianProcess(x_training, y_training)
    np.random.seed(47)
    gp = fit_GP_MAP(gp)

    # Define observation
    obs = [-0.8, 0.0004]

    # Coords to predict
    n_rand = 2000
    x_predict_min = -3
    x_predict_max = 53
    x_predict = np.random.rand(n_rand)
    x_predict = np.sort(x_predict, axis=0)
    x_predict *= (x_predict_max - x_predict_min)
    x_predict += x_predict_min
    x_predict = x_predict[:,None]

    coords = x_predict

    # Compute GPE expectations
    expectations = gp.predict(coords)

    # Compute Implausbility
    hm = HistoryMatching(obs=obs, expectations=expectations)
    I = hm.get_implausibility()
    NROY = hm.get_NROY()
    RO = hm.get_RO()

    print("Fraction of points ruled out {:6}".format(str(float(len(RO))/float(n_rand))))

    # Plotting

    if makeplots:
        fig, axs = plt.subplots(2, 1, sharex=True)
        fig.subplots_adjust(hspace=0)
        x_hist_plot = [min(x_predict)[0], max(x_predict)[0]]
        y_hist_plot = [obs[0], obs[0]]
        y_hist_err = 3*np.sqrt(obs[1])
        y_hist_up = [val + y_hist_err for val in y_hist_plot]
        y_hist_dn = [val - y_hist_err for val in y_hist_plot]

        axs[0].plot(                # Horizontal line at value of y_obs
            x_hist_plot,
            y_hist_plot,
            color = 'black',
            label = 'observation'
        )

        axs[0].fill_between(        # Error bounds on y_obs
            x_hist_plot,
            y_hist_dn,
            y_hist_up,
            color='black',
            alpha=0.25
        )

        axs[0].plot(                # Simulator output
            coords,
            get_y_simulated_1D(coords),
            color = 'black',
            label = 'simulator'
        )

        axs[0].scatter(             # Training Data
            x_training,
            y_training,
            marker = '.',
            color  = 'black',
            label  = 'Training Data',
            s      = 100
        )

        axs[0].plot(                # GPE expectation
            coords,
            expectations[0],
            color = 'red',
            label = 'GPE'
        )

        axs[0].fill_between(        # GPE uncertainty
            coords[:,0],
            expectations[0] - 3*np.sqrt(expectations[1]),
            expectations[0] + 3*np.sqrt(expectations[1]),
            color = 'red',
            alpha = 0.5
        )

        axs[1].scatter(             # Implausibility
            coords,
            I,
            marker='.',
            color='black'
        )

        axs[1].scatter(
            coords[NROY],
            I[NROY],
            marker='.',
            color='green'
        )

        axs[1].plot(                # implausibility Threshold
            x_hist_plot,
            [3,3],
            color = 'green',
            label = 'implausibility threshold'
        )

        axs[0].set(
            ylabel='Model Output f(x)'
        )
        axs[1].set(
            xlabel='Imput Parameter x',
            ylabel='Implausibility I(x)',
            ylim=(-1, 21)
        )


        plt.savefig('histmatch_1D.png', bbox_inches = 'tight')
def demo_2D():
    # Create a Gaussian Process
    x_training = np.array([
        [0., 0.],
        [1.5, 1.5],
        [3., 3.],
        [0., 1.5],
        [1.5, 0.],
        [0., 3.],
        [3., 0.],
        [3., 1.5],
        [1.5, 3.]
    ])

    y_training = get_y_simulated_2D(x_training)

    gp = GaussianProcess(x_training, y_training)
    np.random.seed(47)
    gp = fit_GP_MAP(gp)

    # Define observation
    obs = [0.1, 0.0004]

    # Coords to predict
    n_rand = 2000
    a_predict_min = 0
    a_predict_max = np.pi
    b_predict_min = a_predict_min
    b_predict_max = a_predict_max
    a_predict = np.random.rand(n_rand) * (a_predict_max - a_predict_min) + a_predict_min
    b_predict = np.random.rand(n_rand) * (b_predict_max - b_predict_min) + b_predict_min
    x_predict = np.concatenate((a_predict[:,None], b_predict[:,None]), axis=1)
    x_predict = np.concatenate((x_predict, x_training), axis=0)

    coords = x_predict

    # Compute GPE expectations
    expectations = gp.predict(coords)

    # Compute Implausbility
    hm = HistoryMatching(obs=obs, expectations=expectations)
    I = hm.get_implausibility()
    NROY = hm.get_NROY()
    RO = hm.get_RO()

    print("Fraction of points ruled out {:6}".format(str(float(len(RO))/float(n_rand))))

    # Plotting
    if makeplots:
        from mpl_toolkits.mplot3d import Axes3D
        fig = plt.figure()
        ax = fig.add_subplot(111, projection='3d')

        Axes3D.scatter(     # Training Data
            ax,
            x_training[:,0],
            x_training[:,1],
            y_training,
            color='black',
            marker = '.',
            s = 100
        )

        #Axes3D.scatter(      # GPE prediction
        #    ax,
        #    coords[:,0],
        #    coords[:,1],
        #    expectations[0],
        #    color='red',
        #    marker='.',
        #    s=2
        #)

        Axes3D.scatter(     # GPE prediction uncertainty
            ax,
            coords[:,0][RO],
            coords[:,1][RO],
            expectations[0][RO] + 3*np.sqrt(expectations[1][RO]),
            color='red',
            marker='.',
            s=1
        )
        Axes3D.scatter(
            ax,
            coords[:,0][RO],
            coords[:,1][RO],
            expectations[0][RO] - 3*np.sqrt(expectations[1][RO]),
            color='red',
            marker='.',
            s=1
        )
        Axes3D.scatter(
            ax,
            coords[:,0][NROY],
            coords[:,1][NROY],
            expectations[0][NROY] + 3*np.sqrt(expectations[1][NROY]),
            color='green',
            marker='.',
            s=1
        )
        Axes3D.scatter(
            ax,
            coords[:,0][NROY],
            coords[:,1][NROY],
            expectations[0][NROY] - 3*np.sqrt(expectations[1][NROY]),
            color='green',
            marker='.',
            s=1
        )

        Axes3D.set(
            ax,
            xlabel = 'Input parameter a',
            ylabel = 'Input parameter b',
            zlabel = 'Model output f(a, b)'
        )



        plt.savefig('histmatch_2D.png', bbox_inches = "tight")
Exemple #5
0
def test_sanity_checks():
    "test basic functioning of HistoryMatching"

    # Create a gaussian process
    x_training = np.array([[0.], [10.], [20.], [30.], [43.], [50.]])

    y_training = get_y_simulated_1D(x_training)

    gp = GaussianProcess(x_training, y_training)
    np.random.seed(47)
    gp.learn_hyperparameters()

    # Define observation and implausibility threshold
    obs = [-0.8, 0.0004]

    # Coords to predict
    n_rand = 2000
    x_predict_min = -3
    x_predict_max = 53
    x_predict = np.random.rand(n_rand)
    x_predict = np.sort(x_predict, axis=0)
    x_predict *= (x_predict_max - x_predict_min)
    x_predict += x_predict_min
    x_predict = x_predict[:, None]

    coords = x_predict

    expectations = gp.predict(coords)

    # Create History Matching Instance
    print("---TEST INPUTS---")
    print("No Args")
    hm = HistoryMatching()
    hm.status()

    print("Obs Only a - list")
    hm = HistoryMatching(obs=obs)
    hm.status()

    print("Obs only b - single-element list")
    hm = HistoryMatching(obs=[3.])
    hm.status()

    print("Obs only c - single-value")
    hm = HistoryMatching(obs=3.)
    hm.status()

    print("gp Only")
    hm = HistoryMatching(gp=gp)
    hm.status()

    print("Coords only a - 2d ndarray")
    hm = HistoryMatching(coords=coords)
    hm.status()

    print("Coords only b - 1d ndarray")
    hm = HistoryMatching(coords=np.random.rand(n_rand))
    hm.status()

    print("Coords only c - list")
    hm = HistoryMatching(coords=[a for a in range(n_rand)])
    hm.status()

    print("Expectation only")
    hm = HistoryMatching(expectations=expectations)
    hm.status()

    print("Threshold Only")
    hm = HistoryMatching(threshold=3.)
    hm.status()

    print("---TEST ASSIGNMENT---")
    print("Assign gp")
    hm = HistoryMatching(obs)
    hm.status()
    hm.set_gp(gp)
    hm.status()

    print("Assign Obs")
    hm = HistoryMatching(gp)
    hm.status()
    hm.set_obs(obs)
    hm.status()

    print("Assign Coords")
    hm = HistoryMatching()
    hm.status()
    hm.set_coords(coords)
    hm.status()

    print("Assign Expectations")
    hm = HistoryMatching()
    hm.status()
    hm.set_expectations(expectations)
    hm.status()

    print("Assign Threshold")
    hm = HistoryMatching()
    hm.status()
    hm.set_threshold(3.)
    hm.status()

    print("---TEST IMPLAUSABILIY---")
    print("implausibility test a - no vars")
    hm = HistoryMatching(obs=obs, gp=gp, coords=coords)
    I = hm.get_implausibility()

    print("implausibility test b - single value")
    hm = HistoryMatching(obs=obs, gp=gp, coords=coords)
    I = hm.get_implausibility(7.)
Exemple #6
0
    def predict(self,
                testing,
                unc=True,
                deriv=True,
                include_nugget=True,
                processes=None):
        """
        Make a prediction for a set of input vectors

        Makes predictions for each of the emulators on a given set of input vectors. The
        input vectors must be passed as a ``(n_predict, D)`` or ``(D,)`` shaped array-like
        object, where ``n_predict`` is the number of different prediction points under
        consideration and ``D`` is the number of inputs to the emulator. If the prediction
        inputs array has shape ``(D,)``, then the method assumes ``n_predict == 1``.
        The prediction points are passed to each emulator and the predictions are collected
        into an ``(n_emulators, n_predict)`` shaped numpy array as the first return value
        from the method.

        Optionally, the emulator can also calculate the uncertainties in the predictions
        (as a variance) and the derivatives with respect to each input parameter. If the
        uncertainties are computed, they are returned as the second output from the method
        as an ``(n_emulators, n_predict)`` shaped numpy array. If the derivatives are
        computed, they are returned as the third output from the method as an
        ``(n_emulators, n_predict, D)`` shaped numpy array. Finally, if uncertainties
        are computed, the ``include_nugget`` flag determines if the uncertainties should
        include the nugget. By default, this is set to ``True``.

        As with the fitting, this computation can be done independently for each emulator
        and thus can be done in parallel.

        :param testing: Array-like object holding the points where predictions will be made.
                        Must have shape ``(n_predict, D)`` or ``(D,)`` (for a single prediction)
        :type testing: ndarray
        :param unc: (optional) Flag indicating if the uncertainties are to be computed.
                    If ``False`` the method returns ``None`` in place of the uncertainty
                    array. Default value is ``True``.
        :type unc: bool
        :param deriv: (optional) Flag indicating if the derivatives are to be computed.
                      If ``False`` the method returns ``None`` in place of the derivative
                      array. Default value is ``True``.
        :type deriv: bool
        :param include_nugget: (optional) Flag indicating if the nugget should be included
                               in the predictive variance. Only relevant if ``unc = True``.
                               Default is ``True``.
        :type include_nugget: bool
        :param processes: (optional) Number of processes to use when making the predictions.
                          Must be a positive integer or ``None`` to use the number of
                          processors on the computer (default is ``None``)
        :type processes: int or None
        :returns: Tuple of numpy arrays holding the predictions, uncertainties, and derivatives,
                  respectively. Predictions and uncertainties have shape ``(n_emulators, n_predict)``
                  while the derivatives have shape ``(n_emulators, n_predict, D)``. If
                  the ``do_unc`` or ``do_deriv`` flags are set to ``False``, then those arrays
                  are replaced by ``None``.
        :rtype: tuple
        """

        testing = np.array(testing)
        if testing.shape == (self.D, ):
            testing = np.reshape(testing, (1, self.D))
        assert len(testing.shape) == 2, "testing must be a 2D array"
        assert testing.shape[
            1] == self.D, "second dimension of testing must be the same as the number of input parameters"
        if not processes is None:
            processes = int(processes)
            assert processes > 0, "number of processes must be a positive integer"

        if platform.system() == "Windows":
            predict_vals = [
                GaussianProcess.predict(gp, testing, unc, deriv,
                                        include_nugget)
                for gp in self.emulators
            ]
        else:
            with Pool(processes) as p:
                predict_vals = p.starmap(
                    GaussianProcess.predict,
                    [(gp, testing, unc, deriv, include_nugget)
                     for gp in self.emulators])

        # repackage predictions into numpy arrays

        predict_unpacked, unc_unpacked, deriv_unpacked = [
            np.array(t) for t in zip(*predict_vals)
        ]

        if not unc:
            unc_unpacked = None
        if not deriv:
            deriv_unpacked = None

        return PredictResult(mean=predict_unpacked,
                             unc=unc_unpacked,
                             deriv=deriv_unpacked)