node-red-contrib-prib-functions 0.21.0 → 0.22.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/README.md +4 -0
- package/dataAnalysis/arrayAverage.js +13 -0
- package/dataAnalysis/arraySum.js +14 -0
- package/dataAnalysis/arrayTypesForEach.js +5 -0
- package/dataAnalysis/autocorrelation.js +29 -0
- package/dataAnalysis/dataAnalysis.html +3 -1
- package/dataAnalysis/dataAnalysis.js +3 -0
- package/documentation/matrix.jpg +0 -0
- package/package.json +3 -1
- package/test/data/.config.nodes.json +1 -1
- package/test/data/.config.nodes.json.backup +1 -1
- package/test/data/.flow.json.backup +98 -2
- package/test/data/flow.json +96 -0
- package/test/dataAnalysisExtensions.js +20 -0
- package/testing/test.html +4 -0
- package/testing/test.js +1 -1
package/README.md
CHANGED
|
@@ -30,6 +30,8 @@ being outside 3 standard deviations from mean. This can be changed to median and
|
|
|
30
30
|
A set of data analysis functions that can be run over an array of data
|
|
31
31
|
|
|
32
32
|
Single value metrics:
|
|
33
|
+
* autocorrelation
|
|
34
|
+
* Autocovariance
|
|
33
35
|
* Average/Mean
|
|
34
36
|
* Maximum
|
|
35
37
|
* Median
|
|
@@ -301,6 +303,8 @@ Test/example flow in test/generalTest.json
|
|
|
301
303
|
|
|
302
304
|
# Version
|
|
303
305
|
|
|
306
|
+
0.22.0 Add autocovariance + autocorealationship to real time data analystics, improves test
|
|
307
|
+
|
|
304
308
|
0.21.0 Add lag/seasonal to real time data analystics
|
|
305
309
|
|
|
306
310
|
0.20.3 Add difference + monitor system
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
const arrayTypesForEach=require("./arrayTypesForEach.js")
|
|
2
|
+
require("./arraySum.js")
|
|
3
|
+
|
|
4
|
+
arrayTypesForEach(object=>{
|
|
5
|
+
if(object.prototype.average==null)
|
|
6
|
+
Object.defineProperty(object.prototype, "average", {
|
|
7
|
+
value(i=0,end=this.length-1) {
|
|
8
|
+
return this.sum(i,end)/this.length;
|
|
9
|
+
},
|
|
10
|
+
writable: true,
|
|
11
|
+
configurable: true
|
|
12
|
+
});
|
|
13
|
+
})
|
package/dataAnalysis/arraySum.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/*
|
|
1
2
|
[Array,Float32Array,Float64Array].forEach(object=>{
|
|
2
3
|
if(object.prototype.sum==null)
|
|
3
4
|
Object.defineProperty(object.prototype, "sum", {
|
|
@@ -8,4 +9,17 @@
|
|
|
8
9
|
writable: true,
|
|
9
10
|
configurable: true
|
|
10
11
|
});
|
|
12
|
+
})
|
|
13
|
+
*/
|
|
14
|
+
const arrayTypesForEach=require("./arrayTypesForEach.js")
|
|
15
|
+
arrayTypesForEach(object=>{
|
|
16
|
+
if(object.prototype.sum==null)
|
|
17
|
+
Object.defineProperty(object.prototype, "sum", {
|
|
18
|
+
value(i=0,end=this.length-1,sum=0) {
|
|
19
|
+
for(;i<=end;i++) sum+=this[i];
|
|
20
|
+
return sum;
|
|
21
|
+
},
|
|
22
|
+
writable: true,
|
|
23
|
+
configurable: true
|
|
24
|
+
});
|
|
11
25
|
})
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
const typedArrays= {Array:Array,Int8Array:Int8Array,Uint8Array:Uint8Array,Uint8ClampedArray:Uint8ClampedArray,Int16Array:Int16Array,Uint16Array:Uint16Array,
|
|
2
|
+
Int32Array:Int32Array,Uint32Array:Uint32Array,Float32Array:Float32Array,
|
|
3
|
+
Float64Array:Float64Array,BigInt64Array:BigInt64Array,BigUint64Array:BigUint64Array}
|
|
4
|
+
|
|
5
|
+
module.exports=(call)=>Object.keys(typedArrays).map(t=>typedArrays[t]).forEach(type=>call(type))
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
|
|
2
|
+
require("./arrayAverage.js");
|
|
3
|
+
const arrayTypesForEach=require("./arrayTypesForEach.js")
|
|
4
|
+
arrayTypesForEach(object=>{
|
|
5
|
+
if(object.prototype.autocovariance==null)
|
|
6
|
+
Object.defineProperty(object.prototype, "autocovariance", {
|
|
7
|
+
value(lag,avg=this.average()) {
|
|
8
|
+
let autoCov = 0
|
|
9
|
+
const vectorSize=this.length
|
|
10
|
+
const vectorSizeLagged=vectorSize-lag
|
|
11
|
+
for(let i=0; i<vectorSizeLagged; i++) {
|
|
12
|
+
autoCov += ((this[i+lag])-avg)*(this[i]-avg)
|
|
13
|
+
}
|
|
14
|
+
return (1/(vectorSize-1))*autoCov
|
|
15
|
+
},
|
|
16
|
+
writable: true,
|
|
17
|
+
configurable: true
|
|
18
|
+
})
|
|
19
|
+
})
|
|
20
|
+
arrayTypesForEach(object=>{
|
|
21
|
+
if(object.prototype.autocorrelation==null)
|
|
22
|
+
Object.defineProperty(object.prototype, "autocorrelation", {
|
|
23
|
+
value(lag,avg=this.average()) {
|
|
24
|
+
return this.autocovariance(lag, avg) / this.autocovariance(0, avg)
|
|
25
|
+
},
|
|
26
|
+
writable: true,
|
|
27
|
+
configurable: true
|
|
28
|
+
})
|
|
29
|
+
})
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
}
|
|
48
48
|
});
|
|
49
49
|
$("#node-input-action").change(function() {
|
|
50
|
-
if(["differenceSeasonal","differenceSeasonalSecondOrder","realtime","realtimePredict"].includes( $(this).val() )) {
|
|
50
|
+
if(["autocovariance","autocorrelation","differenceSeasonal","differenceSeasonalSecondOrder","realtime","realtimePredict"].includes( $(this).val() )) {
|
|
51
51
|
$(".form-row-http-in-lag").show();
|
|
52
52
|
} else {
|
|
53
53
|
$(".form-row-http-in-lag").hide();
|
|
@@ -158,6 +158,8 @@
|
|
|
158
158
|
<div class="form-row">
|
|
159
159
|
<label for="node-input-action"><i class="fa fa-list-ul"></i> Method</label>
|
|
160
160
|
<select id="node-input-action" placeholder="action">
|
|
161
|
+
<option value="autocovariance">Autocovariance</option>
|
|
162
|
+
<option value="autocorrelation">Autocorrelation</option>
|
|
161
163
|
<option value="avg">Average</option>
|
|
162
164
|
<option value="covariance">Covariance</option>
|
|
163
165
|
<option value="corelationship">Corelationship</option>
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
const logger = new (require("node-red-contrib-logger"))("Data Analysis");
|
|
2
2
|
logger.sendInfo("Copyright 2020 Jaroslav Peter Prib");
|
|
3
3
|
|
|
4
|
+
require("./autocorrelation.js");
|
|
4
5
|
require("./arrayLast");
|
|
5
6
|
require("./arrayDifference")
|
|
6
7
|
require("./arrayDifferenceSeasonal")
|
|
@@ -129,6 +130,8 @@ function getColumns(node) {
|
|
|
129
130
|
}
|
|
130
131
|
}
|
|
131
132
|
functions={
|
|
133
|
+
autocovariance:(d,term,node)=>d.autocovariance(node.lag),
|
|
134
|
+
autocorrelation:(d,term,node)=>d.autocorrelation(node.lag),
|
|
132
135
|
avg:(d)=>functions.sum(d)/d.length,
|
|
133
136
|
arrayMax:(d)=>{ // not tested
|
|
134
137
|
let max=[],indices
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "node-red-contrib-prib-functions",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.22.0",
|
|
4
4
|
"description": "Node-RED added node functions.",
|
|
5
5
|
"dependencies": {
|
|
6
6
|
"avsc": ">=5.7.7",
|
|
@@ -38,6 +38,8 @@
|
|
|
38
38
|
"adjoint",
|
|
39
39
|
"append",
|
|
40
40
|
"analysis",
|
|
41
|
+
"autocorrelation",
|
|
42
|
+
"autocovariance",
|
|
41
43
|
"average",
|
|
42
44
|
"avg",
|
|
43
45
|
"AVRO",
|
|
@@ -1238,6 +1238,102 @@
|
|
|
1238
1238
|
]
|
|
1239
1239
|
]
|
|
1240
1240
|
},
|
|
1241
|
+
{
|
|
1242
|
+
"id": "b7da7a9e30699c6f",
|
|
1243
|
+
"type": "Data Analysis",
|
|
1244
|
+
"z": "cf595649.931658",
|
|
1245
|
+
"name": "",
|
|
1246
|
+
"action": "autocorrelation",
|
|
1247
|
+
"columns": "",
|
|
1248
|
+
"lag": 1,
|
|
1249
|
+
"outputs": 2,
|
|
1250
|
+
"outliersBase": "avg",
|
|
1251
|
+
"outliersStdDevs": "3",
|
|
1252
|
+
"term": 10,
|
|
1253
|
+
"keyProperty": "msg.topic",
|
|
1254
|
+
"dataProperty": "msg.payload",
|
|
1255
|
+
"dataProperties": [
|
|
1256
|
+
"msg.payload[0]",
|
|
1257
|
+
"msg.payload[1]"
|
|
1258
|
+
],
|
|
1259
|
+
"x": 520,
|
|
1260
|
+
"y": 420,
|
|
1261
|
+
"wires": [
|
|
1262
|
+
[
|
|
1263
|
+
"542b732966669deb"
|
|
1264
|
+
],
|
|
1265
|
+
[]
|
|
1266
|
+
]
|
|
1267
|
+
},
|
|
1268
|
+
{
|
|
1269
|
+
"id": "114d327f05e06720",
|
|
1270
|
+
"type": "test",
|
|
1271
|
+
"z": "cf595649.931658",
|
|
1272
|
+
"name": "autocovariance data",
|
|
1273
|
+
"errorFactor": "",
|
|
1274
|
+
"escapeString": false,
|
|
1275
|
+
"infiniteIsNull": false,
|
|
1276
|
+
"payload": "[0.05,0.01,-0.02,0.03,-0.04,0.06,0.02,-0.01,-0.03,0.04]",
|
|
1277
|
+
"payloadType": "json",
|
|
1278
|
+
"result": "-0.38",
|
|
1279
|
+
"resultType": "num",
|
|
1280
|
+
"resultProperty": "msg.result",
|
|
1281
|
+
"topic": "",
|
|
1282
|
+
"x": 160,
|
|
1283
|
+
"y": 420,
|
|
1284
|
+
"wires": [
|
|
1285
|
+
[
|
|
1286
|
+
"b7da7a9e30699c6f"
|
|
1287
|
+
],
|
|
1288
|
+
[
|
|
1289
|
+
"da932227f003cc83"
|
|
1290
|
+
],
|
|
1291
|
+
[
|
|
1292
|
+
"74920ca767d590ba"
|
|
1293
|
+
]
|
|
1294
|
+
]
|
|
1295
|
+
},
|
|
1296
|
+
{
|
|
1297
|
+
"id": "da932227f003cc83",
|
|
1298
|
+
"type": "debug",
|
|
1299
|
+
"z": "cf595649.931658",
|
|
1300
|
+
"name": "error",
|
|
1301
|
+
"active": true,
|
|
1302
|
+
"tosidebar": true,
|
|
1303
|
+
"console": false,
|
|
1304
|
+
"tostatus": false,
|
|
1305
|
+
"complete": "true",
|
|
1306
|
+
"targetType": "full",
|
|
1307
|
+
"statusVal": "",
|
|
1308
|
+
"statusType": "auto",
|
|
1309
|
+
"x": 710,
|
|
1310
|
+
"y": 340,
|
|
1311
|
+
"wires": []
|
|
1312
|
+
},
|
|
1313
|
+
{
|
|
1314
|
+
"id": "542b732966669deb",
|
|
1315
|
+
"type": "Monitor Flow",
|
|
1316
|
+
"z": "cf595649.931658",
|
|
1317
|
+
"name": "",
|
|
1318
|
+
"x": 390,
|
|
1319
|
+
"y": 340,
|
|
1320
|
+
"wires": [
|
|
1321
|
+
[
|
|
1322
|
+
"114d327f05e06720"
|
|
1323
|
+
]
|
|
1324
|
+
]
|
|
1325
|
+
},
|
|
1326
|
+
{
|
|
1327
|
+
"id": "74920ca767d590ba",
|
|
1328
|
+
"type": "Monitor Flow",
|
|
1329
|
+
"z": "cf595649.931658",
|
|
1330
|
+
"name": "",
|
|
1331
|
+
"x": 370,
|
|
1332
|
+
"y": 500,
|
|
1333
|
+
"wires": [
|
|
1334
|
+
[]
|
|
1335
|
+
]
|
|
1336
|
+
},
|
|
1241
1337
|
{
|
|
1242
1338
|
"id": "ffd72c7.5d152d",
|
|
1243
1339
|
"type": "Host Available",
|
|
@@ -1668,7 +1764,7 @@
|
|
|
1668
1764
|
"type": "matrix",
|
|
1669
1765
|
"z": "ae9957f07bd56e1b",
|
|
1670
1766
|
"name": "",
|
|
1671
|
-
"action": "
|
|
1767
|
+
"action": "defineEmpty",
|
|
1672
1768
|
"args": [
|
|
1673
1769
|
"rows",
|
|
1674
1770
|
"columns",
|
|
@@ -1705,7 +1801,7 @@
|
|
|
1705
1801
|
"value-type": "msg",
|
|
1706
1802
|
"vector": "payload",
|
|
1707
1803
|
"vector-type": "msg",
|
|
1708
|
-
"x":
|
|
1804
|
+
"x": 310,
|
|
1709
1805
|
"y": 260,
|
|
1710
1806
|
"wires": [
|
|
1711
1807
|
[
|
package/test/data/flow.json
CHANGED
|
@@ -1238,6 +1238,102 @@
|
|
|
1238
1238
|
]
|
|
1239
1239
|
]
|
|
1240
1240
|
},
|
|
1241
|
+
{
|
|
1242
|
+
"id": "b7da7a9e30699c6f",
|
|
1243
|
+
"type": "Data Analysis",
|
|
1244
|
+
"z": "cf595649.931658",
|
|
1245
|
+
"name": "",
|
|
1246
|
+
"action": "autocorrelation",
|
|
1247
|
+
"columns": "",
|
|
1248
|
+
"lag": 1,
|
|
1249
|
+
"outputs": 2,
|
|
1250
|
+
"outliersBase": "avg",
|
|
1251
|
+
"outliersStdDevs": "3",
|
|
1252
|
+
"term": 10,
|
|
1253
|
+
"keyProperty": "msg.topic",
|
|
1254
|
+
"dataProperty": "msg.payload",
|
|
1255
|
+
"dataProperties": [
|
|
1256
|
+
"msg.payload[0]",
|
|
1257
|
+
"msg.payload[1]"
|
|
1258
|
+
],
|
|
1259
|
+
"x": 520,
|
|
1260
|
+
"y": 420,
|
|
1261
|
+
"wires": [
|
|
1262
|
+
[
|
|
1263
|
+
"542b732966669deb"
|
|
1264
|
+
],
|
|
1265
|
+
[]
|
|
1266
|
+
]
|
|
1267
|
+
},
|
|
1268
|
+
{
|
|
1269
|
+
"id": "114d327f05e06720",
|
|
1270
|
+
"type": "test",
|
|
1271
|
+
"z": "cf595649.931658",
|
|
1272
|
+
"name": "autocovariance data",
|
|
1273
|
+
"errorFactor": "0.001",
|
|
1274
|
+
"escapeString": false,
|
|
1275
|
+
"infiniteIsNull": false,
|
|
1276
|
+
"payload": "[0.05,0.01,-0.02,0.03,-0.04,0.06,0.02,-0.01,-0.03,0.04]",
|
|
1277
|
+
"payloadType": "json",
|
|
1278
|
+
"result": "-0.38",
|
|
1279
|
+
"resultType": "num",
|
|
1280
|
+
"resultProperty": "msg.result",
|
|
1281
|
+
"topic": "",
|
|
1282
|
+
"x": 160,
|
|
1283
|
+
"y": 420,
|
|
1284
|
+
"wires": [
|
|
1285
|
+
[
|
|
1286
|
+
"b7da7a9e30699c6f"
|
|
1287
|
+
],
|
|
1288
|
+
[
|
|
1289
|
+
"da932227f003cc83"
|
|
1290
|
+
],
|
|
1291
|
+
[
|
|
1292
|
+
"74920ca767d590ba"
|
|
1293
|
+
]
|
|
1294
|
+
]
|
|
1295
|
+
},
|
|
1296
|
+
{
|
|
1297
|
+
"id": "da932227f003cc83",
|
|
1298
|
+
"type": "debug",
|
|
1299
|
+
"z": "cf595649.931658",
|
|
1300
|
+
"name": "error",
|
|
1301
|
+
"active": true,
|
|
1302
|
+
"tosidebar": true,
|
|
1303
|
+
"console": false,
|
|
1304
|
+
"tostatus": false,
|
|
1305
|
+
"complete": "true",
|
|
1306
|
+
"targetType": "full",
|
|
1307
|
+
"statusVal": "",
|
|
1308
|
+
"statusType": "auto",
|
|
1309
|
+
"x": 710,
|
|
1310
|
+
"y": 340,
|
|
1311
|
+
"wires": []
|
|
1312
|
+
},
|
|
1313
|
+
{
|
|
1314
|
+
"id": "542b732966669deb",
|
|
1315
|
+
"type": "Monitor Flow",
|
|
1316
|
+
"z": "cf595649.931658",
|
|
1317
|
+
"name": "",
|
|
1318
|
+
"x": 390,
|
|
1319
|
+
"y": 340,
|
|
1320
|
+
"wires": [
|
|
1321
|
+
[
|
|
1322
|
+
"114d327f05e06720"
|
|
1323
|
+
]
|
|
1324
|
+
]
|
|
1325
|
+
},
|
|
1326
|
+
{
|
|
1327
|
+
"id": "74920ca767d590ba",
|
|
1328
|
+
"type": "Monitor Flow",
|
|
1329
|
+
"z": "cf595649.931658",
|
|
1330
|
+
"name": "",
|
|
1331
|
+
"x": 370,
|
|
1332
|
+
"y": 500,
|
|
1333
|
+
"wires": [
|
|
1334
|
+
[]
|
|
1335
|
+
]
|
|
1336
|
+
},
|
|
1241
1337
|
{
|
|
1242
1338
|
"id": "ffd72c7.5d152d",
|
|
1243
1339
|
"type": "Host Available",
|
|
@@ -158,6 +158,13 @@ describe('sum', function(){
|
|
|
158
158
|
done();
|
|
159
159
|
});
|
|
160
160
|
});
|
|
161
|
+
describe('average', function(){
|
|
162
|
+
require("../dataAnalysis/arrayAverage.js");
|
|
163
|
+
it("array 1 to 4", function(done){
|
|
164
|
+
assert.deepEqual([1,2,3,4].average(),(1+2+3+4)/4)
|
|
165
|
+
done();
|
|
166
|
+
});
|
|
167
|
+
});
|
|
161
168
|
describe('sumSquared', function(){
|
|
162
169
|
require("../dataAnalysis/arraySumSquared.js");
|
|
163
170
|
it("array 1 to 4", function(done){
|
|
@@ -468,4 +475,17 @@ describe('pca', function(){
|
|
|
468
475
|
console.log(multiplyMatrix(matrix,3,2,[[1,1],[1,1]]));
|
|
469
476
|
done();
|
|
470
477
|
})
|
|
478
|
+
describe('autocovariance', function(){ //autocorrelation
|
|
479
|
+
require("../dataAnalysis/autocorrelation.js");
|
|
480
|
+
const data=[0.05,0.01,-0.02,0.03,-0.04,0.06,0.02,-0.01,-0.03,0.04]
|
|
481
|
+
it("autocovariance", function(done){
|
|
482
|
+
assert.deepEqual(data.autocovariance(1).toFixed(5),-0.00046)
|
|
483
|
+
done();
|
|
484
|
+
});
|
|
485
|
+
it("autocorrelation", function(done){
|
|
486
|
+
assert.deepEqual(data.autocorrelation(1).toFixed(2),-0.38)
|
|
487
|
+
done();
|
|
488
|
+
});
|
|
489
|
+
|
|
490
|
+
});
|
|
471
491
|
});
|
package/testing/test.html
CHANGED
|
@@ -46,7 +46,11 @@
|
|
|
46
46
|
<input type="number" id="node-input-errorFactor" list="defaultErrorFactors" >
|
|
47
47
|
<datalist id="defaultErrorFactors">
|
|
48
48
|
<option value="0">
|
|
49
|
+
<option value="0.1">
|
|
50
|
+
<option value="0.01">
|
|
49
51
|
<option value="0.001">
|
|
52
|
+
<option value="0.0001">
|
|
53
|
+
<option value="0.00001">
|
|
50
54
|
<option value="0.000001">
|
|
51
55
|
<option value="0.000000001">
|
|
52
56
|
</datalist>
|
package/testing/test.js
CHANGED
|
@@ -37,7 +37,7 @@ function equalObjects(obj1,obj2,errorFactor,callEquals=()=>true,callNotEquals=()
|
|
|
37
37
|
if( Number.isNaN(obj1) && obj2==="NaN") return callEquals();
|
|
38
38
|
const obj1type=typeof obj1;
|
|
39
39
|
if( obj1type != typeof obj2 ) return callNotEquals();
|
|
40
|
-
if(errorFactor && obj1type=="number") return (Math.abs(obj2-obj1)/obj2)<errorFactor;
|
|
40
|
+
if(errorFactor && obj1type=="number") return (Math.abs(obj2-obj1)/obj2)<errorFactor?callEquals():callNotEquals();
|
|
41
41
|
if( !(obj1 instanceof Object) ) return callNotEquals();
|
|
42
42
|
if( Object.keys(obj1).length !== Object.keys(obj2).length ) return callNotEquals();
|
|
43
43
|
try{
|