node-red-contrib-prib-functions 0.18.0 → 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 (87) 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 +22 -19
  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 +546 -0
  27. package/dataAnalysis/svd.js +239 -0
  28. package/documentation/loadInjector.png +0 -0
  29. package/echart/echart.html +68 -0
  30. package/echart/echart.js +85 -0
  31. package/echart/icons/chart-671.png +0 -0
  32. package/echart/lib/echarts.js +95886 -0
  33. package/lib/Chart.js +177 -0
  34. package/lib/Column.js +99 -0
  35. package/lib/GraphDB.js +14 -0
  36. package/lib/Table.js +185 -0
  37. package/lib/objectExtensions.js +361 -0
  38. package/matrix/matrix.js +50 -50
  39. package/matrix/matrixNode.html +144 -154
  40. package/matrix/matrixNode.js +26 -9
  41. package/monitor/BarGauge.js +8 -0
  42. package/monitor/Dataset.js +29 -0
  43. package/monitor/DialGauge.js +109 -0
  44. package/monitor/DialNeedle.js +36 -0
  45. package/monitor/Format.js +74 -0
  46. package/monitor/centerElement.js +14 -0
  47. package/monitor/compareElements.js +95 -0
  48. package/monitor/defs.js +23 -0
  49. package/monitor/extensions.js +906 -0
  50. package/monitor/functions.js +36 -0
  51. package/monitor/json2xml.js +103 -0
  52. package/monitor/monitorSystem.html +198 -0
  53. package/monitor/monitorSystem.js +322 -0
  54. package/monitor/svgHTML.js +179 -0
  55. package/monitor/svgObjects.js +64 -0
  56. package/package.json +31 -8
  57. package/test/00-objectExtensions.js +94 -0
  58. package/test/01-base.js +88 -0
  59. package/test/04-tables.js +33 -0
  60. package/test/data/.config.nodes.json +608 -0
  61. package/test/data/.config.nodes.json.backup +608 -0
  62. package/test/data/.config.runtime.json +4 -0
  63. package/test/data/.config.runtime.json.backup +3 -0
  64. package/test/data/.config.users.json +21 -0
  65. package/test/data/.config.users.json.backup +21 -0
  66. package/test/data/.flow.json.backup +3433 -0
  67. package/test/data/float32vector10.npy +0 -0
  68. package/test/data/flow.json +3433 -0
  69. package/test/data/int2matrix2x3.npy +0 -0
  70. package/test/data/package-lock.json +158 -0
  71. package/test/data/package.json +11 -0
  72. package/test/data/settings.js +544 -0
  73. package/test/dataAnalysisExtensions.js +472 -0
  74. package/test/dataAnalysisPCA.js +54 -0
  75. package/test/dataAnalysisSVD.js +31 -0
  76. package/test/euclideanDistance.js +2 -2
  77. package/test/matrix/02base.js +36 -0
  78. package/test/transformNumPy.js +132 -0
  79. package/testing/data/countries.csv +250 -0
  80. package/testing/hostAvailable.html +0 -2
  81. package/testing/load-injector.html +76 -21
  82. package/testing/load-injector.js +35 -54
  83. package/testing/test.js +1 -0
  84. package/transform/NumPy.js +303 -0
  85. package/transform/transform.html +73 -19
  86. package/transform/transform.js +144 -8
  87. package/documentation/LoadInjector.JPG +0 -0
@@ -0,0 +1,239 @@
1
+ // SVD Singular Value Decomposition and Least Squares Solutions
2
+
3
+ require("./arrayForEachRange.js");
4
+ require("./arrayReduceRange.js");
5
+ require("./arraySwap.js");
6
+ require("./arrayOverlay.js");
7
+
8
+ function getMatrix(rows=2,columns=rows,fill=0,rowType=Float32Array) {
9
+ const matrix=Array(rows);
10
+ for(let i=0; i<rows; i++) matrix[i]=new rowType(columns).fill(fill);
11
+ return matrix;
12
+ }
13
+
14
+ /*
15
+ * matrix = U * diag(q) * V(t), U(t) * U = V(t) * V = I
16
+ */
17
+ const SVD = (matrix, orthonormalizedColumns=true, orthogonalMatrix=true,rowType=Float64Array) => {
18
+ let eps=rowType instanceof Float64Array?
19
+ Math.pow(2, -52):
20
+ rowType instanceof Float32Array?Math.pow(2, -23):Number.EPSILON;
21
+ tolerance = 1e-64 / eps
22
+ if(!matrix) throw new TypeError('Matrix is not defined')
23
+ const columns=matrix[0].length;
24
+ const rows = matrix.length;
25
+ if(rows < columns) throw new TypeError('Invalid matrix for SVD: rows < columns')
26
+ const columnEndOffset=columns-1;
27
+ const rowEndOffset=rows-1;
28
+
29
+ let i, j, k, l,c, f, g=0, h, s, x=0, y, z
30
+ const e = [];
31
+ const rowsOrColumns = (orthonormalizedColumns === 'f') ? rows : columns
32
+ const u=getMatrix(rows,rowsOrColumns);
33
+ const v=getMatrix(columns,columns);
34
+ const q = new rowType(columns).fill(0)
35
+ u.overlay(matrix);
36
+
37
+ for(i = 0; i < columns; i++) {
38
+ const ui=u[i];
39
+ e[i] = g
40
+ const iPlus1=i+1;
41
+ const sumSqCol=u.reduceRange(i,rowEndOffset,(previousValue,row)=>previousValue+Math.pow(row[i],2));
42
+ if(sumSqCol < tolerance) {
43
+ g = 0
44
+ } else {
45
+ const uii = ui[i]
46
+ g = uii < 0 ? Math.sqrt(sumSqCol) : -Math.sqrt(sumSqCol)
47
+ h = uii * g - sumSqCol
48
+ ui[i]-= g
49
+ for(j = iPlus1; j < columns; j++) {
50
+ const factor=u.reduceRange(i,rowEndOffset,(previousValue,row)=>previousValue+row[i]*row[j])/h;
51
+ u.forEachRange(i,rowEndOffset,row=>row[j]+=factor * row[i])
52
+ }
53
+ }
54
+ q[i] = g
55
+
56
+ const sumSqRow=ui.reduceRange(iPlus1,columnEndOffset,(previousValue,cell)=>previousValue+cell*cell);
57
+ if(sumSqRow < tolerance) {
58
+ g = 0
59
+ } else {
60
+ f = ui[iPlus1]
61
+ g = f < 0 ? Math.sqrt(sumSqRow) : -Math.sqrt(sumSqRow)
62
+ h = f * g - sumSqRow
63
+ ui[iPlus1] -= g
64
+ ui.forEachRange(iPlus1,columnEndOffset,(cell,columnIndex)=>e[columnIndex]=cell/h)
65
+ u.forEachRange(iPlus1,rowEndOffset,row=>{
66
+ const factor=ui.reduceRange(iPlus1,columnEndOffset,(previousValue,cell,columnIndex)=>previousValue+row[columnIndex]*cell);
67
+ row.forEachRange(iPlus1,columnEndOffset,(cell,columnIndex)=>row[columnIndex]+=factor*e[columnIndex])
68
+ })
69
+ }
70
+ y = Math.abs(q[i]) + Math.abs(e[i])
71
+ if(y > x) {
72
+ x = y
73
+ }
74
+ }
75
+
76
+ // Accumulation of right-hand transformations
77
+ if(orthogonalMatrix) {
78
+ l=columns;
79
+ for(i = columns - 1; i >= 0; i--) {
80
+ const ui=u[i];
81
+ const vi=v[i];
82
+ if(g !== 0) {
83
+ h = ui[i+1] * g
84
+ v.forEachRange(l,columnEndOffset,(row,j)=>row[i]=ui[j]/h)
85
+ console.log({l:l,columns:columns})
86
+ for(j = l; j < columns; j++) {
87
+ const sum=ui.reduceRange(l,columnEndOffset,(previousValue,cell,k)=>previousValue+cell*v[k][j]);
88
+ v.forEachRange(l,columnEndOffset,row=>row[j]+= sum*row[i])
89
+ }
90
+ }
91
+ if(l<=columnEndOffset){
92
+ v.forEachRange(l,columnEndOffset,(row,rowIndex)=>{
93
+ vi[rowIndex] = 0;
94
+ row[i] = 0;
95
+ })
96
+ }
97
+ vi[i] = 1
98
+ g = e[i]
99
+ l = i
100
+ }
101
+ }
102
+
103
+ // Accumulation of left-hand transformations
104
+ if(orthonormalizedColumns) {
105
+ if(orthonormalizedColumns !== true) {
106
+ u.forEachRange(columns,rowEndOffset,(row,rowIndex)=>{
107
+ row.forEachRange(columns,rowEndOffset,(cell,columnIndex)=>row[columnIndex]=0)
108
+ row[rowIndex]=1;
109
+ })
110
+ }
111
+ for(i = columns - 1; i >= 0; i--) {
112
+ l = i + 1
113
+ g = q[i]
114
+ const ui = u[i];
115
+
116
+ if(l<rowsOrColumns)
117
+ ui.forEachRange(l,rowsOrColumns-1,(cell,columnIndex,row)=>row[columnIndex]=0)
118
+ if(g !== 0) {
119
+ h = ui[i] * g
120
+ for(j = l; j < rowsOrColumns; j++) {
121
+ f=u.reduceRange(l,rowEndOffset,(previousValue,row)=>previousValue+row[i]*row[j])/h
122
+ u.forEachRange(i,rowEndOffset,row=>row[j]+=f*row[i])
123
+ }
124
+ u.forEachRange(i,rowEndOffset,row=>row[i]/=g)
125
+ } else {
126
+ u.forEachRange(i,rowEndOffset,row=>row[i]=0)
127
+ }
128
+ ui[i]++;
129
+ }
130
+ }
131
+
132
+ // Diagonalisation of the bidiagonal form
133
+ eps = eps * x
134
+ let testConvergence
135
+ for(k = columns - 1; k >= 0; k--) {
136
+ for(let iteration = 0; iteration < 50; iteration++) { // test-f-splitting
137
+ testConvergence = false
138
+ for (l = k; l >= 0; l--) {
139
+ testConvergence=(Math.abs(e[l])<=eps);
140
+ if(testConvergence) break
141
+ if(Math.abs(q[l - 1]) <= eps) break
142
+ }
143
+ if(!testConvergence) { // cancellation of e[l] if l>0
144
+ c = 0
145
+ s = 1
146
+ const lMinus1 = l - 1;
147
+ try{
148
+ e.forEachRange(l,k+1,(cell,i)=>{
149
+ f = s * cell
150
+ e[i] *= c;
151
+ if(Math.abs(f) <= eps) throw Error("convergence")
152
+ const qi = q[i]
153
+ const h=Math.sqrt(f*f + qi*qi);
154
+ q[i] = h
155
+ c = g / h
156
+ s = -f / h
157
+ if(orthonormalizedColumns) {
158
+ v.forEach(row=>{
159
+ const y = row[lMinus1]
160
+ const ri = row[i]
161
+ row[lMinus1] = ri * s + y * c
162
+ row[i] = ri * c -y * s
163
+ })
164
+ }
165
+ })
166
+ } catch(ex){
167
+ if(ex.message!="convergence") throw ex;
168
+ }
169
+ }
170
+ z = q[k]
171
+ if(l === k) { // convergence
172
+ if(z < 0) { // q[k] is made non-negative
173
+ q[k] = -z
174
+ if(orthogonalMatrix) v.forEach(row=>row[k]*=-1)
175
+ }
176
+ break // break out of iteration loop and move on to next k value
177
+ }
178
+
179
+ // Shift from bottom 2x2 minor
180
+ const kMinus1=k-1;
181
+ x = q[l]
182
+ y = q[kMinus1]
183
+ g = e[kMinus1]
184
+ const ek=e[k]
185
+ const zSq=z*z;
186
+ f = (y*y - zSq + g*g - ek*ek ) / (2 * ek * y)
187
+ g = Math.sqrt(f*f + 1)*(f < 0 ?-1:1)
188
+ f = (x*x - zSq + ek * (y /(f+g) - ek)) / x
189
+
190
+ // Next QR transformation
191
+ c = s= 1;
192
+ for(i = l + 1; i <= k ; i++) {
193
+ const iMinus1=i-1;
194
+ const ei=e[i]
195
+ const qi = q[i]
196
+ h = s * ei
197
+ g = c * ei
198
+ z = Math.sqrt(f * f + h * h)
199
+ e[iMinus1] = z
200
+ c = f / z
201
+ s = h / z
202
+ f = x * c + g * s
203
+ g = -x * s + g * c
204
+ h = qi * s
205
+ y = qi * c
206
+ if(orthogonalMatrix) {
207
+ v.forEach(row=>{
208
+ const columnMinus1 = row[iMinus1]
209
+ const column = row[i]
210
+ row[iMinus1] = columnMinus1 * c + column * s
211
+ row[i] = -columnMinus1 * s + column * c
212
+ })
213
+ }
214
+ z = Math.sqrt(f * f + h * h)
215
+ q[iMinus1] = z
216
+ c = f / z
217
+ s = h / z
218
+ f = c * g + s * y
219
+ x = -s * g + c * y
220
+ if(orthonormalizedColumns) {
221
+ u.forEach(row=>{
222
+ const columnMinus1 = row[iMinus1]
223
+ const column = row[i]
224
+ row[iMinus1] = columnMinus1 * c + column * s
225
+ row[i] = -columnMinus1 * s + column * c
226
+ })
227
+ }
228
+ }
229
+ e[l] = 0
230
+ e[k] = f
231
+ q[k] = x
232
+ }
233
+ }
234
+ q.filter(v=>v<eps).forEach((v,i)=>q[i]=0); //orthonormalizedColumns=true, orthogonalMatrix=true,
235
+ return {singularValues:q,
236
+ orthonormalizedColumns:orthonormalizedColumns==true?u:null,
237
+ orthogonalMatrix:orthogonalMatrix==true?v:null}
238
+ }
239
+ module.exports = SVD;
Binary file
@@ -0,0 +1,68 @@
1
+ <script type="text/javascript">
2
+ /*globals RED */
3
+ RED.nodes.registerType('eChart', {
4
+ category: 'function',
5
+ color: '#fdeea2',
6
+ defaults: {
7
+ name: {value: ""},
8
+ source1Property:{value:"msg.payload"},
9
+ source2Property:{value:"msg.payload"},
10
+ targetProperty:{value:"msg.payload"}
11
+ },
12
+ inputs: 1,
13
+ outputs: 2,
14
+ icon: "Tape-Measure-icchart-671.png",
15
+ align: 'left',
16
+ paletteLabel: "eChart",
17
+ inputLabels: "Message In",
18
+ outputLabels: ["Message Out","Error"],
19
+ label: function () {
20
+ return this.name || "eChart";
21
+ },
22
+ oneditprepare: function() {
23
+ },
24
+ oneditsave: function() {
25
+ },
26
+ oneditresize: function() {
27
+ },
28
+ resizeRule: function(file,newWidth) {
29
+ }
30
+ });
31
+ </script>
32
+
33
+ <script type="text/x-red" data-template-name="eChart">
34
+
35
+ <div class="form-row">
36
+ <label for="node-input-name"><i class="fa fa-tag"></i> Name </label>
37
+ <input type="text" id="node-input-name" placeholder="Name">
38
+ </div>
39
+ <div class="form-row form-row-http-in-source1Property show">
40
+ <label for="node-input-source1Property" style="white-space: nowrap"><i class="icon-bookmark"></i> Argument 1</label>
41
+ <input type="text" id="node-input-source1Property" placeholder="msg.payload">
42
+ </div>
43
+ <div class="form-row form-row-http-in-source1Property show">
44
+ <label for="node-input-source2Property" style="white-space: nowrap"><i class="icon-bookmark"></i> Argument 2</label>
45
+ <input type="text" id="node-input-source2Property" placeholder="msg.payload">
46
+ </div>
47
+ <div class="form-row form-row-http-in-targetProperty show">
48
+ <label for="node-input-targetProperty" style="white-space: nowrap"><i class="icon-bookmark"></i> Target Property </label>
49
+ <input type="text" id="node-input-targetProperty" placeholder="msg.payload">
50
+ </div>
51
+
52
+ </script>
53
+
54
+ <script type="text/x-red" data-help-name="eChart">
55
+ <p>
56
+ eChart for two strings
57
+ </p>
58
+ <p>
59
+ Source/Target/Topic/Columns allows the override of the property to an expression which can reference RED, node or msg variables.
60
+ </p>
61
+ <h3>Inputs</h3>
62
+ <dl class="message-properties">
63
+ <dt>msg <span class="property-type">topic</span></dt>
64
+ <dd>incoming message with topic</dd>
65
+ <dt>msg <span class="property-type">payload</span></dt>
66
+ <dd></dd>
67
+ </dl>
68
+ </script>
@@ -0,0 +1,85 @@
1
+ const logger = new (require("node-red-contrib-logger"))("eChart");
2
+ logger.sendInfo("Copyright 2020 Jaroslav Peter Prib");
3
+ function error(node,message,shortMessage){
4
+ if(logger.active) logger.send({label:"error",node:node.id,error:error,shortMessage});
5
+ node.error(message);
6
+ node.status({fill:"red",shape:"ring",text:shortMessage});
7
+ }
8
+ function evalFunction(id,mapping){
9
+ try{
10
+ return eval(mapping);
11
+ } catch(ex) {
12
+ throw Error(id+" "+ex.message);
13
+ }
14
+ }
15
+ module.exports = function (RED) {
16
+ function loggerNode (n) {
17
+ RED.nodes.createNode(this, n);
18
+ const node = Object.assign(this, n);
19
+
20
+ const source1Map="(RED,node,msg)=>"+(node.source1Property||"msg.payload"),
21
+ targetMap="(RED,node,msg,data)=>{"+(node.targetProperty||"msg.payload")+"=data;}";
22
+ logger.sendInfo({label:"mappings",source1:source1Map,source2:source2Map,target:targetMap});
23
+ try{
24
+ node.getData1=evalFunction("source1",source1Map);
25
+ node.setData=evalFunction("target",targetMap);
26
+ } catch(ex) {
27
+ error(node,ex,"Invalid setup "+ex.message);
28
+ return;
29
+ }
30
+ node.on('input', function (msg) {
31
+ try{
32
+ node.setData(RED,node,msg,node.generateChart(node.getData1(RED,node,msg)));
33
+ node.send(msg);
34
+ } catch(ex) {
35
+ msg.error=ex.message;
36
+ error(node,ex,"Error(s), check log");
37
+ node.send([null,msg]);
38
+ }
39
+ });
40
+ }
41
+ RED.nodes.registerType(logger.label, loggerNode);
42
+ };
43
+ /*
44
+
45
+ <div id="main"></div>
46
+ <script type="text/javascript">
47
+ var myChart = echarts.init(document.getElementById('main'), null, {
48
+ width: 600,
49
+ height: 400
50
+ });
51
+
52
+ </script>
53
+ <div id="main" style="width: 600px;height:400px;"></div>
54
+ <script type="text/javascript">
55
+ var myChart = echarts.init(document.getElementById('main'));
56
+ var option = {
57
+ title: {
58
+ text: 'ECharts Getting Started Example'
59
+ },
60
+ tooltip: {
61
+
62
+ },
63
+ legend: {
64
+ data: ['sales']
65
+ },
66
+ xAxis: {
67
+ data: ['Shirts', 'Cardigans', 'Chiffons', 'Pants', 'Heels', 'Socks']
68
+ },
69
+ yAxis: {
70
+
71
+ },
72
+ series: [
73
+ {
74
+ name: 'sales',
75
+ type: 'bar',
76
+ data: [5, 20, 36, 10, 10, 20]
77
+ }
78
+ ]
79
+ };
80
+ myChart.setOption(option);
81
+ window.addEventListener('resize', function() {
82
+ myChart.resize();
83
+ });
84
+ </script>
85
+ */
Binary file