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)
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)
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)
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
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])
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)
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 ] ])
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())
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
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]) )