Skip to content

Commit cb004ca

Browse files
authored
Create coupling_indices.py
1 parent b3862b6 commit cb004ca

1 file changed

Lines changed: 270 additions & 0 deletions

File tree

Lines changed: 270 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,270 @@
1+
def compute_distribution(v):
2+
"""
3+
v: vector de valores enteros
4+
devuelve un diccionario con la probabilidad de cada valor
5+
computado como la frecuencia de ocurrencia
6+
"""
7+
d= defaultdict(int)
8+
for e in v: d[e]+=1
9+
s= float(sum(d.values()))
10+
return dict((k, v/s) for k, v in d.items())
11+
12+
def entropy(y):
13+
"""
14+
Computa la entropia de un vector discreto
15+
"""
16+
# P(Y)
17+
Py= compute_distribution(y)
18+
res=0.0
19+
for k, v in Py.items():
20+
res+=v*log2(v)
21+
return -res
22+
23+
def conditional_entropy(x, y):
24+
"""
25+
x: vector de numeros reales
26+
y: vector de numeros enteros
27+
devuelve H(Y|X)
28+
"""
29+
# discretizacion de X
30+
#print(int(x.size/10))
31+
# https://stats.stackexchange.com/questions/179674/number-of-bins-when-computing-mutual-information#:~:text=3%20Answers&text=There%20is%20no%20best%20number,on%20histograms%20have%20been%20proposed.
32+
# Choosing number of bins
33+
#hx, bx= histogram(x, bins=int(x.size/10), density=True)
34+
hx, bx= histogram(x, bins=int(np.sqrt(x.size/5)),density=True)
35+
36+
Py= compute_distribution(y)
37+
Px= compute_distribution(digitize(x,bx))
38+
39+
res= 0
40+
for ey in set(y):
41+
# P(X | Y)
42+
x1= x[y==ey]
43+
condPxy= compute_distribution(digitize(x1,bx))
44+
45+
for k, v in condPxy.items():
46+
res+= (v*Py[ey]*(log2(Px[k]) - log2(v*Py[ey])))
47+
48+
def mutual_information(x,y):
49+
return entropy(y) - conditional_entropy(x,y)
50+
51+
#https://course.ccs.neu.edu/cs6140sp15/7_locality_cluster/Assignment-6/NMI.pdf
52+
def normalized_mutual_information(x,y):
53+
return (2* mutual_information(x,y))/(entropy(x)+entropy(y))
54+
55+
from copent import transent
56+
from pandas import read_csv
57+
import numpy as np
58+
59+
url = "https://archive.ics.uci.edu/ml/machine-learning-databases/00381/PRSA_data_2010.1.1-2014.12.31.csv"
60+
prsa2010 = read_csv(url)
61+
# index: 5(PM2.5),6(Dew Point),7(Temperature),8(Pressure),10(Cumulative Wind Speed)
62+
data = prsa2010.iloc[2200:2700,[5,8]].values
63+
64+
te = np.zeros(24)
65+
for lag in range(1,2):
66+
te[lag-1] = transent(data[:,0],data[:,1],1)
67+
print(data[:,0].shape)
68+
str_ = "TE from pressure to PM2.5 at %d hours lag : %f" %(lag,te[lag-1])
69+
print(str_)
70+
71+
# TE from y to x
72+
def transfer_entropy(x,y):
73+
return transent(x,y,40)
74+
75+
def multivariate_mutual_information(xs1,xs2,xtar):
76+
# https://stackoverflow.com/questions/20332750/python-joint-distribution-of-n-variables
77+
numBins =int(np.sqrt(xs1.shape[0]/5)) # number of bins in each dimension
78+
#print(xtar)
79+
xs1 = xs1[np.isfinite(xs1)]
80+
xs2 = xs2[np.isfinite(xs1)]
81+
xtar = xtar[np.isfinite(xs1)]
82+
83+
xs2 = xs2[np.isfinite(xs2)]
84+
xs2 = xs2[np.isfinite(xtar)]
85+
86+
xtar = xtar[np.isfinite(xs2)]
87+
xtar = xtar[np.isfinite(xtar)]
88+
#print(xtar)
89+
data = np.stack((xs1, xs2, xtar)).T
90+
#data = np.random.randn(100000, 3) # generate 100000 3-d random data points
91+
jointProbs3, edges = np.histogramdd(data, bins=numBins)
92+
jointProbs3 /= jointProbs3.sum()
93+
jointProbs2, edges = np.histogramdd(data[:,:2], bins=numBins)
94+
jointProbs2 /= jointProbs2.sum()
95+
jointProbs1, edges = np.histogramdd(data[:,2:], bins=numBins)
96+
jointProbs1 /= jointProbs1.sum()
97+
jointProbs3_ = jointProbs3.copy()
98+
for i in range(jointProbs1.shape[0]):
99+
jointProbs3_[i,:,:] = jointProbs1[i]*jointProbs2[:,:]
100+
arr = jointProbs3*(np.log2(jointProbs3)-np.log2(jointProbs3_))
101+
return np.mean(arr[np.isfinite(arr)])
102+
103+
# TCI for control
104+
# mrsos_control[0].shape
105+
# mrsos_std = np.zeros((mrsos_control[0].shape[1], mrsos_control[0].shape[2]))
106+
# for i_lat in range(mrsos_control[0].shape[1]):
107+
# for j_lon in range(mrsos_control)
108+
# https://stackoverflow.com/questions/58546999/calculate-correlation-in-xarray-with-missing-data
109+
def linear_trend(x, y):
110+
#print(x.shape)
111+
# if np.sum(np.isnan(x))>0:
112+
# pf = np.empty((x.shape[0]))
113+
# else:
114+
# try:
115+
idx = np.isfinite(x) & np.isfinite(y)
116+
#print(x.shape)
117+
pf = np.polyfit(x[idx], y[idx], 1)
118+
# except:
119+
# pf = np.empty((x.shape[0]))
120+
return xr.DataArray(pf[0])
121+
122+
def compute_tci(sm, lh):
123+
print(sm.shape, lh.shape)
124+
sm_std = sm.std(dim='time')
125+
slopes = np.zeros_like(sm_std.values)
126+
127+
x = sm
128+
y = lh
129+
n = y.notnull().sum(dim='time')
130+
xmean = x.mean(axis=0)
131+
ymean = y.mean(axis=0)
132+
xstd = x.std(axis=0)
133+
ystd = y.std(axis=0)
134+
cov = np.sum((x - xmean)*(y - ymean), axis=0)/(n)
135+
slopes = cov/(xstd**2)
136+
intercept = ymean - xmean*slopes
137+
sm_std['slopes'] = (('lat', 'lon'), slopes)
138+
tci = sm_std.slopes*sm_std
139+
return tci
140+
#mrsos_control[0].std(dim='time').plot()
141+
142+
def compute_aci(tas, hfss):
143+
sm = tas
144+
lh = hfss
145+
146+
print(sm.shape, lh.shape)
147+
sm_std = sm.std(dim='time')
148+
slopes = np.zeros_like(sm_std.values)
149+
150+
x = sm
151+
y = lh
152+
n = y.notnull().sum(dim='time')
153+
xmean = x.mean(axis=0)
154+
ymean = y.mean(axis=0)
155+
xstd = x.std(axis=0)
156+
ystd = y.std(axis=0)
157+
cov = np.sum((x - xmean)*(y - ymean), axis=0)/(n)
158+
slopes = cov/(xstd**2)
159+
intercept = ymean - xmean*slopes
160+
sm_std['slopes'] = (('lat', 'lon'), slopes)
161+
tci = sm_std.slopes*sm_std
162+
return tci
163+
#mrsos_control[0].std(dim='time').plot()
164+
165+
def soilm_memory(ds_soilm):
166+
threshold = 1./np.exp(1.)
167+
soilm = ds_soilm.values
168+
smemory = np.zeros_like((ds_soilm.values[0,:,:]))
169+
ntim = 50 # ds_piClim_control_MPIESM_r1i1p1f1_mrso.mrso.values.shape[0]
170+
correlation_ = np.zeros((ntim, \
171+
ds_soilm.shape[1], \
172+
ds_soilm.shape[2]))
173+
for tt in range(2,ntim):
174+
soilm_lagged = soilm[tt:,:,:]
175+
times = ds_soilm.time.values[tt:]
176+
lats = ds_soilm.lat.values
177+
lons = ds_soilm.lon.values
178+
ds = xr.Dataset({
179+
'soilm': xr.DataArray(
180+
data = soilm[:-tt], # enter data here
181+
dims = ['time', 'lat', 'lon'],
182+
coords = {'time': times, 'lat':lats, 'lon':lons},
183+
),
184+
'soilm_lagged': xr.DataArray(
185+
data = soilm_lagged, # enter data here
186+
dims = ['time', 'lat', 'lon'],
187+
coords = {'time': times, 'lat':lats, 'lon':lons},
188+
189+
)
190+
},
191+
)
192+
#print('lag = ', tt)
193+
x = ds['soilm']
194+
y = ds['soilm_lagged']
195+
n = y.notnull().sum(dim='time')
196+
xmean = x.mean(axis=0)
197+
ymean = y.mean(axis=0)
198+
xstd = x.std(axis=0)
199+
ystd = y.std(axis=0)
200+
201+
#4. Compute covariance along time axis
202+
cov = np.sum((x - xmean)*(y - ymean), axis=0)/(n)
203+
204+
#5. Compute correlation along time axis
205+
cor = cov/(xstd*ystd)
206+
correlation_[tt-2,:,:] = cor.values
207+
for i_lat in range(correlation_.shape[1]):
208+
for j_lon in range(correlation_.shape[2]):
209+
idx = np.where(correlation_[:,i_lat, j_lon] < 1/np.exp(1.))[0]
210+
#print(idx)
211+
#print(len(idx))
212+
#print(np.sum(np.isnan(soilm[:,i_lat,j_lon])))
213+
if len(idx)==0:
214+
smemory[i_lat, j_lon] = np.nan
215+
elif len(idx)==2:
216+
smemory[i_lat, j_lon] = np.nan
217+
else:
218+
print(idx)
219+
smemory[i_lat, j_lon] = idx[0]+1
220+
ds = xr.Dataset({
221+
'smemory': xr.DataArray(
222+
data = smemory, # enter data here
223+
dims = [ 'lat', 'lon'],
224+
coords = {'lat':lats, 'lon':lons},
225+
)
226+
},
227+
)
228+
229+
return ds
230+
231+
def notaro_feedback_parameter(x,y):
232+
tau = 20 # daily data
233+
stptau = x.shift(time=tau)
234+
st = x
235+
atptau = y.shift(time=tau)
236+
n = atptau.notnull().sum(dim='time')
237+
xmean = st.mean(axis=0, skipna =True)
238+
ymean = atptau.mean(axis=0, skipna =True)
239+
xstd = st.std(axis=0, skipna =True)
240+
ystd = atptau.std(axis=0, skipna =True)
241+
cov_num = np.sum((st - xmean)*(atptau - ymean), axis=0)/(n)
242+
243+
n = stptau.notnull().sum(dim='time')
244+
xmean = st.mean(axis=0, skipna =True)
245+
ymean = stptau.mean(axis=0, skipna =True)
246+
xstd = st.std(axis=0, skipna =True)
247+
ystd = stptau.std(axis=0, skipna =True)
248+
cov_den = np.sum((st - xmean)*(stptau - ymean), axis=0)/(n)
249+
250+
nfp = cov_num/cov_den
251+
252+
return nfp
253+
254+
def zengs_gamma(x,y):
255+
n = y.notnull().sum(dim='time')
256+
xmean = x.mean(axis=0)
257+
ymean = y.mean(axis=0)
258+
xstd = x.std(axis=0)
259+
ystd = y.std(axis=0)
260+
261+
#4. Compute covariance along time axis
262+
cov = np.sum((x - xmean)*(y - ymean), axis=0)/(n)
263+
264+
#5. Compute correlation along time axis
265+
cor = cov/(xstd*ystd)
266+
267+
cor = cor * (xstd/ystd)
268+
return cor
269+
270+

0 commit comments

Comments
 (0)