rbmatlab  1.13.10
 All Classes Namespaces Files Functions Variables Groups Pages
orthonormalize_qr.m
1 function Xon = orthonormalize_qr(X,A,epsilon)
2 % function Xon = orthonormalize_qr(X[,A,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 
13 % Bernard Haasdonk 22.8.2008
14 
15 if nargin < 3
16  epsilon = 1e-7; % => for nonlinear evolution this value is required.
17 end;
18 
19 if isempty(X)
20  Xon = zeros(size(X));
21  return;
22 end;
23 
24 if nargin<2
25  A = 1;
26 end;
27 
28 % check on identity of vectors (can happen, that numerics does not detect
29 % this afterwards due to rounding errors!!)
30 
31 for i=1:(size(X,2)-1)
32  for j=(i+1):size(X,2)
33  if isequal(X(:,i),X(:,j))
34  X(:,j) = 0;
35  end;
36  end;
37 end;
38 
39 Xon = X;
40 
41 % incomplete cholesky of inner-product matrix:
42 opts.shape = 'upper';
43 opts.type = 'ict';
44 R_M = ichol(sparse(A), opts);
45 
46 % qr decomposition of R_M * X with permutation indices E
47 [Q, R, E]= qr(R_M * Xon,0 );
48 
49 % sort such that linear independent first and Q * R = R_M * Xon
50 Xon = Xon(:,E);
51 
52 % search nonvanishing diagonal entries of R
53 ind = find(abs(diag(R))>epsilon);
54 Xon = Xon(:,ind);
55 Rind = R(ind,ind);
56 Xon = Xon(:,ind) / Rind;
57 
58 % resort vectors such that original order is recovered most:
59 K = abs(X'* A * Xon);
60 % search in each row maximum entry
61 ind = [];
62 for i = 1:size(Xon,2)
63  [max_val, max_i] = max(K(i,:));
64  if length(max_i)>1
65  error('found multiple matching vectors!');
66  end;
67  if max_val > 0
68  ind = [ind, max_i];
69  end;
70  K(:,max_i) = 0; % "delete" from further search
71 end;
72 all_ind = ones(1,size(Xon,2));
73 all_ind(ind) = 0;
74 rest_ind = find(all_ind);
75 % resort:
76 if ~isempty(rest_ind)
77  Xon = [Xon(:,ind),Xon(:,rest_ind)];
78 else
79  Xon = Xon(:,ind);
80 end;
81 
82 %disp('check orthonormality!!');
83 %keyboard;
84 %K = Xon'*A*Xon;
85 %if max(max(abs(eye(size(Xon,2))-K)))>1e-3
86 % K
87 % error(['check orthonormalization!! Non orthogonal vectors' ...%
88 % ' generated']
89 %end;
90 
91 % eliminate zero-columns
92 %nsqr = sum(Xon.^2);
93 %i = find(nsqr > 0.1);
94 %Xon = Xon(:,i);
95 
96 %resort zero-columns to back
97 %nsqr = sum(Xon.^2);
98 %[s,i] = sort(-nsqr);
99 %Xon = Xon(:,i);
100 %| \docupdate