@digitaldefiance/node-accelerate 1.0.6 → 2.0.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 +1277 -166
- package/accelerate.cc +1346 -0
- package/examples/advanced-functions.js +0 -0
- package/examples/data-processing.js +123 -0
- package/examples/machine-learning.js +158 -0
- package/examples/mathematical-functions.js +101 -0
- package/examples/matrix-multiply.js +50 -0
- package/examples/ml-pipeline.js +317 -0
- package/examples/signal-processing-advanced.js +98 -0
- package/examples/signal-processing.js +70 -0
- package/examples/statistical-operations.js +44 -0
- package/examples/trigonometric-functions.js +52 -0
- package/examples/vector-operations.js +73 -0
- package/index.d.ts +720 -0
- package/index.js +636 -0
- package/package.json +13 -3
|
File without changes
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Data Processing Examples
|
|
3
|
+
* Demonstrates clipping, thresholding, interpolation, and matrix operations
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const accelerate = require('..');
|
|
7
|
+
|
|
8
|
+
console.log('=== Data Processing ===\n');
|
|
9
|
+
|
|
10
|
+
// 1. Clipping
|
|
11
|
+
console.log('--- Clipping ---');
|
|
12
|
+
const data = new Float64Array(10);
|
|
13
|
+
for (let i = 0; i < 10; i++) {
|
|
14
|
+
data[i] = (i - 5) * 10; // -50 to 40
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const clipped = new Float64Array(10);
|
|
18
|
+
accelerate.vclip(data, clipped, -20, 20);
|
|
19
|
+
|
|
20
|
+
console.log('Original:', Array.from(data));
|
|
21
|
+
console.log('Clipped [-20, 20]:', Array.from(clipped));
|
|
22
|
+
|
|
23
|
+
// 2. Thresholding
|
|
24
|
+
console.log('\n--- Thresholding ---');
|
|
25
|
+
const signal = new Float64Array(10);
|
|
26
|
+
for (let i = 0; i < 10; i++) {
|
|
27
|
+
signal[i] = Math.random() * 100;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const thresholded = new Float64Array(10);
|
|
31
|
+
accelerate.vthreshold(signal, thresholded, 50);
|
|
32
|
+
|
|
33
|
+
console.log('Original:', Array.from(signal).map(x => x.toFixed(1)));
|
|
34
|
+
console.log('Threshold > 50:', Array.from(thresholded).map(x => x.toFixed(1)));
|
|
35
|
+
|
|
36
|
+
// 3. Vector Reversal
|
|
37
|
+
console.log('\n--- Vector Reversal ---');
|
|
38
|
+
const sequence = new Float64Array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
|
|
39
|
+
const reversed = new Float64Array(10);
|
|
40
|
+
|
|
41
|
+
accelerate.vreverse(sequence, reversed);
|
|
42
|
+
|
|
43
|
+
console.log('Original:', Array.from(sequence));
|
|
44
|
+
console.log('Reversed:', Array.from(reversed));
|
|
45
|
+
|
|
46
|
+
// 4. Matrix Transpose
|
|
47
|
+
console.log('\n--- Matrix Transpose ---');
|
|
48
|
+
const rows = 3, cols = 4;
|
|
49
|
+
const matrix = new Float64Array(rows * cols);
|
|
50
|
+
|
|
51
|
+
// Fill matrix
|
|
52
|
+
for (let i = 0; i < rows; i++) {
|
|
53
|
+
for (let j = 0; j < cols; j++) {
|
|
54
|
+
matrix[i * cols + j] = i * cols + j + 1;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const transposed = new Float64Array(rows * cols);
|
|
59
|
+
accelerate.transpose(matrix, transposed, rows, cols);
|
|
60
|
+
|
|
61
|
+
console.log('Original matrix (3×4):');
|
|
62
|
+
for (let i = 0; i < rows; i++) {
|
|
63
|
+
const row = [];
|
|
64
|
+
for (let j = 0; j < cols; j++) {
|
|
65
|
+
row.push(matrix[i * cols + j].toFixed(0).padStart(3));
|
|
66
|
+
}
|
|
67
|
+
console.log(' [' + row.join(' ') + ']');
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
console.log('Transposed matrix (4×3):');
|
|
71
|
+
for (let i = 0; i < cols; i++) {
|
|
72
|
+
const row = [];
|
|
73
|
+
for (let j = 0; j < rows; j++) {
|
|
74
|
+
row.push(transposed[i * rows + j].toFixed(0).padStart(3));
|
|
75
|
+
}
|
|
76
|
+
console.log(' [' + row.join(' ') + ']');
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// 5. Linear Interpolation
|
|
80
|
+
console.log('\n--- Linear Interpolation ---');
|
|
81
|
+
const xData = new Float64Array([0, 1, 2, 3, 4]);
|
|
82
|
+
const yData = new Float64Array([0, 1, 4, 9, 16]); // y = x²
|
|
83
|
+
|
|
84
|
+
const xiData = new Float64Array([0.5, 1.5, 2.5, 3.5]);
|
|
85
|
+
const yiData = new Float64Array(4);
|
|
86
|
+
|
|
87
|
+
accelerate.interp1d(xData, yData, xiData, yiData);
|
|
88
|
+
|
|
89
|
+
console.log('Known points (x, y):');
|
|
90
|
+
for (let i = 0; i < xData.length; i++) {
|
|
91
|
+
console.log(` (${xData[i]}, ${yData[i]})`);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
console.log('Interpolated points:');
|
|
95
|
+
for (let i = 0; i < xiData.length; i++) {
|
|
96
|
+
console.log(` x=${xiData[i]} → y=${yiData[i].toFixed(2)}`);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// 6. Data Normalization Pipeline
|
|
100
|
+
console.log('\n--- Data Normalization Pipeline ---');
|
|
101
|
+
const rawData = new Float64Array(100);
|
|
102
|
+
for (let i = 0; i < 100; i++) {
|
|
103
|
+
rawData[i] = Math.random() * 200 - 100; // -100 to 100
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Step 1: Clip outliers
|
|
107
|
+
const clippedData = new Float64Array(100);
|
|
108
|
+
accelerate.vclip(rawData, clippedData, -50, 50);
|
|
109
|
+
|
|
110
|
+
// Step 2: Take absolute value
|
|
111
|
+
const absData = new Float64Array(100);
|
|
112
|
+
accelerate.vabs(clippedData, absData);
|
|
113
|
+
|
|
114
|
+
// Step 3: Normalize to [0, 1]
|
|
115
|
+
const maxVal = accelerate.max(absData);
|
|
116
|
+
const normalized = new Float64Array(100);
|
|
117
|
+
accelerate.vscale(absData, 1.0 / maxVal, normalized);
|
|
118
|
+
|
|
119
|
+
console.log('Pipeline statistics:');
|
|
120
|
+
console.log(' Raw data range:', [accelerate.min(rawData).toFixed(2), accelerate.max(rawData).toFixed(2)]);
|
|
121
|
+
console.log(' After clipping:', [accelerate.min(clippedData).toFixed(2), accelerate.max(clippedData).toFixed(2)]);
|
|
122
|
+
console.log(' After abs:', [accelerate.min(absData).toFixed(2), accelerate.max(absData).toFixed(2)]);
|
|
123
|
+
console.log(' After normalization:', [accelerate.min(normalized).toFixed(2), accelerate.max(normalized).toFixed(2)]);
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Example: Machine Learning Operations
|
|
4
|
+
* Demonstrates using Accelerate for ML inference
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const accelerate = require('../index');
|
|
8
|
+
|
|
9
|
+
console.log('Machine Learning Example');
|
|
10
|
+
console.log('='.repeat(50));
|
|
11
|
+
console.log('');
|
|
12
|
+
|
|
13
|
+
// Simple neural network layer: y = activation(W*x + b)
|
|
14
|
+
function denseLayer(input, weights, bias, output) {
|
|
15
|
+
const inputSize = input.length;
|
|
16
|
+
const outputSize = output.length;
|
|
17
|
+
|
|
18
|
+
// Matrix-vector multiply: output = weights * input
|
|
19
|
+
accelerate.matvec(weights, input, output, outputSize, inputSize);
|
|
20
|
+
|
|
21
|
+
// Add bias: output = output + bias
|
|
22
|
+
accelerate.axpy(1.0, bias, output);
|
|
23
|
+
|
|
24
|
+
// ReLU activation: output = max(0, output)
|
|
25
|
+
const zeros = new Float64Array(outputSize);
|
|
26
|
+
for (let i = 0; i < outputSize; i++) {
|
|
27
|
+
output[i] = Math.max(0, output[i]);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return output;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Example: 2-layer network
|
|
34
|
+
console.log('Building 2-layer neural network...');
|
|
35
|
+
console.log(' Input: 784 (28×28 image)');
|
|
36
|
+
console.log(' Hidden: 128');
|
|
37
|
+
console.log(' Output: 10 (digits 0-9)');
|
|
38
|
+
console.log('');
|
|
39
|
+
|
|
40
|
+
// Layer 1: 784 → 128
|
|
41
|
+
const input = new Float64Array(784);
|
|
42
|
+
for (let i = 0; i < input.length; i++) {
|
|
43
|
+
input[i] = Math.random();
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const weights1 = new Float64Array(128 * 784);
|
|
47
|
+
const bias1 = new Float64Array(128);
|
|
48
|
+
const hidden = new Float64Array(128);
|
|
49
|
+
|
|
50
|
+
for (let i = 0; i < weights1.length; i++) weights1[i] = Math.random() - 0.5;
|
|
51
|
+
for (let i = 0; i < bias1.length; i++) bias1[i] = Math.random() - 0.5;
|
|
52
|
+
|
|
53
|
+
console.log('Layer 1: Forward pass...');
|
|
54
|
+
let start = process.hrtime.bigint();
|
|
55
|
+
denseLayer(input, weights1, bias1, hidden);
|
|
56
|
+
let end = process.hrtime.bigint();
|
|
57
|
+
console.log(` Time: ${(Number(end - start) / 1e6).toFixed(3)}ms`);
|
|
58
|
+
console.log('');
|
|
59
|
+
|
|
60
|
+
// Layer 2: 128 → 10
|
|
61
|
+
const weights2 = new Float64Array(10 * 128);
|
|
62
|
+
const bias2 = new Float64Array(10);
|
|
63
|
+
const output = new Float64Array(10);
|
|
64
|
+
|
|
65
|
+
for (let i = 0; i < weights2.length; i++) weights2[i] = Math.random() - 0.5;
|
|
66
|
+
for (let i = 0; i < bias2.length; i++) bias2[i] = Math.random() - 0.5;
|
|
67
|
+
|
|
68
|
+
console.log('Layer 2: Forward pass...');
|
|
69
|
+
start = process.hrtime.bigint();
|
|
70
|
+
denseLayer(hidden, weights2, bias2, output);
|
|
71
|
+
end = process.hrtime.bigint();
|
|
72
|
+
console.log(` Time: ${(Number(end - start) / 1e6).toFixed(3)}ms`);
|
|
73
|
+
console.log('');
|
|
74
|
+
|
|
75
|
+
// Softmax (normalize to probabilities)
|
|
76
|
+
console.log('Softmax activation...');
|
|
77
|
+
const expOutput = new Float64Array(10);
|
|
78
|
+
for (let i = 0; i < output.length; i++) {
|
|
79
|
+
expOutput[i] = Math.exp(output[i]);
|
|
80
|
+
}
|
|
81
|
+
const sumExp = accelerate.sum(expOutput);
|
|
82
|
+
for (let i = 0; i < expOutput.length; i++) {
|
|
83
|
+
expOutput[i] /= sumExp;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
console.log('Output probabilities:');
|
|
87
|
+
for (let i = 0; i < 10; i++) {
|
|
88
|
+
console.log(` Digit ${i}: ${(expOutput[i] * 100).toFixed(2)}%`);
|
|
89
|
+
}
|
|
90
|
+
console.log('');
|
|
91
|
+
|
|
92
|
+
// K-means clustering example
|
|
93
|
+
console.log('K-means Clustering Example');
|
|
94
|
+
console.log('-'.repeat(50));
|
|
95
|
+
|
|
96
|
+
const numPoints = 1000;
|
|
97
|
+
const numClusters = 3;
|
|
98
|
+
const dimensions = 2;
|
|
99
|
+
|
|
100
|
+
// Generate random points
|
|
101
|
+
const points = new Float64Array(numPoints * dimensions);
|
|
102
|
+
for (let i = 0; i < points.length; i++) {
|
|
103
|
+
points[i] = Math.random() * 100;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Initialize centroids
|
|
107
|
+
const centroids = new Float64Array(numClusters * dimensions);
|
|
108
|
+
for (let i = 0; i < numClusters; i++) {
|
|
109
|
+
const idx = Math.floor(Math.random() * numPoints);
|
|
110
|
+
centroids[i * dimensions] = points[idx * dimensions];
|
|
111
|
+
centroids[i * dimensions + 1] = points[idx * dimensions + 1];
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
console.log('Finding nearest centroids for 1000 points...');
|
|
115
|
+
start = process.hrtime.bigint();
|
|
116
|
+
|
|
117
|
+
const assignments = new Int32Array(numPoints);
|
|
118
|
+
const point = new Float64Array(dimensions);
|
|
119
|
+
const centroid = new Float64Array(dimensions);
|
|
120
|
+
|
|
121
|
+
for (let i = 0; i < numPoints; i++) {
|
|
122
|
+
point[0] = points[i * dimensions];
|
|
123
|
+
point[1] = points[i * dimensions + 1];
|
|
124
|
+
|
|
125
|
+
let minDist = Infinity;
|
|
126
|
+
let minCluster = 0;
|
|
127
|
+
|
|
128
|
+
for (let j = 0; j < numClusters; j++) {
|
|
129
|
+
centroid[0] = centroids[j * dimensions];
|
|
130
|
+
centroid[1] = centroids[j * dimensions + 1];
|
|
131
|
+
|
|
132
|
+
const dist = accelerate.euclidean(point, centroid);
|
|
133
|
+
if (dist < minDist) {
|
|
134
|
+
minDist = dist;
|
|
135
|
+
minCluster = j;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
assignments[i] = minCluster;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
end = process.hrtime.bigint();
|
|
143
|
+
console.log(` Time: ${(Number(end - start) / 1e6).toFixed(3)}ms`);
|
|
144
|
+
console.log('');
|
|
145
|
+
|
|
146
|
+
// Count assignments
|
|
147
|
+
const counts = [0, 0, 0];
|
|
148
|
+
for (let i = 0; i < numPoints; i++) {
|
|
149
|
+
counts[assignments[i]]++;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
console.log('Cluster assignments:');
|
|
153
|
+
for (let i = 0; i < numClusters; i++) {
|
|
154
|
+
console.log(` Cluster ${i}: ${counts[i]} points`);
|
|
155
|
+
}
|
|
156
|
+
console.log('');
|
|
157
|
+
|
|
158
|
+
console.log('✓ Machine learning operations completed!');
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mathematical Functions Examples
|
|
3
|
+
* Demonstrates exp, log, power, and other math operations
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const accelerate = require('..');
|
|
7
|
+
|
|
8
|
+
console.log('=== Mathematical Functions ===\n');
|
|
9
|
+
|
|
10
|
+
const n = 1000;
|
|
11
|
+
|
|
12
|
+
// 1. Exponential and Logarithm
|
|
13
|
+
console.log('--- Exponential and Logarithm ---');
|
|
14
|
+
const x = new Float64Array(n);
|
|
15
|
+
const expX = new Float64Array(n);
|
|
16
|
+
const logExpX = new Float64Array(n);
|
|
17
|
+
|
|
18
|
+
for (let i = 0; i < n; i++) {
|
|
19
|
+
x[i] = i / 100; // 0 to 10
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
accelerate.vexp(x, expX);
|
|
23
|
+
accelerate.vlog(expX, logExpX);
|
|
24
|
+
|
|
25
|
+
// Verify log(exp(x)) = x
|
|
26
|
+
let maxError = 0;
|
|
27
|
+
for (let i = 0; i < n; i++) {
|
|
28
|
+
const error = Math.abs(x[i] - logExpX[i]);
|
|
29
|
+
if (error > maxError) maxError = error;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
console.log('log(exp(x)) = x verification');
|
|
33
|
+
console.log('Max error:', maxError.toFixed(10));
|
|
34
|
+
|
|
35
|
+
// 2. Power functions
|
|
36
|
+
console.log('\n--- Power Functions ---');
|
|
37
|
+
const base = new Float64Array(100);
|
|
38
|
+
const exponent = new Float64Array(100);
|
|
39
|
+
const result = new Float64Array(100);
|
|
40
|
+
|
|
41
|
+
for (let i = 0; i < 100; i++) {
|
|
42
|
+
base[i] = i / 10 + 1; // 1 to 11
|
|
43
|
+
exponent[i] = 2; // Square everything
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
accelerate.vpow(base, exponent, result);
|
|
47
|
+
|
|
48
|
+
console.log('First 5 values squared:');
|
|
49
|
+
for (let i = 0; i < 5; i++) {
|
|
50
|
+
console.log(` ${base[i].toFixed(1)}^2 = ${result[i].toFixed(2)}`);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// 3. Square root verification
|
|
54
|
+
console.log('\n--- Square Root ---');
|
|
55
|
+
const squares = new Float64Array(100);
|
|
56
|
+
const sqrtResult = new Float64Array(100);
|
|
57
|
+
|
|
58
|
+
for (let i = 0; i < 100; i++) {
|
|
59
|
+
squares[i] = i * i;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
accelerate.vsqrt(squares, sqrtResult);
|
|
63
|
+
|
|
64
|
+
console.log('sqrt(x²) = x verification:');
|
|
65
|
+
console.log(' sqrt(25) =', sqrtResult[5].toFixed(4));
|
|
66
|
+
console.log(' sqrt(100) =', sqrtResult[10].toFixed(4));
|
|
67
|
+
console.log(' sqrt(10000) =', sqrtResult[100-1].toFixed(4));
|
|
68
|
+
|
|
69
|
+
// 4. Log base 10
|
|
70
|
+
console.log('\n--- Logarithm Base 10 ---');
|
|
71
|
+
const powers10 = new Float64Array([1, 10, 100, 1000, 10000]);
|
|
72
|
+
const log10Result = new Float64Array(5);
|
|
73
|
+
|
|
74
|
+
accelerate.vlog10(powers10, log10Result);
|
|
75
|
+
|
|
76
|
+
console.log('log10 of powers of 10:');
|
|
77
|
+
for (let i = 0; i < 5; i++) {
|
|
78
|
+
console.log(` log10(${powers10[i]}) = ${log10Result[i].toFixed(4)}`);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// 5. Absolute value
|
|
82
|
+
console.log('\n--- Absolute Value ---');
|
|
83
|
+
const mixed = new Float64Array([-5, -3, -1, 0, 1, 3, 5]);
|
|
84
|
+
const absResult = new Float64Array(7);
|
|
85
|
+
|
|
86
|
+
accelerate.vabs(mixed, absResult);
|
|
87
|
+
|
|
88
|
+
console.log('Absolute values:');
|
|
89
|
+
console.log(' Input:', Array.from(mixed));
|
|
90
|
+
console.log(' Output:', Array.from(absResult));
|
|
91
|
+
|
|
92
|
+
// 6. Negation
|
|
93
|
+
console.log('\n--- Negation ---');
|
|
94
|
+
const positive = new Float64Array([1, 2, 3, 4, 5]);
|
|
95
|
+
const negative = new Float64Array(5);
|
|
96
|
+
|
|
97
|
+
accelerate.vneg(positive, negative);
|
|
98
|
+
|
|
99
|
+
console.log('Negation:');
|
|
100
|
+
console.log(' Input:', Array.from(positive));
|
|
101
|
+
console.log(' Output:', Array.from(negative));
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Example: Matrix Multiplication
|
|
4
|
+
* Demonstrates hardware-accelerated matrix operations
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const accelerate = require('../index');
|
|
8
|
+
|
|
9
|
+
console.log('Matrix Multiplication Example');
|
|
10
|
+
console.log('='.repeat(50));
|
|
11
|
+
console.log('');
|
|
12
|
+
|
|
13
|
+
// Create two 1000×1000 matrices
|
|
14
|
+
const M = 1000, K = 1000, N = 1000;
|
|
15
|
+
console.log(`Computing C = A × B where:`);
|
|
16
|
+
console.log(` A is ${M}×${K}`);
|
|
17
|
+
console.log(` B is ${K}×${N}`);
|
|
18
|
+
console.log(` C is ${M}×${N}`);
|
|
19
|
+
console.log('');
|
|
20
|
+
|
|
21
|
+
const A = new Float64Array(M * K);
|
|
22
|
+
const B = new Float64Array(K * N);
|
|
23
|
+
const C = new Float64Array(M * N);
|
|
24
|
+
|
|
25
|
+
// Fill with random data
|
|
26
|
+
console.log('Filling matrices with random data...');
|
|
27
|
+
for (let i = 0; i < A.length; i++) A[i] = Math.random();
|
|
28
|
+
for (let i = 0; i < B.length; i++) B[i] = Math.random();
|
|
29
|
+
|
|
30
|
+
// Perform matrix multiplication
|
|
31
|
+
console.log('Performing matrix multiplication...');
|
|
32
|
+
const start = process.hrtime.bigint();
|
|
33
|
+
accelerate.matmul(A, B, C, M, K, N);
|
|
34
|
+
const end = process.hrtime.bigint();
|
|
35
|
+
|
|
36
|
+
const timeMs = Number(end - start) / 1e6;
|
|
37
|
+
console.log(`✓ Completed in ${timeMs.toFixed(2)}ms`);
|
|
38
|
+
console.log('');
|
|
39
|
+
|
|
40
|
+
// Calculate GFLOPS
|
|
41
|
+
const operations = 2 * M * K * N; // 2 ops per multiply-add
|
|
42
|
+
const gflops = operations / (timeMs * 1e6);
|
|
43
|
+
console.log(`Performance: ${gflops.toFixed(2)} GFLOPS`);
|
|
44
|
+
console.log('');
|
|
45
|
+
|
|
46
|
+
// Verify result (check a few elements)
|
|
47
|
+
console.log('Sample results:');
|
|
48
|
+
console.log(` C[0,0] = ${C[0].toFixed(6)}`);
|
|
49
|
+
console.log(` C[0,1] = ${C[1].toFixed(6)}`);
|
|
50
|
+
console.log(` C[1,0] = ${C[N].toFixed(6)}`);
|