def __init__(self, ttype, n, s, defouttype=None, forceppy=False, sketch_transform=None): """ Create the transform from n dimensional vectors to s dimensional vectors. Here we define the interface, but the constructor should not be called directly by the user. :param ttype: String identifying the sketch type. This parameter is omitted in derived classes. :param n: Number of dimensions in input vectors. :param s: Number of dimensions in output vectors. :param defouttype: Default output type when using the * and / operators. If None the output will have same type as the input. :param forceppy: whether to force a pure python implementation :param sketch_transform: Loaded sketch transform from serialized data. :returns: the transform object """ self._baseinit(ttype, n, s, defouttype, forceppy) if not self._ppy: if sketch_transform is None: sketch_transform = c_void_p() lib.callsl("sl_create_sketch_transform", lib.ctxt_obj, ttype, n, s, byref(sketch_transform)) self._obj = sketch_transform else: self._obj = sketch_transform
def __init__(self, n, s, sigma=1.0, defouttype=None, forceppy=False, sketch_transform=None): super(FastGaussianRFT, self)._baseinit("FastGaussianRFT", n, s, defouttype, forceppy) self._sigma = sigma if self._ppy: self._blocks = int(math.ceil(float(s) / n)) self._sigma = sigma self._b = numpy.matrix(numpy.random.uniform(0, 2 * pi, (s, 1))) binary = scipy.stats.bernoulli(0.5) self._B = [2.0 * binary.rvs(n) - 1.0 for i in range(self._blocks)] self._G = [numpy.random.randn(n) for i in range(self._blocks)] self._P = [ numpy.random.permutation(n) for i in range(self._blocks) ] else: if sketch_transform is None: sketch_transform = c_void_p() lib.callsl("sl_create_sketch_transform", lib.ctxt_obj, "FastGaussianRFT", n, s, \ byref(sketch_transform), ctypes.c_double(sigma)) self._obj = sketch_transform else: self._obj = sketch_transform
def __init__(self, n, s, q=3, c=0, gamma=1, defouttype=None, forceppy=False, sketch_transform=None): super(PPT, self)._baseinit("PPT", n, s, defouttype, forceppy) if c < 0: raise ValueError("c parameter must be >= 0") if self._ppy: self._q = q self._gamma = gamma self._c = c self._css = [ CWT(n + (c > 0), s, forceppy=forceppy) for i in range(q) ] else: if sketch_transform is None: sketch_transform = c_void_p() lib.callsl("sl_create_sketch_transform", lib.ctxt_obj, "PPT", n, s, \ byref(sketch_transform), \ ctypes.c_int(q), ctypes.c_double(c), ctypes.c_double(gamma)) self._obj = sketch_transform else: self._obj = sketch_transform
def __setstate__(self, d): self.__dict__ = d try: sketch_transform = c_void_p() lib.callsl("sl_deserialize_sketch_transform", \ json.dumps(d["_obj"]), byref(sketch_transform)) self._obj = sketch_transform.value except: pass
def deserialize_sketch(sketch_dict): """ Load Serialized Transform :param sketch_dict dictionary that is the sketch in serialized form (from .serialize()). """ sketch_transform = c_void_p() lib.callsl("sl_deserialize_sketch_transform", \ json.dumps(sketch_dict), byref(sketch_transform)) sketch_name = str(sketch_dict['sketch_type']) return _map_csketch_type_to_cfun[sketch_name](sketch_dict, sketch_transform)
def __init__(self, n, s, sigma=1.0, skip=0, defouttype=None, forceppy=False, sketch_transform=None): super(LaplacianQRFT, self)._baseinit("LaplacianQRFT", n, s, defouttype, forceppy) if not self._ppy: if sketch_transform is None: sketch_transform = c_void_p() lib.callsl("sl_create_sketch_transform", lib.ctxt_obj, "LaplacianQRFT", n, s, \ byref(sketch_transform), ctypes.c_double(sigma), c_int(skip)) self._obj = sketch_transform else: self._obj = sketch_transform
def __init__(self, n, s, nu, l, defouttype=None, forceppy=False, sketch_transform=None): super(MaternRFT, self)._baseinit("MaternRFT", n, s, defouttype, forceppy) if not self._ppy: if sketch_transform is None: sketch_transform = c_void_p() lib.callsl("sl_create_sketch_transform", lib.ctxt_obj, "MaternRFT", n, s, \ byref(sketch_transform), ctypes.c_double(nu), ctypes.c_double(l)) self._obj = sketch_transform else: self._obj = sketch_transform
def __init__(self, n, s, beta=1.0, defouttype=None, forceppy=False, sketch_transform=None): super(ExpSemigroupQRLT, self)._baseinit("ExpSemigroupQRLT", n, s, defouttype, forceppy) self._beta = beta if not self._ppy: if sketch_transform is None: sketch_transform = c_void_p() lib.callsl("sl_create_sketch_transform", lib.ctxt_obj, "ExpSemigroupQRLT", n, s, \ byref(sketch_transform), ctypes.c_double(beta)) self._obj = sketch_transform else: self._obj = sketch_transform
def __init__(self, n, s, C, defouttype=None, forceppy=False, sketch_transform=None): super(CT, self)._baseinit("CT", n, s, defouttype, forceppy) if self._ppy: self._S = numpy.random.standard_cauchy((s, n)) * (C / s) else: if sketch_transform is None: sketch_transform = c_void_p() lib.callsl("sl_create_sketch_transform", lib.ctxt_obj, "CT", n, s, \ byref(sketch_transform), ctypes.c_double(C)) self._obj = sketch_transform else: self._obj = sketch_transform
def __init__(self, n, s, sigma=1.0, defouttype=None, forceppy=False, sketch_transform=None): super(GaussianRFT, self)._baseinit("GaussianRFT", n, s, defouttype, forceppy) self._sigma = sigma if self._ppy: self._T = JLT(n, s, forceppy=forceppy) self._b = numpy.matrix(numpy.random.uniform(0, 2 * pi, (s,1))) else: if sketch_transform is None: sketch_transform = c_void_p() lib.callsl("sl_create_sketch_transform", lib.ctxt_obj, "GaussianRFT", n, s, \ byref(sketch_transform), ctypes.c_double(sigma)) self._obj = sketch_transform else: self._obj = sketch_transform
def __init__(self, n, s, p, defouttype=None, forceppy=False, sketch_transform=None): super(WZT, self)._baseinit("WZT", n, s, defouttype, forceppy) if self._ppy: # The following is not memory efficient, but for a pure Python impl # it will do distribution = WZT._WZTDistribution(p) self._S = _hashmap(s, n, distribution, dimension = 0) else: if sketch_transform is None: sketch_transform = c_void_p() lib.callsl("sl_create_sketch_transform", lib.ctxt_obj, "WZT", n, s, \ byref(sketch_transform), ctypes.c_double(p)) self._obj = sketch_transform else: self._obj = sketch_transform
def __init__(self, n, s, sigma=1.0, defouttype=None, forceppy=False, sketch_transform=None): super(LaplacianRFT, self)._baseinit("LaplacianRFT", n, s, defouttype, forceppy) if not self._ppy: if sketch_transform is None: sketch_transform = c_void_p() lib.callsl("sl_create_sketch_transform", lib.ctxt_obj, "LaplacianRFT", n, s, \ byref(sketch_transform), ctypes.c_double(sigma)) self._obj = sketch_transform else: self._obj = sketch_transform
def __init__(self, n, s, sigma=1.0, defouttype=None, forceppy=False, sketch_transform=None): super(FastGaussianRFT, self)._baseinit("FastGaussianRFT", n, s, defouttype, forceppy); self._sigma = sigma if self._ppy: self._blocks = int(math.ceil(float(s) / n)) self._sigma = sigma self._b = numpy.matrix(numpy.random.uniform(0, 2 * pi, (s,1))) binary = scipy.stats.bernoulli(0.5) self._B = [2.0 * binary.rvs(n) - 1.0 for i in range(self._blocks)] self._G = [numpy.random.randn(n) for i in range(self._blocks)] self._P = [numpy.random.permutation(n) for i in range(self._blocks)] else: if sketch_transform is None: sketch_transform = c_void_p() lib.callsl("sl_create_sketch_transform", lib.ctxt_obj, "FastGaussianRFT", n, s, \ byref(sketch_transform), ctypes.c_double(sigma)) self._obj = sketch_transform else: self._obj = sketch_transform
def __init__(self, n, s, q=3, c=0, gamma=1, defouttype=None, forceppy=False, sketch_transform=None): super(PPT, self)._baseinit("PPT", n, s, defouttype, forceppy); if c < 0: raise ValueError("c parameter must be >= 0") if self._ppy: self._q = q self._gamma = gamma self._c = c self._css = [CWT(n + (c > 0), s, forceppy=forceppy) for i in range(q)] else: if sketch_transform is None: sketch_transform = c_void_p() lib.callsl("sl_create_sketch_transform", lib.ctxt_obj, "PPT", n, s, \ byref(sketch_transform), \ ctypes.c_int(q), ctypes.c_double(c), ctypes.c_double(gamma)) self._obj = sketch_transform else: self._obj = sketch_transform
def serialize(self): """ Returns a dictionary that is the sketch in a serialized for. That is, the sketch object can be reconstructed using the deserialize_sketch function. """ if not self._ppy: json_data = c_char_p() lib.callsl("sl_serialize_sketch_transform", self._obj, byref(json_data)) try: serialized_sketch = json.loads(json_data.value) except ValueError: _libc.free(json_data) print "Failed to parse JSON" else: _libc.free(json_data) return serialized_sketch else: # TODO: python serialization of sketch pass
def __init__(self, n, s, nu, l, defouttype=None, forceppy=False, sketch_transform=None): super(FastMaternRFT, self)._baseinit("FastMaternRFT", n, s, defouttype, forceppy) self._nu = nu self._l = l if not self._ppy: if sketch_transform is None: sketch_transform = c_void_p() lib.callsl("sl_create_sketch_transform", lib.ctxt_obj, "FastMaternRFT", n, s, \ byref(sketch_transform), ctypes.c_double(nu), ctypes.c_double(l)) self._obj = sketch_transform else: self._obj = sketch_transform
def __init__(self, n, s, sigma=1.0, defouttype=None, forceppy=False, sketch_transform=None): super(GaussianRFT, self)._baseinit("GaussianRFT", n, s, defouttype, forceppy) self._sigma = sigma if self._ppy: self._T = JLT(n, s, forceppy=forceppy) self._b = numpy.matrix(numpy.random.uniform(0, 2 * pi, (s, 1))) else: if sketch_transform is None: sketch_transform = c_void_p() lib.callsl("sl_create_sketch_transform", lib.ctxt_obj, "GaussianRFT", n, s, \ byref(sketch_transform), ctypes.c_double(sigma)) self._obj = sketch_transform else: self._obj = sketch_transform
def __init__(self, n, s, p, defouttype=None, forceppy=False, sketch_transform=None): super(WZT, self)._baseinit("WZT", n, s, defouttype, forceppy) if self._ppy: # The following is not memory efficient, but for a pure Python impl # it will do distribution = WZT._WZTDistribution(p) self._S = _hashmap(s, n, distribution, dimension=0) else: if sketch_transform is None: sketch_transform = c_void_p() lib.callsl("sl_create_sketch_transform", lib.ctxt_obj, "WZT", n, s, \ byref(sketch_transform), ctypes.c_double(p)) self._obj = sketch_transform else: self._obj = sketch_transform
def __del__(self): if not self._ppy: lib.callsl("sl_free_sketch_transform", self._obj)
def apply(self, A, SA, dim=0): """ Apply the transform on **A** along dimension **dim** and write result in **SA**. Note: for rowwise (aka right) sketching **A** is mapped to **A S^T**. :param A: Input matrix. :param SA: Ouptut matrix. If "None" then the output will be allocated. :param dim: Dimension to apply along. 0 - columnwise, 1 - rowwise. or can use "columnwise"/"rowwise", "left"/"right" default is columnwise :returns: SA """ if dim == 0 or dim == "columnwise" or dim == "left": dim = 0 if dim == "rowwise" or dim == "right": dim = 1 if dim != 0 and dim != 1: raise ValueError( "Dimension must be either columnwise/rowwise or left/right or 0/1" ) A = lib.adapt(A) # Allocate in case SA is not given, and then adapt it. if SA is None: if self._defouttype is None: ctor = A.getctor() else: ctor = lib.map_to_ctor[self._defouttype] if dim == 0: SA = ctor(self._s, A.getdim(1), A) if dim == 1: SA = ctor(A.getdim(0), self._s, A) SA = lib.adapt(SA) reqcomb = (self._ttype, A.ctype(), SA.ctype()) if reqcomb not in SUPPORTED_SKETCH_TRANSFORMS: raise errors.UnsupportedError("Unsupported transform-input-output combination: " \ + str(reqcomb)) incomp, cinvert = A.iscompatible(SA) if incomp is not None: raise errors.UnsupportedError( "Input and output are incompatible: " + incomp) if A.getdim(dim) != self._n: raise errors.DimensionMistmatchError( "Sketched dimension is incorrect (input)") if SA.getdim(dim) != self._s: raise errors.DimensionMistmatchError( "Sketched dimension is incorrect (output)") if A.getdim(1 - dim) != SA.getdim(1 - dim): raise errors.DimensionMistmatchError( "Sketched dimension is incorrect (input != output)") if self._ppy: self._ppyapply(A.getobj(), SA.getobj(), dim) else: Aobj = A.ptr() SAobj = SA.ptr() if (Aobj == -1 or SAobj == -1): raise errors.InvalidObjectError( "Invalid/unsupported object passed as A or SA") if cinvert: cdim = 1 - dim else: cdim = dim lib.callsl("sl_apply_sketch_transform", self._obj, \ A.ctype(), Aobj, SA.ctype(), SAobj, cdim+1) A.ptrcleaner() SA.ptrcleaner() return SA.getobj()
def apply(self, A, SA, dim=0): """ Apply the transform on **A** along dimension **dim** and write result in **SA**. Note: for rowwise (aka right) sketching **A** is mapped to **A S^T**. :param A: Input matrix. :param SA: Ouptut matrix. If "None" then the output will be allocated. :param dim: Dimension to apply along. 0 - columnwise, 1 - rowwise. or can use "columnwise"/"rowwise", "left"/"right" default is columnwise :returns: SA """ if dim == 0 or dim == "columnwise" or dim == "left": dim = 0 if dim == "rowwise" or dim == "right": dim = 1 if dim != 0 and dim != 1: raise ValueError("Dimension must be either columnwise/rowwise or left/right or 0/1") A = lib.adapt(A) # Allocate in case SA is not given, and then adapt it. if SA is None: if self._defouttype is None: ctor = A.getctor() else: ctor = lib.map_to_ctor[self._defouttype] if dim == 0: SA = ctor(self._s, A.getdim(1), A) if dim == 1: SA = ctor(A.getdim(0), self._s, A) SA = lib.adapt(SA) reqcomb = (self._ttype, A.ctype(), SA.ctype()) if reqcomb not in SUPPORTED_SKETCH_TRANSFORMS: raise errors.UnsupportedError("Unsupported transform-input-output combination: " \ + str(reqcomb)) incomp, cinvert = A.iscompatible(SA) if incomp is not None: raise errors.UnsupportedError("Input and output are incompatible: " + incomp) if A.getdim(dim) != self._n: raise errors.DimensionMistmatchError("Sketched dimension is incorrect (input)") if SA.getdim(dim) != self._s: raise errors.DimensionMistmatchError("Sketched dimension is incorrect (output)") if A.getdim(1 - dim) != SA.getdim(1 - dim): raise errors.DimensionMistmatchError("Sketched dimension is incorrect (input != output)") if self._ppy: self._ppyapply(A.getobj(), SA.getobj(), dim) else: Aobj = A.ptr() SAobj = SA.ptr() if (Aobj == -1 or SAobj == -1): raise errors.InvalidObjectError("Invalid/unsupported object passed as A or SA") if cinvert: cdim = 1 - dim else: cdim = dim lib.callsl("sl_apply_sketch_transform", self._obj, \ A.ctype(), Aobj, SA.ctype(), SAobj, cdim+1) A.ptrcleaner() SA.ptrcleaner() return SA.getobj()