packages feed

HaskellNN-0.1: src/AI/Training/Internal/lbfgs_aux.c

//_______________________________________________________________________________
//
//                             Author: Kiet Lam
//                             File lbfgs_aux.c
//_______________________________________________________________________________
// Last Updated: Time-stamp: <2012-01-18 23:41:52 (lam)>
//
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.


#include <lbfgs.h>
#include <stdio.h>


#define HASKELLARRAY(A) int A##n, double* A##p


typedef double (*fFunc) (int, const lbfgsfloatval_t*);
typedef int (*dfFunc) (int, const lbfgsfloatval_t*, int, lbfgsfloatval_t*);


typedef struct
{
  double (*f) (int, const lbfgsfloatval_t*);
  int (*df) (int, const lbfgsfloatval_t*, int, double*);
} FdfData;


lbfgsfloatval_t lbfgs_evaluate_aux (void* data,
                                    const lbfgsfloatval_t* x,
                                    lbfgsfloatval_t* g,
                                    const int n,
                                    const lbfgsfloatval_t step)
{
  FdfData* fdf = (FdfData*) data;
  fdf->df(n, x, n, g);
  return fdf->f(n, x);
}



int minimizeLBFGS (double precision, int max_iter, double init_step, double tol,
                   fFunc fun, dfFunc dfun, HASKELLARRAY(x), HASKELLARRAY(r))
{
  FdfData fdfDat;
  fdfDat.f = fun;
  fdfDat.df = dfun;

  lbfgs_parameter_t param;

  lbfgs_parameter_init(&param);

  param.epsilon = precision;
  param.max_iterations = max_iter;

  lbfgsfloatval_t* v = lbfgs_malloc(xn);

  int i;
  for (i = 0; i < xn; ++i)
    {
      v[i] = xp[i];
    }

  lbfgs(xn, v, NULL, lbfgs_evaluate_aux, NULL, &fdfDat, &param);

  int j;
  for (j = 0; j < xn; ++j)
    {
      rp[j] = v[j];
    }

  lbfgs_free(v);
}