a b/inst/scAImodel_py.py
1
2
# python implementation of scAI optimization model
3
# import packages
4
import numpy as np
5
from numpy import linalg as LA
6
from numpy import matrix
7
8
9
def scAImodel_py(X1,X2,K,S=0.25,Alpha=1,Lambda=10000,Gamma=1,Maxiter = 500,Stop_rule=1,Seed=1,W1=None,W2=None,H=None,Z=None,R=None):
10
# parameters
11
    d1 = X1.shape
12
    d2 = X2.shape
13
    p = d1[0]
14
    n = d1[1]
15
    q = d2[0]
16
    np.random.seed(Seed)
17
    if W1 is None:
18
        W1 = np.random.rand(p,K)
19
        
20
    if W2 is None:
21
        W2 = np.random.rand(q,K)
22
    
23
    if H is None:
24
        H = np.random.rand(K,n)
25
    
26
    if Z is None:
27
        Z = np.random.rand(n,n)
28
    
29
    if R is None:
30
        R = np.random.binomial(1,S,size=(n,n))
31
    # main function
32
    XtX2 = np.dot(np.transpose(X2),X2)
33
    obj_old = 1
34
#    W1 = np.asarray(W1)
35
#    W2 = np.asarray(W2)
36
#    Z = np.asarray(Z)
37
#    R = np.asarray(R)
38
    for iter in range(1,Maxiter+1):
39
        #  print(iter)
40
        # normalize H
41
#        H = matrix(H)
42
#        lib = np.sum(H,axis = 1)
43
#        H = H/np.tile(lib,(1,n))
44
#        H = np.asarray(H)
45
        H = H/H.sum(axis=1,keepdims=1)
46
        # update W1
47
        HHt = np.dot(H,np.transpose(H))
48
        X1Ht = np.dot(X1,np.transpose(H))
49
        W1HHt = np.dot(W1,HHt)
50
        W1 = W1*X1Ht/(W1HHt+np.spacing(1))
51
        # update W2
52
        ZR = Z*R
53
        ZRHt = np.dot(ZR,np.transpose(H))
54
        X2ZRHt = np.dot(X2,ZRHt)
55
        W2HHt = np.dot(W2,HHt)
56
        W2 = W2*X2ZRHt/(W2HHt+np.spacing(1))
57
        # update H
58
        W1tX1 = np.dot(np.transpose(W1),X1)
59
        W2tX2 = np.dot(np.transpose(W2),X2)
60
        W2tX2ZR = np.dot(W2tX2,ZR)
61
        HZZt = np.dot(H,(Z+np.transpose(Z)))
62
        W1tW1 = np.dot(np.transpose(W1),W1)
63
        W2tW2 = np.dot(np.transpose(W2),W2)
64
        H = H*(Alpha*W1tX1+W2tX2ZR+Lambda*HZZt)/(np.dot(Alpha*W1tW1+W2tW2+2*Lambda*HHt+Gamma*np.ones([K,K]),H)+np.spacing(1))
65
        # update Z
66
        HtH = np.dot(np.transpose(H),H)
67
        X2tW2H = np.dot(np.transpose(W2tX2),H)
68
        RX2tW2H = R*X2tW2H
69
        XtX2ZR = np.dot(XtX2,ZR)
70
        XtX2ZRR = XtX2ZR*R
71
        Z = Z*(RX2tW2H+Lambda*HtH)/(XtX2ZRR+Lambda*Z+np.spacing(1))
72
        if Stop_rule == 2:
73
            obj = Alpha*pow(LA.norm(X1-np.dot(W1,H),ord = 'fro'),2)+pow(LA.norm(np.dot(X2,ZR)-np.dot(W2,H),ord = 'fro'),2)+Lambda*pow(LA.norm(Z-np.dot(np.transpose(H),H),ord = 'fro'),2)+Gamma*pow(LA.norm(np.dot(np.ones([1,K]),H),ord = 'fro'),2)
74
            if (obj_old-obj)/obj_old < 1e-6 and iter > 1:
75
                break
76
        iter = iter+1
77
            
78
# print ("\n")
79
#   print ("## Running scAI with seed %d ##" % Seed)
80
#   print ("\n")
81
    
82
    return W1, W2, H, Z, R
83