1 // Copyright (c) 1997-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
4 // This file is part of Open CASCADE Technology software library.
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
16 #define No_Standard_RangeError
17 #define No_Standard_OutOfRange
18 #define No_Standard_DimensionError
22 #include <math_Householder.hxx>
23 #include <math_Matrix.hxx>
24 #include <Standard_ConstructionError.hxx>
25 #include <Standard_DimensionError.hxx>
26 #include <Standard_OutOfRange.hxx>
27 #include <StdFail_NotDone.hxx>
29 // Cette classe decrit la methode de Householder qui transforme A en un
30 // produit de matrice orthogonale par une triangulaire superieure. Les seconds
31 // membres sont modifies dans le meme temps.
32 // Les references sur le cote sont celles de l'algorithme explique en page
33 // 90 du livre "Introduction a l'analyse numerique matricielle et a
34 // l'optimisation." par P.G. CIARLET, edition MASSON. Les secondes
35 // references sont celles du sous-programme HOUSEO d'Euclid.
36 // A la difference du sous-programme Houseo, la premiere colonne n'est pas
37 // traitee separement. Les tests effectues ont montre que le code effectue
38 // specialement pour celle-ci etait plus long qu'une simple recopie. C'est
39 // donc cette solution de recopie initiale qui a ete retenue.
40 math_Householder::math_Householder(const math_Matrix& A, const math_Vector& B,
41 const Standard_Real EPS):
42 Sol(1, A.ColNumber(), 1, 1),
46 mylowerArow = A.LowerRow();
47 mylowerAcol = A.LowerCol();
48 myupperArow = A.UpperRow();
49 myupperAcol = A.UpperCol();
50 math_Matrix B1(1, B.Length(), 1, 1);
57 math_Householder::math_Householder(const math_Matrix& A, const math_Matrix& B,
58 const Standard_Real EPS):
62 A.LowerCol(), A.UpperCol()) {
64 mylowerArow = A.LowerRow();
65 mylowerAcol = A.LowerCol();
66 myupperArow = A.UpperRow();
67 myupperAcol = A.UpperCol();
72 math_Householder::math_Householder(const math_Matrix& A, const math_Matrix& B,
73 const Standard_Integer lowerArow,
74 const Standard_Integer upperArow,
75 const Standard_Integer lowerAcol,
76 const Standard_Integer upperAcol,
77 const Standard_Real EPS):
78 Sol(1, upperAcol-lowerAcol+1,
80 Q(1, upperArow-lowerArow+1,
81 1, upperAcol-lowerAcol+1) {
82 mylowerArow = lowerArow;
83 myupperArow = upperArow;
84 mylowerAcol = lowerAcol;
85 myupperAcol = upperAcol;
91 void math_Householder::Perform(const math_Matrix& A, const math_Matrix& B,
92 const Standard_Real EPS) {
94 Standard_Integer i, j, k, n, l, m;
95 Standard_Real scale, f, g, h = 0., alfaii;
101 math_Matrix B2(1, l, 1, m);
103 Standard_Integer lbrow = B.LowerRow();
104 for (i = 1; i <= l; i++) {
105 for (j = 1; j <= n; j++) {
106 Q(i, j) = A(i+mylowerArow-1, j+mylowerAcol-1);
108 for (j=1; j <= m; j++) {
109 B2(i, j) = B(i+lbrow-1, j);
113 Standard_DimensionError_Raise_if(l != B.RowNumber() || n > l, " ");
115 // Traitement de chaque colonne de A:
116 for (i = 1; i <= n; i++) {
118 for (k = i; k <= l; k++) {
120 h += qki*qki; // = ||a||*||a|| = EUAI
122 f = Q(i,i); // = a1 = AII
123 g = f<1.e-15 ? Sqrt(h) : -Sqrt(h);
124 if (fabs(g) <= EPS) {
125 Done = Standard_False;
128 h -= f*g; // = (v*v)/2 = C1
129 alfaii = g-f; // = v = ALFAII
130 for (j =i+1; j <= n; j++) {
132 for (k = i; k <= l; k++) {
133 scale += Q(k,i)* Q(k,j); // = SCAL
135 cj = (g*Q(i,j) - scale)/h;
136 Q(i,j) = Q(i,j) - alfaii*cj;
137 for(k= i+1; k <= l; k++) {
138 Q(k,j) = Q(k, j) + cj * Q(k,i);
142 // Modification de B:
144 for (j = 1; j <= m; j++) {
145 scale= Q(i,i)*B2(i,j);
146 for (k = i+1; k <= l; k++) {
147 scale += Q(k,i)*B2(k,j);
149 cj = (g*B2(i,j) - scale)/h;
150 B2(i,j) = B2(i,j) - cj*alfaii;
151 for (k = i+1; k <= l; k++) {
152 B2(k,j) = B2(k,j) + cj*Q(k,i);
160 for (j = 1; j <= m; j++) {
161 Sol(n,j) = B2(n,j)/Q(n,n);
162 for (i = n -1; i >=1; i--) {
164 for(k = i+1; k <= n; k++) {
165 scale += Q(i,k) * Sol(k,j);
167 Sol(i,j) = (B2(i,j) - scale)/Q(i,i);
170 Done = Standard_True;
176 void math_Householder::Dump(Standard_OStream& o) const {
178 o <<"math_Householder ";
180 o << " Status = Done \n";
183 o << "Status = not Done \n";