Skip to content
GitLab
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
51de4744
Commit
51de4744
authored
Jan 26, 2018
by
Philipp Arras
Browse files
Merge remote-tracking branch 'origin/NIFTy_4' into addUnits
parents
cfbb194e
7fe10569
Changes
19
Hide whitespace changes
Inline
Side-by-side
.gitlab-ci.yml
View file @
51de4744
...
@@ -17,10 +17,10 @@ test_min:
...
@@ -17,10 +17,10 @@ test_min:
stage
:
test
stage
:
test
script
:
script
:
-
pip install --user .
-
pip install --user .
-
nosetests -
x
--with-coverage --cover-package=nifty4 --cover-branches
-
nosetests -
q
--with-coverage --cover-package=nifty4 --cover-branches
-
OMP_NUM_THREADS=1 mpiexec --allow-run-as-root -n 4 nosetests -
x --with-coverage --cover-package=nifty4 --cover-branches
-
OMP_NUM_THREADS=1 mpiexec --allow-run-as-root -n 4 nosetests -
q
-
pip3 install --user .
-
pip3 install --user .
-
nosetests3 -
x
-
nosetests3 -
q
-
OMP_NUM_THREADS=1 mpiexec --allow-run-as-root -n 4 nosetests3 -
x
-
OMP_NUM_THREADS=1 mpiexec --allow-run-as-root -n 4 nosetests3 -
q
-
>
-
>
coverage report | grep TOTAL | awk '{ print "TOTAL: "$6; }'
coverage report | grep TOTAL | awk '{ print "TOTAL: "$6; }'
|| true
ci/install_basics.sh
View file @
51de4744
apt-get
install
-y
build-essential git autoconf libtool pkg-config libfftw3-dev openmpi-bin libopenmpi-dev
\
apt-get
install
-y
build-essential git autoconf libtool pkg-config libfftw3-dev openmpi-bin libopenmpi-dev
\
python python-pip python-dev python-nose python-numpy python-matplotlib python-future python-mpi4py
\
python python-pip python-dev python-nose python-numpy python-matplotlib python-future python-mpi4py
python-scipy
\
python3 python3-pip python3-dev python3-nose python3-numpy python3-matplotlib python3-future python3-mpi4py
python3 python3-pip python3-dev python3-nose python3-numpy python3-matplotlib python3-future python3-mpi4py
python3-scipy
demos/critical_filtering.py
View file @
51de4744
...
@@ -12,7 +12,7 @@ if __name__ == "__main__":
...
@@ -12,7 +12,7 @@ if __name__ == "__main__":
# Define harmonic transformation and associated harmonic space
# Define harmonic transformation and associated harmonic space
h_space
=
s_space
.
get_default_codomain
()
h_space
=
s_space
.
get_default_codomain
()
fft
=
ift
.
FFT
Operator
(
h_space
,
s_space
)
fft
=
ift
.
HarmonicTransform
Operator
(
h_space
,
s_space
)
# Set up power space
# Set up power space
p_space
=
ift
.
PowerSpace
(
h_space
,
p_space
=
ift
.
PowerSpace
(
h_space
,
...
...
demos/wiener_filter_via_curvature.py
View file @
51de4744
...
@@ -2,6 +2,7 @@ import numpy as np
...
@@ -2,6 +2,7 @@ import numpy as np
import
nifty4
as
ift
import
nifty4
as
ift
import
numericalunits
as
nu
import
numericalunits
as
nu
if
__name__
==
"__main__"
:
if
__name__
==
"__main__"
:
# In MPI mode, the random seed for numericalunits must be set by hand
# In MPI mode, the random seed for numericalunits must be set by hand
#nu.reset_units(43)
#nu.reset_units(43)
...
@@ -38,7 +39,7 @@ if __name__ == "__main__":
...
@@ -38,7 +39,7 @@ if __name__ == "__main__":
signal_space
=
ift
.
RGSpace
(
shape
,
distances
=
L
/
N_pixels
)
signal_space
=
ift
.
RGSpace
(
shape
,
distances
=
L
/
N_pixels
)
harmonic_space
=
signal_space
.
get_default_codomain
()
harmonic_space
=
signal_space
.
get_default_codomain
()
fft
=
ift
.
FFT
Operator
(
harmonic_space
,
target
=
signal_space
)
fft
=
ift
.
HarmonicTransform
Operator
(
harmonic_space
,
target
=
signal_space
)
power_space
=
ift
.
PowerSpace
(
harmonic_space
)
power_space
=
ift
.
PowerSpace
(
harmonic_space
)
# Creating the mock data
# Creating the mock data
...
@@ -48,34 +49,27 @@ if __name__ == "__main__":
...
@@ -48,34 +49,27 @@ if __name__ == "__main__":
mock_power
=
ift
.
PS_field
(
power_space
,
power_spectrum
)
mock_power
=
ift
.
PS_field
(
power_space
,
power_spectrum
)
mock_harmonic
=
ift
.
power_synthesize
(
mock_power
,
real_signal
=
True
)
mock_harmonic
=
ift
.
power_synthesize
(
mock_power
,
real_signal
=
True
)
print
mock_harmonic
.
val
[
0
]
/
nu
.
K
/
(
nu
.
m
**
dimensionality
)
mock_signal
=
fft
(
mock_harmonic
)
mock_signal
=
fft
(
mock_harmonic
)
print
"msig"
,
mock_signal
.
val
[
0
:
10
]
/
nu
.
K
sensitivity
=
(
1.
/
nu
.
m
)
**
dimensionality
/
nu
.
K
sensitivity
=
(
1.
/
nu
.
m
)
**
dimensionality
/
nu
.
K
R
=
ift
.
ResponseOperator
(
signal_space
,
sigma
=
(
0.
*
response_sigma
,),
R
=
ift
.
ResponseOperator
(
signal_space
,
sigma
=
(
response_sigma
,),
sensitivity
=
(
sensitivity
,))
sensitivity
=
(
sensitivity
,))
data_domain
=
R
.
target
[
0
]
data_domain
=
R
.
target
[
0
]
R_harmonic
=
R
*
fft
R_harmonic
=
R
*
fft
noise_amplitude
=
1.
/
signal_to_noise
*
field_sigma
*
sensitivity
*
((
L
/
N_pixels
)
**
dimensionality
)
noise_amplitude
=
1.
/
signal_to_noise
*
field_sigma
*
sensitivity
*
((
L
/
N_pixels
)
**
dimensionality
)
print
noise_amplitude
print
"noise amplitude:"
,
noise_amplitude
N
=
ift
.
DiagonalOperator
(
N
=
ift
.
DiagonalOperator
(
ift
.
Field
.
full
(
data_domain
,
noise_amplitude
**
2
))
ift
.
Field
.
full
(
data_domain
,
noise_amplitude
**
2
))
noise
=
ift
.
Field
.
from_random
(
noise
=
ift
.
Field
.
from_random
(
domain
=
data_domain
,
random_type
=
'normal'
,
domain
=
data_domain
,
random_type
=
'normal'
,
std
=
noise_amplitude
,
mean
=
0
)
std
=
noise_amplitude
,
mean
=
0
)
data
=
R
(
mock_signal
)
data
=
R
(
mock_signal
)
+
noise
print
data
.
val
[
5
:
10
]
data
+=
noise
print
data
.
val
[
5
:
10
]
# Wiener filter
# Wiener filter
j
=
R_harmonic
.
adjoint_times
(
N
.
inverse_times
(
data
))
j
=
R_harmonic
.
adjoint_times
(
N
.
inverse_times
(
data
))
print
"xx"
,
j
.
val
[
0
]
*
nu
.
K
*
(
nu
.
m
**
dimensionality
)
exit
()
ctrl
=
ift
.
GradientNormController
(
ctrl
=
ift
.
GradientNormController
(
verbose
=
True
,
tol_abs_gradnorm
=
1e-
40
/
(
nu
.
K
*
(
nu
.
m
**
dimensionality
)))
verbose
=
True
,
tol_abs_gradnorm
=
1e-
5
/
(
nu
.
K
*
(
nu
.
m
**
dimensionality
)))
inverter
=
ift
.
ConjugateGradient
(
controller
=
ctrl
)
inverter
=
ift
.
ConjugateGradient
(
controller
=
ctrl
)
wiener_curvature
=
ift
.
library
.
WienerFilterCurvature
(
wiener_curvature
=
ift
.
library
.
WienerFilterCurvature
(
S
=
S
,
N
=
N
,
R
=
R_harmonic
,
inverter
=
inverter
)
S
=
S
,
N
=
N
,
R
=
R_harmonic
,
inverter
=
inverter
)
...
@@ -85,8 +79,10 @@ if __name__ == "__main__":
...
@@ -85,8 +79,10 @@ if __name__ == "__main__":
sspace2
=
ift
.
RGSpace
(
shape
,
distances
=
L
/
N_pixels
/
nu
.
m
)
sspace2
=
ift
.
RGSpace
(
shape
,
distances
=
L
/
N_pixels
/
nu
.
m
)
ift
.
plot
(
ift
.
Field
(
sspace2
,
mock_signal
.
val
)
/
nu
.
K
,
name
=
"mock_signal.png"
)
ift
.
plot
(
ift
.
Field
(
sspace2
,
mock_signal
.
val
)
/
nu
.
K
,
title
=
"mock_signal.png"
)
data
=
ift
.
dobj
.
to_global_data
(
data
.
val
).
reshape
(
sspace2
.
shape
)
#data = ift.dobj.to_global_data(data.val).reshape(sspace2.shape)
data
=
ift
.
Field
(
sspace2
,
val
=
ift
.
dobj
.
from_global_data
(
data
))
#data = ift.Field(sspace2, val=ift.dobj.from_global_data(data))
ift
.
plot
(
ift
.
Field
(
sspace2
,
val
=
data
),
name
=
"data.png"
)
ift
.
plot
(
ift
.
Field
(
sspace2
,
val
=
R
.
adjoint_times
(
data
).
val
),
title
=
"data.png"
)
ift
.
plot
(
ift
.
Field
(
sspace2
,
m_s
.
val
)
/
nu
.
K
,
name
=
"map.png"
)
print
"msig"
,
np
.
min
(
mock_signal
.
val
)
/
nu
.
K
,
np
.
max
(
mock_signal
.
val
)
/
nu
.
K
print
"map"
,
np
.
min
(
m_s
.
val
)
/
nu
.
K
,
np
.
max
(
m_s
.
val
)
/
nu
.
K
ift
.
plot
(
ift
.
Field
(
sspace2
,
m_s
.
val
)
/
nu
.
K
,
title
=
"map.png"
)
demos/wiener_filter_via_hamiltonian.py
View file @
51de4744
...
@@ -11,7 +11,7 @@ if __name__ == "__main__":
...
@@ -11,7 +11,7 @@ if __name__ == "__main__":
# Define associated harmonic space and harmonic transformation
# Define associated harmonic space and harmonic transformation
h_space
=
s_space
.
get_default_codomain
()
h_space
=
s_space
.
get_default_codomain
()
fft
=
ift
.
FFT
Operator
(
h_space
,
s_space
)
fft
=
ift
.
HarmonicTransform
Operator
(
h_space
,
s_space
)
# Setting up power space
# Setting up power space
p_space
=
ift
.
PowerSpace
(
h_space
)
p_space
=
ift
.
PowerSpace
(
h_space
)
...
...
docs/source/start.rst
View file @
51de4744
...
@@ -116,7 +116,6 @@ typical examples for this category are the :py:class:`ScalingOperator`, which si
...
@@ -116,7 +116,6 @@ typical examples for this category are the :py:class:`ScalingOperator`, which si
Nifty4 allows simple and intuitive construction of combined operators.
Nifty4 allows simple and intuitive construction of combined operators.
As an example, if :math:`A`, :math:`B` and :math:`C` are of type :py:class:`LinearOperator` and :math:`f_1` and :math:`f_2` are fields, writing::
As an example, if :math:`A`, :math:`B` and :math:`C` are of type :py:class:`LinearOperator` and :math:`f_1` and :math:`f_2` are fields, writing::
X = A*B.inverse*A.adjoint + C
X = A*B.inverse*A.adjoint + C
f2 = X(f1)
f2 = X(f1)
...
...
nifty4/__init__.py
View file @
51de4744
...
@@ -19,6 +19,7 @@ from .operators.linear_operator import LinearOperator
...
@@ -19,6 +19,7 @@ from .operators.linear_operator import LinearOperator
from
.operators.endomorphic_operator
import
EndomorphicOperator
from
.operators.endomorphic_operator
import
EndomorphicOperator
from
.operators.scaling_operator
import
ScalingOperator
from
.operators.scaling_operator
import
ScalingOperator
from
.operators.diagonal_operator
import
DiagonalOperator
from
.operators.diagonal_operator
import
DiagonalOperator
from
.operators.harmonic_transform_operator
import
HarmonicTransformOperator
from
.operators.fft_operator
import
FFTOperator
from
.operators.fft_operator
import
FFTOperator
from
.operators.fft_smoothing_operator
import
FFTSmoothingOperator
from
.operators.fft_smoothing_operator
import
FFTSmoothingOperator
from
.operators.direct_smoothing_operator
import
DirectSmoothingOperator
from
.operators.direct_smoothing_operator
import
DirectSmoothingOperator
...
@@ -44,6 +45,7 @@ from .minimization.descent_minimizer import DescentMinimizer
...
@@ -44,6 +45,7 @@ from .minimization.descent_minimizer import DescentMinimizer
from
.minimization.steepest_descent
import
SteepestDescent
from
.minimization.steepest_descent
import
SteepestDescent
from
.minimization.vl_bfgs
import
VL_BFGS
from
.minimization.vl_bfgs
import
VL_BFGS
from
.minimization.relaxed_newton
import
RelaxedNewton
from
.minimization.relaxed_newton
import
RelaxedNewton
from
.minimization.scipy_minimizer
import
NewtonCG
,
L_BFGS_B
from
.minimization.energy
import
Energy
from
.minimization.energy
import
Energy
from
.minimization.quadratic_energy
import
QuadraticEnergy
from
.minimization.quadratic_energy
import
QuadraticEnergy
from
.minimization.line_energy
import
LineEnergy
from
.minimization.line_energy
import
LineEnergy
...
...
nifty4/data_objects/distributed_do.py
View file @
51de4744
...
@@ -27,6 +27,10 @@ rank = _comm.Get_rank()
...
@@ -27,6 +27,10 @@ rank = _comm.Get_rank()
master
=
(
rank
==
0
)
master
=
(
rank
==
0
)
def
is_numpy
():
return
False
def
mprint
(
*
args
):
def
mprint
(
*
args
):
if
master
:
if
master
:
print
(
*
args
)
print
(
*
args
)
...
@@ -259,6 +263,7 @@ class data_object(object):
...
@@ -259,6 +263,7 @@ class data_object(object):
def
fill
(
self
,
value
):
def
fill
(
self
,
value
):
self
.
_data
.
fill
(
value
)
self
.
_data
.
fill
(
value
)
def
full
(
shape
,
fill_value
,
dtype
=
None
,
distaxis
=
0
):
def
full
(
shape
,
fill_value
,
dtype
=
None
,
distaxis
=
0
):
return
data_object
(
shape
,
np
.
full
(
local_shape
(
shape
,
distaxis
),
return
data_object
(
shape
,
np
.
full
(
local_shape
(
shape
,
distaxis
),
fill_value
,
dtype
),
distaxis
)
fill_value
,
dtype
),
distaxis
)
...
@@ -346,7 +351,7 @@ def local_data(arr):
...
@@ -346,7 +351,7 @@ def local_data(arr):
def
ibegin_from_shape
(
glob_shape
,
distaxis
=
0
):
def
ibegin_from_shape
(
glob_shape
,
distaxis
=
0
):
res
=
[
0
]
*
len
(
glob_shape
)
res
=
[
0
]
*
len
(
glob_shape
)
if
distaxis
<
0
:
if
distaxis
<
0
:
return
res
return
res
res
[
distaxis
]
=
_shareRange
(
glob_shape
[
distaxis
],
ntask
,
rank
)[
0
]
res
[
distaxis
]
=
_shareRange
(
glob_shape
[
distaxis
],
ntask
,
rank
)[
0
]
return
tuple
(
res
)
return
tuple
(
res
)
...
...
nifty4/data_objects/numpy_do.py
View file @
51de4744
...
@@ -30,6 +30,10 @@ rank = 0
...
@@ -30,6 +30,10 @@ rank = 0
master
=
True
master
=
True
def
is_numpy
():
return
True
def
mprint
(
*
args
):
def
mprint
(
*
args
):
print
(
*
args
)
print
(
*
args
)
...
...
nifty4/dobj.py
View file @
51de4744
...
@@ -33,4 +33,4 @@ __all__ = ["ntask", "rank", "master", "local_shape", "data_object", "full",
...
@@ -33,4 +33,4 @@ __all__ = ["ntask", "rank", "master", "local_shape", "data_object", "full",
"log"
,
"tanh"
,
"sqrt"
,
"from_object"
,
"from_random"
,
"log"
,
"tanh"
,
"sqrt"
,
"from_object"
,
"from_random"
,
"local_data"
,
"ibegin"
,
"ibegin_from_shape"
,
"np_allreduce_sum"
,
"local_data"
,
"ibegin"
,
"ibegin_from_shape"
,
"np_allreduce_sum"
,
"distaxis"
,
"from_local_data"
,
"from_global_data"
,
"to_global_data"
,
"distaxis"
,
"from_local_data"
,
"from_global_data"
,
"to_global_data"
,
"redistribute"
,
"default_distaxis"
,
"mprint"
]
"redistribute"
,
"default_distaxis"
,
"mprint"
,
"is_numpy"
]
nifty4/minimization/scipy_minimizer.py
0 → 100644
View file @
51de4744
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# Copyright(C) 2013-2017 Max-Planck-Society
#
# NIFTy is being developed at the Max-Planck-Institut fuer Astrophysik
# and financially supported by the Studienstiftung des deutschen Volkes.
from
__future__
import
division
from
.minimizer
import
Minimizer
from
..field
import
Field
from
..
import
dobj
class
ScipyMinimizer
(
Minimizer
):
"""Scipy-based minimizer
Parameters
----------
controller : IterationController
Object that decides when to terminate the minimization.
method : str
The selected Scipy minimization method.
options : dictionary
A set of custom options for the selected minimizer.
"""
def
__init__
(
self
,
controller
,
method
,
options
,
need_hessp
):
super
(
ScipyMinimizer
,
self
).
__init__
()
if
not
dobj
.
is_numpy
():
raise
NotImplementedError
self
.
_controller
=
controller
self
.
_method
=
method
self
.
_options
=
options
self
.
_need_hessp
=
need_hessp
def
__call__
(
self
,
energy
):
class
_MinimizationDone
(
BaseException
):
pass
class
_MinHelper
(
object
):
def
__init__
(
self
,
controller
,
energy
):
self
.
_controller
=
controller
self
.
_energy
=
energy
self
.
_domain
=
energy
.
position
.
domain
def
_update
(
self
,
x
):
pos
=
Field
(
self
.
_domain
,
x
.
reshape
(
self
.
_domain
.
shape
))
if
(
pos
.
val
!=
self
.
_energy
.
position
.
val
).
any
():
self
.
_energy
=
self
.
_energy
.
at
(
pos
)
status
=
self
.
_controller
.
check
(
self
.
_energy
)
if
status
!=
self
.
_controller
.
CONTINUE
:
raise
_MinimizationDone
def
fun
(
self
,
x
):
self
.
_update
(
x
)
return
self
.
_energy
.
value
def
jac
(
self
,
x
):
self
.
_update
(
x
)
return
self
.
_energy
.
gradient
.
val
.
reshape
(
-
1
)
def
hessp
(
self
,
x
,
p
):
self
.
_update
(
x
)
vec
=
Field
(
self
.
_domain
,
p
.
reshape
(
self
.
_domain
.
shape
))
res
=
self
.
_energy
.
curvature
(
vec
)
return
res
.
val
.
reshape
(
-
1
)
import
scipy.optimize
as
opt
hlp
=
_MinHelper
(
self
.
_controller
,
energy
)
energy
=
None
status
=
self
.
_controller
.
start
(
hlp
.
_energy
)
if
status
!=
self
.
_controller
.
CONTINUE
:
return
hlp
.
_energy
,
status
try
:
if
self
.
_need_hessp
:
opt
.
minimize
(
hlp
.
fun
,
hlp
.
_energy
.
position
.
val
.
reshape
(
-
1
),
method
=
self
.
_method
,
jac
=
hlp
.
jac
,
hessp
=
hlp
.
hessp
,
options
=
self
.
_options
)
else
:
opt
.
minimize
(
hlp
.
fun
,
hlp
.
_energy
.
position
.
val
.
reshape
(
-
1
),
method
=
self
.
_method
,
jac
=
hlp
.
jac
,
options
=
self
.
_options
)
except
_MinimizationDone
:
status
=
self
.
_controller
.
check
(
hlp
.
_energy
)
return
hlp
.
_energy
,
self
.
_controller
.
check
(
hlp
.
_energy
)
return
hlp
.
_energy
,
self
.
_controller
.
ERROR
def
NewtonCG
(
controller
):
return
ScipyMinimizer
(
controller
,
"Newton-CG"
,
{
"xtol"
:
1e-20
,
"maxiter"
:
None
},
True
)
def
L_BFGS_B
(
controller
,
maxcor
=
10
):
return
ScipyMinimizer
(
controller
,
"L-BFGS-B"
,
{
"ftol"
:
1e-20
,
"gtol"
:
1e-20
,
"maxcor"
:
maxcor
},
False
)
nifty4/minimization/scipy_minimizer.py.bak
0 → 100644
View file @
51de4744
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# Copyright(C) 2013-2017 Max-Planck-Society
#
# NIFTy is being developed at the Max-Planck-Institut fuer Astrophysik
# and financially supported by the Studienstiftung des deutschen Volkes.
from __future__ import division
from .minimizer import Minimizer
from ..field import Field
from .. import dobj
class ScipyMinimizer(Minimizer):
"""Scipy-based minimizer
Parameters
----------
controller : IterationController
Object that decides when to terminate the minimization.
"""
def __init__(self, controller, method="trust-ncg"):
super(ScipyMinimizer, self).__init__()
if not dobj.is_numpy():
raise NotImplementedError
self._controller = controller
self._method = method
def __call__(self, energy):
class _MinimizationDone:
pass
class _MinHelper(object):
def __init__(self, controller, energy):
self._controller = controller
self._energy = energy
self._domain = energy.position.domain
def _update(self, x):
pos = Field(self._domain, x.reshape(self._domain.shape))
if (pos.val != self._energy.position.val).any():
self._energy = self._energy.at(pos)
status = self._controller.check(self._energy)
if status != self._controller.CONTINUE:
raise _MinimizationDone
def fun(self, x):
self._update(x)
return self._energy.value
def jac(self, x):
self._update(x)
return self._energy.gradient.val.reshape(-1)
def hessp(self, x, p):
self._update(x)
vec = Field(self._domain, p.reshape(self._domain.shape))
res = self._energy.curvature(vec)
return res.val.reshape(-1)
import scipy.optimize as opt
status = self._controller.start(energy)
if status != self._controller.CONTINUE:
return energy, status
hlp = _MinHelper(self._controller, energy)
options = {'disp': False,
'xtol': 1e-15,
'eps': 1.4901161193847656e-08,
'return_all': False,
'maxiter': None}
options = {'disp': False,
'ftol': 1e-15,
'gtol': 1e-15,
'eps': 1.4901161193847656e-08}
try:
opt.minimize(hlp.fun, energy.position.val.reshape(-1),
method=self._method, jac=hlp.jac,
hessp=hlp.hessp,
options=options)
except _MinimizationDone:
energy = hlp._energy
status = self._controller.check(energy)
return energy, status
return hlp._energy, self._controller.ERROR
nifty4/operators/fft_operator.py
View file @
51de4744
...
@@ -23,42 +23,22 @@ from .linear_operator import LinearOperator
...
@@ -23,42 +23,22 @@ from .linear_operator import LinearOperator
from
..
import
dobj
from
..
import
dobj
from
..
import
utilities
from
..
import
utilities
from
..field
import
Field
from
..field
import
Field
from
..spaces.gl_space
import
GLSpace
class
FFTOperator
(
LinearOperator
):
class
FFTOperator
(
LinearOperator
):
"""Transforms between a pair of position and harmonic domains.
"""Transforms between a pair of position and harmonic RGSpaces.
Built-in domain pairs are
- a harmonic and a non-harmonic RGSpace (with matching distances)
- a HPSpace and a LMSpace
- a GLSpace and a LMSpace
Within a domain pair, both orderings are possible.
For RGSpaces, the operator provides the full set of operations.
For the sphere-related domains, it only supports the transform from
harmonic to position space and its adjoint; if the operator domain is
harmonic, this will be times() and adjoint_times(), otherwise
inverse_times() and adjoint_inverse_times()
Parameters
Parameters
----------
----------
domain: Space
or single-element tuple of Spaces
domain: Space
, tuple of Spaces or DomainObject
The domain of the data that is input by "times" and output by
The domain of the data that is input by "times" and output by
"adjoint_times".
"adjoint_times".
target: Space
The target space of the transform operation.
If omitted, a space will be chosen automatically.
space: the index of the space on which the operator should act
space: the index of the space on which the operator should act
If None, it is set to 0 if domain contains exactly one space
If None, it is set to 0 if domain contains exactly one space.
target: Space or single-element tuple of Spaces (optional)
domain[space] must be an RGSpace.
The domain of the data that is output by "times" and input by
"adjoint_times".
If omitted, a co-domain will be chosen automatically.
Whenever "domain" is an RGSpace, the codomain (and its parameters) are
uniquely determined.
For GLSpace, HPSpace, and LMSpace, a sensible (but not unique)
co-domain is chosen that should work satisfactorily in most situations,
but for full control, the user should explicitly specify a codomain.
"""
"""
def
__init__
(
self
,
domain
,
target
=
None
,
space
=
None
):
def
__init__
(
self
,
domain
,
target
=
None
,
space
=
None
):
...
@@ -69,6 +49,8 @@ class FFTOperator(LinearOperator):
...
@@ -69,6 +49,8 @@ class FFTOperator(LinearOperator):
self
.
_space
=
utilities
.
infer_space
(
self
.
_domain
,
space
)
self
.
_space
=
utilities
.
infer_space
(
self
.
_domain
,
space
)
adom
=
self
.
_domain
[
self
.
_space
]
adom
=
self
.
_domain
[
self
.
_space
]
if
not
isinstance
(
adom
,
RGSpace
):
raise
TypeError
(
"FFTOperator only works on RGSpaces"
)
if
target
is
None
:
if
target
is
None
:
target
=
adom
.
get_default_codomain
()
target
=
adom
.
get_default_codomain
()
...
@@ -78,47 +60,18 @@ class FFTOperator(LinearOperator):
...
@@ -78,47 +60,18 @@ class FFTOperator(LinearOperator):
adom
.
check_codomain
(
target
)
adom
.
check_codomain
(
target
)
target
.
check_codomain
(
adom
)
target
.
check_codomain
(
adom
)
if
isinstance
(
adom
,
RGSpace
):
import
pyfftw
self
.
_applyfunc
=
self
.
_apply_cartesian
pyfftw
.
interfaces
.
cache
.
enable
()
self
.
_capability
=
self
.
_all_ops
import
pyfftw
pyfftw
.
interfaces
.
cache
.
enable
()
else
:
from
pyHealpix
import
sharpjob_d
self
.
_applyfunc
=
self
.
_apply_spherical
hspc
=
adom
if
adom
.
harmonic
else
target
pspc
=
target
if
adom
.
harmonic
else
adom
self
.
lmax
=
hspc
.
lmax
self
.
mmax
=
hspc
.
mmax
self
.
sjob
=
sharpjob_d
()
self
.
sjob
.
set_triangular_alm_info
(
self
.
lmax
,
self
.
mmax
)
if
isinstance
(
pspc
,
GLSpace
):
self
.
sjob
.
set_Gauss_geometry
(
pspc
.
nlat
,
pspc
.
nlon
)
else
:
self
.
sjob
.
set_Healpix_geometry
(
pspc
.
nside
)
if
adom
.
harmonic
:
self
.
_capability
=
self
.
TIMES
|
self
.
ADJOINT_TIMES
else
:
self
.
_capability
=
(
self
.
INVERSE_TIMES
|
self
.
INVERSE_ADJOINT_TIMES
)
def
apply
(
self
,
x
,
mode
):
def
apply
(
self
,
x
,
mode
):
self
.
_check_input
(
x
,
mode
)
self
.
_check_input
(
x
,
mode
)
if
np
.
issubdtype
(
x
.
dtype
,
np
.
complexfloating
):
if
np
.
issubdtype
(
x
.
dtype
,
np
.
complexfloating
):
return
(
self
.
_apply
func
(
x
.
real
,
mode
)
+
return
(
self
.
_apply
_cartesian
(
x
.
real
,
mode
)
+
1j
*
self
.
_apply
func
(
x
.
imag
,
mode
))
1j
*
self
.
_apply
_cartesian
(
x
.
imag
,
mode
))
else
:
else
:
return
self
.
_apply
func
(
x
,
mode
)
return
self
.
_apply
_cartesian
(
x
,
mode
)
def
_apply_cartesian
(
self
,
x
,
mode
):
def
_apply_cartesian
(
self
,
x
,
mode
):
"""
RG -> RG transform method.
Parameters
----------
x : Field
The field to be transformed
"""
from
pyfftw.interfaces.numpy_fft
import
fftn
from
pyfftw.interfaces.numpy_fft
import
fftn
axes
=
x
.
domain
.
axes
[
self
.
_space
]
axes
=
x
.
domain
.
axes
[
self
.
_space
]