def frobenius_inner_product(A, B, normalize=False): r"""Frobenius inner product between two matrices. .. math:: \langle A, B \rangle_F = \sum_{i,j=1}^n A_{ij} B_{ij} = \operatorname{tr} (A^T B) The Frobenius inner product is equivalent to the Hilbert-Schmidt inner product for matrices with real-valued entries. Args: A (tensor_like[float]): First matrix, assumed to be a square array. B (tensor_like[float]): Second matrix, assumed to be a square array. normalize (bool): If True, divide the inner product by the Frobenius norms of A and B. Returns: float: Frobenius inner product of A and B **Example** >>> A = np.random.random((3,3)) >>> B = np.random.random((3,3)) >>> qml.math.frobenius_inner_product(A, B) 3.091948202943376 """ interface = _multi_dispatch([A, B]) A, B = np.coerce([A, B], like=interface) inner_product = np.sum(A * B) if normalize: norm = np.sqrt(np.sum(A * A) * np.sum(B * B)) inner_product = inner_product / norm return inner_product
def marginal_prob(prob, axis): """Compute the marginal probability given a joint probability distribution expressed as a tensor. Each random variable corresponds to a dimension. If the distribution arises from a quantum circuit measured in computational basis, each dimension corresponds to a wire. For example, for a 2-qubit quantum circuit `prob[0, 1]` is the probability of measuring the first qubit in state 0 and the second in state 1. Args: prob (tensor_like): 1D tensor of probabilities. This tensor should of size ``(2**N,)`` for some integer value ``N``. axis (list[int]): the axis for which to calculate the marginal probability distribution Returns: tensor_like: the marginal probabilities, of size ``(2**len(axis),)`` **Example** >>> x = tf.Variable([1, 0, 0, 1.], dtype=tf.float64) / np.sqrt(2) >>> marginal_prob(x, axis=[0, 1]) <tf.Tensor: shape=(4,), dtype=float64, numpy=array([0.70710678, 0. , 0. , 0.70710678])> >>> marginal_prob(x, axis=[0]) <tf.Tensor: shape=(2,), dtype=float64, numpy=array([0.70710678, 0.70710678])> """ prob = np.flatten(prob) num_wires = int(np.log2(len(prob))) if num_wires == len(axis): return prob inactive_wires = tuple(set(range(num_wires)) - set(axis)) prob = np.reshape(prob, [2] * num_wires) prob = np.sum(prob, axis=inactive_wires) return np.flatten(prob)
def order_matrix(original, sortd, sigma=0.1): """Apply a simple RBF kernel to the difference between original and sortd, with the kernel width set by sigma. Normalise each row to sum to 1.0.""" diff = ((original).reshape(-1, 1) - sortd.reshape(1, -1))**2 rbf = np.exp(-(diff) / (2 * sigma**2)) return (rbf.T / np.sum(rbf, axis=1)).T