コード例 #1
0
 def test_max_sigma_noise(self):
     M = 51
     N = 325
     J = 25
     TR = 1.
     Thrf = 25.
     dt = .5
     data = self.data_simu
     X = OrderedDict([])
     Y = data.bold
     onsets = data.get_joined_onsets()
     durations = data.paradigm.stimDurations
     P = vt.PolyMat(N, 4, TR)
     L = vt.polyFit(Y, TR, 4, P)
     PL = np.dot(P, L)
     TT, m_h = getCanoHRF(Thrf, dt)
     sigma_epsilone = np.ones(J)
     Gamma = np.identity(N)
     m_A = np.zeros((J, M), dtype=np.float64)
     Sigma_A = np.zeros((M, M, J), np.float64)
     m_H = np.array(m_h).astype(np.float64)
     D = len(m_H)
     Sigma_H = np.ones((D, D), dtype=np.float64)
     zerosMM = np.zeros((M, M), dtype=np.float64)
     _, occurence_matrix, _ = vt.create_conditions(onsets, durations, M, N,
                                                   D, TR, dt)
     sigma_eps = vt.maximization_noise_var(occurence_matrix, m_H, Sigma_H, m_A, Sigma_A,
                                           Gamma, Y, N)
コード例 #2
0
 def test_expectH(self):
     M = 51
     J = 25
     N = 325
     D = 3
     TR = 1.
     Thrf = 25.
     dt = .5
     data = self.data_simu
     Gamma = np.identity(N)
     Q_barnCond = np.zeros((M, M, D, D), dtype=np.float64)
     XGamma = np.zeros((M, D, N), dtype=np.float64)
     XX = np.zeros((M, N, D), dtype=np.int32)
     Y = data.bold
     P = vt.PolyMat(N, 4, TR)
     L = vt.polyFit(Y, TR, 4, P)
     PL = np.dot(P, L)
     y_tilde = Y - np.dot(P, L)
     TT, m_h = getCanoHRF(Thrf, dt)
     m_h = m_h[:D]
     m_H = np.array(m_h)
     sigma_epsilone = np.ones(J)
     Sigma_H = np.ones((D, D), dtype=float)
     m_A = np.zeros((J, M), dtype=np.float64)
     Sigma_A = np.zeros((M, M, J), np.float64)
     scale = 1
     order = 2
     D2 = vt.buildFiniteDiffMatrix(order, D)
     R = np.dot(D2, D2) / pow(dt, 2 * order)
     sigmaH = 0.1
     UtilsC.expectation_H(XGamma, Q_barnCond, sigma_epsilone, Gamma,
                          R, Sigma_H, Y, y_tilde, m_A, m_H, Sigma_A,
                          XX.astype(np.int32), J, D, M, N, scale, sigmaH)
コード例 #3
0
 def test_expectA(self):
     M = 51
     K = 2
     J = 25
     N = 325
     D = 3
     TR = 1.
     Thrf = 25.
     dt = .5
     data = self.data_simu
     Y = data.bold
     Onsets = data.get_joined_onsets()
     Gamma = np.identity(N)
     XX = np.zeros((M, N, D), dtype=np.int32)
     P = vt.PolyMat(N, 4, TR)
     L = vt.polyFit(Y, TR, 4, P)
     PL = np.dot(P, L)
     y_tilde = Y - np.dot(P, L)
     TT, m_h = getCanoHRF(Thrf, dt)
     m_h = m_h[:D]
     sigma_epsilone = np.ones(J)
     m_H = np.array(m_h)
     Sigma_H = np.ones((D, D), dtype=float)
     m_A = np.zeros((J, M), dtype=np.float64)
     Sigma_A = np.zeros((M, M, J), np.float64)
     for j in xrange(0, J):
         Sigma_A[:, :, j] = 0.01 * np.identity(M)
     mu_M = np.zeros((M, K), dtype=np.float64)
     sigma_M = np.ones((M, K), dtype=np.float64)
     q_Z = np.zeros((M, K, J), dtype=np.float64)
     UtilsC.expectation_A(q_Z, mu_M, sigma_M, PL, sigma_epsilone, Gamma,
                          Sigma_H, Y, y_tilde, m_A, m_H, Sigma_A,
                          XX.astype(np.int32), J, D, M, N, K)
コード例 #4
0
 def test_expectA(self):
     M = 51
     K = 2
     J = 25
     N = 325
     D = 3
     TR = 1.
     Thrf = 25.
     dt = .5
     data = self.data_simu
     Y = data.bold
     Onsets = data.get_joined_onsets()
     Gamma = np.identity(N)
     XX = np.zeros((M, N, D), dtype=np.int32)
     P = vt.PolyMat(N, 4, TR)
     L = vt.polyFit(Y, TR, 4, P)
     PL = np.dot(P, L)
     y_tilde = Y - np.dot(P, L)
     TT, m_h = getCanoHRF(Thrf, dt)
     m_h = m_h[:D]
     sigma_epsilone = np.ones(J)
     m_H = np.array(m_h)
     Sigma_H = np.ones((D, D), dtype=float)
     m_A = np.zeros((J, M), dtype=np.float64)
     Sigma_A = np.zeros((M, M, J), np.float64)
     for j in xrange(0, J):
         Sigma_A[:, :, j] = 0.01 * np.identity(M)
     mu_M = np.zeros((M, K), dtype=np.float64)
     sigma_M = np.ones((M, K), dtype=np.float64)
     q_Z = np.zeros((M, K, J), dtype=np.float64)
     UtilsC.expectation_A(q_Z, mu_M, sigma_M, PL, sigma_epsilone, Gamma,
                          Sigma_H, Y, y_tilde, m_A, m_H, Sigma_A,
                          XX.astype(np.int32), J, D, M, N, K)
コード例 #5
0
 def test_expectH(self):
     M = 51
     J = 25
     N = 325
     D = 3
     TR = 1.
     Thrf = 25.
     dt = .5
     data = self.data_simu
     Gamma = np.identity(N)
     Q_barnCond = np.zeros((M, M, D, D), dtype=np.float64)
     XGamma = np.zeros((M, D, N), dtype=np.float64)
     XX = np.zeros((M, N, D), dtype=np.int32)
     Y = data.bold
     P = vt.PolyMat(N, 4, TR)
     L = vt.polyFit(Y, TR, 4, P)
     PL = np.dot(P, L)
     y_tilde = Y - np.dot(P, L)
     TT, m_h = getCanoHRF(Thrf, dt)
     m_h = m_h[:D]
     m_H = np.array(m_h)
     sigma_epsilone = np.ones(J)
     Sigma_H = np.ones((D, D), dtype=float)
     m_A = np.zeros((J, M), dtype=np.float64)
     Sigma_A = np.zeros((M, M, J), np.float64)
     scale = 1
     order = 2
     D2 = vt.buildFiniteDiffMatrix(order, D)
     R = np.dot(D2, D2) / pow(dt, 2 * order)
     sigmaH = 0.1
     UtilsC.expectation_H(XGamma, Q_barnCond, sigma_epsilone, Gamma, R,
                          Sigma_H, Y, y_tilde, m_A, m_H, Sigma_A,
                          XX.astype(np.int32), J, D, M, N, scale, sigmaH)
コード例 #6
0
 def test_polyFit(self):
     N = 325
     TR = 1.
     data = self.data_simu
     Y = data.bold
     P = vt.PolyMat(N, 4, TR)
     L = vt.polyFit(Y, TR, 4, P)
コード例 #7
0
ファイル: test_jde_vem_tools.py プロジェクト: ainafp/pyhrf
 def test_free_energy(self):
     """ Test of vem tool to compute free energy """
     M = 51
     D = 3
     N = 325
     J = 25
     K = 2
     TR = 1.
     Thrf=25.
     dt=.5
     data = self.data_simu
     Y = data.bold
     graph = data.get_graph()
     P = vt.PolyMat( N , 4 , TR)
     L = vt.polyFit(Y, TR, 4,P)
     y_tilde = Y - np.dot(P,L)
     TT,m_h = getCanoHRF(Thrf,dt)
     order = 2
     D2 = vt.buildFiniteDiffMatrix(order,D)
     R = np.dot(D2,D2) / pow(dt,2*order)
     invR = np.linalg.inv(R)
     Det_invR = np.linalg.det(invR)
     q_Z = np.zeros((M,K,J),dtype=np.float64)
     maxNeighbours = max([len(nl) for nl in graph])
     neighboursIndexes = np.zeros((J, maxNeighbours), dtype=np.int32)
     Beta = np.ones((M),dtype=np.float64)
     sigma_epsilone = np.ones(J)
     XX = np.zeros((M,N,D),dtype=np.int32)
     Gamma = np.identity(N)
     Det_Gamma = np.linalg.det(Gamma)
     XGamma = np.zeros((M,D,N),dtype=np.float64)
     m_A = np.zeros((J,M),dtype=np.float64)
     Sigma_A = np.zeros((M,M,J),np.float64)
     mu_M = np.zeros((M,K),dtype=np.float64)
     sigma_M = np.ones((M,K),dtype=np.float64)
     m_H = np.array(m_h).astype(np.float64)
     Sigma_H = np.ones((D,D),dtype=np.float64)
     p_Wtilde = np.zeros((M,K),dtype=np.float64)
     p_Wtilde1 = np.zeros((M,K),dtype=np.float64)
     p_Wtilde[:,1] = 1
     FreeEnergy = vt.Compute_FreeEnergy(y_tilde,m_A,Sigma_A,mu_M,sigma_M,
                                        m_H,Sigma_H,R,Det_invR,0.0,p_Wtilde,
                                        0.0,0.0,q_Z,neighboursIndexes,
                                        maxNeighbours,Beta,sigma_epsilone,
                                        XX,Gamma,Det_Gamma,XGamma,
                                        J,M,D,N,2,100,"CompMod")
コード例 #8
0
ファイル: test_jde_vem_tools.py プロジェクト: ainafp/pyhrf
 def test_max_L(self):
     M = 51
     N = 325
     J = 25
     TR = 1.
     Thrf=25.
     dt=.5
     TT,m_h = getCanoHRF(Thrf,dt)
     m_A = np.zeros((J,M),dtype=np.float64)
     m_H = np.array(m_h).astype(np.float64)
     data = self.data_simu
     Y = data.bold
     X = OrderedDict([])
     P = vt.PolyMat( N , 4 , TR)
     L = vt.polyFit(Y, TR, 4,P)
     zerosP = np.zeros((P.shape[0]),dtype=np.float64)
     L = vt.maximization_L(Y,m_A,X,m_H,L,P,zerosP)
コード例 #9
0
 def test_free_energy(self):
     """ Test of vem tool to compute free energy """
     M = 51
     D = 3
     N = 325
     J = 25
     K = 2
     TR = 1.
     Thrf = 25.
     dt = .5
     gamma_h = 1000
     data = self.data_simu
     Y = data.bold
     graph = data.get_graph()
     onsets = data.paradigm.get_joined_onsets()
     durations = data.paradigm.stimDurations
     P = vt.PolyMat(N, 4, TR)
     L = vt.polyFit(Y, TR, 4, P)
     y_tilde = Y - np.dot(P, L)
     TT, m_h = getCanoHRF(Thrf, dt)
     order = 2
     D2 = vt.buildFiniteDiffMatrix(order, D)
     R = np.dot(D2, D2) / pow(dt, 2*order)
     invR = np.linalg.inv(R)
     Det_invR = np.linalg.det(invR)
     q_Z = 0.5 * np.ones((M, K, J), dtype=np.float64)
     neighbours_indexes = vt.create_neighbours(graph)
     Beta = np.ones((M), dtype=np.float64)
     sigma_epsilone = np.ones(J)
     _, occurence_matrix, _ = vt.create_conditions(onsets, durations, M, N, D, TR, dt)
     Gamma = np.identity(N)
     Det_Gamma = np.linalg.det(Gamma)
     XGamma = np.zeros((M, D, N), dtype=np.float64)
     m_A = np.zeros((J, M), dtype=np.float64)
     Sigma_A = np.zeros((M, M, J), np.float64)
     mu_M = np.zeros((M, K), dtype=np.float64)
     sigma_M = np.ones((M, K), dtype=np.float64)
     m_H = np.array(m_h[:D]).astype(np.float64)
     Sigma_H = np.ones((D, D), dtype=np.float64)
     free_energy = vt.free_energy_computation(m_A, Sigma_A, m_H, Sigma_H, D,
                                              q_Z, y_tilde, occurence_matrix,
                                              sigma_epsilone, Gamma, M, J, N,
                                              K, mu_M, sigma_M, neighbours_indexes,
                                              Beta, Sigma_H, np.linalg.inv(R),
                                              R, Det_Gamma, gamma_h)
コード例 #10
0
 def test_max_L(self):
     M = 51
     N = 325
     J = 25
     D = 3
     TR = 1.
     Thrf = 25.
     dt = .5
     TT, m_h = getCanoHRF(Thrf, dt)
     m_A = np.zeros((J, M), dtype=np.float64)
     m_H = np.array(m_h).astype(np.float64)
     data = self.data_simu
     Y = data.bold
     XX = np.zeros((M, N, D), dtype=np.int32)
     P = vt.PolyMat(N, 4, TR)
     L = vt.polyFit(Y, TR, 4, P)
     Ndrift = L.shape[0]
     zerosP = np.zeros((P.shape[0]), dtype=np.float64)
     UtilsC.maximization_L(
         Y, m_A, m_H, L, P, XX.astype(np.int32), J, D, M, Ndrift, N)
コード例 #11
0
 def test_max_L(self):
     M = 51
     N = 325
     J = 25
     D = 3
     TR = 1.
     Thrf = 25.
     dt = .5
     TT, m_h = getCanoHRF(Thrf, dt)
     m_A = np.zeros((J, M), dtype=np.float64)
     m_H = np.array(m_h).astype(np.float64)
     data = self.data_simu
     Y = data.bold
     XX = np.zeros((M, N, D), dtype=np.int32)
     P = vt.PolyMat(N, 4, TR)
     L = vt.polyFit(Y, TR, 4, P)
     Ndrift = L.shape[0]
     zerosP = np.zeros((P.shape[0]), dtype=np.float64)
     UtilsC.maximization_L(Y, m_A, m_H, L, P, XX.astype(np.int32), J, D, M,
                           Ndrift, N)
コード例 #12
0
 def test_max_L(self):
     M = 51
     N = 325
     J = 25
     TR = 1.
     Thrf = 25.
     dt = .5
     TT, m_h = getCanoHRF(Thrf, dt)
     m_A = np.zeros((J, M), dtype=np.float64)
     m_H = np.array(m_h).astype(np.float64)
     data = self.data_simu
     onsets = data.paradigm.get_joined_onsets()
     durations = data.paradigm.get_joined_durations()
     Y = data.bold
     X = OrderedDict([])
     P = vt.PolyMat(N, 4, TR)
     L = vt.polyFit(Y, TR, 4, P)
     zerosP = np.zeros((P.shape[0]), dtype=np.float64)
     _, occurence_matrix, _ = vt.create_conditions(onsets, durations, M, N,
                                                   len(m_H), TR, dt)
     L = vt.maximization_drift_coeffs(Y, m_A, occurence_matrix, m_H, np.identity(N), P)
コード例 #13
0
 def test_expectA(self):
     M = 51
     K = 2
     J = 25
     N = 325
     D = 3
     TR = 1.
     Thrf = 25.
     dt = .5
     data = self.data_simu
     Y = data.bold
     Onsets = data.get_joined_onsets()
     durations = data.paradigm.stimDurations
     Gamma = np.identity(N)
     X = OrderedDict([])
     for condition, Ons in Onsets.iteritems():
         X[condition] = vt.compute_mat_X_2(N, TR, D, dt, Ons)
     P = vt.PolyMat(N, 4, TR)
     L = vt.polyFit(Y, TR, 4, P)
     PL = np.dot(P, L)
     y_tilde = Y - np.dot(P, L)
     TT, m_h = getCanoHRF(Thrf, dt)
     m_h = m_h[:D]
     sigma_epsilone = np.ones(J)
     m_H = np.array(m_h)
     Sigma_H = np.ones((D, D), dtype=float)
     m_A = np.zeros((J, M), dtype=np.float64)
     Sigma_A = np.ones((M, M, J), np.float64)
     for j in xrange(0, J):
         Sigma_A[:, :, j] = 0.01*np.identity(M)
     mu_M = np.zeros((M, K), dtype=np.float64)
     sigma_M = np.ones((M, K), dtype=np.float64)
     q_Z = 0.5 * np.ones((M, K, J), dtype=np.float64)
     zerosJMD = np.zeros((J, M, D), dtype=np.float64)
     _, occurence_matrix, _ = vt.create_conditions(Onsets, durations, M, N,
                                                   D, TR, dt)
     m_A, Sigma_A = vt.nrls_expectation(m_H, m_A, occurence_matrix, Gamma,
                                        q_Z, mu_M, sigma_M, M, y_tilde, Sigma_A,
                                        Sigma_H, sigma_epsilone)
コード例 #14
0
 def test_expectH(self):
     M = 51
     K = 2
     J = 25
     N = 325
     D = 3
     TR = 1.
     Thrf = 25.
     dt = .5
     data = self.data_simu
     Gamma = np.identity(N)
     X = OrderedDict([])
     Y = data.bold
     onsets = data.get_joined_onsets()
     durations = data.paradigm.stimDurations
     P = vt.PolyMat(N, 4, TR)
     L = vt.polyFit(Y, TR, 4, P)
     PL = np.dot(P, L)
     y_tilde = Y - np.dot(P, L)
     TT, m_h = getCanoHRF(Thrf, dt)
     m_h = m_h[:D]
     m_H = np.array(m_h)
     sigma_epsilone = np.ones(J)
     Sigma_H = np.ones((D, D), dtype=float)
     m_A = np.zeros((J, M), dtype=np.float64)
     Sigma_A = np.zeros((M, M, J), np.float64)
     scale = 1
     zerosDD = np.zeros((D, D), dtype=np.float64)
     zerosD = np.zeros((D), dtype=np.float64)
     zerosND = np.zeros((N, D), dtype=np.float64)
     order = 2
     D2 = vt.buildFiniteDiffMatrix(order, D)
     R = np.dot(D2, D2) / pow(dt, 2*order)
     sigmaH = 0.1
     _, occurence_matrix, _ = vt.create_conditions(onsets, durations, M, N,
                                                   D, TR, dt)
     m_H, Sigma_H = vt.hrf_expectation(Sigma_A, m_A, occurence_matrix, Gamma, R,
                                       sigmaH, J, y_tilde, sigma_epsilone)
コード例 #15
0
ファイル: test_jde_vem_tools.py プロジェクト: ainafp/pyhrf
 def test_max_sigma_noise(self):
     M = 51
     D = 3
     N = 325
     J = 25
     TR = 1.
     Thrf=25.
     dt=.5
     data = self.data_simu
     X = OrderedDict([])
     Y = data.bold
     P = vt.PolyMat( N , 4 , TR)
     L = vt.polyFit(Y, TR, 4,P)
     PL = np.dot(P,L)
     TT,m_h = getCanoHRF(Thrf,dt)
     sigma_epsilone = np.ones(J)
     m_A = np.zeros((J,M),dtype=np.float64)
     Sigma_A = np.zeros((M,M,J),np.float64)
     m_H = np.array(m_h).astype(np.float64)
     Sigma_H = np.ones((D,D),dtype=np.float64)
     zerosMM = np.zeros((M,M),dtype=np.float64)
     sigma_eps = vt.maximization_sigma_noise(Y,X,m_A,m_H,Sigma_H,Sigma_A,
                                             PL,sigma_epsilone,M,zerosMM)
コード例 #16
0
 def test_max_sigma_noise(self):
     M = 51
     D = 3
     N = 325
     J = 25
     TR = 1.
     Thrf = 25.
     dt = .5
     Gamma = np.identity(N)
     data = self.data_simu
     XX = np.zeros((M, N, D), dtype=np.int32)
     Y = data.bold
     P = vt.PolyMat(N, 4, TR)
     L = vt.polyFit(Y, TR, 4, P)
     PL = np.dot(P, L)
     TT, m_h = getCanoHRF(Thrf, dt)
     sigma_epsilone = np.ones(J)
     m_A = np.zeros((J, M), dtype=np.float64)
     Sigma_A = np.zeros((M, M, J), np.float64)
     m_H = np.array(m_h).astype(np.float64)
     Sigma_H = np.ones((D, D), dtype=np.float64)
     UtilsC.maximization_sigma_noise(Gamma, PL, sigma_epsilone,
                                     Sigma_H, Y, m_A, m_H, Sigma_A,
                                     XX.astype(np.int32), J, D, M, N)
コード例 #17
0
ファイル: test_jde_vem_tools.py プロジェクト: ainafp/pyhrf
 def test_expectH(self):
     M = 51
     K = 2
     J = 25
     N = 325
     D = 3
     TR = 1.
     Thrf=25.
     dt=.5
     data = self.data_simu
     Gamma = np.identity(N)
     X = OrderedDict([])
     Y = data.bold
     P = vt.PolyMat( N , 4 , TR)
     L = vt.polyFit(Y, TR, 4,P)
     PL = np.dot(P,L)
     y_tilde = Y - np.dot(P,L)
     TT,m_h = getCanoHRF(Thrf,dt)
     m_h = m_h[:D]
     m_H = np.array(m_h)
     sigma_epsilone = np.ones(J)
     Sigma_H = np.ones((D,D),dtype=float)
     m_A = np.zeros((J,M),dtype=np.float64)
     Sigma_A = np.zeros((M,M,J),np.float64)
     scale=1
     zerosDD = np.zeros((D,D),dtype=np.float64)
     zerosD = np.zeros((D),dtype=np.float64)
     zerosND = np.zeros((N,D),dtype=np.float64)
     order = 2
     D2 = vt.buildFiniteDiffMatrix(order,D)
     R = np.dot(D2,D2) / pow(dt,2*order)
     sigmaH = 0.1
     Sigma_H, m_H = vt.expectation_H(Y,Sigma_A,m_A,X,Gamma,PL,D,R,
                                     sigmaH,J,N,y_tilde,zerosND,
                                     sigma_epsilone,scale,zerosDD,
                                     zerosD)
コード例 #18
0
 def test_max_sigma_noise(self):
     M = 51
     D = 3
     N = 325
     J = 25
     TR = 1.
     Thrf = 25.
     dt = .5
     Gamma = np.identity(N)
     data = self.data_simu
     XX = np.zeros((M, N, D), dtype=np.int32)
     Y = data.bold
     P = vt.PolyMat(N, 4, TR)
     L = vt.polyFit(Y, TR, 4, P)
     PL = np.dot(P, L)
     TT, m_h = getCanoHRF(Thrf, dt)
     sigma_epsilone = np.ones(J)
     m_A = np.zeros((J, M), dtype=np.float64)
     Sigma_A = np.zeros((M, M, J), np.float64)
     m_H = np.array(m_h).astype(np.float64)
     Sigma_H = np.ones((D, D), dtype=np.float64)
     UtilsC.maximization_sigma_noise(Gamma, PL, sigma_epsilone, Sigma_H,
                                     Y, m_A, m_H, Sigma_A,
                                     XX.astype(np.int32), J, D, M, N)
コード例 #19
0
def Main_vbjde_Extension_constrained(graph, Y, Onsets, Thrf, K, TR, beta,
                                     dt, scale=1, estimateSigmaH=True,
                                     sigmaH=0.05, NitMax=-1,
                                     NitMin=1, estimateBeta=True,
                                     PLOT=False, contrasts=[],
                                     computeContrast=False,
                                     gamma_h=0, estimateHRF=True,
                                     TrueHrfFlag=False,
                                     HrfFilename='hrf.nii',
                                     estimateLabels=True,
                                     LabelsFilename='labels.nii',
                                     MFapprox=False, InitVar=0.5,
                                     InitMean=2.0, MiniVEMFlag=False,
                                     NbItMiniVem=5):
    # VBJDE Function for BOLD with contraints

    logger.info("Fast EM with C extension started ...")
    np.random.seed(6537546)

    ##########################################################################
    # INITIALIZATIONS
    # Initialize parameters
    tau1 = 0.0
    tau2 = 0.0
    S = 100
    Init_sigmaH = sigmaH
    Nb2Norm = 1
    NormFlag = False
    if NitMax < 0:
        NitMax = 100
    gamma = 7.5
    #gamma_h = 1000
    gradientStep = 0.003
    MaxItGrad = 200
    Thresh = 1e-5
    Thresh_FreeEnergy = 1e-5
    estimateLabels = True  # WARNING!! They should be estimated

    # Initialize sizes vectors
    D = int(np.ceil(Thrf / dt)) + 1  # D = int(np.ceil(Thrf/dt))
    M = len(Onsets)
    N = Y.shape[0]
    J = Y.shape[1]
    l = int(np.sqrt(J))
    condition_names = []

    # Neighbours
    maxNeighbours = max([len(nl) for nl in graph])
    neighboursIndexes = np.zeros((J, maxNeighbours), dtype=np.int32)
    neighboursIndexes -= 1
    for i in xrange(J):
        neighboursIndexes[i, :len(graph[i])] = graph[i]
    # Conditions
    X = OrderedDict([])
    for condition, Ons in Onsets.iteritems():
        X[condition] = vt.compute_mat_X_2(N, TR, D, dt, Ons)
        condition_names += [condition]
    XX = np.zeros((M, N, D), dtype=np.int32)
    nc = 0
    for condition, Ons in Onsets.iteritems():
        XX[nc, :, :] = X[condition]
        nc += 1
    # Covariance matrix
    order = 2
    D2 = vt.buildFiniteDiffMatrix(order, D)
    R = np.dot(D2, D2) / pow(dt, 2 * order)
    invR = np.linalg.inv(R)
    Det_invR = np.linalg.det(invR)

    Gamma = np.identity(N)
    Det_Gamma = np.linalg.det(Gamma)

    p_Wtilde = np.zeros((M, K), dtype=np.float64)
    p_Wtilde1 = np.zeros((M, K), dtype=np.float64)
    p_Wtilde[:, 1] = 1

    Crit_H = 1
    Crit_Z = 1
    Crit_A = 1
    Crit_AH = 1
    AH = np.zeros((J, M, D), dtype=np.float64)
    AH1 = np.zeros((J, M, D), dtype=np.float64)
    Crit_FreeEnergy = 1

    cA = []
    cH = []
    cZ = []
    cAH = []
    FreeEnergy_Iter = []
    cTime = []
    cFE = []

    SUM_q_Z = [[] for m in xrange(M)]
    mu1 = [[] for m in xrange(M)]
    h_norm = []
    h_norm2 = []

    CONTRAST = np.zeros((J, len(contrasts)), dtype=np.float64)
    CONTRASTVAR = np.zeros((J, len(contrasts)), dtype=np.float64)
    Q_barnCond = np.zeros((M, M, D, D), dtype=np.float64)
    XGamma = np.zeros((M, D, N), dtype=np.float64)
    m1 = 0
    for k1 in X:  # Loop over the M conditions
        m2 = 0
        for k2 in X:
            Q_barnCond[m1, m2, :, :] = np.dot(
                np.dot(X[k1].transpose(), Gamma), X[k2])
            m2 += 1
        XGamma[m1, :, :] = np.dot(X[k1].transpose(), Gamma)
        m1 += 1

    if MiniVEMFlag:
        logger.info("MiniVEM to choose the best initialisation...")
        """InitVar, InitMean, gamma_h = MiniVEM_CompMod(Thrf,TR,dt,beta,Y,K,
                                                     gamma,gradientStep,
                                                     MaxItGrad,D,M,N,J,S,
                                                     maxNeighbours,
                                                     neighboursIndexes,
                                                     XX,X,R,Det_invR,Gamma,
                                                     Det_Gamma,
                                                     scale,Q_barnCond,XGamma,
                                                     NbItMiniVem,
                                                     sigmaH,estimateHRF)"""

        InitVar, InitMean, gamma_h = vt.MiniVEM_CompMod(Thrf, TR, dt, beta, Y, K, gamma, gradientStep, MaxItGrad, D, M, N, J, S, maxNeighbours,
                                                        neighboursIndexes, XX, X, R, Det_invR, Gamma, Det_Gamma, p_Wtilde, scale, Q_barnCond, XGamma, tau1, tau2, NbItMiniVem, sigmaH, estimateHRF)

    sigmaH = Init_sigmaH
    sigma_epsilone = np.ones(J)
    logger.info(
        "Labels are initialized by setting active probabilities to ones ...")
    q_Z = np.zeros((M, K, J), dtype=np.float64)
    q_Z[:, 1, :] = 1
    q_Z1 = np.zeros((M, K, J), dtype=np.float64)
    Z_tilde = q_Z.copy()

    # TT,m_h = getCanoHRF(Thrf-dt,dt) #TODO: check
    TT, m_h = getCanoHRF(Thrf, dt)  # TODO: check
    m_h = m_h[:D]
    m_H = np.array(m_h).astype(np.float64)
    m_H1 = np.array(m_h)
    sigmaH1 = sigmaH
    if estimateHRF:
        Sigma_H = np.ones((D, D), dtype=np.float64)
    else:
        Sigma_H = np.zeros((D, D), dtype=np.float64)

    Beta = beta * np.ones((M), dtype=np.float64)
    P = vt.PolyMat(N, 4, TR)
    L = vt.polyFit(Y, TR, 4, P)
    PL = np.dot(P, L)
    y_tilde = Y - PL
    Ndrift = L.shape[0]

    sigma_M = np.ones((M, K), dtype=np.float64)
    sigma_M[:, 0] = 0.5
    sigma_M[:, 1] = 0.6
    mu_M = np.zeros((M, K), dtype=np.float64)
    for k in xrange(1, K):
        mu_M[:, k] = InitMean
    Sigma_A = np.zeros((M, M, J), np.float64)
    for j in xrange(0, J):
        Sigma_A[:, :, j] = 0.01 * np.identity(M)
    m_A = np.zeros((J, M), dtype=np.float64)
    m_A1 = np.zeros((J, M), dtype=np.float64)
    for j in xrange(0, J):
        for m in xrange(0, M):
            for k in xrange(0, K):
                m_A[j, m] += np.random.normal(mu_M[m, k],
                                              np.sqrt(sigma_M[m, k])) * q_Z[m, k, j]
    m_A1 = m_A

    t1 = time.time()

    ##########################################################################
    # VBJDE num. iter. minimum

    ni = 0

    while ((ni < NitMin) or (((Crit_FreeEnergy > Thresh_FreeEnergy) or (Crit_AH > Thresh)) and (ni < NitMax))):

        logger.info("------------------------------ Iteration n° " +
                    str(ni + 1) + " ------------------------------")

        #####################
        # EXPECTATION
        #####################

        # A
        logger.info("E A step ...")
        UtilsC.expectation_A(q_Z, mu_M, sigma_M, PL, sigma_epsilone, Gamma,
                             Sigma_H, Y, y_tilde, m_A, m_H, Sigma_A, XX.astype(np.int32), J, D, M, N, K)
        val = np.reshape(m_A, (M * J))
        val[np.where((val <= 1e-50) & (val > 0.0))] = 0.0
        val[np.where((val >= -1e-50) & (val < 0.0))] = 0.0

        # crit. A
        DIFF = np.reshape(m_A - m_A1, (M * J))
        # To avoid numerical problems
        DIFF[np.where((DIFF < 1e-50) & (DIFF > 0.0))] = 0.0
        # To avoid numerical problems
        DIFF[np.where((DIFF > -1e-50) & (DIFF < 0.0))] = 0.0
        Crit_A = (
            np.linalg.norm(DIFF) / np.linalg.norm(np.reshape(m_A1, (M * J)))) ** 2
        cA += [Crit_A]
        m_A1[:, :] = m_A[:, :]

        # HRF h
        if estimateHRF:
            ################################
            #  HRF ESTIMATION
            ################################
            UtilsC.expectation_H(XGamma, Q_barnCond, sigma_epsilone, Gamma, R, Sigma_H, Y,
                                 y_tilde, m_A, m_H, Sigma_A, XX.astype(np.int32), J, D, M, N, scale, sigmaH)

            import cvxpy as cvx
            m, n = Sigma_H.shape
            Sigma_H_inv = np.linalg.inv(Sigma_H)
            zeros_H = np.zeros_like(m_H[:, np.newaxis])

            # Construct the problem. PRIMAL
            h = cvx.Variable(n)
            expression = cvx.quad_form(h - m_H[:, np.newaxis], Sigma_H_inv)
            objective = cvx.Minimize(expression)
            #constraints = [h[0] == 0, h[-1]==0, h >= zeros_H, cvx.square(cvx.norm(h,2))<=1]
            constraints = [
                h[0] == 0, h[-1] == 0, cvx.square(cvx.norm(h, 2)) <= 1]
            prob = cvx.Problem(objective, constraints)
            result = prob.solve(verbose=0, solver=cvx.CVXOPT)

            # Now we update the mean of h
            m_H_old = m_H
            Sigma_H_old = Sigma_H
            m_H = np.squeeze(np.array((h.value)))
            Sigma_H = np.zeros_like(Sigma_H)

            h_norm += [np.linalg.norm(m_H)]
            # print 'h_norm = ', h_norm

            # Plotting HRF
            if PLOT and ni >= 0:
                import matplotlib.pyplot as plt
                plt.figure(M + 1)
                plt.plot(m_H)
                plt.hold(True)
        else:
            if TrueHrfFlag:
                #TrueVal, head = read_volume(HrfFilename)
                TrueVal, head = read_volume(HrfFilename)[:, 0, 0, 0]
                print TrueVal
                print TrueVal.shape
                m_H = TrueVal

        # crit. h
        Crit_H = (np.linalg.norm(m_H - m_H1) / np.linalg.norm(m_H1)) ** 2
        cH += [Crit_H]
        m_H1[:] = m_H[:]

        # crit. AH
        for d in xrange(0, D):
            AH[:, :, d] = m_A[:, :] * m_H[d]
        DIFF = np.reshape(AH - AH1, (M * J * D))
        # To avoid numerical problems
        DIFF[np.where((DIFF < 1e-50) & (DIFF > 0.0))] = 0.0
        # To avoid numerical problems
        DIFF[np.where((DIFF > -1e-50) & (DIFF < 0.0))] = 0.0
        if np.linalg.norm(np.reshape(AH1, (M * J * D))) == 0:
            Crit_AH = 1000000000.
        else:
            Crit_AH = (
                np.linalg.norm(DIFF) / np.linalg.norm(np.reshape(AH1, (M * J * D)))) ** 2
        cAH += [Crit_AH]
        AH1[:, :, :] = AH[:, :, :]

        # Z labels
        if estimateLabels:
            logger.info("E Z step ...")
            # WARNING!!! ParsiMod gives better results, but we need the other
            # one.
            if MFapprox:
                UtilsC.expectation_Z(Sigma_A, m_A, sigma_M, Beta, Z_tilde, mu_M, q_Z, neighboursIndexes.astype(
                    np.int32), M, J, K, maxNeighbours)
            if not MFapprox:
                UtilsC.expectation_Z_ParsiMod_RVM_and_CompMod(
                    Sigma_A, m_A, sigma_M, Beta, mu_M, q_Z, neighboursIndexes.astype(np.int32), M, J, K, maxNeighbours)
        else:
            logger.info("Using True Z ...")
            TrueZ = read_volume(LabelsFilename)
            for m in xrange(M):
                q_Z[m, 1, :] = np.reshape(TrueZ[0][:, :, :, m], J)
                q_Z[m, 0, :] = 1 - q_Z[m, 1, :]

        # crit. Z
        val = np.reshape(q_Z, (M * K * J))
        val[np.where((val <= 1e-50) & (val > 0.0))] = 0.0

        DIFF = np.reshape(q_Z - q_Z1, (M * K * J))
        # To avoid numerical problems
        DIFF[np.where((DIFF < 1e-50) & (DIFF > 0.0))] = 0.0
        # To avoid numerical problems
        DIFF[np.where((DIFF > -1e-50) & (DIFF < 0.0))] = 0.0
        if np.linalg.norm(np.reshape(q_Z1, (M * K * J))) == 0:
            Crit_Z = 1000000000.
        else:
            Crit_Z = (
                np.linalg.norm(DIFF) / np.linalg.norm(np.reshape(q_Z1, (M * K * J)))) ** 2
        cZ += [Crit_Z]
        q_Z1 = q_Z

        #####################
        # MAXIMIZATION
        #####################

        # HRF: Sigma_h
        if estimateHRF:
            if estimateSigmaH:
                logger.info("M sigma_H step ...")
                if gamma_h > 0:
                    sigmaH = vt.maximization_sigmaH_prior(
                        D, Sigma_H_old, R, m_H_old, gamma_h)
                else:
                    sigmaH = vt.maximization_sigmaH(D, Sigma_H, R, m_H)
                logger.info('sigmaH = %s', str(sigmaH))

        # (mu,sigma)
        logger.info("M (mu,sigma) step ...")
        mu_M, sigma_M = vt.maximization_mu_sigma(
            mu_M, sigma_M, q_Z, m_A, K, M, Sigma_A)
        for m in xrange(M):
            SUM_q_Z[m] += [sum(q_Z[m, 1, :])]
            mu1[m] += [mu_M[m, 1]]

        # Drift L
        UtilsC.maximization_L(
            Y, m_A, m_H, L, P, XX.astype(np.int32), J, D, M, Ndrift, N)
        PL = np.dot(P, L)
        y_tilde = Y - PL

        # Beta
        if estimateBeta:
            logger.info("estimating beta")
            for m in xrange(0, M):
                if MFapprox:
                    Beta[m] = UtilsC.maximization_beta(beta, q_Z[m, :, :].astype(np.float64), Z_tilde[m, :, :].astype(
                        np.float64), J, K, neighboursIndexes.astype(np.int32), gamma, maxNeighbours, MaxItGrad, gradientStep)
                if not MFapprox:
                    #Beta[m] = UtilsC.maximization_beta(beta,q_Z[m,:,:].astype(np.float64),q_Z[m,:,:].astype(np.float64),J,K,neighboursIndexes.astype(int32),gamma,maxNeighbours,MaxItGrad,gradientStep)
                    Beta[m] = UtilsC.maximization_beta_CB(beta, q_Z[m, :, :].astype(
                        np.float64), J, K, neighboursIndexes.astype(np.int32), gamma, maxNeighbours, MaxItGrad, gradientStep)
            logger.info("End estimating beta")
            logger.info(Beta)

        # Sigma noise
        logger.info("M sigma noise step ...")
        UtilsC.maximization_sigma_noise(
            Gamma, PL, sigma_epsilone, Sigma_H, Y, m_A, m_H, Sigma_A, XX.astype(np.int32), J, D, M, N)

        #### Computing Free Energy ####
        if ni > 0:
            FreeEnergy1 = FreeEnergy

        """FreeEnergy = vt.Compute_FreeEnergy(y_tilde,m_A,Sigma_A,mu_M,sigma_M,
                                           m_H,Sigma_H,R,Det_invR,sigmaH,
                                           p_Wtilde,q_Z,neighboursIndexes,
                                           maxNeighbours,Beta,sigma_epsilone,
                                           XX,Gamma,Det_Gamma,XGamma,J,D,M,
                                           N,K,S,"CompMod")"""
        FreeEnergy = vt.Compute_FreeEnergy(y_tilde, m_A, Sigma_A, mu_M, sigma_M, m_H, Sigma_H, R, Det_invR, sigmaH, p_Wtilde, tau1,
                                           tau2, q_Z, neighboursIndexes, maxNeighbours, Beta, sigma_epsilone, XX, Gamma, Det_Gamma, XGamma, J, D, M, N, K, S, "CompMod")

        if ni > 0:
            Crit_FreeEnergy = (FreeEnergy1 - FreeEnergy) / FreeEnergy1
        FreeEnergy_Iter += [FreeEnergy]
        cFE += [Crit_FreeEnergy]

        # Update index
        ni += 1

        t02 = time.time()
        cTime += [t02 - t1]

    t2 = time.time()

    ##########################################################################
    # PLOTS and SNR computation

    FreeEnergyArray = np.zeros((ni), dtype=np.float64)
    for i in xrange(ni):
        FreeEnergyArray[i] = FreeEnergy_Iter[i]

    SUM_q_Z_array = np.zeros((M, ni), dtype=np.float64)
    mu1_array = np.zeros((M, ni), dtype=np.float64)
    h_norm_array = np.zeros((ni), dtype=np.float64)
    for m in xrange(M):
        for i in xrange(ni):
            SUM_q_Z_array[m, i] = SUM_q_Z[m][i]
            mu1_array[m, i] = mu1[m][i]
            h_norm_array[i] = h_norm[i]

    if PLOT and 0:
        import matplotlib.pyplot as plt
        import matplotlib
        font = {'size': 15}
        matplotlib.rc('font', **font)
        plt.savefig('./HRF_Iter_CompMod.png')
        plt.hold(False)
        plt.figure(2)
        plt.plot(cAH[1:-1], 'lightblue')
        plt.hold(True)
        plt.plot(cFE[1:-1], 'm')
        plt.hold(False)
        #plt.legend( ('CA','CH', 'CZ', 'CAH', 'CFE') )
        plt.legend(('CAH', 'CFE'))
        plt.grid(True)
        plt.savefig('./Crit_CompMod.png')
        plt.figure(3)
        plt.plot(FreeEnergyArray)
        plt.grid(True)
        plt.savefig('./FreeEnergy_CompMod.png')

        plt.figure(4)
        for m in xrange(M):
            plt.plot(SUM_q_Z_array[m])
            plt.hold(True)
        plt.hold(False)
        #plt.legend( ('m=0','m=1', 'm=2', 'm=3') )
        #plt.legend( ('m=0','m=1') )
        plt.savefig('./Sum_q_Z_Iter_CompMod.png')

        plt.figure(5)
        for m in xrange(M):
            plt.plot(mu1_array[m])
            plt.hold(True)
        plt.hold(False)
        plt.savefig('./mu1_Iter_CompMod.png')

        plt.figure(6)
        plt.plot(h_norm_array)
        plt.savefig('./HRF_Norm_CompMod.png')

        Data_save = xndarray(h_norm_array, ['Iteration'])
        Data_save.save('./HRF_Norm_Comp.nii')

    CompTime = t2 - t1
    cTimeMean = CompTime / ni

    sigma_M = np.sqrt(np.sqrt(sigma_M))
    logger.info("Nb iterations to reach criterion: %d", ni)
    logger.info("Computational time = %s min %s s", str(
        int(CompTime // 60)), str(int(CompTime % 60)))
    # print "Computational time = " + str(int( CompTime//60 ) ) + " min " + str(int(CompTime%60)) + " s"
    # print "sigma_H = " + str(sigmaH)
    logger.info('mu_M: %f', mu_M)
    logger.info('sigma_M: %f', sigma_M)
    logger.info("sigma_H = %s" + str(sigmaH))
    logger.info("Beta = %s" + str(Beta))

    StimulusInducedSignal = vt.computeFit(m_H, m_A, X, J, N)
    SNR = 20 * \
        np.log(
            np.linalg.norm(Y) / np.linalg.norm(Y - StimulusInducedSignal - PL))
    SNR /= np.log(10.)
    logger.info("SNR = %d", SNR)
    return ni, m_A, m_H, q_Z, sigma_epsilone, mu_M, sigma_M, Beta, L, PL, CONTRAST, CONTRASTVAR, cA[2:], cH[2:], cZ[2:], cAH[2:], cTime[2:], cTimeMean, Sigma_A, StimulusInducedSignal, FreeEnergyArray
コード例 #20
0
def Main_vbjde_physio(graph, Y, Onsets, durations, Thrf, K, TR, beta, dt,
                      scale=1, estimateSigmaH=True, estimateSigmaG=True,
                      sigmaH=0.05, sigmaG=0.05, gamma_h=0, gamma_g=0,
                      NitMax=-1, NitMin=1, estimateBeta=True, PLOT=False,
                      contrasts=[], computeContrast=False,
                      idx_first_tag=0, simulation=None, sigmaMu=None,
                      estimateH=True, estimateG=True, estimateA=True,
                      estimateC=True, estimateZ=True, estimateNoise=True,
                      estimateMP=True, estimateLA=True, use_hyperprior=False,
                      positivity=False, constraint=False,
                      phy_params=PHY_PARAMS_KHALIDOV11, prior='omega', zc=False):

    logger.info("EM for ASL!")
    np.random.seed(6537540)
    logger.info("data shape: ")
    logger.info(Y.shape)

    Thresh = 1e-5
    D, M = np.int(np.ceil(Thrf / dt)) + 1, len(Onsets)
    #D, M = np.int(np.ceil(Thrf / dt)), len(Onsets)
    n_sess, N, J = Y.shape[0], Y.shape[1], Y.shape[2]

    Crit_AH, Crit_CG, cTime, rerror, FE = 1, 1, [], [], []
    EP, EPlh, Ent = [],[],[]
    Crit_H, Crit_G, Crit_Z, Crit_A, Crit_C = 1, 1, 1, 1, 1
    cAH, cCG, AH1, CG1 = [], [], [], []
    cA, cC, cH, cG, cZ = [], [], [], [], []
    h_norm, g_norm = [], []
    SUM_q_Z = [[] for m in xrange(M)]
    mua1 = [[] for m in xrange(M)]
    muc1 = [[] for m in xrange(M)]
    sigmaH = sigmaH * J / 100
    print sigmaH
    gamma_h = gamma_h * 100 / J
    print gamma_h

    # Beta data
    MaxItGrad = 200
    gradientStep = 0.005
    gamma = 7.5
    print 'gamma = ', gamma
    print 'voxels = ', J
    maxNeighbours, neighboursIndexes = vt.create_neighbours(graph, J)
    print 'graph.shape = ', graph.shape

    # Conditions
    print 'Onsets: ', Onsets
    print 'durations = ', durations
    print 'creating conditions...'
    X, XX, condition_names = vt.create_conditions_block_ms(Onsets, durations,
                                                    M, N, D, n_sess, TR, dt)

    # Covariance matrix
    #R = vt.covariance_matrix(2, D, dt)
    _, R_inv = genGaussianSmoothHRF(zc, D, dt, 1., 2)
    R = np.linalg.inv(R_inv)

    if zc:
        XX = XX[:, :, :, 1:-1]    # XX shape (S, M, N, D)
        D = D - 2

    AH1, CG1 = np.zeros((J, M, D)), np.zeros((J, M, D))

    print 'HRF length = ', D
    print 'Condition number = ', M
    print 'Number of scans = ', N
    print 'Number of voxels = ', J
    print 'Number of sessions = ', n_sess
    print 'XX.shape = ', XX.shape

    # Noise matrix
    Gamma = np.identity(N)
    # Noise initialization
    sigma_eps = np.ones((n_sess, J))
    # Labels
    logger.info("Labels are initialized by setting active probabilities "
                "to ones ...")
    q_Z = np.ones((M, K, J), dtype=np.float64) / 2.
    #q_Z = np.zeros((M, K, J), dtype=np.float64)
    #q_Z[:, 1, :] = 1
    q_Z1 = copy.deepcopy(q_Z)
    Z_tilde = copy.deepcopy(q_Z)

    # H and G
    TT, m_h = getCanoHRF(Thrf, dt)
    H = np.array(m_h[:D]).astype(np.float64)
    H /= np.linalg.norm(H)
    Hb = create_physio_brf(phy_params, response_dt=dt, response_duration=Thrf)
    Hb /= np.linalg.norm(Hb)
    if prior=='balloon':
        H = Hb.copy()
    H1 = copy.deepcopy(H)
    Sigma_H = np.zeros((D, D), dtype=np.float64)

    # Initialize model parameters
    Beta = beta * np.ones((M), dtype=np.float64)
    n_drift = 4
    P = np.zeros((n_sess, N, n_drift+1), dtype=np.float64)
    L = np.zeros((n_drift+1, J, n_sess), dtype=np.float64)
    for s in xrange(0, n_sess):
        P[s, :, :] = vt.PolyMat(N, n_drift, TR)
        L[:, :, s] = vt.polyFit(Y[s, :, :], TR, n_drift, P[s, :, :])
    print 'P shape = ', P.shape
    print 'L shape = ', L.shape
    WP = P.copy()
    AL = L.copy()
    PL = np.einsum('ijk,kli->ijl', P, L)
    y_tilde = Y - PL

    # Parameters Gaussian mixtures
    mu_Ma = np.append(np.zeros((M, 1)), np.ones((M, 1)), axis=1).astype(np.float64)
    sigma_Ma = np.ones((M, K), dtype=np.float64) * 0.3

    # Params RLs
    m_A = np.zeros((n_sess, J, M), dtype=np.float64)
    for s in xrange(0, n_sess):
        for j in xrange(0, J):
            m_A[s, j, :] = (np.random.normal(mu_Ma, np.sqrt(sigma_Ma)) * q_Z[:, :, j]).sum(axis=1).T
    m_A1 = m_A.copy()
    Sigma_A = np.ones((M, M, J, n_sess)) * np.identity(M)[:, :, np.newaxis, np.newaxis]

    G = np.zeros_like(H)
    m_C = np.zeros_like(m_A)
    Sigma_G = np.zeros_like(Sigma_H)
    Sigma_C = np.zeros_like(Sigma_A)
    mu_Mc = np.zeros_like(mu_Ma)
    sigma_Mc = np.ones_like(sigma_Ma)
    W = np.zeros_like(Gamma)            # (N, N)

    # Precomputations
    print 'W shape is ', W.shape
    WX = W.dot(XX).transpose(1, 2, 0, 3)                                       # shape (S, M, N, D)
    Gamma_X = np.zeros((N, n_sess, M, D), dtype=np.float64)                    # shape (N, S, M, D)
    X_Gamma_X = np.zeros((D, M, n_sess, M, D), dtype=np.float64)               # shape (D, M, S, M, D)
    Gamma_WX = np.zeros((N, n_sess, M, D), dtype=np.float64)                   # shape (N, S, M, D)
    XW_Gamma_WX = np.zeros((D, M, n_sess, M, D), dtype=np.float64)             # shape (D, M, S, M, D)
    Gamma_WP = np.zeros((N, n_sess, n_drift+1), dtype=np.float64)              # shape (N, S, M, D)
    WP_Gamma_WP = np.zeros((n_sess, n_drift+1, n_drift+1), dtype=np.float64)   # shape (D, M, S, M, D)
    for s in xrange(0, n_sess):
        Gamma_X[:, s, :, :] = np.tensordot(Gamma, XX[s, :, :, :], axes=(1, 1))
        X_Gamma_X[:, :, s, :, :] = np.tensordot(XX[s, :, :, :].T, Gamma_X[:, s, :, :], axes=(1, 0))
        Gamma_WX[:, s, :, :] = np.tensordot(Gamma, WX[s, :, :, :], axes=(1, 1))
        XW_Gamma_WX[:, :, s, :, :] = np.tensordot(WX[s, :, :, :].T, Gamma_WX[:, s, :, :], axes=(1, 0))
        Gamma_WP[:, s, :] = Gamma.dot(WP[s, :, :])                             # (N, n_drift)
        WP_Gamma_WP[s, :, :] = WP[s, :, :].T.dot(Gamma_WP[:, s, :])            # (n_drift, n_drift)
    sigma_eps_m = np.maximum(sigma_eps, eps)                                   # (n_sess, J)
    cov_noise = sigma_eps_m[:, :, np.newaxis, np.newaxis]                      # (n_sess, J, 1, 1)


    ###########################################################################
    #############################################             VBJDE

    t1 = time.time()
    ni = 0

    #while ((ni < NitMin + 1) or (((Crit_AH > Thresh) or (Crit_CG > Thresh)) \
    #        and (ni < NitMax))):
    #while ((ni < NitMin + 1) or (((Crit_AH > Thresh)) \
    #        and (ni < NitMax))):
    while ((ni < NitMin + 1) or (((Crit_FE > Thresh * np.ones_like(Crit_FE)).any()) \
            and (ni < NitMax))):

        logger.info("-------- Iteration n° " + str(ni + 1) + " --------")

        if PLOT and ni >= 0:  # Plotting HRF and PRF
            logger.info("Plotting HRF and PRF for current iteration")
            vt.plot_response_functions_it(ni, NitMin, M, H, G)


        # Managing types of prior
        priorH_cov_term = np.zeros_like(R_inv)
        matrix_covH = R_inv.copy()
        if prior=='balloon':
            logger.info("   prior balloon")
            #matrix_covH = np.eye(R_inv.shape[0], R_inv.shape[1])
            priorH_mean_term = np.dot(matrix_covH / sigmaH, Hb)
        else:
            logger.info("   NO prior")
            priorH_mean_term = np.zeros_like(H)
            priorG_mean_term = np.zeros_like(G)


        #####################
        # EXPECTATION
        #####################


        # HRF H
        if estimateH:
            logger.info("E H step ...")
            Ht, Sigma_H = vt.expectation_H_ms(Sigma_A, m_A, m_C, G, XX, W, Gamma,
                                            Gamma_X, X_Gamma_X, J, y_tilde,
                                            cov_noise, matrix_covH, sigmaH,
                                            priorH_mean_term, priorH_cov_term, N, M, D, n_sess)

            if constraint:
                if not np.linalg.norm(Ht)==1:
                    logger.info("   constraint l2-norm = 1")
                    H = vt.constraint_norm1_b(Ht, Sigma_H)
                    #H = Ht / np.linalg.norm(Ht)
                else:
                    logger.info("   l2-norm already 1!!!!!")
                    H = Ht.copy()
                Sigma_H = np.zeros_like(Sigma_H)
            else:
                H = Ht.copy()
                h_norm = np.append(h_norm, np.linalg.norm(H))
                print 'h_norm = ', h_norm

            Crit_H = (np.linalg.norm(H - H1) / np.linalg.norm(H1)) ** 2
            cH += [Crit_H]
            H1[:] = H[:]


        # A
        if estimateA:
            logger.info("E A step ...")
            m_A, Sigma_A = vt.expectation_A_ms(m_A, Sigma_A, H, G, m_C, W, XX,
                                             Gamma, Gamma_X, q_Z,
                                             mu_Ma, sigma_Ma, J, y_tilde,
                                             Sigma_H, sigma_eps_m, N, M, D, n_sess)

            cA += [(np.linalg.norm(m_A - m_A1) / np.linalg.norm(m_A1)) ** 2]
            m_A1[:, :, :] = m_A[:, :, :]

        # Q labels
        if estimateZ:
            logger.info("E Q step ...")
            q_Z, Z_tilde = vt.expectation_Q_ms(Sigma_A, m_A, Sigma_C, m_C,
                                            sigma_Ma, mu_Ma, sigma_Mc, mu_Mc,
                                            Beta, Z_tilde, q_Z, neighboursIndexes, graph, M, J, K, n_sess)

            if 0:
                import matplotlib.pyplot as plt
                plt.close('all')
                fig = plt.figure(1)
                for m in xrange(M):
                    ax = fig.add_subplot(2, M, m + 1)
                    im = ax.matshow(m_A[:, :, m].mean(0).reshape(20, 20))
                    plt.colorbar(im, ax=ax)
                    ax = fig.add_subplot(2, M, m + 3)
                    im = ax.matshow(q_Z[m, 1, :].reshape(20, 20))
                    plt.colorbar(im, ax=ax)
                fig = plt.figure(2)
                for m in xrange(M):
                    for s in xrange(n_sess):
                        ax = fig.add_subplot(M, n_sess, n_sess * m + s + 1)
                        im = ax.matshow(m_A[s, :, m].reshape(20, 20))
                        plt.colorbar(im, ax=ax)
                plt.show()

            cZ += [(np.linalg.norm(q_Z - q_Z1) / (np.linalg.norm(q_Z1) + eps)) ** 2]
            q_Z1 = q_Z

        if ni > 0:
            free_energyE = 0
            for s in xrange(n_sess):
                free_energyE += vt.Compute_FreeEnergy(y_tilde[s, :, :], m_A[s, :, :], Sigma_A[:, :, :, s],
                                             mu_Ma, sigma_Ma, H, Sigma_H, AuxH, R, R_inv, sigmaH, sigmaG,
                                             m_C[s, :, :], Sigma_C[:, :, :, s], mu_Mc, sigma_Mc, G, Sigma_G,
                                             AuxG, q_Z, neighboursIndexes, Beta, Gamma,
                                             gamma, gamma_h, gamma_g, sigma_eps[s, :], XX[s, :, :, :],
                                             W, J, D, M, N, K, use_hyperprior, Gamma_X[:, s, :, :],
                                             Gamma_WX[:, s, :, :], bold=True, S=n_sess)
            if free_energyE < free_energy:
                logger.info("free energy has decreased after E step from %f to %f", free_energy, free_energyE)


        # crit. AH and CG
        logger.info("crit. AH and CG")
        AH = m_A[:, :, :, np.newaxis] * H[np.newaxis, np.newaxis, :]

        Crit_AH = (np.linalg.norm(AH - AH1) / (np.linalg.norm(AH1) + eps)) ** 2
        cAH += [Crit_AH]
        AH1 = AH.copy()
        logger.info("Crit_AH = " + str(Crit_AH))


        #####################
        # MAXIMIZATION
        #####################

        if prior=='balloon':
            logger.info("   prior balloon")
            AuxH = H - Hb
            AuxG = G - Gb
        else:
            logger.info("   NO prior")
            AuxH = H.copy()
            AuxG = G.copy()

        # Variance HRF: sigmaH
        if estimateSigmaH:
            logger.info("M sigma_H step ...")
            sigmaH = vt.maximization_sigma_asl(D, Sigma_H, matrix_covH, AuxH, use_hyperprior, gamma_h)
            logger.info('sigmaH = ' + str(sigmaH))

        if ni > 0:
            free_energyVh = 0
            for s in xrange(n_sess):
                free_energyVh += vt.Compute_FreeEnergy(y_tilde[s, :, :], m_A[s, :, :], Sigma_A[:, :, :, s], mu_Ma, sigma_Ma,
                                             H, Sigma_H, AuxH, R, R_inv, sigmaH, sigmaG,
                                             m_C[s, :, :], Sigma_C[:, :, :, s], mu_Mc, sigma_Mc, G, Sigma_G,
                                             AuxG, q_Z, neighboursIndexes, Beta, Gamma,
                                             gamma, gamma_h, gamma_g, sigma_eps[s, :], XX[s, :, :, :], W,
                                             J, D, M, N, K, use_hyperprior, Gamma_X[:, s, :, :], Gamma_WX[:, s, :, :], bold=True, S=n_sess)
            if free_energyVh < free_energyE:
                logger.info("free energy has decreased after v_h computation from %f to %f", free_energyE, free_energyVh)


        # (mu,sigma)
        if estimateMP:
            logger.info("M (mu,sigma) a and c step ...")
            #print 'q_Z = ', q_Z
            #print q_Z.shape
            mu_Ma, sigma_Ma = vt.maximization_mu_sigma_ms(q_Z, m_A, Sigma_A, M, J, n_sess, K)
            print 'mu_Ma = ', mu_Ma
            print 'sigma_Ma = ', sigma_Ma

        if ni > 0:
            free_energyMP = 0
            for s in xrange(n_sess):
                free_energyMP += vt.Compute_FreeEnergy(y_tilde[s, :, :], m_A[s, :, :], Sigma_A[:, :, :, s], mu_Ma, sigma_Ma,
                                             H, Sigma_H, AuxH, R, R_inv, sigmaH, sigmaG,
                                             m_C[s, :, :], Sigma_C[:, :, :, s], mu_Mc, sigma_Mc, G, Sigma_G,
                                             AuxG, q_Z, neighboursIndexes, Beta, Gamma,
                                             gamma, gamma_h, gamma_g, sigma_eps[s, :], XX[s, :, :, :], W,
                                             J, D, M, N, K, use_hyperprior, Gamma_X[:, s, :, :], Gamma_WX[:, s, :, :], bold=True, S=n_sess)
            if free_energyMP < free_energyVh:
                logger.info("free energy has decreased after GMM parameters computation from %f to %f", free_energyVh, free_energyMP)


        # Drift L, alpha
        if estimateLA:
            logger.info("M L, alpha step ...")
            for s in xrange(n_sess):
                AL[:, :, s] = vt.maximization_LA_asl(Y[s, :, :], m_A[s, :, :], m_C[s, :, :], XX[s, :, :, :],
                                                     WP[s, :, :], W, WP_Gamma_WP[s, :, :], H, G, Gamma)
            PL = np.einsum('ijk,kli->ijl', WP, AL)
            y_tilde = Y - PL

        if ni > 0:
            free_energyLA = 0
            for s in xrange(n_sess):
                free_energyLA += vt.Compute_FreeEnergy(y_tilde[s, :, :], m_A[s, :, :], Sigma_A[:, :, :, s], mu_Ma, sigma_Ma,
                                                 H, Sigma_H, AuxH, R, R_inv, sigmaH, sigmaG,
                                                 m_C[s, :, :], Sigma_C[:, :, :, s], mu_Mc, sigma_Mc, G, Sigma_G,
                                                 AuxG, q_Z, neighboursIndexes, Beta, Gamma,
                                                 gamma, gamma_h, gamma_g, sigma_eps[s, :], XX[s, :, :, :], W,
                                                 J, D, M, N, K, use_hyperprior, Gamma_X[:, s, :, :], Gamma_WX[:, s, :, :], bold=True, S=n_sess)
            if free_energyLA < free_energyMP:
                logger.info("free energy has decreased after drifts computation from %f to %f", free_energyMP, free_energyLA)


        # Beta
        if estimateBeta:
            logger.info("M beta step ...")
            """Qtilde = np.concatenate((Z_tilde, np.zeros((M, K, 1), dtype=Z_tilde.dtype)), axis=2)
            Qtilde_sumneighbour = Qtilde[:, :, neighboursIndexes].sum(axis=3)
            Beta = vt.maximization_beta_m2(Beta.copy(), q_Z, Qtilde_sumneighbour,
                                             Qtilde, neighboursIndexes, maxNeighbours,
                                             gamma, MaxItGrad, gradientStep)
            logger.info(Beta)
            """
            logger.info("M beta step ...")
            Qtilde = np.concatenate((Z_tilde, np.zeros((M, K, 1), dtype=Z_tilde.dtype)), axis=2)
            Qtilde_sumneighbour = Qtilde[:, :, neighboursIndexes].sum(axis=3)
            for m in xrange(0, M):
                Beta[m] = vt.maximization_beta_m2_scipy_asl(Beta[m].copy(), q_Z[m, :, :], Qtilde_sumneighbour[m, :, :],
                                                   Qtilde[m, :, :], neighboursIndexes, maxNeighbours,
                                                   gamma, MaxItGrad, gradientStep)
            logger.info(Beta)
        if ni > 0:
            free_energyB = 0
            for s in xrange(n_sess):
                free_energyB += vt.Compute_FreeEnergy(y_tilde[s, :, :], m_A[s, :, :], Sigma_A[:, :, :, s], mu_Ma, sigma_Ma,
                                             H, Sigma_H, AuxH, R, R_inv, sigmaH, sigmaG,
                                             m_C[s, :, :], Sigma_C[:, :, :, s], mu_Mc, sigma_Mc, G, Sigma_G,
                                             AuxG, q_Z, neighboursIndexes, Beta, Gamma,
                                             gamma, gamma_h, gamma_g, sigma_eps[s, :], XX[s, :, :, :], W,
                                             J, D, M, N, K, use_hyperprior, Gamma_X[:, s, :, :], Gamma_WX[:, s, :, :], bold=True, S=n_sess)
            if free_energyB < free_energyLA:
                logger.info("free energy has decreased after Beta computation from %f to %f", \
                                free_energyLA, free_energyB)
        if 0 and ni < 5:
            plt.close('all')
            for m in xrange(0, M):
                range_b = np.arange(-10., 20., 0.1)
                beta_plotting = np.zeros_like(range_b)
                grad_plotting = np.zeros_like(range_b)
                for ib, b in enumerate(range_b):
                    beta_plotting[ib] = vt.fun(b, q_Z[m, :, :], Qtilde_sumneighbour[m, :, :],
                                                          neighboursIndexes, gamma)
                    grad_plotting[ib] = vt.grad_fun(b, q_Z[m, :, :], Qtilde_sumneighbour[m, :, :],
                                                     neighboursIndexes, gamma)
                #print beta_plotting
                plt.figure(1)
                plt.hold('on')
                plt.plot(range_b, beta_plotting)
                plt.figure(2)
                plt.hold('on')
                plt.plot(range_b, grad_plotting)
            plt.show()


        # Sigma noise
        if estimateNoise:
            logger.info("M sigma noise step ...")
            for s in xrange(n_sess):
                sigma_eps[s, :] = vt.maximization_sigma_noise_asl(XX[s, :, :, :], m_A[s, :, :], Sigma_A[:, :, :, s], H, m_C[s, :, :], Sigma_C[:, :, :, s], \
                                                    G, Sigma_H, Sigma_G, W, y_tilde[s, :, :], Gamma, \
                                                    Gamma_X[:, s, :, :], Gamma_WX[:, s, :, :], N)

        if PLOT:
            for m in xrange(M):
                SUM_q_Z[m] += [q_Z[m, 1, :].sum()]
                mua1[m] += [mu_Ma[m, 1]]

        free_energy = 0
        for s in xrange(n_sess):
            if s==n_sess-1:
                plotFE = True
            else:
                plotFE = False
            free_energy += vt.Compute_FreeEnergy(y_tilde[s, :, :], m_A[s, :, :], Sigma_A[:, :, :, s], mu_Ma, sigma_Ma,
                                             H, Sigma_H, AuxH, R, R_inv, sigmaH, sigmaG,
                                             m_C[s, :, :], Sigma_C[:, :, :, s], mu_Mc, sigma_Mc, G, Sigma_G,
                                             AuxG, q_Z, neighboursIndexes, Beta, Gamma,
                                             gamma, gamma_h, gamma_g, sigma_eps[s, :], XX[s, :, :, :], W,
                                             J, D, M, N, K, use_hyperprior, Gamma_X[:, s, :, :], Gamma_WX[:, s, :, :],
                                             plot=plotFE, bold=True, S=n_sess)
        if ni > 0:
            if free_energy < free_energyB:
                logger.info("free energy has decreased after Noise computation from %f to %f", free_energyB, free_energy)

        if ni > 0:
            if free_energy < FE[-1]:
                logger.info("WARNING! free energy has decreased in this iteration from %f to %f", FE[-1], free_energy)

        FE += [free_energy]

        if ni > 5:
            #Crit_FE = np.abs((FE[-1] - FE[-2]) / FE[-2])
            FE0 = np.array(FE)
            Crit_FE = np.abs((FE0[-5:] - FE0[-6:-1]) / FE0[-6:-1])
            print Crit_FE
            print (Crit_FE > Thresh * np.ones_like(Crit_FE)).any()
        else:
            Crit_FE = 100

        ni += 1
        cTime += [time.time() - t1]

        logger.info("Computing reconstruction error")
        StimulusInducedSignal = vt.computeFit_asl(H, m_A[s, :, :], G, m_C[s, :, :], W, XX[s, :, :, :])
        rerror = np.append(rerror, \
                           np.mean(((Y[s, :, :] - StimulusInducedSignal) ** 2).sum(axis=0)) \
                           / np.mean((Y[s, :, :] ** 2).sum(axis=0)))

    CompTime = time.time() - t1


    # Normalize if not done already
    if not constraint: # or not normg:
        logger.info("l2-norm of H and G to 1 if not constraint")
        Hnorm = np.linalg.norm(H)
        H /= Hnorm
        Sigma_H /= Hnorm**2
        m_A *= Hnorm

    if zc:
        H = np.concatenate(([0], H, [0]))

    ## Compute contrast maps and variance
    if computeContrast and len(contrasts) > 0:
        logger.info("Computing contrasts ... ")
        CONTRAST_A, CONTRASTVAR_A, \
        CONTRAST_C, CONTRASTVAR_C = vt.compute_contrasts(condition_names,
                                                         contrasts, m_A[s, :, :], m_C[s, :, :],
                                                         Sigma_A[:, :, :, s], Sigma_C[:, :, :, s], M, J)
    else:
        CONTRAST_A, CONTRASTVAR_A, CONTRAST_C, CONTRASTVAR_C = 0, 0, 0, 0


    ###########################################################################
    ##########################################    PLOTS and SNR computation

    logger.info("Nb iterations to reach criterion: %d",  ni)
    logger.info("Computational time = %s min %s s",
                str(np.int(CompTime // 60)), str(np.int(CompTime % 60)))
    logger.info("Iteration time = %s min %s s",
                str(np.int((CompTime // ni) // 60)), str(np.int((CompTime / ni) % 60)))

    logger.info("perfusion baseline mean = %f", np.mean(AL[0, :, s]))
    logger.info("perfusion baseline var = %f", np.var(AL[0, :, s]))
    logger.info("drifts mean = %f", np.mean(AL[1:, :, s]))
    logger.info("drifts var = %f", np.var(AL[1:, :, s]))
    logger.info("noise mean = %f", np.mean(sigma_eps[s, :]))
    logger.info("noise var = %f", np.var(sigma_eps[s, :]))

    SNR10 = 20 * (np.log10(np.linalg.norm(Y[s, :, :]) / \
                np.linalg.norm(Y[s, :, :] - StimulusInducedSignal - PL[s, :, :])))
    logger.info("SNR = %d",  SNR10)

    return ni, m_A.mean(0), H, m_C.mean(0), G, Z_tilde, sigma_eps[s, :], \
           mu_Ma, sigma_Ma, mu_Mc, sigma_Mc, Beta, AL[:, :, s], PL[s, :, :], \
           np.zeros_like(AL[0, :, s]), Sigma_A[:, :, :, s], Sigma_C[:, :, :, s], Sigma_H, Sigma_G, rerror, \
           CONTRAST_A, CONTRASTVAR_A, CONTRAST_C, CONTRASTVAR_C, \
           cA[:], cH[2:], cC[2:], cG[2:], cZ[2:], cAH[2:], cCG[2:], \
           cTime, FE
コード例 #21
0
def Main_vbjde_Extension_constrained_stable(graph, Y, Onsets, Thrf, K, TR, beta,
                                            dt, scale=1, estimateSigmaH=True,
                                            sigmaH=0.05, NitMax=-1,
                                            NitMin=1, estimateBeta=True,
                                            PLOT=False, contrasts=[],
                                            computeContrast=False,
                                            gamma_h=0):
    """ Version modified by Lofti from Christine's version """
    logger.info(
        "Fast EM with C extension started ... Here is the stable version !")

    np.random.seed(6537546)

    # Initialize parameters
    S = 100
    if NitMax < 0:
        NitMax = 100
    gamma = 7.5  # 7.5
    gradientStep = 0.003
    MaxItGrad = 200
    Thresh = 1e-5

    # Initialize sizes vectors
    D = np.int(np.ceil(Thrf / dt)) + 1
    M = len(Onsets)
    N = Y.shape[0]
    J = Y.shape[1]
    l = np.int(np.sqrt(J))
    condition_names = []

    # Neighbours
    maxNeighbours = max([len(nl) for nl in graph])
    neighboursIndexes = np.zeros((J, maxNeighbours), dtype=np.int32)
    neighboursIndexes -= 1
    for i in xrange(J):
        neighboursIndexes[i, :len(graph[i])] = graph[i]
    # Conditions
    X = OrderedDict([])
    for condition, Ons in Onsets.iteritems():
        X[condition] = vt.compute_mat_X_2(N, TR, D, dt, Ons)
        condition_names += [condition]
    XX = np.zeros((M, N, D), dtype=np.int32)
    nc = 0
    for condition, Ons in Onsets.iteritems():
        XX[nc, :, :] = X[condition]
        nc += 1
    # Covariance matrix
    order = 2
    D2 = vt.buildFiniteDiffMatrix(order, D)
    R = np.dot(D2, D2) / pow(dt, 2 * order)
    invR = np.linalg.inv(R)
    Det_invR = np.linalg.det(invR)

    Gamma = np.identity(N)
    Det_Gamma = np.linalg.det(Gamma)

    Crit_H = 1
    Crit_Z = 1
    Crit_A = 1
    Crit_AH = 1
    AH = np.zeros((J, M, D), dtype=np.float64)
    AH1 = np.zeros((J, M, D), dtype=np.float64)
    Crit_FreeEnergy = 1
    cTime = []
    cA = []
    cH = []
    cZ = []
    cAH = []

    CONTRAST = np.zeros((J, len(contrasts)), dtype=np.float64)
    CONTRASTVAR = np.zeros((J, len(contrasts)), dtype=np.float64)
    Q_barnCond = np.zeros((M, M, D, D), dtype=np.float64)
    XGamma = np.zeros((M, D, N), dtype=np.float64)
    m1 = 0
    for k1 in X:  # Loop over the M conditions
        m2 = 0
        for k2 in X:
            Q_barnCond[m1, m2, :, :] = np.dot(
                np.dot(X[k1].transpose(), Gamma), X[k2])
            m2 += 1
        XGamma[m1, :, :] = np.dot(X[k1].transpose(), Gamma)
        m1 += 1

    sigma_epsilone = np.ones(J)
    logger.info(
        "Labels are initialized by setting active probabilities to ones ...")
    q_Z = np.zeros((M, K, J), dtype=np.float64)
    q_Z[:, 1, :] = 1
    q_Z1 = np.zeros((M, K, J), dtype=np.float64)
    Z_tilde = q_Z.copy()

    TT, m_h = getCanoHRF(Thrf, dt)  # TODO: check
    m_h = m_h[:D]
    m_H = np.array(m_h).astype(np.float64)
    m_H1 = np.array(m_h)
    sigmaH1 = sigmaH
    Sigma_H = np.ones((D, D), dtype=np.float64)

    Beta = beta * np.ones((M), dtype=np.float64)
    P = vt.PolyMat(N, 4, TR)
    L = vt.polyFit(Y, TR, 4, P)
    PL = np.dot(P, L)
    y_tilde = Y - PL
    Ndrift = L.shape[0]

    sigma_M = np.ones((M, K), dtype=np.float64)
    sigma_M[:, 0] = 0.5
    sigma_M[:, 1] = 0.6
    mu_M = np.zeros((M, K), dtype=np.float64)
    for k in xrange(1, K):
        mu_M[:, k] = 1  # InitMean
    Sigma_A = np.zeros((M, M, J), np.float64)
    for j in xrange(0, J):
        Sigma_A[:, :, j] = 0.01 * np.identity(M)
    m_A = np.zeros((J, M), dtype=np.float64)
    m_A1 = np.zeros((J, M), dtype=np.float64)
    for j in xrange(0, J):
        for m in xrange(0, M):
            for k in xrange(0, K):
                m_A[j, m] += np.random.normal(mu_M[m, k],
                                              np.sqrt(sigma_M[m, k])) * q_Z[m, k, j]
    m_A1 = m_A

    t1 = time.time()

    ##########################################################################
    # VBJDE num. iter. minimum

    ni = 0

    while ((ni < NitMin + 1) or ((Crit_AH > Thresh) and (ni < NitMax))):

        logger.info("------------------------------ Iteration n° " +
                    str(ni + 1) + " ------------------------------")

        #####################
        # EXPECTATION
        #####################

        # A
        logger.info("E A step ...")
        UtilsC.expectation_A(q_Z, mu_M, sigma_M, PL, sigma_epsilone, Gamma,
                             Sigma_H, Y, y_tilde, m_A, m_H, Sigma_A, XX.astype(np.int32), J, D, M, N, K)

        # crit. A
        DIFF = np.reshape(m_A - m_A1, (M * J))
        Crit_A = (
            np.linalg.norm(DIFF) / np.linalg.norm(np.reshape(m_A1, (M * J)))) ** 2
        cA += [Crit_A]
        m_A1[:, :] = m_A[:, :]

        # HRF h
        UtilsC.expectation_H(XGamma, Q_barnCond, sigma_epsilone, Gamma, R, Sigma_H, Y,
                             y_tilde, m_A, m_H, Sigma_A, XX.astype(np.int32), J, D, M, N, scale, sigmaH)
        #m_H[0] = 0
        #m_H[-1] = 0
        # Constrain with optimization strategy
        import cvxpy as cvx
        m, n = Sigma_H.shape
        Sigma_H_inv = np.linalg.inv(Sigma_H)
        zeros_H = np.zeros_like(m_H[:, np.newaxis])
        # Construct the problem. PRIMAL
        h = cvx.Variable(n)
        expression = cvx.quad_form(h - m_H[:, np.newaxis], Sigma_H_inv)
        objective = cvx.Minimize(expression)
        #constraints = [h[0] == 0, h[-1]==0, h >= zeros_H, cvx.square(cvx.norm(h,2))<=1]
        constraints = [h[0] == 0, h[-1] == 0, cvx.square(cvx.norm(h, 2)) <= 1]
        prob = cvx.Problem(objective, constraints)
        result = prob.solve(verbose=0, solver=cvx.CVXOPT)
        # Now we update the mean of h
        m_H_old = m_H
        Sigma_H_old = Sigma_H
        m_H = np.squeeze(np.array((h.value)))
        Sigma_H = np.zeros_like(Sigma_H)
        # and the norm
        h_norm += [np.linalg.norm(m_H)]

        # crit. h
        Crit_H = (np.linalg.norm(m_H - m_H1) / np.linalg.norm(m_H1)) ** 2
        cH += [Crit_H]
        m_H1[:] = m_H[:]

        # crit. AH
        for d in xrange(0, D):
            AH[:, :, d] = m_A[:, :] * m_H[d]
        DIFF = np.reshape(AH - AH1, (M * J * D))
        Crit_AH = (np.linalg.norm(
            DIFF) / (np.linalg.norm(np.reshape(AH1, (M * J * D))) + eps)) ** 2
        cAH += [Crit_AH]
        AH1[:, :, :] = AH[:, :, :]

        # Z labels
        logger.info("E Z step ...")
        UtilsC.expectation_Z(Sigma_A, m_A, sigma_M, Beta, Z_tilde, mu_M,
                             q_Z, neighboursIndexes.astype(np.int32), M, J, K, maxNeighbours)

        # crit. Z
        DIFF = np.reshape(q_Z - q_Z1, (M * K * J))
        Crit_Z = (np.linalg.norm(DIFF) /
                  (np.linalg.norm(np.reshape(q_Z1, (M * K * J))) + eps)) ** 2
        cZ += [Crit_Z]
        q_Z1[:, :, :] = q_Z[:, :, :]

        #####################
        # MAXIMIZATION
        #####################

        # HRF: Sigma_h
        if estimateSigmaH:
            logger.info("M sigma_H step ...")
            if gamma_h > 0:
                sigmaH = vt.maximization_sigmaH_prior(
                    D, Sigma_H, R, m_H, gamma_h)
            else:
                sigmaH = vt.maximization_sigmaH(D, Sigma_H, R, m_H)
            logger.info('sigmaH = %s', str(sigmaH))

        # (mu,sigma)
        logger.info("M (mu,sigma) step ...")
        mu_M, sigma_M = vt.maximization_mu_sigma(
            mu_M, sigma_M, q_Z, m_A, K, M, Sigma_A)

        # Drift L
        UtilsC.maximization_L(
            Y, m_A, m_H, L, P, XX.astype(np.int32), J, D, M, Ndrift, N)
        PL = np.dot(P, L)
        y_tilde = Y - PL

        # Beta
        if estimateBeta:
            logger.info("estimating beta")
            for m in xrange(0, M):
                Beta[m] = UtilsC.maximization_beta(beta, q_Z[m, :, :].astype(np.float64), Z_tilde[m, :, :].astype(
                    np.float64), J, K, neighboursIndexes.astype(np.int32), gamma, maxNeighbours, MaxItGrad, gradientStep)
            logger.info("End estimating beta")
            logger.info(Beta)

        # Sigma noise
        logger.info("M sigma noise step ...")
        UtilsC.maximization_sigma_noise(
            Gamma, PL, sigma_epsilone, Sigma_H, Y, m_A, m_H, Sigma_A, XX.astype(np.int32), J, D, M, N)

        t02 = time.time()
        cTime += [t02 - t1]

    t2 = time.time()

    ##########################################################################
    # PLOTS and SNR computation

    if PLOT and 0:
        font = {'size': 15}
        matplotlib.rc('font', **font)
        savefig('./HRF_Iter_CompMod.png')
        hold(False)
        figure(2)
        plot(cAH[1:-1], 'lightblue')
        hold(True)
        plot(cFE[1:-1], 'm')
        hold(False)
        legend(('CAH', 'CFE'))
        grid(True)
        savefig('./Crit_CompMod.png')
        figure(3)
        plot(FreeEnergyArray)
        grid(True)
        savefig('./FreeEnergy_CompMod.png')

        figure(4)
        for m in xrange(M):
            plot(SUM_q_Z_array[m])
            hold(True)
        hold(False)
        savefig('./Sum_q_Z_Iter_CompMod.png')

        figure(5)
        for m in xrange(M):
            plot(mu1_array[m])
            hold(True)
        hold(False)
        savefig('./mu1_Iter_CompMod.png')

        figure(6)
        plot(h_norm_array)
        savefig('./HRF_Norm_CompMod.png')

        Data_save = xndarray(h_norm_array, ['Iteration'])
        Data_save.save('./HRF_Norm_Comp.nii')

    CompTime = t2 - t1
    cTimeMean = CompTime / ni

    """
    Norm = np.linalg.norm(m_H)
    m_H /= Norm
    Sigma_H /= Norm**2
    sigmaH /= Norm**2
    m_A *= Norm
    Sigma_A *= Norm**2
    mu_M *= Norm
    sigma_M *= Norm**2
    sigma_M = np.sqrt(np.sqrt(sigma_M))
    """
    logger.info("Nb iterations to reach criterion: %d", ni)
    logger.info("Computational time = %s min %s s", str(
        np.int(CompTime // 60)), str(np.int(CompTime % 60)))
    logger.info('mu_M: %f', mu_M)
    logger.info('sigma_M: %f', sigma_M)
    logger.info("sigma_H = %s", str(sigmaH))
    logger.info("Beta = %s", str(Beta))

    StimulusInducedSignal = vt.computeFit(m_H, m_A, X, J, N)
    SNR = 20 * \
        np.log(
            np.linalg.norm(Y) / np.linalg.norm(Y - StimulusInducedSignal - PL))
    SNR /= np.log(10.)
    logger.info('SNR comp = %f', SNR)
    return ni, m_A, m_H, q_Z, sigma_epsilone, mu_M, sigma_M, Beta, L, PL, CONTRAST, CONTRASTVAR, cA[2:], cH[2:], cZ[2:], cAH[2:], cTime[2:], cTimeMean, Sigma_A, StimulusInducedSignal
コード例 #22
0
ファイル: vem_asl_constrained.py プロジェクト: ainafp/pyhrf
def Main_vbjde_constrained(graph, Y, Onsets, Thrf, K, TR, beta, dt, scale=1,
                           estimateSigmaH=True, estimateSigmaG=True,
                           sigmaH=0.05, sigmaG=0.05, gamma_h=0, gamma_g=0,
                           NitMax=-1, NitMin=1, estimateBeta=True, PLOT=False,
                           idx_first_tag=0, simulation=None,
                           estimateH=True, estimateG=True, estimateA=True,
                           estimateC=True, estimateZ=True, estimateNoise=True,
                           estimateMP=True, estimateLA=True):
    """ Version modified by Lofti from Christine's version """
    logger.info("EM for ASL!")
    np.random.seed(6537546)

    # Initialization
    gamma_h = 1000000000  #7.5
    gamma_g = 1000000000  #7.5
    gamma = 0.0000000001
    beta = 100
    Thresh = 1e-5
    D, M = np.int(np.ceil(Thrf / dt)) + 1, len(Onsets)
    N, J = Y.shape[0], Y.shape[1]
    Crit_AH, Crit_CG = 1, 1
    AH = np.zeros((J, M, D), dtype=np.float64)
    AH1 = np.zeros((J, M, D), dtype=np.float64)
    CG = np.zeros((J, M, D), dtype=np.float64)
    CG1 = np.zeros((J, M, D), dtype=np.float64)
    cTime = []
    cZ = []
    cAH = []
    cCG = []
    h_norm = []
    g_norm = []
    SUM_q_Z = [[] for m in xrange(M)]
    mua1 = [[] for m in xrange(M)]
    muc1 = [[] for m in xrange(M)]

    # Neighbours
    maxNeighbours, neighboursIndexes = EM.create_neighbours(graph, J)
    # Conditions
    X, XX = EM.create_conditions(Onsets, M, N, D, TR, dt)
    # Covariance matrix
    R = EM.covariance_matrix(2, D, dt)
    # Noise matrix
    Gamma = np.identity(N)
    # Noise initialization
    sigma_eps = np.ones(J)
    #Labels
    logger.info("Labels are initialized by setting active probabilities "
                "to ones ...")
    q_Z = np.zeros((M, K, J), dtype=np.float64)
    q_Z[:, 1, :] = 1
    q_Z1 = copy.deepcopy(q_Z)
    Z_tilde = copy.deepcopy(q_Z)
    # H and G
    TT, m_h = getCanoHRF(Thrf, dt)
    m_h = m_h[:D]
    H = np.array(m_h).astype(np.float64)
    Ht = copy.deepcopy(H)
    Sigma_H = np.zeros((D, D), dtype=np.float64)
    G = copy.deepcopy(H)
    Gt = copy.deepcopy(H)
    Sigma_G = copy.deepcopy(Sigma_H)
    # others
    Beta = beta * np.ones((M), dtype=np.float64)
    P = vt.PolyMat(N, 4, TR)
    L = vt.polyFit(Y, TR, 4, P)
    PL = np.dot(P, L)
    alpha = np.zeros((J), dtype=np.float64)
    w = np.ones((N))
    w[idx_first_tag::2] = -1
    w = - w
    W = np.diag(w)
    wa = np.dot(w[:, np.newaxis], alpha[np.newaxis, :])
    y_tilde = Y - PL - wa
    # Parameters Gaussian mixtures
    sigma_Ma = np.ones((M, K), dtype=np.float64)
    sigma_Ma[:, 0] = 0.5
    sigma_Ma[:, 1] = 0.6
    mu_Ma = np.zeros((M, K), dtype=np.float64)
    for k in xrange(1, K):
        mu_Ma[:, k] = 1
    sigma_Mc = copy.deepcopy(sigma_Ma)
    mu_Mc = copy.deepcopy(mu_Ma)
    # Params RLs
    Sigma_A = np.zeros((M, M, J), np.float64)
    for j in xrange(0, J):
        Sigma_A[:, :, j] = 0.01 * np.identity(M)
    m_A = np.zeros((J, M), dtype=np.float64)
    for j in xrange(0, J):
        for m in xrange(0, M):
            for k in xrange(0, K):
                m_A[j, m] += np.random.normal(mu_Ma[m, k], \
                                np.sqrt(sigma_Ma[m, k])) * q_Z[m, k, j]
    Sigma_C = copy.deepcopy(Sigma_A)
    m_C = copy.deepcopy(m_A)

    if simulation is not None:
        #print simulation
        # simulated values
        if not estimateH:
            H = Ht = simulation['brf'][:, 0]
            sigmaH = 20.
        if not estimateG:
            G = Gt = simulation['prf'][:, 0]
            sigmaG = 40.
        A = simulation['brls'].T
        if not estimateA:
            m_A = A
        C = simulation['prls'].T
        if not estimateC:
            m_C = C
        Z = simulation['labels']
        Z = np.append(Z[:, np.newaxis, :], Z[:, np.newaxis, :], axis=1)
        #Z[:, 1, :] = 1
        if not estimateZ:
            q_Z = copy.deepcopy(Z)
            Z_tilde = copy.deepcopy(Z)
        if not estimateLA:
            alpha = np.mean(simulation['perf_baseline'], 0)
            L = simulation['drift_coeffs']
            PL = np.dot(P, L)
            wa = np.dot(w[:, np.newaxis], alpha[np.newaxis, :])
            y_tilde = Y - PL - wa
        if not estimateNoise:
            sigma_eps = np.var(simulation['noise'], 0)
        if not estimateMP:
            #print simulation['condition_defs'][0]
            mu_Ma = np.array([[0, 2.2], [0, 2.2]])
            sigma_Ma = np.array([[.3, .3], [.3, .3]])
            mu_Mc = np.array([[0, 1.6], [0, 1.6]])
            sigma_Mc = np.array([[.3, .3], [.3, .3]])
    #print simulation['condition_defs'][0]
    #print simulation['condition_defs'][0]

    #sigmaH = 0.0001
    #sigmaG = 0.0001


    ###########################################################################
    #############################################             VBJDE

    t1 = time.time()
    ni = 0

    while ((ni < NitMin + 1) or ((Crit_AH > Thresh) and (Crit_CG > Thresh) \
            and (ni < NitMax))):

        logger.info("-------- Iteration n° " + str(ni + 1) + " ---------")

        #####################
        # EXPECTATION
        #####################

        # HRF H
        logger.info("E H step ...")
        if estimateH:
            logger.info("estimation")
            #sigmaH = 0.0001
            print sigmaH
            Ht, Sigma_H = EM.expectation_H(Sigma_A, m_A, m_C, G, X, W, Gamma,
                                           D, J, N, y_tilde, sigma_eps, scale,
                                           R, sigmaH)
            H = EM.constraint_norm1_b(Ht, Sigma_H)
            #H = Ht / np.linalg.norm(Ht)
            print 'BRF ERROR = ', EM.error(H, simulation['brf'][:, 0])
            h_norm = np.append(h_norm, np.linalg.norm(H))
            print 'h_norm = ', h_norm

        # PRF G
        logger.info("E G step ...")
        if estimateG:
            logger.info("estimation")
            Gt, Sigma_G = EM.expectation_G(Sigma_C, m_C, m_A, H, X, W, Gamma,
                                           D, J, N, y_tilde, sigma_eps, scale,
                                           R, sigmaG)
            G = EM.constraint_norm1_b(Gt, Sigma_G, positivity=True,
                                      perfusion=alpha)
            #G = Gt / np.linalg.norm(Gt)
            print 'PRF ERROR = ', EM.error(G, simulation['prf'][:, 0])
            g_norm = np.append(g_norm, np.linalg.norm(G))
            print 'g_norm = ', g_norm

        # A
        logger.info("E A step ...")
        if estimateA:
            logger.info("estimation")
            m_A, Sigma_A = EM.expectation_A(H, m_A, G, m_C, W, X, Gamma, q_Z,
                                            mu_Ma, sigma_Ma, D, J, M, K,
                                            y_tilde, Sigma_A, sigma_eps)
            print 'BRLS ERROR = ', EM.error(m_A, A)

        # C
        logger.info("E C step ...")
        if estimateC:
            logger.info("estimation")
            m_C, Sigma_C = EM.expectation_C(G, m_C, H, m_A, W, X, Gamma, q_Z,
                                            mu_Mc, sigma_Mc, D, J, M, K,
                                            y_tilde, Sigma_C, sigma_eps)
            #print 'true values: ', C
            #print 'estimated values: ', m_C
            print 'PRLS ERROR = ', EM.error(m_C, C)

        # Q labels
        logger.info("E Z step ...")
        if estimateZ:
            logger.info("estimation")
            q_Z, Z_tilde = EM.expectation_Z(Sigma_A, m_A, Sigma_C, m_C,
                                            sigma_Ma, mu_Ma, sigma_Mc, mu_Mc,
                                            Beta, Z_tilde, q_Z, graph, M, J, K)
            #print 'LABELS ERROR = ', EM.error(q_Z, Z)
            # crit. Z
            Crit_Z = (np.linalg.norm((q_Z - q_Z1).flatten()) / \
                         (np.linalg.norm(q_Z1).flatten() + eps)) ** 2
            cZ += [Crit_Z]
            q_Z1 = q_Z

        # crit. AH and CG
        for d in xrange(0, D):
            AH[:, :, d] = m_A[:, :] * H[d]
            CG[:, :, d] = (m_C[:, :] * G[d])
        Crit_AH = (np.linalg.norm(np.reshape(AH - AH1, (M * J * D))) / \
                  (np.linalg.norm(np.reshape(AH1, (M * J * D))) + eps)) ** 2
        cAH += [Crit_AH]
        AH1 = AH
        Crit_CG = (np.linalg.norm(np.reshape(CG - CG1, (M * J * D))) / \
                  (np.linalg.norm(np.reshape(CG1, (M * J * D))) + eps)) ** 2
        cCG += [Crit_CG]
        CG1 = CG

        if PLOT and ni >= 0:  # Plotting HRF and PRF
            import matplotlib.pyplot as plt
            plt.figure(M + 1)
            plt.plot(H)
            plt.hold(True)
            plt.figure(M + 2)
            plt.plot(G)
            plt.hold(True)

        #####################
        # MAXIMIZATION
        #####################

        # HRF: Sigma_h
        if estimateSigmaH:
            logger.info("M sigma_H step ...")
            print gamma_h
            sigmaH = EM.maximization_sigma_prior(D, R, H, gamma_h)
            logger.info('sigmaH = ' + str(sigmaH))
        # PRF: Sigma_g
        if estimateSigmaG:
            logger.info("M sigma_G step ...")
            sigmaG = EM.maximization_sigma_prior(D, R, G, gamma_g)
            logger.info('sigmaG = ' + str(sigmaG))
        # (mu,sigma)
        if estimateMP:
            logger.info("M (mu,sigma) a and c step ...")
            Mu_Ma, sigma_Ma = EM.maximization_mu_sigma(mu_Ma, sigma_Ma,
                                                   q_Z, m_A, K, M, Sigma_A)
            mu_Mc, sigma_Mc = EM.maximization_mu_sigma(mu_Mc, sigma_Mc,
                                                   q_Z, m_C, K, M, Sigma_C)

        # Drift L, alpha
        if estimateLA:
            L, alpha = EM.maximization_L_alpha(Y, m_A, m_C, X, W, w, H, \
                                               G, L, P, alpha)
            print 'ALPHA ERROR = ', EM.error(alpha, np.mean(\
                                            simulation['perf_baseline'], 0))
            print 'DRIFT ERROR = ', EM.error(L, simulation['drift_coeffs'])
            #alpha = np.zeros_like(np.mean(simulation['perf_baseline'], 0))
            PL = np.dot(P, L)
            wa = np.dot(w[:, np.newaxis], alpha[np.newaxis, :])
            y_tilde = Y - PL - wa

        # Beta
        if estimateBeta:
            logger.info("estimating beta")
            for m in xrange(0, M):
                Beta[m] = EM.maximization_beta(Beta[m], q_Z, Z_tilde,
                                        J, K, m, graph, gamma,
                                        neighboursIndexes, maxNeighbours)
            print Beta
            logger.info("End estimating beta")
            logger.info(Beta)

        # Sigma noise
        if estimateNoise:
            logger.info("M sigma noise step ...")
            sigma_eps = EM.maximization_sigma_noise(Y, X, m_A, Sigma_A, H,
                          m_C, Sigma_C, G, W, M, N, J, y_tilde, sigma_eps)
            print 'NOISE ERROR = ', EM.error(sigma_eps,
                                             np.var(simulation['noise'], 0))
            #print '  - est var noise: ', sigma_eps
            #print '  - sim var noise: ', np.var(simulation['noise'], 0)

        for m in xrange(M):
            SUM_q_Z[m] += [sum(q_Z[m, 1, :])]
            mua1[m] += [mu_Ma[m, 1]]
            muc1[m] += [mu_Mc[m, 1]]

        ni += 1
        t02 = time.time()
        cTime += [t02 - t1]

    t2 = time.time()
    CompTime = t2 - t1
    cTimeMean = CompTime / ni

    ###########################################################################
    ##########################################    PLOTS and SNR computation

    SUM_q_Z_array = np.zeros((M, ni), dtype=np.float64)
    mua1_array = np.zeros((M, ni), dtype=np.float64)
    muc1_array = np.zeros((M, ni), dtype=np.float64)
    #h_norm_array = np.zeros((ni), dtype=np.float64)
    for m in xrange(M):
        for i in xrange(ni):
            SUM_q_Z_array[m, i] = SUM_q_Z[m][i]
            mua1_array[m, i] = mua1[m][i]
            muc1_array[m, i] = muc1[m][i]
            #h_norm_array[i] = h_norm[i]

    if PLOT:
        font = {'size': 15}
        import matplotlib
        import matplotlib.pyplot as plt
        matplotlib.rc('font', **font)
        plt.figure(M + 1)
        plt.savefig('./BRF_Iter_ASL.png')
        plt.figure(M + 2)
        plt.savefig('./PRF_Iter_ASL.png')
        plt.hold(False)
        plt.figure(2)
        plt.plot(cAH[1:-1], 'lightblue')
        plt.hold(True)
        plt.plot(cCG[1:-1], 'm')
        plt.hold(False)
        plt.legend(('CAH', 'CCG'))
        plt.grid(True)
        plt.savefig('./Crit_ASL.png')
        plt.figure(4)
        for m in xrange(M):
            plt.plot(SUM_q_Z_array[m])
            plt.hold(True)
        plt.hold(False)
        plt.savefig('./Sum_q_Z_Iter_ASL.png')
        """plt.figure(5)
        for m in xrange(M):
            plt.plot(mua1_array[m])
            plt.hold(True)
            plt.plot(muc1_array[m])
        plt.hold(False)
        plt.legend(('mu_a', 'mu_c'))
        plt.savefig('./mu1_Iter_ASL.png')
        plt.figure(6)
        plt.plot(h_norm_array)
        plt.savefig('./HRF_Norm_ASL.png')"""

    logger.info("Nb iterations to reach criterion: %d",  ni)
    logger.info("Computational time = %s min %s s",
                str(np.int(CompTime // 60)), str(np.int(CompTime % 60)))

    StimulusInducedSignal = EM.computeFit(H, m_A, G, m_C, W, X, J, N)
    SNR = 20 * (np.log(np.linalg.norm(Y) / \
                np.linalg.norm(Y - StimulusInducedSignal - PL))) / np.log(10.)

    logger.info('mu_Ma: %f', mu_Ma)
    logger.info('sigma_Ma: %f', sigma_Ma)
    logger.info("sigma_H = %s" + str(sigmaH))
    logger.info('mu_Mc: %f', mu_Mc)
    logger.info('sigma_Mc: %f', sigma_Mc)
    logger.info("sigma_G = %s" + str(sigmaG))
    logger.info("Beta = %s" + str(Beta))
    logger.info('SNR comp = %f', SNR)

    return ni, m_A, H, m_C, G, q_Z, sigma_eps, cZ[2:],\
           cTime, cTimeMean, mu_Ma, sigma_Ma, mu_Mc, sigma_Mc, Beta, L, PL, \
           Sigma_A, Sigma_C, StimulusInducedSignal
コード例 #23
0
def Main_vbjde_Python_constrained(graph, Y, Onsets, Thrf, K, TR, beta, dt, scale=1, estimateSigmaH=True, sigmaH=0.1, NitMax=-1, NitMin=1, estimateBeta=False, PLOT=False):
    logger.info("EM started ...")
    np.random.seed(6537546)

    ##########################################################################
    # INITIALIZATIONS
    # Initialize parameters
    if NitMax < 0:
        NitMax = 100
    gamma = 7.5
    gradientStep = 0.005
    MaxItGrad = 120
    #Thresh = 1e-5
    Thresh_FreeEnergy = 1e-5

    # Initialize sizes vectors
    D = int(np.ceil(Thrf / dt))
    M = len(Onsets)
    N = Y.shape[0]
    J = Y.shape[1]
    l = int(np.sqrt(J))
    sigma_epsilone = np.ones(J)

    # Neighbours
    maxNeighbours = max([len(nl) for nl in graph])
    neighboursIndexes = np.zeros((J, maxNeighbours), dtype=np.int32)
    neighboursIndexes -= 1
    for i in xrange(J):
        neighboursIndexes[i, :len(graph[i])] = graph[i]
    # Conditions
    X = OrderedDict([])
    for condition, Ons in Onsets.iteritems():
        X[condition] = vt.compute_mat_X_2(N, TR, D, dt, Ons)
    XX = np.zeros((M, N, D), dtype=np.int32)
    nc = 0
    for condition, Ons in Onsets.iteritems():
        XX[nc, :, :] = X[condition]
        nc += 1
    # Sigma and mu
    mu_M = np.zeros((M, K), dtype=np.float64)
    sigma_M = 0.5 * np.ones((M, K), dtype=np.float64)
    sigma_M0 = 0.5 * np.ones((M, K), dtype=np.float64)
    for k in xrange(1, K):
        mu_M[:, k] = 2.0
    # Covariance matrix
    order = 2
    D2 = vt.buildFiniteDiffMatrix(order, D)
    R = np.dot(D2, D2) / pow(dt, 2 * order)

    Gamma = np.identity(N)

    q_Z = np.zeros((M, K, J), dtype=np.float64)
    # for k in xrange(0,K):
    q_Z[:, 1, :] = 1
    q_Z1 = np.zeros((M, K, J), dtype=np.float64)
    Z_tilde = q_Z.copy()

    Sigma_A = np.zeros((M, M, J), np.float64)
    m_A = np.zeros((J, M), dtype=np.float64)
    TT, m_h = getCanoHRF(Thrf - dt, dt)  # TODO: check
    for j in xrange(0, J):
        Sigma_A[:, :, j] = 0.01 * np.identity(M)
        for m in xrange(0, M):
            for k in xrange(0, K):
                m_A[j, m] += np.random.normal(mu_M[m, k],
                                              np.sqrt(sigma_M[m, k])) * Z_tilde[m, k, j]
    m_H = np.array(m_h).astype(np.float64)
    m_H1 = np.array(m_h)
    Sigma_H = np.ones((D, D), dtype=np.float64)
    Beta = beta * np.ones((M), dtype=np.float64)

    zerosDD = np.zeros((D, D), dtype=np.float64)
    zerosD = np.zeros((D), dtype=np.float64)
    zerosND = np.zeros((N, D), dtype=np.float64)
    zerosMM = np.zeros((M, M), dtype=np.float64)
    zerosJMD = np.zeros((J, M, D), dtype=np.float64)
    zerosK = np.zeros(K)

    P = vt.PolyMat(N, 4, TR)
    zerosP = np.zeros((P.shape[0]), dtype=np.float64)
    L = vt.polyFit(Y, TR, 4, P)
    PL = np.dot(P, L)
    y_tilde = Y - PL
    sigmaH1 = sigmaH

    Crit_H = 1
    Crit_Z = 1
    Crit_A = 1
    cA = []
    cH = []
    cZ = []
    Ndrift = L.shape[0]
    Crit_FreeEnergy = 1

    t1 = time.time()

    ##########################################################################
    # VBJDE num. iter. minimum

    ni = 0

    while ((ni < NitMin) or (((Crit_FreeEnergy > Thresh_FreeEnergy) or ((Crit_H > Thresh) and (Crit_Z > Thresh) and (Crit_A > Thresh))) and (ni < NitMax))):

        logger.info("------------------------------ Iteration n° " +
                    str(ni + 1) + " ------------------------------")

        #####################
        # EXPECTATION
        #####################

        # A
        logger.info("E A step ...")
        Sigma_A, m_A = vt.expectation_A(
            Y, Sigma_H, m_H, m_A, X, Gamma, PL, sigma_M, q_Z, mu_M, D, N, J, M, K, y_tilde, Sigma_A, sigma_epsilone, zerosJMD)
        m_A1 = m_A

        # crit A
        DIFF = np.abs(np.reshape(m_A, (M * J)) - np.reshape(m_A1, (M * J)))
        Crit_A = sum(DIFF) / len(np.where(DIFF != 0))
        cA += [Crit_A]

        # H
        logger.info("E H step ...")
        Sigma_H, m_H = vt.expectation_H(
            Y, Sigma_A, m_A, X, Gamma, PL, D, R, sigmaH, J, N, y_tilde, zerosND, sigma_epsilone, scale, zerosDD, zerosD)
        m_H[0] = 0
        m_H[-1] = 0
        m_H1 = m_H

        # crit H
        Crit_H = np.abs(np.mean(m_H - m_H1) / np.mean(m_H))
        cH += [Crit_H]

        # Z
        logger.info("E Z step ...")
        q_Z, Z_tilde = vt.expectation_Z(
            Sigma_A, m_A, sigma_M, Beta, Z_tilde, mu_M, q_Z, graph, M, J, K, zerosK)

        # crit Z
        DIFF = np.abs(
            np.reshape(q_Z, (M * K * J)) - np.reshape(q_Z1, (M * K * J)))
        Crit_Z = sum(DIFF) / len(np.where(DIFF != 0))
        cZ += [Crit_Z]
        q_Z1 = q_Z

        # Plotting HRF
        if PLOT and ni >= 0:
            import matplotlib.pyplot as plt
            plt.figure(M + 1)
            plt.plot(m_H)
            plt.hold(True)

        ####################
        # MAXIMIZATION
        #####################

        # HRF: Sigma_h
        if estimateSigmaH:
            logger.info("M sigma_H step ...")
            sigmaH = (np.dot(vt.mult(m_H, m_H) + Sigma_H, R)).trace()
            sigmaH /= D

        # (mu,sigma)
        logger.info("M (mu,sigma) step ...")
        mu_M, sigma_M = vt.maximization_mu_sigma(
            mu_M, sigma_M, q_Z, m_A, K, M, Sigma_A)

        # Drift L
        L = vt.maximization_L(Y, m_A, X, m_H, L, P, zerosP)
        PL = np.dot(P, L)
        y_tilde = Y - PL

        # Beta
        if estimateBeta:
            logger.info("estimating beta")
            for m in xrange(0, M):
                Beta[m] = vt.maximization_beta(
                    Beta[m], q_Z, Z_tilde, J, K, m, graph, gamma, neighboursIndexes, maxNeighbours)
            logger.info("End estimating beta")
            # logger.info(Beta)

        # Sigma noise
        logger.info("M sigma noise step ...")
        sigma_epsilone = vt.maximization_sigma_noise(
            Y, X, m_A, m_H, Sigma_H, Sigma_A, PL, sigma_epsilone, M, zerosMM)

        #### Computing Free Energy ####
        """
        if ni > 0:
            FreeEnergy1 = FreeEnergy
        FreeEnergy = Compute_FreeEnergy(y_tilde,m_A,Sigma_A,mu_M,sigma_M,m_H,Sigma_H,R,Det_invR,sigmaH,p_Wtilde,tau1,tau2,q_Z,neighboursIndexes,maxNeighbours,Beta,sigma_epsilone,XX,Gamma,Det_Gamma,XGamma,J,D,M,N,K,S,"CompMod")
        if ni > 0:
            Crit_FreeEnergy = (FreeEnergy1 - FreeEnergy) / FreeEnergy1
        FreeEnergy_Iter += [FreeEnergy]
        cFE += [Crit_FreeEnergy]
        """

        # Update index
        ni += 1

    t2 = time.time()

    ##########################################################################
    # PLOTS and SNR computation

    """FreeEnergyArray = np.zeros((ni),dtype=np.float64)
    for i in xrange(ni):
        FreeEnergyArray[i] = FreeEnergy_Iter[i]

    SUM_q_Z_array = np.zeros((M,ni),dtype=np.float64)
    mu1_array = np.zeros((M,ni),dtype=np.float64)
    h_norm_array = np.zeros((ni),dtype=np.float64)
    for m in xrange(M):
        for i in xrange(ni):
            SUM_q_Z_array[m,i] = SUM_q_Z[m][i]
            mu1_array[m,i] = mu1[m][i]
            h_norm_array[i] = h_norm[i]
    sigma_M = np.sqrt(np.sqrt(sigma_M))
    """

    Norm = np.linalg.norm(m_H)
    m_H /= Norm
    m_A *= Norm
    mu_M *= Norm
    sigma_M *= Norm
    sigma_M = np.sqrt(sigma_M)

    if PLOT and 0:
        import matplotlib.pyplot as plt
        import matplotlib
        font = {'size': 15}
        matplotlib.rc('font', **font)
        plt.savefig('./HRF_Iter_CompMod.png')
        plt.hold(False)
        plt.figure(2)
        plt.plot(cAH[1:-1], 'lightblue')
        plt.hold(True)
        plt.plot(cFE[1:-1], 'm')
        plt.hold(False)
        #plt.legend( ('CA','CH', 'CZ', 'CAH', 'CFE') )
        plt.legend(('CAH', 'CFE'))
        plt.grid(True)
        plt.savefig('./Crit_CompMod.png')
        plt.figure(3)
        plt.plot(FreeEnergyArray)
        plt.grid(True)
        plt.savefig('./FreeEnergy_CompMod.png')

        plt.figure(4)
        for m in xrange(M):
            plt.plot(SUM_q_Z_array[m])
            plt.hold(True)
        plt.hold(False)
        plt.savefig('./Sum_q_Z_Iter_CompMod.png')

        plt.figure(5)
        for m in xrange(M):
            plt.plot(mu1_array[m])
            plt.hold(True)
        plt.hold(False)
        plt.savefig('./mu1_Iter_CompMod.png')

        plt.figure(6)
        plt.plot(h_norm_array)
        plt.savefig('./HRF_Norm_CompMod.png')

        Data_save = xndarray(h_norm_array, ['Iteration'])
        Data_save.save('./HRF_Norm_Comp.nii')

    CompTime = t2 - t1
    cTimeMean = CompTime / ni

    logger.info("Nb iterations to reach criterion: %d", ni)
    logger.info("Computational time = %s min %s s", str(
        int(CompTime // 60)), str(int(CompTime % 60)))
    # print "Computational time = " + str(int( CompTime//60 ) ) + " min " +
    # str(int(CompTime%60)) + " s"
    logger.info('mu_M: %f', mu_M)
    logger.info('sigma_M: %f', sigma_M)
    logger.info("sigma_H = %s" + str(sigmaH))
    logger.info("Beta = %s" + str(Beta))

    StimulusInducedSignal = vt.computeFit(m_H, m_A, X, J, N)
    SNR = 20 * \
        np.log(
            np.linalg.norm(Y) / np.linalg.norm(Y - StimulusInducedSignal - PL))
    SNR /= np.log(10.)
    logger.info('SNR comp = %f', SNR)
    return m_A, m_H, q_Z, sigma_epsilone, mu_M, sigma_M, Beta, L, PL
コード例 #24
0
ファイル: vem_asl_constrained.py プロジェクト: ainafp/pyhrf
def Main_vbjde_c_constrained(graph, Y, Onsets, Thrf, K, TR, beta, dt, scale=1,
                             estimateSigmaH=True, estimateSigmaG=True,
                             sigmaH=0.05, sigmaG=0.05, gamma_h=0, gamma_g=0,
                             NitMax=-1, NitMin=1, estimateBeta=True,
                             PLOT=False, idx_first_tag=0, simulation=None,
                             estimateH=True, estimateG=True, estimateA=True,
                             estimateC=True, estimateZ=True, M_step=True,
                             estimateNoise=True, estimateMP=True,
                             estimateLA=True):
    """ Version modified by Lofti from Christine's version """
    logger.info("Fast EM with C extension started ... "
                "Here is the stable version !")
    np.random.seed(6537546)

    #Initialize parameters
    #gamma_h = 7.5
    #gamma_g = 7.5
    D, M = np.int(np.ceil(Thrf / dt)) + 1, len(Onsets)
    N, J = Y.shape[0], Y.shape[1]
    if NitMax < 0:
        NitMax = 100
    gamma = 7.5
    gradientStep = 0.003
    MaxItGrad = 200
    Thresh = 1e-5

    # Neighbours
    maxNeighbours, neighboursIndexes = EM.create_neighbours(graph, J)
    # Conditions
    X, XX = EM.create_conditions(Onsets, M, N, D, TR, dt)
    # Covariance matrix
    R = EM.covariance_matrix(2, D, dt)
    # Noise matrix
    Gamma = np.identity(N)
    # Noise initialization
    sigma_eps = np.ones(J)

    Crit_AH, Crit_CG = 1, 1
    Crit_H, Crit_G, Crit_Z, Crit_A, Crit_C = 1, 1, 1, 1, 1
    AH = np.zeros((J, M, D), dtype=np.float64)
    AH1 = np.zeros((J, M, D), dtype=np.float64)
    CG = np.zeros((J, M, D), dtype=np.float64)
    CG1 = np.zeros((J, M, D), dtype=np.float64)
    cTime = []
    cAH, cCG = [], []
    cA, cC, cH, cG, cZ = [], [], [], [], []
    h_norm, g_norm = [], []

    #Labels
    logger.info("Labels are initialized by setting active probabilities "
                "to ones ...")
    q_Z = np.zeros((M, K, J), dtype=np.float64)
    q_Z[:, 1, :] = 1
    q_Z1 = np.zeros((M, K, J), dtype=np.float64)
    Z_tilde = copy.deepcopy(q_Z)
    # H and G
    TT, m_h = getCanoHRF(Thrf, dt)
    m_h = m_h[:D]
    H = np.array(m_h).astype(np.float64)
    H1 = copy.deepcopy(H)
    Sigma_H = np.zeros((D, D), dtype=np.float64)
    G = copy.deepcopy(H)
    G1 = copy.deepcopy(H)
    Sigma_G = copy.deepcopy(Sigma_H)
    #m_H = np.array(m_h).astype(np.float64)
    #m_H1 = np.array(m_h)

    # others
    Beta = beta * np.ones((M), dtype=np.float64)
    P = vt.PolyMat(N, 4, TR)
    L = vt.polyFit(Y, TR, 4, P)
    Ndrift = L.shape[0]
    PL = np.dot(P, L)
    alpha = np.zeros((J), dtype=np.float64)
    w = np.ones((N))
    w[idx_first_tag::2] = -1
    w = - w
    W = np.diag(w)
    wa = np.dot(w[:, np.newaxis], alpha[np.newaxis, :])
    y_tilde = Y - PL - wa

    # Parameters Gaussian mixtures
    sigma_Ma = np.ones((M, K), dtype=np.float64)
    sigma_Ma[:, 0] = 0.5
    sigma_Ma[:, 1] = 0.6
    mu_Ma = np.zeros((M, K), dtype=np.float64)
    for k in xrange(1, K):
        mu_Ma[:, k] = 1
    sigma_Mc = copy.deepcopy(sigma_Ma)
    mu_Mc = copy.deepcopy(mu_Ma)
    # Params RLs
    Sigma_A = np.zeros((M, M, J), np.float64)
    for j in xrange(0, J):
        Sigma_A[:, :, j] = 0.01 * np.identity(M)
    m_A = np.zeros((J, M), dtype=np.float64)
    m_A1 = np.zeros((J, M), dtype=np.float64)
    for j in xrange(0, J):
        for m in xrange(0, M):
            for k in xrange(0, K):
                m_A[j, m] += np.random.normal(mu_Ma[m, k], \
                                np.sqrt(sigma_Ma[m, k])) * q_Z[m, k, j]
    m_A1 = m_A
    Sigma_C = copy.deepcopy(Sigma_A)
    m_C1 = m_C = copy.deepcopy(m_A)

    Q_barnCond = np.zeros((M, M, D, D), dtype=np.float64)
    XGamma = np.zeros((M, D, N), dtype=np.float64)
    XWGamma = np.zeros((M, D, N), dtype=np.float64)
    for m1, k1 in enumerate(X):            # Loop over the M conditions
        for m2, k2 in enumerate(X):
            Q_barnCond[m1, m2, :, :] = np.dot(np.dot(X[k1].T, \
                                                     Gamma), X[k2])
        XGamma[m1, :, :] = np.dot(X[k1].T, Gamma)
        XWGamma[m1, :, :] = np.dot(np.dot(X[k1].T, W), Gamma)

    sigma_eps = np.ones(J)

    # simulated values
    if not estimateH:
        H = H1 = simulation['primary_brf']
        sigmaH = 20.
    if not estimateG:
        G = G1 = simulation['primary_prf']
        sigmaG = 40.
    if not estimateA:
        A = simulation['brls'].T
        print 'shape BRLs: ', A.shape
        m_A = A
    if not estimateC:
        C = simulation['prls'].T
        print 'shape PRLs: ', C.shape
        m_C = C
    if not estimateZ:
        Z = np.reshape(simulation['labels_vol'], [2, 1, 400])
        Z = np.append(Z, np.ones_like(Z), axis=1)
        print np.reshape(Z[0, 0, :], [20, 20])
    if not estimateLA:
        alpha = np.mean(simulation['perf_baseline'], 0)
        L = simulation['drift_coeffs']
        PL = np.dot(P, L)
        wa = np.dot(w[:, np.newaxis], alpha[np.newaxis, :])
        y_tilde = Y - PL - wa
    if not estimateNoise:
        sigma_eps = np.mean(simulation['noise'], 0)
    if not estimateMP:
        mu_Ma = np.array([[0, 2.2], [0, 2.2]])
        sigma_Ma = np.array([[.3, .3], [.3, .3]])
        mu_Mc = np.array([[0, 1.6], [0, 1.6]])
        sigma_Mc = np.array([[.3, .3], [.3, .3]])

    t1 = time.time()

    ##########################################################################
    #############################################    VBJDE num. iter. minimum

    ni = 0

    while ((ni < NitMin + 1) or ((Crit_AH > Thresh) and (ni < NitMax))):

        logger.info("------------------------------ Iteration n° " + \
                    str(ni + 1) + " ------------------------------")

        #####################
        # EXPECTATION
        #####################

        # A
        if estimateA:
            logger.info("E A step ...")
            UtilsC.expectation_A(q_Z, mu_Mc, sigma_Mc, PL, sigma_eps,
                                 Gamma, Sigma_H, Y, y_tilde, m_A, H, Sigma_A,
                                 XX.astype(np.int32), J, D, M, N, K)

        # crit. A
        DIFF = np.reshape(m_A - m_A1, (M * J))
        Crit_A = (np.linalg.norm(DIFF) / \
                    np.linalg.norm(np.reshape(m_A1, (M * J)))) ** 2
        cA += [Crit_A]
        m_A1[:, :] = m_A[:, :]

        # C
        if estimateC:
            logger.info("E C step ...")
            UtilsC.expectation_C(q_Z, mu_Mc, sigma_Mc, PL, sigma_eps,
                                 Gamma, Sigma_H, Y, y_tilde, m_A, H, Sigma_A,
                                 XX.astype(np.int32), J, D, M, N, K)

        # crit. C
        DIFF = np.reshape(m_C - m_C1, (M * J))
        Crit_C = (np.linalg.norm(DIFF) / \
                            np.linalg.norm(np.reshape(m_C1, (M * J)))) ** 2
        cC += [Crit_C]
        m_C1[:, :] = m_C[:, :]

        # HRF h
        if estimateH:
            logger.info("E H step ...")
            UtilsC.expectation_H(XGamma, Q_barnCond, sigma_eps, Gamma, R,
                                 Sigma_H, Y, y_tilde, m_A, H, Sigma_A,
                                 XX.astype(np.int32), J, D, M, N, scale,
                                 sigmaH)
            #H = EM.constraint_norm1(m_H, Sigma_H)
            H = H / np.linalg.norm(H)
            print 'BRF ERROR = ', EM.error(H, simulation['primary_brf'])
            h_norm = np.append(h_norm, np.linalg.norm(H))
            print 'h_norm = ', h_norm

        # crit. h
        Crit_H = (np.linalg.norm(H - H1) / np.linalg.norm(H1)) ** 2
        cH += [Crit_H]
        H1[:] = H[:]

        # PRF g
        if estimateG:
            logger.info("E G step ...")
            UtilsC.expectation_G(XGamma, Q_barnCond, sigma_eps, Gamma, R,
                                 Sigma_H, Y, y_tilde, m_A, H, Sigma_A,
                                 XX.astype(np.int32), J, D, M, N, scale,
                                 sigmaH)
            G = EM.constraint_norm1(G, Sigma_G)
            print 'PRF ERROR = ', EM.error(G, simulation['primary_prf'])
            g_norm = np.append(g_norm, np.linalg.norm(G))
            print 'g_norm = ', g_norm

        # crit. g
        Crit_G = (np.linalg.norm(G - G1) / np.linalg.norm(G1)) ** 2
        cG += [Crit_G]
        G1[:] = G[:]

        # crit. AH
        for d in xrange(0, D):
            AH[:, :, d] = m_A[:, :] * H[d]
        DIFF = np.reshape(AH - AH1, (M * J * D))
        Crit_AH = (np.linalg.norm(DIFF) / \
                  (np.linalg.norm(np.reshape(AH1, (M * J * D))) + eps)) ** 2
        cAH += [Crit_AH]
        AH1[:, :, :] = AH[:, :, :]

        # crit. CG
        for d in xrange(0, D):
            CG[:, :, d] = m_C[:, :] * G[d]
        DIFF = np.reshape(CG - CG1, (M * J * D))
        Crit_CG = (np.linalg.norm(DIFF) / \
                  (np.linalg.norm(np.reshape(CG1, (M * J * D))) + eps)) ** 2
        cCG += [Crit_CG]
        CG1[:, :, :] = CG[:, :, :]

        # Z labels
        if estimateZ:
            logger.info("E Z step ...")
            UtilsC.expectation_Z(Sigma_A, m_A, sigma_M, Beta, Z_tilde, mu_M,
                                 q_Z, neighboursIndexes.astype(np.int32), M,
                                 J, K, maxNeighbours)

        # crit. Z
        DIFF = np.reshape(q_Z - q_Z1, (M * K * J))
        Crit_Z = (np.linalg.norm(DIFF) / \
                 (np.linalg.norm(np.reshape(q_Z1, (M * K * J))) + eps)) ** 2
        cZ += [Crit_Z]
        q_Z1[:, :, :] = q_Z[:, :, :]

        #####################
        # MAXIMIZATION
        #####################

        # HRF: Sigma_h
        if estimateSigmaH:
            logger.info("M sigma_H step ...")
            if gamma_h > 0:
                sigmaH = EM.maximization_sigma_prior(D, Sigma_H, R, H,
                                                      gamma_h)
            else:
                sigmaH = EM.maximization_sigma(D, Sigma_H, R, H)
            logger.info('sigmaH = %s', str(sigmaH))

        # PRF: Sigma_g
        if estimateSigmaG:
            logger.info("M sigma_G step ...")
            if gamma_g > 0:
                sigmaG = vt.maximization_sigma_prior(D, Sigma_G, R, G,
                                                      gamma_g)
            else:
                sigmaG = vt.maximization_sigma(D, Sigma_G, R, G)
            logger.info('sigmaG = %s',  str(sigmaG))

        # (mu_a,sigma_a)
        if estimateMP:
            logger.info("M (mu_a,sigma_a) step ...")
            mu_Ma, sigma_Ma = vt.maximization_mu_sigma(mu_Ma, sigma_Ma, q_Z,
                                                       m_A, K, M, Sigma_A)
            # (mu_c,sigma_c)
            logger.info("M (mu_c,sigma_c) step ...")
            mu_Mc, sigma_Mc = vt.maximization_mu_sigma(mu_Mc, sigma_Mc, q_Z,
                                                     m_A, K, M, Sigma_A)

        # Drift L
        if estimateLA:
            UtilsC.maximization_L(Y, m_A, H, L, P, XX.astype(np.int32), J, D,
                                  M, Ndrift, N)
            PL = np.dot(P, L)
            y_tilde = Y - PL

        # Beta
        if estimateBeta:
            logger.info("estimating beta")
            for m in xrange(0, M):
                Beta[m] = UtilsC.maximization_beta(beta, \
                            q_Z[m, :, :].astype(np.float64),
                            Z_tilde[m, :, :].astype(np.float64), J, K,
                            neighboursIndexes.astype(np.int32), gamma,
                            maxNeighbours, MaxItGrad, gradientStep)
            logger.info("End estimating beta")
            logger.info(Beta)

        # Sigma noise
        if estimateNoise:
            logger.info("M sigma noise step ...")
            UtilsC.maximization_sigma_noise(Gamma, PL, sigma_eps, Sigma_H,
                                            Y, m_A, H, Sigma_A,
                                            XX.astype(np.int32), J, D, M, N)

        t02 = time.time()
        cTime += [t02 - t1]

    t2 = time.time()

    ###########################################################################
    ###########################################    PLOTS and SNR computation

    CompTime = t2 - t1
    cTimeMean = CompTime / ni

    if 0:
        Norm = np.linalg.norm(H)
        H /= Norm
        Sigma_H /= Norm ** 2
        sigmaH /= Norm ** 2
        m_A *= Norm
        Sigma_A *= Norm ** 2
        mu_Ma *= Norm
        sigma_Ma *= Norm ** 2
        sigma_Ma = np.sqrt(np.sqrt(sigma_Ma))
        Norm = np.linalg.norm(G)
        G /= Norm
        Sigma_G /= Norm ** 2
        sigmaG /= Norm ** 2
        m_C *= Norm
        Sigma_C *= Norm ** 2
        mu_Mc *= Norm
        sigma_Mc *= Norm ** 2
        sigma_Mc = np.sqrt(np.sqrt(sigma_Mc))

    logger.info("Nb iterations to reach criterion: %d",  ni)
    logger.info("Computational time = %s min %s s", str(np.int(CompTime // 60)), str(np.int(CompTime % 60)))

    StimulusInducedSignal = vt.computeFit(H, m_A, X, J, N)
    SNR = 20 * np.log(np.linalg.norm(Y) / \
               np.linalg.norm(Y - StimulusInducedSignal - PL))
    SNR /= np.log(10.)

    logger.info('mu_Ma: %f', mu_Ma)
    logger.info('sigma_Ma: %f', sigma_Ma)
    logger.info("sigma_H = %s" + str(sigmaH))
    logger.info("Beta = %s" + str(Beta))
    logger.info('SNR comp = %f', SNR)

    return ni, m_A, H, q_Z, sigma_eps, mu_Ma, sigma_Ma, Beta, L, PL, \
           cA[2:], cH[2:], cZ[2:], cAH[2:], cTime[2:], \
           cTimeMean, Sigma_A, StimulusInducedSignal
コード例 #25
0
def Main_vbjde_physio(graph, Y, Onsets, durations, Thrf, K, TR, beta, dt,
                      scale=1, estimateSigmaH=True, estimateSigmaG=True,
                      sigmaH=0.05, sigmaG=0.05, gamma_h=0, gamma_g=0,
                      NitMax=-1, NitMin=1, estimateBeta=True, PLOT=False,
                      contrasts=[], computeContrast=False,
                      idx_first_tag=0, simulation=None, sigmaMu=None,
                      estimateH=True, estimateG=True, estimateA=True,
                      estimateC=True, estimateZ=True, estimateNoise=True,
                      estimateMP=True, estimateLA=True, use_hyperprior=False,
                      positivity=False, constraint=False,
                      phy_params=PHY_PARAMS_KHALIDOV11, prior='omega', zc=False):

    logger.info("EM for ASL!")
    np.random.seed(6537540)
    logger.info("data shape: ")
    logger.info(Y.shape)

    Thresh = 1e-5
    D, M = np.int(np.ceil(Thrf / dt)) + 1, len(Onsets)
    #D, M = np.int(np.ceil(Thrf / dt)), len(Onsets)
    N, J = Y.shape[0], Y.shape[1]
    Crit_AH, Crit_CG, cTime, rerror, FE = 1, 1, [], [], []
    EP, EPlh, Ent = [],[],[]
    Crit_H, Crit_G, Crit_Z, Crit_A, Crit_C = 1, 1, 1, 1, 1
    cAH, cCG, AH1, CG1 = [], [], [], []
    cA, cC, cH, cG, cZ = [], [], [], [], []
    h_norm, g_norm = [], []
    SUM_q_Z = [[] for m in xrange(M)]
    mua1 = [[] for m in xrange(M)]
    muc1 = [[] for m in xrange(M)]

    # Beta data
    MaxItGrad = 200
    gradientStep = 0.005
    gamma = 7.5
    maxNeighbours, neighboursIndexes = vt.create_neighbours(graph, J)

    # Control-tag
    w = np.ones((N))
    w[idx_first_tag + 1::2] = -1
    W = np.diag(w)
    # Conditions
    X, XX, condition_names = vt.create_conditions_block(Onsets, durations, M, N, D, TR, dt)
    #X, XX, condition_names = vt.create_conditions(Onsets, M, N, D, TR, dt)
    if zc:
        XX = XX[:, :, 1:-1]    # XX shape (S, M, N, D)
        D = D - 2
    AH1, CG1 = np.zeros((J, M, D)), np.zeros((J, M, D))

    # Covariance matrix
    #R = vt.covariance_matrix(2, D, dt)
    _, R_inv = genGaussianSmoothHRF(False, D, dt, 1., 2)
    R = np.linalg.inv(R_inv)
    # Noise matrix
    Gamma = np.identity(N)
    # Noise initialization
    sigma_eps = np.ones(J)
    # Labels
    logger.info("Labels are initialized by setting active probabilities "
                "to ones ...")
    q_Z = np.ones((M, K, J), dtype=np.float64) / 2.
    #q_Z = np.zeros((M, K, J), dtype=np.float64)
    #q_Z[:, 1, :] = 1
    q_Z1 = copy.deepcopy(q_Z)
    Z_tilde = copy.deepcopy(q_Z)

    # H and G
    TT, m_h = getCanoHRF(Thrf, dt)
    H = np.array(m_h[1:D+1]).astype(np.float64)
    H /= np.linalg.norm(H)
    G = copy.deepcopy(H)
    Hb = create_physio_brf(phy_params, response_dt=dt, response_duration=Thrf)
    Hb /= np.linalg.norm(Hb)
    Gb = create_physio_prf(phy_params, response_dt=dt, response_duration=Thrf)
    Gb /= np.linalg.norm(Gb)
    if prior=='balloon':
        H = Hb.copy()
        G = Gb.copy()
    Mu = Hb.copy()
    H1 = copy.deepcopy(H)
    Sigma_H = np.zeros((D, D), dtype=np.float64)
    G1 = copy.deepcopy(G)
    Sigma_G = copy.deepcopy(Sigma_H)
    normOh = False
    normg = False
    if prior=='hierarchical' or prior=='omega':
        Omega = linear_rf_operator(len(H), phy_params, dt, calculating_brf=False)
    if prior=='omega':
        Omega0 = Omega.copy()
        OmegaH = np.dot(Omega, H)
        G = np.dot(Omega, H)
        if normOh or normg:
            Omega /= np.linalg.norm(OmegaH)
            OmegaH /=np.linalg.norm(OmegaH)
            G /= np.linalg.norm(G)
    # Initialize model parameters
    Beta = beta * np.ones((M), dtype=np.float64)
    P = vt.PolyMat(N, 4, TR)
    L = vt.polyFit(Y, TR, 4, P)
    alpha = np.zeros((J), dtype=np.float64)
    WP = np.append(w[:, np.newaxis], P, axis=1)
    AL = np.append(alpha[np.newaxis, :], L, axis=0)
    y_tilde = Y - WP.dot(AL)

    # Parameters Gaussian mixtures
    mu_Ma = np.append(np.zeros((M, 1)), np.ones((M, 1)), axis=1).astype(np.float64)
    mu_Mc = mu_Ma.copy()
    sigma_Ma = np.ones((M, K), dtype=np.float64) * 0.3
    sigma_Mc = sigma_Ma.copy()

    # Params RLs
    m_A = np.zeros((J, M), dtype=np.float64)
    for j in xrange(0, J):
        m_A[j, :] = (np.random.normal(mu_Ma, np.sqrt(sigma_Ma)) * q_Z[:, :, j]).sum(axis=1).T
    m_A1 = m_A.copy()
    Sigma_A = np.ones((M, M, J)) * np.identity(M)[:, :, np.newaxis]
    m_C = m_A.copy()
    m_C1 = m_C.copy()
    Sigma_C = Sigma_A.copy()

    # Precomputations
    WX = W.dot(XX).transpose(1, 0, 2)
    Gamma_X = np.tensordot(Gamma, XX, axes=(1, 1))
    X_Gamma_X = np.tensordot(XX.T, Gamma_X, axes=(1, 0))    # shape (D, M, M, D)
    Gamma_WX = np.tensordot(Gamma, WX, axes=(1, 1))
    XW_Gamma_WX = np.tensordot(WX.T, Gamma_WX, axes=(1, 0)) # shape (D, M, M, D)
    Gamma_WP = Gamma.dot(WP)
    WP_Gamma_WP = WP.T.dot(Gamma_WP)
    sigma_eps_m = np.maximum(sigma_eps, eps)
    cov_noise = sigma_eps_m[:, np.newaxis, np.newaxis]

    ###########################################################################
    #############################################             VBJDE

    t1 = time.time()
    ni = 0

    #while ((ni < NitMin + 1) or (((Crit_AH > Thresh) or (Crit_CG > Thresh)) \
    #        and (ni < NitMax))):
    #while ((ni < NitMin + 1) or (((Crit_AH > Thresh)) \
    #        and (ni < NitMax))):
    while ((ni < NitMin + 1) or (((Crit_FE > Thresh * np.ones_like(Crit_FE)).any()) \
            and (ni < NitMax))):

        logger.info("-------- Iteration n° " + str(ni + 1) + " --------")

        if PLOT and ni >= 0:  # Plotting HRF and PRF
            logger.info("Plotting HRF and PRF for current iteration")
            vt.plot_response_functions_it(ni, NitMin, M, H, G, Mu, prior)


        # Managing types of prior
        priorH_cov_term = np.zeros_like(R_inv)
        priorG_cov_term = np.zeros_like(R_inv)
        matrix_covH = R_inv.copy()
        matrix_covG = R_inv.copy()
        if prior=='balloon':
            logger.info("   prior balloon")
            #matrix_covH = np.eye(R_inv.shape[0], R_inv.shape[1])
            #matrix_covG = np.eye(R_inv.shape[0], R_inv.shape[1])
            priorH_mean_term = np.dot(matrix_covH / sigmaH, Hb)
            priorG_mean_term = np.dot(matrix_covG / sigmaG, Gb)
        elif prior=='omega':
            logger.info("   prior omega")
            #matrix_covG = np.eye(R_inv.shape[0], R_inv.shape[1])
            priorH_mean_term = np.dot(np.dot(Omega.T, matrix_covG / sigmaG), G)
            priorH_cov_term = np.dot(np.dot(Omega.T, matrix_covG / sigmaG), Omega)
            priorG_mean_term = np.dot(matrix_covG / sigmaG, OmegaH)
        elif prior=='hierarchical':
            logger.info("   prior hierarchical")
            matrix_covH = np.eye(R_inv.shape[0], R_inv.shape[1])
            matrix_covG = np.eye(R_inv.shape[0], R_inv.shape[1])
            priorH_mean_term = Mu / sigmaH
            priorG_mean_term = np.dot(Omega, Mu / sigmaG)
        else:
            logger.info("   NO prior")
            priorH_mean_term = np.zeros_like(H)
            priorG_mean_term = np.zeros_like(G)


        #####################
        # EXPECTATION
        #####################


        # HRF H
        if estimateH:
            logger.info("E H step ...")
            Ht, Sigma_H = vt.expectation_H_asl(Sigma_A, m_A, m_C, G, XX, W, Gamma,
                                            Gamma_X, X_Gamma_X, J, y_tilde,
                                            cov_noise, matrix_covH, sigmaH,
                                            priorH_mean_term, priorH_cov_term)

            if constraint:
                if not np.linalg.norm(Ht)==1:
                    logger.info("   constraint l2-norm = 1")
                    H = vt.constraint_norm1_b(Ht, Sigma_H)
                    #H = Ht / np.linalg.norm(Ht)
                else:
                    logger.info("   l2-norm already 1!!!!!")
                    H = Ht.copy()
                Sigma_H = np.zeros_like(Sigma_H)
            else:
                H = Ht.copy()
                h_norm = np.append(h_norm, np.linalg.norm(H))
                print 'h_norm = ', h_norm

            Crit_H = (np.linalg.norm(H - H1) / np.linalg.norm(H1)) ** 2
            cH += [Crit_H]
            H1[:] = H[:]
            if prior=='omega':
                OmegaH = np.dot(Omega0, H)
                Omega = Omega0
                if normOh:
                    Omega /= np.linalg.norm(OmegaH)
                    OmegaH /= np.linalg.norm(OmegaH)

        if ni > 0:
            free_energyH = vt.Compute_FreeEnergy(y_tilde, m_A, Sigma_A, mu_Ma, sigma_Ma,
                                             H, Sigma_H, AuxH, R, R_inv, sigmaH, sigmaG,
                                             m_C, Sigma_C, mu_Mc, sigma_Mc, G, Sigma_G,
                                             AuxG, q_Z, neighboursIndexes, Beta, Gamma,
                                             gamma, gamma_h, gamma_g, sigma_eps, XX, W,
                                             J, D, M, N, K, use_hyperprior, Gamma_X, Gamma_WX)
            if free_energyH < free_energy:
                logger.info("free energy has decreased after E-H step from %f to %f", free_energy, free_energyH)

        # A
        if estimateA:
            logger.info("E A step ...")
            m_A, Sigma_A = vt.expectation_A_asl(H, G, m_C, W, XX, Gamma, Gamma_X, q_Z,
                                             mu_Ma, sigma_Ma, J, y_tilde,
                                             Sigma_H, sigma_eps_m)

            cA += [(np.linalg.norm(m_A - m_A1) / np.linalg.norm(m_A1)) ** 2]
            m_A1[:, :] = m_A[:, :]

        if ni > 0:
            free_energyA = vt.Compute_FreeEnergy(y_tilde, m_A, Sigma_A, mu_Ma, sigma_Ma,
                                             H, Sigma_H, AuxH, R, R_inv, sigmaH, sigmaG,
                                             m_C, Sigma_C, mu_Mc, sigma_Mc, G, Sigma_G,
                                             AuxG, q_Z, neighboursIndexes, Beta, Gamma,
                                             gamma, gamma_h, gamma_g, sigma_eps, XX, W,
                                             J, D, M, N, K, use_hyperprior, Gamma_X, Gamma_WX)
            if free_energyA < free_energyH:
                logger.info("free energy has decreased after E-A step from %f to %f", free_energyH, free_energyA)

        # PRF G
        if estimateG:
            logger.info("E G step ...")
            Gt, Sigma_G = vt.expectation_G_asl(Sigma_C, m_C, m_A, H, XX, W, WX, Gamma,
                                            Gamma_WX, XW_Gamma_WX, J, y_tilde,
                                            cov_noise, matrix_covG, sigmaG,
                                            priorG_mean_term, priorG_cov_term)

            if constraint and normg:
                if not np.linalg.norm(Gt)==1:
                    logger.info("   constraint l2-norm = 1")
                    G = vt.constraint_norm1_b(Gt, Sigma_G, positivity=positivity)
                    #G = Gt / np.linalg.norm(Gt)
                else:
                    logger.info("   l2-norm already 1!!!!!")
                    G = Gt.copy()
                Sigma_G = np.zeros_like(Sigma_G)
            else:
                G = Gt.copy()
                g_norm = np.append(g_norm, np.linalg.norm(G))
                print 'g_norm = ', g_norm
            cG += [(np.linalg.norm(G - G1) / np.linalg.norm(G1)) ** 2]
            G1[:] = G[:]

        if ni > 0:
            free_energyG = vt.Compute_FreeEnergy(y_tilde, m_A, Sigma_A, mu_Ma, sigma_Ma,
                                             H, Sigma_H, AuxH, R, R_inv, sigmaH, sigmaG,
                                             m_C, Sigma_C, mu_Mc, sigma_Mc, G, Sigma_G,
                                             AuxG, q_Z, neighboursIndexes, Beta, Gamma,
                                             gamma, gamma_h, gamma_g, sigma_eps, XX, W,
                                             J, D, M, N, K, use_hyperprior, Gamma_X, Gamma_WX)
            if free_energyG < free_energyA:
                logger.info("free energy has decreased after E-G step from %f to %f", free_energyA, free_energyG)


        # C
        if estimateC:
            logger.info("E C step ...")
            m_C, Sigma_C = vt.expectation_C_asl(G, H, m_A, W, XX, Gamma, Gamma_X, q_Z,
                                             mu_Mc, sigma_Mc, J, y_tilde,
                                             Sigma_G, sigma_eps_m)

            cC += [(np.linalg.norm(m_C - m_C1) / np.linalg.norm(m_C1)) ** 2]
            m_C1[:, :] = m_C[:, :]

        if ni > 0:
            free_energyC = vt.Compute_FreeEnergy(y_tilde, m_A, Sigma_A, mu_Ma, sigma_Ma,
                                             H, Sigma_H, AuxH, R, R_inv, sigmaH, sigmaG,
                                             m_C, Sigma_C, mu_Mc, sigma_Mc, G, Sigma_G,
                                             AuxG, q_Z, neighboursIndexes, Beta, Gamma,
                                             gamma, gamma_h, gamma_g, sigma_eps, XX, W,
                                             J, D, M, N, K, use_hyperprior, Gamma_X, Gamma_WX)
            if free_energyC < free_energyG:
                logger.info("free energy has decreased after E-C step from %f to %f", free_energyG, free_energyC)


        # Q labels
        if estimateZ:
            logger.info("E Q step ...")
            q_Z, Z_tilde = vt.expectation_Q_asl(Sigma_A, m_A, Sigma_C, m_C,
                                            sigma_Ma, mu_Ma, sigma_Mc, mu_Mc,
                                            Beta, Z_tilde, q_Z, neighboursIndexes, graph, M, J, K)
            #q_Z0, Z_tilde0 = vt.expectation_Q_async(Sigma_A, m_A, Sigma_C, m_C,
            #                                sigma_Ma, mu_Ma, sigma_Mc, mu_Mc,
            #                                Beta, Z_tilde, q_Z, neighboursIndexes, graph, M, J, K)
            #print 'synchronous vs asynchronous: ', np.abs(q_Z - q_Z0).sum()
            cZ += [(np.linalg.norm(q_Z - q_Z1) / (np.linalg.norm(q_Z1) + eps)) ** 2]
            q_Z1 = q_Z

        if ni > 0:
            free_energyQ = vt.Compute_FreeEnergy(y_tilde, m_A, Sigma_A, mu_Ma, sigma_Ma,
                                             H, Sigma_H, AuxH, R, R_inv, sigmaH, sigmaG,
                                             m_C, Sigma_C, mu_Mc, sigma_Mc, G, Sigma_G,
                                             AuxG, q_Z, neighboursIndexes, Beta, Gamma,
                                             gamma, gamma_h, gamma_g, sigma_eps, XX, W,
                                             J, D, M, N, K, use_hyperprior, Gamma_X, Gamma_WX)
            if free_energyQ < free_energyC:
                logger.info("free energy has decreased after E-Q step from %f to %f", free_energyC, free_energyQ)


        # crit. AH and CG
        logger.info("crit. AH and CG")
        AH = m_A[:, :, np.newaxis] * H[np.newaxis, np.newaxis, :]
        CG = m_C[:, :, np.newaxis] * G[np.newaxis, np.newaxis, :]

        Crit_AH = (np.linalg.norm(AH - AH1) / (np.linalg.norm(AH1) + eps)) ** 2
        cAH += [Crit_AH]
        AH1 = AH.copy()
        Crit_CG = (np.linalg.norm(CG - CG1) / (np.linalg.norm(CG1) + eps)) ** 2
        cCG += [Crit_CG]
        CG1 = CG.copy()
        logger.info("Crit_AH = " + str(Crit_AH))
        logger.info("Crit_CG = " + str(Crit_CG))


        #####################
        # MAXIMIZATION
        #####################

        if prior=='balloon':
            logger.info("   prior balloon")
            AuxH = H - Hb
            AuxG = G - Gb
        elif prior=='omega':
            logger.info("   prior omega")
            AuxH = H.copy()
            AuxG = G - np.dot(Omega, H) #/np.linalg.norm(np.dot(Omega, H))
        elif prior=='hierarchical':
            logger.info("   prior hierarchical")
            AuxH = H - Mu
            AuxG = G - np.dot(Omega, Mu)
        else:
            logger.info("   NO prior")
            AuxH = H.copy()
            AuxG = G.copy()

        # Variance HRF: sigmaH
        if estimateSigmaH:
            logger.info("M sigma_H step ...")
            sigmaH = vt.maximization_sigma_asl(D, Sigma_H, matrix_covH, AuxH, use_hyperprior, gamma_h)
            logger.info('sigmaH = ' + str(sigmaH))

        if ni > 0:
            free_energyVh = vt.Compute_FreeEnergy(y_tilde, m_A, Sigma_A, mu_Ma, sigma_Ma,
                                             H, Sigma_H, AuxH, R, R_inv, sigmaH, sigmaG,
                                             m_C, Sigma_C, mu_Mc, sigma_Mc, G, Sigma_G,
                                             AuxG, q_Z, neighboursIndexes, Beta, Gamma,
                                             gamma, gamma_h, gamma_g, sigma_eps, XX, W,
                                             J, D, M, N, K, use_hyperprior, Gamma_X, Gamma_WX)

            if free_energyVh < free_energyQ:
                logger.info("free energy has decreased after v_h computation from %f to %f", free_energyQ, free_energyVh)


        # Variance PRF: sigmaG
        if estimateSigmaG:
            logger.info("M sigma_G step ...")
            sigmaG = vt.maximization_sigma_asl(D, Sigma_G, matrix_covG, AuxG, use_hyperprior, gamma_g)
            logger.info('sigmaG = ' + str(sigmaG))

        if ni > 0:
            free_energyVg = vt.Compute_FreeEnergy(y_tilde, m_A, Sigma_A, mu_Ma, sigma_Ma,
                                             H, Sigma_H, AuxH, R, R_inv, sigmaH, sigmaG,
                                             m_C, Sigma_C, mu_Mc, sigma_Mc, G, Sigma_G,
                                             AuxG, q_Z, neighboursIndexes, Beta, Gamma,
                                             gamma, gamma_h, gamma_g, sigma_eps, XX, W,
                                             J, D, M, N, K, use_hyperprior, Gamma_X, Gamma_WX)

            if free_energyVg < free_energyVh:
                logger.info("free energy has decreased after v_g computation from %f to %f", free_energyVh, free_energyVg)


        # Mu: True HRF in the hierarchical prior case
        if prior=='hierarchical':
            logger.info("M sigma_G step ...")
            Mu = vt.maximization_Mu_asl(H, G, matrix_covH, matrix_covG,
                                     sigmaH, sigmaG, sigmaMu, Omega, R_inv)
            logger.info('sigmaG = ' + str(sigmaG))

        if ni > 0:
            free_energyMu = vt.Compute_FreeEnergy(y_tilde, m_A, Sigma_A, mu_Ma, sigma_Ma,
                                             H, Sigma_H, AuxH, R, R_inv, sigmaH, sigmaG,
                                             m_C, Sigma_C, mu_Mc, sigma_Mc, G, Sigma_G,
                                             AuxG, q_Z, neighboursIndexes, Beta, Gamma,
                                             gamma, gamma_h, gamma_g, sigma_eps, XX, W,
                                             J, D, M, N, K, use_hyperprior, Gamma_X, Gamma_WX)

            if free_energyMu < free_energyVg:
                logger.info("free energy has decreased after v_g computation from %f to %f", free_energyVg, free_energyMu)


        # (mu,sigma)
        if estimateMP:
            logger.info("M (mu,sigma) a and c step ...")
            mu_Ma, sigma_Ma = vt.maximization_mu_sigma_asl(q_Z, m_A, Sigma_A)
            mu_Mc, sigma_Mc = vt.maximization_mu_sigma_asl(q_Z, m_C, Sigma_C)

        if ni > 0:
            free_energyMP = vt.Compute_FreeEnergy(y_tilde, m_A, Sigma_A, mu_Ma, sigma_Ma,
                                             H, Sigma_H, AuxH, R, R_inv, sigmaH, sigmaG,
                                             m_C, Sigma_C, mu_Mc, sigma_Mc, G, Sigma_G,
                                             AuxG, q_Z, neighboursIndexes, Beta, Gamma,
                                             gamma, gamma_h, gamma_g, sigma_eps, XX, W,
                                             J, D, M, N, K, use_hyperprior, Gamma_X, Gamma_WX)
            if free_energyMP < free_energyVg:
                logger.info("free energy has decreased after GMM parameters computation from %f to %f", free_energyVg, free_energyMP)


        # Drift L, alpha
        if estimateLA:
            logger.info("M L, alpha step ...")
            AL = vt.maximization_LA_asl(Y, m_A, m_C, XX, WP, W, WP_Gamma_WP, H, G, Gamma)
            y_tilde = Y - WP.dot(AL)

        if ni > 0:
            free_energyLA = vt.Compute_FreeEnergy(y_tilde, m_A, Sigma_A, mu_Ma, sigma_Ma,
                                                 H, Sigma_H, AuxH, R, R_inv, sigmaH, sigmaG,
                                                 m_C, Sigma_C, mu_Mc, sigma_Mc, G, Sigma_G,
                                                 AuxG, q_Z, neighboursIndexes, Beta, Gamma,
                                                 gamma, gamma_h, gamma_g, sigma_eps, XX, W,
                                                 J, D, M, N, K, use_hyperprior, Gamma_X, Gamma_WX)
            if free_energyLA < free_energyMP:
                logger.info("free energy has decreased after drifts computation from %f to %f", free_energyMP, free_energyLA)


        # Beta
        if estimateBeta:
            logger.info("M beta step ...")
            """
            Qtilde = np.concatenate((Z_tilde, np.zeros((M, K, 1), dtype=Z_tilde.dtype)), axis=2)
            Qtilde_sumneighbour = Qtilde[:, :, neighboursIndexes].sum(axis=3)
            Beta = vt.maximization_beta_m2(Beta.copy(), q_Z, Qtilde_sumneighbour,
                                             Qtilde, neighboursIndexes, maxNeighbours,
                                             gamma, MaxItGrad, gradientStep)
            """
            Qtilde = np.concatenate((Z_tilde, np.zeros((M, K, 1), dtype=Z_tilde.dtype)), axis=2)
            Qtilde_sumneighbour = Qtilde[:, :, neighboursIndexes].sum(axis=3)
            for m in xrange(0, M):
                Beta[m] = vt.maximization_beta_m2_scipy_asl(Beta[m].copy(), q_Z[m, :, :],
                                                   Qtilde_sumneighbour[m, :, :],
                                                   Qtilde[m, :, :], neighboursIndexes,
                                                   maxNeighbours, gamma, MaxItGrad, gradientStep)
            logger.info(Beta)

        if ni > 0:
            free_energyB = vt.Compute_FreeEnergy(y_tilde, m_A, Sigma_A, mu_Ma, sigma_Ma,
                                             H, Sigma_H, AuxH, R, R_inv, sigmaH, sigmaG,
                                             m_C, Sigma_C, mu_Mc, sigma_Mc, G, Sigma_G,
                                             AuxG, q_Z, neighboursIndexes, Beta, Gamma,
                                             gamma, gamma_h, gamma_g, sigma_eps, XX, W,
                                             J, D, M, N, K, use_hyperprior, Gamma_X, Gamma_WX)
            if free_energyB < free_energyLA:
                logger.info("free energy has decreased after Beta computation from %f to %f", \
                                free_energyLA, free_energyB)
        if 0:
            plt.close('all')
            for m in xrange(0, M):
                range_b = np.arange(-10., 20., 0.1)
                beta_plotting = np.zeros_like(range_b)
                for ib, b in enumerate(range_b):
                    beta_plotting[ib] = vt.beta_function(b, q_Z[m, :, :], Qtilde_sumneighbour[m, :, :],
                                                         neighboursIndexes, gamma)
                #print beta_plotting
                plt.figure(1)
                plt.hold('on')
                plt.plot(range_b, beta_plotting)
            plt.show()

        # Sigma noise
        if estimateNoise:
            logger.info("M sigma noise step ...")
            sigma_eps = vt.maximization_sigma_noise_asl(XX, m_A, Sigma_A, H, m_C, Sigma_C, \
                                                    G, Sigma_H, Sigma_G, W, y_tilde, Gamma, \
                                                    Gamma_X, Gamma_WX, N)

        if PLOT:
            for m in xrange(M):
                SUM_q_Z[m] += [q_Z[m, 1, :].sum()]
                mua1[m] += [mu_Ma[m, 1]]
                muc1[m] += [mu_Mc[m, 1]]


        free_energy = vt.Compute_FreeEnergy(y_tilde, m_A, Sigma_A, mu_Ma, sigma_Ma,
                                             H, Sigma_H, AuxH, R, R_inv, sigmaH, sigmaG,
                                             m_C, Sigma_C, mu_Mc, sigma_Mc, G, Sigma_G,
                                             AuxG, q_Z, neighboursIndexes, Beta, Gamma,
                                             gamma, gamma_h, gamma_g, sigma_eps, XX, W,
                                             J, D, M, N, K, use_hyperprior, Gamma_X, Gamma_WX, plot=True)
        if ni > 0:
            if free_energy < free_energyB:
                logger.info("free energy has decreased after Noise computation from %f to %f", free_energyB, free_energy)

        if ni > 0:
            if free_energy < FE[-1]:
                logger.info("WARNING! free energy has decreased in this iteration from %f to %f", FE[-1], free_energy)

        FE += [free_energy]
        #EP += [EPt]
        #EPlh += [EPt_lh]
        #Ent += [Entropy]

        if ni > NitMin:
            #Crit_FE = np.abs((FE[-1] - FE[-2]) / FE[-2])
            FE0 = np.array(FE)
            Crit_FE = np.abs((FE0[-5:] - FE0[-6:-1]) / FE0[-6:-1])
            print Crit_FE
            print (Crit_FE > Thresh * np.ones_like(Crit_FE)).any()
        else:
            Crit_FE = 100

        ni += 1
        cTime += [time.time() - t1]

        logger.info("Computing reconstruction error")
        StimulusInducedSignal = vt.computeFit_asl(H, m_A, G, m_C, W, XX)
        rerror = np.append(rerror, \
                           np.mean(((Y - StimulusInducedSignal) ** 2).sum(axis=0)) \
                           / np.mean((Y ** 2).sum(axis=0)))

    CompTime = time.time() - t1


    # Normalize if not done already
    if not constraint or not normg:
        logger.info("l2-norm of H and G to 1 if not constraint")
        Hnorm = np.linalg.norm(H)
        H /= Hnorm
        Sigma_H /= Hnorm**2
        m_A *= Hnorm
        Gnorm = np.linalg.norm(G)
        G /= Gnorm
        Sigma_G /= Gnorm**2
        m_C *= Gnorm

    if zc:
        H = np.concatenate(([0], H, [0]))
        G = np.concatenate(([0], G, [0]))

    ## Compute contrast maps and variance
    if computeContrast and len(contrasts) > 0:
        logger.info("Computing contrasts ... ")
        CONTRAST_A, CONTRASTVAR_A, \
        CONTRAST_C, CONTRASTVAR_C = vt.compute_contrasts(condition_names,
                                                         contrasts, m_A, m_C,
                                                         Sigma_A, Sigma_C, M, J)
    else:
        CONTRAST_A, CONTRASTVAR_A, CONTRAST_C, CONTRASTVAR_C = 0, 0, 0, 0


    ###########################################################################
    ##########################################    PLOTS and SNR computation

    if PLOT:
        logger.info("plotting...")
        print 'FE = ', FE
        vt.plot_convergence(ni, M, cA, cC, cH, cG, cAH, cCG, SUM_q_Z, mua1, muc1, FE)

    logger.info("Nb iterations to reach criterion: %d",  ni)
    logger.info("Computational time = %s min %s s",
                str(np.int(CompTime // 60)), str(np.int(CompTime % 60)))
    logger.info("Iteration time = %s min %s s",
                str(np.int((CompTime // ni) // 60)), str(np.int((CompTime / ni) % 60)))

    logger.info("perfusion baseline mean = %f", np.mean(AL[0, :]))
    logger.info("perfusion baseline var = %f", np.var(AL[0, :]))
    logger.info("drifts mean = %f", np.mean(AL[1:, :]))
    logger.info("drifts var = %f", np.var(AL[1:, :]))
    logger.info("noise mean = %f", np.mean(sigma_eps))
    logger.info("noise var = %f", np.var(sigma_eps))

    SNR10 = 20 * (np.log10(np.linalg.norm(Y) / \
                np.linalg.norm(Y - StimulusInducedSignal - WP.dot(AL))))
    logger.info("SNR = %d",  SNR10)

    return ni, m_A, H, m_C, G, Z_tilde, sigma_eps, \
           mu_Ma, sigma_Ma, mu_Mc, sigma_Mc, Beta, AL[1:, :], np.dot(P, AL[1:, :]), \
           AL[0, :], Sigma_A, Sigma_C, Sigma_H, Sigma_G, rerror, \
           CONTRAST_A, CONTRASTVAR_A, CONTRAST_C, CONTRASTVAR_C, \
           cA[:], cH[2:], cC[2:], cG[2:], cZ[2:], cAH[2:], cCG[2:], \
           cTime, FE #, EP, EPlh, Ent
コード例 #26
0
ファイル: vem_bold_constrained.py プロジェクト: ainafp/pyhrf
def Main_vbjde_Extension_constrained_stable(graph, Y, Onsets, Thrf, K, TR, beta,
                                            dt, scale=1, estimateSigmaH=True,
                                            sigmaH=0.05, NitMax=-1,
                                            NitMin=1, estimateBeta=True,
                                            PLOT=False, contrasts=[],
                                            computeContrast=False,
                                            gamma_h=0):
    """ Version modified by Lofti from Christine's version """
    logger.info(
        "Fast EM with C extension started ... Here is the stable version !")

    np.random.seed(6537546)

    # Initialize parameters
    S = 100
    if NitMax < 0:
        NitMax = 100
    gamma = 7.5  # 7.5
    gradientStep = 0.003
    MaxItGrad = 200
    Thresh = 1e-5

    # Initialize sizes vectors
    D = np.int(np.ceil(Thrf / dt)) + 1
    M = len(Onsets)
    N = Y.shape[0]
    J = Y.shape[1]
    l = np.int(np.sqrt(J))
    condition_names = []

    # Neighbours
    maxNeighbours = max([len(nl) for nl in graph])
    neighboursIndexes = np.zeros((J, maxNeighbours), dtype=np.int32)
    neighboursIndexes -= 1
    for i in xrange(J):
        neighboursIndexes[i, :len(graph[i])] = graph[i]
    # Conditions
    X = OrderedDict([])
    for condition, Ons in Onsets.iteritems():
        X[condition] = vt.compute_mat_X_2(N, TR, D, dt, Ons)
        condition_names += [condition]
    XX = np.zeros((M, N, D), dtype=np.int32)
    nc = 0
    for condition, Ons in Onsets.iteritems():
        XX[nc, :, :] = X[condition]
        nc += 1
    # Covariance matrix
    order = 2
    D2 = vt.buildFiniteDiffMatrix(order, D)
    R = np.dot(D2, D2) / pow(dt, 2 * order)
    invR = np.linalg.inv(R)
    Det_invR = np.linalg.det(invR)

    Gamma = np.identity(N)
    Det_Gamma = np.linalg.det(Gamma)

    Crit_H = 1
    Crit_Z = 1
    Crit_A = 1
    Crit_AH = 1
    AH = np.zeros((J, M, D), dtype=np.float64)
    AH1 = np.zeros((J, M, D), dtype=np.float64)
    Crit_FreeEnergy = 1
    cTime = []
    cA = []
    cH = []
    cZ = []
    cAH = []

    CONTRAST = np.zeros((J, len(contrasts)), dtype=np.float64)
    CONTRASTVAR = np.zeros((J, len(contrasts)), dtype=np.float64)
    Q_barnCond = np.zeros((M, M, D, D), dtype=np.float64)
    XGamma = np.zeros((M, D, N), dtype=np.float64)
    m1 = 0
    for k1 in X:  # Loop over the M conditions
        m2 = 0
        for k2 in X:
            Q_barnCond[m1, m2, :, :] = np.dot(
                np.dot(X[k1].transpose(), Gamma), X[k2])
            m2 += 1
        XGamma[m1, :, :] = np.dot(X[k1].transpose(), Gamma)
        m1 += 1

    sigma_epsilone = np.ones(J)
    logger.info(
        "Labels are initialized by setting active probabilities to ones ...")
    q_Z = np.zeros((M, K, J), dtype=np.float64)
    q_Z[:, 1, :] = 1
    q_Z1 = np.zeros((M, K, J), dtype=np.float64)
    Z_tilde = q_Z.copy()

    TT, m_h = getCanoHRF(Thrf, dt)  # TODO: check
    m_h = m_h[:D]
    m_H = np.array(m_h).astype(np.float64)
    m_H1 = np.array(m_h)
    sigmaH1 = sigmaH
    Sigma_H = np.ones((D, D), dtype=np.float64)

    Beta = beta * np.ones((M), dtype=np.float64)
    P = vt.PolyMat(N, 4, TR)
    L = vt.polyFit(Y, TR, 4, P)
    PL = np.dot(P, L)
    y_tilde = Y - PL
    Ndrift = L.shape[0]

    sigma_M = np.ones((M, K), dtype=np.float64)
    sigma_M[:, 0] = 0.5
    sigma_M[:, 1] = 0.6
    mu_M = np.zeros((M, K), dtype=np.float64)
    for k in xrange(1, K):
        mu_M[:, k] = 1  # InitMean
    Sigma_A = np.zeros((M, M, J), np.float64)
    for j in xrange(0, J):
        Sigma_A[:, :, j] = 0.01 * np.identity(M)
    m_A = np.zeros((J, M), dtype=np.float64)
    m_A1 = np.zeros((J, M), dtype=np.float64)
    for j in xrange(0, J):
        for m in xrange(0, M):
            for k in xrange(0, K):
                m_A[j, m] += np.random.normal(mu_M[m, k],
                                              np.sqrt(sigma_M[m, k])) * q_Z[m, k, j]
    m_A1 = m_A

    t1 = time.time()

    ##########################################################################
    # VBJDE num. iter. minimum

    ni = 0

    while ((ni < NitMin + 1) or ((Crit_AH > Thresh) and (ni < NitMax))):

        logger.info("------------------------------ Iteration n° " +
                    str(ni + 1) + " ------------------------------")

        #####################
        # EXPECTATION
        #####################

        # A
        logger.info("E A step ...")
        UtilsC.expectation_A(q_Z, mu_M, sigma_M, PL, sigma_epsilone, Gamma,
                             Sigma_H, Y, y_tilde, m_A, m_H, Sigma_A, XX.astype(np.int32), J, D, M, N, K)

        # crit. A
        DIFF = np.reshape(m_A - m_A1, (M * J))
        Crit_A = (
            np.linalg.norm(DIFF) / np.linalg.norm(np.reshape(m_A1, (M * J)))) ** 2
        cA += [Crit_A]
        m_A1[:, :] = m_A[:, :]

        # HRF h
        UtilsC.expectation_H(XGamma, Q_barnCond, sigma_epsilone, Gamma, R, Sigma_H, Y,
                             y_tilde, m_A, m_H, Sigma_A, XX.astype(np.int32), J, D, M, N, scale, sigmaH)
        #m_H[0] = 0
        #m_H[-1] = 0
        # Constrain with optimization strategy
        import cvxpy as cvx
        m, n = Sigma_H.shape
        Sigma_H_inv = np.linalg.inv(Sigma_H)
        zeros_H = np.zeros_like(m_H[:, np.newaxis])
        # Construct the problem. PRIMAL
        h = cvx.Variable(n)
        expression = cvx.quad_form(h - m_H[:, np.newaxis], Sigma_H_inv)
        objective = cvx.Minimize(expression)
        #constraints = [h[0] == 0, h[-1]==0, h >= zeros_H, cvx.square(cvx.norm(h,2))<=1]
        constraints = [h[0] == 0, h[-1] == 0, cvx.square(cvx.norm(h, 2)) <= 1]
        prob = cvx.Problem(objective, constraints)
        result = prob.solve(verbose=0, solver=cvx.CVXOPT)
        # Now we update the mean of h
        m_H_old = m_H
        Sigma_H_old = Sigma_H
        m_H = np.squeeze(np.array((h.value)))
        Sigma_H = np.zeros_like(Sigma_H)
        # and the norm
        h_norm += [np.linalg.norm(m_H)]

        # crit. h
        Crit_H = (np.linalg.norm(m_H - m_H1) / np.linalg.norm(m_H1)) ** 2
        cH += [Crit_H]
        m_H1[:] = m_H[:]

        # crit. AH
        for d in xrange(0, D):
            AH[:, :, d] = m_A[:, :] * m_H[d]
        DIFF = np.reshape(AH - AH1, (M * J * D))
        Crit_AH = (np.linalg.norm(
            DIFF) / (np.linalg.norm(np.reshape(AH1, (M * J * D))) + eps)) ** 2
        cAH += [Crit_AH]
        AH1[:, :, :] = AH[:, :, :]

        # Z labels
        logger.info("E Z step ...")
        UtilsC.expectation_Z(Sigma_A, m_A, sigma_M, Beta, Z_tilde, mu_M,
                             q_Z, neighboursIndexes.astype(np.int32), M, J, K, maxNeighbours)

        # crit. Z
        DIFF = np.reshape(q_Z - q_Z1, (M * K * J))
        Crit_Z = (np.linalg.norm(DIFF) /
                  (np.linalg.norm(np.reshape(q_Z1, (M * K * J))) + eps)) ** 2
        cZ += [Crit_Z]
        q_Z1[:, :, :] = q_Z[:, :, :]

        #####################
        # MAXIMIZATION
        #####################

        # HRF: Sigma_h
        if estimateSigmaH:
            logger.info("M sigma_H step ...")
            if gamma_h > 0:
                sigmaH = vt.maximization_sigmaH_prior(
                    D, Sigma_H, R, m_H, gamma_h)
            else:
                sigmaH = vt.maximization_sigmaH(D, Sigma_H, R, m_H)
            logger.info('sigmaH = %s', str(sigmaH))

        # (mu,sigma)
        logger.info("M (mu,sigma) step ...")
        mu_M, sigma_M = vt.maximization_mu_sigma(
            mu_M, sigma_M, q_Z, m_A, K, M, Sigma_A)

        # Drift L
        UtilsC.maximization_L(
            Y, m_A, m_H, L, P, XX.astype(np.int32), J, D, M, Ndrift, N)
        PL = np.dot(P, L)
        y_tilde = Y - PL

        # Beta
        if estimateBeta:
            logger.info("estimating beta")
            for m in xrange(0, M):
                Beta[m] = UtilsC.maximization_beta(beta, q_Z[m, :, :].astype(np.float64), Z_tilde[m, :, :].astype(
                    np.float64), J, K, neighboursIndexes.astype(np.int32), gamma, maxNeighbours, MaxItGrad, gradientStep)
            logger.info("End estimating beta")
            logger.info(Beta)

        # Sigma noise
        logger.info("M sigma noise step ...")
        UtilsC.maximization_sigma_noise(
            Gamma, PL, sigma_epsilone, Sigma_H, Y, m_A, m_H, Sigma_A, XX.astype(np.int32), J, D, M, N)

        t02 = time.time()
        cTime += [t02 - t1]

    t2 = time.time()

    ##########################################################################
    # PLOTS and SNR computation

    if PLOT and 0:
        font = {'size': 15}
        matplotlib.rc('font', **font)
        savefig('./HRF_Iter_CompMod.png')
        hold(False)
        figure(2)
        plot(cAH[1:-1], 'lightblue')
        hold(True)
        plot(cFE[1:-1], 'm')
        hold(False)
        legend(('CAH', 'CFE'))
        grid(True)
        savefig('./Crit_CompMod.png')
        figure(3)
        plot(FreeEnergyArray)
        grid(True)
        savefig('./FreeEnergy_CompMod.png')

        figure(4)
        for m in xrange(M):
            plot(SUM_q_Z_array[m])
            hold(True)
        hold(False)
        savefig('./Sum_q_Z_Iter_CompMod.png')

        figure(5)
        for m in xrange(M):
            plot(mu1_array[m])
            hold(True)
        hold(False)
        savefig('./mu1_Iter_CompMod.png')

        figure(6)
        plot(h_norm_array)
        savefig('./HRF_Norm_CompMod.png')

        Data_save = xndarray(h_norm_array, ['Iteration'])
        Data_save.save('./HRF_Norm_Comp.nii')

    CompTime = t2 - t1
    cTimeMean = CompTime / ni

    """
    Norm = np.linalg.norm(m_H)
    m_H /= Norm
    Sigma_H /= Norm**2
    sigmaH /= Norm**2
    m_A *= Norm
    Sigma_A *= Norm**2
    mu_M *= Norm
    sigma_M *= Norm**2
    sigma_M = np.sqrt(np.sqrt(sigma_M))
    """
    logger.info("Nb iterations to reach criterion: %d", ni)
    logger.info("Computational time = %s min %s s", str(
        np.int(CompTime // 60)), str(np.int(CompTime % 60)))
    logger.info('mu_M: %f', mu_M)
    logger.info('sigma_M: %f', sigma_M)
    logger.info("sigma_H = %s", str(sigmaH))
    logger.info("Beta = %s", str(Beta))

    StimulusInducedSignal = vt.computeFit(m_H, m_A, X, J, N)
    SNR = 20 * \
        np.log(
            np.linalg.norm(Y) / np.linalg.norm(Y - StimulusInducedSignal - PL))
    SNR /= np.log(10.)
    print 'SNR comp =', SNR
    return ni, m_A, m_H, q_Z, sigma_epsilone, mu_M, sigma_M, Beta, L, PL, CONTRAST, CONTRASTVAR, cA[2:], cH[2:], cZ[2:], cAH[2:], cTime[2:], cTimeMean, Sigma_A, StimulusInducedSignal
コード例 #27
0
ファイル: vem_bold_constrained.py プロジェクト: ainafp/pyhrf
def Main_vbjde_Python_constrained(graph, Y, Onsets, Thrf, K, TR, beta, dt, scale=1, estimateSigmaH=True, sigmaH=0.1, NitMax=-1, NitMin=1, estimateBeta=False, PLOT=False):
    logger.info("EM started ...")
    np.random.seed(6537546)

    ##########################################################################
    # INITIALIZATIONS
    # Initialize parameters
    if NitMax < 0:
        NitMax = 100
    gamma = 7.5
    gradientStep = 0.005
    MaxItGrad = 120
    #Thresh = 1e-5
    Thresh_FreeEnergy = 1e-5

    # Initialize sizes vectors
    D = int(np.ceil(Thrf / dt))
    M = len(Onsets)
    N = Y.shape[0]
    J = Y.shape[1]
    l = int(np.sqrt(J))
    sigma_epsilone = np.ones(J)

    # Neighbours
    maxNeighbours = max([len(nl) for nl in graph])
    neighboursIndexes = np.zeros((J, maxNeighbours), dtype=np.int32)
    neighboursIndexes -= 1
    for i in xrange(J):
        neighboursIndexes[i, :len(graph[i])] = graph[i]
    # Conditions
    X = OrderedDict([])
    for condition, Ons in Onsets.iteritems():
        X[condition] = vt.compute_mat_X_2(N, TR, D, dt, Ons)
    XX = np.zeros((M, N, D), dtype=np.int32)
    nc = 0
    for condition, Ons in Onsets.iteritems():
        XX[nc, :, :] = X[condition]
        nc += 1
    # Sigma and mu
    mu_M = np.zeros((M, K), dtype=np.float64)
    sigma_M = 0.5 * np.ones((M, K), dtype=np.float64)
    sigma_M0 = 0.5 * np.ones((M, K), dtype=np.float64)
    for k in xrange(1, K):
        mu_M[:, k] = 2.0
    # Covariance matrix
    order = 2
    D2 = vt.buildFiniteDiffMatrix(order, D)
    R = np.dot(D2, D2) / pow(dt, 2 * order)

    Gamma = np.identity(N)

    q_Z = np.zeros((M, K, J), dtype=np.float64)
    # for k in xrange(0,K):
    q_Z[:, 1, :] = 1
    q_Z1 = np.zeros((M, K, J), dtype=np.float64)
    Z_tilde = q_Z.copy()

    Sigma_A = np.zeros((M, M, J), np.float64)
    m_A = np.zeros((J, M), dtype=np.float64)
    TT, m_h = getCanoHRF(Thrf - dt, dt)  # TODO: check
    for j in xrange(0, J):
        Sigma_A[:, :, j] = 0.01 * np.identity(M)
        for m in xrange(0, M):
            for k in xrange(0, K):
                m_A[j, m] += np.random.normal(mu_M[m, k],
                                              np.sqrt(sigma_M[m, k])) * Z_tilde[m, k, j]
    m_H = np.array(m_h).astype(np.float64)
    m_H1 = np.array(m_h)
    Sigma_H = np.ones((D, D), dtype=np.float64)
    Beta = beta * np.ones((M), dtype=np.float64)

    zerosDD = np.zeros((D, D), dtype=np.float64)
    zerosD = np.zeros((D), dtype=np.float64)
    zerosND = np.zeros((N, D), dtype=np.float64)
    zerosMM = np.zeros((M, M), dtype=np.float64)
    zerosJMD = np.zeros((J, M, D), dtype=np.float64)
    zerosK = np.zeros(K)

    P = vt.PolyMat(N, 4, TR)
    zerosP = np.zeros((P.shape[0]), dtype=np.float64)
    L = vt.polyFit(Y, TR, 4, P)
    PL = np.dot(P, L)
    y_tilde = Y - PL
    sigmaH1 = sigmaH

    Crit_H = 1
    Crit_Z = 1
    Crit_A = 1
    cA = []
    cH = []
    cZ = []
    Ndrift = L.shape[0]
    Crit_FreeEnergy = 1

    t1 = time.time()

    ##########################################################################
    # VBJDE num. iter. minimum

    ni = 0

    while ((ni < NitMin) or (((Crit_FreeEnergy > Thresh_FreeEnergy) or ((Crit_H > Thresh) and (Crit_Z > Thresh) and (Crit_A > Thresh))) and (ni < NitMax))):

        logger.info("------------------------------ Iteration n° " +
                    str(ni + 1) + " ------------------------------")

        #####################
        # EXPECTATION
        #####################

        # A
        logger.info("E A step ...")
        Sigma_A, m_A = vt.expectation_A(
            Y, Sigma_H, m_H, m_A, X, Gamma, PL, sigma_M, q_Z, mu_M, D, N, J, M, K, y_tilde, Sigma_A, sigma_epsilone, zerosJMD)
        m_A1 = m_A

        # crit A
        DIFF = np.abs(np.reshape(m_A, (M * J)) - np.reshape(m_A1, (M * J)))
        Crit_A = sum(DIFF) / len(np.where(DIFF != 0))
        cA += [Crit_A]

        # H
        logger.info("E H step ...")
        Sigma_H, m_H = vt.expectation_H(
            Y, Sigma_A, m_A, X, Gamma, PL, D, R, sigmaH, J, N, y_tilde, zerosND, sigma_epsilone, scale, zerosDD, zerosD)
        m_H[0] = 0
        m_H[-1] = 0
        m_H1 = m_H

        # crit H
        Crit_H = np.abs(np.mean(m_H - m_H1) / np.mean(m_H))
        cH += [Crit_H]

        # Z
        logger.info("E Z step ...")
        q_Z, Z_tilde = vt.expectation_Z(
            Sigma_A, m_A, sigma_M, Beta, Z_tilde, mu_M, q_Z, graph, M, J, K, zerosK)

        # crit Z
        DIFF = np.abs(
            np.reshape(q_Z, (M * K * J)) - np.reshape(q_Z1, (M * K * J)))
        Crit_Z = sum(DIFF) / len(np.where(DIFF != 0))
        cZ += [Crit_Z]
        q_Z1 = q_Z

        # Plotting HRF
        if PLOT and ni >= 0:
            import matplotlib.pyplot as plt
            plt.figure(M + 1)
            plt.plot(m_H)
            plt.hold(True)

        ####################
        # MAXIMIZATION
        #####################

        # HRF: Sigma_h
        if estimateSigmaH:
            logger.info("M sigma_H step ...")
            sigmaH = (np.dot(vt.mult(m_H, m_H) + Sigma_H, R)).trace()
            sigmaH /= D

        # (mu,sigma)
        logger.info("M (mu,sigma) step ...")
        mu_M, sigma_M = vt.maximization_mu_sigma(
            mu_M, sigma_M, q_Z, m_A, K, M, Sigma_A)

        # Drift L
        L = vt.maximization_L(Y, m_A, X, m_H, L, P, zerosP)
        PL = np.dot(P, L)
        y_tilde = Y - PL

        # Beta
        if estimateBeta:
            logger.info("estimating beta")
            for m in xrange(0, M):
                Beta[m] = vt.maximization_beta(
                    Beta[m], q_Z, Z_tilde, J, K, m, graph, gamma, neighboursIndexes, maxNeighbours)
            logger.info("End estimating beta")
            # logger.info(Beta)

        # Sigma noise
        logger.info("M sigma noise step ...")
        sigma_epsilone = vt.maximization_sigma_noise(
            Y, X, m_A, m_H, Sigma_H, Sigma_A, PL, sigma_epsilone, M, zerosMM)

        #### Computing Free Energy ####
        """
        if ni > 0:
            FreeEnergy1 = FreeEnergy
        FreeEnergy = Compute_FreeEnergy(y_tilde,m_A,Sigma_A,mu_M,sigma_M,m_H,Sigma_H,R,Det_invR,sigmaH,p_Wtilde,tau1,tau2,q_Z,neighboursIndexes,maxNeighbours,Beta,sigma_epsilone,XX,Gamma,Det_Gamma,XGamma,J,D,M,N,K,S,"CompMod")
        if ni > 0:
            Crit_FreeEnergy = (FreeEnergy1 - FreeEnergy) / FreeEnergy1
        FreeEnergy_Iter += [FreeEnergy]
        cFE += [Crit_FreeEnergy]
        """

        # Update index
        ni += 1

    t2 = time.time()

    ##########################################################################
    # PLOTS and SNR computation

    """FreeEnergyArray = np.zeros((ni),dtype=np.float64)
    for i in xrange(ni):
        FreeEnergyArray[i] = FreeEnergy_Iter[i]

    SUM_q_Z_array = np.zeros((M,ni),dtype=np.float64)
    mu1_array = np.zeros((M,ni),dtype=np.float64)
    h_norm_array = np.zeros((ni),dtype=np.float64)
    for m in xrange(M):
        for i in xrange(ni):
            SUM_q_Z_array[m,i] = SUM_q_Z[m][i]
            mu1_array[m,i] = mu1[m][i]
            h_norm_array[i] = h_norm[i]
    sigma_M = np.sqrt(np.sqrt(sigma_M))
    """

    Norm = np.linalg.norm(m_H)
    m_H /= Norm
    m_A *= Norm
    mu_M *= Norm
    sigma_M *= Norm
    sigma_M = np.sqrt(sigma_M)

    if PLOT and 0:
        import matplotlib.pyplot as plt
        import matplotlib
        font = {'size': 15}
        matplotlib.rc('font', **font)
        plt.savefig('./HRF_Iter_CompMod.png')
        plt.hold(False)
        plt.figure(2)
        plt.plot(cAH[1:-1], 'lightblue')
        plt.hold(True)
        plt.plot(cFE[1:-1], 'm')
        plt.hold(False)
        #plt.legend( ('CA','CH', 'CZ', 'CAH', 'CFE') )
        plt.legend(('CAH', 'CFE'))
        plt.grid(True)
        plt.savefig('./Crit_CompMod.png')
        plt.figure(3)
        plt.plot(FreeEnergyArray)
        plt.grid(True)
        plt.savefig('./FreeEnergy_CompMod.png')

        plt.figure(4)
        for m in xrange(M):
            plt.plot(SUM_q_Z_array[m])
            plt.hold(True)
        plt.hold(False)
        plt.savefig('./Sum_q_Z_Iter_CompMod.png')

        plt.figure(5)
        for m in xrange(M):
            plt.plot(mu1_array[m])
            plt.hold(True)
        plt.hold(False)
        plt.savefig('./mu1_Iter_CompMod.png')

        plt.figure(6)
        plt.plot(h_norm_array)
        plt.savefig('./HRF_Norm_CompMod.png')

        Data_save = xndarray(h_norm_array, ['Iteration'])
        Data_save.save('./HRF_Norm_Comp.nii')

    CompTime = t2 - t1
    cTimeMean = CompTime / ni

    logger.info("Nb iterations to reach criterion: %d", ni)
    logger.info("Computational time = %s min %s s", str(
        int(CompTime // 60)), str(int(CompTime % 60)))
    # print "Computational time = " + str(int( CompTime//60 ) ) + " min " +
    # str(int(CompTime%60)) + " s"
    logger.info('mu_M: %f', mu_M)
    logger.info('sigma_M: %f', sigma_M)
    logger.info("sigma_H = %s" + str(sigmaH))
    logger.info("Beta = %s" + str(Beta))

    StimulusInducedSignal = vt.computeFit(m_H, m_A, X, J, N)
    SNR = 20 * \
        np.log(
            np.linalg.norm(Y) / np.linalg.norm(Y - StimulusInducedSignal - PL))
    SNR /= np.log(10.)
    print 'SNR comp =', SNR
    return m_A, m_H, q_Z, sigma_epsilone, mu_M, sigma_M, Beta, L, PL
コード例 #28
0
ファイル: vem_bold_constrained.py プロジェクト: ainafp/pyhrf
def Main_vbjde_Extension_constrained(graph, Y, Onsets, Thrf, K, TR, beta,
                                     dt, scale=1, estimateSigmaH=True,
                                     sigmaH=0.05, NitMax=-1,
                                     NitMin=1, estimateBeta=True,
                                     PLOT=False, contrasts=[],
                                     computeContrast=False,
                                     gamma_h=0, estimateHRF=True,
                                     TrueHrfFlag=False,
                                     HrfFilename='hrf.nii',
                                     estimateLabels=True,
                                     LabelsFilename='labels.nii',
                                     MFapprox=False, InitVar=0.5,
                                     InitMean=2.0, MiniVEMFlag=False,
                                     NbItMiniVem=5):
    # VBJDE Function for BOLD with contraints

    logger.info("Fast EM with C extension started ...")
    np.random.seed(6537546)

    ##########################################################################
    # INITIALIZATIONS
    # Initialize parameters
    tau1 = 0.0
    tau2 = 0.0
    S = 100
    Init_sigmaH = sigmaH
    Nb2Norm = 1
    NormFlag = False
    if NitMax < 0:
        NitMax = 100
    gamma = 7.5
    #gamma_h = 1000
    gradientStep = 0.003
    MaxItGrad = 200
    Thresh = 1e-5
    Thresh_FreeEnergy = 1e-5
    estimateLabels = True  # WARNING!! They should be estimated

    # Initialize sizes vectors
    D = int(np.ceil(Thrf / dt)) + 1  # D = int(np.ceil(Thrf/dt))
    M = len(Onsets)
    N = Y.shape[0]
    J = Y.shape[1]
    l = int(np.sqrt(J))
    condition_names = []

    # Neighbours
    maxNeighbours = max([len(nl) for nl in graph])
    neighboursIndexes = np.zeros((J, maxNeighbours), dtype=np.int32)
    neighboursIndexes -= 1
    for i in xrange(J):
        neighboursIndexes[i, :len(graph[i])] = graph[i]
    # Conditions
    X = OrderedDict([])
    for condition, Ons in Onsets.iteritems():
        X[condition] = vt.compute_mat_X_2(N, TR, D, dt, Ons)
        condition_names += [condition]
    XX = np.zeros((M, N, D), dtype=np.int32)
    nc = 0
    for condition, Ons in Onsets.iteritems():
        XX[nc, :, :] = X[condition]
        nc += 1
    # Covariance matrix
    order = 2
    D2 = vt.buildFiniteDiffMatrix(order, D)
    R = np.dot(D2, D2) / pow(dt, 2 * order)
    invR = np.linalg.inv(R)
    Det_invR = np.linalg.det(invR)

    Gamma = np.identity(N)
    Det_Gamma = np.linalg.det(Gamma)

    p_Wtilde = np.zeros((M, K), dtype=np.float64)
    p_Wtilde1 = np.zeros((M, K), dtype=np.float64)
    p_Wtilde[:, 1] = 1

    Crit_H = 1
    Crit_Z = 1
    Crit_A = 1
    Crit_AH = 1
    AH = np.zeros((J, M, D), dtype=np.float64)
    AH1 = np.zeros((J, M, D), dtype=np.float64)
    Crit_FreeEnergy = 1

    cA = []
    cH = []
    cZ = []
    cAH = []
    FreeEnergy_Iter = []
    cTime = []
    cFE = []

    SUM_q_Z = [[] for m in xrange(M)]
    mu1 = [[] for m in xrange(M)]
    h_norm = []
    h_norm2 = []

    CONTRAST = np.zeros((J, len(contrasts)), dtype=np.float64)
    CONTRASTVAR = np.zeros((J, len(contrasts)), dtype=np.float64)
    Q_barnCond = np.zeros((M, M, D, D), dtype=np.float64)
    XGamma = np.zeros((M, D, N), dtype=np.float64)
    m1 = 0
    for k1 in X:  # Loop over the M conditions
        m2 = 0
        for k2 in X:
            Q_barnCond[m1, m2, :, :] = np.dot(
                np.dot(X[k1].transpose(), Gamma), X[k2])
            m2 += 1
        XGamma[m1, :, :] = np.dot(X[k1].transpose(), Gamma)
        m1 += 1

    if MiniVEMFlag:
        logger.info("MiniVEM to choose the best initialisation...")
        """InitVar, InitMean, gamma_h = MiniVEM_CompMod(Thrf,TR,dt,beta,Y,K,
                                                     gamma,gradientStep,
                                                     MaxItGrad,D,M,N,J,S,
                                                     maxNeighbours,
                                                     neighboursIndexes,
                                                     XX,X,R,Det_invR,Gamma,
                                                     Det_Gamma,
                                                     scale,Q_barnCond,XGamma,
                                                     NbItMiniVem,
                                                     sigmaH,estimateHRF)"""

        InitVar, InitMean, gamma_h = vt.MiniVEM_CompMod(Thrf, TR, dt, beta, Y, K, gamma, gradientStep, MaxItGrad, D, M, N, J, S, maxNeighbours,
                                                        neighboursIndexes, XX, X, R, Det_invR, Gamma, Det_Gamma, p_Wtilde, scale, Q_barnCond, XGamma, tau1, tau2, NbItMiniVem, sigmaH, estimateHRF)

    sigmaH = Init_sigmaH
    sigma_epsilone = np.ones(J)
    logger.info(
        "Labels are initialized by setting active probabilities to ones ...")
    q_Z = np.zeros((M, K, J), dtype=np.float64)
    q_Z[:, 1, :] = 1
    q_Z1 = np.zeros((M, K, J), dtype=np.float64)
    Z_tilde = q_Z.copy()

    # TT,m_h = getCanoHRF(Thrf-dt,dt) #TODO: check
    TT, m_h = getCanoHRF(Thrf, dt)  # TODO: check
    m_h = m_h[:D]
    m_H = np.array(m_h).astype(np.float64)
    m_H1 = np.array(m_h)
    sigmaH1 = sigmaH
    if estimateHRF:
        Sigma_H = np.ones((D, D), dtype=np.float64)
    else:
        Sigma_H = np.zeros((D, D), dtype=np.float64)

    Beta = beta * np.ones((M), dtype=np.float64)
    P = vt.PolyMat(N, 4, TR)
    L = vt.polyFit(Y, TR, 4, P)
    PL = np.dot(P, L)
    y_tilde = Y - PL
    Ndrift = L.shape[0]

    sigma_M = np.ones((M, K), dtype=np.float64)
    sigma_M[:, 0] = 0.5
    sigma_M[:, 1] = 0.6
    mu_M = np.zeros((M, K), dtype=np.float64)
    for k in xrange(1, K):
        mu_M[:, k] = InitMean
    Sigma_A = np.zeros((M, M, J), np.float64)
    for j in xrange(0, J):
        Sigma_A[:, :, j] = 0.01 * np.identity(M)
    m_A = np.zeros((J, M), dtype=np.float64)
    m_A1 = np.zeros((J, M), dtype=np.float64)
    for j in xrange(0, J):
        for m in xrange(0, M):
            for k in xrange(0, K):
                m_A[j, m] += np.random.normal(mu_M[m, k],
                                              np.sqrt(sigma_M[m, k])) * q_Z[m, k, j]
    m_A1 = m_A

    t1 = time.time()

    ##########################################################################
    # VBJDE num. iter. minimum

    ni = 0

    while ((ni < NitMin) or (((Crit_FreeEnergy > Thresh_FreeEnergy) or (Crit_AH > Thresh)) and (ni < NitMax))):

        logger.info("------------------------------ Iteration n° " +
                    str(ni + 1) + " ------------------------------")

        #####################
        # EXPECTATION
        #####################

        # A
        logger.info("E A step ...")
        UtilsC.expectation_A(q_Z, mu_M, sigma_M, PL, sigma_epsilone, Gamma,
                             Sigma_H, Y, y_tilde, m_A, m_H, Sigma_A, XX.astype(np.int32), J, D, M, N, K)
        val = np.reshape(m_A, (M * J))
        val[np.where((val <= 1e-50) & (val > 0.0))] = 0.0
        val[np.where((val >= -1e-50) & (val < 0.0))] = 0.0

        # crit. A
        DIFF = np.reshape(m_A - m_A1, (M * J))
        # To avoid numerical problems
        DIFF[np.where((DIFF < 1e-50) & (DIFF > 0.0))] = 0.0
        # To avoid numerical problems
        DIFF[np.where((DIFF > -1e-50) & (DIFF < 0.0))] = 0.0
        Crit_A = (
            np.linalg.norm(DIFF) / np.linalg.norm(np.reshape(m_A1, (M * J)))) ** 2
        cA += [Crit_A]
        m_A1[:, :] = m_A[:, :]

        # HRF h
        if estimateHRF:
            ################################
            #  HRF ESTIMATION
            ################################
            UtilsC.expectation_H(XGamma, Q_barnCond, sigma_epsilone, Gamma, R, Sigma_H, Y,
                                 y_tilde, m_A, m_H, Sigma_A, XX.astype(np.int32), J, D, M, N, scale, sigmaH)

            import cvxpy as cvx
            m, n = Sigma_H.shape
            Sigma_H_inv = np.linalg.inv(Sigma_H)
            zeros_H = np.zeros_like(m_H[:, np.newaxis])

            # Construct the problem. PRIMAL
            h = cvx.Variable(n)
            expression = cvx.quad_form(h - m_H[:, np.newaxis], Sigma_H_inv)
            objective = cvx.Minimize(expression)
            #constraints = [h[0] == 0, h[-1]==0, h >= zeros_H, cvx.square(cvx.norm(h,2))<=1]
            constraints = [
                h[0] == 0, h[-1] == 0, cvx.square(cvx.norm(h, 2)) <= 1]
            prob = cvx.Problem(objective, constraints)
            result = prob.solve(verbose=0, solver=cvx.CVXOPT)

            # Now we update the mean of h
            m_H_old = m_H
            Sigma_H_old = Sigma_H
            m_H = np.squeeze(np.array((h.value)))
            Sigma_H = np.zeros_like(Sigma_H)

            h_norm += [np.linalg.norm(m_H)]
            # print 'h_norm = ', h_norm

            # Plotting HRF
            if PLOT and ni >= 0:
                import matplotlib.pyplot as plt
                plt.figure(M + 1)
                plt.plot(m_H)
                plt.hold(True)
        else:
            if TrueHrfFlag:
                #TrueVal, head = read_volume(HrfFilename)
                TrueVal, head = read_volume(HrfFilename)[:, 0, 0, 0]
                print TrueVal
                print TrueVal.shape
                m_H = TrueVal

        # crit. h
        Crit_H = (np.linalg.norm(m_H - m_H1) / np.linalg.norm(m_H1)) ** 2
        cH += [Crit_H]
        m_H1[:] = m_H[:]

        # crit. AH
        for d in xrange(0, D):
            AH[:, :, d] = m_A[:, :] * m_H[d]
        DIFF = np.reshape(AH - AH1, (M * J * D))
        # To avoid numerical problems
        DIFF[np.where((DIFF < 1e-50) & (DIFF > 0.0))] = 0.0
        # To avoid numerical problems
        DIFF[np.where((DIFF > -1e-50) & (DIFF < 0.0))] = 0.0
        if np.linalg.norm(np.reshape(AH1, (M * J * D))) == 0:
            Crit_AH = 1000000000.
        else:
            Crit_AH = (
                np.linalg.norm(DIFF) / np.linalg.norm(np.reshape(AH1, (M * J * D)))) ** 2
        cAH += [Crit_AH]
        AH1[:, :, :] = AH[:, :, :]

        # Z labels
        if estimateLabels:
            logger.info("E Z step ...")
            # WARNING!!! ParsiMod gives better results, but we need the other
            # one.
            if MFapprox:
                UtilsC.expectation_Z(Sigma_A, m_A, sigma_M, Beta, Z_tilde, mu_M, q_Z, neighboursIndexes.astype(
                    np.int32), M, J, K, maxNeighbours)
            if not MFapprox:
                UtilsC.expectation_Z_ParsiMod_RVM_and_CompMod(
                    Sigma_A, m_A, sigma_M, Beta, mu_M, q_Z, neighboursIndexes.astype(np.int32), M, J, K, maxNeighbours)
        else:
            logger.info("Using True Z ...")
            TrueZ = read_volume(LabelsFilename)
            for m in xrange(M):
                q_Z[m, 1, :] = np.reshape(TrueZ[0][:, :, :, m], J)
                q_Z[m, 0, :] = 1 - q_Z[m, 1, :]

        # crit. Z
        val = np.reshape(q_Z, (M * K * J))
        val[np.where((val <= 1e-50) & (val > 0.0))] = 0.0

        DIFF = np.reshape(q_Z - q_Z1, (M * K * J))
        # To avoid numerical problems
        DIFF[np.where((DIFF < 1e-50) & (DIFF > 0.0))] = 0.0
        # To avoid numerical problems
        DIFF[np.where((DIFF > -1e-50) & (DIFF < 0.0))] = 0.0
        if np.linalg.norm(np.reshape(q_Z1, (M * K * J))) == 0:
            Crit_Z = 1000000000.
        else:
            Crit_Z = (
                np.linalg.norm(DIFF) / np.linalg.norm(np.reshape(q_Z1, (M * K * J)))) ** 2
        cZ += [Crit_Z]
        q_Z1 = q_Z

        #####################
        # MAXIMIZATION
        #####################

        # HRF: Sigma_h
        if estimateHRF:
            if estimateSigmaH:
                logger.info("M sigma_H step ...")
                if gamma_h > 0:
                    sigmaH = vt.maximization_sigmaH_prior(
                        D, Sigma_H_old, R, m_H_old, gamma_h)
                else:
                    sigmaH = vt.maximization_sigmaH(D, Sigma_H, R, m_H)
                logger.info('sigmaH = %s', str(sigmaH))

        # (mu,sigma)
        logger.info("M (mu,sigma) step ...")
        mu_M, sigma_M = vt.maximization_mu_sigma(
            mu_M, sigma_M, q_Z, m_A, K, M, Sigma_A)
        for m in xrange(M):
            SUM_q_Z[m] += [sum(q_Z[m, 1, :])]
            mu1[m] += [mu_M[m, 1]]

        # Drift L
        UtilsC.maximization_L(
            Y, m_A, m_H, L, P, XX.astype(np.int32), J, D, M, Ndrift, N)
        PL = np.dot(P, L)
        y_tilde = Y - PL

        # Beta
        if estimateBeta:
            logger.info("estimating beta")
            for m in xrange(0, M):
                if MFapprox:
                    Beta[m] = UtilsC.maximization_beta(beta, q_Z[m, :, :].astype(np.float64), Z_tilde[m, :, :].astype(
                        np.float64), J, K, neighboursIndexes.astype(np.int32), gamma, maxNeighbours, MaxItGrad, gradientStep)
                if not MFapprox:
                    #Beta[m] = UtilsC.maximization_beta(beta,q_Z[m,:,:].astype(np.float64),q_Z[m,:,:].astype(np.float64),J,K,neighboursIndexes.astype(int32),gamma,maxNeighbours,MaxItGrad,gradientStep)
                    Beta[m] = UtilsC.maximization_beta_CB(beta, q_Z[m, :, :].astype(
                        np.float64), J, K, neighboursIndexes.astype(np.int32), gamma, maxNeighbours, MaxItGrad, gradientStep)
            logger.info("End estimating beta")
            logger.info(Beta)

        # Sigma noise
        logger.info("M sigma noise step ...")
        UtilsC.maximization_sigma_noise(
            Gamma, PL, sigma_epsilone, Sigma_H, Y, m_A, m_H, Sigma_A, XX.astype(np.int32), J, D, M, N)

        #### Computing Free Energy ####
        if ni > 0:
            FreeEnergy1 = FreeEnergy

        """FreeEnergy = vt.Compute_FreeEnergy(y_tilde,m_A,Sigma_A,mu_M,sigma_M,
                                           m_H,Sigma_H,R,Det_invR,sigmaH,
                                           p_Wtilde,q_Z,neighboursIndexes,
                                           maxNeighbours,Beta,sigma_epsilone,
                                           XX,Gamma,Det_Gamma,XGamma,J,D,M,
                                           N,K,S,"CompMod")"""
        FreeEnergy = vt.Compute_FreeEnergy(y_tilde, m_A, Sigma_A, mu_M, sigma_M, m_H, Sigma_H, R, Det_invR, sigmaH, p_Wtilde, tau1,
                                           tau2, q_Z, neighboursIndexes, maxNeighbours, Beta, sigma_epsilone, XX, Gamma, Det_Gamma, XGamma, J, D, M, N, K, S, "CompMod")

        if ni > 0:
            Crit_FreeEnergy = (FreeEnergy1 - FreeEnergy) / FreeEnergy1
        FreeEnergy_Iter += [FreeEnergy]
        cFE += [Crit_FreeEnergy]

        # Update index
        ni += 1

        t02 = time.time()
        cTime += [t02 - t1]

    t2 = time.time()

    ##########################################################################
    # PLOTS and SNR computation

    FreeEnergyArray = np.zeros((ni), dtype=np.float64)
    for i in xrange(ni):
        FreeEnergyArray[i] = FreeEnergy_Iter[i]

    SUM_q_Z_array = np.zeros((M, ni), dtype=np.float64)
    mu1_array = np.zeros((M, ni), dtype=np.float64)
    h_norm_array = np.zeros((ni), dtype=np.float64)
    for m in xrange(M):
        for i in xrange(ni):
            SUM_q_Z_array[m, i] = SUM_q_Z[m][i]
            mu1_array[m, i] = mu1[m][i]
            h_norm_array[i] = h_norm[i]

    if PLOT and 0:
        import matplotlib.pyplot as plt
        import matplotlib
        font = {'size': 15}
        matplotlib.rc('font', **font)
        plt.savefig('./HRF_Iter_CompMod.png')
        plt.hold(False)
        plt.figure(2)
        plt.plot(cAH[1:-1], 'lightblue')
        plt.hold(True)
        plt.plot(cFE[1:-1], 'm')
        plt.hold(False)
        #plt.legend( ('CA','CH', 'CZ', 'CAH', 'CFE') )
        plt.legend(('CAH', 'CFE'))
        plt.grid(True)
        plt.savefig('./Crit_CompMod.png')
        plt.figure(3)
        plt.plot(FreeEnergyArray)
        plt.grid(True)
        plt.savefig('./FreeEnergy_CompMod.png')

        plt.figure(4)
        for m in xrange(M):
            plt.plot(SUM_q_Z_array[m])
            plt.hold(True)
        plt.hold(False)
        #plt.legend( ('m=0','m=1', 'm=2', 'm=3') )
        #plt.legend( ('m=0','m=1') )
        plt.savefig('./Sum_q_Z_Iter_CompMod.png')

        plt.figure(5)
        for m in xrange(M):
            plt.plot(mu1_array[m])
            plt.hold(True)
        plt.hold(False)
        plt.savefig('./mu1_Iter_CompMod.png')

        plt.figure(6)
        plt.plot(h_norm_array)
        plt.savefig('./HRF_Norm_CompMod.png')

        Data_save = xndarray(h_norm_array, ['Iteration'])
        Data_save.save('./HRF_Norm_Comp.nii')

    CompTime = t2 - t1
    cTimeMean = CompTime / ni

    sigma_M = np.sqrt(np.sqrt(sigma_M))
    logger.info("Nb iterations to reach criterion: %d", ni)
    logger.info("Computational time = %s min %s s", str(
        int(CompTime // 60)), str(int(CompTime % 60)))
    # print "Computational time = " + str(int( CompTime//60 ) ) + " min " + str(int(CompTime%60)) + " s"
    # print "sigma_H = " + str(sigmaH)
    logger.info('mu_M: %f', mu_M)
    logger.info('sigma_M: %f', sigma_M)
    logger.info("sigma_H = %s" + str(sigmaH))
    logger.info("Beta = %s" + str(Beta))

    StimulusInducedSignal = vt.computeFit(m_H, m_A, X, J, N)
    SNR = 20 * \
        np.log(
            np.linalg.norm(Y) / np.linalg.norm(Y - StimulusInducedSignal - PL))
    SNR /= np.log(10.)
    logger.info("SNR = %d", SNR)
    return ni, m_A, m_H, q_Z, sigma_epsilone, mu_M, sigma_M, Beta, L, PL, CONTRAST, CONTRASTVAR, cA[2:], cH[2:], cZ[2:], cAH[2:], cTime[2:], cTimeMean, Sigma_A, StimulusInducedSignal, FreeEnergyArray