@zushah/chalkboard 1.5.0 → 1.7.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/CHANGELOG.md +71 -15
- package/LICENSE.md +1 -1
- package/README.md +41 -30
- package/docs/README.md +1 -1
- package/examples/README.md +1 -1
- package/examples/fluid.js +1 -1
- package/examples/hyperbolics.js +4 -4
- package/examples/mandelbrot.js +1 -1
- package/examples/matr-donut.js +3 -5
- package/examples/newton.js +4 -4
- package/examples/quat-donut.js +2 -2
- package/package.json +5 -2
- package/src/Chalkboard.js +1563 -533
- package/src/ChalkboardProcessing.js +1433 -410
package/src/Chalkboard.js
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
/*
|
|
2
2
|
The Chalkboard Library
|
|
3
|
-
Version 1.
|
|
3
|
+
Version 1.7.0 Descartes released 01/01/2024
|
|
4
4
|
Authored by Zushah ===> https://www.github.com/Zushah
|
|
5
5
|
Available under the MIT License ===> https://www.opensource.org/license/mit/
|
|
6
6
|
|
|
7
7
|
The Chalkboard library is a JavaScript namespace that provides a plethora of both practical and abstract mathematical functionalities for its user.
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
Repository ===> https://www.github.com/Zushah/Chalkboard
|
|
10
|
+
Website ===> https://zushah.github.io/Chalkboard/home.html
|
|
11
11
|
*/
|
|
12
12
|
var Chalkboard = {
|
|
13
13
|
README: function() {
|
|
14
|
-
console.log("The Chalkboard Library\nVersion 1.
|
|
14
|
+
console.log("The Chalkboard Library\nVersion 1.7.0 Descartes released 01/01/2024\nAuthored by Zushah ===> https://www.github.com/Zushah\nAvailable under the MIT License ===> https://www.opensource.org/license/mit/\n\nThe Chalkboard library is a JavaScript namespace that provides a plethora of both practical and abstract mathematical functionalities for its user.\n\nRepository ===> https://www.github.com/Zushah/Chalkboard\nWebsite ===> https://zushah.github.io/Chalkboard/home.html");
|
|
15
15
|
},
|
|
16
16
|
LOGO: function(x, y, s, context) {
|
|
17
|
-
x = x || canvas.width / 2;
|
|
18
|
-
y = y || canvas.height / 2;
|
|
17
|
+
x = x || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.width / 2;
|
|
18
|
+
y = y || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.height / 2;
|
|
19
19
|
s = s || 1;
|
|
20
|
-
context = context ||
|
|
20
|
+
context = context || Chalkboard.real.parse(Chalkboard.CONTEXT);
|
|
21
21
|
context.save();
|
|
22
22
|
context.translate(x, y);
|
|
23
23
|
context.scale(s, s);
|
|
@@ -50,11 +50,49 @@ var Chalkboard = {
|
|
|
50
50
|
exponent = exponent || 1;
|
|
51
51
|
return Math.pow(Math.pow(10, 1 / Math.log(10)), exponent);
|
|
52
52
|
},
|
|
53
|
+
CONTEXT: "ctx",
|
|
54
|
+
PARSEPREFIX: "",
|
|
53
55
|
numb: {
|
|
54
56
|
random: function(inf, sup) {
|
|
55
|
-
inf
|
|
56
|
-
|
|
57
|
-
|
|
57
|
+
if(inf === undefined) {
|
|
58
|
+
inf = 0;
|
|
59
|
+
}
|
|
60
|
+
if(sup === undefined) {
|
|
61
|
+
sup = 1;
|
|
62
|
+
}
|
|
63
|
+
return inf + (sup - inf) * Math.random();
|
|
64
|
+
},
|
|
65
|
+
exponential: function(l) {
|
|
66
|
+
if(l === undefined) {
|
|
67
|
+
l = 1;
|
|
68
|
+
}
|
|
69
|
+
return l <= 0 ? 0 : -Math.log(Math.random()) / l;
|
|
70
|
+
},
|
|
71
|
+
Gaussian: function(height, mean, deviation) {
|
|
72
|
+
var u1 = Math.random(), u2 = Math.random();
|
|
73
|
+
var random = Chalkboard.real.sqrt(-2 * Chalkboard.real.ln(u1)) * Chalkboard.trig.cos(Chalkboard.PI(2) * u2);
|
|
74
|
+
return random * height * Chalkboard.real.sqrt(deviation) + mean;
|
|
75
|
+
},
|
|
76
|
+
Bernoullian: function(p) {
|
|
77
|
+
if(p === undefined) {
|
|
78
|
+
p = 0.5;
|
|
79
|
+
}
|
|
80
|
+
return Math.random() < p ? 1 : 0;
|
|
81
|
+
},
|
|
82
|
+
Poissonian: function(l) {
|
|
83
|
+
if(l === undefined) {
|
|
84
|
+
l = 1;
|
|
85
|
+
}
|
|
86
|
+
if(l > 0) {
|
|
87
|
+
var L = Chalkboard.E(-l);
|
|
88
|
+
var p = 1, k = 0;
|
|
89
|
+
for(; p > L; ++k) {
|
|
90
|
+
p *= Math.random();
|
|
91
|
+
}
|
|
92
|
+
return k - 1;
|
|
93
|
+
} else {
|
|
94
|
+
return 0;
|
|
95
|
+
}
|
|
58
96
|
},
|
|
59
97
|
factorial: function(num) {
|
|
60
98
|
if(num >= 0) {
|
|
@@ -228,11 +266,23 @@ var Chalkboard = {
|
|
|
228
266
|
}
|
|
229
267
|
},
|
|
230
268
|
binomial: function(n, k) {
|
|
269
|
+
if(k < 0 || k > n) {
|
|
270
|
+
return 0;
|
|
271
|
+
}
|
|
231
272
|
if(k === 0 || k === n) {
|
|
232
273
|
return 1;
|
|
233
|
-
} else {
|
|
234
|
-
return Chalkboard.numb.binomial(n - 1, k - 1) + Chalkboard.numb.binomial(n - 1, k);
|
|
235
274
|
}
|
|
275
|
+
if(k === 1 || k === n - 1) {
|
|
276
|
+
return n;
|
|
277
|
+
}
|
|
278
|
+
if(n - k < k) {
|
|
279
|
+
k = n - k;
|
|
280
|
+
}
|
|
281
|
+
var result = n;
|
|
282
|
+
for(var i = 2; i <= k; i++) {
|
|
283
|
+
result *= (n - i + 1) / i;
|
|
284
|
+
}
|
|
285
|
+
return Math.round(result);
|
|
236
286
|
},
|
|
237
287
|
Fibonacci: function(num) {
|
|
238
288
|
var sequence = [0, 1];
|
|
@@ -241,18 +291,39 @@ var Chalkboard = {
|
|
|
241
291
|
}
|
|
242
292
|
return sequence[num];
|
|
243
293
|
},
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
294
|
+
Goldbach: function(num) {
|
|
295
|
+
if(num % 2 === 0) {
|
|
296
|
+
if(num !== 4) {
|
|
297
|
+
var a = num / 2, b = num / 2;
|
|
298
|
+
if(a % 2 === 0) {
|
|
299
|
+
a--;
|
|
300
|
+
b++;
|
|
301
|
+
}
|
|
302
|
+
while(a >= 3) {
|
|
303
|
+
if(Chalkboard.numb.isPrime(a) && Chalkboard.numb.isPrime(b)) {
|
|
304
|
+
return [a, b];
|
|
305
|
+
}
|
|
306
|
+
a -= 2;
|
|
307
|
+
b += 2;
|
|
308
|
+
}
|
|
309
|
+
return undefined;
|
|
310
|
+
} else {
|
|
311
|
+
return [2, 2];
|
|
252
312
|
}
|
|
313
|
+
} else {
|
|
314
|
+
return undefined;
|
|
315
|
+
}
|
|
316
|
+
},
|
|
317
|
+
Euler: function(num) {
|
|
318
|
+
if(num > 0) {
|
|
319
|
+
var factors = Chalkboard.numb.factors(num);
|
|
320
|
+
for(var i = 0; i < factors.length; i++) {
|
|
321
|
+
num *= (factors[i] - 1) / factors[i];
|
|
322
|
+
}
|
|
323
|
+
return num;
|
|
324
|
+
} else {
|
|
325
|
+
return undefined;
|
|
253
326
|
}
|
|
254
|
-
var z = u * Chalkboard.real.sqrt(-2 * Chalkboard.real.ln(s) / s);
|
|
255
|
-
return z * height * deviation + mean;
|
|
256
327
|
}
|
|
257
328
|
},
|
|
258
329
|
real: {
|
|
@@ -260,7 +331,9 @@ var Chalkboard = {
|
|
|
260
331
|
type = type || "expl";
|
|
261
332
|
if(type === "expl") {
|
|
262
333
|
return {definition: definition, type: type};
|
|
263
|
-
}
|
|
334
|
+
} else if(type === "inve") {
|
|
335
|
+
return {definition: definition, type: type};
|
|
336
|
+
} else if(type === "pola") {
|
|
264
337
|
return {definition: definition, type: type};
|
|
265
338
|
} else if(type === "curv") {
|
|
266
339
|
return definition.length === 2 ? {definition: [definition[0], definition[1]], type: type} : {definition: [definition[0], definition[1], definition[2]], type: type};
|
|
@@ -269,17 +342,19 @@ var Chalkboard = {
|
|
|
269
342
|
} else if(type === "mult") {
|
|
270
343
|
return {definition: definition, type: type};
|
|
271
344
|
} else {
|
|
272
|
-
return "TypeError: Parameter \"type\" must be either \"expl\", \"pola\", \"curv\", \"surf\", or \"mult\".";
|
|
345
|
+
return "TypeError: Parameter \"type\" must be either \"expl\", \"inve\", \"pola\", \"curv\", \"surf\", or \"mult\".";
|
|
273
346
|
}
|
|
274
347
|
},
|
|
275
|
-
parse: function(str
|
|
276
|
-
|
|
277
|
-
return Function('"use strict"; ' + init + ' return (' + str + ')')();
|
|
348
|
+
parse: function(str) {
|
|
349
|
+
return Function('"use strict"; ' + Chalkboard.PARSEPREFIX + ' return (' + str + ')')();
|
|
278
350
|
},
|
|
279
351
|
val: function(func, val) {
|
|
280
352
|
if(func.type === "expl") {
|
|
281
353
|
var f = Chalkboard.real.parse("x => " + func.definition);
|
|
282
354
|
return f(val);
|
|
355
|
+
} else if(func.type === "inve") {
|
|
356
|
+
var f = Chalkboard.real.parse("y => " + func.definition);
|
|
357
|
+
return f(val);
|
|
283
358
|
} else if(func.type === "pola") {
|
|
284
359
|
var r = Chalkboard.real.parse("O => " + func.definition);
|
|
285
360
|
return r(val);
|
|
@@ -315,7 +390,11 @@ var Chalkboard = {
|
|
|
315
390
|
}
|
|
316
391
|
},
|
|
317
392
|
pow: function(base, num) {
|
|
318
|
-
|
|
393
|
+
if(base === 0 && num === 0) {
|
|
394
|
+
return 1;
|
|
395
|
+
} else {
|
|
396
|
+
return Math.exp(num * Math.log(base));
|
|
397
|
+
}
|
|
319
398
|
},
|
|
320
399
|
log: function(base, num) {
|
|
321
400
|
return Chalkboard.real.ln(num) / Chalkboard.real.ln(base);
|
|
@@ -333,7 +412,8 @@ var Chalkboard = {
|
|
|
333
412
|
return undefined;
|
|
334
413
|
}
|
|
335
414
|
},
|
|
336
|
-
|
|
415
|
+
root: function(num, index) {
|
|
416
|
+
index = index || 3;
|
|
337
417
|
return Math.exp(Math.log(num) / index);
|
|
338
418
|
},
|
|
339
419
|
tetration: function(base, num) {
|
|
@@ -448,14 +528,20 @@ var Chalkboard = {
|
|
|
448
528
|
},
|
|
449
529
|
comp: {
|
|
450
530
|
new: function(a, b) {
|
|
451
|
-
|
|
531
|
+
if(b === undefined) {
|
|
532
|
+
return {a: a, b: 0, type: "comp"};
|
|
533
|
+
} else {
|
|
534
|
+
return {a: a, b: b, type: "comp"};
|
|
535
|
+
}
|
|
536
|
+
},
|
|
537
|
+
copy: function(comp) {
|
|
538
|
+
return Object.create(Object.getPrototypeOf(comp), Object.getOwnPropertyDescriptors(comp));
|
|
452
539
|
},
|
|
453
540
|
function: function(realDefinition, imagDefinition) {
|
|
454
541
|
return {definition: [realDefinition, imagDefinition], type: "comp"};
|
|
455
542
|
},
|
|
456
|
-
parse: function(str
|
|
457
|
-
|
|
458
|
-
return Function('"use strict"; ' + init + ' return (' + str + ')')();
|
|
543
|
+
parse: function(str) {
|
|
544
|
+
return Function('"use strict"; ' + Chalkboard.PARSEPREFIX + ' return (' + str + ')')();
|
|
459
545
|
},
|
|
460
546
|
val: function(func, comp) {
|
|
461
547
|
if(func.type === "comp") {
|
|
@@ -534,6 +620,18 @@ var Chalkboard = {
|
|
|
534
620
|
sqrt: function(comp) {
|
|
535
621
|
return Chalkboard.comp.new(Chalkboard.real.sqrt((comp.a + Chalkboard.real.sqrt((comp.a * comp.a) + (comp.b * comp.b))) / 2), Chalkboard.numb.sgn(comp.b) * Chalkboard.real.sqrt((-comp.a + Chalkboard.real.sqrt((comp.a * comp.a) + (comp.b * comp.b))) / 2));
|
|
536
622
|
},
|
|
623
|
+
root: function(comp, index) {
|
|
624
|
+
index = index || 3;
|
|
625
|
+
if(Number.isInteger(index) && index > 0) {
|
|
626
|
+
var result = [];
|
|
627
|
+
var r = Chalkboard.comp.mag(comp);
|
|
628
|
+
var t = Chalkboard.comp.arg(comp);
|
|
629
|
+
for(var i = 0; i < index; i++) {
|
|
630
|
+
result.push(Chalkboard.comp.new(Chalkboard.real.root(r, index) * Chalkboard.trig.cos((t + Chalkboard.PI(2 * i)) / index), Chalkboard.real.root(r, index) * Chalkboard.trig.sin((t + Chalkboard.PI(2 * i)) / index)));
|
|
631
|
+
}
|
|
632
|
+
return result;
|
|
633
|
+
}
|
|
634
|
+
},
|
|
537
635
|
rotate: function(comp, rad) {
|
|
538
636
|
return Chalkboard.comp.new(Chalkboard.comp.mag(comp) * Chalkboard.trig.cos(Chalkboard.comp.arg(comp) + rad), Chalkboard.comp.mag(comp) * Chalkboard.trig.sin(Chalkboard.comp.arg(comp) + rad));
|
|
539
637
|
},
|
|
@@ -543,21 +641,22 @@ var Chalkboard = {
|
|
|
543
641
|
conjugate: function(comp) {
|
|
544
642
|
return Chalkboard.comp.new(comp.a, -comp.b);
|
|
545
643
|
},
|
|
546
|
-
root: function(comp, n) {
|
|
547
|
-
if(Number.isInteger(n) && n > 0) {
|
|
548
|
-
var result = [];
|
|
549
|
-
var r = Chalkboard.comp.mag(comp);
|
|
550
|
-
var t = Chalkboard.comp.arg(comp);
|
|
551
|
-
for(var i = 0; i < n; i++) {
|
|
552
|
-
result.push(Chalkboard.comp.new(Chalkboard.real.nrt(r, n) * Chalkboard.trig.cos((t + Chalkboard.PI(2 * i)) / n), Chalkboard.real.nrt(r, n) * Chalkboard.trig.sin((t + Chalkboard.PI(2 * i)) / n)));
|
|
553
|
-
}
|
|
554
|
-
return result;
|
|
555
|
-
}
|
|
556
|
-
},
|
|
557
644
|
dist: function(comp_1, comp_2) {
|
|
645
|
+
if(typeof comp_1 === "number") {
|
|
646
|
+
comp_1 = Chalkboard.comp.new(comp_1, 0);
|
|
647
|
+
}
|
|
648
|
+
if(typeof comp_2 === "number") {
|
|
649
|
+
comp_2 = Chalkboard.comp.new(comp_2, 0);
|
|
650
|
+
}
|
|
558
651
|
return Chalkboard.real.sqrt(((comp_2.a - comp_1.a) * (comp_2.a - comp_1.a)) + ((comp_2.b - comp_1.b) * (comp_2.b - comp_1.b)));
|
|
559
652
|
},
|
|
560
653
|
distsq: function(comp_1, comp_2) {
|
|
654
|
+
if(typeof comp_1 === "number") {
|
|
655
|
+
comp_1 = Chalkboard.comp.new(comp_1, 0);
|
|
656
|
+
}
|
|
657
|
+
if(typeof comp_2 === "number") {
|
|
658
|
+
comp_2 = Chalkboard.comp.new(comp_2, 0);
|
|
659
|
+
}
|
|
561
660
|
return ((comp_2.a - comp_1.a) * (comp_2.a - comp_1.a)) + ((comp_2.b - comp_1.b) * (comp_2.b - comp_1.b));
|
|
562
661
|
},
|
|
563
662
|
scl: function(comp, num) {
|
|
@@ -567,15 +666,39 @@ var Chalkboard = {
|
|
|
567
666
|
return Chalkboard.comp.new(Chalkboard.numb.constrain(comp.a, range), Chalkboard.numb.constrain(comp.b, range));
|
|
568
667
|
},
|
|
569
668
|
add: function(comp_1, comp_2) {
|
|
669
|
+
if(typeof comp_1 === "number") {
|
|
670
|
+
comp_1 = Chalkboard.comp.new(comp_1, 0);
|
|
671
|
+
}
|
|
672
|
+
if(typeof comp_2 === "number") {
|
|
673
|
+
comp_2 = Chalkboard.comp.new(comp_2, 0);
|
|
674
|
+
}
|
|
570
675
|
return Chalkboard.comp.new(comp_1.a + comp_2.a, comp_1.b + comp_2.b);
|
|
571
676
|
},
|
|
572
677
|
sub: function(comp_1, comp_2) {
|
|
678
|
+
if(typeof comp_1 === "number") {
|
|
679
|
+
comp_1 = Chalkboard.comp.new(comp_1, 0);
|
|
680
|
+
}
|
|
681
|
+
if(typeof comp_2 === "number") {
|
|
682
|
+
comp_2 = Chalkboard.comp.new(comp_2, 0);
|
|
683
|
+
}
|
|
573
684
|
return Chalkboard.comp.new(comp_1.a - comp_2.a, comp_1.b - comp_2.b);
|
|
574
685
|
},
|
|
575
686
|
mul: function(comp_1, comp_2) {
|
|
687
|
+
if(typeof comp_1 === "number") {
|
|
688
|
+
comp_1 = Chalkboard.comp.new(comp_1, 0);
|
|
689
|
+
}
|
|
690
|
+
if(typeof comp_2 === "number") {
|
|
691
|
+
comp_2 = Chalkboard.comp.new(comp_2, 0);
|
|
692
|
+
}
|
|
576
693
|
return Chalkboard.comp.new((comp_1.a * comp_2.a) - (comp_1.b * comp_2.b), (comp_1.a * comp_2.b) + (comp_1.b * comp_2.a));
|
|
577
694
|
},
|
|
578
695
|
div: function(comp_1, comp_2) {
|
|
696
|
+
if(typeof comp_1 === "number") {
|
|
697
|
+
comp_1 = Chalkboard.comp.new(comp_1, 0);
|
|
698
|
+
}
|
|
699
|
+
if(typeof comp_2 === "number") {
|
|
700
|
+
comp_2 = Chalkboard.comp.new(comp_2, 0);
|
|
701
|
+
}
|
|
579
702
|
return Chalkboard.comp.new(((comp_1.a * comp_2.a) - (comp_1.b * comp_2.b)) / Chalkboard.comp.magsq(comp_2), ((comp_1.a * comp_2.b) + (comp_1.b * comp_2.a)) / Chalkboard.comp.magsq(comp_2));
|
|
580
703
|
},
|
|
581
704
|
toVector: function(comp) {
|
|
@@ -597,7 +720,14 @@ var Chalkboard = {
|
|
|
597
720
|
},
|
|
598
721
|
quat: {
|
|
599
722
|
new: function(a, b, c, d) {
|
|
600
|
-
|
|
723
|
+
if(b === undefined && c === undefined && d === undefined) {
|
|
724
|
+
return {a: a, b: 0, c: 0, d: 0, type: "quat"};
|
|
725
|
+
} else {
|
|
726
|
+
return {a: a, b: b, c: c, d: d, type: "quat"};
|
|
727
|
+
}
|
|
728
|
+
},
|
|
729
|
+
copy: function(quat) {
|
|
730
|
+
return Object.create(Object.getPrototypeOf(quat), Object.getOwnPropertyDescriptors(quat));
|
|
601
731
|
},
|
|
602
732
|
random: function(inf, sup) {
|
|
603
733
|
return Chalkboard.quat.new(Chalkboard.numb.random(inf, sup), Chalkboard.numb.random(inf, sup), Chalkboard.numb.random(inf, sup), Chalkboard.numb.random(inf, sup));
|
|
@@ -639,9 +769,21 @@ var Chalkboard = {
|
|
|
639
769
|
return Chalkboard.quat.new(quat.a, -quat.b, -quat.c, -quat.d);
|
|
640
770
|
},
|
|
641
771
|
dist: function(quat_1, quat_2) {
|
|
772
|
+
if(typeof quat_1 === "number") {
|
|
773
|
+
quat_1 = Chalkboard.quat.new(quat_1, 0, 0, 0);
|
|
774
|
+
}
|
|
775
|
+
if(typeof quat_2 === "number") {
|
|
776
|
+
quat_2 = Chalkboard.quat.new(quat_2, 0, 0, 0);
|
|
777
|
+
}
|
|
642
778
|
return Chalkboard.real.sqrt(((quat_2.a - quat_1.a) * (quat_2.a - quat_1.a)) + ((quat_2.b - quat_1.b) * (quat_2.b - quat_1.b)) + ((quat_2.c - quat_1.c) * (quat_2.c - quat_1.c)) + ((quat_2.d - quat_1.d) * (quat_2.d - quat_1.d)));
|
|
643
779
|
},
|
|
644
780
|
distsq: function(quat_1, quat_2) {
|
|
781
|
+
if(typeof quat_1 === "number") {
|
|
782
|
+
quat_1 = Chalkboard.quat.new(quat_1, 0, 0, 0);
|
|
783
|
+
}
|
|
784
|
+
if(typeof quat_2 === "number") {
|
|
785
|
+
quat_2 = Chalkboard.quat.new(quat_2, 0, 0, 0);
|
|
786
|
+
}
|
|
645
787
|
return ((quat_2.a - quat_1.a) * (quat_2.a - quat_1.a)) + ((quat_2.b - quat_1.b) * (quat_2.b - quat_1.b)) + ((quat_2.c - quat_1.c) * (quat_2.c - quat_1.c)) + ((quat_2.d - quat_1.d) * (quat_2.d - quat_1.d));
|
|
646
788
|
},
|
|
647
789
|
scl: function(quat, num) {
|
|
@@ -651,14 +793,41 @@ var Chalkboard = {
|
|
|
651
793
|
return Chalkboard.quat.new(Chalkboard.numb.constrain(quat.a, range), Chalkboard.numb.constrain(quat.b, range), Chalkboard.numb.constrain(quat.c, range), Chalkboard.numb.constrain(quat.d, range));
|
|
652
794
|
},
|
|
653
795
|
add: function(quat_1, quat_2) {
|
|
796
|
+
if(typeof quat_1 === "number") {
|
|
797
|
+
quat_1 = Chalkboard.quat.new(quat_1, 0, 0, 0);
|
|
798
|
+
}
|
|
799
|
+
if(typeof quat_2 === "number") {
|
|
800
|
+
quat_2 = Chalkboard.quat.new(quat_2, 0, 0, 0);
|
|
801
|
+
}
|
|
654
802
|
return Chalkboard.quat.new(quat_1.a + quat_2.a, quat_1.b + quat_2.b, quat_1.c + quat_2.c, quat_1.d + quat_2.d);
|
|
655
803
|
},
|
|
656
804
|
sub: function(quat_1, quat_2) {
|
|
805
|
+
if(typeof quat_1 === "number") {
|
|
806
|
+
quat_1 = Chalkboard.quat.new(quat_1, 0, 0, 0);
|
|
807
|
+
}
|
|
808
|
+
if(typeof quat_2 === "number") {
|
|
809
|
+
quat_2 = Chalkboard.quat.new(quat_2, 0, 0, 0);
|
|
810
|
+
}
|
|
657
811
|
return Chalkboard.quat.new(quat_1.a - quat_2.a, quat_1.b - quat_2.b, quat_1.c - quat_2.c, quat_1.d - quat_2.d);
|
|
658
812
|
},
|
|
659
813
|
mul: function(quat_1, quat_2) {
|
|
814
|
+
if(typeof quat_1 === "number") {
|
|
815
|
+
quat_1 = Chalkboard.quat.new(quat_1, 0, 0, 0);
|
|
816
|
+
}
|
|
817
|
+
if(typeof quat_2 === "number") {
|
|
818
|
+
quat_2 = Chalkboard.quat.new(quat_2, 0, 0, 0);
|
|
819
|
+
}
|
|
660
820
|
return Chalkboard.quat.new((quat_1.a * quat_2.a) - (quat_1.b * quat_2.b) - (quat_1.c * quat_2.c) - (quat_1.d * quat_2.d), (quat_1.a * quat_2.b) + (quat_1.b * quat_2.a) + (quat_1.c * quat_2.d) - (quat_1.d * quat_2.c), (quat_1.a * quat_2.c) - (quat_1.b * quat_2.d) + (quat_1.c * quat_2.a) + (quat_1.d * quat_2.b), (quat_1.a * quat_2.d) + (quat_1.b * quat_2.c) - (quat_1.c * quat_2.b) + (quat_1.d * quat_2.a));
|
|
661
821
|
},
|
|
822
|
+
div: function(quat_1, quat_2) {
|
|
823
|
+
if(typeof quat_1 === "number") {
|
|
824
|
+
quat_1 = Chalkboard.quat.new(quat_1, 0, 0, 0);
|
|
825
|
+
}
|
|
826
|
+
if(typeof quat_2 === "number") {
|
|
827
|
+
quat_2 = Chalkboard.quat.new(quat_2, 0, 0, 0);
|
|
828
|
+
}
|
|
829
|
+
return Chalkboard.quat.new((quat_1.a * quat_2.a + quat_1.b * quat_2.b + quat_1.c * quat_2.c + quat_1.d * quat_2.d) / Chalkboard.quat.magsq(quat_2), (quat_1.b * quat_2.a - quat_1.a * quat_2.b - quat_1.d * quat_2.c + quat_1.c * quat_2.d) / Chalkboard.quat.magsq(quat_2), (quat_1.c * quat_2.a + quat_1.d * quat_2.b - quat_1.a * quat_2.c - quat_1.b * quat_2.d) / Chalkboard.quat.magsq(quat_2), (quat_1.d * quat_2.a - quat_1.c * quat_2.b + quat_1.b * quat_2.c - quat_1.a * quat_2.d) / Chalkboard.quat.magsq(quat_2));
|
|
830
|
+
},
|
|
662
831
|
fromAxis: function(vec3, rad) {
|
|
663
832
|
return Chalkboard.quat.new(Chalkboard.trig.cos(rad / 2), vec3.x * Chalkboard.trig.sin(rad / 2), vec3.y * Chalkboard.trig.sin(rad / 2), vec3.z * Chalkboard.trig.sin(rad / 2));
|
|
664
833
|
},
|
|
@@ -703,136 +872,153 @@ var Chalkboard = {
|
|
|
703
872
|
}
|
|
704
873
|
},
|
|
705
874
|
plot: {
|
|
706
|
-
xyplane: function(
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
context.
|
|
717
|
-
context.
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
context.
|
|
732
|
-
context.
|
|
733
|
-
context.
|
|
734
|
-
context.
|
|
735
|
-
context.
|
|
736
|
-
context.
|
|
737
|
-
context.
|
|
738
|
-
context.
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
context.
|
|
756
|
-
context.lineWidth =
|
|
757
|
-
context.beginPath();
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
context.
|
|
762
|
-
context.
|
|
763
|
-
context.
|
|
764
|
-
context.
|
|
765
|
-
context.
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
875
|
+
xyplane: function(config) {
|
|
876
|
+
(config = {
|
|
877
|
+
x: (config = config || {}).x || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.width / 2,
|
|
878
|
+
y: config.y || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.height / 2,
|
|
879
|
+
size: config.size || 1,
|
|
880
|
+
strokeStyle: config.strokeStyle || "black",
|
|
881
|
+
lineWidth: config.lineWidth || 2,
|
|
882
|
+
context: config.context || Chalkboard.real.parse(Chalkboard.CONTEXT)
|
|
883
|
+
}).size /= 100;
|
|
884
|
+
var cw = Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.width;
|
|
885
|
+
config.context.save();
|
|
886
|
+
config.context.translate(config.x, config.y);
|
|
887
|
+
config.context.strokeStyle = config.strokeStyle;
|
|
888
|
+
config.context.lineWidth = config.lineWidth / 4;
|
|
889
|
+
config.context.beginPath();
|
|
890
|
+
for(var i = Math.floor(-config.x / config.size); i <= (cw - config.x) / config.size; i++) {
|
|
891
|
+
config.context.moveTo(i / config.size, -config.y);
|
|
892
|
+
config.context.lineTo(i / config.size, cw - config.y);
|
|
893
|
+
}
|
|
894
|
+
config.context.stroke();
|
|
895
|
+
config.context.beginPath();
|
|
896
|
+
for(var i = Math.floor(-config.y / config.size); i <= (cw - config.y) / config.size; i++) {
|
|
897
|
+
config.context.moveTo(-config.x, i / config.size);
|
|
898
|
+
config.context.lineTo(cw - config.x, i / config.size);
|
|
899
|
+
}
|
|
900
|
+
config.context.stroke();
|
|
901
|
+
config.context.lineWidth = config.lineWidth;
|
|
902
|
+
config.context.beginPath();
|
|
903
|
+
config.context.moveTo(-config.x, 0);
|
|
904
|
+
config.context.lineTo(cw - config.x, 0);
|
|
905
|
+
config.context.stroke();
|
|
906
|
+
config.context.beginPath();
|
|
907
|
+
config.context.moveTo(0, -config.y);
|
|
908
|
+
config.context.lineTo(0, cw - config.y);
|
|
909
|
+
config.context.stroke();
|
|
910
|
+
config.context.restore();
|
|
911
|
+
},
|
|
912
|
+
rOplane: function(config) {
|
|
913
|
+
(config = {
|
|
914
|
+
x: (config = config || {}).x || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.width / 2,
|
|
915
|
+
y: config.y || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.height / 2,
|
|
916
|
+
size: config.size || 1,
|
|
917
|
+
strokeStyle: config.strokeStyle || "black",
|
|
918
|
+
lineWidth: config.lineWidth || 2,
|
|
919
|
+
context: config.context || Chalkboard.real.parse(Chalkboard.CONTEXT)
|
|
920
|
+
}).size /= 100;
|
|
921
|
+
var cw = Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.width;
|
|
922
|
+
config.context.save();
|
|
923
|
+
config.context.translate(config.x, config.y);
|
|
924
|
+
config.context.strokeStyle = config.strokeStyle;
|
|
925
|
+
config.context.lineWidth = config.lineWidth / 4;
|
|
926
|
+
config.context.beginPath();
|
|
927
|
+
for(var i = 0; i <= config.size * cw / 2; i++) {
|
|
928
|
+
config.context.ellipse(0, 0, i / config.size, i / config.size, 0, 0, Chalkboard.PI(2));
|
|
929
|
+
}
|
|
930
|
+
config.context.stroke();
|
|
931
|
+
config.context.lineWidth = config.lineWidth;
|
|
932
|
+
config.context.beginPath();
|
|
933
|
+
config.context.moveTo(-config.x, 0);
|
|
934
|
+
config.context.lineTo(cw - config.x, 0);
|
|
935
|
+
config.context.stroke()
|
|
936
|
+
config.context.beginPath();
|
|
937
|
+
config.context.moveTo(0, -config.y);
|
|
938
|
+
config.context.lineTo(0, cw - config.y);
|
|
939
|
+
config.context.stroke();
|
|
940
|
+
config.context.restore();
|
|
941
|
+
},
|
|
942
|
+
function: function(func, config) {
|
|
943
|
+
(config = {
|
|
944
|
+
x: (config = config || {}).x || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.width / 2,
|
|
945
|
+
y: config.y || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.height / 2,
|
|
946
|
+
size: config.size || 1,
|
|
947
|
+
strokeStyle: config.strokeStyle || "black",
|
|
948
|
+
lineWidth: config.lineWidth || 2,
|
|
949
|
+
domain: config.domain || (func.type === "comp" ? [[-10, 10], [-10, 10]] : [-10, 10]),
|
|
950
|
+
context: config.context || Chalkboard.real.parse(Chalkboard.CONTEXT)
|
|
951
|
+
}).size /= 100;
|
|
775
952
|
var data = [];
|
|
776
|
-
context.save();
|
|
777
|
-
context.translate(
|
|
778
|
-
context.lineWidth =
|
|
779
|
-
context.strokeStyle =
|
|
780
|
-
context.beginPath();
|
|
953
|
+
config.context.save();
|
|
954
|
+
config.context.translate(config.x, config.y);
|
|
955
|
+
config.context.lineWidth = config.lineWidth;
|
|
956
|
+
config.context.strokeStyle = config.strokeStyle;
|
|
957
|
+
config.context.beginPath();
|
|
781
958
|
if(func.type === "expl") {
|
|
782
959
|
var f = Chalkboard.real.parse("x => " + func.definition);
|
|
783
|
-
for(var i = domain[0] /
|
|
784
|
-
context.lineTo(i, -f(i *
|
|
960
|
+
for(var i = config.domain[0] / config.size; i <= config.domain[1] / config.size; i++) {
|
|
961
|
+
config.context.lineTo(i, -f(i * config.size) / config.size);
|
|
785
962
|
data.push([i, f(i)]);
|
|
786
963
|
}
|
|
964
|
+
} else if(func.type === "inve") {
|
|
965
|
+
var f = Chalkboard.real.parse("y => " + func.definition);
|
|
966
|
+
for(var i = config.domain[0] / config.size; i <= config.domain[1] / config.size; i++) {
|
|
967
|
+
config.context.lineTo(f(i * config.size) / config.size, -i);
|
|
968
|
+
data.push([f(i), i]);
|
|
969
|
+
}
|
|
787
970
|
} else if(func.type === "pola") {
|
|
788
971
|
var r = Chalkboard.real.parse("O => " + func.definition);
|
|
789
|
-
for(var i = domain[0] /
|
|
790
|
-
context.lineTo(r(i *
|
|
972
|
+
for(var i = config.domain[0] / config.size; i <= config.domain[1] / config.size; i++) {
|
|
973
|
+
config.context.lineTo(r(i * config.size) / config.size * Chalkboard.trig.cos(i * config.size), -r(i * config.size) / config.size * Chalkboard.trig.sin(i * config.size));
|
|
791
974
|
data.push([i, r(i)]);
|
|
792
975
|
}
|
|
793
976
|
} else if(func.type === "curv") {
|
|
794
977
|
var x = Chalkboard.real.parse("t => " + func.definition[0]),
|
|
795
978
|
y = Chalkboard.real.parse("t => " + func.definition[1]);
|
|
796
|
-
for(var i = domain[0] /
|
|
797
|
-
context.lineTo(x(i *
|
|
979
|
+
for(var i = config.domain[0] / config.size; i <= config.domain[1] / config.size; i++) {
|
|
980
|
+
config.context.lineTo(x(i * config.size) / config.size, -y(i * config.size) / config.size);
|
|
798
981
|
data.push([x(i), y(i)]);
|
|
799
982
|
}
|
|
800
983
|
} else if(func.type === "comp") {
|
|
801
984
|
var u = Chalkboard.comp.parse("(a, b) => " + func.definition[0]),
|
|
802
985
|
v = Chalkboard.comp.parse("(a, b) => " + func.definition[1]);
|
|
803
|
-
for(var i = domain[0][0] /
|
|
804
|
-
for(var j = domain[1][0] /
|
|
805
|
-
var z = Chalkboard.comp.new(u(i *
|
|
986
|
+
for(var i = config.domain[0][0] / config.size; i <= config.domain[0][1] / config.size; i += 5) {
|
|
987
|
+
for(var j = config.domain[1][0] / config.size; j <= config.domain[1][1] / config.size; j += 5) {
|
|
988
|
+
var z = Chalkboard.comp.new(u(i * config.size, j * config.size) / config.size, v(i * config.size, j * config.size) / config.size);
|
|
806
989
|
if(z.a === 0 && z.b === 0) {
|
|
807
|
-
context.fillStyle = "rgb(0, 0, 0)";
|
|
990
|
+
config.context.fillStyle = "rgb(0, 0, 0)";
|
|
808
991
|
} else if(z.a === Infinity && z.b === Infinity) {
|
|
809
|
-
context.fillStyle = "rgb(255, 255, 255)";
|
|
992
|
+
config.context.fillStyle = "rgb(255, 255, 255)";
|
|
810
993
|
} else {
|
|
811
|
-
context.fillStyle = "hsl(" + Chalkboard.trig.toDeg(Chalkboard.comp.arg(z)) + ", 100%, " + (Chalkboard.trig.tanh(Chalkboard.comp.mag(z) / Chalkboard.real.pow(10, 20)) + 0.5) * 100 + "%)";
|
|
994
|
+
config.context.fillStyle = "hsl(" + Chalkboard.trig.toDeg(Chalkboard.comp.arg(z)) + ", 100%, " + (Chalkboard.trig.tanh(Chalkboard.comp.mag(z) / Chalkboard.real.pow(10, 20)) + 0.5) * 100 + "%)";
|
|
812
995
|
}
|
|
813
|
-
context.fillRect(i, j, 5, 5);
|
|
996
|
+
config.context.fillRect(i, j, 5, 5);
|
|
814
997
|
data.push([u(i, j), v(i, j)]);
|
|
815
998
|
}
|
|
816
999
|
}
|
|
817
1000
|
} else {
|
|
818
|
-
return "TypeError: Property \"type\" of parameter \"func\" must be either \"expl\", \"pola\", \"curv\", or \"comp\".";
|
|
1001
|
+
return "TypeError: Property \"type\" of parameter \"func\" must be either \"expl\", \"inve\", \"pola\", \"curv\", or \"comp\".";
|
|
819
1002
|
}
|
|
820
|
-
context.stroke();
|
|
821
|
-
context.restore();
|
|
1003
|
+
config.context.stroke();
|
|
1004
|
+
config.context.restore();
|
|
822
1005
|
return data;
|
|
823
1006
|
},
|
|
824
|
-
barplot: function(arr, bins,
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
context.
|
|
835
|
-
context.
|
|
1007
|
+
barplot: function(arr, bins, config) {
|
|
1008
|
+
(config = {
|
|
1009
|
+
x: (config = config || {}).x || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.width / 2,
|
|
1010
|
+
y: config.y || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.height / 2,
|
|
1011
|
+
size: config.size || 1,
|
|
1012
|
+
fillStyle: config.fillStyle || "white",
|
|
1013
|
+
strokeStyle: config.strokeStyle || "black",
|
|
1014
|
+
lineWidth: config.lineWidth || 2,
|
|
1015
|
+
context: config.context || Chalkboard.real.parse(Chalkboard.CONTEXT)
|
|
1016
|
+
}).size /= 100;
|
|
1017
|
+
config.context.save();
|
|
1018
|
+
config.context.translate(config.x, config.y);
|
|
1019
|
+
config.context.lineWidth = config.lineWidth;
|
|
1020
|
+
config.context.strokeStyle = config.strokeStyle;
|
|
1021
|
+
config.context.fillStyle = config.fillStyle;
|
|
836
1022
|
var bars = [];
|
|
837
1023
|
for(var i = 0; i < bins.length; i++) {
|
|
838
1024
|
if(i === 0) {
|
|
@@ -847,26 +1033,28 @@ var Chalkboard = {
|
|
|
847
1033
|
for(var i = 0; i < bars.length; i++) {
|
|
848
1034
|
counts.push(bars[i].length);
|
|
849
1035
|
}
|
|
850
|
-
var x = 0, width = counts.length / (2 *
|
|
1036
|
+
var x = 0, width = counts.length / (2 * config.size);
|
|
851
1037
|
for(var i = 0; i < counts.length; i++) {
|
|
852
|
-
context.fillRect(x - width, 0, 1 /
|
|
853
|
-
context.strokeRect(x - width, 0, 1 /
|
|
854
|
-
x += 1 /
|
|
1038
|
+
config.context.fillRect(x - width, 0, 1 / config.size, -counts[i] / config.size);
|
|
1039
|
+
config.context.strokeRect(x - width, 0, 1 / config.size, -counts[i] / config.size);
|
|
1040
|
+
x += 1 / config.size;
|
|
855
1041
|
}
|
|
856
|
-
context.restore();
|
|
1042
|
+
config.context.restore();
|
|
857
1043
|
return bars;
|
|
858
1044
|
},
|
|
859
|
-
lineplot: function(arr, bins,
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
context.
|
|
869
|
-
context.
|
|
1045
|
+
lineplot: function(arr, bins, config) {
|
|
1046
|
+
(config = {
|
|
1047
|
+
x: (config = config || {}).x || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.width / 2,
|
|
1048
|
+
y: config.y || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.height / 2,
|
|
1049
|
+
size: config.size || 1,
|
|
1050
|
+
strokeStyle: config.strokeStyle || "black",
|
|
1051
|
+
lineWidth: config.lineWidth || 2,
|
|
1052
|
+
context: config.context || Chalkboard.real.parse(Chalkboard.CONTEXT)
|
|
1053
|
+
}).size /= 100;
|
|
1054
|
+
config.context.save();
|
|
1055
|
+
config.context.translate(config.x, config.y);
|
|
1056
|
+
config.context.lineWidth = config.lineWidth;
|
|
1057
|
+
config.context.strokeStyle = config.strokeStyle;
|
|
870
1058
|
var verts = [];
|
|
871
1059
|
for(var i = 0; i < bins.length; i++) {
|
|
872
1060
|
if(i === 0) {
|
|
@@ -881,353 +1069,392 @@ var Chalkboard = {
|
|
|
881
1069
|
for(var i = 0; i < verts.length; i++) {
|
|
882
1070
|
counts.push(verts[i].length);
|
|
883
1071
|
}
|
|
884
|
-
context.beginPath();
|
|
1072
|
+
config.context.beginPath();
|
|
885
1073
|
for(var i = 0; i < counts.length; i++) {
|
|
886
|
-
context.lineTo(i /
|
|
1074
|
+
config.context.lineTo(i / config.size, -counts[i] / config.size);
|
|
887
1075
|
}
|
|
888
|
-
context.stroke();
|
|
889
|
-
context.restore();
|
|
1076
|
+
config.context.stroke();
|
|
1077
|
+
config.context.restore();
|
|
890
1078
|
return verts;
|
|
891
1079
|
},
|
|
892
|
-
scatterplot: function(arr1, arr2,
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
1080
|
+
scatterplot: function(arr1, arr2, config) {
|
|
1081
|
+
(config = {
|
|
1082
|
+
x: (config = config || {}).x || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.width / 2,
|
|
1083
|
+
y: config.y || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.height / 2,
|
|
1084
|
+
size: config.size || 1,
|
|
1085
|
+
fillStyle: config.fillStyle || "black",
|
|
1086
|
+
lineWidth: config.lineWidth || 5,
|
|
1087
|
+
context: config.context || Chalkboard.real.parse(Chalkboard.CONTEXT)
|
|
1088
|
+
}).size /= 100;
|
|
899
1089
|
var data = [];
|
|
900
|
-
context.save();
|
|
901
|
-
context.translate(
|
|
902
|
-
context.fillStyle =
|
|
1090
|
+
config.context.save();
|
|
1091
|
+
config.context.translate(config.x, config.y);
|
|
1092
|
+
config.context.fillStyle = config.fillStyle;
|
|
903
1093
|
if(arr1.length === arr2.length) {
|
|
904
1094
|
for(var i = 0; i < arr1.length; i++) {
|
|
905
|
-
context.beginPath();
|
|
906
|
-
context.ellipse(arr1[i] /
|
|
907
|
-
context.fill();
|
|
1095
|
+
config.context.beginPath();
|
|
1096
|
+
config.context.ellipse(arr1[i] / config.size - arr1.length / (2 * config.size), -arr2[i] / config.size + arr1.length / (2 * config.size), config.lineWidth, config.lineWidth, 0, 0, Chalkboard.PI(2));
|
|
1097
|
+
config.context.fill();
|
|
908
1098
|
data.push([arr1[i], arr2[i]]);
|
|
909
1099
|
}
|
|
910
1100
|
}
|
|
911
|
-
context.restore();
|
|
1101
|
+
config.context.restore();
|
|
912
1102
|
return data;
|
|
913
1103
|
},
|
|
914
|
-
comp: function(comp,
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
context.
|
|
924
|
-
context.
|
|
925
|
-
context.
|
|
926
|
-
context.
|
|
927
|
-
context.
|
|
1104
|
+
comp: function(comp, config) {
|
|
1105
|
+
(config = {
|
|
1106
|
+
x: (config = config || {}).x || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.width / 2,
|
|
1107
|
+
y: config.y || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.height / 2,
|
|
1108
|
+
size: config.size || 1,
|
|
1109
|
+
fillStyle: config.fillStyle || "black",
|
|
1110
|
+
lineWidth: config.lineWidth || 5,
|
|
1111
|
+
context: config.context || Chalkboard.real.parse(Chalkboard.CONTEXT)
|
|
1112
|
+
}).size /= 100;
|
|
1113
|
+
config.context.fillStyle = config.fillStyle;
|
|
1114
|
+
config.context.save();
|
|
1115
|
+
config.context.translate(config.x, config.y);
|
|
1116
|
+
config.context.beginPath();
|
|
1117
|
+
config.context.ellipse(comp.a / config.size, -comp.b / config.size, config.lineWidth, config.lineWidth, 0, 0, Chalkboard.PI(2));
|
|
1118
|
+
config.context.fill();
|
|
1119
|
+
config.context.restore();
|
|
928
1120
|
return [[comp.a], [comp.b]];
|
|
929
1121
|
},
|
|
930
|
-
vec2: function(vec2,
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
context.
|
|
940
|
-
context.
|
|
941
|
-
context.
|
|
942
|
-
context.
|
|
943
|
-
context.
|
|
944
|
-
context.
|
|
945
|
-
context.
|
|
1122
|
+
vec2: function(vec2, config) {
|
|
1123
|
+
(config = {
|
|
1124
|
+
x: (config = config || {}).x || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.width / 2,
|
|
1125
|
+
y: config.y || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.height / 2,
|
|
1126
|
+
size: config.size || 1,
|
|
1127
|
+
strokeStyle: config.strokeStyle || "black",
|
|
1128
|
+
lineWidth: config.lineWidth || 5,
|
|
1129
|
+
context: config.context || Chalkboard.real.parse(Chalkboard.CONTEXT)
|
|
1130
|
+
}).size /= 100;
|
|
1131
|
+
config.context.strokeStyle = config.strokeStyle;
|
|
1132
|
+
config.context.lineWidth = config.lineWidth;
|
|
1133
|
+
config.context.save();
|
|
1134
|
+
config.context.translate(config.x, config.y);
|
|
1135
|
+
config.context.beginPath();
|
|
1136
|
+
config.context.moveTo(0, 0);
|
|
1137
|
+
config.context.lineTo(vec2.x / config.size, -vec2.y / config.size);
|
|
1138
|
+
config.context.stroke();
|
|
1139
|
+
config.context.restore();
|
|
946
1140
|
return [[vec2.x], [vec2.y]];
|
|
947
1141
|
},
|
|
948
|
-
field: function(vec2field,
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
1142
|
+
field: function(vec2field, config) {
|
|
1143
|
+
(config = {
|
|
1144
|
+
x: (config = config || {}).x || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.width / 2,
|
|
1145
|
+
y: config.y || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.height / 2,
|
|
1146
|
+
size: config.size || 1,
|
|
1147
|
+
strokeStyle: config.strokeStyle || "black",
|
|
1148
|
+
lineWidth: config.lineWidth || 2,
|
|
1149
|
+
domain: config.domain || [[-10, 10], [10, 10]],
|
|
1150
|
+
res: config.res || 25,
|
|
1151
|
+
context: config.context || Chalkboard.real.parse(Chalkboard.CONTEXT)
|
|
1152
|
+
}).size /= 100;
|
|
957
1153
|
var data = [];
|
|
958
|
-
context.strokeStyle =
|
|
959
|
-
context.lineWidth =
|
|
960
|
-
context.save();
|
|
961
|
-
context.translate(
|
|
962
|
-
for(var i = domain[0][0] /
|
|
963
|
-
for(var j = domain[1][0] /
|
|
1154
|
+
config.context.strokeStyle = config.strokeStyle;
|
|
1155
|
+
config.context.lineWidth = config.lineWidth;
|
|
1156
|
+
config.context.save();
|
|
1157
|
+
config.context.translate(config.x, config.y);
|
|
1158
|
+
for(var i = config.domain[0][0] / config.size; i <= config.domain[0][1] / config.size; i += config.res) {
|
|
1159
|
+
for(var j = config.domain[1][0] / config.size; j <= config.domain[1][1] / config.size; j += config.res) {
|
|
964
1160
|
var v = Chalkboard.vec2.fromField(vec2field, Chalkboard.vec2.new(i, j));
|
|
965
|
-
context.beginPath();
|
|
966
|
-
context.moveTo(i, j);
|
|
967
|
-
context.lineTo(i + v.x, j + v.y);
|
|
968
|
-
context.stroke();
|
|
1161
|
+
config.context.beginPath();
|
|
1162
|
+
config.context.moveTo(i, j);
|
|
1163
|
+
config.context.lineTo(i + v.x, j + v.y);
|
|
1164
|
+
config.context.stroke();
|
|
969
1165
|
data.push([i + v.x, j + v.y]);
|
|
970
1166
|
}
|
|
971
1167
|
}
|
|
972
|
-
context.restore();
|
|
1168
|
+
config.context.restore();
|
|
973
1169
|
return data;
|
|
974
1170
|
},
|
|
975
|
-
vec3: function(vec3,
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
context.
|
|
985
|
-
context.
|
|
986
|
-
context.
|
|
987
|
-
context.
|
|
988
|
-
context.
|
|
989
|
-
context.
|
|
990
|
-
context.
|
|
1171
|
+
vec3: function(vec3, config) {
|
|
1172
|
+
(config = {
|
|
1173
|
+
x: (config = config || {}).x || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.width / 2,
|
|
1174
|
+
y: config.y || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.height / 2,
|
|
1175
|
+
size: config.size || 1,
|
|
1176
|
+
strokeStyle: config.strokeStyle || "black",
|
|
1177
|
+
lineWidth: config.lineWidth || 5,
|
|
1178
|
+
context: config.context || Chalkboard.real.parse(Chalkboard.CONTEXT)
|
|
1179
|
+
}).size /= 100;
|
|
1180
|
+
config.context.strokeStyle = config.strokeStyle;
|
|
1181
|
+
config.context.lineWidth = config.lineWidth;
|
|
1182
|
+
config.context.save();
|
|
1183
|
+
config.context.translate(config.x, config.y);
|
|
1184
|
+
config.context.beginPath();
|
|
1185
|
+
config.context.moveTo(0, 0);
|
|
1186
|
+
config.context.lineTo((vec3.x / config.size) / (vec3.z * 0.25 + 1), (-vec3.y / config.size) / (vec3.z * 0.25 + 1));
|
|
1187
|
+
config.context.stroke();
|
|
1188
|
+
config.context.restore();
|
|
991
1189
|
return [[vec3.x], [vec3.y], [vec3.z]];
|
|
992
1190
|
},
|
|
993
|
-
matr: function(matr,
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
for(var i =
|
|
1004
|
-
Chalkboard.vec2.
|
|
1005
|
-
Chalkboard.vec2.
|
|
1006
|
-
Chalkboard.vec2.
|
|
1007
|
-
Chalkboard.vec2.
|
|
1008
|
-
}
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
Chalkboard.vec2.plot(plotposaxisx, scl, rgba, origin, weight, context);
|
|
1014
|
-
Chalkboard.vec2.plot(plotnegaxisx, scl, rgba, origin, weight, context);
|
|
1015
|
-
Chalkboard.vec2.plot(plotposaxisy, scl, rgba, origin, weight, context);
|
|
1016
|
-
Chalkboard.vec2.plot(plotnegaxisy, scl, rgba, origin, weight, context);
|
|
1191
|
+
matr: function(matr, config) {
|
|
1192
|
+
(config = {
|
|
1193
|
+
x: (config = config || {}).x || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.width / 2,
|
|
1194
|
+
y: config.y || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.height / 2,
|
|
1195
|
+
size: config.size || 1,
|
|
1196
|
+
strokeStyle: config.strokeStyle || "black",
|
|
1197
|
+
lineWidth: config.lineWidth || 2,
|
|
1198
|
+
domain: config.domain || [-10, 10],
|
|
1199
|
+
context: config.context || Chalkboard.real.parse(Chalkboard.CONTEXT)
|
|
1200
|
+
}).size /= 100;
|
|
1201
|
+
for(var i = config.domain[0]; i <= config.domain[1]; i++) {
|
|
1202
|
+
Chalkboard.plot.vec2(Chalkboard.vec2.new(matr[0][0], matr[1][0]), {x: config.x, y: config.y + (i / config.size) * matr[1][1], size: config.size, strokeStyle: config.strokeStyle, lineWidth: config.lineWidth / 4, context: config.context});
|
|
1203
|
+
Chalkboard.plot.vec2(Chalkboard.vec2.new(-matr[0][0], -matr[1][0]), {x: config.x, y: config.y + (i / config.size) * matr[1][1], size: config.size, strokeStyle: config.strokeStyle, lineWidth: config.lineWidth / 4, context: config.context});
|
|
1204
|
+
Chalkboard.plot.vec2(Chalkboard.vec2.new(matr[0][1], matr[1][1]), {x: config.x + (i / config.size) * matr[0][0], y: config.y, size: config.size, strokeStyle: config.strokeStyle, lineWidth: config.lineWidth / 4, context: config.context});
|
|
1205
|
+
Chalkboard.plot.vec2(Chalkboard.vec2.new(-matr[0][1], -matr[1][1]), {x: config.x + (i / config.size) * matr[0][0], y: config.y, size: config.size, strokeStyle: config.strokeStyle, lineWidth: config.lineWidth / 4, context: config.context});
|
|
1206
|
+
}
|
|
1207
|
+
Chalkboard.plot.vec2(Chalkboard.vec2.new(matr[0][0], matr[1][0]), config);
|
|
1208
|
+
Chalkboard.plot.vec2(Chalkboard.vec2.new(-matr[0][0], -matr[1][0]), config);
|
|
1209
|
+
Chalkboard.plot.vec2(Chalkboard.vec2.new(matr[0][1], matr[1][1]), config);
|
|
1210
|
+
Chalkboard.plot.vec2(Chalkboard.vec2.new(-matr[0][1], -matr[1][1]), config);
|
|
1017
1211
|
return matr;
|
|
1018
1212
|
},
|
|
1019
|
-
dfdx: function(func,
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1213
|
+
dfdx: function(func, config) {
|
|
1214
|
+
(config = {
|
|
1215
|
+
x: (config = config || {}).x || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.width / 2,
|
|
1216
|
+
y: config.y || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.height / 2,
|
|
1217
|
+
size: config.size || 1,
|
|
1218
|
+
strokeStyle: config.strokeStyle || "black",
|
|
1219
|
+
lineWidth: config.lineWidth || 2,
|
|
1220
|
+
domain: config.domain || [-10, 10],
|
|
1221
|
+
res: config.res || 25,
|
|
1222
|
+
context: config.context || Chalkboard.real.parse(Chalkboard.CONTEXT)
|
|
1223
|
+
}).size /= 100;
|
|
1028
1224
|
var data = [];
|
|
1029
|
-
context.save();
|
|
1030
|
-
context.translate(
|
|
1031
|
-
context.lineWidth =
|
|
1032
|
-
context.strokeStyle =
|
|
1033
|
-
context.beginPath();
|
|
1034
|
-
for(var i = domain[0] /
|
|
1035
|
-
|
|
1036
|
-
|
|
1225
|
+
config.context.save();
|
|
1226
|
+
config.context.translate(config.x, config.y);
|
|
1227
|
+
config.context.lineWidth = config.lineWidth;
|
|
1228
|
+
config.context.strokeStyle = config.strokeStyle;
|
|
1229
|
+
config.context.beginPath();
|
|
1230
|
+
for(var i = config.domain[0] / config.size; i <= config.domain[1] / config.size; i += config.res) {
|
|
1231
|
+
if(func.type === "expl") {
|
|
1232
|
+
config.context.lineTo(i, -Chalkboard.calc.dfdx(func, i * config.size) / config.size);
|
|
1233
|
+
data.push([i, Chalkboard.calc.dfdx(func, i)]);
|
|
1234
|
+
} else if(func.type === "inve") {
|
|
1235
|
+
config.context.lineTo(Chalkboard.calc.dfdx(func, i * config.size) / config.size, -i);
|
|
1236
|
+
data.push([Chalkboard.calc.dfdx(func, i), i]);
|
|
1237
|
+
}
|
|
1037
1238
|
}
|
|
1038
|
-
context.stroke();
|
|
1039
|
-
context.restore();
|
|
1239
|
+
config.context.stroke();
|
|
1240
|
+
config.context.restore();
|
|
1040
1241
|
return data;
|
|
1041
1242
|
},
|
|
1042
|
-
d2fdx2: function(func,
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1243
|
+
d2fdx2: function(func, config) {
|
|
1244
|
+
(config = {
|
|
1245
|
+
x: (config = config || {}).x || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.width / 2,
|
|
1246
|
+
y: config.y || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.height / 2,
|
|
1247
|
+
size: config.size || 1,
|
|
1248
|
+
strokeStyle: config.strokeStyle || "black",
|
|
1249
|
+
lineWidth: config.lineWidth || 2,
|
|
1250
|
+
domain: config.domain || [-10, 10],
|
|
1251
|
+
res: config.res || 25,
|
|
1252
|
+
context: config.context || Chalkboard.real.parse(Chalkboard.CONTEXT)
|
|
1253
|
+
}).size /= 100;
|
|
1051
1254
|
var data = [];
|
|
1052
|
-
context.save();
|
|
1053
|
-
context.translate(
|
|
1054
|
-
context.lineWidth =
|
|
1055
|
-
context.strokeStyle =
|
|
1056
|
-
context.beginPath();
|
|
1057
|
-
for(var i = domain[0] /
|
|
1058
|
-
|
|
1059
|
-
|
|
1255
|
+
config.context.save();
|
|
1256
|
+
config.context.translate(config.x, config.y);
|
|
1257
|
+
config.context.lineWidth = config.lineWidth;
|
|
1258
|
+
config.context.strokeStyle = config.strokeStyle;
|
|
1259
|
+
config.context.beginPath();
|
|
1260
|
+
for(var i = config.domain[0] / config.size; i <= config.domain[1] / config.size; i += config.res) {
|
|
1261
|
+
if(func.type === "expl") {
|
|
1262
|
+
config.context.lineTo(i, -Chalkboard.calc.d2fdx2(func, i * config.size) / config.size);
|
|
1263
|
+
data.push([i, Chalkboard.calc.d2fdx2(func, i)]);
|
|
1264
|
+
} else if(func.type === "inve") {
|
|
1265
|
+
config.context.lineTo(Chalkboard.calc.d2fdx2(func, i * config.size) / config.size, -i);
|
|
1266
|
+
data.push([Chalkboard.calc.d2fdx2(func, i), i]);
|
|
1267
|
+
}
|
|
1060
1268
|
}
|
|
1061
|
-
context.stroke();
|
|
1062
|
-
context.restore();
|
|
1269
|
+
config.context.stroke();
|
|
1270
|
+
config.context.restore();
|
|
1063
1271
|
return data;
|
|
1064
1272
|
},
|
|
1065
|
-
fxdx: function(func,
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1273
|
+
fxdx: function(func, config) {
|
|
1274
|
+
(config = {
|
|
1275
|
+
x: (config = config || {}).x || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.width / 2,
|
|
1276
|
+
y: config.y || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.height / 2,
|
|
1277
|
+
size: config.size || 1,
|
|
1278
|
+
strokeStyle: config.strokeStyle || "black",
|
|
1279
|
+
lineWidth: config.lineWidth || 2,
|
|
1280
|
+
domain: config.domain || [-10, 10],
|
|
1281
|
+
res: config.res || 25,
|
|
1282
|
+
context: config.context || Chalkboard.real.parse(Chalkboard.CONTEXT)
|
|
1283
|
+
}).size /= 100;
|
|
1074
1284
|
var data = [];
|
|
1075
|
-
context.save();
|
|
1076
|
-
context.translate(
|
|
1077
|
-
context.lineWidth =
|
|
1078
|
-
context.strokeStyle =
|
|
1079
|
-
context.beginPath();
|
|
1080
|
-
for(var i = domain[0] /
|
|
1081
|
-
|
|
1082
|
-
|
|
1285
|
+
config.context.save();
|
|
1286
|
+
config.context.translate(config.x, config.y);
|
|
1287
|
+
config.context.lineWidth = config.lineWidth;
|
|
1288
|
+
config.context.strokeStyle = config.strokeStyle;
|
|
1289
|
+
config.context.beginPath();
|
|
1290
|
+
for(var i = config.domain[0] / config.size; i <= config.domain[1] / config.size; i += config.res) {
|
|
1291
|
+
if(func.type === "expl") {
|
|
1292
|
+
config.context.lineTo(i, -Chalkboard.calc.fxdx(func, 0, i * config.size) / config.size);
|
|
1293
|
+
data.push([i, Chalkboard.calc.fxdx(func, 0, i)]);
|
|
1294
|
+
} else if(func.type === "inve") {
|
|
1295
|
+
config.context.lineTo(Chalkboard.calc.fxdx(func, 0, i * config.size) / config.size, -i);
|
|
1296
|
+
data.push([Chalkboard.calc.fxdx(func, 0, i), i]);
|
|
1297
|
+
}
|
|
1083
1298
|
}
|
|
1084
|
-
context.stroke();
|
|
1085
|
-
context.restore();
|
|
1299
|
+
config.context.stroke();
|
|
1300
|
+
config.context.restore();
|
|
1086
1301
|
return data;
|
|
1087
1302
|
},
|
|
1088
|
-
convolution: function(func_1, func_2,
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1303
|
+
convolution: function(func_1, func_2, config) {
|
|
1304
|
+
(config = {
|
|
1305
|
+
x: (config = config || {}).x || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.width / 2,
|
|
1306
|
+
y: config.y || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.height / 2,
|
|
1307
|
+
size: config.size || 1,
|
|
1308
|
+
strokeStyle: config.strokeStyle || "black",
|
|
1309
|
+
lineWidth: config.lineWidth || 2,
|
|
1310
|
+
domain: config.domain || [-10, 10],
|
|
1311
|
+
res: config.res || 25,
|
|
1312
|
+
context: config.context || Chalkboard.real.parse(Chalkboard.CONTEXT)
|
|
1313
|
+
}).size /= 100;
|
|
1097
1314
|
var data = [];
|
|
1098
|
-
context.save();
|
|
1099
|
-
context.translate(
|
|
1100
|
-
context.lineWidth =
|
|
1101
|
-
context.strokeStyle =
|
|
1102
|
-
context.beginPath();
|
|
1103
|
-
for(var i = domain[0] /
|
|
1104
|
-
context.lineTo(i, -Chalkboard.calc.convolution(func_1, func_2, i *
|
|
1315
|
+
config.context.save();
|
|
1316
|
+
config.context.translate(config.x, config.y);
|
|
1317
|
+
config.context.lineWidth = config.lineWidth;
|
|
1318
|
+
config.context.strokeStyle = config.strokeStyle;
|
|
1319
|
+
config.context.beginPath();
|
|
1320
|
+
for(var i = config.domain[0] / config.size; i <= config.domain[1] / config.size; i += config.res) {
|
|
1321
|
+
config.context.lineTo(i, -Chalkboard.calc.convolution(func_1, func_2, i * config.size) / config.size);
|
|
1105
1322
|
data.push([i, Chalkboard.calc.convolution(func_1, func_2, i)]);
|
|
1106
1323
|
}
|
|
1107
|
-
context.stroke();
|
|
1108
|
-
context.restore();
|
|
1324
|
+
config.context.stroke();
|
|
1325
|
+
config.context.restore();
|
|
1109
1326
|
return data;
|
|
1110
1327
|
},
|
|
1111
|
-
correlation: function(func_1, func_2,
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1328
|
+
correlation: function(func_1, func_2, config) {
|
|
1329
|
+
(config = {
|
|
1330
|
+
x: (config = config || {}).x || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.width / 2,
|
|
1331
|
+
y: config.y || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.height / 2,
|
|
1332
|
+
size: config.size || 1,
|
|
1333
|
+
strokeStyle: config.strokeStyle || "black",
|
|
1334
|
+
lineWidth: config.lineWidth || 2,
|
|
1335
|
+
domain: config.domain || [-10, 10],
|
|
1336
|
+
res: config.res || 25,
|
|
1337
|
+
context: config.context || Chalkboard.real.parse(Chalkboard.CONTEXT)
|
|
1338
|
+
}).size /= 100;
|
|
1120
1339
|
var data = [];
|
|
1121
|
-
context.save();
|
|
1122
|
-
context.translate(
|
|
1123
|
-
context.lineWidth =
|
|
1124
|
-
context.strokeStyle =
|
|
1125
|
-
context.beginPath();
|
|
1126
|
-
for(var i = domain[0] /
|
|
1127
|
-
context.lineTo(i, -Chalkboard.calc.correlation(func_1, func_2, i *
|
|
1340
|
+
config.context.save();
|
|
1341
|
+
config.context.translate(config.x, config.y);
|
|
1342
|
+
config.context.lineWidth = config.lineWidth;
|
|
1343
|
+
config.context.strokeStyle = config.strokeStyle;
|
|
1344
|
+
config.context.beginPath();
|
|
1345
|
+
for(var i = config.domain[0] / config.size; i <= config.domain[1] / config.size; i += config.res) {
|
|
1346
|
+
config.context.lineTo(i, -Chalkboard.calc.correlation(func_1, func_2, i * config.size) / config.size);
|
|
1128
1347
|
data.push([i, Chalkboard.calc.correlation(func_1, func_2, i)]);
|
|
1129
1348
|
}
|
|
1130
|
-
context.stroke();
|
|
1131
|
-
context.restore();
|
|
1349
|
+
config.context.stroke();
|
|
1350
|
+
config.context.restore();
|
|
1132
1351
|
return data;
|
|
1133
1352
|
},
|
|
1134
|
-
autocorrelation: function(func,
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1353
|
+
autocorrelation: function(func, config) {
|
|
1354
|
+
(config = {
|
|
1355
|
+
x: (config = config || {}).x || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.width / 2,
|
|
1356
|
+
y: config.y || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.height / 2,
|
|
1357
|
+
size: config.size || 1,
|
|
1358
|
+
strokeStyle: config.strokeStyle || "black",
|
|
1359
|
+
lineWidth: config.lineWidth || 2,
|
|
1360
|
+
domain: config.domain || [-10, 10],
|
|
1361
|
+
res: config.res || 25,
|
|
1362
|
+
context: config.context || Chalkboard.real.parse(Chalkboard.CONTEXT)
|
|
1363
|
+
}).size /= 100;
|
|
1143
1364
|
var data = [];
|
|
1144
|
-
context.save();
|
|
1145
|
-
context.translate(
|
|
1146
|
-
context.lineWidth =
|
|
1147
|
-
context.strokeStyle =
|
|
1148
|
-
context.beginPath();
|
|
1149
|
-
for(var i = domain[0] /
|
|
1150
|
-
context.lineTo(i, -Chalkboard.calc.autocorrelation(func, i *
|
|
1365
|
+
config.context.save();
|
|
1366
|
+
config.context.translate(config.x, config.y);
|
|
1367
|
+
config.context.lineWidth = config.lineWidth;
|
|
1368
|
+
config.context.strokeStyle = config.strokeStyle;
|
|
1369
|
+
config.context.beginPath();
|
|
1370
|
+
for(var i = config.domain[0] / config.size; i <= config.domain[1] / config.size; i += config.res) {
|
|
1371
|
+
config.context.lineTo(i, -Chalkboard.calc.autocorrelation(func, i * config.size) / config.size);
|
|
1151
1372
|
data.push([i, Chalkboard.calc.autocorrelation(func, i)]);
|
|
1152
1373
|
}
|
|
1153
|
-
context.stroke();
|
|
1154
|
-
context.restore();
|
|
1374
|
+
config.context.stroke();
|
|
1375
|
+
config.context.restore();
|
|
1155
1376
|
return data;
|
|
1156
1377
|
},
|
|
1157
|
-
Taylor: function(func, n, a,
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1378
|
+
Taylor: function(func, n, a, config) {
|
|
1379
|
+
(config = {
|
|
1380
|
+
x: (config = config || {}).x || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.width / 2,
|
|
1381
|
+
y: config.y || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.height / 2,
|
|
1382
|
+
size: config.size || 1,
|
|
1383
|
+
strokeStyle: config.strokeStyle || "black",
|
|
1384
|
+
lineWidth: config.lineWidth || 2,
|
|
1385
|
+
domain: config.domain || [-10, 10],
|
|
1386
|
+
res: config.res || 25,
|
|
1387
|
+
context: config.context || Chalkboard.real.parse(Chalkboard.CONTEXT)
|
|
1388
|
+
}).size /= 100;
|
|
1166
1389
|
var data = [];
|
|
1167
|
-
context.save();
|
|
1168
|
-
context.translate(
|
|
1169
|
-
context.lineWidth =
|
|
1170
|
-
context.strokeStyle =
|
|
1171
|
-
context.beginPath();
|
|
1172
|
-
for(var i = domain[0] /
|
|
1173
|
-
context.lineTo(i, -Chalkboard.calc.Taylor(func, i *
|
|
1390
|
+
config.context.save();
|
|
1391
|
+
config.context.translate(config.x, config.y);
|
|
1392
|
+
config.context.lineWidth = config.lineWidth;
|
|
1393
|
+
config.context.strokeStyle = config.strokeStyle;
|
|
1394
|
+
config.context.beginPath();
|
|
1395
|
+
for(var i = config.domain[0] / config.size; i <= config.domain[1] / config.size; i += config.res) {
|
|
1396
|
+
config.context.lineTo(i, -Chalkboard.calc.Taylor(func, i * config.size, n, a) / config.size);
|
|
1174
1397
|
data.push([i, Chalkboard.calc.Taylor(func, i, n, a)]);
|
|
1175
1398
|
}
|
|
1176
|
-
context.stroke();
|
|
1177
|
-
context.restore();
|
|
1399
|
+
config.context.stroke();
|
|
1400
|
+
config.context.restore();
|
|
1178
1401
|
return data;
|
|
1179
1402
|
},
|
|
1180
|
-
Laplace: function(func,
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1403
|
+
Laplace: function(func, config) {
|
|
1404
|
+
(config = {
|
|
1405
|
+
x: (config = config || {}).x || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.width / 2,
|
|
1406
|
+
y: config.y || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.height / 2,
|
|
1407
|
+
size: config.size || 1,
|
|
1408
|
+
strokeStyle: config.strokeStyle || "black",
|
|
1409
|
+
lineWidth: config.lineWidth || 2,
|
|
1410
|
+
domain: config.domain || [-10, 10],
|
|
1411
|
+
res: config.res || 25,
|
|
1412
|
+
context: config.context || Chalkboard.real.parse(Chalkboard.CONTEXT)
|
|
1413
|
+
}).size /= 100;
|
|
1189
1414
|
var data = [];
|
|
1190
|
-
context.save();
|
|
1191
|
-
context.translate(
|
|
1192
|
-
context.lineWidth =
|
|
1193
|
-
context.strokeStyle =
|
|
1194
|
-
context.beginPath();
|
|
1195
|
-
if(domain[0] >= 0) {
|
|
1196
|
-
for(var i = domain[0] /
|
|
1197
|
-
context.lineTo(i, -Chalkboard.calc.Laplace(func, i *
|
|
1415
|
+
config.context.save();
|
|
1416
|
+
config.context.translate(config.x, config.y);
|
|
1417
|
+
config.context.lineWidth = config.lineWidth;
|
|
1418
|
+
config.context.strokeStyle = config.strokeStyle;
|
|
1419
|
+
config.context.beginPath();
|
|
1420
|
+
if( config.domain[0] >= 0) {
|
|
1421
|
+
for(var i = config.domain[0] / config.size; i <= config.domain[1] / config.size; i += config.res) {
|
|
1422
|
+
config.context.lineTo(i, -Chalkboard.calc.Laplace(func, i * config.size) / config.size);
|
|
1198
1423
|
data.push([i, Chalkboard.calc.Laplace(func, i)]);
|
|
1199
1424
|
}
|
|
1200
1425
|
} else {
|
|
1201
|
-
for(var i = 0; i <= domain[1] /
|
|
1202
|
-
context.lineTo(i, -Chalkboard.calc.Laplace(func, i *
|
|
1426
|
+
for(var i = 0; i <= config.domain[1] / config.size; i += config.res) {
|
|
1427
|
+
config.context.lineTo(i, -Chalkboard.calc.Laplace(func, i * config.size) / config.size);
|
|
1203
1428
|
data.push([i, Chalkboard.calc.Laplace(func, i)]);
|
|
1204
1429
|
}
|
|
1205
1430
|
}
|
|
1206
|
-
context.stroke();
|
|
1207
|
-
context.restore();
|
|
1431
|
+
config.context.stroke();
|
|
1432
|
+
config.context.restore();
|
|
1208
1433
|
return data;
|
|
1209
1434
|
},
|
|
1210
|
-
Fourier: function(func,
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1435
|
+
Fourier: function(func, config) {
|
|
1436
|
+
(config = {
|
|
1437
|
+
x: (config = config || {}).x || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.width / 2,
|
|
1438
|
+
y: config.y || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.height / 2,
|
|
1439
|
+
size: config.size || 1,
|
|
1440
|
+
strokeStyle: config.strokeStyle || "black",
|
|
1441
|
+
lineWidth: config.lineWidth || 2,
|
|
1442
|
+
domain: config.domain || [-10, 10],
|
|
1443
|
+
res: config.res || 25,
|
|
1444
|
+
context: config.context || Chalkboard.real.parse(Chalkboard.CONTEXT)
|
|
1445
|
+
}).size /= 100;
|
|
1219
1446
|
var data = [];
|
|
1220
|
-
context.save();
|
|
1221
|
-
context.translate(
|
|
1222
|
-
context.lineWidth =
|
|
1223
|
-
context.strokeStyle =
|
|
1224
|
-
context.beginPath();
|
|
1225
|
-
for(var i = domain[0] /
|
|
1226
|
-
context.lineTo(i, -Chalkboard.calc.Fourier(func, i *
|
|
1447
|
+
config.context.save();
|
|
1448
|
+
config.context.translate(config.x, config.y);
|
|
1449
|
+
config.context.lineWidth = config.lineWidth;
|
|
1450
|
+
config.context.strokeStyle = config.strokeStyle;
|
|
1451
|
+
config.context.beginPath();
|
|
1452
|
+
for(var i = config.domain[0] / config.size; i <= config.domain[1] / config.size; i += config.res) {
|
|
1453
|
+
config.context.lineTo(i, -Chalkboard.calc.Fourier(func, i * config.size) / config.size);
|
|
1227
1454
|
data.push([i, Chalkboard.calc.Fourier(func, i)]);
|
|
1228
1455
|
}
|
|
1229
|
-
context.stroke();
|
|
1230
|
-
context.restore();
|
|
1456
|
+
config.context.stroke();
|
|
1457
|
+
config.context.restore();
|
|
1231
1458
|
return data;
|
|
1232
1459
|
}
|
|
1233
1460
|
},
|
|
@@ -1375,7 +1602,7 @@ var Chalkboard = {
|
|
|
1375
1602
|
return h * (Chalkboard.real.sqrt(-(a * a * a * a) + 2 * (a * b) * (a * b) + 2 * (a * c) * (a * c) - (b * b * b * b) + 2 * (b * c) * (b * c) - (c * c * c * c))) / 4;
|
|
1376
1603
|
},
|
|
1377
1604
|
line3D: function(x1, y1, z1, x2, y2, z2, context) {
|
|
1378
|
-
context = context ||
|
|
1605
|
+
context = context || Chalkboard.real.parse(Chalkboard.CONTEXT);
|
|
1379
1606
|
context.beginPath();
|
|
1380
1607
|
context.moveTo(x1 / (z1 * 0.0025 + 1), y1 / (z1 * 0.0025 + 1));
|
|
1381
1608
|
context.lineTo(x2 / (z2 * 0.0025 + 1), y2 / (z2 * 0.0025 + 1));
|
|
@@ -1559,6 +1786,16 @@ var Chalkboard = {
|
|
|
1559
1786
|
}
|
|
1560
1787
|
return result;
|
|
1561
1788
|
},
|
|
1789
|
+
shuffle: function(arr) {
|
|
1790
|
+
var index, temp, rindex;
|
|
1791
|
+
for(index = arr.length - 1; index > 0; index--) {
|
|
1792
|
+
rindex = Math.floor(Chalkboard.numb.random(0, index + 1));
|
|
1793
|
+
temp = arr[index];
|
|
1794
|
+
arr[index] = arr[rindex];
|
|
1795
|
+
arr[rindex] = temp;
|
|
1796
|
+
}
|
|
1797
|
+
return arr;
|
|
1798
|
+
},
|
|
1562
1799
|
norm: function(arr, type) {
|
|
1563
1800
|
type = type || "L2";
|
|
1564
1801
|
var result = 0;
|
|
@@ -1632,7 +1869,7 @@ var Chalkboard = {
|
|
|
1632
1869
|
},
|
|
1633
1870
|
eq: function(arr, arrORnum) {
|
|
1634
1871
|
var result = [];
|
|
1635
|
-
if(arrORnum
|
|
1872
|
+
if(Array.isArray(arrORnum)) {
|
|
1636
1873
|
if(arr.length === arrORnum.length) {
|
|
1637
1874
|
for(var i = 0; i < arr.length; i++) {
|
|
1638
1875
|
if(arr[i] === arrORnum[i]) {
|
|
@@ -1653,7 +1890,7 @@ var Chalkboard = {
|
|
|
1653
1890
|
includeInf = includeInf || false;
|
|
1654
1891
|
includeSup = includeSup || false;
|
|
1655
1892
|
var result = [];
|
|
1656
|
-
if(inf
|
|
1893
|
+
if(Array.isArray(inf) && Array.isArray(sup)) {
|
|
1657
1894
|
if(arr.length === inf.length && arr.length === sup.length) {
|
|
1658
1895
|
for(var i = 0; i < arr.length; i++) {
|
|
1659
1896
|
if(includeInf) {
|
|
@@ -1709,7 +1946,7 @@ var Chalkboard = {
|
|
|
1709
1946
|
lt: function(arr, arrORnum, includeEnd) {
|
|
1710
1947
|
includeEnd = includeEnd || false;
|
|
1711
1948
|
var result = [];
|
|
1712
|
-
if(arrORnum
|
|
1949
|
+
if(Array.isArray(arrORnum)) {
|
|
1713
1950
|
if(arr.length === arrORnum.length) {
|
|
1714
1951
|
for(var i = 0; i < arr.length; i++) {
|
|
1715
1952
|
if(includeEnd) {
|
|
@@ -1741,7 +1978,7 @@ var Chalkboard = {
|
|
|
1741
1978
|
gt: function(arr, arrORnum, includeEnd) {
|
|
1742
1979
|
includeEnd = includeEnd || false;
|
|
1743
1980
|
var result = [];
|
|
1744
|
-
if(arrORnum
|
|
1981
|
+
if(Array.isArray(arrORnum)) {
|
|
1745
1982
|
if(arr.length === arrORnum.length) {
|
|
1746
1983
|
for(var i = 0; i < arr.length; i++) {
|
|
1747
1984
|
if(includeEnd) {
|
|
@@ -1770,6 +2007,23 @@ var Chalkboard = {
|
|
|
1770
2007
|
}
|
|
1771
2008
|
return result;
|
|
1772
2009
|
},
|
|
2010
|
+
subsets: function(arr) {
|
|
2011
|
+
var result = [[]];
|
|
2012
|
+
arr.sort();
|
|
2013
|
+
for(var i = 0; i < arr.length; i++) {
|
|
2014
|
+
if(i === 0 || arr[i] !== arr[i - 1]) {
|
|
2015
|
+
var curr = arr[i];
|
|
2016
|
+
var subsetsWithCurr = [];
|
|
2017
|
+
for(var j = 0; j < result.length; j++) {
|
|
2018
|
+
var subset = result[j].slice();
|
|
2019
|
+
subset.push(curr);
|
|
2020
|
+
subsetsWithCurr.push(subset);
|
|
2021
|
+
}
|
|
2022
|
+
result = result.concat(subsetsWithCurr);
|
|
2023
|
+
}
|
|
2024
|
+
}
|
|
2025
|
+
return result;
|
|
2026
|
+
},
|
|
1773
2027
|
max: function(arr) {
|
|
1774
2028
|
var max = arr[0];
|
|
1775
2029
|
for(var i = 0; i < arr.length; i++) {
|
|
@@ -1803,7 +2057,7 @@ var Chalkboard = {
|
|
|
1803
2057
|
for(var i = 0; i < arr.length; i++) {
|
|
1804
2058
|
result *= arr[i];
|
|
1805
2059
|
}
|
|
1806
|
-
return Chalkboard.real.
|
|
2060
|
+
return Chalkboard.real.root(Math.abs(result), arr.length);
|
|
1807
2061
|
} else if(type === "harmonic") {
|
|
1808
2062
|
for(var i = 0; i < arr.length; i++) {
|
|
1809
2063
|
result += 1 / arr[i];
|
|
@@ -1968,13 +2222,93 @@ var Chalkboard = {
|
|
|
1968
2222
|
Gaussian: function(height, mean, deviation) {
|
|
1969
2223
|
return Chalkboard.real.function(height.toString() + " * Math.exp(-((x - " + mean.toString() + ") * (x - " + mean.toString() + ")) / (2 * " + deviation.toString() + " * " + deviation.toString() + "))");
|
|
1970
2224
|
},
|
|
1971
|
-
|
|
2225
|
+
regression: function(data, type, degree) {
|
|
2226
|
+
type = type || "linear";
|
|
2227
|
+
degree = degree || 2;
|
|
2228
|
+
if(type === "linear") {
|
|
2229
|
+
var x = 0, y = 0;
|
|
2230
|
+
var xx = 0, xy = 0;
|
|
2231
|
+
for(var i = 0; i < data.length; i++) {
|
|
2232
|
+
x += data[i][0];
|
|
2233
|
+
y += data[i][1];
|
|
2234
|
+
xx += data[i][0] * data[i][0];
|
|
2235
|
+
xy += data[i][0] * data[i][1];
|
|
2236
|
+
}
|
|
2237
|
+
var a = (data.length * xy - x * y) / (data.length * xx - x * x),
|
|
2238
|
+
b = (y / data.length) - (a * x) / data.length;
|
|
2239
|
+
return Chalkboard.real.function(a + " * x + " + b);
|
|
2240
|
+
} else if(type === "polynomial") {
|
|
2241
|
+
var A = Chalkboard.matr.new();
|
|
2242
|
+
for(var i = 0; i < data.length; i++) {
|
|
2243
|
+
A.push([]);
|
|
2244
|
+
for(var j = 0; j <= degree; j++) {
|
|
2245
|
+
A[i].push(Chalkboard.real.pow(data[i][0], j));
|
|
2246
|
+
}
|
|
2247
|
+
}
|
|
2248
|
+
var AT = Chalkboard.matr.transpose(A);
|
|
2249
|
+
var B = Chalkboard.matr.new();
|
|
2250
|
+
for(var i = 0; i < data.length; i++) {
|
|
2251
|
+
B.push([data[i][1]]);
|
|
2252
|
+
}
|
|
2253
|
+
var ATA = Chalkboard.matr.mul(AT, A);
|
|
2254
|
+
var ATAI = Chalkboard.matr.invert(ATA);
|
|
2255
|
+
var x = Chalkboard.matr.mul(Chalkboard.matr.mul(ATAI, AT), B);
|
|
2256
|
+
var coeff = [];
|
|
2257
|
+
for(var i = 0; i < x.length; i++) {
|
|
2258
|
+
coeff.push(x[i][0]);
|
|
2259
|
+
}
|
|
2260
|
+
var f = coeff[0].toString() + " + " + coeff[1].toString() + " * x";
|
|
2261
|
+
for(var i = 2; i <= degree; i++) {
|
|
2262
|
+
f += " + " + coeff[i].toString() + " * Math.pow(x, " + i + ")";
|
|
2263
|
+
}
|
|
2264
|
+
return Chalkboard.real.function(f);
|
|
2265
|
+
} else if(type === "power") {
|
|
2266
|
+
var arr = [0, 0, 0, 0];
|
|
2267
|
+
for(var i = 0; i < data.length; i++) {
|
|
2268
|
+
arr[0] += Chalkboard.real.ln(data[i][0]);
|
|
2269
|
+
arr[1] += data[i][1] * Chalkboard.real.ln(data[i][0]);
|
|
2270
|
+
arr[2] += data[i][1];
|
|
2271
|
+
arr[3] += Chalkboard.real.ln(data[i][0]) * Chalkboard.real.ln(data[i][0]);
|
|
2272
|
+
}
|
|
2273
|
+
var a = Chalkboard.E((arr[2] - ((data.length * arr[1] - arr[2] * arr[0]) / (data.length * arr[3] - arr[0] * arr[0])) * arr[0]) / data.length),
|
|
2274
|
+
b = (data.length * arr[1] - arr[2] * arr[0]) / (data.length * arr[3] - arr[0] * arr[0]);
|
|
2275
|
+
return Chalkboard.real.function(a + " * Math.pow(x, " + b + ")");
|
|
2276
|
+
} else if(type === "exponential") {
|
|
2277
|
+
var arr = [0, 0, 0, 0, 0, 0];
|
|
2278
|
+
for(var i = 0; i < data.length; i++) {
|
|
2279
|
+
arr[0] += data[i][0];
|
|
2280
|
+
arr[1] += data[i][1];
|
|
2281
|
+
arr[2] += data[i][0] * data[i][0] * data[i][1];
|
|
2282
|
+
arr[3] += data[i][1] * Chalkboard.real.ln(data[i][1]);
|
|
2283
|
+
arr[4] += data[i][0] & data[i][1] * Chalkboard.real.ln(data[i][1]);
|
|
2284
|
+
arr[5] += data[i][0] * data[i][1];
|
|
2285
|
+
}
|
|
2286
|
+
var a = Chalkboard.E((arr[2] * arr[3] - arr[5] * arr[4]) / (arr[1] * arr[2] - arr[5] * arr[5])),
|
|
2287
|
+
b = (arr[1] * arr[4] - arr[5] * arr[3]) / (arr[1] * arr[2] - arr[5] * arr[5]);
|
|
2288
|
+
return Chalkboard.real.function(a + "* Math.exp(" + b + " * x)");
|
|
2289
|
+
} else if(type === "logarithmic") {
|
|
2290
|
+
var arr = [0, 0, 0, 0];
|
|
2291
|
+
for(var i = 0; i < data.length; i++) {
|
|
2292
|
+
arr[0] += Chalkboard.real.ln(data[i][0]);
|
|
2293
|
+
arr[1] += data[i][1] * Chalkboard.real.ln(data[i][0]);
|
|
2294
|
+
arr[2] += data[i][1];
|
|
2295
|
+
arr[3] += Chalkboard.real.ln(data[i][0]) * Chalkboard.real.ln(data[i][0]);
|
|
2296
|
+
}
|
|
2297
|
+
var a = (arr[2] - ((data.length * arr[1] - arr[2] * arr[0]) / (data.length * arr[3] - arr[0] * arr[0])) * arr[0]) / data.length,
|
|
2298
|
+
b = (data.length * arr[1] - arr[2] * arr[0]) / (data.length * arr[3] - arr[0] * arr[0]);
|
|
2299
|
+
return Chalkboard.real.function(a + " + " + b + " * Math.log(x)");
|
|
2300
|
+
} else {
|
|
2301
|
+
return "TypeError: Parameter \"type\" must be either \"linear\", \"polynomial\", \"power\", \"exponential\", or \"logarithmic\".";
|
|
2302
|
+
}
|
|
2303
|
+
},
|
|
2304
|
+
toVector: function(arr, type, index) {
|
|
2305
|
+
if(index === undefined) { index = 0; }
|
|
1972
2306
|
if(type === "vec2") {
|
|
1973
|
-
return Chalkboard.vec2.new(arr[
|
|
2307
|
+
return Chalkboard.vec2.new(arr[index], arr[index + 1]);
|
|
1974
2308
|
} else if(type === "vec3") {
|
|
1975
|
-
return Chalkboard.vec3.new(arr[
|
|
2309
|
+
return Chalkboard.vec3.new(arr[index], arr[index + 1], arr[index + 2]);
|
|
1976
2310
|
} else if(type === "vec4") {
|
|
1977
|
-
return Chalkboard.vec4.new(arr[
|
|
2311
|
+
return Chalkboard.vec4.new(arr[index], arr[index + 1], arr[index + 2], arr[index + 3]);
|
|
1978
2312
|
} else {
|
|
1979
2313
|
return "TypeError: Parameter \"type\" should be \"vec2\", \"vec3\", or \"vec4\".";
|
|
1980
2314
|
}
|
|
@@ -1995,6 +2329,12 @@ var Chalkboard = {
|
|
|
1995
2329
|
}
|
|
1996
2330
|
return result;
|
|
1997
2331
|
},
|
|
2332
|
+
toTensor: function(arr, size) {
|
|
2333
|
+
if(!Array.isArray(size)) {
|
|
2334
|
+
size = Array.from(arguments).slice(1);
|
|
2335
|
+
}
|
|
2336
|
+
return Chalkboard.tens.resize(arr, size);
|
|
2337
|
+
},
|
|
1998
2338
|
toObject: function(arr) {
|
|
1999
2339
|
var result = {};
|
|
2000
2340
|
for(var i = 0; i < arr.length; i++) {
|
|
@@ -2017,6 +2357,9 @@ var Chalkboard = {
|
|
|
2017
2357
|
return {x: x, y: y, type: "vec2"};
|
|
2018
2358
|
}
|
|
2019
2359
|
},
|
|
2360
|
+
copy: function(vec2) {
|
|
2361
|
+
return Object.create(Object.getPrototypeOf(vec2), Object.getOwnPropertyDescriptors(vec2));
|
|
2362
|
+
},
|
|
2020
2363
|
random: function(inf, sup) {
|
|
2021
2364
|
return Chalkboard.vec2.new(Chalkboard.numb.random(inf, sup), Chalkboard.numb.random(inf, sup));
|
|
2022
2365
|
},
|
|
@@ -2161,6 +2504,9 @@ var Chalkboard = {
|
|
|
2161
2504
|
return {x: x, y: y, z: z, type: "vec3"};
|
|
2162
2505
|
}
|
|
2163
2506
|
},
|
|
2507
|
+
copy: function(vec3) {
|
|
2508
|
+
return Object.create(Object.getPrototypeOf(vec3), Object.getOwnPropertyDescriptors(vec3));
|
|
2509
|
+
},
|
|
2164
2510
|
random: function(inf, sup) {
|
|
2165
2511
|
return Chalkboard.vec3.new(Chalkboard.numb.random(inf, sup), Chalkboard.numb.random(inf, sup), Chalkboard.numb.random(inf, sup));
|
|
2166
2512
|
},
|
|
@@ -2312,6 +2658,9 @@ var Chalkboard = {
|
|
|
2312
2658
|
return {x: x, y: y, z: z, w: w, type: "vec4"};
|
|
2313
2659
|
}
|
|
2314
2660
|
},
|
|
2661
|
+
copy: function(vec4) {
|
|
2662
|
+
return Object.create(Object.getPrototypeOf(vec4), Object.getOwnPropertyDescriptors(vec4));
|
|
2663
|
+
},
|
|
2315
2664
|
random: function(inf, sup) {
|
|
2316
2665
|
return Chalkboard.vec4.new(Chalkboard.numb.random(inf, sup), Chalkboard.numb.random(inf, sup), Chalkboard.numb.random(inf, sup), Chalkboard.numb.random(inf, sup));
|
|
2317
2666
|
},
|
|
@@ -2446,7 +2795,23 @@ var Chalkboard = {
|
|
|
2446
2795
|
},
|
|
2447
2796
|
matr: {
|
|
2448
2797
|
new: function(matrix) {
|
|
2449
|
-
|
|
2798
|
+
if(arguments.length === 0) {
|
|
2799
|
+
return [];
|
|
2800
|
+
} else if(Array.isArray(matrix) && Array.isArray(matrix[0])) {
|
|
2801
|
+
return matrix;
|
|
2802
|
+
} else {
|
|
2803
|
+
return Array.from(arguments);
|
|
2804
|
+
}
|
|
2805
|
+
},
|
|
2806
|
+
copy: function(matr) {
|
|
2807
|
+
var result = Chalkboard.matr.new();
|
|
2808
|
+
for(var i = 0; i < Chalkboard.matr.rows(matr); i++) {
|
|
2809
|
+
result.push([]);
|
|
2810
|
+
for(var j = 0; j < Chalkboard.matr.cols(matr); j++) {
|
|
2811
|
+
result[i].push(matr[i][j]);
|
|
2812
|
+
}
|
|
2813
|
+
}
|
|
2814
|
+
return result;
|
|
2450
2815
|
},
|
|
2451
2816
|
rows: function(matr) {
|
|
2452
2817
|
return matr.length;
|
|
@@ -2454,12 +2819,75 @@ var Chalkboard = {
|
|
|
2454
2819
|
cols: function(matr) {
|
|
2455
2820
|
return matr[0].length;
|
|
2456
2821
|
},
|
|
2457
|
-
|
|
2458
|
-
if(
|
|
2822
|
+
resize: function(matr, rows, cols) {
|
|
2823
|
+
if(cols === undefined) {
|
|
2824
|
+
cols = rows;
|
|
2825
|
+
}
|
|
2826
|
+
var result = Chalkboard.matr.new();
|
|
2827
|
+
var flat = Chalkboard.matr.toArray(matr);
|
|
2828
|
+
var index = 0;
|
|
2829
|
+
for(var i = 0; i < rows; i++) {
|
|
2830
|
+
result.push([]);
|
|
2831
|
+
for(var j = 0; j < cols; j++) {
|
|
2832
|
+
result[i].push(index < flat.length ? flat[index++] : 0);
|
|
2833
|
+
}
|
|
2834
|
+
}
|
|
2835
|
+
return result;
|
|
2836
|
+
},
|
|
2837
|
+
push: function(matr, type, rowORcol, elements) {
|
|
2838
|
+
rowORcol -= 1;
|
|
2839
|
+
if(type === "row") {
|
|
2840
|
+
matr.splice(rowORcol, 0, elements);
|
|
2841
|
+
return matr;
|
|
2842
|
+
} else if(type === "col") {
|
|
2843
|
+
for(var i = 0; i < Chalkboard.matr.rows(matr); i++) {
|
|
2844
|
+
matr[i].splice(rowORcol, 0, elements[i]);
|
|
2845
|
+
}
|
|
2846
|
+
return matr;
|
|
2847
|
+
} else {
|
|
2848
|
+
return "TypeError: Parameter \"type\" must be either \"row\" or \"col\".";
|
|
2849
|
+
}
|
|
2850
|
+
},
|
|
2851
|
+
pull: function(matr, type, rowORcol) {
|
|
2852
|
+
rowORcol -= 1;
|
|
2853
|
+
if(type === "row") {
|
|
2854
|
+
matr.splice(rowORcol, 1);
|
|
2855
|
+
return matr;
|
|
2856
|
+
} else if(type === "col") {
|
|
2857
|
+
for(var i = 0; i < Chalkboard.matr.rows(matr); i++) {
|
|
2858
|
+
matr[i].splice(rowORcol, 1);
|
|
2859
|
+
}
|
|
2860
|
+
return matr;
|
|
2861
|
+
} else {
|
|
2862
|
+
return "TypeError: Parameter \"type\" must be either \"row\" or \"col\".";
|
|
2863
|
+
}
|
|
2864
|
+
},
|
|
2865
|
+
fill: function(element, rows, cols) {
|
|
2866
|
+
if(cols === undefined) {
|
|
2867
|
+
cols = rows;
|
|
2868
|
+
}
|
|
2869
|
+
if(Number.isInteger(rows) && Number.isInteger(cols) && rows > 0 && cols > 0) {
|
|
2870
|
+
var result = Chalkboard.matr.new();
|
|
2871
|
+
for(var i = 0; i < rows; i++) {
|
|
2872
|
+
result.push([]);
|
|
2873
|
+
for(var j = 0; j < cols; j++) {
|
|
2874
|
+
result[i].push(element);
|
|
2875
|
+
}
|
|
2876
|
+
}
|
|
2877
|
+
return result;
|
|
2878
|
+
} else {
|
|
2879
|
+
return undefined;
|
|
2880
|
+
}
|
|
2881
|
+
},
|
|
2882
|
+
empty: function(rows, cols) {
|
|
2883
|
+
if(cols === undefined) {
|
|
2884
|
+
cols = rows;
|
|
2885
|
+
}
|
|
2886
|
+
if(Number.isInteger(rows) && Number.isInteger(cols) && rows > 0 && cols > 0) {
|
|
2459
2887
|
var result = Chalkboard.matr.new();
|
|
2460
|
-
for(var i = 0; i <
|
|
2888
|
+
for(var i = 0; i < rows; i++) {
|
|
2461
2889
|
result.push([]);
|
|
2462
|
-
for(var j = 0; j <
|
|
2890
|
+
for(var j = 0; j < cols; j++) {
|
|
2463
2891
|
result[i].push(null);
|
|
2464
2892
|
}
|
|
2465
2893
|
}
|
|
@@ -2468,11 +2896,11 @@ var Chalkboard = {
|
|
|
2468
2896
|
return undefined;
|
|
2469
2897
|
}
|
|
2470
2898
|
},
|
|
2471
|
-
identity: function(
|
|
2472
|
-
if(Number.isInteger(
|
|
2899
|
+
identity: function(size) {
|
|
2900
|
+
if(Number.isInteger(size) && size > 0) {
|
|
2473
2901
|
var result = Chalkboard.matr.new();
|
|
2474
|
-
for(var i = 0; i <
|
|
2475
|
-
result.push(Array(
|
|
2902
|
+
for(var i = 0; i < size; i++) {
|
|
2903
|
+
result.push(Array(size).fill(0));
|
|
2476
2904
|
result[i][i] = 1;
|
|
2477
2905
|
}
|
|
2478
2906
|
return result;
|
|
@@ -2480,14 +2908,30 @@ var Chalkboard = {
|
|
|
2480
2908
|
return undefined;
|
|
2481
2909
|
}
|
|
2482
2910
|
},
|
|
2483
|
-
|
|
2484
|
-
if(Number.isInteger(
|
|
2485
|
-
|
|
2486
|
-
|
|
2911
|
+
exchange: function(size) {
|
|
2912
|
+
if(Number.isInteger(size) && size > 0) {
|
|
2913
|
+
var result = Chalkboard.matr.fill(0, size, size);
|
|
2914
|
+
for(var i = 0; i < size; i++) {
|
|
2915
|
+
for(var j = 0; j < size; j++) {
|
|
2916
|
+
if(i + j === size - 1) {
|
|
2917
|
+
result[i][j] = 1;
|
|
2918
|
+
}
|
|
2919
|
+
}
|
|
2920
|
+
}
|
|
2921
|
+
return result;
|
|
2922
|
+
} else {
|
|
2923
|
+
return undefined;
|
|
2924
|
+
}
|
|
2925
|
+
},
|
|
2926
|
+
random: function(inf, sup, rows, cols) {
|
|
2927
|
+
if(cols === undefined) {
|
|
2928
|
+
cols = rows;
|
|
2929
|
+
}
|
|
2930
|
+
if(Number.isInteger(rows) && Number.isInteger(cols) && rows > 0 && cols > 0) {
|
|
2487
2931
|
var result = Chalkboard.matr.new();
|
|
2488
|
-
for(var i = 0; i <
|
|
2932
|
+
for(var i = 0; i < rows; i++) {
|
|
2489
2933
|
result.push([]);
|
|
2490
|
-
for(var j = 0; j <
|
|
2934
|
+
for(var j = 0; j < cols; j++) {
|
|
2491
2935
|
result[i].push(Chalkboard.numb.random(inf, sup));
|
|
2492
2936
|
}
|
|
2493
2937
|
}
|
|
@@ -2496,8 +2940,75 @@ var Chalkboard = {
|
|
|
2496
2940
|
return undefined;
|
|
2497
2941
|
}
|
|
2498
2942
|
},
|
|
2943
|
+
shift: function(size, shiftAmount) {
|
|
2944
|
+
shiftAmount = shiftAmount || 1;
|
|
2945
|
+
if(Number.isInteger(size) && size > 0) {
|
|
2946
|
+
var result = Chalkboard.matr.fill(0, size, size);
|
|
2947
|
+
for(var i = 0; i < size; i++) {
|
|
2948
|
+
for(var j = 0; j < size; j++) {
|
|
2949
|
+
result[i][j] = Chalkboard.numb.Kronecker(i + shiftAmount, j);
|
|
2950
|
+
}
|
|
2951
|
+
}
|
|
2952
|
+
return result;
|
|
2953
|
+
} else {
|
|
2954
|
+
return undefined;
|
|
2955
|
+
}
|
|
2956
|
+
},
|
|
2957
|
+
binomial: function(size, type) {
|
|
2958
|
+
type = type || "lower";
|
|
2959
|
+
if(Number.isInteger(size) && size > 0) {
|
|
2960
|
+
var result = Chalkboard.matr.new();
|
|
2961
|
+
for(var i = 0; i < size; i++) {
|
|
2962
|
+
result.push([]);
|
|
2963
|
+
for(var j = 0; j < size; j++) {
|
|
2964
|
+
if(type === "lower") {
|
|
2965
|
+
result[i].push(Chalkboard.numb.binomial(i, j));
|
|
2966
|
+
} else if(type === "upper") {
|
|
2967
|
+
result[i].push(Chalkboard.numb.binomial(j, i));
|
|
2968
|
+
}
|
|
2969
|
+
}
|
|
2970
|
+
}
|
|
2971
|
+
if(type === "symmetric") {
|
|
2972
|
+
return Chalkboard.matr.mul(Chalkboard.matr.binomial(size, "lower"), Chalkboard.matr.binomial(size, "upper"));
|
|
2973
|
+
} else if(type !== "lower" && type !== "upper") {
|
|
2974
|
+
return "TypeError: Parameter \"type\" must be either \"lower\", \"upper\", or \"symmetric\".";
|
|
2975
|
+
} else {
|
|
2976
|
+
return result;
|
|
2977
|
+
}
|
|
2978
|
+
} else {
|
|
2979
|
+
return undefined;
|
|
2980
|
+
}
|
|
2981
|
+
},
|
|
2982
|
+
Hilbert: function(size) {
|
|
2983
|
+
if(Number.isInteger(size) && size > 0) {
|
|
2984
|
+
var result = Chalkboard.matr.new();
|
|
2985
|
+
for(var i = 0; i < size; i++) {
|
|
2986
|
+
result.push([]);
|
|
2987
|
+
for(var j = 0; j < size; j++) {
|
|
2988
|
+
result[i].push(1 / (i + j + 1));
|
|
2989
|
+
}
|
|
2990
|
+
}
|
|
2991
|
+
return result;
|
|
2992
|
+
} else {
|
|
2993
|
+
return undefined;
|
|
2994
|
+
}
|
|
2995
|
+
},
|
|
2996
|
+
Lehmer: function(size) {
|
|
2997
|
+
if(Number.isInteger(size) && size > 0) {
|
|
2998
|
+
var result = Chalkboard.matr.new();
|
|
2999
|
+
for(var i = 0; i < size; i++) {
|
|
3000
|
+
result.push([]);
|
|
3001
|
+
for(var j = 0; j < size; j++) {
|
|
3002
|
+
result[i].push(Math.min(i + 1, j + 1) / Math.max(i + 1, j + 1));
|
|
3003
|
+
}
|
|
3004
|
+
}
|
|
3005
|
+
return result;
|
|
3006
|
+
} else {
|
|
3007
|
+
return undefined;
|
|
3008
|
+
}
|
|
3009
|
+
},
|
|
2499
3010
|
cofactor: function(matr, row, col) {
|
|
2500
|
-
return matr.slice(0, row - 1).concat(matr.slice(row)).map(function
|
|
3011
|
+
return matr.slice(0, row - 1).concat(matr.slice(row)).map(function(row) {
|
|
2501
3012
|
return row.slice(0, col - 1).concat(row.slice(col));
|
|
2502
3013
|
});
|
|
2503
3014
|
},
|
|
@@ -2534,15 +3045,15 @@ var Chalkboard = {
|
|
|
2534
3045
|
}
|
|
2535
3046
|
},
|
|
2536
3047
|
rank: function(matr) {
|
|
2537
|
-
return Chalkboard.matr.reduce(matr).filter(function
|
|
2538
|
-
return row.some(function
|
|
3048
|
+
return Chalkboard.matr.reduce(matr).filter(function(row) {
|
|
3049
|
+
return row.some(function(element) {
|
|
2539
3050
|
return element !== 0;
|
|
2540
3051
|
});
|
|
2541
3052
|
}).length;
|
|
2542
3053
|
},
|
|
2543
3054
|
rowspace: function(matr) {
|
|
2544
|
-
return Chalkboard.matr.reduce(matr).filter(function
|
|
2545
|
-
return row.some(function
|
|
3055
|
+
return Chalkboard.matr.reduce(matr).filter(function(row) {
|
|
3056
|
+
return row.some(function(element) {
|
|
2546
3057
|
return element !== 0;
|
|
2547
3058
|
});
|
|
2548
3059
|
});
|
|
@@ -2551,15 +3062,15 @@ var Chalkboard = {
|
|
|
2551
3062
|
return Chalkboard.matr.transpose(Chalkboard.matr.rowspace(Chalkboard.matr.transpose(matr)));
|
|
2552
3063
|
},
|
|
2553
3064
|
nullspace: function(matr) {
|
|
2554
|
-
var augmented = matr.map(function
|
|
3065
|
+
var augmented = matr.map(function(row) {
|
|
2555
3066
|
return row.slice().concat(Array(Chalkboard.matr.rows(matr)).fill(0));
|
|
2556
3067
|
});
|
|
2557
3068
|
var reduced = Chalkboard.matr.reduce(augmented);
|
|
2558
|
-
return reduced.filter(function
|
|
2559
|
-
return row.slice(0, Chalkboard.matr.rows(matr)).every(function
|
|
3069
|
+
return reduced.filter(function(row) {
|
|
3070
|
+
return row.slice(0, Chalkboard.matr.rows(matr)).every(function(element) {
|
|
2560
3071
|
return element === 0;
|
|
2561
3072
|
});
|
|
2562
|
-
}).map(function
|
|
3073
|
+
}).map(function(row) {
|
|
2563
3074
|
return row.slice(Chalkboard.matr.rows(matr));
|
|
2564
3075
|
});
|
|
2565
3076
|
},
|
|
@@ -2615,6 +3126,78 @@ var Chalkboard = {
|
|
|
2615
3126
|
return undefined;
|
|
2616
3127
|
}
|
|
2617
3128
|
},
|
|
3129
|
+
LUdecomp: function(matr) {
|
|
3130
|
+
if(Chalkboard.matr.rows(matr) === Chalkboard.matr.cols(matr)) {
|
|
3131
|
+
var L = Chalkboard.matr.identity(Chalkboard.matr.rows(matr)),
|
|
3132
|
+
U = Chalkboard.matr.fill(0, Chalkboard.matr.rows(matr));
|
|
3133
|
+
for(var j = 0; j < Chalkboard.matr.cols(matr); j++) {
|
|
3134
|
+
for(var i = 0; i <= j; i++) {
|
|
3135
|
+
var sum = 0;
|
|
3136
|
+
for(var k = 0; k < i; k++) {
|
|
3137
|
+
sum += L[i][k] * U[k][j];
|
|
3138
|
+
}
|
|
3139
|
+
U[i][j] = matr[i][j] - sum;
|
|
3140
|
+
}
|
|
3141
|
+
for(var i = j + 1; i < Chalkboard.matr.rows(matr); i++) {
|
|
3142
|
+
var sum = 0;
|
|
3143
|
+
for(var k = 0; k < j; k++) {
|
|
3144
|
+
sum += L[i][k] * U[k][j];
|
|
3145
|
+
}
|
|
3146
|
+
L[i][j] = (matr[i][j] - sum) / U[j][j];
|
|
3147
|
+
}
|
|
3148
|
+
}
|
|
3149
|
+
return {L: L, U: U};
|
|
3150
|
+
} else {
|
|
3151
|
+
return undefined;
|
|
3152
|
+
}
|
|
3153
|
+
},
|
|
3154
|
+
QRdecomp: function(matr) {
|
|
3155
|
+
var Q = Chalkboard.matr.identity(Chalkboard.matr.rows(matr)),
|
|
3156
|
+
R = Chalkboard.matr.copy(matr);
|
|
3157
|
+
for(var j = 0; j < Math.min(Chalkboard.matr.rows(matr), Chalkboard.matr.cols(matr)) - (Chalkboard.matr.rows(matr) > Chalkboard.matr.cols(matr) ? 0 : 1); j++) {
|
|
3158
|
+
var norm = 0;
|
|
3159
|
+
for(var i = j; i < Chalkboard.matr.rows(matr); i++) {
|
|
3160
|
+
norm += R[i][j] * R[i][j];
|
|
3161
|
+
}
|
|
3162
|
+
norm = Chalkboard.real.sqrt(norm);
|
|
3163
|
+
var v = [];
|
|
3164
|
+
v[0] = norm - R[j][j];
|
|
3165
|
+
var normalizer = v[0] * v[0];
|
|
3166
|
+
for(var i = 1; i < Chalkboard.matr.rows(matr) - j; i++) {
|
|
3167
|
+
v[i] = -R[i + j][j];
|
|
3168
|
+
normalizer += v[i] * v[i];
|
|
3169
|
+
}
|
|
3170
|
+
normalizer = 1 / Chalkboard.real.sqrt(normalizer);
|
|
3171
|
+
for(var i = 0; i < v.length; i++) {
|
|
3172
|
+
v[i] *= normalizer;
|
|
3173
|
+
}
|
|
3174
|
+
R[j][j] = norm;
|
|
3175
|
+
for(var i = j + 1; i < Chalkboard.matr.rows(R); i++) {
|
|
3176
|
+
R[i][j] = 0;
|
|
3177
|
+
}
|
|
3178
|
+
for(var k = j + 1; k < Chalkboard.matr.cols(R); k++) {
|
|
3179
|
+
var dot = 0;
|
|
3180
|
+
for(var i = 0; i < v.length; i++) {
|
|
3181
|
+
dot += v[i] * R[i + j][k];
|
|
3182
|
+
}
|
|
3183
|
+
dot *= 2;
|
|
3184
|
+
for(var i = 0; i < v.length; i++) {
|
|
3185
|
+
R[i + j][k] -= dot * v[i];
|
|
3186
|
+
}
|
|
3187
|
+
}
|
|
3188
|
+
for(var k = 0; k < Chalkboard.matr.cols(Q); k++) {
|
|
3189
|
+
var dot = 0;
|
|
3190
|
+
for(var i = 0; i < v.length; i++) {
|
|
3191
|
+
dot += v[i] * Q[k][i + j];
|
|
3192
|
+
}
|
|
3193
|
+
dot *= 2;
|
|
3194
|
+
for(var i = 0; i < v.length; i++) {
|
|
3195
|
+
Q[k][i + j] -= dot * v[i];
|
|
3196
|
+
}
|
|
3197
|
+
}
|
|
3198
|
+
}
|
|
3199
|
+
return {Q: Q, R: R};
|
|
3200
|
+
},
|
|
2618
3201
|
zero: function(matr) {
|
|
2619
3202
|
var result = Chalkboard.matr.new();
|
|
2620
3203
|
for(var i = 0; i < Chalkboard.matr.rows(matr); i++) {
|
|
@@ -2715,6 +3298,28 @@ var Chalkboard = {
|
|
|
2715
3298
|
}
|
|
2716
3299
|
return result;
|
|
2717
3300
|
},
|
|
3301
|
+
concat: function(matr_1, matr_2, type) {
|
|
3302
|
+
type = type || "row";
|
|
3303
|
+
if(type === "row") {
|
|
3304
|
+
if(Chalkboard.matr.rows(matr_1) === Chalkboard.matr.rows(matr_2)) {
|
|
3305
|
+
return Chalkboard.matr.new(matr_1.concat(matr_2));
|
|
3306
|
+
} else {
|
|
3307
|
+
return undefined;
|
|
3308
|
+
}
|
|
3309
|
+
} else if(type === "col") {
|
|
3310
|
+
if(Chalkboard.matr.cols(matr_1) === Chalkboard.matr.cols(matr_2)) {
|
|
3311
|
+
var result = Chalkboard.matr.new();
|
|
3312
|
+
for(var i = 0; i < Chalkboard.matr.rows(matr_1); i++) {
|
|
3313
|
+
result.push(matr_1[i].concat(matr_2[i]));
|
|
3314
|
+
}
|
|
3315
|
+
return result;
|
|
3316
|
+
} else {
|
|
3317
|
+
return undefined;
|
|
3318
|
+
}
|
|
3319
|
+
} else {
|
|
3320
|
+
return "TypeError: Parameter \"type\" should be either \"row\" or \"col\".";
|
|
3321
|
+
}
|
|
3322
|
+
},
|
|
2718
3323
|
add: function(matr_1, matr_2) {
|
|
2719
3324
|
if(Chalkboard.matr.rows(matr_1) === Chalkboard.matr.rows(matr_2) && Chalkboard.matr.cols(matr_1) === Chalkboard.matr.cols(matr_2)) {
|
|
2720
3325
|
var result = Chalkboard.matr.new();
|
|
@@ -2760,6 +3365,29 @@ var Chalkboard = {
|
|
|
2760
3365
|
return undefined;
|
|
2761
3366
|
}
|
|
2762
3367
|
},
|
|
3368
|
+
mulvec: function(matr, vec) {
|
|
3369
|
+
if(vec.type === "vec2") {
|
|
3370
|
+
if(Chalkboard.matr.rows(matr) === 2) {
|
|
3371
|
+
return Chalkboard.matr.toVector(Chalkboard.matr.mul(matr, Chalkboard.vec2.toMatrix(vec)), "vec2");
|
|
3372
|
+
} else {
|
|
3373
|
+
return Chalkboard.matr.mul(matr, Chalkboard.vec2.toMatrix(vec));
|
|
3374
|
+
}
|
|
3375
|
+
} else if(vec.type === "vec3") {
|
|
3376
|
+
if(Chalkboard.matr.rows(matr) === 3) {
|
|
3377
|
+
return Chalkboard.matr.toVector(Chalkboard.matr.mul(matr, Chalkboard.vec3.toMatrix(vec)), "vec3");
|
|
3378
|
+
} else {
|
|
3379
|
+
return Chalkboard.matr.mul(matr, Chalkboard.vec2.toMatrix(vec));
|
|
3380
|
+
}
|
|
3381
|
+
} else if(vec.type === "vec4") {
|
|
3382
|
+
if(Chalkboard.matr.rows(matr) === 4) {
|
|
3383
|
+
return Chalkboard.matr.toVector(Chalkboard.matr.mul(matr, Chalkboard.vec4.toMatrix(vec)), "vec4");
|
|
3384
|
+
} else {
|
|
3385
|
+
return Chalkboard.matr.mul(matr, Chalkboard.vec2.toMatrix(vec));
|
|
3386
|
+
}
|
|
3387
|
+
} else {
|
|
3388
|
+
return "TypeError: Parameter \"vec\" should be \"vec2\", \"vec3\", or \"vec4\".";
|
|
3389
|
+
}
|
|
3390
|
+
},
|
|
2763
3391
|
pow: function(matr, num) {
|
|
2764
3392
|
if(Chalkboard.matr.rows(matr) === Chalkboard.matr.cols(matr)) {
|
|
2765
3393
|
if(Number.isInteger(num) && num >= 0) {
|
|
@@ -2779,6 +3407,29 @@ var Chalkboard = {
|
|
|
2779
3407
|
return undefined;
|
|
2780
3408
|
}
|
|
2781
3409
|
},
|
|
3410
|
+
addKronecker: function(matr_1, matr_2) {
|
|
3411
|
+
if(Chalkboard.matr.rows(matr_1) === Chalkboard.matr.cols(matr_1) && Chalkboard.matr.rows(matr_2) === Chalkboard.matr.cols(matr_2)) {
|
|
3412
|
+
return Chalkboard.matr.add(Chalkboard.matr.mulKronecker(matr_1, Chalkboard.matr.identity(Chalkboard.matr.rows(matr_1))), Chalkboard.matr.mulKronecker(Chalkboard.matr.identity(Chalkboard.matr.rows(matr_2)), matr_2));
|
|
3413
|
+
} else {
|
|
3414
|
+
return undefined;
|
|
3415
|
+
}
|
|
3416
|
+
},
|
|
3417
|
+
mulKronecker: function(matr_1, matr_2) {
|
|
3418
|
+
var result = Chalkboard.matr.new();
|
|
3419
|
+
for(var i = 0; i < Chalkboard.matr.rows(matr_1); i++) {
|
|
3420
|
+
for(var j = 0; j < Chalkboard.matr.cols(matr_1); j++) {
|
|
3421
|
+
for(var k = 0; k < Chalkboard.matr.rows(matr_2); k++) {
|
|
3422
|
+
for(var l = 0; l < Chalkboard.matr.cols(matr_2); l++) {
|
|
3423
|
+
if(!result[i * Chalkboard.matr.rows(matr_2) + k]) {
|
|
3424
|
+
result[i * Chalkboard.matr.rows(matr_2) + k] = [];
|
|
3425
|
+
}
|
|
3426
|
+
result[i * Chalkboard.matr.rows(matr_2) + k][j * Chalkboard.matr.cols(matr_2) + l] = matr_1[i][j] * matr_2[k][l];
|
|
3427
|
+
}
|
|
3428
|
+
}
|
|
3429
|
+
}
|
|
3430
|
+
}
|
|
3431
|
+
return result;
|
|
3432
|
+
},
|
|
2782
3433
|
reduce: function(matr) {
|
|
2783
3434
|
var lead = 0;
|
|
2784
3435
|
for(var row = 0; row < Chalkboard.matr.rows(matr); row++) {
|
|
@@ -2862,6 +3513,12 @@ var Chalkboard = {
|
|
|
2862
3513
|
return "TypeError: Parameter \"vec\" should be \"vec2\", \"vec3\", or \"vec4\".";
|
|
2863
3514
|
}
|
|
2864
3515
|
},
|
|
3516
|
+
toTensor: function(matr, size) {
|
|
3517
|
+
if(!Array.isArray(size)) {
|
|
3518
|
+
size = Array.from(arguments).slice(1);
|
|
3519
|
+
}
|
|
3520
|
+
return Chalkboard.tens.resize(matr, size);
|
|
3521
|
+
},
|
|
2865
3522
|
toArray: function(matr) {
|
|
2866
3523
|
var result = [];
|
|
2867
3524
|
for(var i = 0; i < Chalkboard.matr.rows(matr); i++) {
|
|
@@ -2871,6 +3528,16 @@ var Chalkboard = {
|
|
|
2871
3528
|
}
|
|
2872
3529
|
return result;
|
|
2873
3530
|
},
|
|
3531
|
+
toObject: function(matr) {
|
|
3532
|
+
var result = {};
|
|
3533
|
+
for(var i = 0; i < Chalkboard.matr.rows(matr); i++) {
|
|
3534
|
+
result["i" + (i + 1)] = {};
|
|
3535
|
+
for(var j = 0; j < Chalkboard.matr.cols(matr); j++) {
|
|
3536
|
+
result["i" + (i + 1)]["j" + (j + 1)] = matr[i][j];
|
|
3537
|
+
}
|
|
3538
|
+
}
|
|
3539
|
+
return result;
|
|
3540
|
+
},
|
|
2874
3541
|
toString: function(matr) {
|
|
2875
3542
|
var result = "";
|
|
2876
3543
|
for(var i = 0; i < Chalkboard.matr.rows(matr); i++) {
|
|
@@ -2882,18 +3549,369 @@ var Chalkboard = {
|
|
|
2882
3549
|
}
|
|
2883
3550
|
return result;
|
|
2884
3551
|
},
|
|
2885
|
-
|
|
2886
|
-
|
|
2887
|
-
|
|
2888
|
-
|
|
2889
|
-
|
|
2890
|
-
|
|
3552
|
+
print: function(matr) {
|
|
3553
|
+
console.log(Chalkboard.matr.toString(matr));
|
|
3554
|
+
}
|
|
3555
|
+
},
|
|
3556
|
+
tens: {
|
|
3557
|
+
new: function(tensor) {
|
|
3558
|
+
if(arguments.length === 0) {
|
|
3559
|
+
return [];
|
|
3560
|
+
} else if(arguments.length === 1 && Array.isArray(arguments[0])) {
|
|
3561
|
+
tensor = arguments[0];
|
|
3562
|
+
} else {
|
|
3563
|
+
tensor = Array.from(arguments);
|
|
3564
|
+
}
|
|
3565
|
+
var newNDArray = function(arr) {
|
|
3566
|
+
return arr.map(function(subarr) {
|
|
3567
|
+
if(Array.isArray(subarr)) {
|
|
3568
|
+
return newNDArray(subarr);
|
|
3569
|
+
} else {
|
|
3570
|
+
return subarr;
|
|
3571
|
+
}
|
|
3572
|
+
});
|
|
3573
|
+
};
|
|
3574
|
+
return newNDArray(tensor);
|
|
3575
|
+
},
|
|
3576
|
+
copy: function(tens) {
|
|
3577
|
+
if(Array.isArray(tens)) {
|
|
3578
|
+
var result = Chalkboard.tens.new();
|
|
3579
|
+
for(var i = 0; i < tens.length; i++) {
|
|
3580
|
+
result[i] = Chalkboard.tens.copy(tens[i]);
|
|
2891
3581
|
}
|
|
3582
|
+
return result;
|
|
3583
|
+
} else {
|
|
3584
|
+
return tens;
|
|
2892
3585
|
}
|
|
3586
|
+
},
|
|
3587
|
+
rank: function(tens) {
|
|
3588
|
+
if(Array.isArray(tens)) {
|
|
3589
|
+
var result = 0;
|
|
3590
|
+
for(var i = 0; i < tens.length; i++) {
|
|
3591
|
+
result = Math.max(result, Chalkboard.tens.rank(tens[i]));
|
|
3592
|
+
}
|
|
3593
|
+
return result + 1;
|
|
3594
|
+
} else {
|
|
3595
|
+
return 0;
|
|
3596
|
+
}
|
|
3597
|
+
},
|
|
3598
|
+
size: function(tens) {
|
|
3599
|
+
if(Array.isArray(tens)) {
|
|
3600
|
+
var result = [tens.length];
|
|
3601
|
+
if(Array.isArray(tens[0])) {
|
|
3602
|
+
result = result.concat(Chalkboard.tens.size(tens[0]));
|
|
3603
|
+
}
|
|
3604
|
+
return result;
|
|
3605
|
+
} else {
|
|
3606
|
+
return [];
|
|
3607
|
+
}
|
|
3608
|
+
},
|
|
3609
|
+
resize: function(tens, size) {
|
|
3610
|
+
if(!Array.isArray(size)) {
|
|
3611
|
+
size = Array.from(arguments).slice(1);
|
|
3612
|
+
}
|
|
3613
|
+
var result = Chalkboard.tens.fill(0, size);
|
|
3614
|
+
var refill = function(arr1, arr2) {
|
|
3615
|
+
for(var i = 0; i < arr2.length; i++) {
|
|
3616
|
+
if(Array.isArray(arr2[i])) {
|
|
3617
|
+
refill(arr1, arr2[i]);
|
|
3618
|
+
} else {
|
|
3619
|
+
arr2[i] = arr1.length > 0 ? arr1.shift() : 0;
|
|
3620
|
+
}
|
|
3621
|
+
}
|
|
3622
|
+
};
|
|
3623
|
+
refill(Chalkboard.tens.toArray(tens), result);
|
|
2893
3624
|
return result;
|
|
2894
3625
|
},
|
|
2895
|
-
|
|
2896
|
-
|
|
3626
|
+
push: function(tens, rank, index, elements) {
|
|
3627
|
+
if(rank === 0) {
|
|
3628
|
+
tens.splice(index, 0, elements);
|
|
3629
|
+
return tens;
|
|
3630
|
+
} else {
|
|
3631
|
+
for(var i = 0; i < tens.length; i++) {
|
|
3632
|
+
Chalkboard.tens.push(tens[i], rank - 1, index, elements[i]);
|
|
3633
|
+
}
|
|
3634
|
+
return tens;
|
|
3635
|
+
}
|
|
3636
|
+
},
|
|
3637
|
+
pull: function(tens, rank, index) {
|
|
3638
|
+
if(rank === 0) {
|
|
3639
|
+
tens.splice(index, 1);
|
|
3640
|
+
return tens;
|
|
3641
|
+
} else {
|
|
3642
|
+
for(var i = 0; i < tens.length; i++) {
|
|
3643
|
+
Chalkboard.tens.pull(tens[i], rank - 1, index);
|
|
3644
|
+
}
|
|
3645
|
+
return tens;
|
|
3646
|
+
}
|
|
3647
|
+
},
|
|
3648
|
+
fill: function(element, size) {
|
|
3649
|
+
if(!Array.isArray(size)) {
|
|
3650
|
+
size = Array.from(arguments).slice(1);
|
|
3651
|
+
}
|
|
3652
|
+
var newNDArray = function(size) {
|
|
3653
|
+
if(size.length === 0) {
|
|
3654
|
+
return element;
|
|
3655
|
+
}
|
|
3656
|
+
var curr = size[0];
|
|
3657
|
+
var rest = size.slice(1);
|
|
3658
|
+
var result = [];
|
|
3659
|
+
for(var i = 0; i < curr; i++) {
|
|
3660
|
+
result[i] = newNDArray(rest);
|
|
3661
|
+
}
|
|
3662
|
+
return result;
|
|
3663
|
+
}
|
|
3664
|
+
return newNDArray(size);
|
|
3665
|
+
},
|
|
3666
|
+
empty: function(size) {
|
|
3667
|
+
if(!Array.isArray(size)) {
|
|
3668
|
+
size = Array.from(arguments);
|
|
3669
|
+
}
|
|
3670
|
+
var newNDArray = function(size) {
|
|
3671
|
+
if(size.length === 0) {
|
|
3672
|
+
return null;
|
|
3673
|
+
}
|
|
3674
|
+
var curr = size[0];
|
|
3675
|
+
var rest = size.slice(1);
|
|
3676
|
+
var result = [];
|
|
3677
|
+
for(var i = 0; i < curr; i++) {
|
|
3678
|
+
result[i] = newNDArray(rest);
|
|
3679
|
+
}
|
|
3680
|
+
return result;
|
|
3681
|
+
}
|
|
3682
|
+
return newNDArray(size);
|
|
3683
|
+
},
|
|
3684
|
+
random: function(inf, sup, size) {
|
|
3685
|
+
if(!Array.isArray(size)) {
|
|
3686
|
+
size = Array.from(arguments).slice(2);
|
|
3687
|
+
}
|
|
3688
|
+
var newNDArray = function(size) {
|
|
3689
|
+
if(size.length === 0) {
|
|
3690
|
+
return Chalkboard.numb.random(inf, sup);
|
|
3691
|
+
}
|
|
3692
|
+
var curr = size[0];
|
|
3693
|
+
var rest = size.slice(1);
|
|
3694
|
+
var result = [];
|
|
3695
|
+
for(var i = 0; i < curr; i++) {
|
|
3696
|
+
result[i] = newNDArray(rest);
|
|
3697
|
+
}
|
|
3698
|
+
return result;
|
|
3699
|
+
}
|
|
3700
|
+
return newNDArray(size);
|
|
3701
|
+
},
|
|
3702
|
+
contract: function(tens) {
|
|
3703
|
+
if(Chalkboard.tens.rank(tens) > 2) {
|
|
3704
|
+
return Chalkboard.tens.resize(tens, Chalkboard.tens.size(tens)[0], Chalkboard.tens.size(tens).slice(1).reduce(function(a, b) { return a * b; }) / Chalkboard.tens.size(tens)[0]);
|
|
3705
|
+
} else if(Chalkboard.tens.rank(tens) === 2) {
|
|
3706
|
+
return Chalkboard.matr.trace(tens);
|
|
3707
|
+
}
|
|
3708
|
+
},
|
|
3709
|
+
transpose: function(tens) {
|
|
3710
|
+
return Chalkboard.tens.resize(tens, Chalkboard.tens.size(tens).reverse());
|
|
3711
|
+
},
|
|
3712
|
+
zero: function(tens) {
|
|
3713
|
+
var result = Chalkboard.tens.new();
|
|
3714
|
+
if(Array.isArray(tens)) {
|
|
3715
|
+
for(var i = 0; i < tens.length; i++) {
|
|
3716
|
+
result[i] = Chalkboard.tens.zero(tens[i]);
|
|
3717
|
+
}
|
|
3718
|
+
return result;
|
|
3719
|
+
} else {
|
|
3720
|
+
return 0;
|
|
3721
|
+
}
|
|
3722
|
+
},
|
|
3723
|
+
negate: function(tens) {
|
|
3724
|
+
var result = Chalkboard.tens.new();
|
|
3725
|
+
if(Array.isArray(tens)) {
|
|
3726
|
+
for(var i = 0; i < tens.length; i++) {
|
|
3727
|
+
result[i] = Chalkboard.tens.negate(tens[i]);
|
|
3728
|
+
}
|
|
3729
|
+
return result;
|
|
3730
|
+
} else {
|
|
3731
|
+
return -tens;
|
|
3732
|
+
}
|
|
3733
|
+
},
|
|
3734
|
+
reciprocate: function(tens) {
|
|
3735
|
+
var result = Chalkboard.tens.new();
|
|
3736
|
+
if(Array.isArray(tens)) {
|
|
3737
|
+
for(var i = 0; i < tens.length; i++) {
|
|
3738
|
+
result[i] = Chalkboard.tens.reciprocate(tens[i]);
|
|
3739
|
+
}
|
|
3740
|
+
return result;
|
|
3741
|
+
} else {
|
|
3742
|
+
return 1 / tens;
|
|
3743
|
+
}
|
|
3744
|
+
},
|
|
3745
|
+
absolute: function(tens) {
|
|
3746
|
+
var result = Chalkboard.tens.new();
|
|
3747
|
+
if(Array.isArray(tens)) {
|
|
3748
|
+
for(var i = 0; i < tens.length; i++) {
|
|
3749
|
+
result[i] = Chalkboard.tens.absolute(tens[i]);
|
|
3750
|
+
}
|
|
3751
|
+
return result;
|
|
3752
|
+
} else {
|
|
3753
|
+
return Math.abs(tens);
|
|
3754
|
+
}
|
|
3755
|
+
},
|
|
3756
|
+
round: function(tens) {
|
|
3757
|
+
var result = Chalkboard.tens.new();
|
|
3758
|
+
if(Array.isArray(tens)) {
|
|
3759
|
+
for(var i = 0; i < tens.length; i++) {
|
|
3760
|
+
result[i] = Chalkboard.tens.round(tens[i]);
|
|
3761
|
+
}
|
|
3762
|
+
return result;
|
|
3763
|
+
} else {
|
|
3764
|
+
return Math.round(tens);
|
|
3765
|
+
}
|
|
3766
|
+
},
|
|
3767
|
+
scl: function(tens, num) {
|
|
3768
|
+
var result = Chalkboard.tens.new();
|
|
3769
|
+
if(Array.isArray(tens)) {
|
|
3770
|
+
for(var i = 0; i < tens.length; i++) {
|
|
3771
|
+
result[i] = Chalkboard.tens.scl(tens[i], num);
|
|
3772
|
+
}
|
|
3773
|
+
return result;
|
|
3774
|
+
} else {
|
|
3775
|
+
return tens * num;
|
|
3776
|
+
}
|
|
3777
|
+
},
|
|
3778
|
+
constrain: function(tens, range) {
|
|
3779
|
+
var result = Chalkboard.tens.new();
|
|
3780
|
+
if(Array.isArray(tens)) {
|
|
3781
|
+
for(var i = 0; i < tens.length; i++) {
|
|
3782
|
+
result[i] = Chalkboard.tens.constrain(tens[i], range);
|
|
3783
|
+
}
|
|
3784
|
+
return result;
|
|
3785
|
+
} else {
|
|
3786
|
+
return Chalkboard.numb.constrain(tens, range);
|
|
3787
|
+
}
|
|
3788
|
+
},
|
|
3789
|
+
concat: function(tens_1, tens_2, rank) {
|
|
3790
|
+
rank = rank || 1;
|
|
3791
|
+
var concatAtRank = function(arr1, arr2, currentRank) {
|
|
3792
|
+
if(currentRank === rank) {
|
|
3793
|
+
return Chalkboard.tens.new(arr1.concat(arr2));
|
|
3794
|
+
}
|
|
3795
|
+
return arr1.map(function(element, index) {
|
|
3796
|
+
return concatAtRank(element, arr2[index], currentRank);
|
|
3797
|
+
});
|
|
3798
|
+
}
|
|
3799
|
+
return concatAtRank(tens_1, tens_2, 1);
|
|
3800
|
+
},
|
|
3801
|
+
add: function(tens_1, tens_2) {
|
|
3802
|
+
var result = Chalkboard.tens.new();
|
|
3803
|
+
if(Array.isArray(tens_1) && Array.isArray(tens_2)) {
|
|
3804
|
+
for(var i = 0; i < Math.max(tens_1.length, tens_2.length); i++) {
|
|
3805
|
+
result[i] = Chalkboard.tens.add(tens_1[i] !== undefined ? tens_1[i] : 0, tens_2[i] !== undefined ? tens_2[i] : 0);
|
|
3806
|
+
}
|
|
3807
|
+
return result;
|
|
3808
|
+
} else {
|
|
3809
|
+
return tens_1 + tens_2;
|
|
3810
|
+
}
|
|
3811
|
+
},
|
|
3812
|
+
sub: function(tens_1, tens_2) {
|
|
3813
|
+
var result = Chalkboard.tens.new();
|
|
3814
|
+
if(Array.isArray(tens_1) && Array.isArray(tens_2)) {
|
|
3815
|
+
for(var i = 0; i < Math.max(tens_1.length, tens_2.length); i++) {
|
|
3816
|
+
result[i] = Chalkboard.tens.sub(tens_1[i] !== undefined ? tens_1[i] : 0, tens_2[i] !== undefined ? tens_2[i] : 0);
|
|
3817
|
+
}
|
|
3818
|
+
return result;
|
|
3819
|
+
} else {
|
|
3820
|
+
return tens_1 - tens_2;
|
|
3821
|
+
}
|
|
3822
|
+
},
|
|
3823
|
+
mul: function(tens_1, tens_2) {
|
|
3824
|
+
var result = Chalkboard.tens.new();
|
|
3825
|
+
if(Array.isArray(tens_1) && Array.isArray(tens_2)) {
|
|
3826
|
+
for(var i = 0; i < tens_1.length; i++) {
|
|
3827
|
+
var subarr = Chalkboard.tens.new();
|
|
3828
|
+
for(var j = 0; j < tens_2.length; j++) {
|
|
3829
|
+
subarr[j] = Chalkboard.tens.mul(tens_1[i], tens_2[j]);
|
|
3830
|
+
}
|
|
3831
|
+
result.push(subarr);
|
|
3832
|
+
}
|
|
3833
|
+
return result;
|
|
3834
|
+
} else {
|
|
3835
|
+
return tens_1 * tens_2;
|
|
3836
|
+
}
|
|
3837
|
+
},
|
|
3838
|
+
toVector: function(tens, type, index) {
|
|
3839
|
+
if(index === undefined) { index = 0; }
|
|
3840
|
+
var arr = Chalkboard.tens.toArray(tens);
|
|
3841
|
+
if(type === "vec2") {
|
|
3842
|
+
return Chalkboard.vec2.new(arr[index], arr[index + 1]);
|
|
3843
|
+
} else if(type === "vec3") {
|
|
3844
|
+
return Chalkboard.vec3.new(arr[index], arr[index + 1], arr[index + 2]);
|
|
3845
|
+
} else if(type === "vec4") {
|
|
3846
|
+
return Chalkboard.vec4.new(arr[index], arr[index + 1], arr[index + 2], arr[index + 3]);
|
|
3847
|
+
} else {
|
|
3848
|
+
return "TypeError: Parameter \"type\" should be \"vec2\", \"vec3\", or \"vec4\".";
|
|
3849
|
+
}
|
|
3850
|
+
},
|
|
3851
|
+
toMatrix: function(tens) {
|
|
3852
|
+
var result = Chalkboard.matr.new();
|
|
3853
|
+
var flatten = function(tens, result) {
|
|
3854
|
+
for(var i = 0; i < tens.length; i++) {
|
|
3855
|
+
if(Array.isArray(tens[i])) {
|
|
3856
|
+
flatten(tens[i], result);
|
|
3857
|
+
} else {
|
|
3858
|
+
result.push(tens[i]);
|
|
3859
|
+
}
|
|
3860
|
+
}
|
|
3861
|
+
}
|
|
3862
|
+
var matr = Chalkboard.matr.new();
|
|
3863
|
+
flatten(tens, matr);
|
|
3864
|
+
var rows = tens.length || 1;
|
|
3865
|
+
for(var j = 0; j < rows; j++) {
|
|
3866
|
+
result.push(matr.slice(j * matr.length / rows, (j + 1) * matr.length / rows));
|
|
3867
|
+
}
|
|
3868
|
+
return result;
|
|
3869
|
+
},
|
|
3870
|
+
toArray: function(tens) {
|
|
3871
|
+
var result = [];
|
|
3872
|
+
var flatten = function(tens) {
|
|
3873
|
+
for(var i = 0; i < tens.length; i++) {
|
|
3874
|
+
if(Array.isArray(tens[i])) {
|
|
3875
|
+
flatten(tens[i]);
|
|
3876
|
+
} else {
|
|
3877
|
+
result.push(tens[i]);
|
|
3878
|
+
}
|
|
3879
|
+
}
|
|
3880
|
+
}
|
|
3881
|
+
flatten(tens);
|
|
3882
|
+
return result;
|
|
3883
|
+
},
|
|
3884
|
+
toObject: function(tens) {
|
|
3885
|
+
if(Array.isArray(tens)) {
|
|
3886
|
+
var result = {};
|
|
3887
|
+
for(var i = 0; i < tens.length; i++) {
|
|
3888
|
+
result["_" + (i + 1)] = Chalkboard.tens.toObject(tens[i]);
|
|
3889
|
+
}
|
|
3890
|
+
return result;
|
|
3891
|
+
} else {
|
|
3892
|
+
return tens;
|
|
3893
|
+
}
|
|
3894
|
+
},
|
|
3895
|
+
toString: function(tens, indentation) {
|
|
3896
|
+
if(indentation === undefined) { indentation = 0; }
|
|
3897
|
+
if(Array.isArray(tens[0])) {
|
|
3898
|
+
var result = "\t".repeat(indentation) + "[\n";
|
|
3899
|
+
for(var i = 0; i < tens.length; i++) {
|
|
3900
|
+
result += Chalkboard.tens.toString(tens[i], indentation + 1);
|
|
3901
|
+
}
|
|
3902
|
+
result += "\t".repeat(indentation) + "]\n";
|
|
3903
|
+
return result;
|
|
3904
|
+
} else {
|
|
3905
|
+
var result = "\t".repeat(indentation) + "[ ";
|
|
3906
|
+
for(var i = 0; i < tens.length; i++) {
|
|
3907
|
+
result += tens[i].toString() + " ";
|
|
3908
|
+
}
|
|
3909
|
+
result += "]\n";
|
|
3910
|
+
return result;
|
|
3911
|
+
}
|
|
3912
|
+
},
|
|
3913
|
+
print: function(tens) {
|
|
3914
|
+
return console.log(Chalkboard.tens.toString(tens));
|
|
2897
3915
|
}
|
|
2898
3916
|
},
|
|
2899
3917
|
calc: {
|
|
@@ -2931,6 +3949,9 @@ var Chalkboard = {
|
|
|
2931
3949
|
if(func.type === "expl") {
|
|
2932
3950
|
var f = Chalkboard.real.parse("x => " + func.definition);
|
|
2933
3951
|
return (f(val + h) - f(val)) / h;
|
|
3952
|
+
} else if(func.type === "inve") {
|
|
3953
|
+
var f = Chalkboard.real.parse("y => " + func.definition);
|
|
3954
|
+
return (f(val + h) - f(val)) / h;
|
|
2934
3955
|
} else if(func.type === "pola") {
|
|
2935
3956
|
var r = Chalkboard.real.parse("O => " + func.definition);
|
|
2936
3957
|
return (r(val + h) - r(val)) / h;
|
|
@@ -2946,7 +3967,7 @@ var Chalkboard = {
|
|
|
2946
3967
|
return Chalkboard.vec3.new((x(val + h) - x(val)) / h, (y(val + h) - y(val)) / h, (z(val + h) - z(val)) / h);
|
|
2947
3968
|
}
|
|
2948
3969
|
} else {
|
|
2949
|
-
return "TypeError: Parameter \"func\" must be of type \"expl\", \"pola\", or \"curv\".";
|
|
3970
|
+
return "TypeError: Parameter \"func\" must be of type \"expl\", \"inve\", \"pola\", or \"curv\".";
|
|
2950
3971
|
}
|
|
2951
3972
|
},
|
|
2952
3973
|
d2fdx2: function(func, val) {
|
|
@@ -2954,6 +3975,9 @@ var Chalkboard = {
|
|
|
2954
3975
|
if(func.type === "expl") {
|
|
2955
3976
|
var f = Chalkboard.real.parse("x => " + func.definition);
|
|
2956
3977
|
return (f(val + h) - 2 * f(val) + f(val - h)) / (h * h);
|
|
3978
|
+
} else if(func.type === "inve") {
|
|
3979
|
+
var f = Chalkboard.real.parse("y => " + func.definition);
|
|
3980
|
+
return (f(val + h) - 2 * f(val) + f(val - h)) / (h * h);
|
|
2957
3981
|
} else if(func.type === "pola") {
|
|
2958
3982
|
var r = Chalkboard.real.parse("O => " + func.definition);
|
|
2959
3983
|
return (r(val + h) - 2 * r(val) + r(val - h)) / (h * h);
|
|
@@ -2969,7 +3993,7 @@ var Chalkboard = {
|
|
|
2969
3993
|
return Chalkboard.vec3.new((x(val + h) - 2 * x(val) + x(val - h)) / (h * h), (y(val + h) - 2 * y(val) + y(val - h)) / (h * h), (z(val + h) - 2 * z(val) + z(val - h)) / (h * h));
|
|
2970
3994
|
}
|
|
2971
3995
|
} else {
|
|
2972
|
-
return "TypeError: Parameter \"func\" must be of type \"expl\", \"pola\", or \"curv\".";
|
|
3996
|
+
return "TypeError: Parameter \"func\" must be of type \"expl\", \"inve\", \"pola\", or \"curv\".";
|
|
2973
3997
|
}
|
|
2974
3998
|
},
|
|
2975
3999
|
tangent: function(func, val) {
|
|
@@ -3224,7 +4248,7 @@ var Chalkboard = {
|
|
|
3224
4248
|
return "TypeError: Parameter \"func\" must be of type \"comp\".";
|
|
3225
4249
|
}
|
|
3226
4250
|
},
|
|
3227
|
-
|
|
4251
|
+
d2fdz2: function(func, comp) {
|
|
3228
4252
|
var h = 0.00001;
|
|
3229
4253
|
if(func.type === "comp") {
|
|
3230
4254
|
var u = Chalkboard.comp.parse("(a, b) => " + func.definition[0]),
|
|
@@ -3238,59 +4262,61 @@ var Chalkboard = {
|
|
|
3238
4262
|
return "TypeError: Parameter \"func\" must be of type \"comp\".";
|
|
3239
4263
|
}
|
|
3240
4264
|
},
|
|
3241
|
-
fxdx: function(func,
|
|
3242
|
-
if(func.type === "expl" || func.type === "pola") {
|
|
4265
|
+
fxdx: function(func, inf, sup) {
|
|
4266
|
+
if(func.type === "expl" || func.type === "inve" || func.type === "pola") {
|
|
3243
4267
|
var f;
|
|
3244
4268
|
if(func.type === "expl") {
|
|
3245
4269
|
f = Chalkboard.real.parse("x => " + func.definition);
|
|
4270
|
+
} else if(func.type === "inve") {
|
|
4271
|
+
f = Chalkboard.real.parse("y => " + func.definition);
|
|
3246
4272
|
} else if(func.type === "pola") {
|
|
3247
4273
|
f = Chalkboard.real.parse("O => " + "((" + func.definition + ") * (" + func.definition + ")) / 2");
|
|
3248
4274
|
}
|
|
3249
|
-
var fx = f(
|
|
3250
|
-
var dx = (
|
|
4275
|
+
var fx = f(inf) + f(sup);
|
|
4276
|
+
var dx = (sup - inf) / 1000000;
|
|
3251
4277
|
for(var i = 1; i < 1000000; i++) {
|
|
3252
|
-
fx += i % 2 === 0 ? 2 * f(
|
|
4278
|
+
fx += i % 2 === 0 ? 2 * f(inf + i * dx) : 4 * f(inf + i * dx);
|
|
3253
4279
|
}
|
|
3254
4280
|
return (fx * dx) / 3;
|
|
3255
4281
|
} else if(func.type === "curv") {
|
|
3256
4282
|
if(func.definition.length === 2) {
|
|
3257
4283
|
var x = Chalkboard.real.parse("t => " + func.definition[0]),
|
|
3258
4284
|
y = Chalkboard.real.parse("t => " + func.definition[1]);
|
|
3259
|
-
var xt = x(
|
|
3260
|
-
yt = y(
|
|
3261
|
-
var dt = (
|
|
4285
|
+
var xt = x(inf) + x(sup),
|
|
4286
|
+
yt = y(inf) + y(sup);
|
|
4287
|
+
var dt = (sup - inf) / 1000000;
|
|
3262
4288
|
for(var i = 1; i < 1000000; i++) {
|
|
3263
|
-
xt += i % 2 === 0 ? 2 * x(
|
|
3264
|
-
yt += i % 2 === 0 ? 2 * y(
|
|
4289
|
+
xt += i % 2 === 0 ? 2 * x(inf + i * dt) : 4 * x(inf + i * dt);
|
|
4290
|
+
yt += i % 2 === 0 ? 2 * y(sup + i * dt) : 4 * y(sup + i * dt);
|
|
3265
4291
|
}
|
|
3266
4292
|
return Chalkboard.vec2.new((xt * dt) / 3, (yt * dt) / 3);
|
|
3267
4293
|
} else if(func.definition.length === 3) {
|
|
3268
4294
|
var x = Chalkboard.real.parse("t => " + func.definition[0]),
|
|
3269
4295
|
y = Chalkboard.real.parse("t => " + func.definition[1]),
|
|
3270
4296
|
z = Chalkboard.real.parse("t => " + func.definition[2]);
|
|
3271
|
-
var xt = x(
|
|
3272
|
-
yt = y(
|
|
3273
|
-
zt = z(
|
|
3274
|
-
var dt = (
|
|
4297
|
+
var xt = x(inf) + x(sup),
|
|
4298
|
+
yt = y(inf) + y(sup),
|
|
4299
|
+
zt = z(inf) + z(sup);
|
|
4300
|
+
var dt = (sup - inf) / 1000000;
|
|
3275
4301
|
for(var i = 1; i < 1000000; i++) {
|
|
3276
|
-
xt += i % 2 === 0 ? 2 * x(
|
|
3277
|
-
yt += i % 2 === 0 ? 2 * y(
|
|
3278
|
-
zt += i % 2 === 0 ? 2 * z(
|
|
4302
|
+
xt += i % 2 === 0 ? 2 * x(inf + i * dt) : 4 * x(inf + i * dt);
|
|
4303
|
+
yt += i % 2 === 0 ? 2 * y(inf + i * dt) : 4 * y(inf + i * dt);
|
|
4304
|
+
zt += i % 2 === 0 ? 2 * z(inf + i * dt) : 4 * z(inf + i * dt);
|
|
3279
4305
|
}
|
|
3280
4306
|
return Chalkboard.vec3.new((xt * dt) / 3, (yt * dt) / 3, (zt * dt) / 3);
|
|
3281
4307
|
}
|
|
3282
4308
|
} else {
|
|
3283
|
-
return "TypeError: Parameter \"func\" must be of type \"expl\", \"pola\", or \"curv\".";
|
|
4309
|
+
return "TypeError: Parameter \"func\" must be of type \"expl\", \"inve\", \"pola\", or \"curv\".";
|
|
3284
4310
|
}
|
|
3285
4311
|
},
|
|
3286
|
-
fxydxdy: function(func,
|
|
4312
|
+
fxydxdy: function(func, xinf, xsup, yinf, ysup) {
|
|
3287
4313
|
if(func.type === "mult") {
|
|
3288
4314
|
var f = Chalkboard.real.parse("(x, y) => " + func.definition);
|
|
3289
4315
|
var result = 0;
|
|
3290
|
-
var dx = (
|
|
3291
|
-
dy = (
|
|
3292
|
-
for(var x =
|
|
3293
|
-
for(var y =
|
|
4316
|
+
var dx = (xsup - xinf) / 10000,
|
|
4317
|
+
dy = (ysup - yinf) / 10000;
|
|
4318
|
+
for(var x = xinf; x <= xsup; x += dx) {
|
|
4319
|
+
for(var y = yinf; y <= ysup; y += dy) {
|
|
3294
4320
|
result += f(x, y);
|
|
3295
4321
|
}
|
|
3296
4322
|
}
|
|
@@ -3299,29 +4325,29 @@ var Chalkboard = {
|
|
|
3299
4325
|
return "TypeError: Parameter \"func\" must be of type \"mult\".";
|
|
3300
4326
|
}
|
|
3301
4327
|
},
|
|
3302
|
-
fds: function(func,
|
|
4328
|
+
fds: function(func, tinf, tsup, sinf, ssup) {
|
|
3303
4329
|
var result = 0;
|
|
3304
4330
|
var drdt, drds;
|
|
3305
4331
|
if(func.type === "curv") {
|
|
3306
|
-
var dt = (
|
|
4332
|
+
var dt = (tsup - tinf) / 10000;
|
|
3307
4333
|
if(func.definition.length === 2) {
|
|
3308
|
-
for(var t =
|
|
4334
|
+
for(var t = tinf; t <= tsup; t += dt) {
|
|
3309
4335
|
drdt = Chalkboard.calc.dfdx(func, t);
|
|
3310
4336
|
result += Chalkboard.vec2.mag(drdt);
|
|
3311
4337
|
}
|
|
3312
4338
|
return result * dt;
|
|
3313
4339
|
} else if(func.definition.length === 3) {
|
|
3314
|
-
for(var t =
|
|
4340
|
+
for(var t = tinf; t <= tsup; t += dt) {
|
|
3315
4341
|
drdt = Chalkboard.calc.dfdx(func, t);
|
|
3316
4342
|
result += Chalkboard.vec3.mag(drdt);
|
|
3317
4343
|
}
|
|
3318
4344
|
return result * dt;
|
|
3319
4345
|
}
|
|
3320
4346
|
} else if(func.type === "surf") {
|
|
3321
|
-
var dt = (
|
|
3322
|
-
ds = (
|
|
3323
|
-
for(var s =
|
|
3324
|
-
for(var t =
|
|
4347
|
+
var dt = (tsup - tinf) / 100,
|
|
4348
|
+
ds = (ssup - sinf) / 100;
|
|
4349
|
+
for(var s = sinf; s <= ssup; s += ds) {
|
|
4350
|
+
for(var t = tinf; t <= tsup; t += dt) {
|
|
3325
4351
|
drds = Chalkboard.matr.toVector(Chalkboard.calc.grad(func, Chalkboard.vec2.new(s, t)), "vec3", "col", 1);
|
|
3326
4352
|
drdt = Chalkboard.matr.toVector(Chalkboard.calc.grad(func, Chalkboard.vec2.new(s, t)), "vec3", "col", 2);
|
|
3327
4353
|
result += Chalkboard.vec3.mag(Chalkboard.vec3.cross(drds, drdt));
|
|
@@ -3332,22 +4358,22 @@ var Chalkboard = {
|
|
|
3332
4358
|
return "TypeError: Parameter \"func\" must be of type \"curv\" or \"surf\".";
|
|
3333
4359
|
}
|
|
3334
4360
|
},
|
|
3335
|
-
frds: function(funcORvecfield, func,
|
|
4361
|
+
frds: function(funcORvecfield, func, inf, sup) {
|
|
3336
4362
|
if(func.type === "curv") {
|
|
3337
4363
|
var result = 0;
|
|
3338
|
-
var dt = (
|
|
4364
|
+
var dt = (sup - inf) / 10000;
|
|
3339
4365
|
if(funcORvecfield.type === "mult") {
|
|
3340
|
-
for(var t =
|
|
3341
|
-
result += Chalkboard.real.val(funcORvecfield, Chalkboard.
|
|
4366
|
+
for(var t = inf; t <= sup; t += dt) {
|
|
4367
|
+
result += Chalkboard.real.val(funcORvecfield, Chalkboard.real.val(func, t)) * Chalkboard.vec2.mag(Chalkboard.calc.dfdx(func, t));
|
|
3342
4368
|
}
|
|
3343
4369
|
return result * dt;
|
|
3344
4370
|
} else if(funcORvecfield.type === "vec2field") {
|
|
3345
|
-
for(var t =
|
|
4371
|
+
for(var t = inf; t <= sup; t += dt) {
|
|
3346
4372
|
result += Chalkboard.vec2.dot(Chalkboard.vec2.fromField(funcORvecfield, Chalkboard.real.val(func, t)), Chalkboard.calc.dfdx(func, t));
|
|
3347
4373
|
}
|
|
3348
4374
|
return result * dt;
|
|
3349
4375
|
} else if(funcORvecfield.type === "vec3field") {
|
|
3350
|
-
for(var t =
|
|
4376
|
+
for(var t = inf; t <= sup; t += dt) {
|
|
3351
4377
|
result += Chalkboard.vec3.dot(Chalkboard.vec3.fromField(funcORvecfield, Chalkboard.real.val(func, t)), Chalkboard.calc.dfdx(func, t));
|
|
3352
4378
|
}
|
|
3353
4379
|
return result * dt;
|
|
@@ -3358,29 +4384,29 @@ var Chalkboard = {
|
|
|
3358
4384
|
return "TypeError: Parameter \"func\" must be of type \"curv\".";
|
|
3359
4385
|
}
|
|
3360
4386
|
},
|
|
3361
|
-
fnds: function(vecfield, func,
|
|
4387
|
+
fnds: function(vecfield, func, tinf, tsup, sinf, ssup) {
|
|
3362
4388
|
var result = 0;
|
|
3363
4389
|
var drdt, drds;
|
|
3364
4390
|
if(func.type === "curv") {
|
|
3365
|
-
var dt = (
|
|
4391
|
+
var dt = (tsup - tinf) / 10000;
|
|
3366
4392
|
if(func.definition.length === 2) {
|
|
3367
|
-
for(var t =
|
|
4393
|
+
for(var t = tinf; t <= tsup; t += dt) {
|
|
3368
4394
|
drdt = Chalkboard.calc.dfdx(func, t);
|
|
3369
4395
|
result += Chalkboard.vec2.dot(Chalkboard.vec2.fromField(vecfield, Chalkboard.real.val(func, t)), Chalkboard.vec2.new(-drdt.y, drdt.x)) * Chalkboard.vec2.mag(drdt);
|
|
3370
4396
|
}
|
|
3371
4397
|
return result * dt;
|
|
3372
4398
|
} else if(func.definition.length === 3) {
|
|
3373
|
-
for(var t =
|
|
4399
|
+
for(var t = tinf; t <= tsup; t += dt) {
|
|
3374
4400
|
drdt = Chalkboard.calc.dfdx(func, t);
|
|
3375
4401
|
result += Chalkboard.vec3.dot(Chalkboard.vec3.fromField(vecfield, Chalkboard.real.val(func, t)), Chalkboard.calc.normal(func, t)) * Chalkboard.vec3.mag(drdt);
|
|
3376
4402
|
}
|
|
3377
4403
|
return result * dt;
|
|
3378
4404
|
}
|
|
3379
4405
|
} else if(func.type === "surf") {
|
|
3380
|
-
var dt = (
|
|
3381
|
-
ds = (
|
|
3382
|
-
for(var s =
|
|
3383
|
-
for(var t =
|
|
4406
|
+
var dt = (tsup - tinf) / 100,
|
|
4407
|
+
ds = (ssup - sinf) / 100;
|
|
4408
|
+
for(var s = sinf; s <= ssup; s += ds) {
|
|
4409
|
+
for(var t = tinf; t <= tsup; t += dt) {
|
|
3384
4410
|
drds = Chalkboard.matr.toVector(Chalkboard.calc.grad(func, Chalkboard.vec2.new(s, t)), "vec3", "col", 1);
|
|
3385
4411
|
drdt = Chalkboard.matr.toVector(Chalkboard.calc.grad(func, Chalkboard.vec2.new(s, t)), "vec3", "col", 2);
|
|
3386
4412
|
result += Chalkboard.vec3.scalarTriple(Chalkboard.vec3.fromField(vecfield, Chalkboard.real.val(func, Chalkboard.vec2.new(s, t))), drds, drdt);
|
|
@@ -3391,12 +4417,12 @@ var Chalkboard = {
|
|
|
3391
4417
|
return "TypeError: Parameter \"func\" must be of type \"curv\" or \"surf\".";
|
|
3392
4418
|
}
|
|
3393
4419
|
},
|
|
3394
|
-
fzdz: function(func_1, func_2,
|
|
4420
|
+
fzdz: function(func_1, func_2, inf, sup) {
|
|
3395
4421
|
if(func_1.type === "comp") {
|
|
3396
4422
|
if(func_2.type === "curv") {
|
|
3397
4423
|
var result = Chalkboard.comp.new(0, 0);
|
|
3398
|
-
var dt = (
|
|
3399
|
-
for(var t =
|
|
4424
|
+
var dt = (sup - inf) / 10000;
|
|
4425
|
+
for(var t = inf; t <= sup; t += dt) {
|
|
3400
4426
|
var fz = Chalkboard.comp.val(func_1, Chalkboard.vec2.toComplex(Chalkboard.real.val(func_2, t)));
|
|
3401
4427
|
var rt = Chalkboard.calc.dfdx(func_2, t);
|
|
3402
4428
|
result = Chalkboard.comp.add(result, Chalkboard.comp.new((fz.a * rt.x) - (fz.b * rt.y), (fz.b * rt.x) + (fz.a * rt.y)));
|
|
@@ -3478,4 +4504,8 @@ var Chalkboard = {
|
|
|
3478
4504
|
}
|
|
3479
4505
|
}
|
|
3480
4506
|
};
|
|
3481
|
-
|
|
4507
|
+
if(typeof window === "undefined") {
|
|
4508
|
+
module.exports = Chalkboard;
|
|
4509
|
+
} else {
|
|
4510
|
+
window.Chalkboard = Chalkboard;
|
|
4511
|
+
}
|