def inner(self, X, G, H): GR, GI = frac(G) HR, HI = frac(H) # (AR + iAI)(BR + iBI) = ARBR - AIBI + i(ARBI + AIBR) # we return only real part of sum(hadamard(G, H)) # old # return T.real(T.sum((GR + 1j * GI) *(HR + 1j * HI))) return tensor.sum(GR * HR - GI * HI)
def retr(self, X, U, mode="default"): if mode == "exp": return self.exp(X, U) elif mode == "qr": YR, YI = frac(X + U) Q, R = tensor.nlinalg.qr(YR + 1j * YI) Y = tensor.stack([Q.real, Q.imag]) return Y elif mode == "svd": YR, YI = frac(X + U) U, S, V = tensor.nlinalg.svd(YR + 1j * YI, full_matrices=False) Y = U.dot(tensor.eye(S.size)).dot(V) Y = tensor.stack([Y.real, Y.imag]) return Y elif mode == "cayley": A = complex_dot(hconj(U), X) + complex_dot(hconj(X), U) return complex_dot( complex_matrix_inverse(identity(self._n) + 0.5 * A), (identity(self._n) - 0.5 * A)) elif mode == "default": return self.retr(X, U, mode=self.retr_mode) else: raise ValueError( 'mode must equal to "svd", "qr", "exp" or "default", but "{}" is given' .format(mode))
def get_output_for(self, input, **kwargs): UR, UI = frac(self.U) if input.ndim > 2: # if the input has more than two dimensions, flatten it into a # batch of feature vectors. input = input.flatten(2) unitary_input = T.reshape(input, (input.shape[0], 2, self.num_inputs)) IR, II = unitary_input[:, 0, :], unitary_input[:, 1, :] output = T.stack([IR.dot(UR) - II.dot(UI), IR.dot(UR) + II.dot(UR)], axis=1) output = output.reshape((input.shape[0], -1)) return output
def retr(self, X, U, mode="default"): if mode == "exp": return self.exp(X, U) elif mode == "qr": YR, YI = frac(X + U) Q, R = tensor.nlinalg.qr(YR + 1j * YI) Y = tensor.stack([Q.real, Q.imag]) return Y elif mode == "svd": YR, YI = frac(X + U) U, S, V = tensor.nlinalg.svd(YR + 1j * YI, full_matrices=False) Y = U.dot(tensor.eye(S.size)).dot(V) Y = tensor.stack([Y.real, Y.imag]) return Y elif mode == "default": return self.retr(X, U, mode=self.retr_mode) else: raise ValueError( 'mode must equal to "svd", "qr", "exp" or "default", but "{}" is given' .format(mode))
def retr(self, X, U, mode="default"): if mode == "exp": return self.exp(X, U) elif mode == "qr": YR, YI = frac(X + U) Q, R = tensor.nlinalg.qr(YR + 1j * YI) Y = tensor.stack([Q.real, Q.imag]) return Y elif mode == "svd": YR, YI = frac(X + U) U, S, V = tensor.nlinalg.svd(YR + 1j * YI, full_matrices=False) Y = U.dot(tensor.eye(S.size)).dot(V) Y = tensor.stack([Y.real, Y.imag]) return Y elif mode == "cayley": A = complex_dot(hconj(U), X) + complex_dot(hconj(X), U) return complex_dot(complex_matrix_inverse(identity(self._n) + 0.5 * A), (identity(self._n) - 0.5 * A)) elif mode == "default": return self.retr(X, U, mode=self.retr_mode) else: raise ValueError('mode must equal to "svd", "qr", "exp" or "default", but "{}" is given'.format(mode))
def norm(self, X, G): GR, GI = frac(G) return (GR + 1j * GI).norm()