docs: public static void scale_row(final int blockLength,
                                   DSubmatrixD1 A, int rowA,
                                   double alpha, DSubmatrixD1 B, int rowB,
                                   int offset, int end)
      {
          final double dataA[] = A.original.data;
          final double dataB[] = B.original.data;
  
          // handle the case where offset is more than a block
          int startI = offset - offset % blockLength;
          offset = offset % blockLength;
  
          // handle rows in any block
          int rowBlockA = A.row0 + rowA - rowA % blockLength;
          rowA = rowA % blockLength;
          int rowBlockB = B.row0 + rowB - rowB % blockLength;
          rowB = rowB % blockLength;
  
          final int heightA = Math.min(blockLength,A.row1-rowBlockA);
          final int heightB = Math.min(blockLength,B.row1-rowBlockB);
  
          for( int i = startI; i < end; i += blockLength ) {
              int segment = Math.min(blockLength,end-i);
  
              int widthA = Math.min(blockLength,A.col1-A.col0-i);
              int widthB = Math.min(blockLength,B.col1-B.col0-i);
  
              int indexA = rowBlockA*A.original.numCols + (A.col0+i)*heightA + rowA*widthA;
              int indexB = rowBlockB*B.original.numCols + (B.col0+i)*heightB + rowB*widthB;
  
              if( i == startI ) {
                  indexA += offset;
                  indexB += offset;
  
                  for( int j = offset; j < segment; j++ ) {
                      dataB[indexB++] = alpha*dataA[indexA++];
                  }
              } else {
                  for( int j = 0; j < segment; j++ ) {
                      dataB[indexB++] = alpha*dataA[indexA++];
                  }
              }
          }
      }