def isin(element, test_elements, assume_unique=False, invert=False): if isinstance(element, BlockVector) and isinstance(test_elements, BlockVector): assert not element.has_none, 'Operation not allowed with None blocks. Specify all blocks in BlockVector' assert not test_elements.has_none, 'Operation not allowed with None blocks. Specify all blocks in BlockVector' assert element.nblocks == test_elements.nblocks, 'Operation on BlockVectors need the same number of blocks on each operand' res = BlockVector(element.nblocks) for i in range(element.nblocks): res[i] = isin(element[i], test_elements[i], assume_unique=assume_unique, invert=invert) return res elif isinstance(element, BlockVector) and isinstance(test_elements, np.ndarray): assert not element.has_none, 'Operation not allowed with None blocks. Specify all blocks in BlockVector' res = BlockVector(element.nblocks) for i in range(element.nblocks): res[i] = isin(element[i], test_elements, assume_unique=assume_unique, invert=invert) return res elif isinstance(element, np.ndarray) and isinstance(test_elements, np.ndarray): return np.isin(element, test_elements, assume_unique=assume_unique, invert=invert) else: raise NotImplementedError()
def test_compress(self): v = self.ones with self.assertRaises(NotImplementedError) as ctx: vv = v.compress(1, out=1) v = BlockVector(2) a = np.ones(5) b = np.zeros(9) v[0] = a v[1] = b c = v.compress(v < 1) v2 = BlockVector(2) b = np.zeros(9) v2[0] = np.ones(0) v2[1] = b self.assertEqual(c.nblocks, v.nblocks) for bid, blk in enumerate(c): self.assertTrue(np.allclose(blk, v2[bid])) flags = v < 1 c = v.compress(flags.flatten()) self.assertEqual(c.nblocks, v.nblocks) for bid, blk in enumerate(c): self.assertTrue(np.allclose(blk, v2[bid])) with self.assertRaises(Exception) as context: v.compress(1.0)
def test_compress(self): v = self.ones v = BlockVector(2) a = np.ones(5) b = np.zeros(9) v.set_block(0, a) v.set_block(1, b) c = v.compress(v < 1) v2 = BlockVector(2) b = np.zeros(9) v2.set_block(0, np.ones(0)) v2.set_block(1, b) self.assertEqual(c.nblocks, v.nblocks) for bid, blk in enumerate(c): self.assertTrue(np.allclose(blk, v2.get_block(bid))) flags = v < 1 c = v.compress(flags.flatten()) self.assertEqual(c.nblocks, v.nblocks) for bid, blk in enumerate(c): self.assertTrue(np.allclose(blk, v2.get_block(bid))) with self.assertRaises(Exception) as context: v.compress(1.0)
def test_binary_ufuncs(self): v = BlockVector(2) a = np.ones(3) * 0.5 b = np.ones(2) * 0.8 v[0] = a v[1] = b v2 = BlockVector(2) a2 = np.ones(3) * 3.0 b2 = np.ones(2) * 2.8 v2[0] = a2 v2[1] = b2 binary_ufuncs = [np.add, np.multiply, np.divide, np.subtract, np.greater, np.greater_equal, np.less, np.less_equal, np.not_equal, np.maximum, np.minimum, np.fmax, np.fmin, np.equal, np.logaddexp, np.logaddexp2, np.remainder, np.heaviside, np.hypot] for fun in binary_ufuncs: flat_res = fun(v.flatten(), v2.flatten()) res = fun(v, v2) self.assertTrue(np.allclose(flat_res, res.flatten())) res = fun(v, v2.flatten()) self.assertTrue(np.allclose(flat_res, res.flatten())) res = fun(v.flatten(), v2) self.assertTrue(np.allclose(flat_res, res.flatten())) flat_res = fun(v.flatten(), 5) res = fun(v, 5) self.assertTrue(np.allclose(flat_res, res.flatten())) flat_res = fun(3.0, v2.flatten()) res = fun(3.0, v2) self.assertTrue(np.allclose(flat_res, res.flatten())) v = BlockVector(2) a = np.ones(3, dtype=bool) b = np.ones(2, dtype=bool) v[0] = a v[1] = b v2 = BlockVector(2) a2 = np.zeros(3, dtype=bool) b2 = np.zeros(2, dtype=bool) v2[0] = a2 v2[1] = b2 binary_ufuncs = [np.logical_and, np.logical_or, np.logical_xor] for fun in binary_ufuncs: flat_res = fun(v.flatten(), v2.flatten()) res = fun(v, v2) self.assertTrue(np.allclose(flat_res, res.flatten()))
def __mul__(self, other): """ When doing A*B with numpy arrays, element-by-element multiplication is done. However, when doing A*B with scipy sparse matrices, a matrix-matrix dot product is performed. We are following the scipy sparse matrix API. """ bm, bn = self.bshape if np.isscalar(other): return self._binary_operation_helper(other, operator.mul) elif isinstance(other, BlockVector): assert bn == other.bshape[0], 'Dimension mismatch' assert self.shape[1] == other.shape[0], 'Dimension mismatch' assert not other.has_none, 'Block vector must not have none entries' assert_block_structure(self) nblocks = self.bshape[0] result = BlockVector(nblocks) for i in range(bm): result.set_block(i, np.zeros(self._brow_lengths[i])) for i, j in zip(*np.nonzero(self._block_mask)): x = other.get_block(j) A = self._blocks[i, j] blk = result.get_block(i) _tmp = A * x _tmp += blk result.set_block(i, _tmp) return result elif isinstance(other, np.ndarray): if other.ndim != 1: raise NotImplementedError( 'Operation not supported by BlockMatrix') assert self.shape[1] == other.shape[0], \ 'Dimension mismatch {}!={}'.format(self.shape[1], other.shape[0]) assert_block_structure(self) nblocks = self.bshape[0] result = BlockVector(nblocks) for i in range(bm): result.set_block(i, np.zeros(self._brow_lengths[i])) counter = 0 for j in range(bn): if not self.is_empty_block(i, j): A = self._blocks[i, j] x = other[counter:counter + A.shape[1]] blk = result.get_block(i) blk += A * x counter += self.get_col_size(j) return result elif isinstance(other, BlockMatrix) or isspmatrix(other): assert_block_structure(self) return self._mul_sparse_matrix(other) else: return NotImplemented
def test_any(self): v = BlockVector(2) a = np.zeros(5) b = np.ones(3) v[0] = a v[1] = b self.assertTrue(v.any()) v = BlockVector(2) a = np.zeros(5) b = np.zeros(3) v[0] = a v[1] = b self.assertFalse(v.any())
def test_any(self): v = BlockVector(2) a = np.zeros(5) b = np.ones(3) v.set_block(0, a) v.set_block(1, b) self.assertTrue(v.any()) v = BlockVector(2) a = np.zeros(5) b = np.zeros(3) v.set_block(0, a) v.set_block(1, b) self.assertFalse(v.any())
def __mul__(self, other): self._check_mask() bm = self.bshape[0] if np.isscalar(other): result = BlockSymMatrix(bm) ii, jj = np.nonzero(self._block_mask) for i, j in zip(ii, jj): if not self.is_empty_block(i, j): scaled = self._blocks[i, j] * other result[i, j] = scaled return result elif isinstance(other, BlockVector): assert bm == other.bshape[0], 'Dimension missmatch' assert self.shape[1] == other.shape[0], 'Dimension missmatch' other._check_mask() nblocks = self.bshape[0] result = BlockVector(nblocks) # initialize in zeros the result for i in range(bm): result[i] = np.zeros(self._brow_lengths[i]) # populate result for i in range(bm): for j in range(bm): x = other[ j] # this flattens block vectors that are within block vectors if not self.is_empty_block(i, j): A = self._blocks[i, j] result[i] += A * x if i != j: if not self.is_empty_block(i, j): x = other[i] A = self._blocks[i, j].transpose() result[j] += A * x return result elif isinstance(other, np.ndarray): assert self.shape[1] == other.shape[0], 'Dimension missmatch' nblocks = self.bshape[0] block_x = BlockVector(nblocks) for i in range(bm): block_x[i] = np.zeros(self._bcol_lengths[i]) block_x.copyfrom(other) return self.__mul__(block_x) else: raise NotImplementedError('not implemented')
def test_mean(self): flat_v = np.ones(self.ones.size) v = self.ones self.assertEqual(v.mean(), flat_v.mean()) v = BlockVector(2) with self.assertRaises(NotFullyDefinedBlockVectorError): v_mean = v.mean()
def test_lt(self): v = BlockVector(2) a = np.ones(5) b = np.zeros(9) v[0] = a v[1] = b flags = v < 1 v[0] = a-1 v[1] = b+1 self.assertEqual(v.nblocks, flags.nblocks) for bid, blk in enumerate(flags): self.assertTrue(np.allclose(blk, v[bid])) v[0] = a + 1 v[1] = b - 1 flags = v < np.ones(v.size) v[0] = a - 1 v[1] = b + 1 self.assertEqual(v.nblocks, flags.nblocks) for bid, blk in enumerate(flags): self.assertTrue(np.allclose(blk, v[bid])) v[0] = a + 1 v[1] = b - 1 vv = v.copy() vv.fill(1.0) flags = v < vv v[0] = a - 1 v[1] = b + 1 self.assertEqual(v.nblocks, flags.nblocks) for bid, blk in enumerate(flags): self.assertTrue(np.allclose(blk, v[bid]))
def test_nonzero(self): v = BlockVector(2) a = np.ones(5) b = np.zeros(9) v[0] = a v[1] = b n = v.nonzero() v2 = BlockVector(2) v2[0] = np.arange(5) v2[1] = np.zeros(0) self.assertEqual(n[0].nblocks, v.nblocks) for bid, blk in enumerate(n[0]): self.assertTrue(np.allclose(blk, v2[bid]))
def test_le(self): v = BlockVector(2) a = np.ones(5) b = np.zeros(9) v[0] = a v[1] = b flags = v <= 1 v[1] = b + 1 self.assertEqual(v.nblocks, flags.nblocks) for bid, blk in enumerate(flags): self.assertTrue(np.allclose(blk, v[bid])) flags = v <= v vv = v.copy() vv.fill(1.0) self.assertEqual(v.nblocks, flags.nblocks) for bid, blk in enumerate(flags): self.assertTrue(np.allclose(blk, vv[bid])) flags = v <= v.flatten() vv = v.copy() vv.fill(1.0) self.assertEqual(v.nblocks, flags.nblocks) for bid, blk in enumerate(flags): self.assertTrue(np.allclose(blk, vv[bid]))
def test_le(self): v = BlockVector(2) a = np.ones(5) b = np.zeros(9) v.set_block(0, a) v.set_block(1, b) flags = v <= 1 v.set_block(1, b + 1) self.assertEqual(v.nblocks, flags.nblocks) for bid, blk in enumerate(flags): self.assertTrue(np.allclose(blk, v.get_block(bid))) flags = v <= v vv = v.copy() vv.fill(1.0) self.assertEqual(v.nblocks, flags.nblocks) for bid, blk in enumerate(flags): self.assertTrue(np.allclose(blk, vv.get_block(bid))) flags = v <= v.flatten() vv = v.copy() vv.fill(1.0) self.assertEqual(v.nblocks, flags.nblocks) for bid, blk in enumerate(flags): self.assertTrue(np.allclose(blk, vv.get_block(bid)))
def test_nonzero(self): v = BlockVector(2) a = np.ones(5) b = np.zeros(9) v.set_block(0, a) v.set_block(1, b) n = v.nonzero() v2 = BlockVector(2) v2.set_block(0, np.arange(5)) v2.set_block(1, np.zeros(0)) self.assertEqual(n[0].nblocks, v.nblocks) for bid, blk in enumerate(n[0]): self.assertTrue(np.allclose(blk, v2.get_block(bid)))
def test_ge(self): v = BlockVector(2) a = np.ones(5) b = np.zeros(9) v.set_block(0, a) v.set_block(1, b) flags = v >= 0 v.set_block(1, b + 1) self.assertEqual(v.nblocks, flags.nblocks) for bid, blk in enumerate(flags): self.assertTrue(np.allclose(blk, v.get_block(bid))) v.set_block(1, b - 1) flags = v >= np.zeros(v.size) v.set_block(1, b) self.assertEqual(v.nblocks, flags.nblocks) for bid, blk in enumerate(flags): self.assertTrue(np.allclose(blk, v.get_block(bid))) v.set_block(1, b - 1) vv = v.copy() vv.fill(0.0) flags = v >= vv v.set_block(1, b) self.assertEqual(v.nblocks, flags.nblocks) for bid, blk in enumerate(flags): self.assertTrue(np.allclose(blk, v.get_block(bid)))
def __mul__(self, other): self._check_mask() bm, bn = self.bshape if np.isscalar(other): result = BlockMatrix(bm, bn) ii, jj = np.nonzero(self._block_mask) for i, j in zip(ii, jj): scaled = self._blocks[i, j] * other result[i, j] = scaled return result elif isinstance(other, BlockVector): assert bn == other.bshape[0], 'Dimension mismatch' assert self.shape[1] == other.shape[0], 'Dimension mismatch' other._check_mask() nblocks = self.bshape[0] result = BlockVector(nblocks) for i in range(bm): result[i] = np.zeros(self._brow_lengths[i]) for j in range(bn): x = other[ j] # this flattens block vectors that are within block vectors if not self.is_empty_block(i, j): A = self._blocks[i, j] result[i] += A * x return result elif isinstance(other, np.ndarray): assert self.shape[1] == other.shape[ 0], 'Dimension mismatch {}!={}'.format(self.shape[1], other.shape[0]) nblocks = self.bshape[0] result = BlockVector(nblocks) for i in range(bm): result[i] = np.zeros(self._brow_lengths[i]) counter = 0 for j in range(bn): if not self.is_empty_block(i, j): A = self._blocks[i, j] x = other[counter:counter + A.shape[1]] result[i] += A * x counter += A.shape[0] return result elif isinstance(other, BlockMatrix) or isspmatrix(other): return self._mul_sparse_matrix(other) else: raise NotImplementedError( 'input not recognized for multiplication')
def test_flatten(self): v = BlockVector(2) a = np.arange(5) b = np.arange(9) c = np.concatenate([a, b]) v.set_block(0, a) v.set_block(1, b) self.assertListEqual(v.flatten().tolist(), c.tolist())
def test_constructor(self): v = BlockVector(2) self.assertEqual(v.nblocks, 2) self.assertEqual(v.bshape, (2, )) with self.assertRaises(NotFullyDefinedBlockVectorError): v_size = v.size v.set_block(0, np.ones(2)) v.set_block(1, np.ones(4)) self.assertEqual(v.size, 6) self.assertEqual(v.shape, (6, )) with self.assertRaises(AssertionError): v.set_block(0, None) with self.assertRaises(Exception) as context: BlockVector('hola')
def test_flatten(self): v = BlockVector(2) a = np.arange(5) b = np.arange(9) c = np.concatenate([a, b]) v[0] = a v[1] = b self.assertListEqual(v.flatten().tolist(), c.tolist())
def test_copy(self): v = BlockVector(2) a = np.ones(5) b = np.zeros(9) v.set_block(0, a) v.set_block(1, b) v2 = v.copy() self.assertTrue(np.allclose(v.flatten(), v2.flatten()))
def test_copy(self): v = BlockVector(2) a = np.ones(5) b = np.zeros(9) v[0] = a v[1] = b v2 = v.copy() self.assertTrue(np.allclose(v.flatten(), v2.flatten()))
def intersect1d(ar1, ar2, assume_unique=False, return_indices=False): if return_indices: raise NotImplementedError() if isinstance(ar1, tuple) and len(ar1) == 1: x = ar1[0] elif isinstance(ar1, np.ndarray) or isinstance(ar1, BlockVector): x = ar1 else: raise RuntimeError('ar1 type not recognized. Needs to be np.ndarray or BlockVector') if isinstance(ar2, tuple) and len(ar2) == 1: y = ar2[0] elif isinstance(ar2, np.ndarray) or isinstance(ar1, BlockVector): y = ar2 else: raise RuntimeError('ar2 type not recognized. Needs to be np.ndarray or BlockVector') if isinstance(x, BlockVector) and isinstance(y, BlockVector): assert x.nblocks == y.nblocks, "Number of blocks does not match" assert not x.has_none, 'Operation not allowed with None blocks. Specify all blocks in BlockVector' assert not y.has_none, 'Operation not allowed with None blocks. Specify all blocks in BlockVector' res = BlockVector(x.nblocks) for i in range(x.nblocks): res.set_block(i, intersect1d(x.get_block(i), y.get_block(i), assume_unique=assume_unique)) return res elif isinstance(x, BlockVector) and isinstance(y, np.ndarray): assert not x.has_none, 'Operation not allowed with None blocks. Specify all blocks in BlockVector' res = BlockVector(x.nblocks) for i in range(x.nblocks): res.set_block(i, np.intersect1d(x.get_block(i), y, assume_unique=assume_unique)) return res elif isinstance(x, np.ndarray) and isinstance(y, BlockVector): assert not y.has_none, 'Operation not allowed with None blocks. Specify all blocks in BlockVector' res = BlockVector(y.nblocks) for i in range(y.nblocks): res.set_block(i, np.intersect1d(x, y.get_block(i), assume_unique=assume_unique)) return res else: return np.intersect1d(x, y, assume_unique=assume_unique)
def test_iadd(self): v = self.ones v += 3 self.assertListEqual(v.tolist(), [4] * v.size) v.fill(1.0) v += v self.assertListEqual(v.tolist(), [2] * v.size) v.fill(1.0) v += np.ones(v.size) * 3 self.assertTrue(np.allclose(v.flatten(), np.ones(v.size) * 4)) v = BlockVector(2) a = np.ones(5) b = np.zeros(9) a_copy = a.copy() b_copy = b.copy() v.set_block(0, a) v.set_block(1, b) v += 1.0 self.assertTrue(np.allclose(v.get_block(0), a_copy + 1)) self.assertTrue(np.allclose(v.get_block(1), b_copy + 1)) v = BlockVector(2) a = np.ones(5) b = np.zeros(9) a_copy = a.copy() b_copy = b.copy() v.set_block(0, a) v.set_block(1, b) v2 = BlockVector(2) v2.set_block(0, np.ones(5)) v2.set_block(1, np.ones(9)) v += v2 self.assertTrue(np.allclose(v.get_block(0), a_copy + 1)) self.assertTrue(np.allclose(v.get_block(1), b_copy + 1)) self.assertTrue(np.allclose(v2.get_block(0), np.ones(5))) self.assertTrue(np.allclose(v2.get_block(1), np.ones(9))) with self.assertRaises(Exception) as context: v += 'hola'
def test_copy_structure(self): v = BlockVector(2) a = np.ones(5) b = np.zeros(9) v.set_block(0, a) v.set_block(1, b) v2 = v.copy_structure() self.assertEqual(v.get_block(0).size, v2.get_block(0).size) self.assertEqual(v.get_block(1).size, v2.get_block(1).size)
def test_copyfrom(self): v = self.ones v1 = np.zeros(v.size) v.copyfrom(v1) self.assertListEqual(v.tolist(), v1.tolist()) v2 = BlockVector(len(self.list_sizes_ones)) for i, s in enumerate(self.list_sizes_ones): v2[i] = np.ones(s)*i v.copyfrom(v2) for idx, blk in enumerate(v2): self.assertListEqual(blk.tolist(), v2[idx].tolist()) v3 = BlockVector(2) v4 = v.clone(2) v3[0] = v4 v3[1] = np.zeros(3) self.assertListEqual(v3.tolist(), v4.tolist() + [0]*3)
def test_min(self): self.assertEqual(self.ones.min(), 1) v = BlockVector(2) a = np.arange(5) b = np.arange(9) c = np.concatenate([a, b]) v.set_block(0, a) v.set_block(1, b) self.assertEqual(v.min(), c.min())
def test_copyfrom(self): v = self.ones v1 = np.zeros(v.size) v.copyfrom(v1) self.assertListEqual(v.tolist(), v1.tolist()) v2 = BlockVector(len(self.list_sizes_ones)) for i, s in enumerate(self.list_sizes_ones): v2.set_block(i, np.ones(s) * i) v.copyfrom(v2) for idx, blk in enumerate(v2): self.assertListEqual(blk.tolist(), v2.get_block(idx).tolist()) v3 = BlockVector(2) v4 = v.clone(2) v3.set_block(0, v4) v3.set_block(1, np.zeros(3)) self.assertListEqual(v3.tolist(), v4.tolist() + [0] * 3)
def test_has_none(self): v = self.ones self.assertFalse(v.has_none) v = BlockVector(3) v.set_block(0, np.ones(2)) v.set_block(2, np.ones(3)) self.assertTrue(v.has_none) v.set_block(1, np.ones(2)) self.assertFalse(v.has_none)
def test_fill(self): v = BlockVector(2) a = np.arange(5) b = np.arange(9) v.set_block(0, a) v.set_block(1, b) v.fill(1.0) c = np.ones(v.size) self.assertListEqual(v.tolist(), c.tolist())
def test_argmin(self): v = BlockVector(3) a = np.array([3, 2, 1]) v.set_block(0, a.copy()) v.set_block(1, a.copy()) v.set_block(2, a.copy()) v.get_block(1)[1] = -5 argmin = v.argmin() self.assertEqual(argmin, 4)