mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-05 18:16:23 +03:00
License statement text corrected; compiler warnings caused by Bison 2.41 disabled for MSVC; a few other compiler warnings on 54-bit Windows eliminated by appropriate type cast Wrong license statements corrected in several files. Copyright and license statements added in XSD and GLSL files. Copyright year updated in some files. Obsolete documentation files removed from DrawResources.
250 lines
6.9 KiB
C++
250 lines
6.9 KiB
C++
// Copyright (c) 1997-1999 Matra Datavision
|
|
// Copyright (c) 1999-2014 OPEN CASCADE SAS
|
|
//
|
|
// This file is part of Open CASCADE Technology software library.
|
|
//
|
|
// This library is free software; you can redistribute it and/or modify it under
|
|
// the terms of the GNU Lesser General Public License version 2.1 as published
|
|
// by the Free Software Foundation, with special exception defined in the file
|
|
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
|
// distribution for complete text of the license and disclaimer of any warranty.
|
|
//
|
|
// Alternatively, this file may be used under the terms of Open CASCADE
|
|
// commercial license or contractual agreement.
|
|
|
|
//#ifndef DEB
|
|
#define No_Standard_RangeError
|
|
#define No_Standard_OutOfRange
|
|
#define No_Standard_DimensionError
|
|
//#endif
|
|
|
|
#include <math_FRPR.ixx>
|
|
|
|
#include <math_BracketMinimum.hxx>
|
|
#include <math_BrentMinimum.hxx>
|
|
#include <math_Function.hxx>
|
|
#include <math_MultipleVarFunction.hxx>
|
|
#include <math_MultipleVarFunctionWithGradient.hxx>
|
|
|
|
// l'utilisation de math_BrentMinumim pur trouver un minimum dans une direction
|
|
// 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 {
|
|
|
|
math_Vector *P0;
|
|
math_Vector *Dir;
|
|
math_Vector *P;
|
|
math_MultipleVarFunction *F;
|
|
|
|
public :
|
|
|
|
DirFunctionTer(math_Vector& V1,
|
|
math_Vector& V2,
|
|
math_Vector& V3,
|
|
math_MultipleVarFunction& f);
|
|
|
|
void Initialize(const math_Vector& p0, const math_Vector& dir);
|
|
|
|
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;
|
|
}
|
|
|
|
void DirFunctionTer::Initialize(const math_Vector& p0,
|
|
const math_Vector& dir) {
|
|
|
|
*P0 = p0;
|
|
*Dir = dir;
|
|
}
|
|
|
|
Standard_Boolean DirFunctionTer::Value(const Standard_Real x, Standard_Real& fval) {
|
|
|
|
*P = *Dir;
|
|
P->Multiply(x);
|
|
P->Add(*P0);
|
|
F->Value(*P, fval);
|
|
return Standard_True;
|
|
}
|
|
|
|
static Standard_Boolean MinimizeDirection(math_Vector& P,
|
|
math_Vector& Dir,
|
|
Standard_Real& Result,
|
|
DirFunctionTer& F) {
|
|
|
|
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(F, ax, xx, bx, 1.0e-10, 100);
|
|
if(Sol.IsDone()) {
|
|
Standard_Real Scale = Sol.Location();
|
|
Result = Sol.Minimum();
|
|
Dir.Multiply(Scale);
|
|
P.Add(Dir);
|
|
return Standard_True;
|
|
}
|
|
}
|
|
return Standard_False;
|
|
}
|
|
|
|
|
|
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(!IsGood) {
|
|
Done = Standard_False;
|
|
TheStatus = math_DirectionSearchError;
|
|
return;
|
|
}
|
|
if(IsSolutionReached(F)) {
|
|
Done = Standard_True;
|
|
State = F.GetStateNumber();
|
|
TheStatus = math_OK;
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
Standard_Boolean math_FRPR::IsSolutionReached(
|
|
// math_MultipleVarFunctionWithGradient& F) {
|
|
math_MultipleVarFunctionWithGradient& ) {
|
|
|
|
return (2.0 * fabs(TheMinimum - PreviousMinimum)) <=
|
|
XTol * (fabs(TheMinimum) + fabs(PreviousMinimum) + EPSZ);
|
|
}
|
|
|
|
math_FRPR::math_FRPR(math_MultipleVarFunctionWithGradient& F,
|
|
const math_Vector& StartingPoint,
|
|
const Standard_Real Tolerance,
|
|
const Standard_Integer NbIterations,
|
|
const Standard_Real ZEPS)
|
|
: TheLocation(1, StartingPoint.Length()),
|
|
TheGradient(1, StartingPoint.Length()) {
|
|
|
|
XTol = Tolerance;
|
|
EPSZ = ZEPS;
|
|
Itermax = NbIterations;
|
|
Perform(F, StartingPoint);
|
|
}
|
|
|
|
|
|
math_FRPR::math_FRPR(math_MultipleVarFunctionWithGradient& F,
|
|
const Standard_Real Tolerance,
|
|
const Standard_Integer NbIterations,
|
|
const Standard_Real ZEPS)
|
|
: TheLocation(1, F.NbVariables()),
|
|
TheGradient(1, F.NbVariables()) {
|
|
|
|
XTol = Tolerance;
|
|
EPSZ = ZEPS;
|
|
Itermax = NbIterations;
|
|
}
|
|
|
|
|
|
void math_FRPR::Delete()
|
|
{}
|
|
|
|
void math_FRPR::Dump(Standard_OStream& o) const {
|
|
|
|
o << "math_FRPR ";
|
|
if(Done) {
|
|
o << " Status = Done \n";
|
|
o << " Location Vector = "<< TheLocation << "\n";
|
|
o << " Minimum value = " << TheMinimum <<"\n";
|
|
o << " Number of iterations = " << Iter <<"\n";
|
|
}
|
|
else {
|
|
o << " Status = not Done because " << (Standard_Integer)TheStatus << "\n";
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|