casacore
Loading...
Searching...
No Matches
LSQFit.h
Go to the documentation of this file.
1// # LSQFit.h: Basic class for least squares fitting
2// # Copyright (C) 1999-2001,2004-2008
3// # Associated Universities, Inc. Washington DC, USA.
4// #
5// # This library is free software; you can redistribute it and/or modify it
6// # under the terms of the GNU Library General Public License as published by
7// # the Free Software Foundation; either version 2 of the License, or (at your
8// # option) any later version.
9// #
10// # This library is distributed in the hope that it will be useful, but WITHOUT
11// # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12// # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
13// # License for more details.
14// #
15// # You should have received a copy of the GNU Library General Public License
16// # along with this library; if not, write to the Free Software Foundation,
17// # Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
18// #
19// # Correspondence concerning AIPS++ should be addressed as follows:
20// # Internet email: casa-feedback@nrao.edu.
21// # Postal address: AIPS++ Project Office
22// # National Radio Astronomy Observatory
23// # 520 Edgemont Road
24// # Charlottesville, VA 22903-2475 USA
25
26#ifndef SCIMATH_LSQFIT_H
27#define SCIMATH_LSQFIT_H
28
29// # Includes
30#include <casacore/casa/aips.h>
31#include <casacore/casa/Utilities/RecordTransformable.h>
32#include <casacore/scimath/Fitting/LSQMatrix.h>
33#include <casacore/scimath/Fitting/LSQTraits.h>
34#include <complex>
35#include <string>
36#include <utility>
37#include <vector>
38
39namespace casacore { // # NAMESPACE CASACORE - BEGIN
40
41// # Forward Declarations
42
43// <summary> Basic class for the least squares fitting </summary>
44// <reviewed reviewer="Neil Killeen" date="2000/06/01" tests="tLSQFit"
45// demos="">
46// </reviewed>
47
48// <prerequisite>
49// <li> Some knowledge of Matrix operations
50// <li> The background information provided in
51// <a href="../notes/224.html">Note 224</a>.
52// <li> <linkto module="Fitting">Fitting module</linkto>
53// </prerequisite>
54//
55// <etymology>
56// From Least SQuares and Fitting
57// </etymology>
58//
59// <synopsis>
60// The LSQFit class contains the basic functions to do all the fitting
61// described in the
62// <a href="../notes/224.html">Note</a>
63// about fitting.
64// It handles real, and complex equations;<br>
65// linear and non-linear (Levenberg-Marquardt) solutions;<br>
66// regular (with optional constraints) or Singular Value Decomposition
67// (<src>SVD</src>).<br>
68// In essence they are a set of routines to generate normal equations
69// (<src>makeNorm()</src>) in triangular form from a set of condition
70// equations;<br>
71// to do a Cholesky-type decomposition of the normal
72// equations (either regular or <src>SVD</src>) and test its rank
73// (<src>invert()</src>);<br>
74// to do a quasi inversion of the decomposed equations (<src>solve()</src>) to
75// obtain the solution and/or the errors.
76//
77// All calculations are done in place.
78// Methods to obtain additional information about the fitting process are
79// available.
80//
81// This class can be used as a stand-alone class outside of the Casacore
82// environment. In that case the aips.h include file
83// can be replaced if necessary by appropriate typedefs for Double, Float and
84// uInt.<br>
85// The interface to the methods have standard data or standard STL iterator
86// arguments only. They can be used with any container having an STL
87// random-access iterator interface. Especially they can be used with
88// <src>carrays</src> (necessary templates provided),
89// Casacore Vectors (necessary templates
90// provided in <src>LSQaips</src>),
91// standard random access STL containers (like <src>std::vector</src>).
92//
93// The normal operation of the class consists of the following steps:
94// <ul>
95// <li> Create an LSQFit object.
96// The information that can be provided in the constructor of the object,
97// either directly, or indirectly using the <src>set()</src> commands, is
98// (see <a href="../notes/224.html">Note 224</a>):
99// <ul>
100// <li> The number of unknowns that have to be solved for (mandatory)
101// <li> The number of constraint equations you want to use explicitly
102// (defaults to 0, but can be changed on-the-fly)
103// </ul>
104// Separately settable are:
105// <ul>
106// <li> A collinearity test factor (defaults to 1e-8)
107// <note role=warning>
108// The collinearity factor is the square of the sine of the angle between
109// a column in the normal equations, and the hyper-plane through
110// all the other columns. In special cases (e.g. fitting a polynomial
111// in a very narrow bandwidth window, it could be advisable to set this
112// factor to zero if you want a solution (whatever the truth of it maybe).
113// </note>
114// <li> A Levenberg-Marquardt adjustment factor (if appropriate,
115// defaults to 1e-3)
116// </ul>
117//
118// <li>Create the normal equations used in solving the set of condition
119// equations of the user, by using the <src>makeNorm()</src> methods.
120// Separate <src>makenorm()</src> methods are provided for sparse condition
121// equations (e.g. if data for 3 antennas are provided, rather than for all 64)
122//
123// <li>If there are user provided constraints, either limiting constraints like
124// the sum of the angles in a triangle is 180 degrees, or constraints to add
125// missing information if e.g. only differences between parameters have been
126// measured, they can be added to the normal
127// equations with the <src>setConstraint()</src> or
128// the <src>addConstraint()</src> methods. Lagrange multipliers will be used to
129// solve the extended normal equations.
130//
131// <li>The normal equations are triangu;arised (using the collinearity factor
132// as a check for solvability) with the <src>invert()</src> method. If the
133// normal equations are non-solvable an error is returned, or a switch to
134// an SVD solution is made if indicated in the <src>invert</src> call.
135//
136// <li>The solutions and adjustment errors are obtained with the
137// <src>solve()</src> method.
138// A non-linear loop in a Levenberg-Marquardt adjustment can be obtained
139// (together with convergence information), with the <src>solveLoop()</src>
140// method (see below) replacing the combination of
141// <src>invert</src> and <src>solve</src>.
142//
143// <li>Non-linear loops are done by looping through the data using
144// <src>makeNorm()</src> calls, and upgrade the solution with the
145// <src>solveLoop()</src> method.
146// The normal equations are upgraded by changing LM factors. Upgrade depends
147// on the 'balanced' factor. The LM factor is either added in some way to all
148// diagonal elements (if balanced) or all diagonal elements are multiplied by
149// <src>(1+factor)</src> After each loop convergence can be tested
150// by the <src>isReady()</src> call; which will return <src>False</src> or
151// a non-zero code indicating the ready reason. Reasons for stopping can be:
152// <ul>
153// <li> SOLINCREMENT: the relative change in the norm of the parameter
154// solutions is less than
155// (a settable, <src>setEpsValue()</src>, default 1e-8) value.
156// <li> DERIVLEVEL: the inf-norm of the known vector of the equations to be
157// solved is less than the settable, <src>setEpsDerivative()</src>, default
158// 1e-8, value.
159// <li> MAXITER: maximum number of iterations reached (only possible if a
160// number is explicitly set)
161// <li> NOREDUCTION: if the Levenberg-Marquardt correction factor goes towards
162// infinity. I.e. if no Chi2 improvement seems possible. Have to redo the
163// solution with a different start condition for the unknowns.
164// <li> SINGULAR: can only happen due to numeric rounding, since the LM
165// equations are always positive-definite. Best solution is to indicate SVD
166// needed in the <src>solveLoop</src> call, which is cost-free
167// </ul>
168//
169// <li>Covariance information in various forms can be obtained with the
170// <src>getCovariance(), getErrors()</src>, <src>getChi()</src>
171// (or <src>getChi2</src>), <src>getSD</src> and <src>getWeightedSD</src>
172// methods after a <src>solve()</src> or after the final loop in a non-linear
173// solution (of course, when necessary only).
174// </ul>
175//
176// An LSQFit object can be re-used by issuing the <src>reset()</src> command,
177// or <src>set()</src> of new
178// values. If an unknown has not been used in the condition equations at all,
179// the <src>doDiagonal()</src> will make sure a proper solution is obtained,
180// with missing unknowns zeroed.
181//
182// Most of the calculations are done in place; however, enough data is saved
183// that it is possible to continue
184// with the same (partial) normal equations after e.g. an interim solution.
185//
186// If the normal equations are produced in separate partial sets (e.g.
187// in a multi-processor environment) a <src>merge()</src> method can combine
188// them.
189// <note role=tip>
190// It is suggested to add any possible constraint equations after the merge.
191// </note>
192//
193// A <src>debugIt()</src> method provides read access to all internal
194// information.
195//
196// The member definitions are split over three files. The second
197// one contains the templated member function definitions, to bypass the
198// problem of duplicate definitions of non-templated members when
199// pre-compiling them. The third contains methods for saving objects as
200// Records or through AipsIO.
201//
202// <note role=warning> No boundary checks on input and output containers
203// is done for faster execution. In general these tests should be done at
204// the higher level routines, like the
205// <linkto class=LinearFit>LinearFit</linkto> and
206// <linkto class=NonLinearFitLM>NonLinearFit</linkto> classes which should be
207// checked for usage of LSQFit.
208// </note>
209//
210// The contents can be saved in a record (<src>toRecord</src>),
211// and an object can be created from a record (<src>fromRecord</src>).
212// The record identifier is 'lfit'.
213// <br>The object can also be saved or restored using AipsIO.
214// </synopsis>
215//
216// <example>
217// See the tLSQFit.cc and tLSQaips.cc program for extensive examples.
218//
219// The following example will first create 2 condition equations for
220// 3 unknowns (the third is degenerate). It will first create normal equations
221// for a 2 unknown solution and solve; then it will create normal equations
222// for a 3 unknown solution, and solve (note that the degenerate will be
223// set to 0. The last one will use SVD and one condition equation.r
224// <srcblock>
225// #include <casacore/casa/aips.h>
226// #include <casacore/scimath/Fitting/LSQFit.h>
227// #include <iostream>
228//
229// int main() {
230// // Condition equations for x+y=2; x-y=4;
231// Double ce[2][3] = {{1, 1, 0}, {1, -1, 0}};
232// Double m[2] = {2, 4};
233// // Solution and error area
234// Double sol[3];
235// Double sd, mu;
236// uInt rank;
237// Bool ok;
238//
239// // LSQ object
240// LSQFit fit(2);
241//
242// // Make normal equation
243// for (uInt i=0; i<2; i++) fit.makeNorm(ce[i], 1.0, m[i]);
244// // Invert(decompose) and show
245// ok = fit.invert(rank);
246// cout << "ok? " << ok << "; rank: " << rank << endl;
247// // Solve and show
248// if (ok) {
249// fit.solve(sol, &sd, &mu);
250// for (uInt i=0; i<2; i++) cout << "Sol" << i << ": " << sol[i] << endl;
251// cout << "sd: "<< sd << "; mu: " << mu << endl;
252// };
253// cout << "----------" << endl;
254//
255// // Retry with 3 unknowns: note auto fill of unmentioned one
256// fit.set(uInt(3));
257// for (uInt i=0; i<2; i++) fit.makeNorm(ce[i], 1.0, m[i]);
258// ok = fit.invert(rank);
259// cout << "ok? " << ok << "; rank: " << rank << endl;
260// if (ok) {
261// fit.solve(sol, &sd, &mu);
262// for (uInt i=0; i<3; i++) cout << "Sol" << i << ": " << sol[i] << endl;
263// cout << "sd: "<< sd << "; mu: " << mu << endl;
264// };
265// cout << "----------" << endl;
266//
267// // Retry with 3 unknowns; but 1 condition equation and use SVD
268// fit.reset();
269// for (uInt i=0; i<1; i++) fit.makeNorm(ce[i], 1.0, m[i]);
270// ok = fit.invert(rank, True);
271// cout << "ok? " << ok << "; rank: " << rank << endl;
272// if (ok) {
273// fit.solve(sol, &sd, &mu);
274// for (uInt i=0; i<3; i++) cout << "Sol" << i << ": " << sol[i] << endl;
275// cout << "sd: "<< sd << "; mu: " << mu << endl;
276// };
277// cout << "----------" << endl;
278//
279// // Without SVD it would be:
280// fit.reset();
281// for (uInt i=0; i<1; i++) fit.makeNorm(ce[i], 1.0, m[i]);
282// ok = fit.invert(rank);
283// cout << "ok? " << ok << "; rank: " << rank << endl;
284// if (ok) {
285// fit.solve(sol, &sd, &mu);
286// for (uInt i=0; i<3; i++) cout << "Sol" << i << ": " << sol[i] << endl;
287// cout << "sd: "<< sd << "; mu: " << mu << endl;
288// };
289// cout << "----------" << endl;
290//
291// exit(0);
292// }
293// </srcblock>
294// Which will produce the output:
295// <srcblock>
296// ok? 1; rank: 2
297// Sol0: 3
298// Sol1: -1
299// sd: 0; mu: 0
300// ----------
301// ok? 1; rank: 3
302// Sol0: 3
303// Sol1: -1
304// Sol2: 0
305// sd: 0; mu: 0
306// ----------
307// ok? 1; rank: 2
308// Sol0: 1
309// Sol1: 1
310// Sol2: 0
311// sd: 0; mu: 0
312// ----------
313// ok? 0; rank: 2
314// ----------
315// </srcblock>
316// </example>
317//
318// <motivation>
319// The class was written to be able to do complex, real standard and SVD
320// solutions in a simple and fast way.
321// </motivation>
322//
323// <todo asof="2006/04/02">
324// <li> a thorough check if all loops are optimal in the makeNorm() methods
325// <li> input of condition equations with cross covariance
326// </todo>
327
328class LSQFit {
329 public:
330 // Simple classes to overload templated memberfunctions
331 struct Real {
332 enum normType { REAL };
333 };
334 struct Complex {
336 };
337 struct Separable {
339 };
340 struct AsReal {
341 enum normType { ASREAL };
342 };
343 struct Conjugate {
345 };
346 // And values to use
347 static Real REAL;
352
353 // # Public enums
354 // State of the non-linear solution
364 // Offset of fields in error_p data area.
366 // Number of condition equations
368 // Sum weights of condition equations
370 // Sum known terms squared
372 // Calculated chi^2
374 // Number of error fields
376 };
377 // # Constructors
378 // Construct an object with the number of unknowns and
379 // constraints, using the default collinearity factor and the
380 // default Levenberg-Marquardt adjustment factor.
381 // <group>
382 // Assume real
384 // Allow explicit Real specification
386 // Allow explicit Complex specification
388 // </group>
389 // Default constructor (empty, only usable after a <src>set(nUnknowns)</src>)
391 // Copy constructor (deep copy)
392 LSQFit(const LSQFit &other);
393 // Assignment (deep copy)
394 LSQFit &operator=(const LSQFit &other);
395
396 // # Destructor
398
399 // # Operators
400
401 // # General Member Functions
402 // Triangularize the normal equations and determine
403 // the rank <src>nRank</src> of the normal equations and, in the case of
404 // an <src>SVD</src> solution, the constraint
405 // equations. The collinearity factor is used
406 // to determine if the system can be solved (in essence it is the square
407 // of the sine of the angle between a column in the normal equations and
408 // the plane suspended by the other columns: if too
409 // parallel, the equations are degenerate).
410 // If <src>doSVD</src> is given as False, False is returned if rank not
411 // maximal, else an <src>SVD</src> solution is done.
412 Bool invert(uInt &nRank, Bool doSVD = False);
413 // Copy date from beg to end; converting if necessary to complex data
414 // <group>
415 template <class U>
416 void copy(const Double *beg, const Double *end, U &sol, LSQReal);
417 template <class U>
418 void copy(const Double *beg, const Double *end, U &sol, LSQComplex);
419 template <class U>
420 void copy(const Double *beg, const Double *end, U *sol, LSQReal);
421 template <class U>
422 void copy(const Double *beg, const Double *end, U *sol, LSQComplex);
423 template <class U>
424 void uncopy(Double *beg, const Double *end, U &sol, LSQReal);
425 template <class U>
426 void uncopy(Double *beg, const Double *end, U &sol, LSQComplex);
427 template <class U>
428 void uncopy(Double *beg, const Double *end, U *sol, LSQReal);
429 template <class U>
430 void uncopy(Double *beg, const Double *end, U *sol, LSQComplex);
431 template <class U>
433 template <class U>
435 // </group>
436 // Solve normal equations.
437 // The solution will be given in <src>sol</src>.
438 // <group>
439 template <class U>
440 void solve(U *sol);
441 template <class U>
442 void solve(std::complex<U> *sol);
443 template <class U>
444 void solve(U &sol);
445 // </group>
446 // Solve a loop in a non-linear set.
447 // The methods with the <src>fit</src> argument are deprecated. Use
448 // the combination without the 'fit' parameter, and the <src>isReady()</src>
449 // call. The 'fit' parameter returns
450 // for each loop a goodness
451 // of fit indicator. If it is >0; more loops are necessary.
452 // If it is negative,
453 // and has an absolute value of say less than .001, it is probably ok, and
454 // the iterations can be stopped.
455 // Other arguments are as for <src>solve()</src> and <src>invert()</src>.
456 // The <src>sol</src> is used for both input (parameter guess) and output.
457 // <group>
458 template <class U>
459 Bool solveLoop(uInt &nRank, U *sol, Bool doSVD = False);
460 template <class U>
461 Bool solveLoop(uInt &nRank, std::complex<U> *sol, Bool doSVD = False);
462 template <class U>
463 Bool solveLoop(uInt &nRank, U &sol, Bool doSVD = False);
464 template <class U>
465 Bool solveLoop(Double &fit, uInt &nRank, U *sol, Bool doSVD = False);
466 template <class U>
467 Bool solveLoop(Double &fit, uInt &nRank, std::complex<U> *sol, Bool doSVD = False);
468 template <class U>
469 Bool solveLoop(Double &fit, uInt &nRank, U &sol, Bool doSVD = False);
470 // </group>
471 // Make normal equations using the <src>cEq</src> condition equation (cArray)
472 // (with <src>nUnknowns</src> elements) and a weight <src>weight</src>,
473 // given the known observed value <src>obs</src>.
474 //
475 // <src>doNorm</src> and <src>doKnown</src> can be used
476 // to e.g. re-use existing normal equations, i.e. the condition equations,
477 // but make a new known side (i.e. new observations).
478 //
479 // The versions with <src>cEqIndex[]</src> indicate which of the
480 // <src>nUnknowns</src> are actually present in the condition equation
481 // (starting indexing at 0); the other terms are supposed to be zero. E.g.
482 // if a 12-telescope array has an equation only using telescopes 2 and 4,
483 // the lengths of <src>cEqIndex</src> and <src>cEq</src> will be both 2,
484 // and the index will contain 1 and 3 (when telescope numbering starts at 1)
485 // or 2 and 4 (when telescope numbering starts at 0. The index is given
486 // as an iterator (and hence can be a raw pointer)
487 //
488 // The complex versions can have different interpretation of the inputs,
489 // where the complex number can be seen either as a complex number; as two
490 // real numbers, or as coefficients of equations with complex conjugates.
491 // See <a href="../notes/224.html">Note 224</a>)
492 // for the details.
493 //
494 // Versions with <em>pair</em> assume that the pairs are created by the
495 // <em>SparseDiff</em> automatic differentiation class. The pair is an index
496 // and a value. The indices are assumed to be sorted.
497 //
498 // Special (<em>makeNormSorted</em>) indexed versions exist which assume
499 // that the given indices are sorted (which is the case for the
500 // LOFAR BBS environment).
501 //
502 // Some versions exist with two sets of equations (<em>cEq2, obs2</em>).
503 // If two simultaneous equations are created they will be faster.
504 //
505 // Note that the
506 // use of <src>const U &</src> is due to a Float->Double conversion problem
507 // on Solaris. Linux was ok.
508 // <group>
509 template <class U, class V>
510 void makeNorm(const V &cEq, const U &weight, const U &obs, Bool doNorm = True,
511 Bool doKnown = True);
512 template <class U, class V>
513 void makeNorm(const V &cEq, const U &weight, const U &obs, LSQFit::Real, Bool doNorm = True,
514 Bool doKnown = True);
515 template <class U, class V>
516 void makeNorm(const V &cEq, const U &weight, const std::complex<U> &obs, Bool doNorm = True,
517 Bool doKnown = True);
518 template <class U, class V>
519 void makeNorm(const V &cEq, const U &weight, const std::complex<U> &obs, LSQFit::Complex,
520 Bool doNorm = True, Bool doKnown = True);
521 template <class U, class V>
522 void makeNorm(const V &cEq, const U &weight, const std::complex<U> &obs, LSQFit::Separable,
523 Bool doNorm = True, Bool doKnown = True);
524 template <class U, class V>
525 void makeNorm(const V &cEq, const U &weight, const std::complex<U> &obs, LSQFit::AsReal,
526 Bool doNorm = True, Bool doKnown = True);
527 template <class U, class V>
528 void makeNorm(const V &cEq, const U &weight, const std::complex<U> &obs, LSQFit::Conjugate,
529 Bool doNorm = True, Bool doKnown = True);
530 //
531 template <class U, class V, class W>
532 void makeNorm(uInt nIndex, const W &cEqIndex, const V &cEq, const U &weight, const U &obs,
533 Bool doNorm = True, Bool doKnown = True);
534 template <class U, class V, class W>
535 void makeNorm(uInt nIndex, const W &cEqIndex, const V &cEq, const V &cEq2, const U &weight,
536 const U &obs, const U &obs2, Bool doNorm = True, Bool doKnown = True);
537 template <class U, class V, class W>
538 void makeNorm(uInt nIndex, const W &cEqIndex, const V &cEq, const U &weight, const U &obs,
539 LSQFit::Real, Bool doNorm = True, Bool doKnown = True);
540 template <class U, class V, class W>
541 void makeNorm(uInt nIndex, const W &cEqIndex, const V &cEq, const U &weight,
542 const std::complex<U> &obs, Bool doNorm = True, Bool doKnown = True);
543 template <class U, class V, class W>
544 void makeNorm(uInt nIndex, const W &cEqIndex, const V &cEq, const U &weight,
545 const std::complex<U> &obs, LSQFit::Complex, Bool doNorm = True,
546 Bool doKnown = True);
547 template <class U, class V, class W>
548 void makeNorm(uInt nIndex, const W &cEqIndex, const V &cEq, const U &weight,
549 const std::complex<U> &obs, LSQFit::Separable, Bool doNorm = True,
550 Bool doKnown = True);
551 template <class U, class V, class W>
552 void makeNorm(uInt nIndex, const W &cEqIndex, const V &cEq, const U &weight,
553 const std::complex<U> &obs, LSQFit::AsReal, Bool doNorm = True,
554 Bool doKnown = True);
555 template <class U, class V, class W>
556 void makeNorm(uInt nIndex, const W &cEqIndex, const V &cEq, const U &weight,
557 const std::complex<U> &obs, LSQFit::Conjugate, Bool doNorm = True,
558 Bool doKnown = True);
559 //
560 template <class U, class V>
561 void makeNorm(const std::vector<std::pair<uInt, V>> &cEq, const U &weight, const U &obs,
562 Bool doNorm = True, Bool doKnown = True);
563 template <class U, class V>
564 void makeNorm(const std::vector<std::pair<uInt, V>> &cEq, const U &weight, const U &obs,
565 LSQFit::Real, Bool doNorm = True, Bool doKnown = True);
566 template <class U, class V>
567 void makeNorm(const std::vector<std::pair<uInt, V>> &cEq, const U &weight,
568 const std::complex<U> &obs, Bool doNorm = True, Bool doKnown = True);
569 template <class U, class V>
570 void makeNorm(const std::vector<std::pair<uInt, V>> &cEq, const U &weight,
571 const std::complex<U> &obs, LSQFit::Complex, Bool doNorm = True,
572 Bool doKnown = True);
573 template <class U, class V>
574 void makeNorm(const std::vector<std::pair<uInt, V>> &cEq, const U &weight,
575 const std::complex<U> &obs, LSQFit::Separable, Bool doNorm = True,
576 Bool doKnown = True);
577 template <class U, class V>
578 void makeNorm(const std::vector<std::pair<uInt, V>> &cEq, const U &weight,
579 const std::complex<U> &obs, LSQFit::AsReal, Bool doNorm = True,
580 Bool doKnown = True);
581 template <class U, class V>
582 void makeNorm(const std::vector<std::pair<uInt, V>> &cEq, const U &weight,
583 const std::complex<U> &obs, LSQFit::Conjugate, Bool doNorm = True,
584 Bool doKnown = True);
585 //
586 template <class U, class V, class W>
587 void makeNormSorted(uInt nIndex, const W &cEqIndex, const V &cEq, const U &weight, const U &obs,
588 Bool doNorm = True, Bool doKnown = True);
589 template <class U, class V, class W>
590 void makeNormSorted(uInt nIndex, const W &cEqIndex, const V &cEq, const V &cEq2, const U &weight,
591 const U &obs, const U &obs2, Bool doNorm = True, Bool doKnown = True);
592 // </group>
593 // Get the <src>n-th</src> (from 0 to the rank deficiency, or missing rank,
594 // see e.g. <src>getDeficiency()</src>)
595 // constraint equation as determined by <src>invert()</src> in SVD-mode in
596 // <src> cEq[nUnknown]</src>. False returned for illegal n. Note
597 // that nMissing will be equal to the number of unknowns
598 // (<src>nUnknowns</src>, or double that for the complex case) minus the
599 // rank as returned from the <src>invert()</src> method.
600 // <group>
601 template <class U>
602 Bool getConstraint(uInt n, U *cEq) const;
603 template <class U>
604 Bool getConstraint(uInt n, std::complex<U> *cEq) const;
605 template <class U>
606 Bool getConstraint(uInt n, U &cEq) const;
607 // </group>
608 // Add a new constraint equation (updating nConstraints); or set a
609 // numbered constraint equation (0..nConstraints-1). False if illegal
610 // number n. The constraints are equations with <src>nUnknowns</src> terms,
611 // and a constant value. E.g. measuring three angles of a triangle
612 // could lead to equation <src>[1,1,1]</src> with obs as
613 // <src>3.1415</src>. Note that each complex constraint will be
614 // converted into two real constraints (see
615 // <a href="../notes/224.html">Note 224</a>).
616 // <group>
617 template <class U, class V>
618 Bool setConstraint(uInt n, const V &cEq, const U &obs);
619 template <class U, class V>
620 Bool setConstraint(uInt n, const V &cEq, const std::complex<U> &obs);
621 template <class U, class V, class W>
622 Bool setConstraint(uInt n, uInt nIndex, const W &cEqIndex, const V &cEq, const U &obs);
623 template <class U, class V, class W>
624 Bool setConstraint(uInt n, uInt nIndex, const W &cEqIndex, const V &cEq,
625 const std::complex<U> &obs);
626 template <class U, class V>
627 Bool addConstraint(const V &cEq, const U &obs);
628 template <class U, class V>
629 Bool addConstraint(const V &cEq, const std::complex<U> &obs);
630 template <class U, class V, class W>
631 Bool addConstraint(uInt nIndex, const W &cEqIndex, const V &cEq, const U &obs);
632 template <class U, class V, class W>
633 Bool addConstraint(uInt nIndex, const W &cEqIndex, const V &cEq, const std::complex<U> &obs);
634 // </group>
635 // Merge other <src>LSQFit</src> object (i.e. the normal equation and
636 // related information) into <src>this</src>. Both objects must have the
637 // same number of unknowns, and be pure normal equations (i.e. no
638 // <src>invert(), solve(), solveLoop()</src> or statistics calls
639 // should have been made). If merging cannot be done, <src>False</src>
640 // is returned. The index case (the index is an iterator) assumes that
641 // the normal equations to be merged are a sparse subset of the complete
642 // matrix. The index 'vector' specifies which unknowns are present. An index
643 // outside the scope of the final equations will be skipped.
644 // <note role=tip> For highest numerical precision in the case of a larger
645 // number of partial normal equations to be merged, it is best to merge
646 // them in pairs (and repeat).
647 // </note>
648 // <group>
649 Bool merge(const LSQFit &other);
650 Bool merge(const LSQFit &other, uInt nIndex, const uInt *nEqIndex) {
651 return mergeIt(other, nIndex, nEqIndex);
652 }
653 Bool merge(const LSQFit &other, uInt nIndex, const std::vector<uInt> &nEqIndex) {
654 return mergeIt(other, nIndex, &nEqIndex[0]);
655 }
656 template <class W>
657 Bool merge(const LSQFit &other, uInt nIndex, const W &nEqIndex) {
658 std::vector<uInt> ix(nIndex);
659 for (uInt i = 0; i < nIndex; ++i) ix[i] = nEqIndex[i];
660 return mergeIt(other, nIndex, &ix[0]);
661 }
662 // </group>
663 // Reset status to empty
664 void reset();
665 // Set new sizes (default is for Real)
666 // <group>
669 set(static_cast<uInt>(nUnknowns), static_cast<uInt>(nConstraints));
670 };
673 };
677 set(static_cast<uInt>(nUnknowns), LSQComplex(), static_cast<uInt>(nConstraints));
678 };
679 // </group>
680 // Set new factors (collinearity <src>factor</src>, and Levenberg-Marquardt
681 // <src>LMFactor</src>)
682 void set(Double factor = 1e-6, Double LMFactor = 1e-3);
683 // Set new value solution test
684 void setEpsValue(Double epsval = 1e-8) { epsval_p = epsval; };
685 // Set new derivative test
686 void setEpsDerivative(Double epsder = 1e-8) { epsder_p = epsder; };
687 // Set maximum number of iterations
688 void setMaxIter(uInt maxiter = 0) { maxiter_p = maxiter; };
689 // Get number of iterations done
690 uInt nIterations() const { return (maxiter_p > 0 ? maxiter_p - niter_p : 0); };
691 // Set the expected form of the normal equations
692 void setBalanced(Bool balanced = False) { balanced_p = balanced; };
693 // Ask the state of the non-linear solutions
694 // <group>
695 LSQFit::ReadyCode isReady() const { return ready_p; };
696 const std::string &readyText() const;
697 // </group>
698 // Get the covariance matrix (of size <src>nUnknowns * nUnknowns</src>)
699 // <group>
700 template <class U>
702 template <class U>
703 Bool getCovariance(std::complex<U> *covar);
704 // </group>
705 // Get main diagonal of covariance function (of size <src>nUnknowns</src>)
706 // <group>
707 template <class U>
709 template <class U>
710 Bool getErrors(std::complex<U> *errors);
711 template <class U>
713 // </group>
714 // Get the number of unknowns
715 uInt nUnknowns() const { return nun_p; };
716 // Get the number of constraints
717 uInt nConstraints() const { return ncon_p; };
718 // Get the rank deficiency <note role=warning>Note that the number is
719 // returned assuming real values. For complex values it has to be halved
720 // </note>
721 uInt getDeficiency() const { return n_p - r_p; };
722 // Get chi^2 (both are identical); the standard deviation (per observation)
723 // and the standard deviation per weight unit.
724 // <group>
725 Double getChi() const;
726 Double getChi2() const { return getChi(); };
727 Double getSD() const;
729 // </group>
730 // Debug:
731 // <ul>
732 // <li> <src>nun = </src> number of unknowns
733 // <li> <src>np = </src> total number of solved unknowns (nun+ncon)
734 // <li> <src>ncon = </src> number of constraint equations
735 // <li> <src>ner = </src> number of elements in chi<sup>2</sup> vector
736 // <li> <src>rank = </src> rank)
737 // <li> <src>nEq = </src> normal equation (nun*nun as triangular matrix)
738 // <li> <src>known = </src> known vector (np)
739 // <li> <src>constr = </src> constraint matrix (ncon*nun)
740 // <li> <src>er = </src> error info vector (ner)
741 // <li> <src>piv = </src> pivot vector (np)
742 // <li> <src>sEq = </src> normal solution equation (np*np triangular)
743 // <li> <src>sol = </src> internal solution vector (np)
744 // <li> <src>prec = </src> collinearity precision
745 // <li> <src>nonlin = </src> current Levenberg factor-1
746 // </ul>
747 // Note that all pointers may be 0.
748 void debugIt(uInt &nun, uInt &np, uInt &ncon, uInt &ner, uInt &rank, Double *&nEq, Double *&known,
749 Double *&constr, Double *&er, uInt *&piv, Double *&sEq, Double *&sol, Double &prec,
750 Double &nonlin) const;
751 //
752 // Create an LSQFit object from a record.
753 // An error message is generated, and False
754 // returned if an invalid record is given. A valid record will return True.
755 // Error messages are postfixed to error.
756 // <group>
758 // </group>
759 // Create a record from an LSQFit object.
760 // The return will be False and an error
761 // message generated only if the object does not contain a valid object.
762 // Error messages are postfixed to error.
763 Bool toRecord(String &error, RecordInterface &out) const;
764 // Get identification of record
765 const String &ident() const;
766 //
767 // Save or restore using AipsIO.
768 // <group>
769 void toAipsIO(AipsIO &) const;
771 // </group>
772 //
773 protected:
774 // # enum
775 // Bits that can be set/referenced
776 enum StateBit {
777 // Inverted matrix present
779 // Triangularised
781 // Non-linear solution
783 // Filler for cxx2html
785 };
786
787 // Record field names
788 // <group>
789 static const String recid;
790 static const String state;
791 static const String nun;
792 static const String ncon;
793 static const String prec;
794 static const String startnon;
795 static const String nonlin;
796 static const String rank;
797 static const String nnc;
798 static const String piv;
799 static const String constr;
800 static const String known;
801 static const String errors;
802 static const String sol;
803 static const String lar;
804 static const String wsol;
805 static const String wcov;
806 static const String nceq;
807 static const String nar;
808 // </group>
809
810 // # Data
811 // Bits set to indicate state
813 // Number of unknowns
815 // Number of constraints
817 // Matrix size (will be n_p = nun_p + ncon_p)
819 // Rank of normal equations (normally n_p)
821 // Collinearity precision
823 // Levenberg start factor
825 // Levenberg current factor
827 // Levenberg step factor
829 // Test value for [incremental] solution in non-linear loop.
830 // The <src>||sol increment||/||sol||</src> is tested
832 // Test value for known vector in non-linear loop.
833 // ||known||<sub>inf</sub> is tested
835 // Indicator for a well balanced normal equation. A balanced equation is
836 // one with similar values in the main diagonal.
838 // Maximum number of iterations for non-linear solution. If a non-zero
839 // maximum number of iterations is set, the value is tested in non-linear
840 // loops
842 // Iteration count for non-linear solution
844 // Indicate the non-linear state. A non-zero code indicates that non-linear
845 // looping is ready.
847
848 // Pivot table (n_p)
850 // Normal equations (triangular nun_p * nun_p)
852 // Current length nceq_p
854 // Normal combined with constraint equations for solutions
855 // (triangular nnc_p*nnc_p)
857 // Known part equations (n_p)
859 // Counts for errors (N_ErrorField)
861 // Constraint equation area (nun_p*ncon_p))
863 // Solution area (n_p)
865 // Save area for non-linear case (size determined internally)
867 // Save area for non-symmetric (i.e. with constraints) (n_p * n_p)
869 // Work areas for interim solutions and covariance
870 // <group>
873 // </group>
874
875 // # Member functions
876 // Get pointer in rectangular array
877 // <group>
878 Double *rowrt(uInt i) const { return &lar_p[n_p * i]; };
879 Double *rowru(uInt i) const { return &lar_p[nun_p * i]; };
880 // </group>
881 // Calculate the real or imag part of <src>x*conj(y)</src>
882 // <group>
883 static Double realMC(const std::complex<Double> &x, const std::complex<Double> &y) {
884 return (x.real() * y.real() + x.imag() * y.imag());
885 };
886 static Double imagMC(const std::complex<Double> &x, const std::complex<Double> &y) {
887 return (x.imag() * y.real() - x.real() * y.imag());
888 };
889 static Float realMC(const std::complex<Float> &x, const std::complex<Float> &y) {
890 return (x.real() * y.real() + x.imag() * y.imag());
891 };
892 static Float imagMC(const std::complex<Float> &x, const std::complex<Float> &y) {
893 return (x.imag() * y.real() - x.real() * y.imag());
894 };
895 // </group>
896 // Initialise areas
897 void init();
898 // Clear areas
899 void clear();
900 // De-initialise area
901 void deinit();
902 // Solve normal equations
903 void solveIt();
904 // One non-linear LM loop
905 Bool solveItLoop(Double &fit, uInt &nRank, Bool doSVD = False);
906 // Solve missing rank part
907 void solveMR(uInt nin);
908 // Invert rectangular matrix (i.e. when constraints present)
910 // Get the norm of the current solution vector
912 // Get the infinite norm of the known vector
914 // Merge sparse normal equations
915 Bool mergeIt(const LSQFit &other, uInt nIndex, const uInt *nEqIndex);
916 // Save current status (or part)
917 void save(Bool all = True);
918 // Restore current status
920 // Copy data. If all False, only the relevant data for non-linear
921 // solution are copied (normal equations, knows and errors).
922 void copy(const LSQFit &other, Bool all = True);
923 // Extend the constraint equation area to the specify number of
924 // equations.
926 // Create the solution equation area nceq_p and fill it.
928 // Get work areas for solutions, covariance
929 // <group>
932 // </group>
933 //
934};
935
936} // namespace casacore
937
938#ifndef CASACORE_NO_AUTO_TEMPLATES
939#include <casacore/scimath/Fitting/LSQFit2.tcc>
940#endif // # CASACORE_NO_AUTO_TEMPLATES
941#endif
Type of complex numeric class indicator.
Definition LSQTraits.h:69
Double stepfactor_p
Levenberg step factor.
Definition LSQFit.h:828
void solve(U *sol)
Solve normal equations.
Double prec_p
Collinearity precision.
Definition LSQFit.h:822
uInt nUnknowns() const
Get the number of unknowns.
Definition LSQFit.h:715
static const String nceq
Definition LSQFit.h:806
void makeNorm(uInt nIndex, const W &cEqIndex, const V &cEq, const U &weight, const std::complex< U > &obs, LSQFit::Complex, Bool doNorm=True, Bool doKnown=True)
void createNCEQ()
Create the solution equation area nceq_p and fill it.
Bool merge(const LSQFit &other)
Merge other LSQFit object (i.e.
void set(Int nUnknowns, Int nConstraints=0)
Definition LSQFit.h:668
Bool invert(uInt &nRank, Bool doSVD=False)
Triangularize the normal equations and determine the rank nRank of the normal equations and,...
void extendConstraints(uInt n)
Extend the constraint equation area to the specify number of equations.
Bool solveLoop(uInt &nRank, U *sol, Bool doSVD=False)
Solve a loop in a non-linear set.
static const String state
Definition LSQFit.h:790
Bool setConstraint(uInt n, const V &cEq, const std::complex< U > &obs)
void makeNorm(const std::vector< std::pair< uInt, V > > &cEq, const U &weight, const U &obs, LSQFit::Real, Bool doNorm=True, Bool doKnown=True)
static Separable SEPARABLE
Definition LSQFit.h:349
Double * wsol_p
Work areas for interim solutions and covariance.
Definition LSQFit.h:871
Bool getCovariance(std::complex< U > *covar)
static const String recid
Record field names.
Definition LSQFit.h:789
void uncopy(Double *beg, const Double *end, U &sol, LSQComplex)
void makeNorm(uInt nIndex, const W &cEqIndex, const V &cEq, const U &weight, const U &obs, Bool doNorm=True, Bool doKnown=True)
ReadyCode ready_p
Indicate the non-linear state.
Definition LSQFit.h:846
Bool getErrors(std::complex< U > *errors)
void set(uInt nUnknowns, uInt nConstraints=0)
Set new sizes (default is for Real).
Bool getConstraint(uInt n, U *cEq) const
Get the n-th (from 0 to the rank deficiency, or missing rank, see e.g.
Bool solveLoop(Double &fit, uInt &nRank, U &sol, Bool doSVD=False)
const String & ident() const
Get identification of record.
void save(Bool all=True)
Save current status (or part).
void init()
Initialise areas.
uInt nIterations() const
Get number of iterations done.
Definition LSQFit.h:690
void makeNorm(const V &cEq, const U &weight, const std::complex< U > &obs, Bool doNorm=True, Bool doKnown=True)
static const String nonlin
Definition LSQFit.h:795
void set(Double factor=1e-6, Double LMFactor=1e-3)
Set new factors (collinearity factor, and Levenberg-Marquardt LMFactor).
Double startnon_p
Levenberg start factor.
Definition LSQFit.h:824
LSQFit(uInt nUnknowns, const LSQComplex &, uInt nConstraints=0)
Allow explicit Complex specification.
Bool invertRect()
Invert rectangular matrix (i.e.
Double normInfKnown(const Double *known) const
Get the infinite norm of the known vector.
uInt r_p
Rank of normal equations (normally n_p).
Definition LSQFit.h:820
static const String constr
Definition LSQFit.h:799
LSQFit * nar_p
Save area for non-linear case (size determined internally).
Definition LSQFit.h:866
Double normSolution(const Double *sol) const
Get the norm of the current solution vector.
Bool solveLoop(Double &fit, uInt &nRank, std::complex< U > *sol, Bool doSVD=False)
void solveIt()
Solve normal equations.
uInt nnc_p
Current length nceq_p.
Definition LSQFit.h:853
uInt state_p
Bits set to indicate state.
Definition LSQFit.h:812
void makeNorm(uInt nIndex, const W &cEqIndex, const V &cEq, const U &weight, const std::complex< U > &obs, LSQFit::AsReal, Bool doNorm=True, Bool doKnown=True)
void makeNorm(const std::vector< std::pair< uInt, V > > &cEq, const U &weight, const std::complex< U > &obs, Bool doNorm=True, Bool doKnown=True)
Double * rowru(uInt i) const
Definition LSQFit.h:879
Double * rowrt(uInt i) const
Get pointer in rectangular array.
Definition LSQFit.h:878
Double getChi() const
Get chi^2 (both are identical); the standard deviation (per observation) and the standard deviation p...
Bool getConstraint(uInt n, U &cEq) const
void makeNorm(const V &cEq, const U &weight, const std::complex< U > &obs, LSQFit::AsReal, Bool doNorm=True, Bool doKnown=True)
uInt nun_p
Number of unknowns.
Definition LSQFit.h:814
Double * constr_p
Constraint equation area (nun_p*ncon_p)).
Definition LSQFit.h:862
static AsReal ASREAL
Definition LSQFit.h:350
void toAipsIO(AipsIO &) const
Save or restore using AipsIO.
LSQFit(const LSQFit &other)
Copy constructor (deep copy).
uInt n_p
Matrix size (will be n_p = nun_p + ncon_p).
Definition LSQFit.h:818
static Complex COMPLEX
Definition LSQFit.h:348
Bool getErrors(U &errors)
Bool solveLoop(Double &fit, uInt &nRank, U *sol, Bool doSVD=False)
uInt * piv_p
Pivot table (n_p).
Definition LSQFit.h:849
static const String wsol
Definition LSQFit.h:804
Bool addConstraint(const V &cEq, const U &obs)
void uncopy(Double *beg, const Double *end, U *sol, LSQReal)
void makeNorm(const std::vector< std::pair< uInt, V > > &cEq, const U &weight, const std::complex< U > &obs, LSQFit::Complex, Bool doNorm=True, Bool doKnown=True)
void makeNorm(uInt nIndex, const W &cEqIndex, const V &cEq, const U &weight, const std::complex< U > &obs, Bool doNorm=True, Bool doKnown=True)
Double epsval_p
Test value for [incremental] solution in non-linear loop.
Definition LSQFit.h:831
LSQMatrix * nceq_p
Normal combined with constraint equations for solutions (triangular nnc_p*nnc_p).
Definition LSQFit.h:856
Bool addConstraint(const V &cEq, const std::complex< U > &obs)
Double * wcov_p
Definition LSQFit.h:872
void makeNorm(const std::vector< std::pair< uInt, V > > &cEq, const U &weight, const U &obs, Bool doNorm=True, Bool doKnown=True)
Bool merge(const LSQFit &other, uInt nIndex, const W &nEqIndex)
Definition LSQFit.h:657
Double * lar_p
Save area for non-symmetric (i.e.
Definition LSQFit.h:868
LSQFit(uInt nUnknowns, const LSQReal &, uInt nConstraints=0)
Allow explicit Real specification.
Bool solveLoop(uInt &nRank, std::complex< U > *sol, Bool doSVD=False)
uInt ncon_p
Number of constraints.
Definition LSQFit.h:816
static Double realMC(const std::complex< Double > &x, const std::complex< Double > &y)
Calculate the real or imag part of x*conj(y).
Definition LSQFit.h:883
void makeNorm(const std::vector< std::pair< uInt, V > > &cEq, const U &weight, const std::complex< U > &obs, LSQFit::Separable, Bool doNorm=True, Bool doKnown=True)
Bool getConstraint(uInt n, std::complex< U > *cEq) const
Bool addConstraint(uInt nIndex, const W &cEqIndex, const V &cEq, const U &obs)
Bool getCovariance(U *covar)
Get the covariance matrix (of size nUnknowns * nUnknowns).
void solve(U &sol)
static const String known
Definition LSQFit.h:800
Bool setConstraint(uInt n, uInt nIndex, const W &cEqIndex, const V &cEq, const std::complex< U > &obs)
Double getChi2() const
Definition LSQFit.h:726
const std::string & readyText() const
Bool solveItLoop(Double &fit, uInt &nRank, Bool doSVD=False)
One non-linear LM loop.
Bool toRecord(String &error, RecordInterface &out) const
Create a record from an LSQFit object.
Double * error_p
Counts for errors (N_ErrorField).
Definition LSQFit.h:860
void solve(std::complex< U > *sol)
void setMaxIter(uInt maxiter=0)
Set maximum number of iterations.
Definition LSQFit.h:688
Bool getErrors(U *errors)
Get main diagonal of covariance function (of size nUnknowns).
void set(uInt nUnknowns, const LSQReal &, uInt nConstraints=0)
Definition LSQFit.h:671
void makeNormSorted(uInt nIndex, const W &cEqIndex, const V &cEq, const V &cEq2, const U &weight, const U &obs, const U &obs2, Bool doNorm=True, Bool doKnown=True)
static const String errors
Definition LSQFit.h:801
uInt nConstraints() const
Get the number of constraints.
Definition LSQFit.h:717
void copy(const Double *beg, const Double *end, U *sol, LSQComplex)
void makeNorm(const V &cEq, const U &weight, const U &obs, LSQFit::Real, Bool doNorm=True, Bool doKnown=True)
void clear()
Clear areas.
static const String ncon
Definition LSQFit.h:792
void makeNorm(const V &cEq, const U &weight, const U &obs, Bool doNorm=True, Bool doKnown=True)
Make normal equations using the cEq condition equation (cArray) (with nUnknowns elements) and a weigh...
void makeNorm(const std::vector< std::pair< uInt, V > > &cEq, const U &weight, const std::complex< U > &obs, LSQFit::Conjugate, Bool doNorm=True, Bool doKnown=True)
void makeNorm(const V &cEq, const U &weight, const std::complex< U > &obs, LSQFit::Separable, Bool doNorm=True, Bool doKnown=True)
void set(Int nUnknowns, const LSQComplex &, Int nConstraints=0)
Definition LSQFit.h:676
void copy(const LSQFit &other, Bool all=True)
Copy data.
static const String rank
Definition LSQFit.h:796
LSQFit()
Default constructor (empty, only usable after a set(nUnknowns)).
Double * sol_p
Solution area (n_p).
Definition LSQFit.h:864
Bool setConstraint(uInt n, uInt nIndex, const W &cEqIndex, const V &cEq, const U &obs)
static const String nun
Definition LSQFit.h:791
void setEpsValue(Double epsval=1e-8)
Set new value solution test.
Definition LSQFit.h:684
void getWorkSOL()
Get work areas for solutions, covariance.
static Double imagMC(const std::complex< Double > &x, const std::complex< Double > &y)
Definition LSQFit.h:886
static const String wcov
Definition LSQFit.h:805
LSQFit(uInt nUnknowns, uInt nConstraints=0)
Construct an object with the number of unknowns and constraints, using the default collinearity facto...
Bool merge(const LSQFit &other, uInt nIndex, const std::vector< uInt > &nEqIndex)
Definition LSQFit.h:653
uInt niter_p
Iteration count for non-linear solution.
Definition LSQFit.h:843
void makeNorm(const V &cEq, const U &weight, const std::complex< U > &obs, LSQFit::Complex, Bool doNorm=True, Bool doKnown=True)
LSQFit::ReadyCode isReady() const
Ask the state of the non-linear solutions.
Definition LSQFit.h:695
Bool setConstraint(uInt n, const V &cEq, const U &obs)
Add a new constraint equation (updating nConstraints); or set a numbered constraint equation (0....
void makeNorm(uInt nIndex, const W &cEqIndex, const V &cEq, const V &cEq2, const U &weight, const U &obs, const U &obs2, Bool doNorm=True, Bool doKnown=True)
static const String sol
Definition LSQFit.h:802
void makeNorm(const std::vector< std::pair< uInt, V > > &cEq, const U &weight, const std::complex< U > &obs, LSQFit::AsReal, Bool doNorm=True, Bool doKnown=True)
uInt maxiter_p
Maximum number of iterations for non-linear solution.
Definition LSQFit.h:841
void setBalanced(Bool balanced=False)
Set the expected form of the normal equations.
Definition LSQFit.h:692
void fromAipsIO(AipsIO &)
Bool balanced_p
Indicator for a well balanced normal equation.
Definition LSQFit.h:837
void set(uInt nUnknowns, const LSQComplex &, uInt nConstraints=0)
void restore(Bool all=True)
Restore current status.
StateBit
Bits that can be set/referenced.
Definition LSQFit.h:776
@ NONLIN
Non-linear solution.
Definition LSQFit.h:782
@ TRIANGLE
Triangularised.
Definition LSQFit.h:780
@ N_StateBit
Filler for cxx2html.
Definition LSQFit.h:784
@ INVERTED
Inverted matrix present.
Definition LSQFit.h:778
void uncopy(Double *beg, const Double *end, U &sol, LSQReal)
static const String lar
Definition LSQFit.h:803
ErrorField
Offset of fields in error_p data area.
Definition LSQFit.h:365
@ NC
Number of condition equations.
Definition LSQFit.h:367
@ CHI2
Calculated chi^2.
Definition LSQFit.h:373
@ SUMWEIGHT
Sum weights of condition equations.
Definition LSQFit.h:369
@ N_ErrorField
Number of error fields.
Definition LSQFit.h:375
@ SUMLL
Sum known terms squared.
Definition LSQFit.h:371
Bool merge(const LSQFit &other, uInt nIndex, const uInt *nEqIndex)
Definition LSQFit.h:650
Bool solveLoop(uInt &nRank, U &sol, Bool doSVD=False)
void makeNorm(const V &cEq, const U &weight, const std::complex< U > &obs, LSQFit::Conjugate, Bool doNorm=True, Bool doKnown=True)
Double * known_p
Known part equations (n_p).
Definition LSQFit.h:858
void uncopy(Double *beg, const Double *end, U *sol, LSQComplex)
void makeNorm(uInt nIndex, const W &cEqIndex, const V &cEq, const U &weight, const U &obs, LSQFit::Real, Bool doNorm=True, Bool doKnown=True)
Double nonlin_p
Levenberg current factor.
Definition LSQFit.h:826
static Float imagMC(const std::complex< Float > &x, const std::complex< Float > &y)
Definition LSQFit.h:892
static const String startnon
Definition LSQFit.h:794
uInt getDeficiency() const
Get the rank deficiency Warning: Note that the number is returned assuming real values; For complex ...
Definition LSQFit.h:721
void copyDiagonal(U &errors, LSQComplex)
static const String piv
Definition LSQFit.h:798
static Real REAL
And values to use.
Definition LSQFit.h:347
Bool mergeIt(const LSQFit &other, uInt nIndex, const uInt *nEqIndex)
Merge sparse normal equations.
ReadyCode
State of the non-linear solution.
Definition LSQFit.h:355
void makeNorm(uInt nIndex, const W &cEqIndex, const V &cEq, const U &weight, const std::complex< U > &obs, LSQFit::Separable, Bool doNorm=True, Bool doKnown=True)
void reset()
Reset status to empty.
static const String nnc
Definition LSQFit.h:797
void copy(const Double *beg, const Double *end, U &sol, LSQReal)
Copy date from beg to end; converting if necessary to complex data.
Double getWeightedSD() const
Bool fromRecord(String &error, const RecordInterface &in)
Create an LSQFit object from a record.
static Conjugate CONJUGATE
Definition LSQFit.h:351
void makeNorm(uInt nIndex, const W &cEqIndex, const V &cEq, const U &weight, const std::complex< U > &obs, LSQFit::Conjugate, Bool doNorm=True, Bool doKnown=True)
static const String prec
Definition LSQFit.h:793
static Float realMC(const std::complex< Float > &x, const std::complex< Float > &y)
Definition LSQFit.h:889
void setEpsDerivative(Double epsder=1e-8)
Set new derivative test.
Definition LSQFit.h:686
void solveMR(uInt nin)
Solve missing rank part.
void set(Int nUnknowns, const LSQReal &, Int nConstraints=0)
Definition LSQFit.h:674
void debugIt(uInt &nun, uInt &np, uInt &ncon, uInt &ner, uInt &rank, Double *&nEq, Double *&known, Double *&constr, Double *&er, uInt *&piv, Double *&sEq, Double *&sol, Double &prec, Double &nonlin) const
Debug:
void deinit()
De-initialise area.
LSQMatrix * norm_p
Normal equations (triangular nun_p * nun_p).
Definition LSQFit.h:851
LSQFit & operator=(const LSQFit &other)
Assignment (deep copy).
Bool addConstraint(uInt nIndex, const W &cEqIndex, const V &cEq, const std::complex< U > &obs)
Double getSD() const
void makeNormSorted(uInt nIndex, const W &cEqIndex, const V &cEq, const U &weight, const U &obs, Bool doNorm=True, Bool doKnown=True)
void copy(const Double *beg, const Double *end, U *sol, LSQReal)
Double epsder_p
Test value for known vector in non-linear loop.
Definition LSQFit.h:834
void copy(const Double *beg, const Double *end, U &sol, LSQComplex)
void copyDiagonal(U &errors, LSQReal)
static const String nar
Definition LSQFit.h:807
String: the storage and methods of handling collections of characters.
Definition String.h:355
For temporary backward namespace compatibility, use casa as alias for casacore.
Definition mainpage.dox:28
const Bool False
Definition aipstype.h:42
int * factor
Definition hdu.h:521
unsigned int uInt
Definition aipstype.h:49
float Float
Definition aipstype.h:52
RecordInterface()
The default constructor creates an empty record with a variable structure.
int Int
Definition aipstype.h:48
bool Bool
Define the standard types used by Casacore.
Definition aipstype.h:40
const Bool True
Definition aipstype.h:41
double Double
Definition aipstype.h:53
LatticeExprNode all(const LatticeExprNode &expr)
iterator end()
Definition Block.h:601
Simple classes to overload templated memberfunctions.
Definition LSQFit.h:331