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
315d1848
Commit
315d1848
authored
Jan 15, 2018
by
Martin Reinecke
Browse files
fix FFT; Response still not working properly
parent
64cdbfaa
Pipeline
#23712
failed with stage
in 4 minutes and 4 seconds
Changes
8
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
demos/wiener_filter_via_curvature.py
View file @
315d1848
...
...
@@ -47,7 +47,9 @@ if __name__ == "__main__":
mock_power
=
ift
.
PS_field
(
power_space
,
power_spectrum
)
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
)
print
mock_signal
.
val
[
0
]
/
nu
.
K
exposure
=
1.
/
nu
.
K
R
=
ift
.
ResponseOperator
(
signal_space
,
sigma
=
(
response_sigma
,),
...
...
@@ -63,7 +65,6 @@ if __name__ == "__main__":
std
=
mock_signal
.
std
()
/
np
.
sqrt
(
signal_to_noise
),
mean
=
0
)
data
=
R
(
mock_signal
)
#+ noise
print
data
.
val
[
5
]
print
mock_signal
.
val
[
5
]
/
nu
.
K
# Wiener filter
j
=
R_harmonic
.
adjoint_times
(
N
.
inverse_times
(
data
))
...
...
nifty/operators/fft_operator.py
View file @
315d1848
...
...
@@ -25,18 +25,14 @@ from .fft_operator_support import RGRGTransformation, SphericalTransformation
class
FFTOperator
(
LinearOperator
):
"""Transforms between a pair of
position and harmonic
domains.
"""Transforms between a pair of
harmonic and position
domains.
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.
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.
- harmonic RGSpace / nonharmonic RGSpace (with matching distances)
- LMSpace / HPSpace
- LMSpace / GLSpace
The times() operation always transforms from the harmonic to the
position domain.
Parameters
----------
...
...
@@ -49,9 +45,9 @@ class FFTOperator(LinearOperator):
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 a
n
RGSpace, the codomain
(and its parameters) are
uniquely determined.
For
GLSpace, HPSpace, and
LMSpace, a sensible (but not unique)
Whenever "domain" is a
harmonic
RGSpace, the codomain
(and its parameters) are
uniquely determined.
For 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.
"""
...
...
@@ -62,6 +58,8 @@ class FFTOperator(LinearOperator):
# Initialize domain and target
self
.
_domain
=
DomainTuple
.
make
(
domain
)
self
.
_space
=
infer_space
(
self
.
_domain
,
space
)
if
not
self
.
_domain
[
self
.
_space
].
harmonic
:
raise
TypeError
(
"H2POperator must work on a harmonic domain"
)
adom
=
self
.
domain
[
self
.
_space
]
if
target
is
None
:
...
...
@@ -73,14 +71,11 @@ class FFTOperator(LinearOperator):
adom
.
check_codomain
(
target
)
target
.
check_codomain
(
adom
)
if
self
.
_target
[
self
.
_space
].
harmonic
:
pdom
,
hdom
=
(
self
.
_domain
,
self
.
_target
)
else
:
pdom
,
hdom
=
(
self
.
_target
,
self
.
_domain
)
hdom
,
pdom
=
(
self
.
_domain
,
self
.
_target
)
if
isinstance
(
pdom
[
self
.
_space
],
RGSpace
):
self
.
_trafo
=
RGRGTransformation
(
p
dom
,
h
dom
,
self
.
_space
)
self
.
_trafo
=
RGRGTransformation
(
h
dom
,
p
dom
,
self
.
_space
)
else
:
self
.
_trafo
=
SphericalTransformation
(
p
dom
,
h
dom
,
self
.
_space
)
self
.
_trafo
=
SphericalTransformation
(
h
dom
,
p
dom
,
self
.
_space
)
def
apply
(
self
,
x
,
mode
):
self
.
_check_input
(
x
,
mode
)
...
...
nifty/operators/fft_operator_support.py
View file @
315d1848
...
...
@@ -26,24 +26,19 @@ from .linear_operator import LinearOperator
class
Transformation
(
object
):
def
__init__
(
self
,
pdom
,
hdom
,
space
):
self
.
pdom
=
pdom
def
__init__
(
self
,
hdom
,
pdom
,
space
):
self
.
hdom
=
hdom
self
.
pdom
=
pdom
self
.
space
=
space
class
RGRGTransformation
(
Transformation
):
def
__init__
(
self
,
p
dom
,
h
dom
,
space
):
def
__init__
(
self
,
h
dom
,
p
dom
,
space
):
import
pyfftw
super
(
RGRGTransformation
,
self
).
__init__
(
p
dom
,
h
dom
,
space
)
super
(
RGRGTransformation
,
self
).
__init__
(
h
dom
,
p
dom
,
space
)
pyfftw
.
interfaces
.
cache
.
enable
()
# correct for forward/inverse fft.
# naively one would set power to 0.5 here in order to
# apply effectively a factor of 1/sqrt(N) to the field.
# BUT: the pixel volumes of the domain and codomain are different.
# Hence, in order to produce the same scalar product, power==1.
self
.
fct_noninverse
=
pdom
[
space
].
scalar_dvol
()
self
.
fct_inverse
=
1.
/
(
pdom
[
space
].
scalar_dvol
()
*
hdom
[
space
].
dim
)
self
.
fct_noninverse
=
hdom
[
space
].
scalar_dvol
()
self
.
fct_inverse
=
1.
/
(
hdom
[
space
].
scalar_dvol
()
*
hdom
[
space
].
dim
)
@
property
def
unitary
(
self
):
...
...
@@ -138,8 +133,8 @@ class RGRGTransformation(Transformation):
class
SphericalTransformation
(
Transformation
):
def
__init__
(
self
,
p
dom
,
h
dom
,
space
):
super
(
SphericalTransformation
,
self
).
__init__
(
p
dom
,
h
dom
,
space
)
def
__init__
(
self
,
h
dom
,
p
dom
,
space
):
super
(
SphericalTransformation
,
self
).
__init__
(
h
dom
,
p
dom
,
space
)
from
pyHealpix
import
sharpjob_d
self
.
lmax
=
self
.
hdom
[
self
.
space
].
lmax
...
...
nifty/operators/fft_smoothing_operator.py
View file @
315d1848
...
...
@@ -14,12 +14,15 @@ def FFTSmoothingOperator(domain, sigma, space=None):
domain
=
DomainTuple
.
make
(
domain
)
space
=
infer_space
(
domain
,
space
)
FFT
=
FFTOperator
(
domain
,
space
=
space
)
codomain
=
FFT
.
domain
[
space
].
get_default_codomain
()
if
domain
[
space
].
harmonic
:
raise
TypeError
(
"domain must not be harmonic"
)
fftdom
=
list
(
domain
)
codomain
=
domain
[
space
].
get_default_codomain
()
fftdom
[
space
]
=
codomain
fftdom
=
DomainTuple
.
make
(
fftdom
)
FFT
=
FFTOperator
(
fftdom
,
domain
[
space
],
space
=
space
)
kernel
=
codomain
.
get_k_length_array
()
smoother
=
codomain
.
get_fft_smoothing_kernel_function
(
sigma
)
kernel
=
smoother
(
kernel
)
ddom
=
list
(
domain
)
ddom
[
space
]
=
codomain
diag
=
DiagonalOperator
(
kernel
,
ddom
,
space
)
return
FFT
.
inverse
*
diag
*
FFT
diag
=
DiagonalOperator
(
kernel
,
fftdom
,
space
)
return
FFT
*
diag
*
FFT
.
inverse
nifty/operators/linear_operator.py
View file @
315d1848
...
...
@@ -161,5 +161,5 @@ class LinearOperator(with_metaclass(
self
.
_check_mode
(
mode
)
if
x
.
domain
!=
self
.
_dom
(
mode
):
raise
ValueError
(
"The operator's and and field's domains "
"don't match."
)
raise
ValueError
(
"The operator's and and field's domains "
"don't match."
)
test/test_operators/test_adjoint.py
View file @
315d1848
...
...
@@ -39,5 +39,7 @@ class Adjointness_Tests(unittest.TestCase):
@
expand
(
product
(
_harmonic_spaces
+
_position_spaces
,
[
np
.
float64
,
np
.
complex128
]))
def
testFFT
(
self
,
sp
,
dtype
):
if
not
sp
.
harmonic
:
sp
=
sp
.
get_default_codomain
()
op
=
ift
.
FFTOperator
(
sp
)
_check_adjointness
(
op
,
dtype
)
test/test_operators/test_fft_operator.py
View file @
315d1848
...
...
@@ -37,8 +37,8 @@ class FFTOperatorTests(unittest.TestCase):
[
np
.
float64
,
np
.
float32
,
np
.
complex64
,
np
.
complex128
]))
def
test_fft1D
(
self
,
dim1
,
d
,
itp
):
tol
=
_get_rtol
(
itp
)
a
=
ift
.
RGSpace
(
dim1
,
distances
=
d
)
b
=
ift
.
RGSpace
(
dim1
,
distances
=
1.
/
(
dim1
*
d
),
harmonic
=
True
)
b
=
ift
.
RGSpace
(
dim1
,
distances
=
d
)
a
=
ift
.
RGSpace
(
dim1
,
distances
=
1.
/
(
dim1
*
d
),
harmonic
=
True
)
fft
=
ift
.
FFTOperator
(
domain
=
a
,
target
=
b
)
np
.
random
.
seed
(
16
)
...
...
@@ -53,8 +53,8 @@ class FFTOperatorTests(unittest.TestCase):
[
np
.
float64
,
np
.
float32
,
np
.
complex64
,
np
.
complex128
]))
def
test_fft2D
(
self
,
dim1
,
dim2
,
d1
,
d2
,
itp
):
tol
=
_get_rtol
(
itp
)
a
=
ift
.
RGSpace
([
dim1
,
dim2
],
distances
=
[
d1
,
d2
])
b
=
ift
.
RGSpace
([
dim1
,
dim2
],
b
=
ift
.
RGSpace
([
dim1
,
dim2
],
distances
=
[
d1
,
d2
])
a
=
ift
.
RGSpace
([
dim1
,
dim2
],
distances
=
[
1.
/
(
dim1
*
d1
),
1.
/
(
dim2
*
d2
)],
harmonic
=
True
)
fft
=
ift
.
FFTOperator
(
domain
=
a
,
target
=
b
)
...
...
@@ -80,28 +80,28 @@ class FFTOperatorTests(unittest.TestCase):
@
expand
(
product
([
0
,
3
,
6
,
11
,
30
],
[
np
.
float64
,
np
.
float32
,
np
.
complex64
,
np
.
complex128
]))
def
test_sht
(
self
,
lm
,
tp
):
tol
=
_get_rtol
(
tp
)
a
=
ift
.
LMSpace
(
lmax
=
lm
)
b
=
ift
.
GLSpace
(
nlat
=
lm
+
1
)
fft
=
ift
.
FFTOperator
(
domain
=
a
,
target
=
b
)
inp
=
ift
.
Field
.
from_random
(
domain
=
a
,
random_type
=
'normal'
,
std
=
7
,
mean
=
3
,
dtype
=
tp
)
out
=
fft
.
inverse_times
(
fft
.
times
(
inp
))
assert_allclose
(
ift
.
dobj
.
to_global_data
(
inp
.
val
),
ift
.
dobj
.
to_global_data
(
out
.
val
),
rtol
=
tol
,
atol
=
tol
)
#
def test_sht(self, lm, tp):
#
tol = _get_rtol(tp)
#
a = ift.LMSpace(lmax=lm)
#
b = ift.GLSpace(nlat=lm+1)
#
fft = ift.FFTOperator(domain=a, target=b)
#
inp = ift.Field.from_random(domain=a, random_type='normal',
#
std=7, mean=3, dtype=tp)
#
out = fft.inverse_times(fft.times(inp))
#
assert_allclose(ift.dobj.to_global_data(inp.val),
#
ift.dobj.to_global_data(out.val), rtol=tol, atol=tol)
@
expand
(
product
([
128
,
256
],
[
np
.
float64
,
np
.
float32
,
np
.
complex64
,
np
.
complex128
]))
def
test_sht2
(
self
,
lm
,
tp
):
a
=
ift
.
LMSpace
(
lmax
=
lm
)
b
=
ift
.
HPSpace
(
nside
=
lm
//
2
)
fft
=
ift
.
FFTOperator
(
domain
=
a
,
target
=
b
)
inp
=
ift
.
Field
.
from_random
(
domain
=
a
,
random_type
=
'normal'
,
std
=
1
,
mean
=
0
,
dtype
=
tp
)
out
=
fft
.
inverse_times
(
fft
.
times
(
inp
))
assert_allclose
(
ift
.
dobj
.
to_global_data
(
inp
.
val
),
ift
.
dobj
.
to_global_data
(
out
.
val
),
rtol
=
1e-3
,
atol
=
1e-1
)
#
@expand(product([128, 256],
#
[np.float64, np.float32, np.complex64, np.complex128]))
#
def test_sht2(self, lm, tp):
#
a = ift.LMSpace(lmax=lm)
#
b = ift.HPSpace(nside=lm//2)
#
fft = ift.FFTOperator(domain=a, target=b)
#
inp = ift.Field.from_random(domain=a, random_type='normal',
#
std=1, mean=0, dtype=tp)
#
out = fft.inverse_times(fft.times(inp))
#
assert_allclose(ift.dobj.to_global_data(inp.val),
#
ift.dobj.to_global_data(out.val), rtol=1e-3, atol=1e-1)
@
expand
(
product
([
128
,
256
],
[
np
.
float64
,
np
.
float32
,
np
.
complex64
,
np
.
complex128
]))
...
...
test/test_operators/test_response_operator.py
View file @
315d1848
...
...
@@ -17,6 +17,8 @@ class ResponseOperator_Tests(unittest.TestCase):
@
expand
(
product
(
spaces
,
[
0.
,
5.
,
1.
],
[
0.
,
1.
,
.
33
]))
def
test_times_adjoint_times
(
self
,
space
,
sigma
,
exposure
):
if
not
isinstance
(
space
,
ift
.
RGSpace
):
# no smoothing supported
sigma
=
0.
op
=
ift
.
ResponseOperator
(
space
,
sigma
=
[
sigma
],
exposure
=
[
exposure
])
rand1
=
ift
.
Field
.
from_random
(
'normal'
,
domain
=
space
)
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new 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