Search All of the Math Forum:

Views expressed in these public forums are not endorsed by NCTM or The Math Forum.

Notice: We are no longer accepting new posts, but the forums will continue to be readable.

Topic: partial matrix operations without memory copying
Replies: 2   Last Post: Dec 2, 2012 6:30 AM

 Messages: [ Previous | Next ]
 James Tursa Posts: 2,326 Registered: 8/5/09
Re: partial matrix operations without memory copying
Posted: Dec 2, 2012 6:30 AM

"Nick" wrote in message <k9e78r\$m21\$1@newscl01ah.mathworks.com>...
> I would like to do operations on vectors of a matrix efficiently, without memory copying.
> For example, say V is KxK, A is Nxp p>k
> I want to do X(:,1:K)*V efficiently. As it is currently written, matlab makes a temporary copy of the first K colomns of X and does the multiplication. The primitive BLAS routines can handle this without memory copying: just give it the same pointer to X with different number of columns as input. I would like to realize this speedup without having to go to mex. Is this possible?

It is *not* possible without a mex routine. For your particular example, however, the mex routine is very easy. Since you want the *first* k columns we can use a simple shared data copy with an altered number of columns:

/* Create shared data copy of 1st k columns of input */
/* B = subblock(A,k) */
/* A = m x n matrix (any class) */
/* B = m x k matrix using shared data of A */
/* */
/* If k < 0, then 0 is used. */
/* If k > n, then n is used. */
/* */
/* Programmer: James Tursa */

#include "mex.h"

#ifndef MWSIZE_MAX
#define mwSize int
#endif

mxArray *mxCreateSharedDataCopy(mxArray *); /* Undocumented API function */

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
mwSize k, n;

if( nrhs != 2 ) {
mexErrMsgTxt("Need exactly two inputs.");
}
if( nlhs > 1 ) {
mexErrMsgTxt("Too many outputs.");
}
if( !mxIsNumeric(prhs[1]) || mxGetNumberOfElements(prhs[1]) != 1 ) {
mexErrMsgTxt("2nd argument must be a numeric scalar.");
}
n = mxGetN(prhs[0]);
k = mxGetScalar(prhs[1]);
if( k < 0 ) k = 0;
if( k > n ) k = n;
plhs[0] = mxCreateSharedDataCopy(prhs[0]);
mxSetN(plhs[0],k); /* Manually set the number of columns */
}

Note that this routine is very robust and does not require any special care on your part to use. The returned variable can be deleted at any time, or even exist in memory if you clear the original. The only caveat is that if you have a large variable then all of the original memory is locked up in the truncated variable. So if you start with a 1,000,000 column variable and you use the routine to get only the first column then clear the original 1,000,000 column variable, the new variable with only 1 column will still have the original 1,000,000 columns locked in memory. It simply is fooling MATLAB into thinking that there is only one column. To clear all the memory you will need to clear the variable.

If you want the sub-matrix to be an arbitrary set of contiguous columns and not necessarily the first set of contiguous columns, then you will have to use something like Bruno's suggested code.

James Tursa

Date Subject Author
12/1/12 NIcholas
12/2/12 Bruno Luong
12/2/12 James Tursa