Back to home page

EIC code displayed by LXR

 
 

    


Warning, /include/opencascade/math_VectorBase.lxx is written in an unsupported language. File is not indexed.

0001 // Copyright (c) 1997-1999 Matra Datavision
0002 // Copyright (c) 1999-2023 OPEN CASCADE SAS
0003 //
0004 // This file is part of Open CASCADE Technology software library.
0005 //
0006 // This library is free software; you can redistribute it and/or modify it under
0007 // the terms of the GNU Lesser General Public License version 2.1 as published
0008 // by the Free Software Foundation, with special exception defined in the file
0009 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
0010 // distribution for complete text of the license and disclaimer of any warranty.
0011 //
0012 // Alternatively, this file may be used under the terms of Open CASCADE
0013 // commercial license or contractual agreement.
0014 
0015 #include <Standard_DimensionError.hxx>
0016 #include <Standard_DivideByZero.hxx>
0017 #include <Standard_RangeError.hxx>
0018 #include <Standard_NullValue.hxx>
0019 
0020 #include <stdio.h>
0021 
0022 template<typename TheItemType>
0023 math_VectorBase<TheItemType>::math_VectorBase(const Standard_Integer theLower,
0024                                               const Standard_Integer theUpper) :
0025   Array(*myBuffer.data(), theLower, theUpper, (theUpper - theLower + 1 <= math_VectorBase::THE_BUFFER_SIZE))
0026 {}
0027 
0028 template<typename TheItemType>
0029 math_VectorBase<TheItemType>::math_VectorBase(const Standard_Integer theLower,
0030                                               const Standard_Integer theUpper,
0031                                               const TheItemType    theInitialValue) :
0032   Array(*myBuffer.data(), theLower, theUpper, (theUpper - theLower + 1 <= math_VectorBase::THE_BUFFER_SIZE))
0033 {
0034   Array.Init(theInitialValue);
0035 }
0036 
0037 template<typename TheItemType>
0038 math_VectorBase<TheItemType>::math_VectorBase(const TheItemType* theTab,
0039                                               const Standard_Integer theLower,
0040                                               const Standard_Integer theUpper) :
0041   Array(*theTab, theLower, theUpper)
0042 {}
0043 
0044 template<typename TheItemType>
0045 math_VectorBase<TheItemType>::math_VectorBase(const gp_XY& theOther) :
0046   Array(*myBuffer.data(), 1, 2)
0047 {
0048   Array(1) = static_cast<TheItemType>(theOther.X());
0049   Array(2) = static_cast<TheItemType>(theOther.Y());
0050 }
0051 
0052 template<typename TheItemType>
0053 math_VectorBase<TheItemType>::math_VectorBase(const gp_XYZ& theOther) :
0054   Array(*myBuffer.data(), 1, 3)
0055 {
0056   Array(1) = static_cast<TheItemType>(theOther.X());
0057   Array(2) = static_cast<TheItemType>(theOther.Y());
0058   Array(3) = static_cast<TheItemType>(theOther.Z());
0059 }
0060 
0061 template<typename TheItemType>
0062 void math_VectorBase<TheItemType>::Init(const TheItemType theInitialValue)
0063 {
0064   Array.Init(theInitialValue);
0065 }
0066 
0067 template<typename TheItemType>
0068 math_VectorBase<TheItemType>::math_VectorBase(const math_VectorBase<TheItemType>& theOther) :
0069   Array(theOther.Array)
0070 {}
0071 
0072 template<typename TheItemType>
0073 void math_VectorBase<TheItemType>::SetLower(const Standard_Integer theLower)
0074 {
0075   Array.UpdateLowerBound(theLower);
0076 }
0077 
0078 template<typename TheItemType>
0079 Standard_Real math_VectorBase<TheItemType>::Norm() const
0080 {
0081   Standard_Real Result = 0;
0082   for (Standard_Integer Index = Lower(); Index <= Upper(); Index++)
0083   {
0084     Result = Result + Array(Index) * Array(Index);
0085   }
0086   return Sqrt(Result);
0087 }
0088 
0089 template<typename TheItemType>
0090 Standard_Real math_VectorBase<TheItemType>::Norm2() const
0091 {
0092   Standard_Real Result = 0;
0093 
0094   for (Standard_Integer Index = Lower(); Index <= Upper(); Index++)
0095   {
0096     Result = Result + Array(Index) * Array(Index);
0097   }
0098   return Result;
0099 }
0100 
0101 template<typename TheItemType>
0102 Standard_Integer math_VectorBase<TheItemType>::Max() const
0103 {
0104   Standard_Integer I = 0;
0105   Standard_Real X = RealFirst();
0106 
0107   for (Standard_Integer Index = Lower(); Index <= Upper(); Index++)
0108   {
0109     if (Array(Index) > X)
0110     {
0111       X = Array(Index);
0112       I = Index;
0113     }
0114   }
0115   return I;
0116 }
0117 
0118 template<typename TheItemType>
0119 Standard_Integer math_VectorBase<TheItemType>::Min() const
0120 {
0121   Standard_Integer I = 0;
0122   Standard_Real X = RealLast();
0123 
0124   for (Standard_Integer Index = Lower(); Index <= Upper(); Index++)
0125   {
0126     if (Array(Index) < X)
0127     {
0128       X = Array(Index);
0129       I = Index;
0130     }
0131   }
0132   return I;
0133 }
0134 
0135 template<typename TheItemType>
0136 void math_VectorBase<TheItemType>::Set(const Standard_Integer theI1,
0137                                        const Standard_Integer theI2,
0138                                        const math_VectorBase<TheItemType>& theV)
0139 {
0140   Standard_RangeError_Raise_if((theI1 < Lower()) || (theI2 > Upper()) \
0141                                || (theI1 > theI2) || (theI2 - theI1 + 1 != theV.Length()), \
0142                                "math_VectorBase::Set() - invalid indices");
0143   Standard_Integer I = theV.Lower();
0144   for (Standard_Integer Index = theI1; Index <= theI2; Index++)
0145   {
0146     Array(Index) = theV.Array(I);
0147     I++;
0148   }
0149 }
0150 
0151 template<typename TheItemType>
0152 void math_VectorBase<TheItemType>::Normalize()
0153 {
0154   Standard_Real Result = Norm();
0155   Standard_NullValue_Raise_if((Result <= RealEpsilon()), \
0156                               "math_VectorBase::Normalize() - vector has zero norm");
0157   for (Standard_Integer Index = Lower(); Index <= Upper(); Index++)
0158   {
0159     Array(Index) = Array(Index) / Result;
0160   }
0161 }
0162 
0163 template<typename TheItemType>
0164 math_VectorBase<TheItemType> math_VectorBase<TheItemType>::Normalized() const
0165 {
0166   math_VectorBase Result = *this;
0167   Result.Normalize();
0168   return Result;
0169 }
0170 
0171 template<typename TheItemType>
0172 void math_VectorBase<TheItemType>::Invert()
0173 {
0174   for (Standard_Integer Index = Lower(); Index <= (Lower() + Length()) >> 1; Index++)
0175   {
0176     Standard_Integer J = Upper() + Lower() - Index;
0177     TheItemType aTemp = Array(Index);
0178     Array(Index) = Array(J);
0179     Array(J) = aTemp;
0180   }
0181 }
0182 
0183 template<typename TheItemType>
0184 math_VectorBase<TheItemType> math_VectorBase<TheItemType>::Inverse() const
0185 {
0186   math_VectorBase Result = *this;
0187   Result.Invert();
0188   return Result;
0189 }
0190 
0191 template<typename TheItemType>
0192 math_VectorBase<TheItemType> math_VectorBase<TheItemType>::Multiplied(const TheItemType theRight) const
0193 {
0194   math_VectorBase Result(Lower(), Upper());
0195   for (Standard_Integer Index = Lower(); Index <= Upper(); Index++)
0196   {
0197     Result.Array(Index) = Array(Index) * theRight;
0198   }
0199   return Result;
0200 }
0201 
0202 template<typename TheItemType>
0203 math_VectorBase<TheItemType> math_VectorBase<TheItemType>::TMultiplied(const TheItemType theRight) const
0204 {
0205   math_VectorBase Result(Lower(), Upper());
0206   for (Standard_Integer Index = Lower(); Index <= Upper(); Index++)
0207   {
0208     Result.Array(Index) = Array(Index) * theRight;
0209   }
0210   return Result;
0211 }
0212 
0213 template<typename TheItemType>
0214 void math_VectorBase<TheItemType>::Multiply(const TheItemType theRight)
0215 {
0216   for (Standard_Integer Index = Lower(); Index <= Upper(); Index++)
0217   {
0218     Array(Index) = Array(Index) * theRight;
0219   }
0220 }
0221 
0222 template<typename TheItemType>
0223 void math_VectorBase<TheItemType>::Divide(const TheItemType theRight)
0224 {
0225   Standard_DivideByZero_Raise_if(Abs(theRight) <= RealEpsilon(), \
0226                                  "math_VectorBase::Divide() - devisor is zero");
0227 
0228   for (Standard_Integer Index = Lower(); Index <= Upper(); Index++)
0229   {
0230     Array(Index) = Array(Index) / theRight;
0231   }
0232 }
0233 
0234 template<typename TheItemType>
0235 math_VectorBase<TheItemType> math_VectorBase<TheItemType>::Divided(const TheItemType theRight) const
0236 {
0237   Standard_DivideByZero_Raise_if(Abs(theRight) <= RealEpsilon(), \
0238                                  "math_VectorBase::Divided() - devisor is zero");
0239   math_VectorBase temp = Multiplied(1. / theRight);
0240   return temp;
0241 }
0242 
0243 template<typename TheItemType>
0244 void math_VectorBase<TheItemType>::Add(const math_VectorBase<TheItemType>& theRight)
0245 {
0246   Standard_DimensionError_Raise_if(Length() != theRight.Length(), \
0247                                    "math_VectorBase::Add() - input vector has wrong dimensions");
0248 
0249   Standard_Integer I = theRight.Lower();
0250   for (Standard_Integer Index = Lower(); Index <= Upper(); Index++)
0251   {
0252     Array(Index) = Array(Index) + theRight.Array(I);
0253     I++;
0254   }
0255 }
0256 
0257 template<typename TheItemType>
0258 math_VectorBase<TheItemType> math_VectorBase<TheItemType>::Added(const math_VectorBase<TheItemType>& theRight) const
0259 {
0260   Standard_DimensionError_Raise_if(Length() != theRight.Length(), \
0261                                    "math_VectorBase::Added() - input vector has wrong dimensions");
0262 
0263   math_VectorBase Result(Lower(), Upper());
0264 
0265   Standard_Integer I = theRight.Lower();
0266   for (Standard_Integer Index = Lower(); Index <= Upper(); Index++)
0267   {
0268     Result.Array(Index) = Array(Index) + theRight.Array(I);
0269     I++;
0270   }
0271   return Result;
0272 }
0273 
0274 template<typename TheItemType>
0275 void math_VectorBase<TheItemType>::Subtract(const math_VectorBase<TheItemType>& theRight)
0276 {
0277   Standard_DimensionError_Raise_if(Length() != theRight.Length(), \
0278                                    "math_VectorBase::Subtract() - input vector has wrong dimensions");
0279 
0280   Standard_Integer I = theRight.Lower();
0281   for (Standard_Integer Index = Lower(); Index <= Upper(); Index++)
0282   {
0283     Array(Index) = Array(Index) - theRight.Array(I);
0284     I++;
0285   }
0286 }
0287 
0288 template<typename TheItemType>
0289 math_VectorBase<TheItemType> math_VectorBase<TheItemType>::Subtracted(const math_VectorBase<TheItemType>& theRight) const
0290 {
0291   Standard_DimensionError_Raise_if(Length() != theRight.Length(), \
0292                                    "math_VectorBase::Subtracted() - input vector has wrong dimensions");
0293 
0294   math_VectorBase Result(Lower(), Upper());
0295 
0296   Standard_Integer I = theRight.Lower();
0297   for (Standard_Integer Index = Lower(); Index <= Upper(); Index++)
0298   {
0299     Result.Array(Index) = Array(Index) - theRight.Array(I);
0300     I++;
0301   }
0302   return Result;
0303 }
0304 
0305 template<typename TheItemType>
0306 math_VectorBase<TheItemType> math_VectorBase<TheItemType>::Slice(const Standard_Integer theI1, const Standard_Integer theI2) const
0307 {
0308   Standard_RangeError_Raise_if((theI1 < Lower()) || (theI1 > Upper()) || (theI2 < Lower()) || (theI2 > Upper()), \
0309                                "math_VectorBase::Slice() - invalid indices");
0310 
0311   if (theI2 >= theI1)
0312   {
0313     math_VectorBase Result(theI1, theI2);
0314     for (Standard_Integer Index = theI1; Index <= theI2; Index++)
0315     {
0316       Result.Array(Index) = Array(Index);
0317     }
0318     return Result;
0319   }
0320   else
0321   {
0322     math_VectorBase Result(theI2, theI1);
0323     for (Standard_Integer Index = theI1; Index >= theI2; Index--)
0324     {
0325       Result.Array(Index) = Array(Index);
0326     }
0327     return Result;
0328   }
0329 }
0330 
0331 template<typename TheItemType>
0332 void math_VectorBase<TheItemType>::Add(const math_VectorBase<TheItemType>& theLeft, const math_VectorBase<TheItemType>& theRight)
0333 {
0334   Standard_DimensionError_Raise_if((Length() != theRight.Length()) || (theRight.Length() != theLeft.Length()), \
0335                                    "math_VectorBase::Add() - input vectors have wrong dimensions");
0336 
0337   Standard_Integer I = theLeft.Lower();
0338   Standard_Integer J = theRight.Lower();
0339   for (Standard_Integer Index = Lower(); Index <= Upper(); Index++)
0340   {
0341     Array(Index) = theLeft.Array(I) + theRight.Array(J);
0342     I++;
0343     J++;
0344   }
0345 }
0346 
0347 template<typename TheItemType>
0348 void math_VectorBase<TheItemType>::Subtract(const math_VectorBase<TheItemType>& theLeft, const math_VectorBase<TheItemType>& theRight)
0349 {
0350   Standard_DimensionError_Raise_if((Length() != theRight.Length()) || (theRight.Length() != theLeft.Length()), \
0351                                    "math_VectorBase::Subtract() - input vectors have wrong dimensions");
0352 
0353   Standard_Integer I = theLeft.Lower();
0354   Standard_Integer J = theRight.Lower();
0355   for (Standard_Integer Index = Lower(); Index <= Upper(); Index++)
0356   {
0357     Array(Index) = theLeft.Array(I) - theRight.Array(J);
0358     I++;
0359     J++;
0360   }
0361 }
0362 
0363 template<typename TheItemType>
0364 void math_VectorBase<TheItemType>::Multiply(const math_Matrix& theLeft, const math_VectorBase<TheItemType>& theRight)
0365 {
0366   Standard_DimensionError_Raise_if((Length() != theLeft.RowNumber()) \
0367                                    || (theLeft.ColNumber() != theRight.Length()), \
0368                                    "math_VectorBase::Multiply() - input matrix and /or vector have wrong dimensions");
0369 
0370   Standard_Integer Index = Lower();
0371   for (Standard_Integer I = theLeft.LowerRowIndex; I <= theLeft.UpperRowIndex; I++)
0372   {
0373     Array(Index) = 0.0;
0374     Standard_Integer K = theRight.Lower();
0375     for (Standard_Integer J = theLeft.LowerColIndex; J <= theLeft.UpperColIndex; J++)
0376     {
0377       Array(Index) = Array(Index) + theLeft.Array(I, J) * theRight.Array(K);
0378       K++;
0379     }
0380     Index++;
0381   }
0382 }
0383 
0384 template<typename TheItemType>
0385 void math_VectorBase<TheItemType>::Multiply(const math_VectorBase<TheItemType>& theLeft, const math_Matrix& theRight)
0386 {
0387   Standard_DimensionError_Raise_if((Length() != theRight.ColNumber()) \
0388                                    || (theLeft.Length() != theRight.RowNumber()), \
0389                                    "math_VectorBase::Multiply() - input matrix and /or vector have wrong dimensions");
0390 
0391   Standard_Integer Index = Lower();
0392   for (Standard_Integer J = theRight.LowerColIndex; J <= theRight.UpperColIndex; J++)
0393   {
0394     Array(Index) = 0.0;
0395     Standard_Integer K = theLeft.Lower();
0396     for (Standard_Integer I = theRight.LowerRowIndex; I <= theRight.UpperRowIndex; I++)
0397     {
0398       Array(Index) = Array(Index) + theLeft.Array(K) * theRight.Array(I, J);
0399       K++;
0400     }
0401     Index++;
0402   }
0403 }
0404 
0405 template<typename TheItemType>
0406 void math_VectorBase<TheItemType>::TMultiply(const math_Matrix& theTLeft, const math_VectorBase<TheItemType>& theRight)
0407 {
0408   Standard_DimensionError_Raise_if((Length() != theTLeft.ColNumber()) \
0409                                    || (theTLeft.RowNumber() != theRight.Length()), \
0410                                    "math_VectorBase::TMultiply() - input matrix and /or vector have wrong dimensions");
0411 
0412   Standard_Integer Index = Lower();
0413   for (Standard_Integer I = theTLeft.LowerColIndex; I <= theTLeft.UpperColIndex; I++)
0414   {
0415     Array(Index) = 0.0;
0416     Standard_Integer K = theRight.Lower();
0417     for (Standard_Integer J = theTLeft.LowerRowIndex; J <= theTLeft.UpperRowIndex; J++)
0418     {
0419       Array(Index) = Array(Index) + theTLeft.Array(J, I) * theRight.Array(K);
0420       K++;
0421     }
0422     Index++;
0423   }
0424 }
0425 
0426 template<typename TheItemType>
0427 void math_VectorBase<TheItemType>::TMultiply(const math_VectorBase<TheItemType>& theLeft, const math_Matrix& theTRight)
0428 {
0429   Standard_DimensionError_Raise_if((Length() != theTRight.RowNumber()) \
0430                                    || (theLeft.Length() != theTRight.ColNumber()), \
0431                                    "math_VectorBase::TMultiply() - input matrix and /or vector have wrong dimensions");
0432 
0433   Standard_Integer Index = Lower();
0434   for (Standard_Integer J = theTRight.LowerRowIndex; J <= theTRight.UpperRowIndex; J++)
0435   {
0436     Array(Index) = 0.0;
0437     Standard_Integer K = theLeft.Lower();
0438     for (Standard_Integer I = theTRight.LowerColIndex;
0439          I <= theTRight.UpperColIndex; I++)
0440     {
0441       Array(Index) = Array(Index) + theLeft.Array(K) * theTRight.Array(J, I);
0442       K++;
0443     }
0444     Index++;
0445   }
0446 }
0447 
0448 template<typename TheItemType>
0449 TheItemType math_VectorBase<TheItemType>::Multiplied(const math_VectorBase<TheItemType>& theRight) const
0450 {
0451   Standard_Real Result = 0;
0452 
0453   Standard_DimensionError_Raise_if(Length() != theRight.Length(), \
0454                                    "math_VectorBase::Multiplied() - input vector has wrong dimensions");
0455 
0456   Standard_Integer I = theRight.Lower();
0457   for (Standard_Integer Index = Lower(); Index <= Upper(); Index++)
0458   {
0459     Result = Result + Array(Index) * theRight.Array(I);
0460     I++;
0461   }
0462   return Result;
0463 }
0464 
0465 template<typename TheItemType>
0466 math_VectorBase<TheItemType> math_VectorBase<TheItemType>::Opposite()
0467 {
0468   math_VectorBase Result(Lower(), Upper());
0469   for (Standard_Integer Index = Lower(); Index <= Upper(); Index++)
0470   {
0471     Result.Array(Index) = -Array(Index);
0472   }
0473   return Result;
0474 }
0475 
0476 template<typename TheItemType>
0477 math_VectorBase<TheItemType> math_VectorBase<TheItemType>::Multiplied(const math_Matrix& theRight)const
0478 {
0479   Standard_DimensionError_Raise_if(Length() != theRight.RowNumber(), \
0480                                    "math_VectorBase::Multiplied() - input matrix has wrong dimensions");
0481 
0482   math_VectorBase Result(theRight.LowerColIndex, theRight.UpperColIndex);
0483   for (Standard_Integer J2 = theRight.LowerColIndex; J2 <= theRight.UpperColIndex; J2++)
0484   {
0485     Result.Array(J2) = 0.0;
0486     Standard_Integer theI2 = theRight.LowerRowIndex;
0487     for (Standard_Integer I = Lower(); I <= Upper(); I++)
0488     {
0489       Result.Array(J2) = Result.Array(J2) + Array(I) * theRight.Array(theI2, J2);
0490       theI2++;
0491     }
0492   }
0493   return Result;
0494 }
0495 
0496 template<typename TheItemType>
0497 void math_VectorBase<TheItemType>::Multiply(const TheItemType theLeft, const math_VectorBase<TheItemType>& theRight)
0498 {
0499   Standard_DimensionError_Raise_if((Length() != theRight.Length()), \
0500                                    "math_VectorBase::Multiply() - input vector has wrong dimensions");
0501   for (Standard_Integer I = Lower(); I <= Upper(); I++)
0502   {
0503     Array(I) = theLeft * theRight.Array(I);
0504   }
0505 }
0506 
0507 template<typename TheItemType>
0508 math_VectorBase<TheItemType>& math_VectorBase<TheItemType>::Initialized(const math_VectorBase<TheItemType>& theOther)
0509 {
0510   Standard_DimensionError_Raise_if(Length() != theOther.Length(), \
0511                                    "math_VectorBase::Initialized() - input vector has wrong dimensions");
0512   memmove(&Array.ChangeFirst(), &theOther.Array.First(), sizeof(TheItemType) * Array.Length());
0513   return *this;
0514 }
0515 
0516 template<typename TheItemType>
0517 void math_VectorBase<TheItemType>::Dump(Standard_OStream& theO) const
0518 {
0519   theO << "math_Vector of Length = " << Length() << "\n";
0520   for (Standard_Integer Index = Lower(); Index <= Upper(); Index++)
0521   {
0522     theO << "math_Vector(" << Index << ") = " << Array(Index) << "\n";
0523   }
0524 }