Example #1
0
    def test_derivative(self):

        spde = LatticeSPDE.construct(
                dimension_specification = [(5, 20, 15)],
                basis_function=WendlandC4Basis(),
                overlap_factor=2.5)

        A = spde.build_A(numpy.array( [ 10.2 ] ) )
        self.assertEqual((1,15), A.shape)

        Q = spde.build_Q_stationary(numpy.log(1.0), numpy.log(1.0), 2, 1.01, 'csc')
        self.assertEqual((15,15), Q.shape)

        epsilon = 0.000001

        expected_dQ0 = \
            ((spde.build_Q_stationary(numpy.log(1.0)+epsilon, numpy.log(1.0), 2, 1.01, 'csc') - 
              spde.build_Q_stationary(numpy.log(1.0)-epsilon, numpy.log(1.0), 2, 1.01, 'csc')) / (2.0 * epsilon)).todense()

        expected_dQ1 = \
            ((spde.build_Q_stationary(numpy.log(1.0), numpy.log(1.0)+epsilon, 2, 1.01, 'csc') - 
              spde.build_Q_stationary(numpy.log(1.0), numpy.log(1.0)-epsilon, 2, 1.01, 'csc')) / (2.0 * epsilon)).todense()

        dQ0 = spde.build_dQdp_stationary(numpy.log(1.0), numpy.log(1.0), 2, 1.01, 0, 'csc').todense()
        dQ1 = spde.build_dQdp_stationary(numpy.log(1.0), numpy.log(1.0), 2, 1.01, 1, 'csc').todense()
        
        numpy.testing.assert_almost_equal(dQ0, expected_dQ0, decimal=7)
        numpy.testing.assert_almost_equal(dQ1, expected_dQ1, decimal=7)
Example #2
0
    def test_prior_precision_derivative(self):

        dQ_0 = self.prior.prior_precision_derivative(0)
        dQ_1 = self.prior.prior_precision_derivative(1)
        dQ_2 = self.prior.prior_precision_derivative(2)

        self.assertEqual(SPARSEFORMAT, dQ_0.getformat())
        self.assertEqual(SPARSEFORMAT, dQ_1.getformat())
        self.assertEqual(SPARSEFORMAT, dQ_2.getformat())
        self.assertEqual((210, 210), dQ_0.shape)
        self.assertEqual((210, 210), dQ_1.shape)
        self.assertEqual((210, 210), dQ_2.shape)

        # Numerical derivative
        numerical = [[], [], []]
        epsilon = 0.0001
        for parameter_index in range(3):

            for sign_index, sign in enumerate([-epsilon, +epsilon]):

                parameter_vector = numpy.array(
                    [numpy.log(1.0),
                     numpy.log(1.1),
                     numpy.log(1.2)])
                parameter_vector[parameter_index] += sign

                Q_numerical = SpaceTimeKroneckerPrior(
                    hyperparameters=SpaceTimeSPDEHyperparameters(
                        parameter_vector[0], parameter_vector[1],
                        parameter_vector[2]),
                    spatial_model=SphereMeshSPDE(level=1),
                    alpha=2,
                    temporal_model=LatticeSPDE.construct(
                        dimension_specification=[(23, 27, 5)],
                        basis_function=WendlandC4Basis(),
                        overlap_factor=2.5),
                    H=1.01).prior_precision()

                numerical[parameter_index].append(Q_numerical)

        numerical_dQ0 = ((numerical[0][1]) -
                         (numerical[0][0])) / (2.0 * epsilon)
        numerical_dQ1 = ((numerical[1][1]) -
                         (numerical[1][0])) / (2.0 * epsilon)
        numerical_dQ2 = ((numerical[2][1]) -
                         (numerical[2][0])) / (2.0 * epsilon)

        # Check numerical derivative corresponds to computed one
        numpy.testing.assert_almost_equal(dQ_0.todense(),
                                          numerical_dQ0.todense())
        numpy.testing.assert_almost_equal(dQ_1.todense(),
                                          numerical_dQ1.todense())
        numpy.testing.assert_almost_equal(dQ_2.todense(),
                                          numerical_dQ2.todense(),
                                          decimal=7)
Example #3
0
    def setUp(self):

        self.prior = SpaceTimeFactorPrior(
            hyperparameters=SpaceTimeSPDEHyperparameters(numpy.log(1.0), numpy.log(1.1), numpy.log(1.2)),
            spatial_model=SphereMeshSPDE(level=1),
            alpha=2,
            temporal_model=LatticeSPDE.construct(
                dimension_specification = [(23, 27, 5)],
                basis_function=WendlandC4Basis(),
                overlap_factor=2.5),
            H=1.01)
Example #4
0
 def __init__(self, n_triangulation_divisions, alpha, starttime, endtime, n_nodes, overlap_factor, H, wrap_dimensions=None):
     """Initialise space and time SPDE definitions."""
     
     super(SpaceTimeSPDEElement, self).__init__()
     self.spatial_model = SphereMeshSPDE(level=n_triangulation_divisions, sparse_format=SPARSEFORMAT)
     self.alpha = alpha
     self.temporal_model = LatticeSPDE.construct(
         dimension_specification = [(starttime, endtime, n_nodes)],
         basis_function = WendlandC4Basis(),
         overlap_factor = overlap_factor,
         wrap_dimensions = wrap_dimensions)
     self.H = H
Example #5
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])
Example #6
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)
Example #7
0
    def test_init(self):

        design = SpaceTimeFactorDesign(
            observationstructure=TestSpaceTimeFactorElement.SimulatedObservationStructure(),
            spatial_model=SphereMeshSPDE(level=1),
            alpha=2,
            temporal_model=LatticeSPDE.construct(
                dimension_specification = [(23, 27, 5)],
                basis_function=WendlandC4Basis(),
                overlap_factor=2.5),
            H=1.01)

        self.assertEqual(2, design.alpha)
        self.assertEqual(1.01, design.H)
        self.assertEqual(1, design.spatial_model.triangulation.level)
        self.assertEqual(2.5, design.temporal_model.lattice.basis_function.basis_span)
        numpy.testing.assert_almost_equal(design.temporal_model.lattice.axis_coordinates, [ [ 23.0 ], [ 24.0 ], [ 25.0 ], [ 26.0 ], [ 27.0 ] ])
Example #8
0
    def test_design_state_parameters(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)

        self.assertEqual(210, design.design_number_of_state_parameters())
        numpy.testing.assert_equal(numpy.zeros(210, ),
                                   design.design_initial_state())
Example #9
0
    def __init__(self, alpha, n_nodes, overlap_factor, H):
        """Initialise SPDE definitions.
        
        1D SPDE model in latitude with n_nodes spanning that range [-90, 90] degrees.
        
        """

        super(LatitudeSplineElement, self).__init__()

        node_separation = HALF_SPHERE_DEGREES / (n_nodes - 1)
        n_nodes_padded = n_nodes + PADDING_NODES * 2
        padding_distance = PADDING_NODES * node_separation

        self.alpha = alpha
        self.spde = LatticeSPDE.construct(dimension_specification=[
            (-90.0 - padding_distance, 90.0 + padding_distance, n_nodes_padded)
        ],
                                          basis_function=WendlandC4Basis(),
                                          overlap_factor=overlap_factor)
        self.H = H
Example #10
0
    def test_locate_nearby_basis_indices(self):
        """ Test that specified indices are identified by locate_nearby_basis_indices
        
        Allows for additional redundent locations that are not included 
        in the expected test indices to also be identified .
        
        """
        
        obs_locations = numpy.array([[-0.5, 0.0, 0.5, 1.5, 8.5, 9.0, 9.5]]).T
        
        # Non wrapped dimension test
        lattice_1d = LatticeMesh( dimension_specification = [(0., 9., 10),],
                               basis_function=WendlandC4Basis(),
                               overlap_factor=2.51,
                               wrap_dimensions = None )
    
        obs_map, node_map = lattice_1d.locate_nearby_basis_indices(obs_locations)
    
        expected_output = [[0, 0],
                           [0, 1],
                           [0, 2],
                           [1, 0],
                           [1, 1],
                           [1, 2],
                           [2, 0],
                           [2, 1],
                           [2, 2],
                           [2, 3],
                           [3, 0],
                           [3, 1],
                           [3, 2],
                           [3, 3],
                           [3, 4],
                           [4, 6],
                           [4, 7],
                           [4, 8],
                           [4, 9],
                           [5, 7],
                           [5, 8],
                           [5, 9],
                           [6, 7],
                           [6, 8],
                           [6, 9]]
    
        output_mapping = numpy.vstack((obs_map, node_map)).T

        self.assertTrue( numpy.all([output in output_mapping for output in expected_output]) )

        
        # Wrapped dimension test
        lattice_1d_wrapped = LatticeMesh( dimension_specification = [(0., 10., 10),],
                                       basis_function=WendlandC4Basis(),
                                       overlap_factor=2.5,
                                       wrap_dimensions = [True,] )
                                       
        obs_map, node_map = lattice_1d_wrapped.locate_nearby_basis_indices(obs_locations)
        
        expected_output = [[0, 7],
                           [0, 8],
                           [0, 9],
                           [0, 0],
                           [0, 1],
                           [0, 2],
                           [1, 8],
                           [1, 9],
                           [1, 0],
                           [1, 1],
                           [1, 2],
                           [2, 8],
                           [2, 9],
                           [2, 0],
                           [2, 1],
                           [2, 2],
                           [2, 3],
                           [3, 9],
                           [3, 0],
                           [3, 1],
                           [3, 2],
                           [3, 3],
                           [3, 4],
                           [4, 6],
                           [4, 7],
                           [4, 8],
                           [4, 9],
                           [4, 0],
                           [4, 1],
                           [5, 7],
                           [5, 8],
                           [5, 9],
                           [5, 0],
                           [5, 1],
                           [6, 7],
                           [6, 8],
                           [6, 9],
                           [6, 0],
                           [6, 1],
                           [6, 2]]
                           
        self.assertTrue( numpy.all([output in output_mapping for output in expected_output]) )