node-red-contrib-prib-functions 0.19.2 → 0.20.4

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.
Files changed (75) hide show
  1. package/.github/workflows/codeql-analysis.yml +3 -3
  2. package/.github/workflows/npmpublish.yml +6 -6
  3. package/.vs/VSWorkspaceState.json +7 -0
  4. package/.vs/node-red-contrib-prib-functions/v17/.wsuo +0 -0
  5. package/README.md +6 -2
  6. package/arima/index.js +18 -0
  7. package/dataAnalysis/arrayAllRowsSwap.js +15 -0
  8. package/dataAnalysis/arrayCompareToPrecision.js +34 -0
  9. package/dataAnalysis/arrayDifference.js +14 -0
  10. package/dataAnalysis/arrayDifferenceSeasonal.js +15 -0
  11. package/dataAnalysis/arrayDifferenceSeasonalSecondOrder.js +20 -0
  12. package/dataAnalysis/arrayDifferenceSecondOrder.js +14 -0
  13. package/dataAnalysis/arrayForEachRange.js +38 -0
  14. package/dataAnalysis/arrayOverlay.js +13 -0
  15. package/dataAnalysis/arrayProduct.js +11 -0
  16. package/dataAnalysis/arrayRandom.js +14 -0
  17. package/dataAnalysis/arrayReduceRange.js +11 -0
  18. package/dataAnalysis/arrayScale.js +11 -0
  19. package/dataAnalysis/arraySum.js +11 -0
  20. package/dataAnalysis/arraySumSquared.js +11 -0
  21. package/dataAnalysis/arraySwap.js +11 -0
  22. package/dataAnalysis/dataAnalysis.html +31 -14
  23. package/dataAnalysis/dataAnalysis.js +10 -1
  24. package/dataAnalysis/generateMatrixFunction.js +89 -0
  25. package/dataAnalysis/generateVectorFunction.js +25 -0
  26. package/dataAnalysis/pca.js +472 -325
  27. package/dataAnalysis/svd.js +239 -0
  28. package/echart/echart.html +68 -0
  29. package/echart/echart.js +85 -0
  30. package/echart/icons/chart-671.png +0 -0
  31. package/echart/lib/echarts.js +95886 -0
  32. package/lib/Chart.js +177 -0
  33. package/lib/Column.js +99 -0
  34. package/lib/GraphDB.js +14 -0
  35. package/lib/Table.js +185 -0
  36. package/lib/objectExtensions.js +361 -0
  37. package/matrix/matrix.js +2 -48
  38. package/monitor/BarGauge.js +8 -0
  39. package/monitor/Dataset.js +29 -0
  40. package/monitor/DialGauge.js +109 -0
  41. package/monitor/DialNeedle.js +36 -0
  42. package/monitor/Format.js +74 -0
  43. package/monitor/centerElement.js +14 -0
  44. package/monitor/compareElements.js +95 -0
  45. package/monitor/defs.js +23 -0
  46. package/monitor/extensions.js +906 -0
  47. package/monitor/functions.js +36 -0
  48. package/monitor/json2xml.js +103 -0
  49. package/monitor/monitorSystem.html +198 -0
  50. package/monitor/monitorSystem.js +322 -0
  51. package/monitor/svgHTML.js +179 -0
  52. package/monitor/svgObjects.js +64 -0
  53. package/package.json +18 -6
  54. package/test/00-objectExtensions.js +94 -0
  55. package/test/04-tables.js +33 -0
  56. package/test/data/.config.nodes.json +608 -0
  57. package/test/data/.config.nodes.json.backup +608 -0
  58. package/test/data/.config.runtime.json +4 -0
  59. package/test/data/.config.runtime.json.backup +3 -0
  60. package/test/data/.config.users.json +21 -0
  61. package/test/data/.config.users.json.backup +21 -0
  62. package/test/data/.flow.json.backup +2448 -2207
  63. package/test/data/float32vector10.npy +0 -0
  64. package/test/data/flow.json +2412 -2191
  65. package/test/data/int2matrix2x3.npy +0 -0
  66. package/test/data/package-lock.json +158 -0
  67. package/test/data/package.json +11 -0
  68. package/test/dataAnalysisExtensions.js +472 -0
  69. package/test/dataAnalysisPCA.js +54 -0
  70. package/test/dataAnalysisSVD.js +31 -0
  71. package/test/euclideanDistance.js +2 -2
  72. package/test/transformNumPy.js +132 -0
  73. package/transform/NumPy.js +303 -0
  74. package/transform/transform.html +12 -0
  75. package/transform/transform.js +34 -2
@@ -35,7 +35,7 @@ jobs:
35
35
 
36
36
  steps:
37
37
  - name: Checkout repository
38
- uses: actions/checkout@v2
38
+ uses: actions/checkout@v4
39
39
 
40
40
  # Initializes the CodeQL tools for scanning.
41
41
  - name: Initialize CodeQL
@@ -50,7 +50,7 @@ jobs:
50
50
  # Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
51
51
  # If this step fails, then you should remove it and run the build manually (see below)
52
52
  - name: Autobuild
53
- uses: github/codeql-action/autobuild@v1
53
+ uses: github/codeql-action/autobuild@v3
54
54
 
55
55
  # ℹ️ Command-line programs to run using the OS shell.
56
56
  # 📚 https://git.io/JvXDl
@@ -64,4 +64,4 @@ jobs:
64
64
  # make release
65
65
 
66
66
  - name: Perform CodeQL Analysis
67
- uses: github/codeql-action/analyze@v1
67
+ uses: github/codeql-action/analyze@v3
@@ -11,10 +11,10 @@ jobs:
11
11
  build:
12
12
  runs-on: ubuntu-latest
13
13
  steps:
14
- - uses: actions/checkout@v2
15
- - uses: actions/setup-node@v1
14
+ - uses: actions/checkout@v4
15
+ - uses: actions/setup-node@v4
16
16
  with:
17
- node-version: 12
17
+ node-version: 'latest'
18
18
  - run: npm ci
19
19
  - run: npm test
20
20
 
@@ -22,10 +22,10 @@ jobs:
22
22
  needs: build
23
23
  runs-on: ubuntu-latest
24
24
  steps:
25
- - uses: actions/checkout@v2
26
- - uses: actions/setup-node@v1
25
+ - uses: actions/checkout@v4
26
+ - uses: actions/setup-node@v4
27
27
  with:
28
- node-version: 12
28
+ node-version: 'latest'
29
29
  registry-url: https://registry.npmjs.org/
30
30
  - run: npm ci
31
31
  - run: npm publish
@@ -0,0 +1,7 @@
1
+ {
2
+ "ExpandedNodes": [
3
+ ""
4
+ ],
5
+ "SelectedNode": "\\C:\\Users\\peter\\Source\\Repos\\node-red-contrib-prib-functions",
6
+ "PreviewInSolutionExplorer": false
7
+ }
package/README.md CHANGED
@@ -44,6 +44,9 @@ Single value metrics:
44
44
  Array metrics:
45
45
  * Deltas
46
46
  * Deltas Normalised
47
+ * difference
48
+ * difference seasonal
49
+ * difference seasonal second order
47
50
  * Moving Average Simple (SMA)
48
51
  * Moving Average Cumulative (CMA)
49
52
  * Moving Average Weighted (WMA)
@@ -53,8 +56,9 @@ Array metrics:
53
56
 
54
57
  Array data
55
58
  * distances
56
- * minimum distance(s) between points
57
- * maximum distance(s) between points
59
+ * distance(s) minimum between points
60
+ * distance(s) maximum between points
61
+
58
62
 
59
63
  ![Data Analysis](documentation/DataAnalysis.JPG "Data Analysis")
60
64
 
package/arima/index.js ADDED
@@ -0,0 +1,18 @@
1
+ const observations=[]
2
+
3
+
4
+
5
+ if(Array.prototype.differenceSeasonalSecondOrder ==null)
6
+ Object.defineProperty(Array.prototype, "differenceSeasonalSecondOrder", {
7
+ value(lag) {
8
+ let i=result.length-lag-1
9
+ const result=new Array(size)
10
+ while(i--) {
11
+ const ilag=i-lag
12
+ result[i]=this[i]-this[i+1]-this[iLag]+this[iLag+1]
13
+ }
14
+ return result;
15
+ },
16
+ writable: true,
17
+ configurable: true
18
+ });
@@ -0,0 +1,15 @@
1
+ if(Array.prototype.allRowsSwap==null)
2
+ Object.defineProperty(Array.prototype, "allRowsSwap", {
3
+ value(x,y) {
4
+ const l=this.length;
5
+ for(let i=0; i<l; i++) {
6
+ const row=this[i]
7
+ const temp = row[x];
8
+ row[x] = row[y];
9
+ row[y] = temp;
10
+ }
11
+ return this;
12
+ },
13
+ writable: true,
14
+ configurable: true
15
+ });
@@ -0,0 +1,34 @@
1
+ [Array,Float32Array,Float64Array].forEach(object=>{
2
+ if(object.prototype.compareToPrecision==null)
3
+ Object.defineProperty(object.prototype, "compareToPrecision", {
4
+ value(toArray,precision=6) {
5
+ const basePrecision=Math.pow(10,-precision);
6
+ if(this.length!=toArray.length) throw Error("array length different")
7
+ this.forEach((element,index)=>{
8
+ const toElement=toArray[index];
9
+ if(typeof element !== typeof toElement) throw Error("types no same for "+index)
10
+ if(typeof element == "array"){
11
+ element.compareToPrecision(toElement,precision)
12
+ return
13
+ }
14
+ switch (typeof element) {
15
+ case "array":
16
+ try{
17
+ element.compareRounded(toElement,precision)
18
+ } catch(ex) {
19
+ throw Error(index+","+ex.message)
20
+ }
21
+ return;
22
+ default:
23
+ const diff = Math.abs(element-toElement) ;
24
+ // console.log({diff:diff,basePrecision:basePrecision})
25
+ if(Math.abs(element-toElement)/element > basePrecision)
26
+ throw Error(index+ " failed "+element+" <> "+toElement);
27
+ }
28
+ });
29
+ },
30
+ writable: true,
31
+ configurable: true
32
+ });
33
+
34
+ });
@@ -0,0 +1,14 @@
1
+ [Array,Float32Array,Float64Array].forEach(object=>{
2
+ if(object.prototype.difference==null)
3
+ Object.defineProperty(object.prototype, "difference", {
4
+ value(order=0) {
5
+ let i=this.length
6
+ if(i<2) return new object()
7
+ const result=new object(i-1)
8
+ while(--i) result[i-1]=this[i]-this[i-1];
9
+ return order?result.difference(--order):result;
10
+ },
11
+ writable: true,
12
+ configurable: true
13
+ });
14
+ })
@@ -0,0 +1,15 @@
1
+
2
+ [Array,Float32Array,Float64Array].forEach(object=>{
3
+ if(object.prototype.differenceSeasonal==null)
4
+ Object.defineProperty(object.prototype, "differenceSeasonal", {
5
+ value(lag=1,order=0) {
6
+ let i=this.length-lag
7
+ if(i<1) return new object()
8
+ const result=new object(i)
9
+ while(--i>=0) result[i]=this[i+lag]-this[i];
10
+ return order?result.difference(--order):result;
11
+ },
12
+ writable: true,
13
+ configurable: true
14
+ });
15
+ })
@@ -0,0 +1,20 @@
1
+ [Array,Float32Array,Float64Array].forEach(object=>{
2
+ if(object.prototype.differenceSeasonalSecondOrder==null)
3
+ Object.defineProperty(object.prototype, "differenceSeasonalSecondOrder", {
4
+ value(lag=1) {
5
+ let i=this.length-lag-1
6
+ if(i<1) return new object()
7
+ const result=new object(i)
8
+ let lastDiff=this[i+lag-1]-this[i-1]
9
+ while(--i>=0){
10
+ const newDiff=this[i+lag-1]-this[i-1]
11
+ result[i]=lastDiff-newDiff
12
+ lastDiff=newDiff
13
+ }
14
+ return result
15
+ },
16
+ writable: true,
17
+ configurable: true
18
+ });
19
+ })
20
+
@@ -0,0 +1,14 @@
1
+ [Array,Float32Array,Float64Array].forEach(object=>{
2
+ if(object.prototype.differenceSecondOrder==null)
3
+ Object.defineProperty(object.prototype, "differenceSecondOrder", {
4
+ value() {
5
+ let i=this.length-1
6
+ if(i<2) return new object()
7
+ const result=new object(i-1)
8
+ while(--i) result[i-1]=this[i-1]-2*this[i]+this[i+1]
9
+ return result;
10
+ },
11
+ writable: true,
12
+ configurable: true
13
+ });
14
+ })
@@ -0,0 +1,38 @@
1
+ [Array,Float32Array,Float64Array].forEach(object=>{
2
+ if(object.prototype.forEachRange==null)
3
+ Object.defineProperty(object.prototype, "forEachRange", {
4
+ value(start=0,end=this.length-1,func,o=this) {
5
+ if(start<=end) {
6
+ if(end>=this.length) throw Error("end offset "+end+" >= array length "+this.length);
7
+ if(start<0) throw Error("start offset "+start+"< 0");
8
+ for(let i=start;i<=end;i++) func(this[i],i,this)
9
+ } else {
10
+ if(start>=this.length) throw Error("end<start and start offset "+start+" >= array length "+this.length);
11
+ if(end<0) throw Error("end<start and end offset "+end+"< 0")
12
+ for(let i=start;i>=end;i--) func(this[i],i,this)
13
+ }
14
+ return this;
15
+ },
16
+ writable: true,
17
+ configurable: true
18
+ });
19
+ if(object.prototype.forEachRangeNotTested==null)
20
+ Object.defineProperty(object.prototype, "forEachRangeNotTested", {
21
+ value(start=0,end=this.length-1,func,o=this) {
22
+ if(start<=end) {
23
+ if(end>=this.length) end=this.length-1;
24
+ if(start<0) start=0;
25
+ for(let i=start;i<=end;i++) func(this[i],i,this)
26
+ } else {
27
+ if(start>=this.length) start=this.length-1
28
+ if(end<0) end=0
29
+ for(let i=start;i>=end;i--) func(this[i],i,this)
30
+ }
31
+ return this;
32
+ },
33
+ writable: true,
34
+ configurable: true
35
+ });
36
+
37
+ });
38
+
@@ -0,0 +1,13 @@
1
+ [Array,Float32Array,Float64Array].forEach(object=>{
2
+ if(object.prototype.overlay==null)
3
+ Object.defineProperty(object.prototype, "overlay", {
4
+ value(array) {
5
+ if(array[0] instanceof Array)
6
+ array.forEach((element,index)=>this[index].overlay(element));
7
+ else
8
+ array.forEach((element,index)=>this[index]=element);
9
+ },
10
+ writable: true,
11
+ configurable: true
12
+ });
13
+ });
@@ -0,0 +1,11 @@
1
+ [Array,Float32Array,Float64Array].forEach(object=>{
2
+ if(object.prototype.product==null)
3
+ Object.defineProperty(object.prototype, "product", {
4
+ value(i=0,end=this.length-1,product=this[i]) {
5
+ for(i++;i<=end;i++) product*=this[i];
6
+ return product;
7
+ },
8
+ writable: true,
9
+ configurable: true
10
+ });
11
+ })
@@ -0,0 +1,14 @@
1
+
2
+ [Array,Float32Array,Float64Array].forEach(object=>{
3
+ if(object.prototype.random==null)
4
+ Object.defineProperty(object.prototype, "random", {
5
+ value(size=this.length) {
6
+ let i=size
7
+ const result=new object(i)
8
+ while(i--) result[i]=Math.random();
9
+ return result;
10
+ },
11
+ writable: true,
12
+ configurable: true
13
+ })
14
+ })
@@ -0,0 +1,11 @@
1
+ [Array,Float32Array,Float64Array].forEach(object=>{
2
+ if(object.prototype.reduceRange==null)
3
+ Object.defineProperty(object.prototype, "reduceRange", {
4
+ value(start=0,end=this.length-1,func=(aggregate,cell,index)=>aggregate+cell,aggregate=0,o=this) {
5
+ for(let i=start;i<=end;i++) aggregate=func(aggregate,this[i],i,this)
6
+ return aggregate;
7
+ },
8
+ writable: true,
9
+ configurable: true
10
+ });
11
+ })
@@ -0,0 +1,11 @@
1
+ [Array,Float32Array,Float64Array].forEach(object=>{
2
+ if(object.prototype.scale==null)
3
+ Object.defineProperty(object.prototype, "scale", {
4
+ value(factor,start=0,end=this.length-1) {
5
+ for(let i=start;i<=end;i++) this[i]*=factor;
6
+ return this;
7
+ },
8
+ writable: true,
9
+ configurable: true
10
+ });
11
+ })
@@ -0,0 +1,11 @@
1
+ [Array,Float32Array,Float64Array].forEach(object=>{
2
+ if(object.prototype.sum==null)
3
+ Object.defineProperty(object.prototype, "sum", {
4
+ value(i=0,end=this.length-1,sum=0) {
5
+ for(;i<=end;i++) sum+=this[i];
6
+ return sum;
7
+ },
8
+ writable: true,
9
+ configurable: true
10
+ });
11
+ })
@@ -0,0 +1,11 @@
1
+ [Array,Float32Array,Float64Array].forEach(object=>{
2
+ if(object.prototype.sumSquared==null)
3
+ Object.defineProperty(object.prototype, "sumSquared", {
4
+ value(i=0,end=this.length-1,sum=0) {
5
+ for(;i<=end;i++) sum+=this[i]**2;
6
+ return sum;
7
+ },
8
+ writable: true,
9
+ configurable: true
10
+ });
11
+ })
@@ -0,0 +1,11 @@
1
+ if(Array.prototype.swap==null)
2
+ Object.defineProperty(Array.prototype, "swap", {
3
+ value(x,y) {
4
+ const temp = this[x];
5
+ this[x] = this[y];
6
+ this[y] = temp;
7
+ return this;
8
+ },
9
+ writable: true,
10
+ configurable: true
11
+ });
@@ -7,6 +7,7 @@
7
7
  name: {value:"",required:false},
8
8
  action: {value:"avg",required:true},
9
9
  columns:{value:"",required:false},
10
+ lag: {value:1,required:true},
10
11
  outputs: {value:(["realtime","realtimePredict"].includes(this.action)?3:2),required:true},
11
12
  outliersBase: {value:"avg",required:false},
12
13
  outliersStdDevs: {value:"3",required:false},
@@ -45,50 +46,56 @@
45
46
  }
46
47
  });
47
48
  $("#node-input-action").change(function() {
48
- if(["distances","distancesMax","distancesMin"].includes( $(this).val() )) {
49
+ if(["differenceSeasonal","differenceSeasonalSecondOrder"].includes( $(this).val() )) {
50
+ $(".form-row-http-in-lag").show();
51
+ } else {
52
+ $(".form-row-http-in-lag").hide();
53
+ }
54
+ if(["distances","distancesMax","distancesMin"].includes( $(this).val() )) {
49
55
  $(".form-row-http-in-columns").show();
50
- } else {
56
+ } else {
51
57
  $(".form-row-http-in-columns").hide();
52
- }
58
+ }
53
59
  if(["movingAvgSimple","movingAvgWeighted","movingAvgExponential","realtime","realtimePredict"].includes( $(this).val() )) {
54
60
  $(".form-row-http-in-term").show();
55
- } else {
61
+ } else {
56
62
  $(".form-row-http-in-term").hide();
57
- }
58
- if(["movingAvgExponential"].includes( $(this).val() )) {
63
+ }
64
+ if(["movingAvgExponential"].includes( $(this).val() )) {
59
65
  $("#node-input-term").attr({min:0,max:1,step:0.1});
60
66
  if(node.term<0 || node.term>1) $("#node-input-term").val(0.5);
61
67
  $("#node-input-term").change(function() {
62
68
  if(node.term<0) $(this).val(0);
63
69
  if(node.term>1) $(this).val(1);
64
70
  });
65
- } else {
71
+ } else {
66
72
  $("#node-input-term").attr({min:1,max:100,step:1});
67
73
  $("#node-input-term").change(function() {
68
74
  if(node.term<1) $(this).val(1);
69
75
  if(node.term>100) $(this).val(100);
70
76
  });
71
- }
72
- if(["realtime","realtimePredict"].includes( $(this).val() )) {
77
+ }
78
+ if(["realtime","realtimePredict"].includes( $(this).val() )) {
73
79
  node.outputs=3;
74
80
  $(".form-row-http-in-keyProperty").show();
75
81
  $(".form-row-http-in-outliersStdDevs").show();
76
82
  $(".form-row-http-in-outliersBase").show();
77
83
  $("#node-input-outliersStdDevs").change();
78
- } else {
84
+ } else {
79
85
  node.outputs=2;
80
86
  $(".form-row-http-in-keyProperty").hide();
81
87
  $(".form-row-http-in-outliersStdDevs").hide();
82
88
  $(".form-row-http-in-outliersBase").hide();
83
- }
84
- if(["pearsonR","covariance","corelationship"].includes( $(this).val() )) {
89
+ }
90
+ if(["pearsonR","covariance","corelationship"].includes( $(this).val() )) {
85
91
  $(".node-input-dataProperties-container-row").show();
86
92
  $(".form-row-http-in-dataProperty").hide();
87
- } else {
93
+ } else {
88
94
  $(".node-input-dataProperties-container-row").hide();
89
95
  $(".form-row-http-in-dataProperty").show();
90
- }
96
+ }
91
97
  $("#node-input-term").change();
98
+ $("#node-input-lag").change();
92
99
  });
93
100
 
94
101
  node.dataProperties.forEach((r)=>addDataProperty(r));
@@ -148,6 +155,10 @@
148
155
  <option value="corelationship">Corelationship</option>
149
156
  <option value="deltas">Deltas</option>
150
157
  <option value="deltaNormalised">Deltas Normalised</option>
158
+ <option value="difference">Difference</option>
159
+ <option value="differenceSeasonal">Difference Seasonal</option>
160
+ <option value="differenceSeasonalSecondOrder">Difference Seasonal Second Order</option>
161
+ <option value="differenceSecondOrder">Difference Second Order</option>
151
162
  <option value="distances">Euclidean Distances</option>
152
163
  <option value="distancesMax">Euclidean Distances Max</option>
153
164
  <option value="distancesMin">Euclidean Distances Min</option>
@@ -162,6 +173,7 @@
162
173
  <option value="movingAvgExponential">Moving Average Exponential (EMA/EWMA)</option>
163
174
  <option value="normalize">Normalise</option>
164
175
  <option value="pearsonR">Pearson Product Moment Correlation (PPMC)</option>
176
+ <option value="randomise">Randomise</option>
165
177
  <option value="range">Range</option>
166
178
  <option value="realtime">RealTime Metrics</option>
167
179
  <option value="realtimePredict">RealTime Metrics + predicts</option>
@@ -179,6 +191,11 @@
179
191
  <label for="node-input-columns"><i class="icon-bookmark"></i> Columns</label>
180
192
  <input type="text" id="node-input-columns" placeholder="columns">
181
193
  </div>
194
+
195
+ <div class="form-row form-row-http-in-lag hide">
196
+ <label for="node-input-lag"><i class="icon-bookmark"></i> Lag</label>
197
+ <input type="number" id="node-input-lag" placeholder="lag" min="1" max="10000" step="1">
198
+ </div>
182
199
 
183
200
  <div class="form-row form-row-http-in-term hide">
184
201
  <label for="node-input-term"><i class="icon-bookmark"></i> Term</label>
@@ -2,6 +2,11 @@ const logger = new (require("node-red-contrib-logger"))("Data Analysis");
2
2
  logger.sendInfo("Copyright 2020 Jaroslav Peter Prib");
3
3
 
4
4
  require("./arrayLast");
5
+ require("./arrayDifference")
6
+ require("./arrayDifferenceSeasonal")
7
+ require("./arrayDifferenceSeasonalSecondOrder")
8
+ require("./arrayDifferenceSecondOrder")
9
+ require("./arrayRandom")
5
10
  const ed=require("./euclideanDistance.js");
6
11
  require("./forNestedEach");
7
12
 
@@ -157,6 +162,10 @@ functions={
157
162
  },
158
163
  distancesMin: (d,term,node)=>ed.minDistances(d,getColumns(node)),
159
164
  distancesMax: (d,term,node)=>ed.maxDistances(d,getColumns(node)),
165
+ difference: (d)=>d.difference(),
166
+ differenceSeasonal: (d,term,node)=>d.differenceSeasonal(node.lag),
167
+ differenceSeasonalSecondOrder: (d,term,node)=>d.differenceSeasonalSecondOrder(node.lag),
168
+ differenceSecondOrder: (d)=>d.differenceSecondOrder(),
160
169
  max: (d)=> Math.max(...d),
161
170
  median:(d)=>{
162
171
  const i=Math.floor(d.length/2);
@@ -313,7 +322,7 @@ module.exports = function (RED) {
313
322
  }
314
323
  switch (node.action) {
315
324
  case "realtime":
316
- node.outliersStdDevs=Number.parseInt(node.outliersStdDevs,10)||3;
325
+ node.outliersStdDevs=Number.parseInt(node.outliersStdDevs,10)||3;
317
326
  if(![1,2,3].includes(node.outliersStdDevs)) throw Error("outlier std deviation "+node.outliersStdDevs+" not 1,2 or 3");
318
327
  const outliersFunction=(node.outliersBase||"avg")=="median";
319
328
  node.log("realtime outliersBase set avg "+outliersFunction);
@@ -0,0 +1,89 @@
1
+ function generatedMatrixFunction(arg1) {
2
+ if(typeof arg1 !=="object") throw Error("no definitional JSON found");
3
+ Object.assign(this,{
4
+ args:[],
5
+ dimensionOrder:["row","column"],
6
+ returnValue:"this",
7
+ debug:false
8
+ },arg1);
9
+ const extendedArgs=[
10
+ this.dimensionOrder[0]+"StartOffset=0",
11
+ this.dimensionOrder[0]+"EndOffset",
12
+ this.dimensionOrder[1]+"StartOffset=0",
13
+ this.dimensionOrder[1]+"EndOffset",
14
+ "returnValue="+this.returnValue,
15
+ "matrixEndOffset=matrix.length-1",
16
+ "rowOffset",
17
+ "columnOffset",
18
+ "rowVectorOffset",
19
+ "columnVectorOffset",
20
+ "elementOffset",
21
+ "element",
22
+ "getElementArray=()=>matrix[rowOffset][columnOffset]",
23
+ "getElementVector=()=>matrix[elementOffset]",
24
+ "setElementArray=(v)=>matrix[rowOffset][columnOffset]=v",
25
+ "setElementVector=(v)=>matrix[elementOffset]=v",
26
+ "getElement=getElementVector",
27
+ "setElement=setElementVector",
28
+ "getMatrix=()=>Object.create(Object.getPrototypeOf(matrix))",
29
+ "arrayFunctions={"+
30
+ "forEachRowColumn:(call)=>{for(rowOffset=0;rowOffset<=rowEndOffset;rowOffset++) call()},"+
31
+ "forEachColumnRow:(call)=>{for(columnOffset=0;columnOffset<=columnEndOffset;columnOffset++) call()}"+
32
+ "}",
33
+ "vectorFunctions={}"
34
+ ];
35
+ const functionCode=
36
+ "("+["matrix","rows",
37
+ "columns"
38
+ ].concat(this.args,extendedArgs).join()+
39
+ ")=>{\n"+
40
+ " const isArray=(matrix!==null&&matrix instanceof Array)\n"+
41
+ " if(isArray){\n"+
42
+ " rows=matrix.length\n"+
43
+ " columns=matrix[0].length\n"+
44
+ " getElement=getElementArray\n"+
45
+ " setElement=setElementArray\n"+
46
+ " }\n"+
47
+ " if(rows<=0) throw Error('rows < 1')\n"+
48
+ " if(columns<=0) throw Error('rows < 1')\n"+
49
+ " if(rowEndOffset==null) rowEndOffset=rows-1\n"+
50
+ " if(columnEndOffset==null) columnEndOffset=columns-1\n"+
51
+ (this.debug?"console.log({matrix:matrix,matrixEndOffset:matrixEndOffset,rowEndOffset:rowEndOffset,columnEndOffset:columnEndOffset,rows:rows,columns:columns})\n":"")+
52
+ " if(isArray){\n"+
53
+ " for("+this.dimensionOrder[0]+"Offset="+this.dimensionOrder[0]+"StartOffset;"+this.dimensionOrder[0]+"Offset<="+this.dimensionOrder[0]+"EndOffset;"+this.dimensionOrder[0]+"Offset++){\n"+
54
+ " const "+this.dimensionOrder[0]+"=matrix["+this.dimensionOrder[0]+"Offset]\n"+
55
+ (this.debug?"console.log({"+this.dimensionOrder[0]+"Offset:"+this.dimensionOrder[0]+"Offset,})\n":"")+"\n"+
56
+ " for("+this.dimensionOrder[1]+"Offset="+this.dimensionOrder[1]+"StartOffset;"+this.dimensionOrder[1]+"Offset<="+this.dimensionOrder[1]+"EndOffset;"+this.dimensionOrder[1]+"Offset++){\n"+
57
+ " const element=matrix["+this.dimensionOrder[1]+"Offset]\n"+
58
+ (this.debug?"console.log({"+this.dimensionOrder[1]+"Offset:"+this.dimensionOrder[1]+"Offset,element:element})\n":"")+
59
+ this.code+"\n"+
60
+ " }\n"+
61
+ " }\n"+
62
+ " } else {\n"+
63
+ " const innerSize="+(this.dimensionOrder[0]=="row"?"columns":"1")+"\n"+
64
+ " const outerSize="+(this.dimensionOrder[0]=="row"?"1":"columns")+"\n"+
65
+ " for("+this.dimensionOrder[0]+"Offset="+this.dimensionOrder[0]+"StartOffset;"+this.dimensionOrder[0]+"Offset<="+this.dimensionOrder[0]+"EndOffset;"+this.dimensionOrder[0]+"Offset++){\n"+
66
+ " const "+this.dimensionOrder[0]+"VectorOffset="+this.dimensionOrder[0]+"Offset*innerSize\n"+
67
+ (debug?"console.log({"+this.dimensionOrder[0]+"Offset:"+this.dimensionOrder[0]+"Offset,})\n":"")+
68
+ " for("+this.dimensionOrder[1]+"Offset="+this.dimensionOrder[1]+"StartOffset;"+this.dimensionOrder[1]+"Offset<="+this.dimensionOrder[1]+"EndOffset;"+this.dimensionOrder[1]+"Offset++){\n"+
69
+ " "+this.dimensionOrder[1]+"VectorOffset="+this.dimensionOrder[1]+"Offset*outerSize\n"+
70
+ " elementOffset=rowVectorOffset +columnOffset\n"+
71
+ " element=matrix[elementOffset];\n"+
72
+ (debug?"console.log({"+this.dimensionOrder[1]+"Offset:"+this.dimensionOrder[1]+"Offset,rowVectorOffset:rowVectorOffset,columnVectorOffset:columnVectorOffset,elementOffset:elementOffset,element:element})\n":"")+
73
+ " "+this.code+"\n"+
74
+ " }\n"+
75
+ " }\n"+
76
+ " }\n"+
77
+ (this.returnValue==undefined?" return this":" return returnValue")+
78
+ "\n}";
79
+ try{
80
+ const evaluatedCode=eval(functionCode);
81
+ return evaluatedCode;
82
+ } catch(ex) {
83
+ console.error("built function: \n"+functionCode)
84
+ console.error("error: "+ex.message)
85
+ console.error(ex.stack)
86
+ throw Error("code failed")
87
+ }
88
+ }
89
+ module.exports = generatedMatrixFunction;
@@ -0,0 +1,25 @@
1
+ function generatedVectorFunction(arg1) {
2
+ if(typeof arg1 !=="object") throw Error("no definitional JSON found");
3
+ Object.assign(this,{
4
+ args:[],
5
+ debug:false,
6
+ returnValue:"this"
7
+ },arg1);
8
+ const extendedArgs=["startOffset=0","endOffset=vector.length-1,returnValue="+this.returnValue]
9
+ const functionCode=
10
+ "("+["vector"].concat(this.args,extendedArgs).join()+")=>{"+
11
+ "for(let index=startOffset;index<=endOffset;index++){\n"+
12
+ this.code+";\n"+
13
+ "}\n"+
14
+ "return returnValue\n}";
15
+ try{
16
+ if(debug==true) console.log(functionCode);
17
+ const evaluatedCode=eval(functionCode);
18
+ return evaluatedCode;
19
+ } catch(ex) {
20
+ console.error("built function: "+functionCode)
21
+ console.error("error: "+ex.message)
22
+ throw Error("code failed")
23
+ }
24
+ }
25
+ module.exports = generatedVectorFunction;