core/matlab/examples/refbook/phonebook.c

00001 /* ==========================================================================
00002  * phonebook.c 
00003  * example for illustrating how to manipulate structure and cell array
00004  *
00005  * takes a (MxN) structure matrix and returns a new structure (1x1)
00006  * containing corresponding fields: for string input, it will be (MxN)
00007  * cell array; and for numeric (noncomplex, scalar) input, it will be (MxN)
00008  * vector of numbers with the same classID as input, such as int, double
00009  * etc..
00010  *
00011  * This is a MEX-file for MATLAB.
00012  * Copyright 1984-2006 The MathWorks, Inc.
00013  *==========================================================================*/
00014 /* $Revision: 1.1 $ */
00015 
00016 #include "mex.h"
00017 #include "string.h"
00018 
00019 #define MAXCHARS 80   /* max length of string contained in each field */
00020 
00021 /*  the gateway routine.  */
00022 void mexFunction( int nlhs, mxArray *plhs[],
00023                   int nrhs, const mxArray *prhs[] )
00024 {
00025     const char **fnames;       /* pointers to field names */
00026     const mwSize *dims;
00027     mxArray    *tmp, *fout;
00028     char       *pdata=NULL;
00029     int        ifield, nfields;
00030     mxClassID  *classIDflags;
00031     mwIndex    jstruct;
00032     mwSize     NStructElems;
00033     mwSize     ndim;
00034 
00035     /* check proper input and output */
00036     if(nrhs!=1)
00037       mexErrMsgTxt("One input required.");
00038     else if(nlhs > 1)
00039       mexErrMsgTxt("Too many output arguments.");
00040     else if(!mxIsStruct(prhs[0]))
00041       mexErrMsgTxt("Input must be a structure.");
00042     /* get input arguments */
00043     nfields = mxGetNumberOfFields(prhs[0]);
00044     NStructElems = mxGetNumberOfElements(prhs[0]);
00045     /* allocate memory  for storing classIDflags */
00046     classIDflags = mxCalloc(nfields, sizeof(mxClassID));
00047 
00048     /* check empty field, proper data type, and data type consistency;
00049      and get classID for each field. */
00050     for(ifield=0; ifield<nfields; ifield++) {
00051     for(jstruct = 0; jstruct < NStructElems; jstruct++) {
00052         tmp = mxGetFieldByNumber(prhs[0], jstruct, ifield);
00053         if(tmp == NULL) {
00054         mexPrintf("%s%d\t%s%d\n", "FIELD: ", ifield+1, "STRUCT INDEX :", jstruct+1);
00055         mexErrMsgTxt("Above field is empty!"); 
00056         } 
00057         if(jstruct==0) {
00058         if( (!mxIsChar(tmp) && !mxIsNumeric(tmp)) || mxIsSparse(tmp)) { 
00059             mexPrintf("%s%d\t%s%d\n", "FIELD: ", ifield+1, "STRUCT INDEX :", jstruct+1);
00060             mexErrMsgTxt("Above field must have either string or numeric non-sparse data.");
00061         }
00062         classIDflags[ifield]=mxGetClassID(tmp); 
00063         } else {
00064         if (mxGetClassID(tmp) != classIDflags[ifield]) {
00065             mexPrintf("%s%d\t%s%d\n", "FIELD: ", ifield+1, "STRUCT INDEX :", jstruct+1);
00066             mexErrMsgTxt("Inconsistent data type in above field!"); 
00067         } else if(!mxIsChar(tmp) && 
00068               ((mxIsComplex(tmp) || mxGetNumberOfElements(tmp)!=1))){
00069             mexPrintf("%s%d\t%s%d\n", "FIELD: ", ifield+1, "STRUCT INDEX :", jstruct+1);
00070             mexErrMsgTxt("Numeric data in above field must be scalar and noncomplex!"); 
00071         }
00072         }
00073     }
00074     }
00075 
00076     /* allocate memory  for storing pointers */
00077     fnames = mxCalloc(nfields, sizeof(*fnames));
00078     /* get field name pointers */
00079     for (ifield=0; ifield< nfields; ifield++){
00080     fnames[ifield] = mxGetFieldNameByNumber(prhs[0],ifield);
00081     }
00082     /* create a 1x1 struct matrix for output  */
00083     plhs[0] = mxCreateStructMatrix(1, 1, nfields, fnames);
00084     mxFree((void *)fnames);
00085     ndim = mxGetNumberOfDimensions(prhs[0]);
00086     dims = mxGetDimensions(prhs[0]);
00087     for(ifield=0; ifield<nfields; ifield++) {
00088     /* create cell/numeric array */
00089     if(classIDflags[ifield] == mxCHAR_CLASS) {
00090         fout = mxCreateCellArray(ndim, dims);
00091     }else {
00092         fout = mxCreateNumericArray(ndim, dims, classIDflags[ifield], mxREAL);
00093         pdata = mxGetData(fout);
00094     }
00095     /* copy data from input structure array */
00096     for (jstruct=0; jstruct<NStructElems; jstruct++) {
00097         tmp = mxGetFieldByNumber(prhs[0],jstruct,ifield);
00098         if( mxIsChar(tmp)) {
00099         mxSetCell(fout, jstruct, mxDuplicateArray(tmp));
00100         }else {
00101         mwSize     sizebuf;
00102         sizebuf = mxGetElementSize(tmp);
00103         memcpy(pdata, mxGetData(tmp), sizebuf);
00104         pdata += sizebuf;
00105         }
00106     }
00107     /* set each field in output structure */
00108     mxSetFieldByNumber(plhs[0], 0, ifield, fout);
00109     }
00110     mxFree(classIDflags);
00111     return;
00112 }
00113     

GridLAB-DTM Version 1.0
An open-source project initiated by the US Department of Energy