Skip to content

Commit 27a9152

Browse files
author
m.lohmann
committed
Removed addition of fields again, Reverted __repr__ not to include range
1 parent 77842df commit 27a9152

File tree

4 files changed

+79
-80
lines changed

4 files changed

+79
-80
lines changed

odl/operator/operator.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1105,8 +1105,8 @@ def __init__(self, left, right, tmp_ran=None, tmp_dom=None):
11051105
rn(3).element([ 2., 4., 6.])
11061106
"""
11071107
if left.range != right.range:
1108-
if isinstance(left.range, Field) and \
1109-
isinstance(right.range, Field):
1108+
if (isinstance(left.range, Field) and
1109+
isinstance(right.range, Field)):
11101110
range = left.range + right.range
11111111
else:
11121112
raise OpTypeError('operator ranges {!r} and {!r} do not match'

odl/set/sets.py

Lines changed: 4 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -310,25 +310,6 @@ def field(self):
310310
"""
311311
return self
312312

313-
def contains_set(self, other):
314-
raise NotImplementedError('field {!r} does not have method '
315-
'`contains_set`'.format(self))
316-
317-
def __add__(self, other):
318-
if self.contains_set(other):
319-
return self
320-
elif other.contains_set(self):
321-
return other
322-
else:
323-
raise ValueError('Fields {!r} and {!r} do not include '
324-
'each other'.format(self, other))
325-
326-
def __radd__(self, other):
327-
if other == 0:
328-
return self
329-
else:
330-
return self.__add__(other)
331-
332313

333314
class ComplexNumbers(Field):
334315

@@ -447,7 +428,10 @@ def __hash__(self):
447428

448429
def element(self, inp=None):
449430
"""Return a real number from ``inp`` or from scratch."""
450-
return float(getattr(inp, 'real', 0.0))
431+
if inp is None:
432+
return 0.0
433+
else:
434+
return float(getattr(inp, 'real', inp))
451435

452436
@property
453437
def examples(self):

odl/solvers/functional/default_functionals.py

Lines changed: 45 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -182,9 +182,8 @@ def _call(self, x):
182182

183183
def __repr__(self):
184184
"""Return ``repr(self)``."""
185-
return '{}({!r} -> {!r}, {!r})'.format(self.__class__.__name__,
186-
self.domain, self.range,
187-
self.exponent)
185+
return '{}({!r}, {!r})'.format(self.__class__.__name__,
186+
self.domain, self.exponent)
188187

189188

190189
class GroupL1Norm(Functional):
@@ -230,7 +229,7 @@ def __init__(self, vfspace, exponent=None, range=None):
230229
instability. Infinity gives the supremum norm.
231230
Default: ``vfspace.exponent``, usually 2.
232231
range : `Field`, optional
233-
Range of the functional. Default: `vfspace.field`.
232+
Range of the functional. Default: ``vfspace.field``.
234233
235234
Examples
236235
--------
@@ -332,8 +331,8 @@ def convex_conj(self):
332331

333332
def __repr__(self):
334333
"""Return ``repr(self)``."""
335-
return '{}({!r} -> {!r}, exponent={})'.format(self.__class__.__name__,
336-
self.domain, self.range,
334+
return '{}({!r}, exponent={})'.format(self.__class__.__name__,
335+
self.domain,
337336
self.pointwise_norm.exponent)
338337

339338

@@ -426,8 +425,8 @@ def convex_conj(self):
426425

427426
def __repr__(self):
428427
"""Return ``repr(self)``."""
429-
return '{}({!r} -> {!r}, exponent={})'.format(self.__class__.__name__,
430-
self.domain, self.range,
428+
return '{}({!r}, exponent={})'.format(self.__class__.__name__,
429+
self.domain,
431430
self.pointwise_norm.exponent)
432431

433432

@@ -473,7 +472,7 @@ def __init__(self, domain, exponent, range=None):
473472
exponent : int or infinity
474473
Specifies wich norm to use.
475474
range : `Field`, optional
476-
Range of the functional. Default: `domain.field`.
475+
Range of the functional. Default: ``domain.field``.
477476
"""
478477
super(IndicatorLpUnitBall, self).__init__(domain=domain, linear=False,
479478
range=range)
@@ -543,9 +542,8 @@ def proximal(self):
543542

544543
def __repr__(self):
545544
"""Return ``repr(self)``."""
546-
return '{}({!r} -> {!r},{!r})'.format(self.__class__.__name__,
547-
self.domain, self.range,
548-
self.exponent)
545+
return '{}({!r},{!r})'.format(self.__class__.__name__,
546+
self.domain, self.exponent)
549547

550548

551549
class L1Norm(LpNorm):
@@ -591,8 +589,7 @@ def __init__(self, domain, range=None):
591589

592590
def __repr__(self):
593591
"""Return ``repr(self)``."""
594-
return '{}({!r} -> {!r})'.format(self.__class__.__name__,
595-
self.domain, self.range)
592+
return '{}({!r})'.format(self.__class__.__name__, self.domain)
596593

597594

598595
class L2Norm(LpNorm):
@@ -631,8 +628,7 @@ def __init__(self, domain, range=None):
631628

632629
def __repr__(self):
633630
"""Return ``repr(self)``."""
634-
return '{}({!r} -> {!r})'.format(self.__class__.__name__,
635-
self.domain, self.range)
631+
return '{}({!r})'.format(self.__class__.__name__, self.domain)
636632

637633

638634
class L2NormSquared(Functional):
@@ -712,8 +708,7 @@ def convex_conj(self):
712708

713709
def __repr__(self):
714710
"""Return ``repr(self)``."""
715-
return '{}({!r} -> {!r})'.format(self.__class__.__name__,
716-
self.domain, self.range)
711+
return '{}({!r})'.format(self.__class__.__name__, self.domain)
717712

718713

719714
class ConstantFunctional(Functional):
@@ -733,7 +728,7 @@ def __init__(self, domain, constant, range=None):
733728
constant : element in ``domain.field``
734729
The constant value of the functional
735730
range : `Field`, optional
736-
Range of the functional. Default: `domain.field`.
731+
Range of the functional. Default: ``domain.field``.
737732
"""
738733
super(ConstantFunctional, self).__init__(
739734
domain=domain, linear=(constant == 0), grad_lipschitz=0,
@@ -777,9 +772,8 @@ def convex_conj(self):
777772

778773
def __repr__(self):
779774
"""Return ``repr(self)``."""
780-
return '{}({!r} -> {!r}, {!r})'.format(self.__class__.__name__,
781-
self.domain, self.range,
782-
self.constant)
775+
return '{}({!r}, {!r})'.format(self.__class__.__name__,
776+
self.domain, self.constant)
783777

784778

785779
class ZeroFunctional(ConstantFunctional):
@@ -794,15 +788,14 @@ def __init__(self, domain, range=None):
794788
domain : `LinearSpace`
795789
Domain of the functional.
796790
range : `Field`, optional
797-
Range of the functional. Default: `domain.field`.
791+
Range of the functional. Default: ``domain.field``.
798792
"""
799793
super(ZeroFunctional, self).__init__(domain=domain, constant=0,
800794
range=range)
801795

802796
def __repr__(self):
803797
"""Return ``repr(self)``."""
804-
return '{}({!r} -> {!r})'.format(self.__class__.__name__,
805-
self.domain, self.range)
798+
return '{}({!r})'.format(self.__class__.__name__, self.domain)
806799

807800

808801
class ScalingFunctional(Functional, ScalingOperator):
@@ -890,7 +883,7 @@ def __init__(self, domain, lower=None, upper=None, range=None):
890883
The upper bound.
891884
Default: `+infinity`
892885
range : `Field`, optional
893-
Range of the functional. Default: `domain.field`.
886+
Range of the functional. Default: ``domain.field``.
894887
895888
Examples
896889
--------
@@ -919,9 +912,9 @@ def proximal(self):
919912

920913
def __repr__(self):
921914
"""Return ``repr(self)``."""
922-
return '{}({!r} -> {!r}, {!r}, {!r})'.format(self.__class__.__name__,
923-
self.domain, self.range,
924-
self.lower, self.upper)
915+
return '{}({!r}, {!r}, {!r})'.format(self.__class__.__name__,
916+
self.domain,
917+
self.lower, self.upper)
925918

926919

927920
class IndicatorNonnegativity(IndicatorBox):
@@ -947,7 +940,7 @@ def __init__(self, domain, range=None):
947940
domain : `LinearSpace`
948941
Domain of the functional.
949942
range : `Field`, optional
950-
Range of the functional. Default: `domain.field`.
943+
Range of the functional. Default: ``domain.field``.
951944
952945
Examples
953946
--------
@@ -963,8 +956,7 @@ def __init__(self, domain, range=None):
963956

964957
def __repr__(self):
965958
"""Return ``repr(self)``."""
966-
return '{}({!r} -> {!r})'.format(self.__class__.__name__,
967-
self.domain, self.range)
959+
return '{}({!r})'.format(self.__class__.__name__, self.domain)
968960

969961

970962
class IndicatorZero(Functional):
@@ -984,7 +976,7 @@ def __init__(self, domain, constant=0, range=None):
984976
constant : element in ``domain.field``, optional
985977
The constant value of the functional
986978
range : `Field`, optional
987-
Range of the functional. Default: `domain.field`.
979+
Range of the functional. Default: ``domain.field``.
988980
989981
Examples
990982
--------
@@ -1051,9 +1043,8 @@ def zero_proximal(sigma=1.0):
10511043

10521044
def __repr__(self):
10531045
"""Return ``repr(self)``."""
1054-
return '{}({!r} -> {!r}, {!r})'.format(self.__class__.__name__,
1055-
self.domain, self.range,
1056-
self.constant)
1046+
return '{}({!r}, {!r})'.format(self.__class__.__name__,
1047+
self.domain, self.constant)
10571048

10581049

10591050
class KullbackLeibler(Functional):
@@ -1220,9 +1211,8 @@ def convex_conj(self):
12201211

12211212
def __repr__(self):
12221213
"""Return ``repr(self)``."""
1223-
return '{}({!r} -> {!r}, {!r})'.format(self.__class__.__name__,
1224-
self.domain, self.range,
1225-
self.prior)
1214+
return '{}({!r}, {!r})'.format(self.__class__.__name__,
1215+
self.domain, self.prior)
12261216

12271217

12281218
class KullbackLeiblerConvexConj(Functional):
@@ -1690,7 +1680,14 @@ def __init__(self, *functionals):
16901680
# Make a power space if the second argument is an integer
16911681
if (len(functionals) == 2 and isinstance(functionals[1], Integral)):
16921682
functionals = [functionals[0]] * functionals[1]
1693-
range = sum(func.range for func in functionals)
1683+
for func1 in functionals:
1684+
if all(func1.range.contains_set(func2.range)
1685+
for func2 in functionals):
1686+
range = func1.range
1687+
break
1688+
else:
1689+
raise ValueError('No functional range contained all other ranges '
1690+
'in SeparableSum of {!r}'.format(functionals))
16941691

16951692
domains = [func.domain for func in functionals]
16961693
domain = ProductSpace(*domains)
@@ -1777,8 +1774,7 @@ def convex_conj(self):
17771774
def __repr__(self):
17781775
"""Return ``repr(self)``."""
17791776
func_repr = ', '.join(repr(func) for func in self.functionals)
1780-
return '{}({} -> {!r})'.format(self.__class__.__name__,
1781-
func_repr, self.range)
1777+
return '{}({})'.format(self.__class__.__name__, func_repr)
17821778

17831779

17841780
class QuadraticForm(Functional):
@@ -2146,10 +2142,9 @@ def convex_conj(self):
21462142

21472143
def __repr__(self):
21482144
"""Return ``repr(self)``."""
2149-
return '{}({!r} -> {!r}, {}, {})'.format(self.__class__.__name__,
2150-
self.domain, self.range,
2151-
self.outernorm.exponent,
2152-
self.pwisenorm.exponent)
2145+
return '{}({!r}, {}, {})'.format(self.__class__.__name__, self.domain,
2146+
self.outernorm.exponent,
2147+
self.pwisenorm.exponent)
21532148

21542149

21552150
class IndicatorNuclearNormUnitBall(Functional):
@@ -2193,7 +2188,7 @@ def __init__(self, domain, outer_exp=1, singular_vector_exp=2, range=None):
21932188
singular_vector_exp : {1, 2, inf}, optional
21942189
Exponent for the norm for the singular vectors.
21952190
range : `Field`, optional
2196-
Range of the functional. Default: `domain.field`.
2191+
Range of the functional. Default: ``domain.field``.
21972192
Examples
21982193
--------
21992194
Simple example, nuclear norm of matrix valued function with all ones
@@ -2243,10 +2238,9 @@ def convex_conj(self):
22432238

22442239
def __repr__(self):
22452240
"""Return ``repr(self)``."""
2246-
return '{}({!r} -> {!r}, {}, {})'.format(self.__class__.__name__,
2247-
self.domain, self.range,
2248-
self.__norm.outernorm.exponent,
2249-
self.__norm.pwisenorm.exponent)
2241+
return '{}({!r}, {}, {})'.format(self.__class__.__name__, self.domain,
2242+
self.__norm.outernorm.exponent,
2243+
self.__norm.pwisenorm.exponent)
22502244

22512245

22522246
class MoreauEnvelope(Functional):

odl/solvers/functional/functional.py

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -48,21 +48,21 @@ class Functional(Operator):
4848
<http://odlgroup.github.io/odl/guide/in_depth/functional_guide.html>`_.
4949
"""
5050

51-
def __init__(self, domain, linear=False, grad_lipschitz=np.nan,
52-
range=None):
51+
def __init__(self, domain, range=None, linear=False,
52+
grad_lipschitz=np.nan):
5353
"""Initialize a new instance.
5454
5555
Parameters
5656
----------
5757
domain : `LinearSpace`
5858
The domain of this functional, i.e., the set of elements to
5959
which this functional can be applied.
60+
range : `Field`, optional
61+
Range of the functional. Default: ``domain.field``.
6062
linear : bool, optional
6163
If `True`, the functional is considered as linear.
6264
grad_lipschitz : float, optional
6365
The Lipschitz constant of the gradient. Default: ``nan``
64-
range : `Field`, optional
65-
Range of the functional. Default: `domain.field`.
6666
"""
6767
# Cannot use `super(Functional, self)` here since that breaks
6868
# subclasses with multiple inheritance (at least those where both
@@ -745,7 +745,14 @@ def __init__(self, left, right):
745745
if not isinstance(right, Functional):
746746
raise TypeError('`right` {!r} is not a `Functional` instance'
747747
''.format(right))
748-
range = left.range + right.range
748+
if left.range.contains_set(right.range):
749+
range = left.range
750+
elif right.range.contains_set(left.range):
751+
range = right.range
752+
else:
753+
raise ValueError('The ranges of the `Functionals` in the sum '
754+
'({!r} and {!r}) do not contain one another'
755+
''.format(left.range, right.range))
749756

750757
Functional.__init__(
751758
self, domain=left.domain,
@@ -1171,7 +1178,14 @@ def __init__(self, left, right):
11711178
if not isinstance(right, Functional):
11721179
raise TypeError('`right` {} is not a `Functional` instance'
11731180
''.format(right))
1174-
range = left.range + right.range
1181+
if left.range.contains_set(right.range):
1182+
range = left.range
1183+
elif right.range.contains_set(left.range):
1184+
range = right.range
1185+
else:
1186+
raise ValueError('The ranges of the `Functionals` in the product '
1187+
'({!r} and {!r}) do not contain one another'
1188+
''.format(left.range, right.range))
11751189

11761190
OperatorPointwiseProduct.__init__(self, left, right)
11771191
Functional.__init__(self, left.domain, linear=False,
@@ -1232,7 +1246,14 @@ def __init__(self, dividend, divisor):
12321246
raise TypeError('`divisor` {} is not a `Functional` instance'
12331247
''.format(divisor))
12341248

1235-
range = dividend.range + divisor.range
1249+
if dividend.range.contains_set(divisor.range):
1250+
range = dividend.range
1251+
elif divisor.range.contains_set(dividend.range):
1252+
range = divisor.range
1253+
else:
1254+
raise ValueError('The ranges of the `Functionals` in the quotient '
1255+
'({!r} and {!r}) do not contain one another'
1256+
''.format(dividend.range, divisor.range))
12361257

12371258
self.__dividend = dividend
12381259
self.__divisor = divisor

0 commit comments

Comments
 (0)