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
55c9fea0
Commit
55c9fea0
authored
Apr 01, 2018
by
Martin Reinecke
Browse files
first steps
parent
9740e2f3
Changes
8
Hide whitespace changes
Inline
Side-by-side
nifty4/library/wiener_filter_curvature.py
View file @
55c9fea0
...
@@ -40,4 +40,4 @@ def WienerFilterCurvature(R, N, S, inverter):
...
@@ -40,4 +40,4 @@ def WienerFilterCurvature(R, N, S, inverter):
The minimizer to use during numerical inversion
The minimizer to use during numerical inversion
"""
"""
op
=
SandwichOperator
(
R
,
N
.
inverse
)
+
S
.
inverse
op
=
SandwichOperator
(
R
,
N
.
inverse
)
+
S
.
inverse
return
InversionEnabler
(
op
,
inverter
,
S
)
return
InversionEnabler
(
op
,
inverter
,
S
.
inverse
)
nifty4/operators/adjoint_operator.py
deleted
100644 → 0
View file @
9740e2f3
# 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-2018 Max-Planck-Society
#
# NIFTy is being developed at the Max-Planck-Institut fuer Astrophysik
# and financially supported by the Studienstiftung des deutschen Volkes.
from
.linear_operator
import
LinearOperator
class
AdjointOperator
(
LinearOperator
):
"""Adapter class representing the adjoint of a given operator."""
def
__init__
(
self
,
op
):
super
(
AdjointOperator
,
self
).
__init__
()
self
.
_op
=
op
@
property
def
domain
(
self
):
return
self
.
_op
.
target
@
property
def
target
(
self
):
return
self
.
_op
.
domain
@
property
def
capability
(
self
):
return
self
.
_adjointCapability
[
self
.
_op
.
capability
]
@
property
def
adjoint
(
self
):
return
self
.
_op
def
apply
(
self
,
x
,
mode
):
return
self
.
_op
.
apply
(
x
,
self
.
_adjointMode
[
mode
])
nifty4/operators/chain_operator.py
View file @
55c9fea0
...
@@ -96,13 +96,15 @@ class ChainOperator(LinearOperator):
...
@@ -96,13 +96,15 @@ class ChainOperator(LinearOperator):
def
target
(
self
):
def
target
(
self
):
return
self
.
_ops
[
0
].
target
return
self
.
_ops
[
0
].
target
@
property
def
_flip_modes
(
self
,
mode
):
def
inverse
(
self
):
if
mode
==
0
:
return
self
.
make
([
op
.
inverse
for
op
in
reversed
(
self
.
_ops
)])
return
self
if
mode
==
1
or
mode
==
2
:
@
property
return
self
.
make
([
op
.
_flip_modes
(
mode
)
def
adjoint
(
self
):
for
op
in
reversed
(
self
.
_ops
)])
return
self
.
make
([
op
.
adjoint
for
op
in
reversed
(
self
.
_ops
)])
if
mode
==
3
:
return
self
.
make
([
op
.
_flip_modes
(
mode
)
for
op
in
self
.
_ops
])
raise
ValueError
(
"bad operator flipping mode"
)
@
property
@
property
def
capability
(
self
):
def
capability
(
self
):
...
...
nifty4/operators/diagonal_operator.py
View file @
55c9fea0
...
@@ -158,18 +158,20 @@ class DiagonalOperator(EndomorphicOperator):
...
@@ -158,18 +158,20 @@ class DiagonalOperator(EndomorphicOperator):
def
capability
(
self
):
def
capability
(
self
):
return
self
.
_all_ops
return
self
.
_all_ops
@
property
def
_flip_modes
(
self
,
mode
):
def
inverse
(
self
):
if
mode
==
0
:
res
=
self
.
_skeleton
(())
return
self
res
.
_ldiag
=
1.
/
self
.
_ldiag
if
mode
==
1
and
np
.
issubdtype
(
self
.
_ldiag
.
dtype
,
np
.
floating
):
return
res
@
property
def
adjoint
(
self
):
if
np
.
issubdtype
(
self
.
_ldiag
.
dtype
,
np
.
floating
):
return
self
return
self
res
=
self
.
_skeleton
(())
res
=
self
.
_skeleton
(())
res
.
_ldiag
=
self
.
_ldiag
.
conjugate
()
if
mode
==
1
:
res
.
_ldiag
=
self
.
_ldiag
.
conjugate
()
elif
mode
==
2
:
res
.
_ldiag
=
1.
/
self
.
_ldiag
elif
mode
==
3
:
res
.
_ldiag
=
1.
/
self
.
_ldiag
.
conjugate
()
else
:
raise
ValueError
(
"bad operator flipping mode"
)
return
res
return
res
def
draw_sample
(
self
,
dtype
=
np
.
float64
):
def
draw_sample
(
self
,
dtype
=
np
.
float64
):
...
...
nifty4/operators/inversion_enabler.py
View file @
55c9fea0
...
@@ -66,12 +66,14 @@ class InversionEnabler(LinearOperator):
...
@@ -66,12 +66,14 @@ class InversionEnabler(LinearOperator):
if
self
.
_op
.
capability
&
mode
:
if
self
.
_op
.
capability
&
mode
:
return
self
.
_op
.
apply
(
x
,
mode
)
return
self
.
_op
.
apply
(
x
,
mode
)
def
func
(
x
):
return
self
.
_op
.
apply
(
x
,
self
.
_inverseMode
[
mode
])
x0
=
Field
.
zeros
(
self
.
_tgt
(
mode
),
dtype
=
x
.
dtype
)
x0
=
Field
.
zeros
(
self
.
_tgt
(
mode
),
dtype
=
x
.
dtype
)
energy
=
QuadraticEnergy
(
A
=
func
,
b
=
x
,
position
=
x0
)
invmode
=
self
.
_modeTable
[
self
.
INVERSE_BIT
][
self
.
_ilog
[
mode
]]
r
,
stat
=
self
.
_inverter
(
energy
,
preconditioner
=
self
.
_preconditioner
)
invop
=
self
.
_op
.
_flip_modes
(
self
.
_ilog
[
invmode
])
prec
=
self
.
_preconditioner
if
prec
is
not
None
:
prec
=
prec
.
_flip_modes
(
self
.
_ilog
[
mode
])
energy
=
QuadraticEnergy
(
A
=
invop
,
b
=
x
,
position
=
x0
)
r
,
stat
=
self
.
_inverter
(
energy
,
preconditioner
=
prec
)
if
stat
!=
IterationController
.
CONVERGED
:
if
stat
!=
IterationController
.
CONVERGED
:
logger
.
warning
(
"Error detected during operator inversion"
)
logger
.
warning
(
"Error detected during operator inversion"
)
return
r
.
position
return
r
.
position
...
...
nifty4/operators/linear_operator.py
View file @
55c9fea0
...
@@ -48,11 +48,16 @@ class LinearOperator(NiftyMetaBase()):
...
@@ -48,11 +48,16 @@ class LinearOperator(NiftyMetaBase()):
by means of a single integer number.
by means of a single integer number.
"""
"""
_ilog
=
(
-
1
,
0
,
1
,
-
1
,
2
,
-
1
,
-
1
,
-
1
,
3
)
_validMode
=
(
False
,
True
,
True
,
False
,
True
,
False
,
False
,
False
,
True
)
_validMode
=
(
False
,
True
,
True
,
False
,
True
,
False
,
False
,
False
,
True
)
_inverseMode
=
(
0
,
4
,
8
,
0
,
1
,
0
,
0
,
0
,
2
)
_modeTable
=
((
1
,
2
,
4
,
8
),
_inverseCapability
=
(
0
,
4
,
8
,
12
,
1
,
5
,
9
,
13
,
2
,
6
,
10
,
14
,
3
,
7
,
11
,
15
)
(
2
,
1
,
8
,
4
),
_adjointMode
=
(
0
,
2
,
1
,
0
,
8
,
0
,
0
,
0
,
4
)
(
4
,
8
,
1
,
2
),
_adjointCapability
=
(
0
,
2
,
1
,
3
,
8
,
10
,
9
,
11
,
4
,
6
,
5
,
7
,
12
,
14
,
13
,
15
)
(
8
,
4
,
2
,
1
))
_capTable
=
((
0
,
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
,
10
,
11
,
12
,
13
,
14
,
15
),
(
0
,
2
,
1
,
3
,
8
,
10
,
9
,
11
,
4
,
6
,
5
,
7
,
12
,
14
,
13
,
15
),
(
0
,
4
,
8
,
12
,
1
,
5
,
9
,
13
,
2
,
6
,
10
,
14
,
3
,
7
,
11
,
15
),
(
0
,
8
,
4
,
12
,
2
,
10
,
6
,
14
,
1
,
9
,
5
,
13
,
3
,
11
,
7
,
15
))
_addInverse
=
(
0
,
5
,
10
,
15
,
5
,
5
,
15
,
15
,
10
,
15
,
10
,
15
,
15
,
15
,
15
,
15
)
_addInverse
=
(
0
,
5
,
10
,
15
,
5
,
5
,
15
,
15
,
10
,
15
,
10
,
15
,
15
,
15
,
15
,
15
)
_backwards
=
6
_backwards
=
6
_all_ops
=
15
_all_ops
=
15
...
@@ -61,6 +66,8 @@ class LinearOperator(NiftyMetaBase()):
...
@@ -61,6 +66,8 @@ class LinearOperator(NiftyMetaBase()):
INVERSE_TIMES
=
4
INVERSE_TIMES
=
4
ADJOINT_INVERSE_TIMES
=
8
ADJOINT_INVERSE_TIMES
=
8
INVERSE_ADJOINT_TIMES
=
8
INVERSE_ADJOINT_TIMES
=
8
ADJOINT_BIT
=
1
INVERSE_BIT
=
2
def
_dom
(
self
,
mode
):
def
_dom
(
self
,
mode
):
return
self
.
domain
if
(
mode
&
9
)
else
self
.
target
return
self
.
domain
if
(
mode
&
9
)
else
self
.
target
...
@@ -85,14 +92,17 @@ class LinearOperator(NiftyMetaBase()):
...
@@ -85,14 +92,17 @@ class LinearOperator(NiftyMetaBase()):
The domain on which the Operator's output Field lives."""
The domain on which the Operator's output Field lives."""
raise
NotImplementedError
raise
NotImplementedError
def
_flip_modes
(
self
,
mode
):
from
.operator_adapter
import
OperatorAdapter
return
self
if
mode
==
0
else
OperatorAdapter
(
self
,
mode
)
@
property
@
property
def
inverse
(
self
):
def
inverse
(
self
):
"""LinearOperator : the inverse of `self`
"""LinearOperator : the inverse of `self`
Returns a LinearOperator object which behaves as if it were
Returns a LinearOperator object which behaves as if it were
the inverse of this operator."""
the inverse of this operator."""
from
.inverse_operator
import
InverseOperator
return
self
.
_flip_modes
(
self
.
INVERSE_BIT
)
return
InverseOperator
(
self
)
@
property
@
property
def
adjoint
(
self
):
def
adjoint
(
self
):
...
@@ -100,8 +110,7 @@ class LinearOperator(NiftyMetaBase()):
...
@@ -100,8 +110,7 @@ class LinearOperator(NiftyMetaBase()):
Returns a LinearOperator object which behaves as if it were
Returns a LinearOperator object which behaves as if it were
the adjoint of this operator."""
the adjoint of this operator."""
from
.adjoint_operator
import
AdjointOperator
return
self
.
_flip_modes
(
self
.
ADJOINT_BIT
)
return
AdjointOperator
(
self
)
@
staticmethod
@
staticmethod
def
_toOperator
(
thing
,
dom
):
def
_toOperator
(
thing
,
dom
):
...
...
nifty4/operators/
inverse_operato
r.py
→
nifty4/operators/
operator_adapte
r.py
View file @
55c9fea0
...
@@ -20,34 +20,41 @@ from .linear_operator import LinearOperator
...
@@ -20,34 +20,41 @@ from .linear_operator import LinearOperator
import
numpy
as
np
import
numpy
as
np
class
Inverse
Operator
(
LinearOperator
):
class
Operato
rAdapte
r
(
LinearOperator
):
"""
Adapter c
lass representing the inverse
of a given
operator."""
"""
C
lass representing the inverse
and/or adjoint of another
operator."""
def
__init__
(
self
,
op
):
def
__init__
(
self
,
op
,
mode
):
super
(
Inverse
Operator
,
self
).
__init__
()
super
(
Operato
rAdapte
r
,
self
).
__init__
()
self
.
_op
=
op
self
.
_op
=
op
self
.
_mode
=
int
(
mode
)
if
self
.
_mode
<
1
or
self
.
_mode
>
3
:
raise
ValueError
(
"invalid mode"
)
@
property
@
property
def
domain
(
self
):
def
domain
(
self
):
return
self
.
_op
.
target
return
self
.
_op
.
_dom
(
1
<<
self
.
_mode
)
@
property
@
property
def
target
(
self
):
def
target
(
self
):
return
self
.
_op
.
domain
return
self
.
_op
.
_tgt
(
1
<<
self
.
_mode
)
@
property
@
property
def
capability
(
self
):
def
capability
(
self
):
return
self
.
_
inverseC
apab
ility
[
self
.
_op
.
capability
]
return
self
.
_
c
ap
T
ab
le
[
self
.
_mode
]
[
self
.
_op
.
capability
]
@
property
def
_flip_modes
(
self
,
mode
):
def
inverse
(
self
):
newmode
=
mode
^
self
.
_mode
return
self
.
_op
return
self
.
_op
if
newmode
==
0
else
OperatorAdapter
(
self
.
_op
,
newmode
)
def
apply
(
self
,
x
,
mode
):
def
apply
(
self
,
x
,
mode
):
return
self
.
_op
.
apply
(
x
,
self
.
_
inverseMode
[
mode
])
return
self
.
_op
.
apply
(
x
,
self
.
_
modeTable
[
self
.
_mode
][
self
.
_ilog
[
mode
]
]
)
def
draw_sample
(
self
,
dtype
=
np
.
float64
):
def
draw_sample
(
self
,
dtype
=
np
.
float64
):
return
self
.
_op
.
inverse_draw_sample
(
dtype
)
if
self
.
_mode
&
self
.
INVERSE_BIT
:
return
self
.
_op
.
inverse_draw_sample
(
dtype
)
return
self
.
_op
.
draw_sample
(
dtype
)
def
inverse_draw_sample
(
self
,
dtype
=
np
.
float64
):
def
inverse_draw_sample
(
self
,
dtype
=
np
.
float64
):
return
self
.
_op
.
draw_sample
(
dtype
)
if
self
.
_mode
&
self
.
INVERSE_BIT
:
return
self
.
_op
.
draw_sample
(
dtype
)
return
self
.
_op
.
inverse_draw_sample
(
dtype
)
nifty4/operators/scaling_operator.py
View file @
55c9fea0
...
@@ -72,18 +72,18 @@ class ScalingOperator(EndomorphicOperator):
...
@@ -72,18 +72,18 @@ class ScalingOperator(EndomorphicOperator):
else
:
else
:
return
x
*
(
1.
/
np
.
conj
(
self
.
_factor
))
return
x
*
(
1.
/
np
.
conj
(
self
.
_factor
))
@
property
def
_flip_modes
(
self
,
mode
):
def
inverse
(
self
):
if
mode
==
0
:
if
self
.
_factor
!=
0.
:
return
ScalingOperator
(
1.
/
self
.
_factor
,
self
.
_domain
)
from
.inverse_operator
import
InverseOperator
return
InverseOperator
(
self
)
@
property
def
adjoint
(
self
):
if
np
.
issubdtype
(
type
(
self
.
_factor
),
np
.
floating
):
return
self
return
self
return
ScalingOperator
(
np
.
conj
(
self
.
_factor
),
self
.
_domain
)
if
mode
==
1
and
np
.
issubdtype
(
type
(
self
.
_factor
),
np
.
floating
):
return
self
if
mode
==
1
:
return
ScalingOperator
(
np
.
conj
(
self
.
_factor
),
self
.
_domain
)
elif
mode
==
2
:
return
ScalingOperator
(
1.
/
self
.
_factor
,
self
.
_domain
)
elif
mode
==
3
:
return
ScalingOperator
(
1.
/
np
.
conj
(
self
.
_factor
),
self
.
_domain
)
raise
ValueError
(
"bad operator flipping mode"
)
@
property
@
property
def
domain
(
self
):
def
domain
(
self
):
...
@@ -91,8 +91,6 @@ class ScalingOperator(EndomorphicOperator):
...
@@ -91,8 +91,6 @@ class ScalingOperator(EndomorphicOperator):
@
property
@
property
def
capability
(
self
):
def
capability
(
self
):
if
self
.
_factor
==
0.
:
return
self
.
TIMES
|
self
.
ADJOINT_TIMES
return
self
.
_all_ops
return
self
.
_all_ops
def
_sample_helper
(
self
,
fct
,
dtype
):
def
_sample_helper
(
self
,
fct
,
dtype
):
...
...
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