14 #if defined(DEBUG) || defined(WARNINGMSG)
26 LAVector eigenvalues(
const LASymMatrix&);
29 MinimumState MnPosDef::operator()(
const MinimumState& st,
const MnMachinePrecision& prec)
const {
31 MinimumError err = (*this)(st.Error(), prec);
32 return MinimumState(st.Parameters(), err, st.Gradient(), st.Edm(), st.NFcn());
35 MinimumError MnPosDef::operator()(
const MinimumError& e,
const MnMachinePrecision& prec)
const {
38 MnAlgebraicSymMatrix err(e.InvHessian());
39 if(err.size() == 1 && err(0,0) < prec.Eps()) {
41 return MinimumError(err, MinimumError::MnMadePosDef());
43 if(err.size() == 1 && err(0,0) > prec.Eps()) {
48 double epspdf = std::max(1.e-6, prec.Eps2());
49 double dgmin = err(0,0);
51 for(
unsigned int i = 0; i < err.Nrow(); i++) {
54 MN_INFO_VAL2(
"negative or zero diagonal element in covariance matrix",i);
56 if(err(i,i) < dgmin) dgmin = err(i,i);
61 dg = 0.5 + epspdf - dgmin;
64 MN_INFO_VAL2(
"added to diagonal of Error matrix a value",dg);
69 MnAlgebraicVector s(err.Nrow());
70 MnAlgebraicSymMatrix p(err.Nrow());
71 for(
unsigned int i = 0; i < err.Nrow(); i++) {
73 if(err(i,i) < 0.) err(i,i) = 1.;
74 s(i) = 1./sqrt(err(i,i));
75 for(
unsigned int j = 0; j <= i; j++) {
76 p(i,j) = err(i,j)*s(i)*s(j);
81 MnAlgebraicVector eval = eigenvalues(p);
82 double pmin = eval(0);
83 double pmax = eval(eval.size() - 1);
85 pmax = std::max(fabs(pmax), 1.);
86 if(pmin > epspdf*pmax)
return MinimumError(err, e.Dcovar());
88 double padd = 0.001*pmax - pmin;
90 std::cout<<
"eigenvalues: "<<std::endl;
92 for(
unsigned int i = 0; i < err.Nrow(); i++) {
93 err(i,i) *= (1. + padd);
95 std::cout<<eval(i)<<std::endl;
100 MN_INFO_VAL2(
"matrix forced pos-def by adding to diagonal",padd);
102 return MinimumError(err, MinimumError::MnMadePosDef());