def __init__(self, d, ell):
        self.class_name = 'SparseSketcher_sparseMatrix'
        self.d = d
        self.ell = ell
        self._sketch = zeros((2 * self.ell, self.d))

        self.buffer_nnz_threshold = 2 * self.ell * self.d
        self.buffer = SparseMatrix(self.buffer_nnz_threshold)
class SparseSketcher(MatrixSketcherBase):

    def __init__(self, d, ell):
        self.class_name = 'SparseSketcher_sparseMatrix'
        self.d = d
        self.ell = ell
        self._sketch = zeros( (2 * self.ell, self.d) )

        self.buffer_nnz_threshold = 2 * self.ell * self.d
        self.buffer = SparseMatrix (self.buffer_nnz_threshold)

 
    def append(self, vector): 
        if (self.buffer.nnz >= self.buffer_nnz_threshold):
            self.__rotate__()

        self.buffer.append(vector)
       
      

    def __rotate__(self):
        # First shrink the buffer
        [s,vt] = blockpower(self.buffer, self.ell)

        # insert the shrunk part into the sketch
        if len(s) < self.ell:
            self._sketch[self.ell : self.ell+len(s),:] = dot(diag(s), vt[:len(s),:])
        else: #len(s) == self.ell
            sShrunk = sqrt(s[:self.ell]**2 - s[self.ell-1]**2)
            self._sketch[self.ell:,:] = dot(diag(sShrunk), vt[:self.ell,:])


        # resetting the buffer matrix
        del self.buffer
        self.buffer = lil_matrix( (self.d, self.d) )
        self.buffer_nnz = 0
        self.buffer_nextRow = 0


        # A dense shrink of the sketch
        [_,s,vt] = svd(self._sketch, full_matrices = False)
        if len(s) >= self.ell:
            sShrunk = sqrt(s[:self.ell]**2 - s[self.ell-1]**2)
            self._sketch[:self.ell,:] = dot(diag(sShrunk), vt[:self.ell,:])
            self._sketch[self.ell:,:] = 0
        else:
            self._sketch[:len(s),:] = dot(diag(s), vt[:len(s),:])
            self._sketch[len(s):,:] = 0


    def get(self):
        self.__rotate__()
        return self._sketch[:self.ell,:]
class SparseSketcher(MatrixSketcherBase):
    def __init__(self, d, ell):
        self.class_name = 'SparseSketcher_sparseMatrix'
        self.d = d
        self.ell = ell
        self._sketch = zeros((2 * self.ell, self.d))

        self.buffer_nnz_threshold = 2 * self.ell * self.d
        self.buffer = SparseMatrix(self.buffer_nnz_threshold)

    def append(self, vector):
        if (self.buffer.nnz >= self.buffer_nnz_threshold):
            self.__rotate__()

        self.buffer.append(vector)

    def __rotate__(self):
        # First shrink the buffer
        [s, vt] = blockpower(self.buffer, self.ell)

        # insert the shrunk part into the sketch
        if len(s) < self.ell:
            self._sketch[self.ell:self.ell + len(s), :] = dot(
                diag(s), vt[:len(s), :])
        else:  #len(s) == self.ell
            sShrunk = sqrt(s[:self.ell]**2 - s[self.ell - 1]**2)
            self._sketch[self.ell:, :] = dot(diag(sShrunk), vt[:self.ell, :])

        # resetting the buffer matrix
        del self.buffer
        self.buffer = lil_matrix((self.d, self.d))
        self.buffer_nnz = 0
        self.buffer_nextRow = 0

        # A dense shrink of the sketch
        [_, s, vt] = svd(self._sketch, full_matrices=False)
        if len(s) >= self.ell:
            sShrunk = sqrt(s[:self.ell]**2 - s[self.ell - 1]**2)
            self._sketch[:self.ell, :] = dot(diag(sShrunk), vt[:self.ell, :])
            self._sketch[self.ell:, :] = 0
        else:
            self._sketch[:len(s), :] = dot(diag(s), vt[:len(s), :])
            self._sketch[len(s):, :] = 0

    def get(self):
        self.__rotate__()
        return self._sketch[:self.ell, :]
    def __init__(self, d, ell):
        self.class_name = 'SparseSketcher_sparseMatrix'
        self.d = d
        self.ell = ell
        self._sketch = zeros( (2 * self.ell, self.d) )

        self.buffer_nnz_threshold = 2 * self.ell * self.d
        self.buffer = SparseMatrix (self.buffer_nnz_threshold)
from sparseMatrix import SparseMatrix

M = SparseMatrix(10, 10)
M[2, 3] = 5
print(M[2, 3])

K = SparseMatrix(10, 10)
K[3, 3] = 5
A = K + M
A.scaleBy(10)

for entry in A._entryList:
    print(entry._value, entry._row, entry._col)

B = K - M

print(A[2, 3])
print(B[2, 3])