def test_derivative(self): """Check that numerical and analytical derivatives of Q match.""" spde = SphereMeshSPDE(level=3) Q = spde.build_Q_stationary(numpy.log(1.0), numpy.log(1.0), 2) epsilon = 0.000001 expected_dQ0 = \ ((spde.build_Q_stationary(numpy.log(1.0)+epsilon, numpy.log(1.0), 2) - spde.build_Q_stationary(numpy.log(1.0)-epsilon, numpy.log(1.0), 2)) / (2.0 * epsilon)).todense() expected_dQ1 = \ ((spde.build_Q_stationary(numpy.log(1.0), numpy.log(1.0)+epsilon, 2) - spde.build_Q_stationary(numpy.log(1.0), numpy.log(1.0)-epsilon, 2)) / (2.0 * epsilon)).todense() dQ0 = spde.build_dQdp_stationary(numpy.log(1.0), numpy.log(1.0), 2, 0).todense() dQ1 = spde.build_dQdp_stationary(numpy.log(1.0), numpy.log(1.0), 2, 1).todense() # print numpy.abs(dQ0 - expected_dQ0).ravel().max() / numpy.abs(expected_dQ0).ravel().max() # print numpy.abs(dQ1 - expected_dQ1).ravel().max() / numpy.abs(expected_dQ1).ravel().max() numpy.testing.assert_almost_equal(dQ0, expected_dQ0, decimal=7) numpy.testing.assert_almost_equal(dQ1, expected_dQ1, decimal=7)
def test_covariance_function(self): """Check that inverse precision follows matern covariance patterns.""" # Generate spde = SphereMeshSPDE(level=5) # Index 12 in the mesh is 0 latitude, 0 longitude # - The covariance evaluated will relate to distance from this chosen point # but the same shape of graph should be obtained for any point - # there is nothing special about this choice. reference_index = 12 # nu and rho as used in matern definition nu = 1.0 rho = 0.3 # Make precision precision = spde.build_Q_stationary(log_sigma=numpy.log( numpy.sqrt(1.0)), log_rho=numpy.log(2.0 * rho), alpha=2) # Sample covariance at reference index # This is the vector with 1 in the reference location and zeros everywhere else # like [ 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 ... ] reference_unit = scipy.sparse.csc_matrix( ([1.0], ([reference_index], [0])), shape=(precision.shape[0], 1)) # Solve Q.x = reference unit # This is like picking the column of inverse(Q) corresponding to reference index # and so is the covariance with respect to that reference location covariance_wrt_reference = scipy.sparse.linalg.spsolve( precision, reference_unit) # Great arc distances from reference point points = spde.triangulation.points refpoint = points[reference_index, :] dotprod = points.dot(refpoint) distance_from_reference = numpy.arccos(dotprod) # There is a scale factor difference between estimated covariance and Matern model sigma0 = numpy.sqrt(covariance_wrt_reference[reference_index]) # Compute disparity (taking into account scale factor difference) disparity = max( numpy.abs(covariance_wrt_reference - TestSphereMeshSPDE.matern( distance_from_reference, sigma0, nu, rho))) # Convert to percentage and check disparity_percent = 100.0 * disparity / (sigma0**2) # print 'Disparity (%): ', disparity_percent self.assertTrue(disparity_percent < 2.0)