@woosh/meep-engine 2.96.0 → 2.97.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/meep.cjs +64 -27
- package/build/meep.min.js +1 -1
- package/build/meep.module.js +64 -27
- package/package.json +1 -1
- package/src/core/binary/BitSet.d.ts +2 -2
- package/src/core/binary/BitSet.d.ts.map +1 -1
- package/src/core/binary/BitSet.js +8 -5
- package/src/core/graph/v2/Graph.d.ts.map +1 -1
- package/src/core/graph/v2/Graph.js +9 -0
- package/src/core/math/spline/computeNonuniformCaltmullRomSplineDerivative.d.ts +16 -0
- package/src/core/math/spline/computeNonuniformCaltmullRomSplineDerivative.d.ts.map +1 -0
- package/src/core/math/spline/computeNonuniformCaltmullRomSplineDerivative.js +90 -0
- package/src/core/primitives/strings/string_jaro_distance.d.ts +10 -0
- package/src/core/primitives/strings/string_jaro_distance.d.ts.map +1 -0
- package/src/core/primitives/strings/string_jaro_distance.js +127 -0
- package/src/core/primitives/strings/string_jaro_winkler.d.ts.map +1 -1
- package/src/core/primitives/strings/string_jaro_winkler.js +5 -105
- package/src/engine/graphics/ecs/path/testPathDisplaySystem.js +142 -10
- package/src/engine/graphics/ecs/path/tube/build/TubePathBuilder.d.ts.map +1 -1
- package/src/engine/graphics/ecs/path/tube/build/TubePathBuilder.js +9 -9
- package/src/engine/graphics/ecs/path/tube/build/build_geometry_catmullrom.d.ts.map +1 -1
- package/src/engine/graphics/ecs/path/tube/build/build_geometry_catmullrom.js +173 -23
- package/src/engine/graphics/ecs/path/tube/prototypeAnimatedPathMask.js +16 -2
package/build/meep.module.js
CHANGED
|
@@ -69972,13 +69972,15 @@ BitSet.prototype.setShrinkFactor = function (x) {
|
|
|
69972
69972
|
|
|
69973
69973
|
/**
|
|
69974
69974
|
*
|
|
69975
|
-
* @param {number}
|
|
69975
|
+
* @param {number} bit_count
|
|
69976
69976
|
*/
|
|
69977
|
-
BitSet.prototype.setCapacity = function (
|
|
69978
|
-
|
|
69979
|
-
|
|
69977
|
+
BitSet.prototype.setCapacity = function (bit_count) {
|
|
69978
|
+
|
|
69979
|
+
if (this.__length > bit_count) {
|
|
69980
|
+
throw new Error(`Current length(=${this.__length}) is greater than requested size(=${bit_count})`);
|
|
69980
69981
|
}
|
|
69981
|
-
|
|
69982
|
+
|
|
69983
|
+
this.__resize(bit_count);
|
|
69982
69984
|
};
|
|
69983
69985
|
|
|
69984
69986
|
/**
|
|
@@ -71490,8 +71492,17 @@ class Graph {
|
|
|
71490
71492
|
*/
|
|
71491
71493
|
findPath(start, goal) {
|
|
71492
71494
|
const start_node_container = this.__nodes.get(start);
|
|
71495
|
+
|
|
71496
|
+
if (start_node_container === undefined) {
|
|
71497
|
+
throw new Error(`Start node not found in the graph '${start}'`);
|
|
71498
|
+
}
|
|
71499
|
+
|
|
71493
71500
|
const goal_node_container = this.__nodes.get(goal);
|
|
71494
71501
|
|
|
71502
|
+
if (goal_node_container === undefined) {
|
|
71503
|
+
throw new Error(`Goal node not found in the graph '${goal}'`);
|
|
71504
|
+
}
|
|
71505
|
+
|
|
71495
71506
|
const open = new Set();
|
|
71496
71507
|
open.add(start_node_container);
|
|
71497
71508
|
|
|
@@ -82203,22 +82214,20 @@ function seedVariablesIntoTemplateString(template, seed) {
|
|
|
82203
82214
|
}
|
|
82204
82215
|
|
|
82205
82216
|
/**
|
|
82206
|
-
* Calculate
|
|
82207
|
-
* @param {string} first
|
|
82208
|
-
* @param {string} second
|
|
82209
|
-
* @
|
|
82217
|
+
* Calculate Jaro distance between two strings, this is a measure of string similarity. Higher value means more similarity.
|
|
82218
|
+
* @param {string} first
|
|
82219
|
+
* @param {string} second
|
|
82220
|
+
* @param {number} first_length
|
|
82221
|
+
* @param {number} second_length
|
|
82222
|
+
* @return {number}
|
|
82210
82223
|
*/
|
|
82211
|
-
function
|
|
82212
|
-
|
|
82213
|
-
|
|
82214
|
-
|
|
82215
|
-
if (l1 === 0 && l2 === 0) {
|
|
82216
|
-
// special case for empty string
|
|
82217
|
-
return 1;
|
|
82218
|
-
}
|
|
82224
|
+
function string_jaro_distance(
|
|
82225
|
+
first, second,
|
|
82226
|
+
first_length, second_length
|
|
82227
|
+
) {
|
|
82219
82228
|
|
|
82220
|
-
const matches1 = BitSet.fixedSize(
|
|
82221
|
-
const matches2 = BitSet.fixedSize(
|
|
82229
|
+
const matches1 = BitSet.fixedSize(first_length);
|
|
82230
|
+
const matches2 = BitSet.fixedSize(second_length);
|
|
82222
82231
|
|
|
82223
82232
|
const matches = getMatching(first, second, matches1, matches2);
|
|
82224
82233
|
|
|
@@ -82226,15 +82235,9 @@ function string_jaro_winkler(first, second) {
|
|
|
82226
82235
|
return 0;
|
|
82227
82236
|
}
|
|
82228
82237
|
|
|
82229
|
-
// Calculate the Jaro distance:
|
|
82230
82238
|
const transpositions = getTranspositions(first, second, matches1, matches2);
|
|
82231
|
-
|
|
82239
|
+
return (matches / first_length + matches / second_length + (matches - transpositions) / matches) / 3;
|
|
82232
82240
|
|
|
82233
|
-
// Transform to Jaro-Winkler:
|
|
82234
|
-
// Prefix scale gives more favorable ratings to strings that share common prefixes:
|
|
82235
|
-
const prefix_scale = 0.1;
|
|
82236
|
-
const prefix = getPrefix(first, second, min3(l1, l2, 4));
|
|
82237
|
-
return similarity + prefix * prefix_scale * (1 - similarity);
|
|
82238
82241
|
}
|
|
82239
82242
|
|
|
82240
82243
|
/**
|
|
@@ -82296,8 +82299,12 @@ function getMatching(a1, a2, matches1, matches2) {
|
|
|
82296
82299
|
* @param {string} a2 The second string to compare
|
|
82297
82300
|
* @param {BitSet} matches1
|
|
82298
82301
|
* @param {BitSet} matches2
|
|
82302
|
+
* @returns {number}
|
|
82299
82303
|
*/
|
|
82300
|
-
function getTranspositions(
|
|
82304
|
+
function getTranspositions(
|
|
82305
|
+
a1, a2,
|
|
82306
|
+
matches1, matches2
|
|
82307
|
+
) {
|
|
82301
82308
|
let transpositions = 0;
|
|
82302
82309
|
|
|
82303
82310
|
// Loop to find transpositions:
|
|
@@ -82328,6 +82335,36 @@ function getTranspositions(a1, a2, matches1, matches2) {
|
|
|
82328
82335
|
}
|
|
82329
82336
|
|
|
82330
82337
|
return Math.floor(transpositions * 0.5);
|
|
82338
|
+
}
|
|
82339
|
+
|
|
82340
|
+
/**
|
|
82341
|
+
* Calculate the Jaro-Winkler distance between two strings
|
|
82342
|
+
* @param {string} first The string to compare
|
|
82343
|
+
* @param {string} second The string to compare with
|
|
82344
|
+
* @returns {number} similarity score, higher value means strings are more similar
|
|
82345
|
+
*/
|
|
82346
|
+
function string_jaro_winkler(first, second) {
|
|
82347
|
+
const l1 = first.length;
|
|
82348
|
+
const l2 = second.length;
|
|
82349
|
+
|
|
82350
|
+
if (l1 === 0 && l2 === 0) {
|
|
82351
|
+
// special case for empty string
|
|
82352
|
+
return 1;
|
|
82353
|
+
}
|
|
82354
|
+
|
|
82355
|
+
// Calculate the Jaro distance:
|
|
82356
|
+
const similarity = string_jaro_distance(first, second, l1, l2);
|
|
82357
|
+
|
|
82358
|
+
if (similarity === 0) {
|
|
82359
|
+
// no similarity at all
|
|
82360
|
+
return 0;
|
|
82361
|
+
}
|
|
82362
|
+
|
|
82363
|
+
// Transform to Jaro-Winkler:
|
|
82364
|
+
// Prefix scale gives more favorable ratings to strings that share common prefixes:
|
|
82365
|
+
const prefix_scale = 0.1;
|
|
82366
|
+
const prefix = getPrefix(first, second, min3(l1, l2, 4));
|
|
82367
|
+
return similarity + prefix * prefix_scale * (1 - similarity);
|
|
82331
82368
|
}
|
|
82332
82369
|
|
|
82333
82370
|
/**
|
package/package.json
CHANGED
|
@@ -34,9 +34,9 @@ export class BitSet {
|
|
|
34
34
|
setShrinkFactor(x: number): void;
|
|
35
35
|
/**
|
|
36
36
|
*
|
|
37
|
-
* @param {number}
|
|
37
|
+
* @param {number} bit_count
|
|
38
38
|
*/
|
|
39
|
-
setCapacity(
|
|
39
|
+
setCapacity(bit_count: number): void;
|
|
40
40
|
/**
|
|
41
41
|
* Number of bits currently used for flags.
|
|
42
42
|
* @returns {number}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BitSet.d.ts","sourceRoot":"","sources":["../../../../src/core/binary/BitSet.js"],"names":[],"mappings":"AA6DA;;;GAGG;AACH,+BA0BC;;IAzBG;;;;OAIG;IACH,iBAAiB;IAEjB;;;;OAIG;IACH,mBAAoB;IAEpB;;;;OAIG;IACH,sBAA0D;IAE1D;;OAEG;IACH,gBAFU,MAAM,CAEmB;IAGvC,sBAEC;IAED;;;OAGG;IACH,mBAFW,MAAM,QAOhB;IAED;;;OAGG;IACH,
|
|
1
|
+
{"version":3,"file":"BitSet.d.ts","sourceRoot":"","sources":["../../../../src/core/binary/BitSet.js"],"names":[],"mappings":"AA6DA;;;GAGG;AACH,+BA0BC;;IAzBG;;;;OAIG;IACH,iBAAiB;IAEjB;;;;OAIG;IACH,mBAAoB;IAEpB;;;;OAIG;IACH,sBAA0D;IAE1D;;OAEG;IACH,gBAFU,MAAM,CAEmB;IAGvC,sBAEC;IAED;;;OAGG;IACH,mBAFW,MAAM,QAOhB;IAED;;;OAGG;IACH,uBAFW,MAAM,QAUhB;IAED;;;OAGG;IACH,QAFa,MAAM,CAIlB;IAED;;;OAGG;IACH,YAFa,MAAM,CAIlB;IAO2B,iBAsB3B;IAED,uBAMC;IAO8B,oBAyB9B;IAED;;;;OAIG;IACH,oCAqCC;IAED;;;;OAIG;IACH,4BAFa,MAAM,CAuDlB;IAED;;;;OAIG;IACH,8BAFa,MAAM,CAkDlB;IAED;;;;OAIG;IACH,0BAFW,OAAO,QAmCjB;IAED;;;OAGG;IACH,2BAEC;IAED;;;;OAIG;IACH,qBAHW,MAAM,YACN,MAAM,QAWhB;IAED;;;;OAIG;IACH,uBAHW,MAAM,YACN,MAAM,QAShB;IAGD;;;OAGG;IACH,SAFW,MAAM,SAIhB;IAED;;;;OAIG;IACH,oBAFa,OAAO,CAkBnB;IAED;;;;OAIG;IACH,iBAHW,MAAM,GACJ,OAAO,CAUnB;IAED;;;;OAIG;IACH,mBAHW,MAAM,GACJ,OAAO,CAUnB;IAED;;;;;OAKG;IACH,sBAJW,MAAM,eACN,MAAM,aACN,MAAM,QAShB;IAED;;;;;OAKG;IACH,qBAJW,MAAM,eACN,MAAM,aACN,MAAM,QAShB;IAED;;;;;OAKG;IACH,gBAJW,MAAM,eACN,MAAM,aACN,MAAM,QAQhB;IAED;;OAEG;IACH,cAgBC;IAED;;;OAGG;IACH,YAFW,MAAM,QAoChB;;;IAED;;;;OAIG;IACH,sCASC"}
|
|
@@ -108,13 +108,16 @@ BitSet.prototype.setShrinkFactor = function (x) {
|
|
|
108
108
|
|
|
109
109
|
/**
|
|
110
110
|
*
|
|
111
|
-
* @param {number}
|
|
111
|
+
* @param {number} bit_count
|
|
112
112
|
*/
|
|
113
|
-
BitSet.prototype.setCapacity = function (
|
|
114
|
-
|
|
115
|
-
|
|
113
|
+
BitSet.prototype.setCapacity = function (bit_count) {
|
|
114
|
+
assert.isNonNegativeInteger(bit_count, "bit_count");
|
|
115
|
+
|
|
116
|
+
if (this.__length > bit_count) {
|
|
117
|
+
throw new Error(`Current length(=${this.__length}) is greater than requested size(=${bit_count})`);
|
|
116
118
|
}
|
|
117
|
-
|
|
119
|
+
|
|
120
|
+
this.__resize(bit_count);
|
|
118
121
|
};
|
|
119
122
|
|
|
120
123
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Graph.d.ts","sourceRoot":"","sources":["../../../../../src/core/graph/v2/Graph.js"],"names":[],"mappings":"AAyBA;;GAEG;AACH;IAEI;;;;;OAKG;IACH,yBAAoB;IACpB;;;;;OAKG;IACH,yBAAoB;IAEpB;;OAEG;IACH;QACI;;WAEG;mBADO,OAAO,CAAC,EAAC,IAAI,CAAC;QAGxB;;WAEG;qBADO,OAAO,CAAC,EAAC,IAAI,CAAC;;;MAK1B;IAGF;;;;OAIG;IACH,cAHW,CAAC,GACC,OAAO,CAInB;IAED;;;;OAIG;IACH,cAHW,CAAC,GACC,OAAO,CAenB;IAED;;;;OAIG;IACH,iBAHW,CAAC,GACC,OAAO,CAiBnB;IAED;;;;OAIG;IACH,8BAHoB,CAAC,+BAOpB;IAED,wBAEC;IAED;;;OAGG;IACH,gBAFa,MAAM,CAIlB;IAED;;;;;OAKG;IACH,wBAJoB,CAAC,KAAE,OAAO,kBAEjB,CAAC,GAAC,SAAS,CAgBvB;IAED;;;;OAIG;IACH,uBAHW,CAAC,GACC,cAAc,CAAC,CAAC,GAAC,SAAS,CAItC;IAED;;;;OAIG;IACH,oBAHW,CAAC,GACA,MAAM,CAUjB;IAED;;;OAGG;IACH,iBAEC;IAED;;;OAGG;IACH,YAFY,SAAS,CAAC,CAAC,CAItB;IAED;;;OAGG;IACH,YAFY,IAAI,KAAK,CAAC,CAAC,CAAC,CAIvB;IAED;;;;;;OAMG;IACH,mBALW,CAAC,UACD,CAAC,cACD,iBAAiB,GACf,KAAK,CAAC,CAAC,CAgBnB;IAED;;;;;OAKG;IACH,cAJW,KAAK,CAAC,CAAC,GACL,OAAO,CA4BnB;IAED;;;;OAIG;IACH,iBAHW,KAAK,CAAC,CAAC,GACL,OAAO,CAwBnB;IAED;;;;OAIG;IACH,cAHW,KAAK,CAAC,CAAC,GACL,OAAO,CAQnB;IAED;;;;OAIG;IACH,8BAHoB,KAAK,CAAC,CAAC,+BAO1B;IAED,wBAEC;IAED;;;;;OAKG;IACH,qBAJW,CAAC,KACD,CAAC,GACC,OAAO,CAWnB;IAED;;;;;OAKG;IACH,qBAJW,CAAC,KACD,CAAC,GACC,KAAK,CAAC,CAAC,GAAC,SAAS,CAiB7B;IAED;;;;;OAKG;IACH,yBAJW,CAAC,MACD,CAAC,GACC,KAAK,CAAC,CAAC,GAAC,SAAS,CAU7B;IAED;;;;;OAKG;IACH,yBAJW,KAAK,CAAC,CAAC,EAAE,QACT,CAAC,GACC,MAAM,CA2BlB;IAED;;;;OAIG;IACH,oBAHW,CAAC,GACC,CAAC,EAAE,CAUf;IAED;;;;OAIG;IACH,mBAHW,CAAC,GACC,OAAO,CAYnB;IAED;;;;;OAKG;IACH,gBAJW,CAAC,QACD,CAAC,GACC,IAAI,GAAC,CAAC,EAAE,
|
|
1
|
+
{"version":3,"file":"Graph.d.ts","sourceRoot":"","sources":["../../../../../src/core/graph/v2/Graph.js"],"names":[],"mappings":"AAyBA;;GAEG;AACH;IAEI;;;;;OAKG;IACH,yBAAoB;IACpB;;;;;OAKG;IACH,yBAAoB;IAEpB;;OAEG;IACH;QACI;;WAEG;mBADO,OAAO,CAAC,EAAC,IAAI,CAAC;QAGxB;;WAEG;qBADO,OAAO,CAAC,EAAC,IAAI,CAAC;;;MAK1B;IAGF;;;;OAIG;IACH,cAHW,CAAC,GACC,OAAO,CAInB;IAED;;;;OAIG;IACH,cAHW,CAAC,GACC,OAAO,CAenB;IAED;;;;OAIG;IACH,iBAHW,CAAC,GACC,OAAO,CAiBnB;IAED;;;;OAIG;IACH,8BAHoB,CAAC,+BAOpB;IAED,wBAEC;IAED;;;OAGG;IACH,gBAFa,MAAM,CAIlB;IAED;;;;;OAKG;IACH,wBAJoB,CAAC,KAAE,OAAO,kBAEjB,CAAC,GAAC,SAAS,CAgBvB;IAED;;;;OAIG;IACH,uBAHW,CAAC,GACC,cAAc,CAAC,CAAC,GAAC,SAAS,CAItC;IAED;;;;OAIG;IACH,oBAHW,CAAC,GACA,MAAM,CAUjB;IAED;;;OAGG;IACH,iBAEC;IAED;;;OAGG;IACH,YAFY,SAAS,CAAC,CAAC,CAItB;IAED;;;OAGG;IACH,YAFY,IAAI,KAAK,CAAC,CAAC,CAAC,CAIvB;IAED;;;;;;OAMG;IACH,mBALW,CAAC,UACD,CAAC,cACD,iBAAiB,GACf,KAAK,CAAC,CAAC,CAgBnB;IAED;;;;;OAKG;IACH,cAJW,KAAK,CAAC,CAAC,GACL,OAAO,CA4BnB;IAED;;;;OAIG;IACH,iBAHW,KAAK,CAAC,CAAC,GACL,OAAO,CAwBnB;IAED;;;;OAIG;IACH,cAHW,KAAK,CAAC,CAAC,GACL,OAAO,CAQnB;IAED;;;;OAIG;IACH,8BAHoB,KAAK,CAAC,CAAC,+BAO1B;IAED,wBAEC;IAED;;;;;OAKG;IACH,qBAJW,CAAC,KACD,CAAC,GACC,OAAO,CAWnB;IAED;;;;;OAKG;IACH,qBAJW,CAAC,KACD,CAAC,GACC,KAAK,CAAC,CAAC,GAAC,SAAS,CAiB7B;IAED;;;;;OAKG;IACH,yBAJW,CAAC,MACD,CAAC,GACC,KAAK,CAAC,CAAC,GAAC,SAAS,CAU7B;IAED;;;;;OAKG;IACH,yBAJW,KAAK,CAAC,CAAC,EAAE,QACT,CAAC,GACC,MAAM,CA2BlB;IAED;;;;OAIG;IACH,oBAHW,CAAC,GACC,CAAC,EAAE,CAUf;IAED;;;;OAIG;IACH,mBAHW,CAAC,GACC,OAAO,CAYnB;IAED;;;;;OAKG;IACH,gBAJW,CAAC,QACD,CAAC,GACC,IAAI,GAAC,CAAC,EAAE,CA4EpB;IAED;;OAEG;IACH,cAGC;IAED;;;OAGG;IACH,YAFW,MAAM,CAAC,CAAC,QAOlB;IAED;;OAEG;IACH,SAFa,MAAM,CAAC,CAAC,CAQpB;CACJ;mBAtiBkB,+BAA+B;8BAEpB,oBAAoB;qBADV,YAAY;kCAAZ,YAAY"}
|
|
@@ -446,8 +446,17 @@ export class Graph {
|
|
|
446
446
|
*/
|
|
447
447
|
findPath(start, goal) {
|
|
448
448
|
const start_node_container = this.__nodes.get(start);
|
|
449
|
+
|
|
450
|
+
if (start_node_container === undefined) {
|
|
451
|
+
throw new Error(`Start node not found in the graph '${start}'`);
|
|
452
|
+
}
|
|
453
|
+
|
|
449
454
|
const goal_node_container = this.__nodes.get(goal);
|
|
450
455
|
|
|
456
|
+
if (goal_node_container === undefined) {
|
|
457
|
+
throw new Error(`Goal node not found in the graph '${goal}'`);
|
|
458
|
+
}
|
|
459
|
+
|
|
451
460
|
const open = new Set();
|
|
452
461
|
open.add(start_node_container);
|
|
453
462
|
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Computes derivative of Catmull Rom spline
|
|
3
|
+
* @param {number[]} result_value
|
|
4
|
+
* @param {number} result_value_offset
|
|
5
|
+
* @param {number[]} result_derivative
|
|
6
|
+
* @param {number} result_derivative_offset
|
|
7
|
+
* @param {number[]} p0 spline point 0
|
|
8
|
+
* @param {number[]} p1 spline point 1
|
|
9
|
+
* @param {number[]} p2 spline point 2
|
|
10
|
+
* @param {number[]} p3 spline point 3
|
|
11
|
+
* @param {number} dimensions number of dimensions in the input and output vectors
|
|
12
|
+
* @param {number} f between 0..1
|
|
13
|
+
* @param {number} alpha between 0..1
|
|
14
|
+
*/
|
|
15
|
+
export function computeNonuniformCaltmullRomSplineDerivative(result_value: number[], result_value_offset: number, result_derivative: number[], result_derivative_offset: number, p0: number[], p1: number[], p2: number[], p3: number[], dimensions: number, f: number, alpha: number): void;
|
|
16
|
+
//# sourceMappingURL=computeNonuniformCaltmullRomSplineDerivative.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"computeNonuniformCaltmullRomSplineDerivative.d.ts","sourceRoot":"","sources":["../../../../../src/core/math/spline/computeNonuniformCaltmullRomSplineDerivative.js"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;GAaG;AACH,2EAZW,MAAM,EAAE,uBACR,MAAM,qBACN,MAAM,EAAE,4BACR,MAAM,MACN,MAAM,EAAE,MACR,MAAM,EAAE,MACR,MAAM,EAAE,MACR,MAAM,EAAE,cACR,MAAM,KACN,MAAM,SACN,MAAM,QA2EhB"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { catmull_rom_compute_T } from "./catmull_rom_compute_T.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Computes derivative of Catmull Rom spline
|
|
5
|
+
* @param {number[]} result_value
|
|
6
|
+
* @param {number} result_value_offset
|
|
7
|
+
* @param {number[]} result_derivative
|
|
8
|
+
* @param {number} result_derivative_offset
|
|
9
|
+
* @param {number[]} p0 spline point 0
|
|
10
|
+
* @param {number[]} p1 spline point 1
|
|
11
|
+
* @param {number[]} p2 spline point 2
|
|
12
|
+
* @param {number[]} p3 spline point 3
|
|
13
|
+
* @param {number} dimensions number of dimensions in the input and output vectors
|
|
14
|
+
* @param {number} f between 0..1
|
|
15
|
+
* @param {number} alpha between 0..1
|
|
16
|
+
*/
|
|
17
|
+
export function computeNonuniformCaltmullRomSplineDerivative(
|
|
18
|
+
result_value, result_value_offset,
|
|
19
|
+
result_derivative, result_derivative_offset,
|
|
20
|
+
p0, p1, p2, p3,
|
|
21
|
+
dimensions, f, alpha
|
|
22
|
+
) {
|
|
23
|
+
/*
|
|
24
|
+
@see https://math.stackexchange.com/questions/843595/how-can-i-calculate-the-derivative-of-a-catmull-rom-spline-with-nonuniform-param
|
|
25
|
+
@see http://denkovacs.com/2016/02/catmull-rom-spline-derivatives/
|
|
26
|
+
@see https://en.wikipedia.org/wiki/Centripetal_Catmull%E2%80%93Rom_spline
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
const half_alpha = alpha * 0.5;
|
|
30
|
+
|
|
31
|
+
// calculate T
|
|
32
|
+
const t0 = 0;
|
|
33
|
+
let t_01 = catmull_rom_compute_T(p0, p1, dimensions, half_alpha);
|
|
34
|
+
let t_02 = catmull_rom_compute_T(p1, p2, dimensions, half_alpha);
|
|
35
|
+
let t_03 = catmull_rom_compute_T(p2, p3, dimensions, half_alpha);
|
|
36
|
+
|
|
37
|
+
// safety check for repeated points, to prevent division by 0
|
|
38
|
+
if (t_01 < 1e-4) {
|
|
39
|
+
t_01 = 1;
|
|
40
|
+
}
|
|
41
|
+
if (t_02 < 1e-4) {
|
|
42
|
+
t_02 = t_01;
|
|
43
|
+
}
|
|
44
|
+
if (t_03 < 1e-4) {
|
|
45
|
+
t_03 = t_02;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const t1 = t_01 + t0;
|
|
49
|
+
const t2 = t_02 + t1;
|
|
50
|
+
const t3 = t_03 + t2;
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Interpolation between points 1 and 2
|
|
54
|
+
* @type {number}
|
|
55
|
+
*/
|
|
56
|
+
const t = t1 * (1 - f) + t2 * f;
|
|
57
|
+
|
|
58
|
+
for (let i = 0; i < dimensions; i++) {
|
|
59
|
+
// read vector values for the dimension
|
|
60
|
+
const v0 = p0[i];
|
|
61
|
+
const v1 = p1[i];
|
|
62
|
+
const v2 = p2[i];
|
|
63
|
+
const v3 = p3[i];
|
|
64
|
+
|
|
65
|
+
const A1 = (t1 - t) / (t1 - t0) * v0 + (t - t0) / (t1 - t0) * v1;
|
|
66
|
+
const A2 = (t2 - t) / (t2 - t1) * v1 + (t - t1) / (t2 - t1) * v2;
|
|
67
|
+
const A3 = (t3 - t) / (t3 - t2) * v2 + (t - t2) / (t3 - t2) * v3;
|
|
68
|
+
|
|
69
|
+
const B1 = (t2 - t) / (t2 - t0) * A1 + (t - t0) / (t2 - t0) * A2;
|
|
70
|
+
const B2 = (t3 - t) / (t3 - t1) * A2 + (t - t1) / (t3 - t1) * A3;
|
|
71
|
+
|
|
72
|
+
const C = (t2 - t) / (t2 - t1) * B1 + (t - t1) / (t2 - t1) * B2;
|
|
73
|
+
|
|
74
|
+
result_value[result_value_offset + i] = C;
|
|
75
|
+
|
|
76
|
+
// derivatives
|
|
77
|
+
|
|
78
|
+
const dA1 = (v1 - v0) / (t1 - t0)
|
|
79
|
+
const dA2 = (v2 - v1) / (t2 - t1);
|
|
80
|
+
const dA3 = (v3 - v2) / (t3 - t2);
|
|
81
|
+
|
|
82
|
+
const dB1 = (A2 - A1) / (t2 - t0) + dA1 * (t2 - t) / (t2 - t0) + dA2 * (t - t0) / (t2 - t0);
|
|
83
|
+
const dB2 = (A3 - A2) / (t3 - t1) + dA2 * (t3 - t) / (t3 - t1) + dA3 * (t - t1) / (t3 - t1);
|
|
84
|
+
|
|
85
|
+
const dC = (B2 - B1) / (t2 - t1) + dB1 * (t2 - t) / (t2 - t1) + dB2 * (t - t1) / (t2 - t1);
|
|
86
|
+
|
|
87
|
+
result_derivative[result_derivative_offset + i] = dC;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Calculate Jaro distance between two strings, this is a measure of string similarity. Higher value means more similarity.
|
|
3
|
+
* @param {string} first
|
|
4
|
+
* @param {string} second
|
|
5
|
+
* @param {number} first_length
|
|
6
|
+
* @param {number} second_length
|
|
7
|
+
* @return {number}
|
|
8
|
+
*/
|
|
9
|
+
export function string_jaro_distance(first: string, second: string, first_length: number, second_length: number): number;
|
|
10
|
+
//# sourceMappingURL=string_jaro_distance.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"string_jaro_distance.d.ts","sourceRoot":"","sources":["../../../../../src/core/primitives/strings/string_jaro_distance.js"],"names":[],"mappings":"AAIA;;;;;;;GAOG;AACH,4CANW,MAAM,UACN,MAAM,gBACN,MAAM,iBACN,MAAM,GACL,MAAM,CAmBjB"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { BitSet } from "../../binary/BitSet.js";
|
|
2
|
+
import { max2 } from "../../math/max2.js";
|
|
3
|
+
import { min2 } from "../../math/min2.js";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Calculate Jaro distance between two strings, this is a measure of string similarity. Higher value means more similarity.
|
|
7
|
+
* @param {string} first
|
|
8
|
+
* @param {string} second
|
|
9
|
+
* @param {number} first_length
|
|
10
|
+
* @param {number} second_length
|
|
11
|
+
* @return {number}
|
|
12
|
+
*/
|
|
13
|
+
export function string_jaro_distance(
|
|
14
|
+
first, second,
|
|
15
|
+
first_length, second_length
|
|
16
|
+
) {
|
|
17
|
+
|
|
18
|
+
const matches1 = BitSet.fixedSize(first_length);
|
|
19
|
+
const matches2 = BitSet.fixedSize(second_length);
|
|
20
|
+
|
|
21
|
+
const matches = getMatching(first, second, matches1, matches2);
|
|
22
|
+
|
|
23
|
+
if (matches <= 0) {
|
|
24
|
+
return 0;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const transpositions = getTranspositions(first, second, matches1, matches2);
|
|
28
|
+
return (matches / first_length + matches / second_length + (matches - transpositions) / matches) / 3;
|
|
29
|
+
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Find matching characters in both strings according to Jaro algorithm
|
|
34
|
+
* @param {string} a1
|
|
35
|
+
* @param {string} a2
|
|
36
|
+
* @param {BitSet} matches1
|
|
37
|
+
* @param {BitSet} matches2
|
|
38
|
+
* @return {number}
|
|
39
|
+
*/
|
|
40
|
+
function getMatching(a1, a2, matches1, matches2) {
|
|
41
|
+
const a1_length = a1.length;
|
|
42
|
+
const a2_length = a2.length;
|
|
43
|
+
|
|
44
|
+
// Window is modified to work with string of length 1
|
|
45
|
+
const matchWindow = max2(
|
|
46
|
+
0,
|
|
47
|
+
Math.floor(max2(a1_length, a2_length) * 0.5) - 1
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
let matches = 0;
|
|
51
|
+
|
|
52
|
+
// Loop to find matched characters:
|
|
53
|
+
for (let index1 = 0; index1 < a1_length; index1++) {
|
|
54
|
+
|
|
55
|
+
// Use the highest of the window diff and the min of the window and string 2 length:
|
|
56
|
+
const start = max2(0, index1 - matchWindow);
|
|
57
|
+
const end = min2(index1 + matchWindow + 1, a2_length);
|
|
58
|
+
|
|
59
|
+
// Iterate second string index:
|
|
60
|
+
for (let index2 = start; index2 < end; index2++) {
|
|
61
|
+
|
|
62
|
+
// If second string character already matched, skip:
|
|
63
|
+
if (matches2.get(index2)) {
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// If the characters don't match, skip:
|
|
68
|
+
if (a1.charAt(index1) !== a2.charAt(index2)) {
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Assume match if the above 2 checks don't continue:
|
|
73
|
+
matches1.set(index1, true);
|
|
74
|
+
matches2.set(index2, true);
|
|
75
|
+
|
|
76
|
+
// Add matches by 1, break inner loop:
|
|
77
|
+
++matches;
|
|
78
|
+
break;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return matches;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Calculate the number of transpositions between the two words
|
|
87
|
+
* @param {string} a1 The first string to compare
|
|
88
|
+
* @param {string} a2 The second string to compare
|
|
89
|
+
* @param {BitSet} matches1
|
|
90
|
+
* @param {BitSet} matches2
|
|
91
|
+
* @returns {number}
|
|
92
|
+
*/
|
|
93
|
+
function getTranspositions(
|
|
94
|
+
a1, a2,
|
|
95
|
+
matches1, matches2
|
|
96
|
+
) {
|
|
97
|
+
let transpositions = 0;
|
|
98
|
+
|
|
99
|
+
// Loop to find transpositions:
|
|
100
|
+
const a1_length = a1.length;
|
|
101
|
+
const a2_length = a2.length;
|
|
102
|
+
|
|
103
|
+
for (let i1 = 0, i2 = 0; i1 < a1_length; i1++) {
|
|
104
|
+
// If a non-matching character was found, skip:
|
|
105
|
+
if (matches1.get(i1) === false) {
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Move i2 index to the next match:
|
|
110
|
+
while (
|
|
111
|
+
i2 < a2_length
|
|
112
|
+
&& matches2.get(i2) === false
|
|
113
|
+
) {
|
|
114
|
+
i2++;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// If the characters don't match, increase transposition:
|
|
118
|
+
if (a1.charAt(i1) !== a2.charAt(i2)) {
|
|
119
|
+
transpositions++;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Iterate i2 index normally:
|
|
123
|
+
i2++;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return Math.floor(transpositions * 0.5);
|
|
127
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"string_jaro_winkler.d.ts","sourceRoot":"","sources":["../../../../../src/core/primitives/strings/string_jaro_winkler.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"string_jaro_winkler.d.ts","sourceRoot":"","sources":["../../../../../src/core/primitives/strings/string_jaro_winkler.js"],"names":[],"mappings":"AAGA;;;;;GAKG;AACH,2CAJW,MAAM,UACN,MAAM,GACJ,MAAM,CAwBlB"}
|
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
import { BitSet } from "../../binary/BitSet.js";
|
|
2
|
-
import { max2 } from "../../math/max2.js";
|
|
3
|
-
import { min2 } from "../../math/min2.js";
|
|
4
1
|
import { min3 } from "../../math/min3.js";
|
|
2
|
+
import { string_jaro_distance } from "./string_jaro_distance.js";
|
|
5
3
|
|
|
6
4
|
/**
|
|
7
5
|
* Calculate the Jaro-Winkler distance between two strings
|
|
@@ -18,19 +16,14 @@ export function string_jaro_winkler(first, second) {
|
|
|
18
16
|
return 1;
|
|
19
17
|
}
|
|
20
18
|
|
|
21
|
-
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
const matches = getMatching(first, second, matches1, matches2);
|
|
19
|
+
// Calculate the Jaro distance:
|
|
20
|
+
const similarity = string_jaro_distance(first, second, l1, l2);
|
|
25
21
|
|
|
26
|
-
if (
|
|
22
|
+
if (similarity === 0) {
|
|
23
|
+
// no similarity at all
|
|
27
24
|
return 0;
|
|
28
25
|
}
|
|
29
26
|
|
|
30
|
-
// Calculate the Jaro distance:
|
|
31
|
-
const transpositions = getTranspositions(first, second, matches1, matches2);
|
|
32
|
-
const similarity = (matches / l1 + matches / l2 + (matches - transpositions) / matches) / 3;
|
|
33
|
-
|
|
34
27
|
// Transform to Jaro-Winkler:
|
|
35
28
|
// Prefix scale gives more favorable ratings to strings that share common prefixes:
|
|
36
29
|
const prefix_scale = 0.1;
|
|
@@ -38,99 +31,6 @@ export function string_jaro_winkler(first, second) {
|
|
|
38
31
|
return similarity + prefix * prefix_scale * (1 - similarity);
|
|
39
32
|
}
|
|
40
33
|
|
|
41
|
-
/**
|
|
42
|
-
* Find matching characters in both strings according to Jaro algorithm
|
|
43
|
-
* @param {string} a1
|
|
44
|
-
* @param {string} a2
|
|
45
|
-
* @param {BitSet} matches1
|
|
46
|
-
* @param {BitSet} matches2
|
|
47
|
-
* @return {number}
|
|
48
|
-
*/
|
|
49
|
-
function getMatching(a1, a2, matches1, matches2) {
|
|
50
|
-
const a1_length = a1.length;
|
|
51
|
-
const a2_length = a2.length;
|
|
52
|
-
|
|
53
|
-
// Window is modified to work with string of length 1
|
|
54
|
-
const matchWindow = max2(
|
|
55
|
-
0,
|
|
56
|
-
Math.floor(max2(a1_length, a2_length) * 0.5) - 1
|
|
57
|
-
);
|
|
58
|
-
|
|
59
|
-
let matches = 0;
|
|
60
|
-
|
|
61
|
-
// Loop to find matched characters:
|
|
62
|
-
for (let index1 = 0; index1 < a1_length; index1++) {
|
|
63
|
-
|
|
64
|
-
// Use the highest of the window diff and the min of the window and string 2 length:
|
|
65
|
-
const start = max2(0, index1 - matchWindow);
|
|
66
|
-
const end = min2(index1 + matchWindow + 1, a2_length);
|
|
67
|
-
|
|
68
|
-
// Iterate second string index:
|
|
69
|
-
for (let index2 = start; index2 < end; index2++) {
|
|
70
|
-
|
|
71
|
-
// If second string character already matched, skip:
|
|
72
|
-
if (matches2.get(index2)) {
|
|
73
|
-
continue;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
// If the characters don't match, skip:
|
|
77
|
-
if (a1.charAt(index1) !== a2.charAt(index2)) {
|
|
78
|
-
continue;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
// Assume match if the above 2 checks don't continue:
|
|
82
|
-
matches1.set(index1, true);
|
|
83
|
-
matches2.set(index2, true);
|
|
84
|
-
|
|
85
|
-
// Add matches by 1, break inner loop:
|
|
86
|
-
++matches;
|
|
87
|
-
break;
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
return matches;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* Calculate the number of transpositions between the two words
|
|
96
|
-
* @param {string} a1 The first string to compare
|
|
97
|
-
* @param {string} a2 The second string to compare
|
|
98
|
-
* @param {BitSet} matches1
|
|
99
|
-
* @param {BitSet} matches2
|
|
100
|
-
*/
|
|
101
|
-
function getTranspositions(a1, a2, matches1, matches2) {
|
|
102
|
-
let transpositions = 0;
|
|
103
|
-
|
|
104
|
-
// Loop to find transpositions:
|
|
105
|
-
const a1_length = a1.length;
|
|
106
|
-
const a2_length = a2.length;
|
|
107
|
-
|
|
108
|
-
for (let i1 = 0, i2 = 0; i1 < a1_length; i1++) {
|
|
109
|
-
// If a non-matching character was found, skip:
|
|
110
|
-
if (matches1.get(i1) === false) {
|
|
111
|
-
continue;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
// Move i2 index to the next match:
|
|
115
|
-
while (
|
|
116
|
-
i2 < a2_length
|
|
117
|
-
&& matches2.get(i2) === false
|
|
118
|
-
) {
|
|
119
|
-
i2++;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
// If the characters don't match, increase transposition:
|
|
123
|
-
if (a1.charAt(i1) !== a2.charAt(i2)) {
|
|
124
|
-
transpositions++;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
// Iterate i2 index normally:
|
|
128
|
-
i2++;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
return Math.floor(transpositions * 0.5);
|
|
132
|
-
}
|
|
133
|
-
|
|
134
34
|
/**
|
|
135
35
|
* Counts the number of common characters at the beginning
|
|
136
36
|
* of each word up to a maximum of 4
|