示例#1
0
def test_cp_vonneumann_entropy_mixed_state():
    """Test for cp_vonneumann_entropy on CP tensors. 
    This test checks that the VNE of mixed states is calculated correctly.
    """
    state1 = tl.tensor([[
        0.03004805, 0.42426117, 0.5483771, 0.4784077, 0.25792725, 0.34388784,
        0.99927586, 0.96605812
    ]])
    state1 = state1 / tl.norm(state1)
    state2 = tl.tensor([[
        0.84250089, 0.43429687, 0.26551928, 0.18262211, 0.55584835, 0.2565509,
        0.33197401, 0.97741178
    ]])
    state2 = state2 / tl.norm(state2)
    mat_mixed = tl.tensor((tl.dot(tl.transpose(state1), state1) +
                           tl.dot(tl.transpose(state2), state2)) / 2.)
    actual_vne = 0.5546
    mat = parafac(tl.tensor(mat_mixed), rank=2, normalize_factors=True)
    mat_unnorm = parafac(tl.tensor(mat_mixed), rank=2, normalize_factors=False)
    tl_vne = cp_vonneumann_entropy(mat)
    tl_vne_unnorm = cp_vonneumann_entropy(mat_unnorm)
    tl.testing.assert_array_almost_equal(tl_vne, actual_vne, decimal=3)
    tl.testing.assert_array_almost_equal(tl_vne_unnorm, actual_vne, decimal=3)
    assert_array_almost_equal(tl_vne, actual_vne, decimal=3)
    assert_array_almost_equal(tl_vne_unnorm, actual_vne, decimal=3)
示例#2
0
    def __factor_non_negative(self, tensor, factors, mode):
        """Compute a non-negative factor optimization for TCA

		Parameters
		----------
		tensor : torch.Tensor
			The tensor of activity of N neurons, T timepoints and K trials of shape N, T, K
		factors : list
			List of tensors, each one containing a factor
		mode : int
			Index of the factor to optimize

		Returns
		-------
		float
			Number to which multiply the factor to for optimization

		"""
        sub_indices = [i for i in range(self.dimension) if i != mode]
        for i, e in enumerate(sub_indices):
            if i:
                accum = accum * tl.dot(tl.transpose(factors[e]), factors[e])
            else:
                accum = tl.dot(tl.transpose(factors[e]), factors[e])

        numerator = tl.dot(tl.base.unfold(tensor, mode),
                           tl.tenalg.khatri_rao(factors, skip_matrix=mode))
        numerator = tl.clip(numerator, a_min=self.epsilon, a_max=None)
        denominator = tl.dot(factors[mode], accum)
        denominator = tl.clip(denominator, a_min=self.epsilon, a_max=None)

        return (numerator / denominator)
示例#3
0
    def __factor(self, tensor, factors, mode, pseudo_inverse):
        """Compute a factor optimization for TCA

		Parameters
		----------
		tensor : torch.Tensor
			The tensor of activity of N neurons, T timepoints and K trials of shape N, T, K
		factors : list
			List of tensors, each one containing a factor
		mode : int
			Index of the factor to optimize
		pseudo_inverse : torch.Tensor
			Pseudo inverse matrix of the current factor

		Returns
		-------
		torch.Tensor
			Optimized factor

		"""
        for i, factor in enumerate(factors):
            if i != mode:
                pseudo_inverse = pseudo_inverse * tl.dot(
                    tl.transpose(factor), factor)
        factor = tl.dot(tl.base.unfold(tensor, mode),
                        tl.tenalg.khatri_rao(factors, skip_matrix=mode))
        factor = tl.transpose(
            tl.solve(tl.transpose(pseudo_inverse), tl.transpose(factor)))

        return factor
示例#4
0
文件: _als.py 项目: cohenjer/PIRS8
def als(tensor,rank,factors=None,it_max=100,tol=1e-7,list_factors=False,error_fast=True,time_rec=False):
  """
    ALS methode of CP decomposition

    Parameters
    ----------
    tensor : tensor
    rank : int
    factors : list of matrices, optional
        an initial factor matrices. The default is None.
    it_max : int, optional
        maximal number of iteration. The default is 100.
    tol : float, optional
        error tolerance. The default is 1e-7.
    list_factors : boolean, optional
        If true, then return factor matrices of each iteration. The default is False.
    error_fast : boolean, optional
        If true, use err_fast to compute data fitting error, otherwise, use err. The default is True.
    time_rec : boolean, optional
        If true, return computation time of each iteration. The default is False.

    Returns
    -------
    the CP decomposition, number of iteration and termination criterion. 
    list_fac and list_time are optional.
  """
  N=tl.ndim(tensor) # order of tensor
  norm_tensor=tl.norm(tensor) # norm of tensor
  if time_rec == True : list_time=[]
  if list_factors==True : list_fac=[] # list of factor matrices

  if (factors==None): factors=svd_init_fac(tensor,rank)

  weights=None
  it=0
  if list_factors==True : list_fac.append(copy.deepcopy(factors))
  error=[err(tensor,weights,factors)/norm_tensor]
  while (error[len(error)-1]>tol and it<it_max):
    if time_rec == True : tic=time.time() 
    for n in range(N):
      V=np.ones((rank,rank))
      for i in range(len(factors)):
        if i != n : V=V*tl.dot(tl.transpose(factors[i]),factors[i])
      W=tl.cp_tensor.unfolding_dot_khatri_rao(tensor, (None,factors), n) 
      factors[n]= tl.transpose(tl.solve(tl.transpose(V),tl.transpose(W)))
    if list_factors==True : list_fac.append(copy.deepcopy(factors))
    it=it+1
    if (error_fast==False) : error.append(err(tensor,weights,factors)/norm_tensor)
    else : error.append(err_fast(norm_tensor,factors[N-1],V,W)/norm_tensor)
    if time_rec == True : 
      toc=time.time() 
      list_time.append(toc-tic)
  # weights,factors=tl.cp_tensor.cp_normalize((None,factors))
  if list_factors==True and time_rec==True: return(weights,factors,it,error,list_fac,list_time)
  if time_rec==True : return(weights,factors,it,error,list_time)
  if list_factors==True : return(weights,factors,it,error,list_fac)
  return(weights,factors,it,error)
示例#5
0
def tt_conv(x, tt_tensor, bias=None, stride=1, padding=0, dilation=1):
    """Perform a factorized tt convolution

    Parameters
    ----------
    x : torch.tensor
        tensor of shape (batch_size, C, I_2, I_3, ..., I_N)

    Returns
    -------
    NDConv(x) with an tt kernel
    """
    shape = tt_tensor.shape
    rank = tt_tensor.rank

    batch_size = x.shape[0]
    order = len(shape) - 2

    if isinstance(padding, int):
        padding = (padding, )*order
    if isinstance(stride, int):
        stride = (stride, )*order
    if isinstance(dilation, int):
        dilation = (dilation, )*order

    # Change the number of channels to the rank
    x_shape = list(x.shape)
    x = x.reshape((batch_size, x_shape[1], -1)).contiguous()

    # First conv == tensor contraction
    # from (1, in_channels, rank) to (rank == out_channels, in_channels, 1)
    x = F.conv1d(x, tl.transpose(tt_tensor.factors[0], [2, 1, 0]))

    x_shape[1] = x.shape[1]#rank[1]
    x = x.reshape(x_shape)

    # convolve over non-channels
    for i in range(order):
        # From (in_rank, kernel_size, out_rank) to (out_rank, in_rank, kernel_size)
        kernel = tl.transpose(tt_tensor.factors[i+1], [2, 0, 1])
        x = general_conv1d(x.contiguous(), kernel, i+2, stride=stride[i], padding=padding[i])

    # Revert back number of channels from rank to output_channels
    x_shape = list(x.shape)
    x = x.reshape((batch_size, x_shape[1], -1))
    # Last conv == tensor contraction
    # From (rank, out_channels, 1) to (out_channels, in_channels == rank, 1)
    x = F.conv1d(x, tl.transpose(tt_tensor.factors[-1], [1, 0, 2]), bias=bias)

    x_shape[1] = x.shape[1]
    x = x.reshape(x_shape)

    return x
示例#6
0
def test_vonneumann_entropy_mixed_state():
    """Test for vonneumann_entropy on 2-dimensional tensors.
    This test checks that the VNE of mixed states is calculated correctly.
    """
    state1 = tl.tensor([[0.03004805, 0.42426117, 0.5483771 , 0.4784077 , 0.25792725, 0.34388784, 0.99927586, 0.96605812]])
    state1 = state1/tl.norm(state1)
    state2 = tl.tensor([[0.84250089, 0.43429687, 0.26551928, 0.18262211, 0.55584835, 0.2565509 , 0.33197401, 0.97741178]])
    state2 = state2/tl.norm(state2)
    mat_mixed = tl.tensor((tl.dot(tl.transpose(state1), state1) + tl.dot(tl.transpose(state2), state2))/2.)
    actual_vne = 0.5546
    tl_vne = vonneumann_entropy(mat_mixed)
    assert_array_almost_equal(tl_vne, actual_vne, decimal=3)
示例#7
0
def contract(tensor1, modes1, tensor2, modes2):
    """Tensor contraction between two tensors on specified modes
    
    Parameters
    ----------
    tensor1 : tl.tensor
    modes1 : int list or int
        modes on which to contract tensor1
    tensor2 : tl.tensor
    modes2 : int list or int
        modes on which to contract tensor2

    Returns
    -------
    contraction : tensor1 contracted with tensor2 on the specified modes
    """
    if isinstance(modes1, int):
        modes1 = [modes1]
    if isinstance(modes2, int):
        modes2 = [modes2]
    modes1 = list(modes1)
    modes2 = list(modes2)

    if len(modes1) != len(modes2):
        raise ValueError(
            'Can only contract two tensors along the same number of modes'
            '(len(modes1) == len(modes2))'
            'However, got {} modes for tensor 1 and {} mode for tensor 2'
            '(modes1={}, and modes2={})'.format(len(modes1), len(modes2),
                                                modes1, modes2))

    contraction_dims = [tl.shape(tensor1)[i] for i in modes1]
    if contraction_dims != [tl.shape(tensor2)[i] for i in modes2]:
        raise ValueError(
            'Trying to contract tensors over modes of different sizes'
            '(contracting modes of sizes {} and {}'.format(
                contraction_dims, [tl.shape(tensor2)[i] for i in modes2]))
    shared_dim = int(np.prod(contraction_dims))

    modes1_free = [i for i in range(tl.ndim(tensor1)) if i not in modes1]
    free_shape1 = [tl.shape(tensor1)[i] for i in modes1_free]

    tensor1 = tl.reshape(tl.transpose(tensor1, modes1_free + modes1),
                         (int(np.prod(free_shape1)), shared_dim))

    modes2_free = [i for i in range(tl.ndim(tensor2)) if i not in modes2]
    free_shape2 = [tl.shape(tensor2)[i] for i in modes2_free]

    tensor2 = tl.reshape(tl.transpose(tensor2, modes2 + modes2_free),
                         (shared_dim, int(np.prod(free_shape2))))

    res = tl.dot(tensor1, tensor2)
    return tl.reshape(res, tuple(free_shape1 + free_shape2))
示例#8
0
def cp_conv(x, cp_tensor, bias=None, stride=1, padding=0, dilation=1):
    """Perform a factorized CP convolution

    Parameters
    ----------
    x : torch.tensor
        tensor of shape (batch_size, C, I_2, I_3, ..., I_N)

    Returns
    -------
    NDConv(x) with an CP kernel
    """
    shape = cp_tensor.shape
    rank = cp_tensor.rank

    batch_size = x.shape[0]
    order = len(shape) - 2

    if isinstance(padding, int):
        padding = (padding, )*order
    if isinstance(stride, int):
        stride = (stride, )*order
    if isinstance(dilation, int):
        dilation = (dilation, )*order

    # Change the number of channels to the rank
    x_shape = list(x.shape)
    x = x.reshape((batch_size, x_shape[1], -1)).contiguous()

    # First conv == tensor contraction
    # from (in_channels, rank) to (rank == out_channels, in_channels, 1)
    x = F.conv1d(x, tl.transpose(cp_tensor.factors[1]).unsqueeze(2))

    x_shape[1] = rank
    x = x.reshape(x_shape)

    # convolve over non-channels
    for i in range(order):
        # From (kernel_size, rank) to (rank, 1, kernel_size)
        kernel = tl.transpose(cp_tensor.factors[i+2]).unsqueeze(1)             
        x = general_conv1d(x.contiguous(), kernel, i+2, stride=stride[i], padding=padding[i], groups=rank)

    # Revert back number of channels from rank to output_channels
    x_shape = list(x.shape)
    x = x.reshape((batch_size, x_shape[1], -1))                
    # Last conv == tensor contraction
    # From (out_channels, rank) to (out_channels, in_channels == rank, 1)
    x = F.conv1d(x*cp_tensor.weights.unsqueeze(1).unsqueeze(0), cp_tensor.factors[0].unsqueeze(2), bias=bias)

    x_shape[1] = x.shape[1] # = out_channels
    x = x.reshape(x_shape)

    return x
示例#9
0
def vonneumann_entropy(tensor):
    """Returns the von Neumann entropy of a density matrix (2-mode, square) tensor (matrix).

    Parameters
    ----------
    tensor : Non-decomposed tensor with indices whose shapes are all a factor of two (represent one or more qubits)

    Returns
    -------
    von_neumann_entropy : order-0 tensor

    Notes
    -----
    The von Neumann entropy is :math:`- \\sum_i p_i ln(p_i)`, 
    where p_i are the probabilities that each state is occupied 
    (the eigenvalues of the density matrix).
    """
    square_dim = int(math.sqrt(prod(tensor.shape)))
    tensor = tl.reshape(tensor, (square_dim, square_dim))
    try:
        eig_vals = T.eigh(tensor)[0]
    except:
        #All density matrices are Hermitian, here real. Hermitianize matrix if rounding/transformation
        #errors have occured.
        tensor = (tensor + tl.transpose(tensor)) / 2
        eig_vals = T.eigh(tensor)[0]
    eps = tl.eps(eig_vals.dtype)
    eig_vals = eig_vals[eig_vals > eps]

    return -T.sum(T.log2(eig_vals) * eig_vals)
示例#10
0
def vec2factors(vec, shape, rank, context=None):
    """Wrapper function detailed in Appendix C [1]
    Builds a set of N matrices, where the k-th matrix is shape(k) x rank in dimension

    Parameters
    ----------
    vec : ndarray
        vector of values to proliferate matrices with
    shape: tensor shape
        shape of tensor dictates number of rows in each matrix
    rank: int
        number of columns in each matrix, *** rank cannot be > dimension of smallest mode ***

    Returns
    -------
    M1 : CPTensor
        CPTensor with factor matrices formed by 'vec'
    """
    numFacts = len(shape)
    factors = []
    place = 0
    for i in range(numFacts):
        factor = np.zeros((rank * shape[i]), **context)
        for j in range(shape[i] * rank):
            factor[j] = vec[j + place]
        factor = tl.tensor(factor.reshape((rank, shape[i])), **context)
        factors.append(tl.transpose(factor))
        place += shape[i] * rank
    M1 = CPTensor((tl.ones(rank, ), factors))
    return M1
示例#11
0
def tucker_conv(x, tucker_tensor, bias=None, stride=1, padding=0, dilation=1):
    # Extract the rank from the actual decomposition in case it was changed by, e.g. dropout
    rank = tucker_tensor.rank

    batch_size = x.shape[0]
    n_dim = tl.ndim(x)

    # Change the number of channels to the rank
    x_shape = list(x.shape)
    x = x.reshape((batch_size, x_shape[1], -1)).contiguous()

    # This can be done with a tensor contraction
    # First conv == tensor contraction
    # from (in_channels, rank) to (rank == out_channels, in_channels, 1)
    x = F.conv1d(x, tl.transpose(tucker_tensor.factors[1]).unsqueeze(2))

    x_shape[1] = rank[1]
    x = x.reshape(x_shape)

    modes = list(range(2, n_dim+1))
    weight = tl.tenalg.multi_mode_dot(tucker_tensor.core, tucker_tensor.factors[2:], modes=modes)
    x = convolve(x, weight, bias=None, stride=stride, padding=padding)

    # Revert back number of channels from rank to output_channels
    x_shape = list(x.shape)
    x = x.reshape((batch_size, x_shape[1], -1))
    # Last conv == tensor contraction
    # From (out_channels, rank) to (out_channels, in_channels == rank, 1)
    x = F.conv1d(x, tucker_tensor.factors[0].unsqueeze(2), bias=bias)

    x_shape[1] = x.shape[1]
    x = x.reshape(x_shape)

    return x
示例#12
0
def tt_matrix_to_tensor(tt_matrix):
    """Returns the full tensor whose TT-Matrix decomposition is given by 'factors'

        Re-assembles 'factors', which represent a tensor in TT-Matrix format
        into the corresponding full tensor

    Parameters
    ----------
    factors: list of 4D-arrays
              TT-Matrix factors (known as core) of shape (rank_k, left_dim_k, right_dim_k, rank_{k+1})

    Returns
    -------
    output_tensor: ndarray
                   tensor whose TT-Matrix decomposition was given by 'factors'
    """
    # Each core is of shape (rank_left, size_in, size_out, rank_right)
    rank, in_shape, out_shape, rank_right = zip(*(tl.shape(f) for f in tt_matrix))
    rank += (rank_right[-1], )                           
    ndim = len(in_shape)
    
    # Intertwine the dims 
    # full_shape = in_shape[0], out_shape[0], in_shape[1], ...
    full_shape = sum(zip(*(in_shape, out_shape)), ())
    order = list(range(0, ndim*2, 2)) + list(range(1, ndim*2, 2))

    for i, factor in enumerate(tt_matrix):
        if not i:
            # factor = factor.squeeze(0)
            res = tl.reshape(factor, (factor.shape[1], -1))
        else:
            res = tl.dot(tl.reshape(res, (-1, rank[i])), tl.reshape(factor, (rank[i], -1)))
    res = tl.reshape(res, full_shape)
    
    return tl.transpose(res, order)
示例#13
0
def cp_conv_mobilenet(x, cp_tensor, bias=None, stride=1, padding=0, dilation=1):
    """Perform a factorized CP convolution

    Parameters
    ----------
    x : torch.tensor
        tensor of shape (batch_size, C, I_2, I_3, ..., I_N)

    Returns
    -------
    NDConv(x) with an CP kernel
    """
    factors = cp_tensor.factors
    shape = cp_tensor.shape
    rank = cp_tensor.rank

    batch_size = x.shape[0]
    order = len(shape) - 2

    # Change the number of channels to the rank
    x_shape = list(x.shape)
    x = x.reshape((batch_size, x_shape[1], -1)).contiguous()

    # First conv == tensor contraction
    # from (in_channels, rank) to (rank == out_channels, in_channels, 1)
    x = F.conv1d(x, tl.transpose(factors[1]).unsqueeze(2))

    x_shape[1] = rank
    x = x.reshape(x_shape)

    # convolve over merged actual dimensions
    # Spatial convs
    # From (kernel_size, rank) to (out_rank, 1, kernel_size)
    if order == 1:
        weight = tl.transpose(factors[2]).unsqueeze(1)
        x = F.conv1d(x.contiguous(), weight, stride=stride, padding=padding, dilation=dilation, groups=rank)
    elif order == 2:
        weight = tenalg.tensordot(tl.transpose(factors[2]), 
                                  tl.transpose(factors[3]), modes=(), batched_modes=0
                                  ).unsqueeze(1)
        x = F.conv2d(x.contiguous(), weight, stride=stride, padding=padding, dilation=dilation, groups=rank)
    elif order == 3:
        weight = tenalg.tensordot(tl.transpose(factors[2]), 
                                  tenalg.tensordot(tl.transpose(factors[3]), tl.transpose(factors[4]), modes=(), batched_modes=0),
                                  modes=(), batched_modes=0
                                  ).unsqueeze(1)
        x = F.conv3d(x.contiguous(), weight, stride=stride, padding=padding, dilation=dilation, groups=rank)

    # Revert back number of channels from rank to output_channels
    x_shape = list(x.shape)
    x = x.reshape((batch_size, x_shape[1], -1))

    # Last conv == tensor contraction
    # From (out_channels, rank) to (out_channels, in_channels == rank, 1)
    x = F.conv1d(x*cp_tensor.weights.unsqueeze(1).unsqueeze(0), factors[0].unsqueeze(2), bias=bias)

    x_shape[1] = x.shape[1] # = out_channels
    x = x.reshape(x_shape)

    return x
def show_proj(factors, matlab_data, ex1_em0):
    color = ["r", "g", "b"]
    for i in range(3):
        mat1 = np.array(factors[1][1]).transpose()[i]
        w = tl.norm(factors[1][0][i])

        sq_mat = np.array(mat1).reshape(61, 201)
        m = np.max(sq_mat)
        ind = tl.where(sq_mat == m)
        if (ex1_em0 == 1):
            x = matlab_data["EmAx"][0]
            y = w * tl.transpose(sq_mat[ind[0]])
        else:
            x = matlab_data["ExAx"][0]
            y = w * np.transpose(tl.transpose(sq_mat)[ind[1]])
        plt.grid()
        plt.plot(x, y, color[i])
    plt.show()
示例#15
0
def test_cp_to_tensor():
    """Test for cp_to_tensor."""
    U1 = np.reshape(np.arange(1, 10), (3, 3))
    U2 = np.reshape(np.arange(10, 22), (4, 3))
    U3 = np.reshape(np.arange(22, 28), (2, 3))
    U4 = np.reshape(np.arange(28, 34), (2, 3))
    U = [tl.tensor(t) for t in [U1, U2, U3, U4]]
    true_res = tl.tensor([[[[  46754.,   51524.],
                            [  52748.,   58130.]],

                           [[  59084.,   65114.],
                            [  66662.,   73466.]],

                           [[  71414.,   78704.],
                            [  80576.,   88802.]],

                           [[  83744.,   92294.],
                            [  94490.,  104138.]]],


                          [[[ 113165.,  124784.],
                            [ 127790.,  140912.]],

                           [[ 143522.,  158264.],
                            [ 162080.,  178730.]],

                           [[ 173879.,  191744.],
                            [ 196370.,  216548.]],

                           [[ 204236.,  225224.],
                            [ 230660.,  254366.]]],


                          [[[ 179576.,  198044.],
                            [ 202832.,  223694.]],

                           [[ 227960.,  251414.],
                            [ 257498.,  283994.]],

                           [[ 276344.,  304784.],
                            [ 312164.,  344294.]],

                           [[ 324728.,  358154.],
                            [ 366830.,  404594.]]]])
    res = cp_to_tensor((tl.ones(3), U))
    assert_array_equal(res, true_res, err_msg='Khatri-rao incorrectly transformed into full tensor.')

    columns = 4
    rows = [3, 4, 2]
    matrices = [tl.tensor(np.arange(k * columns).reshape((k, columns))) for k in rows]
    tensor = cp_to_tensor((tl.ones(columns), matrices))
    for i in range(len(rows)):
        unfolded = unfold(tensor, mode=i)
        U_i = matrices.pop(i)
        reconstructed = tl.dot(U_i, tl.transpose(khatri_rao(matrices)))
        assert_array_almost_equal(reconstructed, unfolded)
        matrices.insert(i, U_i)
示例#16
0
def test_vonneumann_entropy_pure_state():
    """Test for vonneumann_entropy on 2-dimensional tensors.
    This test checks that pure states have a VNE of zero.
    """
    state = tl.randn((8, 1))
    state = state / tl.norm(state)
    mat_pure = tl.dot(state, tl.transpose(state))
    tl_vne = vonneumann_entropy(mat_pure)
    assert_array_almost_equal(tl_vne, 0, decimal=3)
示例#17
0
def test_cp_vonneumann_entropy_pure_state():
    """Test for cp_vonneumann_entropy on 2-dimensional CP tensors.
    This test checks that pure states have a VNE of zero.
    """
    state = tl.randn((8, 1))
    state = state / tl.norm(state)
    mat_pure = tl.dot(state, tl.transpose(state))
    mat = parafac(mat_pure, rank=1, normalize_factors=True)
    tl_vne = cp_vonneumann_entropy(mat)
    assert_array_almost_equal(tl_vne, 0, decimal=3)
def test_factors2vec_1():
    """ Test wrapper function from GCP paper"""
    X = tl.tensor(np.arange(24).reshape((3,4,2)), dtype=tl.float32)
    factors = []
    for i in range(3):
        f = tl.transpose(X[:][:][i])
        factors.append(f)
    vec = factors2vec(factors)
    for i in range(vec.size):
        assert(vec[i] == i), "Value at vec[i] = {} doesn't equal the index value i = {}".format(vec[i], i)
示例#19
0
def test_tt_vonneumann_entropy_pure_state():
    """Test for tt_vonneumann_entropy TT tensors.
    This test checks that pure states have a VNE of zero.
    """
    state = tl.randn((8, 1))
    state = state/tl.norm(state)
    mat_pure = tl.reshape(tl.dot(state, tl.transpose(state)), (2, 2, 2, 2, 2, 2))
    mat_pure = matrix_product_state(mat_pure, rank=(1, 3, 2, 1, 2, 3, 1))
    tl_vne = tt_vonneumann_entropy(mat_pure)
    assert_array_almost_equal(tl_vne, 0, decimal=3)
示例#20
0
文件: utils.py 项目: tenggaard/prgds
def uttkrp(tens, mode, mtxs, core=None, transpose=False):
    """
    Alternative implementation of uttkrp in sktensor library.

    The description of that method is modified below:

    Unfolded tensor times Khatri-Rao product:
    :math:`Z = \\unfold{X}{3} (U_1 \kr \cdots \kr U_N)`
    Computes the _matrix_ product of the unfolding
    of a tensor and the Khatri-Rao product of multiple matrices.
    Efficient computations are perfomed by the respective
    tensor implementations.
    Parameters
    ----------
    tens : input tensor
    mtxs : list of array-likes
        Matrices for which the Khatri-Rao product is computed and
        which are multiplied with the tensor in mode `mode`.
    mode : int
        Mode in which the Khatri-Rao product of `mtxs` is multiplied
        with the tensor.
    core: array-like
        Weights for each component (K-length)
    Returns
    -------
    Z : np.ndarray
        Matrix which is the result of the matrix product of the unfolding of
        the tensor and the Khatri-Rao product of `mtxs`.
    See also
    --------
    For efficient computations of unfolded tensor times Khatri-Rao products
    for specialiized tensors see also
    References
    ----------
    [1] B.W. Bader, T.G. Kolda
        Efficient Matlab Computations With Sparse and Factored Tensors
        SIAM J. Sci. Comput, Vol 30, No. 1, pp. 205--231, 2007
    """
    if transpose:
        mtxs = [mtx.T for mtx in mtxs]

    K, D = mtxs[mode].shape
    order = sorted(range(tens.ndim), key=lambda m: mtxs[m].shape[0])
    order.remove(mode)
    Z = tl.transpose(tens, [mode] + order)

    Z = tl.tenalg.mode_dot(Z, mtxs[order[-1]], -1)
    for m in reversed(order[:-1]):
        Z *= mtxs[m].T
        Z = Z.sum(axis=-2)
    
    if core is not None:
        Z *= core[:, np.newaxis] if not transpose else core 

    return Z.T if not transpose else Z
示例#21
0
def general_conv1d_(x, kernel, mode, bias=None, stride=1, padding=0, groups=1, dilation=1, verbose=False):
    """General 1D convolution along the mode-th dimension

    Parameters
    ----------
    x : batch-dize, in_channels, K1, ..., KN
    kernel : out_channels, in_channels/groups, K{mode}
    mode : int
        weight along which to perform the decomposition
    stride : int
    padding : int
    groups : 1
        typically would be equal to thhe number of input-channels
        at least for CP convolutions

    Returns
    -------
    x convolved with the given kernel, along dimension `mode`
    """
    if verbose:
        print(f'Convolving {x.shape} with {kernel.shape} along mode {mode}, '
              f'stride={stride}, padding={padding}, groups={groups}')

    in_channels = tl.shape(x)[1]
    n_dim = tl.ndim(x)
    permutation = list(range(n_dim))
    spatial_dim = permutation.pop(mode)
    channels_dim = permutation.pop(1)
    permutation += [channels_dim, spatial_dim]
    x = tl.transpose(x, permutation)
    x_shape = list(x.shape)
    x = tl.reshape(x, (-1, in_channels, x_shape[-1]))
    x = F.conv1d(x.contiguous(), kernel, bias=bias, stride=stride, dilation=dilation, padding=padding, groups=groups)
    x_shape[-2:] = x.shape[-2:]
    x = tl.reshape(x, x_shape)
    permutation = list(range(n_dim))[:-2]
    permutation.insert(1, n_dim - 2)
    permutation.insert(mode, n_dim - 1)
    x = tl.transpose(x, permutation)
    
    return x
示例#22
0
def factors2vec(factors):
    """Wrapper function detailed in Appendix C [1]
    Stacks the column vectors of a set of matrices into a single vecto

    Parameters
    ---------
    factors : list of ndarrays
        Factor matrices or Gradient wrt factor gradient

    Returns
    -------
    vec : ndarry
        column-wise vectorization of a list of matrices
    """
    vec = None
    for factor in factors:
        if vec is None:
            vec = tl.tensor_to_vec(tl.transpose(factor))
        else:
            vec = tl.concatenate([vec, tl.tensor_to_vec(tl.transpose(factor))])
    return vec
示例#23
0
def homo_decryption(encrypted_Tensor, key_Matrix, n):
    decrypted_tensor = []
    for k in range(encrypted_Tensor.shape[0]):
        decrypted_columns = []
        for i in range(encrypted_Tensor.shape[2]):
            # x, info = cg(key_Matrix, encrypted_Tensor[k, :, i].reshape(n, 1))
            x = solve(key_Matrix, encrypted_Tensor[k, :, i])
            decrypted_columns.append(x)
        decrypted_factors = tl.transpose(
            tl.fold(decrypted_columns, mode=0, shape=(n, n)))
        # print(decrypted_factors)
        decrypted_tensor.append(decrypted_factors)
    decrypted_tensor = tl.fold(decrypted_tensor, mode=0, shape=(n, n, n))
    # print(decrypted_tensor)
    return decrypted_tensor
示例#24
0
def test_cp_to_tensor_with_weights():
    A = tl.reshape(tl.arange(1,5), (2,2))
    B = tl.reshape(tl.arange(5,9), (2,2))
    weigths = tl.tensor([2,-1], **tl.context(A))

    out = cp_to_tensor((weigths, [A,B]))
    expected = tl.tensor([[-2,-2], [6, 10]])  # computed by hand
    assert_array_equal(out, expected)

    (weigths, factors) = random_cp((5, 5, 5), rank=5, normalise_factors=True, full=False)
    true_res = tl.dot(tl.dot(factors[0], tl.diag(weigths)),
                      tl.transpose(tl.tenalg.khatri_rao(factors[1:])))
    true_res = tl.fold(true_res, 0, (5, 5, 5))  
    res = cp_to_tensor((weigths, factors))
    assert_array_almost_equal(true_res, res,
     err_msg='weights incorrectly incorporated in cp_to_tensor')
def test_vec2factors_1():
    """ Test wrapper function from GCP paper"""
    rank = 2
    X = tl.tensor(np.arange(24).reshape((3, 4, 2)), dtype=tl.float32)
    X_shp = tl.shape(X)
    X_cntx = tl.context(X)

    factors = []
    for i in range(3):
        f = tl.transpose(X[:][:][i])
        factors.append(f)
    vec1 = factors2vec(factors)

    M = vec2factors(vec1,X_shp, rank, X_cntx)
    vec2 = factors2vec(M[1])
    for i in range(X_shp[0]):
        assert(vec1[i] == vec2[i])
示例#26
0
文件: _tt.py 项目: sz144/tensorly
def tensor_train_matrix(tensor, rank):
    """Decompose a tensor into a matrix in tt-format
    
    Parameters
    ----------
    tensor : tensorized matrix 
        if your input matrix is of size (4, 9) and your tensorized_shape (2, 2, 3, 3)
        then tensor should be tl.reshape(matrix, (2, 2, 3, 3))
    rank : 'same', float or int tuple
        - if 'same' creates a decomposition with the same number of parameters as `tensor`
        - if float, creates a decomposition with `rank` x the number of parameters of `tensor`
        - otherwise, the actual rank to be used, e.g. (1, rank_2, ..., 1) of size tensor.ndim//2. Note that boundary conditions dictate that the first rank = last rank = 1.
    
    Returns
    -------
    tt_matrix
    """
    order = tl.ndim(tensor)
    n_input = order // 2  # (n_output = n_input)

    if tl.ndim(tensor) != n_input * 2:
        msg = 'The tensor should have as many dimensions for inputs and outputs, i.e. order should be even '
        msg += f'but got a tensor of order tl.ndim(tensor)={order} which is odd.'
        raise ValueError(msg)

    in_shape = tl.shape(tensor)[:n_input]
    out_shape = tl.shape(tensor)[n_input:]

    if n_input == 1:
        # A TTM with a single factor is just a matrix...
        return TTMatrix([tensor.reshape(1, in_shape[0], out_shape[0], 1)])

    new_idx = list([
        idx for tuple_ in zip(range(n_input), range(n_input, 2 * n_input))
        for idx in tuple_
    ])
    new_shape = list([a * b for (a, b) in zip(in_shape, out_shape)])
    tensor = tl.reshape(tl.transpose(tensor, new_idx), new_shape)

    factors = tensor_train(tensor, rank).factors
    for i in range(len(factors)):
        factors[i] = tl.reshape(
            factors[i], (factors[i].shape[0], in_shape[i], out_shape[i], -1))

    return TTMatrix(factors)
示例#27
0
def vonneumann_entropy(tensor):
    """Returns the von Neumann entropy of a density matrix (2-mode, square) tensor (matrix). 

    Parameters
    ----------
    tensor : (matrix)
        Data structure

    Returns
    -------
    von_neumann_entropy : order-0 tensor
    """
    try:
        eig_vals = T.eigh(tensor)[0]
    except:
        #All density matrices are Hermitian, here real. Hermitianize matrix if rounding/transformation
        #errors have occured.
        tensor = (tensor + tl.transpose(tensor)) / 2
        eig_vals = T.eigh(tensor)[0]
    eps = tl.eps(eig_vals.dtype)
    eig_vals = eig_vals[eig_vals > eps]

    return -T.sum(T.log2(eig_vals) * eig_vals)
示例#28
0
def parafac(tensor,
            rank,
            n_iter_max=100,
            tol=1e-8,
            random_state=None,
            verbose=False,
            return_errors=False,
            mode_three_val=[[0.5, 0.5, 0.0], [0.0, 0.5, 0.5]]):
    """CANDECOMP/PARAFAC decomposition via alternating least squares (ALS)

    Computes a rank-`rank` decomposition of `tensor` [1]_ such that,

        ``tensor = [| factors[0], ..., factors[-1] |]``.

    Parameters
    ----------
    tensor : ndarray
    rank  : int
        Number of components.
    n_iter_max : int
        Maximum number of iteration
    tol : float, optional
        (Default: 1e-6) Relative reconstruction error tolerance. The
        algorithm is considered to have found the global minimum when the
        reconstruction error is less than `tol`.
    random_state : {None, int, np.random.RandomState}
    verbose : int, optional
        Level of verbosity
    return_errors : bool, optional
        Activate return of iteration errors


    Returns
    -------
    factors : ndarray list
        List of factors of the CP decomposition element `i` is of shape
        (tensor.shape[i], rank)
    errors : list
        A list of reconstruction errors at each iteration of the algorithms.

    References
    ----------
    .. [1] tl.G.Kolda and B.W.Bader, "Tensor Decompositions and Applications",
       SIAM REVIEW, vol. 51, n. 3, pp. 455-500, 2009.
    """

    factors = initialize_factors(tensor, rank, random_state=random_state)
    rec_errors = []
    norm_tensor = tl.norm(tensor, 2)

    # Mode-3 values that control the country factors are set using the
    # mode_three_val argument.

    fixed_ja = mode_three_val[0]
    fixed_ko = mode_three_val[1]

    for iteration in range(n_iter_max):
        for mode in range(tl.ndim(tensor)):
            pseudo_inverse = tl.tensor(np.ones((rank, rank)),
                                       **tl.context(tensor))

            factors[2][0] = fixed_ja  # set mode-3 values
            factors[2][1] = fixed_ko  # set mode-3 values

            for i, factor in enumerate(factors):
                if i != mode:
                    pseudo_inverse = pseudo_inverse * tl.dot(
                        tl.transpose(factor), factor)
            factor = tl.dot(unfold(tensor, mode),
                            khatri_rao(factors, skip_matrix=mode))
            factor = tl.transpose(
                tl.solve(tl.transpose(pseudo_inverse), tl.transpose(factor)))
            factors[mode] = factor

        if tol:
            rec_error = tl.norm(tensor - kruskal_to_tensor(factors),
                                2) / norm_tensor
            rec_errors.append(rec_error)

            if iteration > 1:
                if verbose:
                    print('reconstruction error={}, variation={}.'.format(
                        rec_errors[-1], rec_errors[-2] - rec_errors[-1]))

                if tol and abs(rec_errors[-2] - rec_errors[-1]) < tol:
                    if verbose:
                        print('converged in {} iterations.'.format(iteration))
                    break

    if return_errors:
        return factors, rec_errors
    else:
        return factors
示例#29
0
def non_negative_parafac(tensor,
                         rank,
                         n_iter_max=100,
                         init='svd',
                         svd='numpy_svd',
                         tol=10e-7,
                         random_state=None,
                         verbose=0,
                         normalize_factors=False,
                         return_errors=False,
                         mask=None,
                         orthogonalise=False,
                         cvg_criterion='abs_rec_error',
                         fixed_modes=[]):
    """
    Non-negative CP decomposition
    Uses multiplicative updates, see [2]_
    This is the same as parafac(non_negative=True).
    Parameters
    ----------
    tensor : ndarray
    rank   : int
            number of components
    n_iter_max : int
                 maximum number of iteration
    init : {'svd', 'random'}, optional
    svd : str, default is 'numpy_svd'
        function to use to compute the SVD, acceptable values in tensorly.SVD_FUNS
    tol : float, optional
          tolerance: the algorithm stops when the variation in
          the reconstruction error is less than the tolerance
    random_state : {None, int, np.random.RandomState}
    verbose : int, optional
        level of verbosity
    fixed_modes : list, default is []
        A list of modes for which the initial value is not modified.
        The last mode cannot be fixed due to error computation.
    Returns
    -------
    factors : ndarray list
            list of positive factors of the CP decomposition
            element `i` is of shape ``(tensor.shape[i], rank)``
    References
    ----------
    .. [2] Amnon Shashua and Tamir Hazan,
       "Non-negative tensor factorization with applications to statistics and computer vision",
       In Proceedings of the International Conference on Machine Learning (ICML),
       pp 792-799, ICML, 2005
    """
    epsilon = 10e-12
    rank = validate_cp_rank(tl.shape(tensor), rank=rank)

    if mask is not None and init == "svd":
        message = "Masking occurs after initialization. Therefore, random initialization is recommended."
        warnings.warn(message, Warning)

    if orthogonalise and not isinstance(orthogonalise, int):
        orthogonalise = n_iter_max

    weights, factors = initialize_cp(tensor,
                                     rank,
                                     init=init,
                                     svd=svd,
                                     random_state=random_state,
                                     non_negative=True,
                                     normalize_factors=normalize_factors)
    rec_errors = []
    norm_tensor = tl.norm(tensor, 2)

    if tl.ndim(tensor) - 1 in fixed_modes:
        warnings.warn(
            'You asked for fixing the last mode, which is not supported while tol is fixed.\n The last mode will not be fixed. Consider using tl.moveaxis()'
        )
        fixed_modes.remove(tl.ndim(tensor) - 1)
    modes_list = [
        mode for mode in range(tl.ndim(tensor)) if mode not in fixed_modes
    ]

    for iteration in range(n_iter_max):
        if orthogonalise and iteration <= orthogonalise:
            for i, f in enumerate(factors):
                if min(tl.shape(f)) >= rank:
                    factors[i] = tl.abs(tl.qr(f)[0])

        if verbose > 1:
            print("Starting iteration", iteration + 1)
        for mode in modes_list:
            if verbose > 1:
                print("Mode", mode, "of", tl.ndim(tensor))

            accum = 1
            # khatri_rao(factors).tl.dot(khatri_rao(factors))
            # simplifies to multiplications
            sub_indices = [i for i in range(len(factors)) if i != mode]
            for i, e in enumerate(sub_indices):
                if i:
                    accum *= tl.dot(tl.transpose(factors[e]), factors[e])
                else:
                    accum = tl.dot(tl.transpose(factors[e]), factors[e])

            if mask is not None:
                tensor = tensor * mask + tl.cp_to_tensor(
                    (None, factors), mask=1 - mask)

            mttkrp = unfolding_dot_khatri_rao(tensor, (None, factors), mode)

            numerator = tl.clip(mttkrp, a_min=epsilon, a_max=None)
            denominator = tl.dot(factors[mode], accum)
            denominator = tl.clip(denominator, a_min=epsilon, a_max=None)
            factor = factors[mode] * numerator / denominator

            factors[mode] = factor

        if normalize_factors:
            weights, factors = cp_normalize((weights, factors))

        if tol:
            # ||tensor - rec||^2 = ||tensor||^2 + ||rec||^2 - 2*<tensor, rec>
            factors_norm = cp_norm((weights, factors))

            # mttkrp and factor for the last mode. This is equivalent to the
            # inner product <tensor, factorization>
            iprod = tl.sum(tl.sum(mttkrp * factor, axis=0) * weights)
            rec_error = tl.sqrt(
                tl.abs(norm_tensor**2 + factors_norm**2 -
                       2 * iprod)) / norm_tensor
            rec_errors.append(rec_error)
            if iteration >= 1:
                rec_error_decrease = rec_errors[-2] - rec_errors[-1]

                if verbose:
                    print(
                        "iteration {}, reconstraction error: {}, decrease = {}"
                        .format(iteration, rec_error, rec_error_decrease))

                if cvg_criterion == 'abs_rec_error':
                    stop_flag = abs(rec_error_decrease) < tol
                elif cvg_criterion == 'rec_error':
                    stop_flag = rec_error_decrease < tol
                else:
                    raise TypeError("Unknown convergence criterion")

                if stop_flag:
                    if verbose:
                        print("PARAFAC converged after {} iterations".format(
                            iteration))
                    break
            else:
                if verbose:
                    print('reconstruction error={}'.format(rec_errors[-1]))

    cp_tensor = CPTensor((weights, factors))

    if return_errors:
        return cp_tensor, rec_errors
    else:
        return cp_tensor
示例#30
0
def coupled_matrix_tensor_3d_factorization(tensor_3d,
                                           matrix,
                                           rank,
                                           init='svd',
                                           n_iter_max=100,
                                           normalize_factors=False):
    """
    Calculates a coupled matrix and tensor factorization of 3rd order tensor and matrix which are
    coupled in first mode.

    Assume you have tensor_3d = [[lambda; A, B, C]] and matrix = [[gamma; A, V]], which are
    coupled in 1st mode. With coupled matrix and tensor factorization (CTMF), the normalized
    factor matrices A, B, C for the CP decomposition of X, the normalized matrix V and the
    weights lambda_ and gamma are found. This implementation only works for a coupling in the
    first mode.

    Solution is found via alternating least squares (ALS) as described in Figure 5 of
    @article{acar2011all,
      title={All-at-once optimization for coupled matrix and tensor factorizations},
      author={Acar, Evrim and Kolda, Tamara G and Dunlavy, Daniel M},
      journal={arXiv preprint arXiv:1105.3422},
      year={2011}
    }

    Notes
    -----
    In the paper, the columns of the factor matrices are not normalized and therefore weights are
    not included in the algorithm.

    Parameters
    ----------
    tensor_3d : tl.tensor or CP tensor
        3rd order tensor X = [[A, B, C]]
    matrix : tl.tensor or CP tensor
        matrix that is coupled with tensor in first mode: Y = [[A, V]]
    rank : int
        rank for CP decomposition of X

    Returns
    -------
    tensor_3d_pred : CPTensor
        tensor_3d_pred = [[lambda; A,B,C]]
    matrix_pred : CPTensor
        matrix_pred = [[gamma; A,V]]
    rec_errors : list
        contains the reconstruction error of each iteration:
        error = 1 / 2 * | X - [[ lambda_; A, B, C ]] | ^ 2 + 1 / 2 * | Y - [[ gamma; A, V ]] | ^ 2

    Examples
    --------
    A = tl.tensor([[1, 2], [3, 4]])
    B = tl.tensor([[1, 0], [0, 2]])
    C = tl.tensor([[2, 0], [0, 1]])
    V = tl.tensor([[2, 0], [0, 1]])
    R = 2

    X = (None, [A, B, C])
    Y = (None, [A, V])

    tensor_3d_pred, matrix_pred = cmtf_als_for_third_order_tensor(X, Y, R)

    """
    rank = validate_cp_rank(tl.shape(tensor_3d), rank=rank)

    # initialize values
    tensor_cp = initialize_cp(tensor_3d, rank, init=init)
    rec_errors = []

    # alternating least squares
    # note that the order of the khatri rao product is reversed since tl.unfold has another order
    # than assumed in paper
    for iteration in range(n_iter_max):
        V = tl.transpose(tl.lstsq(tensor_cp.factors[0], matrix)[0])

        # Loop over modes of the tensor
        for ii in range(tl.ndim(tensor_3d)):
            kr = khatri_rao(tensor_cp.factors, skip_matrix=ii)
            unfolded = tl.unfold(tensor_3d, ii)

            # If we are at the coupled mode, concat the matrix
            if ii == 0:
                kr = tl.concatenate((kr, V), axis=0)
                unfolded = tl.concatenate((unfolded, matrix), axis=1)

            tensor_cp.factors[ii] = tl.transpose(
                tl.lstsq(kr, tl.transpose(unfolded))[0])

        error_new = tl.norm(tensor_3d - cp_to_tensor(tensor_cp))**2 + tl.norm(
            matrix - cp_to_tensor((None, [tensor_cp.factors[0], V])))**2

        if iteration > 0 and (tl.abs(error_new - error_old) / error_old <= 1e-8
                              or error_new < 1e-5):
            break
        error_old = error_new
        rec_errors.append(error_new)

    matrix_pred = CPTensor((None, [tensor_cp.factors[0], V]))

    if normalize_factors:
        tensor_cp = cp_normalize(tensor_cp)
        matrix_pred = cp_normalize(matrix_pred)

    return tensor_cp, matrix_pred, rec_errors