def odo(U: np.array) -> Tuple[np.array, np.array, np.array, np.array]: # odo=orthogonal diagonal orthogonal # Given a unitary matrix U, it finds special (det=1) orthogonal matrices L and R and a diagonal unitary matrix D # such that L * D * R' = U dim_U = np.shape(U)[0] if np.linalg.norm(U @ U.conjugate().transpose() - np.eye(dim_U)) > abs_error: raise ValueError("input matrix for odo decomposition is not unitary") X = (U + U.conjugate()) / 2 Y = (U - U.conjugate()) / 2j # print("\nX\n", X, "\nY\n", Y) [L, DX, DY, R] = simul_real_svd(X, Y) return L, DX, DY, R
def calc_intensity_up_down( sthovl: numpy.ndarray, wavelength: float, field_norm: float, u_matrix: numpy.ndarray, polarization: float, flipper_efficiency: float, f_nucl: numpy.array, fm_perp_loc: tuple, volume_unit_cell: float, model_extinction: str, radius: float, mosaicity: float): """Calculate integrated intensity up and down.""" dder = {} p_u = polarization p_d = (2.*flipper_efficiency-1.)*polarization phi_d, chi_d, omega_d = 0., 0., 0. e_up_loc = calc_e_up_loc(phi_d, chi_d, omega_d, u_matrix) mag_p_1, mag_p_2, mag_p_3 = fm_perp_loc mag_p_sq = abs(mag_p_1*mag_p_1.conjugate() + mag_p_2*mag_p_2.conjugate() + mag_p_3*mag_p_3.conjugate()) mag_p_e_u = mag_p_1*e_up_loc[0]+mag_p_2*e_up_loc[1]+mag_p_3*e_up_loc[2] f_nucl_sq = abs(f_nucl)**2 mag_p_e_u_sq = abs(mag_p_e_u*mag_p_e_u.conjugate()) fnp = (mag_p_e_u*f_nucl.conjugate()+mag_p_e_u.conjugate()*f_nucl).real fp_sq = f_nucl_sq + mag_p_sq + fnp fm_sq = f_nucl_sq + mag_p_sq - fnp fpm_sq = mag_p_sq - mag_p_e_u_sq l_model_extinction = ["gauss", "lorentz"] if model_extinction.lower() in l_model_extinction: yp, dder_yp = calc_extinction_2( radius, mosaicity, model_extinction, fp_sq, volume_unit_cell, sthovl, wavelength) ym, dder_ym = calc_extinction_2( radius, mosaicity, model_extinction, fm_sq, volume_unit_cell, sthovl, wavelength) ypm, dder_ypm = calc_extinction_2( radius, mosaicity, model_extinction, fpm_sq, volume_unit_cell, sthovl, wavelength) else: yp = 1. + 0.*f_nucl_sq ym = yp ypm = yp pppl = 0.5*((1+p_u)*yp+(1-p_u)*ym) ppmin = 0.5*((1-p_d)*yp+(1+p_d)*ym) pmpl = 0.5*((1+p_u)*yp-(1-p_u)*ym) pmmin = 0.5*((1-p_d)*yp-(1+p_d)*ym) # integral intensities and flipping ratios iint_u = (f_nucl_sq+mag_p_e_u_sq)*pppl + pmpl*fnp + ypm*fpm_sq iint_d = (f_nucl_sq+mag_p_e_u_sq)*ppmin + pmmin*fnp + ypm*fpm_sq return iint_u, iint_d, dder
def kak1( U: np.array ) -> Tuple[np.array, np.array, np.array, np.array, np.array]: # Calculates a special case (KAK1) # of Cartan's KAK Decomposition. # For an input 4d unitary matrix U, # it finds [A1, A0, class_vec, B1, B0] # such that U = kron(A1,A0)*exp(i*M)*kron(B1,B0) # where matrix M is a function of # class_vec(1:4) # If # k=class_vec # and # M=k(4)+sigxx*k(1)+sigyy*k(2)+sigzz*k(3) # then # kron(A1,A0)*exp(i*M)*kron(B1,B0) = U if np.shape(U)[0] != 4 or np.shape(U)[1] != 4: raise ValueError("input matrix for kak decomposition is not 4x4") if np.linalg.norm(U @ U.conjugate().transpose() - np.eye(4)) > 1e-8: raise ValueError("input matrix for kak decomposition is not unitary") # normalize U so that it has # unit determinant. Store # det(U)^(1/4) for later use root4th = pow(np.linalg.det(U), (1 / 4)) if abs(root4th - 1) > 1e-8: U = U / root4th U_bell = magic.conjugate().transpose() @ U @ magic [L, D, R] = odo(U_bell) # print("L\n", L, "\nD\n", D, "\nR\n", R) class_vec = diag_to_class_vec(np.diagonal(D)) class_vec[3] = class_vec[3] + np.angle(root4th) [A1, A0] = SO4_to_SU2xSU2(L) [B1, B0] = SO4_to_SU2xSU2(R.conjugate().transpose()) return A1, A0, class_vec, B1, B0
def is_hermitian(matrix: np.array) -> bool: """ Checks if a matrix is Hermitian. >>> import numpy as np >>> A = np.array([ ... [2, 2+1j, 4], ... [2-1j, 3, 1j], ... [4, -1j, 1]]) >>> is_hermitian(A) True >>> A = np.array([ ... [2, 2+1j, 4+1j], ... [2-1j, 3, 1j], ... [4, -1j, 1]]) >>> is_hermitian(A) False """ return np.array_equal(matrix, matrix.conjugate().T)
def rayleigh_quotient(A: np.array, v: np.array) -> float: """ Returns the Rayleigh quotient of a Hermitian matrix A and vector v. >>> import numpy as np >>> A = np.array([ ... [1, 2, 4], ... [2, 3, -1], ... [4, -1, 1] ... ]) >>> v = np.array([ ... [1], ... [2], ... [3] ... ]) >>> rayleigh_quotient(A, v) array([[3.]]) """ v_star = v.conjugate().T return (v_star.dot(A).dot(v)) / (v_star.dot(v))