/*
 * @(#)mcc.h    generated by: makeheader    Sat Aug 15 15:01:32 1998
 *
 *		built from:	mccdata.c
 *				mcmdata.c
 *				libmcc0.c
 *				libmcc1.c
 *				libmcc2.c
 *				libmcc3.c
 *				libmcm0.c
 *				mat.c
 */

#ifndef mcc_h
#define mcc_h


/*
 * CONFIDENTIAL AND CONTAINING PROPRIETARY TRADE SECRETS
 * Copyright (c) 1984-1998 by The MathWorks, Inc.  
 * All Rights Reserved.
 * The source code contained in this listing contains proprietary and
 * confidential trade secrets of The MathWorks, Inc.   The use, modification,
 * or development of derivative work based on the code or ideas obtained
 * from the code is prohibited without the express written permission of The
 * MathWorks, Inc.  The disclosure of this code to any party not authorized
 * by The MathWorks, Inc. is strictly forbidden.
 * CONFIDENTIAL AND CONTAINING PROPRIETARY TRADE SECRETS
 */

/* Tell WATCOM compiler that these libmccmx functions, which
 * return a double, should return the result value to caller
 * on the floating point register stack to be compatible with
 * code generated by other compilers, such as MSVC.
 */
#ifdef __WATCOMC__
#ifndef __cplusplus
#pragma aux mccGetReal value [8087];
#pragma aux mccImportReal value [8087];
#pragma aux mccGetScalar value [8087];
#pragma aux mccImportScalar value [8087];
#pragma aux mccGetRealMatrixElement value [8087];
#pragma aux mccGetRealVectorElement value [8087];
#pragma aux mccGetImagMatrixElement value [8087];
#pragma aux mccGetImagVectorElement value [8087];
#pragma aux mccRealInnerProduct value [8087];
#pragma aux mccRealVectorSum value [8087];
#pragma aux mccRealVectorProduct value [8087];
#pragma aux mccRealVectorMax value [8087];
#pragma aux mccRealVectorMin value [8087];
#pragma aux mccRealmax value [8087];
#pragma aux mccRealmin value [8087];
#pragma aux mcmPi value [8087];
#pragma aux mcmRealPowerInt value [8087];
#pragma aux mcmDivideRealpart value [8087];
#pragma aux mcmDivideImagPart value [8087];
#pragma aux mcmHypot value [8087];
#pragma aux mcmRound value [8087];
#pragma aux mcmLog10 value [8087];
#pragma aux mcmMax value [8087];
#pragma aux mcmMin value [8087];
#pragma aux mccRint value [8087];
#pragma aux mcmFix value [8087];
#endif
#endif

#include "mex.h"


#define mxMAXNAM  32    /* maximum name length */

typedef char mxName[mxMAXNAM];

typedef enum {
    mxDOUBLE_ARRAY      = 2,    /* start here to align with dispatch */
    mxSPARSE_ARRAY,
    mxCHARACTER_ARRAY,
    mxCELL_ARRAY,
    mxSTRUCTURE_ARRAY,
    mxFLOAT_ARRAY,
    mxINT8_ARRAY,
    mxUINT8_ARRAY,
    mxINT16_ARRAY,
    mxUINT16_ARRAY,
    mxINT32_ARRAY,
    mxUINT32_ARRAY,
    mxINT64_ARRAY,      /* place holder - future enhancements */
    mxUINT64_ARRAY,     /* place holder - future enhancements */
    mxOBJECT_ARRAY,
    mxUNKNOWN_ARRAY,
/*
 *  In compiled programs, the 'type' field will be replaced by one
 *  of the fields below.  The translation between these and the fields
 *  used below will be made as follows:
 *
 *  mccBOOL:        type==SCALAR, 2DDOUBLE, or DOUBLE and logical_flag != 0
 *  mccTEXT:        the type field is mxCHAR
 *  mccINT:     the type field is mxINT
 *  mccIX_B:
 *  mccIX_T:
 *  mccIX_I:        An index type--integers containing bools, text, or ints
 *  mccREAL:        the type field is SCALAR, 2DDOUBLE, or DOUBLE, and pi==0
 *  mccCX:      like mccREAL, but pi != 0
 *  mccCELL:        the type field is mxCELL
 *  mccSTRUCT:      the type field is mxSTRUCT
 *  alloc<0:        corresponds to the mxUNASSIGNED type
 */
    mccMASK =       0x20,
    mccBOOL =       0x20,
    mccTEXT,
    mccINT,
    mccREAL,
    mccCX,
    mccCELL,
    mccSTRUCT,  
    mccSPARSEt,
    mccIX_B,
    mccIX_T,
    mccIX_I
            
} mxArrayType;

typedef enum {
    mxLOCAL_SCOPE,
    mxLOCAL_STATIC_SCOPE,
    mxGLOBAL_SCOPE,
    mxMEMBER_SCOPE,
    mxTEMPORARY_SCOPE,
    mxPERSISTENT_SCOPE,
    mxCONSTANT_SCOPE,
    mxAUTO_SCOPE
} mxVariableScope;

struct mxArray_tag {
    mxName            name;
    mxArrayType       type;
    int               scope;
    mxArray          *link;
    int               number_of_dims;
    int               nelements_allocated;
    struct {
        unsigned int    scalar_flag : 1;
        unsigned int    logical_flag : 1;
        unsigned int    empty_flag : 1;
        unsigned int    global_flag : 1;
        unsigned int    on_arraylist_flag : 1;
        unsigned int    zero_imag_flag : 1;
        unsigned int    static_flag : 1;
        unsigned int    colon_flag : 1;
        unsigned int    private_data_flag : 1;
        unsigned int    reference_count : 7;
        unsigned int    kernel_bits : 8;
        unsigned int    user_bits : 7;
        unsigned int    string_flag : 1;
    }   flags;
  
    union {
        struct {
            int  m;
            int  n;
        }   matrix_dims;
        int  *dim_array;
    }   size;
  
    union {
        struct {
            void  *pdata;
            void  *pimag_data;
            int   *ir;
            int   *jc;
        }   number_array;
    
        struct {
            mxArray  **cells;
        }   cell_array;
    
        struct {
            mxArray      **fields;
            mxName        *field_names;
            char          *object_classname;
            int            object_tag;  /* if > 0, structure is object */
            unsigned int   object_chksum;
            int            number_of_fields;
        }   structure_array;

        struct {
            mxArray  *pglobal;
        }   global_array;
    }   data;
};

#define MCC_LOGICAL 0x00000001

#define mccINIT(type,scope,m,n,pr,pi) \
    { {0}, type, scope, 0, 2, 0, {0,0,0,0,0,0,0,0,1,0,0,0,type==mccTEXT}, { m, n }, {pr, pi,0,0} }

#define mccCINIT(type,m,n,pr,pi) mccINIT(type,mxCONSTANT_SCOPE,m,n,pr,pi)

#define mccPR(p) ((double *)mxGetPr(p))
#define mccSPR(p) ((unsigned short *)mxGetPr(p))
#define mccIPR(p) ((int *)mxGetPr(p))

#define mccPRIndex(p,i) ((mccESZ(p)==8) ? (mccPR(p)[i]) : \
            ((mccESZ(p)==4) ? (mccIPR(p)[i]) : mccSPR(p)[i]))
#define mccIPRIndex(p,i) ((mccESZ(p)==8) ? ((int) mccPR(p)[i]) : \
            ((mccESZ(p)==4) ? (mccIPR(p)[i]) : mccSPR(p)[i]))
#define mccSPRIndex(p,i) ((mccESZ(p)==8) ? ((short) mccPR(p)[i]) : \
            ((mccESZ(p)==4) ? ((short) mccIPR(p)[i]) : mccSPR(p)[i]))

#define mccPI(p) ((double *)mxGetPi(p))
#define mccVPR(p) ((void *)mxGetPr(p))
#define mccVPI(p) ((void *)mxGetPi(p))
#define mccM(p) mxGetM(p)
#define mccN(p) mxGetN(p)
#define mccSZ(p) (mccM(p)*mccN(p))
#define mccESZ(p) (mccObjSize[mccTY(p)]) /*  element size */
#define mccDIM(p) ((p)->number_of_dims)
#define mccIR(p) (mxGetIr(p))
#define mccJC(p) (mxGetJc(p))
#define mccSETIR(p,ir) (mxSetIr(p,ir))
#define mccSETJC(p,jc) (mxSetJc(p,jc))
#define mccALLOC(p) ((p)->nelements_allocated)
#define mccLOG(p) ((p)->flags.logical_flag)
#define mccSTRING(p) ((p)->flags.string_flag)
#define mccS_STRING(p) ( ((p)->flags.string_flag) ? mccTEXT : mccTY(p) )
#define mccM_STRING(p) ( ((p) == mccTEXT) ? 1 : 0 )

#define mccSCAL(p) ((p)->flags.scalar_flag)
#define mccEMPT(p) ((p)->flags.empty_flag)
#define mccSCOPE(p) ((p)->scope)
#define mccTY(p) ((p)->type)
#define mccLINK(p) ((p)->link)
#define mccDIMS(p) ((p)->number_of_dims)

/*
 *  The 'unassigned' state will be denoted by nelements_allocated<0
 */

#define mccNOTSET(p) (mccALLOC(p)<0)
#define mccSTATIC(p) (mccSCOPE(p) == mxLOCAL_STATIC_SCOPE)
#define mccSPARSE(p) (mccTY(p) == mxSPARSE_ARRAY)
#define mccSET_FULL(p) (p->type = mxDOUBLE_ARRAY)
#define mccCOMPLEX(p) (mccTY(p) == mccCX)
/*
 * This macro mccREL_NAN(x) is designed to be used in the code generation
 * for conditionals.   Conditional operations sometimes (on certain platforms)
 * generates incorrect results when one or the other of the operands is a Nan.
 * on these platforms, this function could be defined to be zero.  For example
 * x<nan is always false, but on certain platforms a true result is obtained.
 * the code generated (and the code in MATLAB), needs to check to insure
 * that either being nan is an error.  See the code in gen.c to
 * look for sample cases of when this Macro is invoked.
 */

#define mccREL_NAN(e) mxIsNaN(e)

/*
 *  Macro to initialize matrix that has never been set.
 */

#define mccINITIALIZE(p) do{ if( mccALLOC(p) < 0) {\
    mxArrayType f = mccTY(p); *(p) = mccInitialMatrix; mccTY(p)=f; } }while(0)

/*
 *  Functions to simulate nargin() and nargout().
 */

#define mccNargin() nrhs_
#define mccNargout() nlhs_

/*
 *  Macro for 'zeros(n)', n an integer.
 */

#define mccZerosN( p, n ) mccZerosMN( p, n, n )

/*
 *  Macro for 'clear' (this does nothing in compiled code).
 */

#define mccClear()

/*
 *  Define the 'i' and 'j' functions (sqrt(-1)).
 */

#define mccI(p,q) { *p=0.; *q=1.; }
#define mccJ(p,q) { *p=0.; *q=1.; }

/*
 * Macros for computing ones, zeros, etc with no inputs
 */

#define mccOne() (1)
#define mccZero() (0)
#define mccEye() (1)

/*
 *  Macros for converting 0-1 subscripts to index arrays.
 */

#define mccFindMatrixIndex(q,p,r) mccFindIndex(q,p,r,0)
#define mccFindColumnIndex(q,p,r) mccFindIndex(q,p,r,1)
#define mccFindRowIndex(q,p,r) mccFindIndex(q,p,r,2)
 
/*
 *  Macro defining sum that returns an integer scalar.
 */

#define mccIntRealVectorSum( m ) ((int)mccRealVectorSum( m ))

/*
 *  Macro defining an interface for a colon with two ints
 */
#define mccIntColon2(p,m,n) mccIntColon(p,m,1,n) 

/*
 *  Macros defining scalar versions of Any and All
 */
#define mccBoolScalar(x) ((x)!=0)
#define mccBoolScalar2(x,i) ((x)!=0)
#define mccBoolComplex(x,y) (((x)!=0)||((y)!=0))
#define mccBoolComplex2(x,y,i) (((x)!=0)||((y)!=0))

/*
 * Macro for a value-returning error function
 */
#define mccErrorVal(p, s) mccError( s )

/*
 * Macros for the exit() function
 */
#define mccExit() exit(0)


/*
 *  Initialization macros for local variables.
 */

/*
 * NOTE: mccInit must initialize the number of dimensions to 2 and each dimension to 0 so that
 * subsequent references (or calls to mxGetM) do not fail.  This is a new
 * restriction brought about by scalar expansion
 *
 */

#define mccInit(x,y) do{mccALLOC(&x)=-1; mccTY(&x)=y; mccSCOPE(&x)=mxTEMPORARY_SCOPE; mccDIMS(&x) = 2; mxSetM(&x,0); mxSetN(&x,0);  }while(0)

#define mccBoolInit(x) mccInit(x,mccBOOL)
#define mccIntInit(x) mccInit(x,mccINT)
#define mccRealInit(x) mccInit(x,mccREAL)
#define mccTextInit(x) mccInit(x,mccTEXT)
#define mccComplexInit(x) mccInit(x,mccCX)



#define public
#define package

/*
 *	'real' and 'imag' functions for scalar complex variables.
 */

#define mcmReal( x, y )    (x)
#define mcmImag( x, y )    (y)

/*
 *	Simple integer and real remainder functions.
 */

#define mcmRealRem( x, y )     ( y ? fmod(x,y) : mxGetNaN() )

/*
 *	Macro defining int^int in terms of real^int.
 */

#define mcmIntPowerInt( m, n ) ((int)mcmRealPowerInt( (double)(m), (n) ))

/*
 *	Macro defining sqrt(int n) in terms of the C sqrt function.
 */

#define mcmIntSqrt( n ) sqrt( (double)(n) )

/*
 *	Macro defining left complex division in terms of right complex division
 *	(for scalars).
 */

#define mcmLeftDivide( p, q, a, b, c, d) mcmDivide( p, q, c, d, a, b );

/*
 *	Macros defining isnan, isinf, isfinite for complex scalars.
 */

#define mcmIsNaN(re,im) (mxIsNaN(re) || mxIsNaN(im))
#define mcmIsInf(re,im) (mxIsInf(re) || mxIsInf(im))
#define mcmIsFinite(re,im) (mxIsFinite(re) && mxIsFinite(im))

/*
 *  mcmEps1 handles the 'eps(1)' case (archaic).
 */
#define mcmEps mxGetEps
#define mcmEps1(x) mxGetEps()

/***********  SUPPORT FOR DEBUGGING MEMORY ALLOCATION **************/
/*
 * NOTE: This memory allocation debugger DOES NOT WORK properly for
 * values RETURNED to MATLAB.  If you return a value to MATLAB when the
 * memory allocation debugger is turned on with this flag, MATLAB
 * WILL assert.  It is only intended to debug the cleanliness of the library
 * internals or for stand-alone mode.
 *
 *
 * We may want to fix this behavior to make this feature more useful
 * for mex mode.
 */

/* #define mcmDEBUGflag 1 */


extern void *mcmCalloc( int scope, size_t n );
extern void mcmFree( void *pp, int scope, size_t size );

#ifdef mcmDEBUGflag

void *mcmDBCalloc( int scope, size_t size, int line );
void mcmDBFree( void *p, int scope, size_t size, int line );
void mcmDBCheck( void *p, size_t size, int line );

#define mcmCalloc( scope, size )	mcmDBCalloc( scope, size, __LINE__ )
#define mcmFree( p, scope, size )	mcmDBFree( p, scope, size, __LINE__)
#define mcmCallocCheck( p, size )	mcmDBCheck( p, size, __LINE__ )

#else


extern void *mcmDBCalloc( int scope, size_t m, int line );
extern void mcmDBFree( void *p, int scope, size_t size, int line );
extern void mcmDBCheck( void *p, size_t size, int line );

#endif



/*
 *  Used to initialize the automatic mxArray structures.
 */
extern mxArray mccInitialMatrix;


/*
 *  Empty constant matrix.
 */
extern mxArray C_Empty_;


/*
 *  Make a matrix real, using a temporary matrix if needed
 */
extern mxArray *
mccForceReal( mxArray *p, mxArray *temp );

extern mxArray **mccInitOutput(mxArray **a);


/*
 *  Import a MATLAB matrix.  flg is 1 if the MATLAB matrix is to be freed
 *  (this is typically when a returned value is being imported)
 */
extern void
mccImport( mxArray *p, const mxArray *q, int flg, int line );


/*
 *  Import a MATLAB matrix, making a copy so we can change it.
 *  Optionally free the MATLAB data structure.
 */
extern void
mccImportCopy( mxArray *p, const mxArray *q, int flg, int line );


/*
 *  Like mxGetScalar, but checks that the value really is a real scalar.
 *  If there the dimension is not 1x1 or there is a complex part,
 *  a fatal error is produced.
 *
 * This API must maintain the logical flag (hence the need for int *flags)
 *
 * flg is 1 when the memory can be freed, flg is 0 when this is an import
 * for an argument and the memory should not be freed.
 *
 */
extern double
mccImportReal( int *pflag, int *flags, mxArray *q, int flg, char *ss );


/*
 *  Like mxGetScalar, but checks that the value really is a (complex) scalar.
 *  If there the dimension is not 1x1 or there is a complex part,
 *  a fatal error is produced.
 *
 *  mccImportScalar must accept an argument of flags indicating whether
 *  the logical flag was set on import into a scalar.  This is so that
 *  scalars maintain their logical property correctly.  The caller may
 *  pass NULL if the logical flag is not required.
 *
 * flg is 1 when the memory can be freed, flg is 0 when this is an import
 * for an argument and the memory should not be freed.
 *
 */
extern double
mccImportScalar( double *p, int *pflag, int *flags, mxArray *q, int flg, char *ss );


/*
 *  Create an mxn array, p.
 *  If the complex flag of p is on, the created mxArray is complex.
 *  If the returned space is not zeroed (e.g., reuse of older space)
 *  The function returns 1; otherwise, it returns 0.
 */
extern int
mccAllocateMatrix( mxArray *p, int m, int n );


/*
 *  Routine to free a matrix.
 */
extern void
mccFreeMatrix( mxArray *p );


/*
 *  Internal version of a=length(b).
 */

extern int
mccGetLength( mxArray *p );


/*
 *  Internal version of a=isempty(b).
 */
extern int
mccIsEmpty( mxArray *p );


/*
 *  Internal version of [m,n] = size(a).
 */
extern void
mccGetMatrixSize( int *pm, int *pn, mxArray *p );


/*
 *  Internal version of a = size(b,n).
 */
extern int
mccGetDimensionSize( mxArray *p, int nn );


/*
 *  Internal version of a=size(b).
 */
extern void
mccSize( mxArray *p, mxArray *q );


/*
 *  Grow a 1-dimensional array p to have size mn.
 */
extern void
mccGrowVector( mxArray *p, int mn );


/*
 *  Grow a 2-dimensional array p to have size mxn.
 *  Don't even try to grow in place for 2-d arrays.
 *  However, if it looks like a 1d array would work, call mccGrowVector.
 */
extern void
mccGrowMatrix( mxArray *p, int m, int n );


/*
 *  Check size of 1-dimensional array assignment.
 */
extern void
mccCheckVectorSize( mxArray *p, int mn );


/*
 *  Check the sizes of an assignment to a(:).
 */
extern void
mccColonOnLhs( mxArray *p, int mn );


/*
 *  Check size of 2-dimensional array assignment.
 */
extern void
mccCheckMatrixSize( mxArray *p, int m, int n );


/*
 *  Return the maximum element in an index array p.
 *  Check to ensure that no index is 0 or negative
 *
 *  This routine assumes that the matrix is an array of indices
 *  mccFindIndex() is called to convert logical matrices into
 *  arrays of indices for indexing.
 *
 *  It reports an error if any index is <1.
 *
 */
extern int
mccGetMaxIndex( mxArray *p, int asz );


/*
 *  calculates dimensions of a(b).
 */
extern int
mccCalcSubscriptDimensions( int mm, int *pn, int bm, int bn, mxArray *p );


/*
 *    Implements the 2 argument version of 'reshape' function
 */
extern void
mccReshape2( mxArray *p, mxArray *q, mxArray *r );


/*
 *    Implements 'reshape' function
 */
extern void
mccReshape( mxArray *p, mxArray *q, int m, int n );


/*
 *  Implements 'ones(a)'.
 */
extern void
mccOnes( mxArray *p, mxArray *q );


/*
 *  Implements 'ones(m,n)'.
 */
extern void
mccOnesMN( mxArray *p, int m, int n );


/*
 *  Implements zeros(x), for x a matrix.
 */
extern void
mccZeros( mxArray *p, mxArray *q );


/*
 *  Implements zeros(m,n), m and n integers.
 */
extern void
mccZerosMN( mxArray *p, int m, int n );


/*
 *  Make p a matrix of zeros of the same shape as q.
 */
extern void
mccZerosCopyShape( mxArray *p, mxArray *q );


/*
 *  Return 1 if matrix p has nontrivial imaginary part.
 */
extern int
mccIsImag( mxArray *p );


/*
 *  This routine returns the first argument of a function.
 *  Note that the semantics are slightly different for the first
 *  argument if the output argument has never been set.
 */
extern void
mccReturnFirstValue( mxArray **qin, mxArray *p );


extern void
mccFixInternalMatrix( mxArray *matlab5_matrix, mxArray *compiler_matrix, int return_value );


/*
 *  Return the second and later return values from a compiled function.
 */
extern void
mccReturnValue( mxArray **qin, mxArray *p );


/*
 *  Fix the type field and zero the other fields to make the compiler
 *  mxArray acceptable to the interpreter
 */
extern void
mccFixFlags( mxArray *p );


/*
 *  Create and return a scalar quantity.
 *
 *  Accept flags about whether the return value should be logical
 */
extern void
mccReturnScalar( mxArray **qin, double re, double im, mxArrayType kind, int flags );


/*
 *  Implement 'real' of a matrix.
 */
extern void
mccReal( mxArray *p, mxArray *q );


/*
 *  Implement 'imag' of a matrix.
 */
extern void
mccImag( mxArray *p, mxArray *q );


/*
 *  Create p equal to lo:hi.
 */
extern void
mccColon2( mxArray *p, double lo, double hi );


/*
 *  Create p equal to lo:step:hi, with lo and step integers
 */
extern void
mccIntColon( mxArray *p, int ilo, int step, double hi );


/*
 *  Create p equal to lo:step:hi.
 */
extern void
mccColon( mxArray *p, double a, double d, double b );


/*
 *  Version of colon2 that accepts complex matrices.
 */
extern void
mccMatrixColon2( mxArray *p, mxArray *q, mxArray *r );


/*
 *  Version of colon that accepts complex matrices.
 */
extern void
mccMatrixColon( mxArray *p, mxArray *q, mxArray *r, mxArray *s );


/*
 *  Store the integer value v in the (i,j)'th element of p.
 *  Check the current size, and grow if necessary.
 */
extern void
mccSetIntMatrixElement( mxArray *p, int i, int j, int v );


/*
 *  Store the real value (re) in the (i,j)'th element of p.
 *  Check the current size, and grow if necessary.
 */
extern void
mccSetRealMatrixElement( mxArray *p, int i, int j, double re );


/*
 *  Store the real value (re) in the i'th element of p.
 *  Check the current size, and grow if necessary.
 */
extern void
mccSetRealVectorElement( mxArray *p, int i, double re );


/*
 *  Store the int value v in the i'th element of p.
 *  Check the current size, and grow if necessary.
 */
extern void
mccSetIntVectorElement( mxArray *p, int i, int v );


/*
 *  Make p a 1x1 matrix and store the value (re) in the (1,1) element.
 */
extern void
mccCreateRealScalar( mxArray *p, double re );


/*
 *  Store the value (re+i*im) in the (i,j)'th element of p.
 *  Check the current size, and grow if necessary.
 */
extern void
mccSetMatrixElement( mxArray *p, int i, int j, double re, double im );


/*
 *  Store the value (re+i*im) in the i'th element of p.
 *  Check the current size, and grow if necessary.
 */
extern void
mccSetVectorElement( mxArray *p, int i, double re, double im );


/*
 *  Replace p by a 1x1 matrix, and store (re+i*im) in the (1,1) element.
 */
extern void
mccCreateScalar( mxArray *p, double re, double im );


/*
 *  Expand the scalar re+i*im into matrix p whose dimension is given by q.
 */
extern void
mccCreateConstantMatrix( mxArray *p, double re, double im, mxArray *q );


/*
 *  Expand the scalar re+i*im into matrix p whose dimensions are given by
 *  the matrices (of ones) q and r.
 */
extern void
mccCreateConstant2DMatrix( mxArray *p, double re, double im, mxArray *q,
                                                mxArray *r);


/*
 *  Expands the scalar re into a matrix p whose dimension is given by q.
 */
extern void
mccCreateRealConstantMatrix( mxArray *p, double re, mxArray *q );


/*
 *  Expands the scalar re into a matrix p whose dimensions are given by
 *  the matrices (of ones) q and r.
 */
extern void
mccCreateRealConstant2DMatrix( mxArray *p, double re, mxArray *q, mxArray *r );


/*
 *  Return element (i,j) of the real part of matrix p.
 */
extern double
mccGetRealMatrixElement( mxArray *p, int i, int j );


/*
 *  Return element (i,j) of the real part of an integer matrix p.
 */
extern int
mccGetIntMatrixElement( mxArray *p, int i, int j );


/*
 *  Return element i of the real part of matrix p.
 */
extern double
mccGetRealVectorElement( mxArray *p, int i );


/*
 *  Return element i of the real part of an integer matrix p.
 */
extern int
mccGetIntVectorElement( mxArray *p, int i );


/*
 *  Convert one element of a vector into a scalar matrix; preserve string flag.
 */
extern mxArray *
mccTempVectorElement( mxArray *p, double di );


/*
 *  Convert one element of a matrix into a scalar matrix; preserve string flag.
 */
extern mxArray *
mccTempMatrixElement( mxArray *p, double di, double dj );


/*
 *  Return the imaginary part of element (i,j) of matrix p.
 */
extern double
mccGetImagMatrixElement( mxArray *p, int i, int j );


/*
 *  Return the imaginary part of element i of matrix p.
 */
extern double
mccGetImagVectorElement( mxArray *p, int i );


/*
 *  Return a <very> temporary MATLAB matrix, good only for a callback.
 *  Also used to call builtin functions (mccXXX...).
 *
 *  Accept flags about whether the temporary matrix should be logical
 *
 */
extern mxArray *
mccTempMatrix( double re, double im, int cx, int flags );


/*
 *  Return a temporary MATLAB matrix containing string s.
 *  This is good only for callbacks.
 */
extern mxArray *
mccTempMATStr( char *s );


/*
 *  Print the matrix passed as the first argument with a label given by
 *  the second.  Intended for debugging (not all matrix elements printed).
 */
extern void
mccDEBUG( mxArray *p, char *ss );


/*
 *  Does what Matlab does in if's of arrays.
 *  Note: this is subtly different from all(all(p)).
 */
extern int
mccIfCondition( mxArray *p );


/*
 *  Copy matrix q into matrix p.
 */
extern void
mccCopy( mxArray *p, mxArray *q );


/*
 *  Copy the string s into the matrix p.
 */
extern void
mccCreateString( mxArray *p, char *s );


/*
 *  implements ppp = [a,b].
 */
extern void
mccCatenateColumns( mxArray *ppp, mxArray *a, mxArray *b );


/*
 *  Implement pp = [a;b].
 */
extern void
mccCatenateRows( mxArray *ppp, mxArray *a, mxArray *b );


/*
 *  Generate column of data for a 'for' statememt.
 */
extern void
mccForCol( mxArray *p, mxArray *q, int n );


/*
 *  Remove the elements of p indicated by r.  Put the result in q.
 */
extern void
mccZapElements( mxArray *q, mxArray *p, mxArray *r );


/*
 *  Remove the rows of p indicated by r.  Put the result in q.
 */
extern void
mccZapRows( mxArray *q, mxArray *p, mxArray *r );


/*
 *  Remove the columns of p indicated by r.  Put the result in q.
 */
extern void
mccZapColumns( mxArray *q, mxArray *p, mxArray *r );


/*
 *  This routine checks the logical flag on p.  If it is not set,
 *  it copies p to the output array q.  If it is set, it treats
 *  p as a logical index and calculates all of the offsets to the
 *  non-zero elements.
 *
 *  If the index is non-logical, the result has the same shape as the
 *  input.  If the index is logical, the result is a column vector, unless
 *  the input is a row vector in which case it is a row vector.
 *
 */
extern void
mccFindIndex( mxArray *q, mxArray *p );


/*
 *  Make p into an empty matrix.
 */
extern void
mccCreateEmpty( mxArray *p );


/*
 *  Complain about the use of a function argument not present
 *  This function is for the case where the value is used
 */
extern void
mccUndefVariable( mxArray *p, mxArray *s );


/*
 *  Complain about a use of a function argument not present in the call.
 */
extern void
mccUndefVariable1( mxArray *s );


extern void
mccMatrixExpand( mxArray *matrix, double re, double im );


extern void
mccRowExpand( mxArray *matrix, mxArray *rows, double re, double im );


extern void
mccColExpand( mxArray *matrix, mxArray *cols, double re, double im );


/*
 *  Absolute value function.
 */
extern void
mccAbs( mxArray *ppp, mxArray *q );


/*
 *  Inner product of two real vectors.
 */
extern double
mccRealInnerProduct( mxArray *p, mxArray *q );


/*
 *  Complex inner product of two complex vectors.
 */
extern void
mccInnerProduct( double *re, double *im, mxArray *p, mxArray *q );


/*
 *  Implements 'any' function.
 */
extern void
mccAny( mxArray *p, mxArray *q );


/*
 *  Implements 'all' function.
 */
extern void
mccAll( mxArray *p, mxArray *q );


/*
 *  Implements Conjugate Transpose function.
 */
extern void
mccConjTrans( mxArray *ppp, mxArray *q );


/*
 *  Implements Transpose operator.
 */
extern void
mccTrans( mxArray *ppp, mxArray *q );


/*
 *  Implements Complex matrix multiply.
 */
extern void
mccMultiply( mxArray *ppp, mxArray *q, mxArray *r );


/*
 *  Implements 'fix' function.
 */
extern void
mccFix( mxArray *p, mxArray *q );


/*
 *  Implements 'round' function.
 */
extern void
mccRound( mxArray *p, mxArray *q );


/*
 *  Implements 'floor' function.
 */
extern void
mccFloor( mxArray *p, mxArray *q );


/*
 *  Implements 'ceil' function.
 */
extern void
mccCeil( mxArray *p, mxArray *q );


/*
 *  Implements 'find' function for scalars
 */
extern void
mccFindScalar( mxArray *p, int flag );


/*
 *  Implements 'find' function.
 */
extern void
mccFind( mxArray *p, mxArray *q );


extern double mccRint( double x );


extern char *mccGetString( mxArray *string );

 
extern void 
mccLoad(const char *file, ... );


/*
 *  Implements 'sin' function (currently, real only).
 */
extern void
mccSin( mxArray *p, mxArray *q );


/*
 *  Implements 'cos' function (currently, real only).
 */
extern void
mccCos( mxArray *p, mxArray *q );


/*
 *  Implements 'tan' function (currently, real only).
 */
extern void
mccTan( mxArray *p, mxArray *q );


/*
 *  Implements 'asin' function (currently, real only).
 */
extern void
mccAsin( mxArray *p, mxArray *q );


/*
 *  Implements 'acos' function (currently, real only).
 */
extern void
mccAcos( mxArray *p, mxArray *q );


/*
 *  Implements 'atan' function (currently, real only)
 */
extern void
mccAtan( mxArray *p, mxArray *q );


/*
 *  Implements array power (currently, real only).
 */
extern void
mccRealPower( mxArray *p, mxArray *q, mxArray *r );


/*
 *  Implements 'atan2' function (currently, real only).
 */
extern void
mccAtan2( mxArray *p, mxArray *q, mxArray *r );


/*
 *  Implements 'log10' function (currently, real only).
 */
extern void
mccLog10( mxArray *p, mxArray *q );


/*
 *  Implements 'log' function (currently, real only).
 */
extern void
mccLog( mxArray *p, mxArray *q );


/*
 *  Implements 'sqrt' function (currently, real only).
 */
extern void
mccSqrt( mxArray *p, mxArray *q );


/*
 *  Implements 'sign' function (currently, real only).
 */
extern void
mccSign( mxArray *p, mxArray *q );


/*
 *  Implements 'sum' on complex vector, returning scalar result.
 */
extern void
mccVectorSum( double *pr, double *pi, mxArray *p );


/*
 *  Implements 'sum' on real vector, returning scalar result.
 */
extern double
mccRealVectorSum( mxArray *p );


/*
 *  Implements 'sum' of a matrix.
 */
extern void
mccSum( mxArray *p, mxArray *q );


/*
 *  Implements scalar product of a complex vector
 */
extern void
mccVectorProduct( double *pr, double *pi, mxArray *p );


/*
 *  Implements scalar product of a real vector
 */
extern double
mccRealVectorProduct( mxArray *p );


/*
 *  Implements 'max' of a vector of integers.
 *  NOTE: I renamed this function to be more consistent with
 *  other functions that operated on vectors.
 *  JTM: 1/21/97
 */
extern int
mccIntVectorMax( mxArray *p );


/*
 *  Implements 'min' of a vector of integers.
 *  NOTE: I renamed this function to be more consistent with
 *  other functions that operated on vectors.
 *  JTM: 1/21/97
 */
extern int
mccIntVectorMin( mxArray *p );


/*
 *  Implements 'max' of a vector of shorts. 
 */
extern unsigned short
mccShortVectorMax( mxArray *p );


/*
 *  Implements 'min' of a vector of integers. 
 */
extern unsigned short
mccShortVectorMin( mxArray *p );


/*
 *  Implements 'max' of a real vector.
 */
extern double
mccRealVectorMax( mxArray *p );


/*
 *  Implements 'min' of a vector of reals.
 */
extern double
mccRealVectorMin( mxArray *p );


/*
 *  Implements 'max' of a matrix 
 */
extern void
mccMax( mxArray *p, mxArray *q );


/*
 *  Implements 'min' of a matrix
 */
extern void
mccMin( mxArray *p, mxArray *q );


/*
 *  Implements 'strcmp' function.
 *  This will compare complex parts as well, like the interpreter version.
 */
extern int
mccStrcmp( mxArray *p, mxArray *q );


/*
 *  Implements 'findstr' function.
 */
extern void
mccFindstr( mxArray *p, mxArray *q, mxArray *r );


/*
 *  Implement 'isletter'.
 */
extern void
mccIsLetter( mxArray *p, mxArray *q );


/*
 *  Implement 'lower'.
 */
extern void
mccLower( mxArray *p, mxArray *q );


/*
 *  Implement 'upper'.
 */
extern void
mccUpper( mxArray *p, mxArray *q );


/*
 *  Return true if the matrix is actually real
 */
extern int
mccActuallyReal( mxArray *p );


/*
 *      C-callable version of the 'error' function.
 */
extern void
mccError( mxArray *p );


/*
 *  Get the value of global s and put it in p.
 */
extern void 
mccGetGlobal( mxArray *p, const char *name  );


/*
 *  set the global s to the value in p.
 */
extern void
mccSetGlobal( const char *name, mxArray *p );


/*
 *  General callback into MATLAB to run an M-file or mexfile.
 */
extern void
mccCallMATLAB( int nlhs, mxArray **plhs, int nrhs, mxArray **prhs, char *s,
                                                        int line );


/*
 *  Implements Real matrix multiply.
 */
extern void
mccRealMatrixMultiply( mxArray *p, mxArray *q, mxArray *r );


/*
 *  Implement complex array power.
 */
extern void
mccArrayPower( mxArray *p, mxArray *q, mxArray *r );


/*
 *  Implement complex matrix power.
 */
extern void
mccPower( mxArray *p, mxArray *q, mxArray *r );


/*
 *  Implement complex array right division.
 */
extern void
mccArrayRightDivide( mxArray *p, mxArray *q, mxArray *r );


/*
 *  Implement real array right division.
 */
extern void
mccRealArrayRightDivide( mxArray *p, mxArray *q, mxArray *r );


/*
 *  Implement complex matrix right division.
 */
extern void
mccRightDivide( mxArray *p, mxArray *q, mxArray *r );


/*
 *  Implement real matrix right divide.
 */
extern void
mccRealRightDivide( mxArray *p, mxArray *q, mxArray *r );


/*
 *  Implement complex array left division.
 */
extern void
mccArrayLeftDivide( mxArray *p, mxArray *q, mxArray *r );


/*
 *  Implement real array left division.
 */
extern void
mccRealArrayLeftDivide( mxArray *p, mxArray *q, mxArray *r );


/*
 *  Implement complex matrix left division.
 */
extern void
mccLeftDivide( mxArray *p, mxArray *q, mxArray *r );


/*
 *  Implement real matrix left division.
 */
extern void
mccRealLeftDivide( mxArray *p, mxArray *q, mxArray *r );


/*
 *  Stub 'eval' function that complains and dies.
 */
extern void
mccEval( mxArray *p );


/*
 *  Implement the printing of named expressions not ended by a ;.
 */
extern void
mccPrint( mxArray *p, char *s );


/*
 *  Get realmax from a local copy after the first time.
 */
extern double
mccRealmax();


/*
 *  Get realmin from a local copy after the first time.
 */
extern double
mccRealmin();


/*
 *  Output a string.
 */
extern void
mccPuts( char *s );


/*
 *  Get an argument for a standalone program
 */
extern void
mccArgv( mxArray *p, int n );


/*
 *  Get the argument count for a standalone program
 */
extern int
mccArgc();


/*
 *  Set the argc and argv arguments
 */
extern void
mccSetArgs( int argc, char **argv );


/*
 *  Local version of mexPrintf, to get around a bug in it
 */
extern void
mccPrintf( const char *format, ... );


extern void
mccFreeMlfRhs( mxArray *rhs_, int nrhs );


extern void
mccGlobalClear( const char *name );


extern void
mccAllGlobalClear( void );


extern void
mccSave(const char *file, const char *mode, ... );


/*
 * Set the current line number
 */
extern void
mcmSetLineNumber(int line);


/*
 *  Function returning value of pi
 */
extern double
mcmPi();


/*
 *  Routine to print its argument and stop, with an m-file line number if
 *  the user compiled with the -l option.
 */
extern void
mcmError( char *ss );


/*
 *  Routine to print its argument and stop, supplying an m-file line number.
 */
extern void
mcmErrorWithLine( char *s, int line );


/*
 *  Routine to print a fatal internal error message and stop
 */
extern void
mcmFatal( char *ss );


/*
 *  Routine to print its first argument, with an internal (C++ source file)
 *  line number as well as a user (m-file) line number.  Used for debugging.
 */
extern void
mcmInternal( char *ss, int line );


/*
 *  Real raised to an integer power.
 */
extern double
mcmRealPowerInt( double d, int n );


/*
 *  Complex logarithm.
 */
extern void
mcmLog( double *par, double *pai, double br, double bi );


/*
 *  Compiler complex scalar power.
 */
extern void
mcmPower( double *par, double *pai, double br, double bi, double cr, double ci);


/*
 *  Complex divide routine.
 */
extern void
mcmDivide( double *cr, double *ci, double ar, double ai, double br, double bi );


/*
 *  Real part of a complex division.
 */
extern double
mcmDivideRealpart( double ar, double ai, double br, double bi );


/*
 *  Imaginary part of a complex division.
 */
extern double
mcmDivideImagPart( double ar, double ai, double br, double bi );


/*
 *  Check the total size of an assignment.
 */
extern void
mcmCheck( int sz1, int sz2 );


/*
 *  Array with 1 +/- 2*eps, for colon computations.
 */
extern double mcmEps2[2];


/*
 *  Number of elements in 3-argument colon expression.
 */
extern int
mcmColonCount( double lo, double step, double hi );


/*
 *  Largest element in 3-argument colon expression.
 */
extern int
mcmColonMax( double lo, double step, double hi );


/*
 *  mm and *pn are the current size of a matrix result.  A new matrix
 *  whose size is given by m and n is combined with the current size.
 *  mcmCalcResultSize returns the resulting value of m, and updates the
 *  value of n through *pn.
 */
extern int
mcmCalcResultSize( int mm, int *pn, int m, int n );


/*
 *  Hypot function.
 */
extern double
mcmHypot( double re, double im );


/*
 *  Round function.
 */
extern double
mcmRound( double d );


/*
 *  Complex Round function.
 */
extern void
mcmComplexRound( double *pr, double *pi, double qr, double qi );


/*
 *  Fix function.
 */
extern double
mcmFix( double d );


/*
 *  Constant used to convert log to log10.
 */
extern double mcmLog10Const;


/*
 *  Log10 function (real argument only).
 */
extern double
mcmLog10( double d );


/*
 *  Max of two integers.
 */
extern int
mcmIntMax( int m, int n );


/*
 *  Max of two reals.
 */
extern double
mcmMax( double m, double n );


/*
 *  Min of two integers.
 */
extern int
mcmIntMin( int m, int n );


/*
 *  Min of two reals. 
 */
extern double
mcmMin( double m, double n );


/*
 *  Sign function (real argument).
 */
extern int
mcmRealSign( double d );


/*
 *  Sign function (integer argument).
 */
extern int
mcmIntSign( int n );


/*
 *  Debugging routine to display mxArray object
 */
extern void
mccDUMP( mxArray *p, char *s );


/*
 *  Check for basic sanity in a matrix (for debugging)
 */
extern void
mccCK( mxArray *p, char *s );


/*
 *  Generate a matrix pointer and check the type
 */
extern void *
mccDbp( const mxArray *p, int sz );


/*
 *  Converts type into the element size
 *  Works for both interpreter and compiler types
 */
extern int
mccObjSize[];

#endif /* mcc_h */
