//  [python]
def cal_trans_weight(self, src_keypts, tgt_keypts, weight):
        # weight:[bs,L]
        corr_pos = torch.cat((src_keypts, tgt_keypts), dim=-1)  # [bs, num_corr, 4]
        bs, num_corr = corr_pos.shape[0], corr_pos.shape[1]
        k = num_corr

        #################################
        # construct the spatial consistency matrix
        #################################
        src_dist = torch.linalg.norm((src_keypts[:, :, None, :] - src_keypts[:, None, :, :]), dim=-1)
        corr_compatibility = src_dist - torch.linalg.norm((tgt_keypts[:, :, None, :] - tgt_keypts[:, None, :, :]),
                                                   dim=-1)
        corr_compatibility = torch.clamp(1.0 - corr_compatibility ** 2 / self.sigma_spat ** 2, min=0)  # bs,L,l

        #################################
        # Power iteratation to get the inlier probability
        #################################
        corr_compatibility[:, torch.arange(corr_compatibility.shape[1]), torch.arange(corr_compatibility.shape[1])] = 0

        total_weight = self.cal_leading_eigenvector(corr_compatibility, method='power')

        total_weight = total_weight.view([bs, k]) * weight
        total_weight = total_weight / (torch.sum(total_weight, dim=-1, keepdim=True) + 1e-6)
        #################################
        # calculate the transformation by weighted least-squares for each subsets in parallel
        #################################
        total_weight = total_weight.view([-1, k])

        src_knn, tgt_knn = src_keypts.view([-1, k, 2]), tgt_keypts.view([-1, k, 2])
        seed_as_center = False

        if seed_as_center:
            assert ("Not codes!")
        else:
            # not use seeds as neighborhood centers.
            seedwise_trans = self.rigid_transform_2d(src_knn, tgt_knn, total_weight)
            seedwise_trans = seedwise_trans.view([bs, 3, 3])

        #################################
        # calculate the inlier number for each hypothesis, and find the best transformation for each point cloud pair
        #################################
        pred_position = torch.einsum('bnm,bmk->bnk', seedwise_trans[:, :2, :2],
                                     src_keypts.permute(0, 2, 1)) + seedwise_trans[:, :2, 2:3]  # [bs, num_corr, 3]
        pred_position_z = torch.einsum('bnm,bmk->bnk', seedwise_trans[:, 2:3, :2],
                                       src_keypts.permute(0, 2, 1)) + seedwise_trans[:, 2:3, 2:3]  # [bs, num_corr, 3]
        pred_position = pred_position / pred_position_z

        pred_position = pred_position.permute(0, 2, 1)
        L2_dis = torch.linalg.norm(pred_position - tgt_keypts[:, :, :], dim=-1)  # [bs, num_corr]
        seedwise_fitness = torch.mean((L2_dis < self.inlier_threshold).float(), dim=-1)  # [bs, 1]
        # seedwise_inlier_rmse = torch.sum(L2_dis * (L2_dis < config.inlier_threshold).float(), dim=1)
        batch_best_guess = seedwise_fitness

        # refine the pose by using all the inlier correspondences (done in the post-refinement step)
        final_trans = seedwise_trans
        final_labels = (L2_dis < self.inlier_threshold).float()

        return final_trans, final_labels