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 }