Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
ift
NIFTy
Commits
654b09e0
Commit
654b09e0
authored
May 08, 2017
by
Martin Reinecke
Browse files
add documentation; tweak corresponding tests
parent
78cac76f
Pipeline
#12158
passed with stage
in 4 minutes and 53 seconds
Changes
2
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
nifty/operators/fft_operator/fft_operator.py
View file @
654b09e0
...
@@ -34,7 +34,74 @@ from transformations import RGRGTransformation,\
...
@@ -34,7 +34,74 @@ from transformations import RGRGTransformation,\
class
FFTOperator
(
LinearOperator
):
class
FFTOperator
(
LinearOperator
):
""" Transforms between a pair of position and harmonic domains.
Possible 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.
The operator provides a "times" and an "adjoint_times" operation.
For a pair of RGSpaces, the "adjoint_times" operation is equivalent to
"inverse_times"; for the sphere-related domains this is not the case, since
the operator matrix is not square.
Parameters
----------
domain: Space or single-element tuple of Spaces
The domain of the data that is input by "times" and output by
"adjoint_times".
target: Space or single-element tuple of Spaces (optional)
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.
module: String (optional)
Software module employed for carrying out the transform operations.
For RGSpace pairs this can be "numpy" or "fftw", where "numpy" is always
available, but "fftw" offers higher performance and parallelization.
For sphere-related domains, only "pyHealpix" is available.
If omitted, "fftw" is selected for RGSpaces if available, else "numpy";
on the sphere the default is (unsurprisingly) "pyHealpix".
domain_dtype: data type (optional)
Data type of the fields that go into "times" and come out of
"adjoint_times". Default is "numpy.float".
target_dtype: data type (optional)
Data type of the fields that go into "adjoint_times" and come out of
"times". Default is "numpy.complex".
(MR: I feel this is not really a good idea, since it makes no sense for
SHTs. Also, wouldn't it make sense to specify data types
only to "times" and "adjoint_times"? Does the operator itself really
need to know this, or only the individual call?)
Attributes
----------
domain: Tuple of Spaces (with one entry)
The domain of the data that is input by "times" and output by
"adjoint_times".
target: Tuple of Spaces (with one entry)
The domain of the data that is output by "times" and input by
"adjoint_times".
unitary: bool
Returns False.
This is strictly speaking a lie, because FFTOperators on RGSpaces are
in fact unitary ... but if we return True in this case, then
LinearOperator will call _inverse_times instead of _adjoint_times, which
does not exist. This needs some more work.
Raises
------
ValueError:
if "domain" or "target" are not of the proper type.
"""
# ---Class attributes---
# ---Class attributes---
default_codomain_dictionary
=
{
RGSpace
:
RGSpace
,
default_codomain_dictionary
=
{
RGSpace
:
RGSpace
,
...
@@ -170,6 +237,32 @@ class FFTOperator(LinearOperator):
...
@@ -170,6 +237,32 @@ class FFTOperator(LinearOperator):
@
classmethod
@
classmethod
def
get_default_codomain
(
cls
,
domain
):
def
get_default_codomain
(
cls
,
domain
):
""" Returns a codomain to the given domain.
Parameters
----------
domain: Space
An instance of RGSpace, HPSpace, GLSpace or LMSpace.
Returns
-------
target: Space
A (more or less perfect) counterpart to "domain" with respect
to a FFT operation.
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. For full control however, the
user should not rely on this method.
Raises
------
ValueError:
if no default codomain is defined for "domain".
"""
domain_class
=
domain
.
__class__
domain_class
=
domain
.
__class__
try
:
try
:
codomain_class
=
cls
.
default_codomain_dictionary
[
domain_class
]
codomain_class
=
cls
.
default_codomain_dictionary
[
domain_class
]
...
...
test/test_misc.py
View file @
654b09e0
...
@@ -26,9 +26,8 @@ from nifty.config import dependency_injector as di
...
@@ -26,9 +26,8 @@ from nifty.config import dependency_injector as di
from
nifty
import
Field
,
\
from
nifty
import
Field
,
\
RGSpace
,
\
RGSpace
,
\
LMSpace
,
\
LMSpace
,
\
RGRGTransformation
,
\
HPSpace
,
\
LMGLTransformation
,
\
GLSpace
,
\
LMHPTransformation
,
\
FFTOperator
FFTOperator
from
itertools
import
product
from
itertools
import
product
...
@@ -75,7 +74,7 @@ class Misc_Tests(unittest.TestCase):
...
@@ -75,7 +74,7 @@ class Misc_Tests(unittest.TestCase):
raise
SkipTest
raise
SkipTest
tol
=
_get_rtol
(
itp
)
tol
=
_get_rtol
(
itp
)
a
=
RGSpace
(
dim1
,
zerocenter
=
zc1
,
distances
=
d
)
a
=
RGSpace
(
dim1
,
zerocenter
=
zc1
,
distances
=
d
)
b
=
RG
RGTransformation
.
get_codomain
(
a
,
zerocenter
=
zc2
)
b
=
RG
Space
(
dim1
,
zerocenter
=
zc2
,
distances
=
1.
/
(
dim1
*
d
),
harmonic
=
True
)
fft
=
FFTOperator
(
domain
=
a
,
target
=
b
,
domain_dtype
=
itp
,
fft
=
FFTOperator
(
domain
=
a
,
target
=
b
,
domain_dtype
=
itp
,
target_dtype
=
_harmonic_type
(
itp
),
module
=
module
)
target_dtype
=
_harmonic_type
(
itp
),
module
=
module
)
inp
=
Field
.
from_random
(
domain
=
a
,
random_type
=
'normal'
,
std
=
7
,
mean
=
3
,
inp
=
Field
.
from_random
(
domain
=
a
,
random_type
=
'normal'
,
std
=
7
,
mean
=
3
,
...
@@ -85,13 +84,15 @@ class Misc_Tests(unittest.TestCase):
...
@@ -85,13 +84,15 @@ class Misc_Tests(unittest.TestCase):
@
expand
(
product
([
"numpy"
,
"fftw"
],
[
10
,
11
],
[
9
,
12
],
[
False
,
True
],
@
expand
(
product
([
"numpy"
,
"fftw"
],
[
10
,
11
],
[
9
,
12
],
[
False
,
True
],
[
False
,
True
],
[
False
,
True
],
[
False
,
True
],
[
0.1
,
1
,
3.7
],
[
False
,
True
],
[
False
,
True
],
[
False
,
True
],
[
0.1
,
1
,
3.7
],
[
0.4
,
1
,
2.7
],
[
np
.
float64
,
np
.
complex128
,
np
.
float32
,
np
.
complex64
]))
[
np
.
float64
,
np
.
complex128
,
np
.
float32
,
np
.
complex64
]))
def
test_fft2D
(
self
,
module
,
dim1
,
dim2
,
zc1
,
zc2
,
zc3
,
zc4
,
d
,
itp
):
def
test_fft2D
(
self
,
module
,
dim1
,
dim2
,
zc1
,
zc2
,
zc3
,
zc4
,
d
1
,
d2
,
itp
):
if
module
==
"fftw"
and
"pyfftw"
not
in
di
:
if
module
==
"fftw"
and
"pyfftw"
not
in
di
:
raise
SkipTest
raise
SkipTest
tol
=
_get_rtol
(
itp
)
tol
=
_get_rtol
(
itp
)
a
=
RGSpace
([
dim1
,
dim2
],
zerocenter
=
[
zc1
,
zc2
],
distances
=
d
)
a
=
RGSpace
([
dim1
,
dim2
],
zerocenter
=
[
zc1
,
zc2
],
distances
=
[
d1
,
d2
])
b
=
RGRGTransformation
.
get_codomain
(
a
,
zerocenter
=
[
zc3
,
zc4
])
b
=
RGSpace
([
dim1
,
dim2
],
zerocenter
=
[
zc3
,
zc4
],
distances
=
[
1.
/
(
dim1
*
d1
),
1.
/
(
dim2
*
d2
)],
harmonic
=
True
)
fft
=
FFTOperator
(
domain
=
a
,
target
=
b
,
domain_dtype
=
itp
,
fft
=
FFTOperator
(
domain
=
a
,
target
=
b
,
domain_dtype
=
itp
,
target_dtype
=
_harmonic_type
(
itp
),
module
=
module
)
target_dtype
=
_harmonic_type
(
itp
),
module
=
module
)
inp
=
Field
.
from_random
(
domain
=
a
,
random_type
=
'normal'
,
std
=
7
,
mean
=
3
,
inp
=
Field
.
from_random
(
domain
=
a
,
random_type
=
'normal'
,
std
=
7
,
mean
=
3
,
...
@@ -106,7 +107,7 @@ class Misc_Tests(unittest.TestCase):
...
@@ -106,7 +107,7 @@ class Misc_Tests(unittest.TestCase):
raise
SkipTest
raise
SkipTest
tol
=
_get_rtol
(
tp
)
tol
=
_get_rtol
(
tp
)
a
=
LMSpace
(
lmax
=
lm
)
a
=
LMSpace
(
lmax
=
lm
)
b
=
LMGLTransformation
.
get_codomain
(
a
)
b
=
GLSpace
(
nlat
=
lm
+
1
)
fft
=
FFTOperator
(
domain
=
a
,
target
=
b
,
domain_dtype
=
tp
,
target_dtype
=
tp
)
fft
=
FFTOperator
(
domain
=
a
,
target
=
b
,
domain_dtype
=
tp
,
target_dtype
=
tp
)
inp
=
Field
.
from_random
(
domain
=
a
,
random_type
=
'normal'
,
std
=
7
,
mean
=
3
,
inp
=
Field
.
from_random
(
domain
=
a
,
random_type
=
'normal'
,
std
=
7
,
mean
=
3
,
dtype
=
tp
)
dtype
=
tp
)
...
@@ -119,7 +120,7 @@ class Misc_Tests(unittest.TestCase):
...
@@ -119,7 +120,7 @@ class Misc_Tests(unittest.TestCase):
if
'pyHealpix'
not
in
di
:
if
'pyHealpix'
not
in
di
:
raise
SkipTest
raise
SkipTest
a
=
LMSpace
(
lmax
=
lm
)
a
=
LMSpace
(
lmax
=
lm
)
b
=
LMHPTransformation
.
get_codomain
(
a
)
b
=
HPSpace
(
nside
=
lm
//
2
)
fft
=
FFTOperator
(
domain
=
a
,
target
=
b
,
domain_dtype
=
tp
,
target_dtype
=
tp
)
fft
=
FFTOperator
(
domain
=
a
,
target
=
b
,
domain_dtype
=
tp
,
target_dtype
=
tp
)
inp
=
Field
.
from_random
(
domain
=
a
,
random_type
=
'normal'
,
std
=
1
,
mean
=
0
,
inp
=
Field
.
from_random
(
domain
=
a
,
random_type
=
'normal'
,
std
=
1
,
mean
=
0
,
dtype
=
tp
)
dtype
=
tp
)
...
...
Write
Preview
Markdown
is supported
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