//  [python]
def whiten_and_color_torch(self, cF, sF):
        # print("*" * 30 + " whiten_and_color begin")
        
        # ---------------------------------
        # svd for content feature
        cFSize = cF.size() # size: c * hw
        c_mean = torch.mean(cF, 1).unsqueeze(1).expand_as(cF)
        cF = cF - c_mean
        contentConv = torch.mm(cF, cF.t()).div(cFSize[1] - 1) # + torch.eye(cFSize[0]).double()
        # print("-" * 10 + " contentConv torch:")
        # print("convariance matrix abs sum:", np.abs(contentConv).sum().data.cpu().numpy()) # checked, same
        
        c_u, c_s, c_v = torch.linalg.svd(contentConv)
        # print("-" * 10 + " content svd torch:")
        # print("size of U, E, V:", c_u.size(), c_s.size(), c_v.size())
        # print("eigen values:", c_s.data.cpu().numpy())
        # print(np.abs(c_u).sum().data.cpu().numpy()) # checked, different
        # print(np.abs(c_s).sum().data.cpu().numpy())
        # print(np.abs(c_v).sum().data.cpu().numpy())
        
        k_c = cFSize[0]
        for i in range(cFSize[0]):
            if c_s[i] < EigenValueThre:
                k_c = i
                break
        # k_c = NumEigenValue
        # k_c = int(cFSize[0] * RatEigenValue)
        # print("k_c = %s\n" % k_c)
        
        # ---------------------------------
        # svd for style feature
        sFSize = sF.size()
        s_mean = torch.mean(sF, 1)
        sF = sF - s_mean.unsqueeze(1).expand_as(sF)
        styleConv = torch.mm(sF,sF.t()).div(sFSize[1] - 1)
        # print("-" * 10 + " styleConv torch:")
        # print("convariance matrix abs sum:", np.abs(styleConv).sum().data.cpu().numpy()) # checked, same
        
        s_u, s_s, s_v = torch.linalg.svd(styleConv);
        # print("-" * 5 + " style svd torch:")
        # print("size of U, E, V:", s_u.shape, s_s.shape, s_v.shape)
        # print("eigen values:", s_s.data.cpu().numpy())
        # print(np.abs(s_u).sum().data.cpu().numpy())
        # print(np.abs(s_s).sum().data.cpu().numpy())
        # print(np.abs(s_v).sum().data.cpu().numpy())
        
        k_s = sFSize[0]
        for i in range(sFSize[0]):
            if s_s[i] < EigenValueThre:
                k_s = i
                break
        # k_s = NumEigenValue
        # k_s = int(sFSize[0] * RatEigenValue)
        # print("k_s = %s\n" % k_s)
        
        c_d = (c_s[0:k_c]).pow(-0.5)
        step1 = torch.mm(c_v[:, 0:k_c], torch.diag(c_d))
        step2 = torch.mm(step1, (c_v[:, 0:k_c].t()))
        whiten_cF = torch.mm(step2, cF)
        # print("-" * 5 + " whiten_cF torch")
        # print("whitened content abs sum:", np.abs(whiten_cF).sum().data.cpu().numpy()) # checked, same
        
        s_d = (s_s[0:k_s]).pow(0.5)
        targetFeature = torch.mm(torch.mm(torch.mm(s_v[:, 0:k_s], torch.diag(s_d)), (s_v[:, 0:k_s].t())), whiten_cF)
        targetFeature = targetFeature + s_mean.unsqueeze(1).expand_as(targetFeature)
        # print("-" * 5 + " targetFeature torch")
        # print("stylized feature abs sum:", np.abs(targetFeature).sum().data.cpu().numpy()) # checked, different
        
        # print("*" * 30 + " whiten_and_color done\n\n")
        return targetFeature