KrisLibrary  1.0.0
lsqr.h
1 /*
2 * lsqr.h
3 * Contains auxiliary functions, data type definitions, and function
4 * prototypes for the iterative linear solver LSQR.
5 *
6 * 08 Sep 1999: First version from James W. Howse <jhowse@lanl.gov>
7 */
8 
9 /*
10 *------------------------------------------------------------------------------
11 *
12 * LSQR finds a solution x to the following problems:
13 *
14 * 1. Unsymmetric equations -- solve A*x = b
15 *
16 * 2. Linear least squares -- solve A*x = b
17 * in the least-squares sense
18 *
19 * 3. Damped least squares -- solve ( A )*x = ( b )
20 * ( damp*I ) ( 0 )
21 * in the least-squares sense
22 *
23 * where 'A' is a matrix with 'm' rows and 'n' columns, 'b' is an
24 * 'm'-vector, and 'damp' is a scalar. (All quantities are real.)
25 * The matrix 'A' is intended to be large and sparse.
26 *
27 *
28 * Notation
29 * --------
30 *
31 * The following quantities are used in discussing the subroutine
32 * parameters:
33 *
34 * 'Abar' = ( A ), 'bbar' = ( b )
35 * ( damp*I ) ( 0 )
36 *
37 * 'r' = b - A*x, 'rbar' = bbar - Abar*x
38 *
39 * 'rnorm' = sqrt( norm(r)**2 + damp**2 * norm(x)**2 )
40 * = norm( rbar )
41 *
42 * 'rel_prec' = the relative precision of floating-point arithmetic
43 * on the machine being used. For example, on the IBM 370,
44 * 'rel_prec' is about 1.0E-6 and 1.0D-16 in single and double
45 * precision respectively.
46 *
47 * LSQR minimizes the function 'rnorm' with respect to 'x'.
48 *
49 *------------------------------------------------------------------------------
50 */
51 
52 #include <KrisLibrary/Logger.h>
53 #include "stdio.h"
54 #include <KrisLibrary/math/VectorTemplate.h>
55 using namespace Math;
56 
57 /*
58 *------------------------------------------------------------------------------
59 *
60 * Input Quantities
61 * ----------------
62 *
63 * num_rows input The number of rows (e.g., 'm') in the matrix A.
64 *
65 * num_cols input The number of columns (e.g., 'n') in the matrix A.
66 *
67 * damp_val input The damping parameter for problem 3 above.
68 * ('damp_val' should be 0 for problems 1 and 2.)
69 * If the system A*x = b is incompatible, values
70 * of 'damp_val' in the range
71 * 0 to sqrt('rel_prec')*norm(A)
72 * will probably have a negligible effect.
73 * Larger values of 'damp_val' will tend to decrease
74 * the norm of x and reduce the number of
75 * iterations required by LSQR.
76 *
77 * The work per iteration and the storage needed
78 * by LSQR are the same for all values of 'damp_val'.
79 *
80 * rel_mat_err input An estimate of the relative error in the data
81 * defining the matrix 'A'. For example,
82 * if 'A' is accurate to about 6 digits, set
83 * rel_mat_err = 1.0e-6 .
84 *
85 * rel_rhs_err input An extimate of the relative error in the data
86 * defining the right hand side (rhs) vector 'b'. For
87 * example, if 'b' is accurate to about 6 digits, set
88 * rel_rhs_err = 1.0e-6 .
89 *
90 * cond_lim input An upper limit on cond('Abar'), the apparent
91 * condition number of the matrix 'Abar'.
92 * Iterations will be terminated if a computed
93 * estimate of cond('Abar') exceeds 'cond_lim'.
94 * This is intended to prevent certain small or
95 * zero singular values of 'A' or 'Abar' from
96 * coming into effect and causing unwanted growth
97 * in the computed solution.
98 *
99 * 'cond_lim' and 'damp_val' may be used separately or
100 * together to regularize ill-conditioned systems.
101 *
102 * Normally, 'cond_lim' should be in the range
103 * 1000 to 1/rel_prec.
104 * Suggested value:
105 * cond_lim = 1/(100*rel_prec) for compatible systems,
106 * cond_lim = 1/(10*sqrt(rel_prec)) for least squares.
107 *
108 * Note: If the user is not concerned about the parameters
109 * 'rel_mat_err', 'rel_rhs_err' and 'cond_lim', any or all of them
110 * may be set to zero. The effect will be the same as the values
111 * 'rel_prec', 'rel_prec' and 1/rel_prec respectively.
112 *
113 * max_iter input An upper limit on the number of iterations.
114 * Suggested value:
115 * max_iter = n/2 for well-conditioned systems
116 * with clustered singular values,
117 * max_iter = 4*n otherwise.
118 *
119 * lsqr_fp_out input Pointer to the file for sending printed output. If
120 * not NULL, a summary will be printed to the file that
121 * 'lsqr_fp_out' points to.
122 *
123 * rhs input The right hand side (rhs) vector 'b'. This vector
124 * has a length of 'm' (i.e., 'num_rows'). The routine
125 * LSQR is designed to over-write 'rhs'.
126 *
127 * sol input The initial guess for the solution vector 'x'. This
128 * vector has a length of 'n' (i.e., 'num_cols'). The
129 * routine LSQR is designed to over-write 'sol'.
130 *
131 *------------------------------------------------------------------------------
132 */
133 
135 {
136  long num_rows,num_cols;
137  double damp_val;
138  double rel_mat_err,rel_rhs_err;
139  double cond_lim;
140  long max_iter;
141  FILE *lsqr_fp_out;
142  dVector rhs;
143  dVector sol;
144 };
145 
146 /*
147 *------------------------------------------------------------------------------
148 *
149 * Output Quantities
150 * -----------------
151 *
152 * term_flag output An integer giving the reason for termination:
153 *
154 * 0 x = x0 is the exact solution.
155 * No iterations were performed.
156 *
157 * 1 The equations A*x = b are probably compatible.
158 * Norm(A*x - b) is sufficiently small, given the
159 * values of 'rel_mat_err' and 'rel_rhs_err'.
160 *
161 * 2 The system A*x = b is probably not
162 * compatible. A least-squares solution has
163 * been obtained that is sufficiently accurate,
164 * given the value of 'rel_mat_err'.
165 *
166 * 3 An estimate of cond('Abar') has exceeded
167 * 'cond_lim'. The system A*x = b appears to be
168 * ill-conditioned. Otherwise, there could be an
169 * error in subroutine APROD.
170 *
171 * 4 The equations A*x = b are probably
172 * compatible. Norm(A*x - b) is as small as
173 * seems reasonable on this machine.
174 *
175 * 5 The system A*x = b is probably not
176 * compatible. A least-squares solution has
177 * been obtained that is as accurate as seems
178 * reasonable on this machine.
179 *
180 * 6 Cond('Abar') seems to be so large that there is
181 * no point in doing further iterations,
182 * given the precision of this machine.
183 * There could be an error in subroutine APROD.
184 *
185 * 7 The iteration limit 'max_iter' was reached.
186 *
187 * num_iters output The number of iterations performed.
188 *
189 * frob_mat_norm output An estimate of the Frobenius norm of 'Abar'.
190 * This is the square-root of the sum of squares
191 * of the elements of 'Abar'.
192 * If 'damp_val' is small and if the columns of 'A'
193 * have all been scaled to have length 1.0,
194 * 'frob_mat_norm' should increase to roughly
195 * sqrt('n').
196 * A radically different value for 'frob_mat_norm'
197 * may indicate an error in subroutine APROD (there
198 * may be an inconsistency between modes 1 and 2).
199 *
200 * mat_cond_num output An estimate of cond('Abar'), the condition
201 * number of 'Abar'. A very high value of
202 * 'mat_cond_num'
203 * may again indicate an error in APROD.
204 *
205 * resid_norm output An estimate of the final value of norm('rbar'),
206 * the function being minimized (see notation
207 * above). This will be small if A*x = b has
208 * a solution.
209 *
210 * mat_resid_norm output An estimate of the final value of
211 * norm( Abar(transpose)*rbar ), the norm of
212 * the residual for the usual normal equations.
213 * This should be small in all cases.
214 * ('mat_resid_norm'
215 * will often be smaller than the true value
216 * computed from the output vector 'x'.)
217 *
218 * sol_norm output An estimate of the norm of the final
219 * solution vector 'x'.
220 *
221 * sol output The vector which returns the computed solution
222 * 'x'.
223 * This vector has a length of 'n' (i.e.,
224 * 'num_cols').
225 *
226 * std_err output The vector which returns the standard error
227 * estimates for the components of 'x'.
228 * This vector has a length of 'n'
229 * (i.e., 'num_cols'). For each i, std_err(i)
230 * is set to the value
231 * 'resid_norm' * sqrt( sigma(i,i) / T ),
232 * where sigma(i,i) is an estimate of the i-th
233 * diagonal of the inverse of Abar(transpose)*Abar
234 * and T = 1 if m <= n,
235 * T = m - n if m > n and damp_val = 0,
236 * T = m if damp_val != 0.
237 *
238 *------------------------------------------------------------------------------
239 */
240 
242 {
243  enum { X0Exact=0, ExactSolutionRelMat=1, LSSolutionRelMat=2,
244  IllConditioned=3,
245  ExactSolution=4, LSSolution=5,
246  ConditionError=6, MaxItersReached=7 };
247  long term_flag;
248  long num_iters;
249  double frob_mat_norm;
250  double mat_cond_num;
251  double resid_norm;
252  double mat_resid_norm;
253  double sol_norm;
254  dVector sol;
255  dVector std_err;
256 };
257 
258 /*
259 *------------------------------------------------------------------------------
260 *
261 * Workspace Quantities
262 * --------------------
263 *
264 * bidiag_wrk workspace This float vector is a workspace for the
265 * current iteration of the
266 * Lanczos bidiagonalization.
267 * This vector has length 'n' (i.e., 'num_cols').
268 *
269 * srch_dir workspace This float vector contains the search direction
270 * at the current iteration. This vector has a
271 * length of 'n' (i.e., 'num_cols').
272 *
273 *------------------------------------------------------------------------------
274 */
275 
276 struct lsqr_work
277 {
278  dVector bidiag_wrk;
279  dVector srch_dir;
280 };
281 
284 {
285 public:
286  /* compute y = y + A*x*/
287  virtual void MatrixVectorProduct (const dVector& x, dVector& y) =0;
288  /* compute x = x + At*y*/
289  virtual void MatrixTransposeVectorProduct (dVector& x, const dVector& y) =0;
290 };
291 
292 void lsqr( lsqr_input&, lsqr_output&, lsqr_work&, lsqr_func&);
293 
Definition: lsqr.h:276
Definition: lsqr.h:134
The logging system used in KrisLibrary.
Definition: lsqr.h:241
Contains all definitions in the Math package.
Definition: WorkspaceBound.h:12
Definition: lsqr.h:283