import torch


def decorate_with_diffs(data, exponent, remove_raw_data=False):
    """
    L2 norm: ||x-mean||
    decorate_with_diffs 作用: 将原始数据(original data)以及 L2 norm 一起返回, 使 鉴别器 D 了解更多目标数据分布的信息

    :param data: Tensor: 张量
    :param exponent: 幂次
    :param remove_raw_data: 是否移除原始数据
    :return: torch.cat([data, diffs], dim=1), dim=0, 同型张量(Tensor)按行合并; dim=1, 同型张量(Tensor)按列合并;
    """
    # dim=0, 行; dim=1, 列; keepdim: 做 mean后, 保持原数据的维度空间, 即, 原原数据为2维, mean 后仍为2维
    mean = torch.mean(data.data, dim=1, keepdim=True)

    # 利用广播(broadcast)机制进行张量(Tensor)乘法
    mean_broadcast = torch.mul(torch.ones(data.size()), mean.tolist()[0][0])
    # data - data.mean[0]
    diffs = torch.pow(data - mean_broadcast, exponent)
    if remove_raw_data:
        return torch.cat([diffs], dim=1)
    else:
        # diffs: 返回样本数据与样本平均值的偏离程度(可以是n次方(exponent))
        # 并将样本的偏离程度信息与原始样本一同输入到神经网络中
        return torch.cat([data, diffs], dim=1)