Skip to content

Commit b4f7175

Browse files
committed
Bumped to 1.0.0 (and included an apparent fix for dimensions > 2).
1 parent eff6d64 commit b4f7175

File tree

6 files changed

+107
-32
lines changed

6 files changed

+107
-32
lines changed

.travis.yml

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
language: node_js
2+
node_js:
3+
- "0.8"
4+
- "0.10"
5+
- "0.12"
6+
before_install:
7+
- npm install -g npm@">=1.4.6"
8+
sudo: false

README.md

+33-13
Original file line numberDiff line numberDiff line change
@@ -2,38 +2,58 @@ ndarray-select
22
==============
33
Finds the kth element in an ndarray in linear time with high probability. This implementation is based on the [quick select algorithm](http://en.wikipedia.org/wiki/Quickselect) and mutates the array in place.
44

5-
# Example
5+
[![build status](https://secure.travis-ci.org/scijs/ndarray-select.png)](http://travis-ci.org/scijs/ndarray-select)
66

7+
## Examples
8+
### Single list
79
```javascript
810
var pack = require("ndarray-pack")
911
var ndselect = require("ndarray-select")
1012

13+
var points = pack([0, 0, 1, 2.5, -1])
14+
15+
//Find the median element in the list
16+
var median = ndselect(points, points.shape[0]>>1)
17+
18+
console.log(median.get())
19+
```
20+
21+
#### Output
22+
```
23+
0 2.5 -1
24+
```
25+
26+
### Multiple lists
27+
It is also possible to select vectors (using lexicographical comparisons):
28+
```javascript
29+
var pack = require("ndarray-pack")
30+
var ndselect = require("ndarray-select")
1131

1232
var points = pack([
1333
[0, 0, 1],
1434
[100, 0, 10],
1535
[50, 1, 10],
1636
[0, 2.5, -1],
17-
18-
// ... etc.
19-
2037
[-1, -1, -1]
2138
])
2239

23-
2440
//Find the median element in the list
2541
var median = ndselect(points, points.shape[0]>>1)
2642

2743
console.log(median.get(0), median.get(1), median.get(2))
2844
```
2945

30-
# Install
31-
32-
```sh
33-
npm install ndarray-select
46+
#### Output
47+
```
48+
0 2.5 -1
3449
```
3550

36-
# API
51+
## Install
52+
Install using [npm](https://www.npmjs.com/):
53+
54+
npm install ndarray-select
55+
56+
## API
3757

3858
```javascript
3959
var ndselect = require("ndarray-select")
@@ -48,16 +68,16 @@ Selects the kth item from the ndarray `array` along the first axis of `array`.
4868

4969
**Returns** An ndarray view of `array.pick(k)`
5070

51-
**Note** This method modifies `array`. After completion, the element at position `k` will be in sorted order, with all elements `<array.pick(k)` occuring before `k` and all elements `>array.pick(k)` after `k` in the list.
71+
**Note** This method modifies `array`. After completion, the element at position `k` will be in sorted order, with all elements `<array.pick(k)` occuring before `k` and all elements `>array.pick(k)` after `k` in the list.
5272

5373
#### `ndselect.compile(order, useCompare, dtype)`
54-
Precompiles an optimized selection algorithm for an array with the given index order and datatype
74+
Precompiles an optimized selection algorithm for an array with the given index order and datatype.
5575

5676
* `order` is the order of the ndarray
5777
* `useCompare` is a flag which if set uses a comparison function
5878
* `dtype` is the datatype of the array
5979

6080
**Returns** An optimized `ndselect` function
6181

62-
# Credits
82+
## License
6383
(c) 2014 Mikola Lysenko. MIT License

example/example.js

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
"use strict"
2+
var pack = require("ndarray-pack")
3+
var ndselect = require("../select.js")
4+
5+
// Vectors
6+
var points = pack([
7+
[0, 0, 1],
8+
[100, 0, 10],
9+
[50, 1, 10],
10+
[0, 2.5, -1],
11+
[-1, -1, -1]
12+
])
13+
14+
//Find the median element in the list
15+
var median = ndselect(points, points.shape[0]>>1)
16+
17+
console.log(median.get(0), median.get(1), median.get(2))
18+
19+
// Matrices
20+
var points = pack([
21+
[[0, 0],[0, 1]],
22+
[[0, 1],[0, 0]],
23+
[[0, 0],[1, 0]],
24+
[[1, 0],[0, 0]],
25+
[[0, 1],[0, 1]]
26+
])
27+
/* Sorted:
28+
[[0, 0],[0, 1]]
29+
[[0, 1],[0, 0]]
30+
[[0, 1],[0, 1]]
31+
[[0, 0],[1, 0]]
32+
[[1, 0],[0, 0]]
33+
*/
34+
//Find the median element in the list
35+
var median = ndselect(points, points.shape[0]>>1)
36+
37+
console.log(require("ndarray-unpack")(median))

package.json

+12-9
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,21 @@
88
},
99
"dependencies": {},
1010
"devDependencies": {
11-
"ndarray": "~1.0.11",
12-
"ndarray-pack": "~1.0.1",
13-
"ndarray-unpack": "~0.0.0",
14-
"tape": "~2.12.3",
15-
"dup": "0.0.0"
11+
"ndarray": "^1.0.18",
12+
"ndarray-pack": "^1.1.1",
13+
"ndarray-unpack": "^1.0.0",
14+
"tape": "^4.0.0",
15+
"dup": "^1.0.0"
1616
},
1717
"scripts": {
1818
"test": "tape test/*.js"
1919
},
2020
"repository": {
2121
"type": "git",
22-
"url": "git://github.com/mikolalysenko/ndarray-select.git"
22+
"url": "git://github.com/scijs/ndarray-select.git"
2323
},
2424
"keywords": [
25+
"scijs",
2526
"quick",
2627
"select",
2728
"median",
@@ -30,9 +31,11 @@
3031
"sort"
3132
],
3233
"author": "Mikola Lysenko",
34+
"contributors": [
35+
"Jasper van de Gronde <[email protected]>"
36+
],
3337
"license": "MIT",
3438
"bugs": {
35-
"url": "https://github.com/mikolalysenko/ndarray-select/issues"
36-
},
37-
"homepage": "https://github.com/mikolalysenko/ndarray-select"
39+
"url": "https://github.com/scijs/ndarray-select/issues"
40+
}
3841
}

select.js

+10-10
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,9 @@ function compileQuickSelect(order, useCompare, dtype) {
7676
INDEX(i) + "=0")
7777
}
7878
for(var i=1; i<dimension; ++i) {
79-
if(i < dimension-1) {
80-
vars.push(STEP_CMP(i) + "=(" + STRIDE(i) + "-" + SHAPE(i+1) + "*" + STRIDE(i+1) + ")|0",
81-
STEP(order[i]) + "=(" + STRIDE(order[i]) + "-" + SHAPE(order[i+1]) + "*" + STRIDE(order[i+1]) + ")|0")
79+
if(i > 1) {
80+
vars.push(STEP_CMP(i) + "=(" + STRIDE(i) + "-" + SHAPE(i-1) + "*" + STRIDE(i-1) + ")|0",
81+
STEP(order[i]) + "=(" + STRIDE(order[i]) + "-" + SHAPE(order[i-1]) + "*" + STRIDE(order[i-1]) + ")|0")
8282
} else {
8383
vars.push(STEP_CMP(i) + "=" + STRIDE(i),
8484
STEP(order[i]) + "=" + STRIDE(order[i]))
@@ -162,19 +162,19 @@ function compileQuickSelect(order, useCompare, dtype) {
162162
PIVOT, "=(", RND, "()*(", HI, "-", LO, "+1)+", LO, ")|0;")
163163

164164
//Partition array by pivot
165-
swap(PIVOT, HI)
165+
swap(PIVOT, HI) // Store pivot temporarily at the end of the array
166166

167167
code.push(
168-
PIVOT, "=", LO, ";",
168+
PIVOT, "=", LO, ";", // PIVOT will now be used to keep track of the end of the interval of elements less than the pivot
169169
"for(", INDEX(0), "=", LO, ";",
170170
INDEX(0), "<", HI, ";",
171-
INDEX(0), "++){")
172-
compare(TMP, INDEX(0), HI)
171+
INDEX(0), "++){") // Loop over other elements (unequal to the pivot), note that HI now points to the pivot
172+
compare(TMP, INDEX(0), HI) // Lexicographical compare of element with pivot
173173
code.push("if(", TMP, "<0){")
174-
swap(PIVOT, INDEX(0))
175-
code.push(PIVOT, "++;")
174+
swap(PIVOT, INDEX(0)) // Swap current element with element at index PIVOT if it is less than the pivot
175+
code.push(PIVOT, "++;")
176176
code.push("}}")
177-
swap(PIVOT, HI)
177+
swap(PIVOT, HI) // Store pivot right after all elements that are less than the pivot (implying that all elements >= the pivot are behind the pivot)
178178

179179
//Check pivot bounds
180180
code.push(

test/test.js

+7
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,13 @@ tape("ndarray-select", function(t) {
117117
[0,0,0,0,6],
118118
])
119119

120+
verifyArray2D([
121+
[0, 0, 1],
122+
[100, 0, 10],
123+
[50, 1, 10],
124+
[0, 2.5, -1],
125+
[-1, -1, -1]
126+
])
120127

121128
ndselect(pack([
122129
[[0,0],

0 commit comments

Comments
 (0)