forked from nzhiltsov/Ext-RESCAL
-
Notifications
You must be signed in to change notification settings - Fork 0
/
commonFunctions.py
57 lines (50 loc) · 1.75 KB
/
commonFunctions.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
from numpy import dot
from numpy.random import randint
from numpy.random import random_integers
from scipy.sparse import lil_matrix
import numpy as np
def squareFrobeniusNormOfSparse(M):
"""
Computes the square of the Frobenius norm
"""
rows, cols = M.nonzero()
norm = 0
for i in range(len(rows)):
norm += M[rows[i],cols[i]] ** 2
return norm
def trace(M):
""" Compute the trace of a sparse matrix
"""
return sum(M.diagonal())
def fitNorm(X, A, R):
"""
Computes the squared Frobenius norm of the fitting matrix || X - A*R*A^T ||,
where X is a sparse matrix
"""
return squareFrobeniusNormOfSparse(X) + fitNormWithoutNormX(X, A, R)
def fitNormWithoutNormX(X, A, R):
AtA = dot(A.T, A)
secondTerm = dot(A.T, dot(X.dot(A), R.T))
thirdTerm = dot(dot(AtA, R), dot(AtA, R.T))
return np.trace(thirdTerm) - 2 * trace(secondTerm)
def reservoir(it, k):
ls = [next(it) for _ in range(k)]
for i, x in enumerate(it, k + 1):
j = randint(0, i)
if j < k:
ls[j] = x
return ls
def checkingIndices(M, ratio = 1):
"""
Returns the indices for computing fit values
based on non-zero values as well as sample indices
(the sample size is proportional to the given ratio ([0,1]) and number of matrix columns)
"""
rowSize, colSize = M.shape
nonzeroRows, nonzeroCols = M.nonzero()
nonzeroIndices = [(nonzeroRows[i], nonzeroCols[i]) for i in range(len(nonzeroRows))]
sampledRows = random_integers(0, rowSize - 1, round(ratio*colSize))
sampledCols = random_integers(0, colSize - 1, round(ratio*colSize))
sampledIndices = zip(sampledRows, sampledCols)
indices = list(set(sampledIndices + nonzeroIndices))
return indices