r""" Compute objective value and gradients of dual objective. Parameters ---------- alpha: array, shape = len(a) beta: array, shape = len(b) Current iterate of dual potentials. a: array, shape = len(a) b: array, shape = len(b) Input histograms (should be
(alpha, beta, a, b, C, regul)
| 258 | |
| 259 | |
| 260 | def dual_obj_grad(alpha, beta, a, b, C, regul): |
| 261 | r""" |
| 262 | Compute objective value and gradients of dual objective. |
| 263 | |
| 264 | Parameters |
| 265 | ---------- |
| 266 | alpha: array, shape = len(a) |
| 267 | beta: array, shape = len(b) |
| 268 | Current iterate of dual potentials. |
| 269 | a: array, shape = len(a) |
| 270 | b: array, shape = len(b) |
| 271 | Input histograms (should be non-negative and sum to 1). |
| 272 | C: array, shape = (len(a), len(b)) |
| 273 | Ground cost matrix. |
| 274 | regul: Regularization object |
| 275 | Should implement a `delta_Omega(X)` method. |
| 276 | |
| 277 | Returns |
| 278 | ------- |
| 279 | obj: float |
| 280 | Objective value (higher is better). |
| 281 | grad_alpha: array, shape = len(a) |
| 282 | Gradient w.r.t. `alpha`. |
| 283 | grad_beta: array, shape = len(b) |
| 284 | Gradient w.r.t. `beta`. |
| 285 | """ |
| 286 | obj = np.dot(alpha, a) + np.dot(beta, b) |
| 287 | grad_alpha = a.copy() |
| 288 | grad_beta = b.copy() |
| 289 | |
| 290 | # X[:, j] = alpha + beta[j] - C[:, j] |
| 291 | X = alpha[:, np.newaxis] + beta - C |
| 292 | |
| 293 | # val.shape = len(b) |
| 294 | # G.shape = len(a) x len(b) |
| 295 | val, G = regul.delta_Omega(X) |
| 296 | |
| 297 | obj -= np.sum(val) |
| 298 | grad_alpha -= G.sum(axis=1) |
| 299 | grad_beta -= G.sum(axis=0) |
| 300 | |
| 301 | return obj, grad_alpha, grad_beta |
| 302 | |
| 303 | |
| 304 | def solve_dual( |
no test coverage detected