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

Add d3.linspace. #150

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
11 changes: 10 additions & 1 deletion README.md
Expand Up @@ -652,7 +652,7 @@ Returns a new interval [*niceStart*, *niceStop*] covering the given interval [*s

<a name="range" href="#range">#</a> d3.<b>range</b>([<i>start</i>, ]<i>stop</i>[, <i>step</i>]) · [Source](https://github.com/d3/d3-array/blob/main/src/range.js), [Examples](https://observablehq.com/@d3/d3-range)

Returns an array containing an arithmetic progression, similar to the Python built-in [range](http://docs.python.org/library/functions.html#range). This method is often used to iterate over a sequence of uniformly-spaced numeric values, such as the indexes of an array or the ticks of a linear scale. (See also [d3.ticks](#ticks) for nicely-rounded values.)
Returns an array containing an arithmetic progression, similar to the Python built-in [range](http://docs.python.org/library/functions.html#range). This method is often used to iterate over a sequence of uniformly-spaced numeric values, such as the indexes of an array or the ticks of a linear scale. (See also [d3.ticks](#ticks) for nicely-rounded values, and [d3.linspace](#linspace) if you prefer to specify the number of values rather than the step.)

If *step* is omitted, it defaults to 1. If *start* is omitted, it defaults to 0. The *stop* value is exclusive; it is not included in the result. If *step* is positive, the last element is the largest *start* + *i* \* *step* less than *stop*; if *step* is negative, the last element is the smallest *start* + *i* \* *step* greater than *stop*. If the returned array would contain an infinite number of values, an empty range is returned.

Expand All @@ -671,6 +671,15 @@ d3.range(0, 1, 1 / 49); // BAD: returns 50 elements!
d3.range(49).map(function(d) { return d / 49; }); // GOOD: returns 49 elements.
```

<a name="linspace" href="#linspace">#</a> d3.<b>linspace</b>(<i>start</i>, <i>stop</i>[, <i>n</i>][, <i>endpoint</i>]) · [Source](https://github.com/d3/d3-array/blob/main/src/linspace.js)<!-- , [Examples](https://observablehq.com/@d3/d3-linspace) -->

Returns an array containing an arithmetic progression of *n* values ranging from *start* to *end*, including *end* if *endpoint* is requested. Similar to numpy’s [linspace](https://numpy.org/doc/stable/reference/generated/numpy.linspace.html). Defaults to *n* = 50 and *endpoint* = true.

```js
d3.linspace(0, 1, 101); // [0, 0.01, 0.02, …, 0.99, 1]
d3.linspace(1, 0, 10, false); // [1, 0.9, 0.8, …, 0.1]
```

<a name="transpose" href="#transpose">#</a> d3.<b>transpose</b>(<i>matrix</i>) · [Source](https://github.com/d3/d3-array/blob/main/src/transpose.js), [Examples](https://observablehq.com/@d3/d3-transpose)

Uses the [zip](#zip) operator as a two-dimensional [matrix transpose](http://en.wikipedia.org/wiki/Transpose).
Expand Down
1 change: 1 addition & 0 deletions src/index.js
Expand Up @@ -30,6 +30,7 @@ export {default as quantile, quantileSorted} from "./quantile.js";
export {default as quickselect} from "./quickselect.js";
export {default as range} from "./range.js";
export {default as rank} from "./rank.js";
export {default as linspace} from "./linspace.js";
export {default as least} from "./least.js";
export {default as leastIndex} from "./leastIndex.js";
export {default as greatest} from "./greatest.js";
Expand Down
12 changes: 12 additions & 0 deletions src/linspace.js
@@ -0,0 +1,12 @@
export default function(start, stop, n = 50, endpoint = true) {
n = Math.floor(n), start = +start, stop = (stop - start) / (endpoint ? n - 1 : n);

var i = -1,
range = new Array(n);

while (++i < n) {
range[i] = start + i * stop;
}

return range;
}
25 changes: 25 additions & 0 deletions test/linspace-test.js
@@ -0,0 +1,25 @@
import assert from "assert";
import {linspace} from "../src/index.js";

it("linspace(start, stop)", () => {
assert.deepStrictEqual(linspace(0, 49), [
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
40, 41, 42, 43, 44, 45, 46, 47, 48, 49
]);
});

it("linspace(start, stop, n)", () => {
assert.deepStrictEqual(linspace(2, 3, 5), [2, 2.25, 2.5, 2.75, 3]);
});

it("linspace(start, stop, n, false)", () => {
assert.deepStrictEqual(linspace(2, 3, 5, false), [2, 2.2, 2.4, 2.6, 2.8]);
});

it("linspace(start, stop, n) descending", () => {
assert.deepStrictEqual(linspace(5, 1, 5), [5, 4, 3, 2, 1]);
assert.deepStrictEqual(linspace(5, 0, 5, false), [5, 4, 3, 2, 1]);
});