import torch


def convert_boxes_to_locations(
    boxes: torch.Tensor,
    priors: torch.Tensor,
    center_variance: float,
    size_variance: float,
) -> torch.Tensor:
    """Convert boxes (x, y, w, h) to regressional location results of SSD

    $$hat{center} * center_variance = \frac {center - center_prior} {hw_prior}$$
    $$exp(hat{hw} * size_variance) = \frac {hw} {hw_prior}$$

    :param boxes: center form boxes
    :param priors: center form priors
    :param center_variance: changes the scale of center
    :param size_variance: changes scale of size
    :return: locations for training SSD
    """
    if priors.dim() + 1 == boxes.dim():
        priors = priors.unsqueeze(0)
    centers = (boxes[..., :2] - priors[..., :2]) / priors[..., 2:] / center_variance
    hws = torch.log(boxes[..., 2:] / priors[..., 2:]) / size_variance
    return torch.cat([centers, hws], dim=boxes.dim() - 1)