es6-fuzz 4.0.1 → 5.0.1
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/Readme.md +3 -4
- package/docs/CHANGELOG.md +30 -20
- package/jsdoc.json +0 -1
- package/lib/curve/grade.js +7 -0
- package/lib/curve/reverse-grade.js +6 -1
- package/lib/curve/sigmoid.js +13 -7
- package/lib/curve/trapezoid.js +25 -2
- package/lib/curve/triangle.js +27 -0
- package/lib/logic.js +0 -2
- package/package.json +6 -6
- package/test/curve/constant.test.js +15 -0
- package/test/{shape-fuzzy-function-test.js → curve/fuzzy-function.test.js} +2 -1
- package/test/{shape-grade-test.js → curve/grade.test.js} +9 -1
- package/test/{shape-reverse-grade-test.js → curve/reverse-grade.test.js} +9 -1
- package/test/curve/shape.test.js +30 -0
- package/test/{shape-sigmoid-test.js → curve/sigmoid/sigmoid-basic.test.js} +3 -13
- package/test/curve/sigmoid/sigmoid-center-behavior.test.js +66 -0
- package/test/curve/sigmoid/sigmoid-slope.test.js +15 -0
- package/test/curve/trapezoid/trapezoid-basic.test.js +54 -0
- package/test/curve/trapezoid/trapezoid-bounds.test.js +30 -0
- package/test/{shape-triangle-test.js → curve/triangle.test.js} +2 -1
- package/test/edge-cases/constant-edge-values.test.js +56 -0
- package/test/edge-cases/fuzzy-function-edge-cases.test.js +71 -0
- package/test/edge-cases/grade-edge-cases.test.js +42 -0
- package/test/edge-cases/reverse-grade-edge-cases.test.js +42 -0
- package/test/edge-cases/shapes-large-values.test.js +78 -0
- package/test/edge-cases/shapes-negative-values.test.js +75 -0
- package/test/edge-cases/sigmoid-edge-cases.test.js +70 -0
- package/test/edge-cases/trapezoid-special-cases.test.js +94 -0
- package/test/edge-cases/triangle-degenerate-cases.test.js +62 -0
- package/test/error-handling/empty-rules-handling.test.js +25 -0
- package/test/error-handling/es6-class-instantiation.test.js +52 -0
- package/test/error-handling/fuzzy-function-validation.test.js +66 -0
- package/test/error-handling/invalid-chaining-sequences.test.js +40 -0
- package/test/error-handling/logic-validation.test.js +78 -0
- package/test/error-handling/property-immutability.test.js +29 -0
- package/test/error-handling/shape-constructor-validation.test.js +70 -0
- package/test/{example-test.js → example.test.js} +1 -0
- package/test/init-called.test.js +1 -0
- package/test/integration/and-or-not-combinations.test.js +42 -0
- package/test/integration/complex-logic-chains.test.js +85 -0
- package/test/integration/edge-case-combinations.test.js +55 -0
- package/test/integration/mixing-shape-types.test.js +44 -0
- package/test/integration/performance-many-rules.test.js +42 -0
- package/test/integration/real-world-scenarios.test.js +50 -0
- package/test/integration/state-management.test.js +47 -0
- package/test/js-bool.test.js +2 -1
- package/test/logic/attack-rage-calculation.test.js +22 -0
- package/test/logic/behaves-like-number.test.js +22 -0
- package/test/logic/interface.test.js +20 -0
- package/test/logic/not-operation.test.js +17 -0
- package/test/constant-test.js +0 -13
- package/test/logic-test.js +0 -66
- package/test/shape-test.js +0 -16
- package/test/shape-trapezoid-test.js +0 -25
package/Readme.md
CHANGED
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
[](https://www.npmjs.com/package/es6-fuzz)
|
|
6
6
|
[](https://github.com/sebs/es6-fuzz/blob/master/LICENSE.md)
|
|
7
7
|
[](https://github.com/sebs/es6-fuzz)
|
|
8
|
-
[](https://travis-ci.org/sebs/es6-fuzz)
|
|
9
8
|
[](https://github.com/sebs/es6-fuzz/issues)
|
|
10
9
|
|
|
11
10
|
Supported fuzzyfiers
|
|
@@ -19,8 +18,8 @@ Supported fuzzyfiers
|
|
|
19
18
|
* Triangle
|
|
20
19
|
|
|
21
20
|
|
|
22
|
-
* [api docs](
|
|
23
|
-
* [changelog](
|
|
21
|
+
* [api docs](http://sebs.github.io/es6-fuzz)
|
|
22
|
+
* [changelog](https://github.com/sebs/es6-fuzz/blob/master/docs/CHANGELOG.md)
|
|
24
23
|
|
|
25
24
|
## Install and Usage
|
|
26
25
|
|
|
@@ -115,7 +114,7 @@ monsterBiteTest(jsBoonInput)
|
|
|
115
114
|
|
|
116
115
|
## development
|
|
117
116
|
|
|
118
|
-
**Tests** use
|
|
117
|
+
**Tests** use node internal testing framework
|
|
119
118
|
|
|
120
119
|
```
|
|
121
120
|
npm test
|
package/docs/CHANGELOG.md
CHANGED
|
@@ -1,9 +1,38 @@
|
|
|
1
|
+
2025-06-26
|
|
2
|
+
==========
|
|
3
|
+
|
|
4
|
+
* 5.0.1
|
|
5
|
+
* refactor: cleanup of test files
|
|
6
|
+
* chore: remove unused test
|
|
7
|
+
* docs: add correct name of test framework
|
|
8
|
+
* (churn): changelog
|
|
9
|
+
* 5.0.0
|
|
10
|
+
* 4.0.4
|
|
11
|
+
* fix: edge cases
|
|
12
|
+
* 4.0.3
|
|
13
|
+
* refactor: cleaned up test structure
|
|
14
|
+
* 4.0.2
|
|
15
|
+
* docs: add a clearer test case for constant
|
|
16
|
+
* fix: [#76](https://github.com/sebs/es6-fuzz/issues/76) sigmoid implementation with weird microoptimizations
|
|
17
|
+
* added a different sigmoid function with easier to understand parameters
|
|
18
|
+
|
|
19
|
+
2023-01-18
|
|
20
|
+
==========
|
|
21
|
+
|
|
22
|
+
* test: find the bug with trapezoid special form square
|
|
23
|
+
|
|
24
|
+
2023-01-17
|
|
25
|
+
==========
|
|
26
|
+
|
|
27
|
+
* test: more tests for the trapezoid
|
|
28
|
+
|
|
1
29
|
2022-06-14
|
|
2
30
|
==========
|
|
3
31
|
|
|
32
|
+
* chore: link docs
|
|
33
|
+
* (churn): changelog
|
|
4
34
|
* 4.0.1
|
|
5
35
|
* fix: update readme
|
|
6
|
-
* (churn): changelog
|
|
7
36
|
* 4.0.0
|
|
8
37
|
* feature: make the api work with boonJsInputs
|
|
9
38
|
* feature: add a test for outoput names only to consist of alphabet
|
|
@@ -131,22 +160,3 @@
|
|
|
131
160
|
* Changelog
|
|
132
161
|
* Added changelog link
|
|
133
162
|
* 2.6.1
|
|
134
|
-
* Docs
|
|
135
|
-
* 2.6.0
|
|
136
|
-
* Added link to api docs
|
|
137
|
-
* More docs
|
|
138
|
-
|
|
139
|
-
2017-04-04
|
|
140
|
-
==========
|
|
141
|
-
|
|
142
|
-
* Added latest es5 export to dist
|
|
143
|
-
* (churn): changelog
|
|
144
|
-
* 2.5.10
|
|
145
|
-
* Added curves
|
|
146
|
-
* 2.5.9
|
|
147
|
-
* add missing dep
|
|
148
|
-
* 2.5.8
|
|
149
|
-
* Pages
|
|
150
|
-
* 2.5.7
|
|
151
|
-
* 2.5.6
|
|
152
|
-
* Added docs
|
package/jsdoc.json
CHANGED
package/lib/curve/grade.js
CHANGED
|
@@ -14,6 +14,13 @@ class Grade extends Shape {
|
|
|
14
14
|
fuzzify(val) {
|
|
15
15
|
let result = 0;
|
|
16
16
|
const x = val;
|
|
17
|
+
|
|
18
|
+
// Handle case where x0 = x1 (vertical grade/step function)
|
|
19
|
+
if (this.x1 === this.x0) {
|
|
20
|
+
if (x < this.x0) return 0;
|
|
21
|
+
return 1; // x >= x0
|
|
22
|
+
}
|
|
23
|
+
|
|
17
24
|
if (x <= this.x0) {
|
|
18
25
|
result = 0;
|
|
19
26
|
} else if (x >= this.x1) {
|
|
@@ -16,7 +16,12 @@ class ReverseGrade extends Shape {
|
|
|
16
16
|
} else if (x >= this.x1) {
|
|
17
17
|
result = 0;
|
|
18
18
|
} else {
|
|
19
|
-
|
|
19
|
+
// Handle case where x0 = x1 (vertical reverse grade)
|
|
20
|
+
if (this.x1 === this.x0) {
|
|
21
|
+
result = 0;
|
|
22
|
+
} else {
|
|
23
|
+
result = (-x / (this.x1 - this.x0)) + (this.x1 / (this.x1 - this.x0));
|
|
24
|
+
}
|
|
20
25
|
}
|
|
21
26
|
return result;
|
|
22
27
|
}
|
package/lib/curve/sigmoid.js
CHANGED
|
@@ -9,20 +9,26 @@
|
|
|
9
9
|
class Sigmoid {
|
|
10
10
|
/**
|
|
11
11
|
* Create a Sigmoid Function.
|
|
12
|
-
* @param {number}
|
|
13
|
-
* @param {number} slope
|
|
12
|
+
* @param {number} center - The center point of the sigmoid curve (where it outputs 0.5)
|
|
13
|
+
* @param {number} slope - The slope of the sigmoid curve (higher = steeper transition)
|
|
14
14
|
*/
|
|
15
|
-
constructor(
|
|
16
|
-
this.
|
|
17
|
-
this.
|
|
15
|
+
constructor(center=0, slope=1) {
|
|
16
|
+
this.center = center;
|
|
17
|
+
this.slope = slope;
|
|
18
18
|
}
|
|
19
19
|
/**
|
|
20
20
|
* Fuzzify
|
|
21
|
-
* @param {number} - Point on X axis
|
|
21
|
+
* @param {number} x - Point on X axis
|
|
22
22
|
* @return {number} fuzzy output 0..1
|
|
23
23
|
*/
|
|
24
24
|
fuzzify(x) {
|
|
25
|
-
|
|
25
|
+
if (this.slope === 0) {
|
|
26
|
+
// When slope is 0, sigmoid becomes a step function
|
|
27
|
+
if (x < this.center) return 0;
|
|
28
|
+
if (x > this.center) return 1;
|
|
29
|
+
return 0.5; // At center point
|
|
30
|
+
}
|
|
31
|
+
return 1.0 / (1.0 + Math.exp(-(x - this.center) / this.slope));
|
|
26
32
|
}
|
|
27
33
|
}
|
|
28
34
|
module.exports = Sigmoid;
|
package/lib/curve/trapezoid.js
CHANGED
|
@@ -15,6 +15,19 @@ class Trapezoid extends Shape {
|
|
|
15
15
|
let result = 0;
|
|
16
16
|
const x = val;
|
|
17
17
|
|
|
18
|
+
// Special case: all points equal (spike at single point)
|
|
19
|
+
if (this.x0 === this.x1 && this.x1 === this.x2 && this.x2 === this.x3) {
|
|
20
|
+
return x === this.x0 ? 1 : 0;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Special case: x0=x1 and x2=x3 (rectangle)
|
|
24
|
+
if (this.x0 === this.x1 && this.x2 === this.x3) {
|
|
25
|
+
if (x < this.x0) return 0;
|
|
26
|
+
if (x >= this.x0 && x <= this.x2) return 1;
|
|
27
|
+
if (x > this.x2) return 0;
|
|
28
|
+
return 0;
|
|
29
|
+
}
|
|
30
|
+
|
|
18
31
|
if (x <= this.x0) {
|
|
19
32
|
result = 0;
|
|
20
33
|
} else if (x >= this.x3) {
|
|
@@ -22,9 +35,19 @@ class Trapezoid extends Shape {
|
|
|
22
35
|
} else if ((x >= this.x1) && (x <= this.x2)) {
|
|
23
36
|
result = 1;
|
|
24
37
|
} else if ((x > this.x0) && (x < this.x1)) {
|
|
25
|
-
|
|
38
|
+
// Handle case where x0 = x1 (vertical left edge)
|
|
39
|
+
if (this.x1 === this.x0) {
|
|
40
|
+
result = 1;
|
|
41
|
+
} else {
|
|
42
|
+
result = (x / (this.x1 - this.x0)) - (this.x0 / (this.x1 - this.x0));
|
|
43
|
+
}
|
|
26
44
|
} else {
|
|
27
|
-
|
|
45
|
+
// Handle case where x2 = x3 (vertical right edge)
|
|
46
|
+
if (this.x3 === this.x2) {
|
|
47
|
+
result = 1;
|
|
48
|
+
} else {
|
|
49
|
+
result = (-x / (this.x3 - this.x2)) + (this.x3 / (this.x3 - this.x2));
|
|
50
|
+
}
|
|
28
51
|
}
|
|
29
52
|
return result;
|
|
30
53
|
}
|
package/lib/curve/triangle.js
CHANGED
|
@@ -13,6 +13,33 @@ class Triangle extends Shape {
|
|
|
13
13
|
*/
|
|
14
14
|
fuzzify(x) {
|
|
15
15
|
let result = 0;
|
|
16
|
+
|
|
17
|
+
// Special case: all points equal (spike at single point)
|
|
18
|
+
if (this.x0 === this.x1 && this.x1 === this.x2) {
|
|
19
|
+
return x === this.x0 ? 1 : 0;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// Special case: x0 = x1 (vertical left edge)
|
|
23
|
+
if (this.x0 === this.x1) {
|
|
24
|
+
if (x < this.x0) return 0;
|
|
25
|
+
if (x === this.x0) return 1;
|
|
26
|
+
if (x >= this.x2) return 0;
|
|
27
|
+
if (x < this.x2) {
|
|
28
|
+
return (this.x2 - x) / (this.x2 - this.x1);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// Special case: x1 = x2 (vertical right edge)
|
|
33
|
+
if (this.x1 === this.x2) {
|
|
34
|
+
if (x <= this.x0) return 0;
|
|
35
|
+
if (x > this.x0 && x < this.x1) {
|
|
36
|
+
return (x - this.x0) / (this.x1 - this.x0);
|
|
37
|
+
}
|
|
38
|
+
if (x === this.x1) return 1;
|
|
39
|
+
if (x > this.x1) return 0;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Normal triangle
|
|
16
43
|
if (x <= this.x0) {
|
|
17
44
|
result = 0;
|
|
18
45
|
} else if (x >= this.x2) {
|
package/lib/logic.js
CHANGED
package/package.json
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "es6-fuzz",
|
|
3
3
|
"description": "fuzzy logic with and for es6",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "5.0.1",
|
|
5
5
|
"main": "lib/logic.js",
|
|
6
6
|
"repository": "git@github.com:sebs/es6-fuzz.git",
|
|
7
7
|
"homepage": "https://github.com/sebs/es6-fuzz",
|
|
8
8
|
"scripts": {
|
|
9
9
|
"changelog": "rm ./docs/CHANGELOG.md && npx changelog https://github.com/sebs/es6-fuzz all > ./docs/CHANGELOG.md && git add . && git commit . -m '(churn): changelog'",
|
|
10
|
-
"test": "
|
|
11
|
-
"test:watch": "
|
|
10
|
+
"test": "node --test ./test/*.test.js ./test/**/*.test.js ./test/curve/**/*.test.js",
|
|
11
|
+
"test:watch": "node --test --watch ./test/*.test.js ./test/**/*.test.js ./test/curve/**/*.test.js",
|
|
12
12
|
"addpush": "git add . && git commit . -m 'docs'",
|
|
13
13
|
"pages": "node ./scripts/publish-gh.js",
|
|
14
14
|
"docs": "jsdoc -c ./jsdoc.json -t ./node_modules/ink-docstrap/template -R ./Readme.md -u ./docs",
|
|
@@ -25,11 +25,11 @@
|
|
|
25
25
|
"author": "Sebastian Schürmann",
|
|
26
26
|
"license": "MIT",
|
|
27
27
|
"devDependencies": {
|
|
28
|
-
"gh-pages": "
|
|
28
|
+
"gh-pages": "6.3.0",
|
|
29
29
|
"ink-docstrap": "1.3.2",
|
|
30
|
-
"jsdoc": "
|
|
30
|
+
"jsdoc": "4.0.4"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"boon-js": "2.0.
|
|
33
|
+
"boon-js": "2.0.5"
|
|
34
34
|
}
|
|
35
35
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
const { describe, it } = require('node:test');
|
|
2
|
+
const Constant= require('../../lib/curve/constant');
|
|
3
|
+
const assert = require('assert');
|
|
4
|
+
|
|
5
|
+
describe('Constant', function() {
|
|
6
|
+
it('is a function', function() {
|
|
7
|
+
assert.equal(typeof Constant, 'function');
|
|
8
|
+
});
|
|
9
|
+
it('same value at 5 and 100', function() {
|
|
10
|
+
var shape = new Constant(1);
|
|
11
|
+
var resFive = shape.fuzzify(5);
|
|
12
|
+
var resHundret = shape.fuzzify(100);
|
|
13
|
+
assert.equal(resFive, resHundret);
|
|
14
|
+
});
|
|
15
|
+
});
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
-
const
|
|
2
|
+
const { describe, it } = require('node:test');
|
|
3
|
+
const FuzzyFunction= require('../../lib/curve/fuzzy-function');
|
|
3
4
|
const assert = require('assert');
|
|
4
5
|
|
|
5
6
|
describe('FuzzyFunction', function() {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
-
const
|
|
2
|
+
const { describe, it } = require('node:test');
|
|
3
|
+
const Grade = require('../../lib/curve/grade');
|
|
3
4
|
const assert = require('assert');
|
|
4
5
|
|
|
5
6
|
describe('Grade', function() {
|
|
@@ -7,8 +8,15 @@ describe('Grade', function() {
|
|
|
7
8
|
assert.equal(typeof Grade, 'function');
|
|
8
9
|
});
|
|
9
10
|
it('can create a new instance', function() {
|
|
11
|
+
var grade = new Grade(0, 1);
|
|
12
|
+
assert.ok(grade instanceof Grade);
|
|
13
|
+
});
|
|
14
|
+
it('sets x0 property correctly', function() {
|
|
10
15
|
var grade = new Grade(0, 1);
|
|
11
16
|
assert.equal(grade.x0, 0);
|
|
17
|
+
});
|
|
18
|
+
it('sets x1 property correctly', function() {
|
|
19
|
+
var grade = new Grade(0, 1);
|
|
12
20
|
assert.equal(grade.x1, 1);
|
|
13
21
|
});
|
|
14
22
|
it('fuzzify', function() {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
-
const
|
|
2
|
+
const { describe, it } = require('node:test');
|
|
3
|
+
const ReverseGrade = require('../../lib/curve/reverse-grade');
|
|
3
4
|
const assert = require('assert');
|
|
4
5
|
|
|
5
6
|
describe('ReverseGrade', function() {
|
|
@@ -7,8 +8,15 @@ describe('ReverseGrade', function() {
|
|
|
7
8
|
assert.equal(typeof ReverseGrade, 'function');
|
|
8
9
|
});
|
|
9
10
|
it('can create a new instance', function() {
|
|
11
|
+
var reverseGrade = new ReverseGrade(0, 1);
|
|
12
|
+
assert.ok(reverseGrade instanceof ReverseGrade);
|
|
13
|
+
});
|
|
14
|
+
it('sets x0 property correctly', function() {
|
|
10
15
|
var reverseGrade = new ReverseGrade(0, 1);
|
|
11
16
|
assert.equal(reverseGrade.x0, 0);
|
|
17
|
+
});
|
|
18
|
+
it('sets x1 property correctly', function() {
|
|
19
|
+
var reverseGrade = new ReverseGrade(0, 1);
|
|
12
20
|
assert.equal(reverseGrade.x1, 1);
|
|
13
21
|
});
|
|
14
22
|
it('fuzzify', function() {
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
const { describe, it } = require('node:test');
|
|
3
|
+
const Shape = require('../../lib/curve/shape');
|
|
4
|
+
const assert = require('assert');
|
|
5
|
+
|
|
6
|
+
describe('Shape', function() {
|
|
7
|
+
it('is a function', function() {
|
|
8
|
+
assert.equal(typeof Shape, 'function');
|
|
9
|
+
});
|
|
10
|
+
it('can create a new instance', function() {
|
|
11
|
+
var shape = new Shape(0, 1, 2, 3);
|
|
12
|
+
assert.ok(shape instanceof Shape);
|
|
13
|
+
});
|
|
14
|
+
it('sets x0 property correctly', function() {
|
|
15
|
+
var shape = new Shape(0, 1, 2, 3);
|
|
16
|
+
assert.equal(shape.x0, 0);
|
|
17
|
+
});
|
|
18
|
+
it('sets x1 property correctly', function() {
|
|
19
|
+
var shape = new Shape(0, 1, 2, 3);
|
|
20
|
+
assert.equal(shape.x1, 1);
|
|
21
|
+
});
|
|
22
|
+
it('sets x2 property correctly', function() {
|
|
23
|
+
var shape = new Shape(0, 1, 2, 3);
|
|
24
|
+
assert.equal(shape.x2, 2);
|
|
25
|
+
});
|
|
26
|
+
it('sets x3 property correctly', function() {
|
|
27
|
+
var shape = new Shape(0, 1, 2, 3);
|
|
28
|
+
assert.equal(shape.x3, 3);
|
|
29
|
+
});
|
|
30
|
+
});
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
-
const
|
|
2
|
+
const { describe, it } = require('node:test');
|
|
3
|
+
const Sigmoid = require('../../../lib/curve/sigmoid');
|
|
3
4
|
const assert = require('assert');
|
|
4
5
|
|
|
5
6
|
describe('Sigmoid', function() {
|
|
@@ -23,15 +24,4 @@ describe('Sigmoid', function() {
|
|
|
23
24
|
var res = sigmoid.fuzzify(1);
|
|
24
25
|
assert.equal(res, 0.5);
|
|
25
26
|
});
|
|
26
|
-
|
|
27
|
-
describe('slope', function() {
|
|
28
|
-
it('slope makes actually a difference', function() {
|
|
29
|
-
const fvalue = 10;
|
|
30
|
-
var sigmoid = new Sigmoid(0, 10);
|
|
31
|
-
var resSmall = sigmoid.fuzzify(fvalue);
|
|
32
|
-
var sigmoid2 = new Sigmoid(0, 100000);
|
|
33
|
-
var resBig = sigmoid2.fuzzify(fvalue);
|
|
34
|
-
assert.notEqual(resSmall, resBig);
|
|
35
|
-
});
|
|
36
|
-
});
|
|
37
|
-
});
|
|
27
|
+
});
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
const { describe, it } = require('node:test');
|
|
3
|
+
const Sigmoid = require('../../../lib/curve/sigmoid');
|
|
4
|
+
const assert = require('assert');
|
|
5
|
+
|
|
6
|
+
describe('center parameter behavior', function() {
|
|
7
|
+
it('should return 0.5 at the center for positive center values', function() {
|
|
8
|
+
var sigmoid = new Sigmoid(2, 1);
|
|
9
|
+
var res = sigmoid.fuzzify(2);
|
|
10
|
+
assert.equal(res, 0.5);
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
it('should return value greater than 0.5 for values right of positive center', function() {
|
|
14
|
+
var sigmoid = new Sigmoid(2, 1);
|
|
15
|
+
var rightOfCenter = sigmoid.fuzzify(4);
|
|
16
|
+
assert(rightOfCenter > 0.5);
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it('should return value less than 1 for values right of positive center', function() {
|
|
20
|
+
var sigmoid = new Sigmoid(2, 1);
|
|
21
|
+
var rightOfCenter = sigmoid.fuzzify(4);
|
|
22
|
+
assert(rightOfCenter < 1);
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it('should return value less than 0.5 for values left of positive center', function() {
|
|
26
|
+
var sigmoid = new Sigmoid(2, 1);
|
|
27
|
+
var leftOfCenter = sigmoid.fuzzify(0);
|
|
28
|
+
assert(leftOfCenter < 0.5);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it('should return value greater than 0 for values left of positive center', function() {
|
|
32
|
+
var sigmoid = new Sigmoid(2, 1);
|
|
33
|
+
var leftOfCenter = sigmoid.fuzzify(0);
|
|
34
|
+
assert(leftOfCenter > 0);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it('should correctly handle negative center values', function() {
|
|
38
|
+
var sigmoid = new Sigmoid(-3, 1);
|
|
39
|
+
|
|
40
|
+
// With center=-3, the sigmoid is centered at x=-3
|
|
41
|
+
// So sigmoid.fuzzify(-3) should return 0.5
|
|
42
|
+
var res = sigmoid.fuzzify(-3);
|
|
43
|
+
assert.equal(res, 0.5);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it('sigmoid should be 0.075 at zero', function() {
|
|
47
|
+
// Test that verifies the sigmoid value at x=0 when center=5
|
|
48
|
+
var sigmoid = new Sigmoid(5, 2);
|
|
49
|
+
var atZero = sigmoid.fuzzify(0);
|
|
50
|
+
assert.equal(atZero, 0.07585818002124355);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
it('should return 0.5 at center point for symmetry', function() {
|
|
54
|
+
var sigmoid = new Sigmoid(5, 2);
|
|
55
|
+
var atCenter = sigmoid.fuzzify(5);
|
|
56
|
+
assert.equal(atCenter, 0.5);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
it('should be symmetric around center point', function() {
|
|
60
|
+
var sigmoid = new Sigmoid(5, 2);
|
|
61
|
+
var rightPoint = sigmoid.fuzzify(7); // 2 units right of center
|
|
62
|
+
var leftPoint = sigmoid.fuzzify(3); // 2 units left of center
|
|
63
|
+
var sum = rightPoint + leftPoint;
|
|
64
|
+
assert(Math.abs(sum - 1) < 0.0000001, `Sum ${sum} should be approximately 1`);
|
|
65
|
+
});
|
|
66
|
+
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
const { describe, it } = require('node:test');
|
|
3
|
+
const Sigmoid = require('../../../lib/curve/sigmoid');
|
|
4
|
+
const assert = require('assert');
|
|
5
|
+
|
|
6
|
+
describe('slope', function() {
|
|
7
|
+
it('slope makes actually a difference', function() {
|
|
8
|
+
const fvalue = 10;
|
|
9
|
+
var sigmoid = new Sigmoid(0, 10);
|
|
10
|
+
var resSmall = sigmoid.fuzzify(fvalue);
|
|
11
|
+
var sigmoid2 = new Sigmoid(0, 100000);
|
|
12
|
+
var resBig = sigmoid2.fuzzify(fvalue);
|
|
13
|
+
assert.notEqual(resSmall, resBig);
|
|
14
|
+
});
|
|
15
|
+
});
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
const { describe, it } = require('node:test');
|
|
3
|
+
const Trapezoid = require('../../../lib/curve/trapezoid');
|
|
4
|
+
const assert = require('assert');
|
|
5
|
+
|
|
6
|
+
describe('Trapezoid', function() {
|
|
7
|
+
it('is a function', function() {
|
|
8
|
+
assert.equal(typeof Trapezoid, 'function');
|
|
9
|
+
});
|
|
10
|
+
it('can create a new instance', function() {
|
|
11
|
+
var trapez = new Trapezoid(0, 10, 20);
|
|
12
|
+
assert.ok(trapez instanceof Trapezoid);
|
|
13
|
+
});
|
|
14
|
+
it('sets x0 property correctly', function() {
|
|
15
|
+
var trapez = new Trapezoid(0, 10, 20);
|
|
16
|
+
assert.equal(trapez.x0, 0);
|
|
17
|
+
});
|
|
18
|
+
it('sets x1 property correctly', function() {
|
|
19
|
+
var trapez = new Trapezoid(0, 10, 20);
|
|
20
|
+
assert.equal(trapez.x1, 10);
|
|
21
|
+
});
|
|
22
|
+
it('sets x2 property correctly', function() {
|
|
23
|
+
var trapez = new Trapezoid(0, 10, 20);
|
|
24
|
+
assert.equal(trapez.x2, 20);
|
|
25
|
+
});
|
|
26
|
+
it('fuzzify', function() {
|
|
27
|
+
var trapez = new Trapezoid(20, 30, 90);
|
|
28
|
+
var res = trapez.fuzzify(25);
|
|
29
|
+
assert.equal(res, 0.5);
|
|
30
|
+
});
|
|
31
|
+
it('avoid NaN if going over max', function() {
|
|
32
|
+
var trapez = new Trapezoid(20, 30, 90, 100);
|
|
33
|
+
var res = trapez.fuzzify(99);
|
|
34
|
+
assert.equal(res, 0.09999999999999964);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it('edge case triangle', function() {
|
|
38
|
+
var trapez = new Trapezoid(0, 0, 1.5, 2.5);
|
|
39
|
+
var res = trapez.fuzzify(0);
|
|
40
|
+
assert.equal(res, 0);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it('edge case triangle right bounds', function() {
|
|
44
|
+
var trapez = new Trapezoid(0, 0, 1.5, 2.5);
|
|
45
|
+
var res = trapez.fuzzify(2.5);
|
|
46
|
+
assert.equal(res, 0);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it('edge case triangle right top', function() {
|
|
50
|
+
var trapez = new Trapezoid(0, 0, 1.5, 2.5);
|
|
51
|
+
var res = trapez.fuzzify(1.5);
|
|
52
|
+
assert.equal(res, 1);
|
|
53
|
+
});
|
|
54
|
+
});
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
const { describe, it } = require('node:test');
|
|
3
|
+
const Trapezoid = require('../../../lib/curve/trapezoid');
|
|
4
|
+
const assert = require('assert');
|
|
5
|
+
|
|
6
|
+
describe('bounds', ()=>{
|
|
7
|
+
it('trapezoid left bounds 0', function() {
|
|
8
|
+
var trapez = new Trapezoid(20, 30, 90, 100);
|
|
9
|
+
var res = trapez.fuzzify(20);
|
|
10
|
+
assert.equal(res, 0);
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
it('trapezoid right bounds 0', function() {
|
|
14
|
+
var trapez = new Trapezoid(20, 30, 90, 100);
|
|
15
|
+
var res = trapez.fuzzify(100);
|
|
16
|
+
assert.equal(res, 0);
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it('trapezoid left top = 1', function() {
|
|
20
|
+
var trapez = new Trapezoid(20, 30, 90, 100);
|
|
21
|
+
var res = trapez.fuzzify(30);
|
|
22
|
+
assert.equal(res, 1);
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it('trapezoid right top = 1', function() {
|
|
26
|
+
var trapez = new Trapezoid(20, 30, 90, 100);
|
|
27
|
+
var res = trapez.fuzzify(90);
|
|
28
|
+
assert.equal(res, 1);
|
|
29
|
+
});
|
|
30
|
+
});
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
const { describe, it } = require('node:test');
|
|
3
|
+
const assert = require('assert');
|
|
4
|
+
const Constant = require('../../lib/curve/constant');
|
|
5
|
+
|
|
6
|
+
describe('Constant edge values', function() {
|
|
7
|
+
describe('all possible constant values', function() {
|
|
8
|
+
it('should return 0 for constant value 0', function() {
|
|
9
|
+
assert.equal(new Constant(0).fuzzify(), 0);
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
it('should return 0.5 for constant value 0.5', function() {
|
|
13
|
+
assert.equal(new Constant(0.5).fuzzify(), 0.5);
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
it('should return 1 for constant value 1', function() {
|
|
17
|
+
assert.equal(new Constant(1).fuzzify(), 1);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it('should return -1 for constant value -1', function() {
|
|
21
|
+
assert.equal(new Constant(-1).fuzzify(), -1);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it('should return 2 for constant value 2', function() {
|
|
25
|
+
assert.equal(new Constant(2).fuzzify(), 2);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it('should return -0.5 for constant value -0.5', function() {
|
|
29
|
+
assert.equal(new Constant(-0.5).fuzzify(), -0.5);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it('should return 1.5 for constant value 1.5', function() {
|
|
33
|
+
assert.equal(new Constant(1.5).fuzzify(), 1.5);
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
describe('ignoring x parameter in fuzzify', function() {
|
|
38
|
+
const constant = new Constant(0.7);
|
|
39
|
+
|
|
40
|
+
it('should return constant value for x=0', function() {
|
|
41
|
+
assert.equal(constant.fuzzify(0), 0.7);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it('should return constant value for x=100', function() {
|
|
45
|
+
assert.equal(constant.fuzzify(100), 0.7);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it('should return constant value for x=-100', function() {
|
|
49
|
+
assert.equal(constant.fuzzify(-100), 0.7);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it('should return constant value for x=Infinity', function() {
|
|
53
|
+
assert.equal(constant.fuzzify(Infinity), 0.7);
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
});
|