Skip to content

Commit 43504c4

Browse files
committed
Implemented A_optimize for relative-only measurements.
1 parent dec0a38 commit 43504c4

File tree

2 files changed

+53
-17
lines changed

2 files changed

+53
-17
lines changed

A_opt.py

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -659,20 +659,25 @@ def G( x, y, alpha=1., beta=0., trans='N'):
659659
# h vector.
660660
h = matrix( 0., (K*(K+1)/2 + K*(K+1)*(K+1), 1))
661661
# F := Fisher matrix
662-
if nsofar is not None or di2 is not None:
663-
if nsofar is None:
664-
F = matrix( 0., (K, K))
665-
F[::K+1] = di2
666-
else:
667-
F = Fisher_matrix( si2, nsofar, di2)
662+
if nsofar is None:
663+
F = matrix( 0., (K, K))
668664
else:
669-
F = None
665+
F = Fisher_matrix( si2, nsofar, di2)
666+
if di2 is not None: F[::K+1] = di2
667+
elif np.all( np.diag( si2) == 0):
668+
# If the diagonal elements of 1/s[i,i]^2 are all zero, the Fisher
669+
# information matrix is singular, and the quantities are determined
670+
# up to a constant. In this case, we constrain the
671+
# mean of the quantities. This corresponds to adding a constant
672+
# omega to the Fisher matrix. The optimal allocation does not
673+
# depend on the value of omega.
674+
omega = 1.
675+
F += omega
670676

671677
row = K*(K+1)/2
672678
for i in xrange(K):
673-
if F is not None:
674-
for j in xrange(K):
675-
h[row + j*(K+1) : row + (j+1)*(K+1)-1] = F[:,j]
679+
for j in xrange(K):
680+
h[row + j*(K+1) : row + (j+1)*(K+1)-1] = F[:,j]
676681
h[row + (i+1)*(K+1)-1] = 1. # e_i^t
677682
h[row + K*(K+1) + i] = 1. # e_i
678683
row += (K+1)*(K+1)
@@ -1151,12 +1156,22 @@ def test_sumdR2( ntrials=10, tol=1e-9):
11511156
print 'Timing for aligned sum dR: %f seconds per call.' % (tfast/ntrials)
11521157
return success
11531158

1159+
def test_relative_only():
1160+
K = 5
1161+
np.random.seed( 1)
1162+
sij = matrix( np.random.rand( K*K), (K,K))
1163+
sij = 0.5*(sij + sij.T)
1164+
for i in range(K): sij[i,i] = np.inf
1165+
nij = A_optimize_fast( sij)
1166+
print nij
1167+
11541168
def unit_test():
11551169
test_Gfunc( ntrials=100)
11561170
test_kkt_solver( ntrials=100)
11571171
test_sumdR2()
11581172

11591173
if __name__ == '__main__':
1174+
test_relative_only()
11601175
K = 200
11611176
sij = matrix( np.random.rand( K*K), (K, K))
11621177
nsofar = matrix( 0.2*np.random.rand( K*K), (K, K))

test_diffnet.py

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,16 @@ def check_optimality( sij, nij, optimality='A', delta=1E-1, ntimes=10):
1111
'''
1212
K = sij.size[0]
1313
C = covariance( cvxopt.div( nij, sij**2))
14-
fC = dict(
15-
A = np.trace( C),
16-
D = np.log( linalg.det( C)),
17-
E = np.max( linalg.eig( C)[0]).real,
18-
Etree = np.max( linalg.eig( C)[0]).real
19-
)
14+
fC = dict()
15+
if optimality=='A':
16+
fC['A'] = np.trace( C)
17+
if optimality=='D':
18+
fC['D'] = np.log( linalg.det( C))
19+
if optimality=='E':
20+
fC['E'] = np.max( linalg.eig( C)[0]).real
21+
if optimality=='Etree':
22+
fC['Etree'] = np.max( linalg.eig( C)[0]).real
23+
2024
df = np.zeros( ntimes)
2125
for t in xrange( ntimes):
2226
zeta = matrix( 1. + 2*delta*(np.random.rand( K, K) - 0.5))
@@ -149,6 +153,20 @@ def check_sparse_A_optimal( sij, ntimes=10, delta=1e-1, tol=1e-5):
149153

150154
return success and success2
151155

156+
def check_relative_only_A_optimal( sij):
157+
'''
158+
'''
159+
sij = matrix(sij)
160+
K = sij.size[0]
161+
for i in range(K): sij[i,i] = np.inf
162+
nij = A_optimize( sij)
163+
success = check_optimality( sij, nij)
164+
if (not success):
165+
print 'FAIL: A_optimize for relative-only measurements did not generate optimal.'
166+
else:
167+
print 'SUCCESS: A_optimize for relative-only measurements.'
168+
return success
169+
152170
def check_hessian( dF, d2F, x0):
153171
'''
154172
Check the Hessian for correctness.
@@ -268,7 +286,6 @@ def unitTest( tol=1.e-4):
268286
[ 0.1, 1., 0.1 ],
269287
[ 0.1, 0.1, 1.2 ]])
270288

271-
272289
from scipy.optimize import check_grad
273290

274291
def F( x):
@@ -336,6 +353,10 @@ def d2F( x):
336353
if (check_sparse_A_optimal( sij)):
337354
print 'Sparse A-optimal passed!'
338355

356+
# Check A-optimal when only relative measurements are included.
357+
if (check_relative_only_A_optimal( sij)):
358+
print 'Relative-only A-optimal passed!'
359+
339360
# Test covariance computation
340361
if (test_covariance(5, T=4000)):
341362
print 'Covariance computation passed!'

0 commit comments

Comments
 (0)