示例#1
0
    def test_design_function(self):

        spde = SphereMeshSPDE(level=1, sparse_format=SPARSEFORMAT)
        design = SeasonalElementDesign(
            TestSeasonalElement.SimulatedObservationStructure(),
            spde,
            n_harmonics=3,
            include_local_mean=True)

        # Initialise zero state vector
        state_vector = numpy.zeros((294, 1))

        # Get indices of nonzero design elements
        A_simulated = spde.build_A(
            TestSeasonalElement.SimulatedObservationStructure(
            ).location_polar_coordinates())
        observation_indices, vertex_indices = A_simulated.sorted_indices(
        ).nonzero()

        # This should select observation 1
        state_vector[vertex_indices[3:6], 0] = 1.0

        # And this will add 0.309016994375 to it
        state_vector[vertex_indices[3:6] + 84, 0] = 1.0

        # Apply state vector
        y = design.design_function(state_vector)

        # Check observation 1 selected with appropriate sum
        numpy.testing.assert_almost_equal(
            y, numpy.array([[0.0], [1.309016994375]]))
示例#2
0
    def test_design_function(self):

        obs = TestSpaceTimeKroneckerElement.SimulatedObservationStructure()

        spde_space = SphereMeshSPDE(level=1)

        spde_time = LatticeSPDE.construct(dimension_specification=[(23, 27, 5)
                                                                   ],
                                          basis_function=WendlandC4Basis(),
                                          overlap_factor=2.5)

        design = SpaceTimeKroneckerDesign(observationstructure=obs,
                                          spatial_model=spde_space,
                                          alpha=2,
                                          temporal_model=spde_time,
                                          H=1.01)

        # Get and check indices of nonzero design elements
        A_space = spde_space.build_A(obs.location_polar_coordinates())
        observation_indices, vertex_indices = A_space.sorted_indices().nonzero(
        )
        numpy.testing.assert_equal(observation_indices, [0, 0, 0, 1, 1, 1])
        self.assertEqual((6, ), vertex_indices.shape)

        # Vertices of observations 0 and 1
        # (one row per vertex, one column per coordinate)
        vertices0 = spde_space.triangulation.points[vertex_indices[0:3], :]
        vertices1 = spde_space.triangulation.points[vertex_indices[3:6], :]

        # Multiply vertices by the weights from A and sum to get cartesian locations
        testpoint0 = A_space[0, vertex_indices[0:3]] * vertices0
        testpoint1 = A_space[1, vertex_indices[3:6]] * vertices1

        # Check results correspond to original polar coordinates
        numpy.testing.assert_almost_equal(cartesian_to_polar2d(testpoint0),
                                          [[15.0, -7.0]])
        numpy.testing.assert_almost_equal(cartesian_to_polar2d(testpoint1),
                                          [[5.0, 100.0]])

        # So the function with those indices set should give required values, provided it's evaluated at time index == 24
        state_vector = numpy.zeros((210, ))
        state_vector[42 + vertex_indices[0:3]] = 40.0
        state_vector[42 + vertex_indices[3:6]] = 28.0
        numpy.testing.assert_almost_equal(design.design_function(state_vector),
                                          [40.0, 28.0])

        # But if we change to a time far away then we get nothing
        state_vector = numpy.zeros((210, ))
        state_vector[(42 * 4) + vertex_indices[0:3]] = 40.0
        state_vector[(42 * 4) + vertex_indices[3:6]] = 28.0
        numpy.testing.assert_almost_equal(design.design_function(state_vector),
                                          [0.0, 0.0])
示例#3
0
    def test_design_jacobian(self):

        obs = TestSpaceTimeKroneckerElement.SimulatedObservationStructure()

        spde_space = SphereMeshSPDE(level=1)

        spde_time = LatticeSPDE.construct(dimension_specification=[(23, 27, 5)
                                                                   ],
                                          basis_function=WendlandC4Basis(),
                                          overlap_factor=2.5)

        design = SpaceTimeKroneckerDesign(observationstructure=obs,
                                          spatial_model=spde_space,
                                          alpha=2,
                                          temporal_model=spde_time,
                                          H=1.01)

        # Build a candidate state vector (as used above for function testing)
        A_space = spde_space.build_A(obs.location_polar_coordinates())
        observation_indices, vertex_indices = A_space.sorted_indices().nonzero(
        )
        state_vector = numpy.zeros((210, ))
        state_vector[42 + vertex_indices[0:3]] = 40.0
        state_vector[42 + vertex_indices[3:6]] = 28.0

        # Numerical jacobian
        J_numerical = numpy.zeros((2, 210))
        epsilon = 0.01
        for parameter_index in range(210):

            x0 = numpy.copy(state_vector)
            x1 = numpy.copy(state_vector)
            x0[parameter_index] -= epsilon
            x1[parameter_index] += epsilon
            J_numerical[:, parameter_index] = (design.design_function(x1) -
                                               design.design_function(x0)) / (
                                                   2.0 * epsilon)

        # Computed jacobian
        J_calculated = design.design_jacobian(state_vector)

        # Should be the same
        numpy.testing.assert_almost_equal(J_calculated.todense(), J_numerical)

        # And numbers of nonzeros also the same
        self.assertEqual(J_calculated.nnz,
                         scipy.sparse.csc_matrix(J_numerical).nnz)
示例#4
0
    def test_design_jacobian(self):

        obs = TestCombinationElement.SimulatedObservationStructure()
        spde = SphereMeshSPDE(1)
        design = CombinationDesign(
            [GrandMeanDesign(2), LocalDesign(obs, spde)])

        # Make a state vector full of a test value 561 which should never actually get accessed
        state_vector = numpy.tile(561.0, (47, 1))

        J = design.design_jacobian(state_vector)

        # A-matrix for comparison
        A = spde.build_A(obs.location_polar_coordinates())

        # Should have ones at start for global mean
        J_expected = numpy.hstack([numpy.array([[1.0], [1.0]]), A.todense()])

        # Check as exepcted
        self.assertEqual(SPARSEFORMAT, J.getformat())
        numpy.testing.assert_equal(J_expected, J.todense())
示例#5
0
    def test_design_function(self):

        obs = TestCombinationElement.SimulatedObservationStructure()
        spde = SphereMeshSPDE(1)
        design = CombinationDesign(
            [GrandMeanDesign(2), LocalDesign(obs, spde)])

        A = spde.build_A(obs.location_polar_coordinates())
        observation_indices, vertex_indices = A.sorted_indices().nonzero()

        # Make a state vector full of a test value 561 which should never actually get accessed
        state_vector = numpy.tile(561.0, (47, 1))

        # Set the grand mean to 20.0
        state_vector[0, 0] = 20.0

        # Choose some numbers for observations of interest
        state_vector[(vertex_indices[0:3] + 1), 0] = 43.5
        state_vector[(vertex_indices[3:6] + 1), 0] = -27.0

        # Should end up with (20.0 + 43.5) and (20.0 - 27.0)
        y = design.design_function(state_vector)
        numpy.testing.assert_almost_equal(y, [[63.5], [-7.0]])
示例#6
0
def optimisation_demo():
    """
    Demonstrate construction of an SPDE model on a tringular mesh on a sphere.
    
    The mesh is constructed as a subdivided icosahedron. Observations are simulated
    and a latent variable model is learnt.
    
    """

    import matplotlib.pyplot as plt
    from advanced_standard.linalg import sparse
    from advanced_standard.utilities import plot_tools

    print "############"
    print "# Setup    #"
    print "############"

    my_spde = SphereMeshSPDE(level=4, project_onto_sphere=True)
    print "number of latent variables:"
    print my_spde.n_latent_variables()

    print "############"
    print "# Q matrix #"
    print "############"

    Q_parameters = np.log(np.array([2., 1.0]))
    print "Q_parameters:", Q_parameters
    Q = my_spde.build_Q(Q_parameters=Q_parameters, alpha=2)
    #dQdp0 = my_spde.build_dQdp(Q_parameters = np.log(np.array([1., 0.5])), alpha = 2, parameter_index = 0)
    #dQdp1 = my_spde.build_dQdp(Q_parameters = np.log(np.array([1., 0.5])), alpha = 2, parameter_index = 1)
    print "############"
    print "# Q sample #"
    print "############"

    c = sparse.sample_mvn(Q, 1)

    print "############"
    print "# Obs gen  #"
    print "############"

    number_of_observations = 25000  #2592
    test_points = np.random.uniform(-1, 1, (number_of_observations, 3))

    standard_error = 1.0
    Q_e = scipy.sparse.eye(number_of_observations) * (1.0 / standard_error**2)

    observation_error = sparse.sample_mvn(Q_e, 1)

    print "############"
    print "# A matrix #"
    print "############"

    A = my_spde.build_A(test_points)
    truth = A * c

    #y = np.atleast_2d(truth + observation_error).T
    y = truth + observation_error
    print "############"
    print "# solving #"
    print "############"

    Q_increment = A.T * Q_e * A
    i_increment = A.T * Q_e * y

    import advanced_standard.linalg.optimisation as optimisation

    Qkwargs = {'alpha': 2, 'sparse_format': 'csc'}

    #    interval = 1e-5
    #
    #    cost_function = optimisation.cost_function(Q_parameters=Q_parameters,
    #                                               i_c = np.zeros( (Q.shape[0],1) ),
    #                                               i_increment= i_increment,
    #                                               Q_increment=Q_increment,
    #                                               Q_function = my_spde.build_Q,
    #                                               dQ_function = my_spde.build_dQdp, set_point_mode = 'fixed',
    #                                               fixed_set_point = np.zeros( (Q.shape[0],1) ),
    #                                               observation_loglik=None,
    #                                               **Qkwargs)
    #
    #    vost_function = optimisation.cost_function(Q_parameters=Q_parameters +np.array([0.0, interval]),
    #                                               i_c = np.zeros( (Q.shape[0],1) ),
    #                                               i_increment= i_increment,
    #                                               Q_increment=Q_increment,
    #                                               Q_function = my_spde.build_Q,
    #                                               dQ_function = my_spde.build_dQdp, set_point_mode = 'fixed',
    #                                               fixed_set_point = np.zeros( (Q.shape[0],1) ),
    #                                               observation_loglik=None,
    #                                               **Qkwargs)
    #
    #    dcost_function = optimisation.cost_function_derivative(Q_parameters=Q_parameters,
    #                                               i_c = np.zeros( (Q.shape[0],1) ),
    #                                               i_increment= i_increment,
    #                                               Q_increment=Q_increment,
    #                                               Q_function = my_spde.build_Q,
    #                                               dQ_function = my_spde.build_dQdp, set_point_mode = 'fixed',
    #                                               fixed_set_point = np.zeros( (Q.shape[0],1) ),
    #                                               **Qkwargs)
    #
    #
    #    print (vost_function - cost_function) / interval
    #
    #    print dcost_function
    #    print cost_function

    Q_init = np.log(np.array([2.0, np.pi / 4]))

    mu_c = np.zeros((Q.shape[0], 1))
    i_increment = i_increment
    Q_increment = Q_increment
    Q_function = my_spde.build_Q
    dQ_function = my_spde.build_dQdp
    set_point_mode = 'fixed'
    fixed_set_point = np.zeros((Q.shape[0], 1))
    observation_loglik = None

    opt_args = (mu_c, i_increment, Q_increment, Q_function, dQ_function,
                set_point_mode, fixed_set_point, observation_loglik, Qkwargs)

    print scipy.optimize.check_grad(optimisation.cost_function,
                                    optimisation.cost_function_derivative,
                                    Q_init, *opt_args)

    def opt_printer(x):
        print x

    fit = scipy.optimize.minimize(optimisation.cost_function,
                                  Q_init,
                                  args=opt_args,
                                  method='BFGS',
                                  jac=optimisation.cost_function_derivative,
                                  tol=None,
                                  callback=opt_printer,
                                  options={
                                      'disp': False,
                                      'gtol': 1e-04,
                                      'eps': 1e-08,
                                      'return_all': False,
                                      'maxiter': 20
                                  })

    print fit

    fitted_hyperparamters = fit['x']

    new_Q = Q_function(Q_parameters=fitted_hyperparamters, **Qkwargs)

    Q_estimate = sparse.compute_Q_u(Q_e, A, new_Q)
    i_estimate = sparse.compute_i_u(
        y, Q_e, A, np.zeros((my_spde.n_latent_variables(), 1)))
    c_estimate = sparse.compute_mu_u(i_estimate, Q_estimate)

    reconstruction = A * c_estimate

    print "############"
    print "# plotting #"
    print "############"

    vmin = -6
    vmax = 6

    plt.figure()
    vertices_coords_2d = cartesian_to_polar(my_spde.triangulation.vertices)
    plot_tools.scatter2d(vertices_coords_2d[:, 1] * 180 / np.pi,
                         vertices_coords_2d[:, 0] * 180 / np.pi,
                         cs=c.ravel(),
                         vmax=vmax,
                         vmin=vmin)

    plt.figure()
    test_point_coords_2d = cartesian_to_polar(test_points)
    plot_tools.scatter2d(test_point_coords_2d[:, 1] * 180 / np.pi,
                         test_point_coords_2d[:, 0] * 180 / np.pi,
                         cs=truth.ravel(),
                         vmax=vmax,
                         vmin=vmin)

    plt.figure()
    test_point_coords_2d = cartesian_to_polar(test_points)
    plot_tools.scatter2d(test_point_coords_2d[:, 1] * 180 / np.pi,
                         test_point_coords_2d[:, 0] * 180 / np.pi,
                         cs=np.asarray(y).ravel(),
                         vmax=vmax,
                         vmin=vmin)

    plt.figure()
    vertices_coords_2d = cartesian_to_polar(my_spde.triangulation.vertices)
    plot_tools.scatter2d(vertices_coords_2d[:, 1] * 180 / np.pi,
                         vertices_coords_2d[:, 0] * 180 / np.pi,
                         cs=c_estimate.ravel(),
                         vmax=vmax,
                         vmin=vmin)

    plt.figure()
    test_point_coords_2d = cartesian_to_polar(test_points)
    plot_tools.scatter2d(test_point_coords_2d[:, 1] * 180 / np.pi,
                         test_point_coords_2d[:, 0] * 180 / np.pi,
                         cs=reconstruction.ravel(),
                         vmax=vmax,
                         vmin=vmin)

    plt.show()
示例#7
0
def spde_demo():
    """
    Demonstrate construction of an SPDE model on a tringular mesh on a sphere.
    
    The mesh is constructed as a subdivided icosahedron. Observations are simulated
    and a latent variable model is learnt.
    
    """

    import matplotlib.pyplot as plt
    from advanced_standard.linalg import sparse
    from advanced_standard.utilities import plot_tools

    print "############"
    print "# Setup    #"
    print "############"

    my_spde = SphereMeshSPDE(level=4, project_onto_sphere=True)
    print "number of latent variables:"
    print my_spde.n_latent_variables()

    print "############"
    print "# Q matrix #"
    print "############"

    Q = my_spde.build_Q(Q_parameters=np.log(np.array([2., 0.5])), alpha=2)
    #dQdp0 = my_spde.build_dQdp(Q_parameters = np.log(np.array([1., 0.5])), alpha = 2, parameter_index = 0)
    #dQdp1 = my_spde.build_dQdp(Q_parameters = np.log(np.array([1., 0.5])), alpha = 2, parameter_index = 1)
    print "############"
    print "# Q sample #"
    print "############"

    c = sparse.sample_mvn(Q, 1)

    print "############"
    print "# Obs gen  #"
    print "############"

    number_of_observations = 2592
    test_points = np.random.uniform(-1, 1, (number_of_observations, 3))

    standard_error = 0.5
    Q_e = scipy.sparse.eye(number_of_observations) * (1.0 / standard_error**2)

    observation_error = sparse.sample_mvn(Q_e, 1)

    print "############"
    print "# A matrix #"
    print "############"

    A = my_spde.build_A(test_points)
    truth = A * c

    y = truth + observation_error

    print "############"
    print "# solving #"
    print "############"

    Q_estimate = sparse.compute_Q_u(Q_e, A, Q)
    i_estimate = sparse.compute_i_u(y, Q_e, A,
                                    np.zeros((my_spde.n_latent_variables())))
    c_estimate = sparse.compute_mu_u(i_estimate, Q_estimate)

    reconstruction = A * c_estimate

    print "############"
    print "# plotting #"
    print "############"

    vmin = -3
    vmax = 3

    plt.figure()
    vertices_coords_2d = cartesian_to_polar(my_spde.triangulation.vertices)
    plot_tools.scatter2d(vertices_coords_2d[:, 1] * 180 / np.pi,
                         vertices_coords_2d[:, 0] * 180 / np.pi,
                         cs=c,
                         vmax=vmax,
                         vmin=vmin)

    plt.figure()
    test_point_coords_2d = cartesian_to_polar(test_points)
    plot_tools.scatter2d(test_point_coords_2d[:, 1] * 180 / np.pi,
                         test_point_coords_2d[:, 0] * 180 / np.pi,
                         cs=truth,
                         vmax=vmax,
                         vmin=vmin)

    plt.figure()
    test_point_coords_2d = cartesian_to_polar(test_points)
    plot_tools.scatter2d(test_point_coords_2d[:, 1] * 180 / np.pi,
                         test_point_coords_2d[:, 0] * 180 / np.pi,
                         cs=y,
                         vmax=vmax,
                         vmin=vmin)

    plt.figure()
    vertices_coords_2d = cartesian_to_polar(my_spde.triangulation.vertices)
    plot_tools.scatter2d(vertices_coords_2d[:, 1] * 180 / np.pi,
                         vertices_coords_2d[:, 0] * 180 / np.pi,
                         cs=c_estimate.ravel(),
                         vmax=vmax,
                         vmin=vmin)

    plt.figure()
    test_point_coords_2d = cartesian_to_polar(test_points)
    plot_tools.scatter2d(test_point_coords_2d[:, 1] * 180 / np.pi,
                         test_point_coords_2d[:, 0] * 180 / np.pi,
                         cs=reconstruction.ravel(),
                         vmax=vmax,
                         vmin=vmin)

    plt.show()