/* The easiest way to pull in all necessary definitions is to include OCT/src/oct.h */ #include #include /* Overwrite type names duplicated in Octave and NAG header files */ #define Complex NagComplex #define MatrixType NagMatrixType // and to include the appropriate NAG header files #include #include extern "C" { static void objfunC(Integer n, double x[], double *objf, double objgrd[], Nag_Comm *comm); static void confunC(Integer n, Integer ncnlin, Integer needc[], double x[], double conf[], double conjac[], Nag_Comm *comm); } // The third parameter (nargout) is not used, so it is // omitted from the list of arguments to DEFUN_DLD in order to avoid // the warning from gcc about an unused function parameter. DEFUN_DLD (nag_opt2, args, , "Calls nag_opt_nlp (e04ucc), which minimizes an arbitrary smooth function \n\ subject to constraints using a sequential quadratic programming (SQP) method.\n\ As many first derivatives as possible should be supplied by you; \n\ any unspecified derivatives are approximated by finite differences. \n\ It is not intended for large sparse problems.\n\ nag_opt_nlp (e04ucc) may also be used for unconstrained, bound-constrained \n\ and linearly constrained optimization.\n") { // Variable to store function output values octave_value_list retval; int nargin = args.length (); if (nargin != 10) { error ("Insufficient input arguments."); } else { // Retrieve input arguments from args Integer n = args(0).int_value(); Integer nclin = args(1).int_value(); Integer ncnlin = args(2).int_value(); Matrix a(args(3).matrix_value()); Integer tda = args(4).int_value(); NDArray bl(args(5).array_value()); NDArray bu(args(6).array_value()); struct fcnptrs {octave_function *obj, *con;} fcns; fcns.obj = args(7).function_value(); fcns.con = args(8).function_value(); NDArray x(args(9).array_value()); dim_vector dv (1); dv(0) = n; NDArray objgrd(dv); if (! error_state) { // Declare local variables double objf=0.0; Nag_Comm comm; NagError fail; INIT_FAIL(fail); // Store Octave functions handles in communication structure comm comm.p = (Pointer) &fcns; // Call NAG routine /* nag_opt_nlp (e04ucc). * Minimization with nonlinear constraints using a * sequential QP method */ nag_opt_nlp(n, nclin, ncnlin, a.fortran_vec(), tda, bl.fortran_vec(), bu.fortran_vec(),objfunC, confunC, x.fortran_vec(),&objf, objgrd.fortran_vec(), E04_DEFAULT, &comm, &fail); /* T* fortran_vec (void) method returns a pointer to the underlying data of the matrix or a array so that it can be manipulated directly by an external library. */ if (fail.code != NE_NOERROR) { error("Error from nag_opt_nlp (e04ucc).\n%s\n", fail.message); goto END; } // Assign output arguments to retval retval(0) = objf; retval(1) = objgrd; retval(2) = fail.code; } } END: return retval; } static void objfunC(Integer n, double x[], double *objf, double objgrd[], Nag_Comm *comm) { // Retrieve Octave objfun handle struct fcnptrs {octave_function *obj, *con;} *fcns; fcns = (struct fcnptrs *) comm->p; octave_function *fcn = (octave_function *) fcns->obj; // Copy C arrays into the Octave type ones dim_vector dv (1); dv(0) = n; NDArray x_oct(dv), objgrd_oct(dv); octave_idx_type i; for (i=0;iflag); newargs(1)=octave_value(x_oct); newargs(2)=octave_value(*objf); newargs(3)=octave_value(objgrd_oct); int nargout=2; // Call Octave objfun function retval=feval(fcn,newargs,nargout); // Retrieve output arguments from retval *objf=retval(0).double_value(); objgrd_oct = retval(1).array_value(); // Copy output arrays back into C type arrays for (i=0;ip; octave_function *fcn = (octave_function *) fcns->con; // Copy C arrays into the Octave type arrays and matrices dim_vector dv (1); dv(0) = ncnlin; dim_vector dv2 (1); dv2(0) = n; NDArray needc_oct(dv), conf_oct(dv), x_oct(dv2); Matrix conjac_oct(ncnlin,n); octave_idx_type i,j; for (i=0;iflag); newargs(1)=octave_value(ncnlin); newargs(2)=octave_value(n); newargs(3)=octave_value(needc_oct); newargs(4)=octave_value(x_oct); newargs(5)=octave_value(conjac_oct); newargs(6)=octave_value(comm->first); int nargout=2; // Call Octave confun function retval=feval(fcn,newargs,nargout); // Retrieve output arguments from retval conf_oct=retval(0).array_value(); conjac_oct = retval(1).matrix_value(); // Copy output arrays and matrices back into C type arrays for (i=0;i