rbmatlab  1.16.09
 All Classes Namespaces Files Functions Variables Modules 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 if matlab_version> 7.9
43  opts.shape = 'upper';
44  opts.type = 'ict';
45  R_M = ichol(sparse(A), opts);
46 else
47  R_M = cholinc(sparse(A),'inf');
48 end;
49 
50 % qr decomposition of R_M * X with permutation indices E
51 [Q, R, E]= qr(R_M * Xon,0 );
52 
53 % sort such that linear independent first and Q * R = R_M * Xon
54 Xon = Xon(:,E);
55 
56 % search nonvanishing diagonal entries of R
57 ind = find(abs(diag(R))>epsilon);
58 Xon = Xon(:,ind);
59 Rind = R(ind,ind);
60 Xon = Xon(:,ind) / Rind;
61 
62 % resort vectors such that original order is recovered most:
63 K = abs(X'* A * Xon);
64 % search in each row maximum entry
65 ind = [];
66 for i = 1:size(Xon,2)
67  [max_val, max_i] = max(K(i,:));
68  if length(max_i)>1
69  error('found multiple matching vectors!');
70  end;
71  if max_val > 0
72  ind = [ind, max_i];
73  end;
74  K(:,max_i) = 0; % "delete" from further search
75 end;
76 all_ind = ones(1,size(Xon,2));
77 all_ind(ind) = 0;
78 rest_ind = find(all_ind);
79 % resort:
80 if ~isempty(rest_ind)
81  Xon = [Xon(:,ind),Xon(:,rest_ind)];
82 else
83  Xon = Xon(:,ind);
84 end;
85 
86 %disp('check orthonormality!!');
87 %keyboard;
88 %K = Xon'*A*Xon;
89 %if max(max(abs(eye(size(Xon,2))-K)))>1e-3
90 % K
91 % error(['check orthonormalization!! Non orthogonal vectors' ...%
92 % ' generated']
93 %end;
94 
95 % eliminate zero-columns
96 %nsqr = sum(Xon.^2);
97 %i = find(nsqr > 0.1);
98 %Xon = Xon(:,i);
99 
100 %resort zero-columns to back
101 %nsqr = sum(Xon.^2);
102 %[s,i] = sort(-nsqr);
103 %Xon = Xon(:,i);
104 %| \docupdate