Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
ift
NIFTy
Commits
fd1af103
Commit
fd1af103
authored
Jul 13, 2017
by
Martin Reinecke
Browse files
intermediate
parent
7c50e35f
Changes
6
Hide whitespace changes
Inline
Side-by-side
demos/critical_filtering.py
View file @
fd1af103
...
...
@@ -102,8 +102,8 @@ if __name__ == "__main__":
data_power
=
log
(
fft
(
d
).
power_analyze
(
logarithmic
=
p_space
.
config
[
"logarithmic"
],
nbin
=
p_space
.
config
[
"nbin"
]))
d_data
=
d
.
val
.
get_full_data
().
real
if
rank
==
0
:
pl
.
plot
([
go
.
Heatmap
(
z
=
d_data
)],
filename
=
'data.html'
)
#
if rank == 0:
#
pl.plot([go.Heatmap(z=d_data)], filename='data.html')
# minimization strategy
...
...
@@ -150,7 +150,7 @@ if __name__ == "__main__":
# Plotting current estimate
print
i
if
i
%
50
==
0
:
plot_parameters
(
m0
,
t0
,
log
(
sp
),
data_power
)
#
if i%50 == 0:
#
plot_parameters(m0,t0,log(sp), data_power)
nifty/energies/line_energy.py
View file @
fd1af103
...
...
@@ -16,10 +16,8 @@
# NIFTy is being developed at the Max-Planck-Institut fuer Astrophysik
# and financially supported by the Studienstiftung des deutschen Volkes.
from
.energy
import
Energy
class
LineEnergy
(
Energy
):
class
LineEnergy
:
""" Evaluates an underlying Energy along a certain line direction.
Given an Energy class and a line direction, its position is parametrized by
...
...
@@ -27,34 +25,31 @@ class LineEnergy(Energy):
Parameters
----------
position : float
The step length parameter along the given line direction.
linepos : float
Defines the full spatial position of this energy via
self.energy.position = zero_point + linepos*line_direction
energy : Energy
The Energy object which will be evaluated along the given direction.
line
_
dir
ection
: Field
Direction used for line evaluation.
zero_point : Field
*optional*
Fixing
the zero point of the line
restriction. Used to memorize this
position
in new initializations. By the default the current posi
tion
of the supplied `energy` instance is used
(default :
None
).
linedir : 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
energy.
position
= zero_point + offset*line_direc
tion
(default :
0.
).
Attributes
----------
position
: float
linepos
: float
The position along the given line direction relative to the zero point.
value : float
The value of the energy functional at given `position`.
gradient : float
The gradient of the underlying energy instance along the line direction
projected on the line direction.
curvature : callable
A positive semi-definite operator or function describing the curvature
of the potential at given `position`.
line_direction : Field
The value of the energy functional at the given position
dd : float
The directional derivative at the given position
linedir : Field
Direction along which the movement is restricted. Does not have to be
normalized.
energy : Energy
The underlying Energy at the
`position` along the line direc
tion
.
The underlying Energy at the
given posi
tion
Raises
------
...
...
@@ -72,45 +67,44 @@ class LineEnergy(Energy):
"""
def
__init__
(
self
,
position
,
energy
,
line_direction
,
zero_point
=
None
):
super
(
LineEnergy
,
self
).
__init__
(
position
=
position
)
self
.
line_direction
=
line_direction
if
zero_point
is
None
:
zero_point
=
energy
.
position
self
.
_zero_point
=
zero_point
def
__init__
(
self
,
linepos
,
energy
,
linedir
,
offset
=
0.
):
self
.
_linepos
=
float
(
linepos
)
self
.
_linedir
=
linedir
pos
ition_on_line
=
self
.
_zero_point
+
self
.
position
*
line
_
dir
ection
self
.
energy
=
energy
.
at
(
position
=
pos
ition_on_line
)
pos
=
energy
.
position
+
(
self
.
_linepos
-
float
(
offset
))
*
self
.
_
linedir
self
.
energy
=
energy
.
at
(
position
=
pos
)
def
at
(
self
,
position
):
def
at
(
self
,
linepos
):
""" Returns LineEnergy at new position, memorizing the zero point.
Parameters
----------
position
: float
linepos
: float
Parameter for the new position on the line direction.
Returns
-------
out : LineEnergy
LineEnergy object at new position with same zero point as `self`.
"""
return
self
.
__class__
(
position
,
return
self
.
__class__
(
linepos
,
self
.
energy
,
self
.
line
_
dir
ection
,
zero_point
=
self
.
_zero_point
)
self
.
linedir
,
offset
=
self
.
linepos
)
@
property
def
value
(
self
):
return
self
.
energy
.
value
@
property
def
gradient
(
self
):
return
self
.
energy
.
gradient
.
vdot
(
self
.
line_direction
)
def
linepos
(
self
):
return
self
.
_linepos
@
property
def
linedir
(
self
):
return
self
.
_linedir
@
property
def
curvature
(
self
):
return
self
.
energy
.
curvature
def
dd
(
self
):
return
self
.
energy
.
gradient
.
vdot
(
self
.
linedir
)
nifty/field.py
View file @
fd1af103
...
...
@@ -181,7 +181,7 @@ class Field(Loggable, Versionable, object):
elif
isinstance
(
val
,
Field
):
distribution_strategy
=
val
.
distribution_strategy
else
:
self
.
logger
.
debug
(
"distribution_strategy set to default!"
)
#
self.logger.debug("distribution_strategy set to default!")
distribution_strategy
=
gc
[
'default_distribution_strategy'
]
elif
distribution_strategy
not
in
DISTRIBUTION_STRATEGIES
[
'global'
]:
raise
ValueError
(
...
...
nifty/minimization/descent_minimizer.py
View file @
fd1af103
...
...
@@ -121,12 +121,18 @@ class DescentMinimizer(Loggable, object):
"""
print
"into line search:"
print
" pos: "
,
energy
.
position
.
val
[
0
]
print
" ene: "
,
energy
.
value
convergence
=
0
f_k_minus_1
=
None
step_length
=
0
iteration_number
=
1
while
True
:
print
"line search next iteration:"
print
" pos: "
,
energy
.
position
.
val
[
0
]
print
" ene: "
,
energy
.
value
if
self
.
callback
is
not
None
:
try
:
self
.
callback
(
energy
,
iteration_number
)
...
...
@@ -147,7 +153,7 @@ class DescentMinimizer(Loggable, object):
# current position is encoded in energy object
descent_direction
=
self
.
get_descent_direction
(
energy
)
print
"descent direction:"
,
descent_direction
.
val
[
0
]
# compute the step length, which minimizes energy.value along the
# search direction
step_length
,
f_k
,
new_energy
=
\
...
...
@@ -155,10 +161,20 @@ class DescentMinimizer(Loggable, object):
energy
=
energy
,
pk
=
descent_direction
,
f_k_minus_1
=
f_k_minus_1
)
print
"out of wolfe:"
print
" old pos: "
,
energy
.
position
.
val
[
0
]
print
" old ene: "
,
energy
.
value
print
" new pos: "
,
new_energy
.
position
.
val
[
0
]
print
" new ene: "
,
new_energy
.
value
print
" f_k: "
,
f_k
f_k_minus_1
=
energy
.
value
print
" step length: "
,
step_length
tx1
=
energy
.
position
-
new_energy
.
position
print
" step length 2: "
,
(
energy
.
position
-
new_energy
.
position
).
norm
()
print
" step length 3: "
,
new_energy
.
position
.
val
[
0
]
-
energy
.
position
.
val
[
0
]
# 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
...
...
nifty/minimization/line_searching/line_search.py
View file @
fd1af103
...
...
@@ -66,9 +66,9 @@ class LineSearch(Loggable, object):
iteration of the line search procedure. (Default: None)
"""
self
.
line_energy
=
LineEnergy
(
position
=
0.
,
self
.
line_energy
=
LineEnergy
(
linepos
=
0.
,
energy
=
energy
,
line
_
dir
ection
=
pk
)
linedir
=
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
...
...
nifty/minimization/line_searching/line_search_strong_wolfe.py
View file @
fd1af103
...
...
@@ -103,16 +103,14 @@ class LineSearchStrongWolfe(LineSearch):
"""
self
.
_set_line_energy
(
energy
,
pk
,
f_k_minus_1
=
f_k_minus_1
)
c1
=
self
.
c1
c2
=
self
.
c2
max_step_size
=
self
.
max_step_size
max_iterations
=
self
.
max_iterations
# initialize the zero phis
old_phi_0
=
self
.
f_k_minus_1
e
nergy
_0
=
self
.
line_energy
.
at
(
0
)
phi_0
=
e
nergy
_0
.
value
phiprime_0
=
energy_0
.
gradient
l
e_0
=
self
.
line_energy
.
at
(
0
)
phi_0
=
l
e_0
.
value
phiprime_0
=
le_0
.
dd
if
phiprime_0
==
0
:
self
.
logger
.
warn
(
"Flat gradient in search direction."
)
...
...
@@ -135,45 +133,52 @@ class LineSearchStrongWolfe(LineSearch):
# start the minimization loop
for
i
in
xrange
(
max_iterations
):
energy_alpha1
=
self
.
line_energy
.
at
(
alpha1
)
phi_alpha1
=
energy_alpha1
.
value
print
"a0a1:"
,
alpha0
,
alpha1
print
"line search outer iteration"
,
i
le_alpha1
=
self
.
line_energy
.
at
(
alpha1
)
print
"position:"
,
le_alpha1
.
energy
.
position
.
val
[
0
]
phi_alpha1
=
le_alpha1
.
value
print
"energy:"
,
le_alpha1
.
value
if
alpha1
==
0
:
self
.
logger
.
warn
(
"Increment size became 0."
)
alpha_star
=
0.
phi_star
=
phi_0
e
nergy
_star
=
e
nergy
_0
l
e_star
=
l
e_0
break
if
(
phi_alpha1
>
phi_0
+
c1
*
alpha1
*
phiprime_0
)
or
\
if
(
phi_alpha1
>
phi_0
+
self
.
c1
*
alpha1
*
phiprime_0
)
or
\
((
phi_alpha1
>=
phi_alpha0
)
and
(
i
>
1
)):
(
alpha_star
,
phi_star
,
e
nergy
_star
)
=
self
.
_zoom
(
(
alpha_star
,
phi_star
,
l
e_star
)
=
self
.
_zoom
(
alpha0
,
alpha1
,
phi_0
,
phiprime_0
,
phi_alpha0
,
phiprime_alpha0
,
phi_alpha1
,
c1
,
c2
)
phi_alpha1
)
break
phiprime_alpha1
=
e
nergy
_alpha1
.
gradient
if
abs
(
phiprime_alpha1
)
<=
-
c2
*
phiprime_0
:
phiprime_alpha1
=
l
e_alpha1
.
dd
if
abs
(
phiprime_alpha1
)
<=
-
self
.
c2
*
phiprime_0
:
alpha_star
=
alpha1
phi_star
=
phi_alpha1
e
nergy
_star
=
e
nergy
_alpha1
l
e_star
=
l
e_alpha1
break
if
phiprime_alpha1
>=
0
:
(
alpha_star
,
phi_star
,
e
nergy
_star
)
=
self
.
_zoom
(
(
alpha_star
,
phi_star
,
l
e_star
)
=
self
.
_zoom
(
alpha1
,
alpha0
,
phi_0
,
phiprime_0
,
phi_alpha1
,
phiprime_alpha1
,
phi_alpha0
,
c1
,
c2
)
phi_alpha0
)
break
# update alphas
alpha0
,
alpha1
=
alpha1
,
min
(
2
*
alpha1
,
max_step_size
)
if
alpha1
==
max_step_size
:
alpha_star
=
alpha1
phi_star
=
phi_alpha1
le_star
=
le_alpha1
break
phi_alpha0
=
phi_alpha1
phiprime_alpha0
=
phiprime_alpha1
# phi_alpha1 = self._phi(alpha1)
...
...
@@ -182,17 +187,17 @@ class LineSearchStrongWolfe(LineSearch):
# max_iterations was reached
alpha_star
=
alpha1
phi_star
=
phi_alpha1
e
nergy
_star
=
e
nergy
_alpha1
l
e_star
=
l
e_alpha1
self
.
logger
.
error
(
"The line search algorithm did not converge."
)
# extract the full energy from the line_energy
energy_star
=
e
nergy
_star
.
energy
energy_star
=
l
e_star
.
energy
direction_length
=
pk
.
norm
()
step_length
=
alpha_star
*
direction_length
return
step_length
,
phi_star
,
energy_star
def
_zoom
(
self
,
alpha_lo
,
alpha_hi
,
phi_0
,
phiprime_0
,
phi_lo
,
phiprime_lo
,
phi_hi
,
c1
,
c2
):
phi_lo
,
phiprime_lo
,
phi_hi
):
"""Performs the second stage of the line search algorithm.
If the first stage was not successful then the Zoom algorithm tries to
...
...
@@ -203,7 +208,7 @@ class LineSearchStrongWolfe(LineSearch):
----------
alpha_lo : float
The lower boundary for the step length interval.
alph_hi : float
alph
a
_hi : float
The upper boundary for the step length interval.
phi_0 : float
Value of the energy at the starting point of the line search
...
...
@@ -219,10 +224,6 @@ class LineSearchStrongWolfe(LineSearch):
phi_hi : float
Value of the energy if we perform a step of length alpha_hi in
descent direction.
c1 : float
Parameter for Armijo condition rule.
c2 : float
Parameter for curvature condition rule.
Returns
-------
...
...
@@ -234,6 +235,10 @@ class LineSearchStrongWolfe(LineSearch):
The new Energy object on the new position.
"""
print
"entering zoom"
print
alpha_lo
,
alpha_hi
print
"pos1:"
,
self
.
line_energy
.
at
(
alpha_lo
).
energy
.
position
.
val
[
0
]
print
"pos2:"
,
self
.
line_energy
.
at
(
alpha_hi
).
energy
.
position
.
val
[
0
]
max_iterations
=
self
.
max_zoom_iterations
# define the cubic and quadratic interpolant checks
cubic_delta
=
0.2
# cubic
...
...
@@ -262,28 +267,28 @@ class LineSearchStrongWolfe(LineSearch):
quad_check
=
quad_delta
*
delta_alpha
alpha_j
=
self
.
_quadmin
(
alpha_lo
,
phi_lo
,
phiprime_lo
,
alpha_hi
,
phi_hi
)
# If quadratic was not successful
l
, try bisection
# If quadratic was not successful, try bisection
if
(
alpha_j
is
None
)
or
(
alpha_j
>
b
-
quad_check
)
or
\
(
alpha_j
<
a
+
quad_check
):
alpha_j
=
alpha_lo
+
0.5
*
delta_alpha
# Check if the current value of alpha_j is already sufficient
e
nergy
_alphaj
=
self
.
line_energy
.
at
(
alpha_j
)
phi_alphaj
=
e
nergy
_alphaj
.
value
l
e_alphaj
=
self
.
line_energy
.
at
(
alpha_j
)
phi_alphaj
=
l
e_alphaj
.
value
# If the first Wolfe condition is not met replace alpha_hi
# by alpha_j
if
(
phi_alphaj
>
phi_0
+
c1
*
alpha_j
*
phiprime_0
)
or
\
if
(
phi_alphaj
>
phi_0
+
self
.
c1
*
alpha_j
*
phiprime_0
)
or
\
(
phi_alphaj
>=
phi_lo
):
alpha_recent
,
phi_recent
=
alpha_hi
,
phi_hi
alpha_hi
,
phi_hi
=
alpha_j
,
phi_alphaj
else
:
phiprime_alphaj
=
e
nergy
_alphaj
.
gradient
phiprime_alphaj
=
l
e_alphaj
.
dd
# If the second Wolfe condition is met, return the result
if
abs
(
phiprime_alphaj
)
<=
-
c2
*
phiprime_0
:
if
abs
(
phiprime_alphaj
)
<=
-
self
.
c2
*
phiprime_0
:
alpha_star
=
alpha_j
phi_star
=
phi_alphaj
e
nergy
_star
=
e
nergy
_alphaj
l
e_star
=
l
e_alphaj
break
# If not, check the sign of the slope
if
phiprime_alphaj
*
delta_alpha
>=
0
:
...
...
@@ -296,12 +301,12 @@ class LineSearchStrongWolfe(LineSearch):
phiprime_alphaj
)
else
:
alpha_star
,
phi_star
,
e
nergy
_star
=
\
alpha_j
,
phi_alphaj
,
e
nergy
_alphaj
alpha_star
,
phi_star
,
l
e_star
=
\
alpha_j
,
phi_alphaj
,
l
e_alphaj
self
.
logger
.
error
(
"The line search algorithm (zoom) did not "
"converge."
)
return
alpha_star
,
phi_star
,
e
nergy
_star
return
alpha_star
,
phi_star
,
l
e_star
def
_cubicmin
(
self
,
a
,
fa
,
fpa
,
b
,
fb
,
c
,
fc
):
"""Estimating the minimum with cubic interpolation.
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment