tiny-essentials 1.25.4 → 1.25.6
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/changelog/1/25/5.md +5 -0
- package/changelog/1/25/6.md +7 -0
- package/dist/v1/TinyEssentials.min.js +1 -1
- package/dist/v1/TinyMaInSys.min.js +1 -0
- package/dist/v1/index.cjs +5 -0
- package/dist/v1/index.d.mts +5 -1
- package/dist/v1/index.mjs +3 -2
- package/dist/v1/libs/TinyMamdaniInferenceSystem.cjs +289 -0
- package/dist/v1/libs/TinyMamdaniInferenceSystem.d.mts +88 -0
- package/dist/v1/libs/TinyMamdaniInferenceSystem.mjs +248 -0
- package/docs/v1/README.md +1 -0
- package/docs/v1/libs/TinyMamdaniInferenceSystem.md +105 -0
- package/package.json +5 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
(()=>{"use strict";var e={d:(t,r)=>{for(var a in r)e.o(r,a)&&!e.o(t,a)&&Object.defineProperty(t,a,{enumerable:!0,get:r[a]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r:e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})}},t={};e.r(t),e.d(t,{FuzzySet:()=>s,MamdaniInferenceSystem:()=>o,defuzzifyCentroid:()=>a,trapezoid:()=>i});const r=e=>{if(!Array.isArray(e))throw new TypeError("Parameter 'sets' must be an array.");if(!e.every(e=>e instanceof s))throw new TypeError("All elements in the array must be instances of FuzzySet.")},a=(e,t,a=.5)=>{n(e,"object","defuzzifyCentroid.fuzzyOutput");for(const t in e)n(e[t],"number",`fuzzyOutput['${t}']`);r(t),n(a,"number","defuzzifyCentroid.step");let i=0,s=0;for(let r=0;r<=100;r+=a){let a=0;t.forEach(t=>{const i=e[t.name]||0,n=Math.min(i,t.calculate(r));a=Math.max(a,n)}),i+=r*a,s+=a}return 0===s?0:i/s},i=(e,t,r,a,i,n=!1)=>{if(n){if(e<=t||e>=i)return 0;if(e>=r&&e<=a)return 1}const s=t===r?1:(e-t)/(r-t),o=a===i?1:(i-e)/(i-a),u=Math.max(0,Math.min(s,1,o));return isNaN(u)?0:u},n=(e,t,r)=>{if(typeof e!==t)throw new TypeError(`Parameter '${r}' must be a ${t}.`)};class s{static trapezoid(e,t,r,a,n,s=!1){return i(e,t,r,a,n,s)}#e="";#t=0;#r=0;#a=0;#i=0;#n=!1;get name(){return this.#e}set name(e){n(e,"string","FuzzySet.name"),this.#e=e}get a(){return this.#t}set a(e){n(e,"number","FuzzySet.a"),this.#t=e}get b(){return this.#r}set b(e){n(e,"number","FuzzySet.b"),this.#r=e}get c(){return this.#a}set c(e){n(e,"number","FuzzySet.c"),this.#a=e}get d(){return this.#i}set d(e){n(e,"number","FuzzySet.d"),this.#i=e}get optimize(){return this.#n}set optimize(e){n(e,"boolean","FuzzySet.optimize"),this.#n=e}constructor(e,t,r,a,i,n=!1){this.name=e,this.a=t,this.b=r,this.c=a,this.d=i,this.optimize=n}calculate(e){return n(e,"number","calculate.x"),s.trapezoid(e,this.#t,this.#r,this.#a,this.#i,this.#n)}}class o{#s=new Map;addVariable(e,t){n(e,"string","addVariable.name"),r(t),this.#s.set(e,t)}removeVariable(e){return n(e,"string","removeVariable.name"),this.#s.delete(e)}getVariable(e){n(e,"string","getVariable.name");const t=this.#s.get(e);if(!t)throw new Error(`Linguistic variable '${e}' not found in the inference system.`);return[...t]}hasVariable(e){return n(e,"string","hasVariable.name"),this.#s.has(e)}fuzzify(e,t){n(e,"string","fuzzify.varName"),n(t,"number","fuzzify.value");const r=this.#s.get(e)||[],a={};return r.forEach(e=>{a[e.name]=e.calculate(t)}),a}}window.TinyMaInSys=t})();
|
package/dist/v1/index.cjs
CHANGED
|
@@ -50,6 +50,7 @@ var TinyColorValidator = require('./libs/TinyColorValidator.cjs');
|
|
|
50
50
|
var TinyAnalogClock = require('./libs/TinyAnalogClock.cjs');
|
|
51
51
|
var TinyTextDiffer = require('./libs/TinyTextDiffer.cjs');
|
|
52
52
|
var TinyArrayComparator = require('./libs/TinyArrayComparator.cjs');
|
|
53
|
+
var TinyMamdaniInferenceSystem = require('./libs/TinyMamdaniInferenceSystem.cjs');
|
|
53
54
|
|
|
54
55
|
|
|
55
56
|
|
|
@@ -181,3 +182,7 @@ exports.TinyColorValidator = TinyColorValidator;
|
|
|
181
182
|
exports.TinyAnalogClock = TinyAnalogClock;
|
|
182
183
|
exports.TinyTextDiffer = TinyTextDiffer;
|
|
183
184
|
exports.TinyArrayComparator = TinyArrayComparator;
|
|
185
|
+
exports.FuzzySet = TinyMamdaniInferenceSystem.FuzzySet;
|
|
186
|
+
exports.MamdaniInferenceSystem = TinyMamdaniInferenceSystem.MamdaniInferenceSystem;
|
|
187
|
+
exports.defuzzifyCentroid = TinyMamdaniInferenceSystem.defuzzifyCentroid;
|
|
188
|
+
exports.trapezoid = TinyMamdaniInferenceSystem.trapezoid;
|
package/dist/v1/index.d.mts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { FuzzySet } from './libs/TinyMamdaniInferenceSystem.mjs';
|
|
2
|
+
import { MamdaniInferenceSystem } from './libs/TinyMamdaniInferenceSystem.mjs';
|
|
1
3
|
import TinyArrayComparator from './libs/TinyArrayComparator.mjs';
|
|
2
4
|
import TinyTextDiffer from './libs/TinyTextDiffer.mjs';
|
|
3
5
|
import TinyAnalogClock from './libs/TinyAnalogClock.mjs';
|
|
@@ -37,6 +39,8 @@ import TinyRateLimiter from './libs/TinyRateLimiter.mjs';
|
|
|
37
39
|
import ColorSafeStringify from './libs/ColorSafeStringify.mjs';
|
|
38
40
|
import TinyPromiseQueue from './libs/TinyPromiseQueue.mjs';
|
|
39
41
|
import TinyLevelUp from './libs/TinyLevelUp.mjs';
|
|
42
|
+
import { defuzzifyCentroid } from './libs/TinyMamdaniInferenceSystem.mjs';
|
|
43
|
+
import { trapezoid } from './libs/TinyMamdaniInferenceSystem.mjs';
|
|
40
44
|
import { diffArrayList } from './basics/array.mjs';
|
|
41
45
|
import { diffStrings } from './basics/text.mjs';
|
|
42
46
|
import { breakdownDuration } from './basics/clock.mjs';
|
|
@@ -126,5 +130,5 @@ import { getTimeDuration } from './basics/clock.mjs';
|
|
|
126
130
|
import { shuffleArray } from './basics/array.mjs';
|
|
127
131
|
import { toTitleCase } from './basics/text.mjs';
|
|
128
132
|
import { toTitleCaseLowerFirst } from './basics/text.mjs';
|
|
129
|
-
export { TinyArrayComparator, TinyTextDiffer, TinyAnalogClock, TinyColorValidator, TinyLoadingScreen, TinyElementObserver, TinySimpleDice, TinyNeedBar, TinyI18, TinyCookieConsent, TinyInventory, TinyInventoryTrader, TinyArrayPaginator, TinyAdvancedRaffle, TinyDayNightCycle, TinyGamepad, TinyTextarea, TinyNewWinEvents, TinyIframeEvents, TinyLocalStorage, TinyEvents, TinyTimeout, TinyColorConverter, TinyClipboard, TinyTextRangeEditor, TinySmartScroller, UltraRandomMsgGen, TinyAfterScrollWatcher, TinyHtml, TinyNotifications, TinyDomReadyManager, TinyDragger, TinyDragDropDetector, TinyToastNotify, TinyNotifyCenter, TinyRateLimiter, ColorSafeStringify, TinyPromiseQueue, TinyLevelUp, diffArrayList, diffStrings, breakdownDuration, calculateMarketcap, compareMarketcap, getPercentage, areElsCollTop, areElsCollBottom, areElsCollLeft, areElsCollRight, areElsCollPerfTop, areElsCollPerfBottom, areElsCollPerfLeft, areElsCollPerfRight, areElsColliding, areElsPerfColliding, getElsColliding, getElsPerfColliding, getElsCollOverlap, getElsCollOverlapPos, getRectCenter, getElsRelativeCenterOffset, getElsCollDirDepth, getElsCollDetails, safeTextTrim, installWindowHiddenScript, genFibonacciSeq, isDirEmptyAsync, fileSizeAsync, dirSizeAsync, listFilesAsync, listDirsAsync, getLatestBackupPath, fetchJson, fetchText, readJsonBlob, readFileBlob, readBase64Blob, saveJsonFile, readJsonFile, writeJsonFile, ensureDirectory, clearDirectoryAsync, clearDirectory, fileExists, dirExists, isDirEmpty, ensureCopyFile, tryDeleteFile, writeTextFile, listFiles, listDirs, fileSize, dirSize, backupFile, restoreLatestBackup, renameFileBatch, renameFileRegex, renameFileAddPrefixSuffix, renameFileNormalizeCase, renameFilePadNumbers, documentIsFullScreen, isScreenFilled, requestFullScreen, exitFullScreen, isFullScreenMode, onFullScreenChange, offFullScreenChange, isJsonObject, arraySortPositions, formatBytes, addAiMarkerShortcut, extendObjType, reorderObjTypeOrder, cloneObjTypeOrder, countObj, checkObj, objType, ruleOfThree, getSimplePerc, asyncReplace, getAge, formatCustomTimer, formatDayTimer, formatTimer, getTimeDuration, shuffleArray, toTitleCase, toTitleCaseLowerFirst };
|
|
133
|
+
export { FuzzySet, MamdaniInferenceSystem, TinyArrayComparator, TinyTextDiffer, TinyAnalogClock, TinyColorValidator, TinyLoadingScreen, TinyElementObserver, TinySimpleDice, TinyNeedBar, TinyI18, TinyCookieConsent, TinyInventory, TinyInventoryTrader, TinyArrayPaginator, TinyAdvancedRaffle, TinyDayNightCycle, TinyGamepad, TinyTextarea, TinyNewWinEvents, TinyIframeEvents, TinyLocalStorage, TinyEvents, TinyTimeout, TinyColorConverter, TinyClipboard, TinyTextRangeEditor, TinySmartScroller, UltraRandomMsgGen, TinyAfterScrollWatcher, TinyHtml, TinyNotifications, TinyDomReadyManager, TinyDragger, TinyDragDropDetector, TinyToastNotify, TinyNotifyCenter, TinyRateLimiter, ColorSafeStringify, TinyPromiseQueue, TinyLevelUp, defuzzifyCentroid, trapezoid, diffArrayList, diffStrings, breakdownDuration, calculateMarketcap, compareMarketcap, getPercentage, areElsCollTop, areElsCollBottom, areElsCollLeft, areElsCollRight, areElsCollPerfTop, areElsCollPerfBottom, areElsCollPerfLeft, areElsCollPerfRight, areElsColliding, areElsPerfColliding, getElsColliding, getElsPerfColliding, getElsCollOverlap, getElsCollOverlapPos, getRectCenter, getElsRelativeCenterOffset, getElsCollDirDepth, getElsCollDetails, safeTextTrim, installWindowHiddenScript, genFibonacciSeq, isDirEmptyAsync, fileSizeAsync, dirSizeAsync, listFilesAsync, listDirsAsync, getLatestBackupPath, fetchJson, fetchText, readJsonBlob, readFileBlob, readBase64Blob, saveJsonFile, readJsonFile, writeJsonFile, ensureDirectory, clearDirectoryAsync, clearDirectory, fileExists, dirExists, isDirEmpty, ensureCopyFile, tryDeleteFile, writeTextFile, listFiles, listDirs, fileSize, dirSize, backupFile, restoreLatestBackup, renameFileBatch, renameFileRegex, renameFileAddPrefixSuffix, renameFileNormalizeCase, renameFilePadNumbers, documentIsFullScreen, isScreenFilled, requestFullScreen, exitFullScreen, isFullScreenMode, onFullScreenChange, offFullScreenChange, isJsonObject, arraySortPositions, formatBytes, addAiMarkerShortcut, extendObjType, reorderObjTypeOrder, cloneObjTypeOrder, countObj, checkObj, objType, ruleOfThree, getSimplePerc, asyncReplace, getAge, formatCustomTimer, formatDayTimer, formatTimer, getTimeDuration, shuffleArray, toTitleCase, toTitleCaseLowerFirst };
|
|
130
134
|
//# sourceMappingURL=index.d.mts.map
|
package/dist/v1/index.mjs
CHANGED
|
@@ -48,7 +48,8 @@ import TinyColorValidator from './libs/TinyColorValidator.mjs';
|
|
|
48
48
|
import TinyAnalogClock from './libs/TinyAnalogClock.mjs';
|
|
49
49
|
import TinyTextDiffer from './libs/TinyTextDiffer.mjs';
|
|
50
50
|
import TinyArrayComparator from './libs/TinyArrayComparator.mjs';
|
|
51
|
+
import { FuzzySet, MamdaniInferenceSystem, trapezoid, defuzzifyCentroid, } from './libs/TinyMamdaniInferenceSystem.mjs';
|
|
51
52
|
// import TinyHtmlElems from './libs/TinyHtml/index.mjs';
|
|
52
|
-
export { TinyArrayComparator, TinyTextDiffer, TinyAnalogClock,
|
|
53
|
+
export { FuzzySet, MamdaniInferenceSystem, TinyArrayComparator, TinyTextDiffer, TinyAnalogClock,
|
|
53
54
|
// TinyHtmlElems,
|
|
54
|
-
TinyColorValidator, TinyLoadingScreen, TinyElementObserver, TinySimpleDice, TinyNeedBar, TinyI18, TinyCookieConsent, TinyInventory, TinyInventoryTrader, TinyArrayPaginator, TinyAdvancedRaffle, TinyDayNightCycle, TinyGamepad, TinyTextarea, TinyNewWinEvents, TinyIframeEvents, TinyLocalStorage, TinyEvents, TinyTimeout, TinyColorConverter, TinyClipboard, TinyTextRangeEditor, TinySmartScroller, UltraRandomMsgGen, TinyAfterScrollWatcher, TinyHtml, TinyNotifications, TinyDomReadyManager, TinyDragger, TinyDragDropDetector, TinyToastNotify, TinyNotifyCenter, TinyRateLimiter, ColorSafeStringify, TinyPromiseQueue, TinyLevelUp, diffArrayList, diffStrings, breakdownDuration, calculateMarketcap, compareMarketcap, getPercentage, areElsCollTop, areElsCollBottom, areElsCollLeft, areElsCollRight, areElsCollPerfTop, areElsCollPerfBottom, areElsCollPerfLeft, areElsCollPerfRight, areElsColliding, areElsPerfColliding, getElsColliding, getElsPerfColliding, getElsCollOverlap, getElsCollOverlapPos, getRectCenter, getElsRelativeCenterOffset, getElsCollDirDepth, getElsCollDetails, safeTextTrim, installWindowHiddenScript, genFibonacciSeq, isDirEmptyAsync, fileSizeAsync, dirSizeAsync, listFilesAsync, listDirsAsync, getLatestBackupPath, fetchJson, fetchText, readJsonBlob, readFileBlob, readBase64Blob, saveJsonFile, readJsonFile, writeJsonFile, ensureDirectory, clearDirectoryAsync, clearDirectory, fileExists, dirExists, isDirEmpty, ensureCopyFile, tryDeleteFile, writeTextFile, listFiles, listDirs, fileSize, dirSize, backupFile, restoreLatestBackup, renameFileBatch, renameFileRegex, renameFileAddPrefixSuffix, renameFileNormalizeCase, renameFilePadNumbers, documentIsFullScreen, isScreenFilled, requestFullScreen, exitFullScreen, isFullScreenMode, onFullScreenChange, offFullScreenChange, isJsonObject, arraySortPositions, formatBytes, addAiMarkerShortcut, extendObjType, reorderObjTypeOrder, cloneObjTypeOrder, countObj, checkObj, objType, ruleOfThree, getSimplePerc, asyncReplace, getAge, formatCustomTimer, formatDayTimer, formatTimer, getTimeDuration, shuffleArray, toTitleCase, toTitleCaseLowerFirst, };
|
|
55
|
+
TinyColorValidator, TinyLoadingScreen, TinyElementObserver, TinySimpleDice, TinyNeedBar, TinyI18, TinyCookieConsent, TinyInventory, TinyInventoryTrader, TinyArrayPaginator, TinyAdvancedRaffle, TinyDayNightCycle, TinyGamepad, TinyTextarea, TinyNewWinEvents, TinyIframeEvents, TinyLocalStorage, TinyEvents, TinyTimeout, TinyColorConverter, TinyClipboard, TinyTextRangeEditor, TinySmartScroller, UltraRandomMsgGen, TinyAfterScrollWatcher, TinyHtml, TinyNotifications, TinyDomReadyManager, TinyDragger, TinyDragDropDetector, TinyToastNotify, TinyNotifyCenter, TinyRateLimiter, ColorSafeStringify, TinyPromiseQueue, TinyLevelUp, defuzzifyCentroid, trapezoid, diffArrayList, diffStrings, breakdownDuration, calculateMarketcap, compareMarketcap, getPercentage, areElsCollTop, areElsCollBottom, areElsCollLeft, areElsCollRight, areElsCollPerfTop, areElsCollPerfBottom, areElsCollPerfLeft, areElsCollPerfRight, areElsColliding, areElsPerfColliding, getElsColliding, getElsPerfColliding, getElsCollOverlap, getElsCollOverlapPos, getRectCenter, getElsRelativeCenterOffset, getElsCollDirDepth, getElsCollDetails, safeTextTrim, installWindowHiddenScript, genFibonacciSeq, isDirEmptyAsync, fileSizeAsync, dirSizeAsync, listFilesAsync, listDirsAsync, getLatestBackupPath, fetchJson, fetchText, readJsonBlob, readFileBlob, readBase64Blob, saveJsonFile, readJsonFile, writeJsonFile, ensureDirectory, clearDirectoryAsync, clearDirectory, fileExists, dirExists, isDirEmpty, ensureCopyFile, tryDeleteFile, writeTextFile, listFiles, listDirs, fileSize, dirSize, backupFile, restoreLatestBackup, renameFileBatch, renameFileRegex, renameFileAddPrefixSuffix, renameFileNormalizeCase, renameFilePadNumbers, documentIsFullScreen, isScreenFilled, requestFullScreen, exitFullScreen, isFullScreenMode, onFullScreenChange, offFullScreenChange, isJsonObject, arraySortPositions, formatBytes, addAiMarkerShortcut, extendObjType, reorderObjTypeOrder, cloneObjTypeOrder, countObj, checkObj, objType, ruleOfThree, getSimplePerc, asyncReplace, getAge, formatCustomTimer, formatDayTimer, formatTimer, getTimeDuration, shuffleArray, toTitleCase, toTitleCaseLowerFirst, };
|
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Internal helper to validate an array of FuzzySets.
|
|
5
|
+
* @param {FuzzySet[]} sets
|
|
6
|
+
*/
|
|
7
|
+
const validateFuzzySets = (sets) => {
|
|
8
|
+
if (!Array.isArray(sets)) {
|
|
9
|
+
throw new TypeError("Parameter 'sets' must be an array.");
|
|
10
|
+
}
|
|
11
|
+
if (!sets.every((set) => set instanceof FuzzySet)) {
|
|
12
|
+
throw new TypeError('All elements in the array must be instances of FuzzySet.');
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Performs defuzzification using the Centroid (Center of Gravity) method.
|
|
18
|
+
* @param {Object.<string, number>} fuzzyOutput - Results from rule evaluation.
|
|
19
|
+
* @param {FuzzySet[]} outputSets - The sets defining the output range.
|
|
20
|
+
* @param {number} [step=0.5] - Resolution of the integral approximation.
|
|
21
|
+
* @returns {number} The crisp output value.
|
|
22
|
+
*/
|
|
23
|
+
const defuzzifyCentroid = (fuzzyOutput, outputSets, step = 0.5) => {
|
|
24
|
+
validateType(fuzzyOutput, 'object', 'defuzzifyCentroid.fuzzyOutput');
|
|
25
|
+
|
|
26
|
+
for (const outputName in fuzzyOutput) {
|
|
27
|
+
validateType(fuzzyOutput[outputName], 'number', `fuzzyOutput['${outputName}']`);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
validateFuzzySets(outputSets);
|
|
31
|
+
validateType(step, 'number', 'defuzzifyCentroid.step');
|
|
32
|
+
|
|
33
|
+
/** @type {number} - Accumulated weighted area for centroid */
|
|
34
|
+
let totalAreaWeighted = 0;
|
|
35
|
+
/** @type {number} - Accumulated total area */
|
|
36
|
+
let totalArea = 0;
|
|
37
|
+
|
|
38
|
+
// Numerical integration (Centroid approximation)
|
|
39
|
+
for (let i = 0; i <= 100; i += step) {
|
|
40
|
+
/** @type {number} - Maximum membership found at point x(i) */
|
|
41
|
+
let maxMembershipAtX = 0;
|
|
42
|
+
|
|
43
|
+
outputSets.forEach((set) => {
|
|
44
|
+
/** @type {number} - Rule strength applied to the output set */
|
|
45
|
+
const strength = fuzzyOutput[set.name] || 0;
|
|
46
|
+
/** @type {number} - Cut or scale the output set membership */
|
|
47
|
+
const membership = Math.min(strength, set.calculate(i));
|
|
48
|
+
|
|
49
|
+
maxMembershipAtX = Math.max(maxMembershipAtX, membership);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
totalAreaWeighted += i * maxMembershipAtX;
|
|
53
|
+
totalArea += maxMembershipAtX;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return totalArea === 0 ? 0 : totalAreaWeighted / totalArea;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Utility to calculate fuzzy membership using a trapezoidal shape safely.
|
|
61
|
+
* @param {number} value - The input value to check.
|
|
62
|
+
* @param {number} a - Start of the rise.
|
|
63
|
+
* @param {number} b - End of the rise (start of plateau).
|
|
64
|
+
* @param {number} c - Start of the fall (end of plateau).
|
|
65
|
+
* @param {number} d - End of the fall.
|
|
66
|
+
* @param {boolean} [optimize=false] - Optimizes performance by skipping math for absolute bounds.
|
|
67
|
+
* @returns {number} Degree of membership [0, 1].
|
|
68
|
+
*/
|
|
69
|
+
const trapezoid = (value, a, b, c, d, optimize = false) => {
|
|
70
|
+
if (optimize) {
|
|
71
|
+
// If the value is completely outside the outer bounds, return 0 immediately
|
|
72
|
+
if (value <= a || value >= d) return 0;
|
|
73
|
+
// If the value is entirely within the plateau, return 1 immediately
|
|
74
|
+
if (value >= b && value <= c) return 1;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/** @type {number} - Safely calculate rising slope */
|
|
78
|
+
const rise = a === b ? 1 : (value - a) / (b - a);
|
|
79
|
+
|
|
80
|
+
/** @type {number} - Safely calculate falling slope */
|
|
81
|
+
const fall = c === d ? 1 : (d - value) / (d - c);
|
|
82
|
+
|
|
83
|
+
/** @type {number} - Internal value clamping between 0 and 1 */
|
|
84
|
+
const membership = Math.max(0, Math.min(rise, 1, fall));
|
|
85
|
+
|
|
86
|
+
return isNaN(membership) ? 0 : membership;
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Utility to validate types and throw formatted errors, preventing code repetition.
|
|
91
|
+
* @param {any} value - The value to evaluate.
|
|
92
|
+
* @param {string} expectedType - The expected data type.
|
|
93
|
+
* @param {string} paramName - The name of the parameter for the error message.
|
|
94
|
+
*/
|
|
95
|
+
const validateType = (value, expectedType, paramName) => {
|
|
96
|
+
if (typeof value !== expectedType) {
|
|
97
|
+
throw new TypeError(`Parameter '${paramName}' must be a ${expectedType}.`);
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Represents a single Membership Function (Trapezoidal).
|
|
103
|
+
*/
|
|
104
|
+
class FuzzySet {
|
|
105
|
+
/**
|
|
106
|
+
* Utility to calculate fuzzy membership using a trapezoidal shape.
|
|
107
|
+
* @param {number} value - The input value to check.
|
|
108
|
+
* @param {number} a - Start of the rise.
|
|
109
|
+
* @param {number} b - End of the rise (start of plateau).
|
|
110
|
+
* @param {number} c - Start of the fall (end of plateau).
|
|
111
|
+
* @param {number} d - End of the fall.
|
|
112
|
+
* @param {boolean} [optimize=false] - Performance optimization flag.
|
|
113
|
+
* @returns {number} Degree of membership [0, 1].
|
|
114
|
+
*/
|
|
115
|
+
static trapezoid(value, a, b, c, d, optimize = false) {
|
|
116
|
+
return trapezoid(value, a, b, c, d, optimize);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/** @type {string} - Internal name of the fuzzy set */
|
|
120
|
+
#name = '';
|
|
121
|
+
/** @type {number} - Internal left foot coordinate */
|
|
122
|
+
#a = 0;
|
|
123
|
+
/** @type {number} - Internal left shoulder coordinate */
|
|
124
|
+
#b = 0;
|
|
125
|
+
/** @type {number} - Internal right shoulder coordinate */
|
|
126
|
+
#c = 0;
|
|
127
|
+
/** @type {number} - Internal right foot coordinate */
|
|
128
|
+
#d = 0;
|
|
129
|
+
/** @type {boolean} - Internal flag to enable calculation optimization */
|
|
130
|
+
#optimize = false;
|
|
131
|
+
|
|
132
|
+
get name() {
|
|
133
|
+
return this.#name;
|
|
134
|
+
}
|
|
135
|
+
set name(value) {
|
|
136
|
+
validateType(value, 'string', 'FuzzySet.name');
|
|
137
|
+
this.#name = value;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
get a() {
|
|
141
|
+
return this.#a;
|
|
142
|
+
}
|
|
143
|
+
set a(value) {
|
|
144
|
+
validateType(value, 'number', 'FuzzySet.a');
|
|
145
|
+
this.#a = value;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
get b() {
|
|
149
|
+
return this.#b;
|
|
150
|
+
}
|
|
151
|
+
set b(value) {
|
|
152
|
+
validateType(value, 'number', 'FuzzySet.b');
|
|
153
|
+
this.#b = value;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
get c() {
|
|
157
|
+
return this.#c;
|
|
158
|
+
}
|
|
159
|
+
set c(value) {
|
|
160
|
+
validateType(value, 'number', 'FuzzySet.c');
|
|
161
|
+
this.#c = value;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
get d() {
|
|
165
|
+
return this.#d;
|
|
166
|
+
}
|
|
167
|
+
set d(value) {
|
|
168
|
+
validateType(value, 'number', 'FuzzySet.d');
|
|
169
|
+
this.#d = value;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
get optimize() {
|
|
173
|
+
return this.#optimize;
|
|
174
|
+
}
|
|
175
|
+
set optimize(value) {
|
|
176
|
+
validateType(value, 'boolean', 'FuzzySet.optimize');
|
|
177
|
+
this.#optimize = value;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* @param {string} name - Name of the set (e.g., "Hot").
|
|
182
|
+
* @param {number} a - Left foot.
|
|
183
|
+
* @param {number} b - Left shoulder.
|
|
184
|
+
* @param {number} c - Right shoulder.
|
|
185
|
+
* @param {number} d - Right feet.
|
|
186
|
+
* @param {boolean} [optimize=false] - Enables performance optimization.
|
|
187
|
+
*/
|
|
188
|
+
constructor(name, a, b, c, d, optimize = false) {
|
|
189
|
+
this.name = name;
|
|
190
|
+
this.a = a;
|
|
191
|
+
this.b = b;
|
|
192
|
+
this.c = c;
|
|
193
|
+
this.d = d;
|
|
194
|
+
this.optimize = optimize;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Calculates the membership degree.
|
|
199
|
+
* @param {number} x - Crisp input.
|
|
200
|
+
* @returns {number}
|
|
201
|
+
*/
|
|
202
|
+
calculate(x) {
|
|
203
|
+
validateType(x, 'number', 'calculate.x');
|
|
204
|
+
return FuzzySet.trapezoid(x, this.#a, this.#b, this.#c, this.#d, this.#optimize);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* The Inference Engine handles linguistic variables and defuzzification.
|
|
210
|
+
*/
|
|
211
|
+
class MamdaniInferenceSystem {
|
|
212
|
+
/** @type {Map<string, FuzzySet[]>} - Storage for linguistic variables */
|
|
213
|
+
#variables = new Map();
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Registers a linguistic variable and its sets.
|
|
217
|
+
* @param {string} name - Variable name (e.g., "temperature").
|
|
218
|
+
* @param {FuzzySet[]} sets - Array of fuzzy sets.
|
|
219
|
+
*/
|
|
220
|
+
addVariable(name, sets) {
|
|
221
|
+
validateType(name, 'string', 'addVariable.name');
|
|
222
|
+
validateFuzzySets(sets);
|
|
223
|
+
this.#variables.set(name, sets);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Removes a linguistic variable.
|
|
228
|
+
* @param {string} name - Variable name (e.g., "temperature").
|
|
229
|
+
* @returns {boolean} True if the element was successfully removed.
|
|
230
|
+
*/
|
|
231
|
+
removeVariable(name) {
|
|
232
|
+
validateType(name, 'string', 'removeVariable.name');
|
|
233
|
+
return this.#variables.delete(name);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Gets a linguistic variable and its sets.
|
|
238
|
+
* @param {string} name - Variable name (e.g., "temperature").
|
|
239
|
+
* @returns {FuzzySet[]}
|
|
240
|
+
*/
|
|
241
|
+
getVariable(name) {
|
|
242
|
+
validateType(name, 'string', 'getVariable.name');
|
|
243
|
+
|
|
244
|
+
/** @type {FuzzySet[] | undefined} - Attempted fetch from map */
|
|
245
|
+
const result = this.#variables.get(name);
|
|
246
|
+
|
|
247
|
+
if (!result)
|
|
248
|
+
throw new Error(`Linguistic variable '${name}' not found in the inference system.`);
|
|
249
|
+
|
|
250
|
+
return [...result];
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* Checks if a linguistic variable exists.
|
|
255
|
+
* @param {string} name - Variable name (e.g., "temperature").
|
|
256
|
+
* @returns {boolean}
|
|
257
|
+
*/
|
|
258
|
+
hasVariable(name) {
|
|
259
|
+
validateType(name, 'string', 'hasVariable.name');
|
|
260
|
+
return this.#variables.has(name);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Fuzzifies a crisp input into a map of memberships.
|
|
265
|
+
* @param {string} varName
|
|
266
|
+
* @param {number} value
|
|
267
|
+
* @returns {Object.<string, number>}
|
|
268
|
+
*/
|
|
269
|
+
fuzzify(varName, value) {
|
|
270
|
+
validateType(varName, 'string', 'fuzzify.varName');
|
|
271
|
+
validateType(value, 'number', 'fuzzify.value');
|
|
272
|
+
|
|
273
|
+
/** @type {FuzzySet[]} - The sets associated with the variable */
|
|
274
|
+
const sets = this.#variables.get(varName) || [];
|
|
275
|
+
/** @type {Object.<string, number>} - The fuzzified results dictionary */
|
|
276
|
+
const results = {};
|
|
277
|
+
|
|
278
|
+
sets.forEach((set) => {
|
|
279
|
+
results[set.name] = set.calculate(value);
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
return results;
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
exports.FuzzySet = FuzzySet;
|
|
287
|
+
exports.MamdaniInferenceSystem = MamdaniInferenceSystem;
|
|
288
|
+
exports.defuzzifyCentroid = defuzzifyCentroid;
|
|
289
|
+
exports.trapezoid = trapezoid;
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
export function defuzzifyCentroid(fuzzyOutput: {
|
|
2
|
+
[x: string]: number;
|
|
3
|
+
}, outputSets: FuzzySet[], step?: number): number;
|
|
4
|
+
export function trapezoid(value: number, a: number, b: number, c: number, d: number, optimize?: boolean): number;
|
|
5
|
+
/**
|
|
6
|
+
* Represents a single Membership Function (Trapezoidal).
|
|
7
|
+
*/
|
|
8
|
+
export class FuzzySet {
|
|
9
|
+
/**
|
|
10
|
+
* Utility to calculate fuzzy membership using a trapezoidal shape.
|
|
11
|
+
* @param {number} value - The input value to check.
|
|
12
|
+
* @param {number} a - Start of the rise.
|
|
13
|
+
* @param {number} b - End of the rise (start of plateau).
|
|
14
|
+
* @param {number} c - Start of the fall (end of plateau).
|
|
15
|
+
* @param {number} d - End of the fall.
|
|
16
|
+
* @param {boolean} [optimize=false] - Performance optimization flag.
|
|
17
|
+
* @returns {number} Degree of membership [0, 1].
|
|
18
|
+
*/
|
|
19
|
+
static trapezoid(value: number, a: number, b: number, c: number, d: number, optimize?: boolean): number;
|
|
20
|
+
/**
|
|
21
|
+
* @param {string} name - Name of the set (e.g., "Hot").
|
|
22
|
+
* @param {number} a - Left foot.
|
|
23
|
+
* @param {number} b - Left shoulder.
|
|
24
|
+
* @param {number} c - Right shoulder.
|
|
25
|
+
* @param {number} d - Right feet.
|
|
26
|
+
* @param {boolean} [optimize=false] - Enables performance optimization.
|
|
27
|
+
*/
|
|
28
|
+
constructor(name: string, a: number, b: number, c: number, d: number, optimize?: boolean);
|
|
29
|
+
set name(value: string);
|
|
30
|
+
get name(): string;
|
|
31
|
+
set a(value: number);
|
|
32
|
+
get a(): number;
|
|
33
|
+
set b(value: number);
|
|
34
|
+
get b(): number;
|
|
35
|
+
set c(value: number);
|
|
36
|
+
get c(): number;
|
|
37
|
+
set d(value: number);
|
|
38
|
+
get d(): number;
|
|
39
|
+
set optimize(value: boolean);
|
|
40
|
+
get optimize(): boolean;
|
|
41
|
+
/**
|
|
42
|
+
* Calculates the membership degree.
|
|
43
|
+
* @param {number} x - Crisp input.
|
|
44
|
+
* @returns {number}
|
|
45
|
+
*/
|
|
46
|
+
calculate(x: number): number;
|
|
47
|
+
#private;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* The Inference Engine handles linguistic variables and defuzzification.
|
|
51
|
+
*/
|
|
52
|
+
export class MamdaniInferenceSystem {
|
|
53
|
+
/**
|
|
54
|
+
* Registers a linguistic variable and its sets.
|
|
55
|
+
* @param {string} name - Variable name (e.g., "temperature").
|
|
56
|
+
* @param {FuzzySet[]} sets - Array of fuzzy sets.
|
|
57
|
+
*/
|
|
58
|
+
addVariable(name: string, sets: FuzzySet[]): void;
|
|
59
|
+
/**
|
|
60
|
+
* Removes a linguistic variable.
|
|
61
|
+
* @param {string} name - Variable name (e.g., "temperature").
|
|
62
|
+
* @returns {boolean} True if the element was successfully removed.
|
|
63
|
+
*/
|
|
64
|
+
removeVariable(name: string): boolean;
|
|
65
|
+
/**
|
|
66
|
+
* Gets a linguistic variable and its sets.
|
|
67
|
+
* @param {string} name - Variable name (e.g., "temperature").
|
|
68
|
+
* @returns {FuzzySet[]}
|
|
69
|
+
*/
|
|
70
|
+
getVariable(name: string): FuzzySet[];
|
|
71
|
+
/**
|
|
72
|
+
* Checks if a linguistic variable exists.
|
|
73
|
+
* @param {string} name - Variable name (e.g., "temperature").
|
|
74
|
+
* @returns {boolean}
|
|
75
|
+
*/
|
|
76
|
+
hasVariable(name: string): boolean;
|
|
77
|
+
/**
|
|
78
|
+
* Fuzzifies a crisp input into a map of memberships.
|
|
79
|
+
* @param {string} varName
|
|
80
|
+
* @param {number} value
|
|
81
|
+
* @returns {Object.<string, number>}
|
|
82
|
+
*/
|
|
83
|
+
fuzzify(varName: string, value: number): {
|
|
84
|
+
[x: string]: number;
|
|
85
|
+
};
|
|
86
|
+
#private;
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=TinyMamdaniInferenceSystem.d.mts.map
|