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
93d877c3
Commit
93d877c3
authored
Aug 25, 2016
by
theos
Browse files
First implementation of power spectrum analysis.
parent
01c352f0
Changes
3
Hide whitespace changes
Inline
Side-by-side
nifty/field.py
View file @
93d877c3
from
__future__
import
division
import
numpy
as
np
import
pylab
as
pl
from
d2o
import
distributed_data_object
,
\
STRATEGIES
as
DISTRIBUTION_STRATEGIES
...
...
@@ -9,10 +8,10 @@ from nifty.config import about,\
nifty_configuration
as
gc
,
\
dependency_injector
as
gdi
from
nifty.field_types
import
FieldType
,
\
FieldArray
from
nifty.field_types
import
FieldType
from
nifty.spaces.space
import
Space
from
nifty.spaces.power_space
import
PowerSpace
import
nifty.nifty_utilities
as
utilities
from
nifty.random
import
Random
...
...
@@ -24,6 +23,7 @@ COMM = getattr(gdi[gc['mpi_module']], gc['default_comm'])
class
Field
(
object
):
# ---Initialization methods---
def
__init__
(
self
,
domain
=
None
,
val
=
None
,
dtype
=
None
,
field_type
=
None
,
datamodel
=
None
,
copy
=
False
):
...
...
@@ -125,8 +125,8 @@ class Field(object):
"ERROR: Invalid datamodel!"
))
return
datamodel
# ---Factory methods---
@
classmethod
def
from_random
(
cls
,
random_type
,
domain
=
None
,
dtype
=
None
,
field_type
=
None
,
datamodel
=
None
,
**
kwargs
):
...
...
@@ -177,7 +177,109 @@ class Field(object):
return
random_arguments
def
power_analyze
(
self
,
spaces
=
None
,
log
=
False
,
nbin
=
None
,
binbounds
=
None
):
# check if the spaces input is valid
spaces
=
utilities
.
cast_axis_to_tuple
(
spaces
,
len
(
self
.
domain
))
if
spaces
is
None
:
if
len
(
self
.
domain
)
==
1
:
spaces
=
(
0
,)
else
:
raise
ValueError
(
about
.
_errors
.
cstring
(
"ERROR: Field has multiple spaces as domain "
"but `spaces` is None."
))
if
len
(
spaces
)
==
0
:
raise
ValueError
(
about
.
_errors
.
cstring
(
"ERROR: No space for analysis specified."
))
elif
len
(
spaces
)
>
1
:
raise
ValueError
(
about
.
_errors
.
cstring
(
"ERROR: Conversion of only one space at a time is allowed."
))
space_index
=
spaces
[
0
]
if
not
self
.
domain
[
space_index
].
harmonic
:
raise
ValueError
(
about
.
_errors
.
cstring
(
"ERROR: Conversion of only one space at a time is allowed."
))
# create the target PowerSpace instance
distribution_strategy
=
\
self
.
val
.
get_axes_local_distribution_strategy
(
self
.
domain_axes
[
space_index
])
harmonic_domain
=
self
.
domain
[
space_index
]
power_domain
=
PowerSpace
(
harmonic_domain
=
harmonic_domain
,
datamodel
=
distribution_strategy
,
log
=
log
,
nbin
=
nbin
,
binbounds
=
binbounds
)
# extract pindex and rho from power_domain and calculate the spectrum
pindex
=
power_domain
.
pindex
rho
=
power_domain
.
rho
power_spectrum
=
self
.
_calculate_power_spectrum
(
x
=
self
.
val
,
pindex
=
pindex
,
rho
=
rho
,
axes
=
self
.
domain_axes
[
space_index
])
# create the result field and put power_spectrum into it
result_domain
=
list
(
self
.
domain
)
result_domain
[
space_index
]
=
power_domain
result_field
=
self
.
copy_empty
(
domain
=
result_domain
)
result_field
.
set_val
(
new_val
=
power_spectrum
,
copy
=
False
)
return
result_field
def
_calculate_power_spectrum
(
self
,
x
,
pindex
,
rho
,
axes
=
None
):
fieldabs
=
abs
(
x
)
fieldabs
**=
2
if
axes
is
not
None
:
pindex
=
self
.
_shape_up_pindex
(
pindex
=
pindex
,
target_shape
=
x
.
shape
,
target_strategy
=
x
.
distribution_strategy
,
axes
=
axes
)
power_spectrum
=
pindex
.
bincount
(
weights
=
fieldabs
,
axis
=
axes
)
if
axes
is
not
None
:
new_rho_shape
=
[
1
,
]
*
len
(
power_spectrum
.
shape
)
new_rho_shape
[
axes
[
0
]]
=
len
(
rho
)
rho
=
rho
.
reshape
(
new_rho_shape
)
power_spectrum
/=
rho
power_spectrum
**=
0.5
return
power_spectrum
def
_shape_up_pindex
(
self
,
pindex
,
target_shape
,
target_strategy
,
axes
):
if
pindex
.
distribution_strategy
not
in
\
DISTRIBUTION_STRATEGIES
[
'global'
]:
raise
ValueError
(
"ERROR: pindex's distribution strategy must be "
"global-type"
)
if
pindex
.
distribution_strategy
in
DISTRIBUTION_STRATEGIES
[
'slicing'
]:
if
((
0
not
in
axes
)
or
(
target_strategy
is
not
pindex
.
distribution_strategy
)):
raise
ValueError
(
"ERROR: A slicing distributor shall not be reshaped to "
"something non-sliced."
)
semiscaled_shape
=
[
1
,
]
*
len
(
target_shape
)
for
i
in
axes
:
semiscaled_shape
[
i
]
=
target_shape
[
i
]
local_data
=
pindex
.
get_local_data
(
copy
=
False
)
semiscaled_local_data
=
local_data
.
reshape
(
semiscaled_shape
)
result_obj
=
pindex
.
copy_empty
(
global_shape
=
target_shape
,
distribution_strategy
=
target_strategy
)
result_obj
.
set_full_data
(
semiscaled_local_data
,
copy
=
False
)
return
result_obj
def
power_synthesize
(
self
):
# check that all spaces in self.domain are real or instances of power_space
# check if field is real- or complex-valued
# ---Properties---
def
set_val
(
self
,
new_val
=
None
,
copy
=
False
):
new_val
=
self
.
cast
(
new_val
)
if
copy
:
...
...
@@ -237,6 +339,7 @@ class Field(object):
return
0
# ---Special unary/binary operations---
def
cast
(
self
,
x
=
None
,
dtype
=
None
):
if
dtype
is
None
:
dtype
=
self
.
dtype
...
...
@@ -429,6 +532,7 @@ class Field(object):
return
work_field
# ---General unary/contraction methods---
def
__pos__
(
self
):
return
self
.
copy
()
...
...
nifty/spaces/power_space/power_space.py
View file @
93d877c3
# -*- coding: utf-8 -*-
import
numpy
as
np
from
d2o
import
STRATEGIES
from
power_index_factory
import
PowerIndexFactory
...
...
@@ -131,49 +130,3 @@ class PowerSpace(Space):
def
rho
(
self
):
return
self
.
_rho
def
calculate_power_spectrum
(
self
,
x
,
axes
=
None
):
fieldabs
=
abs
(
x
)
fieldabs
**=
2
pindex
=
self
.
pindex
if
axes
is
not
None
:
pindex
=
self
.
_shape_up_pindex
(
pindex
=
pindex
,
target_shape
=
x
.
shape
,
target_strategy
=
x
.
distribution_strategy
,
axes
=
axes
)
power_spectrum
=
pindex
.
bincount
(
weights
=
fieldabs
,
axis
=
axes
)
rho
=
self
.
rho
if
axes
is
not
None
:
new_rho_shape
=
[
1
,
]
*
len
(
power_spectrum
.
shape
)
new_rho_shape
[
axes
[
0
]]
=
len
(
rho
)
rho
=
rho
.
reshape
(
new_rho_shape
)
power_spectrum
/=
rho
power_spectrum
**=
0.5
return
power_spectrum
def
_shape_up_pindex
(
self
,
pindex
,
target_shape
,
target_strategy
,
axes
):
if
pindex
.
distribution_strategy
not
in
STRATEGIES
[
'global'
]:
raise
ValueError
(
"ERROR: pindex's distribution strategy must be "
"global-type"
)
if
pindex
.
distribution_strategy
in
STRATEGIES
[
'slicing'
]:
if
((
0
not
in
axes
)
or
(
target_strategy
is
not
pindex
.
distribution_strategy
)):
raise
ValueError
(
"ERROR: A slicing distributor shall not be reshaped to "
"something non-sliced."
)
semiscaled_shape
=
[
1
,
]
*
len
(
target_shape
)
for
i
in
axes
:
semiscaled_shape
[
i
]
=
target_shape
[
i
]
local_data
=
pindex
.
get_local_data
(
copy
=
False
)
semiscaled_local_data
=
local_data
.
reshape
(
semiscaled_shape
)
result_obj
=
pindex
.
copy_empty
(
global_shape
=
target_shape
,
distribution_strategy
=
target_strategy
)
result_obj
.
set_full_data
(
semiscaled_local_data
,
copy
=
False
)
return
result_obj
nifty/spaces/rg_space/rg_space.py
View file @
93d877c3
...
...
@@ -269,28 +269,3 @@ class RGSpace(Space):
temp
=
np
.
empty
(
len
(
self
.
shape
),
dtype
=
bool
)
temp
[:]
=
zerocenter
return
tuple
(
temp
)
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