MCPcopy Create free account
hub / github.com/dblalock/bolt / eigenvalue_allocation

Function eigenvalue_allocation

experiments/python/product_quantize.py:101–162  ·  view source on GitHub ↗

Compute a permutation of eigenvalues to balance variance accross buckets of dimensions. Described in section 3.2.4 in http://research.microsoft.com/pubs/187499/cvpr13opq.pdf Note, the following slides indicate this function will break when fed eigenvalues < 1 without the scaling

(num_buckets, eigenvalues, shuffle=False)

Source from the content-addressed store, hash-verified

99#
100@_memory.cache
101def eigenvalue_allocation(num_buckets, eigenvalues, shuffle=False):
102 """
103 Compute a permutation of eigenvalues to balance variance accross buckets
104 of dimensions.
105 Described in section 3.2.4 in http://research.microsoft.com/pubs/187499/cvpr13opq.pdf
106 Note, the following slides indicate this function will break when fed eigenvalues < 1
107 without the scaling trick implemented below:
108 https://www.robots.ox.ac.uk/~vgg/rg/slides/ge__cvpr2013__optimizedpq.pdf
109 :param int num_buckets:
110 the number of dimension buckets over which to allocate eigenvalues
111 :param ndarray eigenvalues:
112 a vector of eigenvalues
113 :param bool shuffle:
114 whether to randomly shuffle the order of resulting buckets
115 :returns ndarray:
116 a vector of indices by which to permute the eigenvectors
117 """
118 D = len(eigenvalues)
119 dims_per_bucket = D / num_buckets
120 eigenvalue_product = np.zeros(num_buckets, dtype=float)
121 bucket_size = np.zeros(num_buckets, dtype=int)
122 permutation = np.zeros((num_buckets, dims_per_bucket), dtype=int)
123
124 # We first must scale the eigenvalues by dividing by their
125 # smallets non-zero value to avoid problems with the algorithm
126 # when eigenvalues are less than 1.
127 min_non_zero_eigenvalue = np.min(np.abs(eigenvalues[np.nonzero(eigenvalues)]))
128 eigenvalues = eigenvalues / min_non_zero_eigenvalue
129
130 # this is not actually a requirement, but I'm curious about whether this
131 # condition is ever violated
132 if not np.all(eigenvalues > 0):
133 print "WARNING: some eigenvalues were nonpositive"
134
135 # Iterate eigenvalues in descending order
136 sorted_inds = np.argsort(eigenvalues)[::-1]
137 log_eigs = np.log2(abs(eigenvalues))
138 for ind in sorted_inds:
139
140 # Find eligible (not full) buckets
141 eligible = (bucket_size < dims_per_bucket).nonzero()
142
143 # Find eligible bucket with least eigenvalue product
144 i = eigenvalue_product[eligible].argmin(0)
145 bucket = eligible[0][i]
146
147 # Update eigenvalue product for this bucket
148 eigenvalue_product[bucket] = eigenvalue_product[bucket] + log_eigs[ind]
149
150 # Store bucket assignment and update size
151 permutation[bucket, bucket_size[bucket]] = ind
152 bucket_size[bucket] += 1
153
154 if shuffle:
155 shuffle_idxs = np.arange(num_buckets, dtype=np.int)
156 np.random.shuffle(shuffle_idxs)
157 permutation = permutation[shuffle_idxs]
158

Callers 1

Calls 2

absFunction · 0.50
allMethod · 0.45

Tested by

no test coverage detected