// Copyright (c) 1997-1999 Matra Datavision // Copyright (c) 1999-2014 OPEN CASCADE SAS // // This file is part of Open CASCADE Technology software library. // // This library is free software; you can redistribute it and/or modify it under // the terms of the GNU Lesser General Public License version 2.1 as published // by the Free Software Foundation, with special exception defined in the file // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT // distribution for complete text of the license and disclaimer of any warranty. // // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. //#ifndef OCCT_DEBUG #define No_Standard_RangeError #define No_Standard_OutOfRange #define No_Standard_DimensionError //#endif #include #include #include #include #include #include math_SVD::math_SVD (const math_Matrix& A) : U (1, Max(A.RowNumber(),A.ColNumber()), 1, A.ColNumber()) , V (1, A.ColNumber(), 1, A.ColNumber()), Diag (1, A.ColNumber()) { U.Init(0.0); RowA = A.RowNumber() ; U.Set(1, A.RowNumber(), 1, A.ColNumber(), A) ; Standard_Integer Error = SVD_Decompose(U, Diag, V) ; Done = (!Error) ? Standard_True : Standard_False ; } void math_SVD::Solve (const math_Vector& B, math_Vector& X, const Standard_Real Eps) { StdFail_NotDone_Raise_if(!Done, " "); Standard_DimensionError_Raise_if((RowA != B.Length()) || (X.Length() != Diag.Length()), " "); math_Vector BB (1, U.RowNumber()) ; BB.Init(0.0); BB.Set (1, B.Length(), B) ; Standard_Real wmin = Eps * Diag(Diag.Max()); for (Standard_Integer I = 1; I <= Diag.Upper(); I++) { if (Diag(I) < wmin) Diag(I) = 0.0 ; } SVD_Solve (U, Diag, V, BB, X) ; } void math_SVD::PseudoInverse (math_Matrix& Result, const Standard_Real Eps) { Standard_Integer i, j ; StdFail_NotDone_Raise_if(!Done, " "); Standard_Real wmin = Eps * Diag(Diag.Max()); for (i=1; i<=Diag.Upper(); i++) { if (Diag(i) < wmin) Diag(i) = 0.0 ; } Standard_Integer ColA = Diag.Length () ; math_Vector VNorme (1, U.RowNumber()) ; math_Vector Column (1, ColA) ; for (j=1; j<=RowA; j++) { for (i=1; i<=VNorme.Upper(); i++) VNorme(i) = 0.0 ; VNorme(j) = 1.0 ; SVD_Solve (U, Diag, V, VNorme, Column) ; for (i=1; i<=ColA; i++) Result(i,j) = Column(i) ; } } void math_SVD::Dump(Standard_OStream& o) const { o << "math_SVD"; if(Done) { o << " Status = Done \n"; } else { o << " Status = not Done \n"; } }