""" Easier access to matlab functions and variables. Requires PyMat, http://claymore.engineer.gvsu.edu/~steriana/Python Copyright Nathan Srebro, MIT, 2001 nati@mit.edu http://www.ai.mit.edu/~nati/Python """ try: import pymat except: class pymat: def __getattr__(self,attr): raise MatlabUnavialable import types import Numeric import threading class MatLabError(RuntimeError): pass class MatlabUnavialable(MatLabError): pass class matlab: def __init__(self,startcmd='',defer=0): self._startcmd = startcmd self._lock = threading.RLock() if not defer: self._handle = pymat.open(startcmd) def changestartcmd(self,startcmd=None): if startcmd is None: pass # use empty string to set to nothing if hasattr(self,'_handle'): if self._startcmd!=startcmd: raise RuntimeWarning,"MATLAB already initialized with startcmd=%s"%self._startcmd else: self._startcmd = startcmd def _makeactive(self): self._lock.acquire() try: if not hasattr(self,'_handle'): self._handle = pymat.open(self._startcmd) finally: self._lock.release() def __del__(self): try: pymat.close(self._handle) except AttributeError: pass def __call__(self, string, check=1): self._lock.acquire() try: self._makeactive() if check: dostring = "pymatlabok=0 ; "+string+" ; pymatlabok=1" else: dostring = string pymat.eval(self._handle,dostring) if check and not self['pymatlabok'][0]: raise MatLabError,"Operation %s failed"%string finally: self._lock.release() def __getitem__(self, name): self._lock.acquire() try: self._makeactive() return pymat.get(self._handle, name) finally: self._lock.release() def __setitem__(self, name, data): self._lock.acquire() try: self._makeactive() if not isinstance(data,types.StringType): data = Numeric.asarray(data) datashape = Numeric.shape(data) if not datashape: data=Numeric.reshape(data,(1,)) elif len(datashape)>2: data=Numeric.ravel(data) pymat.put(self._handle, name, data) if len(datashape)>2: self('%s = reshape(%s,[%s])'%(name," ".join(map(str,datashape)),name)) finally: self._lock.release() def function(self,*arg,**kwargs): return matlab_function(self,*arg,**kwargs) class matlab_function: def __call__(self, *arg, **kwargs): self._matlab._lock.acquire() try: _nout = self._nout if kwargs: for key,value in kwargs.iteritems(): if key=='nout': _nout = value else: raise ValueError,"Unexpected argument %s"%key _nin = len(arg) for i in range(_nin): self._matlab['in%d' % i]=arg[i] command = ( (_nout>1)*'[ ' +",".join(['out%d' % i for i in range(_nout)]) + (_nout>1)*' ]' + (_nout>0)*" = " + self._name + (_nin>0)*"(" +",".join(['in%d' %i for i in range(_nin)]) + (_nin>0)*")" ) self._matlab(command) if _nout == 1: return self._matlab['out0'] elif _nout > 1: return tuple([self._matlab['out%d' % i] for i in range(_nout)]) finally: self._matlab._lock.release() def __init__(self, matlabobj, name, nout=0): self._matlab = matlabobj self._nout = nout self._name = name M = matlab(defer=1) initM = M.changestartcmd