-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathlangevinnormalization.m
61 lines (51 loc) · 1.82 KB
/
langevinnormalization.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
function c = langevinnormalization(n, kappa, scaling)
% Normalization coefficients for the isotropic Langevin distribution on
% SO(n), with concentration parameters kappa >= 0.
%
% Returns a vector c of the same length as kappa such that for all k,
%
% c(k) = c_n(kappa(k)),
%
% where the function c_n is defined in the paper
%
% http://imaiai.oxfordjournals.org/content/early/2013/09/23/imaiai.iat006.abstract
% N. Boumal, A. Singer, P.-A. Absil and V. D. Blondel,
% Cramér-Rao bounds for synchronization of rotations,
% in Information and Inference, a journal of the IMA, 2013.
%
% In particular, c_n(0) = 1 for all n.
%
% If scaling is set to 1, the outputs are scaled down by exp(-n*kappa).
% By default, scaling is set to 0, which drastically limits the range of
% acceptable values of kappa, for numerical reasons. In most places, it is
% (way) preferable to activate scaling, as done in infoweight for example.
%
% This implementation is valid for n = 2, 3 or 4.
%
% Nicolas Boumal, UCLouvain, Aug. 17, 2011.
assert(numel(n) == 1);
if ~exist('scaling', 'var') || isempty(scaling)
scaling = 0;
end
scaling = double(scaling);
assert(scaling == 0 || scaling == 1);
switch n
case 2
c = besseli(0, 2*kappa, scaling);
case 3
I0 = besseli(0, 2*kappa, scaling);
I1 = besseli(1, 2*kappa, scaling);
if scaling
c = I0-I1;
else
c = exp(kappa).*(I0-I1);
end
case 4
I0 = besseli(0, 2*kappa, scaling);
I1 = besseli(1, 2*kappa, scaling);
I2 = besseli(2, 2*kappa, scaling);
c = I0.^2 - 2*I1.^2 + I0.*I2;
otherwise
error('Invalid value for n. Should be 2, 3 or 4.');
end
end