Source code for monalisa.sparse._sparse_mat_block_partition
"""Port of src/sparseMat/m/bmSparseMat_blockPartition.m."""
import numpy as np
from monalisa._mat import fix
[docs]
def sparse_mat_block_partition(r_nJump, nJumpPerBlock_factor, blockLengthMax_factor, mode=None):
"""Partition the rows in blocks of bounded number of non-zeros.
Returns ``(l_block_start, block_length, nBlock, zero_block_flag)``; with
``mode == 'one'`` a single block holds all rows.
"""
r_nJump = np.ravel(r_nJump)
if np.sum(r_nJump) <= 0:
return None, None, None, True
if mode == "one":
return np.int32(0), np.int32(r_nJump.size), np.int32(1), False
l_nJump = r_nJump.size
r_nJump_max = float(np.max(r_nJump))
nJumpPerBlock = int(fix(float(np.ravel(nJumpPerBlock_factor)[0]) * r_nJump_max) + 1)
block_length_max = int(fix(float(np.ravel(blockLengthMax_factor)[0]) * r_nJump_max))
r = r_nJump.astype(np.int64)
starts, lengths = [], []
zero_block_flag = False
start_last = 0
length_last = 0
while True:
start = start_last + length_last
if not start < l_nJump:
break
length = 1
ind_next = start + 1
if ind_next < l_nJump:
n2 = r[start]
while ind_next < l_nJump:
n2 = n2 + r[ind_next]
if n2 < nJumpPerBlock and length < block_length_max:
length += 1
ind_next += 1
else:
break
if r[start : start + length].sum() <= 0:
zero_block_flag = True
starts.append(start)
lengths.append(length)
start_last, length_last = start, length
else:
if r[start : start + length].sum() <= 0:
zero_block_flag = True
starts.append(start)
lengths.append(length)
break
l_block_start = np.array([starts], dtype=np.int32)
block_length = np.array([lengths], dtype=np.int32)
return l_block_start, block_length, np.int32(len(starts)), zero_block_flag