grib2io.utils.gauss_grid
Tools for working with Gaussian grids.
1""" 2Tools for working with Gaussian grids. 3""" 4 5# Adopted from: https://gist.github.com/ajdawson/b64d24dfac618b91974f 6from __future__ import (absolute_import, division, print_function) 7 8import functools 9 10import numpy as np 11import numpy.linalg as la 12from numpy.polynomial.legendre import legcompanion, legder, legval 13 14 15def __single_arg_fast_cache(func): 16 """Caching decorator for functions of one argument.""" 17 class CachingDict(dict): 18 19 def __missing__(self, key): 20 result = self[key] = func(key) 21 return result 22 23 @functools.wraps(func) 24 def __getitem__(self, *args, **kwargs): 25 return super(CachingDict, self).__getitem__(*args, **kwargs) 26 27 return CachingDict().__getitem__ 28 29 30@__single_arg_fast_cache 31def gaussian_latitudes(nlat): 32 """ 33 Construct latitudes for a Gaussian grid. 34 35 Parameters 36 ---------- 37 38 **`nlat`**: The number of latitudes in the Gaussian grid. 39 40 Returns 41 ------- 42 43 Numpy array of latitudes (in degrees) with a length of `nlat`. 44 """ 45 if abs(int(nlat)) != nlat: 46 raise ValueError('nlat must be a non-negative integer') 47 # Create the coefficients of the Legendre polynomial and construct the 48 # companion matrix: 49 cs = np.array([0] * nlat + [1], dtype=int) 50 cm = legcompanion(cs) 51 # Compute the eigenvalues of the companion matrix (the roots of the 52 # Legendre polynomial) taking advantage of the fact that the matrix is 53 # symmetric: 54 roots = la.eigvalsh(cm) 55 roots.sort() 56 # Improve the roots by one application of Newton's method, using the 57 # solved root as the initial guess: 58 fx = legval(roots, cs) 59 fpx = legval(roots, legder(cs)) 60 roots -= fx / fpx 61 # The roots should exhibit symmetry, but with a sign change, so make sure 62 # this is the case: 63 roots = (roots - roots[::-1]) / 2. 64 # Convert the roots from the interval [-1, 1] to latitude values on the 65 # interval [-90, 90] degrees: 66 latitudes = np.rad2deg(np.arcsin(roots)) 67 # Flip latitudes such that it is oriented from North to South [90, -90] 68 latitudes = np.flip(latitudes) 69 return latitudes
def
gaussian_latitudes():
31@__single_arg_fast_cache 32def gaussian_latitudes(nlat): 33 """ 34 Construct latitudes for a Gaussian grid. 35 36 Parameters 37 ---------- 38 39 **`nlat`**: The number of latitudes in the Gaussian grid. 40 41 Returns 42 ------- 43 44 Numpy array of latitudes (in degrees) with a length of `nlat`. 45 """ 46 if abs(int(nlat)) != nlat: 47 raise ValueError('nlat must be a non-negative integer') 48 # Create the coefficients of the Legendre polynomial and construct the 49 # companion matrix: 50 cs = np.array([0] * nlat + [1], dtype=int) 51 cm = legcompanion(cs) 52 # Compute the eigenvalues of the companion matrix (the roots of the 53 # Legendre polynomial) taking advantage of the fact that the matrix is 54 # symmetric: 55 roots = la.eigvalsh(cm) 56 roots.sort() 57 # Improve the roots by one application of Newton's method, using the 58 # solved root as the initial guess: 59 fx = legval(roots, cs) 60 fpx = legval(roots, legder(cs)) 61 roots -= fx / fpx 62 # The roots should exhibit symmetry, but with a sign change, so make sure 63 # this is the case: 64 roots = (roots - roots[::-1]) / 2. 65 # Convert the roots from the interval [-1, 1] to latitude values on the 66 # interval [-90, 90] degrees: 67 latitudes = np.rad2deg(np.arcsin(roots)) 68 # Flip latitudes such that it is oriented from North to South [90, -90] 69 latitudes = np.flip(latitudes) 70 return latitudes
Construct latitudes for a Gaussian grid.
Parameters
nlat
: The number of latitudes in the Gaussian grid.
Returns
Numpy array of latitudes (in degrees) with a length of nlat
.