def replace_sub_matrix(mat_in, idx, mat_put): """Replaces the values in mat_in in rows and cols idx with values of mat_put""" assert((idx.shape[0] * idx.shape[0]) == mat_put.ravel().shape[0]) sp.put(mat_in, sp.ravel_multi_index([[x for x in idx for _ in idx], [x for _ in idx for x in idx]], (mat_in.shape[0], mat_in.shape[1])), mat_put.ravel()) return mat_in
def getParameterDerivative(self, i): """ This method returns the derivative with respect to parameter i """ eps = self.param['eps'] pert = scipy.zeros((len(self.lambd), ), scipy.float64) scipy.put(pert, i, eps) lambd = self.lambd + pert u_eps_Dt = self.integrate(self.u, lambd) return -(u_eps_Dt - self.u_Dt) / eps
def getParameterDerivative(self,i): """ This method returns the derivative with respect to parameter i """ eps = self.param['eps'] pert = scipy.zeros((len(self.lambd),),scipy.float64) scipy.put(pert,i,eps) lambd=self.lambd+pert u_eps_Dt = self.integrate(self.u,lambd) return -(u_eps_Dt-self.u_Dt)/eps
def replace_sub_matrix(mat_in, idx, mat_put): """Replaces the values in mat_in in rows and cols idx with values of mat_put""" assert ((idx.shape[0] * idx.shape[0]) == mat_put.ravel().shape[0]) sp.put( mat_in, sp.ravel_multi_index([[x for x in idx for _ in idx], [x for _ in idx for x in idx]], (mat_in.shape[0], mat_in.shape[1])), mat_put.ravel()) return mat_in
def _inner_monotonic_spline(ts_data, ts_ticks, tticks): """ Wrapper of monotonic spline function. Parameters ----------- ts : :class:`~vtools.data.timeseries.TimeSeries` Series to be interpolated times : :ref:`time_sequence <time_sequence>` The new times to which the series will be interpolated. filter_nan:boolean,optional if true, null data points of input timeseries are omitted. Returns ------- result: array interpolated values. """ if ts_data.ndim == 1: new_data = _monotonic_spline(ts_ticks, ts_data, tticks) else: l = len(tticks) ## length of data n = ts_data.shape[1] ## num of data elements ## a nan matrix with shape of n*l, new_data = zeros([n, l]) + nan ## transpose original data to speed up temp_data = transpose(ts_data) for i in range(0, n): indices = arange(i * l, (i + 1) * l) subdata = _monotonic_spline(ts_ticks, temp_data[i, :], tticks) put(new_data, indices, subdata) new_data = transpose(new_data) ## in case only single data returned. if not (type(new_data) == type(array([1, 2]))): new_data = array([new_data]) return new_data
def read_mesh_ANSYS(path, name, targetDimensions_scaling_factor, z_offset): """function that reads the mesh and puts it into nice arrays""" content = preRead_mesh_ANSYS( path) # name doesnt count here, since ANSYS has default names print(content) vertexes_key = 'Nodes' V = int(content[vertexes_key][0]) # we get the number of vertexes vertexes_numbers = zeros(V, 'i') vertexes_coord = zeros((V, 3), 'd') index = 0 fileToRead = open(os.path.join(path, 'NLIST.lis' + '.' + vertexes_key), 'r') for line in fileToRead: tmp = line.split() vertexes_numbers[index] = int(tmp[0]) vertexes_coord[index, :] = list(map(float, tmp[1:])) index += 1 if not (targetDimensions_scaling_factor == 1.0): vertexes_coord *= targetDimensions_scaling_factor vertexes_coord[:, -1] += z_offset fileToRead.close() # we now extract the triangles and write them to a file if 'Elements' in content: elements_key = 'Elements' else: print("read_mesh.py: Error in the ANSYS file format: not supported!!") sys.exit(1) T = content[elements_key][0] # N is the number of triangles del content g = open(os.path.join(path, 'ELIST.lis' + "." + elements_key), 'r') triangles_nodes = zeros((T, 3), 'i') triangles_physicalSurface = zeros(T, 'i') index = 0 for line in g: tmp = list(map(int, line.split())) triangles_nodes[index, :] = tmp[-3:] #triangles_physicalSurface[index] = tmp[3] triangles_physicalSurface[ index] = 0 # not like GMSH here: GMSH triangles have a physical surface number index += 1 g.close() # indexes of elements in Python/C++ arrays start at 0. # However, triangles_nodes don't necessarily start at 0. # So the following 4 lines correct that. vertex_number_max = max(vertexes_numbers) nodes_vertexes = zeros(vertex_number_max + 1, 'i') put(nodes_vertexes, vertexes_numbers, range(V)) triangles_vertexes = take(nodes_vertexes, triangles_nodes, axis=0).astype('i') # we will now eliminate the points that we don't need # del triangles_nodes # gain some memory, we now work only with triangles_vertexes... # max_encountered_vertexes = max(triangles_vertexes.flat) # encountered_vertexesTmp = (zeros(max_encountered_vertexes + 1, 'i') - 1).astype('i') # wrapping_code = """ # for (int i=0 ; i<triangles_vertexes.extent(0) ; i++) { # for (int j=0 ; j<triangles_vertexes.extent(1) ; j++) { # const int vertex = triangles_vertexes(i, j); # encountered_vertexesTmp(vertex) = vertex; # } # } # """ # weave.inline(wrapping_code, # ['encountered_vertexesTmp', 'triangles_vertexes'], # type_converters = converters.blitz, # include_dirs = [], # library_dirs = [], # libraries = [], # headers = ['<iostream>'], # compiler = 'gcc', # extra_compile_args = ['-O3', '-pthread', '-w']) # encountered_vertexes = compress(encountered_vertexesTmp>-1, encountered_vertexesTmp, axis=0) # del encountered_vertexesTmp # oldVertex_to_newVertex = zeros(max_encountered_vertexes+1, 'i') # oldVertex_to_newVertex[encountered_vertexes] = range(len(encountered_vertexes)) # triangles_vertexes = take(oldVertex_to_newVertex, triangles_vertexes, axis=0) # vertexes_coord = take(vertexes_coord, encountered_vertexes, axis=0) return vertexes_coord.astype('d'), triangles_vertexes.astype( 'i'), triangles_physicalSurface.astype('i')
def read_mesh_GMSH_1(name, targetDimensions_scaling_factor, z_offset): """function that reads the mesh and puts it into nice arrays preRead does not create separate files with nodes, triangles,... so for big targets read_mesh_GMSH_1 can take lots of memory. This function is to be erased in a near future. """ content = preRead_mesh_GMSH_1(name) if 'Nodes' in content: vertexes_key = 'Nodes' elif 'NOD' in content: vertexes_key = 'NOD' else: print("read_mesh.py: Error in the GMSH file format: not supported!!") sys.exit(1) V = int(content[vertexes_key][0]) # we get the number of vertexes vertexes_numbers = zeros(V, 'i') vertexes_coord = zeros((V, 3), 'd') index = 0 for tmp in content[vertexes_key][1:]: tmp2 = tmp.split() vertexes_numbers[index] = int(tmp2[0]) vertexes_coord[index, :] = list(map(float, tmp2[1:])) index += 1 if not (targetDimensions_scaling_factor == 1.0): vertexes_coord *= targetDimensions_scaling_factor vertexes_coord[:, -1] += z_offset # we check whether we have a source SOURCE = False PhysicalSurfaceNumberToName = {} if 'PhysicalNames' in content: keyPhysicalNames = 'PhysicalNames' NumberPhysicalNames = int(content[keyPhysicalNames][0]) for elem in content[keyPhysicalNames][1:]: elem2 = elem.split() newKey = int(elem2[0]) PhysicalSurfaceNumberToName[newKey] = elem2[1] if "source" in PhysicalSurfaceNumberToName[newKey]: SOURCE = True # we now extract the triangles and write them to a file if 'Elements' in content: elements_key = 'Elements' elif 'ELM' in content: elements_key = 'ELM' else: print("read_mesh.py: Error in the GMSH file format: not supported!!") sys.exit(1) N_elems = int( content[elements_key] [0]) # N is the number of "elements" (border edges, facets,...) g = open(name + ".triangles", "w") #g2 = open(name + ".sourceTriangles", "w") T, T_src = 0, 0 for elementTmp in content[elements_key][1:]: elementTmp2 = elementTmp.split() element = list(map(int, elementTmp2)) if element[1] == 2: # type 'planar triangle' has number 2 listTmp = [element[3]] listTmp += element[-3:] if SOURCE and (listTmp[0] in PhysicalSurfaceNumberToName): T_src += 1 for elem in listTmp: #g2.write(str(elem) + " ") #g2.write("\n") g.write(str(elem) + " ") g.write("\n") else: T += 1 for elem in listTmp: g.write(str(elem) + " ") g.write("\n") g.close() #g2.close() del content # we now read the target triangles from the name.triangles file g = open(name + ".triangles", 'r') triangles_nodes = zeros((T + T_src, 3), 'i') triangles_physicalSurface = zeros(T + T_src, 'i') for k in range(T + T_src): tmp = list(map(int, g.readline().split())) triangles_nodes[k, :] = tmp[1:] triangles_physicalSurface[k] = tmp[0] g.close() vertex_number_max = max(vertexes_numbers) nodes_vertexes = zeros(vertex_number_max + 1, 'i') put(nodes_vertexes, vertexes_numbers, range(V)) triangles_vertexes = take(nodes_vertexes, triangles_nodes, axis=0).astype('i') del triangles_nodes # gain some memory, we now work only with triangles_vertexes... # we will now eliminate the points that we don't need # old non-performant memory-wise code #encountered_vertexesTmp = sort(array(triangles_vertexes.flat) , kind="mergesort") #encountered_vertexes = [encountered_vertexesTmp[0]] #for i in range(1, len(encountered_vertexesTmp)): #if (encountered_vertexesTmp[i] != encountered_vertexes[-1]): #encountered_vertexes.append(encountered_vertexesTmp[i]) #max_encountered_vertexes = max(encountered_vertexes) # new performant memory-wise code max_encountered_vertexes = max(triangles_vertexes.flat) encountered_vertexesTmp = (zeros(max_encountered_vertexes + 1, 'i') - 1).astype('i') for vertex in triangles_vertexes.flat: encountered_vertexesTmp[vertex] = vertex encountered_vertexes = compress(encountered_vertexesTmp > -1, encountered_vertexesTmp, axis=0) del encountered_vertexesTmp oldVertex_to_newVertex = zeros(max_encountered_vertexes + 1, 'i') oldVertex_to_newVertex[encountered_vertexes] = range( len(encountered_vertexes)) triangles_vertexes = take(oldVertex_to_newVertex, triangles_vertexes, axis=0) vertexes_coord = take(vertexes_coord, encountered_vertexes, axis=0) return vertexes_coord.astype('d'), triangles_vertexes.astype( 'i'), triangles_physicalSurface.astype('i')
def read_mesh_GMSH_2(name, targetDimensions_scaling_factor, z_offset): """function that reads the mesh and puts it into nice arrays""" content = preRead_mesh_GMSH_2(name) print(content) if 'Nodes' in content: vertexes_key = 'Nodes' elif 'NOD' in content: vertexes_key = 'NOD' else: print("read_mesh.py: Error in the GMSH file format: not supported!!") sys.exit(1) V = int(content[vertexes_key][0]) # we get the number of vertexes vertexes_numbers = zeros(V, 'i') vertexes_coord = zeros((V, 3), 'd') index = 0 file = open(name + '.' + vertexes_key, 'r') for line in file: tmp = line.split() vertexes_numbers[index] = int(tmp[0]) vertexes_coord[index, :] = list(map(float, tmp[1:])) index += 1 if not (targetDimensions_scaling_factor == 1.0): vertexes_coord *= targetDimensions_scaling_factor vertexes_coord[:, -1] += z_offset file.close() # we check whether we have a source SOURCE = False PhysicalSurfaceNumberToName = {} if 'PhysicalNames' in content: keyPhysicalNames = 'PhysicalNames' NumberPhysicalNames = content[keyPhysicalNames][0] file = open(name + '.' + keyPhysicalNames, 'r') for line in file: elem2 = line.split() newKey = int(elem2[0]) PhysicalSurfaceNumberToName[newKey] = elem2[1] if "source" in PhysicalSurfaceNumberToName[newKey]: SOURCE = True file.close() # we now extract the triangles and write them to a file if 'Elements' in content: elements_key = 'Elements' elif 'ELM' in content: elements_key = 'ELM' else: print("read_mesh.py: Error in the GMSH file format: not supported!!") sys.exit(1) T = content[elements_key][0] # N is the number of triangles del content g = open(name + "." + elements_key, 'r') triangles_nodes = zeros((T, 3), 'i') triangles_physicalSurface = zeros(T, 'i') index = 0 for line in g: tmp = list(map(int, line.split())) triangles_nodes[index, :] = tmp[-3:] triangles_physicalSurface[index] = tmp[3] index += 1 g.close() # indexes of elements in Python/C++ arrays start at 0. # However, triangles_nodes don't necessarily start at 0. # So the following 4 lines correct that. vertex_number_max = max(vertexes_numbers) nodes_vertexes = zeros(vertex_number_max + 1, 'i') put(nodes_vertexes, vertexes_numbers, range(V)) triangles_vertexes = take(nodes_vertexes, triangles_nodes, axis=0).astype('i') # we will now eliminate the points that we don't need # del triangles_nodes # gain some memory, we now work only with triangles_vertexes... # max_encountered_vertexes = max(triangles_vertexes.flat) # encountered_vertexesTmp = (zeros(max_encountered_vertexes + 1, 'i') - 1).astype('i') # wrapping_code = """ # for (int i=0 ; i<triangles_vertexes.extent(0) ; i++) { # for (int j=0 ; j<triangles_vertexes.extent(1) ; j++) { # const int vertex = triangles_vertexes(i, j); # encountered_vertexesTmp(vertex) = vertex; # } # } # """ # weave.inline(wrapping_code, # ['encountered_vertexesTmp', 'triangles_vertexes'], # type_converters = converters.blitz, # include_dirs = [], # library_dirs = [], # libraries = [], # headers = ['<iostream>'], # compiler = 'gcc', # extra_compile_args = ['-O3', '-pthread', '-w']) # encountered_vertexes = compress(encountered_vertexesTmp>-1, encountered_vertexesTmp, axis=0) # del encountered_vertexesTmp # oldVertex_to_newVertex = zeros(max_encountered_vertexes+1, 'i') # oldVertex_to_newVertex[encountered_vertexes] = range(len(encountered_vertexes)) # triangles_vertexes = take(oldVertex_to_newVertex, triangles_vertexes, axis=0) # vertexes_coord = take(vertexes_coord, encountered_vertexes, axis=0) return vertexes_coord.astype('d'), triangles_vertexes.astype( 'i'), triangles_physicalSurface.astype('i')
def _spline(data,ticks,tticks,time_begin=None,time_end=None,\ k=3,s=1.0e-3,filter_nan=True,per=0): """ Estimate missing values within ts data by B-spline interpolation. Parameters ----------- ts : :class:`~vtools.data.timeseries.TimeSeries` Series to be interpolated times : :ref:`time_sequence <time_sequence>` The new times to which the series will be interpolated. time_begin, time_end: int or datetime,optional the boundary of approximating, Default means whole time series will be fitted. k: int,optional The order of the spline fit. s: float,optional A smoothing condition. filter_nan:boolean,optional If true, null data points of input timeseries are omitted. per:int,optional If non-zero, data points are considered periodic. Returns ------- result: array interpolated values. ..note:: k: It is recommended to use cubic splines.Even order splines should be avoided especially with small s values. 1 <= k <= 5. s: The amount of smoothness is determined by satisfying the conditions: sum((w * (y - g))**2,axis=0) <= s where g(x) is the smoothed interpolation of (x,y). The user can use s to control the tradeoff between closeness and smoothness of fit. Larger s means more smoothing while smaller values of s indicate less smoothing. Recommended values of s depend on the weights, w. If the weights represent the inverse of the standard-deviation of y, then a good s value should be found in the range (m-sqrt(2*m),m+sqrt(2*m)) where m is the number of datapoints in x, y, and w. default : s=m-sqrt(2*m). per: If non-zero, data points are considered periodic with period x[m-1] - x[0] and a smooth periodic spline approximation is returned.Values of y[m-1] and w[m-1] are not used. """ if k < 1 or k > 5: raise ValueError("Unsupported spline interpolation order.") (start_i, end_i) = _check_fitting_bounds(ticks, k, time_begin, time_end) if not (start_i == 0) or not (end_i == (len(data) - 1)): ## Sliceing is needed ts_ticks = ticks[start_i:end_i] ts_data = data[start_i:end_i] else: ts_ticks = ticks ts_data = data ## splrep cann't hanle multi-rank data directly. ## so,it needes to be done here. if ts_data.ndim == 1: ## Generate spline representation. tck = splrep(ts_ticks, ts_data, s=s, per=per, k=k) ## Calculate values. v = splev(tticks, tck, der=0) if not isSequenceType(v): v = array([v]) return v elif ts_data.ndim > 1: l = len(tticks) values = zeros([ts_data.shape[1], l]) + nan ## transpose orginal data for speed up temp_data = transpose(ts_data) for i in range(ts_data.shape[1]): tck = splrep(ts_ticks, temp_data[i, :], s=s, per=per, k=k) v = splev(tticks, tck, der=0) indices = arange(i * l, (i + 1) * l) put(values, indices, v) values = transpose(values) return values
def interpolate_ts_nan(ts, method=LINEAR, max_gap=0, **args): """ Estimate missing values within a time series by interpolation. Parameters ---------- ts : :class:`~vtools.data.timeseries.TimeSeries` The time series to be interpolated. Must be univariate. method : {LINEAR,NEAREST,PREVIOUS,NEXT,SPLINE,MSPLINE,RHIST} You can use our constants or the equivalent string as indicated below. LINEAR or 'linear' Linear interpolation NEAREST or 'nearest' Nearest value in time PREVIOUS or 'previous' Previous step with data NEXT or 'next' Next step with data SPLINE or 'spline' numpy 1D spline MSPLINE or 'mspline' Monotonicity (shape) preserving spline RHIST or 'rhist' Rational histospline that conserves area under the curve. max_gap: int,optional The maximum number of continous nan data to allow interpolation. By default 0, which means doing interpolation no matter how big is the continous nan block. **args : dictonary Extra keyword parameters required by the `method`. Returns ------- filled : :class:`~vtools.data.timeseries.TimeSeries` New series with missing values filled using `method` """ if not (ts.has_gap()): return ts tst = deepcopy(ts) if max_gap > 0: gaps = gap_size(tst.data) indexes = where((gaps > 0) & (gaps <= max_gap)) else: indexes = where(isnan(tst.data)) ## no nan just return if (len(indexes[0]) < 1): return ts ## indexes turn out to be a tuple ## only the first element is what ## needed. times = take(tst.ticks, indexes[0]) values = _interpolate_ts2array(tst, times, method, filter_nan=True, **args) put(tst.data, indexes, values) return tst
def _interpolate_ts2array(ts, times, method=LINEAR, filter_nan=True, **dic): """ Interpolate a time series to input 'times'. Parameters ----------- ts : :class:`~vtools.data.timeseries.TimeSeries` Series to be interpolated times : :ref:`time_sequence <time_sequence>` The new times to which the series will be interpolated. method : string, optional See :func:`interpolate_ts_nan` for a list of methods. filter_nan : boolean,optional True if nan points should be omitted or not. **dic : Dictionary Dictonary of extra parameters to be passed to `method` Returns ------- result: array interpolated values. Raise -------- ValueError If interpolate method is not supported, or input time sequence is not a subset of input timeseries datetime range. """ ## do a check of extrapolation, which is not allowed ts_start = ts.ticks[0] ts_end = ts.ticks[-1] tticks = _check_input_times(times) if not ((ts_start <= (tticks[0])) and (ts_end >= (tticks[-1]))): raise ValueError("Interpolation time sequence is not subset of \ input timeseries valid time range") if filter_nan and ts.data.ndim > 1: raise ValueError(" filtering nan is only defined for" + " one dimensional time series data.") valid_ts_data = ts.data valid_ts_ticks = ts.ticks if filter_nan: valid_ts_data, valid_ts_ticks = filter_nana(ts.data, ts.ticks) valid_start = valid_ts_ticks[0] valid_end = valid_ts_ticks[-1] ## find out the indexes within tticks that can be interpolated by ## valid ts data indexes1 = where(tticks >= valid_start) indexes2 = where(tticks <= valid_end) if (len(indexes1[0]) == 0) or (len(indexes2[0]) == 0): raise ValueError("interpolation point is out of valid data range") s1 = indexes1[0][0] s2 = indexes2[0][-1] valid_tticks = tticks[s1:s2 + 1] if isSequenceType(valid_tticks) and len(valid_tticks) == 0: raise ValueError( " interpolation point sequence is out of valid data range") if ts.data.ndim == 1: values = array([nan] * len(tticks)) elif ts.data.ndim == 2: values = array([[nan] * ts.data.shape[1]] * len(tticks)) else: raise ValueError( "interpolation over data with dimension more than 2 is not supported" ) if method == LINEAR: temp = _linear(valid_ts_data, valid_ts_ticks, valid_tticks, **dic) elif method == SPLINE: temp = _spline(valid_ts_data, valid_ts_ticks, valid_tticks, **dic) elif method == NEXT or method == PREVIOUS or method == NEAREST: temp = _flat(valid_ts_data, valid_ts_ticks, valid_tticks, method, **dic) elif method == MONOTONIC_SPLINE: temp = _inner_monotonic_spline(valid_ts_data, valid_ts_ticks, valid_tticks, **dic) elif method == RATIONAL_HISTOSPLINE: if not ts.is_regular(): raise ValueError("Only regular time series are" " supported by histospline") if AGGREGATION in ts.props.keys(): if not ts.props[AGGREGATION] == MEAN: raise ValueError("Only time series with averaged values can be" " interpolated by histospline") if TIMESTAMP in ts.props.keys(): if not ts.props[TIMESTAMP] == PERIOD_START: raise ValueError( "Input time series values must be stamped at start" " of individual period") temp = _rhistinterpbound(valid_ts_data, valid_ts_ticks, valid_tticks, **dic) else: raise ValueError("Not supported interpolation method.") assert (len(temp) == len(valid_tticks)) if ts.data.ndim == 1: put(values, arange(s1, s2 + 1), temp) else: for index in arange(0, ts.data.shape[1]): put(values[:, index], arange(s1, s2 + 1), temp[:, index]) return values