/* mat_gcvspl.c
 * Usage: [C, W, IER] = gcvspl(X, Y, NY, WX, WY, M, N, K, MD, VAL, NC);
 * 
 * This is a MEX file (C program compiled by MATLAB)
 * which calls the C function GCVSPL, Woltring's natural B-spline
 * data smoothing subroutine using generalized cross-validation
 * and mean-squared prediction error criteria of Craven and Wahba (1979).
 * 
 * The mex file outputted by the CMEX complier will be renamed "gcvspl.mexsg"
 * which is easier to type (and makes the gateway seem seamless to the user--
 * i.e. the user thinks that he/she is calling the actual C subroutine when in
 * fact this program is called which in turn calls the actual C subroutine).
 * 
 * An explanation of the subroutine and arguments can be found in the file called
 * gcvspl.m
 * 
 * Tony Reina                               Created: 4/2/1998
 * The Neurosciences Institute,  San Diego,  CA
 * Motor Control Research Laboratory
 * 
 * Updates:
 * 4/6/1998 by GAR
 * 
 * To compile use the CMEX compiler:
 *      cmex mat_gcvspl.c gcvspl.c -output gcvspl.mexsg
 */
#include <strings.h>
#include "mex.h"

void mexFunction(   int nlhs, 
                    mxArray *plhs[], 
                    int nrhs, 
                    const mxArray *prhs[] )
                    
{
    double *X, *Y, *WX, *WY, *VAL, *C, *WK;
    int NY, M, N, K, MD, NC, IER;
    int dims[2] = {1, 1};
    
    /* Verify that there are 11 variables passed into the function */
    /* rhs = right-hand side = input variables */
    if (nrhs != 11) {
        mexErrMsgTxt(strcat("Insufficient number of passed arguments.\n", 
            "Type 'help gcvspl' to obtain more information on this function.\n"));
    }
  
    X = mxGetPr(prhs[0]);
    Y = mxGetPr(prhs[1]);
    NY = (int) (mxGetScalar(prhs[2]));
    WX = mxGetPr(prhs[3]);
    WY = mxGetPr(prhs[4]);
    M = (int) (mxGetScalar(prhs[5]));
    N = (int) (mxGetScalar(prhs[6]));
    K = (int) (mxGetScalar(prhs[7]));
    MD = (int) (mxGetScalar(prhs[8]));    
    VAL = mxGetPr(prhs[9]);
    NC = (int) (mxGetScalar(prhs[10]));
   
    /* This declares the memory space in MATLAB for the left-handed arguments:
     * coefficients, work, and error. These are the output variables.
     */
    plhs[0] = mxCreateDoubleMatrix(NC, K, mxREAL);
    plhs[1] = mxCreateDoubleMatrix(1, (6 * (N * M + 1) + N), mxREAL);    
    plhs[2] = mxCreateNumericArray(2, dims, mxINT32_CLASS, mxREAL); 
    
    /* Connect the pointers C,WK with the output pointers */
    /* ************************************************** */
    C = mxGetPr(plhs[0]);
    WK = mxGetPr(plhs[1]);
    
    /* Call the C subroutine GCVSPL.C - Woltring's Smooth Algorithm */
    /* ************************************************************ */
    gcvspl_(X, Y, &NY, WX, WY, &M, &N, &K, &MD, VAL, C, &NC, WK, &IER);

    /* Update the value pointed to by lhs[2] with IER, the error value */
    *((int *)mxGetData(plhs[2])) = IER;
      
}
