Back to home page

EIC code displayed by LXR

 
 

    


Warning, /include/opencascade/AppParCurves_Gradient.gxx is written in an unsupported language. File is not indexed.

0001 // Copyright (c) 1995-1999 Matra Datavision
0002 // Copyright (c) 1999-2014 OPEN CASCADE SAS
0003 //
0004 // This file is part of Open CASCADE Technology software library.
0005 //
0006 // This library is free software; you can redistribute it and/or modify it under
0007 // the terms of the GNU Lesser General Public License version 2.1 as published
0008 // by the Free Software Foundation, with special exception defined in the file
0009 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
0010 // distribution for complete text of the license and disclaimer of any warranty.
0011 //
0012 // Alternatively, this file may be used under the terms of Open CASCADE
0013 // commercial license or contractual agreement.
0014 
0015 // lpa, le 11/09/91
0016 
0017 
0018 // Application de la methode du gradient corrige pour minimiser 
0019 // F  = somme(||C(ui, Poles(ui)) - ptli||2.
0020 // La methode de gradient conjugue est programmee dans la bibliotheque 
0021 // mathematique: math_BFGS.
0022 // cet algorithme doit etre appele uniquement lorsque on a affaire a un set 
0023 // de points contraints (ailleurs qu aux extremites). En effet, l appel de la 
0024 // fonction F a minimiser implique un appel a ParLeastSquare et ResConstraint.
0025 // Si ce n est pas le cas, l appel a ResConstraint est equivalent a une 
0026 // seconde resolution par les moindres carres donc beaucoup de temps perdu.
0027 
0028 
0029 #define No_Standard_RangeError
0030 #define No_Standard_OutOfRange
0031 
0032 #include <AppParCurves_Constraint.hxx>
0033 #include <math_BFGS.hxx>
0034 #include <StdFail_NotDone.hxx>
0035 #include <AppParCurves_MultiPoint.hxx>
0036 #include <gp_Pnt.hxx>
0037 #include <gp_Pnt2d.hxx>
0038 #include <gp_Vec.hxx>
0039 #include <gp_Vec2d.hxx>
0040 #include <TColgp_Array1OfPnt.hxx>
0041 #include <TColgp_Array1OfPnt2d.hxx>
0042 #include <TColgp_Array1OfVec.hxx>
0043 #include <TColgp_Array1OfVec2d.hxx>
0044 #include <BSplCLib.hxx>
0045 #include <PLib.hxx>
0046 
0047 // #define AppParCurves_Gradient_BFGS BFGS_/**/AppParCurves_Gradient
0048 
0049 
0050 
0051 AppParCurves_Gradient::
0052    AppParCurves_Gradient(const MultiLine& SSP,
0053          const Standard_Integer FirstPoint,
0054          const Standard_Integer LastPoint,
0055          const Handle(AppParCurves_HArray1OfConstraintCouple)& TheConstraints,
0056          math_Vector& Parameters,
0057          const Standard_Integer Deg,
0058          const Standard_Real Tol3d,
0059          const Standard_Real Tol2d,
0060          const Standard_Integer NbIterations):
0061          ParError(FirstPoint, LastPoint,0.0),
0062          AvError(0.0),
0063          MError3d(0.0),
0064          MError2d(0.0)
0065 {
0066 
0067 //  Standard_Boolean grad = Standard_True;
0068   Standard_Integer j, k, i2, l;
0069   Standard_Real UF, DU, Fval = 0.0, FU, DFU;
0070   Standard_Integer nbP3d = ToolLine::NbP3d(SSP);
0071   Standard_Integer nbP2d = ToolLine::NbP2d(SSP);
0072   Standard_Integer mynbP3d=nbP3d, mynbP2d=nbP2d;
0073   Standard_Integer nbP = nbP3d + nbP2d;
0074 //  gp_Pnt Pt, P1, P2;
0075   gp_Pnt Pt;
0076 //  gp_Pnt2d Pt2d, P12d, P22d;
0077   gp_Pnt2d Pt2d;
0078 //  gp_Vec V1, V2, MyV;
0079   gp_Vec V1, MyV;
0080 //  gp_Vec2d V12d, V22d, MyV2d;
0081   gp_Vec2d V12d, MyV2d;
0082   Done = Standard_False;
0083   
0084   if (nbP3d == 0) mynbP3d = 1;
0085   if (nbP2d == 0) mynbP2d = 1;
0086   TColgp_Array1OfPnt TabP(1, mynbP3d);
0087   TColgp_Array1OfPnt2d TabP2d(1, mynbP2d);
0088   TColgp_Array1OfVec TabV(1, mynbP3d);
0089   TColgp_Array1OfVec2d TabV2d(1, mynbP2d);
0090 
0091   // Calcul de la fonction F= somme(||C(ui)-Ptli||2):
0092   // Appel a une fonction heritant de MultipleVarFunctionWithGradient
0093   // pour calculer F et grad_F.
0094   // ================================================================
0095 
0096   AppParCurves_ParFunction MyF(SSP, FirstPoint,LastPoint, TheConstraints, Parameters, Deg);
0097 
0098 
0099   if (!MyF.Value(Parameters, Fval)) {
0100     Done = Standard_False;
0101     return;
0102   }
0103 
0104   SCU = MyF.CurveValue();
0105   Standard_Integer deg = SCU.NbPoles()-1;
0106   TColgp_Array1OfPnt   TabPole(1, deg+1),   TabCoef(1, deg+1);
0107   TColgp_Array1OfPnt2d TabPole2d(1, deg+1), TabCoef2d(1, deg+1);
0108   TColgp_Array1OfPnt    TheCoef(1, (deg+1)*mynbP3d);
0109   TColgp_Array1OfPnt2d  TheCoef2d(1, (deg+1)*mynbP2d);
0110 
0111   
0112   // Stockage des Poles des courbes pour projeter:
0113   // ============================================
0114   i2 = 0;
0115   for (k = 1; k <= nbP3d; k++) {
0116     SCU.Curve(k, TabPole);
0117     BSplCLib::PolesCoefficients(TabPole, PLib::NoWeights(),
0118                                 TabCoef, PLib::NoWeights());
0119     for (j=1; j<=deg+1; j++) TheCoef(j+i2) = TabCoef(j);
0120     i2 += deg+1;
0121   }
0122   i2 = 0;
0123   for (k = 1; k <= nbP2d; k++) {
0124     SCU.Curve(nbP3d+k, TabPole2d);
0125     BSplCLib::PolesCoefficients(TabPole2d, PLib::NoWeights(),
0126                                 TabCoef2d, PLib::NoWeights());
0127     for (j=1; j<=deg+1; j++) TheCoef2d(j+i2) = TabCoef2d(j);
0128     i2 += deg+1;
0129   }
0130 
0131   //  Une iteration rapide de projection est faite par la methode de 
0132   //  Rogers & Fog 89, methode equivalente a Hoschek 88 qui ne necessite pas
0133   //  le calcul de D2.
0134 
0135 
0136   // Iteration de Projection:
0137   // =======================
0138   for (j = FirstPoint+1; j <= LastPoint-1; j++) {
0139     UF = Parameters(j);
0140     if (nbP != 0 && nbP2d != 0) ToolLine::Value(SSP, j, TabP, TabP2d);
0141     else if (nbP2d != 0)        ToolLine::Value(SSP, j, TabP2d);
0142     else                        ToolLine::Value(SSP, j, TabP);
0143     
0144     FU = 0.0;
0145     DFU = 0.0;
0146     i2 = 0;
0147     for (k = 1; k <= nbP3d; k++) {
0148       for (l=1; l<=deg+1; l++) TabCoef(l) = TheCoef(l+i2);
0149       i2 += deg+1;
0150       BSplCLib::CoefsD1(UF, TabCoef, BSplCLib::NoWeights(), Pt, V1);
0151       MyV = gp_Vec(Pt, TabP(k));
0152       FU += MyV*V1;
0153       DFU += V1.SquareMagnitude();
0154     }
0155     i2 = 0;
0156     for (k = 1; k <= nbP2d; k++) {
0157       for (l=1; l<=deg+1; l++) TabCoef2d(l) = TheCoef2d(l+i2);
0158       i2 += deg+1;
0159       BSplCLib::CoefsD1(UF, TabCoef2d, BSplCLib::NoWeights(), Pt2d, V12d);
0160       MyV2d = gp_Vec2d(Pt2d, TabP2d(k));
0161       FU += MyV2d*V12d;
0162       DFU += V12d.SquareMagnitude();
0163     }
0164     
0165     if (DFU >= RealEpsilon()) {
0166       DU = FU/DFU;
0167       DU = Sign(Min(5.e-02, Abs(DU)), DU);
0168       UF += DU;
0169       Parameters(j) = UF;
0170     }
0171   }
0172 
0173   
0174   if (!MyF.Value(Parameters, Fval)) {
0175     SCU = AppParCurves_MultiCurve();
0176     Done = Standard_False;
0177     return;
0178   }
0179   MError3d = MyF.MaxError3d();
0180   MError2d = MyF.MaxError2d();
0181   
0182   if (MError3d<= Tol3d && MError2d <= Tol2d) {
0183     Done = Standard_True;
0184     SCU = MyF.CurveValue();
0185   }
0186   else if (NbIterations != 0) {
0187     // NbIterations de gradient conjugue:
0188     // =================================
0189     Standard_Real Eps = 1.e-07;
0190     AppParCurves_Gradient_BFGS FResol(MyF, Parameters, Tol3d, Tol2d, Eps, NbIterations);
0191     Parameters = MyF.NewParameters();
0192     SCU = MyF.CurveValue();
0193   }
0194 
0195     
0196   AvError = 0.;
0197   for (j = FirstPoint; j <= LastPoint; j++) {  
0198     // Recherche des erreurs maxi et moyenne a un index donne:
0199     for (k = 1; k <= nbP; k++) {
0200       ParError(j) = Max(ParError(j), MyF.Error(j, k));
0201     }
0202     AvError += ParError(j);
0203   }
0204   AvError = AvError/(LastPoint-FirstPoint+1);
0205 
0206 
0207   MError3d = MyF.MaxError3d();
0208   MError2d = MyF.MaxError2d();
0209   if (MError3d <= Tol3d && MError2d <= Tol2d) {
0210     Done = Standard_True;
0211   }
0212 
0213 }
0214 
0215 
0216 
0217 AppParCurves_MultiCurve AppParCurves_Gradient::Value() const {
0218   return SCU;
0219 }
0220 
0221 
0222 Standard_Boolean AppParCurves_Gradient::IsDone() const {
0223   return Done;
0224 }
0225 
0226 
0227 Standard_Real AppParCurves_Gradient::Error(const Standard_Integer Index) const {
0228   return ParError(Index);
0229 }
0230 
0231 Standard_Real AppParCurves_Gradient::AverageError() const {
0232   return AvError;
0233 }
0234 
0235 Standard_Real AppParCurves_Gradient::MaxError3d() const {
0236   return MError3d;
0237 }
0238 
0239 Standard_Real AppParCurves_Gradient::MaxError2d() const {
0240   return MError2d;
0241 }
0242 
0243