github.com/kaydxh/golang@v0.0.131/pkg/gocv/cgo/third_path/opencv4/include/opencv2/flann/simplex_downhill.h (about)

     1  /***********************************************************************
     2   * Software License Agreement (BSD License)
     3   *
     4   * Copyright 2008-2009  Marius Muja (mariusm@cs.ubc.ca). All rights reserved.
     5   * Copyright 2008-2009  David G. Lowe (lowe@cs.ubc.ca). All rights reserved.
     6   *
     7   * THE BSD LICENSE
     8   *
     9   * Redistribution and use in source and binary forms, with or without
    10   * modification, are permitted provided that the following conditions
    11   * are met:
    12   *
    13   * 1. Redistributions of source code must retain the above copyright
    14   *    notice, this list of conditions and the following disclaimer.
    15   * 2. Redistributions in binary form must reproduce the above copyright
    16   *    notice, this list of conditions and the following disclaimer in the
    17   *    documentation and/or other materials provided with the distribution.
    18   *
    19   * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
    20   * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
    21   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
    22   * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
    23   * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
    24   * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    25   * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    26   * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    27   * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
    28   * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    29   *************************************************************************/
    30  
    31  #ifndef OPENCV_FLANN_SIMPLEX_DOWNHILL_H_
    32  #define OPENCV_FLANN_SIMPLEX_DOWNHILL_H_
    33  
    34  //! @cond IGNORED
    35  
    36  namespace cvflann
    37  {
    38  
    39  /**
    40      Adds val to array vals (and point to array points) and keeping the arrays sorted by vals.
    41   */
    42  template <typename T>
    43  void addValue(int pos, float val, float* vals, T* point, T* points, int n)
    44  {
    45      vals[pos] = val;
    46      for (int i=0; i<n; ++i) {
    47          points[pos*n+i] = point[i];
    48      }
    49  
    50      // bubble down
    51      int j=pos;
    52      while (j>0 && vals[j]<vals[j-1]) {
    53          swap(vals[j],vals[j-1]);
    54          for (int i=0; i<n; ++i) {
    55              swap(points[j*n+i],points[(j-1)*n+i]);
    56          }
    57          --j;
    58      }
    59  }
    60  
    61  
    62  /**
    63      Simplex downhill optimization function.
    64      Preconditions: points is a 2D mattrix of size (n+1) x n
    65                      func is the cost function taking n an array of n params and returning float
    66                      vals is the cost function in the n+1 simplex points, if NULL it will be computed
    67  
    68      Postcondition: returns optimum value and points[0..n] are the optimum parameters
    69   */
    70  template <typename T, typename F>
    71  float optimizeSimplexDownhill(T* points, int n, F func, float* vals = NULL )
    72  {
    73      const int MAX_ITERATIONS = 10;
    74  
    75      CV_DbgAssert(n>0);
    76  
    77      T* p_o = new T[n];
    78      T* p_r = new T[n];
    79      T* p_e = new T[n];
    80  
    81      int alpha = 1;
    82  
    83      int iterations = 0;
    84  
    85      bool ownVals = false;
    86      if (vals == NULL) {
    87          ownVals = true;
    88          vals = new float[n+1];
    89          for (int i=0; i<n+1; ++i) {
    90              float val = func(points+i*n);
    91              addValue(i, val, vals, points+i*n, points, n);
    92          }
    93      }
    94      int nn = n*n;
    95  
    96      while (true) {
    97  
    98          if (iterations++ > MAX_ITERATIONS) break;
    99  
   100          // compute average of simplex points (except the highest point)
   101          for (int j=0; j<n; ++j) {
   102              p_o[j] = 0;
   103              for (int i=0; i<n; ++i) {
   104                  p_o[i] += points[j*n+i];
   105              }
   106          }
   107          for (int i=0; i<n; ++i) {
   108              p_o[i] /= n;
   109          }
   110  
   111          bool converged = true;
   112          for (int i=0; i<n; ++i) {
   113              if (p_o[i] != points[nn+i]) {
   114                  converged = false;
   115              }
   116          }
   117          if (converged) break;
   118  
   119          // trying a reflection
   120          for (int i=0; i<n; ++i) {
   121              p_r[i] = p_o[i] + alpha*(p_o[i]-points[nn+i]);
   122          }
   123          float val_r = func(p_r);
   124  
   125          if ((val_r>=vals[0])&&(val_r<vals[n])) {
   126              // reflection between second highest and lowest
   127              // add it to the simplex
   128              Logger::info("Choosing reflection\n");
   129              addValue(n, val_r,vals, p_r, points, n);
   130              continue;
   131          }
   132  
   133          if (val_r<vals[0]) {
   134              // value is smaller than smallest in simplex
   135  
   136              // expand some more to see if it drops further
   137              for (int i=0; i<n; ++i) {
   138                  p_e[i] = 2*p_r[i]-p_o[i];
   139              }
   140              float val_e = func(p_e);
   141  
   142              if (val_e<val_r) {
   143                  Logger::info("Choosing reflection and expansion\n");
   144                  addValue(n, val_e,vals,p_e,points,n);
   145              }
   146              else {
   147                  Logger::info("Choosing reflection\n");
   148                  addValue(n, val_r,vals,p_r,points,n);
   149              }
   150              continue;
   151          }
   152          if (val_r>=vals[n]) {
   153              for (int i=0; i<n; ++i) {
   154                  p_e[i] = (p_o[i]+points[nn+i])/2;
   155              }
   156              float val_e = func(p_e);
   157  
   158              if (val_e<vals[n]) {
   159                  Logger::info("Choosing contraction\n");
   160                  addValue(n,val_e,vals,p_e,points,n);
   161                  continue;
   162              }
   163          }
   164          {
   165              Logger::info("Full contraction\n");
   166              for (int j=1; j<=n; ++j) {
   167                  for (int i=0; i<n; ++i) {
   168                      points[j*n+i] = (points[j*n+i]+points[i])/2;
   169                  }
   170                  float val = func(points+j*n);
   171                  addValue(j,val,vals,points+j*n,points,n);
   172              }
   173          }
   174      }
   175  
   176      float bestVal = vals[0];
   177  
   178      delete[] p_r;
   179      delete[] p_o;
   180      delete[] p_e;
   181      if (ownVals) delete[] vals;
   182  
   183      return bestVal;
   184  }
   185  
   186  }
   187  
   188  //! @endcond
   189  
   190  #endif //OPENCV_FLANN_SIMPLEX_DOWNHILL_H_