Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

14 testing implement tests for full coverage #128

Merged
merged 10 commits into from
Jun 3, 2023
79 changes: 42 additions & 37 deletions pyttb/cp_apr.py
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ def tt_cp_apr_mu(
kktModeViolations = np.zeros((N,))

if printitn > 0:
print("\nCP_APR:\n")
print("CP_APR:")

# Start the wall clock timer.
start = time.time()
Expand Down Expand Up @@ -304,7 +304,7 @@ def tt_cp_apr_mu(
# Print status
if printinneritn != 0 and divmod(i, printinneritn)[1] == 0:
print(
"\t\tMode = {}, Inner Iter = {}, KKT violation = {}\n".format(
"\t\tMode = {}, Inner Iter = {}, KKT violation = {}".format(
n, i, kktModeViolations[n]
)
)
Expand All @@ -325,11 +325,11 @@ def tt_cp_apr_mu(
# Check for convergence
if isConverged:
if printitn > 0:
print("Exiting because all subproblems reached KKT tol.\n")
print("Exiting because all subproblems reached KKT tol.")
break
if nTimes[iter] > stoptime:
if printitn > 0:
print("Exiting because time limit exceeded.\n")
print("Exiting because time limit exceeded.")
break

t_stop = time.time() - start
Expand All @@ -345,12 +345,12 @@ def tt_cp_apr_mu(
normTensor**2 + M.norm() ** 2 - 2 * input_tensor.innerprod(M)
)
fit = 1 - (normresidual / normTensor) # fraction explained by model
print("===========================================\n")
print(" Final log-likelihood = {} \n".format(obj))
print(" Final least squares fit = {} \n".format(fit))
print(" Final KKT violation = {}\n".format(kktViolations[iter]))
print(" Total inner iterations = {}\n".format(sum(nInnerIters)))
print(" Total execution time = {} secs\n".format(t_stop))
print("===========================================")
print(" Final log-likelihood = {}".format(obj))
print(" Final least squares fit = {}".format(fit))
print(" Final KKT violation = {}".format(kktViolations[iter]))
print(" Total inner iterations = {}".format(sum(nInnerIters)))
print(" Total execution time = {} secs".format(t_stop))

output = {}
output["params"] = (
Expand Down Expand Up @@ -472,7 +472,7 @@ def tt_cp_apr_pdnr(
times = np.zeros((maxiters, 1))

if printitn > 0:
print("\nCP_PDNR (alternating Poisson regression using damped Newton)\n")
print("CP_PDNR (alternating Poisson regression using damped Newton)")

dispLineWarn = printinneritn > 0

Expand All @@ -493,7 +493,7 @@ def tt_cp_apr_pdnr(
sparseIx.append(row_indices)

if printitn > 0:
print("done\n")
print("done")

e_vec = np.ones((1, rank))

Expand Down Expand Up @@ -578,13 +578,16 @@ def tt_cp_apr_pdnr(
kktModeViolations[n] = kkt_violation

if printinneritn > 0 and np.mod(i, printinneritn) == 0:
print("\tMode = {}, Row = {}, InnerIt = {}".format(n, jj, i))
print(
"\tMode = {}, Row = {}, InnerIt = {}".format(n, jj, i),
end="",
)

if i == 0:
print(", RowKKT = {}\n".format(kkt_violation))
print(", RowKKT = {}".format(kkt_violation))
else:
print(
", RowKKT = {}, RowObj = {}\n".format(
", RowKKT = {}, RowObj = {}".format(
kkt_violation, -f_new
)
)
Expand Down Expand Up @@ -667,7 +670,7 @@ def tt_cp_apr_pdnr(
if printitn > 0 and np.mod(iter, printitn) == 0:
fnVals[iter] = -tt_loglikelihood(input_tensor, M)
print(
"{}. Ttl Inner Its: {}, KKT viol = {}, obj = {}, nz: {}\n".format(
"{}. Ttl Inner Its: {}, KKT viol = {}, obj = {}, nz: {}".format(
iter,
nInnerIters[iter],
kktViolations[iter],
Expand All @@ -684,7 +687,7 @@ def tt_cp_apr_pdnr(
if isConverged and inexact and rowsubprobStopTol <= stoptol:
break
if times[iter] > stoptime:
print("EXiting because time limit exceeded\n")
print("EXiting because time limit exceeded")
break

t_stop = time.time() - start
Expand All @@ -700,12 +703,12 @@ def tt_cp_apr_pdnr(
normTensor**2 + M.norm() ** 2 - 2 * input_tensor.innerprod(M)
)
fit = 1 - (normresidual / normTensor) # fraction explained by model
print("===========================================\n")
print(" Final log-likelihood = {} \n".format(obj))
print(" Final least squares fit = {} \n".format(fit))
print(" Final KKT violation = {}\n".format(kktViolations[iter]))
print(" Total inner iterations = {}\n".format(sum(nInnerIters)))
print(" Total execution time = {} secs\n".format(t_stop))
print("===========================================")
print(" Final log-likelihood = {}".format(obj))
print(" Final least squares fit = {}".format(fit))
print(" Final KKT violation = {}".format(kktViolations[iter]))
print(" Total inner iterations = {}".format(sum(nInnerIters)))
print(" Total execution time = {} secs".format(t_stop))

output = {}
output["params"] = (
Expand Down Expand Up @@ -840,7 +843,7 @@ def tt_cp_apr_pqnr(
times = np.zeros((maxiters, 1))

if printitn > 0:
print("\nCP_PQNR (alternating Poisson regression using quasi-Newton)\n")
print("CP_PQNR (alternating Poisson regression using quasi-Newton)")

dispLineWarn = printinneritn > 0

Expand All @@ -861,7 +864,7 @@ def tt_cp_apr_pqnr(
sparseIx.append(row_indices)

if printitn > 0:
print("done\n")
print("done")

# Main loop: iterate until convergence or a max threshold is reached
for iter in range(maxiters):
Expand Down Expand Up @@ -958,20 +961,22 @@ def tt_cp_apr_pqnr(

# We now use \| KKT \|_{inf}:
kkt_violation = np.max(np.abs(np.minimum(m_row, gradM)))
# print("Intermediate Printing m_row: {}\n and gradM{}".format(m_row, gradM))

# Report largest row subproblem initial violation
if i == 0 and kkt_violation > kktModeViolations[n]:
kktModeViolations[n] = kkt_violation

if printinneritn > 0 and np.mod(i, printinneritn) == 0:
print("\tMode = {}, Row = {}, InnerIt = {}".format(n, jj, i))
print(
"\tMode = {}, Row = {}, InnerIt = {}".format(n, jj, i),
end="",
)

if i == 0:
print(", RowKKT = {}\n".format(kkt_violation))
print(", RowKKT = {}".format(kkt_violation))
else:
print(
", RowKKT = {}, RowObj = {}\n".format(
", RowKKT = {}, RowObj = {}".format(
kkt_violation, -f_new
)
)
Expand Down Expand Up @@ -1075,7 +1080,7 @@ def tt_cp_apr_pqnr(
if printitn > 0 and np.mod(iter, printitn) == 0:
fnVals[iter] = -tt_loglikelihood(input_tensor, M)
print(
"{}. Ttl Inner Its: {}, KKT viol = {}, obj = {}, nz: {}\n".format(
"{}. Ttl Inner Its: {}, KKT viol = {}, obj = {}, nz: {}".format(
iter, nInnerIters[iter], kktViolations[iter], fnVals[iter], num_zero
)
)
Expand All @@ -1086,7 +1091,7 @@ def tt_cp_apr_pqnr(
if isConverged:
break
if times[iter] > stoptime:
print("Exiting because time limit exceeded\n")
print("Exiting because time limit exceeded")
break

t_stop = time.time() - start
Expand All @@ -1102,12 +1107,12 @@ def tt_cp_apr_pqnr(
normTensor**2 + M.norm() ** 2 - 2 * input_tensor.innerprod(M)
)
fit = 1 - (normresidual / normTensor) # fraction explained by model
print("===========================================\n")
print(" Final log-likelihood = {} \n".format(obj))
print(" Final least squares fit = {} \n".format(fit))
print(" Final KKT violation = {}\n".format(kktViolations[iter]))
print(" Total inner iterations = {}\n".format(sum(nInnerIters)))
print(" Total execution time = {} secs\n".format(t_stop))
print("===========================================")
print(" Final log-likelihood = {}".format(obj))
print(" Final least squares fit = {}".format(fit))
print(" Final KKT violation = {}".format(kktViolations[iter]))
print(" Total inner iterations = {}".format(sum(nInnerIters)))
print(" Total execution time = {} secs".format(t_stop))

output = {}
output["params"] = (
Expand Down
6 changes: 3 additions & 3 deletions pyttb/export_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ def export_data(data, filename, fmt_data=None, fmt_weights=None):
"""
Export tensor-related data to a file.
"""
if not isinstance(data, (ttb.tensor, ttb.sptensor, ttb.ktensor, np.ndarray)):
assert False, f"Invalid data type for export: {type(data)}"

# open file
fp = open(filename, "w")

Expand Down Expand Up @@ -54,9 +57,6 @@ def export_data(data, filename, fmt_data=None, fmt_weights=None):
export_size(fp, data.shape)
export_array(fp, data, fmt_data)

else:
assert False, "Invalid data type for export"


def export_size(fp, shape):
# Export the size of something to a file
Expand Down
8 changes: 5 additions & 3 deletions pyttb/import_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,23 +24,27 @@ def import_data(filename):
data_type = import_type(fp)

if data_type not in ["tensor", "sptensor", "matrix", "ktensor"]:
fp.close()
assert False, f"Invalid data type found: {data_type}"

if data_type == "tensor":
shape = import_shape(fp)
data = import_array(fp, np.prod(shape))
fp.close()
return ttb.tensor().from_data(data, shape)

elif data_type == "sptensor":
shape = import_shape(fp)
nz = import_nnz(fp)
subs, vals = import_sparse_array(fp, len(shape), nz)
fp.close()
return ttb.sptensor().from_data(subs, vals, shape)

elif data_type == "matrix":
shape = import_shape(fp)
mat = import_array(fp, np.prod(shape))
mat = np.reshape(mat, np.array(shape))
fp.close()
return mat

elif data_type == "ktensor":
Expand All @@ -54,11 +58,9 @@ def import_data(filename):
fac = import_array(fp, np.prod(fac_shape))
fac = np.reshape(fac, np.array(fac_shape))
factor_matrices.append(fac)
fp.close()
return ttb.ktensor().from_data(weights, factor_matrices)

# Close file
fp.close()


def import_type(fp):
# Import IO data type
Expand Down
16 changes: 3 additions & 13 deletions pyttb/sptensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -671,14 +671,11 @@ def logical_and(self, B: Union[float, sptensor, ttb.tensor]) -> sptensor:
if not self.shape == B.shape:
assert False, "Must be tensors of the same shape"

def is_length_2(x):
return len(x) == 2

C = sptensor.from_aggregator(
np.vstack((self.subs, B.subs)),
np.vstack((self.vals, B.vals)),
self.shape,
is_length_2,
lambda x: len(x) == 2,
)

return C
Expand Down Expand Up @@ -735,15 +732,11 @@ def logical_or(
assert False, "Logical Or requires tensors of the same size"

if isinstance(B, ttb.sptensor):

def is_length_ge_1(x):
return len(x) >= 1

return sptensor.from_aggregator(
np.vstack((self.subs, B.subs)),
np.ones((self.subs.shape[0] + B.subs.shape[0], 1)),
self.shape,
is_length_ge_1,
lambda x: len(x) >= 1,
)

assert False, "Sptensor Logical Or argument must be scalar or sptensor"
Expand Down Expand Up @@ -780,12 +773,9 @@ def logical_xor(
if self.shape != other.shape:
assert False, "Logical XOR requires tensors of the same size"

def length1(x):
return len(x) == 1

subs = np.vstack((self.subs, other.subs))
return ttb.sptensor.from_aggregator(
subs, np.ones((len(subs), 1)), self.shape, length1
subs, np.ones((len(subs), 1)), self.shape, lambda x: len(x) == 1
)

assert False, "The argument must be an sptensor, tensor or scalar"
Expand Down
11 changes: 11 additions & 0 deletions tests/data/invalid_dims.tns
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
matrix
2
4 2 1
1.0000000000000000e+00
5.0000000000000000e+00
2.0000000000000000e+00
6.0000000000000000e+00
3.0000000000000000e+00
7.0000000000000000e+00
4.0000000000000000e+00
8.0000000000000000e+00
11 changes: 11 additions & 0 deletions tests/data/invalid_type.tns
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
list
2
4 2
1.0000000000000000e+00
5.0000000000000000e+00
2.0000000000000000e+00
6.0000000000000000e+00
3.0000000000000000e+00
7.0000000000000000e+00
4.0000000000000000e+00
8.0000000000000000e+00
8 changes: 5 additions & 3 deletions tests/test_cp_apr.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ def test_cpapr_mu(capsys):
ktensorInstance = ttb.ktensor.from_data(weights, factor_matrices)
tensorInstance = ktensorInstance.full()
np.random.seed(123)
M, _, _ = ttb.cp_apr(tensorInstance, 2)
M, _, _ = ttb.cp_apr(tensorInstance, 2, printinneritn=1)
# Consume the cp_apr diagnostic printing
capsys.readouterr()
assert np.isclose(M.full().data, ktensorInstance.full().data).all()
Expand All @@ -175,7 +175,9 @@ def test_cpapr_pdnr(capsys):
ktensorInstance = ttb.ktensor.from_data(weights, factor_matrices)
tensorInstance = ktensorInstance.full()
np.random.seed(123)
M, _, _ = ttb.cp_apr(tensorInstance, 2, algorithm="pdnr")
M, _, _ = ttb.cp_apr(
tensorInstance, 2, algorithm="pdnr", printinneritn=1, inexact=False
)
capsys.readouterr()
assert np.isclose(M.full().data, ktensorInstance.full().data, rtol=1e-04).all()

Expand Down Expand Up @@ -221,7 +223,7 @@ def test_cpapr_pqnr(capsys):
ktensorInstance = ttb.ktensor.from_data(weights, factor_matrices)
tensorInstance = ktensorInstance.full()
np.random.seed(123)
M, _, _ = ttb.cp_apr(tensorInstance, 2, algorithm="pqnr")
M, _, _ = ttb.cp_apr(tensorInstance, 2, algorithm="pqnr", printinneritn=1)
capsys.readouterr()
assert np.isclose(M.full().data, ktensorInstance.full().data, rtol=1e-01).all()

Expand Down
Loading