function-plot
function-plot copied to clipboard
Document return type of FunctionPlotDatum.fn functions
The string syntax for specifying a fn
is nice, but I prefer to implement my function as an actual Function. For example, instead of fn: 'x^2'
, I wish to use fn: (x) => Math.pow(x, 2)
.
One reason is that the string syntax doesn't support non-integer exponents, demanding that I convert to nth-root instead:
"power is not an integer, you should use nth-root instead, returning an empty interval"
Some experimentation and digging suggests that it is possible to provide an actual function rather than a string, but also that the expected return type is not a number. Nor is the argument a number; with the default sampler (which I think is "interval"), the argument is shaped like:
{ x: { lo: number, hi: number } }
However, none of the following work as a return value:
-
{ y: { lo: number, hi: number } }
(my first guess, which seemed reasonable, and seems like it must be right because the "interval1d" sampler appears to rely on this code to assess the return value) -
[ number, number ]
-
number
And the docs (I think that's the relevant type) specify the return type as any
, which seems like it can't be right; the prose only addresses the interpretation of the string type.
I'd recommend two changes to this documentation:
- change the return type of this:
(scope: FunctionPlotDatumScope) => any
from "any" to some union type - add more prose entries that describe when each item in that union type is appropriate
More digging reveals that the return value (in my scenario) should be shaped like one of your Intervals: { lo: number, hi: number }
. However: it is not true that the return lo
should be based on the sample's x.lo
, but that it must be the lower of the two output values. That is: if the curve implemented curves downward, such that f(lo)
> f(hi)
, then the return values must be swapped.
My curve is like that, so I'm doing this:
// `n` comes from a closure; I'm simultaneously plotting a single expression for multiple values
fn: ( sample ) => ({
hi: n - Math.pow(sample.x.lo, 2),
lo: n - Math.pow(sample.x.hi, 2)
})
A version guaranteed to work in any scenario would do the math on the low and high inputs and then sort them, like so:
fn: (sample) => {
let [ lo, hi ] = [
n - Math.pow(sample.x.lo, 2),
n - Math.pow(sample.x.hi, 2)
].sort()
return { lo, hi }
}
thanks for the report, would this be solved by the hull
function? e.g.
import Interval from 'interval-arithmetic'
// ...
fn: (sample) => {
const t = {
hi: n - Math.pow(sample.x.lo, 2),
lo: n - Math.pow(sample.x.hi, 2)
}
return Interval.hull(t, t)
}
I'm not familiar with the term "hull," but the implementation of that function seems like it does what is needed. That said, it also seems like kind of a weird fit, since it requires two intervals, whereas what's needed here is just to "normalize" a single interval.
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.