each row is placed side-by-side with the length of the row interlaced
        the head of the packed matrix contains offsets to this length
        e.g. [[11, 22, 33], [44, 55], []] => [3, 7, 10, 3, 11, 22, 33, 2, 44, 55, 0]

def packed(self):
        """
        each row is placed side-by-side with the length of the row interlaced
        the head of the packed matrix contains offsets to this length
        e.g. [[11, 22, 33], [44, 55], []] => [3, 7, 10, 3, 11, 22, 33, 2, 44, 55, 0]
        """
        # not the most efficient implementation atm but whatever
        n_rows = len(self)
        size = len(self)*2 + self.n_edges
        packed = numpy.empty(size, self.dtype)
        offset = n_rows
        for r, row in enumerate(self):
            packed[r] = offset
            n_edges = len(row)
            packed[offset] = n_edges
            packed[(offset+1):(offset+1+n_edges)] = numpy.fromiter(row,
                                                                   self.dtype)
            offset += 1 + n_edges
        return packed