import torch


def bbox2loc(bbox_G, bbox_P):
	""" compute offsets and scales given target and source bounding boxes.

	Args:
		bbox_G: (R, 4) contains (y1, x1, y2, x2)
		bbox_P: (R, 4) contains (y1, x1, y2, x2)

	Returns:
		(R, 4) contains (ty, tx, th, tw)
	"""
	assert bbox_G.size(1) == bbox_P.size(1) == 4 and bbox_G.size(0) == bbox_P.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 = (bbox_G[:, 2] - bbox_G[:, 0])
	Gw = (bbox_G[:, 3] - bbox_G[:, 1])
	ctr_Gy = bbox_G[:, 0] + 0.5 * Gh
	ctr_Gx = bbox_G[:, 1] + 0.5 * Gw

	tx = (ctr_Gx - ctr_Px) / Pw
	ty = (ctr_Gy - ctr_Py) / Ph
	th = torch.log(Gh / Ph)
	tw = torch.log(Gw / Pw)

	return torch.stack([ty, tx, th, tw]).transpose(0, 1)