0024624: Lost word in license statement in source files
[occt.git] / src / FEmTool / FEmTool_ProfileMatrix.cxx
CommitLineData
b311480e 1// Created on: 1997-10-31
2// Created by: Roman BORISOV
3// Copyright (c) 1997-1999 Matra Datavision
973c2be1 4// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 5//
973c2be1 6// This file is part of Open CASCADE Technology software library.
b311480e 7//
d5f74e42 8// This library is free software; you can redistribute it and/or modify it under
9// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 10// by the Free Software Foundation, with special exception defined in the file
11// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12// distribution for complete text of the license and disclaimer of any warranty.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
7fd59977 16
17#define No_Standard_RangeError
18#define No_Standard_OutOfRange
19#define No_Standard_DimensionError
20
21#include <FEmTool_ProfileMatrix.ixx>
22#include <gp.hxx>
23
24
25//=======================================================================
26//function : :FEmTool_ProfileMatrix
27//purpose :
28//=======================================================================
b311480e 29FEmTool_ProfileMatrix::FEmTool_ProfileMatrix(const TColStd_Array1OfInteger& FirstIndexes)
7fd59977 30 : profile(1, 2, 1, FirstIndexes.Length())
31{
32 Standard_Integer i, j, k, l;
33 profile(1, 1) = 0;
34 profile(2, 1) = 1;
35 for(i = 2; i <= FirstIndexes.Length(); i++) {
36 profile(1, i) = i - FirstIndexes(i);
37 profile(2, i) = profile(2, i-1) + profile(1, i) + 1;
38 }
39 NextCoeff = new TColStd_HArray1OfInteger(1, profile(2, FirstIndexes.Length()));
40
41 for(i = 1, k = 1; i <= FirstIndexes.Length(); i++)
42 for(j = FirstIndexes(i); j <= i; j++) {
43 for(l = i+1; l <= FirstIndexes.Length() && j < FirstIndexes(l); l++);
44
45 if(l > FirstIndexes.Length()) NextCoeff->SetValue(k, 0);
46 else NextCoeff->SetValue(k, l);
47 k++;
48 }
49
50
51 ProfileMatrix = new TColStd_HArray1OfReal(1, profile(2, FirstIndexes.Length()));
52 SMatrix = new TColStd_HArray1OfReal(1, profile(2, FirstIndexes.Length()));
53 IsDecomp = Standard_False;
54}
55
56//=======================================================================
57//function : Init
58//purpose :
59//=======================================================================
60
61 void FEmTool_ProfileMatrix::Init(const Standard_Real Value)
62{
63 ProfileMatrix->Init(Value);
64 IsDecomp = Standard_False;
65}
66
67//=======================================================================
68//function : ChangeValue
69//purpose :
70//=======================================================================
71
72 Standard_Real& FEmTool_ProfileMatrix::ChangeValue(const Standard_Integer I,
73 const Standard_Integer J)
74{
75 Standard_Integer Ind;
76 Ind = I-J;
77 if (Ind < 0) {
78 Ind = -Ind;
79 Standard_OutOfRange_Raise_if(Ind>profile(1, J),
80 "FEmTool_ProfileMatrix::ChangeValue");
81 Ind = profile(2, J) - Ind;
82 }
83 else {
84 Standard_OutOfRange_Raise_if(Ind>profile(1, I),
85 "FEmTool_ProfileMatrix::ChangeValue");
86 Ind = profile(2, I)-Ind;
87 }
88 return ProfileMatrix->ChangeValue(Ind);
89}
90
91//=======================================================================
92//function : Decompose
93//purpose : Choleski's decomposition
94//=======================================================================
95 Standard_Boolean FEmTool_ProfileMatrix::Decompose()
96{
97 Standard_Integer i, j, k, ik, jk, DiagAddr, CurrAddr, Kmin, Kj;
98 Standard_Real Sum, a, Eps = 1.e-32;
99
100 SMatrix->Init(0.);
101 Standard_Real * SMA = &SMatrix->ChangeValue(1);
102 SMA--;
103 const Standard_Real * PM = &ProfileMatrix->Value(1);
104 PM--;
105
106 for(j = 1; j <= RowNumber(); j++) {
107 DiagAddr = profile(2, j);
108 Kj = j - profile(1, j);
109 Sum = 0;
110 for(k = DiagAddr - profile(1, j); k < DiagAddr; k++)
111 Sum += SMA[k] * SMA[k];
112
113 a = PM[DiagAddr] - Sum;
114 if(a < Eps) {
115 return IsDecomp = Standard_False;// Matrix is not positive defined
116 }
117 a = Sqrt(a);
118 SMA[DiagAddr] = a;
119
120 CurrAddr = DiagAddr;
121 while ((i = NextCoeff->Value(CurrAddr)) > 0) {
122 CurrAddr = profile(2, i) - (i - j);
123
124 // Computation of Sum of S .S for k = 1,..,j-1
125 // ik jk
126 Sum = 0;
127 Kmin = Max((i - profile(1, i)), Kj);
128 ik = profile(2, i) - i + Kmin;
129 jk = DiagAddr - j + Kmin;
130 for(k = Kmin; k <j; k++,ik++,jk++) {
131 Sum += SMA[ik]*SMA[jk];
132 }
133 SMA[CurrAddr] = (PM[CurrAddr] - Sum)/a;
134 }
135 }
136 return IsDecomp = Standard_True;
137}
138
139//=======================================================================
140//function : Solve
141//purpose : Resolution of the system S*t(S)X = B
142//=======================================================================
143 void FEmTool_ProfileMatrix::Solve(const math_Vector& B,math_Vector& X) const
144{
145 if (!IsDecomp) StdFail_NotDone::Raise("Decomposition must be done");
146
147 Standard_Integer i, j, jj,DiagAddr, CurrAddr;
148 Standard_Real Sum;
149
150 Standard_Real * x = &X(X.Lower());
151 x--;
152 Standard_Real * b = &B(B.Lower());
153 b--;
154 const Standard_Real * SMA = &SMatrix->Value(1);
155 SMA --;
156 const Standard_Integer * NC = &NextCoeff->Value(1);
157 NC--;
158
159// Resolution of Sw = B;
160 for(i = 1; i <= RowNumber(); i++) {
161 DiagAddr = profile(2, i);
162 Sum = 0;
163 for(j = i - profile(1, i), jj = DiagAddr - (i - j);
164 j < i; j++, jj++)
165 Sum += SMA[jj]* x[j];
166 x[i] = (b[i] - Sum)/SMA[DiagAddr];
167 }
168
169// Resolution of t(S)X = w;
170 for(i = ColNumber(); i >= 1; i--) {
171 DiagAddr = profile(2, i);
172 j = NC[DiagAddr];
173 Sum = 0;
174 while(j > 0) {
175 CurrAddr = profile(2, j) - (j-i);
176 Sum += SMA[CurrAddr]*x[j];
177 j = NC[CurrAddr];
178 }
179 x[i] = (x[i] - Sum)/SMA[DiagAddr];
180 }
181}
182
183 Standard_Boolean FEmTool_ProfileMatrix::Prepare()
184{
185 Standard_NotImplemented::Raise("FEmTool_ProfileMatrix::Prepare");
186 return Standard_False;
187}
188
189// void FEmTool_ProfileMatrix::Solve(const math_Vector& B,const math_Vector& Init,math_Vector& X,math_Vector& Residual,const Standard_Real Tolerance,const Standard_Integer NbIterations) const
190 void FEmTool_ProfileMatrix::Solve(const math_Vector& ,const math_Vector& ,math_Vector& ,math_Vector& ,const Standard_Real ,const Standard_Integer ) const
191{
192 Standard_NotImplemented::Raise("FEmTool_ProfileMatrix::Solve");
193}
194
195
196//=======================================================================
197//function : Multiplied
198//purpose : MX = H*X
199//=======================================================================
200 void FEmTool_ProfileMatrix::Multiplied(const math_Vector& X,math_Vector& MX) const
201{
202 Standard_Integer i, j, jj, DiagAddr, CurrAddr;
203 Standard_Real * m = &MX(MX.Lower());
204 m--;
205 Standard_Real * x = &X(X.Lower());
206 x--;
207 const Standard_Real * PM = &ProfileMatrix->Value(1);
208 PM--;
209 const Standard_Integer * NC = &NextCoeff->Value(1);
210 NC--;
211
212 for(i = 1; i <= RowNumber(); i++) {
213 DiagAddr = profile(2, i);
214 m[i] = 0;
215 for(j = i - profile(1, i), jj = DiagAddr - (i - j);
216 j <= i; j++, jj++)
217 m[i] += PM[jj]*x[j];
218
219 CurrAddr = DiagAddr;
220 for(j = NC[CurrAddr]; j > 0; j = NC[CurrAddr]) {
221 CurrAddr = profile(2, j) - (j-i);
222 m[i] += PM[CurrAddr]*x[j];
223 }
224 }
225}
226
227 Standard_Integer FEmTool_ProfileMatrix::RowNumber() const
228{
229 return profile.RowLength();
230}
231
232 Standard_Integer FEmTool_ProfileMatrix::ColNumber() const
233{
234 return profile.RowLength();
235}
236
237Standard_Boolean FEmTool_ProfileMatrix::IsInProfile(const Standard_Integer i,
238 const Standard_Integer j) const
239{
240 if (j <= i) {
241 if ((i - j) <= profile(1, i)) return Standard_True;
242 else return Standard_False;
243 }
244 else if ((j - i) <= profile(1, j)) return Standard_True;
245
246 return Standard_False;
247}
248
249 void FEmTool_ProfileMatrix::OutM() const
250{
251 Standard_Integer i, j;
252 cout<<"Matrix A"<<endl;
253 for(i = 1; i <= RowNumber(); i++) {
254 for(j = 1; j < i - profile(1, i); j++)
255 cout<<"0 ";
256
257 for(j = profile(2, i) - profile(1, i); j <= profile(2, i); j++)
258 cout<<ProfileMatrix->Value(j)<<" ";
259 cout<<endl;
260 }
261
262 cout<<"NextCoeff"<<endl;
263 for(i = 1; i <= profile(2, RowNumber()); i++)
264 cout<<NextCoeff->Value(i)<<" ";
265 cout<<endl;
266}
267
268 void FEmTool_ProfileMatrix::OutS() const
269{
270 Standard_Integer i, j;
271 cout<<"Matrix S"<<endl;
272 for(i = 1; i <= RowNumber(); i++) {
273 for(j = 1; j < i - profile(1, i); j++)
274 cout<<"0 ";
275
276 for(j = profile(2, i) - profile(1, i); j <= profile(2, i); j++)
277 cout<<SMatrix->Value(j)<<" ";
278 cout<<endl;
279 }
280}