rbmatlab  1.16.09
 All Classes Namespaces Files Functions Variables Modules Pages
orthonormalize_gram_schmidt.m
1 function onvec = orthonormalize_gram_schmidt(vec,A,epsilon)
2 % function onvec = orthonormalize(vec[,A,epsilon])
3 %
4 % Gram-Schmidt orthonormalization of vectors in columns of
5 % matrix vec to onvec. Almost zero vectors are deleted.
6 % the inner product matrix A can be specified additionally, i.e.
7 % <x,x> = x' * A * x;
8 %
9 % note: a threshold epsilon is involved in this routine for detecting
10 % zero columns. This is a quite sensitive quantity! Change with care, as
11 % many functions build on this!! Default is 1e-7
12 
13 % Bernard Haasdonk 13.6.2002
14 
15 if nargin < 3
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 if nargin<2
29  A = 1;
30 end;
31 
32 % check on identity of vectors (can happen, that numerics does not detect
33 % this afterwards due to rounding errors!!)
34 
35 for i=1:(size(vec,2)-1)
36  for j=(i+1):size(vec,2)
37  if isequal(vec(:,i),vec(:,j))
38  vec(:,j) = 0;
39  end;
40  end;
41 end;
42 
43 onvec = vec;
44 
45 for i = 1:size(vec,2);
46  % orthogonalize next vector i and assume, that it is already
47  % orthogonal to previous ones
48  n = sqrt(onvec(:,i)' * A * onvec(:,i));
49  if (n<epsilon)
50  onvec(:,i) = 0;
51  else
52  onvec(:,i) = onvec(:,i)/n;
53  end;
54 
55  % orthogonalize remaining vectors wrt this one:
56 
57  A_mult_onvec_i = A*onvec(:,i);
58 
59  % create row-vector with projections on the created on-vector
60  coeffs= A_mult_onvec_i' * onvec(:,i+1:end);
61 
62  % create matrix of scaled versions of actual orthonormalized vector
63  coeffmat = onvec(:,i) * coeffs;
64 
65  % perform orthogonalization
66  onvec(:,i+1:end) = onvec(:,i+1:end) - coeffmat;
67 
68 end;
69 
70 %keyboard;
71 
72 % eliminate zero-columns
73 nsqr = sum(onvec.^2);
74 i = find(nsqr > 0.1);
75 onvec = onvec(:,i);
76 
77 
78 
79 %resort zero-columns to back
80 %nsqr = sum(onvec.^2);
81 %[s,i] = sort(-nsqr);
82 %onvec = onvec(:,i);
83 %| \docupdate