0028550: Foundation Classes - fix empty message passed to thrown exception
[occt.git] / src / math / math_Vector.cxx
1 // Copyright (c) 1997-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 //
4 // This file is part of Open CASCADE Technology software library.
5 //
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.
11 //
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
14
15 #include <stdio.h>
16
17 #include <math_Vector.hxx>
18 #include <math_Matrix.hxx>
19
20 #include <Standard_DimensionError.hxx>
21 #include <Standard_DivideByZero.hxx>
22 #include <Standard_RangeError.hxx>
23 #include <Standard_NullValue.hxx>
24
25 math_Vector::math_Vector(const Standard_Integer theLower, const Standard_Integer theUpper) :
26   LowerIndex(theLower),
27   UpperIndex(theUpper),
28   Array(theLower,theUpper)
29 {
30   Standard_RangeError_Raise_if (theLower > theUpper, "math_Vector() - invalid dimensions");
31 }
32
33 math_Vector::math_Vector(const Standard_Integer theLower,
34                          const Standard_Integer theUpper,
35                          const Standard_Real    theInitialValue):
36   LowerIndex(theLower),
37   UpperIndex(theUpper),
38   Array(theLower,theUpper)
39 {
40   Standard_RangeError_Raise_if (theLower > theUpper, "math_Vector() - invalid dimensions");
41   Array.Init(theInitialValue);
42 }
43
44 math_Vector::math_Vector(const Standard_Address theTab,
45                          const Standard_Integer theLower,
46                          const Standard_Integer theUpper) :
47   LowerIndex(theLower),
48   UpperIndex(theUpper),
49   Array(theTab, theLower,theUpper)
50 {
51   Standard_RangeError_Raise_if ((theLower > theUpper), "math_Vector() - invalid dimensions");
52 }
53
54 math_Vector::math_Vector(const gp_XY& theOther):
55   LowerIndex(1),
56   UpperIndex(2),
57   Array(1,2)
58 {
59   Array(1) = theOther.X();
60   Array(2) = theOther.Y();
61 }
62
63 math_Vector::math_Vector(const gp_XYZ& theOther):
64   LowerIndex(1),
65   UpperIndex(3),
66   Array(1, 3)
67 {
68   Array(1) = theOther.X();
69   Array(2) = theOther.Y();
70   Array(3) = theOther.Z();
71 }
72
73 void math_Vector::Init(const Standard_Real theInitialValue)
74 {
75   Array.Init(theInitialValue);
76 }
77
78 math_Vector::math_Vector(const math_Vector& theOther) :
79   LowerIndex(theOther.LowerIndex),
80   UpperIndex(theOther.UpperIndex),
81   Array(theOther.Array)
82 {
83 }
84
85 void math_Vector::SetLower(const Standard_Integer theLower)
86 {
87   Array.SetLower(theLower);
88   UpperIndex = UpperIndex - LowerIndex + theLower;
89   LowerIndex = theLower;
90 }
91
92 Standard_Real math_Vector::Norm() const
93 {
94   Standard_Real Result = 0;
95
96   for(Standard_Integer Index = LowerIndex; Index <= UpperIndex; Index++)
97   {
98     Result = Result + Array(Index) * Array(Index);
99   }
100   return Sqrt(Result);
101 }
102
103 Standard_Real math_Vector::Norm2() const
104 {
105   Standard_Real Result = 0;
106
107   for(Standard_Integer Index = LowerIndex; Index <= UpperIndex; Index++)
108   {
109     Result = Result + Array(Index) * Array(Index);
110   }
111   return Result;
112 }
113
114 Standard_Integer math_Vector::Max() const
115 {
116   Standard_Integer I=0;
117   Standard_Real X = RealFirst();
118
119   for(Standard_Integer Index = LowerIndex; Index <= UpperIndex; Index++)
120   {
121     if(Array(Index) > X)
122     {
123       X = Array(Index);
124       I = Index;
125     }
126   }
127   return I;
128 }
129
130 Standard_Integer math_Vector::Min() const
131 {
132   Standard_Integer I=0;
133   Standard_Real X = RealLast();
134
135   for(Standard_Integer Index = LowerIndex; Index <= UpperIndex; Index++)
136   {
137     if(Array(Index) < X)
138     {
139       X = Array(Index);
140       I = Index;
141     }
142   }
143   return I;
144 }
145
146 void math_Vector::Set(const Standard_Integer theI1,
147                       const Standard_Integer theI2,
148                       const math_Vector &theV)
149 {
150   Standard_RangeError_Raise_if ((theI1 < LowerIndex) || (theI2 > UpperIndex)
151                              || (theI1 > theI2) || (theI2 - theI1 + 1 != theV.Length()),
152                                 "math_Vector::Set() - invalid indices");
153
154   Standard_Integer I = theV.Lower();
155   for(Standard_Integer Index = theI1; Index <= theI2; Index++)
156   {
157     Array(Index) = theV.Array(I);
158     I++;
159   }
160 }
161
162 void math_Vector::Normalize()
163 {
164   Standard_Real Result = Norm();
165   Standard_NullValue_Raise_if ((Result <= RealEpsilon()),
166                                 "math_Vector::Normalize() - vector has zero norm");
167   for(Standard_Integer Index = LowerIndex; Index <= UpperIndex; Index++)
168   {
169     Array(Index) = Array(Index) / Result;
170   }
171 }
172
173 math_Vector math_Vector::Normalized() const
174 {
175   math_Vector Result = *this;
176
177   Result.Normalize();
178   return Result;
179 }
180
181 void math_Vector::Invert()
182 {
183   Standard_Integer J;
184   Standard_Real Temp;
185   for(Standard_Integer Index = LowerIndex; Index <= (LowerIndex + Length()) >> 1 ; Index++)
186   {
187     J = UpperIndex + LowerIndex - Index;
188     Temp = Array(Index);
189     Array(Index) = Array(J);
190     Array(J) = Temp;
191   }
192 }
193
194 math_Vector math_Vector::Inverse() const
195 {
196   math_Vector Result = *this;
197   Result.Invert();
198   return Result;
199 }
200
201 math_Vector math_Vector::Multiplied(const Standard_Real theRight) const
202 {
203   math_Vector Result (LowerIndex, UpperIndex);
204
205   for(Standard_Integer Index = LowerIndex; Index <= UpperIndex; Index++)
206   {
207     Result.Array(Index) = Array(Index) * theRight;
208   }
209   return Result;
210 }
211
212 math_Vector math_Vector::TMultiplied(const Standard_Real theRight) const
213 {
214   math_Vector Result (LowerIndex, UpperIndex);
215
216   for(Standard_Integer Index = LowerIndex; Index <= UpperIndex; Index++)
217   {
218     Result.Array(Index) = Array(Index) * theRight;
219   }
220   return Result;
221 }
222
223 void math_Vector::Multiply(const Standard_Real theRight)
224 {
225   for(Standard_Integer Index = LowerIndex; Index <= UpperIndex; Index++)
226   {
227     Array(Index) = Array(Index) * theRight;
228   }
229 }
230
231 void math_Vector::Divide(const Standard_Real theRight)
232 {
233   Standard_DivideByZero_Raise_if (Abs(theRight) <= RealEpsilon(),
234                                   "math_Vector::Divide() - devisor is zero");
235
236   for(Standard_Integer Index =LowerIndex; Index <=UpperIndex; Index++)
237   {
238     Array(Index) = Array(Index) / theRight;
239   }
240 }
241
242 math_Vector math_Vector::Divided (const Standard_Real theRight) const
243 {
244   Standard_DivideByZero_Raise_if (Abs(theRight) <= RealEpsilon(),
245                                   "math_Vector::Divided() - devisor is zero");
246   math_Vector temp = Multiplied(1./theRight);
247   return temp;
248 }
249
250 void math_Vector::Add(const math_Vector& theRight)
251 {
252   Standard_DimensionError_Raise_if (Length() != theRight.Length(),
253                                     "math_Vector::Add() - input vector has wrong dimensions");
254
255   Standard_Integer I = theRight.LowerIndex;
256   for(Standard_Integer Index = LowerIndex; Index <= UpperIndex; Index++)
257   {
258     Array(Index) = Array(Index) + theRight.Array(I);
259     I++;
260   }
261 }
262
263 math_Vector math_Vector::Added(const math_Vector& theRight) const
264 {
265   Standard_DimensionError_Raise_if (Length() != theRight.Length(),
266                                     "math_Vector::Added() - input vector has wrong dimensions");
267
268   math_Vector Result(LowerIndex, UpperIndex);
269
270   Standard_Integer I = theRight.LowerIndex;
271   for(Standard_Integer Index = LowerIndex; Index <= UpperIndex; Index++)
272   {
273     Result.Array(Index) = Array(Index) + theRight.Array(I);
274     I++;
275   }
276   return Result;
277 }
278
279 void math_Vector::Subtract(const math_Vector& theRight)
280 {
281   Standard_DimensionError_Raise_if (Length() != theRight.Length(),
282                                     "math_Vector::Subtract() - input vector has wrong dimensions");
283
284   Standard_Integer I = theRight.LowerIndex;
285   for(Standard_Integer Index = LowerIndex; Index <= UpperIndex; Index++)
286   {
287     Array(Index) = Array(Index) - theRight.Array(I);
288     I++;
289   }
290 }
291
292 math_Vector math_Vector::Subtracted (const math_Vector& theRight) const
293 {
294   Standard_DimensionError_Raise_if (Length() != theRight.Length(),
295                                     "math_Vector::Subtracted() - input vector has wrong dimensions");
296
297   math_Vector Result(LowerIndex, UpperIndex);
298
299   Standard_Integer I = theRight.LowerIndex;
300   for(Standard_Integer Index = LowerIndex; Index <= UpperIndex; Index++)
301   {
302     Result.Array(Index) = Array(Index) - theRight.Array(I);
303     I++;
304   }
305   return Result;
306 }
307
308 math_Vector math_Vector::Slice(const Standard_Integer theI1, const Standard_Integer theI2) const
309 {
310   Standard_RangeError_Raise_if ((theI1 < LowerIndex) || (theI1 > UpperIndex) || (theI2 < LowerIndex) || (theI2 > UpperIndex),
311                                 "math_Vector::Slice() - invalid indices");
312
313   if(theI2 >= theI1)
314   {
315     math_Vector Result(theI1, theI2);
316     for(Standard_Integer Index = theI1; Index <= theI2; Index++)
317     {
318       Result.Array(Index) = Array(Index);
319     }
320     return Result;
321   }
322   else
323   {
324     math_Vector Result(theI2, theI1);
325     for(Standard_Integer Index = theI1; Index >= theI2; Index--)
326     {
327       Result.Array(Index) = Array(Index);
328     }
329     return Result;
330   }
331 }
332
333 void math_Vector::Add (const math_Vector& theLeft, const math_Vector& theRight)
334 {
335   Standard_DimensionError_Raise_if ((Length() != theRight.Length()) || (theRight.Length() != theLeft.Length()),
336                                     "math_Vector::Add() - input vectors have wrong dimensions");
337
338   Standard_Integer I = theLeft.LowerIndex;
339   Standard_Integer J = theRight.LowerIndex;
340   for(Standard_Integer Index = LowerIndex; Index <= UpperIndex; Index++)
341   {
342     Array(Index) = theLeft.Array(I) + theRight.Array(J);
343     I++;
344     J++;
345   }
346 }
347
348 void math_Vector::Subtract (const math_Vector& theLeft, const math_Vector& theRight)
349 {
350   Standard_DimensionError_Raise_if ((Length() != theRight.Length()) || (theRight.Length() != theLeft.Length()),
351                                      "math_Vector::Subtract() - input vectors have wrong dimensions");
352
353   Standard_Integer I = theLeft.LowerIndex;
354   Standard_Integer J = theRight.LowerIndex;
355   for(Standard_Integer Index = LowerIndex; Index <= UpperIndex; Index++)
356   {
357     Array(Index) = theLeft.Array(I) - theRight.Array(J);
358     I++;
359     J++;
360   }
361 }
362
363 void math_Vector::Multiply(const math_Matrix& theLeft, const math_Vector& theRight)
364 {
365   Standard_DimensionError_Raise_if ((Length() != theLeft.RowNumber())
366                                  || (theLeft.ColNumber() != theRight.Length()),
367                                     "math_Vector::Multiply() - input matrix and/or vector have wrong dimensions");
368
369   Standard_Integer Index = LowerIndex;
370   for(Standard_Integer I = theLeft.LowerRowIndex; I <= theLeft.UpperRowIndex; I++)
371   {
372     Array(Index) = 0.0;
373     Standard_Integer K = theRight.LowerIndex;
374     for(Standard_Integer J = theLeft.LowerColIndex; J <= theLeft.UpperColIndex; J++)
375     {
376       Array(Index) = Array(Index) + theLeft.Array(I, J) * theRight.Array(K);
377       K++;
378     }
379     Index++;
380   }
381 }
382
383 void math_Vector::Multiply(const math_Vector& theLeft, const math_Matrix& theRight)
384 {
385   Standard_DimensionError_Raise_if ((Length() != theRight.ColNumber())
386                                  || (theLeft.Length() != theRight.RowNumber()),
387                                     "math_Vector::Multiply() - input matrix and/or vector have wrong dimensions");
388
389   Standard_Integer Index = LowerIndex;
390   for(Standard_Integer J = theRight.LowerColIndex; J <= theRight.UpperColIndex; J++)
391   {
392     Array(Index) = 0.0;
393     Standard_Integer K = theLeft.LowerIndex;
394     for(Standard_Integer I = theRight.LowerRowIndex; I <= theRight.UpperRowIndex; I++)
395     {
396       Array(Index) = Array(Index) + theLeft.Array(K) * theRight.Array(I, J);
397       K++;
398     }
399     Index++;
400   }
401 }
402
403 void math_Vector::TMultiply(const math_Matrix& theTLeft, const math_Vector&  theRight)
404 {
405   Standard_DimensionError_Raise_if ((Length() != theTLeft.ColNumber())
406                                  || (theTLeft.RowNumber() != theRight.Length()),
407                                     "math_Vector::TMultiply() - input matrix and/or vector have wrong dimensions");
408
409   Standard_Integer Index = LowerIndex;
410   for(Standard_Integer I = theTLeft.LowerColIndex; I <= theTLeft.UpperColIndex; I++)
411   {
412     Array(Index) = 0.0;
413     Standard_Integer K = theRight.LowerIndex;
414     for(Standard_Integer J = theTLeft.LowerRowIndex; J <= theTLeft.UpperRowIndex; J++)
415     {
416       Array(Index) = Array(Index) + theTLeft.Array(J, I) * theRight.Array(K);
417       K++;
418     }
419     Index++;
420   }
421 }
422
423 void math_Vector::TMultiply(const math_Vector&  theLeft, const math_Matrix& theTRight)
424 {
425   Standard_DimensionError_Raise_if ((Length() != theTRight.RowNumber())
426                                  || (theLeft.Length() != theTRight.ColNumber()),
427                                     "math_Vector::TMultiply() - input matrix and/or vector have wrong dimensions");
428
429   Standard_Integer Index = LowerIndex;
430   for(Standard_Integer J = theTRight.LowerRowIndex; J <= theTRight.UpperRowIndex; J++)
431   {
432     Array(Index) = 0.0;
433     Standard_Integer K = theLeft.LowerIndex;
434     for(Standard_Integer I = theTRight.LowerColIndex;
435       I <= theTRight.UpperColIndex; I++)
436     {
437         Array(Index) = Array(Index) + theLeft.Array(K) * theTRight.Array(J, I);
438         K++;
439     }
440     Index++;
441   }
442 }
443
444 Standard_Real math_Vector::Multiplied(const math_Vector& theRight) const
445 {
446   Standard_Real Result = 0;
447
448   Standard_DimensionError_Raise_if (Length() != theRight.Length(),
449                                     "math_Vector::Multiplied() - input vector has wrong dimensions");
450
451   Standard_Integer I = theRight.LowerIndex;
452   for(Standard_Integer Index = LowerIndex; Index <= UpperIndex; Index++)
453   {
454     Result = Result + Array(Index) * theRight.Array(I);
455     I++;
456   }
457   return Result;
458 }
459
460 math_Vector math_Vector::Opposite()
461 {
462   math_Vector Result(LowerIndex, UpperIndex);
463
464   for(Standard_Integer Index = LowerIndex; Index <= UpperIndex; Index++)
465   {
466     Result.Array(Index) = - Array(Index);
467   }
468   return Result;
469 }
470
471 math_Vector math_Vector::Multiplied(const math_Matrix& theRight)const
472 {
473   Standard_DimensionError_Raise_if (Length() != theRight.RowNumber(),
474                                     "math_Vector::Multiplied() - input matrix has wrong dimensions");
475
476   math_Vector Result(theRight.LowerColIndex, theRight.UpperColIndex);
477   for(Standard_Integer J2 = theRight.LowerColIndex; J2 <= theRight.UpperColIndex; J2++)
478   {
479       Array(J2) = 0.0;
480       Standard_Integer theI2 = theRight.LowerRowIndex;
481       for(Standard_Integer I = LowerIndex; I <= UpperIndex; I++)
482       {
483         Result.Array(J2) = Result.Array(J2) + Array(I) * theRight.Array(theI2, J2);
484         theI2++;
485       }
486   }
487   return Result;
488 }
489
490 void math_Vector::Multiply(const Standard_Real theLeft, const math_Vector& theRight)
491 {
492   Standard_DimensionError_Raise_if ((Length() != theRight.Length()),
493                                     "math_Vector::Multiply() - input vector has wrong dimensions");
494   for(Standard_Integer I = LowerIndex; I <= UpperIndex; I++)
495   {
496     Array(I) = theLeft * theRight.Array(I);
497   }
498 }
499
500 math_Vector& math_Vector::Initialized(const math_Vector& theOther)
501 {
502   Standard_DimensionError_Raise_if (Length() != theOther.Length(),
503                                     "math_Vector::Initialized() - input vector has wrong dimensions");
504
505   (theOther.Array).Copy(Array);
506   return *this;
507 }
508
509 void math_Vector::Dump(Standard_OStream& theO) const
510 {
511   theO << "math_Vector of Length = " << Length() << "\n";
512   for(Standard_Integer Index = LowerIndex; Index <= UpperIndex; Index++)
513   {
514     theO << "math_Vector(" << Index << ") = " << Array(Index) << "\n";
515   }
516 }
517