AMBHAS
krige.py
Go to the documentation of this file.
00001 # -*- coding: utf-8 -*-
00002 """
00003 Created on Thu Jun  9 17:55:54 2011
00004 
00005 @author: Sat Kumar Tomer
00006 @website: www.ambhas.com
00007 @email: satkumartomer@gmail.com
00008 """
00009 
00010 # import required modules
00011 import numpy as np
00012 import matplotlib.pylab as plt
00013 
00014 
00015 class OK:
00016     """
00017     This performs the ordinary kriging
00018     Input:
00019         x: x vector of location
00020         Y: y vector of location
00021         z: data vector at location (x,y)
00022     
00023     Output:
00024         None
00025         
00026     Methods:
00027         variogram: estimate the variogram
00028         
00029     """
00030     def __init__(self,x,y,z):
00031         self.x = x.flatten()
00032         self.y = y.flatten()
00033         self.z = z.flatten()
00034     
00035     def variogram(self, var_type='averaged', n_lag=9):
00036         """
00037         var_type: averaged or scattered
00038         """
00039         
00040         x = self.x
00041         y = self.y
00042         z = self.z
00043         # make the meshgrid
00044         X1,X2 = np.meshgrid(x,x) 
00045         Y1,Y2 = np.meshgrid(y,y)
00046         Z1,Z2 = np.meshgrid(z,z)
00047         
00048         D = np.sqrt((X1 - X2)**2 + (Y1 - Y2)**2)
00049         
00050         G = 0.5*(Z1 - Z2)**2
00051         indx = range(len(z))
00052         C,R = np.meshgrid(indx,indx)
00053         G = G[R>C]
00054         
00055         self.D = D
00056         DI = D[R > C]
00057         
00058         # group the variogram
00059         # the group are formed based on the equal number of bin
00060         total_n = len(DI)
00061         group_n = int(total_n/n_lag)
00062         sor_i = np.argsort(DI)[::-1]
00063         
00064         DE = np.empty(n_lag)
00065         GE = np.empty(n_lag)
00066         for i in range(n_lag):
00067             if i<n_lag-1:
00068                 DE[i] = DI[sor_i[group_n*i:group_n*(i+1)]].mean()
00069                 GE[i] = G[sor_i[group_n*i:group_n*(i+1)]].mean()
00070                 
00071             else:
00072                 DE[i] = DI[sor_i[group_n*i:]].mean()
00073                 GE[i] = G[sor_i[group_n*i:]].mean()
00074             
00075         if var_type == 'scattered':
00076             return DI,G      
00077         elif var_type == 'averaged':
00078             return DE,GE
00079         else:
00080             raise ValueError('var_type should be either averaged or scatter')
00081         
00082     def vario_model(self, lags, model_par, model_type='linear'):
00083         """
00084         Input:
00085             model_type : the type of variogram model 
00086                              spherical
00087                              linear
00088                              exponential
00089             model_par:  parameters of variogram model
00090                         this should be a dictionary 
00091                         e.g. for shperical and exponential
00092                             model_par = {'nugget':0, 'range':1, 'sill':1}
00093                         for linear
00094                             model_par = {'nugget':0, 'slope':1}
00095         Output:
00096             G:  The fitted variogram model
00097         """
00098         
00099         if model_type == 'spherical':
00100             n = model_par['nugget']
00101             r = model_par['range']
00102             s = model_par['sill']
00103             l = lags
00104             G = n + (s*(1.5*l/r - 0.5*(l/r)**3)*(l<=r) + s*(l>r))
00105         
00106         elif model_type == 'linear':
00107             n = model_par['nugget']
00108             s = model_par['slope']
00109             l = lags
00110             G = n + s*l
00111         
00112         elif model_type == 'exponential':
00113             n = model_par['nugget']
00114             r = model_par['range']
00115             s = model_par['sill']
00116             l = lags
00117             G = n + s*(1 - np.exp(-3*l/r))
00118         
00119         else:
00120             raise ValueError('model_type should be spherical or linear or exponential')
00121             
00122         return G
00123 
00124     def int_vario(self, Xg, Yg, model_par, model_type):
00125         """
00126         this computes the integral of the variogram over a square
00127         using the Monte Carlo integration method
00128         
00129         this works only for two dimensional grid
00130         
00131         Input:
00132             Xg:     x location where krigged data is required
00133             Yg:     y location whre kirgged data is required
00134             model_par: see the vario_model
00135             model_type: see the vario_model
00136         """
00137         avg_vario = np.empty((len(self.x), (len(Xg)-1)*(len(Yg)-1)))
00138         for k in range(len(self.x)):
00139             
00140             avg_vario_ens = np.empty((len(Xg)-1, len(Yg)-1))
00141             for i in range(len(Xg)-1):
00142                 for j in range(len(Yg)-1):
00143                     Xg_rand = Xg[i]+np.random.rand(10)*(Xg[i+1]-Xg[i])
00144                     Yg_rand = Yg[j]+np.random.rand(10)*(Yg[j+1]-Yg[j])    
00145 
00146                     DOR = ((self.x[k] - Xg_rand)**2 + (self.y[k] - Yg_rand)**2)**0.5
00147                     avg_vario_ens[i,j] = self.vario_model(DOR, model_par, model_type).mean()
00148             avg_vario[k,:] = avg_vario_ens.flatten()
00149         return avg_vario
00150     
00151     def krige(self, Xg, Yg, model_par, model_type):
00152         """
00153         Input:
00154             Xg:     x location where krigged data is required
00155             Yg:     y location whre kirgged data is required
00156             model_par: see the vario_model
00157             model_type: see the vario_model
00158             
00159         Attributes:
00160             self.Zg : krigged data
00161             self.s2_k = variance in the data
00162                 
00163         """
00164         
00165         # set up the Gmod matrix 
00166         n = len(self.x)
00167         Gmod = np.empty((n+1,n+1))
00168         Gmod[:n, :n] = self.vario_model(self.D, model_par, model_type)
00169                 
00170         Gmod[:,n] = 1
00171         Gmod[n,:] = 1
00172         Gmod[n,n] = 0
00173 
00174         Gmod = np.matrix(Gmod)      
00175         
00176         # inverse of Gmod
00177         Ginv = Gmod.I
00178 
00179         Xg = Xg.flatten()
00180         Yg = Yg.flatten()        
00181         Zg = np.empty(Xg.shape)
00182         s2_k = np.empty(Xg.shape)
00183         
00184         for k in range(len(Xg)):
00185             
00186             DOR = ((self.x - Xg[k])**2 + (self.y - Yg[k])**2)**0.5
00187             GR = np.empty((n+1,1))
00188             
00189             GR[:n,0] = self.vario_model(DOR, model_par, model_type)
00190             
00191             GR[n,0] = 1
00192             E = np.array(Ginv * GR )
00193             Zg[k] = np.sum(E[:n,0]*self.z)
00194             s2_k[k] = np.sum(E[:n,0]*GR[:n,0])+ E[n, 0]
00195         
00196         self.Zg = Zg
00197         self.s2_k = s2_k
00198         
00199     def block_krige(self, Xg, Yg, model_par, model_type):
00200         """
00201         Input:
00202             Xg:     x location where krigged data is required
00203             Yg:     y location whre krigged data is required
00204             model_par: see the vario_model
00205             model_type: see the vario_model
00206             
00207         Attributes:
00208             self.Zg : krigged data
00209             self.s2_k = variance in the data
00210                 
00211         """
00212         
00213         # set up the Gmod matrix 
00214         n = len(self.x)
00215         Gmod = np.empty((n+1,n+1))
00216         Gmod[:n, :n] = self.vario_model(self.D, model_par, model_type)
00217                 
00218         Gmod[:,n] = 1
00219         Gmod[n,:] = 1
00220         Gmod[n,n] = 0
00221 
00222         Gmod = np.matrix(Gmod)      
00223         
00224         # inverse of Gmod
00225         Ginv = Gmod.I
00226 
00227         Xg = Xg.flatten()
00228         Yg = Yg.flatten()        
00229         
00230      
00231         avg_vario = self.int_vario(Xg, Yg, model_par, model_type)
00232         Zg = np.empty(avg_vario.shape[1])
00233         s2_k = np.empty(avg_vario.shape[1])
00234         
00235         for k in range(avg_vario.shape[1]):
00236             
00237             GR = np.empty((n+1,1))
00238             GR[:n,0] = avg_vario[:,k]
00239             GR[n,0] = 1
00240             E = np.array(Ginv * GR )
00241             Zg[k] = np.sum(E[:n,0]*self.z)
00242             s2_k[k] = np.sum(E[:n,0]*GR[:n,0])+ E[n, 0]
00243         
00244         self.Zg = Zg.reshape(len(Xg)-1, len(Yg)-1)
00245         self.s2_k = s2_k.reshape(len(Xg)-1, len(Yg)-1)
00246             
00247 if __name__ == "__main__":          
00248     # generate some sythetic data
00249     x = np.random.rand(20)
00250     y = np.random.rand(20)
00251     z = 0.0*np.random.normal(size=20)+x+y
00252     
00253     foo = OK(x,y,z)
00254     #ax,ay = foo.variogram('scattered')
00255     ax,ay = foo.variogram()
00256     
00257     plt.plot(ax,ay,'ro')
00258     
00259     lags = np.linspace(0,5)
00260     model_par = {}
00261     model_par['nugget'] = 0
00262     model_par['range'] = 1
00263     model_par['sill'] = 2.0
00264     
00265     G = foo.vario_model(lags, model_par, model_type = 'exponential')
00266     plt.plot(lags, G, 'k')
00267     plt.show()
00268     
00269     Rx = np.linspace(-1,1,1050)
00270     Ry = np.linspace(0,1,750)
00271     XI,YI = np.meshgrid(Rx,Ry)
00272     foo.krige(XI, YI, model_par, 'exponential')
00273     
00274     plt.matshow(foo.Zg.reshape(750,1050))
00275     plt.show()
00276     
00277 #    # block kriging
00278 #    xg = np.linspace(0,1,5)
00279 #    yg = np.linspace(0,1,8)
00280 #    foo.block_krige(xg, yg, model_par, model_type = 'exponential')
00281 #    plt.imshow(foo.s2_k, extent=(0,1,0,1))
00282 #    plt.imshow(foo.Zg, extent=(0,1,0,1))
00283 #    plt.matshow(foo.Zg)
00284 #    plt.matshow(foo.s2_k)
00285 #    plt.colorbar()
00286 #    plt.plot(x,y, 'ro')
00287 #    plt.show()
 All Classes Namespaces Files Functions Variables