db465ebde2ec162174234b3839f52f9de1ec94ee
[occt.git] / src / math / math_Vector.cxx
1 // Copyright (c) 1997-1999 Matra Datavision
2 // Copyright (c) 1999-2012 OPEN CASCADE SAS
3 //
4 // The content of this file is subject to the Open CASCADE Technology Public
5 // License Version 6.5 (the "License"). You may not use the content of this file
6 // except in compliance with the License. Please obtain a copy of the License
7 // at http://www.opencascade.org and read it completely before using this file.
8 //
9 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
10 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
11 //
12 // The Original Code and all software distributed under the License is
13 // distributed on an "AS IS" basis, without warranty of any kind, and the
14 // Initial Developer hereby disclaims all such warranties, including without
15 // limitation, any warranties of merchantability, fitness for a particular
16 // purpose or non-infringement. Please see the License for the specific terms
17 // and conditions governing the rights and limitations under the License.
18
19 //#ifndef DEB
20 #define No_Standard_RangeError
21 #define No_Standard_OutOfRange
22 #define No_Standard_DimensionError
23 //#endif
24
25 #include <stdio.h>
26
27 #include <math_Vector.ixx>
28 #include <math_Matrix.hxx>
29
30 #include <Standard_DimensionError.hxx>
31 #include <Standard_DivideByZero.hxx>
32 #include <Standard_RangeError.hxx>
33 #include <Standard_NullValue.hxx>
34
35
36 math_Vector::math_Vector(const Standard_Integer Lower,
37                          const Standard_Integer Upper):
38                          
39                          LowerIndex(Lower),
40                          UpperIndex(Upper),
41                          Array(Lower,Upper) {
42                            Standard_RangeError_Raise_if(Lower > Upper, "");                    
43                          }
44
45 math_Vector::math_Vector(const Standard_Integer Lower,
46                          const Standard_Integer Upper,
47                          const Standard_Real    InitialValue):
48                          
49                          LowerIndex(Lower),
50                          UpperIndex(Upper),
51                          Array(Lower,Upper) 
52 {
53   Standard_RangeError_Raise_if(Lower > Upper, "");                     
54   Array.Init(InitialValue);
55 }
56
57 math_Vector::math_Vector(const Standard_Address Tab,
58                          const Standard_Integer Lower,
59                          const Standard_Integer Upper) :
60                          
61                          LowerIndex(Lower),
62                          UpperIndex(Upper),
63                          Array(*((const Standard_Real *)Tab), Lower,Upper) 
64 {
65   Standard_RangeError_Raise_if((Lower > Upper) , "");                  
66 }
67
68 void math_Vector::Init(const Standard_Real InitialValue) {
69   Array.Init(InitialValue);
70 }
71
72 math_Vector::math_Vector(const math_Vector& Other): 
73
74 LowerIndex(Other.LowerIndex),
75 UpperIndex(Other.UpperIndex),
76 Array(Other.Array) {}
77
78
79 void math_Vector::SetLower(const Standard_Integer Lower) {
80
81   Array.SetLower(Lower);
82   UpperIndex = UpperIndex - LowerIndex + Lower;
83   LowerIndex = Lower;
84 }
85
86 Standard_Real math_Vector::Norm() const {
87
88   Standard_Real Result = 0;
89
90   for(Standard_Integer Index = LowerIndex; Index <= UpperIndex; Index++) {
91     Result = Result + Array(Index) * Array(Index);
92   }
93   return Sqrt(Result);
94 }
95
96 Standard_Real math_Vector::Norm2() const {
97
98   Standard_Real Result = 0;
99
100   for(Standard_Integer Index = LowerIndex; Index <= UpperIndex; Index++) {
101     Result = Result + Array(Index) * Array(Index);
102   }
103   return Result;
104 }
105
106 Standard_Integer math_Vector::Max() const {
107
108   Standard_Integer I=0;
109   Standard_Real X = RealFirst();
110
111   for(Standard_Integer Index = LowerIndex; Index <= UpperIndex; Index++) {
112     if(Array(Index) > X) {
113       X = Array(Index);
114       I = Index;
115     }
116   }
117   return I;
118 }
119
120 Standard_Integer math_Vector::Min() const {
121
122   Standard_Integer I=0;
123   Standard_Real X = RealLast();
124
125   for(Standard_Integer Index = LowerIndex; Index <= UpperIndex; Index++) {
126     if(Array(Index) < X) {
127       X = Array(Index);
128       I = Index;
129     }
130   }
131   return I;
132 }
133
134 void math_Vector::Set(const Standard_Integer I1, 
135                       const Standard_Integer I2, 
136                       const math_Vector &V) {
137
138   Standard_RangeError_Raise_if((I1 < LowerIndex) || 
139                                (I2 > UpperIndex) || 
140                                (I1 > I2)         ||
141                                (I2 - I1 + 1 != V.Length()), "");
142   
143   Standard_Integer I = V.Lower();
144   for(Standard_Integer Index = I1; Index <= I2; Index++) {
145     Array(Index) = V.Array(I);
146     I++;
147   }
148 }
149
150 void math_Vector::Normalize() {
151
152   Standard_Real Result = Norm();
153   Standard_NullValue_Raise_if((Result <= RealEpsilon()), "");
154   for(Standard_Integer Index = LowerIndex; Index <= UpperIndex; Index++) {
155     Array(Index) = Array(Index) / Result;
156   }
157 }
158
159 math_Vector math_Vector::Normalized() const {
160
161   math_Vector Result = *this;
162
163   Result.Normalize();
164   return Result;
165 }
166
167 void math_Vector::Invert() {
168   Standard_Integer J;
169   Standard_Real Temp;
170   for(Standard_Integer Index = LowerIndex; 
171 //      Index <= LowerIndex + (Length()) >> 1 ; Index++) {
172       Index <= (LowerIndex + Length()) >> 1 ; Index++) {
173     J = UpperIndex + LowerIndex - Index;
174     Temp = Array(Index);
175     Array(Index) = Array(J);
176     Array(J) = Temp;
177   }
178 }
179
180 math_Vector math_Vector::Inverse() const {
181   math_Vector Result = *this;
182   Result.Invert();
183   return Result;
184 }
185
186 math_Vector math_Vector::Multiplied(const Standard_Real Right) const{
187
188   math_Vector Result (LowerIndex, UpperIndex);
189
190   for(Standard_Integer Index = LowerIndex; Index <= UpperIndex; Index++) {
191     Result.Array(Index) = Array(Index) * Right;
192   }
193   return Result;
194 }
195
196 math_Vector math_Vector::TMultiplied(const Standard_Real Right) const{
197
198   math_Vector Result (LowerIndex, UpperIndex);
199
200   for(Standard_Integer Index = LowerIndex; Index <= UpperIndex; Index++) {
201     Result.Array(Index) = Array(Index) * Right;
202   }
203   return Result;
204 }
205
206
207 void math_Vector::Multiply(const Standard_Real Right) {
208
209   for(Standard_Integer Index = LowerIndex; Index <= UpperIndex; Index++) {
210     Array(Index) = Array(Index) * Right;
211   }
212 }
213
214
215 void math_Vector::Divide(const Standard_Real Right) {
216
217   Standard_DivideByZero_Raise_if(Abs(Right) <= RealEpsilon(), "");
218
219   for(Standard_Integer Index =LowerIndex; Index <=UpperIndex; Index++) {
220     Array(Index) = Array(Index) / Right;
221   }
222 }
223
224
225 math_Vector math_Vector::Divided (const Standard_Real Right) const {
226   
227   Standard_DivideByZero_Raise_if(Abs(Right) <= RealEpsilon(), "");
228   math_Vector temp = Multiplied(1./Right);
229   return temp;
230 }
231
232
233 void math_Vector::Add(const math_Vector& Right) {
234
235   Standard_DimensionError_Raise_if(Length() != Right.Length(), "");
236
237   Standard_Integer I = Right.LowerIndex;
238   for(Standard_Integer Index = LowerIndex; Index <= UpperIndex; Index++) {
239     Array(Index) = Array(Index) + Right.Array(I);
240     I++;
241   }
242 }    
243
244 math_Vector math_Vector::Added(const math_Vector& Right) const{
245
246   Standard_DimensionError_Raise_if(Length() != Right.Length(), "");
247
248   math_Vector Result(LowerIndex, UpperIndex);
249   
250   Standard_Integer I = Right.LowerIndex;
251   for(Standard_Integer Index = LowerIndex; Index <= UpperIndex; Index++) {
252     Result.Array(Index) = Array(Index) + Right.Array(I);
253     I++;
254   }
255   return Result;
256 }    
257
258
259
260 void math_Vector::Subtract(const math_Vector& Right) {
261
262   Standard_DimensionError_Raise_if(Length() != Right.Length(), "");
263
264   Standard_Integer I = Right.LowerIndex;
265   for(Standard_Integer Index = LowerIndex; Index <= UpperIndex; Index++) {
266     Array(Index) = Array(Index) - Right.Array(I);
267     I++;
268   }
269 }    
270
271
272 math_Vector math_Vector::Subtracted (const math_Vector& Right) const {
273
274   Standard_DimensionError_Raise_if(Length() != Right.Length(), "");
275   
276   math_Vector Result(LowerIndex, UpperIndex);
277   
278   Standard_Integer I = Right.LowerIndex;
279   for(Standard_Integer Index = LowerIndex; Index <= UpperIndex; Index++) {
280     Result.Array(Index) = Array(Index) - Right.Array(I);
281     I++;
282   }
283   return Result;
284 }    
285
286
287 math_Vector math_Vector::Slice(const Standard_Integer I1, 
288                                const Standard_Integer I2) const 
289 {
290   
291   Standard_RangeError_Raise_if((I1 < LowerIndex) ||
292                                (I1 > UpperIndex) ||
293                                (I2 < LowerIndex) ||
294                                (I2 > UpperIndex) , "");
295   
296
297   if(I2 >= I1) {
298     math_Vector Result(I1, I2);
299     for(Standard_Integer Index = I1; Index <= I2; Index++) {
300       Result.Array(Index) = Array(Index);
301     }        
302     return Result;  
303   }
304   else {
305     math_Vector Result(I2, I1);
306     for(Standard_Integer Index = I1; Index >= I2; Index--) {
307       Result.Array(Index) = Array(Index);
308     }
309     return Result;
310   }   
311 }
312
313
314 void math_Vector::Add (const math_Vector& Left, const math_Vector& Right) {
315
316   Standard_DimensionError_Raise_if((Length() != Right.Length()) ||
317                                    (Right.Length() != Left.Length()), "");
318
319   
320   Standard_Integer I = Left.LowerIndex;
321   Standard_Integer J = Right.LowerIndex;
322   for(Standard_Integer Index = LowerIndex; Index <= UpperIndex; Index++) {
323     Array(Index) = Left.Array(I) + Right.Array(J);
324     I++;
325     J++;
326   }
327 }    
328
329 void math_Vector::Subtract (const math_Vector& Left, 
330                             const math_Vector& Right) {
331
332   Standard_DimensionError_Raise_if((Length() != Right.Length()) ||
333                                    (Right.Length() != Left.Length()), "");
334   
335   Standard_Integer I = Left.LowerIndex;
336   Standard_Integer J = Right.LowerIndex;
337   for(Standard_Integer Index = LowerIndex; Index <= UpperIndex; Index++) {
338     Array(Index) = Left.Array(I) - Right.Array(J);
339     I++;
340     J++;
341   }
342 }    
343
344 void math_Vector::Multiply(const math_Matrix& Left, 
345                            const math_Vector& Right) {
346
347   Standard_DimensionError_Raise_if((Length() != Left.RowNumber()) ||
348                                    (Left.ColNumber() != Right.Length()),
349                                    "");
350
351   Standard_Integer Index = LowerIndex;
352   for(Standard_Integer I = Left.LowerRowIndex; I <= Left.UpperRowIndex; I++) {
353     Array(Index) = 0.0;
354     Standard_Integer K = Right.LowerIndex;
355     for(Standard_Integer J = Left.LowerColIndex; J <= Left.UpperColIndex; J++) {
356       Array(Index) = Array(Index) + Left.Array(I, J) * Right.Array(K);
357       K++;
358     }
359     Index++;
360   }
361 }    
362
363 void math_Vector::Multiply(const math_Vector& Left,
364                            const math_Matrix& Right) {
365
366   Standard_DimensionError_Raise_if((Length() != Right.ColNumber()) ||
367                                    (Left.Length() != Right.RowNumber()),
368                                    "");
369
370   Standard_Integer Index = LowerIndex;
371   for(Standard_Integer J = Right.LowerColIndex; J <= Right.UpperColIndex; J++) {
372     Array(Index) = 0.0;
373     Standard_Integer K = Left.LowerIndex;
374     for(Standard_Integer I = Right.LowerRowIndex; I <= Right.UpperRowIndex; I++) {
375       Array(Index) = Array(Index) + Left.Array(K) * Right.Array(I, J);
376       K++;
377     }
378     Index++;
379   }
380 }    
381
382 void math_Vector::TMultiply(const math_Matrix& TLeft,
383                             const math_Vector&  Right) {
384
385   Standard_DimensionError_Raise_if((Length() != TLeft.ColNumber()) ||
386                                    (TLeft.RowNumber() != Right.Length()),
387                                    "");
388
389   Standard_Integer Index = LowerIndex;
390   for(Standard_Integer I = TLeft.LowerColIndex; I <= TLeft.UpperColIndex; I++) {
391     Array(Index) = 0.0;
392     Standard_Integer K = Right.LowerIndex;
393     for(Standard_Integer J = TLeft.LowerRowIndex; J <= TLeft.UpperRowIndex; J++) {
394       Array(Index) = Array(Index) + TLeft.Array(J, I) * Right.Array(K);
395       K++;
396     }
397     Index++;
398   }
399 }    
400
401 void math_Vector::TMultiply(const math_Vector&  Left,
402                             const math_Matrix& TRight) {
403
404   Standard_DimensionError_Raise_if((Length() != TRight.RowNumber()) ||
405                                    (Left.Length() != TRight.ColNumber()),
406                                    "");
407
408   Standard_Integer Index = LowerIndex;
409   for(Standard_Integer J = TRight.LowerRowIndex; J <= TRight.UpperRowIndex; J++) {
410     Array(Index) = 0.0;
411     Standard_Integer K = Left.LowerIndex;
412     for(Standard_Integer I = TRight.LowerColIndex; 
413         I <= TRight.UpperColIndex; I++) {
414       Array(Index) = Array(Index) + Left.Array(K) * TRight.Array(J, I);
415       K++;
416     }
417     Index++;
418   }
419 }    
420
421
422
423
424 Standard_Real math_Vector::Multiplied(const math_Vector& Right) const{
425   Standard_Real Result = 0;
426
427   Standard_DimensionError_Raise_if(Length() != Right.Length(), "");
428
429   Standard_Integer I = Right.LowerIndex;
430   for(Standard_Integer Index = LowerIndex; Index <= UpperIndex; Index++) {
431     Result = Result + Array(Index) * Right.Array(I);
432     I++;
433   }
434   return Result;
435 }    
436
437 math_Vector math_Vector::Opposite() {
438   math_Vector Result(LowerIndex, UpperIndex);
439
440   for(Standard_Integer Index = LowerIndex; Index <= UpperIndex; Index++) {
441     Result.Array(Index) = - Array(Index);
442   }
443   return Result;
444 }    
445
446 math_Vector math_Vector::Multiplied(const math_Matrix& Right)const {    
447   Standard_DimensionError_Raise_if(Length() != Right.RowNumber(), "");
448
449   math_Vector Result(Right.LowerColIndex, Right.UpperColIndex);
450   for(Standard_Integer J2 = Right.LowerColIndex; 
451       J2 <= Right.UpperColIndex; J2++) {
452     Array(J2) = 0.0;
453     Standard_Integer I2 = Right.LowerRowIndex;
454     for(Standard_Integer I = LowerIndex; I <= UpperIndex; I++) {
455       Result.Array(J2) = Result.Array(J2) + Array(I) * 
456         Right.Array(I2, J2);
457       I2++;
458     }
459   }
460   return Result;
461 }    
462
463
464 void math_Vector::Multiply(const Standard_Real Left,
465                            const math_Vector& Right) 
466 {
467   Standard_DimensionError_Raise_if((Length() != Right.Length()),
468                                    "");
469   for(Standard_Integer I = LowerIndex; I <= UpperIndex; I++) {
470     Array(I) = Left * Right.Array(I);
471   }
472 }
473
474
475 math_Vector& math_Vector::Initialized(const math_Vector& Other) {
476
477   Standard_DimensionError_Raise_if(Length() != Other.Length(), "");
478   
479   (Other.Array).Copy(Array);
480   return *this;
481 }
482
483
484
485 void math_Vector::Dump(Standard_OStream& o) const
486 {
487   o << "math_Vector of Length = " << Length() << "\n";
488   for(Standard_Integer Index = LowerIndex; 
489       Index <= UpperIndex; Index++) {
490     o << "math_Vector(" << Index << ") = " << Array(Index) << "\n";
491   }
492 }