-
Notifications
You must be signed in to change notification settings - Fork 105
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
Op repr updates #1394
base: master
Are you sure you want to change the base?
Op repr updates #1394
Conversation
Checking updated PR...
Comment last updated on August 30, 2018 at 21:51 Hours UTC |
odl/discr/diff_ops.py
Outdated
[[ 2., 2., 2., 2., -3.], | ||
[ 2., 2., 2., 2., -4.], | ||
[ -1., -2., -3., -4., -12.]] | ||
) | ||
|
||
Verify adjoint: | ||
|
||
>>> g = div.range.element(data ** 2) | ||
>>> adj_div_g = div.adjoint(g) |
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.
Remove line
Hey, could someone please have a look at this? It may seem like a daunting task with so many lines of diff, but it's actually not that much. Most of it is documentation and doesn't need that close of a look, in the sense that errors that slip through won't break anything. I've listed the most important changes above. |
I'll try to review this! |
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.
Overall good changes, but this really should have been 2 or even 3 different pull requests since it does wastly different things.
The only thing that needs discussion is the general addition of ranges where it does not seem obviously needed. Why has this been done?
.isort.cfg
Outdated
@@ -0,0 +1,14 @@ | |||
[settings] |
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.
More spam of the top level directory. Why do we need this?
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.
That file slipped through, I'll ditch it.
posargs = [self.domain] | ||
optargs = [('range', self.range, self.domain ** self.domain.ndim), |
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.
Was this a misstake?
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.
That was a bug, yes. Copy 'n paste from Gradient
I suppose.
@@ -12,20 +12,21 @@ | |||
operators. | |||
""" | |||
|
|||
from __future__ import print_function, division, absolute_import | |||
from __future__ import absolute_import, division, print_function |
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.
Is this just standardization? If so (for next time), I'd prefer if it had a separate PR and was done to all of these occurances.
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.
Yeah I ran isort
on the imports, so I don't have to think about where to put new imports. They'll be sorted and grouped nicely automatically.
I already did a few of the files in #1380, this part of the big PR #1276 just continues that. IMO the structure of the imports is better this way, compared to the "random" ordering we had before.
odl/discr/discr_mappings.py
Outdated
-------- | ||
>>> rect = odl.IntervalProd([0, 0], [1, 1]) | ||
>>> fspace = odl.FunctionSpace(rect) | ||
>>> part = odl.uniform_partition_fromintv(rect, shape=(4, 2)) |
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.
Do we need to use this very length version instead of the shorter options?
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.
Maybe not...
>>> resampling_inv(resampling([0.0, 1.0, 0.0])) | ||
uniform_discr(0.0, 1.0, 3).element([ 0., 1., 0.]) | ||
|
||
However, it can fail in the other direction: |
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.
Extremely nice doc!
odl/operator/pspace_ops.py
Outdated
|
||
Examples | ||
-------- | ||
All rows and columns with an operator, i.e., domain and range |
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.
Wording could be improved. E.g. use something else that "with an operator", perhaps even drop it and only go with "Domain and range are inferred if there is at least one operator per row/column", or similar.
odl/operator/pspace_ops.py
Outdated
[0, IdentityOperator(rn(3))]] | ||
) | ||
|
||
Domain not completely determined (column with all zeros): |
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.
Mention that we need to give domain in this case.
odl/operator/pspace_ops.py
Outdated
Domain not completely determined (column with all zeros): | ||
|
||
>>> prod_op = odl.ProductSpaceOperator([[I, 0], | ||
... [I, 0]], domain=pspace) |
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.
Push domain to next row
odl/operator/pspace_ops.py
Outdated
@@ -655,66 +672,70 @@ def __init__(self, space, index): | |||
|
|||
Projection on the 0-th component: | |||
|
|||
>>> proj_adj = odl.ComponentProjectionAdjoint(pspace, 0) | |||
>>> proj_adj = odl.ComponentProjection(pspace, 0).adjoint |
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.
Is there a reason we think users might not want this "embeding"? I'm not 100% sure we only want this accessible like this.
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.
I didn't really think about that. My assumption, given the name, was that it was just there as a "slave" to the "master" class ComponentProjection
.
The class may certainly be of use on its own, if I think about it. How about we call it ComponentEmbedding
? (It feels like we discussed this before.)
@@ -427,7 +439,8 @@ def examples(self): | |||
self.element(np.random.uniform(size=self.shape) + | |||
np.random.uniform(size=self.shape) * 1j)) | |||
else: | |||
# TODO: return something that always works, like zeros or ones? | |||
# TODO(kohr-h): return something that always works, like zeros |
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.
For non-numeric dtypes there is basically nothing left. What would zeros be for e.g. strings?
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.
I think zeros
actually works with any type, meaningful or not.
>>> np.zeros(2, dtype=bool)
array([False, False], dtype=bool)
>>> np.zeros(2, dtype="U2")
array(['', ''],
dtype='<U2')
>>> np.ones(2, dtype=bool)
array([ True, True], dtype=bool)
>>> np.ones(2, dtype="U2")
array(['1', '1'],
dtype='<U2')
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.
I'll be damned
>>> np.zeros(2, dtype=object)
array([0, 0], dtype=object)
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.
Yeah I think that one at least makes a bit of sense. Doesn't matter for us since we don't allow dtype=object
. I personally find np.ones
with string type hilarious.
odl/discr/discr_ops.py
Outdated
>>> resampling = odl.Resampling(coarse_discr, fine_discr) | ||
>>> resampling_inv = resampling.inverse | ||
|
||
The inverse is proper left inverse if the resampling goes from a |
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.
slight wording issue
@@ -258,6 +259,21 @@ def astype(self, dtype): | |||
else: | |||
return self._astype(dtype) | |||
|
|||
def asweighted(self, weighting): |
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.
How about this? It's going to be needed at some point, but not strictly here.
Another idea with this functionality would be to stuff it inside astype
in kwargs
, and to extend that function with more stuff that we might want to change. For instance interpolation, impl
, or even trivial stuff like axis labels.
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.
Bumping this
ac9aaa8
to
67f5b17
Compare
67f5b17
to
958e0a0
Compare
This is largely done, up to some open questions. |
I marked this as obsolete. It can be considered as a cherry-pick-from PR. So keeping it open until the changes are implemented some other way. |
(I just realized that this is based on the #1380 branch, so that should go in first.)Ready for review now.
Here's the next bunch of commits from #1276, kept to the minimum of space, discr and operator. Other submodules follow.
Biggest changes:
__repr__
makes use of the new functionality with automatic line width adjustment (usingnp.get_printoptions()['linewidth']
).__repr__
methods now have a doctest, to make sure the code runs and does something useful at least in one case.range
got it now....Base
with common children to inner class pattern to share context.Questionable stuff:
asweighted
, not quite sure about thisrepr
doesn't quite work that well with linewidth. The reason is that it callsrepr(parent_op)
without knowing about the correct linewidth to use, and then appends its attribute string. I don't quite know how to solve this, but it doesn't feel like a pressing issue either.range
for product space operators (e.g.,PointwiseInner
), we need to consider spaces as compatible (in this narrow context) that have different weightings but are otherwise the same. Needs some thought about the consequences though.Additional changes/fixes:
Operator
is better now IMO__str__
mostly, doesn't really add value very often. The baseOperator
class defaults to__str__ = __repr__
(not literally).isort.cfg
.TODOs (after review):
numpy.getprintoptions()['precision']
.isort.cfg
into a separate PRto/dev/null