-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathphi_divergence.py
85 lines (61 loc) · 1.87 KB
/
phi_divergence.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#!/usr/bin/env python
# coding: utf-8
# In[1]:
import numpy as np
import pandas as pd
import cvxpy as cp
import mosek
import matplotlib.pyplot as plt
import datetime as date
from datetime import datetime as dt
from dateutil.relativedelta import *
import scipy.stats
from scipy.stats import rankdata
# In[5]:
######## The representations of the epigraph of the perspective of the phi conjugates: gamma*(phi^*)(s/gamma) <= t are given below for several
##### phi functions
##### the modified chi-squared function phi(x)= (x-1)^2
def mod_chi2_conj(gamma,s,t,w,constraints):
constraints.append(cp.norm(cp.vstack([w,t/2]))<=(t+2*gamma)/2)
constraints.append(s/2+gamma<= w)
return(constraints)
#### the kullback-leibler function phi(x) = xlog(x)-x+1
def kb_conj(gamma,s,t,w,constraints):
constraints.append(w - gamma <= t)
constraints.append(cp.kl_div(gamma,w)+gamma+s-w<= 0)
return(constraints)
# In[3]:
####### the constraints sum^N_{i=1}p_iphi(q_i/p_i) <= r is written here (in cvxpy syntax) for several phi functions
def mod_chi2_cut(p,q,r,par,constraints):
N = p.shape[0]
phi_cons = 0
for i in range(N):
phi_cons = phi_cons + 1/p[i]*(q[i]-p[i])**2
constraints.append(phi_cons<=r)
return(constraints)
def kb_cut(p,q,r,par,constraints):
N = p.shape[0]
phi_cons = 0
for i in range(N):
phi_cons = phi_cons -cp.entr(q[i]) - q[i]*np.log(p[i])
constraints.append(phi_cons<=r)
return(constraints)
# In[6]:
###### functions that evaluates phi functions
def kb_eva(p,q):
N = len(p)
phi = 0
for i in range(N):
if q[i]<= 0:
phi = phi + 0
else:
phi = phi + q[i]*np.log(q[i]/p[i])
return(phi)
def mod_chi2_eva(p,q):
N = len(p)
phi = 0
for i in range(N):
if p[i]== 0:
return (np.inf)
phi = phi + (p[i]-q[i])**2/p[i]
return(phi)