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
9f0346b6
Commit
9f0346b6
authored
Apr 08, 2018
by
Torsten Ensslin
Browse files
Upload New File
parent
3f8ac11c
Pipeline
#26998
passed with stage
in 1 minute and 23 seconds
Changes
1
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
demos/paper_demos/reconstruction.py
0 → 100644
View file @
9f0346b6
# Program to generate figures of article "Information theory for fields"
# by Torsten Ensslin, Annalen der Physik, submitted to special edition
# "Physics of Information" in April 2018
import
numpy
as
np
import
nifty4
as
ift
import
matplotlib.pyplot
as
plt
if
__name__
==
"__main__"
:
np
.
random
.
seed
(
20
)
# Set up physical constants
nu
=
1.
# excitation field level
kappa
=
10.
# diffusion constant
eps
=
1e-8
# small number to tame zero mode
sigma_n
=
0.2
# noise level
sigma_n2
=
sigma_n
**
2
L
=
1.
# Total length of interval or volume the field lives on
nprobes
=
1000
# Number of probes for uncertainty quantification
# Define resolution (pixels per dimension)
N_pixels
=
1024
# Define two data gaps
N1a
=
int
(
0.6
*
N_pixels
)
N1b
=
int
(
0.64
*
N_pixels
)
N2a
=
int
(
0.67
*
N_pixels
)
N2b
=
int
(
0.8
*
N_pixels
)
# Set up derived constants
amp
=
nu
/
(
2
*
kappa
)
# spectral normalization
pow_spec
=
(
lambda
k
:
amp
/
(
eps
+
k
**
2
))
lambda2
=
2
*
kappa
*
sigma_n2
/
nu
# resulting correlation length squared
lambda1
=
np
.
sqrt
(
lambda2
)
pixel_width
=
L
/
N_pixels
x
=
np
.
arange
(
0
,
1
,
pixel_width
)
# Set up the geometry
s_domain
=
ift
.
RGSpace
([
N_pixels
],
distances
=
pixel_width
)
h_domain
=
s_domain
.
get_default_codomain
()
p_domain
=
ift
.
PowerSpace
(
h_domain
)
HT
=
ift
.
HarmonicTransformOperator
(
h_domain
,
s_domain
)
aHT
=
HT
.
adjoint
# Create mock signal
Phi_h
=
ift
.
create_power_operator
(
h_domain
,
power_spectrum
=
pow_spec
)
phi_h
=
Phi_h
.
draw_sample
()
# remove zero mode as this is part of T_0
phi_h
.
val
[
0
]
=
0
phi
=
HT
(
phi_h
)
# Setting up an exemplary response
GeoRem
=
ift
.
GeometryRemover
(
s_domain
)
GeoAdd
=
GeoRem
.
adjoint
d_domain
=
GeoRem
.
target
[
0
]
mask
=
np
.
ones
(
d_domain
.
shape
)
mask
[
N1a
:
N1b
]
=
0.
mask
[
N2a
:
N2b
]
=
0.
mask
=
ift
.
Field
.
from_global_data
(
d_domain
,
mask
)
Mask
=
ift
.
DiagonalOperator
(
mask
)
R0
=
Mask
*
GeoRem
R
=
R0
*
HT
# Linear measurement scenario
N
=
ift
.
ScalingOperator
(
sigma_n2
,
d_domain
)
# Noise covariance
n
=
Mask
(
N
.
draw_sample
())
# seting the noise to zero in masked region
d
=
R
(
phi_h
)
+
n
# Wiener filter
j
=
R
.
adjoint_times
(
N
.
inverse_times
(
d
))
IC
=
ift
.
GradientNormController
(
name
=
"inverter"
,
iteration_limit
=
500
,
tol_abs_gradnorm
=
1e-3
)
inverter
=
ift
.
ConjugateGradient
(
controller
=
IC
)
D
=
(
ift
.
SandwichOperator
(
R
,
N
.
inverse
)
+
Phi_h
.
inverse
).
inverse
D
=
ift
.
InversionEnabler
(
D
,
inverter
,
approximation
=
Phi_h
)
m
=
HT
(
D
(
j
))
# Uncertainty
D
=
ift
.
SandwichOperator
(
aHT
,
D
)
# real space propagator
Dhat
=
ift
.
probe_with_posterior_samples
(
D
.
inverse
,
None
,
nprobes
=
nprobes
)[
1
]
sig
=
ift
.
sqrt
(
Dhat
)
# Plotting
x_mod
=
x
*
mask
.
val
+
2
*
(
1
-
mask
.
val
)
plt
.
rcParams
[
"text.usetex"
]
=
True
plt
.
fill_between
(
x
,
m
.
val
-
sig
.
val
,
m
.
val
+
sig
.
val
,
color
=
'pink'
,
alpha
=
None
)
plt
.
plot
(
x
,
phi
.
val
,
label
=
r
"$\varphi$"
,
color
=
'black'
)
plt
.
scatter
(
x_mod
,
d
.
val
,
label
=
r
'$d$'
,
s
=
1
,
color
=
'blue'
,
alpha
=
0.5
)
plt
.
plot
(
x
,
m
.
val
,
label
=
r
'$m$'
,
color
=
'red'
)
plt
.
xlim
([
0
,
L
])
plt
.
ylim
([
-
1
,
1
])
#plt.xlabel('coordinate')
#plt.ylabel('field value')
plt
.
title
(
'Wiener filter reconstruction'
)
plt
.
legend
()
#plt.show()
plt
.
savefig
(
'Wiener_filter.pdf'
)
plt
.
close
()
# Nonlinear measurement scenario
rho_0
=
pixel_width
R
=
ift
.
ScalingOperator
(
rho_0
,
d_domain
)
*
R
aR
=
R
.
adjoint
def
Response
(
phi_h
):
return
R
(
aHT
(
ift
.
exp
(
3
*
HT
(
phi_h
))))
lam
=
Response
(
phi_h
)
data
=
ift
.
Field
(
d_domain
,
val
=
np
.
random
.
poisson
(
lam
.
val
),
dtype
=
np
.
float64
,
copy
=
True
)
# defining energy, gradient, curvature
class
Hamiltonian
(
ift
.
Energy
):
def
__init__
(
self
,
position
,
inverter
):
super
(
Hamiltonian
,
self
).
__init__
(
position
=
position
)
self
.
_inverter
=
inverter
lam
=
Response
(
position
)
rho
=
3
*
ift
.
exp
(
3
*
HT
(
position
))
Rho
=
ift
.
DiagonalOperator
(
rho
)
eps
=
1e-100
# to catch harmless 0/0 where data is zero
weight
=
(
data
+
eps
)
/
(
lam
**
2
+
eps
)
W
=
ift
.
DiagonalOperator
(
weight
)
prior_energy
=
0.5
*
position
.
vdot
(
Phi_h
.
inverse_adjoint_times
(
position
))
likel_energy
=
lam
.
sum
()
-
data
.
vdot
(
ift
.
log
(
lam
+
eps
))
prior_grad
=
Phi_h
.
inverse_adjoint_times
(
position
)
likel_grad
=
aHT
(
rho
*
HT
(
aR
((
lam
-
data
)
/
(
lam
+
eps
))))
prior_curv
=
Phi_h
.
inverse
# j = R.adjoint((data-lam)/(lam+eps))
# tmp = aHT(3*rho*HT(j))
# like1_curv = ift.DiagonalOperator(tmp) # dangerous term
R1
=
R0
*
Rho
*
HT
aR1
=
R1
.
adjoint
like2_curv
=
ift
.
SandwichOperator
(
R1
,
W
)
# = aR1*W*R1
self
.
_curv
=
prior_curv
+
like2_curv
self
.
_grad
=
prior_grad
+
likel_grad
self
.
_grad
.
lock
()
self
.
_value
=
prior_energy
+
likel_energy
def
at
(
self
,
position
):
return
self
.
__class__
(
position
,
self
.
_inverter
)
@
property
def
value
(
self
):
return
self
.
_value
@
property
def
gradient
(
self
):
return
self
.
_grad
@
property
def
curvature
(
self
):
return
ift
.
InversionEnabler
(
self
.
_curv
,
self
.
_inverter
,
approximation
=
Phi_h
.
inverse
)
# initial guess
psi0
=
ift
.
Field
.
full
(
h_domain
,
1e-7
)
energy
=
Hamiltonian
(
psi0
,
inverter
)
IC1
=
ift
.
GradientNormController
(
name
=
"IC1"
,
iteration_limit
=
200
,
tol_abs_gradnorm
=
1e-4
)
minimizer
=
ift
.
RelaxedNewton
(
IC1
)
energy
=
minimizer
(
energy
)[
0
]
var
=
ift
.
probe_with_posterior_samples
(
energy
.
curvature
,
HT
,
nprobes
)[
1
]
sig
=
ift
.
sqrt
(
var
)
m
=
HT
(
energy
.
position
)
phi
=
HT
(
phi_h
)
plt
.
rcParams
[
"text.usetex"
]
=
True
c1
=
np
.
exp
(
3
*
(
m
.
val
-
sig
.
val
))
c2
=
np
.
exp
(
3
*
(
m
.
val
+
sig
.
val
))
plt
.
fill_between
(
x
,
c1
,
c2
,
color
=
'pink'
,
alpha
=
None
)
plt
.
plot
(
x
,
np
.
exp
(
3
*
phi
.
val
),
label
=
r
"$e^{3\varphi}$"
,
color
=
'black'
)
plt
.
scatter
(
x_mod
,
data
.
val
,
label
=
r
'$d$'
,
s
=
1
,
color
=
'blue'
,
alpha
=
0.5
)
plt
.
plot
(
x
,
np
.
exp
(
3
*
m
.
val
),
label
=
r
'$e^{3\varphi_\mathrm{cl}}$'
,
color
=
'red'
)
plt
.
xlim
([
0
,
L
])
plt
.
ylim
([
-
0.1
,
7.5
])
#plt.xlabel('coordinate')
#plt.ylabel('field value')
plt
.
title
(
'Poisson log-normal reconstruction'
)
plt
.
legend
()
#plt.show()
plt
.
savefig
(
'Poisson.pdf'
)
exit
()
\ No newline at end of file
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