mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-07-30 13:05:50 +03:00
math_Vector::Multiplied() - fixed modification of original array. math_SVD::Solve(), math_SVD::PseudoInverse(), GeomFill_LocationGuide::InitX() - removed incorrect constness. math_Vector, math_IntegerVector - math_SingleTab has been replaced by NCollection_LocalArray+NCollection_Array1. Added accessors returning const value.
503 lines
15 KiB
C++
503 lines
15 KiB
C++
// Copyright (c) 1997-1999 Matra Datavision
|
|
// Copyright (c) 1999-2014 OPEN CASCADE SAS
|
|
//
|
|
// This file is part of Open CASCADE Technology software library.
|
|
//
|
|
// This library is free software; you can redistribute it and/or modify it under
|
|
// the terms of the GNU Lesser General Public License version 2.1 as published
|
|
// by the Free Software Foundation, with special exception defined in the file
|
|
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
|
// distribution for complete text of the license and disclaimer of any warranty.
|
|
//
|
|
// Alternatively, this file may be used under the terms of Open CASCADE
|
|
// commercial license or contractual agreement.
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <math_Vector.hxx>
|
|
#include <math_Matrix.hxx>
|
|
|
|
#include <Standard_DimensionError.hxx>
|
|
#include <Standard_DivideByZero.hxx>
|
|
#include <Standard_RangeError.hxx>
|
|
#include <Standard_NullValue.hxx>
|
|
|
|
math_Vector::math_Vector(const Standard_Integer theLower, const Standard_Integer theUpper)
|
|
: myLocArray (theUpper - theLower + 1),
|
|
Array (myLocArray[0], theLower, theUpper)
|
|
{
|
|
//
|
|
}
|
|
|
|
math_Vector::math_Vector(const Standard_Integer theLower,
|
|
const Standard_Integer theUpper,
|
|
const Standard_Real theInitialValue)
|
|
: myLocArray (theUpper - theLower + 1),
|
|
Array (myLocArray[0], theLower, theUpper)
|
|
{
|
|
Array.Init(theInitialValue);
|
|
}
|
|
|
|
math_Vector::math_Vector(const Standard_Real* theTab,
|
|
const Standard_Integer theLower,
|
|
const Standard_Integer theUpper)
|
|
: Array (*theTab, theLower, theUpper)
|
|
{
|
|
Standard_RangeError_Raise_if ((theLower > theUpper), "math_Vector() - invalid dimensions");
|
|
}
|
|
|
|
math_Vector::math_Vector (const gp_XY& theOther)
|
|
: myLocArray (2),
|
|
Array (myLocArray[0], 1,2)
|
|
{
|
|
Array(1) = theOther.X();
|
|
Array(2) = theOther.Y();
|
|
}
|
|
|
|
math_Vector::math_Vector (const gp_XYZ& theOther)
|
|
: myLocArray (3),
|
|
Array (myLocArray[0], 1, 3)
|
|
{
|
|
Array(1) = theOther.X();
|
|
Array(2) = theOther.Y();
|
|
Array(3) = theOther.Z();
|
|
}
|
|
|
|
void math_Vector::Init(const Standard_Real theInitialValue)
|
|
{
|
|
Array.Init(theInitialValue);
|
|
}
|
|
|
|
math_Vector::math_Vector (const math_Vector& theOther)
|
|
: myLocArray (theOther.Length()),
|
|
Array (myLocArray[0], theOther.Lower(), theOther.Upper())
|
|
{
|
|
memcpy (&myLocArray[0], &theOther.Array.First(), sizeof(Standard_Real) * theOther.Length());
|
|
}
|
|
|
|
void math_Vector::SetLower(const Standard_Integer theLower)
|
|
{
|
|
Array.Resize (theLower, Array.Upper() - Array.Lower() + theLower, Standard_False);
|
|
}
|
|
|
|
Standard_Real math_Vector::Norm() const
|
|
{
|
|
Standard_Real Result = 0;
|
|
|
|
for(Standard_Integer Index = Lower(); Index <= Upper(); Index++)
|
|
{
|
|
Result = Result + Array(Index) * Array(Index);
|
|
}
|
|
return Sqrt(Result);
|
|
}
|
|
|
|
Standard_Real math_Vector::Norm2() const
|
|
{
|
|
Standard_Real Result = 0;
|
|
|
|
for(Standard_Integer Index = Lower(); Index <= Upper(); Index++)
|
|
{
|
|
Result = Result + Array(Index) * Array(Index);
|
|
}
|
|
return Result;
|
|
}
|
|
|
|
Standard_Integer math_Vector::Max() const
|
|
{
|
|
Standard_Integer I=0;
|
|
Standard_Real X = RealFirst();
|
|
|
|
for(Standard_Integer Index = Lower(); Index <= Upper(); Index++)
|
|
{
|
|
if(Array(Index) > X)
|
|
{
|
|
X = Array(Index);
|
|
I = Index;
|
|
}
|
|
}
|
|
return I;
|
|
}
|
|
|
|
Standard_Integer math_Vector::Min() const
|
|
{
|
|
Standard_Integer I=0;
|
|
Standard_Real X = RealLast();
|
|
|
|
for(Standard_Integer Index = Lower(); Index <= Upper(); Index++)
|
|
{
|
|
if(Array(Index) < X)
|
|
{
|
|
X = Array(Index);
|
|
I = Index;
|
|
}
|
|
}
|
|
return I;
|
|
}
|
|
|
|
void math_Vector::Set(const Standard_Integer theI1,
|
|
const Standard_Integer theI2,
|
|
const math_Vector &theV)
|
|
{
|
|
Standard_RangeError_Raise_if ((theI1 < Lower()) || (theI2 > Upper())
|
|
|| (theI1 > theI2) || (theI2 - theI1 + 1 != theV.Length()),
|
|
"math_Vector::Set() - invalid indices");
|
|
|
|
Standard_Integer I = theV.Lower();
|
|
for(Standard_Integer Index = theI1; Index <= theI2; Index++)
|
|
{
|
|
Array(Index) = theV.Array(I);
|
|
I++;
|
|
}
|
|
}
|
|
|
|
void math_Vector::Normalize()
|
|
{
|
|
Standard_Real Result = Norm();
|
|
Standard_NullValue_Raise_if ((Result <= RealEpsilon()),
|
|
"math_Vector::Normalize() - vector has zero norm");
|
|
for(Standard_Integer Index = Lower(); Index <= Upper(); Index++)
|
|
{
|
|
Array(Index) = Array(Index) / Result;
|
|
}
|
|
}
|
|
|
|
math_Vector math_Vector::Normalized() const
|
|
{
|
|
math_Vector Result = *this;
|
|
|
|
Result.Normalize();
|
|
return Result;
|
|
}
|
|
|
|
void math_Vector::Invert()
|
|
{
|
|
for(Standard_Integer Index = Lower(); Index <= (Lower() + Length()) >> 1 ; Index++)
|
|
{
|
|
Standard_Integer J = Upper() + Lower() - Index;
|
|
Standard_Real aTemp = Array(Index);
|
|
Array(Index) = Array(J);
|
|
Array(J) = aTemp;
|
|
}
|
|
}
|
|
|
|
math_Vector math_Vector::Inverse() const
|
|
{
|
|
math_Vector Result = *this;
|
|
Result.Invert();
|
|
return Result;
|
|
}
|
|
|
|
math_Vector math_Vector::Multiplied(const Standard_Real theRight) const
|
|
{
|
|
math_Vector Result (Lower(), Upper());
|
|
for(Standard_Integer Index = Lower(); Index <= Upper(); Index++)
|
|
{
|
|
Result.Array(Index) = Array(Index) * theRight;
|
|
}
|
|
return Result;
|
|
}
|
|
|
|
math_Vector math_Vector::TMultiplied(const Standard_Real theRight) const
|
|
{
|
|
math_Vector Result (Lower(), Upper());
|
|
for(Standard_Integer Index = Lower(); Index <= Upper(); Index++)
|
|
{
|
|
Result.Array(Index) = Array(Index) * theRight;
|
|
}
|
|
return Result;
|
|
}
|
|
|
|
void math_Vector::Multiply(const Standard_Real theRight)
|
|
{
|
|
for(Standard_Integer Index = Lower(); Index <= Upper(); Index++)
|
|
{
|
|
Array(Index) = Array(Index) * theRight;
|
|
}
|
|
}
|
|
|
|
void math_Vector::Divide(const Standard_Real theRight)
|
|
{
|
|
Standard_DivideByZero_Raise_if (Abs(theRight) <= RealEpsilon(),
|
|
"math_Vector::Divide() - devisor is zero");
|
|
|
|
for(Standard_Integer Index = Lower(); Index <= Upper(); Index++)
|
|
{
|
|
Array(Index) = Array(Index) / theRight;
|
|
}
|
|
}
|
|
|
|
math_Vector math_Vector::Divided (const Standard_Real theRight) const
|
|
{
|
|
Standard_DivideByZero_Raise_if (Abs(theRight) <= RealEpsilon(),
|
|
"math_Vector::Divided() - devisor is zero");
|
|
math_Vector temp = Multiplied(1./theRight);
|
|
return temp;
|
|
}
|
|
|
|
void math_Vector::Add(const math_Vector& theRight)
|
|
{
|
|
Standard_DimensionError_Raise_if (Length() != theRight.Length(),
|
|
"math_Vector::Add() - input vector has wrong dimensions");
|
|
|
|
Standard_Integer I = theRight.Lower();
|
|
for(Standard_Integer Index = Lower(); Index <= Upper(); Index++)
|
|
{
|
|
Array(Index) = Array(Index) + theRight.Array(I);
|
|
I++;
|
|
}
|
|
}
|
|
|
|
math_Vector math_Vector::Added(const math_Vector& theRight) const
|
|
{
|
|
Standard_DimensionError_Raise_if (Length() != theRight.Length(),
|
|
"math_Vector::Added() - input vector has wrong dimensions");
|
|
|
|
math_Vector Result (Lower(), Upper());
|
|
|
|
Standard_Integer I = theRight.Lower();
|
|
for(Standard_Integer Index = Lower(); Index <= Upper(); Index++)
|
|
{
|
|
Result.Array(Index) = Array(Index) + theRight.Array(I);
|
|
I++;
|
|
}
|
|
return Result;
|
|
}
|
|
|
|
void math_Vector::Subtract(const math_Vector& theRight)
|
|
{
|
|
Standard_DimensionError_Raise_if (Length() != theRight.Length(),
|
|
"math_Vector::Subtract() - input vector has wrong dimensions");
|
|
|
|
Standard_Integer I = theRight.Lower();
|
|
for(Standard_Integer Index = Lower(); Index <= Upper(); Index++)
|
|
{
|
|
Array(Index) = Array(Index) - theRight.Array(I);
|
|
I++;
|
|
}
|
|
}
|
|
|
|
math_Vector math_Vector::Subtracted (const math_Vector& theRight) const
|
|
{
|
|
Standard_DimensionError_Raise_if (Length() != theRight.Length(),
|
|
"math_Vector::Subtracted() - input vector has wrong dimensions");
|
|
|
|
math_Vector Result(Lower(), Upper());
|
|
|
|
Standard_Integer I = theRight.Lower();
|
|
for(Standard_Integer Index = Lower(); Index <= Upper(); Index++)
|
|
{
|
|
Result.Array(Index) = Array(Index) - theRight.Array(I);
|
|
I++;
|
|
}
|
|
return Result;
|
|
}
|
|
|
|
math_Vector math_Vector::Slice(const Standard_Integer theI1, const Standard_Integer theI2) const
|
|
{
|
|
Standard_RangeError_Raise_if ((theI1 < Lower()) || (theI1 > Upper()) || (theI2 < Lower()) || (theI2 > Upper()),
|
|
"math_Vector::Slice() - invalid indices");
|
|
|
|
if(theI2 >= theI1)
|
|
{
|
|
math_Vector Result(theI1, theI2);
|
|
for(Standard_Integer Index = theI1; Index <= theI2; Index++)
|
|
{
|
|
Result.Array(Index) = Array(Index);
|
|
}
|
|
return Result;
|
|
}
|
|
else
|
|
{
|
|
math_Vector Result(theI2, theI1);
|
|
for(Standard_Integer Index = theI1; Index >= theI2; Index--)
|
|
{
|
|
Result.Array(Index) = Array(Index);
|
|
}
|
|
return Result;
|
|
}
|
|
}
|
|
|
|
void math_Vector::Add (const math_Vector& theLeft, const math_Vector& theRight)
|
|
{
|
|
Standard_DimensionError_Raise_if ((Length() != theRight.Length()) || (theRight.Length() != theLeft.Length()),
|
|
"math_Vector::Add() - input vectors have wrong dimensions");
|
|
|
|
Standard_Integer I = theLeft.Lower();
|
|
Standard_Integer J = theRight.Lower();
|
|
for(Standard_Integer Index = Lower(); Index <= Upper(); Index++)
|
|
{
|
|
Array(Index) = theLeft.Array(I) + theRight.Array(J);
|
|
I++;
|
|
J++;
|
|
}
|
|
}
|
|
|
|
void math_Vector::Subtract (const math_Vector& theLeft, const math_Vector& theRight)
|
|
{
|
|
Standard_DimensionError_Raise_if ((Length() != theRight.Length()) || (theRight.Length() != theLeft.Length()),
|
|
"math_Vector::Subtract() - input vectors have wrong dimensions");
|
|
|
|
Standard_Integer I = theLeft.Lower();
|
|
Standard_Integer J = theRight.Lower();
|
|
for(Standard_Integer Index = Lower(); Index <= Upper(); Index++)
|
|
{
|
|
Array(Index) = theLeft.Array(I) - theRight.Array(J);
|
|
I++;
|
|
J++;
|
|
}
|
|
}
|
|
|
|
void math_Vector::Multiply(const math_Matrix& theLeft, const math_Vector& theRight)
|
|
{
|
|
Standard_DimensionError_Raise_if ((Length() != theLeft.RowNumber())
|
|
|| (theLeft.ColNumber() != theRight.Length()),
|
|
"math_Vector::Multiply() - input matrix and/or vector have wrong dimensions");
|
|
|
|
Standard_Integer Index = Lower();
|
|
for(Standard_Integer I = theLeft.LowerRowIndex; I <= theLeft.UpperRowIndex; I++)
|
|
{
|
|
Array(Index) = 0.0;
|
|
Standard_Integer K = theRight.Lower();
|
|
for(Standard_Integer J = theLeft.LowerColIndex; J <= theLeft.UpperColIndex; J++)
|
|
{
|
|
Array(Index) = Array(Index) + theLeft.Array(I, J) * theRight.Array(K);
|
|
K++;
|
|
}
|
|
Index++;
|
|
}
|
|
}
|
|
|
|
void math_Vector::Multiply(const math_Vector& theLeft, const math_Matrix& theRight)
|
|
{
|
|
Standard_DimensionError_Raise_if ((Length() != theRight.ColNumber())
|
|
|| (theLeft.Length() != theRight.RowNumber()),
|
|
"math_Vector::Multiply() - input matrix and/or vector have wrong dimensions");
|
|
|
|
Standard_Integer Index = Lower();
|
|
for(Standard_Integer J = theRight.LowerColIndex; J <= theRight.UpperColIndex; J++)
|
|
{
|
|
Array(Index) = 0.0;
|
|
Standard_Integer K = theLeft.Lower();
|
|
for(Standard_Integer I = theRight.LowerRowIndex; I <= theRight.UpperRowIndex; I++)
|
|
{
|
|
Array(Index) = Array(Index) + theLeft.Array(K) * theRight.Array(I, J);
|
|
K++;
|
|
}
|
|
Index++;
|
|
}
|
|
}
|
|
|
|
void math_Vector::TMultiply(const math_Matrix& theTLeft, const math_Vector& theRight)
|
|
{
|
|
Standard_DimensionError_Raise_if ((Length() != theTLeft.ColNumber())
|
|
|| (theTLeft.RowNumber() != theRight.Length()),
|
|
"math_Vector::TMultiply() - input matrix and/or vector have wrong dimensions");
|
|
|
|
Standard_Integer Index = Lower();
|
|
for(Standard_Integer I = theTLeft.LowerColIndex; I <= theTLeft.UpperColIndex; I++)
|
|
{
|
|
Array(Index) = 0.0;
|
|
Standard_Integer K = theRight.Lower();
|
|
for(Standard_Integer J = theTLeft.LowerRowIndex; J <= theTLeft.UpperRowIndex; J++)
|
|
{
|
|
Array(Index) = Array(Index) + theTLeft.Array(J, I) * theRight.Array(K);
|
|
K++;
|
|
}
|
|
Index++;
|
|
}
|
|
}
|
|
|
|
void math_Vector::TMultiply(const math_Vector& theLeft, const math_Matrix& theTRight)
|
|
{
|
|
Standard_DimensionError_Raise_if ((Length() != theTRight.RowNumber())
|
|
|| (theLeft.Length() != theTRight.ColNumber()),
|
|
"math_Vector::TMultiply() - input matrix and/or vector have wrong dimensions");
|
|
|
|
Standard_Integer Index = Lower();
|
|
for(Standard_Integer J = theTRight.LowerRowIndex; J <= theTRight.UpperRowIndex; J++)
|
|
{
|
|
Array(Index) = 0.0;
|
|
Standard_Integer K = theLeft.Lower();
|
|
for(Standard_Integer I = theTRight.LowerColIndex;
|
|
I <= theTRight.UpperColIndex; I++)
|
|
{
|
|
Array(Index) = Array(Index) + theLeft.Array(K) * theTRight.Array(J, I);
|
|
K++;
|
|
}
|
|
Index++;
|
|
}
|
|
}
|
|
|
|
Standard_Real math_Vector::Multiplied(const math_Vector& theRight) const
|
|
{
|
|
Standard_Real Result = 0;
|
|
|
|
Standard_DimensionError_Raise_if (Length() != theRight.Length(),
|
|
"math_Vector::Multiplied() - input vector has wrong dimensions");
|
|
|
|
Standard_Integer I = theRight.Lower();
|
|
for(Standard_Integer Index = Lower(); Index <= Upper(); Index++)
|
|
{
|
|
Result = Result + Array(Index) * theRight.Array(I);
|
|
I++;
|
|
}
|
|
return Result;
|
|
}
|
|
|
|
math_Vector math_Vector::Opposite()
|
|
{
|
|
math_Vector Result(Lower(), Upper());
|
|
for(Standard_Integer Index = Lower(); Index <= Upper(); Index++)
|
|
{
|
|
Result.Array(Index) = - Array(Index);
|
|
}
|
|
return Result;
|
|
}
|
|
|
|
math_Vector math_Vector::Multiplied(const math_Matrix& theRight)const
|
|
{
|
|
Standard_DimensionError_Raise_if (Length() != theRight.RowNumber(),
|
|
"math_Vector::Multiplied() - input matrix has wrong dimensions");
|
|
|
|
math_Vector Result(theRight.LowerColIndex, theRight.UpperColIndex);
|
|
for(Standard_Integer J2 = theRight.LowerColIndex; J2 <= theRight.UpperColIndex; J2++)
|
|
{
|
|
Result.Array(J2) = 0.0;
|
|
Standard_Integer theI2 = theRight.LowerRowIndex;
|
|
for(Standard_Integer I = Lower(); I <= Upper(); I++)
|
|
{
|
|
Result.Array(J2) = Result.Array(J2) + Array(I) * theRight.Array(theI2, J2);
|
|
theI2++;
|
|
}
|
|
}
|
|
return Result;
|
|
}
|
|
|
|
void math_Vector::Multiply(const Standard_Real theLeft, const math_Vector& theRight)
|
|
{
|
|
Standard_DimensionError_Raise_if ((Length() != theRight.Length()),
|
|
"math_Vector::Multiply() - input vector has wrong dimensions");
|
|
for(Standard_Integer I = Lower(); I <= Upper(); I++)
|
|
{
|
|
Array(I) = theLeft * theRight.Array(I);
|
|
}
|
|
}
|
|
|
|
math_Vector& math_Vector::Initialized(const math_Vector& theOther)
|
|
{
|
|
Standard_DimensionError_Raise_if (Length() != theOther.Length(),
|
|
"math_Vector::Initialized() - input vector has wrong dimensions");
|
|
memmove (&Array.ChangeFirst(), &theOther.Array.First(), sizeof(Standard_Real) * Array.Length());
|
|
return *this;
|
|
}
|
|
|
|
void math_Vector::Dump(Standard_OStream& theO) const
|
|
{
|
|
theO << "math_Vector of Length = " << Length() << "\n";
|
|
for(Standard_Integer Index = Lower(); Index <= Upper(); Index++)
|
|
{
|
|
theO << "math_Vector(" << Index << ") = " << Array(Index) << "\n";
|
|
}
|
|
}
|
|
|