-
Notifications
You must be signed in to change notification settings - Fork 107
WIP real-valued functional #1333
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 12 commits
d4e5498
7a278f0
09b1e94
89652b1
69521ba
85650f7
7382635
246a31b
5a55e75
d1c4d68
9003572
77842df
c7a6127
3fa93d9
0951041
0ddd06c
cb6df08
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1071,7 +1071,6 @@ class OperatorSum(Operator): | |
|
||
The sum is only well-defined for `Operator` instances where | ||
`Operator.range` is a `LinearSpace`. | ||
|
||
""" | ||
|
||
def __init__(self, left, right, tmp_ran=None, tmp_dom=None): | ||
|
@@ -1106,8 +1105,14 @@ def __init__(self, left, right, tmp_ran=None, tmp_dom=None): | |
rn(3).element([ 2., 4., 6.]) | ||
""" | ||
if left.range != right.range: | ||
raise OpTypeError('operator ranges {!r} and {!r} do not match' | ||
''.format(left.range, right.range)) | ||
if isinstance(left.range, Field) and \ | ||
isinstance(right.range, Field): | ||
range = left.range + right.range | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just as an aside, you can make this a one-liner without implementing range = max(left.range, right.range, key=lambda s: 0 if s == RealNumbers() else 1) Slightly hackish since it assumes that |
||
else: | ||
raise OpTypeError('operator ranges {!r} and {!r} do not match' | ||
''.format(left.range, right.range)) | ||
else: | ||
range = left.range | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually, I'd prefer not to have any clever mechanism for "fixing" cases that "obviously" should work, like L1Norm(cn(2), range=ComplexNumbers()) + L1Norm(cn(2), range=RealNumbers()) IMO this should fail, and users should explicitly have to use |
||
if not isinstance(left.range, (LinearSpace, Field)): | ||
raise OpTypeError('`left.range` {!r} not a `LinearSpace` or ' | ||
'`Field` instance'.format(left.range)) | ||
|
@@ -1124,7 +1129,7 @@ def __init__(self, left, right, tmp_ran=None, tmp_dom=None): | |
''.format(tmp_dom, left.domain)) | ||
|
||
super(OperatorSum, self).__init__( | ||
left.domain, left.range, | ||
left.domain, range, | ||
linear=left.is_linear and right.is_linear) | ||
self.__left = left | ||
self.__right = right | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -310,6 +310,25 @@ def field(self): | |
""" | ||
return self | ||
|
||
def contains_set(self, other): | ||
raise NotImplementedError('field {!r} does not have method ' | ||
'`contains_set`'.format(self)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This error would already be raised by the parent, wouldn't it? |
||
|
||
def __add__(self, other): | ||
if self.contains_set(other): | ||
return self | ||
elif other.contains_set(self): | ||
return other | ||
else: | ||
raise ValueError('Fields {!r} and {!r} do not include ' | ||
'each other'.format(self, other)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm skeptical towards this. It doesn't fulfill the rules for set addition, and just as a shortcut for something used in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am adding fields, not sets and so I thought I went with the Minkowski addition What would be your suggestion to approach this? At first I did something like There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I was thinking about that definition as well. My point is that IMO, it makes little sense to implement an operation that would be valid (but hard to implement in general) for any The main issue is that the means you chose are way too generic and sweeping for the problem you're trying to solve. Assuming that this problem actually needs to be solved (which it might not, see my other comments), the least invasive solution would be to introduce an ordering of the sets you're looking at and then just use the # At module level
_SET_ORDER = {Integers(): 1, RealNumbers(): 2, ComplexNumbers(): 3}
# Somewhere else
field = max(field1, field2, key=lambda f: _SET_ORDER[f])
# Or making a function (only for internal use)
def _largest_field(*fields):
_SET_ORDER = {Integers(): 1, RealNumbers(): 2, ComplexNumbers(): 3}
return max(fields, key=lambda f: _SET_ORDER[f]) But this would be just a workaround, really. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [look at the comment below first] From my point of view this would be the "obvious" addition for fields. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see... The spaces are homomorph but not isomorph. You were right all along... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🤣 You went on quite a journey there, my mention of finite fields was more like an example.. In some sense you proved my minimal point that it's not trivial to implement set addition and keep it in line with mathematics for arbitrary fields. But it doesn't seem to be necessary here anyway. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I know. But it was fun to try to remember all the maths stuff I learned 5 years ago and never used again. And despite (or maybe because) studying physics I sometimes enjoy to do "recreational maths" 😂 |
||
|
||
def __radd__(self, other): | ||
if other == 0: | ||
return self | ||
else: | ||
return self.__add__(other) | ||
|
||
|
||
class ComplexNumbers(Field): | ||
|
||
|
@@ -428,10 +447,7 @@ def __hash__(self): | |
|
||
def element(self, inp=None): | ||
"""Return a real number from ``inp`` or from scratch.""" | ||
if inp is not None: | ||
return float(inp) | ||
else: | ||
return 0.0 | ||
return float(getattr(inp, 'real', 0.0)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this the way to go? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wouldn't do it this way. The issue is that this maps anything which hasn't got a So I'd prefer this: if inp is None:
return 0.0
else:
return float(getattr(inp, 'real', inp)) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I hadn't thought about that... That is a nice solution! |
||
|
||
@property | ||
def examples(self): | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please no backslash line continuation. To split across lines, use parentheses: