def announce(self,iterator): x = iterator.get_primal_vector() y = iterator.get_dual_vector() (N,) = x.shape if self.k: K = self.k else: K = np.sqrt(N) (P,ip_term,y_term,x_term) = potential(x,y,K) print 'Potential {0:.3g} at iteration {1} ({2:.3g} {3:.3g} {4:.3g})'\ .format(P,iterator.get_iteration(), ip_term, x_term, y_term)
def announce(self,iterator): x = iterator.get_primal_vector() y = iterator.get_dual_vector() (N,) = x.shape if self.k: K = self.k else: K = np.sqrt(N) (P,ip_term,y_term,x_term) = potential(x,y,K) diff = np.abs(self.old_P - P) self.old_P = P print 'Potential change {0:.3g} at iteration {1}'\ .format(diff,iterator.get_iteration())
def next_iteration(self): """Interior point solver based on Kojima et al's "A Unified Approach to Interior Point Algorithms for lcp_objs" Uses a log-barrier w/centering parameter (How is this different than the basic scheme a la Nocedal and Wright?) """ M = self.lcp.M q = self.lcp.q n = self.lcp.dim x = self.x y = self.y self.data['x'].append(x) self.data['y'].append(y) (N,) = x.shape S = x+y print 'min(S):',np.min(S) print 'max(S):',np.max(S) print 'log ratio:', np.log10(np.max(S) / np.min(S)) print 'argmin(S)',np.argmin(S) print 'argmax(S)',np.argmax(S) (P,ip_term,x_term,y_term) = potential(x,y,np.sqrt(N)) #self.data['P'].append(P) sigma = self.sigma r = (M.dot(x) + q) - y print "Residual norm",np.linalg.norm(r) dot = x.dot(y) #self.data['res_norm'].append(np.linalg.norm(r)) print 'IP/N', dot / float(N) self.data['ip'].append(dot / float(N)) # Set up Newton direction equations X = sps.diags(x,0) Y = sps.diags(y,0) I = sps.eye(n) A = sps.bmat([[Y,X], [-M,I]],format='csc') b = np.concatenate([sigma * dot / float(n) * np.ones(n) - x*y, r]) #unarch = Unarchiver("cdiscrete/test.sys") #print "A error: ", np.linalg.norm(A.toarray() - unarch.G.toarray()) #print "b error: ", np.linalg.norm(b - unarch.h) Del = sps.linalg.spsolve(A,b) dir_x = Del[:n] dir_y = Del[n:] print '||dx||:',np.linalg.norm(dir_x) print '||dy||:',np.linalg.norm(dir_y) self.data['dx'].append(dir_x) self.data['dy'].append(dir_y) steplen = steplen_heuristic(x,dir_x,y,dir_y,0.9) print 'Steplen', steplen self.data['steplen'].append(steplen) self.steplen = steplen sigma = sigma_heuristic(sigma,steplen) print 'sigma:',sigma self.data['sigma'].append(sigma) self.sigma = sigma self.x = x + steplen * dir_x self.y = y + steplen * dir_y self.dir_x = dir_x self.dir_y = dir_y self.iteration += 1