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