def project_SR_stats(stats2, A, ind): """Project the high-dim statistics into a line using a SR direction specified by coefficients 'A' and indices 'ind' :Parameters: stats2: Stats2 a vectorintegrated 2D numpy.array ind: array(shape=(n,), dtype='int') indices of the SR feature A: array(shape=(n,), dtype='double') coefficients of the SR feature :Returns: stats2e: a 1D Stats2e representing the projected result """ ofs = stats2.ofs size = stats2.size stats2A = stats2.A.ravel() A = arrayd(A) ind = ind.ravel() outA = zeros(6,'d') code = """ project_SR_with_stats((int*)ofs, (int*)size, stats2A, Nind[0], (int*)ind, A, outA); return_val = 1; """ inline(code, arg_names=['ofs', 'size', 'stats2A', 'ind', 'A', 'outA'], \ headers=['<SdSRFeature.h>'], libraries=['sdcpp', 'cblas_ext', 'cephesd', 'plat_det']) return Stats2e(2, (), outA)
def resampleStratifiednwq(w, M=0 ): code = \ """ int jj = 0; for(int ii = 0; ii < R; ii++) // For each input particle { while( u(jj) <= ww(ii) && jj < M ) { //printf("%f\\n",u(jj)); //printf("%f\\n",ww(ii)); Ind(jj) = ii; jj++; } } """ # Number of input particles R = len(w); # Number of output particles if M==0: M = R; u = ( ( np.arange(0,M,1) + np.random.uniform(0.0,1.0,(M,1)) ) / M ).astype(float); ww = ( np.cumsum(w) / np.sum(w) ).astype(float); Ind = np.empty(M, dtype='int') weave.inline(code,['u','R','M','Ind','ww'], type_converters=weave.converters.blitz) return Ind;
def KramarsKronig(om, f): dh = float((om[-1]-om[1])/(len(om)-1)) # you need to typecast for weave to know the type logo = zeros(len(om), dtype=float) for i in range(1,len(om)-1): logo[i] = log((om[-1]-om[i])/(om[i]-om[0])) deriv = zeros(len(om), dtype=float) deriv[0] = (f[1]-f[0])/dh deriv[-1] = (f[-1]-f[-2])/dh for i in range(1,len(om)-1): deriv[i] = (f[i+1]-f[i-1])/(2*dh) fr = zeros(len(om), dtype=float) ## C++ code code=""" using namespace std; for (int i=0; i<om.size(); i++){ double sum1=0; for (int j=0; j<om.size(); j++){ if (i!=j){ sum1 += (f(j)-f(i))*dh/(om(j)-om(i)); }else{ sum1 += deriv(i)*dh; } } fr(i) = (sum1 + f(i)*logo(i))/pi; } """ weave.inline(code, ['om','f','fr','deriv','logo','dh','pi'], type_converters=weave.converters.blitz, compiler = 'gcc') return fr
def cholupdate(L, x): """ update the LOWER cholesky factor of a pd matrix IN PLACE if L is the lower chol. of K, then this function computes L\_ where L\_ is the lower chol of K + x*x^T """ support_code = """ #include <math.h> """ code = """ double r,c,s; int j,i; for(j=0; j<N; j++){ r = sqrt(L(j,j)*L(j,j) + x(j)*x(j)); c = r / L(j,j); s = x(j) / L(j,j); L(j,j) = r; for (i=j+1; i<N; i++){ L(i,j) = (L(i,j) + s*x(i))/c; x(i) = c*x(i) - s*L(i,j); } } """ x = x.copy() N = x.size weave.inline(code, support_code=support_code, arg_names=['N', 'L', 'x'], type_converters=weave.converters.blitz)
def Laguerre_dirty(x,alpha,max_n): Lag = zeros(max_n+1, dtype=float) codel=""" // Initialize the recursion process. // #include <iostream> using namespace std; double alpha_one_mx = (double) alpha + 1.0L - (double) x; if (max_n >=0 ){ double ln2 = 1.0L; double ln1 = alpha_one_mx; Lag(0) = (double) ln2; if (max_n > 0){ Lag(1) = (double) ln1; if (max_n > 1){ // Calculate Ln(x) for n = 2,...,max_n // for (int k = 1; k < max_n; k++) { double beta = ( (double)(k + k) + alpha_one_mx ); double gamma = (double) k + (double) alpha; double ln = (beta * ln1 - gamma * ln2) / (double)(k+1); Lag(k+1) = (double)ln; ln2 = ln1; ln1 = ln; } } } } """ weave.inline(codel, ['Lag', 'x', 'alpha', 'max_n'], type_converters=weave.converters.blitz, compiler = 'gcc') return Lag
def withweave(nsteps): for _ in xrange(nsteps): weave.inline(codeweave, ['S', 'N', 'A', 'C'], compiler='gcc', extra_compile_args=['-O3', '-ffast-math', '-march=native', ])
def iniGibbsDoc(state,topicCount,topicsWords,alpha): dist = numpy.empty(topicCount.shape[0], dtype = numpy.float_) rand = numpy.random.random(state.shape[0]) code = """ for (int w=0;w<Nstate[0];w++) { // Calculate the unnormalised distribution... float sum = 0.0; for (int t=0;t<Ndist[0];t++) { DIST1(t) = TOPICSWORDS2(t,STATE2(w,0)); DIST1(t) *= TOPICCOUNT1(t) + alpha; DIST1(t) /= float(w) + NtopicCount[0]*alpha; sum += DIST1(t); } // Normalise... for (int t=0;t<Ndist[0];t++) DIST1(t) /= sum; // Select and set the state... sum = 0.0; for (int t=0;t<Ndist[0];t++) { STATE2(w,1) = t; sum += DIST1(t); if (sum>RAND1(w)) break; } // Incriment the relevant count for the words-per-topic array... TOPICCOUNT1(STATE2(w,1)) += 1; } """ weave.inline(code,['state', 'topicCount', 'topicsWords', 'alpha', 'dist', 'rand'])
def depolarize(self, q, p): """ For something a little faster than __mul__, I hard-code multiplication by a depolarizing model on a select qubit. """ nq = self.nq new_vec = np.empty(len(self.vec), dtype=float_type) c_code = ''' int mask_01 = 1 << (nq - q - 1); int mask_10 = 1 << (2 * nq - q - 1); int mask_11 = mask_10 + mask_01; for (int idx = 0; idx < vec_len; ++idx) { new_vec[idx] = (1. - double(p)) * s_vec[idx] + \ double(p) / 3. * (s_vec[idx ^ mask_01] + s_vec[idx ^ mask_10] + s_vec[idx ^ mask_11]); } ''' s_vec = self.vec vec_len = len(self.vec) arg_names = ['s_vec', 'new_vec', 'vec_len', 'nq', 'p', 'q'] inline(c_code, arg_names=arg_names, compiler='gcc', extra_compile_args=[''], libraries=['rt']) #self = DensePauliErrorModel(new_vec) self.vec = new_vec pass
def _set_boundary_conditions(p, flag, dx, dy): code = """ #line 19 "pressure.py" int imax = Np[0]-2; int jmax = Np[1]-2; /* Outer boundary */ for(int i=1; i<=imax; i++) { P2(i, 0) = P2(i, 1); P2(i, jmax+1) = P2(i, jmax); } for(int j=1; j<=jmax; j++) { P2(0, j) = P2(1, j); P2(imax+1, j) = P2(imax, j); } /* Boundary conditions on obstacle cells */ double tmp = 1.0/(dx*dx+dy*dy); for(int i=1; i<=imax; i++) { for(int j=1; j<=jmax; j++) { if( !(FLAG2(i, j)&FC) && (FLAG2(i, j)!=OC)) { switch(FLAG2(i, j)) { case B_N: P2(i, j) = P2(i, j+1); break; case B_E: P2(i, j) = P2(i+1, j); break; case B_S: P2(i, j) = P2(i, j-1); break; case B_W: P2(i, j) = P2(i-1, j); break; case B_NE: P2(i, j) = tmp*(dx*dx*P2(i, j+1)+dy*dy*P2(i+1, j)); P2(i,j) = 0.5*(P2(i,j+1)+P2(i+1,j)); break; case B_SE: P2(i, j) = tmp*(dx*dx*P2(i, j-1)+dy*dy*P2(i+1, j)); P2(i,j) = 0.5*(P2(i,j-1)+P2(i+1,j)); break; case B_SW: P2(i, j) = tmp*(dx*dx*P2(i, j-1)+dy*dy*P2(i-1, j)); P2(i,j) = 0.5*(P2(i,j-1)+P2(i-1,j)); break; case B_NW: P2(i, j) = tmp*(dx*dx*P2(i, j+1)+dy*dy*P2(i-1, j)); P2(i,j) = 0.5*(P2(i,j+1)+P2(i-1,j)); break; } } } } """ weave.inline(code, ['p', 'flag', 'dx', 'dy'], define_macros=cmacros.flag_dict);
def ipopt(alpha, beta, cost_prod, cost_stor, cons_prod, setup, constraint, time_hor, nb_obj, verbose): """ This function solve quadratic problem as define in 'the profit mazimizing capacited lot-size problem'. It is based on ipopt solvers (http://www.coin-or.org/Ipopt/). ipopt(alpha, beta, cost_prod, cost_stor,cons_prod, cost_setup, constraint, time_hor, nb_obj, verbose) """ extra_code = open(join(split(__file__)[0],'LLBP','main.cpp')).read() results = np.zeros((3*nb_obj+1)*time_hor+1, float) if verbose > 1: print "\nCompute lower bound (IpOpt)..." code=""" int status = ipopt(alpha,beta,cost_prod, cost_stor,cons_prod,setup,constraint, results,time_hor,nb_obj,verbose); """ wv.inline(code,['time_hor', 'nb_obj','alpha', 'beta', 'cost_prod', 'cost_stor', 'setup', 'results', 'cons_prod', 'constraint', 'verbose'], include_dirs=["LLBP","/usr/include/coin/"], support_code=extra_code, libraries=['ipopt','lapack','pthread'], sources =[join(split(__file__)[0],'LLBP','LbIpopt.cpp')], type_converters=converters.blitz) #force = 1) return results[0],results[1:time_hor+1],\ results[time_hor+1:(nb_obj+1)*time_hor+1],\ results[(nb_obj+1)*time_hor+1:(2*nb_obj+1)*time_hor+1],\ results[(2*nb_obj+1)*time_hor+1:]
def _thinningIteration(im, iter): I, M = im, np.zeros(im.shape, np.uint8) expr = """ for (int i = 1; i < NI[0]-1; i++) { for (int j = 1; j < NI[1]-1; j++) { int p2 = I2(i-1, j); int p3 = I2(i-1, j+1); int p4 = I2(i, j+1); int p5 = I2(i+1, j+1); int p6 = I2(i+1, j); int p7 = I2(i+1, j-1); int p8 = I2(i, j-1); int p9 = I2(i-1, j-1); int A = (p2 == 0 && p3 == 1) + (p3 == 0 && p4 == 1) + (p4 == 0 && p5 == 1) + (p5 == 0 && p6 == 1) + (p6 == 0 && p7 == 1) + (p7 == 0 && p8 == 1) + (p8 == 0 && p9 == 1) + (p9 == 0 && p2 == 1); int B = p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9; int m1 = iter == 0 ? (p2 * p4 * p6) : (p2 * p4 * p8); int m2 = iter == 0 ? (p4 * p6 * p8) : (p2 * p6 * p8); if (A == 1 && B >= 2 && B <= 6 && m1 == 0 && m2 == 0) { M2(i,j) = 1; } } } """ weave.inline(expr, ["I", "iter", "M"]) return (I & ~M)
def restrict(u_h, weighting='full'): m_h, n_h = u_h.shape m_2h, n_2h = (m_h + 1)//2 - 1, (n_h + 1)//2 - 1, u_2h = zeros((m_2h, n_2h)) center, side, corner = ({ 'full': (4, 2, 1), 'half': (4, 1, 0), 'inject': (1, 0, 0), })[weighting] divider = center + 4 * side + 4 * corner code = ''' for (int i = 0; i < m_2h; ++i) for (int j = 0; j < n_2h; ++j) u_2h(i, j) = (center * (u_h(2 * i + 1, 2 * j + 1)) + side * (u_h(2 * i , 2 * j + 1) + u_h(2 * i + 2, 2 * j + 1) + u_h(2 * i + 1, 2 * j ) + u_h(2 * i + 1, 2 * j + 2)) + corner * (u_h(2 * i , 2 * j ) + u_h(2 * i + 2, 2 * j ) + u_h(2 * i , 2 * j + 2) + u_h(2 * i + 2, 2 * j + 2))) / divider; ''' weave.inline(code, 'm_2h n_2h u_2h u_h center side corner divider'.split(), type_converters=weave.converters.blitz, verbose=1) return u_2h
def thomas(alpha, beta, cost_prod, cost_stor, cons_prod, cost_setup, coef, time_hor, nb_obj, verbose): """ This function is an adapted version of J. Thomas's algorithm (see price-production decision with deterministic demand 1970) for lagrangian relaxatio and multi product thomas(alpha, beta, cost_prod, cost_stor,cons_prod, cost_setup,coef, time_hor, nb_obj, verbose) """ opti_price = np.zeros((nb_obj,time_hor), float) ind = np.zeros((nb_obj,time_hor),int) extra_code = open(join(split(__file__)[0],'LUBP','lupb.cpp')).read() if verbose > 1: print "\nCompute upper bound (Thomas)..." thomas_code = """ int status = thomas(alpha, beta, cost_prod, cost_stor, cons_prod, cost_setup, opti_price, coef, ind, time_hor, nb_obj, verbose); """ wv.inline( thomas_code , ['time_hor', 'nb_obj','alpha', 'beta', 'cost_setup','ind', 'cost_prod', 'cost_stor', 'opti_price','cons_prod','coef','verbose'], support_code=extra_code, type_converters=converters.blitz) return opti_price, ind
def XYPlotToImage(self,xs,ys,intensities,screenlatticesize): N = screenlatticesize xs = array(xs).flatten() ys = array(ys).flatten() intensities = array(intensities).flatten()+ME data = zeros((2*N,2*N),float) xlist = (N+xs*N).astype(int) ylist = (N+ys*N).astype(int) #slow part """ newdata = zeros((2*N,2*N),float) c = 0 for i,j in zip (xlist,ylist): newdata[i,j] += intensities[c] c += 1 """ np = len(xlist) s = 2*N code = """ for (int i=0; i<np; i++) *(data+(*(xlist+i))*s+*(ylist+i)) += *(intensities+i); """ variables = ['np','s','xlist', 'ylist','intensities','data'] W.inline(code, variables, extra_compile_args=["-w"]) return data
def execute(self, image): # self.notify_output_observers("ScipyTestPy: j=6 \n") notify = self.notify_output_observers param = {} for value in self.get_params(): key = value.get_name() param[key] = value.get() weave.inline( """ py::tuple notify_args(1); notify_args[0] = "patatoum"; notify.call(notify_args); cv::Mat mat(Nimage[0], Nimage[1], CV_8UC(3), image); int circlex = (int)PyInt_AsLong(PyDict_GetItemString(param, "Circlex")); int circley = (int)PyInt_AsLong(PyDict_GetItemString(param, "Circley")); int colorr = (int)PyInt_AsLong(PyDict_GetItemString(param, "colorr")); int colorg = (int)PyInt_AsLong(PyDict_GetItemString(param, "colorg")); int colorb = (int)PyInt_AsLong(PyDict_GetItemString(param, "colorb")); cv::circle(mat, cv::Point(circlex, circley), mat.cols/4, cv::Scalar(colorr, colorg, colorb), -1); """, arg_names=['image', 'notify', 'param'], include_dirs=['/usr/local/include/opencv/'], headers=['<cv.h>', '<cxcore.h>'], # libraries = ['ml', 'cvaux', 'highgui', 'cv', 'cxcore'], extra_objects=["`pkg-config --cflags --libs opencv`"] ) return image
def backprop_chol_grad(dL, L): """ Given the derivative of an objective fn with respect to the cholesky L, compute the derivate with respect to the original matrix K, defined as K = LL^T where L was obtained by Cholesky decomposition """ from scipy import weave dL_dK = np.tril(dL).copy() code = """ for(int k=N-1;k>-1;k--){ //printf("%d\\n",k); for(int j=k+1;j<N;j++){ for(int i=j;i<N; i++){ //printf("->%d%d\\n",i,j); dL_dK(i, k) -= dL_dK(i, j) * L(j, k); dL_dK(j, k) -= dL_dK(i, j) * L(i, k); } } for( int j=k+1;j<N; j++){ //printf("-->%d\\n",j); dL_dK(j, k) /= L(k, k); dL_dK(k, k) -= L(j, k) * dL_dK(j, k); } dL_dK(k, k) /= (2 * L(k, k)); } """ N = L.shape[0] weave.inline(code, ['dL_dK', 'L', 'N'], type_converters=weave.converters.blitz) return dL_dK
def det_3x3(weight): """ returns the NxM matrix containing the determinants of a set of 3x3 weight matrices. weight should have shape of the form (0:N, 0:M, 0:3, 0:3). """ import scipy.weave as weave ret = np.zeros(weight[:,:,0,0].shape) n_pix_y, n_pix_x = weight[:,:,0,0].shape zero_det = np.array([0]) c_code = """ #line 11 "util.py" long double cof[3][3]; // A temporary variable for (int iy=0; iy<int(n_pix_y); ++iy) { for (int ix=0; ix<int(n_pix_x); ++ix) { // Take the inverse of the weight matrix in this pixel. cof[0][0] = weight(iy,ix,1,1)*weight(iy,ix,2,2)-weight(iy,ix,1,2)*weight(iy,ix,2,1); cof[1][0] = weight(iy,ix,1,2)*weight(iy,ix,2,0)-weight(iy,ix,1,0)*weight(iy,ix,2,2); cof[2][0] = weight(iy,ix,1,0)*weight(iy,ix,2,1)-weight(iy,ix,1,1)*weight(iy,ix,2,0); double det = (weight(iy,ix,0,0)*cof[0][0] + weight(iy,ix,0,1)*cof[1][0] + weight(iy,ix,0,2)*cof[2][0]); ret(iy,ix) = det; } // end for (loop over ix) } // end for (loop over iy) """ weave.inline(c_code, ['weight', 'zero_det', 'n_pix_y', 'n_pix_x', 'ret'], type_converters=weave.converters.blitz) return ret
def get_arr(arr, socket, handle): dtype2ctype = { npy.dtype(npy.float64): "double", npy.dtype(npy.float32): "float", npy.dtype(npy.int32): "int", npy.dtype(npy.int16): "short", } dt = dtype2ctype.get(arr.dtype) # I'm leaving this code here in case anyone wants to mess with it. assert dt == "double" # Only use float64 arrays! code = """ // // I don't usually program in python, but when I do, I program in C++ // QLocalSocket s; s.connectToServer(QString(socket.c_str())); s.waitForConnected(300); s.write("Vector::getBinaryArray("+QByteArray(handle.c_str())+")"); QDataStream ds(&s); qint64 count; s.waitForReadyRead(-1); ds>>count; PyArray_Dims dims; dims.len = 1; dims.ptr = new npy_intp[1]; dims.ptr[0] = (npy_intp)count; PyArray_Resize(arr_array, &dims, 0, PyArray_ANYORDER); delete[]dims.ptr; NpyIter* it=NpyIter_New(arr_array,NPY_ITER_READWRITE,NPY_CORDER,NPY_NO_CASTING,NULL); char**dataptr = NpyIter_GetDataPtrArray(it); NpyIter_IterNextFunc *iternext = NpyIter_GetIterNext(it, NULL); do { char* data=*dataptr; //i.e., byte array while(ds.atEnd()) {s.waitForReadyRead(-1);} //possible optimization: call ds.atEnd() less ds>>((double*)data)[0]; //possible optimization: QByteArray switches the endianess twice... } while(iternext(it)); """ #% (dt) support_code = """ #include <QtCore> #include <QLocalSocket> """ socket = str(socket) handle = str(handle) inline( code, ["arr", "socket", "handle"], support_code=support_code, include_dirs=pykstpp_h.INCLUDES, libraries=pykstpp_h.LIBS, runtime_library_dirs=pykstpp_h.LIBDIRS, )
def resample2D(array, weights, Nx, xdim, Ntheta): """ Indexed of resampled particles (deterministic scheme) """ code = \ """ for(int i = 0; i < Ntheta; i++) { int j = 0; float csw = weights(0, i); for(int k = 0; k < Nx; k++) { while(csw < u(i)) { j++; csw += weights(j, i); } for (int l = 0; l < xdim; l++){ newarray(k, l, i) = array(j, l, i); } u(i) = u(i) + 1.; } } """ u = random.uniform(size = Ntheta, low = 0, high = 1).astype(float32) print u[0:10],"..." weights = double(weights * Nx / sum(weights, axis = 0)) weights = weights.astype(float32) array = array.astype(float32) newarray = zeros_like(array).astype(float32) weave.inline(code,['u','Nx', 'Ntheta','weights', 'array', 'newarray', 'xdim'], type_converters=weave.converters.blitz) return newarray
def rotation_matrix_weave(axis, theta, mat=None): try: from scipy import weave except ImportError: raise NotImplementedError if mat is None: mat = np.eye(3, 3) support = "#include <math.h>" code = """ double x = sqrt(axis[0] * axis[0] + axis[1] * axis[1] + axis[2] * axis[2]); double a = cos(theta / 2.0); double b = -(axis[0] / x) * sin(theta / 2.0); double c = -(axis[1] / x) * sin(theta / 2.0); double d = -(axis[2] / x) * sin(theta / 2.0); mat[0] = a*a + b*b - c*c - d*d; mat[1] = 2 * (b*c - a*d); mat[2] = 2 * (b*d + a*c); mat[3*1 + 0] = 2*(b*c+a*d); mat[3*1 + 1] = a*a+c*c-b*b-d*d; mat[3*1 + 2] = 2*(c*d-a*b); mat[3*2 + 0] = 2*(b*d-a*c); mat[3*2 + 1] = 2*(c*d+a*b); mat[3*2 + 2] = a*a+d*d-b*b-c*c; """ weave.inline(code, ['axis', 'theta', 'mat'], support_code=support, libraries=['m']) return mat
def shift_sum(v1, shifts, bins): real_type = real_same_precision_as(v1) shifts = numpy.array(shifts, dtype=real_type) bins = numpy.array(bins, dtype=numpy.uint32) blen = len(bins) - 1 v1 = numpy.array(v1.data, copy=False) slen = len(v1) if v1.dtype.name == 'complex64': code = point_chisq_code_single else: code = point_chisq_code_double n = int(len(shifts)) # Create some output memory chisq = numpy.zeros(n, dtype=real_type) inline(code, ['v1', 'n', 'chisq', 'slen', 'shifts', 'bins', 'blen'], extra_compile_args=['-march=native -O3 -w'] + omp_flags, libraries=omp_libs ) return chisq
def grad(self,d_outputs,inputs,gates): if len(inputs.shape) < 2: inputs = inputs[:,newaxis] gates = gates[:,newaxis] numcases = inputs.shape[1] if self.maxcases: gradw = self.gradw[:,:numcases] gradw *= 0.0 else: gradw = \ zeros((self.numin*self.numout*self.numgate,numcases),dtype=float) if self.optlevel > 0: from scipy import weave code = r""" for (int c=0; c<numcases; c++) for (int k=0; k<numgate; k++) for (int i=0; i<numin; i++) for (int j=0; j<numout; j++) gradw(k*(numin*numout)+i*numout+j,c)=inputs(i,c)*gates(k,c)*d_outputs(j,c); """ global_dict = {'inputs':inputs,'d_outputs':d_outputs,'gates':gates,\ 'gradw':gradw,\ 'numout':self.numout,'numin':self.numin,\ 'numgate':self.numgate,'numcases':numcases} weave.inline(code,global_dict.keys(),global_dict=global_dict, type_converters=weave.converters.blitz) else: gradw += (gates.T[:,:,newaxis,newaxis]\ *inputs.T[:,newaxis,:,newaxis]\ *d_outputs.T[:,newaxis,newaxis,:]).\ reshape(inputs.shape[1],self.numin*self.numout*self.numgate).\ transpose(1,0) return gradw
def __getvolumeobject_par(self,objfield,obj,dvol): codestring =""" int i,j,k; volume = 0.0; unsigned int point; unsigned int object; object = int(obj); #pragma omp parallel for reduction(+ : volume) private(i,j,k) for (i=1;i<nx-1;i++){ for (j=1;j<ny-1;j++){ for (k=1;k<nz-1;k++){ point = objfield(i,j,k); if (point == object){ volume = volume + dvol(i+1,j+1,k+1); } } } } """ volume = np.empty((1,),dtype=np.float64) nx = objfield.shape[0] ny = objfield.shape[1] nz = objfield.shape[2] variables = "objfield obj dvol volume nx ny nz".split() inline(codestring, variables, extra_compile_args =['-O3 -fopenmp'], extra_link_args=['-lgomp'], headers=['<cmath>'], compiler='gcc', type_converters=converters.blitz) return volume
def get_mono_rdf(pos, Nbins, L, maxdist=None): if maxdist is None: maxdist = L/2.0 imaxsq = 1.0/(maxdist**2) g = np.zeros([len(pos), Nbins], int) code = """ #pragma omp parallel for for(int i=0; i<Npos[0]; ++i) { for(int j=i+1; j<Npos[0]; ++j) { double disq = 0.0; for(int dim=0; dim<3;++dim) disq += pow(periodic_dist(pos(i,dim), pos(j,dim), L), 2); if(disq*imaxsq>=1) continue; const int r = sqrt(disq*imaxsq)*Ng[1]; #pragma omp atomic ++g(i, r); #pragma omp atomic ++g(j, r); } } """ weave.inline( code,['pos', 'imaxsq', 'L', 'g'], type_converters =converters.blitz, support_code = dist_code, extra_compile_args =['-O3 -fopenmp'], extra_link_args=['-lgomp'], verbose=2, compiler='gcc') return g
def __buildMaskPyramid(self, mask, pyramid): """Given a mask and a pyramid of masks makes a pyramid, where it uses the or operation for combining flags.""" code = start_cpp() + """ // Make curr all false... for (int y=0;y<Ncurr[0];y++) { for (int x=0;x<Ncurr[1];x++) CURR2(y,x) = 0; } // Iterate prev, and update curr... for (int y=0;y<Nprev[0];y++) { for (int x=0;x<Nprev[1];x++) { if (PREV2(y,x)!=0) { CURR2(y/2,x/2) = 1; } } } """ pyramid[0][:,:] = mask for l in xrange(1,len(pyramid)): prev = pyramid[l-1] curr = pyramid[l] weave.inline(code, ['prev','curr'])
def blitz_inline(arr): """Prints the given 3D array by using blitz converters which provides a numpy-like syntax for accessing the numpy data. Notice the following: 1. '\\n' to escape generating a newline in the C++ code. 2. rows, cols = Narr[0], Narr[1]. 3. Array access using arr(i, j, k). """ code = """ int rows = Narr[0]; int cols = Narr[1]; int depth = Narr[2]; for (int i=0; i < rows; i++) { for (int j=0; j < cols; j++) { printf("img[%3d][%3d]=", i, j); for (int k=0; k< depth; ++k) { printf(" %3d", arr(i, j, k)); } printf("\\n"); } } """ weave.inline(code, ['arr'], type_converters=converters.blitz)
def get_N_ngbs(pos, radii, L=203, N=12, maxdist=8.0): assert len(pos) == len(radii) #initialize the geometry of each particle neighbours = -np.ones([len(pos), N], int) code = """ const double maxdistsq = maxdist*maxdist; //look for nearby particles #pragma omp parallel for for(int p=0; p<Npos[0]; ++p) { std::multimap<double, int> ngbbydist; for(int q=0; q<Npos[0]; ++q) { if (p==q) continue; double disq = 0.0; for(int dim=0; dim<3;++dim) disq += pow(periodic_dist(pos(p,dim), pos(q,dim), L), 2); disq /= pow(radii(p) + radii(q), 2); if (disq>maxdistsq) continue; ngbbydist.insert(std::make_pair(disq, q)); } std::multimap<double, int>::const_iterator it = ngbbydist.begin(); for(int i=0; i<Nneighbours[1] && it!=ngbbydist.end(); ++i) neighbours(p, i) = (it++)->second; } """ weave.inline( code,['pos', 'radii', 'maxdist', 'L', 'neighbours'], type_converters =converters.blitz, support_code = dist_code, headers = ['<map>', '<list>'], extra_compile_args =['-O3 -fopenmp -march=native'], extra_link_args=['-lgomp'], verbose=2, compiler='gcc') return neighbours
def bprop(self,d_outputs,inputs,gates): if len(inputs.shape) < 2: inputs = inputs[:,newaxis] gates = gates[:,newaxis] if self.optlevel > 0: numcases = inputs.shape[1] if self.maxcases: d_inputs = self.d_inputs[:,:numcases] d_inputs *= 0.0 else: d_inputs = zeros((self.numin,numcases),dtype=float) from scipy import weave code = r""" for (int c=0; c<numcases; c++) for (int i=0; i<numin; i++) for (int j=0; j<numout; j++) for (int k=0; k<numgate; k++) d_inputs(i,c) += d_outputs(j,c)*gates(k,c)*weights(k,i,j); """ global_dict = \ {'d_inputs':d_inputs,'d_outputs':d_outputs,'gates':gates,\ 'weights':self.w,\ 'numout':self.numout,'numin':self.numin,\ 'numgate':self.numgate,'numcases':numcases} weave.inline(code,global_dict.keys(),global_dict=global_dict, type_converters=weave.converters.blitz) return d_inputs else: return sum(sum(self.w[newaxis,:,:,:]*\ gates.T[:,:,newaxis,newaxis]*\ d_outputs.T[:,newaxis,newaxis,:]\ ,1),2).transpose(1,0)
def pure_inline(arr): """Prints the given 3D array by accessing the raw numpy data and without using blitz converters. Notice the following: 1. '\\n' to escape generating a newline in the C++ code. 2. rows, cols = Narr[0], Narr[1]. 3. Array access using arr[(i*cols + j)*depth + k]. """ code = """ int rows = Narr[0]; int cols = Narr[1]; int depth = Narr[2]; for (int i=0; i < rows; i++) { for (int j=0; j < cols; j++) { printf("img[%3d][%3d]=", i, j); for (int k=0; k< depth; ++k) { printf(" %3d", arr[(i*cols + j)*depth + k]); } printf("\\n"); } } """ weave.inline(code, ['arr'])
def __call__(self, P): if self._arrays_to_check is not None: N = len(P) for name, X in self._arrays_to_check: if len(X) != N: raise ValueError( "Array " + name + " has wrong size (" + str(len(X)) + " instead of " + str(N) + ")" ) self._arrays_to_check = None self.namespace["dt"] = P.clock._dt self.namespace["t"] = P.clock._t self.namespace["num_neurons"] = len(P) self.namespace["_S"] = P._S try: weave.inline( self.code_c, self.namespace.keys(), # ['_S', 'num_neurons', 'dt', 't'], local_dict=self.namespace, support_code=c_support_code, compiler=self._weave_compiler, extra_compile_args=self._extra_compile_args, extra_link_args=self._extra_link_args, ) except: log_warn("brian.experimental.codegen.stateupdaters", "C compilation failed, falling back on Python.") self.__class__ = PythonStateUpdater self.__init__(self.eqs, self.scheme, self.clock, self.freeze) self.__call__(P)
def _subseq_dtw(dist): '''Fast DTW, with inlined C''' nx, ny = dist.shape rv = [0.0, 0] #dtwcost,p path = np.zeros((nx + ny, 2), dtype=np.int) code = ''' int i,j; double* cost = new double[ny]; for (j=0; j<ny; ++j) cost[j] = dist(0,j); char** trace = new char*[nx]; int** length = new int*[nx]; for (i=0; i<nx; ++i) { trace[i] = new char[ny]; trace[i][0] = 0; length[i] = new int[ny]; length[i][0] = i+1; } for (j=0; j<ny; ++j) { trace[0][j] = 1; length[0][j] =1; } double diag,c; for (i=1; i<nx; ++i){ diag = cost[0]; cost[0] += dist(i,0); for (j=1; j<ny; ++j){ // c <- min(cost[j],cost[j-1],diag), trace <- argmin //////////////////////////////////////////////////// double avg_cost1 = (cost[j]+dist(i,j))/(length[i-1][j]+1); double avg_cost2 = (cost[j-1]+dist(i,j))/(length[i][j-1]+1); double avg_diag = (diag+dist(i,j))/(length[i-1][j-1]+2); if (avg_diag < avg_cost1){ if (avg_diag < avg_cost2){ c = diag; trace[i][j] = 2; length[i][j] = length[i-1][j-1]+2; } else { c = cost[j-1]; trace[i][j] = 1; length[i][j] = length[i][j-1]+1; } } else if (avg_cost1 < avg_cost2){ c = cost[j]; trace[i][j] = 0; length[i][j] = length[i-1][j]+1; } else { c = cost[j-1]; trace[i][j] = 1; length[i][j] = length[i][j-1]+1; } diag = cost[j]; cost[j] = dist(i,j) + c; } } rv[0] = cost[0]/length[nx-1][0]; for(i=1;i<ny;i++) { float avg_cost = cost[i]/length[nx-1][i]; if(rv[0]>avg_cost) { rv[0] = avg_cost; j = i; } } delete[] cost; i = nx-1; int p = nx+ny-1; for (;p>=0; --p){ path(p,0) = i; path(p,1) = j; if (i==0) break; switch (trace[i][j]){ case 0: --i; break; case 1: --j; break; default: --i; --j; } } for (i=0; i<nx; ++i) delete[] trace[i]; delete[] trace; for (i=0; i<nx; ++i) delete[] length[i]; delete[] length; rv[1] = p; ''' inline(code, ('nx', 'ny', 'rv', 'dist', 'path'), type_converters=blitz) return rv[0], path[rv[1]:]
def density_median(density, radius = 2, exp_weight = 0.0): """Performs a weighted median for each pixel in a density map - pixels are weighted by 1 minus their distance to the input values density. Uses the given radius to define the window for each pixel. Returns a new modified density map. exp_weight is a weight given to a location based on its value - used to bias towards larger values if set positive for instance.""" ret = density.copy() support = start_cpp() + """ struct Sam { float value; float weight; }; int comp_sam(const void * a, const void * b) { Sam & fa = *(Sam*)a; Sam & fb = *(Sam*)b; if (fa.value<fb.value) return -1; if (fb.value<fa.value) return 1; return 0; } """ code = start_cpp() + """ int rad = radius; float ew = exp_weight; Sam * sam = new Sam[(radius * 2 + 1) * (radius * 2 + 1)]; for (int y=radius; y<Ndensity[0]-radius; y++) { for (int x=radius; x<Ndensity[1]-radius; x++) { // Collect the samples required... float centre_value = DENSITY2(y, x); int total = 0; float total_weight = 0.0; for (int dy=-radius; dy<=radius; dy++) { const int range = radius - abs(dy); for (int dx=-range; dx<=range; dx++) { if ((dx!=0)||(dy!=0)) // Middle pixel doesn't get a vote! { float cv = sam[total].value; if (cv<1e-3) cv = 1e-3; if (cv>1.0) cv = 1.0; sam[total].value = DENSITY2(y+dy, x+dx); sam[total].weight = (1.0 - fabs(centre_value - cv)) * pow(cv, ew); total_weight += sam[total].weight; total += 1; } } } // Sort them... qsort(sam, total, sizeof(Sam), comp_sam); // Find the median, assign the pixel... float remain = 0.5 * total_weight; for (int i=0; i<total; i++) { if (remain>sam[i].weight) { remain -= sam[i].weight; } else { if (i==0) RET2(y, x) = sam[0].value; else { float t = remain / sam[i].weight; RET2(y, x) = (1-t) * sam[i-1].value + t * sam[i].value; } break; } } // Only use it if its larger than - anotehr bias term... if (DENSITY2(y, x)>RET2(y, x)) RET2(y, x) = DENSITY2(y, x); } } delete[] sam; """ weave.inline(code, ['density', 'ret', 'radius', 'exp_weight'], support_code=support) return ret
def nuke_islands(mask, size = 1): """Removes all islands in the mask that are less than or equal to the given size by flipping their state. Good for toasting salt and pepper noise.""" support = start_cpp() + """ struct Tree { Tree * parent; int size; }; Tree * Parent(Tree * tree) { if (tree->parent==NULL) return tree; Tree * ret = Parent(tree->parent); tree->parent = ret; return ret; } void Merge(Tree * a, Tree * b) { a = Parent(a); b = Parent(b); if (a!=b) { b->parent = a; a->size += b->size; } } """ code = start_cpp(support) + """ // Malloc and plant a forest... int trees = Nmask[0] * Nmask[1]; Tree * forest = (Tree*)malloc(trees * sizeof(Tree)); for (int i=0; i<trees; i++) { forest[i].parent = NULL; forest[i].size = 1; } // Merge it to create the islands... for (int y=0; y<Nmask[0]; y++) { for (int x=0; x<Nmask[1]; x++) { int fi = y*Nmask[1] + x; if ((x!=0)&&(MASK2(y, x)==MASK2(y, x-1))) { Merge(forest + fi, forest + fi - 1); } if ((y!=0)&&(MASK2(y, x)==MASK2(y-1, x))) { Merge(forest + fi, forest + fi - Nmask[1]); } } } // Flip the state of all pixels that are in too small an island... for (int y=0; y<Nmask[0]; y++) { for (int x=0; x<Nmask[1]; x++) { int fi = y*Nmask[1] + x; Tree * parent = Parent(forest + fi); if (parent->size <= size) { MASK2(y, x) = (MASK2(y, x) + 1) % 2; } } } // Clean up... free(forest); """ mask = mask.copy() weave.inline(code, ['mask', 'size'], support_code=support) return mask
def smooth_signed_distance(mask, iters = 1): """Given a mask this smooths it using a vaugly-not-stupid techneque based on signed distance to the edge of the line - converts the mask, then smoothes it using an oriented filter, that strongly enforces smooth contours and applies sub-pixel estimation. It then converts it back to a mask using the sign of the resulting distance. Should smoooth out bumps and sharpen small angle intersections.""" # Convert to signed distance, using the 8 way neighbourhood (With sqrt(2) for the diagonals)... ## Initalise with effective infinities... sigdist = numpy.empty(mask.shape, dtype=numpy.float32) sigdist[:,:] = 1e64 ## Mark all pixels that are at a transition boundary with the relevant cost - first the diagonals, then the halfs, as half is less than sqrt(2)... tran_sqrt2 = numpy.zeros(sigdist.shape, dtype=numpy.bool) numpy.logical_or(mask[1:,1:]!=mask[:-1,:-1], tran_sqrt2[:-1,:-1], tran_sqrt2[:-1,:-1]) numpy.logical_or(mask[1:,:-1]!=mask[:-1,1:], tran_sqrt2[:-1,1:], tran_sqrt2[:-1,1:]) numpy.logical_or(mask[:-1,1:]!=mask[1:,:-1], tran_sqrt2[1:,:-1], tran_sqrt2[1:,:-1]) numpy.logical_or(mask[:-1,:-1]!=mask[1:,1:], tran_sqrt2[1:,1:], tran_sqrt2[1:,1:]) sigdist[tran_sqrt2] = numpy.sqrt(2.0) tran_half = numpy.zeros(sigdist.shape, dtype=numpy.bool) numpy.logical_or(mask[1:,:]!=mask[:-1,:], tran_half[:-1,:], tran_half[:-1,:]) numpy.logical_or(mask[:-1,:]!=mask[1:,:], tran_half[1:,:], tran_half[1:,:]) numpy.logical_or(mask[:,1:]!=mask[:,:-1], tran_half[:,:-1], tran_half[:,:-1]) numpy.logical_or(mask[:,:-1]!=mask[:,1:], tran_half[:,1:], tran_half[:,1:]) sigdist[tran_half] = 0.5 ## Do all 8 directions of sweep iterativly until distances stop getting smaller... stop = False while not stop: stop = True code = start_cpp() + """ float sqrt2 = sqrt(2.0); // Forwards pass... for (int y=0; y<Nsigdist[0]; y++) { for (int x=0; x<Nsigdist[1]; x++) { bool negx = x!=0; bool negy = y!=0; if ((negx)&&((SIGDIST2(y, x-1)+1.0)<SIGDIST2(y, x))) { SIGDIST2(y, x) = SIGDIST2(y, x-1) + 1.0; stop = false; } if ((negy)&&((SIGDIST2(y-1, x)+1.0)<SIGDIST2(y, x))) { SIGDIST2(y, x) = SIGDIST2(y-1, x) + 1.0; stop = false; } if ((negx)&&(negy)&&((SIGDIST2(y-1, x-1)+sqrt2)<SIGDIST2(y, x))) { SIGDIST2(y, x) = SIGDIST2(y-1, x-1) + sqrt2; stop = false; } } } // Backwards pass... for (int y=Nsigdist[0]-1; y>=0; y--) { for (int x=Nsigdist[1]-1; x>=0; x--) { bool posx = (x+1)!=Nsigdist[1]; bool posy = (y+1)!=Nsigdist[0]; if ((posx)&&((SIGDIST2(y, x+1)+1.0)<SIGDIST2(y, x))) { SIGDIST2(y, x) = SIGDIST2(y, x+1) + 1.0; stop = false; } if ((posy)&&((SIGDIST2(y+1, x)+1.0)<SIGDIST2(y, x))) { SIGDIST2(y, x) = SIGDIST2(y+1, x) + 1.0; stop = false; } if ((posx)&&(posy)&&((SIGDIST2(y+1, x+1)+sqrt2)<SIGDIST2(y, x))) { SIGDIST2(y, x) = SIGDIST2(y+1, x+1) + sqrt2; stop = false; } } } """ weave.inline(code, ['sigdist', 'stop']) ## Add in the sign - negate all pixels that are within the mask... sigdist[mask] *= -1.0 # Apply a funky smoothing function... temp = sigdist.copy() use = sigdist<16.0 # Don't bother with pixels that are too far from the text. for _ in xrange(iters): support = start_cpp() + """ int comp_float(const void * a, const void * b) { float fa = *(float*)a; float fb = *(float*)b; if (fa<fb) return -1; if (fb<fa) return 1; return 0; } """ code = start_cpp(support) + """ // Calculate and store the smoothed version into temp... for (int y=1; y<Nsigdist[0]-1; y++) { for (int x=1; x<Nsigdist[1]-1; x++) { if (USE2(y, x)==0) continue; // Skip pixels that are too far away to care about. static const char dx[8] = {-1, 0, 1, 1, 1, 0, -1, -1}; static const char dy[8] = {-1, -1, -1, 0, 1, 1, 1, 0}; static const float div[8] = {sqrt(2), 1, sqrt(2), 1, sqrt(2), 1, sqrt(2), 1}; // Loop through using a line direction estimated from each set of 3 adjacent neigbours in the 8-way neighbourhood - select the line direction that results in the lowest MAD, using the median of the estimates. The estimates are based on the signed distance of the neighbour offset by the projection distance to the line... float bestMedian = SIGDIST2(y, x); float bestMAD = 1e64; for (int ni=0; ni<8; ni++) { // Estimate the perpendicular to the line direction from the 3 neighbours under consideration - a maximum liklihood mean direction of a Fisher distribution... float nx = 0.0; float ny = 0.0; bool skip = false; for (int oi=0; oi<3; oi++) { int i = (ni+oi) % 8; if (USE2(y + dy[i], x + dx[i])==0) { skip = true; break; } float l = SIGDIST2(y + dy[i], x + dx[i]) - SIGDIST2(y, x); l /= div[i]; nx += l * dx[i]; ny += l * dy[i]; } if (skip) continue; // Normalise the perpendicular to the projection line... float len = sqrt(nx*nx + ny*ny); if (len<1e-3) continue; nx /= len; ny /= len; // Use the proposed line to calculate all 8 estimates... float e[8]; for (int i=0; i<8; i++) { float dot = nx * dx[i] + ny * dy[i]; e[i] = SIGDIST2(y + dy[i], x + dx[i]) + dot; } // Use the estimates to calculate the median... qsort(e, 8, sizeof(float), comp_float); float median = 0.5 * (e[3] + e[4]); // Mess around and then calculate the MAD... for (int i=0; i<8; i++) { e[i] = fabs(e[i] - median); } qsort(e, 8, sizeof(float), comp_float); float MAD = 0.5 * (e[3] + e[4]); // If its the best MAD thus far record it... if (MAD<bestMAD) { bestMedian = median; bestMAD = MAD; } } TEMP2(y, x) = bestMedian; } } // Copy from temp to the actual signed distance field (Yeah, pointer flipping would make more sense, but no idea how to make a numpy object dance that)... for (int y=1; y<Nsigdist[0]-1; y++) { for (int x=1; x<Nsigdist[1]-1; x++) { SIGDIST2(y, x) = TEMP2(y, x); } } """ weave.inline(code, ['sigdist', 'temp', 'use'], support_code=support) # Convert back to a mask and return... return sigdist<=0.0
part(0) = coord(prtcl,0); part(1) = coord(prtcl,1); part(2) = coord(prtcl,2); m = int(part(0)/h); n = int(part(1)/h); p = int(part(2)/h); for (i = -r + 1; i < r + 1; i = i + 1){ for (j = -r + 1; j < r + 1; j = j + 1){ for (k = -r + 1; k < r + 1; k = k + 1){ xsp = (m+i)*h; ysp = (n+j)*h; zsp = (p+k)*h; if (((part(0)-xsp)*(part(0)-xsp) + (part(1)-ysp)*(part(1)-ysp) + (part(2)-zsp)*(part(2)-zsp)) <= R*R) { meff = m + i; neff = n + j; peff = p + k; if (meff<0) {meff+=numofsph-1;} if (neff<0) {neff+=numofsph-1;} if (peff<0) {peff+=numofsph-1;} if (meff>=numofsph) {meff-=numofsph-1;} if (neff>=numofsph) {neff-=numofsph-1;} if (peff>=numofsph) {peff-=numofsph-1;} density (meff, neff, peff)+=1; } } } } } """ weave.inline (ccode, ['density', 'nop', 'numofsph', 'part', 'R', 'h', 'r', 'coord'], type_converters = converters.blitz, compiler = 'gcc') density = density/V; boundcond() t2 = time() - t1 - t0 print ('time for reading = ', t1, 'time for calculating density', t2) #index = peff+neff*numofsph+meff*numofsph*numofsph; #density[index]+=1;
def steinhardt_g_l(pos, bonds, is_center, Nbins, maxdist, l=6): """ Spatial correlation of the bond's spherical harmonics """ assert len(is_center) == len(pos) maxsq = float(maxdist**2) hq = np.zeros(Nbins) g = np.zeros(Nbins, int) qlms = np.zeros([len(bonds), l + 1], np.complex128) bpos = np.zeros([len(bonds), 3]) code = """ //position and spherical harmonics of each bond #pragma omp parallel for for(int b=0; b<Nbonds[0]; ++b) { int i = bonds(b,0), j = bonds(b,1); blitz::Array<double,1> cart(pos(i, blitz::Range::all()) - pos(j, blitz::Range::all())); bpos(b, blitz::Range::all()) = pos(j, blitz::Range::all()) + 0.5 * cart; double sph[3] = {0, 0, 0}; sph[0] = sqrt(blitz::sum(blitz::pow(cart, 2))); if(abs(cart(2))==sph[0] || sph[0]*sph[0]+1.0 == 1.0) { sph[1] = 0; sph[2] = 0; } else { sph[1] = acos(cart(2)/sph[0]); sph[2] = atan2(cart(1), cart(0)); if(sph[2]<0) sph[2] += 2.0*M_PI; } for(int m=0; m<Nqlms[1]; ++m) qlms(b,m) = boost::math::spherical_harmonic(Nqlms[1]-1, m, sph[1], sph[2]); } #pragma omp parallel for for(int b=0; b<Nbonds[0]; ++b) { int i = bonds(b,0), j = bonds(b,1); if(!is_center(i) || !is_center(j)) continue; for(int c=0; c<Nbonds[0]; ++c) { const double disq = blitz::sum(blitz::pow(bpos(b, blitz::Range::all()) - bpos(c, blitz::Range::all()),2)); if(disq>=(double)maxsq) continue; const int r = sqrt(disq/(double)maxsq)*Nbins; double pq = real(qlms(b,0)*conj(qlms(c,0))); for(int m=1; m<Nqlms[1]; ++m) pq += 2.0*real(qlms(b,m)*conj(qlms(c,m))); pq *= 4.0*M_PI/(2.0*(Nqlms[1]-1)+1); #pragma omp critical { ++g(r); hq(r) += pq; } } } """ weave.inline( code, [ 'qlms', 'pos', 'bonds', 'bpos', 'maxsq', 'Nbins', 'hq', 'g', 'is_center' ], type_converters=converters.blitz, headers=['<boost/math/special_functions/spherical_harmonic.hpp>'], extra_compile_args=['-O3 -fopenmp'], extra_link_args=['-lgomp'], verbose=2, compiler='gcc') return hq, g
static char f_types[] = { NPY_DOUBLE, NPY_DOUBLE, NPY_BOOL, }; ''' ufunc_info = weave.base_info.custom_info() ufunc_info.add_header('"numpy/ufuncobject.h"') mandel = weave.inline('/*' + md5.md5(support_code).hexdigest() + '''*/ import_ufunc(); return_val = PyUFunc_FromFuncAndData(f_functions, NULL, f_types, 1, /* ntypes */ 2, /* nin */ 1, /* nout */ PyUFunc_None, /* identity */ "mandel", /* name */ "doc", /* doc */ 0); ''', support_code=support_code, verbose=0, customize=ufunc_info) # ---------------------------------------------------------------------------- w, h = 8000, 6000 y, x = numpy.ogrid[-1.5:+1.5:h * 1j, -2.75:+1.25:w * 1j]
def global_mass(X, elements, connect, nproc): """Assemble the global mass matrix Parameters ---------- X : array like, (i, j,) Nodal coordinates X[i, j] -> jth coordinate of ith node for i=1...nnode, j=1...ncoord elements : array_like, (i,) Array of element classes connect : array_like, (i, j,) Nodal connections connect[i, j] -> jth node on the ith element Returns ------- mass : array_like """ maxnodes = np.amax([x.nnodes for x in elements]) ndof = elements[0].ndof sdim = ndof * X.shape[0] mass = np.zeros((sdim, sdim)) # Loop over all the elements for (lmn, element) in enumerate(elements): mel = _elmass(lmn, element, maxnodes, connect[lmn], X) # Add the current element mass to the global mass nnodes = elements[lmn].nnodes ncoord = elements[lmn].ncoord ndof = elements[lmn].ndof if not HAS_CCOMPILER: for a in range(nnodes): for i in range(ndof): for b in range(nnodes): for k in range(ndof): rw = ndof * connect[lmn, a] + i cl = ndof * connect[lmn, b] + k elrw = ndof * a + i elcl = ndof * b + k mass[rw, cl] += mel[elrw, elcl] else: code = """ int rw, cl, elrw, elcl; for (int a=0; a < nnodes; ++a) { for (int i=0; i < ndof; ++i) { for (int b=0; b < nnodes; ++b) { for (int k=0; k < ndof; ++k) { rw = ndof * connect(lmn, a) + i; cl = ndof * connect(lmn, b) + k; elrw = ndof * a + i; elcl = ndof * b + k; mass(rw, cl) += mel(elrw, elcl); } } } } """ inline(code, ["nnodes", "ndof", "lmn", "connect", "mass", "mel"], type_converters=converters.blitz) return mass
def EvSync(e, noe, nodes, core, noc, perc, tm, season, P, noep): print "batch %d running ..." % core l = nodes * ((nodes / noc) - 1) / 2 + core * (nodes / noc) Q = np.zeros(l, dtype='bool') taumax = tm var = ['e', 'Q', 'nodes', 'noe', 'taumax', 'core', 'noc', 'P', 'noep'] src = r""" int tau, tmp, count, dst; long i, k, m, n, t, c, li, lk; long long e1, e2; int q; c = 0; for(i = core; i < nodes; i += noc){ for(k = 0; k < i; k++){ count = 0; li = 0; lk = 0; for(m = 1; m < noep[i] - 1; m++) { if(e[i * noe + m] > 0){ li++; for(n = 1; n < noep[k] - 1; n++) { if(e[k * noe + n] > 0){ lk++; dst = e[i * noe + m] - e[k * noe + n]; if(dst > taumax) continue; tmp = e[i * noe + m + 1] - e[i * noe + m]; if(tmp > e[i * noe + m] - e[i * noe + m - 1]) tmp = e[i * noe + m] - e[i * noe + m - 1]; tau = e[k * noe + n + 1] - e[k * noe + n]; if(tau > e[k * noe + n] - e[k * noe + n - 1]) tau = e[k * noe + n] - e[k * noe + n - 1]; if(tau > tmp) tau = tmp; tau /= 2; if(abs(e[i * noe + m] - e[k * noe + n]) <= taumax && abs(e[i * noe + m] - e[k * noe + n]) < tau) count++; if(dst < -taumax) break; } } } } if(li<3) { q = 0; } else if(lk<3) { q = 0; } else { q = count; } e1 = noep[i]; e2 = noep[k]; if(e1 < e2){ e1 = noep[k]; e2 = noep[i]; } if(e1 > 2 && e2 > 2 && q > P[((e1 - 2) * (e1 - 3) / 2 + e2 - 3) * 3 + 2]){ Q[c] = 1; } else{ Q[c] = 0; } c += 1; } } """ weave.inline(src, var) del e np.save( '/p/tmp/boers/Q_trmm7_global_wd_perc%d_tm%d_season%d_bool_nb_sig005_slice%d' % (perc, tm, season, core), Q) print "batch %d saved ..." % core del Q return 0
def find_interval_extremes(array, edges): """ Find the indeces of extreme points within each interval, and on the outsides of the two end edges. :param array: A vector :param edges: A vector of edges defining the intervals. It's assumed that -Inf, Inf form the true outer edges. :return: A vector of ints indicating the indeces of extreme points. If a distinct min and max extreme are found within every interval, this vector will have length 2*(len(edges)+1). Otherwise, it will be shorter. """ indices = np.zeros(len(array), dtype=int) - 1 how_many = np.array([0]) code = """ float min = INFINITY; float max = -INFINITY; int argmin; int argmax; bool foundpoint = false; int in_counter = 0; int out_counter = 0; int edge_counter = 0; while(in_counter<Narray[0]){ float next_edge; if (edge_counter == Nedges[0]) next_edge = INFINITY; else next_edge = edges[edge_counter]; if (array[in_counter] < min){ min = array[in_counter]; argmin = in_counter; foundpoint = true; } if (array[in_counter] > max){ max = array[in_counter]; argmax = in_counter; foundpoint = true; } in_counter++; if (in_counter > next_edge){ if (foundpoint){ if (argmin < argmax){ indices[out_counter] = argmin; indices[out_counter+1] = argmax; out_counter+=2; } else if (argmax < argmin){ indices[out_counter] = argmax; indices[out_counter+1] = argmin; out_counter+=2; } else { indices[out_counter] = argmax; out_counter++; } min = INFINITY; max = -INFINITY; foundpoint = false; } edge_counter++; } } how_many[0] = out_counter; """ weave.inline(code, ['array', 'edges', 'indices', 'how_many'], compiler='gcc') result = indices[:how_many[0]] return result
def scalar_map(y, x, scalar_field, hsml, width, pps, zshape): """ code contains an algorithm for doing sph particle smoothing. """ # !!!!! x and y are reversed in the c-code below - no idea why/how... # !!!!! (Hence the reversal above) zi = numpy.zeros(zshape) nzi = numpy.zeros_like(zi) N_gas = scalar_field.size code = \ r""" int procs, nthreads; int i,j,n, i_min,i_max,j_min,j_max; int flag_i = 0; int flag_j = 0; double center_i,center_j; double r,r2,weight,W_x; /* Get environment information */ procs = omp_get_num_procs(); nthreads = omp_get_num_threads(); /* Print environment information */ printf("Number of processors = %d\n", procs); #pragma omp parallel for \ private(n,i,j,i_min,i_max,j_min,j_max,flag_i,flag_j, \ center_i,center_j,r,r2,weight,W_x) for(n =0; n < N_gas; n++) { i = 0; j = 0; i_min = int((x(n) - hsml(n) + width/2.0) / width*pps); i_max = int((x(n) + hsml(n) + width/2.0) / width*pps); j_min = int((y(n) - hsml(n) + width/2.0) / width*pps); j_max = int((y(n) + hsml(n) + width/2.0) / width*pps); weight = scalar_field(n)*scalar_field(n); do { if(i >= i_min && i <= i_max) { flag_i = 1; center_i = -width/2.0 + (i+0.5) * width/ (double) pps; do { if(j >= j_min && j <= j_max) { flag_j = 1; center_j = -width/2.0 + (j+0.5) * width / (double) pps; r2 = ((x(n) - center_i) * (x(n) - center_i) + (y(n) - center_j) * (y(n) - center_j)) / hsml(n) / hsml(n); if(r2 <= 1.0) { r = sqrt(r2); if(r <= 0.5) W_x = 1.0 - 6.0 * r*r + 6.0 * r*r*r; else W_x = 2.0 * (1.0-r) * (1.0-r) * (1.0-r); zi(i,j) += weight * scalar_field(n) * W_x; nzi(i,j) += weight * W_x; } } else if(j > j_max) { flag_j = 2; } else { flag_j = 0; } j++; } while((flag_j == 0 || flag_j == 1) && j < pps); j = 0; } else if(i > i_max) { flag_i = 2; } else { flag_i = 0; } i++; } while((flag_i == 0 || flag_i == 1) && i < pps); i = 0; } """ weave.inline(code, [ 'pps', 'width', 'x', 'y', 'scalar_field', 'hsml', 'zi', 'nzi', 'N_gas' ], compiler='gcc', headers=['<stdio.h>', '<math.h>', '<omp.h>'], extra_compile_args=['-fopenmp '], libraries=['gomp'], type_converters=converters.blitz) zi = numpy.where(nzi > 0, zi / nzi, zi) return zi
def isPointInPoly(self, pt, poly): ''' Checks if point pt is in a polygon poly @param pt: the point @param poly: the polygon @return: true if point is in the polygon ''' n = len(poly) code = """ double p1x, p2x, p1y, p2y; bool inside = false; double x,y; x = pt[0]; y = pt[1]; py::object p1 = poly[0]; p1x = p1[0]; p1y = p1[1]; for (int i=0; i<n+1; i++) { double p2x, p2y; py::object p2 = poly[i%n]; p2x = p2[0]; p2y = p2[1]; double miny, maxy, minx, maxx; if (p1x < p2x) { minx = p1x; maxx = p2x; } else { minx = p2x; maxx = p1x; } if (p1y < p2y) { miny = p1y; maxy = p2y; } else { miny = p2y; maxy = p1y; } if ((y > miny) && (y <= maxy) && (x <= maxx)) { double xinters = 0; if (p1y != p2y) { xinters = (y-p1y)*(p2x-p1x)/(p2y-p1y)+p1x; if ((p1x == p2x) || (x <= xinters)) { inside = !inside; } } } p1x = p2x; p1y = p2y; } return_val = inside; """ in_poly = weave.inline(code, ['poly', 'pt', 'n'], type_converters=converters.blitz) return in_poly
def pnorm_w(data1, data2=None, weight=None, p=2): """Weighted p-norm between two datasets (scipy.weave implementation) ||x - x'||_w = (\sum_{i=1...N} (w_i*|x_i - x'_i|)**p)**(1/p) Parameters ---------- data1 : np.ndarray First dataset data2 : np.ndarray or None Optional second dataset weight : np.ndarray or None Optional weights per 2nd dimension (features) p Power """ if weight == None: weight = np.ones(data1.shape[1], 'd') pass S1, F1 = data1.shape[:2] code = "" if data2 == None or id(data1)==id(data2): if not (F1==weight.size): raise ValueError, \ "Dataset should have same #columns == #weights. Got " \ "%d %d" % (F1, weight.size) F = F1 d = np.zeros((S1, S1), 'd') try: code_peritem = \ {1.0 : "tmp = tmp+weight(t)*fabs(data1(i,t)-data1(j,t))", 2.0 : "tmp2 = weight(t)*(data1(i,t)-data1(j,t));" \ " tmp = tmp + tmp2*tmp2"}[p] except KeyError: code_peritem = "tmp = tmp+pow(weight(t)*fabs(data1(i,t)-data1(j,t)),p)" code = """ int i,j,t; double tmp, tmp2; for (i=0; i<S1-1; i++) { for (j=i+1; j<S1; j++) { tmp = 0.0; for(t=0; t<F; t++) { %s; } d(i,j) = tmp; } } return_val = 0; """ % code_peritem counter = weave.inline(code, ['data1', 'S1', 'F', 'weight', 'd', 'p'], type_converters=converters.blitz, compiler = 'gcc') d = d + np.triu(d).T # copy upper part to lower part return d**(1.0/p) S2, F2 = data2.shape[:2] if not (F1==F2==weight.size): raise ValueError, \ "Datasets should have same #columns == #weights. Got " \ "%d %d %d" % (F1, F2, weight.size) F = F1 d = np.zeros((S1, S2), 'd') try: code_peritem = \ {1.0 : "tmp = tmp+weight(t)*fabs(data1(i,t)-data2(j,t))", 2.0 : "tmp2 = weight(t)*(data1(i,t)-data2(j,t));" \ " tmp = tmp + tmp2*tmp2"}[p] except KeyError: code_peritem = "tmp = tmp+pow(weight(t)*fabs(data1(i,t)-data2(j,t)),p)" pass code = """ int i,j,t; double tmp, tmp2; for (i=0; i<S1; i++) { for (j=0; j<S2; j++) { tmp = 0.0; for(t=0; t<F; t++) { %s; } d(i,j) = tmp; } } return_val = 0; """ % code_peritem counter = weave.inline(code, ['data1', 'data2', 'S1', 'S2', 'F', 'weight', 'd', 'p'], type_converters=converters.blitz, compiler = 'gcc') return d**(1.0/p)
def nextFrame(self): # Reset some buffers.... self.invMatrix = None self.prevCorrect = None self.currCorrect = None # Update the previous and current... if self.other==None: self.prev = self.curr self.curr = self.video.fetch(self.channel) if self.curr==None: return False if self.prev==None: return True self.curr = self.curr.copy() else: self.prev = self.other.fetch(self.otherChannel) self.curr = self.video.fetch(self.channel) if self.curr==None: return False if self.prev==None: return True # Make sure the temporary is the right size... pixelCount = self.width() * self.height() if self.temp==None or self.temp.shape[0]!=pixelCount: self.temp = numpy.empty((pixelCount,3), dtype=numpy.float32) # Collect for each channel the ratios that are essentially estimates of the lighting change... codeE = start_cpp() + """ int count = 0; for (int y=0;y<Ncurr[0];y++) { for (int x=0;x<Ncurr[1];x++) { if ((CURR3(y,x,0)>lowLimit)&&(PREV3(y,x,0)>lowLimit)) { float diff = 0.0; for (int c=0;c<3;c++) { float cVal = CURR3(y,x,c); float pVal = PREV3(y,x,c); diff += fabs(cVal - pVal); TEMP2(count,c) = cVal / pVal; } if (diff<limit) count += 1; } } } return_val = count; """ curr = self.curr prev = self.prev temp = self.temp limit = self.limit lowLimit = self.lowLimit count = weave.inline(codeE, ['curr', 'prev', 'temp', 'limit', 'lowLimit']) if count<8: self.matrix[:,:] = numpy.identity(4, dtype=numpy.float32) return True # Sort each channel, ready for mean shift... for channel in xrange(3): self.temp[:count,channel].sort() # Mean shift for each channel in turn... codeMS = start_cpp() + """ // Parameters and some initialisation... const float epsilon = 1e-3; const int maxIter = 32; const float hsm = 3.0; const float winWidth = hsm * float(scale); // Iterate the channels... for (int channel=0; channel<channels; channel++) { // Median seems a good initial estimate - as long as at least half the pixels are background at the same time in both images it is guaranteed to be a good estimate... float estimate = TEMP2(count/2,channel); float minVal = estimate - winWidth; float maxVal = estimate + winWidth; // Use a pair of binary searches to initialise the range to sum over... int low = 0; int other = count-1; while (low+1<other) { int half = (low+other)/2; if (TEMP2(half,channel)<minVal) low = half; else other = half; } other = low+1; int high = count-1; while (other+1<high) { int half = (other+high)/2; if (TEMP2(half,channel)>maxVal) high = half; else other = half; } // Iterate and do the mean shift steps... for (int iter=0;iter<maxIter;iter++) { minVal = estimate - winWidth; maxVal = estimate + winWidth; // Update the low and high values by simply offsetting them until correct... for (;low>0;--low) { if (TEMP2(low,channel)<minVal) break; } for (;low<count-1;++low) { if (TEMP2(low,channel)>minVal) break; } for (;high<count-1;++high) { if (TEMP2(high,channel)>maxVal) break; } for (;high>0;--high) { if (TEMP2(high,channel)<maxVal) break; } if (low>=high) break; // No data - give up. // Iterate the relevant values and add them to the kernel... float newEst = 0.0; float weightEst = 0.0; float weight; float prevVal = 1e100; float scale2 = float(scale)*float(scale); for (int i=low;i<=high;i++) { if (fabs(prevVal-TEMP2(i,channel))>epsilon) { prevVal = TEMP2(i,channel); float delta = prevVal - estimate; // weight = exp(-0.5*delta*delta/scale2); // Gaussian option weight = float(scale) / (M_PI * (delta*delta + scale2)); // Cauchy option } weightEst += weight; newEst += (TEMP2(i,channel)-newEst) * weight / weightEst; } // Update the estimate, exit if change is minor... bool done = fabs(newEst-estimate) < epsilon; estimate = newEst; if (done) break; } // Store it... MATRIX2(channel, channel) = estimate; } for (int channel=channels; channel<3; channel++) { MATRIX2(channel, channel) = 1,0; } """ scale = self.scale matrix = self.matrix channels = self.channels weave.inline(codeMS, ['temp', 'count', 'scale', 'matrix', 'channels']) return True
def erode( self, grid, dt=None, node_elevs='topographic_elevation', node_drainage_areas='drainage_area', node_receiving_flow='flow_receiver', node_order_upstream='upstream_ID_order', node_slope='steepest_slope', steepest_link='links_to_flow_receiver', runoff_rate_if_used=None, #W_if_used=None, Q_if_used=None, stability_condition='loose', Dchar_if_used=None, io=None): """ Note this method must be passed both 'receiver' and 'upstream_order', either as strings for field access, or nnode- long arrays of the relevant IDs. These are most easily used as the outputs from route_flow_dn. Note that you must supply either slopes_at_nodes or link_slopes. """ if runoff_rate_if_used != None: runoff_rate = runoff_rate_if_used assert type(runoff_rate) in (int, float, np.ndarray) else: runoff_rate = 1. if dt == None: dt = self.tstep try: self.Dchar = self.Dchar_in except AttributeError: try: self.Dchar = grid.at_node[Dchar_if_used] except FieldError: assert type(Dchar_if_used) == np.ndarray self.Dchar = Dchar_if_used if not self.set_threshold: assert self.override_threshold, "You need to confirm to the module you intend it to internally calculate a shear stress threshold, with set_threshold_from_Dchar in the input file." #we need to adjust the thresholds for the Shields number & gs dynamically: variable_thresh = self.shields_crit * self.g * ( self.sed_density - self.fluid_density) * self.Dchar else: assert Dchar_if_used is None, "Trouble ahead... you can't provide Dchar both in the input file and as an array!" if type(node_elevs) == str: node_z = grid.at_node[node_elevs] else: node_z = node_elevs if type(node_drainage_areas) == str: node_A = grid.at_node[node_drainage_areas] else: node_A = node_drainage_areas if type(node_receiving_flow) == str: flow_receiver = grid.at_node[node_receiving_flow] else: flow_receiver = node_receiving_flow #new V3: if type(node_order_upstream) == str: s_in = grid.at_node[node_order_upstream] else: s_in = node_order_upstream if type(node_slope) == str: node_S = grid.at_node[node_slope] else: node_S = node_slope if self.lamb_flag: variable_shields_crit = 0.15 * node_S**0.25 try: variable_thresh = variable_shields_crit * self.shields_prefactor_to_shear except AttributeError: variable_thresh = variable_shields_crit * self.shields_prefactor_to_shear_noDchar * self.Dchar if type(steepest_link) == str: link_length = np.empty(grid.number_of_nodes, dtype=float) link_length.fill(np.nan) draining_nodes = np.not_equal(grid.at_node[steepest_link], BAD_INDEX_VALUE) core_draining_nodes = np.intersect1d(np.where(draining_nodes)[0], grid.core_nodes, assume_unique=True) link_length[core_draining_nodes] = grid.link_length[ grid.at_node[steepest_link][core_draining_nodes]] #link_length=grid.node_spacing_horizontal else: link_length = grid.link_length[steepest_link] node_Q = self.k_Q * runoff_rate * node_A**self._c shear_stress_prefactor_timesAparts = self.shear_stress_prefactor * node_Q**self.point6onelessb try: transport_capacities_thresh = self.thresh * self.Qs_thresh_prefactor * runoff_rate**( 0.66667 * self._b) * node_A**self.Qs_power_onAthresh except AttributeError: transport_capacities_thresh = variable_thresh * self.Qs_thresh_prefactor * runoff_rate**( 0.66667 * self._b) * node_A**self.Qs_power_onAthresh transport_capacity_prefactor_withA = self.Qs_prefactor * runoff_rate**( 0.6 + self._b / 15.) * node_A**self.Qs_power_onA internal_t = 0. break_flag = False dt_secs = dt * 31557600. counter = 0 rel_sed_flux = np.empty_like(node_Q) #excess_vol_overhead = 0. while 1: #use the break flag, to improve computational efficiency for runs which are very stable #we assume the drainage structure is forbidden to change during the whole dt #print "loop..." #note slopes will be *negative* at pits #track how many loops we perform: counter += 1 #print counter downward_slopes = node_S.clip(0.) #positive_slopes = np.greater(downward_slopes, 0.) slopes_tothe07 = downward_slopes**0.7 transport_capacities_S = transport_capacity_prefactor_withA * slopes_tothe07 trp_diff = (transport_capacities_S - transport_capacities_thresh).clip(0.) transport_capacities = np.sqrt(trp_diff * trp_diff * trp_diff) shear_stress = shear_stress_prefactor_timesAparts * slopes_tothe07 shear_tothe_a = shear_stress**self._a dt_this_step = dt_secs - internal_t #timestep adjustment is made AFTER the dz calc node_vol_capacities = transport_capacities * dt_this_step sed_into_node = np.zeros(grid.number_of_nodes, dtype=float) dz = np.zeros(grid.number_of_nodes, dtype=float) len_s_in = s_in.size cell_areas = self.cell_areas try: raise CompileError #tripped out deliberately for now; doesn't appear to accelerate much weave.inline(self.routing_code, [ 'len_s_in', 'sed_into_node', 'transport_capacities', 'dz', 'cell_areas', 'dt_this_step', 'flow_receiver' ]) except CompileError: for i in s_in[::-1]: #work downstream try: cell_area = cell_areas[i] except TypeError: #it's a float, not an array cell_area = cell_areas sed_flux_into_this_node = sed_into_node[i] node_capacity = transport_capacities[ i] #we work in volume flux, not volume per se here node_vol_capacity = node_vol_capacities[i] if sed_flux_into_this_node < node_vol_capacity: #note incision is forbidden at capacity # sed_flux_ratio = sed_flux_into_this_node/node_capacity # fqsqc=self.get_sed_flux_function(sed_flux_ratio) # try: # thresh = variable_thresh # except: #it doesn't exist # thresh = self.thresh # dz_here = self._K_unit_time*dt_this_step*fqsqc*(shear_tothe_a[i]-thresh).clip(0.) #let's define down as +ve # vol_pass_attempted = dz_here*cell_area + sed_flux_into_this_node # if vol_pass_attempted > node_vol_capacity: # #it's vital we don't allow the final node to erode more than it can remove from the node!! # #=>must modify dz_here, not just drop that sed # excess_volume = vol_pass_attempted-node_vol_capacity # dz_reduction = excess_volume/cell_area # dz_here -= dz_reduction # #add a "sneak" to stop the transition point developing into a sed deposition shock: # if dz_here < 0.: # #excess_vol_overhead += (dz_reduction-dz_here)*cell_area # #node_vol_capacities[flow_receiver[i]] += excess_vol_overhead # dz_here = 0. #this sed packet gets to be "excess overhead" -> it gets freely transported downstream. # #...but problems will arise if the system terminates before a boundary cell! (Mass leak) # #also, upstream node is still incising freely; it can't feel this. # #slopes can still reverse, if the initial gradient was small # #=>no node may incise more than the next node down in the previous tstep? # #could use this to set dt_internal... # #do the "incising" part as normal, then pause once depo occurs,... # #then reduce dt_int so it can't dig further than the next node anywhere... # #then RERUN, don't scale dz # vol_pass = node_vol_capacity # else: # vol_pass = vol_pass_attempted ##implementing the pseudoimplicit method instead: try: thresh = variable_thresh except: #it doesn't exist thresh = self.thresh dz_prefactor = self._K_unit_time * dt_this_step * ( shear_tothe_a[i] - thresh).clip(0.) vol_prefactor = dz_prefactor * cell_area dz_here, sed_flux_out, rel_sed_flux_here, error_in_sed_flux = self.get_sed_flux_function_pseudoimplicit( sed_flux_into_this_node, node_vol_capacity, vol_prefactor, dz_prefactor) #note now dz_here may never create more sed than the out can transport... assert sed_flux_out <= node_vol_capacity, 'failed at node ' + str( s_in.size - i) + ' with rel sed flux ' + str( sed_flux_out / node_capacity) rel_sed_flux[i] = rel_sed_flux_here vol_pass = sed_flux_out #*dt_this_step else: rel_sed_flux[i] = 1. vol_dropped = sed_flux_into_this_node - node_vol_capacity dz_here = -vol_dropped / cell_area vol_pass = node_vol_capacity dz[i] -= dz_here sed_into_node[flow_receiver[i]] += vol_pass # #perform the fractional-slope-change stability analysis # elev_diff = node_z - node_z[flow_receiver] # delta_dz = dz - dz[flow_receiver] #remember, here dz is DOWN (unlike the TL case) # ###delta_dz = np.fabs(delta_dz) # ##excess_fraction = delta_dz/elev_diff # ##most_flattened_nodes = np.argmax(np.fabs(excess_fraction[grid.core_nodes])) # node_flattening = self.fraction_gradient_change*elev_diff - delta_dz #note the condition is that gradient may not change by >X%, not must be >0 # #note all these things are zero for a pit node # most_flattened_nodes = np.argmin(node_flattening[grid.core_nodes]) # most_flattened_nodes = np.take(grid.core_nodes, most_flattened_nodes) #get it back to node number, not core_node number # ##most_flattened_val = np.take(excess_fraction, most_flattened_nodes) # ##abs_most_flattened_val = np.fabs(most_flattened_val) # most_flattened_val = np.take(node_flattening, most_flattened_nodes) # print 'most flattened val: ', most_flattened_val # if most_flattened_val>=0.: # ##if abs_most_flattened_val<self.fraction_gradient_change: # break_flag = True #all nodes are stable # else: # a fraction > the critical fraction # ###need to think about if we can assume dz and dt behave linearly in these cases... # #first impression is that it's OK. Still assume everything works linearly *within any given tstep* # most_extreme_elev_diff = np.take(elev_diff, most_flattened_nodes) # most_extreme_delta_dz = np.take(delta_dz, most_flattened_nodes) # print 'elev_diff: ', most_extreme_elev_diff # print 'delta dz: ', most_extreme_delta_dz # print '***' # dt_fraction = 0.5*self.fraction_gradient_change*most_extreme_elev_diff/most_extreme_delta_dz # ##dt_fraction = self.fraction_gradient_change/abs_most_flattened_val ###persistent failure here happens when elev diff manages to reverse itself, which should be forbidden ###this might be showing that a linear model *isn't* adequate ###how about doing all the stability *before* the analysis? Once we have slope, capacity & fldir for all nodes, ###worst case scenario is that all the potential sed gets dumped in this node ###(better case - deduct the transport capacity out). ...isn't this just the TL stability condition?? # # #print 'dt_fraction: ', dt_fraction # #correct those elevs # dz *= dt_fraction # dt_this_step *= dt_fraction break_flag = True node_z[grid.core_nodes] += dz[grid.core_nodes] if break_flag: break #do we need to reroute the flow/recalc the slopes here? -> NO, slope is such a minor component of Diff we'll be OK #BUT could be important not for the stability, but for the actual calc. So YES. node_S = np.zeros_like(node_S) #print link_length[core_draining_nodes] node_S[core_draining_nodes] = ( node_z - node_z[flow_receiver] )[core_draining_nodes] / link_length[core_draining_nodes] internal_t += dt_this_step #still in seconds, remember self.grid = grid active_nodes = grid.get_active_cell_node_ids() if io: try: io[active_nodes] = node_z[active_nodes] except TypeError: if type(io) == str: elev_name = io else: return grid, io else: elev_name = node_elevs if self.return_ch_props: #add the channel property field entries, #'channel_width', 'channel_depth', and 'channel_discharge' W = self.k_w * node_Q**self._b H = shear_stress / self.rho_g / node_S #...sneaky! grid.at_node['channel_width'] = W grid.at_node['channel_depth'] = H grid.at_node['channel_discharge'] = node_Q grid.at_node['channel_bed_shear_stress'] = shear_stress grid.at_node[ 'fluvial_sediment_transport_capacity'] = transport_capacities grid.at_node['fluvial_sediment_flux_into_node'] = sed_into_node grid.at_node['relative_sediment_flux'] = rel_sed_flux #elevs set automatically to the name used in the function call. self.iterations_in_dt = counter return grid, grid.at_node[elev_name]
def _eval(self): '''Evaluate the integral based on the configuration of algorithm. ''' if self.cached_dG == False and self.compiled_QdG_loop == False: raise NotImplementedError( 'Configuration for pure Python integration is too slow and is not implemented' ) self._set_compiler() # prepare the array of the control variable discretization # eps_arr = self.eps_arr mu_q_arr = zeros((eps_arr.shape[0], ), dtype='float_') # prepare the parameters for the compiled function in # a separate dictionary c_params = {} if self.compiled_eps_loop: # for compiled eps_loop the whole input and output array must be passed to c # c_params['e_arr'] = eps_arr c_params['mu_q_arr'] = mu_q_arr #c_params['n_eps' ] = n_eps if self.compiled_QdG_loop: # prepare the lengths of the arrays to set the iteration bounds # for rv in self.rv_list: c_params['%s_flat' % rv.name] = rv.theta_arr if len(self.rv_list) > 0: if self.cached_dG: c_params['dG_grid'] = self.dG_grid else: for rv in self.rv_list: c_params['%s_pdf' % rv.name] = rv.dG_arr else: c_params['dG_grid'] = self.dG_grid if self.cached_dG: conv = converters.blitz else: conv = converters.default t = time.clock() if self.compiled_eps_loop: # C loop over eps, all inner loops must be compiled as well # inline(self.C_code, self.arg_list, local_dict=c_params, type_converters=conv, compiler=self.compiler, verbose=self.compiler_verbose) else: # Python loop over eps # for idx, e in enumerate(eps_arr): if self.compiled_QdG_loop: # C loop over random dimensions # c_params['e'] = e # prepare the parameter mu_q = inline(self.C_code, self.arg_list, local_dict=c_params, type_converters=conv, compiler=self.compiler, verbose=self.compiler_verbose) else: # Numpy loops over random dimensions # # get the rf grid for all combinations of # parameter values # Q_grid = self.rf(*e, **self.param_dict) # multiply the response grid with the contributions # of pdf distributions (weighted by the delta of the # random variable disretization) # Q_grid *= self.dG_grid # sum all the values to get the integral mu_q = sum(Q_grid) # add the value to the return array mu_q_arr[idx] = mu_q duration = time.clock() - t return mu_q_arr, duration
def subtransitionAndWeight(states, y, parameters, alluniforms1, allK1, alluniforms2, allK2): code = \ """ float tempmeasure1 = 0.; float zs1 = 0.; float vs1 = 0.; float zs2 = 0.; float vs2 = 0.; int currentk1 = 0; int currentk2 = 0; float exponentialscale = 0.; float sum11 = 0.; float sum21 = 0.; float sum12 = 0.; float sum22 = 0.; int k1 = 0; int k2 = 0; float auxiliaryE1 = 0.; float auxiliaryC1 = 0.; float auxiliaryE2 = 0.; float auxiliaryC2 = 0.; exponentialscale = parameters(3) / parameters(2); for(int indexk = 0; indexk < Nx; indexk ++){ sum11 = 0.; sum21 = 0.; k1 = allK1(indexk); for (int indexl = 0; indexl < k1; indexl ++){ auxiliaryE1 = - log(alluniforms1(currentk1)) * exponentialscale; auxiliaryC1 = alluniforms1(currentk1 + 1); currentk1 += 2; sum11 = sum11 + auxiliaryE1; sum21 = sum21 + auxiliaryE1 * exp(-parameters(4) * auxiliaryC1); } sum12 = 0.; sum22 = 0.; k2 = allK2(indexk); for (int indexl = 0; indexl < k2; indexl ++){ auxiliaryE2 = - log(alluniforms2(currentk2)) * exponentialscale; auxiliaryC2 = alluniforms2(currentk2 + 1); currentk2 += 2; sum12 = sum12 + auxiliaryE2; sum22 = sum22 + auxiliaryE2 * exp(-(parameters(4) + parameters(5)) * auxiliaryC2); } zs1 = exp(-parameters(4)) * states(indexk, 2) + sum21; vs1 = (1 / parameters(4)) * (states(indexk, 2) - zs1 + sum11); states(indexk, 1) = vs1; states(indexk, 2) = zs1; zs2 = exp(- (parameters(4) + parameters(5))) * states(indexk, 4) + sum22; vs2 = (1 / (parameters(4) + parameters(5))) * (states(indexk, 4) - zs2 + sum12); states(indexk, 3) = vs2; states(indexk, 4) = zs2; states(indexk, 0) = vs1 + vs2; tempmeasure1 = y(0) - (parameters(0) + parameters(1) * states(indexk, 0)); weights(indexk) = -0.9189385 - 0.5 * log(states(indexk, 0)) - 0.5 / states(indexk, 0) * (tempmeasure1 * tempmeasure1); } """ y = array([y]) Nx = states.shape[0] weights = zeros(Nx) weave.inline(code,['Nx', 'states', 'y', 'parameters', 'weights', 'alluniforms1', \ 'allK1', 'alluniforms2', 'allK2'], \ type_converters=weave.converters.blitz, libraries = ["m"]) return {"states": states, "weights": weights}
def fd_decompress(amp, phase, sample_frequencies, out=None, df=None, f_lower=None, interpolation='linear'): """Decompresses an FD waveform using the given amplitude, phase, and the frequencies at which they are sampled at. Parameters ---------- amp : array The amplitude of the waveform at the sample frequencies. phase : array The phase of the waveform at the sample frequencies. sample_frequencies : array The frequency (in Hz) of the waveform at the sample frequencies. out : {None, FrequencySeries} The output array to save the decompressed waveform to. If this contains slots for frequencies > the maximum frequency in sample_frequencies, the rest of the values are zeroed. If not provided, must provide a df. df : {None, float} The frequency step to use for the decompressed waveform. Must be provided if out is None. f_lower : {None, float} The frequency to start the decompression at. If None, will use whatever the lowest frequency is in sample_frequencies. All values at frequencies less than this will be 0 in the decompressed waveform. interpolation : {'linear', str} The interpolation to use for the amplitude and phase. Default is 'linear'. If 'linear' a custom interpolater is used. Otherwise, ``scipy.interpolate.interp1d`` is used; for other options, see possible values for that function's ``kind`` argument. Returns ------- out : FrqeuencySeries If out was provided, writes to that array. Otherwise, a new FrequencySeries with the decompressed waveform. """ precision = _precision_map[sample_frequencies.dtype.name] if _precision_map[amp.dtype.name] != precision or \ _precision_map[phase.dtype.name] != precision: raise ValueError("amp, phase, and sample_points must all have the " "same precision") if out is None: if df is None: raise ValueError("Either provide output memory or a df") hlen = int(numpy.ceil(sample_frequencies.max() / df + 1)) out = FrequencySeries(numpy.zeros(hlen, dtype=_complex_dtypes[precision]), copy=False, delta_f=df) else: # check for precision compatibility if out.precision == 'double' and precision == 'single': raise ValueError("cannot cast single precision to double") df = out.delta_f hlen = len(out) if f_lower is None: imin = 0 f_lower = sample_frequencies[0] else: if f_lower >= sample_frequencies.max(): raise ValueError("f_lower is > than the maximum sample frequency") imin = int(numpy.searchsorted(sample_frequencies, f_lower)) start_index = int(numpy.floor(f_lower / df)) # interpolate the amplitude and the phase if interpolation == "linear": if precision == 'single': code = _linear_decompress_code32 else: code = _linear_decompress_code # use custom interpolation sflen = len(sample_frequencies) h = numpy.array(out.data, copy=False) delta_f = float(df) inline(code, ['h', 'hlen', 'sflen', 'delta_f', 'sample_frequencies', 'amp', 'phase', 'start_index', 'imin'], extra_compile_args=[WEAVE_FLAGS + '-march=native -O3 -w'] +\ omp_flags, libraries=omp_libs) else: # use scipy for fancier interpolation outfreq = out.sample_frequencies.numpy() amp_interp = interpolate.interp1d(sample_frequencies.numpy(), amp.numpy(), kind=interpolation, bounds_error=False, fill_value=0., assume_sorted=True) phase_interp = interpolate.interp1d(sample_frequencies.numpy(), phase.numpy(), kind=interpolation, bounds_error=False, fill_value=0., assume_sorted=True) A = amp_interp(outfreq) phi = phase_interp(outfreq) out.data[:] = A * numpy.cos(phi) + (1j) * A * numpy.sin(phi) return out
def calculate_capacity(surface_displacement, capacity_parameters): """ Calculate the building capacity curve | ___________ | ___/ - flat region SA | _/ - exponential decay region | / | / - linear region | / |___________________ SD #Fixme - add unit information. """ # print "surface_displacement", surface_displacement Dy, Ay, Du, Au, a, b, c = capacity_parameters num_sites, num_events, num_periods = surface_displacement.shape assert surface_displacement.shape == (num_sites, num_events, num_periods) assert Dy.shape == Ay.shape == Du.shape == Au.shape == a.shape == b.shape == c.shape assert (Dy.shape == (num_sites, num_events, 1) ) or (Dy.shape == (num_sites, 1, 1)) capacity = zeros((num_sites, num_events, num_periods), dtype=float) # print 'surface_displacement',surface_displacement[0,0:5] # print Dy.shape # y1=(Ay/Dy)*surface_displacement # linear region # y2=a*exp(surface_displacement*-b)+c # exp region # y3=c; #constant part # b1=(surface_displacement<=Dy) # linear region # b2=((surface_displacement>Dy)&(surface_displacement<Du)) # exp region # b3=(surface_displacement>Du) # flat region # capacity=(b1*y1+b2*y2+b3*y3) code = """ double Dyy,Duu,Ayy,aa,bb,cc; double sd; for (int i=0; i<num_sites; ++i){ for (int j=0; j<num_events; ++j){ get_constants for (int k=0;k<num_periods;++k){ sd=surface_displacement(i,j,k); if (sd<=Dyy){ capacity(i,j,k)=(Ayy/Dyy)*sd; } else if ((sd>Dyy)&(sd<Duu)){ capacity(i,j,k)=aa*exp(sd*(-bb))+cc; } else{ capacity(i,j,k)=cc; } } } } return_val = 0; """ if (Dy.shape == (num_sites, num_events, 1)): Ay = Ay[:,:, 0] Dy = Dy[:,:, 0] Du = Du[:,:, 0] a = a[:,:, 0] b = b[:,:, 0] c = c[:,:, 0] code = code.replace('get_constants', 'aa=a(i,j);bb=b(i,j);cc=c(i,j);' + 'Duu=Du(i,j);Dyy=Dy(i,j);Ayy=Ay(i,j);') # print code try: weave.inline(code, ['num_sites', 'num_events', 'num_periods', 'surface_displacement', 'capacity', 'a', 'b', 'c', 'Du', 'Dy', 'Ay'], type_converters=weave_converters.eqrm, compiler='gcc') except IOError: raise WeaveIOError else: assert Dy.shape == (num_sites, 1, 1) Ay = Ay[:, 0, 0] Dy = Dy[:, 0, 0] Du = Du[:, 0, 0] a = a[:, 0, 0] b = b[:, 0, 0] c = c[:, 0, 0] code = code.replace('get_constants', 'aa=a(i);bb=b(i);cc=c(i);' + 'Duu=Du(i);Dyy=Dy(i);Ayy=Ay(i);') # print code try: weave.inline(code, ['num_sites', 'num_events', 'num_periods', 'surface_displacement', 'capacity', 'a', 'b', 'c', 'Du', 'Dy', 'Ay'], type_converters=weave_converters.eqrm, compiler='gcc') except IOError: raise WeaveIOError return capacity
def OU_generator_weave1(self, dt, tau, sigma, y0, t_start=0.0, t_stop=1000.0, time_it=False): """ Generates an Orstein Ulbeck process using the forward euler method. The function returns an AnalogSignal object. OU_generator_weave1, as opposed to OU_generator, uses scipy.weave and is thus much faster. Inputs: dt - the time resolution in milliseconds of th signal tau - the correlation time in milliseconds sigma - std dev of the process y0 - initial value of the process, at t_start t_start - start time in milliseconds t_stop - end time in milliseconds array - if True, the functions returns the tuple (y,t) where y and t are the OU signal and the time bins, respectively, and are both numpy arrays. Examples: >> stgen.OU_generator_weave1(0.1, 2, 3, 0, 0, 10000) See also: OU_generator """ try: import scipy.weave as weave except: import weave import time if time_it: t1 = time.time() t = numpy.arange(t_start, t_stop, dt) N = len(t) y = numpy.zeros(N, float) y[0] = y0 fac = dt / tau gauss = fac * y0 + numpy.sqrt( 2 * fac) * sigma * self.rng.standard_normal(N - 1) # python loop... bad+slow! #for i in xrange(1,len(t)): # y[i] = y[i-1]+dt/tau*(y0-y[i-1])+numpy.sqrt(2*dt/tau)*sigma*numpy.ran # dom.normal() # use weave instead code = """ double f = 1.0-fac; for(int i=1;i<Ny[0];i++) { y(i) = y(i-1)*f + gauss(i-1); } """ weave.inline(code, ['y', 'gauss', 'fac'], type_converters=weave.converters.blitz) if time_it: print('Elapsed ', time.time() - t1, ' seconds.') if array: return (y, t) else: raise NotImplementedError()
def transitionAndWeight(states, y, parameters, t): #here, the last argument t now becomes useful if t == 0: time = Time[ 0] - Time_start #the duration from last state to the current else: time = Time[t] - Time[t - 1] # Negative bin is too slow in the c code below, so approximate it by Gaussisan # code = \ # """ # int temp1; # int temp2; # double p; # int n; # for (int j = 0; j < Ntheta; j++) # { # for (int k = 0; k < Nx; k++) # { # states(k, 0, j) = states(k, 0, j) * exp( parameters(2, j) * (%(time)s) + parameters(1, j) * noise(k,j) ); # p = 1 / (1 + parameters(0, j) * states(k, 0, j)); # n = (int) states(k, 0, j) * p / (1-p); # temp1 = 1; # for (int i = 1; i <= y(0); i++) # { # temp1 = temp1 * (1-p) / i; # } # for (int i = 1; i <= n+y(0)-1; i++) # { # temp1 = temp1 * i; # } # for (int i = 1; i <= n-1; i++) # { # temp1 = temp1 * p / i; # } # temp1 = temp1 * p; # temp2 = 1; # for (int i = 1; i <= y(1); i++) # { # temp2 = temp2 * (1-p) / i; # } # for (int i = 1; i <= n+y(1)-1; i++) # { # temp2 = temp2 * i; # } # for (int i = 1; i <= n-1; i++) # { # temp2 = temp2 * p / i; # } # temp2 = temp2 * p; # weights(k, j) = temp1 * temp2; # } # } # double HScoreInferenceFlag = (double) %(HScoreInference)s; # if ( HScoreInferenceFlag > 0 ) # { # double tbd = 0; # } # """ % {"time": time, "HScoreInference": HScoreInference} #the inline code first sample states and udpate weights, then normalize the weights, # the code below uses Gaussian approx. # code = \ # """ # double R; # double loglik1; # double loglik2; # for (int j = 0; j < Ntheta; j++) # { # for (int k = 0; k < Nx; k++) # { # states(k, 0, j) = states(k, 0, j) * exp( parameters(1, j) * noise(k,j) ); # R = states(k, 0, j) + parameters(0, j) * states(k, 0, j) * states(k, 0, j); # loglik1 = -0.9189385 - 0.5 * log(R) - 0.5 / R * ((double) y(0) - states(k, 0, j)) * ((double) y(0) - states(k, 0, j)); # loglik2 = -0.9189385 - 0.5 * log(R) - 0.5 / R * ((double) y(1) - states(k, 0, j)) * ((double) y(1) - states(k, 0, j)); # weights(k, j) = loglik1 + loglik2; # } # } # double HScoreInferenceFlag = (double) %(HScoreInference)s; # if ( HScoreInferenceFlag > 0 ) # { # ; # } # """ % {"time": time, "HScoreInference": HScoreInference} # the code below uses negative bin likelihood code = \ """ for (int j = 0; j < Ntheta; j++) { for (int k = 0; k < Nx; k++) { states(k, 0, j) = states(k, 0, j) * exp( parameters(1, j) * noise(k,j) ); } } double HScoreInferenceFlag = (double) %(HScoreInference)s; if ( HScoreInferenceFlag > 0 ) { ; } """ % {"time": time, "HScoreInference": HScoreInference} dimY = y.shape[0] # if dimY == 1: # print '\n', dimY if dimY == 2: #make sure we are in inference, instead of synthetic-data generating y0 = int(y[0]) y1 = int(y[1]) # y = array([y]) #input to the c++ code must be array type Nx = states.shape[0] Dx = states.shape[1] #state dimension, which is M here Dparam = parameters.shape[0] #dimension of the postulated model/parameter Ntheta = states.shape[2] weights = zeros((Nx, Ntheta)) weightsNormalized = zeros( (Nx, Ntheta)) #normalized and exponentialed weights grad = zeros(Ntheta) lap = zeros(Ntheta) simpleHScore = zeros(Ntheta) noise = random.multivariate_normal(repeat(0, 1), [[time]], (Nx, Ntheta)) #dim: Nx x Ntheta x M weave.inline(code,['Nx', 'Ntheta', 'Dx', 'Dparam', 'states', 'y', 'parameters', 'noise', 'weights', \ 'simpleHScore', 'grad', 'lap', 'weightsNormalized', 'time'], \ type_converters=weave.converters.blitz, libraries = ["m"]) # print '\n' # print y[0][0] # print y[0] # for k in range(Nx): # p = 1 / (1 + parameters[0,:] * states[k,0,:]) # p = minimum(p, 1-1e-4) # n = maximum(1, floor(states[k,0,:] * p / (1-p)) ).astype(int32) # weights[k,:] = nbinom.logpmf(y0, n, p) + nbinom.logpmf(y1, n, p) if dimY == 2: #make sure we are in inference, instead of synthetic-data generating p = zeros((Nx, Ntheta)) n = zeros((Nx, Ntheta)) for k in range(Nx): p[k, :] = 1 / (1 + parameters[0, :] * states[k, 0, :]) p[k, :] = minimum(p[k, :], 1 - 1e-7) p[k, :] = maximum(p[k, :], 1e-7) #to prevent overflow states[k, 0, :] = minimum(states[k, 0, :], 1e7) #to prevent overflow n[k, :] = maximum(1, floor(states[k, 0, :] * p[k, :] / (1 - p[k, :]))).astype(int32) weights[...] = nbinom.logpmf(y0, n, p) + nbinom.logpmf(y1, n, p) return { "states": states, "weights": weights, "simpleHScore": simpleHScore } #the xweights are logged
def calculate_updated_demand(periods, SA0, SD0, Ra, Rv, Rd, TAV, TVD, csm_damping_use_smoothing=CSM_DAMPING_USE_SMOOTHING): """ update the demand, given original responses, damping factors, and corner periods. """ periods = periods[newaxis, newaxis, ...] TAV = TAV[:,:, newaxis] TVD = TVD[:,:, newaxis] assert len(periods.shape) == 3 assert len(TAV.shape) == 3 assert len(TVD.shape) == 3 # print 'SA0',SA0[:,0:5] # print 'SD0',SD0[:,0:5] # print 'TAV',TAV[:,0:5] # print 'TVD',TVD[:,0:5] num_sites, num_events, num_periods = SA0.shape assert TAV.shape == (num_sites, num_events, 1) assert TVD.shape == (1, num_events, 1) assert periods.shape == (1, 1, num_periods) TAV = TAV[:,:, 0] TVD = TVD[0,:, 0] periods = periods[0, 0] assert SA0.shape == (num_sites, num_events, num_periods) assert SD0.shape == (num_sites, num_events, num_periods) assert ((Ra.shape == (num_sites, num_events, 1) and Rv.shape == (num_sites, num_events, 1) and Rd.shape == (num_sites, num_events, 1)) or (Ra.shape == (1, 1, 1) and Rv.shape == (1, 1, 1) and Rd.shape == (1, 1, 1))) R = zeros((num_sites, num_events, num_periods), dtype=float) assert TAV.shape == (num_sites, num_events) assert TVD.shape == (num_events,) assert periods.shape == (num_periods,) code = """ double AV,VD; double p; for (int i=0; i<num_sites; ++i){ for (int j=0; j<num_events; ++j){ get_R AV=TAV(i,j); VD=TVD(j); for (int k=0;k<num_periods;++k){ p=periods(k); if (p<=AV){ R(i,j,k)=Raa; } else if (p<=VD){ R(i,j,k)=Rvv; } else{ R(i,j,k)=Rdd; } } } } return_val = 0; """ if Ra.shape == (1, 1, 1): assert Rv.shape == (1, 1, 1) assert Rd.shape == (1, 1, 1) code = code.replace('get_R', '') code = code.replace('Raa', 'Ra') code = code.replace('Rvv', 'Rv') code = code.replace('Rdd', 'Rd') Ra = float(Ra[0, 0, 0]) Rv = float(Rv[0, 0, 0]) Rd = float(Rd[0, 0, 0]) try: weave.inline(code, ['num_sites', 'num_events', 'num_periods', 'Ra', 'Rv', 'Rd', 'R', 'periods', 'TAV', 'TVD'], type_converters=weave_converters.eqrm, compiler='gcc') except IOError: raise WeaveIOError else: assert Ra.shape == (num_sites, num_events, 1) assert Rv.shape == (num_sites, num_events, 1) assert Rd.shape == (num_sites, num_events, 1) Ra = (Ra[:,:, 0]) Rv = (Rv[:,:, 0]) Rd = (Rd[:,:, 0]) code = code.replace('get_R', 'Raa=Ra(i,j,1);Rvv=Rv(i,j,1);Rdd=Rd(i,j,1);') code = 'double Raa,Rvv,Rdd;' + code try: weave.inline(code, ['num_sites', 'num_events', 'num_periods', 'Ra', 'Rv', 'Rd', 'R', 'periods', 'TAV', 'TVD'], type_converters=weave_converters.eqrm, compiler='gcc') except IOError: raise WeaveIOError if csm_damping_use_smoothing == CSM_DAMPING_USE_SMOOTHING: R[..., 1:-1] = 0.25 * R[..., 0:-2] + 0.5 * R[..., 1:-1] + 0.25 * R[..., 2:] SAnew = SA0 / R SDnew = SD0 / R return SAnew, SDnew
def lens_map(self, map, use_Pool=0, tidy=True, crude=0, do_not_prefilter=False): """ Lens the input map according to the displacement fields dx dy. 'map' typically could be (8192 * 8192) np array, or the path to the array on disk. Does this by splitting the job in chunks (of typically (256 * 256), as specified by the LD_res parameters) allowing a buffer size to ensure the junctions are properly performed. Set use_Pool to a power of two to use explicit threading via the multiprocessing module, or, if < 0, to perform the operation on the GPU. if > 0 'use_Pool' ** 2 is the number of threads. On laptop and Darwin use_Pool = 16 has the best performances. It use_Pool is set, then 'map' must be the path to the map to lens or map will be saved to disk. """ # TODO : could evaluate the splines at low res. assert self.load_map(map).shape == self.shape, (self.load_map(map).shape, self.shape) if crude > 0: return self.lens_map_crude(map, crude) if use_Pool < 0: # use of GPU : try: from lensit.gpu import lens_GPU except: assert 0, 'Import of mllens lens_GPU failed !' GPU_res = np.array(lens_GPU.GPU_HDres_max) if np.all(np.array(self.HD_res) <= GPU_res): return lens_GPU.lens_onGPU(map, self.get_dx_ingridunits(), self.get_dy_ingridunits(), do_not_prefilter=do_not_prefilter) LD_res, buffers = get_GPUbuffers(GPU_res) assert np.all(np.array(buffers) > (np.array(self.buffers) + 5.)), (buffers, self.buffers) Nchunks = 2 ** (np.sum(np.array(self.HD_res) - np.array(LD_res))) lensed_map = np.empty(self.shape) # Output dx_N = np.empty((2 ** LD_res[0] + 2 * buffers[0], 2 ** LD_res[1] + 2 * buffers[1])) dy_N = np.empty((2 ** LD_res[0] + 2 * buffers[0], 2 ** LD_res[1] + 2 * buffers[1])) unl_CMBN = np.empty((2 ** LD_res[0] + 2 * buffers[0], 2 ** LD_res[1] + 2 * buffers[1])) if self.verbose: print '++ lensing map :' \ ' splitting map on GPU , chunk shape %s, buffers %s' % (dx_N.shape, buffers) spliter_lib = map_spliter.periodicmap_spliter() # library to split periodic maps. for N in xrange(Nchunks): sLDs, sHDs = spliter_lib.get_slices_chk_N(N, LD_res, self.HD_res, buffers) for sLD, sHD in zip(sLDs, sHDs): dx_N[sLD] = self.get_dx()[sHD] / self.rmin[1] dy_N[sLD] = self.get_dy()[sHD] / self.rmin[0] unl_CMBN[sLD] = self.load_map(map)[sHD] sLDs, sHDs = spliter_lib.get_slices_chk_N(N, LD_res, self.HD_res, buffers, inverse=True) lensed_map[sHDs[0]] = lens_GPU.lens_onGPU(unl_CMBN, dx_N, dy_N, do_not_prefilter=do_not_prefilter)[ sLDs[0]] return lensed_map elif use_Pool > 100: if not isinstance(map, str): assert self.has_lib_dir(), "Specify lib. dir. if you want to use Pool." np.save(self.lib_dir + '/temp_maptolens_rank%s.npy' % pbs.rank, map) if not self.is_dxdy_ondisk(): assert self.has_lib_dir(), "Specify lib. dir. if you want to use Pool." print "lens_map::writing displacements on disk :" self.write_npy(self.lib_dir + '/temp_displ' + str(pbs.rank)) # this turns dx and dy to the paths path_to_map = map if isinstance(map, str) else self.lib_dir + '/temp_maptolens_rank%s.npy' % pbs.rank ret = ffs_pool.get_lens_Pooled(self.mk_args(path_to_map, self.dx, self.dy), root_Nthreads=use_Pool % 100, do_not_prefilter=do_not_prefilter) if tidy: if os.path.exists(self.lib_dir + '/temp_maptolens_rank%s.npy' % pbs.rank): os.remove(self.lib_dir + '/temp_maptolens_rank%s.npy' % pbs.rank) return ret elif use_Pool == 100 or use_Pool == 101: assert self.load_map(map).shape == self.shape, self.load_map(map).shape s = self.chk_shape idc0, idc1 = np.indices(s) # Two (256 * 256) maps dx_gu = np.empty(s) # will dx displ. in grid units of each chunk (typ. (256 * 256) ) dy_gu = np.empty(s) # will dy displ. in grid units of each chunk (typ. (256 * 256) ) map_chk = np.empty(s) # Will be map chunk # (typ. (256 * 256) ) lensed_map = np.empty(self.shape) spliter_lib = map_spliter.periodicmap_spliter() # library to split periodic maps. for N in xrange(self.N_chks): # doing chunk N sLDs, sHDs = spliter_lib.get_slices_chk_N(N, self.LD_res, self.HD_res, self.buffers) for sLD, sHD in zip(sLDs, sHDs): # Displacements chunk in grid units, and map chunk to displace. dx_gu[sLD] = self.get_dx()[sHD] / self.rmin[1] dy_gu[sLD] = self.get_dy()[sHD] / self.rmin[0] map_chk[sLD] = self.load_map(map)[sHD] if do_not_prefilter: # Undoing the prefiltering prior to apply bicubic interpolation map_chk = np.fft.rfft2(map_chk) w0 = 6. / (2. * np.cos(2. * np.pi * np.fft.fftfreq(s[0])) + 4.) map_chk /= np.outer(w0, w0[0:map_chk.shape[1]]) map_chk = np.fft.irfft2(map_chk, s) lx = (idc1 + dx_gu).flatten() # No need to enforce periodicity here. ly = (idc0 + dy_gu).flatten() # No need to enforce periodicity here. sLDs, sHDs = spliter_lib.get_slices_chk_N(N, self.LD_res, self.HD_res, self.buffers, inverse=True) lensed_map[sHDs[0]] = interpolate.RectBivariateSpline(np.arange(s[0]), np.arange(s[1]), map_chk, kx=self.k, ky=self.k).ev(ly, lx).reshape( self.chk_shape)[sLDs[0]] return lensed_map elif use_Pool == 0 or use_Pool == 1: assert self.shape[0] == self.shape[1], self.shape bicubicspline = r"\ int i,j;\ for( j= 0; j < width; j++ )\ {\ for( i = 0; i < width; i++)\ {\ lenmap[j * width + i] = bicubiclensKernel(filtmap,i + dx_gu[j * width + i],j + dy_gu[j * width + i],width);\ }\ }" header = r' "%s/lensit/gpu/bicubicspline.h" ' % li.LENSITDIR if do_not_prefilter: filtmap = self.load_map(map).astype(np.float64) else: # TODO : may want to add pyFFTW here as well filtmap = np.fft.rfft2(self.load_map(map)) w0 = 6. / (2. * np.cos(2. * np.pi * np.fft.fftfreq(filtmap.shape[0])) + 4.) filtmap *= np.outer(w0, w0[0:filtmap.shape[1]]) filtmap = np.fft.irfft2(filtmap, self.shape) lenmap = np.empty(self.shape, dtype=np.float64) dx_gu = self.get_dx_ingridunits().astype(np.float64) dy_gu = self.get_dy_ingridunits().astype(np.float64) width = int(self.shape[0]) assert self.shape[0] == self.shape[1] weave.inline(bicubicspline, ['lenmap', 'filtmap', 'dx_gu', 'dy_gu', 'width'], headers=[header]) return lenmap elif use_Pool > 1 and use_Pool < 100: # TODO : may want to add pyFFTW here as well if not isinstance(map, str): assert self.has_lib_dir(), "Specify lib. dir. if you want to use Pool." np.save(self.lib_dir + '/temp_maptolens_rank%s.npy' % pbs.rank, map) if not self.is_dxdy_ondisk(): assert self.has_lib_dir(), "Specify lib. dir. if you want to use Pool." print "lens_map::writing displacements on disk :" self.write_npy(self.lib_dir + '/temp_displ' + str(pbs.rank)) # this turns dx and dy to the paths path_to_map = map if isinstance(map, str) else self.lib_dir + '/temp_maptolens_rank%s.npy' % pbs.rank ret = ffs_pool.get_lens_Pooled_weave(self.mk_args(path_to_map, self.dx, self.dy), root_Nthreads=use_Pool, do_not_prefilter=do_not_prefilter) if tidy: if os.path.exists(self.lib_dir + '/temp_maptolens_rank%s.npy' % pbs.rank): os.remove(self.lib_dir + '/temp_maptolens_rank%s.npy' % pbs.rank) return ret else: assert 0
def nextFrame(self): # If first call initialise data structures... if self.output == None: self.output = numpy.empty((self.height(), self.width()), dtype=numpy.int32) self.vote = numpy.empty((self.height(), self.width(), 6), dtype=numpy.int32) # Get the inputs... flow = self.flow.fetch(self.flowChannel) mask = self.mask.fetch(self.maskChannel) # Do the work... code = start_cpp() + """ // Zero the vote array - first 5 entrys map to the words, 6th entry is the vote for 'no-word'... for (int y=0;y<Nvote[0];y++) { for (int x=0;x<Nvote[1];x++) { for (int c=0;c<Nvote[2];c++) VOTE3(y,x,c) = 0; } } // Iterate the pixels, make them each cast a vote... for (int y=0;y<Nflow[0];y++) { for (int x=0;x<Nflow[1];x++) { int vy = y / gridSize; int vx = x / gridSize; if (MASK2(y,x)!=0) { float speed = sqrt(FLOW3(y,x,0)*FLOW3(y,x,0) + FLOW3(y,x,1)*FLOW3(y,x,1)); if (speed<threshold) VOTE3(vy,vx,0) += 1; else { if (fabs(FLOW3(y,x,0))>fabs(FLOW3(y,x,1))) { // dy is greater than dx... if (FLOW3(y,x,0)>0.0) VOTE3(vy,vx,2) += 1; else VOTE3(vy,vx,4) += 1; } else { // dx is greater than dy... if (FLOW3(y,x,1)>0.0) VOTE3(vy,vx,1) += 1; else VOTE3(vy,vx,3) += 1; } } } else VOTE3(vy,vx,5) += 1; } } // Count the votes, declare the winners... for (int y=0;y<Nvote[0];y++) { for (int x=0;x<Nvote[1];x++) { int maxIndex = 0; for (int c=1;c<Nvote[2];c++) { if (VOTE3(y,x,c)>VOTE3(y,x,maxIndex)) maxIndex = c; } if (maxIndex==5) maxIndex = -1; OUTPUT2(y,x) = maxIndex; } } """ output = self.output vote = self.vote threshold = self.threshold gridSize = self.gridSize weave.inline( code, ['flow', 'mask', 'output', 'vote', 'threshold', 'gridSize']) return True
def linear_itpl(p, gpval, pout, do_exp=False): """ this function is used to interpolate complicated species Arguments: p: logp values gpval: gp values at given Ps pout: the location where the values will interpolated to do_exp: if True, the extrapolation will be done Returns: yout, [p1, p2, wgt]: the gpval at pout, and its locations """ out_shape = shape(pout) # print 'shape p' # print shape(p) # print shape(pout) wgt = zeros(out_shape, float) outval = zeros(out_shape, float) nxp = size(p) nyp = size(wgt) pr = zeros(out_shape, int) pl = zeros(out_shape, int) gp = gpval x = p xout = pout # print nxp, nyp c_code = """ int i, j,l; j=0; for (i=0; i<nyp; ++i){ for (l=j; l<nxp;++l) { if (x[l]>=xout[i]) break; } if (l==0){ wgt[i]=1.0; pl[i]=0; pr[i]=0; outval[i]=gp[l]; } else if (l>=nxp){ wgt[i]=1.0; pl[i]=nxp-1; pr[i]=nxp-1; outval[i]=gp[nxp-1]; } else { pl[i]=l-1; pr[i]=l; wgt[i]=(x[l]-xout[i])/(x[l]-x[l-1]); outval[i]=wgt[i]*gp[l-1]+(1.0-wgt[i])*gp[l]; } j=l; } return_val=0; """ axgp=weave.inline(c_code,\ ['nxp', 'nyp', 'x', 'xout', 'gp', 'outval', 'pl', 'pr', 'wgt']) return outval, [pl, pr, wgt]
def get_inverse_chk_N(self, N, NR_iter=None): """ Returns inverse displacement in chunk N Uses periodic boundary conditions, which is not applicable to chunks, thus there will be boudary effects on the edges (2 or 4 pixels depending on the rule). Make sure the buffer is large enough. """ if NR_iter is None: NR_iter = self.NR_iter # Inverse magn. elements. (with a minus sign) We may need to spline these later for further NR iterations : extra_buff = np.array((5, 5)) * ( np.array(self.chk_shape) != np.array(self.shape)) # To avoid surprises with the periodic derivatives dx = np.zeros(self.chk_shape + 2 * extra_buff) # will dx displ. in grid units of each chunk (typ. (256 * 256) ) dy = np.zeros(self.chk_shape + 2 * extra_buff) # will dy displ. in grid units of each chunk (typ. (256 * 256) ) sLDs, sHDs = map_spliter.periodicmap_spliter().get_slices_chk_N(N, self.LD_res, self.HD_res, (self.buffers[0] + extra_buff[0], self.buffers[1] + extra_buff[1])) rmin0 = self.lsides[0] / self.shape[0] rmin1 = self.lsides[1] / self.shape[1] for sLD, sHD in zip(sLDs, sHDs): dx[sLD] = self.get_dx()[sHD] / rmin1 # Need grid units displacement for the bicubic spline dy[sLD] = self.get_dy()[sHD] / rmin0 # Jacobian matrix of the chunk : sl0 = slice(extra_buff[0], dx.shape[0] - extra_buff[0]) sl1 = slice(extra_buff[1], dx.shape[1] - extra_buff[1]) Minv_yy = - (PDP(dx, axis=1)[sl0, sl1] + 1.) Minv_xx = - (PDP(dy, axis=0)[sl0, sl1] + 1.) Minv_xy = PDP(dy, axis=1)[sl0, sl1] Minv_yx = PDP(dx, axis=0)[sl0, sl1] dx = dx[sl0, sl1] dy = dy[sl0, sl1] det = Minv_yy * Minv_xx - Minv_xy * Minv_yx if not np.all(det > 0.): print "ffs_displ::Negative value in det k : something's weird, you'd better check that" # Inverse magn. elements. (with a minus sign) We may need to spline these later for further NR iterations : Minv_xx /= det Minv_yy /= det Minv_xy /= det Minv_yx /= det del det ex = (Minv_xx * dx + Minv_xy * dy) ey = (Minv_yx * dx + Minv_yy * dy) if NR_iter == 0: return ex * rmin1, ey * rmin0 # Setting up a bunch of splines to interpolate the increment to the displacement according to Newton-Raphson. # Needed are splines of the forward displacement and of the (inverse, as implemented here) magnification matrix. # Hopefully the map resolution is enough to spline the magnification matrix. s0, s1 = self.chk_shape r0 = s0 r1 = s1 / 2 + 1 # rfft shape w0 = 6. / (2. * np.cos(2. * np.pi * Freq(np.arange(r0), s0) / s0) + 4.) w1 = 6. / (2. * np.cos(2. * np.pi * Freq(np.arange(r1), s1) / s1) + 4.) # FIXME: switch to pyfftw : bic_filter = lambda _map: np.fft.irfft2(np.fft.rfft2(_map) * np.outer(w0, w1)) dx = bic_filter(dx) dy = bic_filter(dy) Minv_xy = bic_filter(Minv_xy) Minv_yx = bic_filter(Minv_yx) Minv_xx = bic_filter(Minv_xx) Minv_yy = bic_filter(Minv_yy) header = r' "%s/lensit/gpu/bicubicspline.h" ' % li.LENSITDIR iterate = r"\ double fx,fy;\ double ex_len_dx,ey_len_dy,len_Mxx,len_Mxy,len_Myx,len_Myy;\ int i = 0;\ for(int y= 0; y < width; y++ )\ {\ for(int x = 0; x < width; x++,i++)\ {\ fx = x + ex[i];\ fy = y + ey[i];\ ex_len_dx = ex[i] + bicubiclensKernel(dx,fx,fy,width);\ ey_len_dy = ey[i] + bicubiclensKernel(dy,fx,fy,width);\ len_Mxx = bicubiclensKernel(Minv_xx,fx,fy,width);\ len_Myy = bicubiclensKernel(Minv_yy,fx,fy,width);\ len_Mxy = bicubiclensKernel(Minv_xy,fx,fy,width);\ len_Myx = bicubiclensKernel(Minv_yx,fx,fy,width);\ ex[i] += len_Mxx * ex_len_dx + len_Mxy * ey_len_dy;\ ey[i] += len_Myx * ex_len_dx + len_Myy * ey_len_dy;\ }\ }\ " width = int(s0) assert s0 == s1, 'Havent checked how this works with rectangular maps' for i in range(0, NR_iter): weave.inline(iterate, ['ex', 'ey', 'dx', 'dy', 'Minv_xx', 'Minv_yy', 'Minv_xy', 'Minv_yx', 'width'], headers=[header]) return ex * rmin1, ey * rmin0
def exponentialFiltering_ref(self, V, spks_ind, theta_tau) : """ Auxiliary function used to compute the matrix Y used in maximum likelihood. This function compute a set of integrals: theta_i(t) = \int_0^T 1\tau_theta exp(-s/tau_theta) g_j{ V(t-s) }ds After each spike in spks_ind theta_i(t) is reset to 0 mV and the integration restarts. The function returns a matrix where each line is given by theta_i(t). Input parameters: - V : numpy array containing the voltage trace (in mV) - spks_ind : list of spike times in ms (used to reset) - theta_tau : ms, timescale used in the intergration. """ # Input parameters p_T = len(V) p_dt = self.dt p_Tref = self.Tref # Model parameters definin threshold coupling p_theta_tau = theta_tau p_theta_bins = self.theta_bins p_theta_bins = p_theta_bins.astype("double") # Define arrays V = np.array(V, dtype="double") R = len(self.theta_bins)-1 # subthreshold coupling theta theta = np.zeros((p_T,R)) theta = theta.astype("double") spks = np.array(spks_ind, dtype='double') p_spks_L = len(spks) code = """ #include <math.h> int T_ind = int(p_T); float dt = float(p_dt); int Tref_ind = int(float(p_Tref)/dt); float theta_tau = float(p_theta_tau); float theta_taufactor = (1.0-dt/theta_tau); int spks_L = int(p_spks_L); int spks_cnt = 0; int next_spike = int(spks(0)); for (int t=0; t<T_ind-1; t++) { // INTEGRATION THRESHOLD DYNAMICS for (int r=0; r<R; r++) { theta(t+1,r) = theta_taufactor*theta(t,r); // everybody decay if ( V(t) >= p_theta_bins(r) && V(t) < p_theta_bins(r+1) ) { // identify who integrates theta(t+1,r) += dt/theta_tau; } } // MANAGE RESET if ( t+1 >= next_spike ) { if(spks_cnt < spks_L) { spks_cnt += 1; next_spike = int(spks(spks_cnt)); } else { next_spike = T_ind+1; } if ( t + Tref_ind < T_ind-1 ) { for (int r=0; r<R; r++) theta(t + Tref_ind ,r) = 0.0; // reset } t = t + Tref_ind; } } """ vars = [ 'spks', 'p_spks_L', 'theta', 'R', 'p_theta_tau', 'p_theta_bins', 'p_T','p_dt','p_Tref','V' ] v = weave.inline(code, vars, type_converters=converters.blitz) return theta
def getpos(self, val): """ get boundary for given value(s) Auguments: values Return: pl, pr: left and right position of the value(s): Notes: if (val>max) the boundary is set to right-most if (val<min) the boundary is set to left most it maybe is quicker than checkpos for one array """ use_c = False sgl_val = False aval = array(val) tmp_sh = shape(aval) if (len(tmp_sh) == 0): # then we choose to return as single value instead of array sgl_val = True if (use_c): x = self.ax_grd nxp = size(x) if (sgl_val): nyp = 1 xout = array([aval]) else: nyp = size(aval) xout = aval pl = zeros(nyp) pr = zeros(nyp) c_code = """ int i, j,l; j=0; for (i=0; i<nyp; ++i){ for (l=0; l<nxp;++l) { if (x[l]>=xout[i]) break; } if (l==0){ pl[i]=0; pr[i]=0; } else if (l>=nxp){ pl[i]=nxp-1; pr[i]=nxp-1; } else { pl[i]=l-1; pr[i]=l; } j=0; } return_val=0; """ axgp=weave.inline(c_code,\ ['nxp', 'nyp', 'x','xout', 'pl', 'pr']) lp = pl.astype(int) rp = pr.astype(int) # print max(rp), nyp else: rp = searchsorted(self.ax_grd, aval) if (sgl_val): if (rp == 0): lp = 0 elif (rp == self.np): rp = rp - 1 lp = rp else: lp = rp - 1 else: lp = where(rp == 0, 0, rp - 1) lp = where(lp == self.np, self.np - 1, lp) rp = where(rp == self.np, self.np - 1, rp) return lp, rp
def simulate(self, I, V0): """ Simulate the spiking response of the GIF model to an input current I (nA) with time step dt. V0 (mV) indicate the initial condition V(0)=V0. The function returns: - time : ms, support for V, eta_sum, V_T, spks - V : mV, membrane potential - eta_sum : nA, adaptation current - V_T : mV, firing threshold - spks : ms, list of spike times """ # Input parameters p_T = len(I) p_dt = self.dt # Model parameters p_gl = self.gl p_C = self.C p_El = self.El p_Vr = self.Vr p_Tref = self.Tref p_Vt_star = self.Vt_star p_DV = self.DV p_lambda0 = self.lambda0 # Model parameters definin threshold coupling p_theta_tau = self.theta_tau p_theta_bins = self.theta_bins p_theta_bins = p_theta_bins.astype("double") p_theta_i = self.theta_i p_theta_i = p_theta_i.astype("double") # Model kernels (p_eta_support, p_eta) = self.eta.getInterpolatedFilter(self.dt) p_eta = p_eta.astype('double') p_eta_l = len(p_eta) (p_gamma_support, p_gamma) = self.gamma.getInterpolatedFilter(self.dt) p_gamma = p_gamma.astype('double') p_gamma_l = len(p_gamma) # Define arrays V = np.array(np.zeros(p_T), dtype="double") I = np.array(I, dtype="double") theta_trace = np.array(np.zeros(p_T), dtype="double") R = len(self.theta_bins)-1 # subthreshold coupling theta theta = np.zeros((p_T,R)) theta = theta.astype("double") spks = np.array(np.zeros(p_T), dtype="double") eta_sum = np.array(np.zeros(p_T + 2*p_eta_l), dtype="double") gamma_sum = np.array(np.zeros(p_T + 2*p_gamma_l), dtype="double") # Set initial condition V[0] = V0 code = """ #include <math.h> int T_ind = int(p_T); float dt = float(p_dt); float gl = float(p_gl); float C = float(p_C); float El = float(p_El); float Vr = float(p_Vr); int Tref_ind = int(float(p_Tref)/dt); float Vt_star = float(p_Vt_star); float DeltaV = float(p_DV); float lambda0 = float(p_lambda0); float theta_tau = float(p_theta_tau); int eta_l = int(p_eta_l); int gamma_l = int(p_gamma_l); float rand_max = float(RAND_MAX); float p_dontspike = 0.0 ; float lambda = 0.0 ; float rr = 0.0; float theta_taufactor = (1.0-dt/theta_tau); for (int t=0; t<T_ind-1; t++) { // INTEGRATE VOLTAGE V[t+1] = V[t] + dt/C*( -gl*(V[t] - El) + I[t] - eta_sum[t] ); // INTEGRATION THRESHOLD DYNAMICS ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// for (int r=0; r<R; r++) { theta[t+1,r] = theta_taufactor*theta[t,r]; // everybody decay if ( V[t] >= p_theta_bins[r] && V[t] < p_theta_bins[r+1] ) { // identify who integrates theta[t+1,r] += dt/theta_tau; } } float theta_tot = 0.0; for (int r=0; r<R; r++) { theta_tot += p_theta_i[r]*theta[t+1,r]; } theta_trace[t+1] = theta_tot; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // COMPUTE PROBABILITY OF EMITTING ACTION POTENTIAL lambda = lambda0*exp( (V[t+1]-Vt_star-gamma_sum[t+1]-theta_trace[t+1])/DeltaV ); p_dontspike = exp(-lambda*(dt/1000.0)); // since lambda0 is in Hz, dt must also be in Hz (this is why dt/1000.0) // PRODUCE SPIKE STOCHASTICALLY rr = rand()/rand_max; if (rr > p_dontspike) { if (t+1 < T_ind-1) spks[t+1] = 1.0; t = t + Tref_ind; if (t+1 < T_ind-1){ V[t+1] = Vr; for (int r=0; r<R; r++) theta[t+1,r] = 0.0; } // UPDATE ADAPTATION PROCESSES for(int j=0; j<eta_l; j++) eta_sum[t+1+j] += p_eta[j]; for(int j=0; j<gamma_l; j++) gamma_sum[t+1+j] += p_gamma[j] ; } } """ vars = [ 'theta_trace', 'theta', 'R', 'p_theta_tau', 'p_theta_bins', 'p_theta_i', 'p_T','p_dt','p_gl','p_C','p_El','p_Vr','p_Tref','p_Vt_star','p_DV','p_lambda0','V','I','p_eta','p_eta_l','eta_sum','p_gamma','gamma_sum','p_gamma_l','spks' ] v = weave.inline(code, vars) time = np.arange(p_T)*self.dt eta_sum = eta_sum[:p_T] V_T = gamma_sum[:p_T] + p_Vt_star + theta_trace[:p_T] spks = (np.where(spks==1)[0])*self.dt return (time, V, eta_sum, V_T, spks)
def resize_cdef_arr(): """Demos in weave.inline how to allocate a numpy array directly in C, fill it up with values, and then dynamically resize it if it's full, allowing you to continue adding values indefinitely. I can't get resizing to work if the array was originally declared in Python""" #a = np.empty((np.random.randint(50, 150), 2), dtype=np.int64) leninc = np.random.randint(50, 150) # inc arr len this much each time code = r""" #line 53 "weave_example.py" int nd = 2; // num dimensions npy_intp dimsarr[nd]; dimsarr[0] = leninc; // nrows dimsarr[1] = 2; // ncols PyArrayObject *a; a = (PyArrayObject *) PyArray_SimpleNew(nd, dimsarr, NPY_LONGLONG); PyArray_Dims dims; int counter = 0; dims.len = nd; dims.ptr = dimsarr; PyObject *dummy; printf("a started with length %d\n", PyArray_DIM(a, 0)); for (int i=0; i<1000; i++) { if (i == PyArray_DIM(a, 0)) { // resize to prevent going out of bounds dims.ptr[0] += leninc; dummy = PyArray_Resize(a, &dims, 0, NPY_ANYORDER); if (dummy == NULL) { PyErr_Format(PyExc_TypeError, "can't resize a"); return NULL; } // don't need dummy anymore I guess, see // http://www.mail-archive.com/[email protected]/msg13013.html Py_DECREF(dummy); printf("a is now %d long\n", dims.ptr[0]); } // get pointer to i,jth entry in data, typecast appropriately, // then dereference the whole thing so you can assign // a value to it. Using PyArray_GETPTR2 macro is easier than // manually doing pointer math using strides *((long long *) PyArray_GETPTR2(a, i, 0)) = i; // assign to ith row, col 0 *((long long *) PyArray_GETPTR2(a, i, 1)) = 2*i; // assign to ith row, col 1 counter++; } // resize once more to reduce a down to just those values // that were added to it dims.ptr[0] = counter; dummy = PyArray_Resize(a, &dims, 0, NPY_ANYORDER); if (dummy == NULL) { PyErr_Format(PyExc_TypeError, "can't resize a"); return NULL; } Py_DECREF(dummy); printf("a is now %d long\n", dims.ptr[0]); //return_val = Na[0]; //return_val = (PyObject *) a; // these two both return_val = PyArray_Return(a); // seem to work """ a = weave.inline(code, ['leninc'], compiler='gcc') return a