CP-APR: Alternating Poisson Regression for fitting CP to sparse count data

Copyright 2022 National Technology & Engineering Solutions of Sandia,
LLC (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the
U.S. Government retains certain rights in this software.

Set up a sample problem

We follow the general procedure outlined by E. C. Chi and T. G. Kolda, On Tensors, Sparsity, and Nonnegative Factorizations, arXiv:1112.2414 [math.NA], December 2011 (http://arxiv.org/abs/1112.2414).

import os
import sys
import pyttb as ttb
import numpy as np
# Pick the shape and rank
sz = (10, 8, 6)
R = 5

# Generate factor matrices with a few large entries in each column
# this will be the basis of our solution.
np.random.seed(0)  # Set seed for reproducibility
A = []
for n in range(len(sz)):
    A.append(np.random.uniform(size=(sz[n], R)))
    for r in range(R):
        p = np.random.permutation(sz[n])
        nbig = round((1 / R) * sz[n])
        A[-1][p[0:nbig], r] *= 100
weights = np.random.uniform(size=(R,))
S = ttb.ktensor(A, weights)
S.normalize(sort=True, normtype=1)

X = S.to_tensor()
X.data = np.floor(np.abs(X.data))

Call CP-APR

# Compute a solution
short_tutorial = 2  # Cut off solve early for demo
M = ttb.cp_apr(X, R, printitn=10, stoptime=short_tutorial);
CP_APR:
	Iter 0: Inner Its = 30.0 KKT violation = 0.70173684251678, nViolations = 0.0
	Iter 10: Inner Its = 30.0 KKT violation = 0.05721561635359995, nViolations = 0.0
	Iter 20: Inner Its = 26.0 KKT violation = 0.012967978458405804, nViolations = 0.0
	Iter 30: Inner Its = 22.0 KKT violation = 0.008994287986022531, nViolations = 0.0
	Iter 40: Inner Its = 20.0 KKT violation = 0.004412950418894779, nViolations = 0.0
	Iter 50: Inner Its = 19.0 KKT violation = 0.0018915758389355108, nViolations = 0.0
	Iter 60: Inner Its = 20.0 KKT violation = 0.001286969943133709, nViolations = 0.0
	Iter 70: Inner Its = 21.0 KKT violation = 0.0011562208758999493, nViolations = 0.0
	Iter 80: Inner Its = 22.0 KKT violation = 0.0010417291154156683, nViolations = 0.0
	Iter 90: Inner Its = 22.0 KKT violation = 0.0009427649122024651, nViolations = 0.0
	Iter 100: Inner Its = 22.0 KKT violation = 0.0008566762816731854, nViolations = 0.0
	Iter 110: Inner Its = 21.0 KKT violation = 0.000781557311068104, nViolations = 0.0
	Iter 120: Inner Its = 20.0 KKT violation = 0.0007157176199855675, nViolations = 0.0
	Iter 130: Inner Its = 19.0 KKT violation = 0.0006577683101628429, nViolations = 0.0
	Iter 140: Inner Its = 19.0 KKT violation = 0.0006062499144335876, nViolations = 0.0
	Iter 150: Inner Its = 18.0 KKT violation = 0.0005605759635003427, nViolations = 0.0
	Iter 160: Inner Its = 17.0 KKT violation = 0.0005198182925196804, nViolations = 0.0
	Iter 170: Inner Its = 16.0 KKT violation = 0.0004833097888183868, nViolations = 0.0
	Iter 180: Inner Its = 16.0 KKT violation = 0.0004502865737130435, nViolations = 0.0
	Iter 190: Inner Its = 15.0 KKT violation = 0.0004203811655832945, nViolations = 0.0
	Iter 200: Inner Its = 14.0 KKT violation = 0.00039367079629704094, nViolations = 0.0
	Iter 210: Inner Its = 14.0 KKT violation = 0.0003669442505448428, nViolations = 0.0
	Iter 220: Inner Its = 14.0 KKT violation = 0.00034502387049450967, nViolations = 0.0
	Iter 230: Inner Its = 14.0 KKT violation = 0.00032504487639439805, nViolations = 0.0
	Iter 240: Inner Its = 14.0 KKT violation = 0.00030673119777768765, nViolations = 0.0
	Iter 250: Inner Its = 13.0 KKT violation = 0.0002904027811815313, nViolations = 0.0
	Iter 260: Inner Its = 13.0 KKT violation = 0.0002747802137594846, nViolations = 0.0
	Iter 270: Inner Its = 13.0 KKT violation = 0.0002598287806977462, nViolations = 0.0
	Iter 280: Inner Its = 14.0 KKT violation = 0.0002459165246927464, nViolations = 0.0
	Iter 290: Inner Its = 13.0 KKT violation = 0.00023448594524988486, nViolations = 0.0
	Iter 300: Inner Its = 13.0 KKT violation = 0.0002221924972207745, nViolations = 0.0
	Iter 310: Inner Its = 12.0 KKT violation = 0.0002116958303405303, nViolations = 0.0
	Iter 320: Inner Its = 12.0 KKT violation = 0.00020196296321373097, nViolations = 0.0
	Iter 330: Inner Its = 12.0 KKT violation = 0.0001923609910756685, nViolations = 0.0
	Iter 340: Inner Its = 12.0 KKT violation = 0.00018359967830883228, nViolations = 0.0
	Iter 350: Inner Its = 12.0 KKT violation = 0.00017565870937419348, nViolations = 0.0
	Iter 360: Inner Its = 12.0 KKT violation = 0.00016819623625963231, nViolations = 0.0
	Iter 370: Inner Its = 12.0 KKT violation = 0.00016140548517251663, nViolations = 0.0
	Iter 380: Inner Its = 12.0 KKT violation = 0.0001550429662158237, nViolations = 0.0
	Iter 390: Inner Its = 13.0 KKT violation = 0.00014757230955053657, nViolations = 0.0
	Iter 400: Inner Its = 12.0 KKT violation = 0.00013059995354069986, nViolations = 0.0
	Iter 410: Inner Its = 14.0 KKT violation = 0.00011465399883725524, nViolations = 0.0
	Iter 420: Inner Its = 12.0 KKT violation = 0.00013134051357654997, nViolations = 0.0
	Iter 430: Inner Its = 12.0 KKT violation = 0.00011604661571473773, nViolations = 0.0
	Iter 440: Inner Its = 13.0 KKT violation = 0.00010283670571165082, nViolations = 0.0
	Iter 450: Inner Its = 12.0 KKT violation = 0.000117468335004145, nViolations = 0.0
Exiting because all subproblems reached KKT tol.
===========================================
 Final log-likelihood = 21158574.867987577
 Final least squares fit = 0.99988846081266
 Final KKT violation = 9.949517806395747e-05
 Total inner iterations = 7382.0
 Total execution time = 1.9709069728851318 secs