A piecewise linear function y = f(x), using xp and yp as keypoints. We implement f(x) in a differentiable way (i.e. applicable for autograd). The function f(x) is well-defined for all x-axis. (For x beyond the bounds of xp, we use the outmost points of xp to define the linear function.)
(x, xp, yp)
| 1259 | ############################################################# |
| 1260 | |
| 1261 | def interpolate_fn(x, xp, yp): |
| 1262 | """ |
| 1263 | A piecewise linear function y = f(x), using xp and yp as keypoints. |
| 1264 | We implement f(x) in a differentiable way (i.e. applicable for autograd). |
| 1265 | The function f(x) is well-defined for all x-axis. (For x beyond the bounds of xp, we use the outmost points of xp to define the linear function.) |
| 1266 | |
| 1267 | Args: |
| 1268 | x: PyTorch tensor with shape [N, C], where N is the batch size, C is the number of channels (we use C = 1 for DPM-Solver). |
| 1269 | xp: PyTorch tensor with shape [C, K], where K is the number of keypoints. |
| 1270 | yp: PyTorch tensor with shape [C, K]. |
| 1271 | Returns: |
| 1272 | The function values f(x), with shape [N, C]. |
| 1273 | """ |
| 1274 | N, K = x.shape[0], xp.shape[1] |
| 1275 | all_x = torch.cat([x.unsqueeze(2), xp.unsqueeze(0).repeat((N, 1, 1))], dim=2) |
| 1276 | sorted_all_x, x_indices = torch.sort(all_x, dim=2) |
| 1277 | x_idx = torch.argmin(x_indices, dim=2) |
| 1278 | cand_start_idx = x_idx - 1 |
| 1279 | start_idx = torch.where( |
| 1280 | torch.eq(x_idx, 0), |
| 1281 | torch.tensor(1, device=x.device), |
| 1282 | torch.where( |
| 1283 | torch.eq(x_idx, K), torch.tensor(K - 2, device=x.device), cand_start_idx, |
| 1284 | ), |
| 1285 | ) |
| 1286 | end_idx = torch.where(torch.eq(start_idx, cand_start_idx), start_idx + 2, start_idx + 1) |
| 1287 | start_x = torch.gather(sorted_all_x, dim=2, index=start_idx.unsqueeze(2)).squeeze(2) |
| 1288 | end_x = torch.gather(sorted_all_x, dim=2, index=end_idx.unsqueeze(2)).squeeze(2) |
| 1289 | start_idx2 = torch.where( |
| 1290 | torch.eq(x_idx, 0), |
| 1291 | torch.tensor(0, device=x.device), |
| 1292 | torch.where( |
| 1293 | torch.eq(x_idx, K), torch.tensor(K - 2, device=x.device), cand_start_idx, |
| 1294 | ), |
| 1295 | ) |
| 1296 | y_positions_expanded = yp.unsqueeze(0).expand(N, -1, -1) |
| 1297 | start_y = torch.gather(y_positions_expanded, dim=2, index=start_idx2.unsqueeze(2)).squeeze(2) |
| 1298 | end_y = torch.gather(y_positions_expanded, dim=2, index=(start_idx2 + 1).unsqueeze(2)).squeeze(2) |
| 1299 | cand = start_y + (x - start_x) * (end_y - start_y) / (end_x - start_x) |
| 1300 | return cand |
| 1301 | |
| 1302 | |
| 1303 | def expand_dims(v, dims): |
no outgoing calls
no test coverage detected