-
Notifications
You must be signed in to change notification settings - Fork 4
/
generate_hash_codes2.m
118 lines (94 loc) · 3.26 KB
/
generate_hash_codes2.m
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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
function [A,B,f] = generate_hash_codes2(S,m,n,q,percent)
%***************************************************************
%**** THIS IS A MUCH FASTER IMPLEMENTATION OF MY ALGORITHM USING THE
% COORDINATED DESCENT SEARCH METHOD WITH NEWTON UPDATES****
% THIS METHOD USES TABLE LOOKUPS TO SIGNIFICANTLY IMPROVE THE COMPUTATIONAL
% EFFICIENCY. IN ADDITION THERE IS A CHOICE TO SELECT HOW MANY BITS I WANT
% TO UPDATE IN A PARTICULAR LOOP BASED ON THE PARAMETER 'percent'
%***************************************************************
% Now to find A and B - how to do it ?
% Randomly initialize the matrices A and B
% I used the closed form for the solutions to a_il and bjl to get the new
% value of the coefficients. Note that this does not use the newton's
% update step.
a = -1; b = 1;
A = (b-a)*rand(m,q) + a;
A = sign(A);
B = (b-a)*rand(n,q) + a;
B = sign(B);
niter = 100;
tolerance = 1e-6;
for t=1:niter
if t==1
f_prev = 1e100;
else
f_prev = f(t-1);
end
% Fix B and update A
% Do for all rows of A
R1 = [];
H_a = zeros(q,1);
for l=1:q
for j=1:n
H_a(l) = H_a(l) + B(j,l).^2;
end
end
% Randomly Select 10% of the data to update
xx = randperm(m); xxx = round(percent*m);
m_new = xx(1:xxx);
for z=1:xxx
i = m_new(z);
% create the initial lookup table
for j=1:n; R1(j) = (A(i,:)*B(j,:).' - q*S(i,j)); end
for l=1:q
% gradient of a_il
% hessian of a_il
g_a_il = 0;
for j=1:n; g_a_il = g_a_il + R1(j)*B(j,l); end
% distance to move = d
temp = A(i,l);
d = max(-1-A(i,l),min(-(g_a_il/H_a(l)),1-A(i,l)));
A(i,l) = A(i,l) +d;
% update R1 lookup table
for j=1:n; R1(j) = R1(j) - temp*B(j,l) + A(i,l)*B(j,l); end
end
end
% Fix A and update B
% Do for all rows of B
R2 = [];
H_b = zeros(q,1);
for l=1:q
for i=1:m
H_b(l) = H_b(l) + A(i,l).^2;
end
end
% Randomly Select 10% of the data to update
xx = randperm(n); xxx = round(percent*n);
n_new = xx(1:xxx);
for z=1:xxx
j = n_new(z);
% create the initial lookup table
for i=1:m; R2(i) = (A(i,:)*B(j,:).' - q*S(i,j)); end
for l=1:q
% gradient of b_jl
% hessian of b_jl
g_b_jl = 0;
for i=1:m; g_b_jl = g_b_jl + R2(i)*A(i,l); end
% distance to move = d
temp = B(j,l);
d = max(-1-B(j,l),min(-(g_b_jl/H_b(l)),1-B(j,l)));
B(j,l) = B(j,l) +d;
% update R2 lookup table
for i=1:m; R2(i) = R2(i) - A(i,l)*temp + A(i,l)*B(j,l); end
end
end
% Compute the function value
f(t) = norm(q*S-A*B.','fro');
if (f_prev-f(t))/f_prev <= tolerance
break;
end
if mod(t,10)==0
fprintf('The iteration is : %i and f val is : %f \n', t, f(t));
end
end
A = sign(A); B = sign(B);