1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-14 13:30:48 +03:00

Coding - Apply .clang-format formatting #286

Update empty method guards to new style with regex (see PR).
Used clang-format 18.1.8.
New actions to validate code formatting is added.
Update .clang-format with disabling of include sorting.
  It is temporary changes, then include will be sorted.
Apply formatting for /src and /tools folder.
The files with .hxx,.cxx,.lxx,.h,.pxx,.hpp,*.cpp extensions.
This commit is contained in:
dpasukhi
2025-01-25 20:15:22 +00:00
parent dbba6f1289
commit a5a7b3185b
14005 changed files with 1273539 additions and 1195567 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -23,25 +23,22 @@
#include <math_Vector.hxx>
class math
class math
{
public:
DEFINE_STANDARD_ALLOC
Standard_EXPORT static Standard_Integer GaussPointsMax();
Standard_EXPORT static void GaussPoints (const Standard_Integer Index, math_Vector& Points);
Standard_EXPORT static void GaussWeights (const Standard_Integer Index, math_Vector& Weights);
Standard_EXPORT static void GaussPoints(const Standard_Integer Index, math_Vector& Points);
Standard_EXPORT static void GaussWeights(const Standard_Integer Index, math_Vector& Weights);
//! Returns the maximal number of points for that the values
//! are stored in the table. If the number is greater then
//! KronrodPointsMax, the points will be computed.
Standard_EXPORT static Standard_Integer KronrodPointsMax();
//! Returns a vector of Gauss points and a vector of their weights.
//! The difference with the
//! method GaussPoints is the following:
@@ -50,8 +47,10 @@ public:
//! computed.
//! Returns Standard_True if Index is positive, Points' and Weights'
//! length is equal to Index, Points and Weights are successfully computed.
Standard_EXPORT static Standard_Boolean OrderedGaussPointsAndWeights (const Standard_Integer Index, math_Vector& Points, math_Vector& Weights);
Standard_EXPORT static Standard_Boolean OrderedGaussPointsAndWeights(const Standard_Integer Index,
math_Vector& Points,
math_Vector& Weights);
//! Returns a vector of Kronrod points and a vector of their
//! weights for Gauss-Kronrod computation method.
//! Index should be odd and greater then or equal to 3,
@@ -65,8 +64,9 @@ public:
//! if Index is odd, it is equal to the size of Points and Weights
//! and the computation of Points and Weights is performed successfully.
//! Otherwise this method returns Standard_False.
Standard_EXPORT static Standard_Boolean KronrodPointsAndWeights (const Standard_Integer Index, math_Vector& Points, math_Vector& Weights);
Standard_EXPORT static Standard_Boolean KronrodPointsAndWeights(const Standard_Integer Index,
math_Vector& Points,
math_Vector& Weights);
};
#endif // _math_HeaderFile

View File

@@ -22,5 +22,4 @@
typedef NCollection_Array1<math_ValueAndWeight> math_Array1OfValueAndWeight;
#endif

View File

@@ -12,12 +12,12 @@
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
//#ifndef OCCT_DEBUG
// #ifndef OCCT_DEBUG
#define No_Standard_RangeError
#define No_Standard_OutOfRange
#define No_Standard_DimensionError
//#endif
// #endif
#include <math_BFGS.hxx>
#include <math_BracketMinimum.hxx>
@@ -36,42 +36,37 @@
class DirFunction : public math_FunctionWithDerivative
{
math_Vector *P0;
math_Vector *Dir;
math_Vector *P;
math_Vector *G;
math_MultipleVarFunctionWithGradient *F;
math_Vector* P0;
math_Vector* Dir;
math_Vector* P;
math_Vector* G;
math_MultipleVarFunctionWithGradient* F;
public:
//! Ctor.
DirFunction(math_Vector& V1,
math_Vector& V2,
math_Vector& V3,
math_Vector& V4,
DirFunction(math_Vector& V1,
math_Vector& V2,
math_Vector& V3,
math_Vector& V4,
math_MultipleVarFunctionWithGradient& f)
: P0(&V1),
Dir(&V2),
P(&V3),
G(&V4),
F(&f)
{}
: P0(&V1),
Dir(&V2),
P(&V3),
G(&V4),
F(&f)
{
}
//! Sets point and direction.
void Initialize(const math_Vector& p0,
const math_Vector& dir) const
void Initialize(const math_Vector& p0, const math_Vector& dir) const
{
*P0 = p0;
*P0 = p0;
*Dir = dir;
}
void TheGradient(math_Vector& Grad)
{
Grad = *G;
}
void TheGradient(math_Vector& Grad) { Grad = *G; }
virtual Standard_Boolean Value(const Standard_Real x,
Standard_Real& fval)
virtual Standard_Boolean Value(const Standard_Real x, Standard_Real& fval)
{
*P = *Dir;
P->Multiply(x);
@@ -80,9 +75,7 @@ public:
return F->Value(*P, fval);
}
virtual Standard_Boolean Values(const Standard_Real x,
Standard_Real& fval,
Standard_Real& D)
virtual Standard_Boolean Values(const Standard_Real x, Standard_Real& fval, Standard_Real& D)
{
*P = *Dir;
P->Multiply(x);
@@ -96,8 +89,8 @@ public:
return Standard_False;
}
virtual Standard_Boolean Derivative(const Standard_Real x,
Standard_Real& D)
virtual Standard_Boolean Derivative(const Standard_Real x, Standard_Real& D)
{
*P = *Dir;
P->Multiply(x);
@@ -112,13 +105,11 @@ public:
return Standard_False;
}
};
//=============================================================================
//function : ComputeInitScale
//purpose : Compute the appropriate initial value of scale factor to apply
// function : ComputeInitScale
// purpose : Compute the appropriate initial value of scale factor to apply
// to the direction to approach to the minimum of the function
//=============================================================================
static Standard_Boolean ComputeInitScale(const Standard_Real theF0,
@@ -131,8 +122,8 @@ static Standard_Boolean ComputeInitScale(const Standard_Real theF0,
return Standard_False;
const Standard_Real aHnr1 = theDir.Norm2();
const Standard_Real alfa = 0.7*(-theF0) / dy1;
theScale = 0.015 / Sqrt(aHnr1);
const Standard_Real alfa = 0.7 * (-theF0) / dy1;
theScale = 0.015 / Sqrt(aHnr1);
if (theScale > alfa)
theScale = alfa;
@@ -140,11 +131,11 @@ static Standard_Boolean ComputeInitScale(const Standard_Real theF0,
}
//=============================================================================
//function : ComputeMinMaxScale
//purpose : For a given point and direction, and bounding box,
// function : ComputeMinMaxScale
// purpose : For a given point and direction, and bounding box,
// find min and max scale factors with which the point reaches borders
// if we apply translation Point+Dir*Scale.
//return : True if found, False if point is out of bounds.
// return : True if found, False if point is out of bounds.
//=============================================================================
static Standard_Boolean ComputeMinMaxScale(const math_Vector& thePoint,
const math_Vector& theDir,
@@ -155,7 +146,7 @@ static Standard_Boolean ComputeMinMaxScale(const math_Vector& thePoint,
{
for (Standard_Integer anIdx = 1; anIdx <= theLeft.Upper(); anIdx++)
{
const Standard_Real aLeft = theLeft(anIdx) - thePoint(anIdx);
const Standard_Real aLeft = theLeft(anIdx) - thePoint(anIdx);
const Standard_Real aRight = theRight(anIdx) - thePoint(anIdx);
if (Abs(theDir(anIdx)) > RealSmall())
{
@@ -189,8 +180,7 @@ static Standard_Boolean ComputeMinMaxScale(const math_Vector& thePoint,
{
// Direction is parallel to the border.
// Check that the point is not out of bounds
if (aLeft > Precision::PConfusion() ||
aRight < -Precision::PConfusion())
if (aLeft > Precision::PConfusion() || aRight < -Precision::PConfusion())
{
return Standard_False;
}
@@ -200,8 +190,8 @@ static Standard_Boolean ComputeMinMaxScale(const math_Vector& thePoint,
}
//=============================================================================
//function : MinimizeDirection
//purpose : Solves 1D minimization problem when point and directions
// function : MinimizeDirection
// purpose : Solves 1D minimization problem when point and directions
// are known.
//=============================================================================
static Standard_Boolean MinimizeDirection(math_Vector& P,
@@ -233,8 +223,8 @@ static Standard_Boolean MinimizeDirection(math_Vector& P,
// Make direction to go along the border
for (Standard_Integer anIdx = 1; anIdx <= theLeft.Upper(); anIdx++)
{
if ((Abs(P(anIdx) - theRight(anIdx)) < Precision::PConfusion() && Dir(anIdx) > 0.0) ||
(Abs(P(anIdx) - theLeft(anIdx)) < Precision::PConfusion() && Dir(anIdx) < 0.0))
if ((Abs(P(anIdx) - theRight(anIdx)) < Precision::PConfusion() && Dir(anIdx) > 0.0)
|| (Abs(P(anIdx) - theLeft(anIdx)) < Precision::PConfusion() && Dir(anIdx) < 0.0))
{
Dir(anIdx) = 0.0;
}
@@ -268,14 +258,14 @@ static Standard_Boolean MinimizeDirection(math_Vector& P,
Bracket.Values(ax, xx, bx);
Bracket.FunctionValues(Fax, Fxx, Fbx);
Standard_Integer niter = 100;
Standard_Real tol = 1.e-03;
Standard_Integer niter = 100;
Standard_Real tol = 1.e-03;
math_BrentMinimum Sol(tol, Fxx, niter, 1.e-08);
Sol.Perform(F, ax, xx, bx);
if (Sol.IsDone())
{
Standard_Real Scale = Sol.Location();
Result = Sol.Minimum();
Result = Sol.Minimum();
Dir.Multiply(Scale);
P.Add(Dir);
return Standard_True;
@@ -294,12 +284,12 @@ static Standard_Boolean MinimizeDirection(math_Vector& P,
if (aFMin < aFMax)
{
aBestLambda = aMinLambda;
Result = aFMin;
Result = aFMin;
}
else
{
aBestLambda = aMaxLambda;
Result = aFMax;
Result = aFMax;
}
Dir.Multiply(aBestLambda);
P.Add(Dir);
@@ -309,16 +299,15 @@ static Standard_Boolean MinimizeDirection(math_Vector& P,
}
//=============================================================================
//function : Perform
//purpose : Performs minimization problem using BFGS method.
// function : Perform
// purpose : Performs minimization problem using BFGS method.
//=============================================================================
void math_BFGS::Perform(math_MultipleVarFunctionWithGradient& F,
const math_Vector& StartingPoint)
void math_BFGS::Perform(math_MultipleVarFunctionWithGradient& F, const math_Vector& StartingPoint)
{
const Standard_Integer n = TheLocation.Length();
Standard_Boolean Good = Standard_True;
Standard_Integer j, i;
Standard_Real fae, fad, fac;
const Standard_Integer n = TheLocation.Length();
Standard_Boolean Good = Standard_True;
Standard_Integer j, i;
Standard_Real fae, fad, fac;
math_Vector xi(1, n), dg(1, n), hdg(1, n);
math_Matrix hessin(1, n, 1, n);
@@ -331,37 +320,42 @@ void math_BFGS::Perform(math_MultipleVarFunctionWithGradient& F,
DirFunction F_Dir(Temp1, Temp2, Temp3, Temp4, F);
TheLocation = StartingPoint;
Good = F.Values(TheLocation, PreviousMinimum, TheGradient);
Good = F.Values(TheLocation, PreviousMinimum, TheGradient);
if (!Good)
{
Done = Standard_False;
Done = Standard_False;
TheStatus = math_FunctionError;
return;
}
for (i = 1; i <= n; i++)
{
hessin(i, i) = 1.0;
xi(i) = -TheGradient(i);
xi(i) = -TheGradient(i);
}
for (nbiter = 1; nbiter <= Itermax; nbiter++)
{
TheMinimum = PreviousMinimum;
const Standard_Boolean IsGood = MinimizeDirection(TheLocation, TheMinimum, TheGradient,
xi, TheMinimum, F_Dir, myIsBoundsDefined,
myLeft, myRight);
TheMinimum = PreviousMinimum;
const Standard_Boolean IsGood = MinimizeDirection(TheLocation,
TheMinimum,
TheGradient,
xi,
TheMinimum,
F_Dir,
myIsBoundsDefined,
myLeft,
myRight);
if (IsSolutionReached(F))
{
Done = Standard_True;
Done = Standard_True;
TheStatus = math_OK;
return;
}
if (!IsGood)
{
Done = Standard_False;
Done = Standard_False;
TheStatus = math_DirectionSearchError;
return;
}
@@ -372,7 +366,7 @@ void math_BFGS::Perform(math_MultipleVarFunctionWithGradient& F,
Good = F.Values(TheLocation, TheMinimum, TheGradient);
if (!Good)
{
Done = Standard_False;
Done = Standard_False;
TheStatus = math_FunctionError;
return;
}
@@ -412,58 +406,50 @@ void math_BFGS::Perform(math_MultipleVarFunctionWithGradient& F,
xi(i) -= hessin(i, j) * TheGradient(j);
}
}
Done = Standard_False;
Done = Standard_False;
TheStatus = math_TooManyIterations;
return;
}
//=============================================================================
//function : IsSolutionReached
//purpose : Checks whether solution reached or not.
// function : IsSolutionReached
// purpose : Checks whether solution reached or not.
//=============================================================================
Standard_Boolean math_BFGS::IsSolutionReached(math_MultipleVarFunctionWithGradient&) const
{
return 2.0 * fabs(TheMinimum - PreviousMinimum) <=
XTol * (fabs(TheMinimum) + fabs(PreviousMinimum) + EPSZ);
return 2.0 * fabs(TheMinimum - PreviousMinimum)
<= XTol * (fabs(TheMinimum) + fabs(PreviousMinimum) + EPSZ);
}
//=============================================================================
//function : math_BFGS
//purpose : Constructor.
//=============================================================================
math_BFGS::math_BFGS(const Standard_Integer NbVariables,
const Standard_Real Tolerance,
const Standard_Integer NbIterations,
const Standard_Real ZEPS)
: TheStatus(math_OK),
TheLocation(1, NbVariables),
TheGradient(1, NbVariables),
PreviousMinimum(0.),
TheMinimum(0.),
XTol(Tolerance),
EPSZ(ZEPS),
nbiter(0),
myIsBoundsDefined(Standard_False),
myLeft(1, NbVariables, 0.0),
myRight(1, NbVariables, 0.0),
Done(Standard_False),
Itermax(NbIterations)
//=================================================================================================
math_BFGS::math_BFGS(const Standard_Integer NbVariables,
const Standard_Real Tolerance,
const Standard_Integer NbIterations,
const Standard_Real ZEPS)
: TheStatus(math_OK),
TheLocation(1, NbVariables),
TheGradient(1, NbVariables),
PreviousMinimum(0.),
TheMinimum(0.),
XTol(Tolerance),
EPSZ(ZEPS),
nbiter(0),
myIsBoundsDefined(Standard_False),
myLeft(1, NbVariables, 0.0),
myRight(1, NbVariables, 0.0),
Done(Standard_False),
Itermax(NbIterations)
{
}
//=============================================================================
//function : ~math_BFGS
//purpose : Destructor.
//=============================================================================
math_BFGS::~math_BFGS()
{
}
//=================================================================================================
math_BFGS::~math_BFGS() {}
//=================================================================================================
//=============================================================================
//function : Dump
//purpose : Prints dump.
//=============================================================================
void math_BFGS::Dump(Standard_OStream& o) const
{
@@ -480,13 +466,12 @@ void math_BFGS::Dump(Standard_OStream& o) const
}
//=============================================================================
//function : SetBoundary
//purpose : Set boundaries for conditional optimization
// function : SetBoundary
// purpose : Set boundaries for conditional optimization
//=============================================================================
void math_BFGS::SetBoundary(const math_Vector& theLeftBorder,
const math_Vector& theRightBorder)
void math_BFGS::SetBoundary(const math_Vector& theLeftBorder, const math_Vector& theRightBorder)
{
myLeft = theLeftBorder;
myRight = theRightBorder;
myLeft = theLeftBorder;
myRight = theRightBorder;
myIsBoundsDefined = Standard_True;
}

View File

@@ -26,8 +26,6 @@
#include <Standard_OStream.hxx>
class math_MultipleVarFunctionWithGradient;
//! This class implements the Broyden-Fletcher-Goldfarb-Shanno variant of
//! Davidson-Fletcher-Powell minimization algorithm of a function of
//! multiple variables.Knowledge of the function's gradient is required.
@@ -36,13 +34,11 @@ class math_MultipleVarFunctionWithGradient;
//! Method SetBoundary is used to define hyperparallelepiped borders. With boundaries
//! defined, the algorithm will not make evaluations of the function outside of the
//! borders.
class math_BFGS
class math_BFGS
{
public:
DEFINE_STANDARD_ALLOC
//! Initializes the computation of the minimum of a function with
//! NbVariables.
//! Tolerance, ZEPS and NbIterations are described in the method Perform.
@@ -50,13 +46,17 @@ public:
//! A call to the Perform method must be made after this
//! initialization to effectively compute the minimum of the
//! function F.
Standard_EXPORT math_BFGS(const Standard_Integer NbVariables, const Standard_Real Tolerance = 1.0e-8, const Standard_Integer NbIterations = 200, const Standard_Real ZEPS = 1.0e-12);
Standard_EXPORT math_BFGS(const Standard_Integer NbVariables,
const Standard_Real Tolerance = 1.0e-8,
const Standard_Integer NbIterations = 200,
const Standard_Real ZEPS = 1.0e-12);
Standard_EXPORT virtual ~math_BFGS();
//! Set boundaries for conditional optimization.
//! The expected indices range of vectors is [1, NbVariables].
Standard_EXPORT void SetBoundary(const math_Vector& theLeftBorder, const math_Vector& theRightBorder);
Standard_EXPORT void SetBoundary(const math_Vector& theLeftBorder,
const math_Vector& theRightBorder);
//! Given the starting point StartingPoint,
//! minimization is done on the function F.
@@ -64,87 +64,71 @@ public:
//! 2.0 * abs(Fi - Fi-1) <= Tolerance * (abs(Fi) + abs(Fi-1) + ZEPS).
//! Tolerance, ZEPS and maximum number of iterations are given
//! in the constructor.
Standard_EXPORT void Perform (math_MultipleVarFunctionWithGradient& F, const math_Vector& StartingPoint);
Standard_EXPORT void Perform(math_MultipleVarFunctionWithGradient& F,
const math_Vector& StartingPoint);
//! This method is called at the end of each iteration to check if the
//! solution is found.
//! It can be redefined in a sub-class to implement a specific test to
//! stop the iterations.
Standard_EXPORT virtual Standard_Boolean IsSolutionReached (math_MultipleVarFunctionWithGradient& F) const;
Standard_EXPORT virtual Standard_Boolean IsSolutionReached(
math_MultipleVarFunctionWithGradient& F) const;
//! Returns true if the computations are successful, otherwise returns false.
Standard_Boolean IsDone() const;
Standard_Boolean IsDone() const;
//! returns the location vector of the minimum.
//! Exception NotDone is raised if the minimum was not found.
const math_Vector& Location() const;
const math_Vector& Location() const;
//! outputs the location vector of the minimum in Loc.
//! Exception NotDone is raised if the minimum was not found.
//! Exception DimensionError is raised if the range of Loc is not
//! equal to the range of the StartingPoint.
void Location (math_Vector& Loc) const;
void Location(math_Vector& Loc) const;
//! returns the value of the minimum.
//! Exception NotDone is raised if the minimum was not found.
Standard_Real Minimum() const;
Standard_Real Minimum() const;
//! Returns the gradient vector at the minimum.
//! Exception NotDone is raised if the minimum was not found.
const math_Vector& Gradient() const;
const math_Vector& Gradient() const;
//! Returns the value of the gradient vector at the minimum in Grad.
//! Exception NotDone is raised if the minimum was not found.
//! Exception DimensionError is raised if the range of Grad is not
//! equal to the range of the StartingPoint.
void Gradient (math_Vector& Grad) const;
void Gradient(math_Vector& Grad) const;
//! Returns the number of iterations really done in the
//! calculation of the minimum.
//! The exception NotDone is raised if the minimum was not found.
Standard_Integer NbIterations() const;
Standard_Integer NbIterations() const;
//! Prints on the stream o information on the current state
//! of the object.
//! Is used to redefine the operator <<.
Standard_EXPORT void Dump (Standard_OStream& o) const;
Standard_EXPORT void Dump(Standard_OStream& o) const;
protected:
math_Status TheStatus;
math_Vector TheLocation;
math_Vector TheGradient;
Standard_Real PreviousMinimum;
Standard_Real TheMinimum;
Standard_Real XTol;
Standard_Real EPSZ;
math_Status TheStatus;
math_Vector TheLocation;
math_Vector TheGradient;
Standard_Real PreviousMinimum;
Standard_Real TheMinimum;
Standard_Real XTol;
Standard_Real EPSZ;
Standard_Integer nbiter;
Standard_Boolean myIsBoundsDefined;
math_Vector myLeft;
math_Vector myRight;
math_Vector myLeft;
math_Vector myRight;
private:
Standard_Boolean Done;
Standard_Integer Itermax;
};
#include <math_BFGS.lxx>
#endif // _math_BFGS_HeaderFile

View File

@@ -15,47 +15,49 @@
#include <StdFail_NotDone.hxx>
#include <math_Vector.hxx>
inline Standard_Boolean math_BFGS::IsDone() const { return Done; }
inline Standard_Boolean math_BFGS::IsDone() const
{
return Done;
}
inline Standard_OStream& operator<<(Standard_OStream& o,
const math_BFGS& B)
inline Standard_OStream& operator<<(Standard_OStream& o, const math_BFGS& B)
{
B.Dump(o);
return o;
}
inline const math_Vector& math_BFGS::Location() const{
inline const math_Vector& math_BFGS::Location() const
{
StdFail_NotDone_Raise_if(!Done, " ");
return TheLocation;
return TheLocation;
}
inline void math_BFGS::Location(math_Vector& Loc) const{
inline void math_BFGS::Location(math_Vector& Loc) const
{
StdFail_NotDone_Raise_if(!Done, " ");
Loc = TheLocation;
Loc = TheLocation;
}
inline Standard_Real math_BFGS::Minimum() const{
inline Standard_Real math_BFGS::Minimum() const
{
StdFail_NotDone_Raise_if(!Done, " ");
return TheMinimum;
}
inline const math_Vector& math_BFGS::Gradient() const {
inline const math_Vector& math_BFGS::Gradient() const
{
StdFail_NotDone_Raise_if(!Done, " ");
return TheGradient;
}
inline void math_BFGS::Gradient(math_Vector& Grad) const {
inline void math_BFGS::Gradient(math_Vector& Grad) const
{
StdFail_NotDone_Raise_if(!Done, " ");
Grad = TheGradient;
}
inline Standard_Integer math_BFGS::NbIterations() const {
inline Standard_Integer math_BFGS::NbIterations() const
{
StdFail_NotDone_Raise_if(!Done, " ");
return nbiter;
}

View File

@@ -12,153 +12,159 @@
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <math_BissecNewton.hxx>
#include <math_FunctionWithDerivative.hxx>
#include <StdFail_NotDone.hxx>
//=======================================================================
//function : math_BissecNewton
//purpose : Constructor
//=======================================================================
//=================================================================================================
math_BissecNewton::math_BissecNewton(const Standard_Real theXTolerance)
: TheStatus(math_NotBracketed),
XTol (theXTolerance),
x (0.0),
dx (0.0),
f (0.0),
df (0.0),
Done (Standard_False)
: TheStatus(math_NotBracketed),
XTol(theXTolerance),
x(0.0),
dx(0.0),
f(0.0),
df(0.0),
Done(Standard_False)
{
}
//=======================================================================
//function : ~math_BissecNewton
//purpose : Destructor
//=======================================================================
math_BissecNewton::~math_BissecNewton()
{
}
//=================================================================================================
math_BissecNewton::~math_BissecNewton() {}
//=================================================================================================
//=======================================================================
//function : Perform
//purpose :
//=======================================================================
void math_BissecNewton::Perform(math_FunctionWithDerivative& F,
const Standard_Real Bound1,
const Standard_Real Bound2,
const Standard_Integer NbIterations)
const Standard_Real Bound1,
const Standard_Real Bound2,
const Standard_Integer NbIterations)
{
Standard_Boolean GOOD;
Standard_Integer j;
Standard_Real dxold, fh, fl;
Standard_Real temp, xh, xl;
Standard_Real dxold, fh, fl;
Standard_Real temp, xh, xl;
GOOD = F.Values(Bound1, fl, df);
if(!GOOD) {
Done = Standard_False;
if (!GOOD)
{
Done = Standard_False;
TheStatus = math_FunctionError;
return;
}
GOOD = F.Values(Bound2, fh, df);
if(!GOOD) {
Done = Standard_False;
if (!GOOD)
{
Done = Standard_False;
TheStatus = math_FunctionError;
return;
}
// Modified by Sergey KHROMOV - Wed Jan 22 12:06:45 2003 Begin
// Modified by Sergey KHROMOV - Wed Jan 22 12:06:45 2003 Begin
constexpr Standard_Real aFTol = RealEpsilon();
// if(fl * fh >= 0.0) {
if(fl * fh > aFTol*aFTol) {
Done = Standard_False;
// if(fl * fh >= 0.0) {
if (fl * fh > aFTol * aFTol)
{
Done = Standard_False;
TheStatus = math_NotBracketed;
return;
}
// if(fl < 0.0) {
if(fl < -aFTol || (fl < aFTol && fh < -aFTol)) {
// if(fl < 0.0) {
if (fl < -aFTol || (fl < aFTol && fh < -aFTol))
{
xl = Bound1;
xh = Bound2;
}
else {
else
{
xl = Bound2;
xh = Bound1;
}
// Modified by Sergey KHROMOV - Wed Jan 22 12:06:49 2003 End
x = 0.5 * (Bound1 + Bound2);
// Modified by Sergey KHROMOV - Wed Jan 22 12:06:49 2003 End
x = 0.5 * (Bound1 + Bound2);
dxold = fabs(Bound2 - Bound1);
dx = dxold;
GOOD = F.Values(x, f, df);
if(!GOOD) {
Done = Standard_False;
dx = dxold;
GOOD = F.Values(x, f, df);
if (!GOOD)
{
Done = Standard_False;
TheStatus = math_FunctionError;
return;
}
for(j = 1; j <= NbIterations; j++) {
if((((x - xh) * df - f) * ((x - xl) * df - f) >= 0.0)
|| (fabs(2.0 * f) > fabs(dxold * df))) {
for (j = 1; j <= NbIterations; j++)
{
if ((((x - xh) * df - f) * ((x - xl) * df - f) >= 0.0) || (fabs(2.0 * f) > fabs(dxold * df)))
{
dxold = dx;
dx = 0.5 * (xh - xl);
x = xl + dx;
if(Abs(dx) < XTol) {
TheStatus = math_OK;
Done = Standard_True;
return;
dx = 0.5 * (xh - xl);
x = xl + dx;
if (Abs(dx) < XTol)
{
TheStatus = math_OK;
Done = Standard_True;
return;
}
}
else {
else
{
dxold = dx;
dx = f / df;
temp = x;
dx = f / df;
temp = x;
x -= dx;
if(temp == x) {
TheStatus = math_OK;
Done = Standard_True;
return;
if (temp == x)
{
TheStatus = math_OK;
Done = Standard_True;
return;
}
}
if(IsSolutionReached(F)) {
if (IsSolutionReached(F))
{
TheStatus = math_OK;
Done = Standard_True;
Done = Standard_True;
return;
}
GOOD = F.Values(x, f, df);
if(!GOOD) {
Done = Standard_False;
if (!GOOD)
{
Done = Standard_False;
TheStatus = math_FunctionError;
return;
}
if(f < 0.0) {
if (f < 0.0)
{
xl = x;
}
else if(f > 0.0) {
else if (f > 0.0)
{
xh = x;
}
else {
else
{
TheStatus = math_OK;
Done = Standard_True;
Done = Standard_True;
return;
}
}
TheStatus = math_TooManyIterations;
Done = Standard_False;
Done = Standard_False;
return;
}
//=======================================================================
//function : Dump
//purpose :
//=======================================================================
void math_BissecNewton::Dump(Standard_OStream& o) const {
//=================================================================================================
void math_BissecNewton::Dump(Standard_OStream& o) const
{
o << "math_BissecNewton ";
if(Done) {
if (Done)
{
o << " Status = Done \n";
o << " The Root is: " << x << std::endl;
o << " The value at this Root is: " << f << std::endl;
}
else {
else
{
o << " Status = not Done \n";
}
}

View File

@@ -26,22 +26,17 @@
#include <Standard_OStream.hxx>
class math_FunctionWithDerivative;
//! This class implements a combination of Newton-Raphson and bissection
//! methods to find the root of the function between two bounds.
//! Knowledge of the derivative is required.
class math_BissecNewton
class math_BissecNewton
{
public:
DEFINE_STANDARD_ALLOC
//! Constructor.
//! @param theXTolerance - algorithm tolerance.
Standard_EXPORT math_BissecNewton(const Standard_Real theXTolerance);
//! A combination of Newton-Raphson and bissection methods is done to find
//! the root of the function F between the bounds Bound1 and Bound2
@@ -50,67 +45,52 @@ public:
//! The solution is found when:
//! abs(Xi - Xi-1) <= TolX and F(Xi) * F(Xi-1) <= 0
//! The maximum number of iterations allowed is given by NbIterations.
Standard_EXPORT void Perform (math_FunctionWithDerivative& F, const Standard_Real Bound1, const Standard_Real Bound2, const Standard_Integer NbIterations = 100);
Standard_EXPORT void Perform(math_FunctionWithDerivative& F,
const Standard_Real Bound1,
const Standard_Real Bound2,
const Standard_Integer NbIterations = 100);
//! This method is called at the end of each iteration to check if the
//! solution has been found.
//! It can be redefined in a sub-class to implement a specific test to
//! stop the iterations.
virtual Standard_Boolean IsSolutionReached (math_FunctionWithDerivative& theFunction);
virtual Standard_Boolean IsSolutionReached(math_FunctionWithDerivative& theFunction);
//! Tests is the root has been successfully found.
Standard_Boolean IsDone() const;
Standard_Boolean IsDone() const;
//! returns the value of the root.
//! Exception NotDone is raised if the minimum was not found.
Standard_Real Root() const;
Standard_Real Root() const;
//! returns the value of the derivative at the root.
//! Exception NotDone is raised if the minimum was not found.
Standard_Real Derivative() const;
Standard_Real Derivative() const;
//! returns the value of the function at the root.
//! Exception NotDone is raised if the minimum was not found.
Standard_Real Value() const;
Standard_Real Value() const;
//! Prints on the stream o information on the current state
//! of the object.
//! Is used to redifine the operator <<.
Standard_EXPORT void Dump (Standard_OStream& o) const;
Standard_EXPORT void Dump(Standard_OStream& o) const;
//! Destructor
Standard_EXPORT virtual ~math_BissecNewton();
protected:
math_Status TheStatus;
math_Status TheStatus;
Standard_Real XTol;
Standard_Real x;
Standard_Real dx;
Standard_Real f;
Standard_Real df;
private:
Standard_Boolean Done;
};
#include <math_BissecNewton.lxx>
#endif // _math_BissecNewton_HeaderFile

View File

@@ -19,35 +19,31 @@ inline Standard_Boolean math_BissecNewton::IsSolutionReached(math_FunctionWithDe
return Abs(dx) <= XTol;
}
inline Standard_OStream& operator<<(Standard_OStream& o,
const math_BissecNewton& Bi)
inline Standard_OStream& operator<<(Standard_OStream& o, const math_BissecNewton& Bi)
{
Bi.Dump(o);
return o;
}
inline Standard_Boolean math_BissecNewton::IsDone() const
{
return Done;
}
inline Standard_Boolean math_BissecNewton::IsDone() const { return Done; }
inline Standard_Real math_BissecNewton::Root() const{
inline Standard_Real math_BissecNewton::Root() const
{
StdFail_NotDone_Raise_if(!Done, " ");
return x;
}
inline Standard_Real math_BissecNewton::Derivative() const{
inline Standard_Real math_BissecNewton::Derivative() const
{
StdFail_NotDone_Raise_if(!Done, " ");
return df;
}
inline Standard_Real math_BissecNewton::Value() const{
inline Standard_Real math_BissecNewton::Value() const
{
StdFail_NotDone_Raise_if(!Done, " ");
return f;
}

View File

@@ -12,30 +12,31 @@
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <math_BracketMinimum.hxx>
#include <math_Function.hxx>
#include <StdFail_NotDone.hxx>
// waiting for NotDone Exception
#define GOLD 1.618034
#define CGOLD 0.3819660
#define GLIMIT 100.0
#define TINY 1.0e-20
#define GOLD 1.618034
#define CGOLD 0.3819660
#define GLIMIT 100.0
#define TINY 1.0e-20
#ifdef MAX
#undef MAX
#undef MAX
#endif
#define MAX(a,b) ((a) > (b) ? (a) : (b))
#define SIGN(a,b) ((b) > 0.0 ? fabs(a) : -fabs(a))
#define SHFT(a,b,c,d) (a)=(b);(b)=(c);(c)=(d)
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#define SIGN(a, b) ((b) > 0.0 ? fabs(a) : -fabs(a))
#define SHFT(a, b, c, d) \
(a) = (b); \
(b) = (c); \
(c) = (d)
Standard_Boolean math_BracketMinimum::LimitAndMayBeSwap
(math_Function& F,
const Standard_Real theA,
Standard_Real& theB,
Standard_Real& theFB,
Standard_Real& theC,
Standard_Real& theFC) const
Standard_Boolean math_BracketMinimum::LimitAndMayBeSwap(math_Function& F,
const Standard_Real theA,
Standard_Real& theB,
Standard_Real& theFB,
Standard_Real& theC,
Standard_Real& theFC) const
{
theC = Limited(theC);
if (Abs(theB - theC) < Precision::PConfusion())
@@ -54,199 +55,227 @@ Standard_Boolean math_BracketMinimum::LimitAndMayBeSwap
return Standard_True;
}
void math_BracketMinimum::Perform(math_Function& F)
void math_BracketMinimum::Perform(math_Function& F)
{
Standard_Boolean OK;
Standard_Real ulim, u, r, q, fu, dum;
Done = Standard_False;
Standard_Real Lambda = GOLD;
if (!myFA)
{
OK = F.Value(Ax, FAx);
if (!OK)
return;
}
if (!myFB)
{
OK = F.Value(Bx, FBx);
if (!OK)
return;
}
if (FBx > FAx)
{
SHFT(dum, Ax, Bx, dum);
SHFT(dum, FBx, FAx, dum);
}
// get next prob after (A, B)
Cx = Bx + Lambda * (Bx - Ax);
if (myIsLimited)
{
OK = LimitAndMayBeSwap(F, Ax, Bx, FBx, Cx, FCx);
if (!OK)
return;
}
else
{
OK = F.Value(Cx, FCx);
if (!OK)
return;
}
while (FBx > FCx)
{
r = (Bx - Ax) * (FBx - FCx);
q = (Bx - Cx) * (FBx - FAx);
u = Bx - ((Bx - Cx) * q - (Bx - Ax) * r) / (2.0 * SIGN(MAX(fabs(q - r), TINY), q - r));
ulim = Bx + GLIMIT * (Cx - Bx);
if (myIsLimited)
ulim = Limited(ulim);
if ((Bx - u) * (u - Cx) > 0.0)
{
// u is between B and C
OK = F.Value(u, fu);
if (!OK)
return;
if (fu < FCx)
{
// solution is found (B, u, c)
Ax = Bx;
Bx = u;
FAx = FBx;
FBx = fu;
Done = Standard_True;
return;
}
else if (fu > FBx)
{
// solution is found (A, B, u)
Cx = u;
FCx = fu;
Done = Standard_True;
return;
}
// get next prob after (B, C)
u = Cx + Lambda * (Cx - Bx);
if (myIsLimited)
{
OK = LimitAndMayBeSwap(F, Bx, Cx, FCx, u, fu);
if (!OK)
return;
}
else
{
OK = F.Value(u, fu);
if (!OK)
return;
}
}
else if ((Cx - u) * (u - ulim) > 0.0)
{
// u is beyond C but between C and limit
OK = F.Value(u, fu);
if (!OK)
return;
}
else if ((u - ulim) * (ulim - Cx) >= 0.0)
{
// u is beyond limit
u = ulim;
OK = F.Value(u, fu);
if (!OK)
return;
}
else
{
// u tends to approach to the side of A,
// so reset it to the next prob after (B, C)
u = Cx + GOLD * (Cx - Bx);
if (myIsLimited)
{
OK = LimitAndMayBeSwap(F, Bx, Cx, FCx, u, fu);
if (!OK)
return;
}
else
{
OK = F.Value(u, fu);
if (!OK)
return;
}
}
SHFT(Ax, Bx, Cx, u);
SHFT(FAx, FBx, FCx, fu);
}
Done = Standard_True;
}
Standard_Boolean OK;
Standard_Real ulim, u, r, q, fu, dum;
Done = Standard_False;
Standard_Real Lambda = GOLD;
if (!myFA) {
OK = F.Value(Ax, FAx);
if(!OK) return;
}
if (!myFB) {
OK = F.Value(Bx, FBx);
if(!OK) return;
}
if(FBx > FAx) {
SHFT(dum, Ax, Bx, dum);
SHFT(dum, FBx, FAx, dum);
}
// get next prob after (A, B)
Cx = Bx + Lambda * (Bx - Ax);
if (myIsLimited)
{
OK = LimitAndMayBeSwap(F, Ax, Bx, FBx, Cx, FCx);
if (!OK)
return;
}
else
{
OK = F.Value(Cx, FCx);
if (!OK)
return;
}
while(FBx > FCx) {
r = (Bx - Ax) * (FBx -FCx);
q = (Bx - Cx) * (FBx -FAx);
u = Bx - ((Bx - Cx) * q - (Bx - Ax) * r) /
(2.0 * SIGN(MAX(fabs(q - r), TINY), q - r));
ulim = Bx + GLIMIT * (Cx - Bx);
if (myIsLimited)
ulim = Limited(ulim);
if ((Bx - u) * (u - Cx) > 0.0) {
// u is between B and C
OK = F.Value(u, fu);
if(!OK) return;
if(fu < FCx) {
// solution is found (B, u, c)
Ax = Bx;
Bx = u;
FAx = FBx;
FBx = fu;
Done = Standard_True;
return;
}
else if(fu > FBx) {
// solution is found (A, B, u)
Cx = u;
FCx = fu;
Done = Standard_True;
return;
}
// get next prob after (B, C)
u = Cx + Lambda * (Cx - Bx);
if (myIsLimited)
{
OK = LimitAndMayBeSwap(F, Bx, Cx, FCx, u, fu);
if (!OK)
return;
}
else
{
OK = F.Value(u, fu);
if (!OK)
return;
}
}
else if((Cx - u) * (u - ulim) > 0.0) {
// u is beyond C but between C and limit
OK = F.Value(u, fu);
if(!OK) return;
}
else if ((u - ulim) * (ulim - Cx) >= 0.0) {
// u is beyond limit
u = ulim;
OK = F.Value(u, fu);
if(!OK) return;
}
else {
// u tends to approach to the side of A,
// so reset it to the next prob after (B, C)
u = Cx + GOLD * (Cx - Bx);
if (myIsLimited)
{
OK = LimitAndMayBeSwap(F, Bx, Cx, FCx, u, fu);
if (!OK)
return;
}
else
{
OK = F.Value(u, fu);
if (!OK)
return;
}
}
SHFT(Ax, Bx, Cx, u);
SHFT(FAx, FBx, FCx, fu);
}
Done = Standard_True;
}
math_BracketMinimum::math_BracketMinimum(math_Function& F,
const Standard_Real A,
const Standard_Real B)
math_BracketMinimum::math_BracketMinimum(math_Function& F,
const Standard_Real A,
const Standard_Real B)
: Done(Standard_False),
Ax(A), Bx(B), Cx(0.),
FAx(0.), FBx(0.), FCx(0.),
Ax(A),
Bx(B),
Cx(0.),
FAx(0.),
FBx(0.),
FCx(0.),
myLeft(-Precision::Infinite()),
myRight(Precision::Infinite()),
myIsLimited(Standard_False),
myFA(Standard_False),
myFB (Standard_False)
{
Perform(F);
}
myFB(Standard_False)
{
Perform(F);
}
math_BracketMinimum::math_BracketMinimum(math_Function& F,
const Standard_Real A,
const Standard_Real B,
const Standard_Real FA)
math_BracketMinimum::math_BracketMinimum(math_Function& F,
const Standard_Real A,
const Standard_Real B,
const Standard_Real FA)
: Done(Standard_False),
Ax(A), Bx(B), Cx(0.),
FAx(FA), FBx(0.), FCx(0.),
Ax(A),
Bx(B),
Cx(0.),
FAx(FA),
FBx(0.),
FCx(0.),
myLeft(-Precision::Infinite()),
myRight(Precision::Infinite()),
myIsLimited(Standard_False),
myFA(Standard_True),
myFB (Standard_False)
{
Perform(F);
}
myFB(Standard_False)
{
Perform(F);
}
math_BracketMinimum::math_BracketMinimum(math_Function& F,
const Standard_Real A,
const Standard_Real B,
const Standard_Real FA,
const Standard_Real FB)
math_BracketMinimum::math_BracketMinimum(math_Function& F,
const Standard_Real A,
const Standard_Real B,
const Standard_Real FA,
const Standard_Real FB)
: Done(Standard_False),
Ax(A), Bx(B), Cx(0.),
FAx(FA), FBx(FB), FCx(0.),
Ax(A),
Bx(B),
Cx(0.),
FAx(FA),
FBx(FB),
FCx(0.),
myLeft(-Precision::Infinite()),
myRight(Precision::Infinite()),
myIsLimited(Standard_False),
myFA(Standard_True),
myFB(Standard_True)
{
Perform(F);
}
void math_BracketMinimum::Values(Standard_Real& A, Standard_Real& B, Standard_Real& C) const{
StdFail_NotDone_Raise_if(!Done, " ");
A = Ax;
B = Bx;
C = Cx;
}
void math_BracketMinimum::FunctionValues(Standard_Real& FA, Standard_Real& FB, Standard_Real& FC) const{
StdFail_NotDone_Raise_if(!Done, " ");
FA = FAx;
FB = FBx;
FC = FCx;
}
void math_BracketMinimum::Dump(Standard_OStream& o) const {
o << "math_BracketMinimum ";
if(Done) {
o << " Status = Done \n";
o << " The bracketed triplet is: " << std::endl;
o << Ax << ", " << Bx << ", " << Cx << std::endl;
o << " The corresponding function values are: "<< std::endl;
o << FAx << ", " << FBx << ", " << FCx << std::endl;
}
else {
o << " Status = not Done \n";
}
{
Perform(F);
}
void math_BracketMinimum::Values(Standard_Real& A, Standard_Real& B, Standard_Real& C) const
{
StdFail_NotDone_Raise_if(!Done, " ");
A = Ax;
B = Bx;
C = Cx;
}
void math_BracketMinimum::FunctionValues(Standard_Real& FA,
Standard_Real& FB,
Standard_Real& FC) const
{
StdFail_NotDone_Raise_if(!Done, " ");
FA = FAx;
FB = FBx;
FC = FCx;
}
void math_BracketMinimum::Dump(Standard_OStream& o) const
{
o << "math_BracketMinimum ";
if (Done)
{
o << " Status = Done \n";
o << " The bracketed triplet is: " << std::endl;
o << Ax << ", " << Bx << ", " << Cx << std::endl;
o << " The corresponding function values are: " << std::endl;
o << FAx << ", " << FBx << ", " << FCx << std::endl;
}
else
{
o << " Status = not Done \n";
}
}

View File

@@ -25,7 +25,6 @@
#include <Standard_OStream.hxx>
class math_Function;
//! Given two distinct initial points, BracketMinimum
//! implements the computation of three points (a, b, c) which
//! bracket the minimum of the function and verify A less than
@@ -38,7 +37,6 @@ class math_Function;
class math_BracketMinimum
{
public:
DEFINE_STANDARD_ALLOC
//! Constructor preparing A and B parameters only. It does not perform the job.
@@ -49,8 +47,9 @@ public:
//! (such that Bx is between Ax and Cx, F(Bx) is
//! less than both F(Bx) and F(Cx)) the Brent minimization is done
//! on the function F.
Standard_EXPORT math_BracketMinimum(math_Function& F, const Standard_Real A, const Standard_Real B);
Standard_EXPORT math_BracketMinimum(math_Function& F,
const Standard_Real A,
const Standard_Real B);
//! Given two initial values this class computes a
//! bracketing triplet of abscissae Ax, Bx, Cx
@@ -58,8 +57,10 @@ public:
//! less than both F(Bx) and F(Cx)) the Brent minimization is done
//! on the function F.
//! This constructor has to be used if F(A) is known.
Standard_EXPORT math_BracketMinimum(math_Function& F, const Standard_Real A, const Standard_Real B, const Standard_Real FA);
Standard_EXPORT math_BracketMinimum(math_Function& F,
const Standard_Real A,
const Standard_Real B,
const Standard_Real FA);
//! Given two initial values this class computes a
//! bracketing triplet of abscissae Ax, Bx, Cx
@@ -67,7 +68,11 @@ public:
//! less than both F(Bx) and F(Cx)) the Brent minimization is done
//! on the function F.
//! This constructor has to be used if F(A) and F(B) are known.
Standard_EXPORT math_BracketMinimum(math_Function& F, const Standard_Real A, const Standard_Real B, const Standard_Real FA, const Standard_Real FB);
Standard_EXPORT math_BracketMinimum(math_Function& F,
const Standard_Real A,
const Standard_Real B,
const Standard_Real FA,
const Standard_Real FB);
//! Set limits of the parameter. By default no limits are applied to the parameter change.
//! If no minimum is found in limits then IsDone() will return false. The user
@@ -85,24 +90,25 @@ public:
//! Returns true if the computations are successful, otherwise returns false.
Standard_Boolean IsDone() const;
//! Returns the bracketed triplet of abscissae.
//! Exceptions
//! StdFail_NotDone if the algorithm fails (and IsDone returns false).
Standard_EXPORT void Values (Standard_Real& A, Standard_Real& B, Standard_Real& C) const;
Standard_EXPORT void Values(Standard_Real& A, Standard_Real& B, Standard_Real& C) const;
//! returns the bracketed triplet function values.
//! Exceptions
//! StdFail_NotDone if the algorithm fails (and IsDone returns false).
Standard_EXPORT void FunctionValues (Standard_Real& FA, Standard_Real& FB, Standard_Real& FC) const;
Standard_EXPORT void FunctionValues(Standard_Real& FA,
Standard_Real& FB,
Standard_Real& FC) const;
//! Prints on the stream o information on the current state
//! of the object.
//! Is used to redefine the operator <<.
Standard_EXPORT void Dump (Standard_OStream& o) const;
Standard_EXPORT void Dump(Standard_OStream& o) const;
private:
//! Limit the given value to become within the range [myLeft, myRight].
Standard_Real Limited(const Standard_Real theValue) const;
@@ -111,33 +117,28 @@ private:
//! values of B and C.
//! Return false in the case of C becomes equal to B or function calculation
//! failure.
Standard_Boolean LimitAndMayBeSwap(math_Function& F, const Standard_Real theA,
Standard_Real& theB, Standard_Real& theFB,
Standard_Real& theC, Standard_Real& theFC) const;
Standard_Boolean LimitAndMayBeSwap(math_Function& F,
const Standard_Real theA,
Standard_Real& theB,
Standard_Real& theFB,
Standard_Real& theC,
Standard_Real& theFC) const;
private:
Standard_Boolean Done;
Standard_Real Ax;
Standard_Real Bx;
Standard_Real Cx;
Standard_Real FAx;
Standard_Real FBx;
Standard_Real FCx;
Standard_Real myLeft;
Standard_Real myRight;
Standard_Real Ax;
Standard_Real Bx;
Standard_Real Cx;
Standard_Real FAx;
Standard_Real FBx;
Standard_Real FCx;
Standard_Real myLeft;
Standard_Real myRight;
Standard_Boolean myIsLimited;
Standard_Boolean myFA;
Standard_Boolean myFB;
};
#include <math_BracketMinimum.lxx>
#endif // _math_BracketMinimum_HeaderFile

View File

@@ -16,23 +16,28 @@
#include <Precision.hxx>
inline math_BracketMinimum::math_BracketMinimum(const Standard_Real A,
const Standard_Real B)
: Done(Standard_False),
Ax(A), Bx(B), Cx(0.),
FAx(0.), FBx(0.), FCx(0.),
myLeft(-Precision::Infinite()),
myRight(Precision::Infinite()),
myIsLimited(Standard_False),
myFA(Standard_False),
myFB(Standard_False)
inline math_BracketMinimum::math_BracketMinimum(const Standard_Real A, const Standard_Real B)
: Done(Standard_False),
Ax(A),
Bx(B),
Cx(0.),
FAx(0.),
FBx(0.),
FCx(0.),
myLeft(-Precision::Infinite()),
myRight(Precision::Infinite()),
myIsLimited(Standard_False),
myFA(Standard_False),
myFB(Standard_False)
{
}
inline Standard_Boolean math_BracketMinimum::IsDone() const { return Done; }
inline Standard_Boolean math_BracketMinimum::IsDone() const
{
return Done;
}
inline Standard_OStream& operator<<(Standard_OStream& o,
const math_BracketMinimum& Br)
inline Standard_OStream& operator<<(Standard_OStream& o, const math_BracketMinimum& Br)
{
Br.Dump(o);
return o;
@@ -41,25 +46,24 @@ inline Standard_OStream& operator<<(Standard_OStream& o,
inline void math_BracketMinimum::SetLimits(const Standard_Real theLeft,
const Standard_Real theRight)
{
myLeft = theLeft;
myRight = theRight;
myLeft = theLeft;
myRight = theRight;
myIsLimited = Standard_True;
}
inline void math_BracketMinimum::SetFA(const Standard_Real theValue)
{
FAx = theValue;
FAx = theValue;
myFA = Standard_True;
}
inline void math_BracketMinimum::SetFB(const Standard_Real theValue)
{
FBx = theValue;
FBx = theValue;
myFB = Standard_True;
}
inline Standard_Real math_BracketMinimum::Limited(const Standard_Real theValue) const
{
return theValue < myLeft ? myLeft :
theValue > myRight ? myRight : theValue;
return theValue < myLeft ? myLeft : theValue > myRight ? myRight : theValue;
}

View File

@@ -12,106 +12,127 @@
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <math_BracketedRoot.hxx>
#include <math_Function.hxx>
#include <StdFail_NotDone.hxx>
// reference algorithme:
// Brent method
// reference algorithme:
// Brent method
// numerical recipes in C p 269
math_BracketedRoot::math_BracketedRoot (math_Function& F,
const Standard_Real Bound1,
const Standard_Real Bound2,
const Standard_Real Tolerance,
const Standard_Integer NbIterations,
const Standard_Real ZEPS ) {
math_BracketedRoot::math_BracketedRoot(math_Function& F,
const Standard_Real Bound1,
const Standard_Real Bound2,
const Standard_Real Tolerance,
const Standard_Integer NbIterations,
const Standard_Real ZEPS)
{
Standard_Real Fa,Fc,a,c=0,d=0,e=0;
Standard_Real min1,min2,p,q,r,s,tol1,xm;
a = Bound1;
TheRoot = Bound2;
F.Value(a,Fa);
F.Value(TheRoot,TheError);
if (Fa*TheError > 0.) { Done = Standard_False;}
else {
Fc = TheError ;
for (NbIter = 1; NbIter <= NbIterations; NbIter++) {
if (TheError*Fc > 0.) {
c = a; // rename a TheRoot c and adjust bounding interval d
Fc = Fa;
d = TheRoot - a;
e = d;
}
if ( Abs(Fc) < Abs(Fa) ) {
a = TheRoot;
TheRoot = c;
c = a;
Fa = TheError;
TheError = Fc;
Fc = Fa;
}
tol1 = 2.*ZEPS * Abs(TheRoot) + 0.5 * Tolerance; // convergence check
xm = 0.5 * ( c - TheRoot );
if (Abs(xm) <= tol1 || TheError == 0. ) {
Done = Standard_True;
return;
}
if (Abs(e) >= tol1 && Abs(Fa) > Abs(TheError) ) {
s = TheError / Fa; // attempt inverse quadratic interpolation
if (a == c) {
p = 2.*xm*s;
q = 1. - s;
}
else {
q = Fa / Fc;
r = TheError / Fc;
p = s * (2.*xm *q * (q - r) - (TheRoot - a)*(r - 1.));
q = (q -1.) * (r - 1.) * (s - 1.);
}
if ( p > 0. ) { q = -q;} // check whether in bounds
p = Abs(p);
min1 = 3.* xm* q - Abs(tol1 *q);
min2 = Abs(e * q);
if (2.* p < (min1 < min2 ? min1 : min2) ) {
e = d ; // accept interpolation
d = p / q;
}
else {
d = xm; // interpolation failed,use bissection
e = d;
}
}
else { // bounds decreasing too slowly ,use bissection
d = xm;
e =d;
}
a = TheRoot ; // move last best guess to a
Fa = TheError;
if (Abs(d) > tol1) { // evaluate new trial root
TheRoot += d;
}
else {
TheRoot += (xm > 0. ? Abs(tol1) : -Abs(tol1));
}
F.Value(TheRoot,TheError);
}
Done = Standard_False;
}
Standard_Real Fa, Fc, a, c = 0, d = 0, e = 0;
Standard_Real min1, min2, p, q, r, s, tol1, xm;
a = Bound1;
TheRoot = Bound2;
F.Value(a, Fa);
F.Value(TheRoot, TheError);
if (Fa * TheError > 0.)
{
Done = Standard_False;
}
else
{
Fc = TheError;
for (NbIter = 1; NbIter <= NbIterations; NbIter++)
{
if (TheError * Fc > 0.)
{
c = a; // rename a TheRoot c and adjust bounding interval d
Fc = Fa;
d = TheRoot - a;
e = d;
}
if (Abs(Fc) < Abs(Fa))
{
a = TheRoot;
TheRoot = c;
c = a;
Fa = TheError;
TheError = Fc;
Fc = Fa;
}
tol1 = 2. * ZEPS * Abs(TheRoot) + 0.5 * Tolerance; // convergence check
xm = 0.5 * (c - TheRoot);
if (Abs(xm) <= tol1 || TheError == 0.)
{
Done = Standard_True;
return;
}
if (Abs(e) >= tol1 && Abs(Fa) > Abs(TheError))
{
s = TheError / Fa; // attempt inverse quadratic interpolation
if (a == c)
{
p = 2. * xm * s;
q = 1. - s;
}
else
{
q = Fa / Fc;
r = TheError / Fc;
p = s * (2. * xm * q * (q - r) - (TheRoot - a) * (r - 1.));
q = (q - 1.) * (r - 1.) * (s - 1.);
}
if (p > 0.)
{
q = -q;
} // check whether in bounds
p = Abs(p);
min1 = 3. * xm * q - Abs(tol1 * q);
min2 = Abs(e * q);
if (2. * p < (min1 < min2 ? min1 : min2))
{
e = d; // accept interpolation
d = p / q;
}
else
{
d = xm; // interpolation failed,use bissection
e = d;
}
}
else
{ // bounds decreasing too slowly ,use bissection
d = xm;
e = d;
}
a = TheRoot; // move last best guess to a
Fa = TheError;
if (Abs(d) > tol1)
{ // evaluate new trial root
TheRoot += d;
}
else
{
TheRoot += (xm > 0. ? Abs(tol1) : -Abs(tol1));
}
F.Value(TheRoot, TheError);
}
Done = Standard_False;
}
}
void math_BracketedRoot::Dump(Standard_OStream& o) const
{
o << "math_BracketedRoot ";
if (Done)
{
o << " Status = Done \n";
o << " Number of iterations = " << NbIter << std::endl;
o << " The Root is: " << TheRoot << std::endl;
o << " The value at the root is: " << TheError << std::endl;
}
else
{
o << " Status = not Done \n";
}
void math_BracketedRoot::Dump(Standard_OStream& o) const {
o << "math_BracketedRoot ";
if(Done) {
o << " Status = Done \n";
o << " Number of iterations = " << NbIter << std::endl;
o << " The Root is: " << TheRoot << std::endl;
o << " The value at the root is: " << TheError << std::endl;
}
else {
o << " Status = not Done \n";
}
}

View File

@@ -25,17 +25,13 @@
#include <Standard_OStream.hxx>
class math_Function;
//! This class implements the Brent method to find the root of a function
//! located within two bounds. No knowledge of the derivative is required.
class math_BracketedRoot
class math_BracketedRoot
{
public:
DEFINE_STANDARD_ALLOC
//! The Brent method is used to find the root of the function F between
//! the bounds Bound1 and Bound2 on the function F.
//! If F(Bound1)*F(Bound2) >0 the Brent method fails.
@@ -43,54 +39,41 @@ public:
//! The solution is found when :
//! abs(Xi - Xi-1) <= Tolerance;
//! The maximum number of iterations allowed is given by NbIterations.
Standard_EXPORT math_BracketedRoot(math_Function& F, const Standard_Real Bound1, const Standard_Real Bound2, const Standard_Real Tolerance, const Standard_Integer NbIterations = 100, const Standard_Real ZEPS = 1.0e-12);
Standard_EXPORT math_BracketedRoot(math_Function& F,
const Standard_Real Bound1,
const Standard_Real Bound2,
const Standard_Real Tolerance,
const Standard_Integer NbIterations = 100,
const Standard_Real ZEPS = 1.0e-12);
//! Returns true if the computations are successful, otherwise returns false.
Standard_Boolean IsDone() const;
Standard_Boolean IsDone() const;
//! returns the value of the root.
//! Exception NotDone is raised if the minimum was not found.
Standard_Real Root() const;
Standard_Real Root() const;
//! returns the value of the function at the root.
//! Exception NotDone is raised if the minimum was not found.
Standard_Real Value() const;
Standard_Real Value() const;
//! returns the number of iterations really done during the
//! computation of the Root.
//! Exception NotDone is raised if the minimum was not found.
Standard_Integer NbIterations() const;
Standard_Integer NbIterations() const;
//! Prints on the stream o information on the current state
//! of the object.
Standard_EXPORT void Dump (Standard_OStream& o) const;
Standard_EXPORT void Dump(Standard_OStream& o) const;
protected:
private:
Standard_Boolean Done;
Standard_Real TheRoot;
Standard_Real TheError;
Standard_Real TheRoot;
Standard_Real TheError;
Standard_Integer NbIter;
};
#include <math_BracketedRoot.lxx>
#endif // _math_BracketedRoot_HeaderFile

View File

@@ -14,31 +14,31 @@
#include <StdFail_NotDone.hxx>
inline Standard_Boolean math_BracketedRoot::IsDone() const { return Done; }
inline Standard_Boolean math_BracketedRoot::IsDone() const
{
return Done;
}
inline Standard_OStream& operator<<(Standard_OStream& o,
const math_BracketedRoot& Br)
inline Standard_OStream& operator<<(Standard_OStream& o, const math_BracketedRoot& Br)
{
Br.Dump(o);
return o;
}
inline Standard_Real math_BracketedRoot::Root () const {
inline Standard_Real math_BracketedRoot::Root() const
{
StdFail_NotDone_Raise_if(!Done, " ");
return TheRoot;
}
inline Standard_Real math_BracketedRoot::Value () const {
inline Standard_Real math_BracketedRoot::Value() const
{
StdFail_NotDone_Raise_if(!Done, " ");
return TheError;
}
inline Standard_Integer math_BracketedRoot::NbIterations ()const {
inline Standard_Integer math_BracketedRoot::NbIterations() const
{
StdFail_NotDone_Raise_if(!Done, " ");
return NbIter;
}

View File

@@ -12,152 +12,159 @@
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <math_BrentMinimum.hxx>
#include <math_Function.hxx>
#include <StdFail_NotDone.hxx>
static const Standard_Real CGOLD = 0.3819660; //0.5*(3 - sqrt(5));
static const Standard_Real CGOLD = 0.3819660; // 0.5*(3 - sqrt(5));
//=======================================================================
//function : SHFT
//purpose : Shifts arguments
// function : SHFT
// purpose : Shifts arguments
//=======================================================================
inline void SHFT(Standard_Real &theA, Standard_Real &theB,
Standard_Real &theC, Standard_Real &theD)
inline void SHFT(Standard_Real& theA, Standard_Real& theB, Standard_Real& theC, Standard_Real& theD)
{
theA = theB;
theB = theC;
theC = theD;
}
//=======================================================================
//function : math_BrentMinimum
//purpose : Constructor
//=======================================================================
//=================================================================================================
math_BrentMinimum::math_BrentMinimum(const Standard_Real theTolX,
const Standard_Integer theNbIterations,
const Standard_Real theZEPS)
: a (0.0),
b (0.0),
x (0.0),
fx (0.0),
fv (0.0),
fw (0.0),
XTol(theTolX),
EPSZ(theZEPS),
Done (Standard_False),
iter (0),
Itermax(theNbIterations),
myF (Standard_False)
: a(0.0),
b(0.0),
x(0.0),
fx(0.0),
fv(0.0),
fw(0.0),
XTol(theTolX),
EPSZ(theZEPS),
Done(Standard_False),
iter(0),
Itermax(theNbIterations),
myF(Standard_False)
{
}
//=======================================================================
//function : math_BrentMinimum
//purpose : Constructor
//=======================================================================
//=================================================================================================
math_BrentMinimum::math_BrentMinimum(const Standard_Real theTolX,
const Standard_Real theFbx,
const Standard_Integer theNbIterations,
const Standard_Real theZEPS)
: a (0.0),
b (0.0),
x (0.0),
fx (theFbx),
fv (0.0),
fw (0.0),
XTol(theTolX),
EPSZ(theZEPS),
Done (Standard_False),
iter (0),
Itermax(theNbIterations),
myF (Standard_True)
: a(0.0),
b(0.0),
x(0.0),
fx(theFbx),
fv(0.0),
fw(0.0),
XTol(theTolX),
EPSZ(theZEPS),
Done(Standard_False),
iter(0),
Itermax(theNbIterations),
myF(Standard_True)
{
}
//=======================================================================
//function : ~math_BrentMinimum
//purpose : Destructor
//=======================================================================
math_BrentMinimum::~math_BrentMinimum()
{
}
//=================================================================================================
//=======================================================================
//function : Perform
//purpose :
//=======================================================================
void math_BrentMinimum::Perform(math_Function& F,
const Standard_Real ax,
const Standard_Real bx,
const Standard_Real cx)
math_BrentMinimum::~math_BrentMinimum() {}
//=================================================================================================
void math_BrentMinimum::Perform(math_Function& F,
const Standard_Real ax,
const Standard_Real bx,
const Standard_Real cx)
{
Standard_Boolean OK;
Standard_Real etemp, fu, p, q, r;
Standard_Real tol1, tol2, u, v, w, xm;
Standard_Real e = 0.0;
Standard_Real d = RealLast();
Standard_Boolean OK;
Standard_Real etemp, fu, p, q, r;
Standard_Real tol1, tol2, u, v, w, xm;
Standard_Real e = 0.0;
Standard_Real d = RealLast();
a = ((ax < cx) ? ax : cx);
b = ((ax > cx) ? ax : cx);
x = w = v = bx;
if (!myF) {
if (!myF)
{
OK = F.Value(x, fx);
if (!OK) return;
if (!OK)
return;
}
fw = fv = fx;
for (iter = 1; iter <= Itermax; iter++) {
xm = 0.5 * (a + b);
for (iter = 1; iter <= Itermax; iter++)
{
xm = 0.5 * (a + b);
tol1 = XTol * fabs(x) + EPSZ;
tol2 = 2.0 * tol1;
if (IsSolutionReached(F)) {
if (IsSolutionReached(F))
{
Done = Standard_True;
return;
}
if (fabs(e) > tol1) {
if (fabs(e) > tol1)
{
r = (x - w) * (fx - fv);
q = (x - v) * (fx - fw);
p = (x - v) * q - (x - w) * r;
q = 2.0 * (q - r);
if (q > 0.0) p = -p;
q = fabs(q);
if (q > 0.0)
p = -p;
q = fabs(q);
etemp = e;
e = d;
if (fabs(p) >= fabs(0.5 * q * etemp)
|| p <= q * (a - x) || p >= q * (b - x)) {
e = d;
if (fabs(p) >= fabs(0.5 * q * etemp) || p <= q * (a - x) || p >= q * (b - x))
{
e = (x >= xm ? a - x : b - x);
d = CGOLD * e;
}
else {
else
{
d = p / q;
u = x + d;
if (u - a < tol2 || b - u < tol2) d = Sign(tol1, xm - x);
if (u - a < tol2 || b - u < tol2)
d = Sign(tol1, xm - x);
}
}
else {
else
{
e = (x >= xm ? a - x : b - x);
d = CGOLD * e;
}
u = (fabs(d) >= tol1 ? x + d : x + Sign(tol1, d));
u = (fabs(d) >= tol1 ? x + d : x + Sign(tol1, d));
OK = F.Value(u, fu);
if (!OK) return;
if (fu <= fx) {
if (u >= x) a = x; else b = x;
if (!OK)
return;
if (fu <= fx)
{
if (u >= x)
a = x;
else
b = x;
SHFT(v, w, x, u);
SHFT(fv, fw, fx, fu);
}
else {
if (u < x) a = u; else b = u;
if (fu <= fw || w == x) {
v = w;
w = u;
else
{
if (u < x)
a = u;
else
b = u;
if (fu <= fw || w == x)
{
v = w;
w = u;
fv = fw;
fw = fu;
}
else if (fu <= fv || v == x || v == w) {
v = u;
else if (fu <= fv || v == x || v == w)
{
v = u;
fv = fu;
}
}
@@ -166,20 +173,20 @@ void math_BrentMinimum::Perform(math_Function& F,
return;
}
//=======================================================================
//function : Dump
//purpose :
//=======================================================================
//=================================================================================================
void math_BrentMinimum::Dump(Standard_OStream& o) const
{
o << "math_BrentMinimum ";
if(Done) {
if (Done)
{
o << " Status = Done \n";
o << " Location value = " << x <<"\n";
o << " Location value = " << x << "\n";
o << " Minimum value = " << fx << "\n";
o << " Number of iterations = " << iter <<"\n";
o << " Number of iterations = " << iter << "\n";
}
else {
else
{
o << " Status = not Done \n";
}
}

View File

@@ -25,74 +25,68 @@
#include <Standard_OStream.hxx>
class math_Function;
//! This class implements the Brent's method to find the minimum of
//! a function of a single variable.
//! No knowledge of the derivative is required.
class math_BrentMinimum
class math_BrentMinimum
{
public:
DEFINE_STANDARD_ALLOC
//! This constructor should be used in a sub-class to initialize
//! correctly all the fields of this class.
Standard_EXPORT math_BrentMinimum(const Standard_Real TolX, const Standard_Integer NbIterations = 100, const Standard_Real ZEPS = 1.0e-12);
Standard_EXPORT math_BrentMinimum(const Standard_Real TolX,
const Standard_Integer NbIterations = 100,
const Standard_Real ZEPS = 1.0e-12);
//! This constructor should be used in a sub-class to initialize
//! correctly all the fields of this class.
//! It has to be used if F(Bx) is known.
Standard_EXPORT math_BrentMinimum(const Standard_Real TolX, const Standard_Real Fbx, const Standard_Integer NbIterations = 100, const Standard_Real ZEPS = 1.0e-12);
Standard_EXPORT math_BrentMinimum(const Standard_Real TolX,
const Standard_Real Fbx,
const Standard_Integer NbIterations = 100,
const Standard_Real ZEPS = 1.0e-12);
//! Destructor
Standard_EXPORT virtual ~math_BrentMinimum();
//! Brent minimization is performed on function F from a given
//! bracketing triplet of abscissas Ax, Bx, Cx (such that Bx is
//! between Ax and Cx, F(Bx) is less than both F(Bx) and F(Cx))
//! The solution is found when: abs(Xi - Xi-1) <= TolX * abs(Xi) + ZEPS;
Standard_EXPORT void Perform (math_Function& F, const Standard_Real Ax, const Standard_Real Bx, const Standard_Real Cx);
Standard_EXPORT void Perform(math_Function& F,
const Standard_Real Ax,
const Standard_Real Bx,
const Standard_Real Cx);
//! This method is called at the end of each iteration to check if the
//! solution is found.
//! It can be redefined in a sub-class to implement a specific test to
//! stop the iterations.
virtual Standard_Boolean IsSolutionReached (math_Function& theFunction);
virtual Standard_Boolean IsSolutionReached(math_Function& theFunction);
//! Returns true if the computations are successful, otherwise returns false.
Standard_Boolean IsDone() const;
Standard_Boolean IsDone() const;
//! returns the location value of the minimum.
//! Exception NotDone is raised if the minimum was not found.
Standard_Real Location() const;
Standard_Real Location() const;
//! returns the value of the minimum.
//! Exception NotDone is raised if the minimum was not found.
Standard_Real Minimum() const;
Standard_Real Minimum() const;
//! returns the number of iterations really done during the
//! computation of the minimum.
//! Exception NotDone is raised if the minimum was not found.
Standard_Integer NbIterations() const;
Standard_Integer NbIterations() const;
//! Prints on the stream o information on the current state
//! of the object.
//! Is used to redefine the operator <<.
Standard_EXPORT void Dump (Standard_OStream& o) const;
Standard_EXPORT void Dump(Standard_OStream& o) const;
protected:
Standard_Real a;
Standard_Real b;
Standard_Real x;
@@ -102,24 +96,13 @@ protected:
Standard_Real XTol;
Standard_Real EPSZ;
private:
Standard_Boolean Done;
Standard_Integer iter;
Standard_Integer Itermax;
Standard_Boolean myF;
};
#include <math_BrentMinimum.lxx>
#endif // _math_BrentMinimum_HeaderFile

View File

@@ -20,34 +20,31 @@ inline Standard_Boolean math_BrentMinimum::IsSolutionReached(math_Function&)
return (x <= (TwoTol + a)) && (x >= (b - TwoTol));
}
inline Standard_Boolean math_BrentMinimum::IsDone() const
{
return Done;
}
inline Standard_OStream& operator<< (Standard_OStream& o,
const math_BrentMinimum& Br)
inline Standard_OStream& operator<<(Standard_OStream& o, const math_BrentMinimum& Br)
{
Br.Dump(o);
return o;
}
inline Standard_Real math_BrentMinimum::Location() const{
inline Standard_Real math_BrentMinimum::Location() const
{
StdFail_NotDone_Raise_if(!Done, " ");
return x;
}
inline Standard_Real math_BrentMinimum::Minimum() const{
inline Standard_Real math_BrentMinimum::Minimum() const
{
StdFail_NotDone_Raise_if(!Done, " ");
return fx;
}
inline Standard_Integer math_BrentMinimum::NbIterations() const{
inline Standard_Integer math_BrentMinimum::NbIterations() const
{
StdFail_NotDone_Raise_if(!Done, " ");
return iter;
}

View File

@@ -22,16 +22,15 @@
class math_BullardGenerator
{
public:
//! Creates new Xorshift 64-bit RNG.
math_BullardGenerator (unsigned int theSeed = 1)
: myStateHi (theSeed)
math_BullardGenerator(unsigned int theSeed = 1)
: myStateHi(theSeed)
{
SetSeed (theSeed);
SetSeed(theSeed);
}
//! Setup new seed / reset defaults.
void SetSeed (unsigned int theSeed = 1)
void SetSeed(unsigned int theSeed = 1)
{
myStateHi = theSeed;
myStateLo = theSeed ^ 0x49616E42;
@@ -49,16 +48,11 @@ public:
}
//! Generates new floating-point value.
Standard_Real NextReal()
{
return NextInt() / static_cast<Standard_Real> (0xFFFFFFFFu);
}
Standard_Real NextReal() { return NextInt() / static_cast<Standard_Real>(0xFFFFFFFFu); }
private:
unsigned int myStateHi;
unsigned int myStateLo;
};
#endif

View File

@@ -13,18 +13,19 @@
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <math_Array1OfValueAndWeight.hxx>
#include <math_ComputeGaussPointsAndWeights.hxx>
#include <math_EigenValuesSearcher.hxx>
#include <Standard_ErrorHandler.hxx>
#include <algorithm>
math_ComputeGaussPointsAndWeights::math_ComputeGaussPointsAndWeights(const Standard_Integer Number)
{
myIsDone = Standard_False;
try {
try
{
myPoints = new TColStd_HArray1OfReal(1, Number);
myWeights = new TColStd_HArray1OfReal(1, Number);
@@ -33,43 +34,50 @@ math_ComputeGaussPointsAndWeights::math_ComputeGaussPointsAndWeights(const Stand
TColStd_Array1OfReal aDiag(1, Number);
TColStd_Array1OfReal aSubDiag(1, Number);
//Initialization of a real symmetric tridiagonal matrix for
//computation of Gauss quadrature.
// Initialization of a real symmetric tridiagonal matrix for
// computation of Gauss quadrature.
for (i = 1; i <= Number; i++) {
for (i = 1; i <= Number; i++)
{
aDiag(i) = 0.;
if (i == 1)
aSubDiag(i) = 0.;
else {
Standard_Integer sqrIm1 = (i-1)*(i-1);
aSubDiag(i) = sqrIm1/(4.*sqrIm1 - 1);
aSubDiag(i) = Sqrt(aSubDiag(i));
aSubDiag(i) = 0.;
else
{
Standard_Integer sqrIm1 = (i - 1) * (i - 1);
aSubDiag(i) = sqrIm1 / (4. * sqrIm1 - 1);
aSubDiag(i) = Sqrt(aSubDiag(i));
}
}
// Compute eigen values.
math_EigenValuesSearcher EVsearch(aDiag, aSubDiag);
math_EigenValuesSearcher EVsearch(aDiag, aSubDiag);
if (EVsearch.IsDone()) {
if (EVsearch.IsDone())
{
math_Array1OfValueAndWeight VWarray(1, Number);
for (i = 1; i <= Number; i++) {
math_Vector anEigenVector = EVsearch.EigenVector(i);
Standard_Real aWeight = anEigenVector(1);
aWeight = 2. * aWeight * aWeight;
math_ValueAndWeight EVW( EVsearch.EigenValue(i), aWeight );
VWarray(i) = EVW;
for (i = 1; i <= Number; i++)
{
math_Vector anEigenVector = EVsearch.EigenVector(i);
Standard_Real aWeight = anEigenVector(1);
aWeight = 2. * aWeight * aWeight;
math_ValueAndWeight EVW(EVsearch.EigenValue(i), aWeight);
VWarray(i) = EVW;
}
std::sort (VWarray.begin(), VWarray.end());
std::sort(VWarray.begin(), VWarray.end());
for (i = 1; i <= Number; i++) {
myPoints->ChangeValue(i) = VWarray(i).Value();
myWeights->ChangeValue(i) = VWarray(i).Weight();
}
for (i = 1; i <= Number; i++)
{
myPoints->ChangeValue(i) = VWarray(i).Value();
myWeights->ChangeValue(i) = VWarray(i).Weight();
}
myIsDone = Standard_True;
}
} catch (Standard_Failure const&) {
}
catch (Standard_Failure const&)
{
}
}
@@ -81,7 +89,7 @@ Standard_Boolean math_ComputeGaussPointsAndWeights::IsDone() const
math_Vector math_ComputeGaussPointsAndWeights::Points() const
{
Standard_Integer Number = myPoints->Length();
math_Vector thePoints(1, Number);
math_Vector thePoints(1, Number);
for (Standard_Integer i = 1; i <= Number; i++)
thePoints(i) = myPoints->Value(i);
@@ -91,7 +99,7 @@ math_Vector math_ComputeGaussPointsAndWeights::Points() const
math_Vector math_ComputeGaussPointsAndWeights::Weights() const
{
Standard_Integer Number = myWeights->Length();
math_Vector theWeights(1, Number);
math_Vector theWeights(1, Number);
for (Standard_Integer i = 1; i <= Number; i++)
theWeights(i) = myWeights->Value(i);

View File

@@ -24,47 +24,24 @@
#include <Standard_Integer.hxx>
#include <math_Vector.hxx>
class math_ComputeGaussPointsAndWeights
class math_ComputeGaussPointsAndWeights
{
public:
DEFINE_STANDARD_ALLOC
Standard_EXPORT math_ComputeGaussPointsAndWeights(const Standard_Integer Number);
Standard_EXPORT Standard_Boolean IsDone() const;
Standard_EXPORT math_Vector Points() const;
Standard_EXPORT math_Vector Weights() const;
protected:
private:
Handle(TColStd_HArray1OfReal) myPoints;
Handle(TColStd_HArray1OfReal) myWeights;
Standard_Boolean myIsDone;
Standard_Boolean myIsDone;
};
#endif // _math_ComputeGaussPointsAndWeights_HeaderFile

View File

@@ -13,88 +13,97 @@
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <math_Array1OfValueAndWeight.hxx>
#include <math_ComputeKronrodPointsAndWeights.hxx>
#include <math_EigenValuesSearcher.hxx>
#include <Standard_ErrorHandler.hxx>
#include <algorithm>
math_ComputeKronrodPointsAndWeights::math_ComputeKronrodPointsAndWeights(const Standard_Integer Number)
math_ComputeKronrodPointsAndWeights::math_ComputeKronrodPointsAndWeights(
const Standard_Integer Number)
{
myIsDone = Standard_False;
try {
try
{
Standard_Integer i, j;
Standard_Integer a2NP1 = 2*Number + 1;
Standard_Integer a2NP1 = 2 * Number + 1;
myPoints = new TColStd_HArray1OfReal(1, a2NP1);
myWeights = new TColStd_HArray1OfReal(1, a2NP1);
TColStd_Array1OfReal aDiag(1, a2NP1);
TColStd_Array1OfReal aSubDiag(1, a2NP1);
// Initialize symmetric tridiagonal matrix.
Standard_Integer n = Number;
Standard_Integer aKronrodN = 2*Number + 1;
Standard_Integer a3KN2p1 = Min(3*(Number + 1)/2 + 1, aKronrodN);
for (i = 1; i <= a3KN2p1; i++) {
Standard_Integer aKronrodN = 2 * Number + 1;
Standard_Integer a3KN2p1 = Min(3 * (Number + 1) / 2 + 1, aKronrodN);
for (i = 1; i <= a3KN2p1; i++)
{
aDiag(i) = 0.;
if (i == 1)
aSubDiag(i) = 0.;
else {
Standard_Integer sqrIm1 = (i-1)*(i-1);
aSubDiag(i) = sqrIm1/(4.*sqrIm1 - 1);
aSubDiag(i) = 0.;
else
{
Standard_Integer sqrIm1 = (i - 1) * (i - 1);
aSubDiag(i) = sqrIm1 / (4. * sqrIm1 - 1);
}
}
for (i = a3KN2p1 + 1; i <= aKronrodN; i++) {
for (i = a3KN2p1 + 1; i <= aKronrodN; i++)
{
aDiag(i) = 0.;
aSubDiag(i) = 0.;
}
// Algorithm calculates weights and points symmetrically and uses -1 index
// by design. Memory corruption is avoided by moving pointer `s` to the
// by design. Memory corruption is avoided by moving pointer `s` to the
// next element and saving original pointer into `ss` for the proper memory
// releasing. Similarly, `t` and `tt` are addressed.
Standard_Integer aNd2 = Number/2;
Standard_Real *s = new Standard_Real[aNd2 + 2];
Standard_Real *t = new Standard_Real[aNd2 + 2];
Standard_Real *ss = s++;
Standard_Real *tt = t++;
for (i = -1; i <= aNd2; i++) {
Standard_Integer aNd2 = Number / 2;
Standard_Real* s = new Standard_Real[aNd2 + 2];
Standard_Real* t = new Standard_Real[aNd2 + 2];
Standard_Real* ss = s++;
Standard_Real* tt = t++;
for (i = -1; i <= aNd2; i++)
{
s[i] = 0.;
t[i] = 0.;
}
// Generation of Jacobi-Kronrod matrix.
Standard_Real *aa = new Standard_Real [a2NP1+1];
Standard_Real *bb = new Standard_Real [a2NP1+1];
for (i = 1; i <= a2NP1; i++) {
Standard_Real* aa = new Standard_Real[a2NP1 + 1];
Standard_Real* bb = new Standard_Real[a2NP1 + 1];
for (i = 1; i <= a2NP1; i++)
{
aa[i] = aDiag(i);
bb[i] = aSubDiag(i);
}
Standard_Real *ptrtmp;
Standard_Real u;
Standard_Integer m;
Standard_Integer k;
Standard_Integer l;
Standard_Real* ptrtmp;
Standard_Real u;
Standard_Integer m;
Standard_Integer k;
Standard_Integer l;
Standard_Real *a = aa+1;
Standard_Real *b = bb+1;
Standard_Real* a = aa + 1;
Standard_Real* b = bb + 1;
// Eastward phase.
t[0] = b[Number + 1];
for (m = 0; m <= n - 2; m++) {
for (m = 0; m <= n - 2; m++)
{
u = 0;
for (k = (m + 1)/2; k >= 0; k--) {
l = m - k;
u += (a[k + n + 1] - a[l])*t[k] + b[k + n + 1]*s[k - 1] - b[l]*s[k];
s[k] = u;
for (k = (m + 1) / 2; k >= 0; k--)
{
l = m - k;
u += (a[k + n + 1] - a[l]) * t[k] + b[k + n + 1] * s[k - 1] - b[l] * s[k];
s[k] = u;
}
ptrtmp = t;
@@ -106,22 +115,27 @@ math_ComputeKronrodPointsAndWeights::math_ComputeKronrodPointsAndWeights(const S
s[j] = s[j - 1];
// Southward phase.
for (m = n - 1; m <= 2*n - 3; m++) {
for (m = n - 1; m <= 2 * n - 3; m++)
{
u = 0;
for (k = m + 1 - n; k <= (m - 1)/2; k++) {
l = m - k;
j = n - 1 - l;
u += -(a[k + n + 1] - a[l])*t[j] - b[k + n + 1]*s[j] + b[l]*s[j + 1];
s[j] = u;
for (k = m + 1 - n; k <= (m - 1) / 2; k++)
{
l = m - k;
j = n - 1 - l;
u += -(a[k + n + 1] - a[l]) * t[j] - b[k + n + 1] * s[j] + b[l] * s[j + 1];
s[j] = u;
}
if (m % 2 == 0) {
k = m/2;
a[k + n + 1] = a[k] + (s[j] - b[k + n + 1]*s[j + 1])/ t[j + 1];
} else {
k = (m + 1)/2;
b[k + n + 1] = s[j]/s[j + 1];
if (m % 2 == 0)
{
k = m / 2;
a[k + n + 1] = a[k] + (s[j] - b[k + n + 1] * s[j + 1]) / t[j + 1];
}
else
{
k = (m + 1) / 2;
b[k + n + 1] = s[j] / s[j + 1];
}
ptrtmp = t;
@@ -130,42 +144,48 @@ math_ComputeKronrodPointsAndWeights::math_ComputeKronrodPointsAndWeights(const S
}
// Termination phase.
a[2*Number] = a[n - 1] - b[2*Number]*s[0]/t[0];
a[2 * Number] = a[n - 1] - b[2 * Number] * s[0] / t[0];
delete [] ss;
delete [] tt;
for (i = 1; i <= a2NP1; i++) {
delete[] ss;
delete[] tt;
for (i = 1; i <= a2NP1; i++)
{
aDiag(i) = aa[i];
aSubDiag(i) = bb[i];
}
delete [] aa;
delete [] bb;
delete[] aa;
delete[] bb;
for (i = 1; i <= a2NP1; i++)
aSubDiag(i) = Sqrt(aSubDiag(i));
aSubDiag(i) = Sqrt(aSubDiag(i));
// Compute eigen values.
math_EigenValuesSearcher EVsearch(aDiag, aSubDiag);
if (EVsearch.IsDone()) {
math_EigenValuesSearcher EVsearch(aDiag, aSubDiag);
if (EVsearch.IsDone())
{
math_Array1OfValueAndWeight VWarray(1, a2NP1);
for (i = 1; i <= a2NP1; i++) {
math_Vector anEigenVector = EVsearch.EigenVector(i);
Standard_Real aWeight = anEigenVector(1);
aWeight = 2. * aWeight * aWeight;
math_ValueAndWeight EVW( EVsearch.EigenValue(i), aWeight );
VWarray(i) = EVW;
for (i = 1; i <= a2NP1; i++)
{
math_Vector anEigenVector = EVsearch.EigenVector(i);
Standard_Real aWeight = anEigenVector(1);
aWeight = 2. * aWeight * aWeight;
math_ValueAndWeight EVW(EVsearch.EigenValue(i), aWeight);
VWarray(i) = EVW;
}
std::sort (VWarray.begin(), VWarray.end());
for (i = 1; i <= a2NP1; i++) {
myPoints->ChangeValue(i) = VWarray(i).Value();
myWeights->ChangeValue(i) = VWarray(i).Weight();
}
std::sort(VWarray.begin(), VWarray.end());
for (i = 1; i <= a2NP1; i++)
{
myPoints->ChangeValue(i) = VWarray(i).Value();
myWeights->ChangeValue(i) = VWarray(i).Weight();
}
myIsDone = Standard_True;
}
} catch (Standard_Failure const&) {
}
catch (Standard_Failure const&)
{
}
}
@@ -177,7 +197,7 @@ Standard_Boolean math_ComputeKronrodPointsAndWeights::IsDone() const
math_Vector math_ComputeKronrodPointsAndWeights::Points() const
{
Standard_Integer Number = myPoints->Length();
math_Vector thePoints(1, Number);
math_Vector thePoints(1, Number);
for (Standard_Integer i = 1; i <= Number; i++)
thePoints(i) = myPoints->Value(i);
@@ -187,7 +207,7 @@ math_Vector math_ComputeKronrodPointsAndWeights::Points() const
math_Vector math_ComputeKronrodPointsAndWeights::Weights() const
{
Standard_Integer Number = myWeights->Length();
math_Vector theWeights(1, Number);
math_Vector theWeights(1, Number);
for (Standard_Integer i = 1; i <= Number; i++)
theWeights(i) = myWeights->Value(i);

View File

@@ -24,47 +24,24 @@
#include <Standard_Integer.hxx>
#include <math_Vector.hxx>
class math_ComputeKronrodPointsAndWeights
class math_ComputeKronrodPointsAndWeights
{
public:
DEFINE_STANDARD_ALLOC
Standard_EXPORT math_ComputeKronrodPointsAndWeights(const Standard_Integer Number);
Standard_EXPORT Standard_Boolean IsDone() const;
Standard_EXPORT math_Vector Points() const;
Standard_EXPORT math_Vector Weights() const;
protected:
private:
Handle(TColStd_HArray1OfReal) myPoints;
Handle(TColStd_HArray1OfReal) myWeights;
Standard_Boolean myIsDone;
Standard_Boolean myIsDone;
};
#endif // _math_ComputeKronrodPointsAndWeights_HeaderFile

View File

@@ -14,12 +14,12 @@
// lpa le 20/08/91
//#ifndef OCCT_DEBUG
// #ifndef OCCT_DEBUG
#define No_Standard_RangeError
#define No_Standard_OutOfRange
#define No_Standard_DimensionError
//#endif
// #endif
#include <math_Crout.hxx>
#include <math_Matrix.hxx>
@@ -28,115 +28,121 @@
#include <Standard_DimensionError.hxx>
#include <StdFail_NotDone.hxx>
math_Crout::math_Crout(const math_Matrix& A, const Standard_Real MinPivot):
InvA(1, A.RowNumber(), 1, A.ColNumber())
math_Crout::math_Crout(const math_Matrix& A, const Standard_Real MinPivot)
: InvA(1, A.RowNumber(), 1, A.ColNumber())
{
Standard_Integer i,j,k;
Standard_Integer i, j, k;
Standard_Integer Nctl = A.RowNumber();
Standard_Integer lowr = A.LowerRow(), lowc = A.LowerCol();
Standard_Real scale;
Standard_Real scale;
math_Matrix L(1, Nctl, 1, Nctl);
math_Vector Diag(1, Nctl);
math_NotSquare_Raise_if(Nctl != A.ColNumber(), " ");
Det = 1;
for (i =1; i <= Nctl; i++) {
for (j = 1; j <= i -1; j++) {
for (i = 1; i <= Nctl; i++)
{
for (j = 1; j <= i - 1; j++)
{
scale = 0.0;
for (k = 1; k <= j-1; k++) {
scale += L(i,k)*L(j,k)*Diag(k);
for (k = 1; k <= j - 1; k++)
{
scale += L(i, k) * L(j, k) * Diag(k);
}
L(i,j) = (A(i+lowr-1,j+lowc-1)-scale)/Diag(j);
L(i, j) = (A(i + lowr - 1, j + lowc - 1) - scale) / Diag(j);
}
scale = 0.0;
for (k = 1; k <= i-1; k++) {
scale += L(i,k)*L(i,k)*Diag(k);
for (k = 1; k <= i - 1; k++)
{
scale += L(i, k) * L(i, k) * Diag(k);
}
Diag(i) = A(i+lowr-1,i+lowc-1)-scale;
Diag(i) = A(i + lowr - 1, i + lowc - 1) - scale;
Det *= Diag(i);
if (Abs(Diag(i)) <= MinPivot) {
if (Abs(Diag(i)) <= MinPivot)
{
Done = Standard_False;
return;
}
L(i,i) = 1.0;
L(i, i) = 1.0;
}
// Calcul de l inverse de L:
//==========================
// Calcul de l inverse de L:
//==========================
L(1,1) = 1./L(1,1);
for (i = 2; i <= Nctl; i++) {
for (k = 1; k <= i-1; k++) {
L(1, 1) = 1. / L(1, 1);
for (i = 2; i <= Nctl; i++)
{
for (k = 1; k <= i - 1; k++)
{
scale = 0.0;
for (j = k; j <= i-1; j++) {
scale += L(i,j)*L(j,k);
for (j = k; j <= i - 1; j++)
{
scale += L(i, j) * L(j, k);
}
L(i,k) = -scale/L(i,i);
L(i, k) = -scale / L(i, i);
}
L(i,i) = 1./L(i,i);
L(i, i) = 1. / L(i, i);
}
// Calcul de l inverse de Mat:
//============================
// Calcul de l inverse de Mat:
//============================
for (j = 1; j <= Nctl; j++) {
scale = L(j,j)*L(j,j)/Diag(j);
for (k = j+1; k <= Nctl; k++) {
scale += L(k,j) *L(k,j)/Diag(k);
for (j = 1; j <= Nctl; j++)
{
scale = L(j, j) * L(j, j) / Diag(j);
for (k = j + 1; k <= Nctl; k++)
{
scale += L(k, j) * L(k, j) / Diag(k);
}
InvA(j,j) = scale;
for (i = j+1; i <= Nctl; i++) {
scale = L(i,j) *L(i,i)/Diag(i);
for (k = i+1; k <= Nctl; k++) {
scale += L(k,j)*L(k,i)/Diag(k);
InvA(j, j) = scale;
for (i = j + 1; i <= Nctl; i++)
{
scale = L(i, j) * L(i, i) / Diag(i);
for (k = i + 1; k <= Nctl; k++)
{
scale += L(k, j) * L(k, i) / Diag(k);
}
InvA(i,j) = scale;
InvA(i, j) = scale;
}
}
Done = Standard_True;
}
void math_Crout::Solve(const math_Vector& B, math_Vector& X) const
void math_Crout::Solve(const math_Vector& B, math_Vector& X) const
{
StdFail_NotDone_Raise_if(!Done, " ");
Standard_DimensionError_Raise_if((B.Length() != InvA.RowNumber()) ||
(X.Length() != B.Length()), " ");
Standard_Integer n = InvA.RowNumber();
Standard_DimensionError_Raise_if((B.Length() != InvA.RowNumber()) || (X.Length() != B.Length()),
" ");
Standard_Integer n = InvA.RowNumber();
Standard_Integer lowb = B.Lower(), lowx = X.Lower();
Standard_Integer i, j;
for (i = 1; i <= n; i++) {
X(i+lowx-1) = InvA(i, 1)*B(1+lowb-1);
for ( j = 2; j <= i; j++) {
X(i+lowx-1) += InvA(i, j)*B(j+lowb-1);
for (i = 1; i <= n; i++)
{
X(i + lowx - 1) = InvA(i, 1) * B(1 + lowb - 1);
for (j = 2; j <= i; j++)
{
X(i + lowx - 1) += InvA(i, j) * B(j + lowb - 1);
}
for (j = i+1; j <= n; j++) {
X(i+lowx-1) += InvA(j,i)*B(j+lowb-1);
for (j = i + 1; j <= n; j++)
{
X(i + lowx - 1) += InvA(j, i) * B(j + lowb - 1);
}
}
}
void math_Crout::Dump(Standard_OStream& o) const
void math_Crout::Dump(Standard_OStream& o) const
{
o << "math_Crout ";
if(Done) {
if (Done)
{
o << " Status = Done \n";
}
else {
else
{
o << " Status = not Done \n";
}
}

View File

@@ -25,19 +25,16 @@
#include <math_Vector.hxx>
#include <Standard_OStream.hxx>
//! This class implements the Crout algorithm used to solve a
//! system A*X = B where A is a symmetric matrix. It can be used to
//! invert a symmetric matrix.
//! This algorithm is similar to Gauss but is faster than Gauss.
//! Only the inferior triangle of A and the diagonal can be given.
class math_Crout
class math_Crout
{
public:
DEFINE_STANDARD_ALLOC
//! Given an input matrix A, this algorithm inverts A by the
//! Crout algorithm. The user can give only the inferior
//! triangle for the implementation.
@@ -48,63 +45,45 @@ public:
//! considered as singular.
//! Exception NotSquare is raised if A is not a square matrix.
Standard_EXPORT math_Crout(const math_Matrix& A, const Standard_Real MinPivot = 1.0e-20);
//! Returns True if all has been correctly done.
Standard_Boolean IsDone() const;
Standard_Boolean IsDone() const;
//! Given an input vector <B>, this routine returns the
//! solution of the set of linear equations A . X = B.
//! Exception NotDone is raised if the decomposition was not
//! done successfully.
//! Exception DimensionError is raised if the range of B is
//! not equal to the rowrange of A.
Standard_EXPORT void Solve (const math_Vector& B, math_Vector& X) const;
Standard_EXPORT void Solve(const math_Vector& B, math_Vector& X) const;
//! returns the inverse matrix of A. Only the inferior
//! triangle is returned.
//! Exception NotDone is raised if NotDone.
const math_Matrix& Inverse() const;
const math_Matrix& Inverse() const;
//! returns in Inv the inverse matrix of A. Only the inferior
//! triangle is returned.
//! Exception NotDone is raised if NotDone.
void Invert (math_Matrix& Inv) const;
void Invert(math_Matrix& Inv) const;
//! Returns the value of the determinant of the previously LU
//! decomposed matrix A. Zero is returned if the matrix A is considered as singular.
//! Exceptions
//! StdFail_NotDone if the algorithm fails (and IsDone returns false).
Standard_Real Determinant() const;
Standard_Real Determinant() const;
//! Prints on the stream o information on the current state
//! of the object.
Standard_EXPORT void Dump (Standard_OStream& o) const;
Standard_EXPORT void Dump(Standard_OStream& o) const;
protected:
private:
math_Matrix InvA;
math_Matrix InvA;
Standard_Boolean Done;
Standard_Real Det;
Standard_Real Det;
};
#include <math_Crout.lxx>
#endif // _math_Crout_HeaderFile

View File

@@ -14,30 +14,31 @@
#include <StdFail_NotDone.hxx>
inline Standard_Boolean math_Crout::IsDone() const { return Done; }
inline Standard_Boolean math_Crout::IsDone() const
{
return Done;
}
inline Standard_OStream& operator<< (Standard_OStream& o,
const math_Crout& C)
inline Standard_OStream& operator<<(Standard_OStream& o, const math_Crout& C)
{
C.Dump(o);
return o;
}
inline Standard_Real math_Crout::Determinant() const {
inline Standard_Real math_Crout::Determinant() const
{
StdFail_NotDone_Raise_if(!Done, " ");
return Det;
}
inline const math_Matrix& math_Crout::Inverse() const {
inline const math_Matrix& math_Crout::Inverse() const
{
StdFail_NotDone_Raise_if(!Done, " ");
return InvA;
}
inline void math_Crout::Invert(math_Matrix& Inv) const {
inline void math_Crout::Invert(math_Matrix& Inv) const
{
StdFail_NotDone_Raise_if(!Done, " ");
Inv = InvA;
}

View File

@@ -12,12 +12,12 @@
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
//#ifndef OCCT_DEBUG
// #ifndef OCCT_DEBUG
#define No_Standard_RangeError
#define No_Standard_OutOfRange
#define No_Standard_DimensionError
//#endif
// #endif
#include <math_DirectPolynomialRoots.hxx>
#include <StdFail_InfiniteSolutions.hxx>
@@ -26,148 +26,181 @@
// ALGORITHMES NUMERIQUES ANALYSE ET MISE EN OEUVRE, tome 2
// (equations et systemes non lineaires)
// J. VIGNES editions TECHNIP.
const Standard_Real ZERO = 1.0e-30;
const Standard_Real EPSILON = RealEpsilon();
const Standard_Real RADIX = 2;
const Standard_Real Un_Sur_Log_RADIX = 1.0/log(2.0);
const Standard_Real ZERO = 1.0e-30;
const Standard_Real EPSILON = RealEpsilon();
const Standard_Real RADIX = 2;
const Standard_Real Un_Sur_Log_RADIX = 1.0 / log(2.0);
static Standard_Real Value(const Standard_Integer N, Standard_Real *Poly, const Standard_Real X) {
Standard_Real Result = Poly[0];
for(Standard_Integer Index = 1; Index < N; Index++) {
Result = Result * X + Poly[Index];
}
return Result;
}
static Standard_Real Value(const Standard_Integer N, Standard_Real* Poly, const Standard_Real X)
{
Standard_Real Result = Poly[0];
for (Standard_Integer Index = 1; Index < N; Index++)
{
Result = Result * X + Poly[Index];
}
return Result;
}
static void Values(const Standard_Integer N, Standard_Real *Poly, const Standard_Real X,
Standard_Real& Val, Standard_Real& Der) {
Val = Poly[0] * X + Poly[1];
Der = Poly[0];
for(Standard_Integer Index = 2; Index < N; Index++) {
Der = Der * X + Val;
Val = Val * X + Poly[Index];
}
}
static void Values(const Standard_Integer N,
Standard_Real* Poly,
const Standard_Real X,
Standard_Real& Val,
Standard_Real& Der)
{
static Standard_Real Improve(const Standard_Integer N, Standard_Real *Poly, const Standard_Real IniSol) {
Val = Poly[0] * X + Poly[1];
Der = Poly[0];
for (Standard_Integer Index = 2; Index < N; Index++)
{
Der = Der * X + Val;
Val = Val * X + Poly[Index];
}
}
Standard_Real Val = 0., Der, Delta;
Standard_Real Sol = IniSol;
Standard_Real IniVal = Value(N, Poly, IniSol);
Standard_Integer Index;
static Standard_Real Improve(const Standard_Integer N,
Standard_Real* Poly,
const Standard_Real IniSol)
{
// std::cout << "Improve\n";
for(Index = 1; Index < 10; Index++) {
Values(N, Poly, Sol, Val, Der);
if(Abs(Der) <= ZERO) break;
Delta = - Val / Der;
if(Abs(Delta) <= EPSILON * Abs(Sol)) break;
Sol = Sol + Delta;
// std::cout << " Iter = " << Index << " Delta = " << Delta
// << " Val = " << Val << " Der = " << Der << "\n";
}
if(Abs(Val) <= Abs(IniVal)) {
return Sol;
}
else {
return IniSol;
}
}
Standard_Real Val = 0., Der, Delta;
Standard_Real Sol = IniSol;
Standard_Real IniVal = Value(N, Poly, IniSol);
Standard_Integer Index;
Standard_Real Improve(const Standard_Real A, const Standard_Real B, const Standard_Real C,
const Standard_Real D, const Standard_Real E, const Standard_Real IniSol) {
Standard_Real Poly[5];
Poly[0] = A;
Poly[1] = B;
Poly[2] = C;
Poly[3] = D;
Poly[4] = E;
return Improve(5, Poly, IniSol);
}
// std::cout << "Improve\n";
for (Index = 1; Index < 10; Index++)
{
Values(N, Poly, Sol, Val, Der);
if (Abs(Der) <= ZERO)
break;
Delta = -Val / Der;
if (Abs(Delta) <= EPSILON * Abs(Sol))
break;
Sol = Sol + Delta;
// std::cout << " Iter = " << Index << " Delta = " << Delta
// << " Val = " << Val << " Der = " << Der << "\n";
}
if (Abs(Val) <= Abs(IniVal))
{
return Sol;
}
else
{
return IniSol;
}
}
Standard_Real Improve(const Standard_Real A, const Standard_Real B,
const Standard_Real C, const Standard_Real D, const Standard_Real IniSol) {
Standard_Real Poly[4];
Poly[0] = A;
Poly[1] = B;
Poly[2] = C;
Poly[3] = D;
return Improve(4, Poly, IniSol);
}
Standard_Real Improve(const Standard_Real A,
const Standard_Real B,
const Standard_Real C,
const Standard_Real D,
const Standard_Real E,
const Standard_Real IniSol)
{
Standard_Real Improve(const Standard_Real A, const Standard_Real B,
const Standard_Real C, const Standard_Real IniSol) {
Standard_Real Poly[3];
Poly[0] = A;
Poly[1] = B;
Poly[2] = C;
return Improve(3, Poly, IniSol);
}
Standard_Real Poly[5];
Poly[0] = A;
Poly[1] = B;
Poly[2] = C;
Poly[3] = D;
Poly[4] = E;
return Improve(5, Poly, IniSol);
}
Standard_Integer BaseExponent(const Standard_Real X) {
Standard_Real Improve(const Standard_Real A,
const Standard_Real B,
const Standard_Real C,
const Standard_Real D,
const Standard_Real IniSol)
{
if(X > 1.0) {
return (Standard_Integer)(log(X) * Un_Sur_Log_RADIX);
}
else if(X < -1.0) {
return (Standard_Integer)(-log(-X) * Un_Sur_Log_RADIX);
}
else {
return 0;
}
}
Standard_Real Poly[4];
Poly[0] = A;
Poly[1] = B;
Poly[2] = C;
Poly[3] = D;
return Improve(4, Poly, IniSol);
}
Standard_Real Improve(const Standard_Real A,
const Standard_Real B,
const Standard_Real C,
const Standard_Real IniSol)
{
math_DirectPolynomialRoots::math_DirectPolynomialRoots(const Standard_Real A,
const Standard_Real B,
const Standard_Real C,
const Standard_Real D,
const Standard_Real E) {
InfiniteStatus = Standard_False;
Done = Standard_True;
Solve(A, B, C, D, E);
}
Standard_Real Poly[3];
Poly[0] = A;
Poly[1] = B;
Poly[2] = C;
return Improve(3, Poly, IniSol);
}
Standard_Integer BaseExponent(const Standard_Real X)
{
if (X > 1.0)
{
return (Standard_Integer)(log(X) * Un_Sur_Log_RADIX);
}
else if (X < -1.0)
{
return (Standard_Integer)(-log(-X) * Un_Sur_Log_RADIX);
}
else
{
return 0;
}
}
math_DirectPolynomialRoots::math_DirectPolynomialRoots(const Standard_Real A,
const Standard_Real B,
const Standard_Real C,
const Standard_Real D) {
Done = Standard_True;
const Standard_Real B,
const Standard_Real C,
const Standard_Real D,
const Standard_Real E)
{
InfiniteStatus = Standard_False;
Done = Standard_True;
Solve(A, B, C, D, E);
}
math_DirectPolynomialRoots::math_DirectPolynomialRoots(const Standard_Real A,
const Standard_Real B,
const Standard_Real C,
const Standard_Real D)
{
Done = Standard_True;
InfiniteStatus = Standard_False;
Solve(A, B, C, D);
}
math_DirectPolynomialRoots::math_DirectPolynomialRoots(const Standard_Real A,
const Standard_Real B,
const Standard_Real C) {
Done = Standard_True;
const Standard_Real B,
const Standard_Real C)
{
Done = Standard_True;
InfiniteStatus = Standard_False;
Solve(A, B, C);
}
math_DirectPolynomialRoots::math_DirectPolynomialRoots(const Standard_Real A,
const Standard_Real B) {
Done = Standard_True;
math_DirectPolynomialRoots::math_DirectPolynomialRoots(const Standard_Real A, const Standard_Real B)
{
Done = Standard_True;
InfiniteStatus = Standard_False;
Solve(A, B);
}
void math_DirectPolynomialRoots::Solve(const Standard_Real a,
const Standard_Real b,
const Standard_Real c,
const Standard_Real d,
const Standard_Real e) {
if(Abs(a) <= ZERO) {
const Standard_Real b,
const Standard_Real c,
const Standard_Real d,
const Standard_Real e)
{
if (Abs(a) <= ZERO)
{
Solve(b, c, d, e);
return;
}
}
//// modified by jgv, 22.01.09 ////
Standard_Real aZero = ZERO;
@@ -182,11 +215,12 @@ void math_DirectPolynomialRoots::Solve(const Standard_Real a,
if (Abs_e > aZero)
aZero = Abs_e;
if (aZero > ZERO)
aZero = Epsilon(100.*aZero);
aZero = Epsilon(100. * aZero);
if(Abs(a) <= aZero) {
Standard_Real aZero1000 = 1000.*aZero;
Standard_Boolean with_a = Standard_False;
if (Abs(a) <= aZero)
{
Standard_Real aZero1000 = 1000. * aZero;
Standard_Boolean with_a = Standard_False;
if (Abs_b > ZERO && Abs_b <= aZero1000)
with_a = Standard_True;
if (Abs_c > ZERO && Abs_c <= aZero1000)
@@ -197,69 +231,79 @@ void math_DirectPolynomialRoots::Solve(const Standard_Real a,
with_a = Standard_True;
if (!with_a)
{
Solve(b, c, d, e);
return;
}
}
{
Solve(b, c, d, e);
return;
}
}
///////////////////////////////////
Standard_Real A, B, C, D, R3, S3, T3, Q3, Y0, P0, Q0, P, Q, P1, Q1;
Standard_Real Discr, Sdiscr;
Standard_Real A, B, C, D, R3, S3, T3, Q3, Y0, P0, Q0, P, Q, P1, Q1;
Standard_Real Discr, Sdiscr;
Standard_Integer Index;
Standard_Integer Exp;
Standard_Real PowRadix1,PowRadix2;
A = b / a;
B = c / a;
C = d / a;
D = e / a;
Standard_Real PowRadix1, PowRadix2;
A = b / a;
B = c / a;
C = d / a;
D = e / a;
Exp = BaseExponent(D) / 4;
//--
//--
//-- A = A / pow(RADIX, Exp);
//-- B = B / pow(RADIX, 2 * Exp);
//-- C = C / pow(RADIX, 3 * Exp);
//-- D = D / pow(RADIX, 4 * Exp);
PowRadix1 = pow(RADIX,Exp);
A/= PowRadix1; PowRadix2 = PowRadix1 * PowRadix1;
B/= PowRadix2;
C/= PowRadix2 * PowRadix1;
D/= PowRadix2 * PowRadix2;
//--
PowRadix1 = pow(RADIX, Exp);
A /= PowRadix1;
PowRadix2 = PowRadix1 * PowRadix1;
B /= PowRadix2;
C /= PowRadix2 * PowRadix1;
D /= PowRadix2 * PowRadix2;
//--
R3 = -B;
S3 = A * C - 4.0 * D;
T3 = D * (4.0 * B - A * A) - C * C;
Q3 = 1.0;
Q3 = 1.0;
math_DirectPolynomialRoots Sol3(Q3, R3, S3, T3);
//-- ################################################################################
if(Sol3.IsDone() == Standard_False) { Done = Standard_False; return; }
if (Sol3.IsDone() == Standard_False)
{
Done = Standard_False;
return;
}
//-- ################################################################################
Y0 = Sol3.Value(1);
for(Index = 2; Index <= Sol3.NbSolutions(); Index++) {
if(Sol3.Value(Index) > Y0) Y0 = Sol3.Value(Index);
for (Index = 2; Index <= Sol3.NbSolutions(); Index++)
{
if (Sol3.Value(Index) > Y0)
Y0 = Sol3.Value(Index);
}
Discr = A * Y0 * 0.5 - C;
if(Discr >= 0.0) {
if (Discr >= 0.0)
{
Sdiscr = 1.0;
}
else {
else
{
Sdiscr = -1.0;
}
P0 = A * A * 0.25 - B + Y0;
if(P0 < 0.0) P0 = 0.0;
if (P0 < 0.0)
P0 = 0.0;
P0 = sqrt(P0);
Q0 = Y0 * Y0 * 0.25 - D;
if(Q0 < 0.0) Q0 = 0.0;
if (Q0 < 0.0)
Q0 = 0.0;
Q0 = sqrt(Q0);
Standard_Real Ademi = A * 0.5;
Standard_Real Ademi = A * 0.5;
Standard_Real Ydemi = Y0 * 0.5;
Standard_Real SdiscrQ0 = Sdiscr * Q0;
P = Ademi + P0;
Q = Ydemi + SdiscrQ0;
P = Ademi + P0;
Q = Ydemi + SdiscrQ0;
P1 = Ademi - P0;
Q1 = Ydemi - SdiscrQ0;
//
@@ -277,254 +321,316 @@ void math_DirectPolynomialRoots::Solve(const Standard_Real a,
//
Ademi = 1.0;
math_DirectPolynomialRoots ASol2(Ademi, P, Q);
math_DirectPolynomialRoots ASol2(Ademi, P, Q);
//-- ################################################################################
if(ASol2.IsDone() == Standard_False) { Done = Standard_False; return; }
if (ASol2.IsDone() == Standard_False)
{
Done = Standard_False;
return;
}
//-- ################################################################################
math_DirectPolynomialRoots BSol2(Ademi, P1, Q1);
math_DirectPolynomialRoots BSol2(Ademi, P1, Q1);
//-- ################################################################################
if(BSol2.IsDone() == Standard_False) { Done = Standard_False; return; }
if (BSol2.IsDone() == Standard_False)
{
Done = Standard_False;
return;
}
//-- ################################################################################
NbSol = ASol2.NbSolutions() + BSol2.NbSolutions();
for(Index = 0; Index < ASol2.NbSolutions(); Index++) {
for (Index = 0; Index < ASol2.NbSolutions(); Index++)
{
TheRoots[Index] = ASol2.TheRoots[Index];
}
for(Index = 0; Index < BSol2.NbSolutions(); Index++) {
for (Index = 0; Index < BSol2.NbSolutions(); Index++)
{
TheRoots[ASol2.NbSolutions() + Index] = BSol2.TheRoots[Index];
}
for(Index = 0; Index < NbSol; Index++) {
for (Index = 0; Index < NbSol; Index++)
{
TheRoots[Index] = TheRoots[Index] * PowRadix1;
TheRoots[Index] = Improve(a, b, c, d, e, TheRoots[Index]);
}
}
void math_DirectPolynomialRoots::Solve(const Standard_Real A,
const Standard_Real B,
const Standard_Real C,
const Standard_Real D) {
void math_DirectPolynomialRoots::Solve(const Standard_Real A,
const Standard_Real B,
const Standard_Real C,
const Standard_Real D)
{
if(Abs(A) <= ZERO) {
Solve(B, C, D);
return;
}
if (Abs(A) <= ZERO)
{
Solve(B, C, D);
return;
}
Standard_Real Beta, Gamma, Del, P1, P2, P, Ep, Q1, Q2, Q3, Q, Eq, A1, A2, Discr;
Standard_Real Sigma, Psi, D1, D2, Sb, Omega, Sp3, Y1, Dbg, Sdbg, Den1, Den2;
Standard_Real U, H, Sq;
Standard_Integer Exp;
Standard_Real Beta, Gamma, Del, P1, P2, P, Ep, Q1, Q2, Q3, Q, Eq, A1, A2, Discr;
Standard_Real Sigma, Psi, D1, D2, Sb, Omega, Sp3, Y1, Dbg, Sdbg, Den1, Den2;
Standard_Real U, H, Sq;
Standard_Integer Exp;
Beta = B / A;
Gamma = C / A;
Del = D / A;
Beta = B / A;
Gamma = C / A;
Del = D / A;
Exp = BaseExponent(Del) / 3;
Exp = BaseExponent(Del) / 3;
Standard_Real PowRadix1 = pow(RADIX,Exp);
Standard_Real PowRadix2 = PowRadix1*PowRadix1;
Beta/= PowRadix1;
Gamma/= PowRadix2;
Del/= PowRadix2 * PowRadix1;
//-- Beta = Beta / pow(RADIX, Exp);
//-- Gamma = Gamma / pow(RADIX, 2 * Exp);
//-- Del = Del / pow(RADIX, 3 * Exp);
Standard_Real PowRadix1 = pow(RADIX, Exp);
Standard_Real PowRadix2 = PowRadix1 * PowRadix1;
Beta /= PowRadix1;
Gamma /= PowRadix2;
Del /= PowRadix2 * PowRadix1;
//-- Beta = Beta / pow(RADIX, Exp);
//-- Gamma = Gamma / pow(RADIX, 2 * Exp);
//-- Del = Del / pow(RADIX, 3 * Exp);
P1 = Gamma;
P2 = - (Beta * Beta) / 3.0;
P = P1 + P2;
Ep = 5.0 * EPSILON * (Abs(P1) + Abs(P2));
if(Abs(P) <= Ep) P = 0.0;
Q1 = Del;
Q2 = - Beta * Gamma / 3.0;
Q3 = 2.0 * (Beta * Beta * Beta) / 27.0;
Q = Q1 + Q2 + Q3;
Eq = 10.0 * EPSILON * (Abs(Q1) + Abs(Q2) + Abs(Q3));
if(Abs(Q) <= Eq) Q = 0.0;
//-- ############################################################
Standard_Real AbsP = P; if(P<0.0) AbsP = -P;
if(AbsP>1e+80) { Done = Standard_False; return; }
//-- ############################################################
A1 = (P * P * P) / 27.0;
A2 = (Q * Q) / 4.0;
Discr = A1 + A2;
if(P < 0.0) {
Sigma = - Q2 - Q3;
Psi = Gamma * Gamma * (4.0 * Gamma - Beta * Beta) / 27.0;
if(Sigma >= 0.0) {
D1 = Sigma + 2.0 * sqrt(-A1);
}
else {
D1 = Sigma - 2.0 * sqrt(-A1);
}
D2 = Psi / D1;
Discr = 0.0;
if(Abs(Del - D1) >= 18.0 * EPSILON * (Abs(Del) + Abs(D1)) &&
Abs(Del - D2) >= 24.0 * EPSILON * (Abs(Del) + Abs(D2))) {
Discr = (Del - D1) * (Del - D2) / 4.0;
}
P1 = Gamma;
P2 = -(Beta * Beta) / 3.0;
P = P1 + P2;
Ep = 5.0 * EPSILON * (Abs(P1) + Abs(P2));
if (Abs(P) <= Ep)
P = 0.0;
Q1 = Del;
Q2 = -Beta * Gamma / 3.0;
Q3 = 2.0 * (Beta * Beta * Beta) / 27.0;
Q = Q1 + Q2 + Q3;
Eq = 10.0 * EPSILON * (Abs(Q1) + Abs(Q2) + Abs(Q3));
if (Abs(Q) <= Eq)
Q = 0.0;
//-- ############################################################
Standard_Real AbsP = P;
if (P < 0.0)
AbsP = -P;
if (AbsP > 1e+80)
{
Done = Standard_False;
return;
}
//-- ############################################################
A1 = (P * P * P) / 27.0;
A2 = (Q * Q) / 4.0;
Discr = A1 + A2;
if (P < 0.0)
{
Sigma = -Q2 - Q3;
Psi = Gamma * Gamma * (4.0 * Gamma - Beta * Beta) / 27.0;
if (Sigma >= 0.0)
{
D1 = Sigma + 2.0 * sqrt(-A1);
}
else
{
D1 = Sigma - 2.0 * sqrt(-A1);
}
D2 = Psi / D1;
Discr = 0.0;
if (Abs(Del - D1) >= 18.0 * EPSILON * (Abs(Del) + Abs(D1))
&& Abs(Del - D2) >= 24.0 * EPSILON * (Abs(Del) + Abs(D2)))
{
Discr = (Del - D1) * (Del - D2) / 4.0;
}
}
if (Beta >= 0.0)
{
Sb = 1.0;
}
else
{
Sb = -1.0;
}
if (Discr < 0.0)
{
NbSol = 3;
if (Beta == 0.0 && Q == 0.0)
{
TheRoots[0] = sqrt(-P);
TheRoots[1] = -TheRoots[0];
TheRoots[2] = 0.0;
}
else
{
Omega = atan(0.5 * Q / sqrt(-Discr));
Sp3 = sqrt(-P / 3.0);
Y1 = -2.0 * Sb * Sp3 * cos(M_PI / 6.0 - Sb * Omega / 3.0);
TheRoots[0] = -Beta / 3.0 + Y1;
if (Beta * Q <= 0.0)
{
TheRoots[1] = -Beta / 3.0 + 2.0 * Sp3 * sin(Omega / 3.0);
}
if(Beta >= 0.0) {
Sb = 1.0;
else
{
Dbg = Del - Beta * Gamma;
if (Dbg >= 0.0)
{
Sdbg = 1.0;
}
else
{
Sdbg = -1.0;
}
Den1 = 8.0 * Beta * Beta / 9.0 - 4.0 * Beta * Y1 / 3.0 - 2.0 * Q / Y1;
Den2 = 2.0 * Y1 * Y1 - Q / Y1;
TheRoots[1] = Dbg / Den1 + Sdbg * sqrt(-27.0 * Discr) / Den2;
}
else {
Sb = -1.0;
TheRoots[2] = -Del / (TheRoots[0] * TheRoots[1]);
}
}
else if (Discr > 0.0)
{
NbSol = 1;
U = sqrt(Discr) + Abs(Q / 2.0);
if (U >= 0.0)
{
U = pow(U, 1.0 / 3.0);
}
else
{
U = -pow(Abs(U), 1.0 / 3.0);
}
if (P >= 0.0)
{
H = U * U + P / 3.0 + (P / U) * (P / U) / 9.0;
}
else
{
H = U * Abs(Q) / (U * U - P / 3.0);
}
if (Beta * Q >= 0.0)
{
if (Abs(H) <= RealSmall() && Abs(Q) <= RealSmall())
{
TheRoots[0] = -Beta / 3.0 - U + P / (3.0 * U);
}
if(Discr < 0.0) {
NbSol = 3;
if(Beta == 0.0 && Q == 0.0) {
TheRoots[0] = sqrt(-P);
TheRoots[1] = -TheRoots[0];
TheRoots[2] = 0.0;
}
else {
Omega = atan(0.5 * Q / sqrt(- Discr));
Sp3 = sqrt(-P / 3.0);
Y1 = -2.0 * Sb * Sp3 * cos(M_PI / 6.0 - Sb * Omega / 3.0);
TheRoots[0] = - Beta / 3.0 + Y1;
if(Beta * Q <= 0.0) {
TheRoots[1] = - Beta / 3.0 + 2.0 * Sp3 * sin(Omega / 3.0);
}
else {
Dbg = Del - Beta * Gamma;
if(Dbg >= 0.0) {
Sdbg = 1.0;
}
else {
Sdbg = -1.0;
}
Den1 = 8.0 * Beta * Beta / 9.0 - 4.0 * Beta * Y1 / 3.0
- 2.0 * Q / Y1;
Den2 = 2.0 * Y1 * Y1 - Q / Y1;
TheRoots[1] = Dbg / Den1 + Sdbg * sqrt(-27.0 * Discr) / Den2;
}
TheRoots[2] = - Del / (TheRoots[0] * TheRoots[1]);
}
}
else if(Discr > 0.0) {
NbSol = 1;
U = sqrt(Discr) + Abs(Q / 2.0);
if(U >= 0.0) {
U = pow(U, 1.0 / 3.0);
}
else {
U = - pow(Abs(U), 1.0 / 3.0);
}
if(P >= 0.0) {
H = U * U + P / 3.0 + (P / U) * (P / U) / 9.0;
}
else {
H = U * Abs(Q) / (U * U - P / 3.0);
}
if(Beta * Q >= 0.0) {
if(Abs(H) <= RealSmall() && Abs(Q) <= RealSmall()) {
TheRoots[0] = - Beta / 3.0 - U + P / (3.0 * U);
}
else {
TheRoots[0] = - Beta / 3.0 - Q / H;
}
}
else {
TheRoots[0] = - Del / (Beta * Beta / 9.0 + H - Beta * Q / (3.0 * H));
}
}
else {
NbSol = 3;
if(Q >= 0.0) {
Sq = 1.0;
}
else {
Sq = -1.0;
}
Sp3 = sqrt(-P / 3.0);
if(Beta * Q <= 0.0) {
TheRoots[0] = -Beta / 3.0 + Sq * Sp3;
TheRoots[1] = TheRoots[0];
if(Beta * Q == 0.0) {
TheRoots[2] = -Beta / 3.0 - 2.0 * Sq * Sp3;
}
else {
TheRoots[2] = - Del / (TheRoots[0] * TheRoots[1]);
}
}
else {
TheRoots[0] = -Gamma / (Beta + 3.0 * Sq * Sp3);
TheRoots[1] = TheRoots[0];
TheRoots[2] = -Beta / 3.0 - 2.0 * Sq * Sp3;
}
}
for(Standard_Integer Index = 0; Index < NbSol; Index++) {
TheRoots[Index] = TheRoots[Index] * pow(RADIX, Exp);
TheRoots[Index] = Improve(A, B, C, D, TheRoots[Index]);
else
{
TheRoots[0] = -Beta / 3.0 - Q / H;
}
}
void math_DirectPolynomialRoots::Solve(const Standard_Real A,
const Standard_Real B,
const Standard_Real C) {
if(Abs(A) <= ZERO) {
Solve(B, C);
return;
}
Standard_Real EpsD = 3.0 * EPSILON * (B * B + Abs(4.0 * A * C));
Standard_Real Discrim = B * B - 4.0 * A * C;
if(Abs(Discrim) <= EpsD) Discrim = 0.0;
if(Discrim < 0.0) {
NbSol = 0;
}
else if(Discrim == 0.0) {
NbSol = 2;
TheRoots[0] = -0.5 * B / A;
TheRoots[0] = Improve(A, B, C, TheRoots[0]);
TheRoots[1] = TheRoots[0];
}
else {
NbSol = 2;
if(B > 0.0) {
TheRoots[0] = - (B + sqrt(Discrim)) / (2.0 * A);
}
else {
TheRoots[0] = - (B - sqrt(Discrim)) / (2.0 * A);
}
TheRoots[0] = Improve(A, B, C, TheRoots[0]);
TheRoots[1] = C / (A * TheRoots[0]);
TheRoots[1] = Improve(A, B, C, TheRoots[1]);
}
else
{
TheRoots[0] = -Del / (Beta * Beta / 9.0 + H - Beta * Q / (3.0 * H));
}
void math_DirectPolynomialRoots::Solve(const Standard_Real A,
const Standard_Real B) {
if(Abs(A) <= ZERO) {
if (Abs(B) <= ZERO) {
InfiniteStatus = Standard_True;
return;
}
NbSol = 0;
return;
}
NbSol = 1;
TheRoots[0] = -B / A;
}
else
{
NbSol = 3;
if (Q >= 0.0)
{
Sq = 1.0;
}
void math_DirectPolynomialRoots::Dump(Standard_OStream& o) const {
o << "math_DirectPolynomialRoots ";
if (!Done) {
o <<" Not Done \n";
}
else if(InfiniteStatus) {
o << " Status = Infinity Roots \n";
}
else if (!InfiniteStatus) {
o << " Status = Not Infinity Roots \n";
o << " Number of solutions = " << NbSol <<"\n";
for (Standard_Integer i = 1; i <= NbSol; i++) {
o << " Solution number " << i << " = " << TheRoots[i-1] <<"\n";
}
}
else
{
Sq = -1.0;
}
Sp3 = sqrt(-P / 3.0);
if (Beta * Q <= 0.0)
{
TheRoots[0] = -Beta / 3.0 + Sq * Sp3;
TheRoots[1] = TheRoots[0];
if (Beta * Q == 0.0)
{
TheRoots[2] = -Beta / 3.0 - 2.0 * Sq * Sp3;
}
else
{
TheRoots[2] = -Del / (TheRoots[0] * TheRoots[1]);
}
}
else
{
TheRoots[0] = -Gamma / (Beta + 3.0 * Sq * Sp3);
TheRoots[1] = TheRoots[0];
TheRoots[2] = -Beta / 3.0 - 2.0 * Sq * Sp3;
}
}
for (Standard_Integer Index = 0; Index < NbSol; Index++)
{
TheRoots[Index] = TheRoots[Index] * pow(RADIX, Exp);
TheRoots[Index] = Improve(A, B, C, D, TheRoots[Index]);
}
}
void math_DirectPolynomialRoots::Solve(const Standard_Real A,
const Standard_Real B,
const Standard_Real C)
{
if (Abs(A) <= ZERO)
{
Solve(B, C);
return;
}
Standard_Real EpsD = 3.0 * EPSILON * (B * B + Abs(4.0 * A * C));
Standard_Real Discrim = B * B - 4.0 * A * C;
if (Abs(Discrim) <= EpsD)
Discrim = 0.0;
if (Discrim < 0.0)
{
NbSol = 0;
}
else if (Discrim == 0.0)
{
NbSol = 2;
TheRoots[0] = -0.5 * B / A;
TheRoots[0] = Improve(A, B, C, TheRoots[0]);
TheRoots[1] = TheRoots[0];
}
else
{
NbSol = 2;
if (B > 0.0)
{
TheRoots[0] = -(B + sqrt(Discrim)) / (2.0 * A);
}
else
{
TheRoots[0] = -(B - sqrt(Discrim)) / (2.0 * A);
}
TheRoots[0] = Improve(A, B, C, TheRoots[0]);
TheRoots[1] = C / (A * TheRoots[0]);
TheRoots[1] = Improve(A, B, C, TheRoots[1]);
}
}
void math_DirectPolynomialRoots::Solve(const Standard_Real A, const Standard_Real B)
{
if (Abs(A) <= ZERO)
{
if (Abs(B) <= ZERO)
{
InfiniteStatus = Standard_True;
return;
}
NbSol = 0;
return;
}
NbSol = 1;
TheRoots[0] = -B / A;
}
void math_DirectPolynomialRoots::Dump(Standard_OStream& o) const
{
o << "math_DirectPolynomialRoots ";
if (!Done)
{
o << " Not Done \n";
}
else if (InfiniteStatus)
{
o << " Status = Infinity Roots \n";
}
else if (!InfiniteStatus)
{
o << " Status = Not Infinity Roots \n";
o << " Number of solutions = " << NbSol << "\n";
for (Standard_Integer i = 1; i <= NbSol; i++)
{
o << " Solution number " << i << " = " << TheRoots[i - 1] << "\n";
}
}
}

View File

@@ -24,91 +24,82 @@
#include <Standard_Real.hxx>
#include <Standard_OStream.hxx>
//! This class implements the calculation of all the real roots of a real
//! polynomial of degree <= 4 using a direct method. Once found,
//! the roots are polished using the Newton method.
class math_DirectPolynomialRoots
class math_DirectPolynomialRoots
{
public:
DEFINE_STANDARD_ALLOC
//! computes all the real roots of the polynomial
//! Ax4 + Bx3 + Cx2 + Dx + E using a direct method.
Standard_EXPORT math_DirectPolynomialRoots(const Standard_Real A, const Standard_Real B, const Standard_Real C, const Standard_Real D, const Standard_Real E);
Standard_EXPORT math_DirectPolynomialRoots(const Standard_Real A,
const Standard_Real B,
const Standard_Real C,
const Standard_Real D,
const Standard_Real E);
//! computes all the real roots of the polynomial
//! Ax3 + Bx2 + Cx + D using a direct method.
Standard_EXPORT math_DirectPolynomialRoots(const Standard_Real A, const Standard_Real B, const Standard_Real C, const Standard_Real D);
Standard_EXPORT math_DirectPolynomialRoots(const Standard_Real A,
const Standard_Real B,
const Standard_Real C,
const Standard_Real D);
//! computes all the real roots of the polynomial
//! Ax2 + Bx + C using a direct method.
Standard_EXPORT math_DirectPolynomialRoots(const Standard_Real A, const Standard_Real B, const Standard_Real C);
Standard_EXPORT math_DirectPolynomialRoots(const Standard_Real A,
const Standard_Real B,
const Standard_Real C);
//! computes the real root of the polynomial Ax + B.
Standard_EXPORT math_DirectPolynomialRoots(const Standard_Real A, const Standard_Real B);
//! Returns true if the computations are successful, otherwise returns false.
Standard_Boolean IsDone() const;
Standard_Boolean IsDone() const;
//! Returns true if there is an infinity of roots, otherwise returns false.
Standard_Boolean InfiniteRoots() const;
Standard_Boolean InfiniteRoots() const;
//! returns the number of solutions.
//! An exception is raised if there are an infinity of roots.
Standard_Integer NbSolutions() const;
Standard_Integer NbSolutions() const;
//! returns the value of the Nieme root.
//! An exception is raised if there are an infinity of roots.
//! Exception RangeError is raised if Nieme is < 1
//! or Nieme > NbSolutions.
Standard_Real Value (const Standard_Integer Nieme) const;
Standard_Real Value(const Standard_Integer Nieme) const;
//! Prints on the stream o information on the current state
//! of the object.
//! Is used to redefine the operator <<.
Standard_EXPORT void Dump (Standard_OStream& o) const;
Standard_EXPORT void Dump(Standard_OStream& o) const;
protected:
Standard_EXPORT void Solve(const Standard_Real A,
const Standard_Real B,
const Standard_Real C,
const Standard_Real D,
const Standard_Real E);
Standard_EXPORT void Solve (const Standard_Real A, const Standard_Real B, const Standard_Real C, const Standard_Real D, const Standard_Real E);
Standard_EXPORT void Solve (const Standard_Real A, const Standard_Real B, const Standard_Real C, const Standard_Real D);
Standard_EXPORT void Solve (const Standard_Real A, const Standard_Real B, const Standard_Real C);
Standard_EXPORT void Solve (const Standard_Real A, const Standard_Real B);
Standard_EXPORT void Solve(const Standard_Real A,
const Standard_Real B,
const Standard_Real C,
const Standard_Real D);
Standard_EXPORT void Solve(const Standard_Real A, const Standard_Real B, const Standard_Real C);
Standard_EXPORT void Solve(const Standard_Real A, const Standard_Real B);
private:
Standard_Boolean Done;
Standard_Boolean InfiniteStatus;
Standard_Integer NbSol;
Standard_Real TheRoots[4];
Standard_Real TheRoots[4];
};
#include <math_DirectPolynomialRoots.lxx>
#endif // _math_DirectPolynomialRoots_HeaderFile

View File

@@ -15,36 +15,31 @@
#include <Standard_RangeError.hxx>
#include <StdFail_InfiniteSolutions.hxx>
inline Standard_Boolean math_DirectPolynomialRoots::IsDone() const
{
return Done;
}
inline Standard_Boolean math_DirectPolynomialRoots::IsDone() const
{return Done;}
inline Standard_Boolean math_DirectPolynomialRoots::InfiniteRoots() const
{
return InfiniteStatus;
}
inline Standard_Boolean math_DirectPolynomialRoots::InfiniteRoots() const
{return InfiniteStatus; }
inline Standard_OStream& operator<<(Standard_OStream& o,
const math_DirectPolynomialRoots& D)
inline Standard_OStream& operator<<(Standard_OStream& o, const math_DirectPolynomialRoots& D)
{
D.Dump(o);
return o;
}
inline Standard_Integer math_DirectPolynomialRoots::NbSolutions() const
{
StdFail_InfiniteSolutions_Raise_if(InfiniteStatus, " ");
return NbSol;
}
inline Standard_Real math_DirectPolynomialRoots::Value(const Standard_Integer Nieme) const
inline Standard_Real math_DirectPolynomialRoots::Value(const Standard_Integer Nieme) const
{
StdFail_InfiniteSolutions_Raise_if(InfiniteStatus, " ");
Standard_RangeError_Raise_if((Nieme < 0) ||
(Nieme > NbSol), " ");
Standard_RangeError_Raise_if((Nieme < 0) || (Nieme > NbSol), " ");
return TheRoots[Nieme - 1];
}

View File

@@ -18,73 +18,73 @@
#include <Standard_OutOfRange.hxx>
// macro to get size of C array
#define CARRAY_LENGTH(arr) (int)(sizeof(arr)/sizeof(arr[0]))
#define CARRAY_LENGTH(arr) (int)(sizeof(arr) / sizeof(arr[0]))
void math_DoubleTab::Allocate()
{
Standard_Integer RowNumber = UppR - LowR + 1;
Standard_Integer ColNumber = UppC - LowC + 1;
if(isAllocated)
Addr = (Standard_Real*) Standard::Allocate(RowNumber * ColNumber * sizeof(Standard_Real));
if (isAllocated)
Addr = (Standard_Real*)Standard::Allocate(RowNumber * ColNumber * sizeof(Standard_Real));
}
math_DoubleTab::math_DoubleTab(const Standard_Integer LowerRow,
const Standard_Integer UpperRow,
const Standard_Integer LowerCol,
const Standard_Integer UpperCol) :
Addr(Buf),
isAllocated((UpperRow - LowerRow + 1) * (UpperCol - LowerCol + 1) > CARRAY_LENGTH(Buf)),
LowR(LowerRow),
UppR(UpperRow),
LowC(LowerCol),
UppC(UpperCol)
const Standard_Integer UpperRow,
const Standard_Integer LowerCol,
const Standard_Integer UpperCol)
: Addr(Buf),
isAllocated((UpperRow - LowerRow + 1) * (UpperCol - LowerCol + 1) > CARRAY_LENGTH(Buf)),
LowR(LowerRow),
UppR(UpperRow),
LowC(LowerCol),
UppC(UpperCol)
{
Allocate();
}
math_DoubleTab::math_DoubleTab(const Standard_Address Tab,
const Standard_Integer LowerRow,
const Standard_Integer UpperRow,
const Standard_Integer LowerCol,
const Standard_Integer UpperCol) :
Addr(Tab),
isAllocated(Standard_False),
LowR(LowerRow),
UppR(UpperRow),
LowC(LowerCol),
UppC(UpperCol)
const Standard_Integer LowerRow,
const Standard_Integer UpperRow,
const Standard_Integer LowerCol,
const Standard_Integer UpperCol)
: Addr(Tab),
isAllocated(Standard_False),
LowR(LowerRow),
UppR(UpperRow),
LowC(LowerCol),
UppC(UpperCol)
{
Allocate();
}
void math_DoubleTab::Init(const Standard_Real InitValue)
void math_DoubleTab::Init(const Standard_Real InitValue)
{
for (Standard_Integer anIndex = 0; anIndex < (UppR - LowR + 1) * (UppC - LowC + 1); anIndex++)
{
((Standard_Real* )Addr)[anIndex] = InitValue;
((Standard_Real*)Addr)[anIndex] = InitValue;
}
}
math_DoubleTab::math_DoubleTab(const math_DoubleTab& Other) :
Addr(Buf),
isAllocated((Other.UppR - Other.LowR + 1) *
(Other.UppC - Other.LowC + 1) > CARRAY_LENGTH(Buf)),
LowR(Other.LowR),
UppR(Other.UppR),
LowC(Other.LowC),
UppC(Other.UppC)
math_DoubleTab::math_DoubleTab(const math_DoubleTab& Other)
: Addr(Buf),
isAllocated((Other.UppR - Other.LowR + 1) * (Other.UppC - Other.LowC + 1)
> CARRAY_LENGTH(Buf)),
LowR(Other.LowR),
UppR(Other.UppR),
LowC(Other.LowC),
UppC(Other.UppC)
{
Allocate();
memmove (Addr, Other.Addr, (int)((UppR - LowR + 1) * (UppC - LowC + 1) * sizeof(Standard_Real)));
memmove(Addr, Other.Addr, (int)((UppR - LowR + 1) * (UppC - LowC + 1) * sizeof(Standard_Real)));
}
void math_DoubleTab::Free()
{
// free the data
if(isAllocated)
if (isAllocated)
{
Standard::Free (Addr);
Standard::Free(Addr);
}
Addr = 0;
@@ -101,4 +101,3 @@ void math_DoubleTab::SetLowerCol(const Standard_Integer LowerCol)
UppC = UppC - LowC + LowerCol;
LowC = LowerCol;
}

View File

@@ -24,71 +24,56 @@
#include <Standard_Real.hxx>
#include <Standard_Boolean.hxx>
class math_DoubleTab
class math_DoubleTab
{
public:
DEFINE_STANDARD_ALLOC
Standard_EXPORT math_DoubleTab(const Standard_Integer LowerRow, const Standard_Integer UpperRow, const Standard_Integer LowerCol, const Standard_Integer UpperCol);
Standard_EXPORT math_DoubleTab(const Standard_Address Tab, const Standard_Integer LowerRow, const Standard_Integer UpperRow, const Standard_Integer LowerCol, const Standard_Integer UpperCol);
Standard_EXPORT void Init (const Standard_Real InitValue);
Standard_EXPORT math_DoubleTab(const Standard_Integer LowerRow,
const Standard_Integer UpperRow,
const Standard_Integer LowerCol,
const Standard_Integer UpperCol);
Standard_EXPORT math_DoubleTab(const Standard_Address Tab,
const Standard_Integer LowerRow,
const Standard_Integer UpperRow,
const Standard_Integer LowerCol,
const Standard_Integer UpperCol);
Standard_EXPORT void Init(const Standard_Real InitValue);
Standard_EXPORT math_DoubleTab(const math_DoubleTab& Other);
void Copy (math_DoubleTab& Other) const;
Standard_EXPORT void SetLowerRow (const Standard_Integer LowerRow);
Standard_EXPORT void SetLowerCol (const Standard_Integer LowerCol);
Standard_Real& Value (const Standard_Integer RowIndex, const Standard_Integer ColIndex) const;
Standard_Real& operator() (const Standard_Integer RowIndex, const Standard_Integer ColIndex) const
{
return Value(RowIndex,ColIndex);
}
void Copy(math_DoubleTab& Other) const;
Standard_EXPORT void SetLowerRow(const Standard_Integer LowerRow);
Standard_EXPORT void SetLowerCol(const Standard_Integer LowerCol);
Standard_Real& Value(const Standard_Integer RowIndex, const Standard_Integer ColIndex) const;
Standard_Real& operator()(const Standard_Integer RowIndex, const Standard_Integer ColIndex) const
{
return Value(RowIndex, ColIndex);
}
Standard_EXPORT void Free();
~math_DoubleTab()
{
Free();
}
~math_DoubleTab() { Free(); }
protected:
private:
Standard_EXPORT void Allocate();
Standard_Address Addr;
Standard_Real Buf[16];
Standard_Real Buf[16];
Standard_Boolean isAllocated;
Standard_Integer LowR;
Standard_Integer UppR;
Standard_Integer LowC;
Standard_Integer UppC;
};
#include <math_DoubleTab.lxx>
#endif // _math_DoubleTab_HeaderFile

View File

@@ -18,17 +18,13 @@
#include <Standard_OutOfRange.hxx>
inline Standard_Real& math_DoubleTab::Value (const Standard_Integer RowIndex,
const Standard_Integer ColIndex) const
inline Standard_Real& math_DoubleTab::Value(const Standard_Integer RowIndex,
const Standard_Integer ColIndex) const
{
return ((Standard_Real*)Addr)[(UppC - LowC + 1) * (RowIndex - LowR) + (ColIndex - LowC)];
}
inline void math_DoubleTab::Copy(math_DoubleTab& Other)const
inline void math_DoubleTab::Copy(math_DoubleTab& Other) const
{
memmove (Other.Addr, Addr, (int)((UppR - LowR + 1) * (UppC - LowC + 1) * sizeof(Standard_Real)));
memmove(Other.Addr, Addr, (int)((UppR - LowR + 1) * (UppC - LowC + 1) * sizeof(Standard_Real)));
}

View File

@@ -13,22 +13,20 @@
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <math_EigenValuesSearcher.hxx>
#include <StdFail_NotDone.hxx>
//==========================================================================
//function : pythag
// function : pythag
// Computation of sqrt(x*x + y*y).
//==========================================================================
static inline Standard_Real pythag(const Standard_Real x,
const Standard_Real y)
static inline Standard_Real pythag(const Standard_Real x, const Standard_Real y)
{
return Sqrt(x*x + y*y);
return Sqrt(x * x + y * y);
}
math_EigenValuesSearcher::math_EigenValuesSearcher(const TColStd_Array1OfReal& Diagonal,
const TColStd_Array1OfReal& Subdiagonal)
const TColStd_Array1OfReal& Subdiagonal)
{
myIsDone = Standard_False;
@@ -36,20 +34,20 @@ math_EigenValuesSearcher::math_EigenValuesSearcher(const TColStd_Array1OfReal& D
if (Subdiagonal.Length() != n)
throw Standard_Failure("math_EigenValuesSearcher : dimension mismatch");
myDiagonal = new TColStd_HArray1OfReal(1, n);
myDiagonal->ChangeArray1() = Diagonal;
mySubdiagonal = new TColStd_HArray1OfReal(1, n);
myDiagonal = new TColStd_HArray1OfReal(1, n);
myDiagonal->ChangeArray1() = Diagonal;
mySubdiagonal = new TColStd_HArray1OfReal(1, n);
mySubdiagonal->ChangeArray1() = Subdiagonal;
myN = n;
myEigenValues = new TColStd_HArray1OfReal(1, n);
myEigenVectors = new TColStd_HArray2OfReal(1, n, 1, n);
myN = n;
myEigenValues = new TColStd_HArray1OfReal(1, n);
myEigenVectors = new TColStd_HArray2OfReal(1, n, 1, n);
Standard_Real* d = new Standard_Real [n+1];
Standard_Real* e = new Standard_Real [n+1];
Standard_Real** z = new Standard_Real* [n+1];
Standard_Real* d = new Standard_Real[n + 1];
Standard_Real* e = new Standard_Real[n + 1];
Standard_Real** z = new Standard_Real*[n + 1];
Standard_Integer i, j;
for (i = 1; i <= n; i++)
z[i] = new Standard_Real [n+1];
z[i] = new Standard_Real[n + 1];
for (i = 1; i <= n; i++)
d[i] = myDiagonal->Value(i);
@@ -57,13 +55,13 @@ math_EigenValuesSearcher::math_EigenValuesSearcher(const TColStd_Array1OfReal& D
e[i] = mySubdiagonal->Value(i);
for (i = 1; i <= n; i++)
for (j = 1; j <= n; j++)
z[i][j] = (i == j)? 1. : 0.;
z[i][j] = (i == j) ? 1. : 0.;
Standard_Boolean result;
Standard_Integer m;
Standard_Integer l;
Standard_Integer iter;
//Standard_Integer i;
// Standard_Integer i;
Standard_Integer k;
Standard_Real s;
Standard_Real r;
@@ -77,99 +75,106 @@ math_EigenValuesSearcher::math_EigenValuesSearcher(const TColStd_Array1OfReal& D
result = Standard_True;
if (n != 1)
{
// Shift e.
for (i = 2; i <= n; i++)
e[i - 1] = e[i];
e[n] = 0.0;
for (l = 1; l <= n; l++)
{
// Shift e.
for (i = 2; i <= n; i++)
e[i - 1] = e[i];
e[n] = 0.0;
for (l = 1; l <= n; l++) {
iter = 0;
do {
for (m = l; m <= n-1; m++) {
dd = Abs(d[m]) + Abs(d[m + 1]);
if (Abs(e[m]) + dd == dd)
break;
}
if (m != l) {
if (iter++ == 30) {
result = Standard_False;
break; //return result;
}
g = (d[l + 1] - d[l])/(2.*e[l]);
r = pythag(1., g);
if (g < 0)
g = d[m] - d[l] + e[l]/(g - r);
else
g = d[m] - d[l] + e[l]/(g + r);
s = 1.;
c = 1.;
p = 0.;
for (i = m - 1; i >= l; i--) {
f = s*e[i];
b = c*e[i];
r = pythag (f, g);
e[i + 1] = r;
if (r == 0.) {
d[i + 1] -= p;
e[m] = 0.;
break;
}
s = f/r;
c = g/r;
g = d[i + 1] - p;
r = (d[i] - g)*s + 2.0*c*b;
p = s*r;
d[i + 1] = g + p;
g = c*r - b;
for (k = 1; k <= n; k++) {
f = z[k][i + 1];
z[k][i + 1] = s*z[k][i] + c*f;
z[k][i] = c*z[k][i] - s*f;
}
}
if (r == 0 && i >= 1)
continue;
d[l] -= p;
e[l] = g;
e[m] = 0.;
}
}
while (m != l);
if (result == Standard_False)
break;
} //end of for (l = 1; l <= n; l++)
} //end of if (n != 1)
iter = 0;
do
{
for (m = l; m <= n - 1; m++)
{
dd = Abs(d[m]) + Abs(d[m + 1]);
if (Abs(e[m]) + dd == dd)
break;
}
if (m != l)
{
if (iter++ == 30)
{
result = Standard_False;
break; // return result;
}
g = (d[l + 1] - d[l]) / (2. * e[l]);
r = pythag(1., g);
if (g < 0)
g = d[m] - d[l] + e[l] / (g - r);
else
g = d[m] - d[l] + e[l] / (g + r);
s = 1.;
c = 1.;
p = 0.;
for (i = m - 1; i >= l; i--)
{
f = s * e[i];
b = c * e[i];
r = pythag(f, g);
e[i + 1] = r;
if (r == 0.)
{
d[i + 1] -= p;
e[m] = 0.;
break;
}
s = f / r;
c = g / r;
g = d[i + 1] - p;
r = (d[i] - g) * s + 2.0 * c * b;
p = s * r;
d[i + 1] = g + p;
g = c * r - b;
for (k = 1; k <= n; k++)
{
f = z[k][i + 1];
z[k][i + 1] = s * z[k][i] + c * f;
z[k][i] = c * z[k][i] - s * f;
}
}
if (r == 0 && i >= 1)
continue;
d[l] -= p;
e[l] = g;
e[m] = 0.;
}
} while (m != l);
if (result == Standard_False)
break;
} // end of for (l = 1; l <= n; l++)
} // end of if (n != 1)
if (result)
{
for (i = 1; i <= n; i++)
myEigenValues->ChangeValue(i) = d[i];
for (i = 1; i <= n; i++)
for (j = 1; j <= n; j++)
myEigenVectors->ChangeValue(i, j) = z[i][j];
}
{
for (i = 1; i <= n; i++)
myEigenValues->ChangeValue(i) = d[i];
for (i = 1; i <= n; i++)
for (j = 1; j <= n; j++)
myEigenVectors->ChangeValue(i, j) = z[i][j];
}
myIsDone = result;
delete [] d;
delete [] e;
delete[] d;
delete[] e;
for (i = 1; i <= n; i++)
delete [] z[i];
delete [] z;
delete[] z[i];
delete[] z;
}
Standard_Boolean math_EigenValuesSearcher::IsDone() const

View File

@@ -27,60 +27,39 @@
#include <Standard_Real.hxx>
#include <math_Vector.hxx>
//! This class finds eigen values and vectors of
//! real symmetric tridiagonal matrix
class math_EigenValuesSearcher
class math_EigenValuesSearcher
{
public:
DEFINE_STANDARD_ALLOC
Standard_EXPORT math_EigenValuesSearcher(const TColStd_Array1OfReal& Diagonal, const TColStd_Array1OfReal& Subdiagonal);
Standard_EXPORT math_EigenValuesSearcher(const TColStd_Array1OfReal& Diagonal,
const TColStd_Array1OfReal& Subdiagonal);
//! Returns Standard_True if computation is performed
//! successfully.
Standard_EXPORT Standard_Boolean IsDone() const;
//! Returns the dimension of matrix
Standard_EXPORT Standard_Integer Dimension() const;
//! Returns the Index_th eigen value of matrix
//! Index must be in [1, Dimension()]
Standard_EXPORT Standard_Real EigenValue (const Standard_Integer Index) const;
Standard_EXPORT Standard_Real EigenValue(const Standard_Integer Index) const;
//! Returns the Index_th eigen vector of matrix
//! Index must be in [1, Dimension()]
Standard_EXPORT math_Vector EigenVector (const Standard_Integer Index) const;
Standard_EXPORT math_Vector EigenVector(const Standard_Integer Index) const;
protected:
private:
Handle(TColStd_HArray1OfReal) myDiagonal;
Handle(TColStd_HArray1OfReal) mySubdiagonal;
Standard_Boolean myIsDone;
Standard_Integer myN;
Standard_Boolean myIsDone;
Standard_Integer myN;
Handle(TColStd_HArray1OfReal) myEigenValues;
Handle(TColStd_HArray2OfReal) myEigenVectors;
};
#endif // _math_EigenValuesSearcher_HeaderFile

View File

@@ -12,12 +12,12 @@
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
//#ifndef OCCT_DEBUG
// #ifndef OCCT_DEBUG
#define No_Standard_RangeError
#define No_Standard_OutOfRange
#define No_Standard_DimensionError
//#endif
// #endif
#include <math_BracketMinimum.hxx>
#include <math_BrentMinimum.hxx>
@@ -29,217 +29,200 @@
// donnee n'est pas du tout optimale. voir peut etre interpolation cubique
// classique et aussi essayer "recherche unidimensionnelle economique"
// PROGRAMMATION MATHEMATIQUE (theorie et algorithmes) tome1 page 82.
class DirFunctionTer : public math_Function {
class DirFunctionTer : public math_Function
{
math_Vector *P0;
math_Vector *Dir;
math_Vector *P;
math_MultipleVarFunction *F;
math_Vector* P0;
math_Vector* Dir;
math_Vector* P;
math_MultipleVarFunction* F;
public :
public:
DirFunctionTer(math_Vector& V1, math_Vector& V2, math_Vector& V3, math_MultipleVarFunction& f);
DirFunctionTer(math_Vector& V1,
math_Vector& V2,
math_Vector& V3,
math_MultipleVarFunction& f);
void Initialize(const math_Vector& p0, const math_Vector& dir);
void Initialize(const math_Vector& p0, const math_Vector& dir);
virtual Standard_Boolean Value(const Standard_Real x, Standard_Real& fval);
virtual Standard_Boolean Value(const Standard_Real x, Standard_Real& fval);
};
DirFunctionTer::DirFunctionTer(math_Vector& V1,
math_Vector& V2,
math_Vector& V3,
math_MultipleVarFunction& f) {
P0 = &V1;
Dir = &V2;
P = &V3;
F = &f;
}
DirFunctionTer::DirFunctionTer(math_Vector& V1,
math_Vector& V2,
math_Vector& V3,
math_MultipleVarFunction& f)
{
void DirFunctionTer::Initialize(const math_Vector& p0,
const math_Vector& dir) {
P0 = &V1;
Dir = &V2;
P = &V3;
F = &f;
}
*P0 = p0;
*Dir = dir;
}
void DirFunctionTer::Initialize(const math_Vector& p0, const math_Vector& dir)
{
Standard_Boolean DirFunctionTer::Value(const Standard_Real x, Standard_Real& fval) {
*P0 = p0;
*Dir = dir;
}
*P = *Dir;
P->Multiply(x);
P->Add(*P0);
fval = 0.;
return F->Value(*P, fval);
}
Standard_Boolean DirFunctionTer::Value(const Standard_Real x, Standard_Real& fval)
{
static Standard_Boolean MinimizeDirection(math_Vector& P,
math_Vector& Dir,
Standard_Real& Result,
DirFunctionTer& F) {
*P = *Dir;
P->Multiply(x);
P->Add(*P0);
fval = 0.;
return F->Value(*P, fval);
}
Standard_Real ax, xx, bx;
static Standard_Boolean MinimizeDirection(math_Vector& P,
math_Vector& Dir,
Standard_Real& Result,
DirFunctionTer& F)
{
F.Initialize(P, Dir);
math_BracketMinimum Bracket(F, 0.0, 1.0);
if(Bracket.IsDone()) {
Bracket.Values(ax, xx, bx);
math_BrentMinimum Sol(1.e-10);
Sol.Perform(F, ax, xx, bx);
if (Sol.IsDone()) {
Standard_Real Scale = Sol.Location();
Result = Sol.Minimum();
Dir.Multiply(Scale);
P.Add(Dir);
return Standard_True;
}
}
return Standard_False;
Standard_Real ax, xx, bx;
F.Initialize(P, Dir);
math_BracketMinimum Bracket(F, 0.0, 1.0);
if (Bracket.IsDone())
{
Bracket.Values(ax, xx, bx);
math_BrentMinimum Sol(1.e-10);
Sol.Perform(F, ax, xx, bx);
if (Sol.IsDone())
{
Standard_Real Scale = Sol.Location();
Result = Sol.Minimum();
Dir.Multiply(Scale);
P.Add(Dir);
return Standard_True;
}
}
return Standard_False;
}
//=================================================================================================
//=======================================================================
//function : math_FRPR
//purpose : Constructor
//=======================================================================
math_FRPR::math_FRPR(const math_MultipleVarFunctionWithGradient& theFunction,
const Standard_Real theTolerance,
const Standard_Integer theNbIterations,
const Standard_Real theZEPS)
: TheLocation(1, theFunction.NbVariables()),
TheGradient(1, theFunction.NbVariables()),
TheMinimum (0.0),
PreviousMinimum(0.0),
XTol (theTolerance),
EPSZ (theZEPS),
Done (Standard_False),
Iter (0),
State (0),
TheStatus (math_NotBracketed),
Itermax (theNbIterations)
: TheLocation(1, theFunction.NbVariables()),
TheGradient(1, theFunction.NbVariables()),
TheMinimum(0.0),
PreviousMinimum(0.0),
XTol(theTolerance),
EPSZ(theZEPS),
Done(Standard_False),
Iter(0),
State(0),
TheStatus(math_NotBracketed),
Itermax(theNbIterations)
{
}
//=======================================================================
//function : ~math_FRPR
//purpose : Destructor
//=======================================================================
math_FRPR::~math_FRPR()
//=================================================================================================
math_FRPR::~math_FRPR() {}
//=================================================================================================
void math_FRPR::Perform(math_MultipleVarFunctionWithGradient& F, const math_Vector& StartingPoint)
{
Standard_Boolean Good;
Standard_Integer n = TheLocation.Length();
Standard_Integer j, its;
Standard_Real gg, gam, dgg;
math_Vector g(1, n), h(1, n);
math_Vector Temp1(1, n);
math_Vector Temp2(1, n);
math_Vector Temp3(1, n);
DirFunctionTer F_Dir(Temp1, Temp2, Temp3, F);
TheLocation = StartingPoint;
Good = F.Values(TheLocation, PreviousMinimum, TheGradient);
if (!Good)
{
Done = Standard_False;
TheStatus = math_FunctionError;
return;
}
g = -TheGradient;
h = g;
TheGradient = g;
for (its = 1; its <= Itermax; its++)
{
Iter = its;
Standard_Boolean IsGood = MinimizeDirection(TheLocation, TheGradient, TheMinimum, F_Dir);
if (IsSolutionReached(F))
{
Done = Standard_True;
State = F.GetStateNumber();
TheStatus = math_OK;
return;
}
if (!IsGood)
{
Done = Standard_False;
TheStatus = math_DirectionSearchError;
return;
}
Good = F.Values(TheLocation, PreviousMinimum, TheGradient);
if (!Good)
{
Done = Standard_False;
TheStatus = math_FunctionError;
return;
}
dgg = 0.0;
gg = 0.0;
for (j = 1; j <= n; j++)
{
gg += g(j) * g(j);
// dgg += TheGradient(j)*TheGradient(j); //for Fletcher-Reeves
dgg += (TheGradient(j) + g(j)) * TheGradient(j); // for Polak-Ribiere
}
if (gg == 0.0)
{
// Unlikely. If gradient is exactly 0 then we are already done.
Done = Standard_False;
TheStatus = math_FunctionError;
return;
}
gam = dgg / gg;
g = -TheGradient;
TheGradient = g + gam * h;
h = TheGradient;
}
Done = Standard_False;
TheStatus = math_TooManyIterations;
return;
}
//=================================================================================================
//=======================================================================
//function : Perform
//purpose :
//=======================================================================
void math_FRPR::Perform(math_MultipleVarFunctionWithGradient& F,
const math_Vector& StartingPoint)
{
Standard_Boolean Good;
Standard_Integer n = TheLocation.Length();
Standard_Integer j, its;
Standard_Real gg, gam, dgg;
math_Vector g(1, n), h(1, n);
math_Vector Temp1(1, n);
math_Vector Temp2(1, n);
math_Vector Temp3(1, n);
DirFunctionTer F_Dir(Temp1, Temp2, Temp3, F);
TheLocation = StartingPoint;
Good = F.Values(TheLocation, PreviousMinimum, TheGradient);
if(!Good) {
Done = Standard_False;
TheStatus = math_FunctionError;
return;
}
g = -TheGradient;
h = g;
TheGradient = g;
for(its = 1; its <= Itermax; its++) {
Iter = its;
Standard_Boolean IsGood = MinimizeDirection(TheLocation,
TheGradient, TheMinimum, F_Dir);
if (IsSolutionReached(F)) {
Done = Standard_True;
State = F.GetStateNumber();
TheStatus = math_OK;
return;
}
if(!IsGood) {
Done = Standard_False;
TheStatus = math_DirectionSearchError;
return;
}
Good = F.Values(TheLocation, PreviousMinimum, TheGradient);
if(!Good) {
Done = Standard_False;
TheStatus = math_FunctionError;
return;
}
dgg =0.0;
gg = 0.0;
for(j = 1; j<= n; j++) {
gg += g(j)*g(j);
// dgg += TheGradient(j)*TheGradient(j); //for Fletcher-Reeves
dgg += (TheGradient(j)+g(j)) * TheGradient(j); //for Polak-Ribiere
}
if (gg == 0.0) {
//Unlikely. If gradient is exactly 0 then we are already done.
Done = Standard_False;
TheStatus = math_FunctionError;
return;
}
gam = dgg/gg;
g = -TheGradient;
TheGradient = g + gam*h;
h = TheGradient;
}
Done = Standard_False;
TheStatus = math_TooManyIterations;
return;
}
//=======================================================================
//function : Dump
//purpose :
//=======================================================================
void math_FRPR::Dump(Standard_OStream& o) const
{
o << "math_FRPR ";
if(Done) {
if (Done)
{
o << " Status = Done \n";
o << " Location Vector = "<< TheLocation << "\n";
o << " Minimum value = " << TheMinimum <<"\n";
o << " Number of iterations = " << Iter <<"\n";
o << " Location Vector = " << TheLocation << "\n";
o << " Minimum value = " << TheMinimum << "\n";
o << " Number of iterations = " << Iter << "\n";
}
else {
else
{
o << " Status = not Done because " << (Standard_Integer)TheStatus << "\n";
}
}

View File

@@ -25,107 +25,87 @@
#include <Standard_OStream.hxx>
class math_MultipleVarFunctionWithGradient;
//! this class implements the Fletcher-Reeves-Polak_Ribiere minimization
//! algorithm of a function of multiple variables.
//! Knowledge of the function's gradient is required.
class math_FRPR
class math_FRPR
{
public:
DEFINE_STANDARD_ALLOC
//! Initializes the computation of the minimum of F.
//! Warning: constructor does not perform computations.
Standard_EXPORT math_FRPR(const math_MultipleVarFunctionWithGradient& theFunction, const Standard_Real theTolerance, const Standard_Integer theNbIterations = 200, const Standard_Real theZEPS = 1.0e-12);
Standard_EXPORT math_FRPR(const math_MultipleVarFunctionWithGradient& theFunction,
const Standard_Real theTolerance,
const Standard_Integer theNbIterations = 200,
const Standard_Real theZEPS = 1.0e-12);
//! Destructor
Standard_EXPORT virtual ~math_FRPR();
//! The solution F = Fi is found when
//! 2.0 * abs(Fi - Fi-1) <= Tolerance * (abs(Fi) + abs(Fi-1) + ZEPS).
Standard_EXPORT void Perform (math_MultipleVarFunctionWithGradient& theFunction, const math_Vector& theStartingPoint);
Standard_EXPORT void Perform(math_MultipleVarFunctionWithGradient& theFunction,
const math_Vector& theStartingPoint);
//! The solution F = Fi is found when:
//! 2.0 * abs(Fi - Fi-1) <= Tolerance * (abs(Fi) + abs(Fi-1)) + ZEPS.
//! The maximum number of iterations allowed is given by NbIterations.
virtual Standard_Boolean IsSolutionReached (math_MultipleVarFunctionWithGradient& theFunction);
virtual Standard_Boolean IsSolutionReached(math_MultipleVarFunctionWithGradient& theFunction);
//! Returns true if the computations are successful, otherwise returns false.
Standard_Boolean IsDone() const;
Standard_Boolean IsDone() const;
//! returns the location vector of the minimum.
//! Exception NotDone is raised if the minimum was not found.
const math_Vector& Location() const;
const math_Vector& Location() const;
//! outputs the location vector of the minimum in Loc.
//! Exception NotDone is raised if the minimum was not found.
//! Exception DimensionError is raised if the range of Loc is not
//! equal to the range of the StartingPoint.
void Location (math_Vector& Loc) const;
void Location(math_Vector& Loc) const;
//! returns the value of the minimum.
//! Exception NotDone is raised if the minimum was not found.
Standard_Real Minimum() const;
Standard_Real Minimum() const;
//! returns the gradient vector at the minimum.
//! Exception NotDone is raised if the minimum was not found.
const math_Vector& Gradient() const;
const math_Vector& Gradient() const;
//! outputs the gradient vector at the minimum in Grad.
//! Exception NotDone is raised if the minimum was not found.
//! Exception DimensionError is raised if the range of Grad is not
//! equal to the range of the StartingPoint.
void Gradient (math_Vector& Grad) const;
void Gradient(math_Vector& Grad) const;
//! returns the number of iterations really done during the
//! computation of the minimum.
//! Exception NotDone is raised if the minimum was not found.
Standard_Integer NbIterations() const;
Standard_Integer NbIterations() const;
//! Prints on the stream o information on the current state
//! of the object.
//! Is used to redefine the operator <<.
Standard_EXPORT void Dump (Standard_OStream& o) const;
Standard_EXPORT void Dump(Standard_OStream& o) const;
protected:
math_Vector TheLocation;
math_Vector TheGradient;
math_Vector TheLocation;
math_Vector TheGradient;
Standard_Real TheMinimum;
Standard_Real PreviousMinimum;
Standard_Real XTol;
Standard_Real EPSZ;
private:
Standard_Boolean Done;
Standard_Integer Iter;
Standard_Integer State;
math_Status TheStatus;
math_Status TheStatus;
Standard_Integer Itermax;
};
#include <math_FRPR.lxx>
#endif // _math_FRPR_HeaderFile

View File

@@ -17,60 +17,53 @@
inline Standard_Boolean math_FRPR::IsSolutionReached(math_MultipleVarFunctionWithGradient&)
{
return 2.0 * fabs(TheMinimum - PreviousMinimum) <=
XTol * (fabs(TheMinimum) + fabs(PreviousMinimum) + EPSZ);
return 2.0 * fabs(TheMinimum - PreviousMinimum)
<= XTol * (fabs(TheMinimum) + fabs(PreviousMinimum) + EPSZ);
}
inline Standard_Boolean math_FRPR::IsDone() const
{
return Done;
}
inline Standard_OStream& operator<<(Standard_OStream& o,
const math_FRPR& Fr)
inline Standard_OStream& operator<<(Standard_OStream& o, const math_FRPR& Fr)
{
Fr.Dump(o);
return o;
}
inline const math_Vector& math_FRPR::Location() const{
inline const math_Vector& math_FRPR::Location() const
{
StdFail_NotDone_Raise_if(!Done, " ");
return TheLocation;
return TheLocation;
}
inline void math_FRPR::Location(math_Vector& Loc) const{
inline void math_FRPR::Location(math_Vector& Loc) const
{
StdFail_NotDone_Raise_if(!Done, " ");
Loc = TheLocation;
Loc = TheLocation;
}
inline const math_Vector& math_FRPR::Gradient() const{
inline const math_Vector& math_FRPR::Gradient() const
{
StdFail_NotDone_Raise_if(!Done, " ");
return TheGradient;
}
inline void math_FRPR::Gradient(math_Vector& Grad) const{
inline void math_FRPR::Gradient(math_Vector& Grad) const
{
StdFail_NotDone_Raise_if(!Done, " ");
Grad = TheGradient;
}
inline Standard_Real math_FRPR::Minimum() const{
inline Standard_Real math_FRPR::Minimum() const
{
StdFail_NotDone_Raise_if(!Done, " ");
return TheMinimum;
}
inline Standard_Integer math_FRPR::NbIterations() const{
inline Standard_Integer math_FRPR::NbIterations() const
{
StdFail_NotDone_Raise_if(!Done, " ");
return Iter;
}

View File

@@ -12,7 +12,9 @@
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <math_Function.hxx>
Standard_Integer math_Function::GetStateNumber() { return 0; }
Standard_Integer math_Function::GetStateNumber()
{
return 0;
}

View File

@@ -24,24 +24,22 @@
#include <Standard_Boolean.hxx>
#include <Standard_Real.hxx>
//! This abstract class describes the virtual functions
//! associated with a Function of a single variable.
class math_Function
class math_Function
{
public:
DEFINE_STANDARD_ALLOC
//! Virtual destructor, for safe inheritance
virtual ~math_Function () {}
virtual ~math_Function() {}
//! Computes the value of the function <F> for a given value of
//! variable <X>.
//! returns True if the computation was done successfully,
//! False otherwise.
Standard_EXPORT virtual Standard_Boolean Value (const Standard_Real X, Standard_Real& F) = 0;
Standard_EXPORT virtual Standard_Boolean Value(const Standard_Real X, Standard_Real& F) = 0;
//! returns the state of the function corresponding to the
//! latest call of any methods associated with the function.
//! This function is called by each of the algorithms

View File

@@ -12,12 +12,12 @@
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
//#ifndef OCCT_DEBUG
// #ifndef OCCT_DEBUG
#define No_Standard_RangeError
#define No_Standard_OutOfRange
#define No_Standard_DimensionError
//#endif
// #endif
#include <math_FunctionAllRoots.hxx>
#include <math_FunctionRoots.hxx>
@@ -25,206 +25,223 @@
#include <math_FunctionWithDerivative.hxx>
#include <Standard_NumericError.hxx>
math_FunctionAllRoots::math_FunctionAllRoots (
math_FunctionWithDerivative& F,
const math_FunctionSample& S,
const Standard_Real EpsX, const Standard_Real EpsF,
const Standard_Real EpsNul) {
math_FunctionAllRoots::math_FunctionAllRoots(math_FunctionWithDerivative& F,
const math_FunctionSample& S,
const Standard_Real EpsX,
const Standard_Real EpsF,
const Standard_Real EpsNul)
{
done=Standard_False;
done = Standard_False;
Standard_Boolean Nul, PNul, InterNul, Nuld, Nulf;
Standard_Real DebNul = 0., FinNul = 0.;
Standard_Integer Indd = 0, Indf = 0;
Standard_Real cst, val, valsav = 0, valbid;
Standard_Boolean fini;
Standard_Integer Nbp, i;
Nbp = S.NbPoints();
F.Value(S.GetParameter(1), val);
PNul = Abs(val) <= EpsNul;
if (!PNul)
{
valsav = val;
}
InterNul = Standard_False;
Nuld = Standard_False;
Nulf = Standard_False;
Standard_Boolean Nul, PNul, InterNul, Nuld, Nulf;
Standard_Real DebNul = 0., FinNul = 0.;
Standard_Integer Indd = 0, Indf = 0;
Standard_Real cst,val,valsav=0,valbid;
Standard_Boolean fini;
Standard_Integer Nbp,i;
i = 2;
fini = (i > Nbp);
Nbp=S.NbPoints();
F.Value(S.GetParameter(1),val);
PNul=Abs(val)<=EpsNul;
if (!PNul) {valsav=val;}
InterNul=Standard_False;
Nuld=Standard_False;
Nulf=Standard_False;
while (!fini)
{
i=2;
fini=(i>Nbp);
while (!fini) {
F.Value(S.GetParameter(i),val);
Nul=Abs(val)<=EpsNul;
if (!Nul) {
valsav=val;
}
if (InterNul && (!Nul)) {
InterNul=Standard_False;
pdeb.Append(DebNul);
ideb.Append(Indd);
if (val>0.0) {
cst=EpsNul;
}
else {
cst=-EpsNul;
}
math_FunctionRoots Res1(F,S.GetParameter(i-1),S.GetParameter(i),10,
EpsX,EpsF,0.0,cst);
Standard_NumericError_Raise_if((!Res1.IsDone()) ||
(Res1.IsAllNull()) ||
(Res1.NbSolutions()==0), " ");
FinNul=Res1.Value(1);
Indf=Res1.StateNumber(1);
cst=-cst;
math_FunctionRoots Res2(F,S.GetParameter(i-1),S.GetParameter(i),10,
EpsX,EpsF,0.0,cst);
Standard_NumericError_Raise_if((!Res2.IsDone()) ||
(Res2.IsAllNull())," ");
//-- || (Res2.NbSolutions()!=0), " "); lbr le 13 mai 87 (!=0 -> ==0)
if (Res2.NbSolutions()!=0) {
if (Res2.Value(1) < FinNul) {
FinNul = Res2.Value(1);
Indf = Res2.StateNumber(1);
}
}
pfin.Append(FinNul);
ifin.Append(Indf);
}
else if ((!InterNul) && PNul && Nul) {
InterNul=Standard_True;
if (i==2) {
DebNul=S.GetParameter(1);
F.Value(DebNul,valbid);
Indd = F.GetStateNumber();
Nuld=Standard_True;
}
else {
if (valsav>0.0) {
cst=EpsNul;
}
else {
cst=-EpsNul;
}
math_FunctionRoots Res1(F,S.GetParameter(i-2),S.GetParameter(i-1),10,
EpsX,EpsF,0.0,cst);
Standard_NumericError_Raise_if((!Res1.IsDone()) ||
(Res1.IsAllNull()) ||
(Res1.NbSolutions()==0), " ");
DebNul=Res1.Value(Res1.NbSolutions());
Indd = Res1.StateNumber(Res1.NbSolutions());
cst=-cst;
math_FunctionRoots Res3(F,S.GetParameter(i-2),S.GetParameter(i-1),10,
EpsX,EpsF,0.0,cst);
Standard_NumericError_Raise_if((!Res3.IsDone()) ||
(Res3.IsAllNull()), " ");
if (Res3.NbSolutions()!=0) {
if (Res3.Value(Res3.NbSolutions()) > DebNul) {
DebNul = Res3.Value(Res3.NbSolutions());
Indd = Res3.StateNumber(Res3.NbSolutions());
}
}
}
}
i=i+1;
PNul=Nul;
fini=(i>Nbp);
F.Value(S.GetParameter(i), val);
Nul = Abs(val) <= EpsNul;
if (!Nul)
{
valsav = val;
}
if (InterNul) { // rajouter l intervalle finissant au dernier pt
if (InterNul && (!Nul))
{
InterNul = Standard_False;
pdeb.Append(DebNul);
ideb.Append(Indd);
FinNul = S.GetParameter(Nbp);
F.Value(FinNul,valbid);
Indf = F.GetStateNumber();
if (val > 0.0)
{
cst = EpsNul;
}
else
{
cst = -EpsNul;
}
math_FunctionRoots
Res1(F, S.GetParameter(i - 1), S.GetParameter(i), 10, EpsX, EpsF, 0.0, cst);
Standard_NumericError_Raise_if((!Res1.IsDone()) || (Res1.IsAllNull())
|| (Res1.NbSolutions() == 0),
" ");
FinNul = Res1.Value(1);
Indf = Res1.StateNumber(1);
cst = -cst;
math_FunctionRoots
Res2(F, S.GetParameter(i - 1), S.GetParameter(i), 10, EpsX, EpsF, 0.0, cst);
Standard_NumericError_Raise_if((!Res2.IsDone()) || (Res2.IsAllNull()), " ");
//-- || (Res2.NbSolutions()!=0), " "); lbr le 13 mai 87 (!=0 -> ==0)
if (Res2.NbSolutions() != 0)
{
if (Res2.Value(1) < FinNul)
{
FinNul = Res2.Value(1);
Indf = Res2.StateNumber(1);
}
}
pfin.Append(FinNul);
ifin.Append(Indf);
Nulf=Standard_True;
}
else if ((!InterNul) && PNul && Nul)
{
InterNul = Standard_True;
if (i == 2)
{
DebNul = S.GetParameter(1);
F.Value(DebNul, valbid);
Indd = F.GetStateNumber();
Nuld = Standard_True;
}
else
{
if (valsav > 0.0)
{
cst = EpsNul;
}
else
{
cst = -EpsNul;
}
math_FunctionRoots
Res1(F, S.GetParameter(i - 2), S.GetParameter(i - 1), 10, EpsX, EpsF, 0.0, cst);
Standard_NumericError_Raise_if((!Res1.IsDone()) || (Res1.IsAllNull())
|| (Res1.NbSolutions() == 0),
" ");
DebNul = Res1.Value(Res1.NbSolutions());
Indd = Res1.StateNumber(Res1.NbSolutions());
if (pdeb.Length()==0) { // Pas d intervalle nul
cst = -cst;
math_FunctionRoots
Res3(F, S.GetParameter(i - 2), S.GetParameter(i - 1), 10, EpsX, EpsF, 0.0, cst);
Standard_NumericError_Raise_if((!Res3.IsDone()) || (Res3.IsAllNull()), " ");
math_FunctionRoots Res(F,S.GetParameter(1),S.GetParameter(Nbp),Nbp,
EpsX,EpsF,0.0);
Standard_NumericError_Raise_if((!Res.IsDone()) ||
(Res.IsAllNull()), " ");
for (Standard_Integer j=1; j<=Res.NbSolutions(); j++) {
piso.Append(Res.Value(j));
iiso.Append(Res.StateNumber(j));
if (Res3.NbSolutions() != 0)
{
if (Res3.Value(Res3.NbSolutions()) > DebNul)
{
DebNul = Res3.Value(Res3.NbSolutions());
Indd = Res3.StateNumber(Res3.NbSolutions());
}
}
}
}
else {
Standard_Integer NbpMin = 3;
Standard_Integer Nbrpt;
if (!Nuld) { // Recherche des solutions entre S.GetParameter(1)
// et le debut du 1er intervalle nul
Nbrpt=(Standard_Integer ) IntegerPart(
Abs((pdeb.Value(1)-S.GetParameter(1))/
(S.GetParameter(Nbp)-S.GetParameter(1)))*Nbp);
math_FunctionRoots Res(F,S.GetParameter(1),pdeb.Value(1),
Max(Nbrpt, NbpMin), EpsX,EpsF,0.0);
Standard_NumericError_Raise_if((!Res.IsDone()) ||
(Res.IsAllNull()), " ");
for (Standard_Integer j=1; j<=Res.NbSolutions(); j++) {
piso.Append(Res.Value(j));
iiso.Append(Res.StateNumber(j));
}
}
for (Standard_Integer k=2; k<=pdeb.Length(); k++) {
Nbrpt=(Standard_Integer )
IntegerPart(Abs((pdeb.Value(k)-pfin.Value(k-1))/
(S.GetParameter(Nbp)-S.GetParameter(1)))*Nbp);
math_FunctionRoots Res(F,pfin.Value(k-1),pdeb.Value(k),
Max(Nbrpt, NbpMin), EpsX,EpsF,0.0);
Standard_NumericError_Raise_if((!Res.IsDone()) ||
(Res.IsAllNull()), " ");
for (Standard_Integer j=1; j<=Res.NbSolutions(); j++) {
piso.Append(Res.Value(j));
iiso.Append(Res.StateNumber(j));
}
}
if (!Nulf) { // Recherche des solutions entre la fin du
// dernier intervalle nul et Value(Nbp).
Nbrpt=(Standard_Integer )
IntegerPart(Abs((S.GetParameter(Nbp)-
pfin.Value(pdeb.Length()))/
(S.GetParameter(Nbp)-S.GetParameter(1)))*Nbp);
math_FunctionRoots Res(F,pfin.Value(pdeb.Length()),
S.GetParameter(Nbp), Max(Nbrpt, NbpMin),
EpsX,EpsF,0.0);
Standard_NumericError_Raise_if((!Res.IsDone()) ||
(Res.IsAllNull()), " ");
for (Standard_Integer j=1; j<=Res.NbSolutions(); j++) {
piso.Append(Res.Value(j));
iiso.Append(Res.StateNumber(j));
}
}
}
done=Standard_True;
i = i + 1;
PNul = Nul;
fini = (i > Nbp);
}
if (InterNul)
{ // rajouter l intervalle finissant au dernier pt
pdeb.Append(DebNul);
ideb.Append(Indd);
FinNul = S.GetParameter(Nbp);
F.Value(FinNul, valbid);
Indf = F.GetStateNumber();
pfin.Append(FinNul);
ifin.Append(Indf);
Nulf = Standard_True;
}
void math_FunctionAllRoots::Dump(Standard_OStream& o) const {
o<< "math_FunctionAllRoots ";
if(done) {
o<< " Status = Done \n";
if (pdeb.Length() == 0)
{ // Pas d intervalle nul
math_FunctionRoots Res(F, S.GetParameter(1), S.GetParameter(Nbp), Nbp, EpsX, EpsF, 0.0);
Standard_NumericError_Raise_if((!Res.IsDone()) || (Res.IsAllNull()), " ");
for (Standard_Integer j = 1; j <= Res.NbSolutions(); j++)
{
piso.Append(Res.Value(j));
iiso.Append(Res.StateNumber(j));
}
}
else
{
Standard_Integer NbpMin = 3;
Standard_Integer Nbrpt;
if (!Nuld)
{ // Recherche des solutions entre S.GetParameter(1)
// et le debut du 1er intervalle nul
Nbrpt = (Standard_Integer)IntegerPart(
Abs((pdeb.Value(1) - S.GetParameter(1)) / (S.GetParameter(Nbp) - S.GetParameter(1))) * Nbp);
math_FunctionRoots
Res(F, S.GetParameter(1), pdeb.Value(1), Max(Nbrpt, NbpMin), EpsX, EpsF, 0.0);
Standard_NumericError_Raise_if((!Res.IsDone()) || (Res.IsAllNull()), " ");
for (Standard_Integer j = 1; j <= Res.NbSolutions(); j++)
{
piso.Append(Res.Value(j));
iiso.Append(Res.StateNumber(j));
}
}
for (Standard_Integer k = 2; k <= pdeb.Length(); k++)
{
Nbrpt = (Standard_Integer)IntegerPart(
Abs((pdeb.Value(k) - pfin.Value(k - 1)) / (S.GetParameter(Nbp) - S.GetParameter(1))) * Nbp);
math_FunctionRoots
Res(F, pfin.Value(k - 1), pdeb.Value(k), Max(Nbrpt, NbpMin), EpsX, EpsF, 0.0);
Standard_NumericError_Raise_if((!Res.IsDone()) || (Res.IsAllNull()), " ");
for (Standard_Integer j = 1; j <= Res.NbSolutions(); j++)
{
piso.Append(Res.Value(j));
iiso.Append(Res.StateNumber(j));
}
}
if (!Nulf)
{ // Recherche des solutions entre la fin du
// dernier intervalle nul et Value(Nbp).
Nbrpt = (Standard_Integer)IntegerPart(Abs((S.GetParameter(Nbp) - pfin.Value(pdeb.Length()))
/ (S.GetParameter(Nbp) - S.GetParameter(1)))
* Nbp);
math_FunctionRoots
Res(F, pfin.Value(pdeb.Length()), S.GetParameter(Nbp), Max(Nbrpt, NbpMin), EpsX, EpsF, 0.0);
Standard_NumericError_Raise_if((!Res.IsDone()) || (Res.IsAllNull()), " ");
for (Standard_Integer j = 1; j <= Res.NbSolutions(); j++)
{
piso.Append(Res.Value(j));
iiso.Append(Res.StateNumber(j));
}
}
}
done = Standard_True;
}
void math_FunctionAllRoots::Dump(Standard_OStream& o) const
{
o << "math_FunctionAllRoots ";
if (done)
{
o << " Status = Done \n";
o << " Number of null intervals = " << pdeb.Length() << std::endl;
o << " Number of points where the function is null: " << piso.Length() << std::endl;
}
else {
o<< " Status = not Done \n";
else
{
o << " Status = not Done \n";
}
}

View File

@@ -28,19 +28,16 @@
class math_FunctionWithDerivative;
class math_FunctionSample;
//! This algorithm uses a sample of the function to find
//! all intervals on which the function is null, and afterwards
//! uses the FunctionRoots algorithm to find the points
//! where the function is null outside the "null intervals".
//! Knowledge of the derivative is required.
class math_FunctionAllRoots
class math_FunctionAllRoots
{
public:
DEFINE_STANDARD_ALLOC
//! The algorithm uses the sample to find intervals on which
//! the function is null. An interval is found if, for at least
//! two consecutive points of the sample, Ui and Ui+1, we get
@@ -49,73 +46,61 @@ public:
//! algorithm.
//! Between two intervals, the roots of the function F are
//! calculated using the FunctionRoots algorithm.
Standard_EXPORT math_FunctionAllRoots(math_FunctionWithDerivative& F, const math_FunctionSample& S, const Standard_Real EpsX, const Standard_Real EpsF, const Standard_Real EpsNul);
Standard_EXPORT math_FunctionAllRoots(math_FunctionWithDerivative& F,
const math_FunctionSample& S,
const Standard_Real EpsX,
const Standard_Real EpsF,
const Standard_Real EpsNul);
//! Returns True if the computation has been done successfully.
Standard_Boolean IsDone() const;
Standard_Boolean IsDone() const;
//! Returns the number of intervals on which the function
//! is Null.
//! An exception is raised if IsDone returns False.
Standard_Integer NbIntervals() const;
Standard_Integer NbIntervals() const;
//! Returns the interval of parameter of range Index.
//! An exception is raised if IsDone returns False;
//! An exception is raised if Index<=0 or Index >Nbintervals.
void GetInterval (const Standard_Integer Index, Standard_Real& A, Standard_Real& B) const;
void GetInterval(const Standard_Integer Index, Standard_Real& A, Standard_Real& B) const;
//! returns the State Number associated to the interval Index.
//! An exception is raised if IsDone returns False;
//! An exception is raised if Index<=0 or Index >Nbintervals.
void GetIntervalState (const Standard_Integer Index, Standard_Integer& IFirst, Standard_Integer& ILast) const;
void GetIntervalState(const Standard_Integer Index,
Standard_Integer& IFirst,
Standard_Integer& ILast) const;
//! returns the number of points where the function is Null.
//! An exception is raised if IsDone returns False.
Standard_Integer NbPoints() const;
Standard_Integer NbPoints() const;
//! Returns the parameter of the point of range Index.
//! An exception is raised if IsDone returns False;
//! An exception is raised if Index<=0 or Index >NbPoints.
Standard_Real GetPoint (const Standard_Integer Index) const;
Standard_Real GetPoint(const Standard_Integer Index) const;
//! returns the State Number associated to the point Index.
//! An exception is raised if IsDone returns False;
//! An exception is raised if Index<=0 or Index >Nbintervals.
Standard_Integer GetPointState (const Standard_Integer Index) const;
Standard_Integer GetPointState(const Standard_Integer Index) const;
//! Prints on the stream o information on the current state
//! of the object.
Standard_EXPORT void Dump (Standard_OStream& o) const;
Standard_EXPORT void Dump(Standard_OStream& o) const;
protected:
private:
Standard_Boolean done;
TColStd_SequenceOfReal pdeb;
TColStd_SequenceOfReal pfin;
TColStd_SequenceOfReal piso;
Standard_Boolean done;
TColStd_SequenceOfReal pdeb;
TColStd_SequenceOfReal pfin;
TColStd_SequenceOfReal piso;
TColStd_SequenceOfInteger ideb;
TColStd_SequenceOfInteger ifin;
TColStd_SequenceOfInteger iiso;
};
#include <math_FunctionAllRoots.lxx>
#endif // _math_FunctionAllRoots_HeaderFile

View File

@@ -16,50 +16,55 @@
#include <TColStd_SequenceOfReal.hxx>
#include <TColStd_SequenceOfInteger.hxx>
inline Standard_Boolean math_FunctionAllRoots::IsDone() const { return done; }
inline Standard_Boolean math_FunctionAllRoots::IsDone() const
{
return done;
}
inline Standard_OStream& operator<<(Standard_OStream& o,
const math_FunctionAllRoots& F)
inline Standard_OStream& operator<<(Standard_OStream& o, const math_FunctionAllRoots& F)
{
F.Dump(o);
return o;
}
inline Standard_Integer math_FunctionAllRoots::NbIntervals () const {
inline Standard_Integer math_FunctionAllRoots::NbIntervals() const
{
StdFail_NotDone_Raise_if(!done, " ");
return pdeb.Length();
}
inline void math_FunctionAllRoots::GetInterval (const Standard_Integer Index,
Standard_Real& A,
Standard_Real& B) const {
inline void math_FunctionAllRoots::GetInterval(const Standard_Integer Index,
Standard_Real& A,
Standard_Real& B) const
{
StdFail_NotDone_Raise_if(!done, " ");
A=pdeb.Value(Index);
B=pfin.Value(Index);
A = pdeb.Value(Index);
B = pfin.Value(Index);
}
inline void math_FunctionAllRoots::GetIntervalState (const Standard_Integer Index,
Standard_Integer& IFirst,
Standard_Integer& ILast) const {
inline void math_FunctionAllRoots::GetIntervalState(const Standard_Integer Index,
Standard_Integer& IFirst,
Standard_Integer& ILast) const
{
StdFail_NotDone_Raise_if(!done, " ");
IFirst=ideb.Value(Index);
ILast=ifin.Value(Index);
IFirst = ideb.Value(Index);
ILast = ifin.Value(Index);
}
inline Standard_Integer math_FunctionAllRoots::NbPoints () const {
inline Standard_Integer math_FunctionAllRoots::NbPoints() const
{
StdFail_NotDone_Raise_if(!done, " ");
return piso.Length();
}
inline Standard_Real math_FunctionAllRoots::GetPoint (const Standard_Integer Index) const {
inline Standard_Real math_FunctionAllRoots::GetPoint(const Standard_Integer Index) const
{
StdFail_NotDone_Raise_if(!done, " ");
return piso.Value(Index);
}
inline Standard_Integer math_FunctionAllRoots::GetPointState (const Standard_Integer Index) const {
inline Standard_Integer math_FunctionAllRoots::GetPointState(const Standard_Integer Index) const
{
StdFail_NotDone_Raise_if(!done, " ");
return iiso.Value(Index);
}

View File

@@ -12,113 +12,128 @@
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
//#ifndef OCCT_DEBUG
// #ifndef OCCT_DEBUG
#define No_Standard_RangeError
#define No_Standard_OutOfRange
#define No_Standard_DimensionError
//#endif
// #endif
#include <math_FunctionRoot.hxx>
#include <math_FunctionSetRoot.hxx>
#include <math_FunctionSetWithDerivatives.hxx>
#include <math_FunctionWithDerivative.hxx>
class math_MyFunctionSetWithDerivatives : public math_FunctionSetWithDerivatives {
class math_MyFunctionSetWithDerivatives : public math_FunctionSetWithDerivatives
{
private:
math_FunctionWithDerivative *Ff;
public :
private:
math_FunctionWithDerivative* Ff;
math_MyFunctionSetWithDerivatives (math_FunctionWithDerivative& F );
Standard_Integer NbVariables () const;
Standard_Integer NbEquations () const;
Standard_Boolean Value (const math_Vector& X, math_Vector& F) ;
Standard_Boolean Derivatives (const math_Vector& X, math_Matrix& D) ;
Standard_Boolean Values (const math_Vector& X, math_Vector& F, math_Matrix& D) ;
public:
math_MyFunctionSetWithDerivatives(math_FunctionWithDerivative& F);
Standard_Integer NbVariables() const;
Standard_Integer NbEquations() const;
Standard_Boolean Value(const math_Vector& X, math_Vector& F);
Standard_Boolean Derivatives(const math_Vector& X, math_Matrix& D);
Standard_Boolean Values(const math_Vector& X, math_Vector& F, math_Matrix& D);
};
math_MyFunctionSetWithDerivatives::math_MyFunctionSetWithDerivatives(math_FunctionWithDerivative& F)
{
Ff = &F;
}
math_MyFunctionSetWithDerivatives::math_MyFunctionSetWithDerivatives
(math_FunctionWithDerivative& F ) {
Ff = &F ;
}
Standard_Integer math_MyFunctionSetWithDerivatives::NbVariables () const {
return 1;
}
Standard_Integer math_MyFunctionSetWithDerivatives::NbEquations () const {
return 1;
}
Standard_Boolean math_MyFunctionSetWithDerivatives::Value (const math_Vector& X, math_Vector& Fs) {
return Ff->Value(X(1),Fs(1));
}
Standard_Boolean math_MyFunctionSetWithDerivatives::Derivatives (const math_Vector& X, math_Matrix& D) {
return Ff->Derivative(X(1),D(1,1));
}
Standard_Boolean math_MyFunctionSetWithDerivatives::Values (const math_Vector& X, math_Vector& F, math_Matrix& D) {
return Ff->Values(X(1),F(1),D(1,1));
}
Standard_Integer math_MyFunctionSetWithDerivatives::NbVariables() const
{
return 1;
}
Standard_Integer math_MyFunctionSetWithDerivatives::NbEquations() const
{
return 1;
}
Standard_Boolean math_MyFunctionSetWithDerivatives::Value(const math_Vector& X, math_Vector& Fs)
{
return Ff->Value(X(1), Fs(1));
}
Standard_Boolean math_MyFunctionSetWithDerivatives::Derivatives(const math_Vector& X,
math_Matrix& D)
{
return Ff->Derivative(X(1), D(1, 1));
}
math_FunctionRoot::math_FunctionRoot(math_FunctionWithDerivative& F,
const Standard_Real Guess,
const Standard_Real Tolerance,
const Standard_Integer NbIterations ){
math_Vector V(1,1), Tol(1,1);
math_MyFunctionSetWithDerivatives Ff(F);
V(1)=Guess;
Tol(1) = Tolerance;
math_FunctionSetRoot Sol(Ff, Tol, NbIterations);
Sol.Perform(Ff, V);
Done = Sol.IsDone();
if (Done) {
F.GetStateNumber();
TheRoot = Sol.Root()(1);
TheDerivative = Sol.Derivative()(1,1);
F.Value(TheRoot,TheError);
NbIter = Sol.NbIterations();
}
}
math_FunctionRoot::math_FunctionRoot(math_FunctionWithDerivative& F,
const Standard_Real Guess,
const Standard_Real Tolerance,
const Standard_Real A,
const Standard_Real B,
const Standard_Integer NbIterations ){
math_Vector V(1,1),Aa(1,1),Bb(1,1), Tol(1,1);
math_MyFunctionSetWithDerivatives Ff(F);
V(1)=Guess;
Tol(1) = Tolerance;
Aa(1)=A;
Bb(1)=B;
math_FunctionSetRoot Sol(Ff, Tol, NbIterations);
Sol.Perform(Ff, V, Aa, Bb);
Done = Sol.IsDone();
if (Done) {
F.GetStateNumber();
TheRoot = Sol.Root()(1);
TheDerivative = Sol.Derivative()(1,1);
F.Value(TheRoot,TheError);
NbIter = Sol.NbIterations();
}
}
Standard_Boolean math_MyFunctionSetWithDerivatives::Values(const math_Vector& X,
math_Vector& F,
math_Matrix& D)
{
return Ff->Values(X(1), F(1), D(1, 1));
}
void math_FunctionRoot::Dump(Standard_OStream& o) const {
math_FunctionRoot::math_FunctionRoot(math_FunctionWithDerivative& F,
const Standard_Real Guess,
const Standard_Real Tolerance,
const Standard_Integer NbIterations)
{
math_Vector V(1, 1), Tol(1, 1);
math_MyFunctionSetWithDerivatives Ff(F);
V(1) = Guess;
Tol(1) = Tolerance;
math_FunctionSetRoot Sol(Ff, Tol, NbIterations);
Sol.Perform(Ff, V);
Done = Sol.IsDone();
if (Done)
{
F.GetStateNumber();
TheRoot = Sol.Root()(1);
TheDerivative = Sol.Derivative()(1, 1);
F.Value(TheRoot, TheError);
NbIter = Sol.NbIterations();
}
}
o<< "math_FunctionRoot ";
if(Done) {
o<< " Status = Done \n";
o << " Number of iterations = " << NbIter << std::endl;
o << " The Root is: " << TheRoot << std::endl;
o << "The value at the root is: " << TheError << std::endl;
}
else {
o<< " Status = not Done \n";
}
}
math_FunctionRoot::math_FunctionRoot(math_FunctionWithDerivative& F,
const Standard_Real Guess,
const Standard_Real Tolerance,
const Standard_Real A,
const Standard_Real B,
const Standard_Integer NbIterations)
{
math_Vector V(1, 1), Aa(1, 1), Bb(1, 1), Tol(1, 1);
math_MyFunctionSetWithDerivatives Ff(F);
V(1) = Guess;
Tol(1) = Tolerance;
Aa(1) = A;
Bb(1) = B;
math_FunctionSetRoot Sol(Ff, Tol, NbIterations);
Sol.Perform(Ff, V, Aa, Bb);
Done = Sol.IsDone();
if (Done)
{
F.GetStateNumber();
TheRoot = Sol.Root()(1);
TheDerivative = Sol.Derivative()(1, 1);
F.Value(TheRoot, TheError);
NbIter = Sol.NbIterations();
}
}
void math_FunctionRoot::Dump(Standard_OStream& o) const
{
o << "math_FunctionRoot ";
if (Done)
{
o << " Status = Done \n";
o << " Number of iterations = " << NbIter << std::endl;
o << " The Root is: " << TheRoot << std::endl;
o << "The value at the root is: " << TheError << std::endl;
}
else
{
o << " Status = not Done \n";
}
}

View File

@@ -25,28 +25,25 @@
#include <Standard_OStream.hxx>
class math_FunctionWithDerivative;
//! This class implements the computation of a root of a function of
//! a single variable which is near an initial guess using a minimization
//! algorithm.Knowledge of the derivative is required. The
//! algorithm used is the same as in
class math_FunctionRoot
class math_FunctionRoot
{
public:
DEFINE_STANDARD_ALLOC
//! The Newton-Raphson method is done to find the root of the function F
//! from the initial guess Guess.The tolerance required on
//! the root is given by Tolerance. Iterations are stopped if
//! the expected solution does not stay in the range A..B.
//! The solution is found when abs(Xi - Xi-1) <= Tolerance;
//! The maximum number of iterations allowed is given by NbIterations.
Standard_EXPORT math_FunctionRoot(math_FunctionWithDerivative& F, const Standard_Real Guess, const Standard_Real Tolerance, const Standard_Integer NbIterations = 100);
Standard_EXPORT math_FunctionRoot(math_FunctionWithDerivative& F,
const Standard_Real Guess,
const Standard_Real Tolerance,
const Standard_Integer NbIterations = 100);
//! The Newton-Raphson method is done to find the root of the function F
//! from the initial guess Guess.
@@ -55,60 +52,47 @@ public:
//! range A..B
//! The solution is found when abs(Xi - Xi-1) <= Tolerance;
//! The maximum number of iterations allowed is given by NbIterations.
Standard_EXPORT math_FunctionRoot(math_FunctionWithDerivative& F, const Standard_Real Guess, const Standard_Real Tolerance, const Standard_Real A, const Standard_Real B, const Standard_Integer NbIterations = 100);
Standard_EXPORT math_FunctionRoot(math_FunctionWithDerivative& F,
const Standard_Real Guess,
const Standard_Real Tolerance,
const Standard_Real A,
const Standard_Real B,
const Standard_Integer NbIterations = 100);
//! Returns true if the computations are successful, otherwise returns false.
Standard_Boolean IsDone() const;
Standard_Boolean IsDone() const;
//! returns the value of the root.
//! Exception NotDone is raised if the root was not found.
Standard_Real Root() const;
Standard_Real Root() const;
//! returns the value of the derivative at the root.
//! Exception NotDone is raised if the root was not found.
Standard_Real Derivative() const;
Standard_Real Derivative() const;
//! returns the value of the function at the root.
//! Exception NotDone is raised if the root was not found.
Standard_Real Value() const;
Standard_Real Value() const;
//! returns the number of iterations really done on the
//! computation of the Root.
//! Exception NotDone is raised if the root was not found.
Standard_Integer NbIterations() const;
Standard_Integer NbIterations() const;
//! Prints on the stream o information on the current state
//! of the object.
//! Is used to redefine the operator <<.
Standard_EXPORT void Dump (Standard_OStream& o) const;
Standard_EXPORT void Dump(Standard_OStream& o) const;
protected:
private:
Standard_Boolean Done;
Standard_Real TheRoot;
Standard_Real TheError;
Standard_Real TheDerivative;
Standard_Real TheRoot;
Standard_Real TheError;
Standard_Real TheDerivative;
Standard_Integer NbIter;
};
#include <math_FunctionRoot.lxx>
#endif // _math_FunctionRoot_HeaderFile

View File

@@ -14,35 +14,37 @@
#include <StdFail_NotDone.hxx>
inline Standard_Boolean math_FunctionRoot::IsDone() const { return Done; }
inline Standard_Boolean math_FunctionRoot::IsDone() const
{
return Done;
}
inline Standard_OStream& operator<<(Standard_OStream& o,
const math_FunctionRoot& F)
inline Standard_OStream& operator<<(Standard_OStream& o, const math_FunctionRoot& F)
{
F.Dump(o);
return o;
}
inline Standard_Real math_FunctionRoot::Root () const {
inline Standard_Real math_FunctionRoot::Root() const
{
StdFail_NotDone_Raise_if(!Done, " ");
return TheRoot;
}
inline Standard_Real math_FunctionRoot::Derivative () const {
inline Standard_Real math_FunctionRoot::Derivative() const
{
StdFail_NotDone_Raise_if(!Done, " ");
return TheDerivative;
}
inline Standard_Real math_FunctionRoot::Value () const {
inline Standard_Real math_FunctionRoot::Value() const
{
StdFail_NotDone_Raise_if(!Done, " ");
return TheError;
}
inline Standard_Integer math_FunctionRoot::NbIterations () const {
inline Standard_Integer math_FunctionRoot::NbIterations() const
{
StdFail_NotDone_Raise_if(!Done, " ");
return NbIter;
}

File diff suppressed because it is too large Load Diff

View File

@@ -26,81 +26,64 @@
#include <Standard_OStream.hxx>
class math_FunctionWithDerivative;
//! This class implements an algorithm which finds all the real roots of
//! a function with derivative within a given range.
//! Knowledge of the derivative is required.
class math_FunctionRoots
class math_FunctionRoots
{
public:
DEFINE_STANDARD_ALLOC
//! Calculates all the real roots of a function F-K within the range
//! A..B. without conditions on A and B
//! A solution X is found when
//! abs(Xi - Xi-1) <= Epsx and abs(F(Xi)-K) <= EpsF.
//! The function is considered as null between A and B if
//! abs(F-K) <= EpsNull within this range.
Standard_EXPORT math_FunctionRoots(math_FunctionWithDerivative& F, const Standard_Real A, const Standard_Real B, const Standard_Integer NbSample, const Standard_Real EpsX = 0.0, const Standard_Real EpsF = 0.0, const Standard_Real EpsNull = 0.0, const Standard_Real K = 0.0);
Standard_EXPORT math_FunctionRoots(math_FunctionWithDerivative& F,
const Standard_Real A,
const Standard_Real B,
const Standard_Integer NbSample,
const Standard_Real EpsX = 0.0,
const Standard_Real EpsF = 0.0,
const Standard_Real EpsNull = 0.0,
const Standard_Real K = 0.0);
//! Returns true if the computations are successful, otherwise returns false.
Standard_Boolean IsDone() const;
Standard_Boolean IsDone() const;
//! returns true if the function is considered as null between A and B.
//! Exceptions
//! StdFail_NotDone if the algorithm fails (and IsDone returns false).
Standard_Boolean IsAllNull() const;
Standard_Boolean IsAllNull() const;
//! Returns the number of solutions found.
//! Exceptions
//! StdFail_NotDone if the algorithm fails (and IsDone returns false).
Standard_Integer NbSolutions() const;
Standard_Integer NbSolutions() const;
//! Returns the Nth value of the root of function F.
//! Exceptions
//! StdFail_NotDone if the algorithm fails (and IsDone returns false).
Standard_Real Value (const Standard_Integer Nieme) const;
Standard_Real Value(const Standard_Integer Nieme) const;
//! returns the StateNumber of the Nieme root.
//! Exception RangeError is raised if Nieme is < 1
//! or Nieme > NbSolutions.
Standard_Integer StateNumber (const Standard_Integer Nieme) const;
Standard_Integer StateNumber(const Standard_Integer Nieme) const;
//! Prints on the stream o information on the current state
//! of the object.
Standard_EXPORT void Dump (Standard_OStream& o) const;
Standard_EXPORT void Dump(Standard_OStream& o) const;
protected:
private:
Standard_Boolean Done;
Standard_Boolean AllNull;
TColStd_SequenceOfReal Sol;
Standard_Boolean Done;
Standard_Boolean AllNull;
TColStd_SequenceOfReal Sol;
TColStd_SequenceOfInteger NbStateSol;
};
#include <math_FunctionRoots.lxx>
#endif // _math_FunctionRoots_HeaderFile

View File

@@ -16,40 +16,41 @@
#include <TColStd_SequenceOfReal.hxx>
#include <TColStd_SequenceOfInteger.hxx>
inline Standard_Boolean math_FunctionRoots::IsDone() const { return Done; }
inline Standard_Boolean math_FunctionRoots::IsDone() const
{
return Done;
}
inline Standard_OStream& operator<<(Standard_OStream& o,
const math_FunctionRoots& F)
inline Standard_OStream& operator<<(Standard_OStream& o, const math_FunctionRoots& F)
{
F.Dump(o);
return o;
}
inline Standard_Boolean math_FunctionRoots::IsAllNull() const{
inline Standard_Boolean math_FunctionRoots::IsAllNull() const
{
StdFail_NotDone_Raise_if(!Done, " ");
return AllNull;
}
inline Standard_Integer math_FunctionRoots::NbSolutions() const{
inline Standard_Integer math_FunctionRoots::NbSolutions() const
{
StdFail_NotDone_Raise_if(!Done, " ");
return Sol.Length();
}
inline Standard_Real math_FunctionRoots::Value(const Standard_Integer Nieme) const{
inline Standard_Real math_FunctionRoots::Value(const Standard_Integer Nieme) const
{
StdFail_NotDone_Raise_if(!Done, " ");
return Sol.Value(Nieme);
}
inline Standard_Integer math_FunctionRoots::StateNumber(const Standard_Integer Nieme) const{
inline Standard_Integer math_FunctionRoots::StateNumber(const Standard_Integer Nieme) const
{
StdFail_NotDone_Raise_if(!Done, " ");
return NbStateSol.Value(Nieme);
}

View File

@@ -12,37 +12,39 @@
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
//#ifndef OCCT_DEBUG
// #ifndef OCCT_DEBUG
#define No_Standard_RangeError
#define No_Standard_OutOfRange
#define No_Standard_DimensionError
//#endif
// #endif
#include <math_FunctionSample.hxx>
#include <Standard_OutOfRange.hxx>
math_FunctionSample::math_FunctionSample (const Standard_Real A,
const Standard_Real B,
const Standard_Integer N):
a(A),b(B),n(N)
math_FunctionSample::math_FunctionSample(const Standard_Real A,
const Standard_Real B,
const Standard_Integer N)
: a(A),
b(B),
n(N)
{
}
void math_FunctionSample::Bounds (Standard_Real& A, Standard_Real& B) const {
void math_FunctionSample::Bounds(Standard_Real& A, Standard_Real& B) const
{
A=a;
B=b;
A = a;
B = b;
}
Standard_Integer math_FunctionSample::NbPoints () const {
Standard_Integer math_FunctionSample::NbPoints() const
{
return n;
}
Standard_Real math_FunctionSample::GetParameter (const Standard_Integer Index) const {
Standard_OutOfRange_Raise_if((Index <= 0)||(Index > n), " ");
return ((n-Index)*a+(Index-1)*b)/(n-1);
Standard_Real math_FunctionSample::GetParameter(const Standard_Integer Index) const
{
Standard_OutOfRange_Raise_if((Index <= 0) || (Index > n), " ");
return ((n - Index) * a + (Index - 1) * b) / (n - 1);
}

View File

@@ -23,54 +23,34 @@
#include <Standard_Real.hxx>
//! This class gives a default sample (constant difference
//! of parameter) for a function defined between
//! two bound A,B.
class math_FunctionSample
class math_FunctionSample
{
public:
DEFINE_STANDARD_ALLOC
Standard_EXPORT math_FunctionSample(const Standard_Real A, const Standard_Real B, const Standard_Integer N);
Standard_EXPORT math_FunctionSample(const Standard_Real A,
const Standard_Real B,
const Standard_Integer N);
//! Returns the bounds of parameters.
Standard_EXPORT virtual void Bounds (Standard_Real& A, Standard_Real& B) const;
Standard_EXPORT virtual void Bounds(Standard_Real& A, Standard_Real& B) const;
//! Returns the number of sample points.
Standard_EXPORT Standard_Integer NbPoints() const;
//! Returns the value of parameter of the point of
//! range Index : A + ((Index-1)/(NbPoints-1))*B.
//! An exception is raised if Index<=0 or Index>NbPoints.
Standard_EXPORT virtual Standard_Real GetParameter (const Standard_Integer Index) const;
Standard_EXPORT virtual Standard_Real GetParameter(const Standard_Integer Index) const;
protected:
private:
Standard_Real a;
Standard_Real b;
Standard_Real a;
Standard_Real b;
Standard_Integer n;
};
#endif // _math_FunctionSample_HeaderFile

View File

@@ -12,21 +12,14 @@
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <math_FunctionSet.hxx>
//=======================================================================
//function : ~math_FunctionSet
//purpose : Destructor
//=======================================================================
math_FunctionSet::~math_FunctionSet()
{
}
//=================================================================================================
math_FunctionSet::~math_FunctionSet() {}
//=================================================================================================
//=======================================================================
//function : GetStateNumber
//purpose :
//=======================================================================
Standard_Integer math_FunctionSet::GetStateNumber()
{
return 0;

View File

@@ -23,29 +23,25 @@
#include <math_Vector.hxx>
//! This abstract class describes the virtual functions associated to
//! a set on N Functions of M independent variables.
class math_FunctionSet
class math_FunctionSet
{
public:
DEFINE_STANDARD_ALLOC
//! Returns the number of variables of the function.
Standard_EXPORT virtual Standard_Integer NbVariables() const = 0;
//! Returns the number of equations of the function.
Standard_EXPORT virtual Standard_Integer NbEquations() const = 0;
//! Computes the values <F> of the functions for the
//! variable <X>.
//! returns True if the computation was done successfully,
//! False otherwise.
Standard_EXPORT virtual Standard_Boolean Value (const math_Vector& X, math_Vector& F) = 0;
Standard_EXPORT virtual Standard_Boolean Value(const math_Vector& X, math_Vector& F) = 0;
//! Returns the state of the function corresponding to the
//! latestcall of any methods associated with the function.
//! This function is called by each of the algorithms
@@ -63,27 +59,8 @@ public:
Standard_EXPORT virtual Standard_Integer GetStateNumber();
Standard_EXPORT virtual ~math_FunctionSet();
protected:
private:
};
#endif // _math_FunctionSet_HeaderFile

File diff suppressed because it is too large Load Diff

View File

@@ -33,42 +33,44 @@ class math_FunctionSetWithDerivatives;
//! is no success in the Newton direction. This algorithm can also be
//! used for functions minimization. Knowledge of all the partial
//! derivatives (the Jacobian) is required.
class math_FunctionSetRoot
class math_FunctionSetRoot
{
public:
DEFINE_STANDARD_ALLOC
//! is used in a sub-class to initialize correctly all the fields
//! of this class.
//! The range (1, F.NbVariables()) must be especially
//! respected for all vectors and matrix declarations.
Standard_EXPORT math_FunctionSetRoot(math_FunctionSetWithDerivatives& F, const math_Vector& Tolerance, const Standard_Integer NbIterations = 100);
Standard_EXPORT math_FunctionSetRoot(math_FunctionSetWithDerivatives& F,
const math_Vector& Tolerance,
const Standard_Integer NbIterations = 100);
//! is used in a sub-class to initialize correctly all the fields
//! of this class.
//! The range (1, F.NbVariables()) must be especially
//! respected for all vectors and matrix declarations.
//! The method SetTolerance must be called after this
//! constructor.
Standard_EXPORT math_FunctionSetRoot(math_FunctionSetWithDerivatives& F, const Standard_Integer NbIterations = 100);
Standard_EXPORT math_FunctionSetRoot(math_FunctionSetWithDerivatives& F,
const Standard_Integer NbIterations = 100);
//! Destructor
Standard_EXPORT virtual ~math_FunctionSetRoot();
//! Initializes the tolerance values.
Standard_EXPORT void SetTolerance (const math_Vector& Tolerance);
Standard_EXPORT void SetTolerance(const math_Vector& Tolerance);
//! This routine is called at the end of each iteration
//! to check if the solution was found. It can be redefined
//! in a sub-class to implement a specific test to stop the iterations.
//! In this case, the solution is found when: abs(Xi - Xi-1) <= Tolerance
//! for all unknowns.
virtual Standard_Boolean IsSolutionReached (math_FunctionSetWithDerivatives& )
virtual Standard_Boolean IsSolutionReached(math_FunctionSetWithDerivatives&)
{
for (Standard_Integer i = 1; i <= Sol.Length(); ++i)
{
if (Abs (Delta(i)) > Tol(i))
if (Abs(Delta(i)) > Tol(i))
{
return Standard_False;
}
@@ -80,13 +82,19 @@ public:
//! The infinum and supremum may be given to constrain the solution.
//! In this case, the solution is found when: abs(Xi - Xi-1)(j) <= Tolerance(j)
//! for all unknowns.
Standard_EXPORT void Perform (math_FunctionSetWithDerivatives& theFunction, const math_Vector& theStartingPoint, const Standard_Boolean theStopOnDivergent = Standard_False);
Standard_EXPORT void Perform(math_FunctionSetWithDerivatives& theFunction,
const math_Vector& theStartingPoint,
const Standard_Boolean theStopOnDivergent = Standard_False);
//! Improves the root of function from the initial guess point.
//! The infinum and supremum may be given to constrain the solution.
//! In this case, the solution is found when: abs(Xi - Xi-1) <= Tolerance
//! for all unknowns.
Standard_EXPORT void Perform (math_FunctionSetWithDerivatives& theFunction, const math_Vector& theStartingPoint, const math_Vector& theInfBound, const math_Vector& theSupBound, const Standard_Boolean theStopOnDivergent = Standard_False);
Standard_EXPORT void Perform(math_FunctionSetWithDerivatives& theFunction,
const math_Vector& theStartingPoint,
const math_Vector& theInfBound,
const math_Vector& theSupBound,
const Standard_Boolean theStopOnDivergent = Standard_False);
//! Returns true if the computations are successful, otherwise returns false.
Standard_Boolean IsDone() const { return Done; }
@@ -99,7 +107,7 @@ public:
StdFail_NotDone_Raise_if(!Done, " ");
return Kount;
}
//! returns the stateNumber (as returned by
//! F.GetStateNumber()) associated to the root found.
Standard_Integer StateNumber() const
@@ -107,7 +115,7 @@ public:
StdFail_NotDone_Raise_if(!Done, " ");
return State;
}
//! Returns the value of the root of function F.
//! Exception NotDone is raised if the root was not found.
const math_Vector& Root() const
@@ -120,8 +128,8 @@ public:
//! Exception NotDone is raised if the root was not found.
//! Exception DimensionError is raised if the range of Root
//! is not equal to the range of the StartingPoint.
Standard_EXPORT void Root (math_Vector& Root) const;
Standard_EXPORT void Root(math_Vector& Root) const;
//! Returns the matrix value of the derivative at the root.
//! Exception NotDone is raised if the root was not found.
const math_Matrix& Derivative() const
@@ -129,13 +137,13 @@ public:
StdFail_NotDone_Raise_if(!Done, " ");
return DF;
}
//! outputs the matrix value of the derivative
//! at the root in Der.
//! Exception NotDone is raised if the root was not found.
//! Exception DimensionError is raised if the column range
//! of <Der> is not equal to the range of the startingPoint.
void Derivative (math_Matrix& Der) const
void Derivative(math_Matrix& Der) const
{
StdFail_NotDone_Raise_if(!Done, " ");
Standard_DimensionError_Raise_if(Der.ColNumber() != Sol.Length(), " ");
@@ -150,56 +158,52 @@ public:
StdFail_NotDone_Raise_if(!Done, " ");
return Delta;
}
//! outputs the vector value of the error done
//! on the functions at the root in Err.
//! Exception NotDone is raised if the root was not found.
//! Exception DimensionError is raised if the range of Err
//! is not equal to the range of the StartingPoint.
Standard_EXPORT void FunctionSetErrors (math_Vector& Err) const;
Standard_EXPORT void FunctionSetErrors(math_Vector& Err) const;
//! Prints on the stream o information on the current state
//! of the object.
//! Is used to redefine the operator <<.
Standard_EXPORT void Dump (Standard_OStream& o) const;
Standard_EXPORT void Dump(Standard_OStream& o) const;
Standard_Boolean IsDivergent() const { return myIsDivergent; }
protected:
math_Vector Delta;
math_Vector Sol;
math_Matrix DF;
math_Vector Tol;
private:
Standard_Boolean Done;
Standard_Integer Kount;
Standard_Integer State;
Standard_Integer Itermax;
math_Vector InfBound;
math_Vector SupBound;
math_Vector SolSave;
math_Vector GH;
math_Vector DH;
math_Vector DHSave;
math_Vector FF;
math_Vector PreviousSolution;
math_Vector Save;
Standard_Boolean Done;
Standard_Integer Kount;
Standard_Integer State;
Standard_Integer Itermax;
math_Vector InfBound;
math_Vector SupBound;
math_Vector SolSave;
math_Vector GH;
math_Vector DH;
math_Vector DHSave;
math_Vector FF;
math_Vector PreviousSolution;
math_Vector Save;
math_IntegerVector Constraints;
math_Vector Temp1;
math_Vector Temp2;
math_Vector Temp3;
math_Vector Temp4;
Standard_Boolean myIsDivergent;
math_Vector Temp1;
math_Vector Temp2;
math_Vector Temp3;
math_Vector Temp4;
Standard_Boolean myIsDivergent;
};
inline Standard_OStream& operator<< (Standard_OStream& theStream,
const math_FunctionSetRoot& theF)
inline Standard_OStream& operator<<(Standard_OStream& theStream, const math_FunctionSetRoot& theF)
{
theF.Dump (theStream);
theF.Dump(theStream);
return theStream;
}

View File

@@ -25,61 +25,41 @@
#include <math_Vector.hxx>
class math_Matrix;
//! This abstract class describes the virtual functions associated
//! with a set of N Functions each of M independent variables.
class math_FunctionSetWithDerivatives : public math_FunctionSet
class math_FunctionSetWithDerivatives : public math_FunctionSet
{
public:
DEFINE_STANDARD_ALLOC
//! Returns the number of variables of the function.
Standard_EXPORT virtual Standard_Integer NbVariables() const = 0;
//! Returns the number of equations of the function.
Standard_EXPORT virtual Standard_Integer NbEquations() const = 0;
//! Computes the values <F> of the Functions for the
//! variable <X>.
//! Returns True if the computation was done successfully,
//! False otherwise.
Standard_EXPORT virtual Standard_Boolean Value (const math_Vector& X, math_Vector& F) = 0;
Standard_EXPORT virtual Standard_Boolean Value(const math_Vector& X, math_Vector& F) = 0;
//! Returns the values <D> of the derivatives for the
//! variable <X>.
//! Returns True if the computation was done successfully,
//! False otherwise.
Standard_EXPORT virtual Standard_Boolean Derivatives (const math_Vector& X, math_Matrix& D) = 0;
Standard_EXPORT virtual Standard_Boolean Derivatives(const math_Vector& X, math_Matrix& D) = 0;
//! returns the values <F> of the functions and the derivatives
//! <D> for the variable <X>.
//! Returns True if the computation was done successfully,
//! False otherwise.
Standard_EXPORT virtual Standard_Boolean Values (const math_Vector& X, math_Vector& F, math_Matrix& D) = 0;
Standard_EXPORT virtual Standard_Boolean Values(const math_Vector& X,
math_Vector& F,
math_Matrix& D) = 0;
protected:
private:
};
#endif // _math_FunctionSetWithDerivatives_HeaderFile

View File

@@ -12,13 +12,8 @@
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <math_FunctionWithDerivative.hxx>
//=======================================================================
//function : ~math_FunctionWithDerivative
//purpose : Destructor
//=======================================================================
math_FunctionWithDerivative::~math_FunctionWithDerivative()
{
}
//=================================================================================================
math_FunctionWithDerivative::~math_FunctionWithDerivative() {}

View File

@@ -25,57 +25,36 @@
#include <Standard_Boolean.hxx>
#include <Standard_Real.hxx>
//! This abstract class describes the virtual functions associated with
//! a function of a single variable for which the first derivative is
//! available.
class math_FunctionWithDerivative : public math_Function
class math_FunctionWithDerivative : public math_Function
{
public:
DEFINE_STANDARD_ALLOC
//! Computes the value <F>of the function for the variable <X>.
//! Returns True if the calculation were successfully done,
//! False otherwise.
Standard_EXPORT virtual Standard_Boolean Value (const Standard_Real X, Standard_Real& F) = 0;
Standard_EXPORT virtual Standard_Boolean Value(const Standard_Real X, Standard_Real& F) = 0;
//! Computes the derivative <D> of the function
//! for the variable <X>.
//! Returns True if the calculation were successfully done,
//! False otherwise.
Standard_EXPORT virtual Standard_Boolean Derivative (const Standard_Real X, Standard_Real& D) = 0;
Standard_EXPORT virtual Standard_Boolean Derivative(const Standard_Real X, Standard_Real& D) = 0;
//! Computes the value <F> and the derivative <D> of the
//! function for the variable <X>.
//! Returns True if the calculation were successfully done,
//! False otherwise.
Standard_EXPORT virtual Standard_Boolean Values (const Standard_Real X, Standard_Real& F, Standard_Real& D) = 0;
Standard_EXPORT virtual Standard_Boolean Values(const Standard_Real X,
Standard_Real& F,
Standard_Real& D) = 0;
Standard_EXPORT virtual ~math_FunctionWithDerivative();
protected:
private:
};
#endif // _math_FunctionWithDerivative_HeaderFile

View File

@@ -20,96 +20,100 @@
#include <Standard_DimensionError.hxx>
#include <StdFail_NotDone.hxx>
math_Gauss::math_Gauss(const math_Matrix& A,
const Standard_Real MinPivot,
const Message_ProgressRange& theProgress)
: LU (1, A.RowNumber(), 1, A.ColNumber()),
Index(1, A.RowNumber()),
D (0.0),
Done (Standard_False)
math_Gauss::math_Gauss(const math_Matrix& A,
const Standard_Real MinPivot,
const Message_ProgressRange& theProgress)
: LU(1, A.RowNumber(), 1, A.ColNumber()),
Index(1, A.RowNumber()),
D(0.0),
Done(Standard_False)
{
math_NotSquare_Raise_if(A.RowNumber() != A.ColNumber(), " ");
LU = A;
Standard_Integer Error = LU_Decompose(LU,
Index,
D,
MinPivot,
theProgress);
if(!Error) {
Done = Standard_True;
}
else {
Done = Standard_False;
}
math_NotSquare_Raise_if(A.RowNumber() != A.ColNumber(), " ");
LU = A;
Standard_Integer Error = LU_Decompose(LU, Index, D, MinPivot, theProgress);
if (!Error)
{
Done = Standard_True;
}
else
{
Done = Standard_False;
}
}
void math_Gauss::Solve(const math_Vector& B, math_Vector& X) const
{
StdFail_NotDone_Raise_if(!Done, " ");
X = B;
LU_Solve(LU, Index, X);
}
void math_Gauss::Solve(math_Vector& X) const
{
StdFail_NotDone_Raise_if(!Done, " ");
if (X.Length() != LU.RowNumber())
{
throw Standard_DimensionError();
}
LU_Solve(LU, Index, X);
}
Standard_Real math_Gauss::Determinant() const
{
StdFail_NotDone_Raise_if(!Done, " ");
Standard_Real Result = D;
for (Standard_Integer J = 1; J <= LU.UpperRow(); J++)
{
Result *= LU(J, J);
}
return Result;
}
void math_Gauss::Invert(math_Matrix& Inv) const
{
StdFail_NotDone_Raise_if(!Done, " ");
Standard_DimensionError_Raise_if((Inv.RowNumber() != LU.RowNumber())
|| (Inv.ColNumber() != LU.ColNumber()),
" ");
Standard_Integer LowerRow = Inv.LowerRow();
Standard_Integer LowerCol = Inv.LowerCol();
math_Vector Column(1, LU.UpperRow());
Standard_Integer I, J;
for (J = 1; J <= LU.UpperRow(); J++)
{
for (I = 1; I <= LU.UpperRow(); I++)
{
Column(I) = 0.0;
}
void math_Gauss::Solve(const math_Vector& B, math_Vector& X) const{
StdFail_NotDone_Raise_if(!Done, " ");
X = B;
LU_Solve(LU,
Index,
X);
Column(J) = 1.0;
LU_Solve(LU, Index, Column);
for (I = 1; I <= LU.RowNumber(); I++)
{
Inv(I + LowerRow - 1, J + LowerCol - 1) = Column(I);
}
}
}
void math_Gauss::Solve (math_Vector& X) const{
StdFail_NotDone_Raise_if(!Done, " ");
if(X.Length() != LU.RowNumber()) {
throw Standard_DimensionError();
}
LU_Solve(LU,
Index,
X);
}
Standard_Real math_Gauss::Determinant() const{
StdFail_NotDone_Raise_if(!Done, " ");
Standard_Real Result = D;
for(Standard_Integer J = 1; J <= LU.UpperRow(); J++) {
Result *= LU(J,J);
}
return Result;
}
void math_Gauss::Invert(math_Matrix& Inv) const{
StdFail_NotDone_Raise_if(!Done, " ");
Standard_DimensionError_Raise_if((Inv.RowNumber() != LU.RowNumber()) ||
(Inv.ColNumber() != LU.ColNumber()),
" ");
Standard_Integer LowerRow = Inv.LowerRow();
Standard_Integer LowerCol = Inv.LowerCol();
math_Vector Column(1, LU.UpperRow());
Standard_Integer I, J;
for(J = 1; J <= LU.UpperRow(); J++) {
for(I = 1; I <= LU.UpperRow(); I++) {
Column(I) = 0.0;
}
Column(J) = 1.0;
LU_Solve(LU, Index, Column);
for(I = 1; I <= LU.RowNumber(); I++) {
Inv(I+LowerRow-1,J+LowerCol-1) = Column(I);
}
}
}
void math_Gauss::Dump(Standard_OStream& o) const {
o << "math_Gauss ";
if(Done) {
o<< " Status = Done \n";
o << " Determinant of A = " << D << std::endl;
}
else {
o << " Status = not Done \n";
}
}
void math_Gauss::Dump(Standard_OStream& o) const
{
o << "math_Gauss ";
if (Done)
{
o << " Status = Done \n";
o << " Determinant of A = " << D << std::endl;
}
else
{
o << " Status = not Done \n";
}
}

View File

@@ -27,17 +27,15 @@
#include <Standard_OStream.hxx>
#include <Message_ProgressRange.hxx>
//! This class implements the Gauss LU decomposition (Crout algorithm)
//! with partial pivoting (rows interchange) of a square matrix and
//! the different possible derived calculation :
//! - solution of a set of linear equations.
//! - inverse of a matrix.
//! - determinant of a matrix.
class math_Gauss
class math_Gauss
{
public:
DEFINE_STANDARD_ALLOC
//! Given an input n X n matrix A this constructor performs its LU
@@ -47,10 +45,10 @@ public:
//! If the largest pivot found is less than MinPivot the matrix A is
//! considered as singular.
//! Exception NotSquare is raised if A is not a square matrix.
Standard_EXPORT math_Gauss(const math_Matrix& A,
const Standard_Real MinPivot = 1.0e-20,
Standard_EXPORT math_Gauss(const math_Matrix& A,
const Standard_Real MinPivot = 1.0e-20,
const Message_ProgressRange& theProgress = Message_ProgressRange());
//! Returns true if the computations are successful, otherwise returns false
Standard_Boolean IsDone() const { return Done; }
@@ -60,7 +58,7 @@ public:
//! successfully.
//! Exception DimensionError is raised if the range of B is not
//! equal to the number of rows of A.
Standard_EXPORT void Solve (const math_Vector& B, math_Vector& X) const;
Standard_EXPORT void Solve(const math_Vector& B, math_Vector& X) const;
//! Given the input Vector B this routine solves the set of linear
//! equations A . X = B. B is replaced by the vector solution X.
@@ -68,7 +66,7 @@ public:
//! successfully.
//! Exception DimensionError is raised if the range of B is not
//! equal to the number of rows of A.
Standard_EXPORT void Solve (math_Vector& B) const;
Standard_EXPORT void Solve(math_Vector& B) const;
//! This routine returns the value of the determinant of the previously LU
//! decomposed matrix A.
@@ -80,20 +78,18 @@ public:
//! matrix A.
//! Exception DimensionError is raised if the ranges of B are not
//! equal to the ranges of A.
Standard_EXPORT void Invert (math_Matrix& Inv) const;
Standard_EXPORT void Invert(math_Matrix& Inv) const;
//! Prints on the stream o information on the current state
//! of the object.
//! Is used to redefine the operator <<.
Standard_EXPORT void Dump (Standard_OStream& o) const;
Standard_EXPORT void Dump(Standard_OStream& o) const;
protected:
math_Matrix LU;
math_Matrix LU;
math_IntegerVector Index;
Standard_Real D;
Standard_Boolean Done;
Standard_Real D;
Standard_Boolean Done;
};
inline Standard_OStream& operator<<(Standard_OStream& o, const math_Gauss& mG)

View File

@@ -12,12 +12,12 @@
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
//#ifndef OCCT_DEBUG
// #ifndef OCCT_DEBUG
#define No_Standard_RangeError
#define No_Standard_OutOfRange
#define No_Standard_DimensionError
//#endif
// #endif
#include <math_GaussLeastSquare.hxx>
#include <math_Matrix.hxx>
@@ -25,25 +25,23 @@
#include <Standard_DimensionError.hxx>
#include <StdFail_NotDone.hxx>
math_GaussLeastSquare::math_GaussLeastSquare (const math_Matrix& A,
const Standard_Real MinPivot) :
LU(1, A.ColNumber(),
1, A.ColNumber()),
A2(1, A.ColNumber(),
1, A.RowNumber()),
Index(1, A.ColNumber()) {
A2 = A.Transposed();
math_GaussLeastSquare::math_GaussLeastSquare(const math_Matrix& A, const Standard_Real MinPivot)
: LU(1, A.ColNumber(), 1, A.ColNumber()),
A2(1, A.ColNumber(), 1, A.RowNumber()),
Index(1, A.ColNumber())
{
A2 = A.Transposed();
LU.Multiply(A2, A);
Standard_Integer Error = LU_Decompose(LU, Index, D, MinPivot);
Done = (!Error) ? Standard_True : Standard_False;
Done = (!Error) ? Standard_True : Standard_False;
}
void math_GaussLeastSquare::Solve(const math_Vector& B, math_Vector& X) const{
void math_GaussLeastSquare::Solve(const math_Vector& B, math_Vector& X) const
{
StdFail_NotDone_Raise_if(!Done, " ");
Standard_DimensionError_Raise_if((B.Length() != A2.ColNumber()) ||
(X.Length() != A2.RowNumber()), " ");
Standard_DimensionError_Raise_if((B.Length() != A2.ColNumber()) || (X.Length() != A2.RowNumber()),
" ");
X.Multiply(A2, B);
@@ -52,16 +50,16 @@ void math_GaussLeastSquare::Solve(const math_Vector& B, math_Vector& X) const{
return;
}
void math_GaussLeastSquare::Dump(Standard_OStream& o) const
{
void math_GaussLeastSquare::Dump(Standard_OStream& o) const {
o <<"math_GaussLeastSquare ";
if (Done) {
o << " Status = Done \n";
}
else {
o << "Status = not Done \n";
}
o << "math_GaussLeastSquare ";
if (Done)
{
o << " Status = Done \n";
}
else
{
o << "Status = not Done \n";
}
}

View File

@@ -26,20 +26,16 @@
#include <math_Vector.hxx>
#include <Standard_OStream.hxx>
//! This class implements the least square solution of a set of
//! n linear equations of m unknowns (n >= m) using the gauss LU
//! decomposition algorithm.
//! This algorithm is more likely subject to numerical instability
//! than math_SVD.
class math_GaussLeastSquare
class math_GaussLeastSquare
{
public:
DEFINE_STANDARD_ALLOC
//! Given an input n X m matrix A with n >= m this constructor
//! performs the LU decomposition with partial pivoting
//! (interchange of rows) of the matrix AA = A.Transposed() * A;
@@ -47,11 +43,12 @@ public:
//! to do subsequent calculation.
//! If the largest pivot found is less than MinPivot the matrix <A>
//! is considered as singular.
Standard_EXPORT math_GaussLeastSquare(const math_Matrix& A, const Standard_Real MinPivot = 1.0e-20);
Standard_EXPORT math_GaussLeastSquare(const math_Matrix& A,
const Standard_Real MinPivot = 1.0e-20);
//! Returns true if the computations are successful, otherwise returns false.e
Standard_Boolean IsDone() const;
Standard_Boolean IsDone() const;
//! Given the input Vector <B> this routine solves the set
//! of linear equations A . X = B.
//! Exception NotDone is raised if the decomposition of A was
@@ -60,41 +57,24 @@ public:
//! not equal to the rowrange of A.
//! Exception DimensionError is raised if the range of X Inv is
//! not equal to the colrange of A.
Standard_EXPORT void Solve (const math_Vector& B, math_Vector& X) const;
Standard_EXPORT void Solve(const math_Vector& B, math_Vector& X) const;
//! Prints on the stream o information on the current state
//! of the object.
//! Is used to redefine the operator <<.
Standard_EXPORT void Dump (Standard_OStream& o) const;
Standard_EXPORT void Dump(Standard_OStream& o) const;
protected:
Standard_Boolean Singular;
math_Matrix LU;
math_Matrix A2;
Standard_Boolean Singular;
math_Matrix LU;
math_Matrix A2;
math_IntegerVector Index;
Standard_Real D;
Standard_Real D;
private:
Standard_Boolean Done;
};
#include <math_GaussLeastSquare.lxx>
#endif // _math_GaussLeastSquare_HeaderFile

View File

@@ -12,11 +12,12 @@
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
inline Standard_Boolean math_GaussLeastSquare::IsDone() const { return Done; }
inline Standard_Boolean math_GaussLeastSquare::IsDone() const
{
return Done;
}
inline Standard_OStream& operator<<(Standard_OStream& o,
const math_GaussLeastSquare& G)
inline Standard_OStream& operator<<(Standard_OStream& o, const math_GaussLeastSquare& G)
{
G.Dump(o);
return o;

View File

@@ -13,7 +13,7 @@
// commercial license or contractual agreement.
/*
Ce programme permet le calcul de l'integrale nieme d'une fonction. La
Ce programme permet le calcul de l'integrale nieme d'une fonction. La
resolution peut etre vue comme l'integrale de l'integrale de ....(n fois), ce
qui necessite l'emploi de fonction recursive.
@@ -33,12 +33,12 @@ de Gauss.
*/
//#ifndef OCCT_DEBUG
// #ifndef OCCT_DEBUG
#define No_Standard_RangeError
#define No_Standard_OutOfRange
#define No_Standard_DimensionError
//#endif
// #endif
#include <math.hxx>
#include <math_GaussMultipleIntegration.hxx>
@@ -47,167 +47,191 @@ de Gauss.
#include <math_MultipleVarFunction.hxx>
#include <math_Vector.hxx>
class IntegrationFunction {
class IntegrationFunction
{
// Cette classe sert a conserver dans les champs les valeurs de tests de
// la fonction recursive.(En particulier le pointeur sur la fonction F,
// heritant d'une classe abstraite, non traite en cdl.)
// Cette classe sert a conserver dans les champs les valeurs de tests de
// la fonction recursive.(En particulier le pointeur sur la fonction F,
// heritant d'une classe abstraite, non traite en cdl.)
math_MultipleVarFunction *Fsav;
math_IntegerVector Ordsav;
Standard_Integer NVarsav;
math_Vector xr;
math_Vector xm;
math_Matrix GaussPoint;
math_Matrix GaussWeight;
Standard_Real Val;
Standard_Boolean Done;
math_MultipleVarFunction* Fsav;
math_IntegerVector Ordsav;
Standard_Integer NVarsav;
math_Vector xr;
math_Vector xm;
math_Matrix GaussPoint;
math_Matrix GaussWeight;
Standard_Real Val;
Standard_Boolean Done;
public:
IntegrationFunction(math_MultipleVarFunction& F,
const Standard_Integer maxsav, const Standard_Integer NVar,
const math_IntegerVector& Ord,
const math_Vector& Lowsav,
const math_Vector& Uppsav);
public:
IntegrationFunction(math_MultipleVarFunction& F,
const Standard_Integer maxsav,
const Standard_Integer NVar,
const math_IntegerVector& Ord,
const math_Vector& Lowsav,
const math_Vector& Uppsav);
Standard_Real Value() ;
Standard_Boolean IsDone() const;
Standard_Boolean recursive_iteration(Standard_Integer& n, math_IntegerVector& inc);
Standard_Real Value();
Standard_Boolean IsDone() const;
Standard_Boolean recursive_iteration(Standard_Integer& n, math_IntegerVector& inc);
};
IntegrationFunction::IntegrationFunction(math_MultipleVarFunction& F,
const Standard_Integer maxsav, const Standard_Integer NVar,
const math_IntegerVector& Ord,
const math_Vector& Lowsav,const math_Vector& Uppsav):
Ordsav(1, NVar),
xr(1, NVar),
xm(1, NVar),
GaussPoint(1, NVar, 1, maxsav),
GaussWeight(1, NVar, 1, maxsav)
IntegrationFunction::IntegrationFunction(math_MultipleVarFunction& F,
const Standard_Integer maxsav,
const Standard_Integer NVar,
const math_IntegerVector& Ord,
const math_Vector& Lowsav,
const math_Vector& Uppsav)
: Ordsav(1, NVar),
xr(1, NVar),
xm(1, NVar),
GaussPoint(1, NVar, 1, maxsav),
GaussWeight(1, NVar, 1, maxsav)
{
Standard_Integer i, k;
math_IntegerVector inc(1, NVar);
inc.Init(0);
Fsav = &F;
NVarsav = NVar;
Ordsav = Ord;
Done = Standard_False;
Standard_Integer i, k;
math_IntegerVector inc(1, NVar);
inc.Init(0);
Fsav = &F;
NVarsav = NVar;
Ordsav = Ord;
Done = Standard_False;
//Recuperation des points et poids de Gauss dans le fichier GaussPoints
for (i =1; i<= NVarsav; i++) {
xm(i) = 0.5*(Lowsav(i) + Uppsav(i));
xr(i) = 0.5*(Uppsav(i) - Lowsav(i));
math_Vector GP(1,Ordsav(i)), GW(1,Ordsav(i));
math::GaussPoints(Ordsav(i),GP);
math::GaussWeights(Ordsav(i),GW);
for (k = 1; k <= Ordsav(i); k++) {
GaussPoint(i,k) = GP(k); //kieme point et poids de
GaussWeight(i,k) = GW(k);//Gauss de la variable i.
// Recuperation des points et poids de Gauss dans le fichier GaussPoints
for (i = 1; i <= NVarsav; i++)
{
xm(i) = 0.5 * (Lowsav(i) + Uppsav(i));
xr(i) = 0.5 * (Uppsav(i) - Lowsav(i));
math_Vector GP(1, Ordsav(i)), GW(1, Ordsav(i));
math::GaussPoints(Ordsav(i), GP);
math::GaussWeights(Ordsav(i), GW);
for (k = 1; k <= Ordsav(i); k++)
{
GaussPoint(i, k) = GP(k); // kieme point et poids de
GaussWeight(i, k) = GW(k); // Gauss de la variable i.
}
}
Val = 0.0;
Val = 0.0;
Standard_Integer Iterdeb = 1;
Standard_Boolean recur = recursive_iteration(Iterdeb, inc);
if (recur) {
//On ramene l'integration a la bonne echelle.
for ( i = 1; i <= NVarsav; i++) {
Val *= xr(i);
}
Done = Standard_True;
}
}
Standard_Real IntegrationFunction::Value() {
return Val;
}
Standard_Boolean IntegrationFunction::IsDone() const{
return Done;
}
Standard_Boolean IntegrationFunction::recursive_iteration(Standard_Integer& n,
math_IntegerVector& inc) {
// Termination criterium :
// Calcul de la valeur de la fonction aux points de Gauss fixes:
int local;
if (n == (NVarsav+1)) {
math_Vector dx(1, NVarsav);
Standard_Integer j ;
for ( j = 1; j <= NVarsav; j++) {
dx(j) = xr(j)* GaussPoint(j, inc(j));
}
Standard_Real F1;
Standard_Boolean Ok = Fsav->Value(xm + dx, F1);
if (!Ok) {return Standard_False;};
Standard_Real Interm = 1;
for ( j = 1; j <= NVarsav; j++) {
Interm *= GaussWeight(j, inc(j));
}
Val += Interm*F1;
return Standard_True;
}
// Calcul recursif, pour chaque variable n de la valeur de la fonction aux
// Ordsav(n) points de Gauss.
Standard_Boolean OK=Standard_False;
for (inc(n) = 1; inc(n) <= Ordsav(n); inc(n)++) {
local = n + 1;
OK = recursive_iteration(local, inc);
}
return OK;
}
math_GaussMultipleIntegration::
math_GaussMultipleIntegration(math_MultipleVarFunction& F,
const math_Vector& Lower,
const math_Vector& Upper,
const math_IntegerVector& Order)
{
Standard_Integer MaxOrder = math::GaussPointsMax();
Standard_Integer i, max =0;
Standard_Integer NVar = F.NbVariables();
math_IntegerVector Ord(1, NVar);
math_Vector Lowsav(1, NVar);
math_Vector Uppsav(1, NVar);
Lowsav = Lower;
Uppsav = Upper;
// Ord = Order;
Done = Standard_False;
for (i = 1; i <= NVar; i++) {
if (Order(i) > MaxOrder) {
Ord(i) = MaxOrder;
Standard_Boolean recur = recursive_iteration(Iterdeb, inc);
if (recur)
{
// On ramene l'integration a la bonne echelle.
for (i = 1; i <= NVarsav; i++)
{
Val *= xr(i);
}
else {
Ord(i) = Order(i);
}
if(Ord(i) >= max) {max = Ord(i);}
}
//Calcul de l'integrale aux points de Gauss.
// Il s agit d une somme multiple sur le domaine [Lower, Upper].
IntegrationFunction Func(F, max, NVar, Ord, Lowsav, Uppsav);
if (Func.IsDone()) {
Val = Func.Value();
Done = Standard_True;
}
}
void math_GaussMultipleIntegration::Dump(Standard_OStream& o) const {
o <<"math_GaussMultipleIntegration ";
if (Done) {
o << " Status = Done \n";
o << " Integration value = " << Val <<"\n";
}
else {
o << "Status = not Done \n";
}
Standard_Real IntegrationFunction::Value()
{
return Val;
}
Standard_Boolean IntegrationFunction::IsDone() const
{
return Done;
}
Standard_Boolean IntegrationFunction::recursive_iteration(Standard_Integer& n,
math_IntegerVector& inc)
{
// Termination criterium :
// Calcul de la valeur de la fonction aux points de Gauss fixes:
int local;
if (n == (NVarsav + 1))
{
math_Vector dx(1, NVarsav);
Standard_Integer j;
for (j = 1; j <= NVarsav; j++)
{
dx(j) = xr(j) * GaussPoint(j, inc(j));
}
Standard_Real F1;
Standard_Boolean Ok = Fsav->Value(xm + dx, F1);
if (!Ok)
{
return Standard_False;
};
Standard_Real Interm = 1;
for (j = 1; j <= NVarsav; j++)
{
Interm *= GaussWeight(j, inc(j));
}
Val += Interm * F1;
return Standard_True;
}
// Calcul recursif, pour chaque variable n de la valeur de la fonction aux
// Ordsav(n) points de Gauss.
Standard_Boolean OK = Standard_False;
for (inc(n) = 1; inc(n) <= Ordsav(n); inc(n)++)
{
local = n + 1;
OK = recursive_iteration(local, inc);
}
return OK;
}
math_GaussMultipleIntegration::math_GaussMultipleIntegration(math_MultipleVarFunction& F,
const math_Vector& Lower,
const math_Vector& Upper,
const math_IntegerVector& Order)
{
Standard_Integer MaxOrder = math::GaussPointsMax();
Standard_Integer i, max = 0;
Standard_Integer NVar = F.NbVariables();
math_IntegerVector Ord(1, NVar);
math_Vector Lowsav(1, NVar);
math_Vector Uppsav(1, NVar);
Lowsav = Lower;
Uppsav = Upper;
// Ord = Order;
Done = Standard_False;
for (i = 1; i <= NVar; i++)
{
if (Order(i) > MaxOrder)
{
Ord(i) = MaxOrder;
}
else
{
Ord(i) = Order(i);
}
if (Ord(i) >= max)
{
max = Ord(i);
}
}
// Calcul de l'integrale aux points de Gauss.
// Il s agit d une somme multiple sur le domaine [Lower, Upper].
IntegrationFunction Func(F, max, NVar, Ord, Lowsav, Uppsav);
if (Func.IsDone())
{
Val = Func.Value();
Done = Standard_True;
}
}
void math_GaussMultipleIntegration::Dump(Standard_OStream& o) const
{
o << "math_GaussMultipleIntegration ";
if (Done)
{
o << " Status = Done \n";
o << " Integration value = " << Val << "\n";
}
else
{
o << "Status = not Done \n";
}
}

View File

@@ -25,57 +25,37 @@
#include <Standard_OStream.hxx>
class math_MultipleVarFunction;
//! This class implements the integration of a function of multiple
//! variables between the parameter bounds Lower[a..b] and Upper[a..b].
//! Warning: Each element of Order must be inferior or equal to 61.
class math_GaussMultipleIntegration
class math_GaussMultipleIntegration
{
public:
DEFINE_STANDARD_ALLOC
//! The Gauss-Legendre integration with Order = points of
//! integration for each unknown, is done on the function F
//! between the bounds Lower and Upper.
Standard_EXPORT math_GaussMultipleIntegration(math_MultipleVarFunction& F, const math_Vector& Lower, const math_Vector& Upper, const math_IntegerVector& Order);
Standard_EXPORT math_GaussMultipleIntegration(math_MultipleVarFunction& F,
const math_Vector& Lower,
const math_Vector& Upper,
const math_IntegerVector& Order);
//! returns True if all has been correctly done.
Standard_Boolean IsDone() const;
Standard_Boolean IsDone() const;
//! returns the value of the integral.
Standard_Real Value() const;
Standard_Real Value() const;
//! Prints information on the current state of the object.
Standard_EXPORT void Dump (Standard_OStream& o) const;
Standard_EXPORT void Dump(Standard_OStream& o) const;
protected:
private:
Standard_Real Val;
Standard_Real Val;
Standard_Boolean Done;
};
#include <math_GaussMultipleIntegration.lxx>
#endif // _math_GaussMultipleIntegration_HeaderFile

View File

@@ -16,17 +16,19 @@
#include <StdFail_NotDone.hxx>
inline Standard_Boolean math_GaussMultipleIntegration::IsDone() const
{ return Done; }
inline Standard_Boolean math_GaussMultipleIntegration::IsDone() const
{
return Done;
}
inline Standard_OStream& operator<<(Standard_OStream& o,
const math_GaussMultipleIntegration& G)
inline Standard_OStream& operator<<(Standard_OStream& o, const math_GaussMultipleIntegration& G)
{
G.Dump(o);
return o;
}
inline Standard_Real math_GaussMultipleIntegration::Value() const{
inline Standard_Real math_GaussMultipleIntegration::Value() const
{
StdFail_NotDone_Raise_if(!Done, " ");
return Val;
}

View File

@@ -12,12 +12,12 @@
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
//#ifndef OCCT_DEBUG
// #ifndef OCCT_DEBUG
#define No_Standard_RangeError
#define No_Standard_OutOfRange
#define No_Standard_DimensionError
//#endif
// #endif
#include <math.hxx>
#include <math_FunctionSet.hxx>
@@ -26,76 +26,83 @@
#include <Standard_NotImplemented.hxx>
#include <StdFail_NotDone.hxx>
math_GaussSetIntegration::math_GaussSetIntegration(math_FunctionSet& F,
const math_Vector& Lower,
const math_Vector& Upper,
const math_IntegerVector& Order)
: Val(1, F.NbEquations()) {
Standard_Integer NbEqua = F.NbEquations() , NbVar = F.NbVariables();
Standard_Integer i;
Standard_Boolean IsOk;
math_Vector FVal1(1, NbEqua), FVal2(1, NbEqua), Tval(1, NbVar);
// Verification
Standard_NotImplemented_Raise_if(
NbVar != 1 || Order.Value(Order.Lower()) > math::GaussPointsMax(),
"GaussSetIntegration ");
// Initialisations
Done = Standard_False;
Standard_Real Xdeb = Lower.Value( Lower.Lower() );
Standard_Real Xfin = Upper.Value( Upper.Lower() );
Standard_Integer Ordre = Order.Value(Order.Lower());
Standard_Real Xm, Xr;
math_Vector GaussP(1, Ordre), GaussW(1, Ordre);
// Recuperation des points de Gauss dans le fichier GaussPoints.
math::GaussPoints (Ordre, GaussP);
math::GaussWeights (Ordre, GaussW);
// Changement de variable pour la mise a l'echelle [Lower, Upper] :
Xm = 0.5 * (Xdeb + Xfin);
Xr = 0.5 * (Xfin - Xdeb);
Standard_Integer ind = Ordre/2, ind1 = (Ordre+1)/2;
if(ind1 > ind) { // odder case
Tval(1) = Xm; // + Xr * GaussP(ind1);
IsOk = F.Value(Tval, Val);
if (!IsOk) return;
Val *= GaussW(ind1);
}
else {
Val.Init(0);
}
for (i=1; i<= ind; i++) {
Tval(1) = Xm + Xr * GaussP(i);
IsOk = F.Value(Tval, FVal1);
if (!IsOk) return;
Tval(1) = Xm - Xr * GaussP(i);
IsOk = F.Value(Tval, FVal2);
if (!IsOk) return;
FVal1 += FVal2;
FVal1 *= GaussW(i);
Val += FVal1;
}
Val *= Xr;
Done = Standard_True;
}
void math_GaussSetIntegration::Dump(Standard_OStream& o) const
math_GaussSetIntegration::math_GaussSetIntegration(math_FunctionSet& F,
const math_Vector& Lower,
const math_Vector& Upper,
const math_IntegerVector& Order)
: Val(1, F.NbEquations())
{
o <<"math_GaussSetIntegration ";
if (Done) {
o << " Status = Done \n";
o << "Integration Value = " << Val<<"\n";
}
else {
o << "Status = not Done \n";
}
Standard_Integer NbEqua = F.NbEquations(), NbVar = F.NbVariables();
Standard_Integer i;
Standard_Boolean IsOk;
math_Vector FVal1(1, NbEqua), FVal2(1, NbEqua), Tval(1, NbVar);
// Verification
Standard_NotImplemented_Raise_if(NbVar != 1
|| Order.Value(Order.Lower()) > math::GaussPointsMax(),
"GaussSetIntegration ");
// Initialisations
Done = Standard_False;
Standard_Real Xdeb = Lower.Value(Lower.Lower());
Standard_Real Xfin = Upper.Value(Upper.Lower());
Standard_Integer Ordre = Order.Value(Order.Lower());
Standard_Real Xm, Xr;
math_Vector GaussP(1, Ordre), GaussW(1, Ordre);
// Recuperation des points de Gauss dans le fichier GaussPoints.
math::GaussPoints(Ordre, GaussP);
math::GaussWeights(Ordre, GaussW);
// Changement de variable pour la mise a l'echelle [Lower, Upper] :
Xm = 0.5 * (Xdeb + Xfin);
Xr = 0.5 * (Xfin - Xdeb);
Standard_Integer ind = Ordre / 2, ind1 = (Ordre + 1) / 2;
if (ind1 > ind)
{ // odder case
Tval(1) = Xm; // + Xr * GaussP(ind1);
IsOk = F.Value(Tval, Val);
if (!IsOk)
return;
Val *= GaussW(ind1);
}
else
{
Val.Init(0);
}
for (i = 1; i <= ind; i++)
{
Tval(1) = Xm + Xr * GaussP(i);
IsOk = F.Value(Tval, FVal1);
if (!IsOk)
return;
Tval(1) = Xm - Xr * GaussP(i);
IsOk = F.Value(Tval, FVal2);
if (!IsOk)
return;
FVal1 += FVal2;
FVal1 *= GaussW(i);
Val += FVal1;
}
Val *= Xr;
Done = Standard_True;
}
void math_GaussSetIntegration::Dump(Standard_OStream& o) const
{
o << "math_GaussSetIntegration ";
if (Done)
{
o << " Status = Done \n";
o << "Integration Value = " << Val << "\n";
}
else
{
o << "Status = not Done \n";
}
}

View File

@@ -25,57 +25,38 @@
#include <Standard_OStream.hxx>
class math_FunctionSet;
//! -- This class implements the integration of a set of N
//! functions of M variables variables between the
//! parameter bounds Lower[a..b] and Upper[a..b].
//! Warning: - The case M>1 is not implemented.
class math_GaussSetIntegration
class math_GaussSetIntegration
{
public:
DEFINE_STANDARD_ALLOC
//! The Gauss-Legendre integration with Order = points of
//! integration for each unknown, is done on the function F
//! between the bounds Lower and Upper.
Standard_EXPORT math_GaussSetIntegration(math_FunctionSet& F, const math_Vector& Lower, const math_Vector& Upper, const math_IntegerVector& Order);
Standard_EXPORT math_GaussSetIntegration(math_FunctionSet& F,
const math_Vector& Lower,
const math_Vector& Upper,
const math_IntegerVector& Order);
//! returns True if all has been correctly done.
Standard_Boolean IsDone() const;
Standard_Boolean IsDone() const;
//! returns the value of the integral.
const math_Vector& Value() const;
const math_Vector& Value() const;
//! Prints information on the current state of the object.
Standard_EXPORT void Dump (Standard_OStream& o) const;
Standard_EXPORT void Dump(Standard_OStream& o) const;
protected:
private:
math_Vector Val;
math_Vector Val;
Standard_Boolean Done;
};
#include <math_GaussSetIntegration.lxx>
#endif // _math_GaussSetIntegration_HeaderFile

View File

@@ -15,14 +15,13 @@
#include <math_Vector.hxx>
#include <StdFail_NotDone.hxx>
inline Standard_Boolean math_GaussSetIntegration::IsDone() const
inline Standard_Boolean math_GaussSetIntegration::IsDone() const
{
return Done;
}
inline const math_Vector& math_GaussSetIntegration::Value() const
inline const math_Vector& math_GaussSetIntegration::Value() const
{
StdFail_NotDone_Raise_if(!Done, "Integration ");
return Val;
}

View File

@@ -13,12 +13,12 @@
// commercial license or contractual agreement.
/*
Par Gauss le calcul d'une integrale simple se transforme en sommation des
Par Gauss le calcul d'une integrale simple se transforme en sommation des
valeurs de la fonction donnee aux <Order> points de Gauss affectee des poids
de Gauss.
Les points et poids de Gauss sont stockes dans GaussPoints.cxx.
Les points sont compris entre les valeurs -1 et +1, ce qui necessite un
Les points sont compris entre les valeurs -1 et +1, ce qui necessite un
changement de variable pour les faire varier dans l'intervalle [Lower, Upper].
@@ -37,119 +37,128 @@ Etapes du calcul:
*/
//#ifndef OCCT_DEBUG
// #ifndef OCCT_DEBUG
#define No_Standard_RangeError
#define No_Standard_OutOfRange
#define No_Standard_DimensionError
//#endif
// #endif
#include <math.hxx>
#include <math_Function.hxx>
#include <math_GaussSingleIntegration.hxx>
#include <math_Vector.hxx>
math_GaussSingleIntegration::math_GaussSingleIntegration() : Done(Standard_False)
math_GaussSingleIntegration::math_GaussSingleIntegration()
: Done(Standard_False)
{
}
math_GaussSingleIntegration::
math_GaussSingleIntegration(math_Function& F,
const Standard_Real Lower,
const Standard_Real Upper,
const Standard_Integer Order)
math_GaussSingleIntegration::math_GaussSingleIntegration(math_Function& F,
const Standard_Real Lower,
const Standard_Real Upper,
const Standard_Integer Order)
{
Standard_Integer theOrder = Min(math::GaussPointsMax(), Order);
Perform(F, Lower, Upper, theOrder);
}
math_GaussSingleIntegration::
math_GaussSingleIntegration(math_Function& F,
const Standard_Real Lower,
const Standard_Real Upper,
const Standard_Integer Order,
const Standard_Real Tol)
math_GaussSingleIntegration::math_GaussSingleIntegration(math_Function& F,
const Standard_Real Lower,
const Standard_Real Upper,
const Standard_Integer Order,
const Standard_Real Tol)
{
Standard_Integer theOrder = Min(math::GaussPointsMax(), Order);
const Standard_Integer IterMax = 13; // Max number of iteration
Standard_Integer NIter = 1; // current number of iteration
Standard_Integer NbInterval = 1; // current number of subintervals
Standard_Real dU,OldLen,Len;
const Standard_Integer IterMax = 13; // Max number of iteration
Standard_Integer NIter = 1; // current number of iteration
Standard_Integer NbInterval = 1; // current number of subintervals
Standard_Real dU, OldLen, Len;
Perform(F, Lower, Upper, theOrder);
Len = Val;
do {
do
{
OldLen = Len;
Len = 0.;
Len = 0.;
NbInterval *= 2;
dU = (Upper-Lower)/NbInterval;
for (Standard_Integer i=1; i<=NbInterval; i++) {
Perform(F, Lower+(i-1)*dU, Lower+i*dU, theOrder);
if (!Done) return;
dU = (Upper - Lower) / NbInterval;
for (Standard_Integer i = 1; i <= NbInterval; i++)
{
Perform(F, Lower + (i - 1) * dU, Lower + i * dU, theOrder);
if (!Done)
return;
Len += Val;
}
NIter++;
}
while (fabs(OldLen-Len) > Tol && NIter <= IterMax);
} while (fabs(OldLen - Len) > Tol && NIter <= IterMax);
Val = Len;
}
void math_GaussSingleIntegration::Perform(math_Function& F,
const Standard_Real Lower,
const Standard_Real Upper,
const Standard_Integer Order)
void math_GaussSingleIntegration::Perform(math_Function& F,
const Standard_Real Lower,
const Standard_Real Upper,
const Standard_Integer Order)
{
Standard_Real xr, xm, dx;
Standard_Real xr, xm, dx;
Standard_Integer j;
Standard_Real F1, F2;
Standard_Real F1, F2;
Standard_Boolean Ok1;
math_Vector GaussP(1, Order);
math_Vector GaussW(1, Order);
math_Vector GaussP(1, Order);
math_Vector GaussW(1, Order);
Done = Standard_False;
//Recuperation des points de Gauss dans le fichier GaussPoints.
math::GaussPoints(Order,GaussP);
math::GaussWeights(Order,GaussW);
// Recuperation des points de Gauss dans le fichier GaussPoints.
math::GaussPoints(Order, GaussP);
math::GaussWeights(Order, GaussW);
// Calcul de l'integrale aux points de Gauss :
// Calcul de l'integrale aux points de Gauss :
// Changement de variable pour la mise a l'echelle [Lower, Upper] :
xm = 0.5*(Upper + Lower);
xr = 0.5*(Upper - Lower);
// Changement de variable pour la mise a l'echelle [Lower, Upper] :
xm = 0.5 * (Upper + Lower);
xr = 0.5 * (Upper - Lower);
Val = 0.;
Standard_Integer ind = Order/2, ind1 = (Order+1)/2;
if(ind1 > ind) { // odder case
Standard_Integer ind = Order / 2, ind1 = (Order + 1) / 2;
if (ind1 > ind)
{ // odder case
Ok1 = F.Value(xm, Val);
if (!Ok1) return;
if (!Ok1)
return;
Val *= GaussW(ind1);
}
// Sommation sur tous les points de Gauss: avec utilisation de la symetrie.
for (j = 1; j <= ind; j++) {
dx = xr*GaussP(j);
Ok1 = F.Value(xm-dx, F1);
if(!Ok1) return;
Ok1 = F.Value(xm+dx, F2);
if(!Ok1) return;
// Sommation sur tous les points de Gauss: avec utilisation de la symetrie.
for (j = 1; j <= ind; j++)
{
dx = xr * GaussP(j);
Ok1 = F.Value(xm - dx, F1);
if (!Ok1)
return;
Ok1 = F.Value(xm + dx, F2);
if (!Ok1)
return;
// Multiplication par les poids de Gauss.
Standard_Real FT = F1+F2;
Val += GaussW(j)*FT;
Standard_Real FT = F1 + F2;
Val += GaussW(j) * FT;
}
// Mise a l'echelle de l'intervalle [Lower, Upper]
Val *= xr;
Done = Standard_True;
}
void math_GaussSingleIntegration::Dump(Standard_OStream& o) const {
void math_GaussSingleIntegration::Dump(Standard_OStream& o) const
{
o <<"math_GaussSingleIntegration ";
if (Done) {
o << " Status = Done \n";
o << "Integration Value = " << Val<<"\n";
}
else {
o << "Status = not Done \n";
}
o << "math_GaussSingleIntegration ";
if (Done)
{
o << " Status = Done \n";
o << "Integration Value = " << Val << "\n";
}
else
{
o << "Status = not Done \n";
}
}

View File

@@ -24,67 +24,53 @@
#include <Standard_OStream.hxx>
class math_Function;
//! This class implements the integration of a function of a single variable
//! between the parameter bounds Lower and Upper.
//! Warning: Order must be inferior or equal to 61.
class math_GaussSingleIntegration
class math_GaussSingleIntegration
{
public:
DEFINE_STANDARD_ALLOC
Standard_EXPORT math_GaussSingleIntegration();
//! The Gauss-Legendre integration with N = Order points of integration,
//! is done on the function F between the bounds Lower and Upper.
Standard_EXPORT math_GaussSingleIntegration(math_Function& F, const Standard_Real Lower, const Standard_Real Upper, const Standard_Integer Order);
Standard_EXPORT math_GaussSingleIntegration(math_Function& F,
const Standard_Real Lower,
const Standard_Real Upper,
const Standard_Integer Order);
//! The Gauss-Legendre integration with N = Order points of integration and
//! given tolerance = Tol is done on the function F between the bounds
//! Lower and Upper.
Standard_EXPORT math_GaussSingleIntegration(math_Function& F, const Standard_Real Lower, const Standard_Real Upper, const Standard_Integer Order, const Standard_Real Tol);
Standard_EXPORT math_GaussSingleIntegration(math_Function& F,
const Standard_Real Lower,
const Standard_Real Upper,
const Standard_Integer Order,
const Standard_Real Tol);
//! returns True if all has been correctly done.
Standard_Boolean IsDone() const;
Standard_Boolean IsDone() const;
//! returns the value of the integral.
Standard_Real Value() const;
Standard_Real Value() const;
//! Prints information on the current state of the object.
Standard_EXPORT void Dump (Standard_OStream& o) const;
Standard_EXPORT void Dump(Standard_OStream& o) const;
protected:
private:
//! performs actual computation
Standard_EXPORT void Perform (math_Function& F, const Standard_Real Lower, const Standard_Real Upper, const Standard_Integer Order);
Standard_EXPORT void Perform(math_Function& F,
const Standard_Real Lower,
const Standard_Real Upper,
const Standard_Integer Order);
Standard_Real Val;
Standard_Real Val;
Standard_Boolean Done;
};
#include <math_GaussSingleIntegration.lxx>
#endif // _math_GaussSingleIntegration_HeaderFile

View File

@@ -14,17 +14,19 @@
#include <StdFail_NotDone.hxx>
inline Standard_OStream& operator<<(Standard_OStream& o,
const math_GaussSingleIntegration& G)
inline Standard_OStream& operator<<(Standard_OStream& o, const math_GaussSingleIntegration& G)
{
G.Dump(o);
return o;
}
inline Standard_Boolean math_GaussSingleIntegration::IsDone() const
{ return Done; }
inline Standard_Boolean math_GaussSingleIntegration::IsDone() const
{
return Done;
}
inline Standard_Real math_GaussSingleIntegration::Value() const{
inline Standard_Real math_GaussSingleIntegration::Value() const
{
StdFail_NotDone_Raise_if(!Done, " ");
return Val;
}

View File

@@ -23,64 +23,59 @@
#include <Standard_Real.hxx>
#include <Precision.hxx>
//=======================================================================
//function : DistanceToBorder
//purpose :
//=======================================================================
static Standard_Real DistanceToBorder(const math_Vector & theX,
const math_Vector & theMin,
const math_Vector & theMax)
//=================================================================================================
static Standard_Real DistanceToBorder(const math_Vector& theX,
const math_Vector& theMin,
const math_Vector& theMax)
{
Standard_Real aDist = RealLast();
for (Standard_Integer anIdx = theMin.Lower(); anIdx <= theMin.Upper(); ++anIdx)
{
const Standard_Real aDist1 = Abs (theX(anIdx) - theMin(anIdx));
const Standard_Real aDist2 = Abs (theX(anIdx) - theMax(anIdx));
const Standard_Real aDist1 = Abs(theX(anIdx) - theMin(anIdx));
const Standard_Real aDist2 = Abs(theX(anIdx) - theMax(anIdx));
aDist = Min (aDist, Min (aDist1, aDist2));
aDist = Min(aDist, Min(aDist1, aDist2));
}
return aDist;
}
//=================================================================================================
//=======================================================================
//function : math_GlobOptMin
//purpose : Constructor
//=======================================================================
math_GlobOptMin::math_GlobOptMin(math_MultipleVarFunction* theFunc,
const math_Vector& theA,
const math_Vector& theB,
const Standard_Real theC,
const Standard_Real theDiscretizationTol,
const Standard_Real theSameTol)
: myN(theFunc->NbVariables()),
myA(1, myN),
myB(1, myN),
myGlobA(1, myN),
myGlobB(1, myN),
myIsConstLocked(Standard_False),
myX(1, myN),
myTmp(1, myN),
myV(1, myN),
myMaxV(1, myN),
myCellSize(0, myN - 1),
myFilter(theFunc->NbVariables()),
myCont(2),
myF(Precision::Infinite())
const math_Vector& theA,
const math_Vector& theB,
const Standard_Real theC,
const Standard_Real theDiscretizationTol,
const Standard_Real theSameTol)
: myN(theFunc->NbVariables()),
myA(1, myN),
myB(1, myN),
myGlobA(1, myN),
myGlobB(1, myN),
myIsConstLocked(Standard_False),
myX(1, myN),
myTmp(1, myN),
myV(1, myN),
myMaxV(1, myN),
myCellSize(0, myN - 1),
myFilter(theFunc->NbVariables()),
myCont(2),
myF(Precision::Infinite())
{
Standard_Integer i;
myFunc = theFunc;
myC = theC;
myInitC = theC;
myIsFindSingleSolution = Standard_False;
myFunc = theFunc;
myC = theC;
myInitC = theC;
myIsFindSingleSolution = Standard_False;
myFunctionalMinimalValue = -Precision::Infinite();
myZ = -1;
mySolCount = 0;
myZ = -1;
mySolCount = 0;
for(i = 1; i <= myN; i++)
for (i = 1; i <= myN; i++)
{
myGlobA(i) = theA(i);
myGlobB(i) = theB(i);
@@ -89,17 +84,17 @@ math_GlobOptMin::math_GlobOptMin(math_MultipleVarFunction* theFunc,
myB(i) = theB(i);
}
for(i = 1; i <= myN; i++)
for (i = 1; i <= myN; i++)
{
myMaxV(i) = (myB(i) - myA(i)) / 3.0;
}
myTol = theDiscretizationTol;
myTol = theDiscretizationTol;
mySameTol = theSameTol;
const Standard_Integer aMaxSquareSearchSol = 200;
Standard_Integer aSolNb = Standard_Integer(Pow(3.0, Standard_Real(myN)));
myMinCellFilterSol = Max(2 * aSolNb, aMaxSquareSearchSol);
Standard_Integer aSolNb = Standard_Integer(Pow(3.0, Standard_Real(myN)));
myMinCellFilterSol = Max(2 * aSolNb, aMaxSquareSearchSol);
initCellSize();
ComputeInitSol();
@@ -107,25 +102,25 @@ math_GlobOptMin::math_GlobOptMin(math_MultipleVarFunction* theFunc,
}
//=======================================================================
//function : SetGlobalParams
//purpose : Set parameters without memory allocation.
// function : SetGlobalParams
// purpose : Set parameters without memory allocation.
//=======================================================================
void math_GlobOptMin::SetGlobalParams(math_MultipleVarFunction* theFunc,
const math_Vector& theA,
const math_Vector& theB,
const Standard_Real theC,
const Standard_Real theDiscretizationTol,
const Standard_Real theSameTol)
const math_Vector& theA,
const math_Vector& theB,
const Standard_Real theC,
const Standard_Real theDiscretizationTol,
const Standard_Real theSameTol)
{
Standard_Integer i;
myFunc = theFunc;
myC = theC;
myInitC = theC;
myZ = -1;
myFunc = theFunc;
myC = theC;
myInitC = theC;
myZ = -1;
mySolCount = 0;
for(i = 1; i <= myN; i++)
for (i = 1; i <= myN; i++)
{
myGlobA(i) = theA(i);
myGlobB(i) = theB(i);
@@ -134,12 +129,12 @@ void math_GlobOptMin::SetGlobalParams(math_MultipleVarFunction* theFunc,
myB(i) = theB(i);
}
for(i = 1; i <= myN; i++)
for (i = 1; i <= myN; i++)
{
myMaxV(i) = (myB(i) - myA(i)) / 3.0;
}
myTol = theDiscretizationTol;
myTol = theDiscretizationTol;
mySameTol = theSameTol;
initCellSize();
@@ -149,22 +144,21 @@ void math_GlobOptMin::SetGlobalParams(math_MultipleVarFunction* theFunc,
}
//=======================================================================
//function : SetLocalParams
//purpose : Set parameters without memory allocation.
// function : SetLocalParams
// purpose : Set parameters without memory allocation.
//=======================================================================
void math_GlobOptMin::SetLocalParams(const math_Vector& theLocalA,
const math_Vector& theLocalB)
void math_GlobOptMin::SetLocalParams(const math_Vector& theLocalA, const math_Vector& theLocalB)
{
Standard_Integer i;
myZ = -1;
for(i = 1; i <= myN; i++)
for (i = 1; i <= myN; i++)
{
myA(i) = theLocalA(i);
myB(i) = theLocalB(i);
}
for(i = 1; i <= myN; i++)
for (i = 1; i <= myN; i++)
{
myMaxV(i) = (myB(i) - myA(i)) / 3.0;
}
@@ -173,30 +167,29 @@ void math_GlobOptMin::SetLocalParams(const math_Vector& theLocalA,
}
//=======================================================================
//function : SetTol
//purpose : Set algorithm tolerances.
// function : SetTol
// purpose : Set algorithm tolerances.
//=======================================================================
void math_GlobOptMin::SetTol(const Standard_Real theDiscretizationTol,
const Standard_Real theSameTol)
{
myTol = theDiscretizationTol;
myTol = theDiscretizationTol;
mySameTol = theSameTol;
}
//=======================================================================
//function : GetTol
//purpose : Get algorithm tolerances.
// function : GetTol
// purpose : Get algorithm tolerances.
//=======================================================================
void math_GlobOptMin::GetTol(Standard_Real& theDiscretizationTol,
Standard_Real& theSameTol)
void math_GlobOptMin::GetTol(Standard_Real& theDiscretizationTol, Standard_Real& theSameTol)
{
theDiscretizationTol = myTol;
theSameTol = mySameTol;
theSameTol = mySameTol;
}
//=======================================================================
//function : Perform
//purpose : Compute Global extremum point
// function : Perform
// purpose : Compute Global extremum point
//=======================================================================
// In this algo indexes started from 1, not from 0.
void math_GlobOptMin::Perform(const Standard_Boolean isFindSingleSolution)
@@ -206,7 +199,7 @@ void math_GlobOptMin::Perform(const Standard_Boolean isFindSingleSolution)
// Compute parameters range
Standard_Real minLength = RealLast();
Standard_Real maxLength = RealFirst();
for(Standard_Integer i = 1; i <= myN; i++)
for (Standard_Integer i = 1; i <= myN; i++)
{
Standard_Real currentLength = myB(i) - myA(i);
if (currentLength < minLength)
@@ -219,9 +212,9 @@ void math_GlobOptMin::Perform(const Standard_Boolean isFindSingleSolution)
if (minLength < Precision::PConfusion())
{
#ifdef OCCT_DEBUG
#ifdef OCCT_DEBUG
std::cout << "math_GlobOptMin::Perform(): Degenerated parameters space" << std::endl;
#endif
#endif
return;
}
@@ -244,9 +237,9 @@ void math_GlobOptMin::Perform(const Standard_Boolean isFindSingleSolution)
else
{
if (myC > 1.0)
myE3 = - maxLength * myTol / 4.0;
myE3 = -maxLength * myTol / 4.0;
else
myE3 = - maxLength * myTol * myC / 4.0;
myE3 = -maxLength * myTol * myC / 4.0;
}
// Search single solution and current solution in its neighborhood.
@@ -256,29 +249,26 @@ void math_GlobOptMin::Perform(const Standard_Boolean isFindSingleSolution)
return;
}
myLastStep = 0.0;
myLastStep = 0.0;
isFirstCellFilterInvoke = Standard_True;
computeGlobalExtremum(myN);
myDone = Standard_True;
}
//=======================================================================
//function : computeLocalExtremum
//purpose :
//=======================================================================
//=================================================================================================
Standard_Boolean math_GlobOptMin::computeLocalExtremum(const math_Vector& thePnt,
Standard_Real& theVal,
math_Vector& theOutPnt)
Standard_Real& theVal,
math_Vector& theOutPnt)
{
Standard_Integer i;
//Newton method
if (myCont >= 2 &&
dynamic_cast<math_MultipleVarFunctionWithHessian*>(myFunc))
// Newton method
if (myCont >= 2 && dynamic_cast<math_MultipleVarFunctionWithHessian*>(myFunc))
{
math_MultipleVarFunctionWithHessian* aTmp =
dynamic_cast<math_MultipleVarFunctionWithHessian*> (myFunc);
math_MultipleVarFunctionWithHessian* aTmp =
dynamic_cast<math_MultipleVarFunctionWithHessian*>(myFunc);
math_NewtonMinimum newtonMinimum(*aTmp);
newtonMinimum.SetBoundary(myGlobA, myGlobB);
newtonMinimum.Perform(*aTmp, thePnt);
@@ -294,11 +284,10 @@ Standard_Boolean math_GlobOptMin::computeLocalExtremum(const math_Vector& thePnt
}
// BFGS method used.
if (myCont >= 1 &&
dynamic_cast<math_MultipleVarFunctionWithGradient*>(myFunc))
if (myCont >= 1 && dynamic_cast<math_MultipleVarFunctionWithGradient*>(myFunc))
{
math_MultipleVarFunctionWithGradient* aTmp =
dynamic_cast<math_MultipleVarFunctionWithGradient*> (myFunc);
dynamic_cast<math_MultipleVarFunctionWithGradient*>(myFunc);
math_BFGS bfgs(aTmp->NbVariables());
bfgs.SetBoundary(myGlobA, myGlobB);
bfgs.Perform(*aTmp, thePnt);
@@ -317,7 +306,7 @@ Standard_Boolean math_GlobOptMin::computeLocalExtremum(const math_Vector& thePnt
if (dynamic_cast<math_MultipleVarFunction*>(myFunc))
{
math_Matrix m(1, myN, 1, myN, 0.0);
for(i = 1; i <= myN; i++)
for (i = 1; i <= myN; i++)
m(i, i) = 1.0;
math_Powell powell(*myFunc, 1e-10);
@@ -336,42 +325,40 @@ Standard_Boolean math_GlobOptMin::computeLocalExtremum(const math_Vector& thePnt
return Standard_False;
}
//=======================================================================
//function : computeInitialValues
//purpose :
//=======================================================================
//=================================================================================================
void math_GlobOptMin::computeInitialValues()
{
const Standard_Real aMinLC = 0.01;
const Standard_Real aMaxLC = 1000.;
const Standard_Real aMinLC = 0.01;
const Standard_Real aMaxLC = 1000.;
const Standard_Real aMinEps = 0.1;
const Standard_Real aMaxEps = 100.;
Standard_Integer i;
math_Vector aCurrPnt(1, myN);
math_Vector aBestPnt(1, myN);
math_Vector aParamStep(1, myN);
Standard_Real aCurrVal = RealLast();
Standard_Integer i;
math_Vector aCurrPnt(1, myN);
math_Vector aBestPnt(1, myN);
math_Vector aParamStep(1, myN);
Standard_Real aCurrVal = RealLast();
// Lipchitz const approximation.
Standard_Real aLipConst = 0.0, aPrevValDiag, aPrevValProj;
Standard_Integer aPntNb = 13;
Standard_Real aLipConst = 0.0, aPrevValDiag, aPrevValProj;
Standard_Integer aPntNb = 13;
myFunc->Value(myA, aPrevValDiag);
aPrevValProj = aPrevValDiag;
aPrevValProj = aPrevValDiag;
Standard_Real aStep = (myB - myA).Norm() / aPntNb;
aParamStep = (myB - myA) / aPntNb;
for(i = 1; i <= aPntNb; i++)
aParamStep = (myB - myA) / aPntNb;
for (i = 1; i <= aPntNb; i++)
{
aCurrPnt = myA + aParamStep * i;
// Walk over diagonal.
myFunc->Value(aCurrPnt, aCurrVal);
aLipConst = Max (Abs(aCurrVal - aPrevValDiag), aLipConst);
aLipConst = Max(Abs(aCurrVal - aPrevValDiag), aLipConst);
aPrevValDiag = aCurrVal;
// Walk over diag in projected space aPnt(1) = myA(1) = const.
aCurrPnt(1) = myA(1);
myFunc->Value(aCurrPnt, aCurrVal);
aLipConst = Max (Abs(aCurrVal - aPrevValProj), aLipConst);
aLipConst = Max(Abs(aCurrVal - aPrevValProj), aLipConst);
aPrevValProj = aCurrVal;
}
@@ -383,27 +370,24 @@ void math_GlobOptMin::computeInitialValues()
myC = Min(myC * aMaxEps, aMaxLC);
}
//=======================================================================
//function : ComputeGlobalExtremum
//purpose :
//=======================================================================
//=================================================================================================
void math_GlobOptMin::computeGlobalExtremum(Standard_Integer j)
{
Standard_Integer i;
Standard_Real d = RealLast(), aPrevVal; // Functional in original and moved points.
Standard_Real val = RealLast(); // Local extrema computed in moved point.
Standard_Real aStepBestValue = RealLast();
math_Vector aStepBestPoint(1, myN);
Standard_Boolean isInside = Standard_False,
isReached = Standard_False;
Standard_Real d = RealLast(), aPrevVal; // Functional in original and moved points.
Standard_Real val = RealLast(); // Local extrema computed in moved point.
Standard_Real aStepBestValue = RealLast();
math_Vector aStepBestPoint(1, myN);
Standard_Boolean isInside = Standard_False, isReached = Standard_False;
Standard_Real r1, r2, r;
for(myX(j) = myA(j) + myE1; !isReached; myX(j) += myV(j))
for (myX(j) = myA(j) + myE1; !isReached; myX(j) += myV(j))
{
if (myX(j) > myB(j))
{
myX(j) = myB(j);
myX(j) = myB(j);
isReached = Standard_True;
}
@@ -416,32 +400,33 @@ void math_GlobOptMin::computeGlobalExtremum(Standard_Integer j)
aPrevVal = d;
myFunc->Value(myX, d);
r1 = (d + myZ * myC * myLastStep - myF) * myZ; // Evtushenko estimation.
// clang-format off
// clang-format off
r2 = ((d + aPrevVal - myC * myLastStep) * 0.5 - myF) * myZ; // Shubert / Piyavsky estimation.
// clang-format on
// clang-format on
r = Min(r1, r2);
if(r > myE3)
if (r > myE3)
{
Standard_Real aSaveParam = myX(1);
// Piyavsky midpoint estimation.
Standard_Real aParam = (2 * myX(1) - myV(1) ) * 0.5 + (aPrevVal - d) * 0.5 / myC;
Standard_Real aParam = (2 * myX(1) - myV(1)) * 0.5 + (aPrevVal - d) * 0.5 / myC;
if (Precision::IsInfinite(aPrevVal))
aParam = myX(1) - myV(1) * 0.5; // Protection from upper dimension step.
myX(1) = aParam;
myX(1) = aParam;
Standard_Real aVal = 0;
myFunc->Value(myX, aVal);
myX(1) = aSaveParam;
if ( (aVal < d && aVal < aPrevVal) ||
DistanceToBorder(myX, myA, myB) < myE1 ) // Condition optimization case near the border.
if ((aVal < d && aVal < aPrevVal)
|| DistanceToBorder(myX, myA, myB)
< myE1) // Condition optimization case near the border.
{
isInside = computeLocalExtremum(myX, val, myTmp);
}
}
aStepBestValue = (isInside && (val < d))? val : d;
aStepBestPoint = (isInside && (val < d))? myTmp : myX;
aStepBestValue = (isInside && (val < d)) ? val : d;
aStepBestPoint = (isInside && (val < d)) ? myTmp : myX;
// Check point and value on the current step to be optimal.
checkAddCandidate(aStepBestPoint, aStepBestValue);
@@ -449,7 +434,7 @@ void math_GlobOptMin::computeGlobalExtremum(Standard_Integer j)
if (CheckFunctionalStopCriteria())
return; // Best possible value is obtained.
myV(1) = Min(myE2 + Abs(myF - d) / myC, myMaxV(1));
myV(1) = Min(myE2 + Abs(myF - d) / myC, myMaxV(1));
myLastStep = myV(1);
}
else
@@ -458,16 +443,16 @@ void math_GlobOptMin::computeGlobalExtremum(Standard_Integer j)
computeGlobalExtremum(j - 1);
// Nullify steps on lower dimensions.
for(i = 1; i < j; i++)
for (i = 1; i < j; i++)
myV(i) = 0.0;
}
if (j < myN)
{
Standard_Real aUpperDimStep = Max(myV(j), myE2);
Standard_Real aUpperDimStep = Max(myV(j), myE2);
if (myV(j + 1) > aUpperDimStep)
{
if (aUpperDimStep > myMaxV(j + 1)) // Case of too big step.
myV(j + 1) = myMaxV(j + 1);
myV(j + 1) = myMaxV(j + 1);
else
myV(j + 1) = aUpperDimStep;
}
@@ -475,40 +460,37 @@ void math_GlobOptMin::computeGlobalExtremum(Standard_Integer j)
}
}
//=======================================================================
//function : IsInside
//purpose :
//=======================================================================
//=================================================================================================
Standard_Boolean math_GlobOptMin::isInside(const math_Vector& thePnt)
{
Standard_Integer i;
for(i = 1; i <= myN; i++)
{
if (thePnt(i) < myGlobA(i) || thePnt(i) > myGlobB(i))
return Standard_False;
}
for (i = 1; i <= myN; i++)
{
if (thePnt(i) < myGlobA(i) || thePnt(i) > myGlobB(i))
return Standard_False;
}
return Standard_True;
return Standard_True;
}
//=======================================================================
//function : IsStored
//purpose :
//=======================================================================
//=================================================================================================
Standard_Boolean math_GlobOptMin::isStored(const math_Vector& thePnt)
{
Standard_Integer i,j;
Standard_Integer i, j;
Standard_Boolean isSame = Standard_True;
math_Vector aTol(1, myN);
aTol = (myB - myA) * mySameTol;
math_Vector aTol(1, myN);
aTol = (myB - myA) * mySameTol;
// C1 * n^2 = C2 * 3^dim * n
if (mySolCount < myMinCellFilterSol)
{
for(i = 0; i < mySolCount; i++)
for (i = 0; i < mySolCount; i++)
{
isSame = Standard_True;
for(j = 1; j <= myN; j++)
for (j = 1; j <= myN; j++)
{
if ((Abs(thePnt(j) - myY(i * myN + j))) > aTol(j))
{
@@ -528,10 +510,10 @@ Standard_Boolean math_GlobOptMin::isStored(const math_Vector& thePnt)
myFilter.Reset(myCellSize);
// Copy initial data into cell filter.
for(Standard_Integer aSolIdx = 0; aSolIdx < mySolCount; aSolIdx++)
for (Standard_Integer aSolIdx = 0; aSolIdx < mySolCount; aSolIdx++)
{
math_Vector aVec(1, myN);
for(Standard_Integer aSolDim = 1; aSolDim <= myN; aSolDim++)
for (Standard_Integer aSolDim = 1; aSolDim <= myN; aSolDim++)
aVec(aSolDim) = myY(aSolIdx * myN + aSolDim);
myFilter.Add(aVec, aVec);
@@ -555,53 +537,44 @@ Standard_Boolean math_GlobOptMin::isStored(const math_Vector& thePnt)
return Standard_False;
}
//=======================================================================
//function : Points
//purpose :
//=======================================================================
//=================================================================================================
void math_GlobOptMin::Points(const Standard_Integer theIndex, math_Vector& theSol)
{
Standard_Integer j;
for(j = 1; j <= myN; j++)
for (j = 1; j <= myN; j++)
theSol(j) = myY((theIndex - 1) * myN + j);
}
//=======================================================================
//function : initCellSize
//purpose :
//=======================================================================
//=================================================================================================
void math_GlobOptMin::initCellSize()
{
for(Standard_Integer anIdx = 1; anIdx <= myN; anIdx++)
for (Standard_Integer anIdx = 1; anIdx <= myN; anIdx++)
{
myCellSize(anIdx - 1) = (myGlobB(anIdx) - myGlobA(anIdx))
* Precision::PConfusion() / (2.0 * Sqrt(2.0));
myCellSize(anIdx - 1) =
(myGlobB(anIdx) - myGlobA(anIdx)) * Precision::PConfusion() / (2.0 * Sqrt(2.0));
}
}
//=======================================================================
//function : CheckFunctionalStopCriteria
//purpose :
//=======================================================================
//=================================================================================================
Standard_Boolean math_GlobOptMin::CheckFunctionalStopCriteria()
{
// Search single solution and current solution in its neighborhood.
if (myIsFindSingleSolution &&
Abs (myF - myFunctionalMinimalValue) < mySameTol * 0.01)
if (myIsFindSingleSolution && Abs(myF - myFunctionalMinimalValue) < mySameTol * 0.01)
return Standard_True;
return Standard_False;
}
//=======================================================================
//function : ComputeInitSol
//purpose :
//=======================================================================
//=================================================================================================
void math_GlobOptMin::ComputeInitSol()
{
Standard_Real aVal;
math_Vector aPnt(1, myN);
math_Vector aPnt(1, myN);
// Check functional value in midpoint. It is necessary since local optimization
// algorithm may fail and return nothing. This is a protection from uninitialized
@@ -611,21 +584,18 @@ void math_GlobOptMin::ComputeInitSol()
checkAddCandidate(aPnt, aVal);
// Run local optimization from lower corner, midpoint, and upper corner.
for(Standard_Integer i = 1; i <= 3; i++)
for (Standard_Integer i = 1; i <= 3; i++)
{
aPnt = myA + (myB - myA) * (i - 1) / 2.0;
if(computeLocalExtremum(aPnt, aVal, aPnt))
if (computeLocalExtremum(aPnt, aVal, aPnt))
checkAddCandidate(aPnt, aVal);
}
}
//=======================================================================
//function : checkAddCandidate
//purpose :
//=======================================================================
void math_GlobOptMin::checkAddCandidate(const math_Vector& thePnt,
const Standard_Real theValue)
//=================================================================================================
void math_GlobOptMin::checkAddCandidate(const math_Vector& thePnt, const Standard_Real theValue)
{
if (Abs(theValue - myF) < mySameTol * 0.01 && // Value in point is close to optimal value.
!myIsFindSingleSolution) // Several optimal solutions are allowed.
@@ -644,8 +614,7 @@ void math_GlobOptMin::checkAddCandidate(const math_Vector& thePnt,
// new point is out of (mySameTol * 0.01) surrounding or
// new point is better than old and single point search.
Standard_Real aDelta = (theValue - myF) * myZ;
if (aDelta > mySameTol * 0.01 ||
(aDelta > 0.0 && myIsFindSingleSolution))
if (aDelta > mySameTol * 0.01 || (aDelta > 0.0 && myIsFindSingleSolution))
{
myF = theValue;
myY.Clear();

View File

@@ -22,11 +22,12 @@
#include <NCollection_Sequence.hxx>
//! This class represents Evtushenko's algorithm of global optimization based on non-uniform mesh.
//! Article: Yu. Evtushenko. Numerical methods for finding global extreme (case of a non-uniform mesh).
//! U.S.S.R. Comput. Maths. Math. Phys., Vol. 11, N 6, pp. 38-54.
//! Article: Yu. Evtushenko. Numerical methods for finding global extreme (case of a non-uniform
//! mesh). U.S.S.R. Comput. Maths. Math. Phys., Vol. 11, N 6, pp. 38-54.
//!
//! This method performs search on non-uniform mesh. The search space is a box in R^n space.
//! The default behavior is to find all minimums in that box. Computation of maximums is not supported.
//! The default behavior is to find all minimums in that box. Computation of maximums is not
//! supported.
//!
//! The search box can be split into smaller boxes by discontinuity criteria.
//! This functionality is covered by SetGlobalParams and SetLocalParams API.
@@ -49,7 +50,6 @@
class math_GlobOptMin
{
public:
//! Constructor. Perform method is not called from it.
//! @param theFunc - objective functional.
//! @param theLowerBorder - lower corner of the search box.
@@ -58,11 +58,11 @@ public:
//! @param theDiscretizationTol - parameter space discretization tolerance.
//! @param theSameTol - functional value space indifference tolerance.
Standard_EXPORT math_GlobOptMin(math_MultipleVarFunction* theFunc,
const math_Vector& theLowerBorder,
const math_Vector& theUpperBorder,
const Standard_Real theC = 9,
const Standard_Real theDiscretizationTol = 1.0e-2,
const Standard_Real theSameTol = 1.0e-7);
const math_Vector& theLowerBorder,
const math_Vector& theUpperBorder,
const Standard_Real theC = 9,
const Standard_Real theDiscretizationTol = 1.0e-2,
const Standard_Real theSameTol = 1.0e-7);
//! @param theFunc - objective functional.
//! @param theLowerBorder - lower corner of the search box.
@@ -71,17 +71,16 @@ public:
//! @param theDiscretizationTol - parameter space discretization tolerance.
//! @param theSameTol - functional value space indifference tolerance.
Standard_EXPORT void SetGlobalParams(math_MultipleVarFunction* theFunc,
const math_Vector& theLowerBorder,
const math_Vector& theUpperBorder,
const Standard_Real theC = 9,
const Standard_Real theDiscretizationTol = 1.0e-2,
const Standard_Real theSameTol = 1.0e-7);
const math_Vector& theLowerBorder,
const math_Vector& theUpperBorder,
const Standard_Real theC = 9,
const Standard_Real theDiscretizationTol = 1.0e-2,
const Standard_Real theSameTol = 1.0e-7);
//! Method to reduce bounding box. Perform will use this box.
//! @param theLocalA - lower corner of the local box.
//! @param theLocalB - upper corner of the local box.
Standard_EXPORT void SetLocalParams(const math_Vector& theLocalA,
const math_Vector& theLocalB);
Standard_EXPORT void SetLocalParams(const math_Vector& theLocalA, const math_Vector& theLocalB);
//! Method to set tolerances.
//! @param theDiscretizationTol - parameter space discretization tolerance.
@@ -92,8 +91,7 @@ public:
//! Method to get tolerances.
//! @param theDiscretizationTol - parameter space discretization tolerance.
//! @param theSameTol - functional value space indifference tolerance.
Standard_EXPORT void GetTol(Standard_Real& theDiscretizationTol,
Standard_Real& theSameTol);
Standard_EXPORT void GetTol(Standard_Real& theDiscretizationTol, Standard_Real& theSameTol);
//! @param isFindSingleSolution - defines whether to find single solution or all solutions.
Standard_EXPORT void Perform(const Standard_Boolean isFindSingleSolution = Standard_False);
@@ -103,89 +101,79 @@ public:
//! Set / Get continuity of local borders splits (0 ~ C0, 1 ~ C1, 2 ~ C2).
inline void SetContinuity(const Standard_Integer theCont) { myCont = theCont; }
inline Standard_Integer GetContinuity() const {return myCont; }
//! Set / Get functional minimal value.
inline Standard_Integer GetContinuity() const { return myCont; }
//! Set / Get functional minimal value.
inline void SetFunctionalMinimalValue(const Standard_Real theMinimalValue)
{ myFunctionalMinimalValue = theMinimalValue; }
inline Standard_Real GetFunctionalMinimalValue() const {return myFunctionalMinimalValue;}
{
myFunctionalMinimalValue = theMinimalValue;
}
//! Set / Get Lipchitz constant modification state.
inline Standard_Real GetFunctionalMinimalValue() const { return myFunctionalMinimalValue; }
//! Set / Get Lipchitz constant modification state.
//! True means that the constant is locked and unlocked otherwise.
inline void SetLipConstState(const Standard_Boolean theFlag) {myIsConstLocked = theFlag; }
inline void SetLipConstState(const Standard_Boolean theFlag) { myIsConstLocked = theFlag; }
inline Standard_Boolean GetLipConstState() const { return myIsConstLocked; }
//! Return computation state of the algorithm.
inline Standard_Boolean isDone() const {return myDone; }
inline Standard_Boolean isDone() const { return myDone; }
//! Get best functional value.
inline Standard_Real GetF() const {return myF;}
inline Standard_Real GetF() const { return myF; }
//! Return count of global extremas.
inline Standard_Integer NbExtrema() const {return mySolCount;}
inline Standard_Integer NbExtrema() const { return mySolCount; }
private:
//! Class for duplicate fast search. For internal usage only.
class NCollection_CellFilter_Inspector
{
public:
//! Points and target type
typedef math_Vector Point;
typedef math_Vector Target;
NCollection_CellFilter_Inspector(const Standard_Integer theDim,
const Standard_Real theTol)
: myCurrent(1, theDim)
NCollection_CellFilter_Inspector(const Standard_Integer theDim, const Standard_Real theTol)
: myCurrent(1, theDim)
{
myTol = theTol * theTol;
myIsFind = Standard_False;
myTol = theTol * theTol;
myIsFind = Standard_False;
Dimension = theDim;
}
//! Access to coordinate.
static Standard_Real Coord (int i, const Point &thePnt)
{
return thePnt(i + 1);
}
static Standard_Real Coord(int i, const Point& thePnt) { return thePnt(i + 1); }
//! Auxiliary method to shift point by each coordinate on given value;
//! useful for preparing a points range for Inspect with tolerance.
void Shift (const Point& thePnt,
const NCollection_Array1<Standard_Real> &theTol,
Point& theLowPnt,
Point& theUppPnt) const
void Shift(const Point& thePnt,
const NCollection_Array1<Standard_Real>& theTol,
Point& theLowPnt,
Point& theUppPnt) const
{
for(Standard_Integer anIdx = 1; anIdx <= Dimension; anIdx++)
for (Standard_Integer anIdx = 1; anIdx <= Dimension; anIdx++)
{
theLowPnt(anIdx) = thePnt(anIdx) - theTol(anIdx - 1);
theUppPnt(anIdx) = thePnt(anIdx) + theTol(anIdx - 1);
}
}
void ClearFind()
{
myIsFind = Standard_False;
}
void ClearFind() { myIsFind = Standard_False; }
Standard_Boolean isFind()
{
return myIsFind;
}
Standard_Boolean isFind() { return myIsFind; }
//! Set current point to search for coincidence
void SetCurrent (const math_Vector& theCurPnt)
{
myCurrent = theCurPnt;
}
void SetCurrent(const math_Vector& theCurPnt) { myCurrent = theCurPnt; }
//! Implementation of inspection method
NCollection_CellFilter_Action Inspect (const Target& theObject)
NCollection_CellFilter_Action Inspect(const Target& theObject)
{
Standard_Real aSqDist = (myCurrent - theObject).Norm2();
if(aSqDist < myTol)
if (aSqDist < myTol)
{
myIsFind = Standard_True;
}
@@ -194,22 +182,23 @@ private:
}
private:
Standard_Real myTol;
math_Vector myCurrent;
Standard_Real myTol;
math_Vector myCurrent;
Standard_Boolean myIsFind;
Standard_Integer Dimension;
};
// Compute cell size.
void initCellSize();
// Compute initial solution
void ComputeInitSol();
math_GlobOptMin & operator = (const math_GlobOptMin & theOther);
math_GlobOptMin& operator=(const math_GlobOptMin& theOther);
Standard_Boolean computeLocalExtremum(const math_Vector& thePnt, Standard_Real& theVal, math_Vector& theOutPnt);
Standard_Boolean computeLocalExtremum(const math_Vector& thePnt,
Standard_Real& theVal,
math_Vector& theOutPnt);
void computeGlobalExtremum(Standard_Integer theIndex);
@@ -228,36 +217,34 @@ private:
Standard_Boolean isInside(const math_Vector& thePnt);
//! Check presence of thePnt in GlobOpt sequence.
Standard_Boolean isStored(const math_Vector &thePnt);
Standard_Boolean isStored(const math_Vector& thePnt);
//! Check and add candidate point into solutions.
//! @param thePnt Candidate point.
//! @param theValue Function value in the candidate point.
void checkAddCandidate(const math_Vector& thePnt,
const Standard_Real theValue);
void checkAddCandidate(const math_Vector& thePnt, const Standard_Real theValue);
// Input.
math_MultipleVarFunction* myFunc;
Standard_Integer myN;
math_Vector myA; // Left border on current C2 interval.
math_Vector myB; // Right border on current C2 interval.
math_Vector myGlobA; // Global left border.
math_Vector myGlobB; // Global right border.
Standard_Real myTol; // Discretization tolerance, default 1.0e-2.
Standard_Real mySameTol; // points with ||p1 - p2|| < mySameTol is equal,
// function values |val1 - val2| * 0.01 < mySameTol is equal,
// default value is 1.0e-7.
Standard_Real myC; //Lipchitz constant, default 9
Standard_Real myInitC; // Lipchitz constant initial value.
Standard_Boolean myIsFindSingleSolution; // Default value is false.
Standard_Real myFunctionalMinimalValue; // Default value is -Precision::Infinite
Standard_Boolean myIsConstLocked; // Is constant locked for modifications.
Standard_Integer myN;
math_Vector myA; // Left border on current C2 interval.
math_Vector myB; // Right border on current C2 interval.
math_Vector myGlobA; // Global left border.
math_Vector myGlobB; // Global right border.
Standard_Real myTol; // Discretization tolerance, default 1.0e-2.
Standard_Real mySameTol; // points with ||p1 - p2|| < mySameTol is equal,
// function values |val1 - val2| * 0.01 < mySameTol is equal,
// default value is 1.0e-7.
Standard_Real myC; // Lipchitz constant, default 9
Standard_Real myInitC; // Lipchitz constant initial value.
Standard_Boolean myIsFindSingleSolution; // Default value is false.
Standard_Real myFunctionalMinimalValue; // Default value is -Precision::Infinite
Standard_Boolean myIsConstLocked; // Is constant locked for modifications.
// Output.
Standard_Boolean myDone;
NCollection_Sequence<Standard_Real> myY;// Current solutions.
Standard_Integer mySolCount; // Count of solutions.
Standard_Boolean myDone;
NCollection_Sequence<Standard_Real> myY; // Current solutions.
Standard_Integer mySolCount; // Count of solutions.
// Algorithm data.
Standard_Real myZ;
@@ -265,15 +252,15 @@ private:
Standard_Real myE2; // Minimum step size.
Standard_Real myE3; // Local extrema starting parameter.
math_Vector myX; // Current modified solution.
math_Vector myTmp; // Current modified solution.
math_Vector myV; // Steps array.
math_Vector myMaxV; // Max Steps array.
math_Vector myX; // Current modified solution.
math_Vector myTmp; // Current modified solution.
math_Vector myV; // Steps array.
math_Vector myMaxV; // Max Steps array.
Standard_Real myLastStep; // Last step.
NCollection_Array1<Standard_Real> myCellSize;
Standard_Integer myMinCellFilterSol;
Standard_Boolean isFirstCellFilterInvoke;
NCollection_Array1<Standard_Real> myCellSize;
Standard_Integer myMinCellFilterSol;
Standard_Boolean isFirstCellFilterInvoke;
NCollection_CellFilter<NCollection_CellFilter_Inspector> myFilter;
// Continuity of local borders.

View File

@@ -12,12 +12,12 @@
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
//#ifndef OCCT_DEBUG
// #ifndef OCCT_DEBUG
#define No_Standard_RangeError
#define No_Standard_OutOfRange
#define No_Standard_DimensionError
//#endif
// #endif
#include <math_Householder.hxx>
#include <math_Matrix.hxx>
@@ -28,18 +28,19 @@
// produit de matrice orthogonale par une triangulaire superieure. Les seconds
// membres sont modifies dans le meme temps.
// Les references sur le cote sont celles de l'algorithme explique en page
// 90 du livre "Introduction a l'analyse numerique matricielle et a
// l'optimisation." par P.G. CIARLET, edition MASSON. Les secondes
// 90 du livre "Introduction a l'analyse numerique matricielle et a
// l'optimisation." par P.G. CIARLET, edition MASSON. Les secondes
// references sont celles du sous-programme HOUSEO d'Euclid.
// A la difference du sous-programme Houseo, la premiere colonne n'est pas
// A la difference du sous-programme Houseo, la premiere colonne n'est pas
// traitee separement. Les tests effectues ont montre que le code effectue
// specialement pour celle-ci etait plus long qu'une simple recopie. C'est
// donc cette solution de recopie initiale qui a ete retenue.
math_Householder::math_Householder(const math_Matrix& A, const math_Vector& B,
const Standard_Real EPS):
Sol(1, A.ColNumber(), 1, 1),
Q(1, A.RowNumber(),
1, A.ColNumber()) {
math_Householder::math_Householder(const math_Matrix& A,
const math_Vector& B,
const Standard_Real EPS)
: Sol(1, A.ColNumber(), 1, 1),
Q(1, A.RowNumber(), 1, A.ColNumber())
{
mylowerArow = A.LowerRow();
mylowerAcol = A.LowerCol();
@@ -50,14 +51,12 @@ math_Householder::math_Householder(const math_Matrix& A, const math_Vector& B,
Perform(A, B1, EPS);
}
math_Householder::math_Householder(const math_Matrix& A, const math_Matrix& B,
const Standard_Real EPS):
Sol(1, A.ColNumber(),
1, B.ColNumber()),
Q(1, A.RowNumber(),
A.LowerCol(), A.UpperCol()) {
math_Householder::math_Householder(const math_Matrix& A,
const math_Matrix& B,
const Standard_Real EPS)
: Sol(1, A.ColNumber(), 1, B.ColNumber()),
Q(1, A.RowNumber(), A.LowerCol(), A.UpperCol())
{
mylowerArow = A.LowerRow();
mylowerAcol = A.LowerCol();
@@ -66,17 +65,16 @@ math_Householder::math_Householder(const math_Matrix& A, const math_Matrix& B,
Perform(A, B, EPS);
}
math_Householder::math_Householder(const math_Matrix& A, const math_Matrix& B,
math_Householder::math_Householder(const math_Matrix& A,
const math_Matrix& B,
const Standard_Integer lowerArow,
const Standard_Integer upperArow,
const Standard_Integer lowerAcol,
const Standard_Integer upperAcol,
const Standard_Real EPS):
Sol(1, upperAcol-lowerAcol+1,
1, B.ColNumber()),
Q(1, upperArow-lowerArow+1,
1, upperAcol-lowerAcol+1) {
const Standard_Real EPS)
: Sol(1, upperAcol - lowerAcol + 1, 1, B.ColNumber()),
Q(1, upperArow - lowerArow + 1, 1, upperAcol - lowerAcol + 1)
{
mylowerArow = lowerArow;
myupperArow = upperArow;
mylowerAcol = lowerAcol;
@@ -85,100 +83,112 @@ math_Householder::math_Householder(const math_Matrix& A, const math_Matrix& B,
Perform(A, B, EPS);
}
void math_Householder::Perform(const math_Matrix& A, const math_Matrix& B,
const Standard_Real EPS) {
void math_Householder::Perform(const math_Matrix& A, const math_Matrix& B, const Standard_Real EPS)
{
Standard_Integer i, j, k, n, l, m;
Standard_Real f, g, h = 0., alfaii;
Standard_Real qki;
Standard_Real cj;
Standard_Real f, g, h = 0., alfaii;
Standard_Real qki;
Standard_Real cj;
n = Q.ColNumber();
l = Q.RowNumber();
m = B.ColNumber();
math_Matrix B2(1, l, 1, m);
Standard_Integer lbrow = B.LowerRow();
for (i = 1; i <= l; i++) {
for (j = 1; j <= n; j++) {
Q(i, j) = A(i+mylowerArow-1, j+mylowerAcol-1);
for (i = 1; i <= l; i++)
{
for (j = 1; j <= n; j++)
{
Q(i, j) = A(i + mylowerArow - 1, j + mylowerAcol - 1);
}
for (j=1; j <= m; j++) {
B2(i, j) = B(i+lbrow-1, j);
for (j = 1; j <= m; j++)
{
B2(i, j) = B(i + lbrow - 1, j);
}
}
Standard_DimensionError_Raise_if(l != B.RowNumber() || n > l, " ");
// Traitement de chaque colonne de A:
for (i = 1; i <= n; i++) {
h = 0.0;
for (k = i; k <= l; k++) {
qki = Q(k, i);
h += qki*qki; // = ||a||*||a|| = EUAI
}
f = Q(i,i); // = a1 = AII
g = f<1.e-15 ? Sqrt(h) : -Sqrt(h);
if (fabs(g) <= EPS) {
Done = Standard_False;
return;
}
h -= f*g; // = (v*v)/2 = C1
alfaii = g-f; // = v = ALFAII
for (j =i+1; j <= n; j++) {
Standard_Real scale = 0.0;
for (k = i; k <= l; k++) {
scale += Q(k,i)* Q(k,j); // = SCAL
}
cj = (g*Q(i,j) - scale)/h;
Q(i,j) = Q(i,j) - alfaii*cj;
for(k= i+1; k <= l; k++) {
Q(k,j) = Q(k, j) + cj * Q(k,i);
}
}
// Modification de B:
for (j = 1; j <= m; j++) {
Standard_Real scale= Q(i,i)*B2(i,j);
for (k = i+1; k <= l; k++) {
scale += Q(k,i)*B2(k,j);
}
cj = (g*B2(i,j) - scale)/h;
B2(i,j) = B2(i,j) - cj*alfaii;
for (k = i+1; k <= l; k++) {
B2(k,j) = B2(k,j) + cj*Q(k,i);
}
}
Q(i,i) = g;
// Traitement de chaque colonne de A:
for (i = 1; i <= n; i++)
{
h = 0.0;
for (k = i; k <= l; k++)
{
qki = Q(k, i);
h += qki * qki; // = ||a||*||a|| = EUAI
}
f = Q(i, i); // = a1 = AII
g = f < 1.e-15 ? Sqrt(h) : -Sqrt(h);
if (fabs(g) <= EPS)
{
Done = Standard_False;
return;
}
h -= f * g; // = (v*v)/2 = C1
alfaii = g - f; // = v = ALFAII
for (j = i + 1; j <= n; j++)
{
Standard_Real scale = 0.0;
for (k = i; k <= l; k++)
{
scale += Q(k, i) * Q(k, j); // = SCAL
}
cj = (g * Q(i, j) - scale) / h;
Q(i, j) = Q(i, j) - alfaii * cj;
for (k = i + 1; k <= l; k++)
{
Q(k, j) = Q(k, j) + cj * Q(k, i);
}
}
// Modification de B:
for (j = 1; j <= m; j++)
{
Standard_Real scale = Q(i, i) * B2(i, j);
for (k = i + 1; k <= l; k++)
{
scale += Q(k, i) * B2(k, j);
}
cj = (g * B2(i, j) - scale) / h;
B2(i, j) = B2(i, j) - cj * alfaii;
for (k = i + 1; k <= l; k++)
{
B2(k, j) = B2(k, j) + cj * Q(k, i);
}
}
Q(i, i) = g;
}
// Remontee:
for (j = 1; j <= m; j++) {
Sol(n,j) = B2(n,j)/Q(n,n);
for (i = n -1; i >=1; i--) {
Standard_Real scale= 0.0;
for(k = i+1; k <= n; k++) {
scale += Q(i,k) * Sol(k,j);
for (j = 1; j <= m; j++)
{
Sol(n, j) = B2(n, j) / Q(n, n);
for (i = n - 1; i >= 1; i--)
{
Standard_Real scale = 0.0;
for (k = i + 1; k <= n; k++)
{
scale += Q(i, k) * Sol(k, j);
}
Sol(i,j) = (B2(i,j) - scale)/Q(i,i);
Sol(i, j) = (B2(i, j) - scale) / Q(i, i);
}
}
Done = Standard_True;
}
void math_Householder::Dump(Standard_OStream& o) const
{
void math_Householder::Dump(Standard_OStream& o) const {
o <<"math_Householder ";
if (Done) {
o << " Status = Done \n";
}
else {
o << "Status = not Done \n";
}
o << "math_Householder ";
if (Done)
{
o << " Status = Done \n";
}
else
{
o << "Status = not Done \n";
}
}

View File

@@ -25,7 +25,6 @@
#include <math_Vector.hxx>
#include <Standard_OStream.hxx>
//! This class implements the least square solution of a set of
//! linear equations of m unknowns (n >= m) using the Householder
//! method. It solves A.X = B.
@@ -35,13 +34,11 @@
//! It is about 16% longer than GaussLeastSquare if there is only
//! one member B to solve.
//! It is about 30% longer if there are twenty B members to solve.
class math_Householder
class math_Householder
{
public:
DEFINE_STANDARD_ALLOC
//! Given an input matrix A with n>= m, given an input matrix B
//! this constructor performs the least square resolution of
//! the set of linear equations A.X = B for each column of B.
@@ -49,8 +46,10 @@ public:
//! be done.
//! Exception DimensionError is raised if the row number of B
//! is different from the A row number.
Standard_EXPORT math_Householder(const math_Matrix& A, const math_Matrix& B, const Standard_Real EPS = 1.0e-20);
Standard_EXPORT math_Householder(const math_Matrix& A,
const math_Matrix& B,
const Standard_Real EPS = 1.0e-20);
//! Given an input matrix A with n>= m, given an input matrix B
//! this constructor performs the least square resolution of
//! the set of linear equations A.X = B for each column of B.
@@ -58,8 +57,14 @@ public:
//! be done.
//! Exception DimensionError is raised if the row number of B
//! is different from the A row number.
Standard_EXPORT math_Householder(const math_Matrix& A, const math_Matrix& B, const Standard_Integer lowerArow, const Standard_Integer upperArow, const Standard_Integer lowerAcol, const Standard_Integer upperAcol, const Standard_Real EPS = 1.0e-20);
Standard_EXPORT math_Householder(const math_Matrix& A,
const math_Matrix& B,
const Standard_Integer lowerArow,
const Standard_Integer upperArow,
const Standard_Integer lowerAcol,
const Standard_Integer upperAcol,
const Standard_Real EPS = 1.0e-20);
//! Given an input matrix A with n>= m, given an input vector B
//! this constructor performs the least square resolution of
//! the set of linear equations A.X = B.
@@ -67,61 +72,45 @@ public:
//! be done.
//! Exception DimensionError is raised if the length of B
//! is different from the A row number.
Standard_EXPORT math_Householder(const math_Matrix& A, const math_Vector& B, const Standard_Real EPS = 1.0e-20);
Standard_EXPORT math_Householder(const math_Matrix& A,
const math_Vector& B,
const Standard_Real EPS = 1.0e-20);
//! Returns true if the computations are successful, otherwise returns false.
Standard_Boolean IsDone() const;
Standard_Boolean IsDone() const;
//! Given the integer Index, this routine returns the
//! corresponding least square solution sol.
//! Exception NotDone is raised if the resolution has not be
//! done.
//! Exception OutOfRange is raised if Index <=0 or
//! Index is more than the number of columns of B.
void Value (math_Vector& sol, const Standard_Integer Index = 1) const;
void Value(math_Vector& sol, const Standard_Integer Index = 1) const;
//! Returns the matrix sol of all the solutions of the system
//! A.X = B.
//! Exception NotDone is raised is the resolution has not be
//! done.
const math_Matrix& AllValues() const;
const math_Matrix& AllValues() const;
//! Prints information on the current state of the object.
Standard_EXPORT void Dump (Standard_OStream& o) const;
Standard_EXPORT void Dump(Standard_OStream& o) const;
protected:
//! This method is used internally for each constructor
//! above and can't be used directly.
Standard_EXPORT void Perform (const math_Matrix& A, const math_Matrix& B, const Standard_Real EPS);
Standard_EXPORT void Perform(const math_Matrix& A, const math_Matrix& B, const Standard_Real EPS);
private:
math_Matrix Sol;
math_Matrix Q;
math_Matrix Sol;
math_Matrix Q;
Standard_Boolean Done;
Standard_Integer mylowerArow;
Standard_Integer myupperArow;
Standard_Integer mylowerAcol;
Standard_Integer myupperAcol;
};
#include <math_Householder.lxx>
#endif // _math_Householder_HeaderFile

View File

@@ -14,31 +14,26 @@
#include <StdFail_NotDone.hxx>
inline Standard_Boolean math_Householder::IsDone() const
{
return Done;
}
inline Standard_Boolean math_Householder::IsDone() const {return Done; }
inline Standard_OStream& operator<<(Standard_OStream& o,
const math_Householder& H)
inline Standard_OStream& operator<<(Standard_OStream& o, const math_Householder& H)
{
H.Dump(o);
return o;
}
inline void math_Householder::Value(math_Vector& sol,
const Standard_Integer Index) const {
inline void math_Householder::Value(math_Vector& sol, const Standard_Integer Index) const
{
StdFail_NotDone_Raise_if(!Done, " ");
Standard_OutOfRange_Raise_if((Index<1) || (Index>Sol.ColNumber()), " ");
Standard_OutOfRange_Raise_if((Index < 1) || (Index > Sol.ColNumber()), " ");
sol = Sol.Col(Index);
}
inline const math_Matrix& math_Householder::AllValues() const {
inline const math_Matrix& math_Householder::AllValues() const
{
StdFail_NotDone_Raise_if(!Done, " ");
return Sol;
}

View File

@@ -49,4 +49,3 @@
using math_IntegerVector = math_VectorBase<int>;
#endif

View File

@@ -12,47 +12,49 @@
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
//#ifndef OCCT_DEBUG
// #ifndef OCCT_DEBUG
#define No_Standard_RangeError
#define No_Standard_OutOfRange
#define No_Standard_DimensionError
//#endif
// #endif
#include <math_Jacobi.hxx>
#include <math_Matrix.hxx>
#include <math_NotSquare.hxx>
#include <math_Recipes.hxx>
math_Jacobi::math_Jacobi(const math_Matrix& A) : AA(1, A.RowNumber(),
1, A.RowNumber()),
EigenValues(1, A.RowNumber()),
EigenVectors(1, A.RowNumber(),
1, A.RowNumber()) {
math_Jacobi::math_Jacobi(const math_Matrix& A)
: AA(1, A.RowNumber(), 1, A.RowNumber()),
EigenValues(1, A.RowNumber()),
EigenVectors(1, A.RowNumber(), 1, A.RowNumber())
{
math_NotSquare_Raise_if(A.RowNumber() != A.ColNumber(), " ");
math_NotSquare_Raise_if(A.RowNumber() != A.ColNumber(), " ");
AA = A;
Standard_Integer Error = Jacobi(AA, EigenValues, EigenVectors, NbRotations);
if(!Error) {
Done = Standard_True;
}
else {
Done = Standard_False;
}
AA = A;
Standard_Integer Error = Jacobi(AA, EigenValues, EigenVectors, NbRotations);
if (!Error)
{
Done = Standard_True;
}
else
{
Done = Standard_False;
}
void math_Jacobi::Dump(Standard_OStream& o) const {
o <<"math_Jacobi ";
if (Done) {
o << " Status = Done \n";
o << " The eigenvalues vector is: " << EigenValues << std::endl;
}
else {
o << "Status = not Done \n";
}
}
void math_Jacobi::Dump(Standard_OStream& o) const
{
o << "math_Jacobi ";
if (Done)
{
o << " Status = Done \n";
o << " The eigenvalues vector is: " << EigenValues << std::endl;
}
else
{
o << "Status = not Done \n";
}
}

View File

@@ -25,77 +25,54 @@
#include <math_Vector.hxx>
#include <Standard_OStream.hxx>
//! This class implements the Jacobi method to find the eigenvalues and
//! the eigenvectors of a real symmetric square matrix.
//! A sort of eigenvalues is done.
class math_Jacobi
class math_Jacobi
{
public:
DEFINE_STANDARD_ALLOC
//! Given a Real n X n matrix A, this constructor computes all its
//! eigenvalues and eigenvectors using the Jacobi method.
//! The exception NotSquare is raised if the matrix is not square.
//! No verification that the matrix A is really symmetric is done.
Standard_EXPORT math_Jacobi(const math_Matrix& A);
//! Returns true if the computations are successful, otherwise returns false.
Standard_Boolean IsDone() const;
Standard_Boolean IsDone() const;
//! Returns the eigenvalues vector.
//! Exception NotDone is raised if calculation is not done successfully.
const math_Vector& Values() const;
const math_Vector& Values() const;
//! returns the eigenvalue number Num.
//! Eigenvalues are in the range (1..n).
//! Exception NotDone is raised if calculation is not done successfully.
Standard_Real Value (const Standard_Integer Num) const;
Standard_Real Value(const Standard_Integer Num) const;
//! returns the eigenvectors matrix.
//! Exception NotDone is raised if calculation is not done successfully.
const math_Matrix& Vectors() const;
const math_Matrix& Vectors() const;
//! Returns the eigenvector V of number Num.
//! Eigenvectors are in the range (1..n).
//! Exception NotDone is raised if calculation is not done successfully.
void Vector (const Standard_Integer Num, math_Vector& V) const;
void Vector(const Standard_Integer Num, math_Vector& V) const;
//! Prints information on the current state of the object.
//! Is used to redefine the operator <<.
Standard_EXPORT void Dump (Standard_OStream& o) const;
Standard_EXPORT void Dump(Standard_OStream& o) const;
protected:
private:
Standard_Boolean Done;
math_Matrix AA;
math_Matrix AA;
Standard_Integer NbRotations;
math_Vector EigenValues;
math_Matrix EigenVectors;
math_Vector EigenValues;
math_Matrix EigenVectors;
};
#include <math_Jacobi.lxx>
#endif // _math_Jacobi_HeaderFile

View File

@@ -18,35 +18,37 @@
#include <math_Vector.hxx>
#include <math_Matrix.hxx>
inline Standard_Boolean math_Jacobi::IsDone() const { return Done; }
inline Standard_Boolean math_Jacobi::IsDone() const
{
return Done;
}
inline Standard_OStream& operator<<(Standard_OStream& o,
const math_Jacobi& J)
inline Standard_OStream& operator<<(Standard_OStream& o, const math_Jacobi& J)
{
J.Dump(o);
return o;
}
inline const math_Vector& math_Jacobi::Values () const{
inline const math_Vector& math_Jacobi::Values() const
{
StdFail_NotDone_Raise_if(!Done, " ");
return EigenValues;
}
inline Standard_Real math_Jacobi::Value (const Standard_Integer Num) const{
inline Standard_Real math_Jacobi::Value(const Standard_Integer Num) const
{
StdFail_NotDone_Raise_if(!Done, " ");
return EigenValues(Num);
}
inline const math_Matrix& math_Jacobi::Vectors() const{
inline const math_Matrix& math_Jacobi::Vectors() const
{
StdFail_NotDone_Raise_if(!Done, " ");
return EigenVectors;
}
inline void math_Jacobi::Vector (const Standard_Integer Num, math_Vector& V) const{
inline void math_Jacobi::Vector(const Standard_Integer Num, math_Vector& V) const
{
StdFail_NotDone_Raise_if(!Done, " ");
V = EigenVectors.Col(Num);
}

File diff suppressed because it is too large Load Diff

View File

@@ -13,7 +13,6 @@
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <math.hxx>
#include <math_Function.hxx>
#include <math_KronrodSingleIntegration.hxx>
@@ -21,157 +20,166 @@
#include <TColStd_SequenceOfReal.hxx>
//==========================================================================
//function : An empty constructor.
// function : An empty constructor.
//==========================================================================
math_KronrodSingleIntegration::math_KronrodSingleIntegration() :
myIsDone(Standard_False),
myValue(0.),
myErrorReached(0.),
myNbPntsReached(0),
myNbIterReached(0)
math_KronrodSingleIntegration::math_KronrodSingleIntegration()
: myIsDone(Standard_False),
myValue(0.),
myErrorReached(0.),
myNbPntsReached(0),
myNbIterReached(0)
{
}
//==========================================================================
//function : Constructor
//
// function : Constructor
//
//==========================================================================
math_KronrodSingleIntegration::math_KronrodSingleIntegration
( math_Function &theFunction,
const Standard_Real theLower,
const Standard_Real theUpper,
const Standard_Integer theNbPnts):
myIsDone(Standard_False),
myValue(0.),
myErrorReached(0.),
myNbPntsReached(0)
math_KronrodSingleIntegration::math_KronrodSingleIntegration(math_Function& theFunction,
const Standard_Real theLower,
const Standard_Real theUpper,
const Standard_Integer theNbPnts)
: myIsDone(Standard_False),
myValue(0.),
myErrorReached(0.),
myNbPntsReached(0)
{
Perform(theFunction, theLower, theUpper, theNbPnts);
}
//==========================================================================
//function : Constructor
//
// function : Constructor
//
//==========================================================================
math_KronrodSingleIntegration::math_KronrodSingleIntegration
( math_Function &theFunction,
const Standard_Real theLower,
const Standard_Real theUpper,
const Standard_Integer theNbPnts,
const Standard_Real theTolerance,
const Standard_Integer theMaxNbIter) :
myIsDone(Standard_False),
myValue(0.),
myErrorReached(0.),
myNbPntsReached(0)
math_KronrodSingleIntegration::math_KronrodSingleIntegration(math_Function& theFunction,
const Standard_Real theLower,
const Standard_Real theUpper,
const Standard_Integer theNbPnts,
const Standard_Real theTolerance,
const Standard_Integer theMaxNbIter)
: myIsDone(Standard_False),
myValue(0.),
myErrorReached(0.),
myNbPntsReached(0)
{
Perform(theFunction, theLower, theUpper, theNbPnts,
theTolerance, theMaxNbIter);
Perform(theFunction, theLower, theUpper, theNbPnts, theTolerance, theMaxNbIter);
}
//==========================================================================
//function : Perform
// function : Perform
// Computation of the integral.
//==========================================================================
void math_KronrodSingleIntegration::Perform
( math_Function &theFunction,
const Standard_Real theLower,
const Standard_Real theUpper,
const Standard_Integer theNbPnts)
void math_KronrodSingleIntegration::Perform(math_Function& theFunction,
const Standard_Real theLower,
const Standard_Real theUpper,
const Standard_Integer theNbPnts)
{
//const Standard_Real aMinVol = Epsilon(1.);
// const Standard_Real aMinVol = Epsilon(1.);
const Standard_Real aPtol = 1.e-9;
myNbIterReached = 0;
myNbIterReached = 0;
if (theNbPnts < 3 ) {
if (theNbPnts < 3)
{
myIsDone = Standard_False;
return;
}
if(theUpper - theLower < aPtol) {
if (theUpper - theLower < aPtol)
{
myIsDone = Standard_False;
return;
}
// Get an odd value of number of initial points.
myNbPntsReached = (theNbPnts%2 == 0) ? theNbPnts + 1 : theNbPnts;
myNbPntsReached = (theNbPnts % 2 == 0) ? theNbPnts + 1 : theNbPnts;
myErrorReached = RealLast();
Standard_Integer aNGauss = myNbPntsReached/2;
Standard_Integer aNGauss = myNbPntsReached / 2;
math_Vector aKronrodP(1, myNbPntsReached);
math_Vector aKronrodW(1, myNbPntsReached);
math_Vector aGaussP(1, aNGauss);
math_Vector aGaussW(1, aNGauss);
if (!math::KronrodPointsAndWeights(myNbPntsReached, aKronrodP, aKronrodW) ||
!math::OrderedGaussPointsAndWeights(aNGauss, aGaussP, aGaussW)) {
if (!math::KronrodPointsAndWeights(myNbPntsReached, aKronrodP, aKronrodW)
|| !math::OrderedGaussPointsAndWeights(aNGauss, aGaussP, aGaussW))
{
myIsDone = Standard_False;
return;
}
myIsDone = GKRule(theFunction, theLower, theUpper, aGaussP, aGaussW, aKronrodP, aKronrodW,
myValue, myErrorReached);
myIsDone = GKRule(theFunction,
theLower,
theUpper,
aGaussP,
aGaussW,
aKronrodP,
aKronrodW,
myValue,
myErrorReached);
if(!myIsDone) return;
if (!myIsDone)
return;
//Standard_Real anAbsVal = Abs(myValue);
// Standard_Real anAbsVal = Abs(myValue);
myAbsolutError = myErrorReached;
//if (anAbsVal > aMinVol)
//myErrorReached /= anAbsVal;
myNbIterReached++;
// if (anAbsVal > aMinVol)
// myErrorReached /= anAbsVal;
myNbIterReached++;
}
//=======================================================================
//function : Perform
//=================================================================================================
//purpose :
//=======================================================================
void math_KronrodSingleIntegration::Perform
( math_Function &theFunction,
const Standard_Real theLower,
const Standard_Real theUpper,
const Standard_Integer theNbPnts,
const Standard_Real theTolerance,
const Standard_Integer theMaxNbIter)
void math_KronrodSingleIntegration::Perform(math_Function& theFunction,
const Standard_Real theLower,
const Standard_Real theUpper,
const Standard_Integer theNbPnts,
const Standard_Real theTolerance,
const Standard_Integer theMaxNbIter)
{
Standard_Real aMinVol = Epsilon(1.);
myNbIterReached = 0;
myNbIterReached = 0;
// Check prerequisites.
if (theNbPnts < 3 ||
theTolerance <= 0.) {
if (theNbPnts < 3 || theTolerance <= 0.)
{
myIsDone = Standard_False;
return;
}
// Get an odd value of number of initial points.
myNbPntsReached = (theNbPnts%2 == 0) ? theNbPnts + 1 : theNbPnts;
myNbPntsReached = (theNbPnts % 2 == 0) ? theNbPnts + 1 : theNbPnts;
Standard_Integer aNGauss = myNbPntsReached/2;
Standard_Integer aNGauss = myNbPntsReached / 2;
math_Vector aKronrodP(1, myNbPntsReached);
math_Vector aKronrodW(1, myNbPntsReached);
math_Vector aGaussP(1, aNGauss);
math_Vector aGaussW(1, aNGauss);
if (!math::KronrodPointsAndWeights(myNbPntsReached, aKronrodP, aKronrodW) ||
!math::OrderedGaussPointsAndWeights(aNGauss, aGaussP, aGaussW)) {
if (!math::KronrodPointsAndWeights(myNbPntsReached, aKronrodP, aKronrodW)
|| !math::OrderedGaussPointsAndWeights(aNGauss, aGaussP, aGaussW))
{
myIsDone = Standard_False;
return;
}
//First iteration
myIsDone = GKRule(theFunction, theLower, theUpper, aGaussP, aGaussW, aKronrodP, aKronrodW,
myValue, myErrorReached);
// First iteration
myIsDone = GKRule(theFunction,
theLower,
theUpper,
aGaussP,
aGaussW,
aKronrodP,
aKronrodW,
myValue,
myErrorReached);
if(!myIsDone) return;
if (!myIsDone)
return;
Standard_Real anAbsVal = Abs(myValue);
@@ -181,8 +189,10 @@ void math_KronrodSingleIntegration::Perform
myNbIterReached++;
if(myErrorReached <= theTolerance) return;
if(myNbIterReached >= theMaxNbIter) return;
if (myErrorReached <= theTolerance)
return;
if (myNbIterReached >= theMaxNbIter)
return;
TColStd_SequenceOfReal anIntervals;
TColStd_SequenceOfReal anErrors;
@@ -191,173 +201,177 @@ void math_KronrodSingleIntegration::Perform
anIntervals.Append(theLower);
anIntervals.Append(theUpper);
anErrors.Append(myAbsolutError);
aValues.Append(myValue);
Standard_Integer i, nint, nbints;
Standard_Real maxerr;
Standard_Real maxerr;
Standard_Integer count = 0;
while(myErrorReached > theTolerance && myNbIterReached < theMaxNbIter) {
//Searching interval with max error
while (myErrorReached > theTolerance && myNbIterReached < theMaxNbIter)
{
// Searching interval with max error
nbints = anIntervals.Length() - 1;
nint = 0;
nint = 0;
maxerr = 0.;
for(i = 1; i <= nbints; ++i) {
if(anErrors(i) > maxerr) {
maxerr = anErrors(i);
nint = i;
for (i = 1; i <= nbints; ++i)
{
if (anErrors(i) > maxerr)
{
maxerr = anErrors(i);
nint = i;
}
}
Standard_Real a = anIntervals(nint);
Standard_Real b = anIntervals(nint+1);
Standard_Real c = 0.5*(a + b);
Standard_Real b = anIntervals(nint + 1);
Standard_Real c = 0.5 * (a + b);
Standard_Real v1, v2, e1, e2;
myIsDone = GKRule(theFunction, a, c, aGaussP, aGaussW, aKronrodP, aKronrodW,
v1, e1);
if(!myIsDone) return;
myIsDone = GKRule(theFunction, a, c, aGaussP, aGaussW, aKronrodP, aKronrodW, v1, e1);
if (!myIsDone)
return;
myIsDone = GKRule(theFunction, c, b, aGaussP, aGaussW, aKronrodP, aKronrodW, v2, e2);
if (!myIsDone)
return;
myIsDone = GKRule(theFunction, c, b, aGaussP, aGaussW, aKronrodP, aKronrodW,
v2, e2);
if(!myIsDone) return;
myNbIterReached++;
Standard_Real deltav = v1 + v2 - aValues(nint);
myValue += deltav;
if(Abs(deltav) <= Epsilon(Abs(myValue))) ++count;
if (Abs(deltav) <= Epsilon(Abs(myValue)))
++count;
Standard_Real deltae = e1 + e2 - anErrors(nint);
myAbsolutError += deltae;
if(myAbsolutError <= Epsilon(Abs(myValue))) ++count;
if(Abs(myValue) > aMinVol) myErrorReached = myAbsolutError/Abs(myValue);
else myErrorReached = myAbsolutError;
myAbsolutError += deltae;
if (myAbsolutError <= Epsilon(Abs(myValue)))
++count;
if (Abs(myValue) > aMinVol)
myErrorReached = myAbsolutError / Abs(myValue);
else
myErrorReached = myAbsolutError;
if (count > 50)
return;
// Inserting new interval
if(count > 50) return;
//Inserting new interval
anIntervals.InsertAfter(nint, c);
anErrors(nint) = e1;
anErrors.InsertAfter(nint, e2);
aValues(nint) = v1;
aValues.InsertAfter(nint, v2);
}
}
//=======================================================================
//function : GKRule
//purpose :
//=======================================================================
//=================================================================================================
Standard_Boolean math_KronrodSingleIntegration::GKRule(
math_Function &theFunction,
const Standard_Real theLower,
const Standard_Real theUpper,
const math_Vector& /*theGaussP*/,
const math_Vector& theGaussW,
const math_Vector& theKronrodP,
const math_Vector& theKronrodW,
Standard_Real& theValue,
Standard_Real& theError)
Standard_Boolean math_KronrodSingleIntegration::GKRule(math_Function& theFunction,
const Standard_Real theLower,
const Standard_Real theUpper,
const math_Vector& /*theGaussP*/,
const math_Vector& theGaussW,
const math_Vector& theKronrodP,
const math_Vector& theKronrodW,
Standard_Real& theValue,
Standard_Real& theError)
{
Standard_Boolean IsDone;
Standard_Integer aNKronrod = theKronrodP.Length();
Standard_Real aGaussVal;
Standard_Integer aNPnt2 = (aNKronrod + 1)/2;
Standard_Integer aNPnt2 = (aNKronrod + 1) / 2;
Standard_Integer i;
Standard_Real aDx;
Standard_Real aVal1;
Standard_Real aVal2;
math_Vector f1(1, aNPnt2-1);
math_Vector f2(1, aNPnt2-1);
math_Vector f1(1, aNPnt2 - 1);
math_Vector f2(1, aNPnt2 - 1);
Standard_Real aXm = 0.5*(theUpper + theLower);
Standard_Real aXr = 0.5*(theUpper - theLower);
Standard_Real aXm = 0.5 * (theUpper + theLower);
Standard_Real aXr = 0.5 * (theUpper - theLower);
// Compute Gauss quadrature
aGaussVal = 0.;
theValue = 0.;
for (i = 2; i < aNPnt2; i += 2) {
aDx = aXr*theKronrodP.Value(i);
if (!theFunction.Value(aXm + aDx, aVal1) ||
!theFunction.Value(aXm - aDx, aVal2)) {
theValue = 0.;
for (i = 2; i < aNPnt2; i += 2)
{
aDx = aXr * theKronrodP.Value(i);
if (!theFunction.Value(aXm + aDx, aVal1) || !theFunction.Value(aXm - aDx, aVal2))
{
IsDone = Standard_False;
return IsDone;
}
f1(i) = aVal1;
f2(i) = aVal2;
aGaussVal += (aVal1 + aVal2)*theGaussW.Value(i/2);
theValue += (aVal1 + aVal2)*theKronrodW.Value(i);
aGaussVal += (aVal1 + aVal2) * theGaussW.Value(i / 2);
theValue += (aVal1 + aVal2) * theKronrodW.Value(i);
}
// Compute value in the middle point.
if (!theFunction.Value(aXm, aVal1)) {
if (!theFunction.Value(aXm, aVal1))
{
IsDone = Standard_False;
return IsDone;
}
Standard_Real fc = aVal1;
theValue += aVal1*theKronrodW.Value(aNPnt2);
theValue += aVal1 * theKronrodW.Value(aNPnt2);
if (i == aNPnt2)
aGaussVal += aVal1*theGaussW.Value(aNPnt2/2);
aGaussVal += aVal1 * theGaussW.Value(aNPnt2 / 2);
// Compute Kronrod quadrature
for (i = 1; i < aNPnt2; i += 2) {
aDx = aXr*theKronrodP.Value(i);
if (!theFunction.Value(aXm + aDx, aVal1) ||
!theFunction.Value(aXm - aDx, aVal2)) {
for (i = 1; i < aNPnt2; i += 2)
{
aDx = aXr * theKronrodP.Value(i);
if (!theFunction.Value(aXm + aDx, aVal1) || !theFunction.Value(aXm - aDx, aVal2))
{
IsDone = Standard_False;
return IsDone;
}
f1(i) = aVal1;
f2(i) = aVal2;
theValue += (aVal1 + aVal2)*theKronrodW.Value(i);
theValue += (aVal1 + aVal2) * theKronrodW.Value(i);
}
Standard_Real mean = 0.5*theValue;
Standard_Real asc = Abs(fc-mean)*theKronrodW.Value(aNPnt2);
for(i = 1; i < aNPnt2; ++i) {
asc += theKronrodW.Value(i)*(Abs(f1(i) - mean) + Abs(f2(i) - mean));
Standard_Real mean = 0.5 * theValue;
Standard_Real asc = Abs(fc - mean) * theKronrodW.Value(aNPnt2);
for (i = 1; i < aNPnt2; ++i)
{
asc += theKronrodW.Value(i) * (Abs(f1(i) - mean) + Abs(f2(i) - mean));
}
asc *= aXr;
theValue *= aXr;
theValue *= aXr;
aGaussVal *= aXr;
// Compute the error and the new number of Kronrod points.
theError = Abs(theValue - aGaussVal);
Standard_Real scale =1.;
if(asc != 0. && theError != 0.) scale = Pow((200.*theError/asc), 1.5);
if(scale < 1.) theError = Min(theError, asc*scale);
//theFunction.GetStateNumber();
Standard_Real scale = 1.;
if (asc != 0. && theError != 0.)
scale = Pow((200. * theError / asc), 1.5);
if (scale < 1.)
theError = Min(theError, asc * scale);
// theFunction.GetStateNumber();
return Standard_True;
}

View File

@@ -23,36 +23,44 @@
#include <math_Vector.hxx>
class math_Function;
//! This class implements the Gauss-Kronrod method of
//! integral computation.
class math_KronrodSingleIntegration
class math_KronrodSingleIntegration
{
public:
DEFINE_STANDARD_ALLOC
//! An empty constructor.
Standard_EXPORT math_KronrodSingleIntegration();
//! Constructor. Takes the function, the lower and upper bound
//! values, the initial number of Kronrod points
Standard_EXPORT math_KronrodSingleIntegration(math_Function& theFunction, const Standard_Real theLower, const Standard_Real theUpper, const Standard_Integer theNbPnts);
Standard_EXPORT math_KronrodSingleIntegration(math_Function& theFunction,
const Standard_Real theLower,
const Standard_Real theUpper,
const Standard_Integer theNbPnts);
//! Constructor. Takes the function, the lower and upper bound
//! values, the initial number of Kronrod points, the
//! tolerance value and the maximal number of iterations as
//! parameters.
Standard_EXPORT math_KronrodSingleIntegration(math_Function& theFunction, const Standard_Real theLower, const Standard_Real theUpper, const Standard_Integer theNbPnts, const Standard_Real theTolerance, const Standard_Integer theMaxNbIter);
Standard_EXPORT math_KronrodSingleIntegration(math_Function& theFunction,
const Standard_Real theLower,
const Standard_Real theUpper,
const Standard_Integer theNbPnts,
const Standard_Real theTolerance,
const Standard_Integer theMaxNbIter);
//! Computation of the integral. Takes the function,
//! the lower and upper bound values, the initial number
//! of Kronrod points, the relative tolerance value and the
//! maximal number of iterations as parameters.
//! theNbPnts should be odd and greater then or equal to 3.
Standard_EXPORT void Perform (math_Function& theFunction, const Standard_Real theLower, const Standard_Real theUpper, const Standard_Integer theNbPnts);
Standard_EXPORT void Perform(math_Function& theFunction,
const Standard_Real theLower,
const Standard_Real theUpper,
const Standard_Integer theNbPnts);
//! Computation of the integral. Takes the function,
//! the lower and upper bound values, the initial number
//! of Kronrod points, the relative tolerance value and the
@@ -62,59 +70,54 @@ public:
//! solution reaching is:
//! Abs(Kronrod - Gauss)/Abs(Kronrod) < theTolerance.
//! theTolerance should be positive.
Standard_EXPORT void Perform (math_Function& theFunction, const Standard_Real theLower, const Standard_Real theUpper, const Standard_Integer theNbPnts, const Standard_Real theTolerance, const Standard_Integer theMaxNbIter);
Standard_EXPORT void Perform(math_Function& theFunction,
const Standard_Real theLower,
const Standard_Real theUpper,
const Standard_Integer theNbPnts,
const Standard_Real theTolerance,
const Standard_Integer theMaxNbIter);
//! Returns Standard_True if computation is performed
//! successfully.
Standard_Boolean IsDone() const;
Standard_Boolean IsDone() const;
//! Returns the value of the integral.
Standard_Real Value() const;
Standard_Real Value() const;
//! Returns the value of the relative error reached.
Standard_Real ErrorReached() const;
Standard_Real ErrorReached() const;
//! Returns the value of the relative error reached.
Standard_Real AbsolutError() const;
Standard_Real AbsolutError() const;
//! Returns the number of Kronrod points
//! for which the result is computed.
Standard_Integer OrderReached() const;
Standard_Integer OrderReached() const;
//! Returns the number of iterations
//! that were made to compute result.
Standard_Integer NbIterReached() const;
Standard_EXPORT static Standard_Boolean GKRule (math_Function& theFunction, const Standard_Real theLower, const Standard_Real theUpper, const math_Vector& theGaussP, const math_Vector& theGaussW, const math_Vector& theKronrodP, const math_Vector& theKronrodW, Standard_Real& theValue, Standard_Real& theError);
Standard_Integer NbIterReached() const;
Standard_EXPORT static Standard_Boolean GKRule(math_Function& theFunction,
const Standard_Real theLower,
const Standard_Real theUpper,
const math_Vector& theGaussP,
const math_Vector& theGaussW,
const math_Vector& theKronrodP,
const math_Vector& theKronrodW,
Standard_Real& theValue,
Standard_Real& theError);
protected:
private:
Standard_Boolean myIsDone;
Standard_Real myValue;
Standard_Real myErrorReached;
Standard_Real myAbsolutError;
Standard_Real myValue;
Standard_Real myErrorReached;
Standard_Real myAbsolutError;
Standard_Integer myNbPntsReached;
Standard_Integer myNbIterReached;
};
#include <math_KronrodSingleIntegration.lxx>
#endif // _math_KronrodSingleIntegration_HeaderFile

View File

@@ -16,17 +16,17 @@
#include <StdFail_NotDone.hxx>
//==========================================================================
//function : IsDone
// function : IsDone
// Returns Standard_True if computation is performed successfully.
//==========================================================================
inline Standard_Boolean math_KronrodSingleIntegration::IsDone() const
inline Standard_Boolean math_KronrodSingleIntegration::IsDone() const
{
return myIsDone;
}
//==========================================================================
//function : Value
// function : Value
// Returns the value of the integral.
//==========================================================================
@@ -37,7 +37,7 @@ inline Standard_Real math_KronrodSingleIntegration::Value() const
}
//==========================================================================
//function : ErrorReached
// function : ErrorReached
// Returns the value of the relative error reached.
//==========================================================================
@@ -48,8 +48,8 @@ inline Standard_Real math_KronrodSingleIntegration::ErrorReached() const
}
//=======================================================================
//function : AbsolutError
//purpose :
// function : AbsolutError
// purpose :
//=======================================================================
inline Standard_Real math_KronrodSingleIntegration::AbsolutError() const
@@ -57,9 +57,9 @@ inline Standard_Real math_KronrodSingleIntegration::AbsolutError() const
StdFail_NotDone_Raise_if(!myIsDone, "math_KronrodSingleIntegration");
return myAbsolutError;
}
//==========================================================================
//function : OrderReached
// function : OrderReached
// Returns the number of Kronrod points for which the result
// is computed.
//==========================================================================
@@ -71,7 +71,7 @@ inline Standard_Integer math_KronrodSingleIntegration::OrderReached() const
}
//==========================================================================
//function : NbIterReached
// function : NbIterReached
// Returns the number of iterations that were made to compute result.
//==========================================================================

File diff suppressed because it is too large Load Diff

View File

@@ -29,7 +29,8 @@
#undef Opposite
#endif
template<typename T = double> class math_VectorBase;
template <typename T = double>
class math_VectorBase;
//! This class implements the real matrix abstract data type.
//! Matrixes can have an arbitrary range which must be defined
@@ -73,7 +74,6 @@ template<typename T = double> class math_VectorBase;
class math_Matrix
{
public:
DEFINE_STANDARD_ALLOC
friend class math_VectorBase<>;
@@ -85,24 +85,35 @@ public:
//! lower and upper bounds of a row, and
//! - LowerCol and UpperCol are the indexes of the
//! lower and upper bounds of a column.
Standard_EXPORT math_Matrix(const Standard_Integer LowerRow, const Standard_Integer UpperRow, const Standard_Integer LowerCol, const Standard_Integer UpperCol);
Standard_EXPORT math_Matrix(const Standard_Integer LowerRow,
const Standard_Integer UpperRow,
const Standard_Integer LowerCol,
const Standard_Integer UpperCol);
//! constructs a non-initialized matrix of range [LowerRow..UpperRow,
//! LowerCol..UpperCol]
//! whose values are all initialized with the value InitialValue.
Standard_EXPORT math_Matrix(const Standard_Integer LowerRow, const Standard_Integer UpperRow, const Standard_Integer LowerCol, const Standard_Integer UpperCol, const Standard_Real InitialValue);
Standard_EXPORT math_Matrix(const Standard_Integer LowerRow,
const Standard_Integer UpperRow,
const Standard_Integer LowerCol,
const Standard_Integer UpperCol,
const Standard_Real InitialValue);
//! constructs a matrix of range [LowerRow..UpperRow,
//! LowerCol..UpperCol]
//! Sharing data with a "C array" pointed by Tab.
Standard_EXPORT math_Matrix(const Standard_Address Tab, const Standard_Integer LowerRow, const Standard_Integer UpperRow, const Standard_Integer LowerCol, const Standard_Integer UpperCol);
Standard_EXPORT math_Matrix(const Standard_Address Tab,
const Standard_Integer LowerRow,
const Standard_Integer UpperRow,
const Standard_Integer LowerCol,
const Standard_Integer UpperCol);
//! constructs a matrix for copy in initialization.
//! An exception is raised if the matrixes have not the same dimensions.
Standard_EXPORT math_Matrix(const math_Matrix& Other);
//! Initialize all the elements of a matrix to InitialValue.
Standard_EXPORT void Init (const Standard_Real InitialValue);
Standard_EXPORT void Init(const Standard_Real InitialValue);
//! Returns the number of rows of this matrix.
//! Note that for a matrix A you always have the following relations:
@@ -111,7 +122,7 @@ public:
//! - the length of a row of A is equal to the number of columns of A,
//! - the length of a column of A is equal to the number of
//! rows of A.returns the row range of a matrix.
Standard_Integer RowNumber() const;
Standard_Integer RowNumber() const;
//! Returns the number of rows of this matrix.
//! Note that for a matrix A you always have the following relations:
@@ -120,23 +131,23 @@ public:
//! - the length of a row of A is equal to the number of columns of A,
//! - the length of a column of A is equal to the number of
//! rows of A.returns the row range of a matrix.
Standard_Integer ColNumber() const;
Standard_Integer ColNumber() const;
//! Returns the value of the Lower index of the row
//! range of a matrix.
Standard_Integer LowerRow() const;
Standard_Integer LowerRow() const;
//! Returns the Upper index of the row range
//! of a matrix.
Standard_Integer UpperRow() const;
Standard_Integer UpperRow() const;
//! Returns the value of the Lower index of the
//! column range of a matrix.
Standard_Integer LowerCol() const;
Standard_Integer LowerCol() const;
//! Returns the value of the upper index of the
//! column range of a matrix.
Standard_Integer UpperCol() const;
Standard_Integer UpperCol() const;
//! Computes the determinant of a matrix.
//! An exception is raised if the matrix is not a square matrix.
@@ -168,19 +179,18 @@ public:
//! rows of this matrix, or
//! - the number of columns of matrix Right is not equal to
//! the number of columns of this matrix.
Standard_EXPORT void Multiply (const Standard_Real Right);
void operator*= (const Standard_Real Right)
{
Multiply(Right);
}
Standard_EXPORT void Multiply(const Standard_Real Right);
void operator*=(const Standard_Real Right) { Multiply(Right); }
//! multiplies all the elements of a matrix by the
//! value <Right>.
Standard_NODISCARD Standard_EXPORT math_Matrix Multiplied (const Standard_Real Right) const;
Standard_NODISCARD math_Matrix operator* (const Standard_Real Right) const
{
return Multiplied(Right);
}
Standard_NODISCARD Standard_EXPORT math_Matrix Multiplied(const Standard_Real Right) const;
Standard_NODISCARD math_Matrix operator*(const Standard_Real Right) const
{
return Multiplied(Right);
}
//! Sets this matrix to the product of the
//! transposed matrix TLeft, and the matrix Right.
@@ -200,24 +210,23 @@ Standard_NODISCARD math_Matrix operator* (const Standard_Real Right) const
//! rows of this matrix, or
//! - the number of columns of matrix Right is not equal to
//! the number of columns of this matrix.
Standard_NODISCARD Standard_EXPORT math_Matrix TMultiplied (const Standard_Real Right) const;
friend math_Matrix operator *(const Standard_Real Left,const math_Matrix& Right);
Standard_NODISCARD Standard_EXPORT math_Matrix TMultiplied(const Standard_Real Right) const;
friend math_Matrix operator*(const Standard_Real Left, const math_Matrix& Right);
//! divides all the elements of a matrix by the value <Right>.
//! An exception is raised if <Right> = 0.
Standard_EXPORT void Divide (const Standard_Real Right);
void operator/= (const Standard_Real Right)
{
Divide(Right);
}
Standard_EXPORT void Divide(const Standard_Real Right);
void operator/=(const Standard_Real Right) { Divide(Right); }
//! divides all the elements of a matrix by the value <Right>.
//! An exception is raised if <Right> = 0.
Standard_NODISCARD Standard_EXPORT math_Matrix Divided (const Standard_Real Right) const;
Standard_NODISCARD math_Matrix operator/ (const Standard_Real Right) const
{
return Divided(Right);
}
Standard_NODISCARD Standard_EXPORT math_Matrix Divided(const Standard_Real Right) const;
Standard_NODISCARD math_Matrix operator/(const Standard_Real Right) const
{
return Divided(Right);
}
//! adds the matrix <Right> to a matrix.
//! An exception is raised if the dimensions are different.
@@ -225,23 +234,19 @@ Standard_NODISCARD math_Matrix operator/ (const Standard_Real Right) const
//! In order to save time when copying matrices, it is
//! preferable to use operator += or the function Add
//! whenever possible.
Standard_EXPORT void Add (const math_Matrix& Right);
void operator+= (const math_Matrix& Right)
{
Add(Right);
}
Standard_EXPORT void Add(const math_Matrix& Right);
void operator+=(const math_Matrix& Right) { Add(Right); }
//! adds the matrix <Right> to a matrix.
//! An exception is raised if the dimensions are different.
Standard_NODISCARD Standard_EXPORT math_Matrix Added (const math_Matrix& Right) const;
Standard_NODISCARD math_Matrix operator+ (const math_Matrix& Right) const
{
return Added(Right);
}
Standard_NODISCARD Standard_EXPORT math_Matrix Added(const math_Matrix& Right) const;
Standard_NODISCARD math_Matrix operator+(const math_Matrix& Right) const { return Added(Right); }
//! sets a matrix to the addition of <Left> and <Right>.
//! An exception is raised if the dimensions are different.
Standard_EXPORT void Add (const math_Matrix& Left, const math_Matrix& Right);
Standard_EXPORT void Add(const math_Matrix& Left, const math_Matrix& Right);
//! Subtracts the matrix <Right> from <me>.
//! An exception is raised if the dimensions are different.
@@ -249,19 +254,18 @@ Standard_NODISCARD math_Matrix operator+ (const math_Matrix& Right) const
//! In order to avoid time-consuming copying of matrices, it
//! is preferable to use operator -= or the function
//! Subtract whenever possible.
Standard_EXPORT void Subtract (const math_Matrix& Right);
void operator-= (const math_Matrix& Right)
{
Subtract(Right);
}
Standard_EXPORT void Subtract(const math_Matrix& Right);
void operator-=(const math_Matrix& Right) { Subtract(Right); }
//! Returns the result of the subtraction of <Right> from <me>.
//! An exception is raised if the dimensions are different.
Standard_NODISCARD Standard_EXPORT math_Matrix Subtracted (const math_Matrix& Right) const;
Standard_NODISCARD math_Matrix operator- (const math_Matrix& Right) const
{
return Subtracted(Right);
}
Standard_NODISCARD Standard_EXPORT math_Matrix Subtracted(const math_Matrix& Right) const;
Standard_NODISCARD math_Matrix operator-(const math_Matrix& Right) const
{
return Subtracted(Right);
}
//! Sets the values of this matrix,
//! - from index I1 to index I2 on the row dimension, and
@@ -275,38 +279,42 @@ Standard_NODISCARD math_Matrix operator- (const math_Matrix& Right) const
//! - J2 is greater than the index of the upper column bound of this matrix, or
//! - I2 - I1 + 1 is not equal to the number of rows of matrix M, or
//! - J2 - J1 + 1 is not equal to the number of columns of matrix M.
Standard_EXPORT void Set (const Standard_Integer I1, const Standard_Integer I2, const Standard_Integer J1, const Standard_Integer J2, const math_Matrix& M);
Standard_EXPORT void Set(const Standard_Integer I1,
const Standard_Integer I2,
const Standard_Integer J1,
const Standard_Integer J2,
const math_Matrix& M);
//! Sets the row of index Row of a matrix to the vector <V>.
//! An exception is raised if the dimensions are different.
//! An exception is raises if <Row> is inferior to the lower
//! row of the matrix or <Row> is superior to the upper row.
Standard_EXPORT void SetRow (const Standard_Integer Row, const math_VectorBase<>& V);
Standard_EXPORT void SetRow(const Standard_Integer Row, const math_VectorBase<>& V);
//! Sets the column of index Col of a matrix to the vector <V>.
//! An exception is raised if the dimensions are different.
//! An exception is raises if <Col> is inferior to the lower
//! column of the matrix or <Col> is superior to the upper
//! column.
Standard_EXPORT void SetCol (const Standard_Integer Col, const math_VectorBase<>& V);
Standard_EXPORT void SetCol(const Standard_Integer Col, const math_VectorBase<>& V);
//! Sets the diagonal of a matrix to the value <Value>.
//! An exception is raised if the matrix is not square.
Standard_EXPORT void SetDiag (const Standard_Real Value);
Standard_EXPORT void SetDiag(const Standard_Real Value);
//! Returns the row of index Row of a matrix.
Standard_EXPORT math_VectorBase<> Row (const Standard_Integer Row) const;
Standard_EXPORT math_VectorBase<> Row(const Standard_Integer Row) const;
//! Returns the column of index <Col> of a matrix.
Standard_EXPORT math_VectorBase<> Col (const Standard_Integer Col) const;
Standard_EXPORT math_VectorBase<> Col(const Standard_Integer Col) const;
//! Swaps the rows of index Row1 and Row2.
//! An exception is raised if <Row1> or <Row2> is out of range.
Standard_EXPORT void SwapRow (const Standard_Integer Row1, const Standard_Integer Row2);
Standard_EXPORT void SwapRow(const Standard_Integer Row1, const Standard_Integer Row2);
//! Swaps the columns of index <Col1> and <Col2>.
//! An exception is raised if <Col1> or <Col2> is out of range.
Standard_EXPORT void SwapCol (const Standard_Integer Col1, const Standard_Integer Col2);
Standard_EXPORT void SwapCol(const Standard_Integer Col1, const Standard_Integer Col2);
//! Teturns the transposed of a matrix.
//! An exception is raised if the matrix is not a square matrix.
@@ -320,114 +328,97 @@ Standard_NODISCARD math_Matrix operator- (const math_Matrix& Right) const
//! Returns the product of the transpose of a matrix with
//! the matrix <Right>.
//! An exception is raised if the dimensions are different.
Standard_EXPORT math_Matrix TMultiply (const math_Matrix& Right) const;
Standard_EXPORT math_Matrix TMultiply(const math_Matrix& Right) const;
//! Computes a matrix as the product of 2 vectors.
//! An exception is raised if the dimensions are different.
//! <me> = <Left> * <Right>.
Standard_EXPORT void Multiply (const math_VectorBase<>& Left, const math_VectorBase<>& Right);
Standard_EXPORT void Multiply(const math_VectorBase<>& Left, const math_VectorBase<>& Right);
//! Computes a matrix as the product of 2 matrixes.
//! An exception is raised if the dimensions are different.
Standard_EXPORT void Multiply (const math_Matrix& Left, const math_Matrix& Right);
Standard_EXPORT void Multiply(const math_Matrix& Left, const math_Matrix& Right);
//! Computes a matrix to the product of the transpose of
//! the matrix <TLeft> with the matrix <Right>.
//! An exception is raised if the dimensions are different.
Standard_EXPORT void TMultiply (const math_Matrix& TLeft, const math_Matrix& Right);
Standard_EXPORT void TMultiply(const math_Matrix& TLeft, const math_Matrix& Right);
//! Sets a matrix to the Subtraction of the matrix <Right>
//! from the matrix <Left>.
//! An exception is raised if the dimensions are different.
Standard_EXPORT void Subtract (const math_Matrix& Left, const math_Matrix& Right);
Standard_EXPORT void Subtract(const math_Matrix& Left, const math_Matrix& Right);
//! Accesses (in read or write mode) the value of index <Row>
//! and <Col> of a matrix.
//! An exception is raised if <Row> and <Col> are not
//! in the correct range.
Standard_Real& Value (const Standard_Integer Row, const Standard_Integer Col) const;
Standard_Real& operator() (const Standard_Integer Row, const Standard_Integer Col) const
{
return Value(Row,Col);
}
Standard_Real& Value(const Standard_Integer Row, const Standard_Integer Col) const;
Standard_Real& operator()(const Standard_Integer Row, const Standard_Integer Col) const
{
return Value(Row, Col);
}
//! Matrixes are copied through assignment.
//! An exception is raised if the dimensions are different.
Standard_EXPORT math_Matrix& Initialized (const math_Matrix& Other);
math_Matrix& operator= (const math_Matrix& Other)
{
return Initialized(Other);
}
Standard_EXPORT math_Matrix& Initialized(const math_Matrix& Other);
math_Matrix& operator=(const math_Matrix& Other) { return Initialized(Other); }
//! Returns the product of 2 matrices.
//! An exception is raised if the dimensions are different.
Standard_EXPORT void Multiply (const math_Matrix& Right);
void operator*= (const math_Matrix& Right)
{
Multiply(Right);
}
Standard_EXPORT void Multiply(const math_Matrix& Right);
void operator*=(const math_Matrix& Right) { Multiply(Right); }
//! Returns the product of 2 matrices.
//! An exception is raised if the dimensions are different.
Standard_NODISCARD Standard_EXPORT math_Matrix Multiplied (const math_Matrix& Right) const;
Standard_NODISCARD math_Matrix operator* (const math_Matrix& Right) const
{
return Multiplied(Right);
}
Standard_NODISCARD Standard_EXPORT math_Matrix Multiplied(const math_Matrix& Right) const;
Standard_NODISCARD math_Matrix operator*(const math_Matrix& Right) const
{
return Multiplied(Right);
}
//! Returns the product of a matrix by a vector.
//! An exception is raised if the dimensions are different.
Standard_NODISCARD Standard_EXPORT math_VectorBase<> Multiplied (const math_VectorBase<>& Right) const;
Standard_NODISCARD Standard_EXPORT math_VectorBase<> operator* (const math_VectorBase<>& Right) const;
Standard_NODISCARD Standard_EXPORT math_VectorBase<> Multiplied(
const math_VectorBase<>& Right) const;
Standard_NODISCARD Standard_EXPORT math_VectorBase<> operator*(
const math_VectorBase<>& Right) const;
//! Returns the opposite of a matrix.
//! An exception is raised if the dimensions are different.
Standard_EXPORT math_Matrix Opposite();
math_Matrix operator-()
{
return Opposite();
}
math_Matrix operator-() { return Opposite(); }
//! Prints information on the current state of the object.
//! Is used to redefine the operator <<.
Standard_EXPORT void Dump (Standard_OStream& o) const;
Standard_EXPORT void Dump(Standard_OStream& o) const;
protected:
//! The new lower row of the matrix is set to <LowerRow>
Standard_EXPORT void SetLowerRow (const Standard_Integer LowerRow);
Standard_EXPORT void SetLowerRow(const Standard_Integer LowerRow);
//! The new lower column of the matrix is set to the column
//! of range <LowerCol>.
Standard_EXPORT void SetLowerCol (const Standard_Integer LowerCol);
Standard_EXPORT void SetLowerCol(const Standard_Integer LowerCol);
//! The new lower row of the matrix is set to <LowerRow>
//! and the new lower column of the matrix is set to the column
//! of range <LowerCol>.
void SetLower (const Standard_Integer LowerRow, const Standard_Integer LowerCol);
void SetLower(const Standard_Integer LowerRow, const Standard_Integer LowerCol);
private:
Standard_Integer LowerRowIndex;
Standard_Integer UpperRowIndex;
Standard_Integer LowerColIndex;
Standard_Integer UpperColIndex;
math_DoubleTab Array;
math_DoubleTab Array;
};
#include <math_Matrix.lxx>
#endif // _math_Matrix_HeaderFile

View File

@@ -16,63 +16,70 @@
#include <Standard_DimensionError.hxx>
inline Standard_OStream& operator<<(Standard_OStream& o,
const math_Matrix& mat)
inline Standard_OStream& operator<<(Standard_OStream& o, const math_Matrix& mat)
{
mat.Dump(o);
return o;
}
inline math_Matrix operator* (const Standard_Real Left,
const math_Matrix& Right)
inline math_Matrix operator*(const Standard_Real Left, const math_Matrix& Right)
{
return Right.Multiplied(Left);
}
inline Standard_Real& math_Matrix::Value(const Standard_Integer Row,
const Standard_Integer Col)const
inline Standard_Real& math_Matrix::Value(const Standard_Integer Row,
const Standard_Integer Col) const
{
Standard_RangeError_Raise_if(((Row < LowerRowIndex) ||
(Row > UpperRowIndex) ||
(Col < LowerColIndex) ||
(Col > UpperColIndex)), " ");
Standard_RangeError_Raise_if(((Row < LowerRowIndex) || (Row > UpperRowIndex)
|| (Col < LowerColIndex) || (Col > UpperColIndex)),
" ");
return Array(Row, Col);
}
inline Standard_Integer math_Matrix::RowNumber() const
{ return UpperRowIndex - LowerRowIndex + 1; }
inline Standard_Integer math_Matrix::RowNumber() const
{
return UpperRowIndex - LowerRowIndex + 1;
}
// returns the row range of a matrix.
// returns the row range of a matrix.
inline Standard_Integer math_Matrix::ColNumber() const
{ return UpperColIndex - LowerColIndex + 1; }
// returns the column range of a matrix.
inline Standard_Integer math_Matrix::ColNumber() const
{
return UpperColIndex - LowerColIndex + 1;
}
// returns the column range of a matrix.
inline Standard_Integer math_Matrix::LowerRow() const
{
return LowerRowIndex;
}
// returns the value of the Lower index of the row range of a matrix.
inline Standard_Integer math_Matrix::LowerRow() const { return LowerRowIndex; }
inline Standard_Integer math_Matrix::UpperRow() const
{
return UpperRowIndex;
}
// returns the value of the Lower index of the row range of a matrix.
// returns the value of the Upper index of the row range of a matrix.
inline Standard_Integer math_Matrix::UpperRow () const { return UpperRowIndex; }
inline Standard_Integer math_Matrix::LowerCol() const
{
return LowerColIndex;
}
// returns the value of the Upper index of the row range of a matrix.
// returns the value of the Lower index of the column range of a matrix.
inline Standard_Integer math_Matrix::LowerCol() const { return LowerColIndex; }
inline Standard_Integer math_Matrix::UpperCol() const
{
return UpperColIndex;
}
// returns the value of the Lower index of the column range of a matrix.
// returns the value of the Upper index of the column range of a matrix.
inline Standard_Integer math_Matrix::UpperCol() const { return UpperColIndex; }
// returns the value of the Upper index of the column range of a matrix.
inline void math_Matrix::SetLower (const Standard_Integer LowerRow,
const Standard_Integer LowerCol)
inline void math_Matrix::SetLower(const Standard_Integer LowerRow, const Standard_Integer LowerCol)
{
SetLowerRow(LowerRow);
SetLowerCol(LowerCol);

View File

@@ -12,21 +12,14 @@
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <math_MultipleVarFunction.hxx>
//=======================================================================
//function : ~math_MultipleVarFunction
//purpose : Destructor
//=======================================================================
math_MultipleVarFunction::~math_MultipleVarFunction()
{
}
//=================================================================================================
math_MultipleVarFunction::~math_MultipleVarFunction() {}
//=================================================================================================
//=======================================================================
//function : GetStateNumber
//purpose :
//=======================================================================
Standard_Integer math_MultipleVarFunction::GetStateNumber()
{
return 0;

View File

@@ -23,25 +23,21 @@
#include <math_Vector.hxx>
//! Describes the virtual functions associated with a multiple variable function.
class math_MultipleVarFunction
class math_MultipleVarFunction
{
public:
DEFINE_STANDARD_ALLOC
//! Returns the number of variables of the function
Standard_EXPORT virtual Standard_Integer NbVariables() const = 0;
//! Computes the values of the Functions <F> for the
//! variable <X>.
//! returns True if the computation was done successfully,
//! otherwise false.
Standard_EXPORT virtual Standard_Boolean Value (const math_Vector& X, Standard_Real& F) = 0;
Standard_EXPORT virtual Standard_Boolean Value(const math_Vector& X, Standard_Real& F) = 0;
//! return the state of the function corresponding to the latestt
//! call of any methods associated to the function. This
//! function is called by each of the algorithms described
@@ -59,27 +55,8 @@ public:
Standard_EXPORT virtual Standard_Integer GetStateNumber();
Standard_EXPORT virtual ~math_MultipleVarFunction();
protected:
private:
};
#endif // _math_MultipleVarFunction_HeaderFile

View File

@@ -24,56 +24,36 @@
#include <Standard_Integer.hxx>
#include <math_Vector.hxx>
//! The abstract class MultipleVarFunctionWithGradient
//! describes the virtual functions associated with a multiple variable function.
class math_MultipleVarFunctionWithGradient : public math_MultipleVarFunction
class math_MultipleVarFunctionWithGradient : public math_MultipleVarFunction
{
public:
DEFINE_STANDARD_ALLOC
//! Returns the number of variables of the function.
Standard_EXPORT virtual Standard_Integer NbVariables() const = 0;
//! Computes the values of the Functions <F> for the variable <X>.
//! Returns True if the computation was done successfully,
//! False otherwise.
Standard_EXPORT virtual Standard_Boolean Value (const math_Vector& X, Standard_Real& F) = 0;
Standard_EXPORT virtual Standard_Boolean Value(const math_Vector& X, Standard_Real& F) = 0;
//! Computes the gradient <G> of the functions for the variable <X>.
//! Returns True if the computation was done successfully,
//! False otherwise.
Standard_EXPORT virtual Standard_Boolean Gradient (const math_Vector& X, math_Vector& G) = 0;
Standard_EXPORT virtual Standard_Boolean Gradient(const math_Vector& X, math_Vector& G) = 0;
//! computes the value <F> and the gradient <G> of the
//! functions for the variable <X>.
//! Returns True if the computation was done successfully,
//! False otherwise.
Standard_EXPORT virtual Standard_Boolean Values (const math_Vector& X, Standard_Real& F, math_Vector& G) = 0;
Standard_EXPORT virtual Standard_Boolean Values(const math_Vector& X,
Standard_Real& F,
math_Vector& G) = 0;
protected:
private:
};
#endif // _math_MultipleVarFunctionWithGradient_HeaderFile

View File

@@ -25,63 +25,45 @@
#include <math_Vector.hxx>
class math_Matrix;
class math_MultipleVarFunctionWithHessian : public math_MultipleVarFunctionWithGradient
class math_MultipleVarFunctionWithHessian : public math_MultipleVarFunctionWithGradient
{
public:
DEFINE_STANDARD_ALLOC
//! returns the number of variables of the function.
Standard_EXPORT virtual Standard_Integer NbVariables() const = 0;
//! computes the values of the Functions <F> for the
//! variable <X>.
//! Returns True if the computation was done successfully,
//! False otherwise.
Standard_EXPORT virtual Standard_Boolean Value (const math_Vector& X, Standard_Real& F) = 0;
Standard_EXPORT virtual Standard_Boolean Value(const math_Vector& X, Standard_Real& F) = 0;
//! computes the gradient <G> of the functions for the
//! variable <X>.
//! Returns True if the computation was done successfully,
//! False otherwise.
Standard_EXPORT virtual Standard_Boolean Gradient (const math_Vector& X, math_Vector& G) = 0;
Standard_EXPORT virtual Standard_Boolean Gradient(const math_Vector& X, math_Vector& G) = 0;
//! computes the value <F> and the gradient <G> of the
//! functions for the variable <X>.
//! Returns True if the computation was done successfully,
//! False otherwise.
Standard_EXPORT virtual Standard_Boolean Values (const math_Vector& X, Standard_Real& F, math_Vector& G) = 0;
Standard_EXPORT virtual Standard_Boolean Values(const math_Vector& X,
Standard_Real& F,
math_Vector& G) = 0;
//! computes the value <F>, the gradient <G> and the
//! hessian <H> of the functions for the variable <X>.
//! Returns True if the computation was done
//! successfully, False otherwise.
Standard_EXPORT virtual Standard_Boolean Values (const math_Vector& X, Standard_Real& F, math_Vector& G, math_Matrix& H) = 0;
Standard_EXPORT virtual Standard_Boolean Values(const math_Vector& X,
Standard_Real& F,
math_Vector& G,
math_Matrix& H) = 0;
protected:
private:
};
#endif // _math_MultipleVarFunctionWithHessian_HeaderFile

View File

@@ -12,151 +12,161 @@
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <math_FunctionWithDerivative.hxx>
#include <math_NewtonFunctionRoot.hxx>
#include <StdFail_NotDone.hxx>
math_NewtonFunctionRoot::math_NewtonFunctionRoot (math_FunctionWithDerivative& F,
const Standard_Real Guess,
const Standard_Real EpsX ,
const Standard_Real EpsF ,
const Standard_Real A,
const Standard_Real B,
const Standard_Integer NbIterations ){
math_NewtonFunctionRoot::math_NewtonFunctionRoot(math_FunctionWithDerivative& F,
const Standard_Real Guess,
const Standard_Real EpsX,
const Standard_Real EpsF,
const Standard_Real A,
const Standard_Real B,
const Standard_Integer NbIterations)
{
EpsilonX = EpsX;
EpsilonF = EpsF;
Binf = A;
Bsup = B;
Itermax = NbIterations;
Done = Standard_False;
X = RealLast();
DFx = 0;
Fx = RealLast();
It = 0;
Binf = A;
Bsup = B;
Itermax = NbIterations;
Done = Standard_False;
X = RealLast();
DFx = 0;
Fx = RealLast();
It = 0;
Perform(F, Guess);
}
math_NewtonFunctionRoot::math_NewtonFunctionRoot(const Standard_Real A,
const Standard_Real B,
const Standard_Real EpsX,
const Standard_Real EpsF,
const Standard_Integer NbIterations)
{
math_NewtonFunctionRoot::math_NewtonFunctionRoot (const Standard_Real A ,
const Standard_Real B,
const Standard_Real EpsX ,
const Standard_Real EpsF ,
const Standard_Integer NbIterations ){
Binf = A;
Bsup = B;
Binf = A;
Bsup = B;
EpsilonX = EpsX;
EpsilonF = EpsF;
Itermax = NbIterations;
Done = Standard_False;
X = RealLast();
DFx = 0;
Fx = RealLast();
It = 0;
Itermax = NbIterations;
Done = Standard_False;
X = RealLast();
DFx = 0;
Fx = RealLast();
It = 0;
}
math_NewtonFunctionRoot::math_NewtonFunctionRoot (math_FunctionWithDerivative& F,
const Standard_Real Guess,
const Standard_Real EpsX ,
const Standard_Real EpsF ,
const Standard_Integer NbIterations ){
math_NewtonFunctionRoot::math_NewtonFunctionRoot(math_FunctionWithDerivative& F,
const Standard_Real Guess,
const Standard_Real EpsX,
const Standard_Real EpsF,
const Standard_Integer NbIterations)
{
EpsilonX = EpsX;
EpsilonF = EpsF;
Itermax = NbIterations;
Binf = RealFirst();
Bsup = RealLast();
Done = Standard_False;
X = RealLast();
DFx = 0;
Fx = RealLast();
It = 0;
Itermax = NbIterations;
Binf = RealFirst();
Bsup = RealLast();
Done = Standard_False;
X = RealLast();
DFx = 0;
Fx = RealLast();
It = 0;
Perform(F, Guess);
}
void math_NewtonFunctionRoot::Perform(math_FunctionWithDerivative& F, const Standard_Real Guess)
{
void math_NewtonFunctionRoot::Perform(math_FunctionWithDerivative& F,
const Standard_Real Guess) {
Standard_Real Dx;
Standard_Real Dx;
Standard_Boolean Ok;
Standard_Real AA, BB;
Standard_Real AA, BB;
//--------------------------------------------------
//-- lbr le 12 Nov 97
//-- la meilleure estimation n est pas sauvee et on
//-- la meilleure estimation n est pas sauvee et on
//-- renvoie une solution plus fausse que Guess
Standard_Real BestX=X,BestFx=RealLast();
//--
if ( Binf < Bsup) {
Standard_Real BestX = X, BestFx = RealLast();
//--
if (Binf < Bsup)
{
AA = Binf;
BB = Bsup;
}
else {
else
{
AA = Bsup;
BB = Binf;
}
Dx = RealLast();
Fx = RealLast();
X = Guess;
Fx = RealLast();
X = Guess;
It = 1;
while ( (It <= Itermax) && ( (Abs(Dx) > EpsilonX) ||
(Abs(Fx) > EpsilonF) ) ) {
Ok = F.Values(X,Fx,DFx);
Standard_Real AbsFx = Fx; if(AbsFx<0) AbsFx=-AbsFx;
if(AbsFx<BestFx) {
BestFx=AbsFx;
BestX =X;
while ((It <= Itermax) && ((Abs(Dx) > EpsilonX) || (Abs(Fx) > EpsilonF)))
{
Ok = F.Values(X, Fx, DFx);
Standard_Real AbsFx = Fx;
if (AbsFx < 0)
AbsFx = -AbsFx;
if (AbsFx < BestFx)
{
BestFx = AbsFx;
BestX = X;
}
if (Ok) {
if (DFx == 0.) {
Done = Standard_False;
It = Itermax + 1;
if (Ok)
{
if (DFx == 0.)
{
Done = Standard_False;
It = Itermax + 1;
}
else {
Dx = Fx/DFx;
X -= Dx;
// Limitation des variations de X:
if (X <= AA) X = AA;
if (X >= BB) X = BB;
It++;
else
{
Dx = Fx / DFx;
X -= Dx;
// Limitation des variations de X:
if (X <= AA)
X = AA;
if (X >= BB)
X = BB;
It++;
}
}
else {
else
{
Done = Standard_False;
It = Itermax + 1;
It = Itermax + 1;
}
}
X = BestX;
if (It <= Itermax) {
if (It <= Itermax)
{
Done = Standard_True;
}
else
else
{
Done = Standard_False;
}
}
}
void math_NewtonFunctionRoot::Dump(Standard_OStream& o) const
{
void math_NewtonFunctionRoot::Dump(Standard_OStream& o) const {
o <<"math_NewtonFunctionRoot ";
if (Done) {
o << "math_NewtonFunctionRoot ";
if (Done)
{
o << " Status = Done \n";
o << " Location found = " << X <<"\n";
o << " function value at this minimum = " << Fx <<"\n";
o << " Number of iterations = " << It <<"\n";
o << " Location found = " << X << "\n";
o << " function value at this minimum = " << Fx << "\n";
o << " Number of iterations = " << It << "\n";
}
else {
else
{
o << "Status = not Done \n";
}
}

View File

@@ -23,27 +23,25 @@
#include <Standard_OStream.hxx>
class math_FunctionWithDerivative;
//! This class implements the calculation of a root of a function of
//! a single variable starting from an initial near guess using the
//! Newton algorithm. Knowledge of the derivative is required.
class math_NewtonFunctionRoot
class math_NewtonFunctionRoot
{
public:
DEFINE_STANDARD_ALLOC
//! The Newton method is done to find the root of the function F
//! from the initial guess Guess.
//! The tolerance required on the root is given by Tolerance.
//! The solution is found when :
//! abs(Xi - Xi-1) <= EpsX and abs(F(Xi))<= EpsF
//! The maximum number of iterations allowed is given by NbIterations.
Standard_EXPORT math_NewtonFunctionRoot(math_FunctionWithDerivative& F, const Standard_Real Guess, const Standard_Real EpsX, const Standard_Real EpsF, const Standard_Integer NbIterations = 100);
Standard_EXPORT math_NewtonFunctionRoot(math_FunctionWithDerivative& F,
const Standard_Real Guess,
const Standard_Real EpsX,
const Standard_Real EpsF,
const Standard_Integer NbIterations = 100);
//! The Newton method is done to find the root of the function F
//! from the initial guess Guess.
@@ -52,70 +50,62 @@ public:
//! The solution is found when :
//! abs(Xi - Xi-1) <= EpsX and abs(F(Xi))<= EpsF
//! The maximum number of iterations allowed is given by NbIterations.
Standard_EXPORT math_NewtonFunctionRoot(math_FunctionWithDerivative& F, const Standard_Real Guess, const Standard_Real EpsX, const Standard_Real EpsF, const Standard_Real A, const Standard_Real B, const Standard_Integer NbIterations = 100);
Standard_EXPORT math_NewtonFunctionRoot(math_FunctionWithDerivative& F,
const Standard_Real Guess,
const Standard_Real EpsX,
const Standard_Real EpsF,
const Standard_Real A,
const Standard_Real B,
const Standard_Integer NbIterations = 100);
//! is used in a sub-class to initialize correctly all the fields
//! of this class.
Standard_EXPORT math_NewtonFunctionRoot(const Standard_Real A, const Standard_Real B, const Standard_Real EpsX, const Standard_Real EpsF, const Standard_Integer NbIterations = 100);
Standard_EXPORT math_NewtonFunctionRoot(const Standard_Real A,
const Standard_Real B,
const Standard_Real EpsX,
const Standard_Real EpsF,
const Standard_Integer NbIterations = 100);
//! is used internally by the constructors.
Standard_EXPORT void Perform (math_FunctionWithDerivative& F, const Standard_Real Guess);
Standard_EXPORT void Perform(math_FunctionWithDerivative& F, const Standard_Real Guess);
//! Returns true if the computations are successful, otherwise returns false.
Standard_Boolean IsDone() const;
Standard_Boolean IsDone() const;
//! Returns the value of the root of function <F>.
//! Exception NotDone is raised if the root was not found.
Standard_Real Root() const;
Standard_Real Root() const;
//! returns the value of the derivative at the root.
//! Exception NotDone is raised if the root was not found.
Standard_Real Derivative() const;
Standard_Real Derivative() const;
//! returns the value of the function at the root.
//! Exception NotDone is raised if the root was not found.
Standard_Real Value() const;
Standard_Real Value() const;
//! Returns the number of iterations really done on the
//! computation of the Root.
//! Exception NotDone is raised if the root was not found.
Standard_Integer NbIterations() const;
Standard_Integer NbIterations() const;
//! Prints information on the current state of the object.
Standard_EXPORT void Dump (Standard_OStream& o) const;
Standard_EXPORT void Dump(Standard_OStream& o) const;
protected:
private:
Standard_Boolean Done;
Standard_Real X;
Standard_Real Fx;
Standard_Real DFx;
Standard_Real X;
Standard_Real Fx;
Standard_Real DFx;
Standard_Integer It;
Standard_Real EpsilonX;
Standard_Real EpsilonF;
Standard_Real EpsilonX;
Standard_Real EpsilonF;
Standard_Integer Itermax;
Standard_Real Binf;
Standard_Real Bsup;
Standard_Real Binf;
Standard_Real Bsup;
};
#include <math_NewtonFunctionRoot.lxx>
#endif // _math_NewtonFunctionRoot_HeaderFile

View File

@@ -14,34 +14,37 @@
#include <StdFail_NotDone.hxx>
inline Standard_Boolean math_NewtonFunctionRoot::IsDone() const {return Done;}
inline Standard_Boolean math_NewtonFunctionRoot::IsDone() const
{
return Done;
}
inline Standard_OStream& operator<<(Standard_OStream& o,
const math_NewtonFunctionRoot& N)
inline Standard_OStream& operator<<(Standard_OStream& o, const math_NewtonFunctionRoot& N)
{
N.Dump(o);
return o;
}
inline Standard_Real math_NewtonFunctionRoot::Root () const{
inline Standard_Real math_NewtonFunctionRoot::Root() const
{
StdFail_NotDone_Raise_if(!Done, " ");
return X;
}
inline Standard_Real math_NewtonFunctionRoot::Derivative () const {
inline Standard_Real math_NewtonFunctionRoot::Derivative() const
{
StdFail_NotDone_Raise_if(!Done, " ");
return DFx;
}
inline Standard_Real math_NewtonFunctionRoot::Value () const {
inline Standard_Real math_NewtonFunctionRoot::Value() const
{
StdFail_NotDone_Raise_if(!Done, " ");
return Fx;
}
inline Standard_Integer math_NewtonFunctionRoot::NbIterations () const {
inline Standard_Integer math_NewtonFunctionRoot::NbIterations() const
{
StdFail_NotDone_Raise_if(!Done, " ");
return It;
}

View File

@@ -12,159 +12,149 @@
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
//#ifndef OCCT_DEBUG
// #ifndef OCCT_DEBUG
#define No_Standard_RangeError
#define No_Standard_OutOfRange
#define No_Standard_DimensionError
//#endif
// #endif
#include <math_FunctionSetWithDerivatives.hxx>
#include <math_NewtonFunctionSetRoot.hxx>
#include <math_Recipes.hxx>
#include <StdFail_NotDone.hxx>
//=======================================================================
//function : math_NewtonFunctionSetRoot
//purpose : Constructor
//=======================================================================
math_NewtonFunctionSetRoot::math_NewtonFunctionSetRoot(
math_FunctionSetWithDerivatives& theFunction,
const math_Vector& theXTolerance,
const Standard_Real theFTolerance,
const Standard_Integer theNbIterations)
//=================================================================================================
: TolX (1, theFunction.NbVariables()),
TolF (theFTolerance),
Indx (1, theFunction.NbVariables()),
Scratch (1, theFunction.NbVariables()),
Sol (1, theFunction.NbVariables()),
DeltaX (1, theFunction.NbVariables()),
FValues (1, theFunction.NbVariables()),
Jacobian(1, theFunction.NbVariables(), 1, theFunction.NbVariables()),
Done (Standard_False),
State (0),
Iter (0),
Itermax (theNbIterations)
math_NewtonFunctionSetRoot::math_NewtonFunctionSetRoot(math_FunctionSetWithDerivatives& theFunction,
const math_Vector& theXTolerance,
const Standard_Real theFTolerance,
const Standard_Integer theNbIterations)
: TolX(1, theFunction.NbVariables()),
TolF(theFTolerance),
Indx(1, theFunction.NbVariables()),
Scratch(1, theFunction.NbVariables()),
Sol(1, theFunction.NbVariables()),
DeltaX(1, theFunction.NbVariables()),
FValues(1, theFunction.NbVariables()),
Jacobian(1, theFunction.NbVariables(), 1, theFunction.NbVariables()),
Done(Standard_False),
State(0),
Iter(0),
Itermax(theNbIterations)
{
SetTolerance(theXTolerance);
}
//=======================================================================
//function : math_NewtonFunctionSetRoot
//purpose : Constructor
//=======================================================================
math_NewtonFunctionSetRoot::math_NewtonFunctionSetRoot(
math_FunctionSetWithDerivatives& theFunction,
const Standard_Real theFTolerance,
const Standard_Integer theNbIterations)
//=================================================================================================
: TolX (1, theFunction.NbVariables()),
TolF (theFTolerance),
Indx (1, theFunction.NbVariables()),
Scratch (1, theFunction.NbVariables()),
Sol (1, theFunction.NbVariables()),
DeltaX (1, theFunction.NbVariables()),
FValues (1, theFunction.NbVariables()),
Jacobian(1, theFunction.NbVariables(), 1, theFunction.NbVariables()),
Done (Standard_False),
State (0),
Iter (0),
Itermax (theNbIterations)
math_NewtonFunctionSetRoot::math_NewtonFunctionSetRoot(math_FunctionSetWithDerivatives& theFunction,
const Standard_Real theFTolerance,
const Standard_Integer theNbIterations)
: TolX(1, theFunction.NbVariables()),
TolF(theFTolerance),
Indx(1, theFunction.NbVariables()),
Scratch(1, theFunction.NbVariables()),
Sol(1, theFunction.NbVariables()),
DeltaX(1, theFunction.NbVariables()),
FValues(1, theFunction.NbVariables()),
Jacobian(1, theFunction.NbVariables(), 1, theFunction.NbVariables()),
Done(Standard_False),
State(0),
Iter(0),
Itermax(theNbIterations)
{
}
//=======================================================================
//function : ~math_NewtonFunctionSetRoot
//purpose : Destructor
//=======================================================================
math_NewtonFunctionSetRoot::~math_NewtonFunctionSetRoot()
{
}
//=================================================================================================
math_NewtonFunctionSetRoot::~math_NewtonFunctionSetRoot() {}
//=================================================================================================
//=======================================================================
//function : SetTolerance
//purpose :
//=======================================================================
void math_NewtonFunctionSetRoot::SetTolerance(const math_Vector& theXTolerance)
{
for (Standard_Integer i = 1; i <= TolX.Length(); ++i)
TolX(i) = theXTolerance(i);
}
//=======================================================================
//function : Perform
//purpose :
//=======================================================================
void math_NewtonFunctionSetRoot::Perform(
math_FunctionSetWithDerivatives& theFunction,
const math_Vector& theStartingPoint)
//=================================================================================================
void math_NewtonFunctionSetRoot::Perform(math_FunctionSetWithDerivatives& theFunction,
const math_Vector& theStartingPoint)
{
const math_Vector anInf(1, theFunction.NbVariables(), RealFirst());
const math_Vector aSup (1, theFunction.NbVariables(), RealLast ());
const math_Vector aSup(1, theFunction.NbVariables(), RealLast());
Perform(theFunction, theStartingPoint, anInf, aSup);
}
//=======================================================================
//function : Perform
//purpose :
//=======================================================================
void math_NewtonFunctionSetRoot::Perform(
math_FunctionSetWithDerivatives& F,
const math_Vector& StartingPoint,
const math_Vector& InfBound,
const math_Vector& SupBound)
//=================================================================================================
void math_NewtonFunctionSetRoot::Perform(math_FunctionSetWithDerivatives& F,
const math_Vector& StartingPoint,
const math_Vector& InfBound,
const math_Vector& SupBound)
{
Standard_Real d;
Standard_Real d;
Standard_Boolean OK;
Standard_Integer Error;
Done = Standard_False;
Sol = StartingPoint;
OK = F.Values(Sol, FValues, Jacobian);
if(!OK) return;
for(Iter = 1; Iter <= Itermax; Iter++) {
for(Standard_Integer k = 1; k <= DeltaX.Length(); k++) {
Sol = StartingPoint;
OK = F.Values(Sol, FValues, Jacobian);
if (!OK)
return;
for (Iter = 1; Iter <= Itermax; Iter++)
{
for (Standard_Integer k = 1; k <= DeltaX.Length(); k++)
{
DeltaX(k) = -FValues(k);
}
Error = LU_Decompose(Jacobian, Indx, d, Scratch, 1.0e-30);
if(Error) return;
if (Error)
return;
LU_Solve(Jacobian, Indx, DeltaX);
for(Standard_Integer i = 1; i <= Sol.Length(); i++) {
for (Standard_Integer i = 1; i <= Sol.Length(); i++)
{
Sol(i) += DeltaX(i);
// Limitation de Sol dans les bornes [InfBound, SupBound] :
if (Sol(i) <= InfBound(i)) Sol(i) = InfBound(i);
if (Sol(i) >= SupBound(i)) Sol(i) = SupBound(i);
if (Sol(i) <= InfBound(i))
Sol(i) = InfBound(i);
if (Sol(i) >= SupBound(i))
Sol(i) = SupBound(i);
}
OK = F.Values(Sol, FValues, Jacobian);
if(!OK) return;
if(IsSolutionReached(F)) {
if (!OK)
return;
if (IsSolutionReached(F))
{
State = F.GetStateNumber();
Done = Standard_True;
Done = Standard_True;
return;
}
}
}
}
//=======================================================================
//function : Dump
//purpose :
//=======================================================================
void math_NewtonFunctionSetRoot::Dump(Standard_OStream& o) const
//=================================================================================================
void math_NewtonFunctionSetRoot::Dump(Standard_OStream& o) const
{
o <<"math_NewtonFunctionSetRoot ";
if (Done) {
o << "math_NewtonFunctionSetRoot ";
if (Done)
{
o << " Status = Done \n";
o << " Vector solution = " << Sol <<"\n";
o << " Vector solution = " << Sol << "\n";
o << " Value of the function at this solution = \n";
o << FValues <<"\n";
o << " Number of iterations = " << Iter <<"\n";
o << FValues << "\n";
o << " Number of iterations = " << Iter << "\n";
}
else {
else
{
o << "Status = not Done \n";
}
}

View File

@@ -27,144 +27,127 @@
#include <Standard_OStream.hxx>
class math_FunctionSetWithDerivatives;
//! This class computes the root of a set of N functions of N variables,
//! knowing an initial guess at the solution and using the
//! Newton Raphson algorithm. Knowledge of all the partial
//! derivatives (Jacobian) is required.
class math_NewtonFunctionSetRoot
class math_NewtonFunctionSetRoot
{
public:
DEFINE_STANDARD_ALLOC
//! Initialize correctly all the fields of this class.
//! The range (1, F.NbVariables()) must be especially respected for
//! all vectors and matrix declarations.
Standard_EXPORT math_NewtonFunctionSetRoot(math_FunctionSetWithDerivatives& theFunction, const math_Vector& theXTolerance, const Standard_Real theFTolerance, const Standard_Integer tehNbIterations = 100);
Standard_EXPORT math_NewtonFunctionSetRoot(math_FunctionSetWithDerivatives& theFunction,
const math_Vector& theXTolerance,
const Standard_Real theFTolerance,
const Standard_Integer tehNbIterations = 100);
//! This constructor should be used in a sub-class to initialize
//! correctly all the fields of this class.
//! The range (1, F.NbVariables()) must be especially respected for
//! all vectors and matrix declarations.
//! The method SetTolerance must be called before performing the algorithm.
Standard_EXPORT math_NewtonFunctionSetRoot(math_FunctionSetWithDerivatives& theFunction, const Standard_Real theFTolerance, const Standard_Integer theNbIterations = 100);
Standard_EXPORT math_NewtonFunctionSetRoot(math_FunctionSetWithDerivatives& theFunction,
const Standard_Real theFTolerance,
const Standard_Integer theNbIterations = 100);
//! Destructor
Standard_EXPORT virtual ~math_NewtonFunctionSetRoot();
//! Initializes the tolerance values for the unknowns.
Standard_EXPORT void SetTolerance (const math_Vector& XTol);
Standard_EXPORT void SetTolerance(const math_Vector& XTol);
//! The Newton method is done to improve the root of the function
//! from the initial guess point. The solution is found when:
//! abs(Xj - Xj-1)(i) <= XTol(i) and abs(Fi) <= FTol for all i;
Standard_EXPORT void Perform (math_FunctionSetWithDerivatives& theFunction, const math_Vector& theStartingPoint);
Standard_EXPORT void Perform(math_FunctionSetWithDerivatives& theFunction,
const math_Vector& theStartingPoint);
//! The Newton method is done to improve the root of the function
//! from the initial guess point. Bounds may be given, to constrain the solution.
//! The solution is found when:
//! abs(Xj - Xj-1)(i) <= XTol(i) and abs(Fi) <= FTol for all i;
Standard_EXPORT void Perform (math_FunctionSetWithDerivatives& theFunction, const math_Vector& theStartingPoint, const math_Vector& theInfBound, const math_Vector& theSupBound);
Standard_EXPORT void Perform(math_FunctionSetWithDerivatives& theFunction,
const math_Vector& theStartingPoint,
const math_Vector& theInfBound,
const math_Vector& theSupBound);
//! This method is called at the end of each iteration to check if the
//! solution is found.
//! Vectors DeltaX, Fvalues and Jacobian Matrix are consistent with the
//! possible solution Vector Sol and can be inspected to decide whether
//! the solution is reached or not.
virtual Standard_Boolean IsSolutionReached (math_FunctionSetWithDerivatives& F);
virtual Standard_Boolean IsSolutionReached(math_FunctionSetWithDerivatives& F);
//! Returns true if the computations are successful, otherwise returns false.
Standard_Boolean IsDone() const;
Standard_Boolean IsDone() const;
//! Returns the value of the root of function F.
//! Exceptions
//! StdFail_NotDone if the algorithm fails (and IsDone returns false).
const math_Vector& Root() const;
const math_Vector& Root() const;
//! outputs the root vector in Root.
//! Exception NotDone is raised if the root was not found.
//! Exception DimensionError is raised if the range of Root is
//! not equal to the range of the StartingPoint.
void Root (math_Vector& Root) const;
void Root(math_Vector& Root) const;
//! Outputs the state number associated with the solution
//! vector root.
Standard_Integer StateNumber() const;
Standard_Integer StateNumber() const;
//! Returns the matrix value of the derivative at the root.
//! Exception NotDone is raised if the root was not found.
const math_Matrix& Derivative() const;
const math_Matrix& Derivative() const;
//! Outputs the matrix value of the derivative at the root in
//! Der.
//! Exception NotDone is raised if the root was not found.
//! Exception DimensionError is raised if the range of Der is
//! not equal to the range of the StartingPoint.
void Derivative (math_Matrix& Der) const;
void Derivative(math_Matrix& Der) const;
//! Returns the vector value of the error done on the
//! functions at the root.
//! Exception NotDone is raised if the root was not found.
const math_Vector& FunctionSetErrors() const;
const math_Vector& FunctionSetErrors() const;
//! Outputs the vector value of the error done on the
//! functions at the root in Err.
//! Exception NotDone is raised if the root was not found.
//! Exception DimensionError is raised if the range of Err is
//! not equal to the range of the StartingPoint.
void FunctionSetErrors (math_Vector& Err) const;
void FunctionSetErrors(math_Vector& Err) const;
//! Returns the number of iterations really done
//! during the computation of the Root.
//! Exception NotDone is raised if the root was not found.
Standard_Integer NbIterations() const;
Standard_Integer NbIterations() const;
//! Prints information on the current state of the object.
//! Is used to redefine the operator <<.
Standard_EXPORT void Dump (Standard_OStream& o) const;
Standard_EXPORT void Dump(Standard_OStream& o) const;
protected:
math_Vector TolX;
Standard_Real TolF;
math_Vector TolX;
Standard_Real TolF;
math_IntegerVector Indx;
math_Vector Scratch;
math_Vector Sol;
math_Vector DeltaX;
math_Vector FValues;
math_Matrix Jacobian;
math_Vector Scratch;
math_Vector Sol;
math_Vector DeltaX;
math_Vector FValues;
math_Matrix Jacobian;
private:
Standard_Boolean Done;
Standard_Integer State;
Standard_Integer Iter;
Standard_Integer Itermax;
};
#include <math_NewtonFunctionSetRoot.lxx>
#endif // _math_NewtonFunctionSetRoot_HeaderFile

View File

@@ -14,10 +14,11 @@
#include <StdFail_NotDone.hxx>
inline Standard_Boolean math_NewtonFunctionSetRoot::IsSolutionReached(math_FunctionSetWithDerivatives&)
inline Standard_Boolean math_NewtonFunctionSetRoot::IsSolutionReached(
math_FunctionSetWithDerivatives&)
{
for (Standard_Integer i = DeltaX.Lower(); i <= DeltaX.Upper(); ++i)
if ( Abs(DeltaX(i)) > TolX(i) || Abs(FValues(i)) > TolF )
if (Abs(DeltaX(i)) > TolX(i) || Abs(FValues(i)) > TolF)
return Standard_False;
return Standard_True;
@@ -28,53 +29,50 @@ inline Standard_Boolean math_NewtonFunctionSetRoot::IsDone() const
return Done;
}
inline Standard_OStream& operator<<(Standard_OStream& o,
const math_NewtonFunctionSetRoot& N)
inline Standard_OStream& operator<<(Standard_OStream& o, const math_NewtonFunctionSetRoot& N)
{
N.Dump(o);
return o;
}
inline const math_Vector& math_NewtonFunctionSetRoot::Root() const{
inline const math_Vector& math_NewtonFunctionSetRoot::Root() const
{
StdFail_NotDone_Raise_if(!Done, " ");
return Sol;
}
inline void math_NewtonFunctionSetRoot::Root(math_Vector& Root) const{
inline void math_NewtonFunctionSetRoot::Root(math_Vector& Root) const
{
StdFail_NotDone_Raise_if(!Done, " ");
Root = Sol;
}
inline const math_Matrix& math_NewtonFunctionSetRoot::Derivative() const{
inline const math_Matrix& math_NewtonFunctionSetRoot::Derivative() const
{
StdFail_NotDone_Raise_if(!Done, " ");
return Jacobian;
}
inline void math_NewtonFunctionSetRoot::Derivative(math_Matrix& Der) const{
inline void math_NewtonFunctionSetRoot::Derivative(math_Matrix& Der) const
{
StdFail_NotDone_Raise_if(!Done, " ");
Der = Jacobian;
}
inline const math_Vector& math_NewtonFunctionSetRoot::FunctionSetErrors() const{
inline const math_Vector& math_NewtonFunctionSetRoot::FunctionSetErrors() const
{
StdFail_NotDone_Raise_if(!Done, " ");
return DeltaX;
}
inline void math_NewtonFunctionSetRoot::FunctionSetErrors(math_Vector& Err) const{
inline void math_NewtonFunctionSetRoot::FunctionSetErrors(math_Vector& Err) const
{
StdFail_NotDone_Raise_if(!Done, " ");
Err = DeltaX;
}
inline Standard_Integer math_NewtonFunctionSetRoot::NbIterations() const{
inline Standard_Integer math_NewtonFunctionSetRoot::NbIterations() const
{
StdFail_NotDone_Raise_if(!Done, " ");
return Iter;
}

View File

@@ -14,12 +14,12 @@
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
//#ifndef OCCT_DEBUG
// #ifndef OCCT_DEBUG
#define No_Standard_RangeError
#define No_Standard_OutOfRange
#define No_Standard_DimensionError
//#endif
// #endif
#include <math_Gauss.hxx>
#include <math_Jacobi.hxx>
@@ -28,118 +28,112 @@
#include <Precision.hxx>
#include <StdFail_NotDone.hxx>
//=======================================================================
//function : math_NewtonMinimum
//purpose : Constructor
//=======================================================================
math_NewtonMinimum::math_NewtonMinimum(
const math_MultipleVarFunctionWithHessian& theFunction,
const Standard_Real theTolerance,
const Standard_Integer theNbIterations,
const Standard_Real theConvexity,
const Standard_Boolean theWithSingularity
)
: TheStatus (math_NotBracketed),
TheLocation(1, theFunction.NbVariables()),
TheGradient(1, theFunction.NbVariables()),
TheStep (1, theFunction.NbVariables(), 10.0 * theTolerance),
TheHessian (1, theFunction.NbVariables(), 1, theFunction.NbVariables()),
PreviousMinimum (0.0),
TheMinimum (0.0),
MinEigenValue (0.0),
XTol (theTolerance),
CTol (theConvexity),
nbiter (0),
NoConvexTreatement(theWithSingularity),
Convex (Standard_True),
myIsBoundsDefined(Standard_False),
myLeft(1, theFunction.NbVariables(), 0.0),
myRight(1, theFunction.NbVariables(), 0.0),
Done (Standard_False),
Itermax (theNbIterations)
//=================================================================================================
math_NewtonMinimum::math_NewtonMinimum(const math_MultipleVarFunctionWithHessian& theFunction,
const Standard_Real theTolerance,
const Standard_Integer theNbIterations,
const Standard_Real theConvexity,
const Standard_Boolean theWithSingularity)
: TheStatus(math_NotBracketed),
TheLocation(1, theFunction.NbVariables()),
TheGradient(1, theFunction.NbVariables()),
TheStep(1, theFunction.NbVariables(), 10.0 * theTolerance),
TheHessian(1, theFunction.NbVariables(), 1, theFunction.NbVariables()),
PreviousMinimum(0.0),
TheMinimum(0.0),
MinEigenValue(0.0),
XTol(theTolerance),
CTol(theConvexity),
nbiter(0),
NoConvexTreatement(theWithSingularity),
Convex(Standard_True),
myIsBoundsDefined(Standard_False),
myLeft(1, theFunction.NbVariables(), 0.0),
myRight(1, theFunction.NbVariables(), 0.0),
Done(Standard_False),
Itermax(theNbIterations)
{
}
//=======================================================================
//function : ~math_NewtonMinimum
//purpose : Destructor
//=======================================================================
math_NewtonMinimum::~math_NewtonMinimum()
{
}
//=================================================================================================
math_NewtonMinimum::~math_NewtonMinimum() {}
//=======================================================================
//function : SetBoundary
//purpose : Set boundaries for conditional optimization
// function : SetBoundary
// purpose : Set boundaries for conditional optimization
//=======================================================================
void math_NewtonMinimum::SetBoundary(const math_Vector& theLeftBorder,
const math_Vector& theRightBorder)
{
myLeft = theLeftBorder;
myRight = theRightBorder;
myLeft = theLeftBorder;
myRight = theRightBorder;
myIsBoundsDefined = Standard_True;
}
//=======================================================================
//function : Perform
//purpose :
//=======================================================================
//=================================================================================================
void math_NewtonMinimum::Perform(math_MultipleVarFunctionWithHessian& F,
const math_Vector& StartingPoint)
const math_Vector& StartingPoint)
{
math_Vector Point1 (1, F.NbVariables());
Point1 = StartingPoint;
math_Vector Point2(1, F.NbVariables());
math_Vector Point1(1, F.NbVariables());
Point1 = StartingPoint;
math_Vector Point2(1, F.NbVariables());
math_Vector* precedent = &Point1;
math_Vector* suivant = &Point2;
math_Vector* suivant = &Point2;
Standard_Boolean Ok = Standard_True;
Standard_Boolean Ok = Standard_True;
Standard_Integer NbConv = 0, ii, Nreduction;
Standard_Real VPrecedent, VItere;
Standard_Real VPrecedent, VItere;
Done = Standard_True;
Done = Standard_True;
TheStatus = math_OK;
nbiter = 0;
nbiter = 0;
while ( Ok && (NbConv < 2) ) {
while (Ok && (NbConv < 2))
{
nbiter++;
// Positionnement
Ok = F.Values(*precedent, VPrecedent, TheGradient, TheHessian);
if (!Ok) {
Done = Standard_False;
TheStatus = math_FunctionError;
return;
if (!Ok)
{
Done = Standard_False;
TheStatus = math_FunctionError;
return;
}
if (nbiter==1) {
PreviousMinimum = VPrecedent;
TheMinimum = VPrecedent;
if (nbiter == 1)
{
PreviousMinimum = VPrecedent;
TheMinimum = VPrecedent;
}
// Traitement de la non convexite
math_Jacobi CalculVP(TheHessian);
if ( !CalculVP.IsDone() ) {
Done = Standard_False;
TheStatus = math_FunctionError;
return;
if (!CalculVP.IsDone())
{
Done = Standard_False;
TheStatus = math_FunctionError;
return;
}
MinEigenValue = CalculVP.Values() ( CalculVP.Values().Min());
if ( MinEigenValue < CTol)
MinEigenValue = CalculVP.Values()(CalculVP.Values().Min());
if (MinEigenValue < CTol)
{
Convex = Standard_False;
if (NoConvexTreatement && // Treatment is allowed.
Abs (MinEigenValue) > CTol) // Treatment will have effect.
if (NoConvexTreatement && // Treatment is allowed.
Abs(MinEigenValue) > CTol) // Treatment will have effect.
{
Standard_Real Delta = CTol + 0.1 * Abs(MinEigenValue) - MinEigenValue;
for (ii=1; ii<=TheGradient.Length(); ii++)
for (ii = 1; ii <= TheGradient.Length(); ii++)
TheHessian(ii, ii) += Delta;
}
else
{
Done = Standard_False;
Done = Standard_False;
TheStatus = math_FunctionError;
return;
}
@@ -147,9 +141,10 @@ void math_NewtonMinimum::Perform(math_MultipleVarFunctionWithHessian& F,
// Schemas de Newton
math_Gauss LU(TheHessian, CTol/100);
if ( !LU.IsDone()) {
Done = Standard_False;
math_Gauss LU(TheHessian, CTol / 100);
if (!LU.IsDone())
{
Done = Standard_False;
TheStatus = math_DirectionSearchError;
return;
}
@@ -159,9 +154,9 @@ void math_NewtonMinimum::Perform(math_MultipleVarFunctionWithHessian& F,
{
// Project point on bounds or nullify TheStep coords if point lies on boundary.
*suivant = *precedent - TheStep;
*suivant = *precedent - TheStep;
Standard_Real aMult = RealLast();
for(Standard_Integer anIdx = 1; anIdx <= myLeft.Upper(); anIdx++)
for (Standard_Integer anIdx = 1; anIdx <= myLeft.Upper(); anIdx++)
{
const Standard_Real anAbsStep = Abs(TheStep(anIdx));
if (anAbsStep < gp::Resolution())
@@ -170,13 +165,13 @@ void math_NewtonMinimum::Perform(math_MultipleVarFunctionWithHessian& F,
if (suivant->Value(anIdx) < myLeft(anIdx))
{
Standard_Real aValue = Abs(precedent->Value(anIdx) - myLeft(anIdx)) / anAbsStep;
aMult = Min (aValue, aMult);
aMult = Min(aValue, aMult);
}
if (suivant->Value(anIdx) > myRight(anIdx))
{
Standard_Real aValue = Abs(precedent->Value(anIdx) - myRight(anIdx)) / anAbsStep;
aMult = Min (aValue, aMult);
aMult = Min(aValue, aMult);
}
}
@@ -191,10 +186,12 @@ void math_NewtonMinimum::Perform(math_MultipleVarFunctionWithHessian& F,
{
// Old point on border and new point out of border:
// Nullify corresponding TheStep indexes.
for(Standard_Integer anIdx = 1; anIdx <= myLeft.Upper(); anIdx++)
for (Standard_Integer anIdx = 1; anIdx <= myLeft.Upper(); anIdx++)
{
if ((Abs(precedent->Value(anIdx) - myRight(anIdx)) < Precision::PConfusion() && TheStep(anIdx) < 0.0) ||
(Abs(precedent->Value(anIdx) - myLeft(anIdx) ) < Precision::PConfusion() && TheStep(anIdx) > 0.0) )
if ((Abs(precedent->Value(anIdx) - myRight(anIdx)) < Precision::PConfusion()
&& TheStep(anIdx) < 0.0)
|| (Abs(precedent->Value(anIdx) - myLeft(anIdx)) < Precision::PConfusion()
&& TheStep(anIdx) > 0.0))
{
TheStep(anIdx) = 0.0;
}
@@ -217,52 +214,59 @@ void math_NewtonMinimum::Perform(math_MultipleVarFunctionWithHessian& F,
}
} while (hasProblem);
if (IsConverged()) { NbConv++; }
else { NbConv=0; }
if (IsConverged())
{
NbConv++;
}
else
{
NbConv = 0;
}
// Controle et corrections.
VItere = TheMinimum;
VItere = TheMinimum;
TheMinimum = PreviousMinimum;
Nreduction =0;
while (VItere > VPrecedent && Nreduction < 10) {
TheStep *= 0.4;
*suivant = *precedent - TheStep;
F.Value(*suivant, VItere);
Nreduction++;
Nreduction = 0;
while (VItere > VPrecedent && Nreduction < 10)
{
TheStep *= 0.4;
*suivant = *precedent - TheStep;
F.Value(*suivant, VItere);
Nreduction++;
}
if (VItere <= VPrecedent) {
math_Vector* auxiliaire = precedent;
precedent = suivant;
suivant = auxiliaire;
PreviousMinimum = VPrecedent;
TheMinimum = VItere;
Ok = (nbiter < Itermax);
if (!Ok && NbConv < 2) TheStatus = math_TooManyIterations;
}
else {
Ok = Standard_False;
TheStatus = math_DirectionSearchError;
if (VItere <= VPrecedent)
{
math_Vector* auxiliaire = precedent;
precedent = suivant;
suivant = auxiliaire;
PreviousMinimum = VPrecedent;
TheMinimum = VItere;
Ok = (nbiter < Itermax);
if (!Ok && NbConv < 2)
TheStatus = math_TooManyIterations;
}
else
{
Ok = Standard_False;
TheStatus = math_DirectionSearchError;
}
}
TheLocation = *precedent;
TheLocation = *precedent;
}
//=======================================================================
//function : Dump
//purpose :
//=======================================================================
void math_NewtonMinimum::Dump(Standard_OStream& o) const
//=================================================================================================
void math_NewtonMinimum::Dump(Standard_OStream& o) const
{
o<< "math_Newton Optimisation: ";
o << " Done =" << Done << std::endl;
o << "math_Newton Optimisation: ";
o << " Done =" << Done << std::endl;
o << " Status = " << (Standard_Integer)TheStatus << std::endl;
o << " Location Vector = " << Location() << std::endl;
o << " Minimum value = "<< Minimum()<< std::endl;
o << " Previous value = "<< PreviousMinimum << std::endl;
o << " Number of iterations = " <<NbIterations() << std::endl;
o << " Minimum value = " << Minimum() << std::endl;
o << " Previous value = " << PreviousMinimum << std::endl;
o << " Number of iterations = " << NbIterations() << std::endl;
o << " Convexity = " << Convex << std::endl;
o << " Eigen Value = " << MinEigenValue << std::endl;
}

View File

@@ -28,128 +28,106 @@
#include <Standard_OStream.hxx>
class math_MultipleVarFunctionWithHessian;
class math_NewtonMinimum
class math_NewtonMinimum
{
public:
DEFINE_STANDARD_ALLOC
//! The tolerance required on the solution is given by Tolerance.
//! Iteration are stopped if (!WithSingularity) and H(F(Xi)) is not definite
//! positive (if the smaller eigenvalue of H < Convexity)
//! or IsConverged() returns True for 2 successives Iterations.
//! Warning: This constructor does not perform computation.
Standard_EXPORT math_NewtonMinimum(const math_MultipleVarFunctionWithHessian& theFunction,
const Standard_Real theTolerance = Precision::Confusion(),
const Standard_Integer theNbIterations = 40,
const Standard_Real theConvexity = 1.0e-6,
const Standard_Real theTolerance = Precision::Confusion(),
const Standard_Integer theNbIterations = 40,
const Standard_Real theConvexity = 1.0e-6,
const Standard_Boolean theWithSingularity = Standard_True);
//! Search the solution.
Standard_EXPORT void Perform (math_MultipleVarFunctionWithHessian& theFunction, const math_Vector& theStartingPoint);
Standard_EXPORT void Perform(math_MultipleVarFunctionWithHessian& theFunction,
const math_Vector& theStartingPoint);
//! Destructor
Standard_EXPORT virtual ~math_NewtonMinimum();
//! This method is called at the end of each iteration to check the convergence:
//! || Xi+1 - Xi || < Tolerance or || F(Xi+1) - F(Xi)|| < Tolerance * || F(Xi) ||
//! It can be redefined in a sub-class to implement a specific test.
virtual Standard_Boolean IsConverged() const;
virtual Standard_Boolean IsConverged() const;
//! Tests if an error has occurred.
Standard_Boolean IsDone() const;
Standard_Boolean IsDone() const;
//! Tests if the Function is convexe during optimization.
Standard_Boolean IsConvex() const;
Standard_Boolean IsConvex() const;
//! returns the location vector of the minimum.
//! Exception NotDone is raised if an error has occurred.
const math_Vector& Location() const;
const math_Vector& Location() const;
//! outputs the location vector of the minimum in Loc.
//! Exception NotDone is raised if an error has occurred.
//! Exception DimensionError is raised if the range of Loc is not
//! equal to the range of the StartingPoint.
void Location (math_Vector& Loc) const;
void Location(math_Vector& Loc) const;
//! Set boundaries.
Standard_EXPORT void SetBoundary (const math_Vector& theLeftBorder, const math_Vector& theRightBorder);
Standard_EXPORT void SetBoundary(const math_Vector& theLeftBorder,
const math_Vector& theRightBorder);
//! returns the value of the minimum.
//! Exception NotDone is raised if the minimum was not found.
Standard_Real Minimum() const;
Standard_Real Minimum() const;
//! returns the gradient vector at the minimum.
//! Exception NotDone is raised if an error has occurred.
//! The minimum was not found.
const math_Vector& Gradient() const;
const math_Vector& Gradient() const;
//! outputs the gradient vector at the minimum in Grad.
//! Exception NotDone is raised if the minimum was not found.
//! Exception DimensionError is raised if the range of Grad is not
//! equal to the range of the StartingPoint.
void Gradient (math_Vector& Grad) const;
void Gradient(math_Vector& Grad) const;
//! returns the number of iterations really done in the
//! calculation of the minimum.
//! The exception NotDone is raised if an error has occurred.
Standard_Integer NbIterations() const;
Standard_Integer NbIterations() const;
//! Returns the Status of computation.
//! The exception NotDone is raised if an error has occurred.
math_Status GetStatus() const;
math_Status GetStatus() const;
//! Prints on the stream o information on the current state
//! of the object.
//! Is used to redefine the operator <<.
Standard_EXPORT void Dump (Standard_OStream& o) const;
Standard_EXPORT void Dump(Standard_OStream& o) const;
protected:
math_Status TheStatus;
math_Vector TheLocation;
math_Vector TheGradient;
math_Vector TheStep;
math_Matrix TheHessian;
Standard_Real PreviousMinimum;
Standard_Real TheMinimum;
Standard_Real MinEigenValue;
Standard_Real XTol;
Standard_Real CTol;
math_Status TheStatus;
math_Vector TheLocation;
math_Vector TheGradient;
math_Vector TheStep;
math_Matrix TheHessian;
Standard_Real PreviousMinimum;
Standard_Real TheMinimum;
Standard_Real MinEigenValue;
Standard_Real XTol;
Standard_Real CTol;
Standard_Integer nbiter;
Standard_Boolean NoConvexTreatement;
Standard_Boolean Convex;
Standard_Boolean myIsBoundsDefined;
math_Vector myLeft;
math_Vector myRight;
math_Vector myLeft;
math_Vector myRight;
private:
Standard_Boolean Done;
Standard_Integer Itermax;
};
#include <math_NewtonMinimum.lxx>
#endif // _math_NewtonMinimum_HeaderFile

View File

@@ -16,54 +16,54 @@
#include <StdFail_NotDone.hxx>
inline Standard_Boolean math_NewtonMinimum::IsConverged() const
inline Standard_Boolean math_NewtonMinimum::IsConverged() const
{
return ( (TheStep.Norm() <= XTol ) ||
( Abs(TheMinimum-PreviousMinimum) <= XTol * Abs(PreviousMinimum) ));
return ((TheStep.Norm() <= XTol)
|| (Abs(TheMinimum - PreviousMinimum) <= XTol * Abs(PreviousMinimum)));
}
inline Standard_Boolean math_NewtonMinimum::IsDone() const
inline Standard_Boolean math_NewtonMinimum::IsDone() const
{
return Done;
}
inline const math_Vector& math_NewtonMinimum::Location() const
inline const math_Vector& math_NewtonMinimum::Location() const
{
StdFail_NotDone_Raise_if(!Done, "NewtonMinimum");
return TheLocation;
StdFail_NotDone_Raise_if(!Done, "NewtonMinimum");
return TheLocation;
}
inline void math_NewtonMinimum::Location(math_Vector& Loc) const
inline void math_NewtonMinimum::Location(math_Vector& Loc) const
{
StdFail_NotDone_Raise_if(!Done, "NewtonMinimum");
Loc = TheLocation;
StdFail_NotDone_Raise_if(!Done, "NewtonMinimum");
Loc = TheLocation;
}
inline Standard_Real math_NewtonMinimum::Minimum() const
inline Standard_Real math_NewtonMinimum::Minimum() const
{
StdFail_NotDone_Raise_if(!Done, "NewtonMinimum");
return TheMinimum;
StdFail_NotDone_Raise_if(!Done, "NewtonMinimum");
return TheMinimum;
}
inline const math_Vector& math_NewtonMinimum::Gradient() const
inline const math_Vector& math_NewtonMinimum::Gradient() const
{
StdFail_NotDone_Raise_if(!Done, "NewtonMinimum");
return TheGradient;
StdFail_NotDone_Raise_if(!Done, "NewtonMinimum");
return TheGradient;
}
inline void math_NewtonMinimum::Gradient(math_Vector& Grad) const
inline void math_NewtonMinimum::Gradient(math_Vector& Grad) const
{
StdFail_NotDone_Raise_if(!Done, "NewtonMinimum");
Grad = TheGradient;
StdFail_NotDone_Raise_if(!Done, "NewtonMinimum");
Grad = TheGradient;
}
inline Standard_Integer math_NewtonMinimum::NbIterations() const
inline Standard_Integer math_NewtonMinimum::NbIterations() const
{
StdFail_NotDone_Raise_if(!Done, "NewtonMinimum");
return nbiter;
StdFail_NotDone_Raise_if(!Done, "NewtonMinimum");
return nbiter;
}
inline math_Status math_NewtonMinimum::GetStatus() const
inline math_Status math_NewtonMinimum::GetStatus() const
{
return TheStatus;
}

Some files were not shown because too many files have changed in this diff Show More