Advertisement
msarahan

MKL fitting example

Dec 3rd, 2013
94
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.64 KB | None | 0 0
  1. //
  2. //  C-style wrapper for MinPack callback function
  3. //
  4. class FitFunctionWrapper
  5. {
  6. public:
  7.     static void FitFunction_MKL(MKL_INT *m, MKL_INT *n, double *x, double *f, void *priv)
  8.     {
  9.         if (priv)
  10.         {
  11.             CFitFunction* pFFObj = reinterpret_cast<CFitFunction*>(priv);
  12.             return pFFObj->MKL_Evaluate_function(m, n, x, f);
  13.         }
  14.     }
  15. };
  16.  
  17.  
  18. bool CFitFunction::MKL_Fit()
  19. {
  20.     /* n - number of function variables
  21.        m - dimension of function value */
  22.     MKL_INT         n = m_parameters.size(), m = m_data_size;
  23.     /* precisions for stop-criteria (see manual for more details) */
  24.     std::vector<double>eps(6,1E-8);
  25.  
  26.     /* iter1 - maximum number of iterations
  27.        iter2 - maximum number of iterations of calculation of trial-step */
  28.     MKL_INT         iter1 = m_max_iterations, iter2 = 100;
  29.     /* initial step bound */
  30.     double  rs = 1.0;
  31.     /* reverse communication interface parameter */
  32.     MKL_INT         RCI_Request;
  33.     /* controls of rci cycle */
  34.     MKL_INT         successful;
  35.     /* number of iterations */
  36.     MKL_INT         iter;
  37.     /* number of stop-criterion */
  38.     MKL_INT         st_cr;
  39.     /* initial and final residauls */
  40.     double r1=1E12, r2=1E12;
  41.     /* TR solver handle */
  42.     _TRNSPBC_HANDLE_t handle;
  43.     MKL_INT i;
  44.  
  45.     /* initial parameter values */
  46.     std::vector<double> pars = GetParameterValuesVector();
  47.  
  48.     // intermediate function values
  49.     std::vector<double> fvec(m_data_size,0);
  50.     // jacobi matrix
  51.     std::vector<double> fjac(m_data_size,0);
  52.  
  53.     /* lower and upper bounds */
  54.     std::vector<double> lowerBounds = GetLowerBoundsVector();
  55.     std::vector<double> upperBounds = GetUpperBoundsVector();
  56.  
  57.  
  58.     /* initialize solver (allocate mamory, set initial values)
  59.         handle  in/out: TR solver handle
  60.         n       in:     number of function variables
  61.         m       in:     dimension of function value
  62.         x       in:     solution vector. contains values x for f(x)
  63.         eps     in:     precisions for stop-criteria
  64.         iter1   in:     maximum number of iterations
  65.         iter2   in:     maximum number of iterations of calculation of trial-step
  66.         rs      in:     initial step bound */
  67.     if (dtrnlspbc_init (&handle, &n, &m, &pars[0], &lowerBounds[0], &upperBounds[0], &eps[0], &iter1, &iter2, &rs) !=
  68.         TR_SUCCESS)
  69.     {
  70.         /* if function does not complete successful then print error message */
  71.         DM::Debug("| error in dtrnlspbc_init\n");
  72.       /* Release internal MKL memory that might be used for computations         */
  73.       /* NOTE: It is important to call the routine below to avoid memory leaks   */
  74.       /* unless you disable MKL Memory Manager                                   */
  75.       MKL_FreeBuffers();
  76.         /* and exit */
  77.         return 0;
  78.     }
  79.     /* set initial rci cycle variables */
  80.     RCI_Request = 0;
  81.     successful = 0;
  82.     /* rci cycle */
  83.     while (successful == 0)
  84.     {
  85.         /* call tr solver
  86.             handle      in/out: tr solver handle
  87.             fvec        in:     vector
  88.             fjac        in:     jacobi matrix
  89.             RCI_request in/out: return number which denote next step for performing */
  90.         if (dtrnlspbc_solve (&handle, &fvec[0], &fjac[0], &RCI_Request) != TR_SUCCESS)
  91.         {
  92.             /* if function does not complete successful then print error message */
  93.             DM::Debug("| error in dtrnlspbc_solve\n");
  94.             /* Release internal MKL memory that might be used for computations         */
  95.             /* NOTE: It is important to call the routine below to avoid memory leaks   */
  96.             /* unless you disable MKL Memory Manager                                   */
  97.             MKL_FreeBuffers();
  98.             /* and exit */
  99.             return 0;
  100.         }
  101.         /* according with rci_request value we do next step */
  102.         if (RCI_Request == -1 ||
  103.             RCI_Request == -2 ||
  104.             RCI_Request == -3 ||
  105.             RCI_Request == -4 ||
  106.             RCI_Request == -5 ||
  107.             RCI_Request == -6)
  108.             /* exit rci cycle */
  109.             successful = 1;
  110.         if (RCI_Request == 1)
  111.         {
  112.             /* recalculate function value
  113.                 m       in:     dimension of function value
  114.                 n       in:     number of function variables
  115.                 x       in:     solution vector
  116.                 fvec    out:    function value f(x) */
  117.             MKL_Evaluate_function(&m, &n, &pars[0], &fvec[0]);
  118.         }
  119.         if (RCI_Request == 2)
  120.         {
  121.             /* compute jacobi matrix
  122.                 MKL_Evaluate_function   in:     external objective function
  123.                 n               in:     number of function variables
  124.                 m               in:     dimension of function value
  125.                 fjac            out:    jacobi matrix
  126.                 x               in:     solution vector
  127.                 jac_eps         in:     jacobi calculation precision */
  128.             if (djacobix (&FitFunctionWrapper::FitFunction_MKL, &n, &m, &fjac[0], &pars[0], &eps[0], (void *)this) != TR_SUCCESS)
  129.             {
  130.                 /* if function does not complete successful then print error message */
  131.                 DM::Debug("| error in djacobi\n");
  132.                 /* Release internal MKL memory that might be used for computations         */
  133.                 /* NOTE: It is important to call the routine below to avoid memory leaks   */
  134.                 /* unless you disable MKL Memory Manager                                   */
  135.                 MKL_FreeBuffers();
  136.                 /* and exit */
  137.                 return 0;
  138.             }
  139.         }
  140.     }
  141.     /* get solution statuses
  142.         handle            in:   TR solver handle
  143.         iter              out:  number of iterations
  144.         st_cr             out:  number of stop criterion
  145.         r1                out:  initial residuals
  146.         r2                out:  final residuals */
  147.     if (dtrnlspbc_get (&handle, &iter, &st_cr, &r1, &r2) != TR_SUCCESS)
  148.     {
  149.         /* if function does not complete successful then print error message */
  150.         DM::Debug("| error in dtrnlspbc_get\n");
  151.         /* Release internal MKL memory that might be used for computations         */
  152.         /* NOTE: It is important to call the routine below to avoid memory leaks   */
  153.         /* unless you disable MKL Memory Manager                                   */
  154.         MKL_FreeBuffers();
  155.         /* and exit */
  156.         return 0;
  157.     }
  158.     /* free handle memory */
  159.     if (dtrnlspbc_delete (&handle) != TR_SUCCESS)
  160.     {
  161.         /* if function does not complete successful then print error message */
  162.         DM::Debug("| error in dtrnlspbc_delete\n");
  163.         /* Release internal MKL memory that might be used for computations         */
  164.         /* NOTE: It is important to call the routine below to avoid memory leaks   */
  165.         /* unless you disable MKL Memory Manager                                   */
  166.         MKL_FreeBuffers();
  167.         /* and exit */
  168.         return 0;
  169.     }
  170.     SetParameterValues(pars);
  171.  
  172.     //bool converged = !m_abort_fit
  173.     fvec.clear();
  174.     fjac.clear();
  175.     eps.clear();
  176.     pars.clear();
  177.     lowerBounds.clear();
  178.     upperBounds.clear();
  179.  
  180.     /* Release internal MKL memory that might be used for computations         */
  181.     /* NOTE: It is important to call the routine below to avoid memory leaks   */
  182.     /* unless you disable MKL Memory Manager                                   */
  183.     MKL_FreeBuffers();
  184.  
  185.     // If we've gotten this far, then things worked.  Don't check the residual value as a means of convergence,
  186.     //    because we should always allow poor fits (it's pretty hard for us to get really excellent fits on
  187.     //    noisy data with not-completely-accurate models)
  188.     return 1;
  189. }
  190.  
  191. // MKL computes the Jacobian with this.  MKL uses OpenMP to compute this for multiple
  192. //     elements of the Jacobian simultaneously.  DO NOT use the ComputeFunctionValues function,
  193. //     as this would be changing the member temporary parameter values from multiple threads simultaneously.
  194. //     This function should be much more thread-friendly.
  195. void CFitFunction::MKL_Evaluate_function(MKL_INT *m, MKL_INT *n, double *x, double *f)
  196. {
  197.     for (MKL_INT i=0; i<*m; i++)
  198.     {
  199.         f[i]=(m_data_ptr[i]-FunctionValue(0,i,x))/m_errors_ptr[i];
  200.     }
  201. }
  202.  
  203. double CFitFunction::FunctionValue(ulong iValue, ulong i, double *pars)
  204. {
  205.     double N = pars[0];
  206.     double mu = pars[1];
  207.     double sigma = pars[2];
  208.     double x;
  209.     bool inROI;
  210.  
  211.     if (iValue != 0) return 0;
  212.     inROI=CalculateCoordinate(i,x);
  213.     if (!inROI && !GetCalculateOutsideROI()) return 0;
  214.  
  215.     double tmp = (x - mu)/sigma;
  216.     return N * exp( - tmp*tmp);
  217. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement