import torch


def loc2bbox(bbox_a, loc):
	""" compute bounding boxes from offsets and scales

	Args:
		bbox_a: (R, 4) contains (x1, y1, x2, y2)
		loc: (R, 4) contains (tx, ty, tw, th)

	Returns:
		(R, 4)
	"""
	assert bbox_a.size(1) == loc.size(1) == 4 and bbox_a.size(0) == loc.size(0)

	w_a = bbox_a[:, 2] - bbox_a[:, 0]
	h_a = bbox_a[:, 3] - bbox_a[:, 1]
	ctr_x_a = bbox_a[:, 0] + 0.5 * w_a
	ctr_y_a = bbox_a[:, 1] + 0.5 * h_a

	w = w_a * torch.exp(loc[:, 2])
	h = h_a * torch.exp(loc[:, 3])
	ctr_x = w_a * loc[:, 0] + ctr_x_a
	ctr_y = h_a * loc[:, 1] + ctr_y_a

	bbox = torch.zeros_like(bbox_a)
	bbox[:, 0] = ctr_x - 0.5 * w
	bbox[:, 1] = ctr_y - 0.5 * h
	bbox[:, 2] = ctr_x + 0.5 * w
	bbox[:, 3] = ctr_y + 0.5 * h

	return bbox