Skip to content

Conversation

@shoyer
Copy link
Contributor

@shoyer shoyer commented Dec 14, 2013

The goal here was to reduce redundant code and consolidate functionality, to facilitate future extensions of iris.analysis operators.

For example, I would like to be able to easily define new cube operations like >, <, >=, <=, &, |, ^ and % that are analogous to the standard numpy operations.

By putting binary operations that involving broadcasting a cube and another object together, it should also be easier to extend the cube broadcasting rules.

This change includes adjusted docstrings to reflect current functionality and removal of code that wasn't doing anything (as caught by pylint). I also fixed unary math operations (abs, log, exp, etc.) to actually calculate values in place when in_place=True. None of the public facing API is changed. That will come next :).

The refactoring did reveal a few places where broadcasting rules differ for no clear reason between add/subtract and multiply/divide. Arguably, the special logic for add/subtract broadcasting should also be consolidated into _binary_op_common so that it used for multiply/divide as well. Also, there is a case for exposing public interfaces to _math_op_common and _binary_op_common to facilitate writing new cube operations, just like how iris.analaysis.Aggregator facilitates writing new cube aggregations.

@rhattersley
Copy link
Member

After a quick overview this looks promising - thanks @shoyer. 😄

(For future reference, putting the code formatting and docstring changes in a separate PR would make it easier to see the other changes.)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By postponing this check until _binary_op_common() the error from not supplying a Cube can change. For example, _assert_matching_units() might raise an AttributeError.

@rhattersley
Copy link
Member

An excellent PR - both the initial description and the code. Thanks again @shoyer. 😄

The only functional change I spotted was the TypeError issue when the cube argument is not a Cube... which suggests there isn't an existing test for that! Would you mind adding one?

@shoyer
Copy link
Contributor Author

shoyer commented Dec 17, 2013

OK, new patch set is up.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Step ahead of yourself here - we don't have that alias. Yet... 😉

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is actually the original error message in this file (I didn't write this)... but fixed anyways!

The goal here was to reduce redundant code and consolidate functionality, to
facilitate future extensions of iris.analysis operators.

For example, I would like to be able to easily define new cube operations like
`>`, `<`, `>=`, `<=`, `&`, `|`, `^` and `%` that are analogous to the standard
numpy operations.

By putting binary operations that involving broadcasting a cube and another
object together, it should also be easier to extend the cube broadcasting
rules.

This change includes adjusted docstrings to reflect current functionality and
removal of code that wasn't doing anything (as caught by pylint). I also fixed
unary math operations (abs, log, exp, etc.) to actually calculate values in
place when `in_place=True`. None of the public facing API is changed. That
will come next :).

The refactoring did reveal a few places where broadcasting rules differ for no
clear reason between add/subtract and multiply/divide. Arguably, the special
logic for add/subtract broadcasting should also be consolidated into
`_binary_op_common` so that it used for multiply/divide as well. Also, there
is a case for exposing public interfaces to `_math_op_common` and
`_binary_op_common` to facilitate writing new cube operations, just like how
`iris.analaysis.Aggregator` facilitates writing new cube aggregations.
@shoyer
Copy link
Contributor Author

shoyer commented Dec 18, 2013

Oops, I seem to have messed up the history a little bit because of a git rebase. Somehow Richard's latest comment got lost in that (edit: here it is)

For now (see this latest patchset), I decided to move the TypeError tests to the tests/test_basic_maths.py.

More broadly, I understand the value in having a uniform directory structure for tests, but I'm not sure it really makes sense to have a separate file for each top-level function or class. I plan on adding about 15 new functions to iris.analysis.maths (corresponding to different numpy array built-ins), each of which will be only a few lines to define. That will be mean a lot of very short test files.

@rhattersley
Copy link
Member

I decided to move the TypeError tests to the tests/test_basic_maths.py.

That's fine - thanks.

... a lot of very short test files.

A lot of short files is fine by me. It's large messy blobs that cause me concern.

@rhattersley
Copy link
Member

OK - I think this is good to go. 👍 I'll leave it a little while to give @pelson a chance to comment and if it's still all clear then merge.

rhattersley added a commit that referenced this pull request Dec 19, 2013
…erations

Refactored internals of iris.analysis.maths
@rhattersley rhattersley merged commit caec006 into SciTools:master Dec 19, 2013
@rhattersley
Copy link
Member

🎉 😀

@shoyer shoyer deleted the refactored-cube-operations branch December 19, 2013 17:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants