00001
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
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
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
00059
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
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
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
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
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
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
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
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287