def identity(shape, dtype=np.float64): "Returns the identity linear Operator" if shape[0] != shape[1]: raise ValueError('Identity operators must be square') def matvec(x): return x return LinearOperator(shape, matvec=matvec, rmatvec=matvec, dtype=dtype)
def diag(d, shape=None, dtype=None): "Returns a diagonal Linear Operator" if shape is None: shape = 2 * (d.size, ) if shape[0] != shape[1]: raise ValueError('Diagonal operators must be square') def matvec(x): return d * x if dtype is None: dtype = d.dtype return LinearOperator(shape, matvec=matvec, rmatvec=matvec, dtype=dtype)
def masubclass(xin=None, xout=None, shapein=None, shapeout=None, classin=None, classout=None, dictin=None, dictout=None, matvec=None, rmatvec=None, dtype=np.float64, dtypein=None, dtypeout=None): "Wrap linear operation working on ndarray subclasses in MaskedArray style" if xin is not None: shapein = xin.shape classin = xin.__class__ dictin = xin.__dict__ dtype = xin.dtype if xout is not None: shapeout = xout.shape classout = xout.__class__ dictout = xout.__dict__ sizein = np.prod(shapein) sizeout = np.prod(shapeout) shape = (sizeout, sizein) if matvec is not None: def ndmatvec(x): xi = classin(x.reshape(shapein)) xi.__dict__ = dictin return matvec(xi).reshape(sizeout) else: raise ValueError('Requires a matvec function') if rmatvec is not None: def ndrmatvec(x): xo = classout(x.reshape(shapeout)) xo.__dict__ = dictout return rmatvec(xo).reshape(sizein) else: ndrmatvec = None return LinearOperator(shape, matvec=ndmatvec, rmatvec=ndrmatvec, dtype=dtype, dtypein=dtypein, dtypeout=dtypeout)
def eye(shape, dtype=np.float64): "Returns the identity linear Operator" if shape[0] == shape[1]: return identity(shape, dtype=dtype) else: def matvec(x): return x[:shape[0]] def rmatvec(x): return np.concatenate(x, np.zeros(shape[0] - shape[1])) return LinearOperator(shape, matvec=matvec, rmatvec=rmatvec, dtype=dtype)