Commit 6e71f1e8 by Martin Reinecke

### more descriptive interface for LineEnergy

parent 12a5a3ac
Pipeline #15149 passed with stage
in 6 minutes and 36 seconds
 ... ... @@ -25,12 +25,12 @@ class LineEnergy: Parameters ---------- linepos : float line_position : float Defines the full spatial position of this energy via self.energy.position = zero_point + linepos*line_direction self.energy.position = zero_point + line_position*line_direction energy : Energy The Energy object which will be evaluated along the given direction. linedir : Field line_direction : Field Direction used for line evaluation. Does not have to be normalized. offset : float *optional* Indirectly defines the zero point of the line via the equation ... ... @@ -39,13 +39,13 @@ class LineEnergy: Attributes ---------- linepos : float line_position : float The position along the given line direction relative to the zero point. value : float The value of the energy functional at the given position dd : float directional_derivative : float The directional derivative at the given position linedir : Field line_direction : Field Direction along which the movement is restricted. Does not have to be normalized. energy : Energy ... ... @@ -67,19 +67,20 @@ class LineEnergy: """ def __init__(self, linepos, energy, linedir, offset=0.): self._linepos = float(linepos) self._linedir = linedir def __init__(self, line_position, energy, line_direction, offset=0.): self._line_position = float(line_position) self._line_direction = line_direction pos = energy.position + (self._linepos-float(offset))*self._linedir pos = energy.position \ + (self._line_position-float(offset))*self._line_direction self.energy = energy.at(position=pos) def at(self, linepos): def at(self, line_position): """ Returns LineEnergy at new position, memorizing the zero point. Parameters ---------- linepos : float line_position : float Parameter for the new position on the line direction. Returns ... ... @@ -88,27 +89,27 @@ class LineEnergy: """ return self.__class__(linepos, return self.__class__(line_position, self.energy, self.linedir, offset=self.linepos) self.line_direction, offset=self.line_position) @property def value(self): return self.energy.value @property def linepos(self): return self._linepos def line_position(self): return self._line_position @property def linedir(self): return self._linedir def line_direction(self): return self._line_direction @property def dd(self): res = self.energy.gradient.vdot(self.linedir) if abs(res.imag)/max(abs(res.real),1.)>1e-12: print "directional derivative has non-negligible " \ "imaginary part:", res def directional_derivative(self): res = self.energy.gradient.vdot(self.line_direction) if abs(res.imag) / max(abs(res.real), 1.) > 1e-12: print "directional derivative has non-negligible " \ "imaginary part:", res return res.real
 ... ... @@ -162,7 +162,6 @@ class DescentMinimizer(Loggable, object): tx1=energy.position-new_energy.position # check if new energy value is bigger than old energy value if (new_energy.value - energy.value) > 0: print "Line search algorithm returned a new energy that was larger than the old one. Stopping." self.logger.info("Line search algorithm returned a new energy " "that was larger than the old one. Stopping.") break ... ...
 ... ... @@ -63,9 +63,9 @@ class LineSearch(Loggable, object): iteration of the line search procedure. (Default: None) """ self.line_energy = LineEnergy(linepos=0., self.line_energy = LineEnergy(line_position=0., energy=energy, linedir=pk) line_direction=pk) if f_k_minus_1 is not None: f_k_minus_1 = f_k_minus_1.copy() self.f_k_minus_1 = f_k_minus_1 ... ...
 ... ... @@ -110,7 +110,7 @@ class LineSearchStrongWolfe(LineSearch): old_phi_0 = self.f_k_minus_1 le_0 = self.line_energy.at(0) phi_0 = le_0.value phiprime_0 = le_0.dd phiprime_0 = le_0.directional_derivative assert phiprime_0<0, "input direction must be a descent direction" # set alphas ... ... @@ -141,7 +141,6 @@ class LineSearchStrongWolfe(LineSearch): if (phi_alpha1 > phi_0 + self.c1*alpha1*phiprime_0) or \ ((phi_alpha1 >= phi_alpha0) and (i > 0)): print "zoom1:",i (alpha_star, phi_star, le_star) = self._zoom( alpha0, alpha1, phi_0, phiprime_0, ... ... @@ -150,7 +149,7 @@ class LineSearchStrongWolfe(LineSearch): phi_alpha1) break phiprime_alpha1 = le_alpha1.dd phiprime_alpha1 = le_alpha1.directional_derivative if abs(phiprime_alpha1) <= -self.c2*phiprime_0: alpha_star = alpha1 phi_star = phi_alpha1 ... ... @@ -158,7 +157,6 @@ class LineSearchStrongWolfe(LineSearch): break if phiprime_alpha1 >= 0: print "zoom2:",i (alpha_star, phi_star, le_star) = self._zoom( alpha1, alpha0, phi_0, phiprime_0, ... ... @@ -241,11 +239,9 @@ class LineSearchStrongWolfe(LineSearch): #phi_recent = None assert phi_lo <= phi_0 + self.c1*alpha_lo*phiprime_0 assert phiprime_lo*(alpha_hi-alpha_lo)<0. print "enter:" for i in xrange(max_iterations): #assert phi_lo <= phi_0 + self.c1*alpha_lo*phiprime_0 #assert phiprime_lo*(alpha_hi-alpha_lo)<0. # print alpha_lo, alpha_hi delta_alpha = alpha_hi - alpha_lo alpha_j = alpha_lo + 0.5*delta_alpha ... ... @@ -255,18 +251,11 @@ class LineSearchStrongWolfe(LineSearch): # If the first Wolfe condition is not met replace alpha_hi # by alpha_j # print "W1:", phi_alphaj, phi_0 + self.c1*alpha_j*phiprime_0 print alpha_lo, phi_lo print alpha_hi, phi_hi # print phi_lo, phi_hi, phi_alphaj # print phiprime_lo, phiprime_alphaj if (phi_alphaj > phi_0 + self.c1*alpha_j*phiprime_0) or\ (phi_alphaj >= phi_lo): # print "beep" alpha_hi, phi_hi = alpha_j, phi_alphaj else: # print "boop" phiprime_alphaj = le_alphaj.dd phiprime_alphaj = le_alphaj.directional_derivative # If the second Wolfe condition is met, return the result if abs(phiprime_alphaj) <= -self.c2*phiprime_0: alpha_star = alpha_j ... ...
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!