简体   繁体   中英

Numeric precision of climate science calculations in python

I am currently trying to recreate findings of a paper ( https://www.researchgate.net/publication/309723672_Evidence_for_wave_resonance_as_a_key_mechanism_for_generating_high-amplitude_quasi-stationary_waves_in_boreal_summer ) for my masters thesis. I calculate the meridional (degrees North) distribution of the square of the meridional wavenumber of a Rossby wave (a certain kind of flow in the atmosphere), for a number of days. This value is only dependent on the mean zonal (degrees West and East) winds and their first and second meridional derivative, as well as the zonal wavenumber of the 2D Rossby wave. This kind of wave can be thought of like a wave on a drum for example, only in a spherical environment, the atmosphere. I am using python 3.6.5, and I suspect the problem to be numeric precision, however I am not sure.

I have read through other threads concerning numeric precision, and came across this one for example: python sine and cosine precision . However, I have not tried this yet because I am trying to avoid writing my own trigonometric functions. Also, since I have to process quite a large amount of data, i try to not to slow down my code. From experiments I found that the math library is not more precise than the numpy library concerning the trigonometric functions.

Here is the snippet of code that concerns me:

Lat = np.linspace(0,90,37)
MeridWN = np.zeros((29,36), dtype='float64')        
        ######################################################
        #define Meridional wavenumber, l^2
        for i in range(5,28,10):
            for j in range(36):
                MeridWN[i,j] = (((2*EarthRot*np.cos(Lat[j]*np.pi/180.0)**3.0)/(EarthRad*ZonMeanZonWiNH[j]))-
                   ((np.cos(Lat[j]*np.pi/180.)**2.)/(EarthRad**2.0*ZonMeanZonWiNH[j]))*
                   ZonMeanZonWiMeridGradGrad[j]+
                   ((np.sin(Lat[j]*np.pi/180.)*np.cos(Lat[j]*np.pi/180.))/(EarthRad**2.0*ZonMeanZonWiNH[j]))*
                   ZonMeanZonWiMeridGrad[j]+(1./(EarthRad**2.0))-(ZonWN[i]/EarthRad)**2.0)
                MeridWNMerge[i,x,j] = MeridWN[i,j]

Index i is for a range of zonal wavenumbers, x is the day (this snippet is from a larger loop that runs over the days) and j is the Latitude position. To calculate the derivatives I use the numpy gradient functions like this:

ZonMeanZonWiMeridGrad = np.gradient(ZonMeanZonWiNH,np.linspace(0,90,37))
ZonMeanZonWiMeridGradGrad = np.gradient(ZonMeanZonWiMeridGrad,np.linspace(0,90,37))

This is the formula for the calculation of the square of the meridional wavenumber (l), where Omega is the Earths rotation, Phi is the latitudinal position, a is Earths radius, U is the zonal mean, averaged zonally and k is the zonal Wavenumber, in my case an array ranging from 5.5 to 8.5.

This is a comparison of my zonal mean zonal wind field (bottom) from June to August and the one on from the paper (top), indicating that we have the same data and this is not the issue. The color scales are sligthly different, however the most prominent features of the wind profile are very similar, and the small differences shouldn't produce such a different profile of the meridional wavenumber (for k = 7) , where the figure from the paper is again on top and mine on the bottom. Here the colorscales are again different, but large structural similarities should be captured nonetheless. As you can see, I deal with very small numbers, leading to my suspicion of having a numerically imprecise code.
If you want, i can upload my entire code, however I think for the discussion about the precision this is sufficient. I am trying to solve this problem no for about 2 weeks, trying all diferent changes in my code, some were good changes that, however none gave the desired output.

Thank you in advance,
Thomas

If its issue with numerical precision then the algorithm is not the issue but what variable types you are using. if you switch to longer float representations like dtype='c16l' ( 128- complex floating-point number. https://docs.scipy.org/doc/numpy/reference/arrays.dtypes.html

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM