0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022 #include <math.h>
0023 #include "mex.h"
0024
0025
0026
0027 #define xn_IN prhs[0]
0028 #define halfmode_IN prhs[1]
0029 #define fwhm_IN prhs[2]
0030 #define xreset0_IN prhs[3]
0031
0032
0033
0034 #define s0_OUT plhs[0]
0035
0036 #if !defined(MAX)
0037 #define MAX(A, B) ((A) > (B) ? (A) : (B))
0038 #endif
0039
0040 #if !defined(MIN)
0041 #define MIN(A, B) ((A) < (B) ? (A) : (B))
0042 #endif
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054 static double ran2(idum)
0055 long int *idum;
0056 {
0057
0058 long int j;
0059 long int k;
0060 static long int idum2 = 123456789;
0061 static long int iy = 0;
0062 static long int iv[32];
0063 double temp;
0064
0065 double eps = 1.2e-7,rnmx,am,ndiv;
0066 long int im1 = 2147483563,im2 = 2147483399,imm1,ia1 = 40014,ia2 = 40692,iq1 = 53668,iq2 = 52774;
0067 long int ir1 = 12211,ir2 = 3791,ntab = 32;
0068
0069 imm1 = im1 - 1L;
0070 am = (double)1.0/(double)im1;
0071 ndiv = (double)1.0+(double)imm1/(double)ntab;
0072 rnmx = (double)1.0 - eps;
0073
0074 if (*idum <=0L) {
0075 if(-(*idum) < 1L) *idum = 1L;
0076 else *idum = -(*idum);
0077 idum2 = (*idum);
0078 for (j = ntab+7L;j>=0L;j--) {
0079 k = (long int)(*idum)/iq1;
0080 *idum = ia1*(*idum-k*iq1)-k*ir1;
0081 if(*idum<0L) *idum += im1;
0082 if (j < ntab) iv[j] = *idum;
0083 }
0084 iy = iv[0];
0085 }
0086
0087 k = (long int)(*idum)/iq1;
0088 *idum = ia1*(*idum-k*iq1)-k*ir1;
0089 if (*idum < 0L) *idum += im1;
0090 k = (long int)(idum2/iq2);
0091 idum2 = ia2*(idum2-k*iq2)-k*ir2;
0092 if (idum2 < 0L) idum2 += im2;
0093 j = (long)(iy/(long int)ndiv);
0094 iy = iv[j]-idum2;
0095 iv[j] = *idum;
0096 if(iy < 1) iy += imm1;
0097 if ((temp = am*(double)iy) > rnmx) return(rnmx);
0098 else return(temp);
0099 }
0100
0101
0102
0103 void tirgaussian(reset,halfmode,fwhm,res)
0104 long int *reset;
0105 double *halfmode,*fwhm,*res;
0106 {
0107 long int test = 0;
0108 double rand1,rand2,rand3;
0109
0110 while (test == 0) {
0111 rand1 = -(fwhm[0]/(2.0*sqrt(2.0*log(2.0))))*(fwhm[0]/(2.0*sqrt(2.0*log(2.0))))*log(ran2(reset));
0112 rand2 = -(fwhm[0]/(2.0*sqrt(2.0*log(2.0))))*(fwhm[0]/(2.0*sqrt(2.0*log(2.0))))*log(ran2(reset));
0113 rand3 = 0.5*(rand1-1.0)*(rand1-1.0);
0114 if (rand3 <= rand2) {
0115 if (halfmode[0] == 1) {
0116 res[0] = rand1;
0117 } else {
0118 if (ran2(reset) < 0.5) {
0119 res[0] = rand1;
0120 } else {
0121 res[0] = -rand1;
0122 }
0123 }
0124 test = 1;
0125 }
0126 }
0127 }
0128
0129
0130
0131
0132 void gaussian(s0out,xn,halfmode,fwhm,xreset0)
0133 double s0out[];
0134 double *xn,*xreset0,*halfmode,*fwhm;
0135 {
0136 double xx;
0137 long int i,n,reset,reset0;
0138
0139
0140
0141 reset0 = (long int)xreset0[0];
0142 reset = -reset0;
0143
0144 n = (long int)xn[0];
0145
0146 for (i=0L; i < n; i++) {
0147 tirgaussian(&reset,halfmode,fwhm,&xx);
0148 s0out[i] = xx;
0149 }
0150 }
0151
0152
0153
0154 void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
0155
0156 double *s0out;
0157 double *xn,*xreset0,*fwhm,*halfmode;
0158
0159
0160
0161 if (nrhs < 4) mexErrMsgTxt("The function gaussian_gen requires at least four input arguments.");
0162 if (nlhs > 1) mexErrMsgTxt("The function gaussian_gen requires up to one output argument.");
0163
0164 xn = mxGetPr(xn_IN);
0165 halfmode = mxGetPr(halfmode_IN);
0166 fwhm = mxGetPr(fwhm_IN);
0167 xreset0 = mxGetPr(xreset0_IN);
0168
0169
0170
0171 s0_OUT = mxCreateDoubleMatrix((mwSize)xn[0], 1, mxREAL);
0172
0173
0174
0175 s0out = mxGetPr(s0_OUT);
0176
0177
0178
0179 gaussian(s0out,xn,halfmode,fwhm,xreset0);
0180
0181 return;
0182 }