NS2 Notebook: How to Use Matlab in NS

Back to NS2 Menu


This article shows a very simple example of using Matlab functions in your C++ code in NS. The general process is: write you functions in Matlab m files, compile these m files to a shared library using Matlab compiler, then use this library in NS C++ code. The example is based on Matlab compiler documentation. The example is compiled using Matlab compiler 4.1 and gcc 3.2 (NS version 2.27).

1. The first step is to write your Matlab function. The following is a simple function which adds two matrices.

addmatrix.m


function a = addmatrix(a1, a2)
%ADDMATRIX Add two matrices
%    This function adds the two matrices passed as input. This function is
%    used to demonstate the functionality of MATLAB Compiler. Refer to the
%    shared library section of MATLAB Compiler for more information.

% Copyright 2003 The MathWorks, Inc.

a = a1 + a2;

 

2. In Matlab, run command "mcc -B csharedlib:libmatrix addmatrix.m -v", then copy the generated libmatrix.h, libmatrix.ctf, libmatrix.so to ns-2.27/matlab/ directory (you should create it)

 

3. In ns-2.27/matlab/ directory, create two files for matlab class (a wrapper class for using matlab fuctions)

matlab.h



#include <stdio.h> 

/* Include the MCR header file and the library specific header file
 * as generated by MATLAB Compiler */
#include "mclmcr.h" 
#include "libmatrix.h" 

class Matlab {

public:
	Matlab();
	~Matlab();

	void Addmatrix(const double matrix1[], const int matrix1_r, const int matrix1_c,
		       const double matrix2[], const int matrix2_r, const int matrix2_c,
		       double *result, int* result_r, int* result_c );
};



matlab.cc



#include "matlab.h" 
  
// the constructor
Matlab::Matlab() {


	/* Call the mclInitializeApplication routine. Make sure that the application
	* was initialized properly by checking the return status. This initialization
	* has to be done before calling any MATLAB API's or MATLAB Compiler generated
	* shared library functions.  */
		
	if( !mclInitializeApplication(NULL,0) )
    {   
		fprintf(stderr, "Could not initialize the application.\n");
		exit(1);
	}

	/* Call the library intialization routine and make sure that the
	* library was initialized properly. */

	if (!libmatrixInitialize()){
        fprintf(stderr,"Could not initialize the library.\n");
        exit(1);
  	}	
}

// the destructor
Matlab::~Matlab(){
	
    /*If you want to use matlab function in multiple C++ objects, you'd better not
	*put the following code here because matlab application can only be initialized 
	*once during a single simulation run. You can put the following code to the 
	*destructor function of Simulator class which will be called once at the end of 
    *the simulation. */
   
    /* Call the library termination routine */
	libmatrixTerminate();
	libtestTerminate();

	/* Free the memory created */
	mclTerminateApplication();
	
}


void
Matlab::Addmatrix(const double matrix1[], const int matrix1_r, const int matrix1_c, 
                  const double matrix2[], const int matrix2_r, const int matrix2_c, 
                  double *result, int *result_r, int *result_c )
{
	mxArray *in1,	*in2;	/* Define inpute parameters */
	mxArray	*out = NULL;	/* and output parameters to be passed to the library  functions */
	double *data; /* variable to point to the double data stored within the mxArray */
	int i, j;
	
    /* Create the input data */
	in1	=	mxCreateDoubleMatrix(matrix1_r, matrix1_c, mxREAL);
	in2	=	mxCreateDoubleMatrix(matrix2_r, matrix2_c, mxREAL);
	memcpy(mxGetPr(in1), matrix1, matrix1_r*matrix1_c*sizeof(double));
	memcpy(mxGetPr(in2), matrix2, matrix2_r*matrix2_c*sizeof(double));

	/* Call the library function */
	mlfAddmatrix(1, &out, in1, in2);

	/* Get the size of the matrix */
  	*result_r = mxGetM(out);
  	*result_c = mxGetN(out);
 
	/* Get a pointer to the double data in mxArray */
	data = mxGetPr(out);

	/* Put data to result */
	for(i=0;i<*result_r;i++)
	{
		for(j=0;j<*result_c;j++)
			result[i*(*result_c)+j]=data[i*(*result_c)+j];
	}

	/* Free the memory created */
  	mxDestroyArray(in1); in1=0;
  	mxDestroyArray(in2); in2=0;

}

 

4. Write your code in any C++ class to call Matlab::Addmatrix, rememer to include matlab.h file

 

5.Add the following directories to your dynamic library path.
setenv LD_LIBRARY_PATH
/bin/glnx86:
/sys/os/glnx86:
/sys/java/jre/glnx86/jre1.4.2/lib/i386/client:
/sys/java/jre/glnx86/jre1.4.2/lib/i386:
/sys/opengl/lib/glnx86:${LD_LIBRARY_PATH}
setenv XAPPLRESDIR /X11/app-defaults

 

6. Modify ns-2.27/Makefile.in

INCLUDES = \
-I. @V_INCLUDE_X11@ \
@V_INCLUDES@ \
-I./tcp -I./sctp -I./common -I./link -I./queue \
-I./adc -I./apps -I./mac -I./mobile -I./trace \
-I./routing -I./tools -I./classifier -I./mcast \
-I./diffusion3/lib/main -I./diffusion3/lib \
-I./diffusion3/lib/nr -I./diffusion3/ns \
-I./diffusion3/filter_core -I./asim/ -I./qs \
-I/usr/local/matlab7/extern/include
#Please replace the path to matlab header files

......

LIB = \
@V_LIBS@ \
@V_LIB_X11@ \
@V_LIB@ -L./matlab -lmatrix \
-lm @LIBS@

......

OBJ_CC = \
......

matlab/matlab.o \
@V_STLOBJ@

 

 

7. run ./configure, make clean, make depend, make

 

© Copyright 2008. All rights reserved. Powered by Free Site Templates