Mercurial > hg > smallbox
changeset 15:51b76c31c93d
(none)
author | idamnjanovic |
---|---|
date | Thu, 25 Mar 2010 14:05:27 +0000 |
parents | a0571bf2ff54 |
children | 41a5a3c26961 |
files | Problems/private/col2imstep.c Problems/private/col2imstep.m Problems/private/im2colstep.c Problems/private/im2colstep.m Problems/private/mexutils.c Problems/private/mexutils.h Problems/private/sprow.c Problems/private/sprow.m |
diffstat | 8 files changed, 628 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Problems/private/col2imstep.c Thu Mar 25 14:05:27 2010 +0000 @@ -0,0 +1,146 @@ +/************************************************************************** + * + * File name: col2imstep.c + * + * Ron Rubinstein + * Computer Science Department + * Technion, Haifa 32000 Israel + * ronrubin@cs + * + * Last Updated: 31.8.2009 + * + *************************************************************************/ + + +#include "mex.h" + + +/* Input Arguments */ + +#define B_IN prhs[0] +#define N_IN prhs[1] +#define SZ_IN prhs[2] +#define S_IN prhs[3] + + +/* Output Arguments */ + +#define X_OUT plhs[0] + + +void mexFunction(int nlhs, mxArray *plhs[], + int nrhs, const mxArray*prhs[]) + +{ + double *x, *b, *s; + mwSize sz[3], stepsize[3], n[3], ndims; + mwIndex i, j, k, l, m, t, blocknum; + + + /* Check for proper number of arguments */ + + if (nrhs < 3 || nrhs > 4) { + mexErrMsgTxt("Invalid number of input arguments."); + } else if (nlhs > 1) { + mexErrMsgTxt("Too many output arguments."); + } + + + /* Check the the input dimensions */ + + if (!mxIsDouble(B_IN) || mxIsComplex(B_IN) || mxGetNumberOfDimensions(B_IN)>2) { + mexErrMsgTxt("B should be a double matrix."); + } + if (!mxIsDouble(N_IN) || mxIsComplex(N_IN) || mxGetNumberOfDimensions(N_IN)>2) { + mexErrMsgTxt("Invalid output matrix size."); + } + ndims = mxGetM(N_IN)*mxGetN(N_IN); + if (ndims<2 || ndims>3) { + mexErrMsgTxt("Output matrix can only be 2-D or 3-D."); + } + if (!mxIsDouble(SZ_IN) || mxIsComplex(SZ_IN) || mxGetNumberOfDimensions(SZ_IN)>2 || mxGetM(SZ_IN)*mxGetN(SZ_IN)!=ndims) { + mexErrMsgTxt("Invalid block size."); + } + if (nrhs == 4) { + if (!mxIsDouble(S_IN) || mxIsComplex(S_IN) || mxGetNumberOfDimensions(S_IN)>2 || mxGetM(S_IN)*mxGetN(S_IN)!=ndims) { + mexErrMsgTxt("Invalid step size."); + } + } + + + /* Get parameters */ + + s = mxGetPr(N_IN); + if (s[0]<1 || s[1]<1 || (ndims==3 && s[2]<1)) { + mexErrMsgTxt("Invalid output matrix size."); + } + n[0] = (mwSize)(s[0] + 0.01); + n[1] = (mwSize)(s[1] + 0.01); + n[2] = ndims==3 ? (mwSize)(s[2] + 0.01) : 1; + + s = mxGetPr(SZ_IN); + if (s[0]<1 || s[1]<1 || (ndims==3 && s[2]<1)) { + mexErrMsgTxt("Invalid block size."); + } + sz[0] = (mwSize)(s[0] + 0.01); + sz[1] = (mwSize)(s[1] + 0.01); + sz[2] = ndims==3 ? (mwSize)(s[2] + 0.01) : 1; + + if (nrhs == 4) { + s = mxGetPr(S_IN); + if (s[0]<1 || s[1]<1 || (ndims==3 && s[2]<1)) { + mexErrMsgTxt("Invalid step size."); + } + stepsize[0] = (mwSize)(s[0] + 0.01); + stepsize[1] = (mwSize)(s[1] + 0.01); + stepsize[2] = ndims==3 ? (mwSize)(s[2] + 0.01) : 1; + } + else { + stepsize[0] = stepsize[1] = stepsize[2] = 1; + } + + if (n[0]<sz[0] || n[1]<sz[1] || (ndims==3 && n[2]<sz[2])) { + mexErrMsgTxt("Block size too large."); + } + + if (mxGetN(B_IN) != ((n[0]-sz[0])/stepsize[0]+1)*((n[1]-sz[1])/stepsize[1]+1)*((n[2]-sz[2])/stepsize[2]+1)) { + mexErrMsgTxt("Invalid number of columns in B. Please use IM2COLSTEP to compute B."); + } + + + /* Create a matrix for the return argument */ + + X_OUT = mxCreateNumericArray(ndims, n, mxDOUBLE_CLASS, mxREAL); + + + /* Assign pointers */ + + b = mxGetPr(B_IN); + x = mxGetPr(X_OUT); + + + /* Do the actual computation */ + + blocknum = 0; + + /* iterate over all blocks */ + for (k=0; k<=n[2]-sz[2]; k+=stepsize[2]) { + for (j=0; j<=n[1]-sz[1]; j+=stepsize[1]) { + for (i=0; i<=n[0]-sz[0]; i+=stepsize[0]) { + + /* add single block */ + for (m=0; m<sz[2]; m++) { + for (l=0; l<sz[1]; l++) { + for (t=0; t<sz[0]; t++) { + (x+(k+m)*n[0]*n[1]+(j+l)*n[0]+i)[t] += (b + blocknum*sz[0]*sz[1]*sz[2] + m*sz[0]*sz[1] + l*sz[0])[t]; + } + } + } + blocknum++; + + } + } + } + + return; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Problems/private/col2imstep.m Thu Mar 25 14:05:27 2010 +0000 @@ -0,0 +1,25 @@ +%COL2IMSTEP Rearrange matrix columns into blocks. +% A = COL2IMSTEP(B,[MM NN],[N1 N2]) rearranges the columns of B into +% sliding N1-by-N2 blocks producing the matrix A of size MM-by-NN. B is +% usually the result of calling IM2COLSTEP(...) with a stepsize of 1, or +% using Matlab's IM2COL(..,'sliding'). Overlapping blocks are summed in A. +% +% A = COL2IMSTEP(B,[MM NN],[N1 N2],[S1 S2]) arranges the blocks in A with +% a step size of (S1,S2) between them. The first block is at A(1:N1,1:N2), +% and the rest are at A((1:N1)+i*S1,(1:N2)+j*S2). Overlapping blocks are +% summed in A. Note that B is usually the result of calling +% IM2COLSTEP(...) with a stepsize of [S1 S2]. +% +% A = IM2COLSTEP(B,[MM NN KK],[N1 N2 N3],[S1 S2 S3]) generates a 3-D +% output matrix A. The step size [S1 S2 S3] may be ommitted, and defaults +% to [1 1 1]. +% +% See also IM2COLSTEP, IM2COL, COUNTCOVER. + + +% Ron Rubinstein +% Computer Science Department +% Technion, Haifa 32000 Israel +% ronrubin@cs +% +% August 2009
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Problems/private/im2colstep.c Thu Mar 25 14:05:27 2010 +0000 @@ -0,0 +1,131 @@ +/************************************************************************** + * + * File name: im2colstep.c + * + * Ron Rubinstein + * Computer Science Department + * Technion, Haifa 32000 Israel + * ronrubin@cs + * + * Last Updated: 31.8.2009 + * + *************************************************************************/ + + +#include "mex.h" +#include <string.h> + + +/* Input Arguments */ + +#define X_IN prhs[0] +#define SZ_IN prhs[1] +#define S_IN prhs[2] + + +/* Output Arguments */ + +#define B_OUT plhs[0] + + +void mexFunction(int nlhs, mxArray *plhs[], + int nrhs, const mxArray*prhs[]) + +{ + double *x, *b, *s; + mwSize sz[3], stepsize[3], n[3], ndims; + mwIndex i, j, k, l, m, blocknum; + + + /* Check for proper number of arguments */ + + if (nrhs < 2 || nrhs > 3) { + mexErrMsgTxt("Invalid number of input arguments."); + } else if (nlhs > 1) { + mexErrMsgTxt("Too many output arguments."); + } + + + /* Check the the input dimensions */ + + ndims = mxGetNumberOfDimensions(X_IN); + + if (!mxIsDouble(X_IN) || mxIsComplex(X_IN) || ndims>3) { + mexErrMsgTxt("X should be a 2-D or 3-D double matrix."); + } + if (!mxIsDouble(SZ_IN) || mxIsComplex(SZ_IN) || mxGetNumberOfDimensions(SZ_IN)>2 || mxGetM(SZ_IN)*mxGetN(SZ_IN)!=ndims) { + mexErrMsgTxt("Invalid block size."); + } + if (nrhs == 3) { + if (!mxIsDouble(S_IN) || mxIsComplex(S_IN) || mxGetNumberOfDimensions(S_IN)>2 || mxGetM(S_IN)*mxGetN(S_IN)!=ndims) { + mexErrMsgTxt("Invalid step size."); + } + } + + + /* Get parameters */ + + s = mxGetPr(SZ_IN); + if (s[0]<1 || s[1]<1 || (ndims==3 && s[2]<1)) { + mexErrMsgTxt("Invalid block size."); + } + sz[0] = (mwSize)(s[0] + 0.01); + sz[1] = (mwSize)(s[1] + 0.01); + sz[2] = ndims==3 ? (mwSize)(s[2] + 0.01) : 1; + + if (nrhs == 3) { + s = mxGetPr(S_IN); + if (s[0]<1 || s[1]<1 || (ndims==3 && s[2]<1)) { + mexErrMsgTxt("Invalid step size."); + } + stepsize[0] = (mwSize)(s[0] + 0.01); + stepsize[1] = (mwSize)(s[1] + 0.01); + stepsize[2] = ndims==3 ? (mwSize)(s[2] + 0.01) : 1; + } + else { + stepsize[0] = stepsize[1] = stepsize[2] = 1; + } + + n[0] = (mxGetDimensions(X_IN))[0]; + n[1] = (mxGetDimensions(X_IN))[1]; + n[2] = ndims==3 ? (mxGetDimensions(X_IN))[2] : 1; + + if (n[0]<sz[0] || n[1]<sz[1] || (ndims==3 && n[2]<sz[2])) { + mexErrMsgTxt("Block size too large."); + } + + + /* Create a matrix for the return argument */ + + B_OUT = mxCreateDoubleMatrix(sz[0]*sz[1]*sz[2], ((n[0]-sz[0])/stepsize[0]+1)*((n[1]-sz[1])/stepsize[1]+1)*((n[2]-sz[2])/stepsize[2]+1), mxREAL); + + + /* Assign pointers */ + + x = mxGetPr(X_IN); + b = mxGetPr(B_OUT); + + + /* Do the actual computation */ + + blocknum = 0; + + /* iterate over all blocks */ + for (k=0; k<=n[2]-sz[2]; k+=stepsize[2]) { + for (j=0; j<=n[1]-sz[1]; j+=stepsize[1]) { + for (i=0; i<=n[0]-sz[0]; i+=stepsize[0]) { + + /* copy single block */ + for (m=0; m<sz[2]; m++) { + for (l=0; l<sz[1]; l++) { + memcpy(b + blocknum*sz[0]*sz[1]*sz[2] + m*sz[0]*sz[1] + l*sz[0], x+(k+m)*n[0]*n[1]+(j+l)*n[0]+i, sz[0]*sizeof(double)); + } + } + blocknum++; + + } + } + } + + return; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Problems/private/im2colstep.m Thu Mar 25 14:05:27 2010 +0000 @@ -0,0 +1,31 @@ +%IM2COLSTEP Rearrange matrix blocks into columns. +% B = IM2COLSTEP(A,[N1 N2]) converts each sliding N1-by-N2 block of the +% 2-D matrix A into a column of B, with no zero padding. B has N1*N2 rows +% and will contain as many columns as there are N1-by-N2 neighborhoods in +% A. Each column of B contains a neighborhood of A reshaped as NHOOD(:), +% where NHOOD is a matrix containing an N1-by-N2 neighborhood of A. +% +% B = IM2COLSTEP(A,[N1 N2],[S1 S2]) extracts neighborhoods of A with a +% step size of (S1,S2) between them. The first extracted neighborhood is +% A(1:N1,1:N2), and the rest are of the form A((1:N1)+i*S1,(1:N2)+j*S2). +% Note that to ensure coverage of all A by neighborhoods, +% (size(A,i)-Ni)/Si must be whole for i=1,2. The default function behavior +% corresponds to [S1 S2] = [1 1]. Setting S1>=N1 and S2>=N2 results in no +% overlap between the neighborhoods. +% +% B = IM2COLSTEP(A,[N1 N2 N3],[S1 S2 S3]) operates on a 3-D matrix A. The +% step size [S1 S2 S3] may be ommitted, and defaults to [1 1 1]. +% +% Note: the call IM2COLSTEP(A,[N1 N2]) produces the same output as +% Matlab's IM2COL(A,[N1 N2],'sliding'). However, it is significantly +% faster. +% +% See also COL2IMSTEP, IM2COL, COUNTCOVER. + + +% Ron Rubinstein +% Computer Science Department +% Technion, Haifa 32000 Israel +% ronrubin@cs +% +% August 2009
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Problems/private/mexutils.c Thu Mar 25 14:05:27 2010 +0000 @@ -0,0 +1,79 @@ +/************************************************************************** + * + * File name: mexutils.c + * + * Ron Rubinstein + * Computer Science Department + * Technion, Haifa 32000 Israel + * ronrubin@cs + * + * Last Updated: 15.8.2009 + * + *************************************************************************/ + +#include "mexutils.h" +#include <math.h> + + + +/* verify that the mxArray contains a double matrix */ + +void checkmatrix(const mxArray *param, char *fname, char *pname) +{ + char errmsg[100]; + sprintf(errmsg, "%.15s requires that %.25s be a double matrix.", fname, pname); + if (!mxIsDouble(param) || mxIsComplex(param) || mxGetNumberOfDimensions(param)>2) { + mexErrMsgTxt(errmsg); + } +} + + +/* verify that the mxArray contains a 1-D double vector */ + +void checkvector(const mxArray *param, char *fname, char *pname) +{ + char errmsg[100]; + sprintf(errmsg, "%.15s requires that %.25s be a double vector.", fname, pname); + if (!mxIsDouble(param) || mxIsComplex(param) || mxGetNumberOfDimensions(param)>2 || (mxGetM(param)!=1 && mxGetN(param)!=1)) { + mexErrMsgTxt(errmsg); + } +} + + +/* verify that the mxArray contains a double scalar */ + +void checkscalar(const mxArray *param, char *fname, char *pname) +{ + char errmsg[100]; + sprintf(errmsg, "%.15s requires that %.25s be a double scalar.", fname, pname); + if (!mxIsDouble(param) || mxIsComplex(param) || mxGetNumberOfDimensions(param)>2 || + mxGetM(param)!=1 || mxGetN(param)!=1) + { + mexErrMsgTxt(errmsg); + } +} + + +/* verify that the mxArray contains a sparse matrix */ + +void checksparse(const mxArray *param, char *fname, char *pname) +{ + char errmsg[100]; + sprintf(errmsg, "%.15s requires that %.25s be sparse.", fname, pname); + if (!mxIsSparse(param)) { + mexErrMsgTxt(errmsg); + } +} + + +/* verify that the mxArray contains a 1-dimensional cell array */ + +void checkcell_1d(const mxArray *param, char *fname, char *pname) +{ + char errmsg[100]; + sprintf(errmsg, "%.15s requires that %.25s be a 1-D cell array.", fname, pname); + if (!mxIsCell(param) || mxGetNumberOfDimensions(param)>2 || (mxGetM(param)!=1 && mxGetN(param)!=1)) { + mexErrMsgTxt(errmsg); + } +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Problems/private/mexutils.h Thu Mar 25 14:05:27 2010 +0000 @@ -0,0 +1,103 @@ +/************************************************************************** + * + * File name: mexutils.h + * + * Ron Rubinstein + * Computer Science Department + * Technion, Haifa 32000 Israel + * ronrubin@cs + * + * Last Updated: 18.8.2009 + * + * Utility functions for MEX files. + * + *************************************************************************/ + + +#ifndef __MEX_UTILS_H__ +#define __MEX_UTILS_H__ + +#include "mex.h" + + + +/************************************************************************** + * Function checkmatrix: + * + * Verify that the specified mxArray is real, of type double, and has + * no more than two dimensions. If not, an error message is printed + * and the mex file terminates. + * + * Parameters: + * param - the mxArray to be checked + * fname - the name of the function where the error occured (15 characters or less) + * pname - the name of the parameter (25 characters or less) + * + **************************************************************************/ +void checkmatrix(const mxArray *param, char *fname, char *pname); + + +/************************************************************************** + * Function checkvector: + * + * Verify that the specified mxArray is 1-D, real, and of type double. The + * vector may be a column or row vector. Otherwise, an error message is + * printed and the mex file terminates. + * + * Parameters: + * param - the mxArray to be checked + * fname - the name of the function where the error occured (15 characters or less) + * pname - the name of the parameter (25 characters or less) + * + **************************************************************************/ +void checkvector(const mxArray *param, char *fname, char *pname); + + +/************************************************************************** + * Function checkscalar: + * + * Verify that the specified mxArray represents a real double scalar value. + * If not, an error message is printed and the mex file terminates. + * + * Parameters: + * param - the mxArray to be checked + * fname - the name of the function where the error occured (15 characters or less) + * pname - the name of the parameter (25 characters or less) + * + **************************************************************************/ +void checkscalar(const mxArray *param, char *fname, char *pname); + + +/************************************************************************** + * Function checksparse: + * + * Verify that the specified mxArray contains a sparse matrix. If not, + * an error message is printed and the mex file terminates. + * + * Parameters: + * param - the mxArray to be checked + * fname - the name of the function where the error occured (15 characters or less) + * pname - the name of the parameter (25 characters or less) + * + **************************************************************************/ +void checksparse(const mxArray *param, char *fname, char *pname); + + +/************************************************************************** + * Function checkcell_1d: + * + * Verify that the specified mxArray is a 1-D cell array. The cell array + * may be arranged as either a column or a row. If not, an error message + * is printed and the mex file terminates. + * + * Parameters: + * param - the mxArray to be checked + * fname - the name of the function where the error occured (15 characters or less) + * pname - the name of the parameter (25 characters or less) + * + **************************************************************************/ +void checkcell_1d(const mxArray *param, char *fname, char *pname); + + +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Problems/private/sprow.c Thu Mar 25 14:05:27 2010 +0000 @@ -0,0 +1,94 @@ +/************************************************************************** + * + * File name: sprow.c + * + * Ron Rubinstein + * Computer Science Department + * Technion, Haifa 32000 Israel + * ronrubin@cs + * + * Last Updated: 24.8.2009 + * + *************************************************************************/ + + +#include "mex.h" +#include "mexutils.h" + + +/* Input Arguments */ + +#define A_IN prhs[0] +#define J_IN prhs[1] + + +/* Output Arguments */ + +#define X_OUT plhs[0] +#define ID_OUT plhs[1] + + +void mexFunction(int nlhs, mxArray *plhs[], + int nrhs, const mxArray*prhs[]) + +{ + double *pr, *x, *id, rowid; + mwIndex *ir, *jc; + mwSize m, n; + mwIndex i, j, k, l, rowlen; + + if (nrhs != 2) { + mexErrMsgTxt("GETSPROW requires two input arguments."); + } else if (nlhs > 2) { + mexErrMsgTxt("Too many output arguments."); + } + + checkmatrix(A_IN, "GETSPROW", "A"); + checksparse(A_IN, "GETSPROW", "A"); + checkscalar(J_IN, "GETSPROW", "J"); + + m = mxGetM(A_IN); + n = mxGetN(A_IN); + + rowid = mxGetScalar(J_IN); + if (rowid < 0) { + mexErrMsgTxt("Invalid row index."); + } + j = (mwIndex)(rowid + 1e-2); + if (j<1 || j>m) { + mexErrMsgTxt("Row index is out of range."); + } + j--; + + pr = mxGetPr(A_IN); + ir = mxGetIr(A_IN); + jc = mxGetJc(A_IN); + + /* Determine length of row */ + rowlen = 0; + for (i=0; i<jc[n]; ++i) { + rowlen += (ir[i]==j); + } + + /* Allocate output parameters */ + X_OUT = mxCreateDoubleMatrix(1, rowlen, mxREAL); + ID_OUT = mxCreateDoubleMatrix(1, rowlen, mxREAL); + + x = mxGetPr(X_OUT); + id = mxGetPr(ID_OUT); + + /* Compute j-th row */ + k=0; + for (l=1; l<=n; ++l) { + i = jc[l-1]; + while (i<jc[l] && ir[i]<j) { + i++; + } + if (i<jc[l] && ir[i]==j) { + x[k] = pr[i]; + id[k] = l; + k++; + } + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Problems/private/sprow.m Thu Mar 25 14:05:27 2010 +0000 @@ -0,0 +1,19 @@ +%SPROW Extract row of sparse matrix. +% X = SPROW(A,J) where A is a sparse matrix, returns the nonzero values in +% the row A(J,:). +% +% [X,ID] = SPROW(A,J) also returns the column indices of the nonzeros. +% +% Note that the call [X,ID] = SPROW(A,J) is equivalent (but more efficient +% than) the Matlab code +% +% IDS = find(A(J,:)); +% X = A(J,IDS); + + +% Ron Rubinstein +% Computer Science Department +% Technion, Haifa 32000 Israel +% ronrubin@cs +% +% August 2009