#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*
  ---------------------------------------------------------------------
     To compile and link with libraries:
       gcc -c direct.c
       g++ -c migrate.cc
       gcc -c YourMain.c (whatever you want to call it)
       g++ -o name_me direct.o migrate.cc YourMain.o libsearch.a -lgcc
  ---------------------------------------------------------------------
*/

int cpattrn(choice, obj, n, x, step1, step2, maxf, aux, iaux)
     int choice, n, maxf, *iaux;
     void (*obj) (double *, double *, long *);
     double x[], step1, step2, aux[];
{
  /*
    ---------------------------------------------------------------------
       This subroutine indirectly calls C++ libraries to perform 
       a pattern search given a user-defined objective function. It
       returns 1 if no error occurs. (For now, it always returns 1.)
  
       Arguments:
          choice - the search type
                   1 = Coordinate Search
                   2 = Compass Search
                   3 = NLess Search
                   4 = Hooke and Jeeves
                   5 = Hooke and Jeeves (edited by E. Dolan)
         obj     - the subroutine which contains the objective function;
                   The subroutine must have the following signature:
                   obj(x,f,n) - where x is the array of x values to 
                   evaluate, f holds the function evaluation, and n is
                   the dimension of the problem. 
          n      - dimension of the problem
          x      - double precision x (or array of x), which is the
                   starting point of the objective function
          step1  - starting step length (If -1, a default of 0.25 is used)
          step2  - ending step length (If -1, a default of 10E-8 is used)
          maxf   - the maximum allowable number of function evaluations
                   Set to -1 if no maximum is desired.
          aux    - the array of size n+2 returned from the library; the 
                   first value is the final step length, the second is 
                   the minimum function evaluation and the final n 
                   elements are the x values which correspond
          iaux   - returns the number of function evaluations required
  
    ---------------------------------------------------------------------
  */
  
  /* Declare the external routines */
  extern void coord_(int *, double *, double *, double *, int *,
                     int *, double *, int * ,
                     void (*)(double *, double *, long *));
  extern void compss_(int *, double *, double *, double *, int *,
                      int *, double *, int * ,
                      void (*)(double *, double *, long *));
  extern void nless_(int *, double *, double *, double *, int *,
                     int *, double *, int * , 
                     void (*)(double *, double *, long *));
  extern void hj_(int *, double *, double *, double *, int *,
                  int *, double *, int * , 
                  void (*)(double *, double *, long *));
  extern void edhj_(int *, double *, double *, double *, int *,
                    int *, double *, int * , 
                    void (*)(double *, double *, long *));
  int *istat, i;
  i = 0;
  istat = &i;

  if (choice == 1)
    coord_(&n, x, &step1, &step2, &maxf, istat, aux, iaux, obj);
  else if (choice == 2)
    compss_(&n, x, &step1, &step2, &maxf, istat, aux, iaux, obj);
  else if (choice == 3)
    nless_(&n, x, &step1, &step2, &maxf, istat, aux, iaux, obj);
  else if (choice == 4)
    hj_(&n, x, &step1, &step2, &maxf, istat, aux, iaux, obj);
  else if (choice == 5)
    edhj_(&n, x, &step1, &step2, &maxf, istat, aux, iaux, obj);
  else
    printf("\nThat was not a valid method\n");
  return *istat;
}

int cshh(obj, n, x, right, step1, step2, maxf, stddev, aux, iaux)
     int n, right, maxf, stddev, *iaux;
     void (*obj) (double *, double *, long *);
     double x[], step1[], step2, aux[]; 
{
  /*
    ---------------------------------------------------------------------
       This subroutine implements a simplex search based on the
       method of Spendley, Hext, and Himsworth given a user-defined 
       objective function
  
       Arguments:
          obj    - the subroutine which contains the objective function;
                   The subroutine must have the following signature:
                   obj(x,f,n) - where x is the array of x values to 
                   evaluate, f holds the function evaluation, and n is
                   the dimension of the problem. 
          n      - dimension of the problem
          x      - double precision x (or array of x), which is the
                   starting point of the objective function
          right  - a logical integer; If 1, the user wants a right
                   simplex. If 0, the user wants a regular simplex. 
          step1  - an array of the starting edgelengths of the simplex.
                   If the simplex is regular, only one element is
                   required. An array of n edgelengths is required for
                   a right simplex. Set the first element to -1 to use
                   the default values of 2.0 for the edgelengths.
          step2  - ending step length (If -1, a default of 10E-8 is used)  
          maxf   - the maximum allowable number of function evaluations
                   Set to -1 if no maximum is desired.
          stddev - a logical integer which tells the library whether or
                   not to use the standard deviation as a stopping
                   criterion. If 1, program will terminate if standard
                   deviation is less than step2. If 0, program will
                   terminate when delta is less than step2.
                   See Direct Search class design document for more info. 
          istat  - completion status (always 1, since search algorithms
                   have no criteria to stop them from going indefinitely)
          aux    - the array of size n+2 returned from the library; the 
                   first value is the final step length, the second is 
                   the minimum function evaluation and the final n 
                   elements are the x values which correspond
          iaux   - returns the number of function evaluations required
  
    ---------------------------------------------------------------------
  */
  /* Declare the external routines */
  extern void shhsch_(int *, double *, int *, double *, double *,
                      int *, int *, int *, double *, int * , 
                      void (*)(double *, double *, long *) );
  
  int *istat, i;
  i = 0;
  istat = &i;

  shhsch_(&n, x, &right, step1, &step2, &maxf, &stddev, istat, aux, iaux, obj);

  return *istat;
}

int cnm(obj, n, x, right, sigma, alpha, beta, gamma, step1, step2, maxf,
        stddev, aux, iaux)
     int n, right, maxf, stddev, *iaux;
     void (*obj) (double *, double *, long *);
     double x[], step1[], step2, aux[];
     double sigma, alpha, beta, gamma;
{
  /*
    ---------------------------------------------------------------------
       This subroutine implements a simplex search based on the
       method of Spendley, Hext, and Himsworth given a user-defined 
       objective function
  
       Arguments:
          obj    - the subroutine which contains the objective function;
                   The subroutine must have the following signature:
                   obj(x,f,n) - where x is the array of x values to 
                   evaluate, f holds the function evaluation, and n is
                   the dimension of the problem. 
          n      - dimension of the problem
          x      - double precision x (or array of x), which is the
                   starting point of the objective function
          right  - a logical integer; If 1, the user wants a right
                   simplex. If 0, the user wants a regular simplex. 
          sigma  - shrinking coeff   (If -1, a default of 0.5 is used.)  
          alpha  - reflection coeff  (If -1, a default of 1.0 is used.)
          beta   - contraction coeff (If -1, a default of 0.5 is used.)
          gamma  - expansion coeff   (If -1, a default of 2.0 is used.)
          step1  - an array of the starting edgelengths of the simplex.
                   If the simplex is regular, only one element is
                   required. An array of n edgelengths is required for
                   a right simplex. Set the first element to -1 to use
                   the default values of 2.0 for the edgelengths.
          step2  - ending step length (If -1, a default of 10E-8 is used)  
          maxf   - the maximum allowable number of function evaluations
                   Set to -1 if no maximum is desired.
          stddev - a logical integer which tells the library whether or
                   not to use the standard deviation as a stopping
                   criterion. If 1, program will terminate if standard
                   deviation is less than step2. If 0, program will
                   terminate when delta is less than step2.
                   See Direct Search class design document for more info. 
          istat  - completion status (always 1, since search algorithms
                   have no criteria to stop them from going indefinitely)
          aux    - the array of size n+2 returned from the library; the 
                   first value is the final step length, the second is 
                   the minimum function evaluation and the final n 
                   elements are the x values which correspond
          iaux   - returns the number of function evaluations required
  
  ---------------------------------------------------------------------
  */
  
  /* Declare the external routines */
  extern void nmsch_(int *, double *, int *, double *, double *,
                     double *, double *, double *, double *,
                     int *, int *, int *, double *, int * , 
                     void (*pt2Func)(double *, double *, long *) );
  
  int *istat, i;
  i = 0;
  istat = &i;

  nmsch_(&n, x, &right, &sigma, &alpha, &beta, &gamma, step1, &step2, &maxf,
         &stddev, istat, aux, iaux, obj);

  return *istat;
}

int csmd(obj, n, x, right, step1, step2, maxf, stddev, aux, iaux)
     int n, right, maxf, stddev, *iaux;
     void (*obj) (double *, double *, long *);
     double x[], step1[], step2, aux[]; 
{
  /*
    ---------------------------------------------------------------------
       This subroutine implements a simplex search based on the
       method of Spendley, Hext, and Himsworth given a user-defined 
       objective function
  
       Arguments:
          obj    - the subroutine which contains the objective function;
                   The subroutine must have the following signature:
                   obj(x,f,n) - where x is the array of x values to 
                   evaluate, f holds the function evaluation, and n is
                   the dimension of the problem. 
          n      - dimension of the problem
          x      - double precision x (or array of x), which is the
                   starting point of the objective function
          right  - a logical integer; If 1, the user wants a right
                   simplex. If 0, the user wants a regular simplex. 
          step1  - an array of the starting edgelengths of the simplex.
                   If the simplex is regular, only one element is
                   required. An array of n edgelengths is required for
                   a right simplex. Set the first element to -1 to use
                   the default values of 2.0 for the edgelengths.
          step2  - ending step length (If -1, a default of 10E-8 is used)  
          maxf   - the maximum allowable number of function evaluations
                   Set to -1 if no maximum is desired.
          stddev - a logical integer which tells the library whether or
                   not to use the standard deviation as a stopping
                   criterion. If 1, program will terminate if standard
                   deviation is less than step2. If 0, program will
                   terminate when delta is less than step2.
                   See Direct Search class design document for more info. 
          istat  - completion status (always 1, since search algorithms
                   have no criteria to stop them from going indefinitely)
          aux    - the array of size n+2 returned from the library; the 
                   first value is the final step length, the second is 
                   the minimum function evaluation and the final n 
                   elements are the x values which correspond
          iaux   - returns the number of function evaluations required
  
  ---------------------------------------------------------------------
  */
  
  /* Declare the external routines */
  extern void smdsch_(int *, double *, int *, double *, double *,
                     int *, int *, int *, double *, int * , 
                     void (*pt2Func)(double *, double *, long *) );
  
  int *istat, i;
  i = 0;
  istat = &i;

  smdsch_(&n, x, &right, step1, &step2, &maxf, &stddev, istat, aux, iaux, obj);

  return *istat;
}
