/*
 * MATLAB Compiler: 3.0
 * Date: Mon Nov 03 13:00:57 2003
 * Arguments: "-B" "macro_default" "-O" "all" "-O" "fold_scalar_mxarrays:on"
 * "-O" "fold_non_scalar_mxarrays:on" "-O" "optimize_integer_for_loops:on" "-O"
 * "array_indexing:on" "-O" "optimize_conditionals:on" "-m" "-W" "main" "-L"
 * "C" "-t" "-T" "link:exe" "-h" "libmmfile.mlib" "DancingMonkeys" 
 */
#include "prctile.h"
#include "libmatlbm.h"
#include "libmmfile.h"
static mxArray * _mxarray0_;

static mxChar _array2_[31] = { 'P', ' ', 'm', 'u', 's', 't', ' ', 'b',
                               'e', ' ', 'a', ' ', 's', 'c', 'a', 'l',
                               'a', 'r', ' ', 'o', 'r', ' ', 'a', ' ',
                               'v', 'e', 'c', 't', 'o', 'r', '.' };
static mxArray * _mxarray1_;
static mxArray * _mxarray3_;

static mxChar _array5_[36] = { 'P', ' ', 'm', 'u', 's', 't', ' ', 't', 'a',
                               'k', 'e', ' ', 'v', 'a', 'l', 'u', 'e', 's',
                               ' ', 'b', 'e', 't', 'w', 'e', 'e', 'n', ' ',
                               '0', ' ', 'a', 'n', 'd', ' ', '1', '0', '0' };
static mxArray * _mxarray4_;
static mxArray * _mxarray6_;
static mxArray * _mxarray7_;
static mxArray * _mxarray8_;
static mxArray * _mxarray9_;

void InitializeModule_prctile(void) {
    _mxarray0_ = mclInitializeDouble(1.0);
    _mxarray1_ = mclInitializeString(31, _array2_);
    _mxarray3_ = mclInitializeDouble(0.0);
    _mxarray4_ = mclInitializeString(36, _array5_);
    _mxarray6_ = mclInitializeDouble(100.0);
    _mxarray7_ = mclInitializeDouble(2.0);
    _mxarray8_ = mclInitializeDoubleVector(0, 0, (double *)NULL);
    _mxarray9_ = mclInitializeDouble(.5);
}

void TerminateModule_prctile(void) {
    mxDestroyArray(_mxarray9_);
    mxDestroyArray(_mxarray8_);
    mxDestroyArray(_mxarray7_);
    mxDestroyArray(_mxarray6_);
    mxDestroyArray(_mxarray4_);
    mxDestroyArray(_mxarray3_);
    mxDestroyArray(_mxarray1_);
    mxDestroyArray(_mxarray0_);
}

static mxArray * mlfPrctile_prctilecol(mxArray * x, mxArray * p);
static void mlxPrctile_prctilecol(int nlhs,
                                  mxArray * plhs[],
                                  int nrhs,
                                  mxArray * prhs[]);
static mxArray * Mprctile(int nargout_, mxArray * x, mxArray * p);
static mxArray * Mprctile_prctilecol(int nargout_, mxArray * x, mxArray * p);

static mexFunctionTableEntry local_function_table_[1]
  = { { "prctilecol", mlxPrctile_prctilecol, 2, 1, NULL } };

_mexLocalFunctionTable _local_function_table_prctile
  = { 1, local_function_table_ };

/*
 * The function "mlfPrctile" contains the normal interface for the "prctile"
 * M-function from file "c:\matlab65\toolbox\stats\prctile.m" (lines 1-42).
 * This function processes any input arguments and passes them to the
 * implementation version of the function, appearing above.
 */
mxArray * mlfPrctile(mxArray * x, mxArray * p) {
    int nargout = 1;
    mxArray * y = NULL;
    mlfEnterNewContext(0, 2, x, p);
    y = Mprctile(nargout, x, p);
    mlfRestorePreviousContext(0, 2, x, p);
    return mlfReturnValue(y);
}

/*
 * The function "mlxPrctile" contains the feval interface for the "prctile"
 * M-function from file "c:\matlab65\toolbox\stats\prctile.m" (lines 1-42). The
 * feval function calls the implementation version of prctile through this
 * function. This function processes any input arguments and passes them to the
 * implementation version of the function, appearing above.
 */
void mlxPrctile(int nlhs, mxArray * plhs[], int nrhs, mxArray * prhs[]) {
    mxArray * mprhs[2];
    mxArray * mplhs[1];
    int i;
    if (nlhs > 1) {
        mlfError(
          mxCreateString(
            "Run-time Error: File: prctile Line: 1 Column: "
            "1 The function \"prctile\" was called with mor"
            "e than the declared number of outputs (1)."),
          NULL);
    }
    if (nrhs > 2) {
        mlfError(
          mxCreateString(
            "Run-time Error: File: prctile Line: 1 Column:"
            " 1 The function \"prctile\" was called with m"
            "ore than the declared number of inputs (2)."),
          NULL);
    }
    for (i = 0; i < 1; ++i) {
        mplhs[i] = NULL;
    }
    for (i = 0; i < 2 && i < nrhs; ++i) {
        mprhs[i] = prhs[i];
    }
    for (; i < 2; ++i) {
        mprhs[i] = NULL;
    }
    mlfEnterNewContext(0, 2, mprhs[0], mprhs[1]);
    mplhs[0] = Mprctile(nlhs, mprhs[0], mprhs[1]);
    mlfRestorePreviousContext(0, 2, mprhs[0], mprhs[1]);
    plhs[0] = mplhs[0];
}

/*
 * The function "mlfPrctile_prctilecol" contains the normal interface for the
 * "prctile/prctilecol" M-function from file
 * "c:\matlab65\toolbox\stats\prctile.m" (lines 42-62). This function processes
 * any input arguments and passes them to the implementation version of the
 * function, appearing above.
 */
static mxArray * mlfPrctile_prctilecol(mxArray * x, mxArray * p) {
    int nargout = 1;
    mxArray * y = NULL;
    mlfEnterNewContext(0, 2, x, p);
    y = Mprctile_prctilecol(nargout, x, p);
    mlfRestorePreviousContext(0, 2, x, p);
    return mlfReturnValue(y);
}

/*
 * The function "mlxPrctile_prctilecol" contains the feval interface for the
 * "prctile/prctilecol" M-function from file
 * "c:\matlab65\toolbox\stats\prctile.m" (lines 42-62). The feval function
 * calls the implementation version of prctile/prctilecol through this
 * function. This function processes any input arguments and passes them to the
 * implementation version of the function, appearing above.
 */
static void mlxPrctile_prctilecol(int nlhs,
                                  mxArray * plhs[],
                                  int nrhs,
                                  mxArray * prhs[]) {
    mxArray * mprhs[2];
    mxArray * mplhs[1];
    int i;
    if (nlhs > 1) {
        mlfError(
          mxCreateString(
            "Run-time Error: File: prctile/prctilecol Line: 42 Col"
            "umn: 1 The function \"prctile/prctilecol\" was called"
            " with more than the declared number of outputs (1)."),
          NULL);
    }
    if (nrhs > 2) {
        mlfError(
          mxCreateString(
            "Run-time Error: File: prctile/prctilecol Line: 42 Col"
            "umn: 1 The function \"prctile/prctilecol\" was called"
            " with more than the declared number of inputs (2)."),
          NULL);
    }
    for (i = 0; i < 1; ++i) {
        mplhs[i] = NULL;
    }
    for (i = 0; i < 2 && i < nrhs; ++i) {
        mprhs[i] = prhs[i];
    }
    for (; i < 2; ++i) {
        mprhs[i] = NULL;
    }
    mlfEnterNewContext(0, 2, mprhs[0], mprhs[1]);
    mplhs[0] = Mprctile_prctilecol(nlhs, mprhs[0], mprhs[1]);
    mlfRestorePreviousContext(0, 2, mprhs[0], mprhs[1]);
    plhs[0] = mplhs[0];
}

/*
 * The function "Mprctile" is the implementation version of the "prctile"
 * M-function from file "c:\matlab65\toolbox\stats\prctile.m" (lines 1-42). It
 * contains the actual compiled code for that M-function. It is a static
 * function and must only be called from one of the interface functions,
 * appearing below.
 */
/*
 * function y = prctile(x,p);
 */
static mxArray * Mprctile(int nargout_, mxArray * x, mxArray * p) {
    mexLocalFunctionTable save_local_function_table_
      = mclSetCurrentLocalFunctionTable(&_local_function_table_prctile);
    mxArray * y = NULL;
    mxArray * xx = NULL;
    mxArray * j = NULL;
    mxArray * np = NULL;
    mxArray * c = NULL;
    mxArray * ans = NULL;
    mxArray * pcols = NULL;
    mxArray * prows = NULL;
    mclCopyArray(&x);
    mclCopyArray(&p);
    /*
     * %PRCTILE gives the percentiles of the sample in X.
     * %   Y = PRCTILE(X,P) returns a value that is greater than P percent
     * %   of the values in X. For example, if P = 50  Y is the median of X. 
     * %
     * %   P may be either a scalar or a vector. For scalar P, Y is a row   
     * %   vector containing Pth percentile of each column of X. For vector P,
     * %   the ith row of Y is the P(i) percentile of each column of X.
     * 
     * %   Copyright 1993-2002 The MathWorks, Inc. 
     * %   $Revision: 2.10 $  $Date: 2002/01/17 21:31:44 $
     * 
     * [prows pcols] = size(p);
     */
    mlfSize(mlfVarargout(&prows, &pcols, NULL), mclVa(p, "p"), NULL);
    /*
     * if prows ~= 1 & pcols ~= 1
     */
    {
        mxArray * a_ = mclInitialize(mclNe(mclVv(prows, "prows"), _mxarray0_));
        if (mlfTobool(a_)
            && mlfTobool(
                 mclAnd(a_, mclNe(mclVv(pcols, "pcols"), _mxarray0_)))) {
            mxDestroyArray(a_);
            /*
             * error('P must be a scalar or a vector.');
             */
            mlfError(_mxarray1_, NULL);
        } else {
            mxDestroyArray(a_);
        }
    /*
     * end
     */
    }
    /*
     * if any(p > 100) | any(p < 0)
     */
    {
        mxArray * a_
          = mclInitialize(mlfAny(mclGt(mclVa(p, "p"), _mxarray6_), NULL));
        if (mlfTobool(a_)
            || mlfTobool(
                 mclOr(a_, mlfAny(mclLt(mclVa(p, "p"), _mxarray3_), NULL)))) {
            mxDestroyArray(a_);
            /*
             * error('P must take values between 0 and 100');
             */
            mlfError(_mxarray4_, NULL);
        } else {
            mxDestroyArray(a_);
        }
    /*
     * end
     */
    }
    /*
     * 
     * if (~any(isnan(x)))
     */
    if (mclNotBool(mlfAny(mlfIsnan(mclVa(x, "x")), NULL))) {
        /*
         * y = prctilecol(x,p);
         */
        mlfAssign(&y, mlfPrctile_prctilecol(mclVa(x, "x"), mclVa(p, "p")));
    /*
     * else                    % if there are NaNs, process each column
     */
    } else {
        /*
         * if (size(x,1) == 1)
         */
        if (mclEqBool(
              mlfSize(mclValueVarargout(), mclVa(x, "x"), _mxarray0_),
              _mxarray0_)) {
            /*
             * x = x';
             */
            mlfAssign(&x, mlfCtranspose(mclVa(x, "x")));
        /*
         * end
         */
        }
        /*
         * c = size(x,2);
         */
        mlfAssign(&c, mlfSize(mclValueVarargout(), mclVa(x, "x"), _mxarray7_));
        /*
         * np = length(p);
         */
        mlfAssign(&np, mlfScalar(mclLengthInt(mclVa(p, "p"))));
        /*
         * y = zeros(np,c);
         */
        mlfAssign(&y, mlfZeros(mclVv(np, "np"), mclVv(c, "c"), NULL));
        /*
         * for j=1:c
         */
        {
            int v_ = mclForIntStart(1);
            int e_ = mclForIntEnd(mclVv(c, "c"));
            if (v_ > e_) {
                mlfAssign(&j, _mxarray8_);
            } else {
                /*
                 * xx = x(:,j);
                 * xx = xx(~isnan(xx));
                 * y(:,j) = prctilecol(xx,p)';
                 * end
                 */
                for (; ; ) {
                    mlfAssign(
                      &xx,
                      mclArrayRef2(
                        mclVa(x, "x"), mlfCreateColonIndex(), mlfScalar(v_)));
                    mlfAssign(
                      &xx,
                      mclArrayRef1(
                        mclVv(xx, "xx"), mclNot(mlfIsnan(mclVv(xx, "xx")))));
                    mclArrayAssign2(
                      &y,
                      mlfCtranspose(
                        mlfPrctile_prctilecol(mclVv(xx, "xx"), mclVa(p, "p"))),
                      mlfCreateColonIndex(),
                      mlfScalar(v_));
                    if (v_ == e_) {
                        break;
                    }
                    ++v_;
                }
                mlfAssign(&j, mlfScalar(v_));
            }
        }
        /*
         * if (min(size(x)) == 1)
         */
        if (mclEqBool(
              mlfMin(
                NULL,
                mlfSize(mclValueVarargout(), mclVa(x, "x"), NULL),
                NULL,
                NULL),
              _mxarray0_)) {
            /*
             * y = y';
             */
            mlfAssign(&y, mlfCtranspose(mclVv(y, "y")));
        /*
         * end
         */
        }
    /*
     * end
     */
    }
    mclValidateOutput(y, 1, nargout_, "y", "prctile");
    mxDestroyArray(prows);
    mxDestroyArray(pcols);
    mxDestroyArray(ans);
    mxDestroyArray(c);
    mxDestroyArray(np);
    mxDestroyArray(j);
    mxDestroyArray(xx);
    mxDestroyArray(p);
    mxDestroyArray(x);
    mclSetCurrentLocalFunctionTable(save_local_function_table_);
    return y;
    /*
     * 
     * return
     * 
     */
}

/*
 * The function "Mprctile_prctilecol" is the implementation version of the
 * "prctile/prctilecol" M-function from file
 * "c:\matlab65\toolbox\stats\prctile.m" (lines 42-62). It contains the actual
 * compiled code for that M-function. It is a static function and must only be
 * called from one of the interface functions, appearing below.
 */
/*
 * function y = prctilecol(x,p);
 */
static mxArray * Mprctile_prctilecol(int nargout_, mxArray * x, mxArray * p) {
    mexLocalFunctionTable save_local_function_table_
      = mclSetCurrentLocalFunctionTable(&_local_function_table_prctile);
    mxArray * y = NULL;
    mxArray * q = NULL;
    mxArray * n = NULL;
    mxArray * m = NULL;
    mxArray * xx = NULL;
    mclCopyArray(&x);
    mclCopyArray(&p);
    /*
     * xx = sort(x);
     */
    mlfAssign(&xx, mlfSort(NULL, mclVa(x, "x"), NULL));
    /*
     * [m,n] = size(x);
     */
    mlfSize(mlfVarargout(&m, &n, NULL), mclVa(x, "x"), NULL);
    /*
     * 
     * if m==1 | n==1
     */
    {
        mxArray * a_ = mclInitialize(mclEq(mclVv(m, "m"), _mxarray0_));
        if (mlfTobool(a_)
            || mlfTobool(mclOr(a_, mclEq(mclVv(n, "n"), _mxarray0_)))) {
            mxDestroyArray(a_);
            /*
             * m = max(m,n);
             */
            mlfAssign(&m, mlfMax(NULL, mclVv(m, "m"), mclVv(n, "n"), NULL));
            /*
             * if m == 1,
             */
            if (mclEqBool(mclVv(m, "m"), _mxarray0_)) {
                /*
                 * y = x*ones(length(p),1);
                 */
                mlfAssign(
                  &y,
                  mclMtimes(
                    mclVa(x, "x"),
                    mlfOnes(
                      mlfScalar(mclLengthInt(mclVa(p, "p"))),
                      _mxarray0_,
                      NULL)));
                /*
                 * return;
                 */
                goto return_;
            /*
             * end
             */
            }
            /*
             * n = 1;
             */
            mlfAssign(&n, _mxarray0_);
            /*
             * q = 100*(0.5:m - 0.5)./m;
             */
            mlfAssign(
              &q,
              mclRdivide(
                mclMtimes(
                  _mxarray6_,
                  mlfColon(
                    _mxarray9_, mclMinus(mclVv(m, "m"), _mxarray9_), NULL)),
                mclVv(m, "m")));
            /*
             * xx = [min(x); xx(:); max(x)];
             */
            mlfAssign(
              &xx,
              mlfVertcat(
                mlfMin(NULL, mclVa(x, "x"), NULL, NULL),
                mclArrayRef1(mclVv(xx, "xx"), mlfCreateColonIndex()),
                mlfMax(NULL, mclVa(x, "x"), NULL, NULL),
                NULL));
        /*
         * else
         */
        } else {
            mxDestroyArray(a_);
            /*
             * q = 100*(0.5:m - 0.5)./m;
             */
            mlfAssign(
              &q,
              mclRdivide(
                mclMtimes(
                  _mxarray6_,
                  mlfColon(
                    _mxarray9_, mclMinus(mclVv(m, "m"), _mxarray9_), NULL)),
                mclVv(m, "m")));
            /*
             * xx = [min(x); xx; max(x)];
             */
            mlfAssign(
              &xx,
              mlfVertcat(
                mlfMin(NULL, mclVa(x, "x"), NULL, NULL),
                mclVv(xx, "xx"),
                mlfMax(NULL, mclVa(x, "x"), NULL, NULL),
                NULL));
        }
    /*
     * end
     */
    }
    /*
     * 
     * q = [0 q 100];
     */
    mlfAssign(&q, mlfHorzcat(_mxarray3_, mclVv(q, "q"), _mxarray6_, NULL));
    /*
     * y = interp1(q,xx,p);
     */
    mlfAssign(
      &y, mlfInterp1(mclVv(q, "q"), mclVv(xx, "xx"), mclVa(p, "p"), NULL));
    return_:
    mclValidateOutput(y, 1, nargout_, "y", "prctile/prctilecol");
    mxDestroyArray(xx);
    mxDestroyArray(m);
    mxDestroyArray(n);
    mxDestroyArray(q);
    mxDestroyArray(p);
    mxDestroyArray(x);
    mclSetCurrentLocalFunctionTable(save_local_function_table_);
    return y;
}
