def plot_field(eng, mesh, val='u'): Ne = mesh.Ne it = FM.get_connections(mesh) mat = [] for e in mesh.getElements(): mat.append(e.getMaterial().getID() + 1) xyz = [] field = [] for n in mesh.getNodes(): xyz.append(n.getX().tolist()) if val == 'u': for n in mesh.getNodes(): field.append(n.getU().tolist()) elif val == 'v': for n in mesh.getNodes(): field.append(n.getV().tolist()) elif val == 'a': for n in mesh.getNodes(): field.append(n.getU().tolist()) else: return #eng = matlab.engine.start_matlab() IT = matlab.int64(it) MAT = matlab.int64(mat) XYZ = matlab.double(xyz) Field = matlab.double(field) eng.plot_field(IT, Field, XYZ, Ne, MAT, 0) return eng
def convertLabels(self, inLabels): convLabels = [] for stateID in inLabels.keys(): convLabels.append([stateID,'p1',matlab.int64(inLabels[stateID]['p1'][:])]) convLabels.append([stateID,'p2',matlab.int64(inLabels[stateID]['p2'][:])]) convLabels.append([stateID,'p3',matlab.int64(inLabels[stateID]['p3'][:])]) convLabels.append([stateID,'p4',matlab.int64(inLabels[stateID]['p4'][:])]) return convLabels
def interleave(eng, arrData_bin, nParam, strMethod=INTRLV_MATRIX): """ interleave data in a block way """ data_intrlv = None nPadding = None if(strMethod == INTRLV_MATRIX): nCols = nParam arrData_bin, nPadding = ct.zeroPadding(arrData_bin, nCols) nRows = len(arrData_bin)/nCols data = matlab.int64(list(arrData_bin)) data_intrlv = eng.matintrlv(data, nRows, nCols) elif(strMethod == INTRLV_RANDOM): nSeed = 4831 data = matlab.int64(list(arrData_bin)) data_intrlv = eng.randintrlv(data, nSeed) else: raise ValueError("Unsupported interleaving method: %s" % strMethod) arrData_intrlv = np.array([i for i in data_intrlv[0]]) return arrData_intrlv, nPadding
def matlab_SurfStatLinMod(Y, M, surf=None, niter=1, thetalim=0.01, drlim=0.1): from term import Term from brainspace.mesh.mesh_elements import get_cells from brainspace.vtk_interface.wrappers.data_object import BSPolyData if isinstance(Y, np.ndarray): Y = matlab.double(Y.tolist()) else: Y = surfstat_eng.double(Y) if isinstance(M, np.ndarray): M = {'matrix': matlab.double(M.tolist())} elif isinstance(M, Term): M = surfstat_eng.term(matlab.double(M.matrix.values.tolist()), M.matrix.columns.tolist()) else: # Random M1 = matlab.double(M.mean.matrix.values.tolist()) V1 = matlab.double(M.variance.matrix.values.tolist()) M = surfstat_eng.random(V1, M1, surfstat_eng.cell(0), surfstat_eng.cell(0), 1) # Only require 'tri' or 'lat' if surf is None: k = None surf = surfstat_eng.cell(0) else: if isinstance(surf,BSPolyData): surf = {'tri': np.array(get_cells(surf))+1} k = 'tri' if 'tri' in surf else 'lat' s = surf[k] surf = {k: matlab.int64(s.tolist())} slm = surfstat_eng.SurfStatLinMod(Y, M, surf, niter, thetalim, drlim) for key in ['SSE', 'coef']: if key not in slm: continue slm[key] = np.atleast_2d(slm[key]) slm = {k: v if np.isscalar(v) else np.array(v) for k, v in slm.items()} return slm
def matlab_SurfStatLinMod(Y, M, surf=None, niter=1, thetalim=0.01, drlim=0.1): from term import Term if isinstance(Y, np.ndarray): Y = matlab.double(Y.tolist()) else: Y = surfstat_eng.double(Y) if isinstance(M, np.ndarray): M = {'matrix': matlab.double(M.tolist())} elif isinstance(M, Term): M = surfstat_eng.term(matlab.double(M.matrix.values.tolist()), M.matrix.columns.tolist()) else: # Random M1 = matlab.double(M.mean.matrix.values.tolist()) V1 = matlab.double(M.variance.matrix.values.tolist()) M = surfstat_eng.random(V1, M1, surfstat_eng.cell(0), surfstat_eng.cell(0), 1) # Only require 'tri' or 'lat' if surf is None or ('tri' not in surf and 'lat' not in surf): k = None surf = surfstat_eng.cell(0) else: k = 'tri' if 'tri' in surf else 'lat' s = surf[k] surf = {k: matlab.int64(s.tolist())} slm = surfstat_eng.SurfStatLinMod(Y, M, surf, niter, thetalim, drlim) for key in ['SSE', 'coef']: if key not in slm: continue slm[key] = np.atleast_2d(slm[key]) slm = {k: v if np.isscalar(v) else np.array(v) for k, v in slm.items()} return slm
def ndarray_to_matlab(numpy_array): """Conversion of a numpy array to matlab mlarray The conversion is realised without copy for real data. First an empty initialization is realized. Then the numpy array is affected to the _data field. Thus the data field is not really an array.array but a numpy array. Matlab doesn't see anything... For complex data, the strides seems to not work properly with matlab.double. Paramerters ----------- numpy_array : numpy array the array to convert Returns ------- matlab_array : mlarray the converted array that can be passe to matlab Examples -------- >>> npi=numpy.array([[1,2,3],[4,5,6],[7,8,9],[10,11,12]],dtype=numpy.int64,order='C') >>> ndarray_to_matlab(npi) matlab.int64([[1,2,3],[4,5,6],[7,8,9],[10,11,12]]) >>> npif=numpy.array([[1,2,3],[4,5,6],[7,8,9],[10,11,12]],dtype=numpy.int64,order='F') >>> ndarray_to_matlab(npif) matlab.int64([[1,2,3],[4,5,6],[7,8,9],[10,11,12]]) >>> npcf=numpy.array([[1,2+0.2j,3],[4,5,6],[7,8,9],[10+0.1j,11,12]],dtype=numpy.complex,order='F') >>> ndarray_to_matlab(npcf) matlab.double([[(1+0j),(2+0.2j),(3+0j)],[(4+0j),(5+0j),(6+0j)],[(7+0j),(8+0j),(9+0j)],[(10+0.1j),(11+0j),(12+0j)]], is_complex=True) References ----------- https://scipy-lectures.org/advanced/advanced_numpy/ (strides) """ if "ndarray" not in str(type(numpy_array)): # check numpy raise TypeError(f"Expect numpy.ndarray. Got {type(numpy_array)}") shape = numpy_array.shape # get shape num_elements = numpy.prod(shape) # number of elements if numpy_array.flags.f_contiguous: # compute strides (real case) strides = get_strides_f(shape) order = "F" else: strides = get_strides_c(shape) order = "C" if numpy.iscomplexobj(numpy_array): # complex case matlab_array = matlab.double( initializer=None, size=(1, num_elements), is_complex=True ) # create empty matlab.mlarray # associate the data """ # associate the data (no copy), works on 2D array only... matlab_array._real=numpy_array.ravel(order=order) # allow to map real and imaginary part continuously! """ cpx = numpy_array.ravel(order="F") # copy except for fortran like array matlab_array._real = ( cpx.real.ravel() ) # second ravel to correct the strides 18->8 matlab_array._imag = cpx.imag.ravel() matlab_array.reshape(shape) # matlab_array._strides=strides else: # real case # create empty matlab.mlarray if numpy_array.dtype == numpy.float64: matlab_array = matlab.double( initializer=None, size=(1, num_elements), is_complex=False ) elif numpy_array.dtype == numpy.int64: matlab_array = matlab.int64(initializer=None, size=(1, num_elements)) elif numpy_array.dtype == numpy.bool: matlab_array = matlab.logical(initializer=None, size=(1, num_elements)) else: raise TypeError(f"Type {numpy_array.dtype} is missing") matlab_array._data = numpy_array.ravel(order=order) # associate the data # print(matlab_array._data.flags,matlab_array._data,'\n') # control owner matlab_array.reshape(shape) # back to original shape if ( len(shape) > 1 ): # array strides are in number of cell (numpy strides are in bytes) # if len(shape)==1 no need to change. Format pb because _stride expect (1,1) and stride = (1,) matlab_array._strides = ( strides # change stride (matlab use 'F' order ie [nc,1] ) ) return matlab_array
def decompose(self, r, method='tensorly') -> 'DecomposedFactor': """ Decompose this factor into r rank-1 components using non-negative CP decomposition. In certain trivial cases, returns a decomposition with one component rather than r. :param method: Library to use to compute CP decomposition, either 'tensorly' or 'matlab' (see note about MATLAB support at the top of this file). """ assert method in ['tensorly', 'matlab'] if method == 'matlab': assert with_matlab, 'MATLAB Python API not detected' # Variables with cardinality 1 cause problems with tensorly non_negative_decomp, so we only decompose the # nontrivial dimensions of the table (and set the matrices for trivial dimensions to [[1, ..., 1]]). table_nt = np.squeeze(self.table) if table_nt.ndim == 1: # If the nontrivial table has just one variable, the resulting decomposition has just one term (not r terms) # and we don't call the decomposition algorithm at all n_terms = 1 weights = np.ones(n_terms) # Reshape is to change np.array([1,2,3]) to np.array([[1],[2],[3]]) matrices_nt = [table_nt.reshape(table_nt.shape[0], 1)] else: n_terms = r if method == 'tensorly': if 'tensorly' not in sys.modules: if verbosity == 3: import_tensorly() else: with SuppressOutput(): import_tensorly() weights = np.ones(n_terms) matrices_nt = None table_nt_orig = table_nt i = 0 while not matrices_nt: try: matrices_nt = tensorly.decomposition.non_negative_parafac( table_nt, n_terms) except LinAlgError: i += 1 status( "Warning: singular matrix encountered, perturbing tensor and attempting decomposition " "again ({})".format(i), 3) table_nt = perturb(table_nt_orig) elif method == 'matlab': # Initialise MATLAB global eng if not eng: eng = matlab.engine.start_matlab() eng.addpath(MATLAB_PATH) w, T = eng.cp_kolda(matlab.double( table_nt.flatten(order='F').tolist()), matlab.int64(table_nt.shape), r, nargout=2) matrices_nt = [np.array(t) for t in T] weights = np.array(w).flatten() # Add the trivial dimensions back in matrices = [] j = 0 for i in range(self.n_vars): if self.cardinalities[i] == 1: matrices.append(np.ones((1, n_terms))) else: matrices.append(matrices_nt[j]) j += 1 assert matrices[i].shape == (self.cardinalities[i], n_terms) assert j == len(matrices_nt) df = DecomposedFactor(self.vars, weights, matrices) # Make sure the decomposition is close to the original factor # diff = df.expand().table - self.table # print("Reconstruction error: norm=%s, largest=%s" % ( # np.linalg.norm(diff), # np.max(diff), # )) return df
def asiduj_test(): """ Test of the module It runs the doctest and create other tests with matlab engine calls.""" import scipy.linalg as spl print("Run matlab engine...") if len(matlab.engine.find_matlab()) == 0: # si aucune session share, run eng = matlab.engine.start_matlab() else: # connect to a session eng = matlab.engine.connect_matlab(matlab.engine.find_matlab()[0]) print("connected...") print("Further tests....\n") # create matlab data # ------------------------------------------------------------------------ mf = eng.rand(3) mc = matlab.double([[1 + 1j, 0.3, 1j], [1.2j - 1, 0, 1 + 1j]], is_complex=True) mi64 = matlab.int64([1, 2, 3]) mi8 = matlab.int8([1, 2, 3]) mb = matlab.logical([True, True, False]) # Test conversion from matlab to numpy # ------------------------------------------------------------------------ npf = matlab_to_ndarray(mf) # no copy, if mf is changed, npf change! npc = matlab_to_ndarray(mc) # still copy for complex (only) npi64 = matlab_to_ndarray(mi64) npi8 = matlab_to_ndarray(mi8) npb = matlab_to_ndarray(mb) # Test conversion from numpy to matlab # ------------------------------------------------------------------------ npi = numpy.array([[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]], dtype=numpy.int64, order="F") mi = ndarray_to_matlab(npi) mc2 = ndarray_to_matlab(npc) mf2 = ndarray_to_matlab( npf) # copy, because npf has 'F' order (comes from mlarray) mi64_2 = ndarray_to_matlab(npi) mb2 = ndarray_to_matlab(npb) # test orientation in the matlab workspace # ------------------------------------------------------------------------ eng.workspace["mi"] = mi64_2 eng.workspace["mc2"] = mc2 # check results # ------------------------------------------------------------------------ npcc = numpy.array( [ [1.0, 1.1 + 1j], [ 1.12 + 0.13j, 22.1, ], ], dtype=numpy.complex, ) # assume C mcc = ndarray_to_matlab(npcc) npcc_inv = spl.inv(npcc) mcc_inv = eng.inv(mcc) print("Are the inverse of matrix equal ?") print(mcc_inv) print(npcc_inv) # # no copy check # # ------------------------------------------------------------------------ # # complex # # npcc[0,0]=0.25 # print("Are the data reuse ?", ", OWNDATA =", mcc._real.flags.owndata, # "same base =", mcc._real.base is npcc, # ', If one is modified, the other is modified =', mcc._real[0]==npcc[0,0]) # # test sparse matrix requiert Recast4py.m K1, K2 = eng.sptest(3.0, nargout=2) Ksp1 = dict_to_sparse(K1) Ksp2 = dict_to_sparse(K2)
def np2mlarray(npa): """ Conversion of a numpy array to matlab mlarray The conversion is realised without copy for real data. First an empty initialization is realized. Then the numpy array is affected to the _data field. Thus the data field is not really an array.array but a numpy array. Matlab doesn't see anything... For complex data, the strides seems to not work properly with matlab.double. Paramerters ----------- npa : numpy array the array to convert Returns ------- ma : mlarray the converted array that can be passe to matlab Examples -------- >>> npi=np.array([[1,2,3],[4,5,6],[7,8,9],[10,11,12]],dtype=np.int64,order='C') >>> np2mlarray(npi) matlab.int64([[1,2,3],[4,5,6],[7,8,9],[10,11,12]]) >>> npif=np.array([[1,2,3],[4,5,6],[7,8,9],[10,11,12]],dtype=np.int64,order='F') >>> np2mlarray(npif) matlab.int64([[1,2,3],[4,5,6],[7,8,9],[10,11,12]]) >>> npcf=np.array([[1,2+0.2j,3],[4,5,6],[7,8,9],[10+0.1j,11,12]],dtype=np.complex,order='F') >>> np2mlarray(npcf) matlab.double([[(1+0j),(2+0.2j),(3+0j)],[(4+0j),(5+0j),(6+0j)],[(7+0j),(8+0j),(9+0j)],[(10+0.1j),(11+0j),(12+0j)]], is_complex=True) References ----------- https://scipy-lectures.org/advanced/advanced_numpy/ (strides) """ # check numpy if 'ndarray' not in str(type(npa)): raise TypeError('Expect numpy.ndarray. Got %s' % type(npa)) # get shape shape = npa.shape # number of elements N = np.prod(shape) # compute strides (real case) if npa.flags.f_contiguous == True: strides = _getStridesF(shape) # pour la sortie order = 'F' else: strides = _getStridesC(shape) # ok, garde le même order = 'C' # complex case if npa.dtype in (np.complex128, np.complex): # create empty matlab.mlarray ma = matlab.double(initializer=None, size=(1, N), is_complex=True) # associate the data """ # associate the data (no copy), works on 2D array only... ma._real=npa.ravel(order=order) # allow to map real and imaginary part continuously! """ cpx = npa.ravel(order='F') # copy except for fortran like array ma._real = cpx.real.ravel( ) # second ravel to correct the strides 18->8 ma._imag = cpx.imag.ravel() ma.reshape(shape) # ma._strides=strides # real case else: # create empty matlab.mlarray if npa.dtype == np.float64: ma = matlab.double(initializer=None, size=(1, N), is_complex=False) elif npa.dtype == np.int64: ma = matlab.int64(initializer=None, size=(1, N)) elif npa.dtype == np.bool: ma = matlab.logical(initializer=None, size=(1, N)) else: raise TypeError('Type %s is missing' % npa.dtype) # associate the data ma._data = npa.ravel(order=order) # print(ma._data.flags,ma._data,'\n') # control owner # back to original shape ma.reshape(shape) # array strides are in number of cell (numpy strides are in bytes) # if len(shape)==1 no need to change. Format pb because _stride expect (1,1) and stride = (1,) if len(shape) > 1: ma._strides = strides # change stride (matlab use 'F' order ie [nc,1] ) return ma
eng = matlab.engine.start_matlab() else: # connect to a session eng = matlab.engine.connect_matlab(matlab.engine.find_matlab()[0]) print('connected...') else: print('Matlab engine is already runnig...') print('Further tests....\n') # create matlab data # ------------------------------------------------------------------------ mf = eng.rand(3) mc = matlab.double([[1 + 1j, 0.3, 1j], [1.2j - 1, 0, 1 + 1j]], is_complex=True) mi64 = matlab.int64([1, 2, 3]) mi8 = matlab.int8([1, 2, 3]) mb = matlab.logical([True, True, False]) # Test conversion from matlab to numpy # ------------------------------------------------------------------------ npf = mlarray2np(mf) # no copy, if mf is changed, npf change! npc = mlarray2np(mc) # still copy for complex (only) npi64 = mlarray2np(mi64) npi8 = mlarray2np(mi8) npb = mlarray2np(mb) # Test conversion from numpy to matlab # ------------------------------------------------------------------------ npi = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]], dtype=np.int64,