Go to the documentation of this file.00001
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include <mexutils.h>
00016
00017 #include <vl/random.h>
00018 #include <vl/stringop.h>
00019
00020 #include <assert.h>
00021
00022
00023 void
00024 mexFunction(int nout, mxArray *out[],
00025 int nin, const mxArray *in[])
00026 {
00027 enum {
00028 MANIP_STATE,
00029 RUN_GENERATOR
00030 } mode ;
00031
00032 VlRand * rand ;
00033
00034 VL_USE_MATLAB_ENV ;
00035
00036 rand = vl_get_rand() ;
00037
00042 if (nout > 1) {
00043 vlmxError(vlmxErrTooManyInputArguments, NULL) ;
00044 }
00045
00046 if (nin > 0 && ! mxIsNumeric(in[0])) {
00047 mode = MANIP_STATE ;
00048 } else {
00049 mode = RUN_GENERATOR ;
00050 }
00051
00052 switch (mode) {
00053 case RUN_GENERATOR:
00054 {
00055 enum { maxNumDimensions = 30 } ;
00056 vl_size numDimensions = 2, n ;
00057 vl_uindex k ;
00058 mwSize dimensions [maxNumDimensions] = {1, 1} ;
00059 double * x ;
00060
00061 if (nin > 1) {
00062
00063 if (nin >= maxNumDimensions) {
00064 vlmxError(vlmxErrTooManyInputArguments,
00065 "Too many dimensions specified.") ;
00066 }
00067 for (k = 0 ; k < (unsigned)nin ; ++k) {
00068 if (! vlmxIsPlainScalar(in[k])) {
00069 vlmxError(vlmxErrInvalidArgument,
00070 "The %d-th argument is not a plain scalar.", k + 1) ;
00071 }
00072 if (mxGetScalar(in[k]) < 0) {
00073 vlmxError(vlmxErrInvalidArgument,
00074 "The %d-th argument is negative.", k + 1) ;
00075 }
00076 dimensions[k] = mxGetScalar(in[k]) ;
00077 }
00078 numDimensions = k ;
00079
00080 } else if (nin == 1) {
00081
00082 if (! vlmxIsPlainVector(in[0], -1)) {
00083 vlmxError(vlmxErrInvalidArgument,
00084 "The argument is not a plain vector.") ;
00085 }
00086
00087 x = mxGetPr(in[0]) ;
00088 n = mxGetNumberOfElements(in[0]) ;
00089 numDimensions = VL_MAX(2, n) ;
00090
00091 if (numDimensions > maxNumDimensions) {
00092 vlmxError(vlmxErrInvalidArgument,
00093 "Too many dimensions specified.") ;
00094 }
00095
00096 if (n == 1) {
00097 if (*x < 0) {
00098 vlmxError(vlmxErrInvalidArgument,
00099 "The specified dimension is negative.") ;
00100 }
00101 dimensions[0] = dimensions[1] = *x ;
00102 } else {
00103 for (k = 0 ; k < n ; ++k) {
00104 if (x[k] < 0) {
00105 vlmxError(vlmxErrInvalidArgument,
00106 "One of the specified dimensions is negative.") ;
00107 }
00108 dimensions[k] = x[k] ;
00109 }
00110 }
00111 }
00112
00113 out[0] = mxCreateNumericArray (numDimensions, dimensions, mxDOUBLE_CLASS, mxREAL) ;
00114 n = mxGetNumberOfElements (out[0]) ;
00115 x = mxGetPr (out[0]) ;
00116 for (k = 0 ; k < n ; ++k) {
00117 x[k] = vl_rand_res53(rand) ;
00118 }
00119 }
00120 break ;
00121
00122 case MANIP_STATE:
00123 {
00124 enum { buff_size = 32 } ;
00125 char buff [buff_size] ;
00126
00127
00128 if (! vlmxIsString(in[0], -1) ||
00129 mxGetString(in[0], buff, buff_size) ||
00130 vl_string_casei_cmp ("state", buff) != 0 ) {
00131 vlmxError(vlmxErrInvalidArgument, NULL) ;
00132 }
00133
00134
00135 if (nin == 1) {
00136 vl_uindex i ;
00137 vl_uint32 * data ;
00138 out[0] = mxCreateNumericMatrix (625, 1, mxUINT32_CLASS, mxREAL) ;
00139 data = mxGetData(out[0]) ;
00140 for (i = 0 ; i < 624 ; ++i) data[i] = rand->mt[i] ;
00141 data[624] = (vl_uint32) rand->mti ;
00142 } else {
00143 if (vlmxIsPlainScalar(in[1])) {
00144
00145 vl_uint32 x = (vl_uint32) mxGetScalar(in[1]) ;
00146 vl_rand_seed (rand, x) ;
00147 } else if (mxIsNumeric(in[1]) &&
00148 mxGetClassID(in[1]) == mxUINT32_CLASS &&
00149 mxGetNumberOfElements(in[1]) == 624+1 &&
00150 ((vl_uint32 const*)mxGetData(in[1]))[624] <= 624 ) {
00151
00152 vl_uindex i ;
00153 vl_uint32 * data = mxGetData(in[1]) ;
00154 for (i = 0 ; i < 624 ; ++i) rand->mt[i] = data[i] ;
00155 rand->mti = data [624] ;
00156 } else if (mxIsNumeric(in[1]) &&
00157 mxGetClassID(in[1]) == mxDOUBLE_CLASS &&
00158 mxGetNumberOfElements(in[1]) <= 624) {
00159
00160 vl_uint32 key [624] ;
00161 double const * x = mxGetPr(in[1]) ;
00162 vl_size n = mxGetNumberOfElements(in[1]) ;
00163 vl_uindex k ;
00164 for (k = 0 ; k < n ; ++k) {
00165 key [k] = x [k] ;
00166 }
00167 vl_rand_seed_by_array (rand, key, n) ;
00168 }
00169 }
00170 }
00171 break ;
00172
00173 default:
00174 abort() ;
00175 }
00176 }