vl_twister.c
Go to the documentation of this file.
00001 
00007 /*
00008 Copyright (C) 2007-12 Andrea Vedaldi and Brian Fulkerson.
00009 All rights reserved.
00010 
00011 This file is part of the VLFeat library and is made available under
00012 the terms of the BSD license (see the COPYING file).
00013 */
00014 
00015 #include <mexutils.h>
00016 
00017 #include <vl/random.h>
00018 #include <vl/stringop.h>
00019 
00020 #include <assert.h>
00021 
00022 /* driver */
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         /* TWISTER(N1 N2 ...) style */
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         /* TWISTER([N1 N2 ...]) style */
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       /* check for 'state' string */
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       /* TWISTER('state') */
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           /* TWISTER('state', X) */
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           /* TWISTER('state', STATE) */
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           /* TWISTER('state', KEY) */
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 }


libvlfeat
Author(s): Andrea Vedaldi
autogenerated on Thu Jun 6 2019 20:25:51