source: proiecte/pmake3d/make3d_original/Make3dSingleImageStanford_version0.1/third_party/zisserman/vgg_numerics/vgg_solvelin_blksym.m @ 37

Last change on this file since 37 was 37, checked in by (none), 14 years ago

Added original make3d

  • Property svn:executable set to *
File size: 1.7 KB
Line 
1%VGG_SOLVELIN_BLKSYM  Solves M*x==y where M is (typically huge sparse) symmetric 4-block matrix.
2%   It solves the system much more efficiently than a general (sparse) linear system solver.
3%   Typical usage to solve normal equations in Levenberg-Marquardt in bundle adjustment.
4%
5%   X = VGG_SOLVELIN_BLKSYM(A,B,C,p,q [,'nocheck']) solves M*x==Y where
6%   M=[A B; B' C] and y=[p;q].
7%
8%   X = VGG_SOLVELIN_BLKSYM(M,y,sideA [,'nocheck']) does the same but takes M and splits it,
9%   M=[A B; B' C] and size(A)==[sideA sideA].
10%
11%   The function checks whether C is really near to diagonal; if not, a warning is printed.
12%   Parmeter 'nocheck' switches off this test.
13
14% (c) {awf,werner}@robots.ox.ac.uk, March 2002
15
16
17function x = vgg_solvelin_blksym(varargin)
18
19switch nargin
20 case 6
21  [A,B,C,p,q,check] = deal(varargin{:});
22 case 5
23  [A,B,C,p,q] = deal(varargin{:});
24  check = '';
25 case 4
26  [M,y,sideA,check] = deal(varargin{:});
27 case 3
28  [M,y,sideA] = deal(varargin{:});
29  check = '';
30 otherwise
31  error('Bad number of parameters');
32end
33
34if nargin<5
35  Rtop = 1:sideA;
36  Rbot = sideA+1:size(M,1);
37  C = M(Rbot, Rbot);
38  B = M(Rtop, Rbot);
39  A = M(Rtop, Rtop);
40  p = y(Rtop);
41  q = y(Rbot);
42end
43
44if ~strcmp(check,'nocheck') & nnz(C(1,:))/size(C,1) > .1
45  warning('It is likely that M was splitted incorrectly. Check diagonality of C and/or value of sideA.');
46end
47
48%tic
49
50% Surprisingly, branch 1 is 2x slower than branch 2. We don't know why.
51switch 2
52 case 1
53  invC_Btq = C \ [B' q];
54 case 2
55  invC_Btq = inv(C) * [B' q];
56end
57
58invC_Bt = invC_Btq(:,1:end-1);
59invC_q = invC_Btq(:,end);
60     
61u = (A - B * invC_Bt) \ (p - B * invC_q);
62v = invC_q - invC_Bt*u;
63
64x = [u;v];
65
66%toc
67
68return
Note: See TracBrowser for help on using the repository browser.