Commit 14c0517e by Kirill Terekhov

### Fix for mesh modification algorithm

parent 0e99faa2
 ... @@ -298,10 +298,11 @@ namespace INMOST ... @@ -298,10 +298,11 @@ namespace INMOST flag = 0; flag = 0; break; break; } } if( l == 0 ) break; if (fabs(get_value(Sigma(nm,nm))) + anorm == anorm) if (fabs(get_value(Sigma(nm,nm))) + anorm == anorm) break; break; } } if (flag) if (flag && l != 0) { { c = 0.0; c = 0.0; s = 1.0; s = 1.0; ... @@ -377,7 +378,7 @@ namespace INMOST ... @@ -377,7 +378,7 @@ namespace INMOST } } z = pythag(f, h); z = pythag(f, h); Sigma(j,j) = z; Sigma(j,j) = z; if (z) if (get_value(z)) { { z = 1.0 / z; z = 1.0 / z; c = f * z; c = f * z; ... @@ -1115,6 +1116,19 @@ namespace INMOST ... @@ -1115,6 +1116,19 @@ namespace INMOST n = _n; n = _n; m = _m; m = _m; } } Matrix PseudoInvert(INMOST_DATA_REAL_TYPE tol = 0) { Matrix U,S,V; SVD(U,S,V); for(int k = 0; k < S.Cols(); ++k) { if( S(k,k) > tol ) S(k,k) = 1.0/S(k,k); else S(k,k) = 0.0; } return V*S*U.Transpose(); } }; }; typedef Matrix rMatrix; //shortcut for real matrix typedef Matrix rMatrix; //shortcut for real matrix ... ...
 ... @@ -1501,35 +1501,44 @@ namespace INMOST ... @@ -1501,35 +1501,44 @@ namespace INMOST template template class pow_const_expression : public shell_expression > class pow_const_expression : public shell_expression > { { const A & left; const A & left; INMOST_DATA_REAL_TYPE value, ldmult; INMOST_DATA_REAL_TYPE value, ldmult, ldmult2; public: public: pow_const_expression(const shell_expression & pleft, INMOST_DATA_REAL_TYPE pright) : left(pleft) pow_const_expression(const shell_expression & pleft, INMOST_DATA_REAL_TYPE pright) : left(pleft) { { INMOST_DATA_REAL_TYPE lval = left.GetValue(); INMOST_DATA_REAL_TYPE lval = left.GetValue(); value = ::pow(lval,pright); value = ::pow(lval,pright); if( lval != 0 ) if( lval != 0 ) ldmult = value * pright / lval; { else ldmult = value * pright / lval; ldmult = 0; ldmult2 = ldmult * (pright-1) / lval; } } pow_const_expression(const pow_const_expression & other) else :left(other.left), value(other.value), ldmult(other.ldmult) {} ldmult = ldmult2 = 0; __INLINE INMOST_DATA_REAL_TYPE GetValue() const { return value; } } __INLINE void GetJacobian(INMOST_DATA_REAL_TYPE mult, Sparse::RowMerger & r) const pow_const_expression(const pow_const_expression & other) { :left(other.left), value(other.value), ldmult(other.ldmult) {} left.GetJacobian(mult*ldmult,r); __INLINE INMOST_DATA_REAL_TYPE GetValue() const { return value; } } __INLINE void GetJacobian(INMOST_DATA_REAL_TYPE mult, Sparse::RowMerger & r) const __INLINE void GetJacobian(INMOST_DATA_REAL_TYPE mult, Sparse::Row & r) const { { left.GetJacobian(mult*ldmult,r); left.GetJacobian(mult*ldmult,r); } } __INLINE void GetJacobian(INMOST_DATA_REAL_TYPE mult, Sparse::Row & r) const __INLINE void GetHessian(INMOST_DATA_REAL_TYPE multJ, Sparse::Row & J, INMOST_DATA_REAL_TYPE multH, Sparse::HessianRow & H) const { { left.GetJacobian(mult*ldmult,r); throw NotImplemented; } } __INLINE void GetHessian(INMOST_DATA_REAL_TYPE multJ, Sparse::Row & J, INMOST_DATA_REAL_TYPE multH, Sparse::HessianRow & H) const }; { //(F(G))'' = (F'(G)G')' = (F''(G)G'+F'(G)G'') //(g(x)^n)'' = n g(x)^(n - 2) (g(x) g''(x) + (n - 1) g'(x)^2) Sparse::Row JL; Sparse::HessianRow HL; left.GetHessian(1,JL,1,HL); //retrive jacobian row and hessian matrix of the left expression Sparse::HessianRow::MergeJacobianHessian(multH*ldmult2,JL,JL,multH*ldmult,HL,H); for(Sparse::Row::iterator it = JL.Begin(); it != JL.End(); ++it) it->second *= ldmult*multJ; } }; template template class const_pow_expression : public shell_expression > class const_pow_expression : public shell_expression > ... ...