@datagrok/eda 1.0.3

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 (55) hide show
  1. package/README.md +3 -0
  2. package/detectors.js +9 -0
  3. package/dist/111.js +2 -0
  4. package/dist/146.js +2 -0
  5. package/dist/155.js +2 -0
  6. package/dist/355.js +2 -0
  7. package/dist/584.js +2 -0
  8. package/dist/604.js +2 -0
  9. package/dist/632.js +2 -0
  10. package/dist/645.js +2 -0
  11. package/dist/93.js +2 -0
  12. package/dist/d711f70338306e5bddc4.wasm +0 -0
  13. package/dist/package-test.js +2 -0
  14. package/dist/package.js +2 -0
  15. package/package.json +49 -0
  16. package/package.png +0 -0
  17. package/scripts/command.txt +1 -0
  18. package/scripts/exportForTS.py +862 -0
  19. package/scripts/exportForTSConstants.py +93 -0
  20. package/scripts/func.json +1 -0
  21. package/scripts/module.json +11 -0
  22. package/src/EDAtools.ts +46 -0
  23. package/src/EDAui.ts +118 -0
  24. package/src/dataGenerators.ts +74 -0
  25. package/src/demos.ts +38 -0
  26. package/src/package-test.ts +12 -0
  27. package/src/package.ts +248 -0
  28. package/src/svm.ts +485 -0
  29. package/src/utils.ts +51 -0
  30. package/tsconfig.json +71 -0
  31. package/wasm/EDA.js +443 -0
  32. package/wasm/EDA.wasm +0 -0
  33. package/wasm/EDAAPI.js +131 -0
  34. package/wasm/EDAForWebWorker.js +21 -0
  35. package/wasm/PCA/PCA.cpp +151 -0
  36. package/wasm/PCA/PCA.h +48 -0
  37. package/wasm/PLS/PLS.h +64 -0
  38. package/wasm/PLS/pls.cpp +393 -0
  39. package/wasm/callWasm.js +475 -0
  40. package/wasm/callWasmForWebWorker.js +706 -0
  41. package/wasm/dataGenerators.h +169 -0
  42. package/wasm/dataMining.h +116 -0
  43. package/wasm/pcaExport.cpp +64 -0
  44. package/wasm/plsExport.cpp +75 -0
  45. package/wasm/svm.h +608 -0
  46. package/wasm/svmApi.cpp +323 -0
  47. package/wasm/workers/errorWorker.js +13 -0
  48. package/wasm/workers/generateDatasetWorker.js +13 -0
  49. package/wasm/workers/normalizeDatasetWorker.js +13 -0
  50. package/wasm/workers/partialLeastSquareRegressionWorker.js +13 -0
  51. package/wasm/workers/predictByLSSVMWorker.js +13 -0
  52. package/wasm/workers/principalComponentAnalysisWorker.js +13 -0
  53. package/wasm/workers/trainAndAnalyzeLSSVMWorker.js +13 -0
  54. package/wasm/workers/trainLSSVMWorker.js +13 -0
  55. package/webpack.config.js +37 -0
@@ -0,0 +1,706 @@
1
+ // Utilities for calling wasm-functions via webworker.
2
+
3
+ // We use an approach that is well described here:
4
+ // https://becominghuman.ai/passing-and-returning-webassembly-array-parameters-a0f572c65d97
5
+ // It has been modified for usage in DATAGROK.
6
+
7
+ // Constants for wasm-functions in webworkers runtime system
8
+ const TYPE = 'type';
9
+ const NUM_TYPE = 'num';
10
+ const FLOAT_COLUMN_TYPE = 'floatColumn';
11
+ const INT_COLUMN_TYPE = 'intColumn';
12
+ const FLOAT_COLUMNS_TYPE = 'floatColumns';
13
+ const NEW_FLOAT_COLUMNS_TYPE = 'newFloatColumns';
14
+ const INT_COLUMNS_TYPE = 'intColumns';
15
+ const NEW_INT_COLUMNS_TYPE = 'newIntColumns';
16
+ const NEW_FLOAT_COLUMN_TYPE = 'newFloatColumn';
17
+ const NEW_INT_COLUMN_TYPE = 'newIntColumn';
18
+ const COLUMN = 'column';
19
+ const CALL_RESULT = '_callResult';
20
+ const NUM_OF_ROWS = 'numOfRows';
21
+ const NUM_OF_COLUMNS = 'numOfColumns';
22
+ const REF = 'ref';
23
+ const VALUE = 'value';
24
+ const TABLE_OF_COLUMNS = 'tableFromColumns';
25
+ const OBJECTS = 'objects';
26
+ const INT_TYPE = 'int';
27
+ const DOUBLE_TYPE = 'double';
28
+ const NUMBER = 'number';
29
+
30
+ // Type-to-heap correspondence.
31
+ // It is required for JS-module generated by Emscripten,
32
+ // and it is used, when passing array data to/from wasm-functions.
33
+ // More info can be found at the following link:
34
+ // https://becominghuman.ai/passing-and-returning-webassembly-array-parameters-a0f572c65d97
35
+ const heapMap = {
36
+ 'intColumn': "HEAP32",
37
+ 'floatColumn': "HEAPF32",
38
+ 'floatColumns': "HEAPF32",
39
+ 'newFloatColumns': "HEAPF32",
40
+ 'intColumns': "HEAP32",
41
+ 'newIntColumns': "HEAP32",
42
+ 'newFloatColumn': "HEAPF32",
43
+ 'newIntColumn': "HEAP32"
44
+ };
45
+
46
+ // Type signature to typed array map.
47
+ // It is used, when manipulating column(s).
48
+ const typeMap = {
49
+ 'intColumn': Int32Array,
50
+ 'floatColumn': Float32Array,
51
+ 'floatColumns': Float32Array,
52
+ 'newFloatColumns': Float32Array,
53
+ 'intColumns': Int32Array,
54
+ 'newIntColumns': Int32Array,
55
+ 'newFloatColumn': Float32Array,
56
+ 'newIntColumn': Int32Array
57
+ };
58
+
59
+ // Type-to-shift map.
60
+ // It is used, when passing array to/from wasm-functions.
61
+ // More info can be found at the following link:
62
+ // https://becominghuman.ai/passing-and-returning-webassembly-array-parameters-a0f572c65d97
63
+ const shiftMap = {'intColumn': 2,
64
+ 'floatColumn': 2,
65
+ 'floatColumns': 2,
66
+ 'newFloatColumns': 2,
67
+ 'intColumns': 2,
68
+ 'newIntColumns': 2,
69
+ 'newFloatColumn': 2,
70
+ 'newIntColumn': 2
71
+ };
72
+
73
+ // Get input for C++-function.
74
+ // This function takes specification of arguments (argsSpecification) & input data (inputVals)
75
+ // and returns input that will be further used in cpp/wasm-function.
76
+ export function getCppInput(argsSpecification, inputVals) {
77
+ let cppFuncInput = [];
78
+ let ref;
79
+
80
+ // complete an input for cpp
81
+ let i = 0;
82
+ for(const key in argsSpecification) {
83
+ const arg = argsSpecification[key];
84
+ const type = arg.type;
85
+
86
+ // skip auxiliry element
87
+ if(key === CALL_RESULT)
88
+ continue;
89
+
90
+ // here, we consider each type of input
91
+ switch(type) {
92
+
93
+ // numbers
94
+ case NUM_TYPE:
95
+ case INT_TYPE:
96
+ case DOUBLE_TYPE:
97
+ arg.data = inputVals[i];
98
+ i++;
99
+ break;
100
+
101
+ // column
102
+ case INT_COLUMN_TYPE:
103
+ case FLOAT_COLUMN_TYPE:
104
+
105
+ let array;
106
+
107
+ // this is OK if type of column and target type coinside
108
+ //array = inputVals[i].getRawData();
109
+
110
+ let col = inputVals[i];
111
+
112
+ // here, we check types and perform an appropriate transform
113
+ if( ( (col.type === INT_TYPE) && (type === INT_COLUMN_TYPE) )
114
+ || ( (col.type === DOUBLE_TYPE) && (type === FLOAT_COLUMN_TYPE) ) )
115
+ array = col.getRawData();
116
+ else
117
+ array = new typeMap[type](col.getRawData());
118
+
119
+ /*if(((col.type == 'int') && (type == INT_COLUMN_TYPE))
120
+ || ((col.type == 'double') && (type == FLOAT_COLUMN_TYPE)))
121
+ array = col.getRawData();
122
+ else
123
+ array = new typeMap[type](col.getRawData());*/
124
+
125
+ // check types
126
+ arg.data = { 'array': array,
127
+ 'numOfRows': array.length};
128
+
129
+ i++;
130
+ break;
131
+
132
+ // new column
133
+ case NEW_INT_COLUMN_TYPE:
134
+ case NEW_FLOAT_COLUMN_TYPE:
135
+ let val = 0;
136
+
137
+ ref = arg[NUM_OF_ROWS][REF];
138
+
139
+ if (argsSpecification[ref].type === NUM_TYPE)
140
+ val = argsSpecification[ref].data;
141
+ else
142
+ val = argsSpecification[ref].data[arg[NUM_OF_ROWS][VALUE]];
143
+
144
+ arg.data = {'numOfRows': val};
145
+
146
+ i++;
147
+ break;
148
+
149
+ // columns or column_list
150
+ case INT_COLUMNS_TYPE:
151
+ case FLOAT_COLUMNS_TYPE:
152
+ let arrays = [];
153
+
154
+ // this is OK if type of columns and target type coinside
155
+ //for(let col of inputVals[i].toList())
156
+ // arrays.push(col.getRawData());
157
+
158
+ // here, we check types and perform an appropriate transform
159
+ for(let col of inputVals[i].toList())
160
+ if( ( (col.type === INT_TYPE) && (type === INT_COLUMN_TYPE) )
161
+ || ( (col.type === DOUBLE_TYPE) && (type === FLOAT_COLUMN_TYPE) ) )
162
+ arrays.push(col.getRawData());
163
+ else
164
+ arrays.push(new typeMap[type](col.getRawData()));
165
+
166
+ /*for(let col of inputVals[i].toList())
167
+ if(((col.type == 'int') && (type == INT_COLUMN_TYPE))
168
+ || ((col.type == 'double') && (type == FLOAT_COLUMN_TYPE)))
169
+ arrays.push(col.getRawData());
170
+ else
171
+ arrays.push(new typeMap[type](col.getRawData()));*/
172
+
173
+ arg.data = { 'arrays': arrays,
174
+ 'numOfRows': arrays[0].length,
175
+ 'numOfColumns': arrays.length};
176
+
177
+ i++;
178
+ break;
179
+
180
+ // new columns or new column_list
181
+ case NEW_INT_COLUMNS_TYPE:
182
+ case NEW_FLOAT_COLUMNS_TYPE:
183
+ let val1 = 0;
184
+ let val2 = 0;
185
+
186
+ ref = arg[NUM_OF_ROWS][REF];
187
+
188
+ if (argsSpecification[ref].type === NUM_TYPE)
189
+ val1 = argsSpecification[ref].data;
190
+ else
191
+ val1 = argsSpecification[ref].data[arg[NUM_OF_ROWS][VALUE]];
192
+
193
+ ref = arg[NUM_OF_COLUMNS][REF];
194
+
195
+ //console.log('Ref:');
196
+ //console.log(ref);
197
+ //console.log(argsSpecification[ref].data);
198
+
199
+ if (argsSpecification[ref].type === NUM_TYPE)
200
+ val2 = argsSpecification[ref].data;
201
+ else
202
+ val2 = argsSpecification[ref].data[arg[NUM_OF_COLUMNS][VALUE]];
203
+
204
+ arg.data = {'numOfRows': val1,
205
+ 'numOfColumns': val2};
206
+
207
+ i++;
208
+ break;
209
+
210
+ default:
211
+ return; // TODO: specify behaviour
212
+ } // switch
213
+
214
+ cppFuncInput.push(arg);
215
+ } // for key
216
+
217
+ //console.log('cppFuncInput:');
218
+ //console.log(cppFuncInput);
219
+
220
+ return cppFuncInput;
221
+ } // getCppInput
222
+
223
+ // Allocate memory for buffers for array data
224
+ function allocateMemoryForBuffer(module, inputs) {
225
+ for(const arg of inputs) {
226
+ const type = arg.type;
227
+
228
+ switch(type) { // Process each type of input
229
+
230
+ // numbers
231
+ case NUM_TYPE:
232
+ case INT_TYPE:
233
+ case DOUBLE_TYPE:
234
+ break;
235
+
236
+ // column & new column
237
+ case INT_COLUMN_TYPE:
238
+ case FLOAT_COLUMN_TYPE:
239
+ case NEW_FLOAT_COLUMN_TYPE:
240
+ case NEW_INT_COLUMN_TYPE:
241
+ arg.data.buf = module._malloc(arg.data.numOfRows * typeMap[type].BYTES_PER_ELEMENT);
242
+ break;
243
+
244
+ // columns & new columns
245
+ case INT_COLUMNS_TYPE:
246
+ case NEW_INT_COLUMNS_TYPE:
247
+ case FLOAT_COLUMNS_TYPE:
248
+ case NEW_FLOAT_COLUMNS_TYPE: // allocation memory for columns that are created
249
+ arg.data.buf = module._malloc(arg.data.numOfRows * arg.data.numOfColumns
250
+ * typeMap[type].BYTES_PER_ELEMENT);
251
+ break;
252
+
253
+ // TODO: process other cases and mistakes
254
+ default:
255
+ break;
256
+ }
257
+ }
258
+
259
+ //console.log('inputs after memory allocation:');
260
+ //console.log(inputs);
261
+ } // allocateMemoryForBuffer
262
+
263
+ // Get array of values that are put to wasm-function.
264
+ function getArrOfWasmParams(inputs) {
265
+ let params = [];
266
+
267
+ // Process each type of input
268
+ for(const arg of inputs) {
269
+ switch (arg.type) {
270
+
271
+ // numbers
272
+ case NUM_TYPE:
273
+ case INT_TYPE:
274
+ case DOUBLE_TYPE:
275
+ params.push(arg.data);
276
+ break;
277
+
278
+ // column & new column
279
+ case INT_COLUMN_TYPE:
280
+ case FLOAT_COLUMN_TYPE:
281
+ case NEW_FLOAT_COLUMN_TYPE:
282
+ case NEW_INT_COLUMN_TYPE:
283
+ params.push(arg.data.buf);
284
+ params.push(arg.data.numOfRows);
285
+ break;
286
+
287
+ // columns & new columns
288
+ case INT_COLUMNS_TYPE:
289
+ case NEW_INT_COLUMNS_TYPE:
290
+ case FLOAT_COLUMNS_TYPE:
291
+ case NEW_FLOAT_COLUMNS_TYPE:
292
+ params.push(arg.data.buf);
293
+ params.push(arg.data.numOfRows);
294
+ params.push(arg.data.numOfColumns);
295
+ break;
296
+
297
+ // TODO: process other cases and mistakes
298
+ default:
299
+ break;
300
+ }
301
+ }
302
+
303
+ return params;
304
+ } // getArrOfWasmParams
305
+
306
+ // Get array of types that are put to wasm-function.
307
+ function getArrOfWasmTypes(inputs) {
308
+ let types = [];
309
+
310
+ for(const arg of inputs) {
311
+ switch (arg.type) { // Process each type of input
312
+
313
+ // numbers
314
+ case NUM_TYPE:
315
+ case INT_TYPE:
316
+ case DOUBLE_TYPE:
317
+ types.push(NUMBER);
318
+ break;
319
+
320
+ // column & new column
321
+ case INT_COLUMN_TYPE:
322
+ case FLOAT_COLUMN_TYPE:
323
+ case NEW_FLOAT_COLUMN_TYPE:
324
+ case NEW_INT_COLUMN_TYPE:
325
+ types.push(NUMBER);
326
+ types.push(NUMBER);
327
+ break;
328
+
329
+ // columns & new columns
330
+ case INT_COLUMNS_TYPE:
331
+ case NEW_INT_COLUMNS_TYPE:
332
+ case FLOAT_COLUMNS_TYPE:
333
+ case NEW_FLOAT_COLUMNS_TYPE:
334
+ types.push(NUMBER);
335
+ types.push(NUMBER);
336
+ types.push(NUMBER);
337
+ break;
338
+
339
+ // TODO: process other cases and mistakes
340
+ default:
341
+ break;
342
+ }
343
+ }
344
+
345
+ return types;
346
+ } // getArrOfWasmTypes
347
+
348
+ // Put array data to buffer
349
+ function putDataToBuffer(module, inputs) {
350
+ let shift;
351
+ let heap;
352
+
353
+ for(const arg of inputs) {
354
+ const type = arg.type;
355
+
356
+ switch (type) { // Process each type of input
357
+
358
+ // numbers
359
+ case NUM_TYPE:
360
+ case INT_TYPE:
361
+ case DOUBLE_TYPE:
362
+ break;
363
+
364
+ // column
365
+ case INT_COLUMN_TYPE:
366
+ case FLOAT_COLUMN_TYPE:
367
+ shift = shiftMap[type];
368
+ heap = module[heapMap[type]];
369
+ heap.set(arg.data.array, arg.data.buf >> shift);
370
+ break;
371
+
372
+ // columns
373
+ case INT_COLUMNS_TYPE:
374
+ case FLOAT_COLUMNS_TYPE:
375
+ shift = shiftMap[type];
376
+ heap = module[heapMap[type]];
377
+ let numOfBytes = typeMap[type].BYTES_PER_ELEMENT;
378
+ let buf = arg.data.buf;
379
+ let numOfColumns = arg.data.numOfColumns;
380
+ let numOfRows = arg.data.numOfRows;
381
+ let arrays = arg.data.arrays;
382
+
383
+ for(let i = 0; i < numOfColumns; i++)
384
+ heap.set(arrays[i], (buf + i * numOfRows * numOfBytes) >> shift);
385
+
386
+ break;
387
+
388
+ // new column(s)
389
+ case NEW_INT_COLUMNS_TYPE:
390
+ case NEW_FLOAT_COLUMNS_TYPE:
391
+ case NEW_FLOAT_COLUMN_TYPE:
392
+ case NEW_INT_COLUMN_TYPE:
393
+ break;
394
+
395
+ // TODO: process other cases and mistakes
396
+ default:
397
+ break;
398
+ }
399
+ }
400
+ } // putDataToBuffer
401
+
402
+ // Get array data from buffer.
403
+ function getDataFromBuffer(module, inputs) {
404
+
405
+ let heap;
406
+ let numOfRows;
407
+ let numOfCols;
408
+ let numOfBytes;
409
+ let buf;
410
+
411
+ for(const arg of inputs) {
412
+ const type = arg.type;
413
+
414
+ switch (type) { // Process each type of input
415
+
416
+ // number
417
+ case NUM_TYPE:
418
+ case INT_TYPE:
419
+ case DOUBLE_TYPE:
420
+ break;
421
+
422
+ // column(s)
423
+ case INT_COLUMN_TYPE:
424
+ case FLOAT_COLUMN_TYPE:
425
+ case FLOAT_COLUMNS_TYPE:
426
+ case INT_COLUMNS_TYPE:
427
+ break;
428
+
429
+ // new column
430
+ case NEW_FLOAT_COLUMN_TYPE:
431
+ case NEW_INT_COLUMN_TYPE:
432
+ heap = module[heapMap[type]];
433
+ numOfRows = arg.data.numOfRows;
434
+ numOfBytes = typeMap[type].BYTES_PER_ELEMENT;
435
+ buf = arg.data.buf;
436
+ let array = new typeMap[type](numOfRows);
437
+
438
+ for(let j = 0; j < numOfRows; j++)
439
+ array[j] = heap[buf / numOfBytes + j];
440
+
441
+ arg.array = array;
442
+
443
+ break;
444
+
445
+ // new columns
446
+ case NEW_INT_COLUMNS_TYPE:
447
+ case NEW_FLOAT_COLUMNS_TYPE:
448
+ heap = module[heapMap[type]];
449
+ numOfRows = arg.data.numOfRows;
450
+ numOfCols = arg.data.numOfColumns;
451
+ numOfBytes = typeMap[type].BYTES_PER_ELEMENT;
452
+ buf = arg.data.buf;
453
+ let arrays = [];
454
+
455
+ for(let i = 0; i < numOfCols; i++) {
456
+ let arr = new typeMap[type](numOfRows);
457
+
458
+ for(let j = 0; j < numOfRows; j++)
459
+ arr[j] = heap[buf / numOfBytes + j + i * numOfRows];
460
+
461
+ arrays.push(arr);
462
+ }
463
+
464
+ arg.arrays = arrays;
465
+
466
+ break;
467
+
468
+ // TODO: process other cases and mistakes
469
+ default:
470
+ break;
471
+ }
472
+ }
473
+ } // getDataFromBuffer
474
+
475
+ // Clear memory allocated for array data
476
+ function clearMemoryForBuffer(module, inputs) {
477
+ for(const arg of inputs)
478
+ switch(arg.type) { // process each type of input
479
+
480
+ // number
481
+ case NUM_TYPE:
482
+ case INT_TYPE:
483
+ case DOUBLE_TYPE:
484
+ break;
485
+
486
+ // each non-number case
487
+ case INT_COLUMN_TYPE:
488
+ case FLOAT_COLUMN_TYPE:
489
+ case INT_COLUMNS_TYPE:
490
+ case NEW_INT_COLUMNS_TYPE:
491
+ case FLOAT_COLUMNS_TYPE:
492
+ case NEW_FLOAT_COLUMNS_TYPE:
493
+ case NEW_FLOAT_COLUMN_TYPE:
494
+ case NEW_INT_COLUMN_TYPE:
495
+ module._free(arg.data.buf);
496
+ break;
497
+
498
+ // TODO: process other cases and mistakes
499
+ default:
500
+ break;
501
+ }
502
+ } // clearMemoryForBuffer
503
+
504
+ // Extract newly created data: new column(s) are created
505
+ function extractNewlyCreatedData(funcSpecificationArgs, argsAfterWasmCall) {
506
+ // type-to-column_creator map
507
+ const typeToColumnCreatorMap = {'newFloatColumns': DG.Column.fromFloat32Array,
508
+ 'newIntColumns': DG.Column.fromInt32Array,
509
+ 'newFloatColumn': DG.Column.fromFloat32Array,
510
+ 'newIntColumn': DG.Column.fromInt32Array};
511
+
512
+ let i = 0;
513
+
514
+ for(const key in funcSpecificationArgs)
515
+ {
516
+ const arg = funcSpecificationArgs[key];
517
+
518
+ switch(arg.type){ // Process each type
519
+
520
+ // number
521
+ case NUM_TYPE:
522
+ case INT_TYPE:
523
+ case DOUBLE_TYPE:
524
+ break;
525
+
526
+ // column(s)
527
+ case INT_COLUMN_TYPE:
528
+ case FLOAT_COLUMN_TYPE:
529
+ case FLOAT_COLUMNS_TYPE:
530
+ case INT_COLUMNS_TYPE:
531
+ break;
532
+
533
+ // new column
534
+ case NEW_FLOAT_COLUMN_TYPE:
535
+ case NEW_INT_COLUMN_TYPE:
536
+ let name;
537
+
538
+ // specify name for column
539
+ if(arg.name == undefined)
540
+ name = (0).toString();
541
+ else
542
+ names = arg.name;
543
+
544
+ arg.column = typeToColumnCreatorMap[arg.type](name,
545
+ argsAfterWasmCall[i].array);
546
+ break;
547
+
548
+ // new columns
549
+ case NEW_INT_COLUMNS_TYPE:
550
+ case NEW_FLOAT_COLUMNS_TYPE:
551
+ let columns = [];
552
+ let length = argsAfterWasmCall[i].arrays.length;
553
+
554
+ let names = [];
555
+
556
+ // specify name for column
557
+ if(arg.names == undefined)
558
+ for(let k = 1; k <= length; k++)
559
+ names.push((k).toString());
560
+ else names = arg.names;
561
+
562
+ for(let j = 0; j < length; j++)
563
+ columns.push(typeToColumnCreatorMap[arg.type](names[j],
564
+ argsAfterWasmCall[i].arrays[j]));
565
+
566
+ arg.columns = columns;
567
+
568
+ break;
569
+
570
+ // TODO: process other cases and mistakes
571
+ default:
572
+ break;
573
+ }
574
+
575
+ i++;
576
+ }
577
+ } // extractNewlyCreatedData
578
+
579
+ // Get output data: overall output is created
580
+ function getOutput(funcSpecification) {
581
+ let output = funcSpecification.output;
582
+
583
+ const typeToDataFieldMap = {'newFloatColumns': 'columns',
584
+ 'newIntColumns': 'columns',
585
+ 'newFloatColumn': 'column',
586
+ 'newIntColumn': 'column'};
587
+
588
+ switch(output.type) {
589
+
590
+ case NUM_TYPE:
591
+ case INT_TYPE:
592
+ case DOUBLE_TYPE:
593
+ return funcSpecification.arguments[output.source];
594
+ break;
595
+
596
+ case COLUMN:
597
+ return funcSpecification.arguments[output.source].column;
598
+ break;
599
+
600
+ case TABLE_OF_COLUMNS:
601
+ return DG.DataFrame.fromColumns(funcSpecification.arguments[output.source].columns);
602
+ break;
603
+
604
+ case OBJECTS:
605
+ let arrayToReturn = [];
606
+
607
+ // push data of the required arguments
608
+ for(let name of output.source) {
609
+ let arg = funcSpecification.arguments[name];
610
+ arrayToReturn.push(arg[typeToDataFieldMap[arg.type]]);
611
+ }
612
+
613
+ return arrayToReturn;
614
+ break;
615
+
616
+ // TODO: process other cases and mistakes
617
+ default:
618
+ break;
619
+ }
620
+
621
+ } // getOutput
622
+
623
+ // Clear newly created data fields (new column(s))
624
+ function clearNewlyCreatedData(funcSpecificationArgs) {
625
+ for(const key in funcSpecificationArgs) {
626
+ const arg = funcSpecificationArgs[key];
627
+
628
+ switch (arg.type) {
629
+ case NUM_TYPE:
630
+ case INT_TYPE:
631
+ case DOUBLE_TYPE:
632
+ case INT_COLUMN_TYPE:
633
+ case FLOAT_COLUMN_TYPE:
634
+ case INT_COLUMNS_TYPE:
635
+ case FLOAT_COLUMNS_TYPE:
636
+ break;
637
+
638
+ case NEW_INT_COLUMN_TYPE:
639
+ case NEW_FLOAT_COLUMN_TYPE:
640
+ arg.column = null;
641
+ break;
642
+
643
+ case NEW_INT_COLUMNS_TYPE:
644
+ case NEW_FLOAT_COLUMNS_TYPE:
645
+ arg.columns = null;
646
+ break;
647
+
648
+ // TODO: process other cases and mistakes
649
+ default:
650
+ break;
651
+ }
652
+ }
653
+ } // clearNewlyCreatedData
654
+
655
+ // THE MAIN FUNCTION: a wrapper for C++-function call
656
+ export function cppWrapper(module, args, cppFuncName, returnType) {
657
+ // allocate memory for arrays that are passed to C++-function
658
+ allocateMemoryForBuffer(module, args);
659
+
660
+ // put data (just column(s)) to allocated buffers
661
+ putDataToBuffer(module, args);
662
+
663
+ // create array of parameters that are passed to C++-function
664
+ let params = getArrOfWasmParams(args);
665
+
666
+ //console.log('params:');
667
+ //console.log(params);
668
+
669
+ // create array of parameters' types that are passed to C++-function
670
+ let types = getArrOfWasmTypes(args);
671
+
672
+ //console.log('types:');
673
+ //console.log(types);
674
+
675
+ // call wasm-function
676
+ let result = module.ccall(cppFuncName, returnType, types, params);
677
+
678
+ //console.log(result);
679
+
680
+ // get data from buffers (just column(s))
681
+ getDataFromBuffer(module, args);
682
+
683
+ // clear memory that was previousely allocated
684
+ clearMemoryForBuffer(module, args);
685
+
686
+ //console.log('done');
687
+
688
+ return result;
689
+ }
690
+
691
+ // Get the required output.
692
+ // It takes a specification of the function and the data computed
693
+ // and extracts the required results.
694
+ export function getResult(funcSpecification, dataFromWebWorker) {
695
+ funcSpecification.arguments._callResult = dataFromWebWorker.callResult;
696
+
697
+ extractNewlyCreatedData(funcSpecification.arguments, dataFromWebWorker.args);
698
+
699
+ let outPut = getOutput(funcSpecification);
700
+
701
+ // Below, we remove newly created column(s), which are created at the extraction-step.
702
+ // It is especially required, when multiple call of wasm-functions in webworker.
703
+ clearNewlyCreatedData(funcSpecification.arguments);
704
+
705
+ return outPut;
706
+ }