core/matlab/examples/mex/mexcallmatlab.c

00001 /*=================================================================
00002  * mexcallmatlab.c
00003  *
00004  * mexcallmatlab takes no inputs.  This routine first forms and
00005  * displays the following matrix (in MATLAB notation):
00006  *
00007  *      hankel(1:4,4:-1:1) + sqrt(-1)*toeplitz(1:4,1:4)
00008  *
00009  * Next it finds the eigenvalues and eigenvectors (using the MATLAB
00010  * function EIG), and displays the eigenvalue matrix.  Then it
00011  * calculates the inverse of the eigenvalues to demonstrate manipulation
00012  * of MATLAB results and how to deal with complex arithemetic.  Finally,
00013  * the program displays the inverse values.
00014  *
00015  * Copyright 1984-2006 The MathWorks, Inc.
00016  * $Revision: 1.1 $
00017  *================================================================*/
00018 
00019 #include <math.h>
00020 #include "mex.h"
00021 
00022 #define XR(i,j) xr[i+4*j]
00023 #define XI(i,j) xi[i+4*j]
00024 
00025 static void fill_array( double  *xr, double  *xi)
00026 {
00027     double tmp;
00028     int i,j,jj;
00029     /* Remember, MATLAB stores matrices in their transposed form,
00030        i.e., columnwise, like FORTRAN. */
00031     
00032 /* Fill real and imaginary parts of array. */
00033     for (j = 0; j < 4; j++) {
00034     for (i = 0; i <= j; i++) {
00035         XR(i,j) = 4 + i - j;
00036         XR(j,i) = XR(i,j);
00037         XI(i,j) = j - i + 1;
00038         XI(j,i) = XI(i,j);
00039     }
00040     }
00041     /* Reorder columns of xr. */
00042     for (j = 0; j < 2; j++) {
00043     for (i = 0; i < 4; i++) {
00044         tmp = XR(i,j);
00045         jj = 3 - j;
00046         XR(i,j) = XR(i,jj);
00047         XR(i,jj) = tmp;
00048     }
00049     }
00050 }
00051 
00052 /* Invert diagonal elements of complex matrix of order 4 */
00053 static void invertd( double *xr, double *xi )
00054 {
00055     double tmp;
00056     double *rx, *ix;
00057     int i;
00058     
00059     rx = xr;
00060     ix = xi;
00061     
00062     /* I know diagnonal elements of a 4 X 4 are 1:5:16 */
00063     for (i = 0; i < 16; i += 5, rx += 5, ix += 5) {
00064     tmp = *rx * *rx + *ix * *ix;
00065     *rx = *rx / tmp;
00066     *ix = - *ix / tmp;
00067     }       
00068 }
00069 
00070 void 
00071 mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
00072 {
00073     mwSize m, n;
00074     mxArray *lhs[2], *x;
00075     (void) prhs;           /* unused parameter */
00076     
00077     m = n = 4;
00078     
00079     /* Check for proper number of input and output arguments */    
00080     if (nrhs != 0) {
00081     mexErrMsgTxt("No input arguments required.");
00082     } 
00083     if(nlhs > 1){
00084     mexErrMsgTxt("Too many output arguments.");
00085     } 
00086     
00087     /* Allocate x matrix */
00088     x =  mxCreateDoubleMatrix(m, n, mxCOMPLEX);
00089     
00090     /* create values in some arrays -- remember, MATLAB stores matrices
00091        column-wise */
00092     fill_array(mxGetPr(x), mxGetPi(x));
00093     
00094     /* print out initial matrix */
00095     mexCallMATLAB(0,NULL,1, &x, "disp");
00096     
00097     /* calculate eigenvalues and eigenvectors */
00098     mexCallMATLAB(2, lhs, 1, &x, "eig");
00099     
00100     /* print out eigenvalue matrix */
00101     mexCallMATLAB(0,NULL,1, &lhs[1], "disp");
00102     
00103     /* take inverse of complex eigenvalues, just on diagonal */
00104     invertd(mxGetPr(lhs[1]), mxGetPi(lhs[1]));
00105     
00106     /* and print these out */
00107     mexCallMATLAB(0,NULL,1, &lhs[1], "disp");
00108     
00109     /* Free allocated matrices */
00110     mxDestroyArray(x);
00111     mxDestroyArray(lhs[1]);
00112     plhs[0] = lhs[0];
00113 }
00114 

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