import torch


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

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

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

	Ph = (bbox_P[:, 2] - bbox_P[:, 0])
	Pw = (bbox_P[:, 3] - bbox_P[:, 1])
	ctr_Py = bbox_P[:, 0] + 0.5 * Ph
	ctr_Px = bbox_P[:, 1] + 0.5 * Pw

	Gh = Ph * torch.exp(loc[:, 2])
	Gw = Pw * torch.exp(loc[:, 3])
	ctr_Gy = Ph * loc[:, 1] + ctr_Py
	ctr_Gx = Pw * loc[:, 0] + ctr_Px

	bbox_G = torch.zeros_like(bbox_P)
	bbox_G[:, 0] = ctr_Gy - 0.5 * Gh
	bbox_G[:, 1] = ctr_Gx - 0.5 * Gw
	bbox_G[:, 2] = ctr_Gy + 0.5 * Gh
	bbox_G[:, 3] = ctr_Gx + 0.5 * Gw

	return bbox_G