def test_return_shape(self): """ Check that the returned covariance matrix is the correct size :return: Nothing """ print("Testing that covarxy_pv returns 1 dimensional matrix") cov = covarxy_pv(self.input_coords, self.coords, self.long, self.lat, self.phi, self.no_pv) self.assertEqual(cov.shape, (3, ), "covarxy_pv matrix is incorrect shape")
def test_returns_ones(self): """ Check that we get a matrix of almost ones if data is very close (according to scale) :return: nothing """ print("Testing that covarxy_pv returns almost ones if data is close") cov = covarxy_pv(self.input_coords, self.coords, 99999999, 99999999, self.phi, self.no_pv) for i in cov: self.assertAlmostEqual( i, 1, 15, "elements in covarxy_pv matrix are not correct")
def test_returns_correct(self): """ Check that the returned covriance matrix contains the correct values :return: Nothing """ print("Testing that covarxy_pv returns correct values") ans = np.array([1, 0.9134, 0.5941]) cov = covarxy_pv(self.input_coords, self.coords, self.long, self.lat, self.phi, self.no_pv) for i in range(0, ans.size): self.assertAlmostEqual( ans[i], cov[i], 4, "elements in covarxy_pv matrix are not correct")
def build_cov(ptmp, coord_float, config): """ Build the covariance matrix :param ptmp: matrix of potential temperatures :param coord_float_config: the x, y, z position of the float :return: covariance matrix """ # Set up theta boundaries for water masses ptboundaries = np.array([30, 24, 18, 12, 8, 4, 2.5, 1, -2]) ptscale_down = np.array([6, 6, 6, 4, 4, 1.5, 1.5, 1, 1]) ptscale_up = np.array([6, 6, 6, 6, 4, 4, 1.5, 1.5, 1]) # Set up the building tile = vertical covariance matrix # The upper triangle of the matrix (top right values) are the covariance of each ptlevel with # every ptlevel below it, looking down the water column from the diagonal # The lower triangle of the matrix (bottom left values) are the covariance of each ptlevel with # every ptlevel above it, looking up the water column from the diagonal ptmp_rows = ptmp.shape[0] ptmp_columns = ptmp.shape[1] # set up the covariance matrix cov = np.zeros((ptmp_rows * ptmp_columns, ptmp_rows)) # set up interpolation grids upper_interp = interpolate.interp1d(ptboundaries, ptscale_down) lower_interp = interpolate.interp1d(ptboundaries, ptscale_up) # go through each profile for profile in range(0, ptmp_columns): profile_1 = profile * ptmp_rows # go through each level for i in range(0, ptmp_rows): for j in range(0, ptmp_rows): # belongs in the upper triangle, look down water column for vertical scale if i < j: l_theta = upper_interp(ptmp[i, profile]) cov[i + profile_1, j] = np.exp( -1 * (ptmp[j, profile] - ptmp[i, profile])**2 / l_theta**2) # belongs in the lower triangle, look up water column for vertical scale elif i > j: l_theta = lower_interp(ptmp[i, profile]) cov[i + profile_1, j] = np.exp( -1 * (ptmp[j, profile] - ptmp[i, profile])**2 / l_theta**2) # it is in the leading diagonal, so make it equal to 1 else: cov[i + profile_1, j] = 1 # if we don't have a value, make it equal to 1 if np.isnan(cov[i + profile_1, j]): cov[i + profile_1, j] = 1 # set up matrix to hold horizontal covariance h_cov = np.ones((ptmp_columns, ptmp_columns)) * np.nan for profile in range(0, ptmp_columns): h_cov[profile, :] = covarxy_pv(coord_float[profile], coord_float, config['MAPSCALE_LONGITUDE_SMALL'], config['MAPSCALE_LATITUDE_SMALL'], config['MAPSCALE_PHI_SMALL'], config['MAPSCALE_USE_PV']) h_cov = h_cov[:, 0:ptmp_columns] # build final covariance matrix, using horizontal and vertical covariance n_cov = np.tile(cov, [1, ptmp_columns]) # Have to find the covariance for each profile against all other profiles for profile in range(0, ptmp_columns): lower = profile * ptmp_rows upper = (profile + 1) * ptmp_rows # go through each profile for profile_1 in range(0, ptmp_columns): lower_1 = profile_1 * ptmp_rows upper_1 = (profile_1 + 1) * ptmp_rows n_cov[lower:upper, lower_1:upper_1] = h_cov[profile, profile_1] * \ n_cov[lower:upper, lower_1:upper_1] return n_cov