Skip to content

Commit d97ca7f

Browse files
authored
Compatibility with numpy 1.24.x (#49)
Close #48 * Replace "numpy.float" with equivalent "float" numpy.float was deprecated in 1.20 and removed in 1.24 * sptensor.ttv: support 'vector' being a plain list (rather than just numpy.ndarray). Backwards compatible - an ndarray argument still works. This is because in newer numpy, it's not allowed to do np.array(list) where the elements of list are ndarrays of different shapes. * Make ktensor.innerprod call ttv with 'vector' as plain list (instead of numpy.ndarray, because newer versions don't allow ragged arrays) * tensor.ttv: avoid ragged numpy arrays * Fix two unit test failures due to numpy related changes * More numpy updates - numpy.int is removed - use int instead - don't try to construct ragged/inhomogeneous numpy arrays in tests. Use plain lists of vectors instead * Fix typo in assert message * Let ttb.tt_dimscheck catch empty input error In the three ttv methods, ttb.tt_dimscheck checks that 'vector' argument is not an empty list/ndarray. Revert previous changes that checked for this before calling tt_dimscheck.
1 parent fbbf554 commit d97ca7f

File tree

6 files changed

+37
-39
lines changed

6 files changed

+37
-39
lines changed

pyttb/ktensor.py

+13-13
Original file line numberDiff line numberDiff line change
@@ -116,14 +116,14 @@ def from_data(cls, weights, *factor_matrices):
116116
# Create ktensor and populate data members
117117
k = cls()
118118
k.weights = weights.copy()
119-
if k.weights.dtype != np.float:
120-
print("converting weights from {} to np.float".format(k.weights.dtype))
121-
k.weights = k.weights.astype(np.float)
119+
if k.weights.dtype != float:
120+
print("converting weights from {} to float".format(k.weights.dtype))
121+
k.weights = k.weights.astype(float)
122122
k.factor_matrices = _factor_matrices
123123
for i in range(len(k.factor_matrices)):
124-
if k.factor_matrices[i].dtype != np.float:
125-
print("converting factor_matrices[{}] from {} to np.float".format(i, k.factor_matrices[i].dtype))
126-
k.factor_matrices[i] = k.factor_matrices[i].astype(np.float)
124+
if k.factor_matrices[i].dtype != float:
125+
print("converting factor_matrices[{}] from {} to float".format(i, k.factor_matrices[i].dtype))
126+
k.factor_matrices[i] = k.factor_matrices[i].astype(float)
127127

128128
return k
129129

@@ -358,7 +358,7 @@ def from_vector(cls, data, shape, contains_weights):
358358
359359
>>> rank = 2
360360
>>> shape = np.array([2, 3, 4])
361-
>>> data = np.arange(1, rank*sum(shape)+1).astype(np.float)
361+
>>> data = np.arange(1, rank*sum(shape)+1).astype(float)
362362
>>> K_without_weights = ttb.ktensor.from_vector(data[:], shape, False)
363363
>>> print(K_without_weights)
364364
ktensor of shape 2 x 3 x 4
@@ -378,7 +378,7 @@ def from_vector(cls, data, shape, contains_weights):
378378
379379
Create a `ktensor` from a vector containing elements of both the weights and the factor matrices:
380380
381-
>>> weights = 2 * np.ones(rank).astype(np.float)
381+
>>> weights = 2 * np.ones(rank).astype(float)
382382
>>> weights_and_data = np.concatenate((weights, data), axis=0)
383383
>>> K_with_weights = ttb.ktensor.from_vector(weights_and_data[:], shape, True)
384384
>>> print(K_with_weights)
@@ -882,7 +882,7 @@ def innerprod(self, other):
882882
vecs = []
883883
for n in range(self.ndims):
884884
vecs.append(self.factor_matrices[n][:, r])
885-
res = res + self.weights[r] * other.ttv(np.array(vecs))
885+
res = res + self.weights[r] * other.ttv(vecs)
886886
return res
887887

888888
def isequal(self, other):
@@ -1479,7 +1479,7 @@ def score(self, other, weight_penalty=True, threshold=0.99, greedy=True):
14791479

14801480
# Option to do greedy matching
14811481
if greedy:
1482-
best_perm = -1 * np.ones((RA), dtype=np.int)
1482+
best_perm = -1 * np.ones((RA), dtype=int)
14831483
best_score = 0
14841484
for r in range(RB):
14851485
idx = np.argmax(C.reshape(np.prod(C.shape),order='F'))
@@ -1807,11 +1807,11 @@ def ttv(self, vector, dims=None):
18071807
dims = np.array([dims])
18081808

18091809
# Check that vector is a list of vectors, if not place single vector as element in list
1810-
if len(vector.shape) == 1 and isinstance(vector[0], (int, float, np.int_, np.float_)):
1811-
return self.ttv(np.array([vector]), dims)
1810+
if len(vector) > 0 and isinstance(vector[0], (int, float, np.int_, np.float_)):
1811+
return self.ttv([vector], dims)
18121812

18131813
# Get sorted dims and index for multiplicands
1814-
dims, vidx = ttb.tt_dimscheck(dims, self.ndims, vector.shape[0])
1814+
dims, vidx = ttb.tt_dimscheck(dims, self.ndims, len(vector))
18151815

18161816
# Check that each multiplicand is the right size.
18171817
for i in range(dims.size):

pyttb/sptensor.py

+6-6
Original file line numberDiff line numberDiff line change
@@ -137,9 +137,9 @@ def from_function(cls, function_handle, shape, nonzeros):
137137
if (nonzeros < 0) or (nonzeros >= np.prod(shape)):
138138
assert False, "Requested number of non-zeros must be positive and less than the total size"
139139
elif nonzeros < 1:
140-
nonzeros = np.int(np.ceil(np.prod(shape) * nonzeros))
140+
nonzeros = int(np.ceil(np.prod(shape) * nonzeros))
141141
else:
142-
nonzeros = np.int(np.floor(nonzeros))
142+
nonzeros = int(np.floor(nonzeros))
143143

144144
# Keep iterating until we find enough unique non-zeros or we give up
145145
subs = np.array([])
@@ -731,7 +731,7 @@ def mttkrp(self, U, n):
731731
else:
732732
Z.append(np.array([]))
733733
# Perform ttv multiplication
734-
V[:, r] = self.ttv(np.array(Z), -(n+1)).double()
734+
V[:, r] = self.ttv(Z, -(n+1)).double()
735735

736736
return V
737737

@@ -1027,11 +1027,11 @@ def ttv(self, vector, dims=None):
10271027
dims = np.array([dims])
10281028

10291029
# Check that vector is a list of vectors, if not place single vector as element in list
1030-
if len(vector.shape) == 1 and isinstance(vector[0], (int, float, np.int_, np.float_)):
1031-
return self.ttv(np.array([vector]), dims)
1030+
if len(vector) > 0 and isinstance(vector[0], (int, float, np.int_, np.float_)):
1031+
return self.ttv([vector], dims)
10321032

10331033
# Get sorted dims and index for multiplicands
1034-
dims, vidx = ttb.tt_dimscheck(dims, self.ndims, vector.shape[0])
1034+
dims, vidx = ttb.tt_dimscheck(dims, self.ndims, len(vector))
10351035
remdims = np.setdiff1d(np.arange(0, self.ndims), dims).astype(int)
10361036

10371037
# Check that each multiplicand is the right size.

pyttb/tensor.py

+4-6
Original file line numberDiff line numberDiff line change
@@ -1000,13 +1000,11 @@ def ttv(self, vector, dims=None):
10001000
dims = np.array([dims])
10011001

10021002
# Check that vector is a list of vectors, if not place single vector as element in list
1003-
if isinstance(vector, list):
1004-
return self.ttv(np.array(vector), dims)
1005-
if len(vector.shape) == 1 and isinstance(vector[0], (int, float, np.int_, np.float_)):
1006-
return self.ttv(np.array([vector]), dims)
1003+
if len(vector) > 0 and isinstance(vector[0], (int, float, np.int_, np.float_)):
1004+
return self.ttv([vector], dims)
10071005

10081006
# Get sorted dims and index for multiplicands
1009-
dims, vidx = ttb.tt_dimscheck(dims, self.ndims, vector.shape[0])
1007+
dims, vidx = ttb.tt_dimscheck(dims, self.ndims, len(vector))
10101008

10111009
# Check that each multiplicand is the right size.
10121010
for i in range(dims.size):
@@ -1076,7 +1074,7 @@ def ttsv(self, vector, dims=None, version = None):
10761074
if dnew == 2:
10771075
return np.reshape(y, [sz, sz], order='F')
10781076
elif dnew > 2:
1079-
return ttb.tensor.from_data(np.reshape(y, sz*np.ones(dnew, dtype=np.int), order='F'))
1077+
return ttb.tensor.from_data(np.reshape(y, sz*np.ones(dnew, dtype=int), order='F'))
10801078
else:
10811079
return y
10821080
else:

tests/test_ktensor.py

+9-9
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ def sample_ktensor_2way():
2121
def sample_ktensor_3way():
2222
rank = 2
2323
shape = np.array([2, 3, 4])
24-
vector = np.arange(1, rank*sum(shape)+1).astype(np.float)
25-
weights = 2 * np.ones(rank).astype(np.float)
24+
vector = np.arange(1, rank*sum(shape)+1).astype(float)
25+
weights = 2 * np.ones(rank).astype(float)
2626
vector_with_weights = np.concatenate((weights, vector), axis=0)
2727
#vector_with_weights = vector_with_weights.reshape((len(vector_with_weights), 1))
2828
# ground truth
@@ -100,17 +100,17 @@ def test_ktensor_from_data(sample_ktensor_2way, capsys):
100100
weights_int = np.array([1, 2])
101101
K2 = ttb.ktensor.from_data(weights_int, data["factor_matrices"])
102102
out, err = capsys.readouterr()
103-
assert "converting weights from int64 to np.float" in out or \
104-
"converting weights from int32 to np.float" in out
103+
assert "converting weights from int64 to float" in out or \
104+
"converting weights from int32 to float" in out
105105

106106
# Weights that are int should be converted
107107
fm0 = np.array([[1, 2], [3, 4]])
108108
fm1 = np.array([[5, 6], [7, 8]])
109109
factor_matrices = [fm0, fm1]
110110
K3 = ttb.ktensor.from_data(data["weights"], factor_matrices)
111111
out, err = capsys.readouterr()
112-
assert "converting factor_matrices[0] from int64 to np.float" in out or \
113-
"converting factor_matrices[0] from int32 to np.float" in out
112+
assert "converting factor_matrices[0] from int64 to float" in out or \
113+
"converting factor_matrices[0] from int32 to float" in out
114114

115115
@pytest.mark.indevelopment
116116
def test_ktensor_from_function():
@@ -762,15 +762,15 @@ def test_ktensor_ttv(sample_ktensor_3way):
762762
vec2 = np.array([1, 1])
763763
vec3 = np.array([1, 1, 1])
764764
vec4 = np.array([1, 1, 1, 1])
765-
assert K.ttv(np.array([vec2, vec3, vec4])) == 30348
765+
assert K.ttv([vec2, vec3, vec4]) == 30348
766766

767767
# Wrong shape
768768
with pytest.raises(AssertionError) as excinfo:
769-
K.ttv(np.array([vec2, vec3, np.array([1,2])]))
769+
K.ttv([vec2, vec3, np.array([1,2])])
770770
assert "Multiplicand is wrong size" in str(excinfo)
771771

772772
# Multiple dimensions, but fewer than all dimensions, not in same order as ktensor dimensions
773-
K2 = K.ttv(np.array([vec4, vec3]), dims=np.array([2, 1]))
773+
K2 = K.ttv([vec4, vec3], dims=np.array([2, 1]))
774774
weights = np.array([1800., 3564.])
775775
fm0 = np.array([[1., 3.], [2., 4.]])
776776
assert (K2.isequal(ttb.ktensor.from_data(weights, fm0)))

tests/test_sptensor.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -186,11 +186,11 @@ def test_sptensor_full(sample_sptensor):
186186
def test_sptensor_subdims(sample_sptensor):
187187
(data, sptensorInstance) = sample_sptensor
188188

189-
assert (sptensorInstance.subdims(np.array([[1], [1], [1, 3]])) == np.array([0, 1])).all()
189+
assert (sptensorInstance.subdims([[1], [1], [1, 3]]) == np.array([0, 1])).all()
190190
assert (sptensorInstance.subdims((1, 1, slice(None, None, None))) == np.array([0, 1])).all()
191191

192192
with pytest.raises(AssertionError) as excinfo:
193-
sptensorInstance.subdims(np.array([[1], [1, 3]]))
193+
sptensorInstance.subdims([[1], [1, 3]])
194194
assert "Number of subdimensions must equal number of dimensions" in str(excinfo)
195195

196196
@pytest.mark.indevelopment
@@ -1290,7 +1290,7 @@ def test_sptensor_ttv(sample_sptensor):
12901290

12911291
# Wrong shape vector
12921292
with pytest.raises(AssertionError) as excinfo:
1293-
onesSptensor.ttv(np.array([vector, np.array([1,2])]))
1293+
onesSptensor.ttv([vector, np.array([1,2])])
12941294
assert "Multiplicand is wrong size" in str(excinfo)
12951295

12961296
# Returns vector shaped object

tests/test_tensor.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -1092,7 +1092,7 @@ def test_tensor_ttv(sample_tensor_2way, sample_tensor_3way, sample_tensor_4way):
10921092
assert (T2.data == np.array([10,14,18])).all()
10931093

10941094
# Multiply by multiple vectors, infer dimensions
1095-
assert tensorInstance2.ttv(np.array([np.array([2, 2]), np.array([1, 1, 1])])) == 42
1095+
assert tensorInstance2.ttv([np.array([2, 2]), np.array([1, 1, 1])]) == 42
10961096

10971097
# Multiply by multiple vectors as list of numpy.ndarrays
10981098
assert tensorInstance2.ttv([np.array([2, 2]), np.array([1, 1, 1])]) == 42
@@ -1104,7 +1104,7 @@ def test_tensor_ttv(sample_tensor_2way, sample_tensor_3way, sample_tensor_4way):
11041104
assert (T3.data == np.array([[6,30],[14,38],[22,46]])).all()
11051105

11061106
# Multiply by multiple vectors, infer dimensions
1107-
assert tensorInstance3.ttv(np.array([np.array([2, 2]), np.array([1, 1, 1]), np.array([2, 2])])) == 312
1107+
assert tensorInstance3.ttv([np.array([2, 2]), np.array([1, 1, 1]), np.array([2, 2])]) == 312
11081108

11091109
# 4-way Multiply by single vector
11101110
T4 = tensorInstance4.ttv(2 * np.ones((tensorInstance4.shape[0],)), 0)

0 commit comments

Comments
 (0)