Skip to content

Commit 4458c65

Browse files
author
counterclocker
committed
added delete_cols to LLSparseMatrix
1 parent 0888bbc commit 4458c65

8 files changed

Lines changed: 6520 additions & 4025 deletions

File tree

cysparse/sparse/ll_mat_matrices/ll_mat.cpx

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -507,6 +507,83 @@ cdef class LLSparseMatrix_@index@_@type@(MutableSparseMatrix_@index@_@type@):
507507
self.__nrow = newm
508508
self.__nnz = newnnz
509509

510+
def delete_cols(self, B):
511+
"""
512+
Delete columns.
513+
514+
Args:
515+
B: List or :program:`NumPy` array with indices of the rows to be deleted.
516+
"""
517+
# TODO: this code is very slow...
518+
if self.__is_symmetric:
519+
raise NotImplementedError('This method is not allowed for symmetric matrices')
520+
521+
cdef:
522+
@index@ ncol, col
523+
@index@ * col_indices
524+
@index@ * shift
525+
@index@ newn
526+
527+
col_indices = create_c_array_indices_from_python_object_@index@(self.__ncol, <PyObject *> B, &ncol)
528+
529+
# find shift in kept column indices
530+
shift = <@index@ *> malloc(self.__ncol*sizeof(@index@))
531+
newn = self.__ncol
532+
533+
# shift is only valid for the column indices we keep
534+
# after deletion col[i] = col[i] - shift[i]
535+
if find_linear_@index@_@index@(0, col_indices, 0, ncol) == ncol: # keep first column
536+
shift[0] = 0
537+
else: # drop first column
538+
shift[0] = 1
539+
newn -= 1
540+
541+
for col from 1 <= col < self.__ncol:
542+
if find_linear_@index@_@index@(col, col_indices, 0, ncol) == ncol: # keep column
543+
shift[col] = shift[col - 1]
544+
else: # drop column
545+
shift[col] = shift[col - 1] + 1
546+
newn -= 1
547+
548+
# Delete the cols
549+
cdef:
550+
@index@ row, old, act
551+
@index@ newnnz = self.__nnz
552+
553+
for row from 0<= row < self.__nrow:
554+
old = -1
555+
act = self.root[row]
556+
557+
while act != -1:
558+
559+
if find_linear_@index@_@index@(self.col[act], col_indices, 0, ncol) == ncol: # keep column
560+
self.col[act] -= shift[self.col[act]]
561+
old = act
562+
act = self.link[act]
563+
else: # drop column
564+
newnnz -= 1
565+
if self.root[row] == act: # Special case: first row element
566+
self.root[row] = self.link[act]
567+
old = act
568+
act = self.link[act]
569+
self.link[old] = self.free # Append element into freelist
570+
self.free = old
571+
else: # Regular case: element inbetween
572+
act = self.link[act]
573+
self.link[self.link[old]] = self.free
574+
self.free = self.link[old]
575+
self.link[old] = act # Append element into freelist
576+
577+
578+
# Update
579+
self.__ncol = newn
580+
self.__nnz = newnnz
581+
582+
583+
PyMem_Free(col_indices)
584+
free(shift)
585+
586+
510587
def clear_submatrix(self, @index@ start_i, @index@ stop_i, @index@ start_j, @index@ stop_j):
511588
"""
512589
Remove all non zero entries in ``A[start_i:stop_i, start_j: stop_j]``.

cysparse/sparse/ll_mat_matrices/ll_mat_INT32_t_FLOAT64_t.c

Lines changed: 2479 additions & 2012 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cysparse/sparse/ll_mat_matrices/ll_mat_INT32_t_FLOAT64_t.pyx

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -507,6 +507,82 @@ cdef class LLSparseMatrix_INT32_t_FLOAT64_t(MutableSparseMatrix_INT32_t_FLOAT64_
507507
self.__nrow = newm
508508
self.__nnz = newnnz
509509

510+
def delete_cols(self, B):
511+
"""
512+
Delete columns.
513+
514+
Args:
515+
B: List or :program:`NumPy` array with indices of the rows to be deleted.
516+
"""
517+
if self.__is_symmetric:
518+
raise NotImplementedError('This method is not allowed for symmetric matrices')
519+
520+
cdef:
521+
INT32_t ncol, col
522+
INT32_t * col_indices
523+
INT32_t * shift
524+
INT32_t newn
525+
526+
col_indices = create_c_array_indices_from_python_object_INT32_t(self.__ncol, <PyObject *> B, &ncol)
527+
528+
# find shift in kept column indices
529+
shift = <INT32_t *> malloc(self.__ncol*sizeof(INT32_t))
530+
newn = self.__ncol
531+
532+
# shift is only valid for the column indices we keep
533+
# after deletion col[i] = col[i] - shift[i]
534+
if find_linear_INT32_t_INT32_t(0, col_indices, 0, ncol) == ncol: # keep first column
535+
shift[0] = 0
536+
else: # drop first column
537+
shift[0] = 1
538+
newn -= 1
539+
540+
for col from 1 <= col < self.__ncol:
541+
if find_linear_INT32_t_INT32_t(col, col_indices, 0, ncol) == ncol: # keep column
542+
shift[col] = shift[col - 1]
543+
else: # drop column
544+
shift[col] = shift[col - 1] + 1
545+
newn -= 1
546+
547+
# Delete the cols
548+
cdef:
549+
INT32_t row, old, act
550+
INT32_t newnnz = self.__nnz
551+
552+
for row from 0<= row < self.__nrow:
553+
old = -1
554+
act = self.root[row]
555+
556+
while act != -1:
557+
558+
if find_linear_INT32_t_INT32_t(self.col[act], col_indices, 0, ncol) == ncol: # keep column
559+
self.col[act] -= shift[self.col[act]]
560+
old = act
561+
act = self.link[act]
562+
else: # drop column
563+
newnnz -= 1
564+
if self.root[row] == act: # Special case: first row element
565+
self.root[row] = self.link[act]
566+
old = act
567+
act = self.link[act]
568+
self.link[old] = self.free # Append element into freelist
569+
self.free = old
570+
else: # Regular case: element inbetween
571+
act = self.link[act]
572+
self.link[self.link[old]] = self.free
573+
self.free = self.link[old]
574+
self.link[old] = act # Append element into freelist
575+
576+
577+
# Update
578+
self.__ncol = newn
579+
self.__nnz = newnnz
580+
581+
582+
PyMem_Free(col_indices)
583+
free(shift)
584+
585+
510586
def clear_submatrix(self, INT32_t start_i, INT32_t stop_i, INT32_t start_j, INT32_t stop_j):
511587
"""
512588
Remove all non zero entries in ``A[start_i:stop_i, start_j: stop_j]``.

0 commit comments

Comments
 (0)