@thi.ng/distance
Advanced tools
Comparing version 0.2.2 to 0.3.0
@@ -6,2 +6,14 @@ # Change Log | ||
# [0.3.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/distance@0.2.2...@thi.ng/distance@0.3.0) (2021-04-19) | ||
### Features | ||
* **distance:** add argmin*() fns ([72ed376](https://github.com/thi-ng/umbrella/commit/72ed3760c7a6982bcab7d94666957cad90f4f0ef)) | ||
* **distance:** replace HAVERSINE w/ alts ([3a9a77a](https://github.com/thi-ng/umbrella/commit/3a9a77ab0fd06484f2fda5d67c7b151645436a32)) | ||
## [0.2.2](https://github.com/thi-ng/umbrella/compare/@thi.ng/distance@0.2.1...@thi.ng/distance@0.2.2) (2021-04-07) | ||
@@ -8,0 +20,0 @@ |
import { ReadonlyVec } from "@thi.ng/vectors"; | ||
import { Eucledian } from "./eucledian"; | ||
/** | ||
* Distance metric for geo locations given as [lat,lon] vectors. | ||
*/ | ||
export declare const HAVERSINE_LATLON: Eucledian<ReadonlyVec>; | ||
/** | ||
* Distance metric for geo locations given as [lon,lat] vectors. | ||
*/ | ||
export declare const HAVERSINE: Eucledian<ReadonlyVec>; | ||
export declare const HAVERSINE_LONLAT: Eucledian<ReadonlyVec>; | ||
//# sourceMappingURL=haversine.d.ts.map |
@@ -1,6 +0,10 @@ | ||
import { distHaversine } from "@thi.ng/vectors"; | ||
import { distHaversineLatLon, distHaversineLonLat, } from "@thi.ng/vectors"; | ||
import { Eucledian } from "./eucledian"; | ||
/** | ||
* Distance metric for geo locations given as [lat,lon] vectors. | ||
*/ | ||
export const HAVERSINE_LATLON = new Eucledian(distHaversineLatLon); | ||
/** | ||
* Distance metric for geo locations given as [lon,lat] vectors. | ||
*/ | ||
export const HAVERSINE = new Eucledian(distHaversine); | ||
export const HAVERSINE_LONLAT = new Eucledian(distHaversineLonLat); |
export * from "./api"; | ||
export * from "./argmin"; | ||
export * from "./eucledian"; | ||
export * from "./haversine"; | ||
export * from "./knearest"; | ||
export * from "./manhattan"; | ||
export * from "./nearest"; | ||
export * from "./squared"; | ||
export * from "./knearest"; | ||
export * from "./nearest"; | ||
//# sourceMappingURL=index.d.ts.map |
export * from "./api"; | ||
export * from "./argmin"; | ||
export * from "./eucledian"; | ||
export * from "./haversine"; | ||
export * from "./knearest"; | ||
export * from "./manhattan"; | ||
export * from "./nearest"; | ||
export * from "./squared"; | ||
export * from "./knearest"; | ||
export * from "./nearest"; |
102
lib/index.js
@@ -5,42 +5,7 @@ 'use strict'; | ||
var vectors = require('@thi.ng/vectors'); | ||
var api = require('@thi.ng/api'); | ||
var heaps = require('@thi.ng/heaps'); | ||
var math = require('@thi.ng/math'); | ||
var vectors = require('@thi.ng/vectors'); | ||
class Eucledian { | ||
constructor(metric) { | ||
this.metric = metric; | ||
} | ||
to(x) { | ||
return x; | ||
} | ||
from(x) { | ||
return x; | ||
} | ||
} | ||
const EUCLEDIAN = new Eucledian(vectors.dist); | ||
const EUCLEDIAN1 = new Eucledian((a, b) => Math.abs(a - b)); | ||
const EUCLEDIAN2 = new Eucledian(vectors.dist2); | ||
const EUCLEDIAN3 = new Eucledian(vectors.dist3); | ||
const HAVERSINE = new Eucledian(vectors.distHaversine); | ||
class Manhattan { | ||
constructor(dim, metric) { | ||
this.dim = dim; | ||
this.metric = metric; | ||
this._invD = this.dim / Math.sqrt(dim); | ||
} | ||
to(x) { | ||
return x * this._invD; | ||
} | ||
from(x) { | ||
return Math.sqrt((x / this.dim) ** 2 * this.dim); | ||
} | ||
} | ||
const defManhattan = (dim) => new Manhattan(dim, vectors.distManhattan); | ||
const MANHATTAN2 = new Manhattan(2, vectors.distManhattan2); | ||
const MANHATTAN3 = new Manhattan(3, vectors.distManhattan3); | ||
class Squared { | ||
@@ -109,2 +74,60 @@ constructor(metric) { | ||
const argmin = (p, samples, { metric: dist } = DIST_SQ) => { | ||
let minD = Infinity; | ||
let minArg = -1; | ||
for (let i = 0, n = samples.length; i < n; i++) { | ||
const d = dist(p, samples[i]); | ||
if (d < minD) { | ||
minD = d; | ||
minArg = i; | ||
} | ||
} | ||
return minArg; | ||
}; | ||
const argminT = (p, samples, key, dist) => argmin(key(p), samples.map(key), dist); | ||
const argminK = (k, p, samples, dist = DIST_SQ) => { | ||
const neighborhood = knearest(p, k, Infinity, dist); | ||
for (let i = 0, n = samples.length; i < n; i++) { | ||
neighborhood.consider(samples[i], i); | ||
} | ||
return neighborhood.values(); | ||
}; | ||
const argminKT = (k, p, samples, key, dist) => argminK(k, key(p), samples.map(key), dist); | ||
class Eucledian { | ||
constructor(metric) { | ||
this.metric = metric; | ||
} | ||
to(x) { | ||
return x; | ||
} | ||
from(x) { | ||
return x; | ||
} | ||
} | ||
const EUCLEDIAN = new Eucledian(vectors.dist); | ||
const EUCLEDIAN1 = new Eucledian((a, b) => Math.abs(a - b)); | ||
const EUCLEDIAN2 = new Eucledian(vectors.dist2); | ||
const EUCLEDIAN3 = new Eucledian(vectors.dist3); | ||
const HAVERSINE_LATLON = new Eucledian(vectors.distHaversineLatLon); | ||
const HAVERSINE_LONLAT = new Eucledian(vectors.distHaversineLonLat); | ||
class Manhattan { | ||
constructor(dim, metric) { | ||
this.dim = dim; | ||
this.metric = metric; | ||
this._invD = this.dim / Math.sqrt(dim); | ||
} | ||
to(x) { | ||
return x * this._invD; | ||
} | ||
from(x) { | ||
return Math.sqrt((x / this.dim) ** 2 * this.dim); | ||
} | ||
} | ||
const defManhattan = (dim) => new Manhattan(dim, vectors.distManhattan); | ||
const MANHATTAN2 = new Manhattan(2, vectors.distManhattan2); | ||
const MANHATTAN3 = new Manhattan(3, vectors.distManhattan3); | ||
class Nearest { | ||
@@ -153,3 +176,4 @@ constructor(dist, target, radius = Infinity) { | ||
exports.Eucledian = Eucledian; | ||
exports.HAVERSINE = HAVERSINE; | ||
exports.HAVERSINE_LATLON = HAVERSINE_LATLON; | ||
exports.HAVERSINE_LONLAT = HAVERSINE_LONLAT; | ||
exports.KNearest = KNearest; | ||
@@ -161,2 +185,6 @@ exports.MANHATTAN2 = MANHATTAN2; | ||
exports.Squared = Squared; | ||
exports.argmin = argmin; | ||
exports.argminK = argminK; | ||
exports.argminKT = argminKT; | ||
exports.argminT = argminT; | ||
exports.defManhattan = defManhattan; | ||
@@ -163,0 +191,0 @@ exports.knearest = knearest; |
@@ -1,1 +0,1 @@ | ||
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("@thi.ng/vectors"),require("@thi.ng/api"),require("@thi.ng/heaps"),require("@thi.ng/math")):"function"==typeof define&&define.amd?define(["exports","@thi.ng/vectors","@thi.ng/api","@thi.ng/heaps","@thi.ng/math"],e):e(((t="undefined"!=typeof globalThis?globalThis:t||self).thi=t.thi||{},t.thi.ng=t.thi.ng||{},t.thi.ng.distance={}),t.thi.ng.vectors,t.thi.ng.api,t.thi.ng.heaps,t.thi.ng.math)}(this,(function(t,e,s,i,r){"use strict";class n{constructor(t){this.metric=t}to(t){return t}from(t){return t}}const h=new n(e.dist),a=new n(((t,e)=>Math.abs(t-e))),u=new n(e.dist2),c=new n(e.dist3),d=new n(e.distHaversine);class o{constructor(t,e){this.dim=t,this.metric=e,this._invD=this.dim/Math.sqrt(t)}to(t){return t*this._invD}from(t){return Math.sqrt((t/this.dim)**2*this.dim)}}const l=new o(2,e.distManhattan2),p=new o(3,e.distManhattan3);class m{constructor(t){this.metric=t}to(t){return t*t}from(t){return Math.sqrt(t)}}const f=new m(e.distSq),g=new m(((t,e)=>(t-e)**2)),_=new m(e.distSq2),w=new m(e.distSq3);class v{constructor(t,e,n,h=1/0,a=!1){this.dist=t,this.target=e,this.k=n,this.sorted=a,this._heap=new i.Heap(null,{compare:(t,e)=>e[0]-t[0]}),s.assert(n>0,"invalid k (must be > 0)"),this.radius=r.clamp0(h),this.reset()}reset(){return this._currR=this.dist.to(this.radius),this._heap.clear(),this}deref(){return this.sorted?this._heap.max():this._heap.values}values(){return this.deref().map((t=>t[1]))}includesDistance(t,e=!0){return(e?this.dist.to(t):t)<=this._currR}consider(t,e){const s=this.dist.metric(this.target,t);if(s<=this._currR){const t=this._heap;t.length===this.k?(t.pushPop([s,e]),this._currR=t.peek()[0]):t.push([s,e])}return s}}class N{constructor(t,e,s=1/0){this.dist=t,this.target=e,this.radius=r.clamp0(s),this.reset()}reset(){return this._currR=this.dist.to(this.radius),this.value=void 0,this}deref(){return null!=this.value?[this._currR,this.value]:void 0}includesDistance(t,e=!0){return(e?this.dist.to(t):t)<=this._currR}consider(t,e){const s=this.dist.metric(this.target,t);return s<=this._currR&&(this._currR=s,this.value=e),s}}t.DIST_SQ=f,t.DIST_SQ1=g,t.DIST_SQ2=_,t.DIST_SQ3=w,t.EUCLEDIAN=h,t.EUCLEDIAN1=a,t.EUCLEDIAN2=u,t.EUCLEDIAN3=c,t.Eucledian=n,t.HAVERSINE=d,t.KNearest=v,t.MANHATTAN2=l,t.MANHATTAN3=p,t.Manhattan=o,t.Nearest=N,t.Squared=m,t.defManhattan=t=>new o(t,e.distManhattan),t.knearest=(t,e,s,i=f,r)=>new v(i,t,e,s,r),t.knearest2=(t,e,s,i=_,r)=>new v(i,t,e,s,r),t.knearest3=(t,e,s,i=w,r)=>new v(i,t,e,s,r),t.knearestN=(t,e,s,i=g,r)=>new v(i,t,e,s,r),t.nearest=(t,e,s=f)=>new N(s,t,e),t.nearest2=(t,e,s=_)=>new N(s,t,e),t.nearest3=(t,e,s=w)=>new N(s,t,e),t.nearestN=(t,e,s=g)=>new N(s,t,e),Object.defineProperty(t,"__esModule",{value:!0})})); | ||
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("@thi.ng/api"),require("@thi.ng/heaps"),require("@thi.ng/math"),require("@thi.ng/vectors")):"function"==typeof define&&define.amd?define(["exports","@thi.ng/api","@thi.ng/heaps","@thi.ng/math","@thi.ng/vectors"],e):e(((t="undefined"!=typeof globalThis?globalThis:t||self).thi=t.thi||{},t.thi.ng=t.thi.ng||{},t.thi.ng.distance={}),t.thi.ng.api,t.thi.ng.heaps,t.thi.ng.math,t.thi.ng.vectors)}(this,(function(t,e,s,i,r){"use strict";class n{constructor(t){this.metric=t}to(t){return t*t}from(t){return Math.sqrt(t)}}const h=new n(r.distSq),a=new n(((t,e)=>(t-e)**2)),u=new n(r.distSq2),c=new n(r.distSq3);class o{constructor(t,r,n,h=1/0,a=!1){this.dist=t,this.target=r,this.k=n,this.sorted=a,this._heap=new s.Heap(null,{compare:(t,e)=>e[0]-t[0]}),e.assert(n>0,"invalid k (must be > 0)"),this.radius=i.clamp0(h),this.reset()}reset(){return this._currR=this.dist.to(this.radius),this._heap.clear(),this}deref(){return this.sorted?this._heap.max():this._heap.values}values(){return this.deref().map((t=>t[1]))}includesDistance(t,e=!0){return(e?this.dist.to(t):t)<=this._currR}consider(t,e){const s=this.dist.metric(this.target,t);if(s<=this._currR){const t=this._heap;t.length===this.k?(t.pushPop([s,e]),this._currR=t.peek()[0]):t.push([s,e])}return s}}const d=(t,e,s,i=h,r)=>new o(i,t,e,s,r),l=(t,e,{metric:s}=h)=>{let i=1/0,r=-1;for(let n=0,h=e.length;n<h;n++){const h=s(t,e[n]);h<i&&(i=h,r=n)}return r},m=(t,e,s,i=h)=>{const r=d(e,t,1/0,i);for(let t=0,e=s.length;t<e;t++)r.consider(s[t],t);return r.values()};class p{constructor(t){this.metric=t}to(t){return t}from(t){return t}}const g=new p(r.dist),f=new p(((t,e)=>Math.abs(t-e))),_=new p(r.dist2),w=new p(r.dist3),v=new p(r.distHaversineLatLon),N=new p(r.distHaversineLonLat);class A{constructor(t,e){this.dim=t,this.metric=e,this._invD=this.dim/Math.sqrt(t)}to(t){return t*this._invD}from(t){return Math.sqrt((t/this.dim)**2*this.dim)}}const S=new A(2,r.distManhattan2),T=new A(3,r.distManhattan3);class E{constructor(t,e,s=1/0){this.dist=t,this.target=e,this.radius=i.clamp0(s),this.reset()}reset(){return this._currR=this.dist.to(this.radius),this.value=void 0,this}deref(){return null!=this.value?[this._currR,this.value]:void 0}includesDistance(t,e=!0){return(e?this.dist.to(t):t)<=this._currR}consider(t,e){const s=this.dist.metric(this.target,t);return s<=this._currR&&(this._currR=s,this.value=e),s}}t.DIST_SQ=h,t.DIST_SQ1=a,t.DIST_SQ2=u,t.DIST_SQ3=c,t.EUCLEDIAN=g,t.EUCLEDIAN1=f,t.EUCLEDIAN2=_,t.EUCLEDIAN3=w,t.Eucledian=p,t.HAVERSINE_LATLON=v,t.HAVERSINE_LONLAT=N,t.KNearest=o,t.MANHATTAN2=S,t.MANHATTAN3=T,t.Manhattan=A,t.Nearest=E,t.Squared=n,t.argmin=l,t.argminK=m,t.argminKT=(t,e,s,i,r)=>m(t,i(e),s.map(i),r),t.argminT=(t,e,s,i)=>l(s(t),e.map(s),i),t.defManhattan=t=>new A(t,r.distManhattan),t.knearest=d,t.knearest2=(t,e,s,i=u,r)=>new o(i,t,e,s,r),t.knearest3=(t,e,s,i=c,r)=>new o(i,t,e,s,r),t.knearestN=(t,e,s,i=a,r)=>new o(i,t,e,s,r),t.nearest=(t,e,s=h)=>new E(s,t,e),t.nearest2=(t,e,s=u)=>new E(s,t,e),t.nearest3=(t,e,s=c)=>new E(s,t,e),t.nearestN=(t,e,s=a)=>new E(s,t,e),Object.defineProperty(t,"__esModule",{value:!0})})); |
{ | ||
"name": "@thi.ng/distance", | ||
"version": "0.2.2", | ||
"version": "0.3.0", | ||
"description": "N-dimensional distance metrics & K-nearest neighborhoods for point queries", | ||
@@ -55,3 +55,3 @@ "module": "./index.js", | ||
"@thi.ng/math": "^3.4.0", | ||
"@thi.ng/vectors": "^5.2.2" | ||
"@thi.ng/vectors": "^5.3.0" | ||
}, | ||
@@ -87,3 +87,3 @@ "files": [ | ||
}, | ||
"gitHead": "9d35fc75c08bcfdcd67126b8183c869fda71573a" | ||
"gitHead": "a099b0a1f1c6180819df9cc4786faa5c2b535140" | ||
} |
@@ -36,16 +36,17 @@ <!-- This file is generated - DO NOT EDIT! --> | ||
| **Preset** | **Number** | **n-D** | **2D** | **3D** | **Comments** | | ||
|-------------------|------------|---------|--------|--------|----------------------------------------------------------------------| | ||
| `EUCLEDIAN` | | ✅ | | | Eucledian distance | | ||
| `EUCLEDIAN1` | ✅ | | | | | | ||
| `EUCLEDIAN2` | | | ✅ | | | | ||
| `EUCLEDIAN3` | | | | ✅ | | | ||
| `HAVERSINE` | | | ✅ | | Great-circle distance for lon/lat geo locations | | ||
| `DIST_SQ` | | ✅ | | | Squared dist (avoids `Math.sqrt`) | | ||
| `DIST_SQ1` | ✅ | | | | | | ||
| `DIST_SQ2` | | | ✅ | | | | ||
| `DIST_SQ3` | | | | ✅ | | | ||
| `defManhattan(n)` | | ✅ | | | [Manhattan distance](https://en.wikipedia.org/wiki/Taxicab_geometry) | | ||
| `MANHATTAN2` | | | ✅ | | | | ||
| `MANHATTAN3` | | | | ✅ | | | ||
| **Preset** | **Number** | **nD** | **2D** | **3D** | **Comments** | | ||
|--------------------|------------|--------|--------|--------|----------------------------------------------------------------------| | ||
| `EUCLEDIAN` | | ✅ | | | Eucledian distance | | ||
| `EUCLEDIAN1` | ✅ | | | | | | ||
| `EUCLEDIAN2` | | | ✅ | | | | ||
| `EUCLEDIAN3` | | | | ✅ | | | ||
| `HAVERSINE_LATLON` | | | ✅ | | Great-circle distance for lat/lon geo locations | | ||
| `HAVERSINE_LONLAT` | | | ✅ | | Great-circle distance for lon/lat geo locations | | ||
| `DIST_SQ` | | ✅ | | | Squared dist (avoids `Math.sqrt`) | | ||
| `DIST_SQ1` | ✅ | | | | | | ||
| `DIST_SQ2` | | | ✅ | | | | ||
| `DIST_SQ3` | | | | ✅ | | | ||
| `defManhattan(n)` | | ✅ | | | [Manhattan distance](https://en.wikipedia.org/wiki/Taxicab_geometry) | | ||
| `MANHATTAN2` | | | ✅ | | | | ||
| `MANHATTAN3` | | | | ✅ | | | ||
@@ -111,3 +112,3 @@ ### Neighborhoods | ||
Package sizes (gzipped, pre-treeshake): ESM: 887 bytes / CJS: 994 bytes / UMD: 1.01 KB | ||
Package sizes (gzipped, pre-treeshake): ESM: 1.06 KB / CJS: 1.17 KB / UMD: 1.21 KB | ||
@@ -114,0 +115,0 @@ ## Dependencies |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
72198
26
969
170
Updated@thi.ng/vectors@^5.3.0