Skip to content
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

divide, ln, log, mod: Clarified behavior for 0 input / infinity results #473

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Fixed

- `divide`: Clarified behavior for division by 0
- `ln` and `log`: Clarified that for x = 0 -infinity is returned
- `mod`: Clarified behavior for y = 0
- `filter_bbox`, `load_collection`, `load_stac`: Clarified that the bounding box is reprojected to the CRS of the spatial data cube dimensions if required.
- `filter_spatial`: Clarified that masking is applied using the given geometries. [#469](https://github.com/Open-EO/openeo-processes/issues/469)
- `sqrt`: Clarified that NaN is returned for negative numbers.
Expand Down
4 changes: 2 additions & 2 deletions divide.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"id": "divide",
"summary": "Division of two numbers",
"description": "Divides argument `x` by the argument `y` (*`x / y`*) and returns the computed result.\n\nNo-data values are taken into account so that `null` is returned if any element is such a value.\n\nThe computations follow [IEEE Standard 754](https://ieeexplore.ieee.org/document/8766229) whenever the processing environment supports it. Therefore, a division by zero results in ±infinity if the processing environment supports it. Otherwise, a `DivisionByZero` exception must the thrown.",
"description": "Divides argument `x` by the argument `y` (*`x / y`*) and returns the computed result.\n\nNo-data values are taken into account so that `null` is returned if any element is such a value.\n\nThe computations follow [IEEE Standard 754](https://ieeexplore.ieee.org/document/8766229) whenever the processing environment supports it. A division by zero results in:\n\n- +infinity for `x` > 0,\n- -infinity for `x` < 0,\n- `NaN` for `x` = 0,\n- or otherwise, throws a `DivisionByZero` exception if the other options are not supported by the processing environment.",
Copy link
Member

Choose a reason for hiding this comment

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

+infinity for x > 0,\n- -infinity for x < 0,\n-

I'm not sure this is correct (I'm also not sure how tightened down the spec should be here):
the sign of infinity also depends on which side you're looking from, e.g. 1/y at y=0 is +infinity if you "approach" that limit it from positive y values, but -infinity if you approach it from negative values.

I think there is a bit of discrepancy between rigid mathematical definitions and what is practically feasible in a numerical/computer implementation, so I would not over-specify this. I'm kind of fine with what we had originally, or something like

a division by zero results in ±infinity or NaN, depending on the capabilities of the processing environment.

Copy link
Member

Choose a reason for hiding this comment

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

I also wonder if we should recommend against (or forbid) throwing a DivisionByZero error. If you're processing thousands/millions of pixels you probably prefer a NaN in some output pixels over your whole job failing.

Copy link
Member Author

Choose a reason for hiding this comment

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

I can't specify ±Infinity in tests though, that's why I created this PR overall.

Copy link
Member Author

@m-mohr m-mohr Oct 27, 2023

Choose a reason for hiding this comment

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

I also wonder if we should recommend against (or forbid) throwing a DivisionByZero error. If you're processing thousands/millions of pixels you probably prefer a NaN in some output pixels over your whole job failing.

Well, the error only occurs if your environment doesn't support NaN/Infinity. It's difficult to return NaN if NaN is unsupported ;-)

Copy link
Member

Choose a reason for hiding this comment

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

It's difficult to return NaN if NaN is unsupported

sure, but we could recommend against throwing DivisionByZero if the environment does support NaN

"categories": [
"math"
],
Expand Down Expand Up @@ -76,4 +76,4 @@
"title": "IEEE Standard 754-2019 for Floating-Point Arithmetic"
}
]
}
}
4 changes: 2 additions & 2 deletions ln.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"id": "ln",
"summary": "Natural logarithm",
"description": "The natural logarithm is the logarithm to the base *e* of the number `x`, which equals to using the *log* process with the base set to *e*. The natural logarithm is the inverse function of taking *e* to the power x.\n\nThe no-data value `null` is passed through.\n\nThe computations follow [IEEE Standard 754](https://ieeexplore.ieee.org/document/8766229) whenever the processing environment supports it. Therefore, *`ln(0)`* results in ±infinity if the processing environment supports it or otherwise an exception is thrown.",
"description": "The natural logarithm is the logarithm to the base *e* of the number `x`, which equals to using the *log* process with the base set to *e*. The natural logarithm is the inverse function of taking *e* to the power x.\n\nThe no-data value `null` is passed through.\n\nThe computations follow [IEEE Standard 754](https://ieeexplore.ieee.org/document/8766229) whenever the processing environment supports it. Therefore, *`ln(0)`* results in -infinity if the processing environment supports it. Otherwise, an exception is thrown.",
"categories": [
"math > exponential & logarithmic"
],
Expand Down Expand Up @@ -64,4 +64,4 @@
"result": true
}
}
}
}
4 changes: 2 additions & 2 deletions log.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"id": "log",
"summary": "Logarithm to a base",
"description": "Logarithm to the base `base` of the number `x` is defined to be the inverse function of taking b to the power of x.\n\nThe no-data value `null` is passed through and therefore gets propagated if any of the arguments is `null`.\n\nThe computations follow [IEEE Standard 754](https://ieeexplore.ieee.org/document/8766229) whenever the processing environment supports it. Therefore, `log(0, 2)` results in ±infinity if the processing environment supports it or otherwise an exception is thrown.",
"description": "Logarithm to the base `base` of the number `x` is defined to be the inverse function of taking b to the power of x.\n\nThe no-data value `null` is passed through and therefore gets propagated if any of the arguments is `null`.\n\nThe computations follow [IEEE Standard 754](https://ieeexplore.ieee.org/document/8766229) whenever the processing environment supports it. Therefore, having `x` set to `0` with any base results in -infinity if the processing environment supports it. Otherwise, an exception is thrown.",
m-mohr marked this conversation as resolved.
Show resolved Hide resolved
"categories": [
"math > exponential & logarithmic"
],
Expand Down Expand Up @@ -78,4 +78,4 @@
"title": "IEEE Standard 754-2019 for Floating-Point Arithmetic"
}
]
}
}
4 changes: 2 additions & 2 deletions mod.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"id": "mod",
"summary": "Modulo",
"description": "Remainder after a division of `x` by `y` for both integers and floating-point numbers.\n\nThe result of a modulo operation has the sign of the divisor. The handling regarding the sign of the result [differs between programming languages](https://en.wikipedia.org/wiki/Modulo_operation#In_programming_languages) and needs careful consideration to avoid unexpected results.\n\nThe no-data value `null` is passed through and therefore gets propagated if any of the arguments is `null`. A modulo by zero results in ±infinity if the processing environment supports it. Otherwise, a `DivisionByZero` exception must the thrown.",
"description": "Remainder after a division of `x` by `y` for both integers and floating-point numbers.\n\nThe result of a modulo operation has the sign of the divisor. The handling regarding the sign of the result [differs between programming languages](https://en.wikipedia.org/wiki/Modulo_operation#In_programming_languages) and needs careful consideration to avoid unexpected results.\n\nThe no-data value `null` is passed through and therefore gets propagated if any of the arguments is `null`. If `y` is set to 0 this results in:\n\n- +infinity for `x` > 0,\n- -infinity for `x` < 0,\n- `NaN` for `x` = 0,\n- or otherwise, throws a `DivisionByZero` exception if the other options are not supported by the processing environment.",
"categories": [
"math"
],
Expand Down Expand Up @@ -92,4 +92,4 @@
"title": "Modulo explained by Wikipedia"
}
]
}
}