- Timestamp:
- Sep 11, 2016, 8:23:07 PM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/tools/generic_tools.py
r1094 r1096 47 47 # ijlonlat: Function to provide the imin,jmin imax,jmax of a lon,lat box 48 48 # incomming_flow: Function to determine if a fgrid-flow inflows to the central grid point 49 # index_flatten_mat: Function to provide the matrix coordinates of an index from its flatten version 49 50 # index_mat_way: Function to look for a value within a matrix following a direction 50 51 # index_mat: Function to provide the coordinates of a given value inside a matrix … … 56 57 # num_chainSnum: Function to pass a value to a `ChainStrNum' number 57 58 # num_split: Function to split a string at each numeric value keeping the number as the last character of each cut 59 # oper_submatrix: Function to perform an operation of a given matrix along a sub-set of values along its dimensions 58 60 # printing_dictionary: Function to print the content of a dictionary 59 61 # PolyArea: Function to compute the area of the polygon following 'Shoelace formula' 60 62 # radius_angle: Function to generate a matrix with the angle at a given point 61 63 # radius_dist: Function to generate a matrix with the distance at a given point 64 # same_shape: Function to check if two matrices have the same shape 62 65 # search_sec_list: Function to provide the values and indices on a list which matches a section of a string 63 66 # significant_decomposition: Function to decompose a given number by its signifcant potencies … … 8599 8602 return tB 8600 8603 8604 def same_shape(mat1,mat2): 8605 """ Function to check if two matrices have the same shape 8606 mat1,2= matrices to check 8607 """ 8608 fname = 'same_shape' 8609 8610 shape1 = mat1.shape 8611 shape2 = mat2.shape 8612 8613 Ndims1 = len(shape1) 8614 Ndims2 = len(shape2) 8615 8616 if Ndims1 != Ndims2: 8617 print errormsg 8618 print ' ' + fname + ': mat1 and mat2 have different number of dimensions !!' 8619 print ' Ndims mat 1:', Ndims1,' Ndims mat2:', Ndims2 8620 quit(-1) 8621 8622 for idn in range(Ndims1): 8623 if shape1[idn] != shape2[idn]: 8624 print errormsg 8625 print ' ' +fname+ ': length of',idn,'diemsion in mat1 and mat2 differ !!' 8626 print ' Length mat 1:', shape1[idn],' Length mat2:', shape2[idn] 8627 quit(-1) 8628 8629 return 8630 8631 def index_flatten_mat(index,Ldims): 8632 """ Function to provide the matrix coordinates of an index from its flatten version 8633 index= index of the matrix's flatten version 8634 Ldims= lengths of the dimensions of the matrix 8635 >>> index_flatten_mat(17,[3,3,3]) 8636 [1 2 2] 8637 """ 8638 fname = 'index_flatten_mat' 8639 Ndims = len(Ldims) 8640 8641 if index < Ldims[Ndims-1]: 8642 indices = np.zeros((len(Ldims)), dtype=int) 8643 indices[Ndims-1] = index 8644 else: 8645 for idn in range(1,Ndims): 8646 indices = np.zeros((len(Ldims)), dtype=int) 8647 subsize = int(np.prod(Ldims[Ndims-idn-1:Ndims])) 8648 # Reaching depth level in the matrix 8649 if subsize > idn: 8650 # Getting index for each dimension from the depth 8651 prevsubsizeind = index 8652 for idnd in range(Ndims-idn, Ndims): 8653 prevsubsize = int(np.prod(Ldims[idnd:Ndims])) 8654 Nprevsubsize = int(prevsubsizeind/prevsubsize) 8655 indices[idnd-1] = Nprevsubsize 8656 prevsubsizeind = prevsubsizeind - Nprevsubsize*prevsubsize 8657 # Final index 8658 indices[Ndims-1] = prevsubsizeind 8659 8660 return indices 8661 8662 def oper_submatrix(mat,dimns,submatval,oper,opdims): 8663 """ Function to perform an operation of a given matrix along a sub-set of values along its dimensions 8664 mat= matrix with values 8665 dimns= names of the matrix dimensions 8666 submatval= matrix value to use with some dimensions reduced 8667 oper= operation to perform 8668 'sumc', add [val] 8669 'subc', substraction [val] 8670 'mulc', multiply by [val] 8671 'divc', divide by [val] 8672 'lowthres',[val]: modify all values below [val] to submatval 8673 'upthres',[val]: modify all values above [val] to submatval 8674 opdims= dimensions of the operation 8675 >>> mat = np.arange(12).reshape(3,2,2) 8676 >>> dimsn = ['time', 'lon', 'lat'] 8677 >>> oper_submatrix(mat, dimsn, np.matrix([[1., 1.],[2., 2.]]), 'sumc', ['time']) 8678 [[[ 1 2] 8679 [ 4 5]] 8680 8681 [[ 5 6] 8682 [ 8 9]] 8683 8684 [[ 9 10] 8685 [12 13]] 8686 """ 8687 fname = 'dimoper_matrix' 8688 8689 operations = ['sumc', 'subc', 'mulc', 'divc', 'lowthres', 'upthres'] 8690 matype = mat.dtype 8691 8692 if oper.find(',') != -1: 8693 opern = oper.split(',')[0] 8694 val = retype(oper.split(',')[1], matype) 8695 else: 8696 opern = oper 8697 8698 Ndims = len(dimns) 8699 # Getting the slice, on '-1', dimension to operate along 8700 # Keeping in 'ldimuse': length of the dimensions of the values to use 8701 # Keeping in 'ldimop': length of the dimension to operate along 8702 idim = 0 8703 ldimuse = [] 8704 ldimop = [] 8705 slicevals = [] 8706 for dimn in dimns: 8707 for dn in opdims: 8708 if dimn == dn: 8709 slicevals.append(-1) 8710 ldimop.append(mat.shape[idim]) 8711 else: 8712 slicevals.append(mat.shape[idim]) 8713 ldimuse.append(mat.shape[idim]) 8714 idim = idim + 1 8715 8716 Ndop = len(opdims) 8717 Ntotdims = np.prod(ldimop) 8718 8719 # Checking for coincidence in shapes 8720 try: 8721 with Capturing() as output: 8722 same_shape(submatval,np.zeros(ldimuse)) 8723 except: 8724 print errormsg 8725 print ' ' + fname + ': shape of matrix to use and shape of values to ' + \ 8726 'operate differ!!' 8727 for sout in output: print sout 8728 quit(-1) 8729 8730 # Operation 8731 newmat = np.zeros(tuple(mat.shape), dtype=mat.dtype) 8732 for ijk in range(Ntotdims): 8733 ijkop = -1 8734 opslice = [] 8735 idcalc = index_flatten_mat(ijk,ldimop) 8736 for idn in range(Ndims): 8737 if slicevals[idn] == -1: 8738 ijkop = ijkop + 1 8739 opslice.append(idcalc[ijkop]) 8740 else: 8741 opslice.append(slice(0,slicevals[idn])) 8742 8743 if opern == 'sumc': 8744 newmat[tuple(opslice)] = mat[tuple(opslice)] + submatval 8745 elif opern == 'subc': 8746 newmat[tuple(opslice)] = mat[tuple(opslice)] - submatval 8747 elif opern == 'mulc': 8748 newmat[tuple(opslice)] = mat[tuple(opslice)] * submatval 8749 elif opern == 'divc': 8750 newmat[tuple(opslice)] = mat[tuple(opslice)] / submatval 8751 elif opern == 'lowthres': 8752 newmat[tuple(opslice)] = np.where(mat[tuple(opslice)] < val, submatval, \ 8753 mat[tuple(opslice)]) 8754 elif opern == 'upthres': 8755 newmat[tuple(opslice)] = np.where(mat[tuple(opslice)] > val, submatval, \ 8756 mat[tuple(opslice)]) 8757 else: 8758 print errormsg 8759 print ' ' + fname + ": operation '" + opern + "' not ready !!" 8760 print ' ready operations:', operations 8761 quit(-1) 8762 8763 return newmat 8764 8601 8765 #quit() 8602 8766
Note: See TracChangeset
for help on using the changeset viewer.