几何尺寸与公差论坛

 找回密码
 注册
查看: 209|回复: 2

PR #252185 2D best fit, least squares gives too much error

[复制链接]
发表于 2008-3-19 10:42:30 | 显示全部楼层 |阅读模式
<< Beatriz Beraza  --  12/12/07  16:16:11>>
After a CAD= part aligment I use a 2D Best Fit aligment, least squares method. "Rotate and translate" and "translate only"
give errors of milimeters, the result after best fitting is much worse than before.
"Rotate only" option gives this error: "Error in A3".
See 2 example programs attached.
<<END>>
 楼主| 发表于 2008-3-19 10:42:43 | 显示全部楼层

回复: PR #252185 2D best fit, least squares gives too much error

<< Dan Zwick  --  12/17/07  09:43:54>>
Beatriz, since I can't reproduce the CAD=PART problem and the fix I uploaded for the other problem may well have solved this problem as well, I'm going to set this PR as Resolved for the time being. If you think the problem still exists, please upload new part programs clearly demonstrating it.
<<END>>

<< Changes made by Dan Zwick -- 12/17/07  09:44:22>>
Status:  MOREINFO to RESOLVED
<<END>>

<< Dan Zwick  --  12/14/07  10:22:31>>
I uploaded these files to 4.4B as well.
<<END>>

<< Dan Zwick  --  12/13/07  14:48:19>>
Additional files uploaded:
V43R\INFODEFALIGNMENT\info deficient.cpp
V43R\INFODEFALIGNMENT\INFO DEFICIENT.H
V43R\INFODEFALIGNMENT\newuoa.cpp
and dependencies.
<<END>>

<< Dan Zwick  --  12/13/07  13:10:53>>
I fixed the rotate only problem. I had to add a 1D minimizer for this one case: rotate only, no scaling, initial values supplied. This case is not currently being used (no initial values), but it could be in the future. In all other cases of rotate only the result was already correct but the return code was wrong.
Files uploaded so far:
V43B\INFODEFALIGNMENT\info deficient.cpp
V43B\INFODEFALIGNMENT\INFO DEFICIENT.H
V43B\INFODEFALIGNMENT\newuoa.cpp
and dependencies.
<<END>>

<< Dan Zwick  --  12/12/07  18:47:23>>
Hi Beatriz, I'm not sure what the two part programs represent. It looks to me like they both have CAD = PART set when the BF alignment is done. In any case, when I force a recompute of the rotate and translate alignment, I get good results in both cases. This leads me to believe that this problem may already be fixed. Would it be possible for you to try this with the latest 4.2R? In the meantime I'll continue to work on the Rotate Only bug, which has turned out to be not as trivial as I thought.
(Email with this text sent.)
<<END>>

<< Changes made by Dan Zwick -- 12/12/07  18:50:38>>
Action:  Dan Zwick to Beatriz Beraza, Status:  OPEN to MOREINFO
<<END>>

<< Changes made by Tim Wernicke -- 12/12/07  19:31:53>>
Action:  Dan Kurtz to Dan Zwick
<<END>>

<< Changes made by Tim Wernicke -- 12/12/07  16:48:15>>
Action:  Tim Wernicke to Dan Kurtz, Assigned:   to Dan Zwick, Priority:  to Stop Rel.
<<END>>

<< Dan Zwick  --  12/12/07  12:25:30>>
Rotate only with 2D data does generate an error message. This is a bug, but it's easy to fix. As for the rotate and translate alignment, I get good results when I force a recompute with F9 in both part programs. I wonder if you have the latest alignment code. There were a couple of fixes recently that may not yet have made it into the FIT version.
<<END>>

<< Dan Zwick  --  12/12/07  12:07:59>>
I'll take a look at this.
<<END>>
 楼主| 发表于 2008-3-19 11:03:50 | 显示全部楼层

回复: PR #252185 2D best fit, least squares gives too much error

1. V43R\INFODEFALIGNMENT\info deficient.cpp
  zeroVector(3,Xbar);
2. V43R\INFODEFALIGNMENT\newuoa.cpp
/*---------------------------------------------------------------------
* Brent's one-dimensional minimizer finds a local minimum of a single
*      argument function over a given range.
* Input
*      double fminbr(ax,bx,f,tol)
*      const double ax                 a and b, a < b, specify the interval
*      const double bx                 the minimum is to be sought in
*      UnivariateFunctor& f            The function under consideration
*      const double tol                Acceptable tolerance for the minimum
*                                      location. It is an optional parameter
*                                      with default value DBL_EPSILON
* Output
*      Fminbr returns an estimate to the location of the minimum
*      with accuracy 3*SQRT_EPSILON*abs(x) + tol.
*      The procedure can only determine a local minimum, which coincides with
*      the global one if and only if the function under investigation is
*      unimodular.
*      If a function being examined possesses no local minimum within
*      the given interval, Fminbr returns either the left or the right end
*      point of the interval, wherever the function value is smaller.
* Algorithm
*      G.Forsythe, M.Malcolm, C.Moler, Computer methods for mathematical
*      computations. M., Mir, 1980, p.202 of the Russian edition
* The function makes use of a "golden section" procedure combined with
* a parabolic interpolation.
* At each step the code operates three abscissas - x,v, and w.
*      x - the last and the best approximation to the minimum location,
*      i.e. f(x) <= f(a) or/and f(x) <= f(b)
*      if the function f has a local minimum in (a,b), then both
*      conditions are met after one or two steps).
*      v,w are previous approximations to the location of the minimum.
*      They may coincide with a, b, or x (although the algorithm tries
*      to make all u, v, and w distinct).
* Points x, v, and w are used to construct an interpolating parabola,
* whose minimum is regarded as a new approximation to the minimum
* of the function, provided the parabola's minimum falls within [a,b]
* and reduces the current interval [a,b] to a larger extent than the
* gold section procedure does.
* When f(x) has a positive second derivative at the point of minimum
* (which does not coincide with a or b) the procedure converges
* superlinearly at a rate of about 1.324
------------------------------------------------------------------------*/
#define DBL_EPSILON   2.22045e-16
#define SQRT_EPSILON  1.49012e-08
int CInfoDef::fminbr(const double ax, const double bx, /* double (*calfun1)(double x),*/ const double tol,         
                     double *xmin) // xmin is min abscissa
{
  if (tol <= 0)  // Tolerance must be positive.
    return -1;
  if (ax >= bx)  // Left end point of the interval should be strictly less than the
    return -2;   // right one.
  static const double r = (3. - sqrt(5.)) / 2.; // The golden section ratio
  static const double sqrt_eps = SQRT_EPSILON;
  double a = ax, b = bx;                // Current interval
  double v = a + r * (b - a);           // First step - always golden section
  double fv = calfun1(v);
  double x = v;                         // the last and the best approximation
  double fx = fv;
  double w = v;                         // a previous approx to the min
  double fw = fv;
  for (;;) // Main iteration loop.
  {
    const double range = b - a;         // Interval where the minimum is sought.
    const double midpoint = (a + b) / 2.;
    const double tol_act =              // The effective tolerance.
      sqrt_eps * fabs(x) + tol / 3.;
    if (2. * fabs(x - midpoint) + range <= 4. * tol_act)
    {
      *xmin = x;                        // Acceptable approximation is found.
      if (fabs(x - ax) < tol_act)
        return 1;
      else if (fabs(x - bx) < tol_act)
        return 2;
      else
        return 0;                        
    }
    // Compute a new step with the golden section.
    double new_step = r * (x < midpoint ? b - x : a - x);
    // Decide on the interpolation.
    if (fabs(x - w) >= tol_act)         // If x and w are distinct, interpolation may be tried.
    {                                    
      register double p;                // Interpolation step is calculated as p/q; division operation
      register double q;                // is delayed until last moment.
      register double t;                 
      t = (x - w) * (fx - fv);
      q = (x - v) * (fx - fw);
      p = (x - v) * q - (x - w) * t;
      q = 2 * (q - t);
      if (q > 0 )                       // Formulas above computed new_step
        p = -p;                         // = p/q with a wrong sign (on purpose).
      else                              // Correct this, but in such a way so
        q = -q;                         // that q would be positive
      if (fabs(p) < fabs(new_step * q) &&    // If x+p/q falls in [a,b] and is not
        p > q * (a - x + 2. * tol_act) &&  // too close to a and b, and isn't
        p < q * (b - x - 2. * tol_act))    // too large, it is accepted
        new_step = p / q;
      // If p/q is too large then the golden section procedure would
      // reduce [a,b] to larger extent.
    }
    if (fabs(new_step) < tol_act)       // Adjust the step to be not less than tolerance.
      new_step =  new_step > 0 ? tol_act : -tol_act;
    // Obtain the next approximation to min and reduce the encompassing interval.
    register const double t = x + new_step;  // Tentative point for the min
    register const double ft = calfun1(t);
    if (ft <= fx)
    {                                   // t is a better approximation.
      (t < x ? b : a) = x;              // Reduce the interval so that
      v = w;                            // t would fall within it.
      w = x;
      x = t;                           // Assign the best approx to x.
      fv = fw;
      fw = fx;
      fx = ft;
    }
    else                                // x remains the better approx.
    {
      (t < x ? a : b ) = t;             // Reduce the interval encompassing x.
      if (ft <= fw || w == x)
      {
        v = w;
        w = t;
        fv = fw;
        fw = ft;
      }
      else if (ft <= fv || v == x || v == w)
        v = t, fv = ft;
    }
  }
} // end fminbr
您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|Archiver|小黑屋|几何尺寸与公差论坛

GMT+8, 2024-12-22 18:11 , Processed in 0.039145 second(s), 19 queries .

Powered by Discuz! X3.4 Licensed

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表