frcs-colour-transfer
/
generate_rotations.m
132 строки · 2.9 Кб
1% rotations = find_all(ndim, NbRotations)
2%
3% ndim = 2 or 3 (but the code can be changed)
4%
5%
6% code for generating an optimised sequence of rotations
7% for the IDT pdf transfer algorithm
8% although the code is not beautiful, it does the job.
9%
10function rotations = generate_rotations(ndim, NbRotations)
11
12if (ndim == 2)
13l = [0 pi/2];
14elseif (ndim == 3)
15l = [0 0 pi/2 0 pi/2 pi/2];
16else % put here initialisation for higher orders
17end
18
19fprintf('rotation ');
20for i = 1:(NbRotations-1)
21fprintf('%d ...', i );
22l = [l ; find_next(l, ndim)]; %l(end,:)+ones(1,ndim-1)*pi/2)]
23fprintf('\b\b\b', i );
24end
25
26M = ndim;
27
28rotations = cell(1,NbRotations);
29for i=1:size(l, 1)
30for j=1:M
31b_prev(j,:) = hyperspherical2cartesianT(l(i,(1:ndim-1) + (j-1)*(ndim-1)));
32end
33b_prev = grams(b_prev')';
34rotations{i} = b_prev;
35end
36
37
38end
39%
40%
41function [x] = find_next( list_prev_x, ndim)
42
43prevx = list_prev_x; % in hyperspherical coordinates
44nprevx = size(prevx,1);
45hdim = ndim - 1;
46M = ndim;
47
48% convert points to cartesian coordinates
49c_prevx = zeros(nprevx*M, ndim);
50c_prevx = [];
51for i=1:nprevx
52for j=1:M
53b_prev(j,:) = hyperspherical2cartesianT(prevx(i,(1:hdim) + (j-1)*hdim));
54end
55b_prev = grams(b_prev')';
56c_prevx = [c_prevx; b_prev];
57end
58
59c_prevx;
60
61options = optimset('TolX', 1e-10);
62options = optimset(options,'Display','off');
63
64minf = inf;
65for i=1:10
66x0 = rand(1, hdim*M)*pi - pi/2;
67x = fminsearch(@myfun, x0, options);
68f = myfun(x);
69if f < minf
70minf = f;
71mix = x;
72end
73end
74
75%%
76% f - Compute the function value at x
77function [f] = myfun(x)
78% compute the objective function
79c_x = zeros(M, ndim);
80for i=1:M
81c_x(i, :) = hyperspherical2cartesianT(x((1:hdim) + (i-1)*hdim));
82end
83c_x = grams(c_x')';
84f = 0;
85for i=1:M
86for p=1:size(c_prevx, 1)
87d = (c_prevx(p,:) - c_x(i, :)) * (c_prevx(p,:) - c_x(i, :))';
88f = f + 1/(1 + d);
89d = (c_prevx(p,:) + c_x(i, :)) * (c_prevx(p,:) + c_x(i, :))';
90f = f + 1/(1 + d);
91end
92end
93end
94%%
95
96end
97
98
99%
100%
101function c = hyperspherical2cartesianT(x)
102
103c = zeros(1, length(x)+1);
104sk = 1;
105for k=1:length(x)
106c(k) = sk*cos(x(k));
107sk = sk*sin(x(k));
108end
109c(end) = sk;
110
111end
112
113% Gram-Schmidt orthogonalization of the columns of A.
114% The columns of A are assumed to be linearly independent.
115function [Q, R] = grams(A)
116
117[m, n] = size(A);
118Asave = A;
119for j = 1:n
120for k = 1:j-1
121mult = (A(:, j)'*A(:, k)) / (A(:, k)'*A(:, k));
122A(:, j) = A(:, j) - mult*A(:, k);
123end
124end
125for j = 1:n
126if norm(A(:, j)) < sqrt(eps)
127error('Columns of A are linearly dependent.')
128end
129Q(:, j) = A(:, j) / norm(A(:, j));
130end
131R = Q'*Asave;
132end
133
134