core/matlab/examples/mx/mxsetdimensions.c

00001 /*=================================================================
00002  * mxsetdimensions.c 
00003  *
00004  * mxsetdimensions reshapes your input array according to the the new
00005  * dimensions specified as input. For example,
00006  * mxsetdimensions(X,M,N,P,...) returns an N-D array with the same
00007  * elements as X but reshaped to have the size M-by-N-by-P-by-...
00008  * M*N*P*... must contain the same number of elements as X.
00009  *
00010  * This is a MEX-file for MATLAB.  
00011  * Copyright 1984-2006 The MathWorks, Inc.
00012  * All rights reserved.
00013  *=================================================================*/
00014 
00015 /* $Revision: 1.1 $ */
00016 #include <string.h>
00017 #include "mex.h"
00018 
00019 void
00020 mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[])
00021 {
00022     
00023     mwSize number_input_elements, number_new_elements;
00024     mwSize i, number_new_dims, *new_dims;  
00025     
00026     /* Check for proper number of input and output arguments */    
00027     if (nrhs < 3) {
00028         mexErrMsgTxt("At least 3 input arguments required.");
00029     } 
00030     if(nlhs > 1){
00031         mexErrMsgTxt("Too many output arguments.");
00032     }
00033     number_new_dims = nrhs-1;
00034     if (mxIsSparse(prhs[0]) && number_new_dims != 2){
00035     mexErrMsgTxt("Multidimensional sparse arrays are not supported.\n");
00036     }
00037 
00038     number_input_elements = mxGetNumberOfElements(prhs[0]); 
00039     
00040     /* Allocate memory for the new_dims array on the fly */
00041     new_dims = mxMalloc(number_new_dims * sizeof(*new_dims)); 
00042 
00043     /* Create the dimensions array and check to make sure total number of
00044        elements for the input array is the same for the reshaped array. */
00045     number_new_elements=1;
00046     for (i=0; i< number_new_dims;i++){
00047     const mxArray *pa;
00048     pa = prhs[i+1];
00049     if(mxGetNumberOfElements(pa) != 1) {
00050         /* Free allocated memory */
00051         mxFree(new_dims);
00052         mexErrMsgTxt("Size arguments must be integer scalars.");
00053     }
00054     new_dims[i] = (mwSize)mxGetScalar(pa);
00055     number_new_elements = new_dims[i]*number_new_elements; 
00056     }
00057     if (number_new_elements != number_input_elements){
00058     /* Free allocated memory */
00059     mxFree(new_dims);
00060     mexErrMsgTxt("Total number of elements in the new array, must equal number of elements in input array.\n");
00061     } 
00062     /* Duplicate the array */
00063     plhs[0] = mxDuplicateArray(prhs[0]); 
00064     
00065     /* If array is sparse, use the sparse routine to reshape,
00066        otherwise, use mxSetDimensions. */
00067     if (mxIsSparse(plhs[0])){ 
00068     mwSize mold; /* old number of rows */ 
00069     mwSize nold; /* old number of columns */ 
00070     mwIndex *jcold; /*old jc array */ 
00071     mwIndex *ir; /* ir array that is modified in place */ 
00072     mwSize mnew; /* new number of rows */ 
00073     mwSize nnew; /* new number of columns */
00074     mwIndex *jcnew; /* new jc array */  
00075     mwSize j, offset, offset1;
00076         
00077     /* Allocate space for new jc. */    
00078     jcnew = ((mwIndex*)mxCalloc(new_dims[1]+1, sizeof(mwIndex)));
00079 
00080     mnew = new_dims[0];
00081     nnew = new_dims[1];
00082         
00083     /* Get M, N, Ir and Jc of input array. */
00084     mold = mxGetM(plhs[0]);
00085     nold = mxGetN(plhs[0]);
00086     jcold = mxGetJc(plhs[0]);
00087     ir = mxGetIr(plhs[0]);
00088     
00089     /* First change ir so it acts like one long column vector */
00090     for (i=1, offset=mold; i < nold; i++, offset+=mold){
00091         for (j=jcold[i]; j < jcold[i+1]; j++){
00092         ir[j] += offset;
00093         }
00094     }
00095     /* Then fix ir and jcnew for new m and n */
00096     for (i=0, j=0, offset=mnew-1, offset1=0; i < jcold[nold]; ) {
00097         if (ir[i] > offset) {
00098         jcnew[++j] = i;
00099         offset  += mnew;
00100         offset1 += mnew;
00101         } else {
00102         ir[i++] -= offset1;
00103         }
00104     }
00105     for (j++; j <= nnew; j++){
00106         jcnew[j]=jcold[nold];
00107     }
00108 
00109     /* Free the old Jc, set the new Jc, M, and N. */
00110     mxFree(mxGetJc(plhs[0]));
00111     mxSetJc(plhs[0],jcnew);
00112     mxSetM(plhs[0],mnew);
00113     mxSetN(plhs[0],nnew);
00114     }
00115     else{
00116     /* Set the new dimensions. */
00117     mxSetDimensions(plhs[0],new_dims, number_new_dims);
00118     }
00119 
00120 /* Free allocated memory*/
00121     mxFree(new_dims);
00122 }
00123 
00124 
00125 

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