def primal_dual_hess(self, x, z, **kwargs): """ Assemble the "primal-dual" Hessian matrix of the merit function at (x,z): [ H + 2 X^{-1} Z I ] [ I Z^{-1} X ]. """ mu = kwargs.get('mu', self.mu) nlp = self.nlp ; nx = nlp.n ; nz = self.nz Lvar = nlp.Lvar ; Uvar = nlp.Uvar lB = nlp.lowerB ; uB = nlp.upperB ; rB = nlp.rangeB nlB = nlp.nlowerB ; nuB = nlp.nupperB ; nrB = nlp.nrangeB rlB = self.rlB ; ruB = self.ruB ; rrB = self.rrB # Segment s and z for conciseness. slB = x[lB] - Lvar[lB] ; zlB = z[:nlB] suB = Uvar[uB] - x[uB] ; zuB = z[nlB:nlB+nuB] srlB = x[rB] - Lvar[rB] ; zrlB = z[nlB+nuB:nlB+nuB+nrB] sruB = Uvar[rB] - x[rB] ; zruB = z[nlB+nuB+nrB:] H = sp(nrow=nx+nz, ncol=nx+nz, sizeHint=self.nlp.nnzh+3*nz, symmetric=True) # Leading block: H + 2 * mu X^{-2}. H[:nx,:nx] = self.nlp.hess(x, self.nlp.pi0) H.addAt(2 * zlB / slB, lB, lB) H.addAt(2 * zuB / suB, uB, uB) H.addAt(2 * zrlB/srlB, rB, rB) H.addAt(2 * zruB/sruB, rB, rB) # Bottom left block: identity-ish. n1 = nx + rlB ; H.put( 1, n1, lB) n2 = nx + ruB ; H.put(-1, n2, uB) n3 = nx + rrB ; H.put( 1, n3, rB) n4 = nx + nrB + rrB ; H.put(-1, n4, rB) # Bottom right block: mu * Z^{-2}. H.put(slB / zlB, n1, n1) H.put(suB / zuB, n2, n2) H.put(srlB/zrlB, n3, n3) H.put(sruB/zruB, n4, n4) return H
def _hess_template(self, **kwargs): """ Assemble the part of the modified Hessian matrix of the primal-dual merit function that is iteration independent. """ nlp = self.nlp ; nx = nlp.n ; nz = self.nz Lvar = nlp.Lvar ; Uvar = nlp.Uvar lB = nlp.lowerB ; uB = nlp.upperB ; rB = nlp.rangeB nlB = nlp.nlowerB ; rlB = self.rlB nuB = nlp.nupperB ; ruB = self.ruB nrB = nlp.nrangeB ; rrB = self.rrB B = sp(nrow=nx+nz, ncol=nx+nz, sizeHint=self.nlp.nnzh+3*nz, symmetric=True) # Bottom left block: identity-ish. n1 = nx + rlB ; B.put( 1, n1, lB) n2 = nx + ruB ; B.put(-1, n2, uB) n3 = nx + rrB ; B.put( 1, n3, rB) n4 = nx + nrB + rrB ; B.put(-1, n4, rB) return B
def _hess_template(self, **kwargs): """ Assemble the part of the modified Hessian matrix of the primal-dual merit function that is iteration independent. """ nlp = self.nlp nx = nlp.n nz = self.nz Lvar = nlp.Lvar Uvar = nlp.Uvar lB = nlp.lowerB uB = nlp.upperB rB = nlp.rangeB nlB = nlp.nlowerB rlB = self.rlB nuB = nlp.nupperB ruB = self.ruB nrB = nlp.nrangeB rrB = self.rrB B = sp(nrow=nx + nz, ncol=nx + nz, sizeHint=self.nlp.nnzh + 3 * nz, symmetric=True) # Bottom left block: identity-ish. n1 = nx + rlB B.put(1, n1, lB) n2 = nx + ruB B.put(-1, n2, uB) n3 = nx + rrB B.put(1, n3, rB) n4 = nx + nrB + rrB B.put(-1, n4, rB) return B
def primal_dual_hess(self, x, z, **kwargs): """ Assemble the "primal-dual" Hessian matrix of the merit function at (x,z): [ H + 2 X^{-1} Z I ] [ I Z^{-1} X ]. """ mu = kwargs.get('mu', self.mu) nlp = self.nlp nx = nlp.n nz = self.nz Lvar = nlp.Lvar Uvar = nlp.Uvar lB = nlp.lowerB uB = nlp.upperB rB = nlp.rangeB nlB = nlp.nlowerB nuB = nlp.nupperB nrB = nlp.nrangeB rlB = self.rlB ruB = self.ruB rrB = self.rrB # Segment s and z for conciseness. slB = x[lB] - Lvar[lB] zlB = z[:nlB] suB = Uvar[uB] - x[uB] zuB = z[nlB:nlB + nuB] srlB = x[rB] - Lvar[rB] zrlB = z[nlB + nuB:nlB + nuB + nrB] sruB = Uvar[rB] - x[rB] zruB = z[nlB + nuB + nrB:] H = sp(nrow=nx + nz, ncol=nx + nz, sizeHint=self.nlp.nnzh + 3 * nz, symmetric=True) # Leading block: H + 2 * mu X^{-2}. H[:nx, :nx] = self.nlp.hess(x, self.nlp.pi0) H.addAt(2 * zlB / slB, lB, lB) H.addAt(2 * zuB / suB, uB, uB) H.addAt(2 * zrlB / srlB, rB, rB) H.addAt(2 * zruB / sruB, rB, rB) # Bottom left block: identity-ish. n1 = nx + rlB H.put(1, n1, lB) n2 = nx + ruB H.put(-1, n2, uB) n3 = nx + rrB H.put(1, n3, rB) n4 = nx + nrB + rrB H.put(-1, n4, rB) # Bottom right block: mu * Z^{-2}. H.put(slB / zlB, n1, n1) H.put(suB / zuB, n2, n2) H.put(srlB / zrlB, n3, n3) H.put(sruB / zruB, n4, n4) return H