rbmatlab  1.16.09
 All Classes Namespaces Files Functions Variables Modules Pages
model_orthonormalize_qr.m
1 function onvec = model_orthonormalize_qr(model, model_data, vec,epsilon)
2 % function onvec = model_orthonormalize_qr(model, model_data, vec[,epsilon])
3 %
4 % orthonormalization of vectors in columns of
5 % matrix X to Xon by qr-decomposition of vectors and
6 % the inner product matrix A can be specified additionally, i.e.
7 % <x,x> = x' * A * x. Then the Cholesky factoriziation of A is
8 % performed A = R_M' * R_M
9 %
10 % Then a QR-decomposition of R_M * X is performed which yields the
11 % desired new vectors
12 % additionally, a reordering is performed, such that the onb is at
13 % most matched with original vectors
14 
15 if nargin < 4
16  epsilon = 1e-7; % => for nonlinear evolution this value is required.
17 end;
18 %epsilon = 1e-10; => for linear evolution this value was OK.
19 %epsilon = 1e-12; -> This causes error by returning non-orthogonal
20 % vectors (e.g. two identical vectors)
21 % So take epsilon larger than 1e-12!
22 
23 if isempty(vec)
24  onvec = zeros(size(vec));
25  return;
26 end;
27 
28 A = model.get_inner_product_matrix(model_data);
29 
30 % incomplete cholesky of inner-product matrix:
31 if matlab_version> 7.9
32  opts.shape = 'upper';
33  opts.type = 'ict';
34  R_M = ichol(sparse(A), opts);
35 else
36  R_M = cholinc(sparse(A),'inf');
37 end;
38 
39 % qr decomposition of R_M * X with permutation indices E
40 % [Q,R,E] = QR(B,0) produces an "economy size" decomposition in which E
41 % is a permutation vector, so that B(:,E) = Q*R.
42 
43 [Q, R, E]= qr(R_M * vec,0 );
44 %[Q, R]= qr(R_M * vec,0 );
45 
46 %keyboard;
47 
48 % sort such that linear independent first and Q * R = R_M * Xon
49 vec2 = vec(:,E);
50 
51 % search nonvanishing diagonal entries of R
52 ind = find(abs(diag(R))>epsilon);
53 vec2 = vec2(:,ind);
54 Rind = R(ind,ind);
55 onvec = vec2(:,ind) / Rind;
56 
57 % eliminate zero-columns
58 %nsqr = sum(onvec.^2);
59 %i = find(nsqr > 0.1);
60 %onvec = onvec(:,i);
61 
62 %resort zero-columns to back
63 %nsqr = sum(onvec.^2);
64 %[s,i] = sort(-nsqr);
65 %onvec = onvec(:,i);
66 
67 % resort vectors such that original order is recovered most:
68 K = abs(vec'* A * onvec);
69 % search in each row maximum entry
70 ind = [];
71 for i = 1:size(vec,2)
72  [max_val, max_i] = max(K(i,:));
73  if length(max_i)>1
74  error('found multiple matching vectors!');
75  end;
76  if max_val > 0
77  ind = [ind, max_i];
78  end;
79  K(:,max_i) = 0; % "delete" from further search
80 end;
81 all_ind = ones(1,size(onvec,2));
82 all_ind(ind) = 0;
83 rest_ind = find(all_ind);
84 % resort:
85 if ~isempty(rest_ind)
86  onvec = [onvec(:,ind),onvec(:,rest_ind)];
87 else
88  onvec = onvec(:,ind);
89 end;
90 
91 %keyboard;
92 K = model.get_inner_product_matrix(model_data);
93 if max(max(abs(eye(size(onvec,2))-onvec'*K*onvec)))>1e-3
94  K
95  max(max(abs(eye(size(onvec,2))-onvec'*K*onvec)))
96  %error(['check orthonormalization!! Non orthogonal vectors' ...
97 % ' generated'])
98 end;