@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.
@@ -69972,13 +69972,15 @@ BitSet.prototype.setShrinkFactor = function (x) {
69972
69972
 
69973
69973
  /**
69974
69974
  *
69975
- * @param {number} numBits
69975
+ * @param {number} bit_count
69976
69976
  */
69977
- BitSet.prototype.setCapacity = function (numBits) {
69978
- if (this.__length > numBits) {
69979
- throw new Error(`Current length is greater than requested size`);
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
- this.__resize(numBits);
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 the Jaro-Winkler distance between two strings
82207
- * @param {string} first The string to compare
82208
- * @param {string} second The string to compare with
82209
- * @returns {number} similarity score, higher value means strings are more similar
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 string_jaro_winkler(first, second) {
82212
- const l1 = first.length;
82213
- const l2 = second.length;
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(l1);
82221
- const matches2 = BitSet.fixedSize(l2);
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
- const similarity = (matches / l1 + matches / l2 + (matches - transpositions) / matches) / 3;
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(a1, a2, matches1, matches2) {
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
@@ -5,7 +5,7 @@
5
5
  "description": "Fully featured ECS game engine written in JavaScript",
6
6
  "type": "module",
7
7
  "author": "Alexander Goldring",
8
- "version": "2.96.0",
8
+ "version": "2.97.0",
9
9
  "main": "build/meep.module.js",
10
10
  "module": "build/meep.module.js",
11
11
  "exports": {
@@ -34,9 +34,9 @@ export class BitSet {
34
34
  setShrinkFactor(x: number): void;
35
35
  /**
36
36
  *
37
- * @param {number} numBits
37
+ * @param {number} bit_count
38
38
  */
39
- setCapacity(numBits: number): void;
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,qBAFW,MAAM,QAOhB;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"}
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} numBits
111
+ * @param {number} bit_count
112
112
  */
113
- BitSet.prototype.setCapacity = function (numBits) {
114
- if (this.__length > numBits) {
115
- throw new Error(`Current length is greater than requested size`);
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
- this.__resize(numBits);
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,CAmEpB;IAED;;OAEG;IACH,cAGC;IAED;;;OAGG;IACH,YAFW,MAAM,CAAC,CAAC,QAOlB;IAED;;OAEG;IACH,SAFa,MAAM,CAAC,CAAC,CAQpB;CACJ;mBA7hBkB,+BAA+B;8BAEpB,oBAAoB;qBADV,YAAY;kCAAZ,YAAY"}
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":"AAKA;;;;;GAKG;AACH,2CAJW,MAAM,UACN,MAAM,GACJ,MAAM,CA6BlB"}
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
- const matches1 = BitSet.fixedSize(l1);
22
- const matches2 = BitSet.fixedSize(l2);
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 (matches <= 0) {
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