def minL_z(): z1 = z[:self.x.size].reshape(self.x.shape) z2 = z[self.x.size:].reshape(self.G.oshape) u1 = u[:self.x.size].reshape(self.x.shape) u2 = u[self.x.size:].reshape(self.G.oshape) if self.z is None: x_u1 = self.rho * (self.x + u1) else: x_u1 = self.rho * (self.x + u1) + self.lamda * self.z x_u1 /= (self.rho + self.lamda) LinearLeastSquares(self.A, self.y, z1, lamda=self.lamda + self.rho, z=x_u1, P=self.P, max_iter=self.max_cg_iter, show_pbar=self.show_pbar, leave_pbar=False).run() if self.proxg is None: backend.copyto(z2, self.G(self.x) + u2) else: backend.copyto(z2, self.proxg(1 / self.rho, self.G(self.x) + u2))
def _update(self): y = self.A(self.x) device = backend.get_device(y) xp = device.xp with device: self.max_eig = util.asscalar(xp.linalg.norm(y)) backend.copyto(self.x, y / self.max_eig)
def _update(self): y = self.A(self.x) device = backend.get_device(y) xp = device.xp with device: if self.norm_func is None: self.max_eig = xp.linalg.norm(y).item() else: self.max_eig = self.norm_func(y) backend.copyto(self.x, y / self.max_eig)
def _update(self): self.minL(self.mu) if self.g is not None: device = backend.get_device(self.u) xp = device.xp with device: util.axpy(self.u, self.mu, self.g(self.x)) backend.copyto(self.u, xp.clip(self.u, 0, np.infty)) if self.h is not None: util.axpy(self.v, self.mu, self.h(self.x))
def _update(self): backend.copyto(self.u_old, self.u) backend.copyto(self.x_old, self.x) # Update dual. delta_u = self.A(self.x_ext) util.axpy(self.u, self.sigma, delta_u) backend.copyto(self.u, self.proxfc(self.sigma, self.u)) # Update primal. with self.x_device: delta_x = self.AH(self.u) if self.gradh is not None: delta_x += self.gradh(self.x) util.axpy(self.x, -self.tau, delta_x) backend.copyto(self.x, self.proxg(self.tau, self.x)) # Update step-size if neccessary. if self.gamma_primal > 0 and self.gamma_dual == 0: with self.x_device: xp = self.x_device.xp theta = 1 / ( 1 + 2 * self.gamma_primal * xp.amin(xp.abs(self.tau)))**0.5 self.tau *= theta with self.u_device: self.sigma /= theta elif self.gamma_primal == 0 and self.gamma_dual > 0: with self.u_device: xp = self.u_device.xp theta = 1 / ( 1 + 2 * self.gamma_dual * xp.amin(xp.abs(self.sigma)))**0.5 self.sigma *= theta with self.x_device: self.tau /= theta else: theta = self.theta # Extrapolate primal. with self.x_device: xp = self.x_device.xp x_diff = self.x - self.x_old backend.copyto(self.x_ext, self.x + theta * x_diff) x_diff_norm = xp.linalg.norm(x_diff / self.tau**0.5).item() with self.u_device: xp = self.u_device.xp u_diff = self.u - self.u_old u_diff_norm = xp.linalg.norm(u_diff / self.sigma**0.5).item() self.resid = x_diff_norm**2 + u_diff_norm**2
def _update(self): with self.device: if self.accelerate or self.proxg is not None: backend.copyto(self.x_old, self.x) if self.accelerate: backend.copyto(self.x, self.z) gradf_x = self.gradf(self.x) util.axpy(self.x, -self.alpha, gradf_x) if self.proxg is not None: backend.copyto(self.x, self.proxg(self.alpha, self.x)) if self.accelerate: t_old = self.t self.t = (1 + (1 + 4 * t_old**2)**0.5) / 2 backend.copyto( self.z, self.x + (t_old - 1) / self.t * (self.x - self.x_old)) xp = self.device.xp if self.accelerate or self.proxg is not None: self.resid = util.asscalar( xp.linalg.norm((self.x - self.x_old) / self.alpha**0.5)) else: self.resid = util.asscalar(xp.linalg.norm(gradf_x))
def _update(self): device = backend.get_device(self.x) xp = device.xp with device: gradf_x = self.gradf(self.x) p = -self.inv_hessf(self.x)(gradf_x) self.lamda2 = util.asscalar(-xp.real(xp.vdot(p, gradf_x))) if self.lamda2 < 0: raise ValueError('Hessian is not positive semi-definite. ' 'inv_hessf might not be defined correctly.') x_new = self.x + p if self.beta < 1: fx = self.f(self.x) alpha = 1 while self.f(x_new) > fx - alpha / 2 * self.lamda2: alpha *= self.beta x_new = self.x + alpha * p backend.copyto(self.x, x_new) self.residual = self.lamda2**0.5
def minL_v(): if self.G is None: backend.copyto(v, self.x + u) else: backend.copyto(v, self.G(self.x) + u) if self.proxg is not None: backend.copyto(v, self.proxg(1 / self.rho, v))
def _update(self): device = backend.get_device(self.x) xp = device.xp with device: gradf_x = self.gradf(self.x) p = -self.inv_hessf(self.x)(gradf_x) self.lamda2 = -xp.real(xp.vdot(p, gradf_x)).item() if self.lamda2 < 0: raise ValueError( 'Direction is not descending. Got lamda2={}. ' 'inv_hessf might not be defined correctly.'.format( self.lamda2)) x_new = self.x + p if self.beta < 1: fx = self.f(self.x) alpha = 1 while self.f(x_new) > fx - alpha / 2 * self.lamda2: alpha *= self.beta x_new = self.x + alpha * p backend.copyto(self.x, x_new) self.residual = self.lamda2**0.5
def _update(self): xp = self.device.xp with self.device: x_old = self.x.copy() if self.accelerate: backend.copyto(self.x, self.z) # Perform update util.axpy(self.x, -self.alpha, self.gradf(self.x)) if self.proxg is not None: backend.copyto(self.x, self.proxg(self.alpha, self.x)) if self.accelerate: t_old = self.t self.t = (1 + (1 + 4 * t_old**2)**0.5) / 2 backend.copyto( self.z, self.x + ((t_old - 1) / self.t) * (self.x - x_old)) self.resid = xp.linalg.norm(self.x - x_old).item() / self.alpha
def _update(self): x_old = self.x.copy() # Update dual. util.axpy(self.u, self.sigma, self.A(self.x_ext)) backend.copyto(self.u, self.proxfc(self.sigma, self.u)) # Update primal. with self.x_device: util.axpy(self.x, -self.tau, self.AH(self.u)) backend.copyto(self.x, self.proxg(self.tau, self.x)) # Update step-size if neccessary. if self.gamma_primal > 0 and self.gamma_dual == 0: with self.x_device: xp = self.x_device.xp theta = 1 / (1 + 2 * self.gamma_primal * self.tau_min)**0.5 self.tau *= theta self.tau_min *= theta with self.u_device: self.sigma /= theta elif self.gamma_primal == 0 and self.gamma_dual > 0: with self.u_device: xp = self.u_device.xp theta = 1 / (1 + 2 * self.gamma_dual * self.sigma_min)**0.5 self.sigma *= theta self.sigma_min *= theta with self.x_device: self.tau /= theta else: theta = self.theta # Extrapolate primal. with self.x_device: xp = self.x_device.xp x_diff = self.x - x_old self.resid = xp.linalg.norm(x_diff / self.tau**0.5).item() backend.copyto(self.x_ext, self.x + theta * x_diff)
def _update(self): xp = self.device.xp with self.device: if self.accelerate: backend.copyto(self.x, self.z) # Perform update gradf_x = self.gradf(self.x) alpha = self.alpha x_new = self.x - alpha * gradf_x if self.proxg is not None: x_new = self.proxg(alpha, x_new) delta_x = x_new - self.x # Backtracking line search if self.beta < 1: fx = self.f(self.x) while self.f(x_new) > fx + util.asscalar( xp.real(xp.vdot(delta_x, gradf_x))) + \ 1 / (2 * alpha) * util.asscalar( xp.linalg.norm(delta_x))**2: alpha *= self.beta x_new = self.x - alpha * gradf_x if self.proxg is not None: x_new = self.proxg(alpha, x_new) delta_x = x_new - self.x backend.copyto(self.x, x_new) if self.accelerate: t_old = self.t self.t = (1 + (1 + 4 * t_old**2)**0.5) / 2 backend.copyto(self.z, x_new + ((t_old - 1) / self.t) * delta_x) self.resid = util.asscalar(xp.linalg.norm(delta_x / alpha))
def minL_z(): if self.proxg is None: backend.copyto(z, self.x + u) else: backend.copyto(z, self.proxg(1 / self.rho, self.x + u))
def _update(self): backend.copyto(self.x, self.proxf(self.alpha, self.x))