def _psi2computations(dL_dpsi2, variance, Z, mu, S):
<EOL>variance2 = np.square(variance)<EOL>common_sum = np.dot(mu,(variance*Z).T)<EOL>if len(dL_dpsi2.shape)==<NUM_LIT:2>:<EOL><INDENT>Z_expect = (np.dot(dL_dpsi2,Z)*Z).sum(axis=<NUM_LIT:0>)<EOL>dL_dpsi2T = dL_dpsi2+dL_dpsi2.T<EOL>common_expect = np.dot(common_sum,np.dot(dL_dpsi2T,Z))<EOL>Z2_expect = np.inner(common_sum,dL_dpsi2T)<EOL>Z1_expect = np.dot(dL_dpsi2T,Z)<EOL>dL_dvar = <NUM_LIT>*S.sum(axis=<NUM_LIT:0>)*variance*Z_expect+(common_expect*mu).sum(axis=<NUM_LIT:0>)<EOL>dL_dmu = common_expect*variance<EOL>dL_dS = np.empty(S.shape)<EOL>dL_dS[:] = Z_expect*variance2<EOL>dL_dZ = variance2*S.sum(axis=<NUM_LIT:0>)*Z1_expect+np.dot(Z2_expect.T,variance*mu)<EOL><DEDENT>else:<EOL><INDENT>N,M,Q = mu.shape[<NUM_LIT:0>],Z.shape[<NUM_LIT:0>],mu.shape[<NUM_LIT:1>]<EOL>dL_dpsi2_ = dL_dpsi2.sum(axis=<NUM_LIT:0>)<EOL>Z_expect = (np.dot(dL_dpsi2.reshape(N*M,M),Z).reshape(N,M,Q)*Z[None,:,:]).sum(axis=<NUM_LIT:1>)<EOL>dL_dpsi2T = dL_dpsi2_+dL_dpsi2_.T<EOL>dL_dpsi2T_ = dL_dpsi2+np.swapaxes(dL_dpsi2, <NUM_LIT:1>, <NUM_LIT:2>)<EOL>common_expect = np.dot(common_sum,np.dot(dL_dpsi2T,Z))<EOL>common_expect_ = (common_sum[:,:,None]*np.dot(dL_dpsi2T_.reshape(N*M,M),Z).reshape(N,M,Q)).sum(axis=<NUM_LIT:1>)<EOL>Z2_expect = (common_sum[:,:,None]*dL_dpsi2T_).sum(axis=<NUM_LIT:1>)<EOL>Z1_expect = np.dot(dL_dpsi2T_.reshape(N*M,M),Z).reshape(N,M,Q)<EOL>dL_dvar = <NUM_LIT>*variance*(S*Z_expect).sum(axis=<NUM_LIT:0>)+(common_expect_*mu).sum(axis=<NUM_LIT:0>)<EOL>dL_dmu = common_expect_*variance<EOL>dL_dS = np.empty(S.shape)<EOL>dL_dS[:] = variance2* Z_expect<EOL>dL_dZ = variance2*(S[:,None,:]*Z1_expect).sum(axis=<NUM_LIT:0>)+np.dot(Z2_expect.T,variance*mu)<EOL><DEDENT>return dL_dvar, dL_dmu, dL_dS, dL_dZ<EOL>
Z - MxQ
mu - NxQ
S - NxQ
gamma - NxQ