@zushah/chalkboard 1.7.0 → 2.1.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.
@@ -1,4460 +0,0 @@
1
- /*
2
- The Chalkboard Library
3
- Version 1.7.0 Descartes released 01/01/2024
4
- Authored by Zushah ===> https://www.github.com/Zushah
5
- Available under the MIT License ===> https://www.opensource.org/license/mit/
6
-
7
- The Chalkboard library is a JavaScript namespace that provides a plethora of both practical and abstract mathematical functionalities for its user.
8
-
9
- Repository ===> https://www.github.com/Zushah/Chalkboard
10
- Website ===> https://zushah.github.io/Chalkboard/home.html
11
- */
12
- var Chalkboard = {
13
- README: function() {
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
- },
16
- LOGO: function(x, y, s) {
17
- x = x || width / 2;
18
- y = y || height / 2;
19
- s = s || 1;
20
- pushMatrix();
21
- translate(x, y);
22
- scale(s);
23
- noStroke();
24
- fill(25, 25, 25);
25
- rect(-50, -50, 100, 100);
26
- fill(50, 125, 200);
27
- textAlign(CENTER, CENTER);
28
- textSize(75);
29
- textFont(createFont("Times New Roman"));
30
- text("C", -25, 0);
31
- text("B", 25, 0);
32
- stroke(50, 125, 200);
33
- strokeWeight(6);
34
- strokeCap(SQUARE);
35
- line(-30, 25, -30, -22.5);
36
- line(22, 25, 22, -22.5);
37
- textAlign(TOP, LEFT);
38
- popMatrix();
39
- },
40
- PI: function(coefficient) {
41
- coefficient = coefficient || 1;
42
- return coefficient * 4 * (4 * Math.atan(1/5) - Math.atan(1/239));
43
- },
44
- E: function(exponent) {
45
- exponent = exponent || 1;
46
- return Math.pow(Math.pow(10, 1 / Math.log(10)), exponent);
47
- },
48
- CONTEXT: "ctx",
49
- PARSEPREFIX: "",
50
- numb: {
51
- random: function(inf, sup) {
52
- if(inf === undefined) {
53
- inf = 0;
54
- }
55
- if(sup === undefined) {
56
- sup = 1;
57
- }
58
- return inf + (sup - inf) * Math.random();
59
- },
60
- exponential: function(l) {
61
- if(l === undefined) {
62
- l = 1;
63
- }
64
- return l <= 0 ? 0 : -Math.log(Math.random()) / l;
65
- },
66
- Gaussian: function(height, mean, deviation) {
67
- var u1 = Math.random(), u2 = Math.random();
68
- var random = Chalkboard.real.sqrt(-2 * Chalkboard.real.ln(u1)) * Chalkboard.trig.cos(Chalkboard.PI(2) * u2);
69
- return random * height * Chalkboard.real.sqrt(deviation) + mean;
70
- },
71
- Bernoullian: function(p) {
72
- if(p === undefined) {
73
- p = 0.5;
74
- }
75
- return Math.random() < p ? 1 : 0;
76
- },
77
- Poissonian: function(l) {
78
- if(l === undefined) {
79
- l = 1;
80
- }
81
- if(l > 0) {
82
- var L = Chalkboard.E(-l);
83
- var p = 1, k = 0;
84
- for(; p > L; ++k) {
85
- p *= Math.random();
86
- }
87
- return k - 1;
88
- } else {
89
- return 0;
90
- }
91
- },
92
- factorial: function(num) {
93
- if(num >= 0) {
94
- var n = 1;
95
- for(var i = 1; i <= num; i++) {
96
- n *= i;
97
- }
98
- i--;
99
- return n;
100
- } else if(num < 0) {
101
- return undefined;
102
- }
103
- },
104
- gcd: function(a, b) {
105
- if(b === 0) {
106
- return a;
107
- }
108
- return Chalkboard.numb.gcd(b, a % b);
109
- },
110
- lcm: function(a, b) {
111
- return a * (b / Chalkboard.numb.gcd(a, b));
112
- },
113
- sum: function(formula, inf, sup) {
114
- var result = 0;
115
- var f = Chalkboard.real.parse("n => " + formula);
116
- for(var i = inf; i <= sup; i++) {
117
- result += f(i);
118
- }
119
- return result;
120
- },
121
- mul: function(formula, inf, sup) {
122
- var result = 1;
123
- var f = Chalkboard.real.parse("n => " + formula);
124
- for(var i = inf; i <= sup; i++) {
125
- result *= f(i);
126
- }
127
- return result;
128
- },
129
- combination: function(n, r) {
130
- return Chalkboard.numb.factorial(n) / (Chalkboard.numb.factorial(n - r) * Chalkboard.numb.factorial(r));
131
- },
132
- permutation: function(n, r) {
133
- return Chalkboard.numb.factorial(n) / Chalkboard.numb.factorial(n - r);
134
- },
135
- prime: function(num) {
136
- if(num === 2) {
137
- return 2;
138
- }
139
- var n = 1;
140
- var prime = 3;
141
- while(n < num) {
142
- if(Chalkboard.numb.isPrime(prime)) {
143
- n++;
144
- }
145
- if(n < num) {
146
- prime += 2;
147
- }
148
- }
149
- return prime;
150
- },
151
- isPrime: function(num) {
152
- for(var i = 2; i <= Chalkboard.real.sqrt(num); i++) {
153
- if(num % i === 0) {
154
- return false;
155
- }
156
- }
157
- return num > 1;
158
- },
159
- nextPrime: function(num) {
160
- var result = num + 1;
161
- while(!Chalkboard.numb.isPrime(result)) {
162
- result++;
163
- }
164
- return result;
165
- },
166
- primeGap: function(inf, sup) {
167
- var prime = null;
168
- var gap = 0;
169
- for(var i = inf; i <= sup; i++) {
170
- if(Chalkboard.numb.isPrime(i)) {
171
- if(prime !== null) {
172
- var temp = i - prime;
173
- if(temp > gap) {
174
- gap = temp;
175
- }
176
- }
177
- prime = i;
178
- }
179
- }
180
- return gap;
181
- },
182
- primeArr: function(inf, sup) {
183
- var result = [];
184
- for(var i = inf; i <= sup; i++) {
185
- if(Chalkboard.numb.isPrime(i)) {
186
- result.push(i);
187
- }
188
- }
189
- return result;
190
- },
191
- primeCount: function(inf, sup) {
192
- return Chalkboard.numb.primeArr(inf, sup).length;
193
- },
194
- compositeArr: function(inf, sup) {
195
- var result = [];
196
- for(var i = inf; i <= sup; i++) {
197
- if(!Chalkboard.numb.isPrime(i)) {
198
- result.push(i);
199
- }
200
- }
201
- return result;
202
- },
203
- compositeCount: function(inf, sup) {
204
- return Chalkboard.numb.compositeArr(inf, sup).length;
205
- },
206
- factors: function(num) {
207
- var result = [];
208
- while(num % 2 === 0) {
209
- result.push(2);
210
- num /= 2;
211
- }
212
- for(var i = 3; i <= Chalkboard.real.sqrt(num); i += 2) {
213
- while(num % i === 0) {
214
- result.push(i);
215
- num /= i;
216
- }
217
- }
218
- if(num > 2) {
219
- result.push(num);
220
- }
221
- return result;
222
- },
223
- divisors: function(num) {
224
- var result = [];
225
- for(var i = 1; i <= num; i++) {
226
- if(num % i === 0) {
227
- result.push(i);
228
- }
229
- }
230
- return result;
231
- },
232
- sgn: function(num) {
233
- if(num < 0) {
234
- return -1;
235
- } else if(num === 0) {
236
- return 0;
237
- } else if(num > 0) {
238
- return 1;
239
- }
240
- },
241
- Kronecker: function(a, b) {
242
- if(a === b) {
243
- return 1;
244
- } else if(a !== b) {
245
- return 0;
246
- } else {
247
- return undefined;
248
- }
249
- },
250
- change: function(initial, final) {
251
- return (final - initial) / initial;
252
- },
253
- map: function(num, range1, range2) {
254
- return range2[0] + (range2[1] - range2[0]) * ((num - range1[0]) / (range1[1] - range1[0]));
255
- },
256
- constrain: function(num, range) {
257
- if(range === undefined) {
258
- return Math.max(Math.min(num, 1), 0);
259
- } else {
260
- return Math.max(Math.min(num, range[1]), range[0]);
261
- }
262
- },
263
- binomial: function(n, k) {
264
- if(k < 0 || k > n) {
265
- return 0;
266
- }
267
- if(k === 0 || k === n) {
268
- return 1;
269
- }
270
- if(k === 1 || k === n - 1) {
271
- return n;
272
- }
273
- if(n - k < k) {
274
- k = n - k;
275
- }
276
- var result = n;
277
- for(var i = 2; i <= k; i++) {
278
- result *= (n - i + 1) / i;
279
- }
280
- return Math.round(result);
281
- },
282
- Fibonacci: function(num) {
283
- var sequence = [0, 1];
284
- if(sequence[num] === undefined) {
285
- sequence.push(Chalkboard.numb.Fibonacci(num - 1) + sequence[num - 2]);
286
- }
287
- return sequence[num];
288
- },
289
- Goldbach: function(num) {
290
- if(num % 2 === 0) {
291
- if(num !== 4) {
292
- var a = num / 2, b = num / 2;
293
- if(a % 2 === 0) {
294
- a--;
295
- b++;
296
- }
297
- while(a >= 3) {
298
- if(Chalkboard.numb.isPrime(a) && Chalkboard.numb.isPrime(b)) {
299
- return [a, b];
300
- }
301
- a -= 2;
302
- b += 2;
303
- }
304
- return undefined;
305
- } else {
306
- return [2, 2];
307
- }
308
- } else {
309
- return undefined;
310
- }
311
- },
312
- Euler: function(num) {
313
- if(num > 0) {
314
- var factors = Chalkboard.numb.factors(num);
315
- for(var i = 0; i < factors.length; i++) {
316
- num *= (factors[i] - 1) / factors[i];
317
- }
318
- return num;
319
- } else {
320
- return undefined;
321
- }
322
- }
323
- },
324
- real: {
325
- function: function(definition, type) {
326
- type = type || "expl";
327
- if(type === "expl") {
328
- return {definition: definition, type: type};
329
- } else if(type === "inve") {
330
- return {definition: definition, type: type};
331
- } else if(type === "pola") {
332
- return {definition: definition, type: type};
333
- } else if(type === "curv") {
334
- return definition.length === 2 ? {definition: [definition[0], definition[1]], type: type} : {definition: [definition[0], definition[1], definition[2]], type: type};
335
- } else if(type === "surf") {
336
- return {definition: [definition[0], definition[1], definition[2]], type: type};
337
- } else if(type === "mult") {
338
- return {definition: definition, type: type};
339
- } else {
340
- return "TypeError: Parameter \"type\" must be either \"expl\", \"inve\", \"pola\", \"curv\", \"surf\", or \"mult\".";
341
- }
342
- },
343
- parse: function(str) {
344
- return Function('"use strict"; ' + Chalkboard.PARSEPREFIX + ' return (' + str + ')')();
345
- },
346
- val: function(func, val) {
347
- if(func.type === "expl") {
348
- var f = Chalkboard.real.parse("x => " + func.definition);
349
- return f(val);
350
- } else if(func.type === "inve") {
351
- var f = Chalkboard.real.parse("y => " + func.definition);
352
- return f(val);
353
- } else if(func.type === "pola") {
354
- var r = Chalkboard.real.parse("O => " + func.definition);
355
- return r(val);
356
- } else if(func.type === "curv") {
357
- if(func.definition.length === 2) {
358
- var x = Chalkboard.real.parse("t => " + func.definition[0]),
359
- y = Chalkboard.real.parse("t => " + func.definition[1]);
360
- return Chalkboard.vec2.new(x(val), y(val));
361
- } else if(func.definition.length === 3) {
362
- var x = Chalkboard.real.parse("t => " + func.definition[0]),
363
- y = Chalkboard.real.parse("t => " + func.definition[1]),
364
- z = Chalkboard.real.parse("t => " + func.definition[2]);
365
- return Chalkboard.vec3.new(x(val), y(val), z(val));
366
- }
367
- } else if(func.type === "surf") {
368
- var x = Chalkboard.real.parse("(s, t) => " + func.definition[0]),
369
- y = Chalkboard.real.parse("(s, t) => " + func.definition[1]),
370
- z = Chalkboard.real.parse("(s, t) => " + func.definition[2]);
371
- if(val.type === "vec2") {
372
- return Chalkboard.vec3.new(x(val.x, val.y), y(val.x, val.y), z(val.x, val.y));
373
- } else {
374
- return "TypeError: Parameter \"val\" must be of type \"vec2\".";
375
- }
376
- } else if(func.type === "mult") {
377
- if(val.type === "vec2") {
378
- var f = Chalkboard.real.parse("(x, y) => " + func.definition);
379
- return f(val.x, val.y);
380
- } else {
381
- return "TypeError: Parameter \"val\" must be of type \"vec2\".";
382
- }
383
- } else {
384
- return "TypeError: Parameter \"func\" must be of type \"expl\", \"pola\", \"curv\", \"surf\", or \"mult\".";
385
- }
386
- },
387
- pow: function(base, num) {
388
- if(base === 0 && num === 0) {
389
- return 1;
390
- } else {
391
- return Math.exp(num * Math.log(base));
392
- }
393
- },
394
- log: function(base, num) {
395
- return Chalkboard.real.ln(num) / Chalkboard.real.ln(base);
396
- },
397
- ln: function(num) {
398
- return Chalkboard.calc.fxdx(Chalkboard.real.function("1 / x"), 1, num);
399
- },
400
- log10: function(num) {
401
- return Chalkboard.real.log(10, num);
402
- },
403
- sqrt: function(num) {
404
- if(num >= 0) {
405
- return Math.exp(Math.log(num) / 2);
406
- } else if(num < 0) {
407
- return undefined;
408
- }
409
- },
410
- root: function(num, index) {
411
- index = index || 3;
412
- return Math.exp(Math.log(num) / index);
413
- },
414
- tetration: function(base, num) {
415
- if(num === 0) {
416
- return 1;
417
- } else if(num > 0) {
418
- return Math.pow(base, Chalkboard.real.tetration(base, num - 1));
419
- } else {
420
- return undefined;
421
- }
422
- },
423
- Heaviside: function(num, edge, scl) {
424
- edge = edge || 0;
425
- scl = scl || 1;
426
- if(num >= edge) {
427
- return scl;
428
- } else if(num < edge) {
429
- return 0;
430
- }
431
- },
432
- Dirac: function(num, edge, scl) {
433
- edge = edge || 0;
434
- scl = scl || 1;
435
- if(num === edge) {
436
- return scl;
437
- } else if(num !== edge) {
438
- return 0;
439
- }
440
- },
441
- ramp: function(num, edge, scl) {
442
- edge = edge || 0;
443
- scl = scl || 1;
444
- if(num >= edge) {
445
- return num * scl;
446
- } else if(num < edge) {
447
- return 0;
448
- }
449
- },
450
- rect: function(num, center, width, scl) {
451
- center = center || 0;
452
- width = width || 2;
453
- scl = scl || 1;
454
- if(num > (center + width / 2) || num < (center - width / 2)) {
455
- return 0;
456
- } else if(num <= (center + width / 2) || num >= (center - width / 2)) {
457
- return scl;
458
- }
459
- },
460
- pingpong: function(num, edge, scl) {
461
- edge = edge || 0;
462
- scl = scl || 1;
463
- if((num + edge) % (2 * scl) < scl) {
464
- return (num + edge) % scl;
465
- } else {
466
- return scl - (num + edge) % scl;
467
- }
468
- },
469
- slope: function(x1, y1, x2, y2) {
470
- return (y2 - y1) / (x2 - x1);
471
- },
472
- linear: function(x1, y1, x2, y2) {
473
- return Chalkboard.real.function(Chalkboard.real.slope(x1, y1, x2, y2).toString() + " * (x - " + x2.toString() + ") + " + y2.toString());
474
- },
475
- linearFormula: function(a, b, c, d) {
476
- if(c === undefined && d === undefined) {
477
- return -b / a;
478
- } else if(d === undefined) {
479
- return c / a;
480
- } else {
481
- return -b / Chalkboard.real.slope(a, b, c, d) + a;
482
- }
483
- },
484
- lerp: function(p, t) {
485
- return (p[1] - p[0]) * t + p[0];
486
- },
487
- quadratic: function(a, b, c, form) {
488
- form = form || "stan";
489
- if(form === "stan") {
490
- return Chalkboard.real.function(a.toString() + "* x * x + " + b.toString() + " * x +" + c.toString());
491
- } else if(form === "vert") {
492
- return Chalkboard.real.function(a.toString() + " * ((x - " + b.toString() + ") * (x - " + b.toString() + ")) +" + c.toString());
493
- } else {
494
- return "TypeError: Parameter \"form\" must be \"stan\" or \"vert\".";
495
- }
496
- },
497
- discriminant: function(a, b, c, form) {
498
- form = form || "stan";
499
- if(form === "stan") {
500
- return b * b - 4 * a * c;
501
- } else if(form === "vert") {
502
- return (2 * a * b) * (2 * a * b) - 4 * a * c;
503
- } else {
504
- return "TypeError: Parameter \"form\" must be \"stan\" or \"vert\".";
505
- }
506
- },
507
- quadraticFormula: function(a, b, c, form) {
508
- form = form || "stan";
509
- if(form === "stan") {
510
- return [(-b + Chalkboard.real.sqrt(Chalkboard.real.discriminant(a, b, c, "stan"))) / (2 * a), (-b - Math.sqrt(Chalkboard.real.discriminant(a, b, c, "stan"))) / (2 * a)];
511
- } else if(form === "vert") {
512
- return [b + Chalkboard.real.sqrt(-c / a), b - Chalkboard.real.sqrt(-c / a)];
513
- } else {
514
- return "TypeError: Parameter \"form\" must be \"stan\" or \"vert\".";
515
- }
516
- },
517
- qerp: function(p1, p2, p3, t) {
518
- var a = p1[1] / ((p1[0] - p2[0]) * (p1[0] - p3[0])) + p2[1] / ((p2[0] - p1[0]) * (p2[0] - p3[0])) + p3[1] / ((p3[0] - p1[0]) * (p3[0] - p2[0]));
519
- var b = -p1[1] * (p2[0] + p3[0]) / ((p1[0] - p2[0]) * (p1[0] - p3[0])) - p2[1] * (p1[0] + p3[0]) / ((p2[0] - p1[0]) * (p2[0] - p3[0])) - p3[1] * (p1[0] + p2[0]) / ((p3[0] - p1[0]) * (p3[0] - p2[0]));
520
- var c = p1[1] * p2[0] * p3[0] / ((p1[0] - p2[0]) * (p1[0] - p3[0])) + p2[1] * p1[0] * p3[0] / ((p2[0] - p1[0]) * (p2[0] - p3[0])) + p3[1] * p1[0] * p2[0] / ((p3[0] - p1[0]) * (p3[0] - p2[0]));
521
- return a * t * t + b * t + c;
522
- }
523
- },
524
- comp: {
525
- new: function(a, b) {
526
- if(b === undefined) {
527
- return {a: a, b: 0, type: "comp"};
528
- } else {
529
- return {a: a, b: b, type: "comp"};
530
- }
531
- },
532
- copy: function(comp) {
533
- return Object.create(Object.getPrototypeOf(comp), Object.getOwnPropertyDescriptors(comp));
534
- },
535
- function: function(realDefinition, imagDefinition) {
536
- return {definition: [realDefinition, imagDefinition], type: "comp"};
537
- },
538
- parse: function(str) {
539
- return Function('"use strict"; ' + Chalkboard.PARSEPREFIX + ' return (' + str + ')')();
540
- },
541
- val: function(func, comp) {
542
- if(func.type === "comp") {
543
- var u = Chalkboard.comp.parse("(a, b) => " + func.definition[0]),
544
- v = Chalkboard.comp.parse("(a, b) => " + func.definition[1]);
545
- return Chalkboard.comp.new(u(comp.a, comp.b), v(comp.a, comp.b));
546
- } else {
547
- return "TypeError: Parameter \"func\" must be of type \"comp\".";
548
- }
549
- },
550
- Re: function(funcORcomp) {
551
- if(funcORcomp.definition !== undefined && funcORcomp.type === "comp") {
552
- return funcORcomp.definition[0];
553
- } else if(funcORcomp.a !== undefined && funcORcomp.type === "comp") {
554
- return funcORcomp.a;
555
- }
556
- },
557
- Im: function(funcORcomp) {
558
- if(funcORcomp.definition !== undefined && funcORcomp.type === "comp") {
559
- return funcORcomp.definition[1];
560
- } else if(funcORcomp.b !== undefined && funcORcomp.type === "comp") {
561
- return funcORcomp.b;
562
- }
563
- },
564
- random: function(inf, sup) {
565
- return Chalkboard.comp.new(Chalkboard.numb.random(inf, sup), Chalkboard.numb.random(inf, sup));
566
- },
567
- mag: function(comp) {
568
- return Chalkboard.real.sqrt((comp.a * comp.a) + (comp.b * comp.b));
569
- },
570
- magsq: function(comp) {
571
- return (comp.a * comp.a) + (comp.b * comp.b);
572
- },
573
- magset: function(comp, num) {
574
- return Chalkboard.comp.scl(Chalkboard.comp.normalize(comp), num);
575
- },
576
- arg: function(comp) {
577
- return Chalkboard.trig.arctan2(comp.b, comp.a);
578
- },
579
- slope: function(comp) {
580
- return comp.b / comp.a;
581
- },
582
- average: function(comp) {
583
- return (comp.a + comp.b) / 2;
584
- },
585
- normalize: function(comp) {
586
- return Chalkboard.comp.new(comp.a / Chalkboard.comp.mag(comp), comp.b / Chalkboard.comp.mag(comp));
587
- },
588
- zero: function(comp) {
589
- return Chalkboard.comp.new(comp.a * 0, comp.b * 0);
590
- },
591
- negate: function(comp) {
592
- return Chalkboard.comp.new(-comp.a, -comp.b);
593
- },
594
- reciprocate: function(comp) {
595
- return Chalkboard.comp.new(1 / comp.a, 1 / comp.b);
596
- },
597
- absolute: function(comp) {
598
- return Chalkboard.comp.new(Math.abs(comp.a), Math.abs(comp.b));
599
- },
600
- round: function(comp) {
601
- return Chalkboard.comp.new(Math.round(comp.a), Math.round(comp.b));
602
- },
603
- Euler: function(rad) {
604
- return Chalkboard.comp.new(Chalkboard.trig.cos(rad), Chalkboard.trig.sin(rad));
605
- },
606
- pow: function(comp, num) {
607
- return Chalkboard.comp.new(Chalkboard.real.pow(Chalkboard.comp.mag(comp), num) * Chalkboard.trig.cos(num * Chalkboard.comp.arg(comp)), Chalkboard.real.pow(Chalkboard.comp.mag(comp), num) * Chalkboard.trig.sin(num * Chalkboard.comp.arg(comp)));
608
- },
609
- ln: function(comp) {
610
- return Chalkboard.comp.new(Chalkboard.real.ln(Chalkboard.comp.mag(comp)), Chalkboard.trig.arctan2(comp.b, comp.a));
611
- },
612
- sq: function(comp) {
613
- return Chalkboard.comp.new((comp.a * comp.a) - (comp.b * comp.b), 2 * comp.a * comp.b);
614
- },
615
- sqrt: function(comp) {
616
- 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));
617
- },
618
- root: function(comp, index) {
619
- index = index || 3;
620
- if(Number.isInteger(index) && index > 0) {
621
- var result = [];
622
- var r = Chalkboard.comp.mag(comp);
623
- var t = Chalkboard.comp.arg(comp);
624
- for(var i = 0; i < index; i++) {
625
- 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)));
626
- }
627
- return result;
628
- }
629
- },
630
- rotate: function(comp, rad) {
631
- 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));
632
- },
633
- invert: function(comp) {
634
- return Chalkboard.comp.new(comp.a / Chalkboard.comp.magsq(comp), -comp.b / Chalkboard.comp.magsq(comp));
635
- },
636
- conjugate: function(comp) {
637
- return Chalkboard.comp.new(comp.a, -comp.b);
638
- },
639
- dist: function(comp_1, comp_2) {
640
- if(typeof comp_1 === "number") {
641
- comp_1 = Chalkboard.comp.new(comp_1, 0);
642
- }
643
- if(typeof comp_2 === "number") {
644
- comp_2 = Chalkboard.comp.new(comp_2, 0);
645
- }
646
- 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)));
647
- },
648
- distsq: function(comp_1, comp_2) {
649
- if(typeof comp_1 === "number") {
650
- comp_1 = Chalkboard.comp.new(comp_1, 0);
651
- }
652
- if(typeof comp_2 === "number") {
653
- comp_2 = Chalkboard.comp.new(comp_2, 0);
654
- }
655
- 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));
656
- },
657
- scl: function(comp, num) {
658
- return Chalkboard.comp.new(comp.a * num, comp.b * num);
659
- },
660
- constrain: function(comp, range) {
661
- return Chalkboard.comp.new(Chalkboard.numb.constrain(comp.a, range), Chalkboard.numb.constrain(comp.b, range));
662
- },
663
- add: function(comp_1, comp_2) {
664
- if(typeof comp_1 === "number") {
665
- comp_1 = Chalkboard.comp.new(comp_1, 0);
666
- }
667
- if(typeof comp_2 === "number") {
668
- comp_2 = Chalkboard.comp.new(comp_2, 0);
669
- }
670
- return Chalkboard.comp.new(comp_1.a + comp_2.a, comp_1.b + comp_2.b);
671
- },
672
- sub: function(comp_1, comp_2) {
673
- if(typeof comp_1 === "number") {
674
- comp_1 = Chalkboard.comp.new(comp_1, 0);
675
- }
676
- if(typeof comp_2 === "number") {
677
- comp_2 = Chalkboard.comp.new(comp_2, 0);
678
- }
679
- return Chalkboard.comp.new(comp_1.a - comp_2.a, comp_1.b - comp_2.b);
680
- },
681
- mul: function(comp_1, comp_2) {
682
- if(typeof comp_1 === "number") {
683
- comp_1 = Chalkboard.comp.new(comp_1, 0);
684
- }
685
- if(typeof comp_2 === "number") {
686
- comp_2 = Chalkboard.comp.new(comp_2, 0);
687
- }
688
- 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));
689
- },
690
- div: function(comp_1, comp_2) {
691
- if(typeof comp_1 === "number") {
692
- comp_1 = Chalkboard.comp.new(comp_1, 0);
693
- }
694
- if(typeof comp_2 === "number") {
695
- comp_2 = Chalkboard.comp.new(comp_2, 0);
696
- }
697
- 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));
698
- },
699
- toVector: function(comp) {
700
- return Chalkboard.vec2.new(comp.a, comp.b);
701
- },
702
- toArray: function(comp) {
703
- return [comp.a, comp.b];
704
- },
705
- toString: function(comp) {
706
- if(comp.b >= 0) {
707
- return comp.a.toString() + " + " + comp.b.toString() + "i";
708
- } else if(comp.b < 0) {
709
- return comp.a.toString() + " - " + Math.abs(comp.b).toString() + "i";
710
- }
711
- },
712
- print: function(comp) {
713
- console.log(Chalkboard.comp.toString(comp));
714
- }
715
- },
716
- quat: {
717
- new: function(a, b, c, d) {
718
- if(b === undefined && c === undefined && d === undefined) {
719
- return {a: a, b: 0, c: 0, d: 0, type: "quat"};
720
- } else {
721
- return {a: a, b: b, c: c, d: d, type: "quat"};
722
- }
723
- },
724
- copy: function(quat) {
725
- return Object.create(Object.getPrototypeOf(quat), Object.getOwnPropertyDescriptors(quat));
726
- },
727
- random: function(inf, sup) {
728
- return Chalkboard.quat.new(Chalkboard.numb.random(inf, sup), Chalkboard.numb.random(inf, sup), Chalkboard.numb.random(inf, sup), Chalkboard.numb.random(inf, sup));
729
- },
730
- mag: function(quat) {
731
- return Chalkboard.real.sqrt((quat.a * quat.a) + (quat.b * quat.b) + (quat.c * quat.c) + (quat.d * quat.d));
732
- },
733
- magsq: function(quat) {
734
- return (quat.a * quat.a) + (quat.b * quat.b) + (quat.c * quat.c) + (quat.d * quat.d);
735
- },
736
- magset: function(quat, num) {
737
- return Chalkboard.quat.scl(Chalkboard.quat.normalize(quat), num);
738
- },
739
- average: function(quat) {
740
- return (quat.a + quat.b + quat.c + quat.d) / 4;
741
- },
742
- normalize: function(quat) {
743
- return Chalkboard.quat.new(quat.a / Chalkboard.quat.mag(quat), quat.b / Chalkboard.quat.mag(quat), quat.c / Chalkboard.quat.mag(quat), quat.d / Chalkboard.quat.mag(quat));
744
- },
745
- zero: function(quat) {
746
- return Chalkboard.quat.new(quat.a * 0, quat.b * 0, quat.c * 0, quat.d * 0);
747
- },
748
- negate: function(quat) {
749
- return Chalkboard.quat.new(-quat.a, -quat.b, -quat.c, -quat.d);
750
- },
751
- reciprocate: function(quat) {
752
- return Chalkboard.quat.new(1 / quat.a, 1 / quat.b, 1 / quat.c, 1 / quat.d);
753
- },
754
- absolute: function(quat) {
755
- return Chalkboard.quat.new(Math.abs(quat.a), Math.abs(quat.b), Math.abs(quat.c), Math.abs(quat.d));
756
- },
757
- round: function(quat) {
758
- return Chalkboard.quat.new(Math.round(quat.a), Math.round(quat.b), Math.round(quat.c), Math.round(quat.d));
759
- },
760
- invert: function(quat) {
761
- return Chalkboard.quat.new(quat.a / Chalkboard.quat.magsq(quat), -quat.b / Chalkboard.quat.magsq(quat), -quat.c / Chalkboard.quat.magsq(quat), -quat.d / Chalkboard.quat.magsq(quat));
762
- },
763
- conjugate: function(quat) {
764
- return Chalkboard.quat.new(quat.a, -quat.b, -quat.c, -quat.d);
765
- },
766
- dist: function(quat_1, quat_2) {
767
- if(typeof quat_1 === "number") {
768
- quat_1 = Chalkboard.quat.new(quat_1, 0, 0, 0);
769
- }
770
- if(typeof quat_2 === "number") {
771
- quat_2 = Chalkboard.quat.new(quat_2, 0, 0, 0);
772
- }
773
- 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)));
774
- },
775
- distsq: function(quat_1, quat_2) {
776
- if(typeof quat_1 === "number") {
777
- quat_1 = Chalkboard.quat.new(quat_1, 0, 0, 0);
778
- }
779
- if(typeof quat_2 === "number") {
780
- quat_2 = Chalkboard.quat.new(quat_2, 0, 0, 0);
781
- }
782
- 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));
783
- },
784
- scl: function(quat, num) {
785
- return Chalkboard.quat.new(quat.a * num, quat.b * num, quat.c * num, quat.d * num);
786
- },
787
- constrain: function(quat, range) {
788
- 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));
789
- },
790
- add: function(quat_1, quat_2) {
791
- if(typeof quat_1 === "number") {
792
- quat_1 = Chalkboard.quat.new(quat_1, 0, 0, 0);
793
- }
794
- if(typeof quat_2 === "number") {
795
- quat_2 = Chalkboard.quat.new(quat_2, 0, 0, 0);
796
- }
797
- 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);
798
- },
799
- sub: function(quat_1, quat_2) {
800
- if(typeof quat_1 === "number") {
801
- quat_1 = Chalkboard.quat.new(quat_1, 0, 0, 0);
802
- }
803
- if(typeof quat_2 === "number") {
804
- quat_2 = Chalkboard.quat.new(quat_2, 0, 0, 0);
805
- }
806
- 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);
807
- },
808
- mul: function(quat_1, quat_2) {
809
- if(typeof quat_1 === "number") {
810
- quat_1 = Chalkboard.quat.new(quat_1, 0, 0, 0);
811
- }
812
- if(typeof quat_2 === "number") {
813
- quat_2 = Chalkboard.quat.new(quat_2, 0, 0, 0);
814
- }
815
- 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));
816
- },
817
- div: function(quat_1, quat_2) {
818
- if(typeof quat_1 === "number") {
819
- quat_1 = Chalkboard.quat.new(quat_1, 0, 0, 0);
820
- }
821
- if(typeof quat_2 === "number") {
822
- quat_2 = Chalkboard.quat.new(quat_2, 0, 0, 0);
823
- }
824
- 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));
825
- },
826
- fromAxis: function(vec3, rad) {
827
- 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));
828
- },
829
- fromVector: function(vec3) {
830
- return Chalkboard.quat.new(0, vec3.x, vec3.y, vec3.z);
831
- },
832
- toRotation: function(quat, vec3) {
833
- var vector = Chalkboard.quat.fromVector(vec3);
834
- var inverse = Chalkboard.quat.invert(quat);
835
- var quat_vector_inverse = Chalkboard.quat.mul(quat, Chalkboard.quat.mul(vector, inverse));
836
- return Chalkboard.vec3.new(quat_vector_inverse.b, quat_vector_inverse.c, quat_vector_inverse.d);
837
- },
838
- toVector: function(quat) {
839
- return Chalkboard.vec4.new(quat.a, quat.b, quat.c, quat.d);
840
- },
841
- toArray: function(quat) {
842
- return [quat.a, quat.b, quat.c, quat.d];
843
- },
844
- toString: function(quat) {
845
- var quat_b = "";
846
- var quat_c = "";
847
- var quat_d = "";
848
- if(quat.b >= 0) {
849
- quat_b = " + " + quat.b.toString() + "i ";
850
- } else if(quat.b < 0) {
851
- quat_b = " - " + Math.abs(quat.b.toString()) + "i ";
852
- }
853
- if(quat.c >= 0) {
854
- quat_c = "+ " + quat.c.toString() + "j ";
855
- } else if(quat.c < 0) {
856
- quat_c = "- " + Math.abs(quat.c.toString()) + "j ";
857
- }
858
- if(quat.d >= 0) {
859
- quat_d = "+ " + quat.d.toString() + "k ";
860
- } else if(quat.d < 0) {
861
- quat_d = "- " + Math.abs(quat.d.toString()) + "k ";
862
- }
863
- return quat.a.toString() + quat_b + quat_c + quat_d;
864
- },
865
- print: function(quat) {
866
- console.log(Chalkboard.quat.toString(quat));
867
- }
868
- },
869
- plot: {
870
- xyplane: function(config) {
871
- (config = {
872
- x: (config = config || {}).x || width / 2,
873
- y: config.y || height / 2,
874
- size: config.size || 1,
875
- stroke: config.stroke || color(0),
876
- strokeWeight: config.strokeWeight || 2
877
- }).size /= 100;
878
- pushMatrix();
879
- translate(config.x, config.y);
880
- stroke(config.stroke);
881
- strokeWeight(config.strokeWeight / 4);
882
- for(var i = Math.floor(-config.x / config.size); i <= (width - config.x) / config.size; i++) {
883
- line(i / config.size, -config.y, i / config.size, width - config.y);
884
- }
885
- for(var i = Math.floor(-config.y / config.size); i <= (width - config.y) / config.size; i++) {
886
- line(-config.x, i / config.size, width - config.x, i / config.size);
887
- }
888
- strokeWeight(config.strokeWeight);
889
- line(-config.x, 0, width - config.x, 0);
890
- line(0, -config.y, 0, width - config.y);
891
- popMatrix();
892
- },
893
- rOplane: function(config) {
894
- (config = {
895
- x: (config = config || {}).x || width / 2,
896
- y: config.y || height / 2,
897
- size: config.size || 1,
898
- stroke: config.stroke || color(0),
899
- strokeWeight: config.strokeWeight || 2
900
- }).size /= 100;
901
- pushMatrix();
902
- translate(config.x, config.y);
903
- noFill();
904
- stroke(config.stroke);
905
- strokeWeight(config.strokeWeight / 4);
906
- for(var i = 0; i <= config.size * width / 2; i++) {
907
- ellipse(0, 0, 2 * i / config.size, 2 * i / config.size);
908
- }
909
- strokeWeight(config.strokeWeight);
910
- line(-config.x, 0, width - config.x, 0);
911
- line(0, -config.y, 0, width - config.y);
912
- popMatrix();
913
- },
914
- function: function(func, config) {
915
- (config = {
916
- x: (config = config || {}).x || width / 2,
917
- y: config.y || height / 2,
918
- size: config.size || 1,
919
- stroke: config.stroke || color(0),
920
- strokeWeight: config.strokeWeight || 2,
921
- domain: config.domain || (func.type === "comp" ? [[-10, 10], [-10, 10]] : [-10, 10])
922
- }).size /= 100;
923
- var data = [];
924
- pushMatrix();
925
- translate(config.x, config.y);
926
- noFill();
927
- strokeWeight(config.strokeWeight);
928
- stroke(config.stroke);
929
- beginShape();
930
- if(func.type === "expl") {
931
- var f = Chalkboard.real.parse("x => " + func.definition);
932
- for(var i = config.domain[0] / config.size; i <= config.domain[1] / config.size; i++) {
933
- vertex(i, -f(i * config.size) / config.size);
934
- data.push([i, f(i)]);
935
- }
936
- } else if(func.type === "inve") {
937
- var f = Chalkboard.real.parse("y => " + func.definition);
938
- for(var i = config.domain[0] / config.size; i <= config.domain[1] / config.size; i++) {
939
- vertex(f(i * config.size) / config.size, -i);
940
- data.push([f(i), i]);
941
- }
942
- } else if(func.type === "pola") {
943
- var r = Chalkboard.real.parse("O => " + func.definition);
944
- for(var i = config.domain[0] / config.size; i < config.domain[1] / config.size; i++) {
945
- vertex(r(i * config.size) / config.size * Chalkboard.trig.cos(i * config.size), -r(i * config.size) / config.size * Chalkboard.trig.sin(i * config.size));
946
- data.push([i, r(i)]);
947
- }
948
- } else if(func.type === "curv") {
949
- var x = Chalkboard.real.parse("t => " + func.definition[0]),
950
- y = Chalkboard.real.parse("t => " + func.definition[1]);
951
- for(var i = config.domain[0] / config.size; i < config.domain[1] / config.size; i++) {
952
- vertex(x(i * config.size) / config.size, -y(i * config.size) / config.size);
953
- data.push([x(i), y(i)]);
954
- }
955
- } else if(func.type === "comp") {
956
- var u = Chalkboard.comp.parse("(a, b) => " + func.definition[0]),
957
- v = Chalkboard.comp.parse("(a, b) => " + func.definition[1]);
958
- for(var i = config.domain[0][0] / config.size; i <= config.domain[0][1] / config.size; i += 5) {
959
- for(var j = config.domain[1][0] / config.size; j <= config.domain[1][1] / config.size; j += 5) {
960
- var z = Chalkboard.comp.new(u(i * config.size, j * config.size) / config.size, v(i * config.size, j * config.size) / config.size);
961
- noStroke();
962
- if(z.a === 0 && z.b === 0) {
963
- fill(0, 0, 0);
964
- } else if(z.a === Infinity && z.b === Infinity) {
965
- fill(255, 255, 255);
966
- } else {
967
- colorMode(HSB);
968
- fill(Chalkboard.numb.map(Chalkboard.trig.toDeg(Chalkboard.comp.arg(z)), [0, 360], [0, 255]), 255, Chalkboard.numb.map((Chalkboard.trig.tanh(Chalkboard.comp.mag(z) / Chalkboard.real.pow(10, 20)) + 0.5) * 100, [0, 100], [0, 255]));
969
- colorMode(RGB);
970
- }
971
- rect(i, j, 5, 5);
972
- data.push([u(i, j), v(i, j)]);
973
- }
974
- }
975
- } else {
976
- return "TypeError: Property \"type\" of parameter \"func\" must be either \"expl\", \"inve\", \"pola\", \"curv\", or \"comp\".";
977
- }
978
- endShape();
979
- popMatrix();
980
- return data;
981
- },
982
- barplot: function(arr, bins, config) {
983
- (config = {
984
- x: (config = config || {}).x || width / 2,
985
- y: config.y || height / 2,
986
- size: config.size || 1,
987
- fill: config.fill || color(255),
988
- stroke: config.stroke || color(0),
989
- strokeWeight: config.strokeWeight || 2
990
- }).size /= 100;
991
- pushMatrix();
992
- translate(config.x, config.y);
993
- strokeWeight(config.strokeWeight);
994
- stroke(config.stroke);
995
- fill(config.fill);
996
- var bars = [];
997
- for(var i = 0; i < bins.length; i++) {
998
- if(i === 0) {
999
- bars.push(Chalkboard.stat.lt(arr, bins[0], true));
1000
- } else if(i === bins.length) {
1001
- bars.push(Chalkboard.stat.gt(arr, bins[bins.length - 1], true));
1002
- } else {
1003
- bars.push(Chalkboard.stat.ineq(arr, bins[i - 1], bins[i], false, true));
1004
- }
1005
- }
1006
- var counts = [];
1007
- for(var i = 0; i < bars.length; i++) {
1008
- counts.push(bars[i].length);
1009
- }
1010
- var x = 0, width = counts.length / (2 * config.size);
1011
- for(var i = 0; i < counts.length; i++) {
1012
- rect(x - width, 0, 1 / config.size, -counts[i] / config.size);
1013
- x += 1 / config.size;
1014
- }
1015
- popMatrix();
1016
- return bars;
1017
- },
1018
- lineplot: function(arr, bins, config) {
1019
- (config = {
1020
- x: (config = config || {}).x || width / 2,
1021
- y: config.y || height / 2,
1022
- size: config.size || 1,
1023
- stroke: config.stroke || color(0),
1024
- strokeWeight: config.strokeWeight || 2
1025
- }).size /= 100;
1026
- pushMatrix();
1027
- translate(config.x, config.y);
1028
- noFill();
1029
- strokeWeight(config.strokeWeight);
1030
- stroke(config.stroke);
1031
- var verts = [];
1032
- for(var i = 0; i < bins.length; i++) {
1033
- if(i === 0) {
1034
- verts.push(Chalkboard.stat.lt(arr, bins[0], true));
1035
- } else if(i === bins.length) {
1036
- verts.push(Chalkboard.stat.gt(arr, bins[bins.length - 1], true));
1037
- } else {
1038
- verts.push(Chalkboard.stat.ineq(arr, bins[i - 1], bins[i], false, true));
1039
- }
1040
- }
1041
- var counts = [];
1042
- for(var i = 0; i < verts.length; i++) {
1043
- counts.push(verts[i].length);
1044
- }
1045
- beginShape();
1046
- for(var i = 0; i < counts.length; i++) {
1047
- vertex(i / config.size, -counts[i] / config.size);
1048
- }
1049
- endShape();
1050
- popMatrix();
1051
- return verts;
1052
- },
1053
- scatterplot: function(arr1, arr2, config) {
1054
- (config = {
1055
- x: (config = config || {}).x || width / 2,
1056
- y: config.y || height / 2,
1057
- size: config.size || 1,
1058
- stroke: config.stroke || color(0),
1059
- strokeWeight: config.strokeWeight || 5
1060
- }).size /= 100;
1061
- var data = [];
1062
- pushMatrix();
1063
- translate(config.x, config.y);
1064
- strokeWeight(config.strokeWeight);
1065
- stroke(config.stroke);
1066
- if(arr1.length === arr2.length) {
1067
- for(var i = 0; i < arr1.length; i++) {
1068
- point(arr1[i] / config.size - arr1.length / (2 * config.size), -arr2[i] / config.size + arr1.length / (2 * config.size));
1069
- data.push([arr1[i], arr2[i]]);
1070
- }
1071
- }
1072
- popMatrix();
1073
- return data;
1074
- },
1075
- comp: function(comp, config) {
1076
- (config = {
1077
- x: (config = config || {}).x || width / 2,
1078
- y: config.y || height / 2,
1079
- size: config.size || 1,
1080
- stroke: config.stroke || color(0),
1081
- strokeWeight: config.strokeWeight || 5
1082
- }).size /= 100;
1083
- stroke(config.stroke);
1084
- strokeWeight(config.strokeWeight);
1085
- pushMatrix();
1086
- translate(config.x, config.y);
1087
- point(comp.a / config.size, -comp.b / config.size);
1088
- popMatrix();
1089
- noStroke();
1090
- noFill();
1091
- return [[comp.a], [comp.b]];
1092
- },
1093
- vec2: function(vec2, config) {
1094
- (config = {
1095
- x: (config = config || {}).x || width / 2,
1096
- y: config.y || height / 2,
1097
- size: config.size || 1,
1098
- stroke: config.stroke || color(0),
1099
- strokeWeight: config.strokeWeight || 5
1100
- }).size /= 100;
1101
- stroke(config.stroke);
1102
- strokeWeight(config.strokeWeight);
1103
- pushMatrix();
1104
- translate(config.x, config.y);
1105
- line(0, 0, vec2.x / config.size, -vec2.y / config.size);
1106
- popMatrix();
1107
- return [[vec2.x], [vec2.y]];
1108
- },
1109
- field: function(vec2field, config) {
1110
- (config = {
1111
- x: (config = config || {}).x || width / 2,
1112
- y: config.y || height / 2,
1113
- size: config.size || 1,
1114
- stroke: config.stroke || color(0),
1115
- strokeWeight: config.strokeWeight || 5,
1116
- domain: config.domain || [[-10, 10], [-10, 10]],
1117
- res: config.res || 25
1118
- }).size /= 100;
1119
- var data = [];
1120
- stroke(config.stroke);
1121
- strokeWeight(config.strokeWeight);
1122
- pushMatrix();
1123
- translate(config.x, config.y);
1124
- for(var i = config.domain[0][0] / config.size; i <= config.domain[0][1] / config.size; i += config.res) {
1125
- for(var j = config.domain[1][0] / config.size; j <= config.domain[1][1] / config.size; j += config.res) {
1126
- var v = Chalkboard.vec2.fromField(vec2field, Chalkboard.vec2.new(i, j));
1127
- line(i, j, i + v.x, j + v.y);
1128
- data.push([i + v.x, j + v.y]);
1129
- }
1130
- }
1131
- popMatrix();
1132
- return data;
1133
- },
1134
- vec3: function(vec3, config) {
1135
- (config = {
1136
- x: (config = config || {}).x || width / 2,
1137
- y: config.y || height / 2,
1138
- size: config.size || 1,
1139
- stroke: config.stroke || color(0),
1140
- strokeWeight: config.strokeWeight || 5
1141
- }).size /= 100;
1142
- stroke(config.stroke);
1143
- strokeWeight(config.strokeWeight);
1144
- pushMatrix();
1145
- translate(config.x, config.y);
1146
- line(0, 0, (vec3.x / config.size) / (vec3.z * 0.25 + 1), (-vec3.y / config.size) / (vec3.z * 0.25 + 1));
1147
- popMatrix();
1148
- return [[vec3.x], [vec3.y], [vec3.z]];
1149
- },
1150
- matr: function(matr, config) {
1151
- (config = {
1152
- x: (config = config || {}).x || width / 2,
1153
- y: config.y || height / 2,
1154
- size: config.size || 1,
1155
- stroke: config.stroke || color(0),
1156
- strokeWeight: config.strokeWeight || 2,
1157
- domain: config.domain || [-10, 10]
1158
- }).size /= 100;
1159
- for(var i = config.domain[0]; i <= config.domain[1]; i++) {
1160
- 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, stroke: config.stroke, strokeWeight: config.strokeWeight / 4});
1161
- 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, stroke: config.stroke, strokeWeight: config.strokeWeight / 4});
1162
- 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, stroke: config.stroke, strokeWeight: config.strokeWeight / 4});
1163
- 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, stroke: config.stroke, strokeWeight: config.strokeWeight / 4});
1164
- }
1165
- Chalkboard.plot.vec2(Chalkboard.vec2.new(matr[0][0], matr[1][0]), config);
1166
- Chalkboard.plot.vec2(Chalkboard.vec2.new(-matr[0][0], -matr[1][0]), config);
1167
- Chalkboard.plot.vec2(Chalkboard.vec2.new(matr[0][1], matr[1][1]), config);
1168
- Chalkboard.plot.vec2(Chalkboard.vec2.new(-matr[0][1], -matr[1][1]), config);
1169
- return matr;
1170
- },
1171
- dfdx: function(func, config) {
1172
- (config = {
1173
- x: (config = config || {}).x || width / 2,
1174
- y: config.y || height / 2,
1175
- size: config.size || 1,
1176
- stroke: config.stroke || color(0),
1177
- strokeWeight: config.strokeWeight || 2,
1178
- domain: config.domain || [-10, 10],
1179
- res: config.res || 25
1180
- }).size /= 100;
1181
- var data = [];
1182
- pushMatrix();
1183
- translate(config.x, config.y);
1184
- noFill();
1185
- strokeWeight(config.strokeWeight);
1186
- stroke(config.stroke);
1187
- beginShape();
1188
- for(var i = config.domain[0] / config.size; i <= config.domain[1] / config.size; i += config.res) {
1189
- if(func.type === "expl") {
1190
- vertex(i, -Chalkboard.calc.dfdx(func, i * config.size) / config.size);
1191
- data.push([i, Chalkboard.calc.dfdx(func, i)]);
1192
- } else if(func.type === "inve") {
1193
- vertex(Chalkboard.calc.dfdx(func, i * config.size) / config.size, -i);
1194
- data.push([Chalkboard.calc.dfdx(func, i), i]);
1195
- }
1196
- }
1197
- endShape();
1198
- popMatrix();
1199
- return data;
1200
- },
1201
- d2fdx2: function(func, config) {
1202
- (config = {
1203
- x: (config = config || {}).x || width / 2,
1204
- y: config.y || height / 2,
1205
- size: config.size || 1,
1206
- stroke: config.stroke || color(0),
1207
- strokeWeight: config.strokeWeight || 2,
1208
- domain: config.domain || [-10, 10],
1209
- res: config.res || 25
1210
- }).size /= 100;
1211
- var data = [];
1212
- pushMatrix();
1213
- translate(config.x, config.y);
1214
- noFill();
1215
- strokeWeight(config.strokeWeight);
1216
- stroke(config.stroke);
1217
- beginShape();
1218
- for(var i = config.domain[0] / config.size; i <= config.domain[1] / config.size; i += config.res) {
1219
- if(func.type === "expl") {
1220
- vertex(i, -Chalkboard.calc.d2fdx2(func, i * config.size) / config.size);
1221
- data.push([i, Chalkboard.calc.d2fdx2(func, i)]);
1222
- } else if(func.type === "inve") {
1223
- vertex(Chalkboard.calc.d2fdx2(func, i * config.size) / config.size, -i);
1224
- data.push([Chalkboard.calc.d2fdx2(func, i), i]);
1225
- }
1226
- }
1227
- endShape();
1228
- popMatrix();
1229
- return data;
1230
- },
1231
- fxdx: function(func, config) {
1232
- (config = {
1233
- x: (config = config || {}).x || width / 2,
1234
- y: config.y || height / 2,
1235
- size: config.size || 1,
1236
- stroke: config.stroke || color(0),
1237
- strokeWeight: config.strokeWeight || 2,
1238
- domain: config.domain || [-10, 10],
1239
- res: config.res || 25
1240
- }).size /= 100;
1241
- var data = [];
1242
- pushMatrix();
1243
- translate(config.x, config.y);
1244
- noFill();
1245
- strokeWeight(config.strokeWeight);
1246
- stroke(config.stroke);
1247
- beginShape();
1248
- for(var i = config.domain[0] / config.size; i <= config.domain[1] / config.size; i += config.res) {
1249
- if(func.type === "expl") {
1250
- vertex(i, -Chalkboard.calc.fxdx(func, 0, i * config.size) / config.size);
1251
- data.push([i, Chalkboard.calc.fxdx(func, 0, i)]);
1252
- } else if(func.type === "inve") {
1253
- vertex(Chalkboard.calc.fxdx(func, 0, i * config.size) / config.size, -i);
1254
- data.push([Chalkboard.calc.fxdx(func, 0, i), i]);
1255
- }
1256
- }
1257
- endShape();
1258
- popMatrix();
1259
- return data;
1260
- },
1261
- convolution: function(func_1, func_2, config) {
1262
- (config = {
1263
- x: (config = config || {}).x || width / 2,
1264
- y: config.y || height / 2,
1265
- size: config.size || 1,
1266
- stroke: config.stroke || color(0),
1267
- strokeWeight: config.strokeWeight || 2,
1268
- domain: config.domain || [-10, 10],
1269
- res: config.res || 25
1270
- }).size /= 100;
1271
- var data = [];
1272
- pushMatrix();
1273
- translate(config.x, config.y);
1274
- noFill();
1275
- strokeWeight(config.strokeWeight);
1276
- stroke(config.stroke);
1277
- beginShape();
1278
- for(var i = config.domain[0] / config.size; i <= config.domain[1] / config.size; i += config.res) {
1279
- vertex(i, -Chalkboard.calc.convolution(func_1, func_2, i * config.size) / config.size);
1280
- data.push([i, Chalkboard.calc.convolution(func_1, func_2, i)]);
1281
- }
1282
- endShape();
1283
- popMatrix();
1284
- return data;
1285
- },
1286
- correlation: function(func_1, func_2, config) {
1287
- (config = {
1288
- x: (config = config || {}).x || width / 2,
1289
- y: config.y || height / 2,
1290
- size: config.size || 1,
1291
- stroke: config.stroke || color(0),
1292
- strokeWeight: config.strokeWeight || 2,
1293
- domain: config.domain || [-10, 10],
1294
- res: config.res || 25
1295
- }).size /= 100;
1296
- var data = [];
1297
- pushMatrix();
1298
- translate(config.x, config.y);
1299
- noFill();
1300
- strokeWeight(config.strokeWeight);
1301
- stroke(config.stroke);
1302
- beginShape();
1303
- for(var i = config.domain[0] / config.size; i <= config.domain[1] / config.size; i += config.res) {
1304
- vertex(i, -Chalkboard.calc.correlation(func_1, func_2, i * config.size) / config.size);
1305
- data.push([i, Chalkboard.calc.correlation(func_1, func_2, i)]);
1306
- }
1307
- endShape();
1308
- popMatrix();
1309
- return data;
1310
- },
1311
- autocorrelation: function(func, config) {
1312
- (config = {
1313
- x: (config = config || {}).x || width / 2,
1314
- y: config.y || height / 2,
1315
- size: config.size || 1,
1316
- stroke: config.stroke || color(0),
1317
- strokeWeight: config.strokeWeight || 2,
1318
- domain: config.domain || [-10, 10],
1319
- res: config.res || 25
1320
- }).size /= 100;
1321
- var data = [];
1322
- pushMatrix();
1323
- translate(config.x, config.y);
1324
- noFill();
1325
- strokeWeight(config.strokeWeight);
1326
- stroke(config.stroke);
1327
- beginShape();
1328
- for(var i = config.domain[0] / config.size; i <= config.domain[1] / config.size; i += config.res) {
1329
- vertex(i, -Chalkboard.calc.autocorrelation(func, i * config.size) / config.size);
1330
- data.push([i, Chalkboard.calc.autocorrelation(func, i)]);
1331
- }
1332
- endShape();
1333
- popMatrix();
1334
- return data;
1335
- },
1336
- Taylor: function(func, n, a, config) {
1337
- (config = {
1338
- x: (config = config || {}).x || width / 2,
1339
- y: config.y || height / 2,
1340
- size: config.size || 1,
1341
- stroke: config.stroke || color(0),
1342
- strokeWeight: config.strokeWeight || 2,
1343
- domain: config.domain || [-10, 10],
1344
- res: config.res || 25
1345
- }).size /= 100;
1346
- var data = [];
1347
- pushMatrix();
1348
- translate(config.x, config.y);
1349
- noFill();
1350
- strokeWeight(config.strokeWeight);
1351
- stroke(config.stroke);
1352
- beginShape();
1353
- for(var i = config.domain[0] / config.size; i <= config.domain[1] / config.size; i += config.res) {
1354
- vertex(i, -Chalkboard.calc.Taylor(func, i * config.size, n, a) / config.size);
1355
- data.push([i, Chalkboard.calc.Taylor(func, i, n, a)]);
1356
- }
1357
- endShape();
1358
- popMatrix();
1359
- return data;
1360
- },
1361
- Laplace: function(func, config) {
1362
- (config = {
1363
- x: (config = config || {}).x || width / 2,
1364
- y: config.y || height / 2,
1365
- size: config.size || 1,
1366
- stroke: config.stroke || color(0),
1367
- strokeWeight: config.strokeWeight || 2,
1368
- domain: config.domain || [-10, 10],
1369
- res: config.res || 25
1370
- }).size /= 100;
1371
- var data = [];
1372
- pushMatrix();
1373
- translate(config.x, config.y);
1374
- noFill();
1375
- strokeWeight(config.strokeWeight);
1376
- stroke(config.stroke);
1377
- beginShape();
1378
- if(config.domain[0] >= 0) {
1379
- for(var i = config.domain[0] / config.size; i <= config.domain[1] / config.size; i += config.res) {
1380
- vertex(i, -Chalkboard.calc.Laplace(func, i * config.size) / config.size);
1381
- data.push([i, Chalkboard.calc.Laplace(func, i)]);
1382
- }
1383
- } else {
1384
- for(var i = 0; i <= config.domain[1] / config.size; i += config.res) {
1385
- vertex(i, -Chalkboard.calc.Laplace(func, i * config.size) / config.size);
1386
- data.push([i, Chalkboard.calc.Laplace(func, i)]);
1387
- }
1388
- }
1389
- endShape();
1390
- popMatrix();
1391
- return data;
1392
- },
1393
- Fourier: function(func, config) {
1394
- (config = {
1395
- x: (config = config || {}).x || width / 2,
1396
- y: config.y || height / 2,
1397
- size: config.size || 1,
1398
- stroke: config.stroke || color(0),
1399
- strokeWeight: config.strokeWeight || 2,
1400
- domain: config.domain || [-10, 10],
1401
- res: config.res || 25
1402
- }).size /= 100;
1403
- var data = [];
1404
- pushMatrix();
1405
- translate(config.x, config.y);
1406
- noFill();
1407
- strokeWeight(config.strokeWeight);
1408
- stroke(config.stroke);
1409
- beginShape();
1410
- for(var i = config.domain[0] / config.size; i <= config.domain[1] / config.size; i += config.res) {
1411
- vertex(i, -Chalkboard.calc.Fourier(func, i * config.size) / config.size);
1412
- data.push([i, Chalkboard.calc.Fourier(func, i)]);
1413
- }
1414
- endShape();
1415
- popMatrix();
1416
- return data;
1417
- }
1418
- },
1419
- geom: {
1420
- EulerCharacteristic: function(v, e, f) {
1421
- return v - e + f;
1422
- },
1423
- Pythagorean: function(a, b, type) {
1424
- type = type || "hyp";
1425
- if(type === "hyp") {
1426
- return Math.sqrt((a * a) + (b * b));
1427
- } else if(type === "leg") {
1428
- return Math.sqrt((b * b) - (a * a));
1429
- } else {
1430
- return undefined;
1431
- }
1432
- },
1433
- PythagoreanTriple: function(inf, sup) {
1434
- var a = 2 * Math.round(Chalkboard.numb.random(inf, sup)) - 1,
1435
- b = ((a * a) / 2) - 0.5,
1436
- c = ((a * a) / 2) + 0.5;
1437
- return a + ", " + b + ", " + c;
1438
- },
1439
- dist: function(p1, p2) {
1440
- if(p1.length === p2.length) {
1441
- var result = 0;
1442
- for(var i = 0; i < p1.length; i++) {
1443
- result += (p1[i] - p2[i]) * (p1[i] - p2[i]);
1444
- }
1445
- return Chalkboard.real.sqrt(result);
1446
- } else {
1447
- return undefined;
1448
- }
1449
- },
1450
- distsq: function(p1, p2) {
1451
- if(p1.length === p2.length) {
1452
- var result = 0;
1453
- for(var i = 0; i < p1.length; i++) {
1454
- result += (p1[i] - p2[i]) * (p1[i] - p2[i]);
1455
- }
1456
- return result;
1457
- } else {
1458
- return undefined;
1459
- }
1460
- },
1461
- mid: function(p1, p2) {
1462
- if(p1.length === p2.length) {
1463
- var result = [];
1464
- for(var i = 0; i < p1.length; i++) {
1465
- result[i] = (p1[i] + p2[i]) / 2;
1466
- }
1467
- return result;
1468
- } else {
1469
- return undefined;
1470
- }
1471
- },
1472
- circleP: function(r) {
1473
- return 2 * Chalkboard.PI() * r;
1474
- },
1475
- circleA: function(r) {
1476
- return Chalkboard.PI() * r * r;
1477
- },
1478
- sectorP: function(r, rad) {
1479
- return r * rad;
1480
- },
1481
- sectorA: function(r, rad) {
1482
- return (r * r * rad) / 2;
1483
- },
1484
- ellipseP: function(a, b) {
1485
- var h = ((a - b) * (a - b)) / ((a + b) * (a + b));
1486
- return Chalkboard.PI() * (a + b) * (1 + (3 * h) / (10 + Math.sqrt(4 - 3 * h)));
1487
- },
1488
- ellipseA: function(a, b) {
1489
- return Chalkboard.PI() * a * b;
1490
- },
1491
- squareP: function(s) {
1492
- return 4 * s;
1493
- },
1494
- squareA: function(s) {
1495
- return s * s;
1496
- },
1497
- parallelogramP: function(l, w) {
1498
- return 2 * (l + w);
1499
- },
1500
- parallelogramA: function(l, w) {
1501
- return l * w;
1502
- },
1503
- triangleP: function(a, b, c) {
1504
- return a + b + c;
1505
- },
1506
- triangleA: function(b, h) {
1507
- return (b * h) / 2;
1508
- },
1509
- trianglesidesA: function(a, b, c) {
1510
- var s = (a + b + c) / 2;
1511
- return Chalkboard.real.sqrt(s * ((s - a) * (s - b) * (s - c)));
1512
- },
1513
- trapezoidP: function(a, b, c, d) {
1514
- return a + b + c + d;
1515
- },
1516
- trapezoidA: function(b1, b2, h) {
1517
- return ((b1 + b2) / 2) * h;
1518
- },
1519
- polygonP: function(n, s) {
1520
- return n * s;
1521
- },
1522
- polygonA: function(n, s, a) {
1523
- return (n * s * a) / 2;
1524
- },
1525
- sphereA: function(r) {
1526
- return 4 * Chalkboard.PI() * r * r;
1527
- },
1528
- sphereV: function(r) {
1529
- return (4 * Chalkboard.PI() * r * r * r) / 3;
1530
- },
1531
- cylinderA: function(r, h) {
1532
- return 2 * Chalkboard.PI() * r * r + 2 * Math.PI * r * h;
1533
- },
1534
- cylinderV: function(r, h) {
1535
- return Chalkboard.PI() * r * r * h;
1536
- },
1537
- coneA: function(r, h) {
1538
- return Chalkboard.PI() * r * (r + Math.sqrt(h * h + r * r));
1539
- },
1540
- coneV: function(r, h) {
1541
- return (Chalkboard.PI() * r * r * h) / 3;
1542
- },
1543
- cubeA: function(s) {
1544
- return 6 * s * s;
1545
- },
1546
- cubeV: function(s) {
1547
- return s * s * s;
1548
- },
1549
- rectangularprismA: function(l, w, h) {
1550
- return 2 * (l * h + l * h + w * h);
1551
- },
1552
- rectangularprismV: function(l, w, h) {
1553
- return l * w * h;
1554
- },
1555
- triangularprismA: function(a, b, c, h) {
1556
- var s = (a + b + c) / 2;
1557
- return 2 * Chalkboard.real.sqrt(s * ((s - a) * (s - b) * (s - c))) + h * (a + b + c);
1558
- },
1559
- triangularprismV: function(a, b, c, h) {
1560
- 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;
1561
- },
1562
- line3D: function(x1, y1, z1, x2, y2, z2) {
1563
- line(x1 / (z1 * 0.0025 + 1), y1 / (z1 * 0.0025 + 1), x2 / (z2 * 0.0025 + 1), y2 / (z2 * 0.0025 + 1));
1564
- }
1565
- },
1566
- trig: {
1567
- toRad: function(deg) {
1568
- return deg * (Chalkboard.PI() / 180);
1569
- },
1570
- toDeg: function(rad) {
1571
- return rad * (180 / Chalkboard.PI());
1572
- },
1573
- coterminal: function(rad) {
1574
- return rad % (2 * Chalkboard.PI());
1575
- },
1576
- sin: function(rad) {
1577
- rad = Chalkboard.trig.coterminal(rad);
1578
- return ((rad) - (Math.pow(rad, 3) / Chalkboard.numb.factorial(3)) + (Math.pow(rad, 5) / Chalkboard.numb.factorial(5)) - (Math.pow(rad, 7) / Chalkboard.numb.factorial(7)) + (Math.pow(rad, 9) / Chalkboard.numb.factorial(9)) - (Math.pow(rad, 11) / Chalkboard.numb.factorial(11)) + (Math.pow(rad, 13) / Chalkboard.numb.factorial(13)) - (Math.pow(rad, 15) / Chalkboard.numb.factorial(15)) + (Math.pow(rad, 17) / Chalkboard.numb.factorial(17)) - (Math.pow(rad, 19) / Chalkboard.numb.factorial(19)) + (Math.pow(rad, 21) / Chalkboard.numb.factorial(21)) - (Math.pow(rad, 23) / Chalkboard.numb.factorial(23)) + (Math.pow(rad, 25) / Chalkboard.numb.factorial(25)) - (Math.pow(rad, 27) / Chalkboard.numb.factorial(27)) + (Math.pow(rad, 29) / Chalkboard.numb.factorial(29)));
1579
- },
1580
- cos: function(rad) {
1581
- rad = Chalkboard.trig.coterminal(rad);
1582
- return ((1) - (Math.pow(rad, 2) / Chalkboard.numb.factorial(2)) + (Math.pow(rad, 4) / Chalkboard.numb.factorial(4)) - (Math.pow(rad, 6) / Chalkboard.numb.factorial(6)) + (Math.pow(rad, 8) / Chalkboard.numb.factorial(8)) - (Math.pow(rad, 10) / Chalkboard.numb.factorial(10)) + (Math.pow(rad, 12) / Chalkboard.numb.factorial(12)) - (Math.pow(rad, 14) / Chalkboard.numb.factorial(14)) + (Math.pow(rad, 16) / Chalkboard.numb.factorial(16)) - (Math.pow(rad, 18) / Chalkboard.numb.factorial(18)) + (Math.pow(rad, 20) / Chalkboard.numb.factorial(20)) - (Math.pow(rad, 22) / Chalkboard.numb.factorial(22)) + (Math.pow(rad, 24) / Chalkboard.numb.factorial(24)) - (Math.pow(rad, 26) / Chalkboard.numb.factorial(26)) + (Math.pow(rad, 28) / Chalkboard.numb.factorial(28)));
1583
- },
1584
- tan: function(rad) {
1585
- return Chalkboard.trig.sin(rad) / Chalkboard.trig.cos(rad);
1586
- },
1587
- csc: function(rad) {
1588
- return 1 / Chalkboard.trig.sin(rad);
1589
- },
1590
- sec: function(rad) {
1591
- return 1 / Chalkboard.trig.cos(rad);
1592
- },
1593
- cot: function(rad) {
1594
- return 1 / Chalkboard.trig.tan(rad);
1595
- },
1596
- sinh: function(rad) {
1597
- return (Math.pow(Chalkboard.E(), rad) - Math.pow(Chalkboard.E(), -rad)) / 2;
1598
- },
1599
- cosh: function(rad) {
1600
- return (Math.pow(Chalkboard.E(), rad) + Math.pow(Chalkboard.E(), -rad)) / 2;
1601
- },
1602
- tanh: function(rad) {
1603
- return Chalkboard.trig.sinh(rad) / Chalkboard.trig.cosh(rad);
1604
- },
1605
- csch: function(rad) {
1606
- return 1 / Chalkboard.trig.sinh(rad);
1607
- },
1608
- sech: function(rad) {
1609
- return 1 / Chalkboard.trig.cosh(rad);
1610
- },
1611
- coth: function(rad) {
1612
- return 1 / Chalkboard.trig.tanh(rad);
1613
- },
1614
- arcsin: function(rad) {
1615
- if(rad > -1 && rad < 1) {
1616
- return Chalkboard.calc.fxdx(Chalkboard.real.function("1 / (Math.sqrt(1 - x * x))"), 0, rad);
1617
- } else if(rad === 1) {
1618
- return Chalkboard.PI() / 2;
1619
- } else if(rad === -1) {
1620
- return -Chalkboard.PI() / 2;
1621
- } else {
1622
- return undefined;
1623
- }
1624
- },
1625
- arccos: function(rad) {
1626
- if(rad > -1 && rad < 1) {
1627
- return Chalkboard.calc.fxdx(Chalkboard.real.function("1 / (Math.sqrt(1 - x * x))"), rad, 1);
1628
- } else if(rad === 1) {
1629
- return 0;
1630
- } else if(rad === -1) {
1631
- return Chalkboard.PI();
1632
- } else {
1633
- return undefined;
1634
- }
1635
- },
1636
- arctan: function(rad) {
1637
- return Chalkboard.calc.fxdx(Chalkboard.real.function("1 / (1 + x * x)"), 0, rad);
1638
- },
1639
- arctan2: function(y, x) {
1640
- if(x === 0) {
1641
- if(y > 0) {
1642
- return Math.PI / 2;
1643
- } else if(y < 0) {
1644
- return -Math.PI / 2;
1645
- } else {
1646
- return 0;
1647
- }
1648
- } else {
1649
- if(x > 0 && y >= 0) {
1650
- return Math.atan(Math.abs(y / x));
1651
- } else if(x < 0 && y >= 0) {
1652
- return Math.PI - Math.atan(Math.abs(y / x));
1653
- } else if(x < 0 && y < 0) {
1654
- return -Math.PI + Math.atan(Math.abs(y / x));
1655
- } else {
1656
- return -Math.atan(Math.abs(y / x));
1657
- }
1658
- }
1659
- },
1660
- arccsc: function(rad) {
1661
- if(rad > 1) {
1662
- return Chalkboard.calc.fxdx(Chalkboard.real.function("1 / (x * Math.sqrt(x * x - 1))"), rad, 1000);
1663
- } else if(rad === 1) {
1664
- return Chalkboard.PI() / 2;
1665
- } else if(rad === -1) {
1666
- return -Chalkboard.PI() / 2;
1667
- } else if(rad < 1) {
1668
- return -Chalkboard.calc.fxdx(Chalkboard.real.function("1 / (x * Math.sqrt(x * x - 1))"), Math.abs(rad), 1000);
1669
- } else {
1670
- return undefined;
1671
- }
1672
- },
1673
- arcsec: function(rad) {
1674
- if(rad > 1) {
1675
- return Chalkboard.calc.fxdx(Chalkboard.real.function("1 / (x * Math.sqrt(x * x - 1))"), 1.000001, rad);
1676
- } else if(rad === 1) {
1677
- return 0;
1678
- } else if(rad === -1) {
1679
- return Chalkboard.PI();
1680
- } else {
1681
- return undefined;
1682
- }
1683
- },
1684
- arccot: function(rad) {
1685
- return Chalkboard.calc.fxdx(Chalkboard.real.function("1 / (1 + x * x)"), rad, 1000);
1686
- },
1687
- arcsinh: function(rad) {
1688
- return Math.log(rad + Math.sqrt(rad * rad + 1));
1689
- },
1690
- arccosh: function(rad) {
1691
- if(rad >= 1) {
1692
- return Math.log(rad + Math.sqrt(rad * rad - 1));
1693
- } else {
1694
- return undefined;
1695
- }
1696
- },
1697
- arctanh: function(rad) {
1698
- if(rad > -1 && rad < 1) {
1699
- return (Math.log((1 + rad) / (1 - rad))) / 2;
1700
- } else {
1701
- return undefined;
1702
- }
1703
- },
1704
- arccsch: function(rad) {
1705
- if(rad !== 0) {
1706
- return Math.log((1 / rad) + Math.sqrt((1 / (rad * rad)) + 1));
1707
- } else {
1708
- return undefined;
1709
- }
1710
- },
1711
- arcsech: function(rad) {
1712
- if(rad > 0 && rad <= 1) {
1713
- return Math.log((1 / rad) + Math.sqrt((1 / (rad * rad)) - 1));
1714
- } else {
1715
- return undefined;
1716
- }
1717
- },
1718
- arccoth: function(rad) {
1719
- if(rad < -1 || rad > 1) {
1720
- return (Math.log((rad + 1) / (rad - 1))) / 2;
1721
- } else {
1722
- return undefined;
1723
- }
1724
- }
1725
- },
1726
- stat: {
1727
- array: function(inf, sup, length) {
1728
- length = length || sup - inf + 1;
1729
- var result = [];
1730
- var step = (sup - inf) / (length - 1);
1731
- for(var i = 0; i < length; i++) {
1732
- result.push(inf + (step * i));
1733
- }
1734
- return result;
1735
- },
1736
- random: function(inf, sup, length) {
1737
- var result = [];
1738
- for(var i = 0; i < length; i++) {
1739
- result.push(Chalkboard.numb.random(inf, sup));
1740
- }
1741
- return result;
1742
- },
1743
- shuffle: function(arr) {
1744
- var index, temp, rindex;
1745
- for(index = arr.length - 1; index > 0; index--) {
1746
- rindex = Math.floor(Chalkboard.numb.random(0, index + 1));
1747
- temp = arr[index];
1748
- arr[index] = arr[rindex];
1749
- arr[rindex] = temp;
1750
- }
1751
- return arr;
1752
- },
1753
- norm: function(arr, type) {
1754
- type = type || "L2";
1755
- var result = 0;
1756
- if(type === "L0") {
1757
- for(var i = 0; i < arr.length; i++) {
1758
- if(arr[i] !== 0) {
1759
- result += 1;
1760
- }
1761
- }
1762
- return result;
1763
- } else if(type === "L1") {
1764
- for(var i = 0; i < arr.length; i++) {
1765
- result += Math.abs(arr[i]);
1766
- }
1767
- return result;
1768
- } else if(type === "L2") {
1769
- for(var i = 0; i < arr.length; i++) {
1770
- result += arr[i] * arr[i];
1771
- }
1772
- return Chalkboard.real.sqrt(result);
1773
- } else if(type === "LInfinity") {
1774
- return Math.abs(Chalkboard.stat.max(arr));
1775
- } else {
1776
- return "TypeError: Parameter \"type\" must be \"L0\", \"L1\", \"L2\", or \"LInfinity\".";
1777
- }
1778
- },
1779
- normsq: function(arr, type) {
1780
- type = type || "L2";
1781
- var result = 0;
1782
- if(type === "L0") {
1783
- for(var i = 0; i < arr.length; i++) {
1784
- if(arr[i] !== 0) {
1785
- result += 1;
1786
- }
1787
- }
1788
- return result * result;
1789
- } else if(type === "L1") {
1790
- for(var i = 0; i < arr.length; i++) {
1791
- result += Math.abs(arr[i]);
1792
- }
1793
- return result * result;
1794
- } else if(type === "L2") {
1795
- for(var i = 0; i < arr.length; i++) {
1796
- result += arr[i] * arr[i];
1797
- }
1798
- return result;
1799
- } else if(type === "LInfinity") {
1800
- return Math.abs(Chalkboard.stat.max(arr)) * Math.abs(Chalkboard.stat.max(arr));
1801
- } else {
1802
- return "TypeError: Parameter \"type\" must be \"L0\", \"L1\", \"L2\", or \"LInfinity\".";
1803
- }
1804
- },
1805
- normalize: function(arr, type) {
1806
- if(type === "L0" || type === "L1" || type === "L2" || type === "LInfinity") {
1807
- var result = [];
1808
- var norm = Chalkboard.stat.norm(arr, type);
1809
- for(var i = 0; i < arr.length; i++) {
1810
- result.push(arr[i] / norm);
1811
- }
1812
- return result;
1813
- } else {
1814
- return "TypeError: Parameter \"type\" must be \"L0\", \"L1\", \"L2\", or \"LInfinity\".";
1815
- }
1816
- },
1817
- constrain: function(arr, range) {
1818
- var result = [];
1819
- for(var i = 0; i < arr.length; i++) {
1820
- result.push(Chalkboard.numb.constrain(arr[i], range));
1821
- }
1822
- return result;
1823
- },
1824
- eq: function(arr, arrORnum) {
1825
- var result = [];
1826
- if(Array.isArray(arrORnum)) {
1827
- if(arr.length === arrORnum.length) {
1828
- for(var i = 0; i < arr.length; i++) {
1829
- if(arr[i] === arrORnum[i]) {
1830
- result.push(arr[i]);
1831
- }
1832
- }
1833
- }
1834
- } else {
1835
- for(var i = 0; i < arr.length; i++) {
1836
- if(arr[i] === arrORnum) {
1837
- result.push(arr[i]);
1838
- }
1839
- }
1840
- }
1841
- return result;
1842
- },
1843
- ineq: function(arr, inf, sup, includeInf, includeSup) {
1844
- includeInf = includeInf || false;
1845
- includeSup = includeSup || false;
1846
- var result = [];
1847
- if(Array.isArray(inf) && Array.isArray(sup)) {
1848
- if(arr.length === inf.length && arr.length === sup.length) {
1849
- for(var i = 0; i < arr.length; i++) {
1850
- if(includeInf) {
1851
- if(includeSup) {
1852
- if(arr[i] >= inf[i] && arr[i] <= sup[i]) {
1853
- result.push(arr[i]);
1854
- }
1855
- } else {
1856
- if(arr[i] >= inf[i] && arr[i] < sup[i]) {
1857
- result.push(arr[i]);
1858
- }
1859
- }
1860
- } else {
1861
- if(includeSup) {
1862
- if(arr[i] > inf[i] && arr[i] <= sup[i]) {
1863
- result.push(arr[i]);
1864
- }
1865
- } else {
1866
- if(arr[i] > inf[i] && arr[i] < sup[i]) {
1867
- result.push(arr[i]);
1868
- }
1869
- }
1870
- }
1871
- }
1872
- }
1873
- } else {
1874
- for(var i = 0; i < arr.length; i++) {
1875
- if(includeInf) {
1876
- if(includeSup) {
1877
- if(arr[i] >= inf && arr[i] <= sup) {
1878
- result.push(arr[i]);
1879
- }
1880
- } else {
1881
- if(arr[i] >= inf && arr[i] < sup) {
1882
- result.push(arr[i]);
1883
- }
1884
- }
1885
- } else {
1886
- if(includeSup) {
1887
- if(arr[i] > inf && arr[i] <= sup) {
1888
- result.push(arr[i]);
1889
- }
1890
- } else {
1891
- if(arr[i] > inf && arr[i] < sup) {
1892
- result.push(arr[i]);
1893
- }
1894
- }
1895
- }
1896
- }
1897
- }
1898
- return result;
1899
- },
1900
- lt: function(arr, arrORnum, includeEnd) {
1901
- includeEnd = includeEnd || false;
1902
- var result = [];
1903
- if(Array.isArray(arrORnum)) {
1904
- if(arr.length === arrORnum.length) {
1905
- for(var i = 0; i < arr.length; i++) {
1906
- if(includeEnd) {
1907
- if(arr[i] <= arrORnum[i]) {
1908
- result.push(arr[i]);
1909
- }
1910
- } else {
1911
- if(arr[i] < arrORnum[i]) {
1912
- result.push(arr[i]);
1913
- }
1914
- }
1915
- }
1916
- }
1917
- } else {
1918
- for(var i = 0; i < arr.length; i++) {
1919
- if(includeEnd) {
1920
- if(arr[i] <= arrORnum) {
1921
- result.push(arr[i]);
1922
- }
1923
- } else {
1924
- if(arr[i] < arrORnum) {
1925
- result.push(arr[i]);
1926
- }
1927
- }
1928
- }
1929
- }
1930
- return result;
1931
- },
1932
- gt: function(arr, arrORnum, includeEnd) {
1933
- includeEnd = includeEnd || false;
1934
- var result = [];
1935
- if(Array.isArray(arrORnum)) {
1936
- if(arr.length === arrORnum.length) {
1937
- for(var i = 0; i < arr.length; i++) {
1938
- if(includeEnd) {
1939
- if(arr[i] >= arrORnum[i]) {
1940
- result.push(arr[i]);
1941
- }
1942
- } else {
1943
- if(arr[i] > arrORnum[i]) {
1944
- result.push(arr[i]);
1945
- }
1946
- }
1947
- }
1948
- }
1949
- } else {
1950
- for(var i = 0; i < arr.length; i++) {
1951
- if(includeEnd) {
1952
- if(arr[i] >= arrORnum) {
1953
- result.push(arr[i]);
1954
- }
1955
- } else {
1956
- if(arr[i] > arrORnum) {
1957
- result.push(arr[i]);
1958
- }
1959
- }
1960
- }
1961
- }
1962
- return result;
1963
- },
1964
- subsets: function(arr) {
1965
- var result = [[]];
1966
- arr.sort();
1967
- for(var i = 0; i < arr.length; i++) {
1968
- if(i === 0 || arr[i] !== arr[i - 1]) {
1969
- var curr = arr[i];
1970
- var subsetsWithCurr = [];
1971
- for(var j = 0; j < result.length; j++) {
1972
- var subset = result[j].slice();
1973
- subset.push(curr);
1974
- subsetsWithCurr.push(subset);
1975
- }
1976
- result = result.concat(subsetsWithCurr);
1977
- }
1978
- }
1979
- return result;
1980
- },
1981
- max: function(arr) {
1982
- var max = arr[0];
1983
- for(var i = 0; i < arr.length; i++) {
1984
- if(arr[i] > max) {
1985
- max = arr[i];
1986
- }
1987
- }
1988
- return max;
1989
- },
1990
- min: function(arr) {
1991
- var min = arr[0];
1992
- for(var i = 0; i < arr.length; i++) {
1993
- if(arr[i] < min) {
1994
- min = arr[i];
1995
- }
1996
- }
1997
- return min;
1998
- },
1999
- range: function(arr) {
2000
- return Chalkboard.stat.max(arr) - Chalkboard.stat.min(arr);
2001
- },
2002
- mean: function(arr, type) {
2003
- type = type || "arithmetic";
2004
- var result = 0;
2005
- if(type === "arithmetic") {
2006
- for(var i = 0; i < arr.length; i++) {
2007
- result += arr[i];
2008
- }
2009
- return result / arr.length;
2010
- } else if(type === "geometric") {
2011
- for(var i = 0; i < arr.length; i++) {
2012
- result *= arr[i];
2013
- }
2014
- return Chalkboard.real.root(Math.abs(result), arr.length);
2015
- } else if(type === "harmonic") {
2016
- for(var i = 0; i < arr.length; i++) {
2017
- result += 1 / arr[i];
2018
- }
2019
- return arr.length / result;
2020
- } else {
2021
- return "TypeError: Parameter \"type\" must be \"arithmetic\", \"geometric\", or \"harmonic\".";
2022
- }
2023
- },
2024
- median: function(arr) {
2025
- var temp = arr.slice().sort(function(a, b) {
2026
- return a - b;
2027
- });
2028
- if(temp.length % 2 === 1) {
2029
- return temp[Math.floor(temp.length / 2)];
2030
- } else {
2031
- return (temp[temp.length / 2] + temp[(temp.length / 2) - 1]) / 2;
2032
- }
2033
- },
2034
- mode: function(arr) {
2035
- var temp = arr.slice().sort(function(a, b) {
2036
- return a - b;
2037
- });
2038
- var bestStr = 1;
2039
- var currStr = 1;
2040
- var bestElm = temp[0];
2041
- var currElm = temp[0];
2042
- for(var i = 1; i < temp.length; i++) {
2043
- if(temp[i - 1] !== temp[i]) {
2044
- if(currStr > bestStr) {
2045
- bestStr = currStr;
2046
- bestElm = currElm;
2047
- }
2048
- currStr = 0;
2049
- currElm = temp[i];
2050
- }
2051
- currStr++;
2052
- }
2053
- if(currStr > bestStr) {
2054
- return currElm;
2055
- } else {
2056
- return bestElm;
2057
- }
2058
- },
2059
- deviation: function(arr) {
2060
- var result = 0;
2061
- for(var i = 0; i < arr.length; i++) {
2062
- result += (arr[i] - Chalkboard.stat.mean(arr)) * (arr[i] - Chalkboard.stat.mean(arr));
2063
- }
2064
- return Chalkboard.real.sqrt(result / arr.length);
2065
- },
2066
- variance: function(arr) {
2067
- var result = 0;
2068
- for(var i = 0; i < arr.length; i++) {
2069
- result += (arr[i] - Chalkboard.stat.mean(arr)) * (arr[i] - Chalkboard.stat.mean(arr));
2070
- }
2071
- return result / arr.length;
2072
- },
2073
- mad: function(arr) {
2074
- var result = 0;
2075
- for(var i = 0; i < arr.length; i++) {
2076
- result += Math.abs(arr[i] - Chalkboard.stat.mean(arr));
2077
- }
2078
- return result / arr.length;
2079
- },
2080
- error: function(arr) {
2081
- return Chalkboard.stat.deviation(arr) / Chalkboard.real.sqrt(arr.length);
2082
- },
2083
- skewness: function(arr) {
2084
- var result = 0;
2085
- var mean = Chalkboard.stat.mean(arr);
2086
- var deviation = Chalkboard.stat.deviation(arr);
2087
- for(var i = 0; i < arr.length; i++) {
2088
- result += (arr[i] - mean) * (arr[i] - mean) * (arr[i] - mean);
2089
- }
2090
- return result / ((arr.length - 1) * (deviation * deviation * deviation));
2091
- },
2092
- kurtosis: function(arr) {
2093
- var result = 0;
2094
- var mean = Chalkboard.stat.mean(arr);
2095
- var deviation = Chalkboard.stat.deviation(arr);
2096
- for(var i = 0; i < arr.length; i++) {
2097
- result += (arr[i] - mean) * (arr[i] - mean) * (arr[i] - mean) * (arr[i] - mean);
2098
- }
2099
- return result / (deviation * deviation * deviation * deviation) - 3;
2100
- },
2101
- confidenceInterval: function(arr) {
2102
- return [Chalkboard.stat.mean(arr) - 1.96 * (Chalkboard.stat.deviation(arr) / Chalkboard.real.sqrt(arr.length)), Chalkboard.stat.mean(arr) + 1.96 * (Chalkboard.stat.deviation(arr) / Chalkboard.real.sqrt(arr.length))];
2103
- },
2104
- percentile: function(arr, num) {
2105
- var result = 0;
2106
- for(var i = 0; i < arr.length; i++) {
2107
- if(num >= arr[i]) {
2108
- result++;
2109
- }
2110
- }
2111
- return (result / arr.length) * 100;
2112
- },
2113
- quartile: function(arr, type) {
2114
- var temp = arr.slice().sort(function(a, b) {
2115
- return a - b;
2116
- });
2117
- var lo = temp.slice(0, Math.floor(temp.length / 2));
2118
- var hi = temp.slice(Math.ceil(temp.length / 2));
2119
- if(type === "Q1") {
2120
- return Chalkboard.stat.median(lo);
2121
- } else if(type === "Q2") {
2122
- return Chalkboard.stat.median(arr);
2123
- } else if(type === "Q3") {
2124
- return Chalkboard.stat.median(hi);
2125
- } else {
2126
- return "TypeError: Parameter \"type\" must be either \"Q1\", \"Q2\", or \"Q3\".";
2127
- }
2128
- },
2129
- convolution: function(arr1, arr2) {
2130
- var result = [];
2131
- for(var i = 0; i < arr1.length + arr2.length - 1; i++) {
2132
- var sum = 0;
2133
- for(var j = Math.max(0, i - arr2.length + 1); j < Math.min(arr1.length, i + 1); j++) {
2134
- sum += arr1[j] * arr2[i - j];
2135
- }
2136
- result.push(sum);
2137
- }
2138
- return result;
2139
- },
2140
- correlation: function(arr1, arr2) {
2141
- var result = [];
2142
- for(var i = 0; i < arr1.length + arr2.length - 1; i++) {
2143
- var sum = 0;
2144
- for(var j = Math.max(0, i - arr2.length + 1); j < Math.min(arr1.length, i + 1); j++) {
2145
- sum += arr1[j] * arr2[arr2.length - 1 - i + j];
2146
- }
2147
- result.push(sum);
2148
- }
2149
- return result;
2150
- },
2151
- autocorrelation: function(arr) {
2152
- return Chalkboard.stat.correlation(arr, arr);
2153
- },
2154
- change: function(initialArr, finalArr) {
2155
- var result = [];
2156
- if(initialArr.length === finalArr.length) {
2157
- for(var i = 0; i < initialArr.length; i++) {
2158
- result.push(Chalkboard.numb.change(initialArr[i], finalArr[i]));
2159
- }
2160
- return result;
2161
- } else {
2162
- return undefined;
2163
- }
2164
- },
2165
- chiSquared: function(observedArr, expectedArr) {
2166
- var result = [];
2167
- if(observedArr.length === expectedArr.length) {
2168
- for(var i = 0; i < observedArr.length; i++) {
2169
- result.push(((observedArr[i] - expectedArr[i]) * (observedArr[i] - expectedArr[i])) / expectedArr[i]);
2170
- }
2171
- return result;
2172
- } else {
2173
- return undefined;
2174
- }
2175
- },
2176
- Gaussian: function(height, mean, deviation) {
2177
- return Chalkboard.real.function(height.toString() + " * Math.exp(-((x - " + mean.toString() + ") * (x - " + mean.toString() + ")) / (2 * " + deviation.toString() + " * " + deviation.toString() + "))");
2178
- },
2179
- regression: function(data, type, degree) {
2180
- type = type || "linear";
2181
- degree = degree || 2;
2182
- if(type === "linear") {
2183
- var x = 0, y = 0;
2184
- var xx = 0, xy = 0;
2185
- for(var i = 0; i < data.length; i++) {
2186
- x += data[i][0];
2187
- y += data[i][1];
2188
- xx += data[i][0] * data[i][0];
2189
- xy += data[i][0] * data[i][1];
2190
- }
2191
- var a = (data.length * xy - x * y) / (data.length * xx - x * x),
2192
- b = (y / data.length) - (a * x) / data.length;
2193
- return Chalkboard.real.function(a + " * x + " + b);
2194
- } else if(type === "polynomial") {
2195
- var A = Chalkboard.matr.new();
2196
- for(var i = 0; i < data.length; i++) {
2197
- A.push([]);
2198
- for(var j = 0; j <= degree; j++) {
2199
- A[i].push(Chalkboard.real.pow(data[i][0], j));
2200
- }
2201
- }
2202
- var AT = Chalkboard.matr.transpose(A);
2203
- var B = Chalkboard.matr.new();
2204
- for(var i = 0; i < data.length; i++) {
2205
- B.push([data[i][1]]);
2206
- }
2207
- var ATA = Chalkboard.matr.mul(AT, A);
2208
- var ATAI = Chalkboard.matr.invert(ATA);
2209
- var x = Chalkboard.matr.mul(Chalkboard.matr.mul(ATAI, AT), B);
2210
- var coeff = [];
2211
- for(var i = 0; i < x.length; i++) {
2212
- coeff.push(x[i][0]);
2213
- }
2214
- var f = coeff[0].toString() + " + " + coeff[1].toString() + " * x";
2215
- for(var i = 2; i <= degree; i++) {
2216
- f += " + " + coeff[i].toString() + " * Math.pow(x, " + i + ")";
2217
- }
2218
- return Chalkboard.real.function(f);
2219
- } else if(type === "power") {
2220
- var arr = [0, 0, 0, 0];
2221
- for(var i = 0; i < data.length; i++) {
2222
- arr[0] += Chalkboard.real.ln(data[i][0]);
2223
- arr[1] += data[i][1] * Chalkboard.real.ln(data[i][0]);
2224
- arr[2] += data[i][1];
2225
- arr[3] += Chalkboard.real.ln(data[i][0]) * Chalkboard.real.ln(data[i][0]);
2226
- }
2227
- 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),
2228
- b = (data.length * arr[1] - arr[2] * arr[0]) / (data.length * arr[3] - arr[0] * arr[0]);
2229
- return Chalkboard.real.function(a + " * Math.pow(x, " + b + ")");
2230
- } else if(type === "exponential") {
2231
- var arr = [0, 0, 0, 0, 0, 0];
2232
- for(var i = 0; i < data.length; i++) {
2233
- arr[0] += data[i][0];
2234
- arr[1] += data[i][1];
2235
- arr[2] += data[i][0] * data[i][0] * data[i][1];
2236
- arr[3] += data[i][1] * Chalkboard.real.ln(data[i][1]);
2237
- arr[4] += data[i][0] & data[i][1] * Chalkboard.real.ln(data[i][1]);
2238
- arr[5] += data[i][0] * data[i][1];
2239
- }
2240
- var a = Chalkboard.E((arr[2] * arr[3] - arr[5] * arr[4]) / (arr[1] * arr[2] - arr[5] * arr[5])),
2241
- b = (arr[1] * arr[4] - arr[5] * arr[3]) / (arr[1] * arr[2] - arr[5] * arr[5]);
2242
- return Chalkboard.real.function(a + "* Math.exp(" + b + " * x)");
2243
- } else if(type === "logarithmic") {
2244
- var arr = [0, 0, 0, 0];
2245
- for(var i = 0; i < data.length; i++) {
2246
- arr[0] += Chalkboard.real.ln(data[i][0]);
2247
- arr[1] += data[i][1] * Chalkboard.real.ln(data[i][0]);
2248
- arr[2] += data[i][1];
2249
- arr[3] += Chalkboard.real.ln(data[i][0]) * Chalkboard.real.ln(data[i][0]);
2250
- }
2251
- var a = (arr[2] - ((data.length * arr[1] - arr[2] * arr[0]) / (data.length * arr[3] - arr[0] * arr[0])) * arr[0]) / data.length,
2252
- b = (data.length * arr[1] - arr[2] * arr[0]) / (data.length * arr[3] - arr[0] * arr[0]);
2253
- return Chalkboard.real.function(a + " + " + b + " * Math.log(x)");
2254
- } else {
2255
- return "TypeError: Parameter \"type\" must be either \"linear\", \"polynomial\", \"power\", \"exponential\", or \"logarithmic\".";
2256
- }
2257
- },
2258
- toVector: function(arr, type, index) {
2259
- if(index === undefined) { index = 0; }
2260
- if(type === "vec2") {
2261
- return Chalkboard.vec2.new(arr[index], arr[index + 1]);
2262
- } else if(type === "vec3") {
2263
- return Chalkboard.vec3.new(arr[index], arr[index + 1], arr[index + 2]);
2264
- } else if(type === "vec4") {
2265
- return Chalkboard.vec4.new(arr[index], arr[index + 1], arr[index + 2], arr[index + 3]);
2266
- } else {
2267
- return "TypeError: Parameter \"type\" should be \"vec2\", \"vec3\", or \"vec4\".";
2268
- }
2269
- },
2270
- toMatrix: function(arr, rows, cols) {
2271
- var result = Chalkboard.matr.new();
2272
- var index = 0;
2273
- for(var i = 0; i < rows; i++) {
2274
- result[i] = [];
2275
- for(var j = 0; j < cols; j++) {
2276
- if(index < arr.length) {
2277
- result[i].push(arr[index]);
2278
- } else {
2279
- result[i].push(0);
2280
- }
2281
- index++;
2282
- }
2283
- }
2284
- return result;
2285
- },
2286
- toTensor: function(arr, size) {
2287
- if(!Array.isArray(size)) {
2288
- size = Array.from(arguments).slice(1);
2289
- }
2290
- return Chalkboard.tens.resize(arr, size);
2291
- },
2292
- toObject: function(arr) {
2293
- var result = {};
2294
- for(var i = 0; i < arr.length; i++) {
2295
- result["_" + i] = arr[i];
2296
- }
2297
- return result;
2298
- },
2299
- toString: function(arr) {
2300
- return "[" + arr.join(", ") + "]";
2301
- },
2302
- print: function(arr) {
2303
- console.log(Chalkboard.stat.toString(arr));
2304
- }
2305
- },
2306
- vec2: {
2307
- new: function(x, y) {
2308
- if(y === undefined) {
2309
- return {x: x, y: x, type: "vec2"};
2310
- } else {
2311
- return {x: x, y: y, type: "vec2"};
2312
- }
2313
- },
2314
- copy: function(vec2) {
2315
- return Object.create(Object.getPrototypeOf(vec2), Object.getOwnPropertyDescriptors(vec2));
2316
- },
2317
- random: function(inf, sup) {
2318
- return Chalkboard.vec2.new(Chalkboard.numb.random(inf, sup), Chalkboard.numb.random(inf, sup));
2319
- },
2320
- mag: function(vec2) {
2321
- return Chalkboard.real.sqrt((vec2.x * vec2.x) + (vec2.y * vec2.y));
2322
- },
2323
- magsq: function(vec2) {
2324
- return (vec2.x * vec2.x) + (vec2.y * vec2.y);
2325
- },
2326
- magset: function(vec2, num) {
2327
- return Chalkboard.vec2.scl(Chalkboard.vec2.normalize(vec2), num);
2328
- },
2329
- ang: function(vec2) {
2330
- return Chalkboard.trig.arctan2(vec2.y, vec2.x);
2331
- },
2332
- slope: function(vec2) {
2333
- return vec2.y / vec2.x;
2334
- },
2335
- azimuth: function(vec2) {
2336
- return Chalkboard.trig.arctan(vec2.x / vec2.y);
2337
- },
2338
- average: function(vec2) {
2339
- return (vec2.x + vec2.y) / 2;
2340
- },
2341
- normalize: function(vec2) {
2342
- return Chalkboard.vec2.new(vec2.x / Chalkboard.vec2.mag(vec2), vec2.y / Chalkboard.vec2.mag(vec2));
2343
- },
2344
- zero: function(vec2) {
2345
- return Chalkboard.vec2.new(vec2.x * 0, vec2.y * 0);
2346
- },
2347
- negate: function(vec2) {
2348
- return Chalkboard.vec2.new(-vec2.x, -vec2.y);
2349
- },
2350
- reciprocate: function(vec2) {
2351
- return Chalkboard.vec2.new(1 / vec2.x, 1 / vec2.y);
2352
- },
2353
- absolute: function(vec2) {
2354
- return Chalkboard.vec2.new(Math.abs(vec2.x), Math.abs(vec2.y));
2355
- },
2356
- round: function(vec2) {
2357
- return Chalkboard.vec2.new(Math.round(vec2.x), Math.round(vec2.y));
2358
- },
2359
- dist: function(vec2_1, vec2_2) {
2360
- return Chalkboard.real.sqrt(((vec2_2.x - vec2_1.x) * (vec2_2.x - vec2_1.x)) + ((vec2_2.y - vec2_1.y) * (vec2_2.y - vec2_1.y)));
2361
- },
2362
- distsq: function(vec2_1, vec2_2) {
2363
- return ((vec2_2.x - vec2_1.x) * (vec2_2.x - vec2_1.x)) + ((vec2_2.y - vec2_1.y) * (vec2_2.y - vec2_1.y));
2364
- },
2365
- angBtwn: function(vec2_1, vec2_2) {
2366
- return Math.acos((Chalkboard.vec2.dot(vec2_1, vec2_2)) / (Chalkboard.vec2.mag(vec2_1) * Chalkboard.vec2.mag(vec2_2)));
2367
- },
2368
- scl: function(vec2, num) {
2369
- return Chalkboard.vec2.new(vec2.x * num, vec2.y * num);
2370
- },
2371
- constrain: function(vec2, range) {
2372
- return Chalkboard.vec2.new(Chalkboard.numb.constrain(vec2.x, range), Chalkboard.numb.constrain(vec2.y, range));
2373
- },
2374
- add: function(vec2_1, vec2_2) {
2375
- return Chalkboard.vec2.new(vec2_1.x + vec2_2.x, vec2_1.y + vec2_2.y);
2376
- },
2377
- sub: function(vec2_1, vec2_2) {
2378
- return Chalkboard.vec2.new(vec2_1.x - vec2_2.x, vec2_1.y - vec2_2.y);
2379
- },
2380
- mid: function(vec2_1, vec2_2) {
2381
- return Chalkboard.vec2.new((vec2_1.x + vec2_2.x) / 2, (vec2_1.y + vec2_2.y) / 2);
2382
- },
2383
- dot: function(vec2_1, vec2_2) {
2384
- return (vec2_1.x * vec2_2.x) + (vec2_1.y * vec2_2.y);
2385
- },
2386
- cross: function(vec2_1, vec2_2) {
2387
- return Chalkboard.vec3.new(0, 0, (vec2_1.x * vec2_2.y) - (vec2_1.y * vec2_2.x));
2388
- },
2389
- proj: function(vec2_1, vec2_2) {
2390
- return Chalkboard.vec2.scl(vec2_2, Chalkboard.vec2.dot(vec2_1, vec2_2) / Chalkboard.vec2.dot(vec2_2, vec2_2));
2391
- },
2392
- oproj: function(vec2_1, vec2_2) {
2393
- return Chalkboard.vec2.sub(vec2_1, Chalkboard.vec2.proj(vec2_1, vec2_2));
2394
- },
2395
- reflect: function(vec2_1, vec2_2) {
2396
- return Chalkboard.vec2.sub(vec2_1, Chalkboard.vec2.scl(vec2_2, 2 * Chalkboard.vec2.dot(vec2_1, vec2_2)));
2397
- },
2398
- refract: function(vec2_1, vec2_2, refractiveIndex) {
2399
- if(refractiveIndex > 0) {
2400
- var perp = Chalkboard.vec2.scl(Chalkboard.vec2.sub(vec2_1, Chalkboard.vec2.scl(vec2_2, Chalkboard.vec2.dot(vec2_1, vec2_2))), refractiveIndex);
2401
- var parr = Chalkboard.vec2.scl(vec2_2, -Chalkboard.real.sqrt(1 - (refractiveIndex * refractiveIndex) * (1 - (Chalkboard.vec2.dot(vec2_1, vec2_2) * Chalkboard.vec2.dot(vec2_1, vec2_2)))));
2402
- return Chalkboard.vec2.add(perp, parr);
2403
- } else {
2404
- return undefined;
2405
- }
2406
- },
2407
- fromAngle: function(rad) {
2408
- return Chalkboard.vec2.new(Chalkboard.trig.cos(rad), Chalkboard.trig.sin(rad));
2409
- },
2410
- fromPolar: function(vec2) {
2411
- return Chalkboard.vec2.new(vec2.x * Chalkboard.trig.cos(vec2.y), vec2.x * Chalkboard.trig.sin(vec2.y));
2412
- },
2413
- fromBipolar: function(vec2) {
2414
- return Chalkboard.vec2.new((vec2.x * vec2.x - vec2.y * vec2.y) / 4, Chalkboard.real.sqrt(16 * vec2.x * vec2.x - (vec2.x * vec2.x - vec2.y * vec2.y + 4) * (vec2.x * vec2.x - vec2.y * vec2.y + 4)));
2415
- },
2416
- toPolar: function(vec2) {
2417
- return Chalkboard.vec2.new(Chalkboard.vec2.mag(vec2), Chalkboard.vec2.ang(vec2));
2418
- },
2419
- toBipolar: function(vec2) {
2420
- return Chalkboard.vec2.new((vec2.x + 1) * (vec2.x + 1) + (vec2.y * vec2.y), (vec2.x - 1) * (vec2.x - 1) + (vec2.y * vec2.y));
2421
- },
2422
- toMatrix: function(vec2, type) {
2423
- type = type || "col";
2424
- if(type === "col") {
2425
- return Chalkboard.matr.new([vec2.x], [vec2.y]);
2426
- } else if(type === "row") {
2427
- return Chalkboard.matr.new([vec2.x, vec2.y]);
2428
- } else {
2429
- return "TypeError: Parameter \"type\" should be \"row\" or \"col\".";
2430
- }
2431
- },
2432
- toComplex: function(vec2) {
2433
- return Chalkboard.comp.new(vec2.x, vec2.y);
2434
- },
2435
- toArray: function(vec2) {
2436
- return [vec2.x, vec2.y];
2437
- },
2438
- toString: function(vec2) {
2439
- return "(" + vec2.x.toString() + ", " + vec2.y.toString() + ")";
2440
- },
2441
- field: function(p, q) {
2442
- return {p: p, q: q, type: "vec2field"};
2443
- },
2444
- fromField: function(vec2field, vec2) {
2445
- var p = Chalkboard.real.parse("(x, y) => " + vec2field.p),
2446
- q = Chalkboard.real.parse("(x, y) => " + vec2field.q);
2447
- return Chalkboard.vec2.new(p(vec2.x, vec2.y), q(vec2.x, vec2.y));
2448
- },
2449
- print: function(vec2) {
2450
- console.log(Chalkboard.vec2.toString(vec2));
2451
- }
2452
- },
2453
- vec3: {
2454
- new: function(x, y, z) {
2455
- if(y === undefined && z === undefined) {
2456
- return {x: x, y: x, z: x, type: "vec3"};
2457
- } else {
2458
- return {x: x, y: y, z: z, type: "vec3"};
2459
- }
2460
- },
2461
- copy: function(vec3) {
2462
- return Object.create(Object.getPrototypeOf(vec3), Object.getOwnPropertyDescriptors(vec3));
2463
- },
2464
- random: function(inf, sup) {
2465
- return Chalkboard.vec3.new(Chalkboard.numb.random(inf, sup), Chalkboard.numb.random(inf, sup), Chalkboard.numb.random(inf, sup));
2466
- },
2467
- mag: function(vec3) {
2468
- return Chalkboard.real.sqrt((vec3.x * vec3.x) + (vec3.y * vec3.y) + (vec3.z * vec3.z));
2469
- },
2470
- magsq: function(vec3) {
2471
- return (vec3.x * vec3.x) + (vec3.y * vec3.y) + (vec3.z * vec3.z);
2472
- },
2473
- magset: function(vec3, num) {
2474
- return Chalkboard.vec3.scl(Chalkboard.vec3.normalize(vec3), num);
2475
- },
2476
- ang: function(vec3) {
2477
- return [Math.acos(vec3.x / Chalkboard.vec3.mag(vec3)), Math.acos(vec3.y / Chalkboard.vec3.mag(vec3)), Math.acos(vec3.z / Chalkboard.vec3.mag(vec3))];
2478
- },
2479
- slope: function(vec3) {
2480
- return vec3.z / Chalkboard.real.sqrt((vec3.x * vec3.x) + (vec3.y * vec3.y));
2481
- },
2482
- azimuth: function(vec3) {
2483
- return Chalkboard.trig.arctan(vec3.x / vec3.y);
2484
- },
2485
- average: function(vec3) {
2486
- return (vec3.x + vec3.y + vec3.z) / 3;
2487
- },
2488
- normalize: function(vec3) {
2489
- return Chalkboard.vec3.new(vec3.x / Chalkboard.vec3.mag(vec3), vec3.y / Chalkboard.vec3.mag(vec3), vec3.z / Chalkboard.vec3.mag(vec3));
2490
- },
2491
- zero: function(vec3) {
2492
- return Chalkboard.vec3.new(vec3.x * 0, vec3.y * 0, vec3.z * 0);
2493
- },
2494
- negate: function(vec3) {
2495
- return Chalkboard.vec3.new(-vec3.x, -vec3.y, -vec3.z);
2496
- },
2497
- reciprocate: function(vec3) {
2498
- return Chalkboard.vec3.new(1 / vec3.x, 1 / vec3.y, 1 / vec3.z);
2499
- },
2500
- absolute: function(vec3) {
2501
- return Chalkboard.vec3.new(Math.abs(vec3.x), Math.abs(vec3.y), Math.abs(vec3.z));
2502
- },
2503
- round: function(vec3) {
2504
- return Chalkboard.vec3.new(Math.round(vec3.x), Math.round(vec3.y), Math.round(vec3.z));
2505
- },
2506
- dist: function(vec3_1, vec3_2) {
2507
- return Chalkboard.real.sqrt(((vec3_2.x - vec3_1.x) * (vec3_2.x - vec3_1.x)) + ((vec3_2.y - vec3_1.y) * (vec3_2.y - vec3_1.y)) + ((vec3_2.z - vec3_1.z) * (vec3_2.z - vec3_1.z)));
2508
- },
2509
- distsq: function(vec3_1, vec3_2) {
2510
- return ((vec3_2.x - vec3_1.x) * (vec3_2.x - vec3_1.x)) + ((vec3_2.y - vec3_1.y) * (vec3_2.y - vec3_1.y)) + ((vec3_2.z - vec3_1.z) * (vec3_2.z - vec3_1.z));
2511
- },
2512
- angBtwn: function(vec3_1, vec3_2) {
2513
- return Math.acos((Chalkboard.vec3.dot(vec3_1, vec3_2)) / (Chalkboard.vec3.mag(vec3_1) * Chalkboard.vec3.mag(vec3_2)));
2514
- },
2515
- scl: function(vec3, num) {
2516
- return Chalkboard.vec3.new(vec3.x * num, vec3.y * num, vec3.z * num);
2517
- },
2518
- constrain: function(vec3, range) {
2519
- return Chalkboard.vec3.new(Chalkboard.numb.constrain(vec3.x, range), Chalkboard.numb.constrain(vec3.y, range), Chalkboard.numb.constrain(vec3.z, range));
2520
- },
2521
- add: function(vec3_1, vec3_2) {
2522
- return Chalkboard.vec3.new(vec3_1.x + vec3_2.x, vec3_1.y + vec3_2.y, vec3_1.z + vec3_2.z);
2523
- },
2524
- sub: function(vec3_1, vec3_2) {
2525
- return Chalkboard.vec3.new(vec3_1.x - vec3_2.x, vec3_1.y - vec3_2.y, vec3_1.z - vec3_2.z);
2526
- },
2527
- mid: function(vec3_1, vec3_2) {
2528
- return Chalkboard.vec3.new((vec3_1.x + vec3_2.x) / 2, (vec3_1.y + vec3_2.y) / 2, (vec3_1.z + vec3_2.z) / 2);
2529
- },
2530
- dot: function(vec3_1, vec3_2) {
2531
- return (vec3_1.x * vec3_2.x) + (vec3_1.y * vec3_2.y) + (vec3_1.z * vec3_2.z);
2532
- },
2533
- cross: function(vec3_1, vec3_2) {
2534
- return Chalkboard.vec3.new((vec3_1.y * vec3_2.z) - (vec3_1.z * vec3_2.y), (vec3_1.z * vec3_2.x) - (vec3_1.x * vec3_2.z), (vec3_1.x * vec3_2.y) - (vec3_1.y * vec3_2.x));
2535
- },
2536
- scalarTriple: function(vec3_1, vec3_2, vec3_3) {
2537
- return Chalkboard.vec3.dot(vec3_1, Chalkboard.vec3.cross(vec3_2, vec3_3));
2538
- },
2539
- vectorTriple: function(vec3_1, vec3_2, vec3_3) {
2540
- return Chalkboard.vec3.cross(vec3_1, Chalkboard.vec3.cross(vec3_2, vec3_3));
2541
- },
2542
- proj: function(vec3_1, vec3_2) {
2543
- return Chalkboard.vec3.scl(vec3_2, Chalkboard.vec3.dot(vec3_1, vec3_2) / Chalkboard.vec3.dot(vec3_2, vec3_2));
2544
- },
2545
- oproj: function(vec3_1, vec3_2) {
2546
- return Chalkboard.vec3.sub(vec3_1, Chalkboard.vec3.proj(vec3_1, vec3_2));
2547
- },
2548
- reflect: function(vec3_1, vec3_2) {
2549
- return Chalkboard.vec3.sub(vec3_1, Chalkboard.vec3.scl(vec3_2, 2 * Chalkboard.vec3.dot(vec3_1, vec3_2)));
2550
- },
2551
- refract: function(vec3_1, vec3_2, refractiveIndex) {
2552
- if(refractiveIndex > 0) {
2553
- var perp = Chalkboard.vec3.scl(Chalkboard.vec3.sub(vec3_1, Chalkboard.vec3.scl(vec3_2, Chalkboard.vec3.dot(vec3_1, vec3_2))), refractiveIndex);
2554
- var parr = Chalkboard.vec3.scl(vec3_2, -Chalkboard.real.sqrt(1 - (refractiveIndex * refractiveIndex) * (1 - (Chalkboard.vec3.dot(vec3_1, vec3_2) * Chalkboard.vec3.dot(vec3_1, vec3_2)))));
2555
- return Chalkboard.vec3.add(perp, parr);
2556
- } else {
2557
- return undefined;
2558
- }
2559
- },
2560
- fromAngles: function(rad1, rad2) {
2561
- return Chalkboard.vec3.new(Chalkboard.trig.cos(rad1) * Chalkboard.trig.cos(rad2), Chalkboard.trig.sin(rad1) * Chalkboard.trig.cos(rad2), Chalkboard.trig.sin(rad2));
2562
- },
2563
- fromVector: function(vec2) {
2564
- return Chalkboard.vec3.new(vec2.x, vec2.y, 0);
2565
- },
2566
- fromCylindrical: function(vec3) {
2567
- return Chalkboard.vec3.new(vec3.x * Chalkboard.trig.cos(vec3.y), vec3.x * Chalkboard.trig.sin(vec3.y), vec3.z);
2568
- },
2569
- fromSpherical: function(vec3) {
2570
- return Chalkboard.vec3.new(vec3.x * Chalkboard.trig.sin(vec3.z) * Chalkboard.trig.cos(vec3.y), vec3.x * Chalkboard.trig.sin(vec3.z) * Chalkboard.trig.sin(vec3.y), vec3.x * Chalkboard.trig.cos(vec3.z));
2571
- },
2572
- toCylindrical: function(vec3) {
2573
- return Chalkboard.vec3.new(Chalkboard.vec2.mag(vec3), Chalkboard.vec2.ang(vec3), vec3.z);
2574
- },
2575
- toSpherical: function(vec3) {
2576
- return Chalkboard.vec3.new(Chalkboard.vec3.mag(vec3), Chalkboard.vec2.ang(vec3), Chalkboard.vec3.ang(vec3)[2]);
2577
- },
2578
- toMatrix: function(vec3, type) {
2579
- type = type || "col";
2580
- if(type === "col") {
2581
- return Chalkboard.matr.new([vec3.x], [vec3.y], [vec3.z]);
2582
- } else if(type === "row") {
2583
- return Chalkboard.matr.new([vec3.x, vec3.y, vec3.z]);
2584
- } else {
2585
- return "TypeError: Parameter \"type\" should be \"row\" or \"col\".";
2586
- }
2587
- },
2588
- toArray: function(vec3) {
2589
- return [vec3.x, vec3.y, vec3.z];
2590
- },
2591
- toString: function(vec3) {
2592
- return "(" + vec3.x.toString() + ", " + vec3.y.toString() + ", " + vec3.z.toString() + ")";
2593
- },
2594
- field: function(p, q, r) {
2595
- return {p: p, q: q, r: r, type: "vec3field"};
2596
- },
2597
- fromField: function(vec3field, vec3) {
2598
- var p = Chalkboard.real.parse("(x, y, z) => " + vec3field.p),
2599
- q = Chalkboard.real.parse("(x, y, z) => " + vec3field.q),
2600
- r = Chalkboard.real.parse("(x, y, z) => " + vec3field.r);
2601
- return Chalkboard.vec3.new(p(vec3.x, vec3.y, vec3.z), q(vec3.x, vec3.y, vec3.z), r(vec3.x, vec3.y, vec3.z));
2602
- },
2603
- print: function(vec3) {
2604
- console.log(Chalkboard.vec3.toString(vec3));
2605
- }
2606
- },
2607
- vec4: {
2608
- new: function(x, y, z, w) {
2609
- if(y === undefined && z === undefined && w === undefined) {
2610
- return {x: x, y: x, z: x, w: x, type: "vec4"};
2611
- } else {
2612
- return {x: x, y: y, z: z, w: w, type: "vec4"};
2613
- }
2614
- },
2615
- copy: function(vec4) {
2616
- return Object.create(Object.getPrototypeOf(vec4), Object.getOwnPropertyDescriptors(vec4));
2617
- },
2618
- random: function(inf, sup) {
2619
- return Chalkboard.vec4.new(Chalkboard.numb.random(inf, sup), Chalkboard.numb.random(inf, sup), Chalkboard.numb.random(inf, sup), Chalkboard.numb.random(inf, sup));
2620
- },
2621
- mag: function(vec4) {
2622
- return Chalkboard.real.sqrt((vec4.x * vec4.x) + (vec4.y * vec4.y) + (vec4.z * vec4.z) + (vec4.w * vec4.w));
2623
- },
2624
- magsq: function(vec4) {
2625
- return (vec4.x * vec4.x) + (vec4.y * vec4.y) + (vec4.z * vec4.z) + (vec4.w * vec4.w);
2626
- },
2627
- magset: function(vec4, num) {
2628
- return Chalkboard.vec4.scl(Chalkboard.vec4.normalize(vec4), num);
2629
- },
2630
- ang: function(vec4) {
2631
- return [Math.acos(vec4.x / Chalkboard.vec4.mag(vec4)), Math.acos(vec4.y / Chalkboard.vec4.mag(vec4)), Math.acos(vec4.z / Chalkboard.vec4.mag(vec4)), Math.acos(vec4.w / Chalkboard.vec4.mag(vec4))];
2632
- },
2633
- slope: function(vec4) {
2634
- return vec4.w / Chalkboard.real.sqrt((vec4.x * vec4.x) + (vec4.y * vec4.y) + (vec4.z * vec4.z));
2635
- },
2636
- average: function(vec4) {
2637
- return (vec4.x + vec4.y + vec4.z + vec4.w) / 4;
2638
- },
2639
- normalize: function(vec4) {
2640
- return Chalkboard.vec4.new(vec4.x / Chalkboard.vec4.mag(vec4), vec4.y / Chalkboard.vec4.mag(vec4), vec4.z / Chalkboard.vec4.mag(vec4), vec4.w / Chalkboard.vec4.mag(vec4));
2641
- },
2642
- zero: function(vec4) {
2643
- return Chalkboard.vec4.new(vec4.x * 0, vec4.y * 0, vec4.z * 0, vec4.w * 0);
2644
- },
2645
- negate: function(vec4) {
2646
- return Chalkboard.vec4.new(-vec4.x, -vec4.y, -vec4.z, -vec4.w);
2647
- },
2648
- reciprocate: function(vec4) {
2649
- return Chalkboard.vec4.new(1 / vec4.x, 1 / vec4.y, 1 / vec4.z, 1 / vec4.w);
2650
- },
2651
- absolute: function(vec4) {
2652
- return Chalkboard.vec4.new(Math.abs(vec4.x), Math.abs(vec4.y), Math.abs(vec4.z), Math.abs(vec4.w));
2653
- },
2654
- round: function(vec4) {
2655
- return Chalkboard.vec4.new(Math.round(vec4.x), Math.round(vec4.y), Math.round(vec4.z), Math.round(vec4.w));
2656
- },
2657
- dist: function(vec4_1, vec4_2) {
2658
- return Chalkboard.real.sqrt(((vec4_2.x - vec4_1.x) * (vec4_2.x - vec4_1.x)) + ((vec4_2.y - vec4_1.y) * (vec4_2.y - vec4_1.y)) + ((vec4_2.z - vec4_1.z) * (vec4_2.z - vec4_1.z)) + ((vec4_2.w - vec4_1.w) * (vec4_2.w - vec4_1.w)));
2659
- },
2660
- distsq: function(vec4_1, vec4_2) {
2661
- return ((vec4_2.x - vec4_1.x) * (vec4_2.x - vec4_1.x)) + ((vec4_2.y - vec4_1.y) * (vec4_2.y - vec4_1.y)) + ((vec4_2.z - vec4_1.z) * (vec4_2.z - vec4_1.z)) + ((vec4_2.w - vec4_1.w) * (vec4_2.w - vec4_1.w));
2662
- },
2663
- angBtwn: function(vec4_1, vec4_2) {
2664
- return Math.acos((Chalkboard.vec4.dot(vec4_1, vec4_2)) / (Chalkboard.vec4.mag(vec4_1) * Chalkboard.vec4.mag(vec4_2)));
2665
- },
2666
- scl: function(vec4, num) {
2667
- return Chalkboard.vec4.new(vec4.x * num, vec4.y * num, vec4.z * num, vec4.w * num);
2668
- },
2669
- constrain: function(vec4, range) {
2670
- return Chalkboard.vec4.new(Chalkboard.numb.constrain(vec4.x, range), Chalkboard.numb.constrain(vec4.y, range), Chalkboard.numb.constrain(vec4.z, range), Chalkboard.numb.constrain(vec4.w, range));
2671
- },
2672
- add: function(vec4_1, vec4_2) {
2673
- return Chalkboard.vec4.new(vec4_1.x + vec4_2.x, vec4_1.y + vec4_2.y, vec4_1.z + vec4_2.z, vec4_1.w + vec4_2.w);
2674
- },
2675
- sub: function(vec4_1, vec4_2) {
2676
- return Chalkboard.vec4.new(vec4_1.x - vec4_2.x, vec4_1.y - vec4_2.y, vec4_1.z - vec4_2.z, vec4_1.w - vec4_2.w);
2677
- },
2678
- mid: function(vec4_1, vec4_2) {
2679
- return Chalkboard.vec4.new((vec4_1.x + vec4_2.x) / 2, (vec4_1.y + vec4_2.y) / 2, (vec4_1.z + vec4_2.z) / 2, (vec4_1.w + vec4_2.w) / 2);
2680
- },
2681
- dot: function(vec4_1, vec4_2) {
2682
- return (vec4_1.x * vec4_2.x) + (vec4_1.y * vec4_2.y) + (vec4_1.z * vec4_2.z) + (vec4_1.w * vec4_2.w);
2683
- },
2684
- proj: function(vec4_1, vec4_2) {
2685
- return Chalkboard.vec4.scl(vec4_2, Chalkboard.vec4.dot(vec4_1, vec4_2) / Chalkboard.vec4.dot(vec4_2, vec4_2));
2686
- },
2687
- oproj: function(vec4_1, vec4_2) {
2688
- return Chalkboard.vec4.sub(vec4_1, Chalkboard.vec4.proj(vec4_1, vec4_2));
2689
- },
2690
- reflect: function(vec4_1, vec4_2) {
2691
- return Chalkboard.vec4.sub(vec4_1, Chalkboard.vec4.scl(vec4_2, 2 * Chalkboard.vec4.dot(vec4_1, vec4_2)));
2692
- },
2693
- refract: function(vec4_1, vec4_2, refractiveIndex) {
2694
- if(refractiveIndex > 0) {
2695
- var perp = Chalkboard.vec4.scl(Chalkboard.vec4.sub(vec4_1, Chalkboard.vec4.scl(vec4_2, Chalkboard.vec4.dot(vec4_1, vec4_2))), refractiveIndex);
2696
- var parr = Chalkboard.vec4.scl(vec4_2, -Chalkboard.real.sqrt(1 - (refractiveIndex * refractiveIndex) * (1 - (Chalkboard.vec4.dot(vec4_1, vec4_2) * Chalkboard.vec4.dot(vec4_1, vec4_2)))));
2697
- return Chalkboard.vec4.add(perp, parr);
2698
- } else {
2699
- return undefined;
2700
- }
2701
- },
2702
- fromVector: function(vec3) {
2703
- return Chalkboard.vec4.new(vec3.x, vec3.y, vec3.z, 0);
2704
- },
2705
- fromHypercylindrical: function(vec4) {
2706
- return Chalkboard.vec4.new(vec4.x * Chalkboard.trig.cos(vec4.y) * Chalkboard.trig.cos(vec4.z), vec4.x * Chalkboard.trig.cos(vec4.y) * Chalkboard.trig.sin(vec4.z), vec4.x * Chalkboard.trig.sin(vec4.y), vec4.w);
2707
- },
2708
- fromHyperspherical: function(vec4) {
2709
- return Chalkboard.vec4.new(vec4.x * Chalkboard.trig.cos(vec4.y) * Chalkboard.trig.cos(vec4.z) * Chalkboard.trig.cos(vec4.w), vec4.x * Chalkboard.trig.cos(vec4.y) * Chalkboard.trig.sin(vec4.z) * Chalkboard.trig.cos(vec4.w), vec4.x * Chalkboard.trig.sin(vec4.y) * Chalkboard.trig.cos(vec4.w), vec4.x * Chalkboard.trig.sin(vec4.w));
2710
- },
2711
- toHypercylindrical: function(vec4) {
2712
- return Chalkboard.vec4.new(Chalkboard.vec3.mag(vec4), Chalkboard.vec2.ang(vec4), Chalkboard.vec3.ang(vec4)[2], vec4.w);
2713
- },
2714
- toHyperspherical: function(vec4) {
2715
- return Chalkboard.vec4.new(Chalkboard.vec4.mag(vec4), Chalkboard.vec2.ang(vec4), Chalkboard.vec3.ang(vec4)[2], Chalkboard.vec4.ang(vec4)[3]);
2716
- },
2717
- toMatrix: function(vec4, type) {
2718
- type = type || "col";
2719
- if(type === "col") {
2720
- return Chalkboard.matr.new([vec4.x], [vec4.y], [vec4.z], [vec4.w]);
2721
- } else if(type === "row") {
2722
- return Chalkboard.matr.new([vec4.x, vec4.y, vec4.z, vec4.w]);
2723
- } else {
2724
- return "TypeError: Parameter \"type\" should be \"row\" or \"col\".";
2725
- }
2726
- },
2727
- toQuaternion: function(vec4) {
2728
- return Chalkboard.quat.new(vec4.x, vec4.y, vec4.z, vec4.w);
2729
- },
2730
- toArray: function(vec4) {
2731
- return [vec4.x, vec4.y, vec4.z, vec4.w];
2732
- },
2733
- toString: function(vec4) {
2734
- return "(" + vec4.x.toString() + ", " + vec4.y.toString() + ", " + vec4.z.toString() + ", " + vec4.w.toString() + ")";
2735
- },
2736
- field: function(p, q, r, s) {
2737
- return {p: p, q: q, r: r, s: s, type: "vec4field"};
2738
- },
2739
- fromField: function(vec4field, vec4) {
2740
- var p = Chalkboard.real.parse("(x, y, z, w) => " + vec4field.p),
2741
- q = Chalkboard.real.parse("(x, y, z, w) => " + vec4field.q),
2742
- r = Chalkboard.real.parse("(x, y, z, w) => " + vec4field.r),
2743
- s = Chalkboard.real.parse("(x, y, z, w) => " + vec4field.s);
2744
- return Chalkboard.vec4.new(p(vec4.x, vec4.y, vec4.z, vec4.w), q(vec4.x, vec4.y, vec4.z, vec4.w), r(vec4.x, vec4.y, vec4.z, vec4.w), s(vec4.x, vec4.y, vec4.z, vec4.w));
2745
- },
2746
- print: function(vec4) {
2747
- console.log(Chalkboard.vec4.toString(vec4));
2748
- }
2749
- },
2750
- matr: {
2751
- new: function(matrix) {
2752
- if(arguments.length === 0) {
2753
- return [];
2754
- } else if(Array.isArray(matrix) && Array.isArray(matrix[0])) {
2755
- return matrix;
2756
- } else {
2757
- return Array.from(arguments);
2758
- }
2759
- },
2760
- copy: function(matr) {
2761
- var result = Chalkboard.matr.new();
2762
- for(var i = 0; i < Chalkboard.matr.rows(matr); i++) {
2763
- result.push([]);
2764
- for(var j = 0; j < Chalkboard.matr.cols(matr); j++) {
2765
- result[i].push(matr[i][j]);
2766
- }
2767
- }
2768
- return result;
2769
- },
2770
- rows: function(matr) {
2771
- return matr.length;
2772
- },
2773
- cols: function(matr) {
2774
- return matr[0].length;
2775
- },
2776
- resize: function(matr, rows, cols) {
2777
- if(cols === undefined) {
2778
- cols = rows;
2779
- }
2780
- var result = Chalkboard.matr.new();
2781
- var flat = Chalkboard.matr.toArray(matr);
2782
- var index = 0;
2783
- for(var i = 0; i < rows; i++) {
2784
- result.push([]);
2785
- for(var j = 0; j < cols; j++) {
2786
- result[i].push(index < flat.length ? flat[index++] : 0);
2787
- }
2788
- }
2789
- return result;
2790
- },
2791
- push: function(matr, type, rowORcol, elements) {
2792
- rowORcol -= 1;
2793
- if(type === "row") {
2794
- matr.splice(rowORcol, 0, elements);
2795
- return matr;
2796
- } else if(type === "col") {
2797
- for(var i = 0; i < Chalkboard.matr.rows(matr); i++) {
2798
- matr[i].splice(rowORcol, 0, elements[i]);
2799
- }
2800
- return matr;
2801
- } else {
2802
- return "TypeError: Parameter \"type\" must be either \"row\" or \"col\".";
2803
- }
2804
- },
2805
- pull: function(matr, type, rowORcol) {
2806
- rowORcol -= 1;
2807
- if(type === "row") {
2808
- matr.splice(rowORcol, 1);
2809
- return matr;
2810
- } else if(type === "col") {
2811
- for(var i = 0; i < Chalkboard.matr.rows(matr); i++) {
2812
- matr[i].splice(rowORcol, 1);
2813
- }
2814
- return matr;
2815
- } else {
2816
- return "TypeError: Parameter \"type\" must be either \"row\" or \"col\".";
2817
- }
2818
- },
2819
- fill: function(element, rows, cols) {
2820
- if(cols === undefined) {
2821
- cols = rows;
2822
- }
2823
- if(Number.isInteger(rows) && Number.isInteger(cols) && rows > 0 && cols > 0) {
2824
- var result = Chalkboard.matr.new();
2825
- for(var i = 0; i < rows; i++) {
2826
- result.push([]);
2827
- for(var j = 0; j < cols; j++) {
2828
- result[i].push(element);
2829
- }
2830
- }
2831
- return result;
2832
- } else {
2833
- return undefined;
2834
- }
2835
- },
2836
- empty: function(rows, cols) {
2837
- if(cols === undefined) {
2838
- cols = rows;
2839
- }
2840
- if(Number.isInteger(rows) && Number.isInteger(cols) && rows > 0 && cols > 0) {
2841
- var result = Chalkboard.matr.new();
2842
- for(var i = 0; i < rows; i++) {
2843
- result.push([]);
2844
- for(var j = 0; j < cols; j++) {
2845
- result[i].push(null);
2846
- }
2847
- }
2848
- return result;
2849
- } else {
2850
- return undefined;
2851
- }
2852
- },
2853
- identity: function(size) {
2854
- if(Number.isInteger(size) && size > 0) {
2855
- var result = Chalkboard.matr.new();
2856
- for(var i = 0; i < size; i++) {
2857
- result.push(Array(size).fill(0));
2858
- result[i][i] = 1;
2859
- }
2860
- return result;
2861
- } else {
2862
- return undefined;
2863
- }
2864
- },
2865
- exchange: function(size) {
2866
- if(Number.isInteger(size) && size > 0) {
2867
- var result = Chalkboard.matr.fill(0, size, size);
2868
- for(var i = 0; i < size; i++) {
2869
- for(var j = 0; j < size; j++) {
2870
- if(i + j === size - 1) {
2871
- result[i][j] = 1;
2872
- }
2873
- }
2874
- }
2875
- return result;
2876
- } else {
2877
- return undefined;
2878
- }
2879
- },
2880
- random: function(inf, sup, rows, cols) {
2881
- if(cols === undefined) {
2882
- cols = rows;
2883
- }
2884
- if(Number.isInteger(rows) && Number.isInteger(cols) && rows > 0 && cols > 0) {
2885
- var result = Chalkboard.matr.new();
2886
- for(var i = 0; i < rows; i++) {
2887
- result.push([]);
2888
- for(var j = 0; j < cols; j++) {
2889
- result[i].push(Chalkboard.numb.random(inf, sup));
2890
- }
2891
- }
2892
- return result;
2893
- } else {
2894
- return undefined;
2895
- }
2896
- },
2897
- shift: function(size, shiftAmount) {
2898
- shiftAmount = shiftAmount || 1;
2899
- if(Number.isInteger(size) && size > 0) {
2900
- var result = Chalkboard.matr.fill(0, size, size);
2901
- for(var i = 0; i < size; i++) {
2902
- for(var j = 0; j < size; j++) {
2903
- result[i][j] = Chalkboard.numb.Kronecker(i + shiftAmount, j);
2904
- }
2905
- }
2906
- return result;
2907
- } else {
2908
- return undefined;
2909
- }
2910
- },
2911
- binomial: function(size, type) {
2912
- type = type || "lower";
2913
- if(Number.isInteger(size) && size > 0) {
2914
- var result = Chalkboard.matr.new();
2915
- for(var i = 0; i < size; i++) {
2916
- result.push([]);
2917
- for(var j = 0; j < size; j++) {
2918
- if(type === "lower") {
2919
- result[i].push(Chalkboard.numb.binomial(i, j));
2920
- } else if(type === "upper") {
2921
- result[i].push(Chalkboard.numb.binomial(j, i));
2922
- }
2923
- }
2924
- }
2925
- if(type === "symmetric") {
2926
- return Chalkboard.matr.mul(Chalkboard.matr.binomial(size, "lower"), Chalkboard.matr.binomial(size, "upper"));
2927
- } else if(type !== "lower" && type !== "upper") {
2928
- return "TypeError: Parameter \"type\" must be either \"lower\", \"upper\", or \"symmetric\".";
2929
- } else {
2930
- return result;
2931
- }
2932
- } else {
2933
- return undefined;
2934
- }
2935
- },
2936
- Hilbert: function(size) {
2937
- if(Number.isInteger(size) && size > 0) {
2938
- var result = Chalkboard.matr.new();
2939
- for(var i = 0; i < size; i++) {
2940
- result.push([]);
2941
- for(var j = 0; j < size; j++) {
2942
- result[i].push(1 / (i + j + 1));
2943
- }
2944
- }
2945
- return result;
2946
- } else {
2947
- return undefined;
2948
- }
2949
- },
2950
- Lehmer: function(size) {
2951
- if(Number.isInteger(size) && size > 0) {
2952
- var result = Chalkboard.matr.new();
2953
- for(var i = 0; i < size; i++) {
2954
- result.push([]);
2955
- for(var j = 0; j < size; j++) {
2956
- result[i].push(Math.min(i + 1, j + 1) / Math.max(i + 1, j + 1));
2957
- }
2958
- }
2959
- return result;
2960
- } else {
2961
- return undefined;
2962
- }
2963
- },
2964
- cofactor: function(matr, row, col) {
2965
- return matr.slice(0, row - 1).concat(matr.slice(row)).map(function(row) {
2966
- return row.slice(0, col - 1).concat(row.slice(col));
2967
- });
2968
- },
2969
- adjugate: function(matr, row, col) {
2970
- return Chalkboard.matr.transpose(Chalkboard.matr.cofactor(matr, row, col));
2971
- },
2972
- det: function(matr) {
2973
- if(Chalkboard.matr.rows(matr) === Chalkboard.matr.cols(matr)) {
2974
- var result = 0;
2975
- if(Chalkboard.matr.rows(matr) === 1) {
2976
- return matr[0][0];
2977
- } else if(Chalkboard.matr.rows(matr) === 2) {
2978
- return (matr[0][0] * matr[1][1]) - (matr[0][1] * matr[1][0]);
2979
- } else {
2980
- for(var i = 0; i < Chalkboard.matr.rows(matr); i++) {
2981
- var cofactor = matr[0][i] * Chalkboard.matr.det(Chalkboard.matr.cofactor(matr, 1, i + 1));
2982
- result += i % 2 === 0 ? cofactor : -cofactor;
2983
- }
2984
- return result;
2985
- }
2986
- } else {
2987
- return undefined;
2988
- }
2989
- },
2990
- trace: function(matr) {
2991
- if(Chalkboard.matr.rows(matr) === Chalkboard.matr.cols(matr)) {
2992
- var result = 0;
2993
- for(var i = 0; i < Chalkboard.matr.rows(matr); i++) {
2994
- result += matr[i][i];
2995
- }
2996
- return result;
2997
- } else {
2998
- return undefined;
2999
- }
3000
- },
3001
- rank: function(matr) {
3002
- return Chalkboard.matr.reduce(matr).filter(function(row) {
3003
- return row.some(function(element) {
3004
- return element !== 0;
3005
- });
3006
- }).length;
3007
- },
3008
- rowspace: function(matr) {
3009
- return Chalkboard.matr.reduce(matr).filter(function(row) {
3010
- return row.some(function(element) {
3011
- return element !== 0;
3012
- });
3013
- });
3014
- },
3015
- colspace: function(matr) {
3016
- return Chalkboard.matr.transpose(Chalkboard.matr.rowspace(Chalkboard.matr.transpose(matr)));
3017
- },
3018
- nullspace: function(matr) {
3019
- var augmented = matr.map(function(row) {
3020
- return row.slice().concat(Array(Chalkboard.matr.rows(matr)).fill(0));
3021
- });
3022
- var reduced = Chalkboard.matr.reduce(augmented);
3023
- return reduced.filter(function(row) {
3024
- return row.slice(0, Chalkboard.matr.rows(matr)).every(function(element) {
3025
- return element === 0;
3026
- });
3027
- }).map(function(row) {
3028
- return row.slice(Chalkboard.matr.rows(matr));
3029
- });
3030
- },
3031
- transpose: function(matr) {
3032
- var result = Chalkboard.matr.new();
3033
- for(var i = 0; i < Chalkboard.matr.cols(matr); i++) {
3034
- result[i] = [];
3035
- for(var j = 0; j < Chalkboard.matr.rows(matr); j++) {
3036
- result[i][j] = matr[j][i];
3037
- }
3038
- }
3039
- return result;
3040
- },
3041
- invert: function(matr) {
3042
- if(Chalkboard.matr.rows(matr) === Chalkboard.matr.cols(matr)) {
3043
- var result = Chalkboard.matr.new();
3044
- var augmented = Chalkboard.matr.new();
3045
- for(var i = 0; i < Chalkboard.matr.rows(matr); i++) {
3046
- augmented.push(matr[i].concat(Array(Chalkboard.matr.rows(matr)).fill(0)));
3047
- augmented[i][Chalkboard.matr.cols(matr) + i] = 1;
3048
- }
3049
- for(var row = 0; row < Chalkboard.matr.rows(matr); row++) {
3050
- var diagonal = augmented[row][row];
3051
- if(diagonal === 0) {
3052
- var max = row;
3053
- for(var i = row + 1; i < Chalkboard.matr.rows(matr); i++) {
3054
- if(Math.abs(augmented[i][row]) > Math.abs(augmented[max][row])) {
3055
- max = i;
3056
- }
3057
- }
3058
- var temp = augmented[row];
3059
- augmented[row] = augmented[max];
3060
- augmented[max] = temp;
3061
- diagonal = augmented[row][row];
3062
- }
3063
- for(var col = 0; col < 2 * Chalkboard.matr.cols(matr); col++) {
3064
- augmented[row][col] /= diagonal;
3065
- }
3066
- for(var i = 0; i < Chalkboard.matr.rows(matr); i++) {
3067
- if(i !== row) {
3068
- var coeff = augmented[i][row];
3069
- for(var j = 0; j < 2 * Chalkboard.matr.cols(matr); j++) {
3070
- augmented[i][j] -= coeff * augmented[row][j];
3071
- }
3072
- }
3073
- }
3074
- }
3075
- for(var i = 0; i < Chalkboard.matr.rows(matr); i++) {
3076
- result.push(augmented[i].slice(Chalkboard.matr.cols(matr), 2 * Chalkboard.matr.cols(matr)));
3077
- }
3078
- return result;
3079
- } else {
3080
- return undefined;
3081
- }
3082
- },
3083
- LUdecomp: function(matr) {
3084
- if(Chalkboard.matr.rows(matr) === Chalkboard.matr.cols(matr)) {
3085
- var L = Chalkboard.matr.identity(Chalkboard.matr.rows(matr)),
3086
- U = Chalkboard.matr.fill(0, Chalkboard.matr.rows(matr));
3087
- for(var j = 0; j < Chalkboard.matr.cols(matr); j++) {
3088
- for(var i = 0; i <= j; i++) {
3089
- var sum = 0;
3090
- for(var k = 0; k < i; k++) {
3091
- sum += L[i][k] * U[k][j];
3092
- }
3093
- U[i][j] = matr[i][j] - sum;
3094
- }
3095
- for(var i = j + 1; i < Chalkboard.matr.rows(matr); i++) {
3096
- var sum = 0;
3097
- for(var k = 0; k < j; k++) {
3098
- sum += L[i][k] * U[k][j];
3099
- }
3100
- L[i][j] = (matr[i][j] - sum) / U[j][j];
3101
- }
3102
- }
3103
- return {L: L, U: U};
3104
- } else {
3105
- return undefined;
3106
- }
3107
- },
3108
- QRdecomp: function(matr) {
3109
- var Q = Chalkboard.matr.identity(Chalkboard.matr.rows(matr)),
3110
- R = Chalkboard.matr.copy(matr);
3111
- 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++) {
3112
- var norm = 0;
3113
- for(var i = j; i < Chalkboard.matr.rows(matr); i++) {
3114
- norm += R[i][j] * R[i][j];
3115
- }
3116
- norm = Chalkboard.real.sqrt(norm);
3117
- var v = [];
3118
- v[0] = norm - R[j][j];
3119
- var normalizer = v[0] * v[0];
3120
- for(var i = 1; i < Chalkboard.matr.rows(matr) - j; i++) {
3121
- v[i] = -R[i + j][j];
3122
- normalizer += v[i] * v[i];
3123
- }
3124
- normalizer = 1 / Chalkboard.real.sqrt(normalizer);
3125
- for(var i = 0; i < v.length; i++) {
3126
- v[i] *= normalizer;
3127
- }
3128
- R[j][j] = norm;
3129
- for(var i = j + 1; i < Chalkboard.matr.rows(R); i++) {
3130
- R[i][j] = 0;
3131
- }
3132
- for(var k = j + 1; k < Chalkboard.matr.cols(R); k++) {
3133
- var dot = 0;
3134
- for(var i = 0; i < v.length; i++) {
3135
- dot += v[i] * R[i + j][k];
3136
- }
3137
- dot *= 2;
3138
- for(var i = 0; i < v.length; i++) {
3139
- R[i + j][k] -= dot * v[i];
3140
- }
3141
- }
3142
- for(var k = 0; k < Chalkboard.matr.cols(Q); k++) {
3143
- var dot = 0;
3144
- for(var i = 0; i < v.length; i++) {
3145
- dot += v[i] * Q[k][i + j];
3146
- }
3147
- dot *= 2;
3148
- for(var i = 0; i < v.length; i++) {
3149
- Q[k][i + j] -= dot * v[i];
3150
- }
3151
- }
3152
- }
3153
- return {Q: Q, R: R};
3154
- },
3155
- zero: function(matr) {
3156
- var result = Chalkboard.matr.new();
3157
- for(var i = 0; i < Chalkboard.matr.rows(matr); i++) {
3158
- result[i] = [];
3159
- for(var j = 0; j < Chalkboard.matr.cols(matr); j++) {
3160
- result[i][j] = 0;
3161
- }
3162
- }
3163
- return result;
3164
- },
3165
- negate: function(matr) {
3166
- var result = Chalkboard.matr.new();
3167
- for(var i = 0; i < Chalkboard.matr.rows(matr); i++) {
3168
- result[i] = [];
3169
- for(var j = 0; j < Chalkboard.matr.cols(matr); j++) {
3170
- result[i][j] = -matr[i][j];
3171
- }
3172
- }
3173
- return result;
3174
- },
3175
- reciprocate: function(matr) {
3176
- var result = Chalkboard.matr.new();
3177
- for(var i = 0; i < Chalkboard.matr.rows(matr); i++) {
3178
- result[i] = [];
3179
- for(var j = 0; j < Chalkboard.matr.cols(matr); j++) {
3180
- result[i][j] = 1 / matr[i][j];
3181
- }
3182
- }
3183
- return result;
3184
- },
3185
- absolute: function(matr) {
3186
- var result = Chalkboard.matr.new();
3187
- for(var i = 0; i < Chalkboard.matr.rows(matr); i++) {
3188
- result[i] = [];
3189
- for(var j = 0; j < Chalkboard.matr.cols(matr); j++) {
3190
- result[i][j] = Math.abs(matr[i][j]);
3191
- }
3192
- }
3193
- return result;
3194
- },
3195
- round: function(matr) {
3196
- var result = Chalkboard.matr.new();
3197
- for(var i = 0; i < Chalkboard.matr.rows(matr); i++) {
3198
- result[i] = [];
3199
- for(var j = 0; j < Chalkboard.matr.cols(matr); j++) {
3200
- result[i][j] = Math.round(matr[i][j]);
3201
- }
3202
- }
3203
- return result;
3204
- },
3205
- scaler: function(vec) {
3206
- if(vec.type === "vec2") {
3207
- return Chalkboard.matr.new([vec.x, 0], [0, vec.y]);
3208
- } else if(vec.type === "vec3") {
3209
- return Chalkboard.matr.new([vec.x, 0, 0], [0, vec.y, 0], [0, 0, vec.z]);
3210
- } else if(vec.type === "vec4") {
3211
- return Chalkboard.matr.new([vec.x, 0, 0, 0], [0, vec.y, 0, 0], [0, 0, vec.z, 0], [0, 0, 0, vec.w]);
3212
- }
3213
- },
3214
- translator: function(vec) {
3215
- if(vec.type === "vec2") {
3216
- return Chalkboard.matr.new([1, 0, vec.x], [0, 1, vec.y], [0, 0, 1]);
3217
- } else if(vec.type === "vec3") {
3218
- return Chalkboard.matr.new([1, 0, 0, vec.x], [0, 1, 0, vec.y], [0, 0, 1, vec.z], [0, 0, 0, 1]);
3219
- } else if(vec.type === "vec4") {
3220
- return Chalkboard.matr.new([1, 0, 0, 0, vec.x], [0, 1, 0, 0, vec.y], [0, 0, 1, 0, vec.z], [0, 0, 0, 1, vec.w], [0, 0, 0, 0, 1]);
3221
- } else {
3222
- return "TypeError: Parameter \"vec\" should be \"vec2\", \"vec3\", or \"vec4\".";
3223
- }
3224
- },
3225
- rotator: function(radx, rady, radz) {
3226
- if(rady === undefined && radz === undefined) {
3227
- return Chalkboard.matr.new([Chalkboard.trig.cos(radx), -Chalkboard.trig.sin(radx)], [Chalkboard.trig.sin(radx), Chalkboard.trig.cos(radx)]);
3228
- } else {
3229
- var matr_x = Chalkboard.matr.new([1, 0, 0], [0, Chalkboard.trig.cos(radx), -Chalkboard.trig.sin(radx)], [0, Chalkboard.trig.sin(radx), Chalkboard.trig.cos(radx)]),
3230
- matr_y = Chalkboard.matr.new([Chalkboard.trig.cos(rady), 0, Chalkboard.trig.sin(rady)], [0, 1, 0], [-Chalkboard.trig.sin(rady), 0, Chalkboard.trig.cos(rady)]),
3231
- matr_z = Chalkboard.matr.new([Chalkboard.trig.cos(radz), -Chalkboard.trig.sin(radz), 0], [Chalkboard.trig.sin(radz), Chalkboard.trig.cos(radz), 0], [0, 0, 1]);
3232
- return Chalkboard.matr.mul(matr_x, Chalkboard.matr.mul(matr_y, matr_z));
3233
- }
3234
- },
3235
- scl: function(matr, num) {
3236
- var result = Chalkboard.matr.new();
3237
- for(var i = 0; i < Chalkboard.matr.rows(matr); i++) {
3238
- result[i] = [];
3239
- for(var j = 0; j < Chalkboard.matr.cols(matr); j++) {
3240
- result[i][j] = matr[i][j] * num;
3241
- }
3242
- }
3243
- return result;
3244
- },
3245
- constrain: function(matr, range) {
3246
- var result = Chalkboard.matr.new();
3247
- for(var i = 0; i < Chalkboard.matr.rows(matr); i++) {
3248
- result[i] = [];
3249
- for(var j = 0; j < Chalkboard.matr.cols(matr); j++) {
3250
- result[i][j] = Chalkboard.numb.constrain(matr[i][j], range);
3251
- }
3252
- }
3253
- return result;
3254
- },
3255
- concat: function(matr_1, matr_2, type) {
3256
- type = type || "row";
3257
- if(type === "row") {
3258
- if(Chalkboard.matr.rows(matr_1) === Chalkboard.matr.rows(matr_2)) {
3259
- return Chalkboard.matr.new(matr_1.concat(matr_2));
3260
- } else {
3261
- return undefined;
3262
- }
3263
- } else if(type === "col") {
3264
- if(Chalkboard.matr.cols(matr_1) === Chalkboard.matr.cols(matr_2)) {
3265
- var result = Chalkboard.matr.new();
3266
- for(var i = 0; i < Chalkboard.matr.rows(matr_1); i++) {
3267
- result.push(matr_1[i].concat(matr_2[i]));
3268
- }
3269
- return result;
3270
- } else {
3271
- return undefined;
3272
- }
3273
- } else {
3274
- return "TypeError: Parameter \"type\" should be either \"row\" or \"col\".";
3275
- }
3276
- },
3277
- add: function(matr_1, matr_2) {
3278
- if(Chalkboard.matr.rows(matr_1) === Chalkboard.matr.rows(matr_2) && Chalkboard.matr.cols(matr_1) === Chalkboard.matr.cols(matr_2)) {
3279
- var result = Chalkboard.matr.new();
3280
- for(var i = 0; i < Chalkboard.matr.rows(matr_1); i++) {
3281
- result[i] = [];
3282
- for(var j = 0; j < Chalkboard.matr.cols(matr_1); j++) {
3283
- result[i][j] = matr_1[i][j] + matr_2[i][j];
3284
- }
3285
- }
3286
- return result;
3287
- } else {
3288
- return undefined;
3289
- }
3290
- },
3291
- sub: function(matr_1, matr_2) {
3292
- if(Chalkboard.matr.rows(matr_1) === Chalkboard.matr.rows(matr_2) && Chalkboard.matr.cols(matr_1) === Chalkboard.matr.cols(matr_2)) {
3293
- var result = Chalkboard.matr.new();
3294
- for(var i = 0; i < Chalkboard.matr.rows(matr_1); i++) {
3295
- result[i] = [];
3296
- for(var j = 0; j < Chalkboard.matr.cols(matr_1); j++) {
3297
- result[i][j] = matr_1[i][j] - matr_2[i][j];
3298
- }
3299
- }
3300
- return result;
3301
- } else {
3302
- return undefined;
3303
- }
3304
- },
3305
- mul: function(matr_1, matr_2) {
3306
- if(Chalkboard.matr.cols(matr_1) === Chalkboard.matr.rows(matr_2)) {
3307
- var result = Chalkboard.matr.new();
3308
- for(var i = 0; i < Chalkboard.matr.rows(matr_1); i++) {
3309
- result[i] = [];
3310
- for(var j = 0; j < Chalkboard.matr.cols(matr_2); j++) {
3311
- result[i][j] = 0;
3312
- for(var k = 0; k < Chalkboard.matr.cols(matr_1); k++) {
3313
- result[i][j] += matr_1[i][k] * matr_2[k][j];
3314
- }
3315
- }
3316
- }
3317
- return result;
3318
- } else {
3319
- return undefined;
3320
- }
3321
- },
3322
- mulvec: function(matr, vec) {
3323
- if(vec.type === "vec2") {
3324
- if(Chalkboard.matr.rows(matr) === 2) {
3325
- return Chalkboard.matr.toVector(Chalkboard.matr.mul(matr, Chalkboard.vec2.toMatrix(vec)), "vec2");
3326
- } else {
3327
- return Chalkboard.matr.mul(matr, Chalkboard.vec2.toMatrix(vec));
3328
- }
3329
- } else if(vec.type === "vec3") {
3330
- if(Chalkboard.matr.rows(matr) === 3) {
3331
- return Chalkboard.matr.toVector(Chalkboard.matr.mul(matr, Chalkboard.vec3.toMatrix(vec)), "vec3");
3332
- } else {
3333
- return Chalkboard.matr.mul(matr, Chalkboard.vec2.toMatrix(vec));
3334
- }
3335
- } else if(vec.type === "vec4") {
3336
- if(Chalkboard.matr.rows(matr) === 4) {
3337
- return Chalkboard.matr.toVector(Chalkboard.matr.mul(matr, Chalkboard.vec4.toMatrix(vec)), "vec4");
3338
- } else {
3339
- return Chalkboard.matr.mul(matr, Chalkboard.vec2.toMatrix(vec));
3340
- }
3341
- } else {
3342
- return "TypeError: Parameter \"vec\" should be \"vec2\", \"vec3\", or \"vec4\".";
3343
- }
3344
- },
3345
- pow: function(matr, num) {
3346
- if(Chalkboard.matr.rows(matr) === Chalkboard.matr.cols(matr)) {
3347
- if(Number.isInteger(num) && num >= 0) {
3348
- if(num === 0) {
3349
- return Chalkboard.matr.identity(Chalkboard.matr.rows(matr));
3350
- } else {
3351
- var result = matr;
3352
- for(var i = 1; i < num; i++) {
3353
- result = Chalkboard.matr.mul(matr, result);
3354
- }
3355
- return result;
3356
- }
3357
- } else {
3358
- return undefined;
3359
- }
3360
- } else {
3361
- return undefined;
3362
- }
3363
- },
3364
- addKronecker: function(matr_1, matr_2) {
3365
- if(Chalkboard.matr.rows(matr_1) === Chalkboard.matr.cols(matr_1) && Chalkboard.matr.rows(matr_2) === Chalkboard.matr.cols(matr_2)) {
3366
- 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));
3367
- } else {
3368
- return undefined;
3369
- }
3370
- },
3371
- mulKronecker: function(matr_1, matr_2) {
3372
- var result = Chalkboard.matr.new();
3373
- for(var i = 0; i < Chalkboard.matr.rows(matr_1); i++) {
3374
- for(var j = 0; j < Chalkboard.matr.cols(matr_1); j++) {
3375
- for(var k = 0; k < Chalkboard.matr.rows(matr_2); k++) {
3376
- for(var l = 0; l < Chalkboard.matr.cols(matr_2); l++) {
3377
- if(!result[i * Chalkboard.matr.rows(matr_2) + k]) {
3378
- result[i * Chalkboard.matr.rows(matr_2) + k] = [];
3379
- }
3380
- result[i * Chalkboard.matr.rows(matr_2) + k][j * Chalkboard.matr.cols(matr_2) + l] = matr_1[i][j] * matr_2[k][l];
3381
- }
3382
- }
3383
- }
3384
- }
3385
- return result;
3386
- },
3387
- reduce: function(matr) {
3388
- var lead = 0;
3389
- for(var row = 0; row < Chalkboard.matr.rows(matr); row++) {
3390
- if(lead >= Chalkboard.matr.cols(matr)) {
3391
- break;
3392
- }
3393
- var i = row;
3394
- while(matr[i][lead] === 0) {
3395
- i++;
3396
- if(i === Chalkboard.matr.rows(matr)) {
3397
- i = row;
3398
- lead++;
3399
- if(Chalkboard.matr.cols(matr) === lead) {
3400
- return matr;
3401
- }
3402
- }
3403
- }
3404
- var temp = matr[i];
3405
- matr[i] = matr[row];
3406
- matr[row] = temp;
3407
- var scl = matr[row][lead];
3408
- for(var j = 0; j < Chalkboard.matr.cols(matr); j++) {
3409
- matr[row][j] /= scl;
3410
- }
3411
- for(var i = 0; i < Chalkboard.matr.rows(matr); i++) {
3412
- if(i !== row) {
3413
- var coeff = matr[i][lead];
3414
- for(var j = 0; j < Chalkboard.matr.cols(matr); j++) {
3415
- matr[i][j] -= coeff * matr[row][j];
3416
- }
3417
- }
3418
- }
3419
- lead++;
3420
- }
3421
- return matr;
3422
- },
3423
- solve: function(matr_A, matr_B) {
3424
- if(Chalkboard.matr.rows(matr_A) === Chalkboard.matr.cols(matr_A)) {
3425
- if(Chalkboard.matr.rows(matr_A) === Chalkboard.matr.rows(matr_B)) {
3426
- if(Chalkboard.matr.det(matr_A) !== 0) {
3427
- return Chalkboard.matr.mul(Chalkboard.matr.invert(matr_A), matr_B);
3428
- } else {
3429
- return undefined;
3430
- }
3431
- } else {
3432
- return undefined;
3433
- }
3434
- } else {
3435
- return undefined;
3436
- }
3437
- },
3438
- toVector: function(matr, vec, type, rowORcol) {
3439
- type = type || "col";
3440
- rowORcol = rowORcol || 1;
3441
- rowORcol -= 1;
3442
- if(vec === "vec2") {
3443
- if(type === "col") {
3444
- return Chalkboard.vec2.new(matr[0][rowORcol], matr[1][rowORcol]);
3445
- } else if(type === "row") {
3446
- return Chalkboard.vec2.new(matr[rowORcol][0], matr[rowORcol][1]);
3447
- } else {
3448
- return "TypeError: Parameter \"type\" should be \"row\" or \"col\".";
3449
- }
3450
- } else if(vec === "vec3") {
3451
- if(type === "col") {
3452
- return Chalkboard.vec3.new(matr[0][rowORcol], matr[1][rowORcol], matr[2][rowORcol]);
3453
- } else if(type === "row") {
3454
- return Chalkboard.vec3.new(matr[rowORcol][0], matr[rowORcol][1], matr[rowORcol][2]);
3455
- } else {
3456
- return "TypeError: Parameter \"type\" should be \"row\" or \"col\".";
3457
- }
3458
- } else if(vec === "vec4") {
3459
- if(type === "col") {
3460
- return Chalkboard.vec4.new(matr[0][rowORcol], matr[1][rowORcol], matr[2][rowORcol], matr[3][rowORcol]);
3461
- } else if(type === "row") {
3462
- return Chalkboard.vec4.new(matr[rowORcol][0], matr[rowORcol][1], matr[rowORcol][2], matr[rowORcol][3]);
3463
- } else {
3464
- return "TypeError: Parameter \"type\" should be \"row\" or \"col\".";
3465
- }
3466
- } else {
3467
- return "TypeError: Parameter \"vec\" should be \"vec2\", \"vec3\", or \"vec4\".";
3468
- }
3469
- },
3470
- toTensor: function(matr, size) {
3471
- if(!Array.isArray(size)) {
3472
- size = Array.from(arguments).slice(1);
3473
- }
3474
- return Chalkboard.tens.resize(matr, size);
3475
- },
3476
- toArray: function(matr) {
3477
- var result = [];
3478
- for(var i = 0; i < Chalkboard.matr.rows(matr); i++) {
3479
- for(var j = 0; j < Chalkboard.matr.cols(matr); j++) {
3480
- result.push(matr[i][j]);
3481
- }
3482
- }
3483
- return result;
3484
- },
3485
- toObject: function(matr) {
3486
- var result = {};
3487
- for(var i = 0; i < Chalkboard.matr.rows(matr); i++) {
3488
- result["i" + (i + 1)] = {};
3489
- for(var j = 0; j < Chalkboard.matr.cols(matr); j++) {
3490
- result["i" + (i + 1)]["j" + (j + 1)] = matr[i][j];
3491
- }
3492
- }
3493
- return result;
3494
- },
3495
- toString: function(matr) {
3496
- var result = "";
3497
- for(var i = 0; i < Chalkboard.matr.rows(matr); i++) {
3498
- result += "[ ";
3499
- for(var j = 0; j < Chalkboard.matr.cols(matr); j++) {
3500
- result += matr[i][j].toString() + " ";
3501
- }
3502
- result = result.trimEnd() + " ]\n";
3503
- }
3504
- return result;
3505
- },
3506
- print: function(matr) {
3507
- console.log(Chalkboard.matr.toString(matr));
3508
- }
3509
- },
3510
- tens: {
3511
- new: function(tensor) {
3512
- if(arguments.length === 0) {
3513
- return [];
3514
- } else if(arguments.length === 1 && Array.isArray(arguments[0])) {
3515
- tensor = arguments[0];
3516
- } else {
3517
- tensor = Array.from(arguments);
3518
- }
3519
- var newNDArray = function(arr) {
3520
- return arr.map(function(subarr) {
3521
- if(Array.isArray(subarr)) {
3522
- return newNDArray(subarr);
3523
- } else {
3524
- return subarr;
3525
- }
3526
- });
3527
- };
3528
- return newNDArray(tensor);
3529
- },
3530
- copy: function(tens) {
3531
- if(Array.isArray(tens)) {
3532
- var result = Chalkboard.tens.new();
3533
- for(var i = 0; i < tens.length; i++) {
3534
- result[i] = Chalkboard.tens.copy(tens[i]);
3535
- }
3536
- return result;
3537
- } else {
3538
- return tens;
3539
- }
3540
- },
3541
- rank: function(tens) {
3542
- if(Array.isArray(tens)) {
3543
- var result = 0;
3544
- for(var i = 0; i < tens.length; i++) {
3545
- result = Math.max(result, Chalkboard.tens.rank(tens[i]));
3546
- }
3547
- return result + 1;
3548
- } else {
3549
- return 0;
3550
- }
3551
- },
3552
- size: function(tens) {
3553
- if(Array.isArray(tens)) {
3554
- var result = [tens.length];
3555
- if(Array.isArray(tens[0])) {
3556
- result = result.concat(Chalkboard.tens.size(tens[0]));
3557
- }
3558
- return result;
3559
- } else {
3560
- return [];
3561
- }
3562
- },
3563
- resize: function(tens, size) {
3564
- if(!Array.isArray(size)) {
3565
- size = Array.from(arguments).slice(1);
3566
- }
3567
- var result = Chalkboard.tens.fill(0, size);
3568
- var refill = function(arr1, arr2) {
3569
- for(var i = 0; i < arr2.length; i++) {
3570
- if(Array.isArray(arr2[i])) {
3571
- refill(arr1, arr2[i]);
3572
- } else {
3573
- arr2[i] = arr1.length > 0 ? arr1.shift() : 0;
3574
- }
3575
- }
3576
- };
3577
- refill(Chalkboard.tens.toArray(tens), result);
3578
- return result;
3579
- },
3580
- push: function(tens, rank, index, elements) {
3581
- if(rank === 0) {
3582
- tens.splice(index, 0, elements);
3583
- return tens;
3584
- } else {
3585
- for(var i = 0; i < tens.length; i++) {
3586
- Chalkboard.tens.push(tens[i], rank - 1, index, elements[i]);
3587
- }
3588
- return tens;
3589
- }
3590
- },
3591
- pull: function(tens, rank, index) {
3592
- if(rank === 0) {
3593
- tens.splice(index, 1);
3594
- return tens;
3595
- } else {
3596
- for(var i = 0; i < tens.length; i++) {
3597
- Chalkboard.tens.pull(tens[i], rank - 1, index);
3598
- }
3599
- return tens;
3600
- }
3601
- },
3602
- fill: function(element, size) {
3603
- if(!Array.isArray(size)) {
3604
- size = Array.from(arguments).slice(1);
3605
- }
3606
- var newNDArray = function(size) {
3607
- if(size.length === 0) {
3608
- return element;
3609
- }
3610
- var curr = size[0];
3611
- var rest = size.slice(1);
3612
- var result = [];
3613
- for(var i = 0; i < curr; i++) {
3614
- result[i] = newNDArray(rest);
3615
- }
3616
- return result;
3617
- }
3618
- return newNDArray(size);
3619
- },
3620
- empty: function(size) {
3621
- if(!Array.isArray(size)) {
3622
- size = Array.from(arguments);
3623
- }
3624
- var newNDArray = function(size) {
3625
- if(size.length === 0) {
3626
- return null;
3627
- }
3628
- var curr = size[0];
3629
- var rest = size.slice(1);
3630
- var result = [];
3631
- for(var i = 0; i < curr; i++) {
3632
- result[i] = newNDArray(rest);
3633
- }
3634
- return result;
3635
- }
3636
- return newNDArray(size);
3637
- },
3638
- random: function(inf, sup, size) {
3639
- if(!Array.isArray(size)) {
3640
- size = Array.from(arguments).slice(2);
3641
- }
3642
- var newNDArray = function(size) {
3643
- if(size.length === 0) {
3644
- return Chalkboard.numb.random(inf, sup);
3645
- }
3646
- var curr = size[0];
3647
- var rest = size.slice(1);
3648
- var result = [];
3649
- for(var i = 0; i < curr; i++) {
3650
- result[i] = newNDArray(rest);
3651
- }
3652
- return result;
3653
- }
3654
- return newNDArray(size);
3655
- },
3656
- contract: function(tens) {
3657
- if(Chalkboard.tens.rank(tens) > 2) {
3658
- 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]);
3659
- } else if(Chalkboard.tens.rank(tens) === 2) {
3660
- return Chalkboard.matr.trace(tens);
3661
- }
3662
- },
3663
- transpose: function(tens) {
3664
- return Chalkboard.tens.resize(tens, Chalkboard.tens.size(tens).reverse());
3665
- },
3666
- zero: function(tens) {
3667
- var result = Chalkboard.tens.new();
3668
- if(Array.isArray(tens)) {
3669
- for(var i = 0; i < tens.length; i++) {
3670
- result[i] = Chalkboard.tens.zero(tens[i]);
3671
- }
3672
- return result;
3673
- } else {
3674
- return 0;
3675
- }
3676
- },
3677
- negate: function(tens) {
3678
- var result = Chalkboard.tens.new();
3679
- if(Array.isArray(tens)) {
3680
- for(var i = 0; i < tens.length; i++) {
3681
- result[i] = Chalkboard.tens.negate(tens[i]);
3682
- }
3683
- return result;
3684
- } else {
3685
- return -tens;
3686
- }
3687
- },
3688
- reciprocate: function(tens) {
3689
- var result = Chalkboard.tens.new();
3690
- if(Array.isArray(tens)) {
3691
- for(var i = 0; i < tens.length; i++) {
3692
- result[i] = Chalkboard.tens.reciprocate(tens[i]);
3693
- }
3694
- return result;
3695
- } else {
3696
- return 1 / tens;
3697
- }
3698
- },
3699
- absolute: function(tens) {
3700
- var result = Chalkboard.tens.new();
3701
- if(Array.isArray(tens)) {
3702
- for(var i = 0; i < tens.length; i++) {
3703
- result[i] = Chalkboard.tens.absolute(tens[i]);
3704
- }
3705
- return result;
3706
- } else {
3707
- return Math.abs(tens);
3708
- }
3709
- },
3710
- round: function(tens) {
3711
- var result = Chalkboard.tens.new();
3712
- if(Array.isArray(tens)) {
3713
- for(var i = 0; i < tens.length; i++) {
3714
- result[i] = Chalkboard.tens.round(tens[i]);
3715
- }
3716
- return result;
3717
- } else {
3718
- return Math.round(tens);
3719
- }
3720
- },
3721
- scl: function(tens, num) {
3722
- var result = Chalkboard.tens.new();
3723
- if(Array.isArray(tens)) {
3724
- for(var i = 0; i < tens.length; i++) {
3725
- result[i] = Chalkboard.tens.scl(tens[i], num);
3726
- }
3727
- return result;
3728
- } else {
3729
- return tens * num;
3730
- }
3731
- },
3732
- constrain: function(tens, range) {
3733
- var result = Chalkboard.tens.new();
3734
- if(Array.isArray(tens)) {
3735
- for(var i = 0; i < tens.length; i++) {
3736
- result[i] = Chalkboard.tens.constrain(tens[i], range);
3737
- }
3738
- return result;
3739
- } else {
3740
- return Chalkboard.numb.constrain(tens, range);
3741
- }
3742
- },
3743
- concat: function(tens_1, tens_2, rank) {
3744
- rank = rank || 1;
3745
- var concatAtRank = function(arr1, arr2, currentRank) {
3746
- if(currentRank === rank) {
3747
- return Chalkboard.tens.new(arr1.concat(arr2));
3748
- }
3749
- return arr1.map(function(element, index) {
3750
- return concatAtRank(element, arr2[index], currentRank);
3751
- });
3752
- }
3753
- return concatAtRank(tens_1, tens_2, 1);
3754
- },
3755
- add: function(tens_1, tens_2) {
3756
- var result = Chalkboard.tens.new();
3757
- if(Array.isArray(tens_1) && Array.isArray(tens_2)) {
3758
- for(var i = 0; i < Math.max(tens_1.length, tens_2.length); i++) {
3759
- result[i] = Chalkboard.tens.add(tens_1[i] !== undefined ? tens_1[i] : 0, tens_2[i] !== undefined ? tens_2[i] : 0);
3760
- }
3761
- return result;
3762
- } else {
3763
- return tens_1 + tens_2;
3764
- }
3765
- },
3766
- sub: function(tens_1, tens_2) {
3767
- var result = Chalkboard.tens.new();
3768
- if(Array.isArray(tens_1) && Array.isArray(tens_2)) {
3769
- for(var i = 0; i < Math.max(tens_1.length, tens_2.length); i++) {
3770
- result[i] = Chalkboard.tens.sub(tens_1[i] !== undefined ? tens_1[i] : 0, tens_2[i] !== undefined ? tens_2[i] : 0);
3771
- }
3772
- return result;
3773
- } else {
3774
- return tens_1 - tens_2;
3775
- }
3776
- },
3777
- mul: function(tens_1, tens_2) {
3778
- var result = Chalkboard.tens.new();
3779
- if(Array.isArray(tens_1) && Array.isArray(tens_2)) {
3780
- for(var i = 0; i < tens_1.length; i++) {
3781
- var subarr = Chalkboard.tens.new();
3782
- for(var j = 0; j < tens_2.length; j++) {
3783
- subarr[j] = Chalkboard.tens.mul(tens_1[i], tens_2[j]);
3784
- }
3785
- result.push(subarr);
3786
- }
3787
- return result;
3788
- } else {
3789
- return tens_1 * tens_2;
3790
- }
3791
- },
3792
- toVector: function(tens, type, index) {
3793
- if(index === undefined) { index = 0; }
3794
- var arr = Chalkboard.tens.toArray(tens);
3795
- if(type === "vec2") {
3796
- return Chalkboard.vec2.new(arr[index], arr[index + 1]);
3797
- } else if(type === "vec3") {
3798
- return Chalkboard.vec3.new(arr[index], arr[index + 1], arr[index + 2]);
3799
- } else if(type === "vec4") {
3800
- return Chalkboard.vec4.new(arr[index], arr[index + 1], arr[index + 2], arr[index + 3]);
3801
- } else {
3802
- return "TypeError: Parameter \"type\" should be \"vec2\", \"vec3\", or \"vec4\".";
3803
- }
3804
- },
3805
- toMatrix: function(tens) {
3806
- var result = Chalkboard.matr.new();
3807
- var flatten = function(tens, result) {
3808
- for(var i = 0; i < tens.length; i++) {
3809
- if(Array.isArray(tens[i])) {
3810
- flatten(tens[i], result);
3811
- } else {
3812
- result.push(tens[i]);
3813
- }
3814
- }
3815
- }
3816
- var matr = Chalkboard.matr.new();
3817
- flatten(tens, matr);
3818
- var rows = tens.length || 1;
3819
- for(var j = 0; j < rows; j++) {
3820
- result.push(matr.slice(j * matr.length / rows, (j + 1) * matr.length / rows));
3821
- }
3822
- return result;
3823
- },
3824
- toArray: function(tens) {
3825
- var result = [];
3826
- var flatten = function(tens) {
3827
- for(var i = 0; i < tens.length; i++) {
3828
- if(Array.isArray(tens[i])) {
3829
- flatten(tens[i]);
3830
- } else {
3831
- result.push(tens[i]);
3832
- }
3833
- }
3834
- }
3835
- flatten(tens);
3836
- return result;
3837
- },
3838
- toObject: function(tens) {
3839
- if(Array.isArray(tens)) {
3840
- var result = {};
3841
- for(var i = 0; i < tens.length; i++) {
3842
- result["_" + (i + 1)] = Chalkboard.tens.toObject(tens[i]);
3843
- }
3844
- return result;
3845
- } else {
3846
- return tens;
3847
- }
3848
- },
3849
- toString: function(tens, indentation) {
3850
- if(indentation === undefined) { indentation = 0; }
3851
- if(Array.isArray(tens[0])) {
3852
- var result = "\t".repeat(indentation) + "[\n";
3853
- for(var i = 0; i < tens.length; i++) {
3854
- result += Chalkboard.tens.toString(tens[i], indentation + 1);
3855
- }
3856
- result += "\t".repeat(indentation) + "]\n";
3857
- return result;
3858
- } else {
3859
- var result = "\t".repeat(indentation) + "[ ";
3860
- for(var i = 0; i < tens.length; i++) {
3861
- result += tens[i].toString() + " ";
3862
- }
3863
- result += "]\n";
3864
- return result;
3865
- }
3866
- },
3867
- print: function(tens) {
3868
- return console.log(Chalkboard.tens.toString(tens));
3869
- }
3870
- },
3871
- calc: {
3872
- lim: function(func, val) {
3873
- if(func.type === "expl") {
3874
- if(val === Infinity) {
3875
- if(Chalkboard.real.val(func, 101) > Chalkboard.real.val(func, 100)) {
3876
- return Infinity;
3877
- } else if(Chalkboard.real.val(func, 101) < Chalkboard.real.val(func, 100)) {
3878
- return -Infinity;
3879
- }
3880
- } else if(val === -Infinity) {
3881
- if(Chalkboard.real.val(func, -101) > Chalkboard.real.val(func, -100)) {
3882
- return Infinity;
3883
- } else if(Chalkboard.real.val(func, -101) < Chalkboard.real.val(func, -100)) {
3884
- return -Infinity;
3885
- }
3886
- } else {
3887
- if(Chalkboard.real.val(func, val - 0.000001).toFixed(4) === Chalkboard.real.val(func, val + 0.000001).toFixed(4)) {
3888
- if(Chalkboard.real.val(func, val) !== Infinity || Chalkboard.real.val(func, val) !== -Infinity) {
3889
- return Chalkboard.real.val(func, val);
3890
- } else {
3891
- return undefined;
3892
- }
3893
- } else {
3894
- return undefined;
3895
- }
3896
- }
3897
- } else {
3898
- return "TypeError: Parameter \"func\" must be of type \"expl\".";
3899
- }
3900
- },
3901
- dfdx: function(func, val) {
3902
- var h = 0.000000001;
3903
- if(func.type === "expl") {
3904
- var f = Chalkboard.real.parse("x => " + func.definition);
3905
- return (f(val + h) - f(val)) / h;
3906
- } else if(func.type === "inve") {
3907
- var f = Chalkboard.real.parse("y => " + func.definition);
3908
- return (f(val + h) - f(val)) / h;
3909
- } else if(func.type === "pola") {
3910
- var r = Chalkboard.real.parse("O => " + func.definition);
3911
- return (r(val + h) - r(val)) / h;
3912
- } else if(func.type === "curv") {
3913
- if(func.definition.length === 2) {
3914
- var x = Chalkboard.real.parse("t => " + func.definition[0]),
3915
- y = Chalkboard.real.parse("t => " + func.definition[1]);
3916
- return Chalkboard.vec2.new((x(val + h) - x(val)) / h, (y(val + h) - y(val)) / h);
3917
- } else if(func.definition.length === 3) {
3918
- var x = Chalkboard.real.parse("t => " + func.definition[0]),
3919
- y = Chalkboard.real.parse("t => " + func.definition[1]),
3920
- z = Chalkboard.real.parse("t => " + func.definition[2]);
3921
- return Chalkboard.vec3.new((x(val + h) - x(val)) / h, (y(val + h) - y(val)) / h, (z(val + h) - z(val)) / h);
3922
- }
3923
- } else {
3924
- return "TypeError: Parameter \"func\" must be of type \"expl\", \"inve\", \"pola\", or \"curv\".";
3925
- }
3926
- },
3927
- d2fdx2: function(func, val) {
3928
- var h = 0.00001;
3929
- if(func.type === "expl") {
3930
- var f = Chalkboard.real.parse("x => " + func.definition);
3931
- return (f(val + h) - 2 * f(val) + f(val - h)) / (h * h);
3932
- } else if(func.type === "inve") {
3933
- var f = Chalkboard.real.parse("y => " + func.definition);
3934
- return (f(val + h) - 2 * f(val) + f(val - h)) / (h * h);
3935
- } else if(func.type === "pola") {
3936
- var r = Chalkboard.real.parse("O => " + func.definition);
3937
- return (r(val + h) - 2 * r(val) + r(val - h)) / (h * h);
3938
- } else if(func.type === "curv") {
3939
- if(func.definition.length === 2) {
3940
- var x = Chalkboard.real.parse("t => " + func.definition[0]),
3941
- y = Chalkboard.real.parse("t => " + func.definition[1]);
3942
- return Chalkboard.vec2.new((x(val + h) - 2 * x(val) + x(val - h)) / (h * h), (y(val + h) - 2 * y(val) + y(val - h)) / (h * h));
3943
- } else if(func.definition.length === 3) {
3944
- var x = Chalkboard.real.parse("t => " + func.definition[0]),
3945
- y = Chalkboard.real.parse("t => " + func.definition[1]),
3946
- z = Chalkboard.real.parse("t => " + func.definition[2]);
3947
- 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));
3948
- }
3949
- } else {
3950
- return "TypeError: Parameter \"func\" must be of type \"expl\", \"inve\", \"pola\", or \"curv\".";
3951
- }
3952
- },
3953
- tangent: function(func, val) {
3954
- if(func.type === "curv") {
3955
- if(func.definition.length === 2) {
3956
- return Chalkboard.vec2.normalize(Chalkboard.calc.dfdx(func, val));
3957
- } else if(func.definition.length === 3) {
3958
- return Chalkboard.vec3.normalize(Chalkboard.calc.dfdx(func, val));
3959
- }
3960
- } else {
3961
- return "TypeError: Parameter \"func\" must be of type \"curv\".";
3962
- }
3963
- },
3964
- normal: function(func, val) {
3965
- if(func.type === "curv") {
3966
- if(func.definition.length === 2) {
3967
- return Chalkboard.vec2.normalize(Chalkboard.calc.d2fdx2(func, val));
3968
- } else if(func.definition.length === 3) {
3969
- return Chalkboard.vec3.normalize(Chalkboard.calc.d2fdx2(func, val));
3970
- }
3971
- } else {
3972
- return "TypeError: Parameter \"func\" must be of type \"curv\".";
3973
- }
3974
- },
3975
- binormal: function(func, val) {
3976
- if(func.type === "curv") {
3977
- if(func.definition.length === 2) {
3978
- return Chalkboard.vec2.cross(Chalkboard.calc.tangent(func, val), Chalkboard.calc.normal(func, val));
3979
- } else if(func.definition.length === 3) {
3980
- return Chalkboard.vec3.cross(Chalkboard.calc.tangent(func, val), Chalkboard.calc.normal(func, val));
3981
- }
3982
- } else {
3983
- return "TypeError: Parameter \"func\" must be of type \"curv\".";
3984
- }
3985
- },
3986
- dfdv: function(func, vec2_pos, vec2_dir) {
3987
- if(func.type === "mult") {
3988
- return Chalkboard.vec2.dot(Chalkboard.calc.grad(func, vec2_pos), Chalkboard.vec2.normalize(vec2_dir));
3989
- } else {
3990
- return "TypeError: Parameter \"func\" must be of type \"mult\".";
3991
- }
3992
- },
3993
- dfrdt: function(func_1, func_2, val) {
3994
- if(func_1.type === "mult") {
3995
- if(func_2.type === "curv") {
3996
- if(func_2.definition.length === 2) {
3997
- var dfdx = Chalkboard.calc.grad(func_1, Chalkboard.real.val(func_2, val)).x,
3998
- dfdy = Chalkboard.calc.grad(func_1, Chalkboard.real.val(func_2, val)).y,
3999
- dxdt = Chalkboard.calc.dfdx(func_2, val).x,
4000
- dydt = Chalkboard.calc.dfdx(func_2, val).y;
4001
- return dfdx * dxdt + dfdy * dydt;
4002
- }
4003
- } else {
4004
- return "TypeError: Parameter \"func_2\" must be of type \"curv\".";
4005
- }
4006
- } else {
4007
- return "TypeError: Parameter \"func_1\" must be of type \"mult\".";
4008
- }
4009
- },
4010
- grad: function(funcORvecfield, vec) {
4011
- var h = 0.000000001;
4012
- if(funcORvecfield.type === "surf") {
4013
- var x = Chalkboard.real.parse("(s, t) => " + funcORvecfield.definition[0]),
4014
- y = Chalkboard.real.parse("(s, t) => " + funcORvecfield.definition[1]),
4015
- z = Chalkboard.real.parse("(s, t) => " + funcORvecfield.definition[2]);
4016
- var dxds = (x(vec.x + h, vec.y) - x(vec.x, vec.y)) / h,
4017
- dxdt = (x(vec.x, vec.y + h) - x(vec.x, vec.y)) / h,
4018
- dyds = (y(vec.x + h, vec.y) - y(vec.x, vec.y)) / h,
4019
- dydt = (y(vec.x, vec.y + h) - y(vec.x, vec.y)) / h,
4020
- dzds = (z(vec.x + h, vec.y) - z(vec.x, vec.y)) / h,
4021
- dzdt = (z(vec.x, vec.y + h) - z(vec.x, vec.y)) / h;
4022
- return Chalkboard.matr.new([dxds, dxdt],
4023
- [dyds, dydt],
4024
- [dzds, dzdt]);
4025
- } else if(funcORvecfield.type === "mult") {
4026
- var f = Chalkboard.real.parse("(x, y) => " + funcORvecfield.definition);
4027
- var dfdx = (f(vec.x + h, vec.y) - f(vec.x, vec.y)) / h,
4028
- dfdy = (f(vec.x, vec.y + h) - f(vec.x, vec.y)) / h;
4029
- return Chalkboard.vec2.new(dfdx, dfdy);
4030
- } else if(funcORvecfield.type === "vec2field") {
4031
- var p = Chalkboard.real.parse("(x, y) => " + funcORvecfield.p),
4032
- q = Chalkboard.real.parse("(x, y) => " + funcORvecfield.q);
4033
- var dpdx = (p(vec.x + h, vec.y) - p(vec.x, vec.y)) / h,
4034
- dpdy = (p(vec.x, vec.y + h) - p(vec.x, vec.y)) / h,
4035
- dqdx = (q(vec.x + h, vec.y) - q(vec.x, vec.y)) / h,
4036
- dqdy = (q(vec.x, vec.y + h) - q(vec.x, vec.y)) / h;
4037
- return Chalkboard.matr.new([dpdx, dpdy],
4038
- [dqdx, dqdy]);
4039
- } else if(funcORvecfield.type === "vec3field") {
4040
- var p = Chalkboard.real.parse("(x, y, z) => " + funcORvecfield.p),
4041
- q = Chalkboard.real.parse("(x, y, z) => " + funcORvecfield.q),
4042
- r = Chalkboard.real.parse("(x, y, z) => " + funcORvecfield.r);
4043
- var dpdx = (p(vec.x + h, vec.y, vec.z) - p(vec.x, vec.y, vec.z)) / h,
4044
- dpdy = (p(vec.x, vec.y + h, vec.z) - p(vec.x, vec.y, vec.z)) / h,
4045
- dpdz = (p(vec.x, vec.y, vec.z + h) - p(vec.x, vec.y, vec.z)) / h,
4046
- dqdx = (q(vec.x + h, vec.y, vec.z) - q(vec.x, vec.y, vec.z)) / h,
4047
- dqdy = (q(vec.x, vec.y + h, vec.z) - q(vec.x, vec.y, vec.z)) / h,
4048
- dqdz = (q(vec.x, vec.y, vec.z + h) - q(vec.x, vec.y, vec.z)) / h,
4049
- drdx = (r(vec.x + h, vec.y, vec.z) - r(vec.x, vec.y, vec.z)) / h,
4050
- drdy = (r(vec.x, vec.y + h, vec.z) - r(vec.x, vec.y, vec.z)) / h,
4051
- drdz = (r(vec.x, vec.y, vec.z + h) - r(vec.x, vec.y, vec.z)) / h;
4052
- return Chalkboard.matr.new([dpdx, dpdy, dpdz],
4053
- [dqdx, dqdy, dqdz],
4054
- [drdx, drdy, drdz]);
4055
- } else if(funcORvecfield.type === "vec4field") {
4056
- var p = Chalkboard.real.parse("(x, y, z, w) => " + funcORvecfield.p),
4057
- q = Chalkboard.real.parse("(x, y, z, w) => " + funcORvecfield.q),
4058
- r = Chalkboard.real.parse("(x, y, z, w) => " + funcORvecfield.r),
4059
- s = Chalkboard.real.parse("(x, y, z, w) => " + funcORvecfield.s);
4060
- var dpdx = (p(vec.x + h, vec.y, vec.z, vec.w) - p(vec.x, vec.y, vec.z, vec.w)) / h,
4061
- dpdy = (p(vec.x, vec.y + h, vec.z, vec.w) - p(vec.x, vec.y, vec.z, vec.w)) / h,
4062
- dpdz = (p(vec.x, vec.y, vec.z + h, vec.w) - p(vec.x, vec.y, vec.z, vec.w)) / h,
4063
- dpdw = (p(vec.x, vec.y, vec.z, vec.w + h) - p(vec.x, vec.y, vec.z, vec.w)) / h,
4064
- dqdx = (q(vec.x + h, vec.y, vec.z, vec.w) - q(vec.x, vec.y, vec.z, vec.w)) / h,
4065
- dqdy = (q(vec.x, vec.y + h, vec.z, vec.w) - q(vec.x, vec.y, vec.z, vec.w)) / h,
4066
- dqdz = (q(vec.x, vec.y, vec.z + h, vec.w) - q(vec.x, vec.y, vec.z, vec.w)) / h,
4067
- dqdw = (q(vec.x, vec.y, vec.z, vec.w + h) - q(vec.x, vec.y, vec.z, vec.w)) / h,
4068
- drdx = (r(vec.x + h, vec.y, vec.z, vec.w) - r(vec.x, vec.y, vec.z, vec.w)) / h,
4069
- drdy = (r(vec.x, vec.y + h, vec.z, vec.w) - r(vec.x, vec.y, vec.z, vec.w)) / h,
4070
- drdz = (r(vec.x, vec.y, vec.z + h, vec.w) - r(vec.x, vec.y, vec.z, vec.w)) / h,
4071
- drdw = (r(vec.x, vec.y, vec.z, vec.w + h) - r(vec.x, vec.y, vec.z, vec.w)) / h,
4072
- dsdx = (s(vec.x + h, vec.y, vec.z, vec.w) - s(vec.x, vec.y, vec.z, vec.w)) / h,
4073
- dsdy = (s(vec.x, vec.y + h, vec.z, vec.w) - s(vec.x, vec.y, vec.z, vec.w)) / h,
4074
- dsdz = (s(vec.x, vec.y, vec.z + h, vec.w) - s(vec.x, vec.y, vec.z, vec.w)) / h,
4075
- dsdw = (s(vec.x, vec.y, vec.z, vec.w + h) - s(vec.x, vec.y, vec.z, vec.w)) / h;
4076
- return Chalkboard.matr.new([dpdx, dpdy, dpdz, dpdw],
4077
- [dqdx, dqdy, dqdz, dqdw],
4078
- [drdx, drdy, drdz, drdw],
4079
- [dsdx, dsdy, dsdz, dsdw]);
4080
- } else {
4081
- return "TypeError: Parameter \"funcORvecfield\" must be of type \"surf\", \"mult\", \"vec2field\", \"vec3field\", or \"vec4field\".";
4082
- }
4083
- },
4084
- grad2: function(funcORvecfield, vec) {
4085
- var h = 0.00001;
4086
- if(funcORvecfield.type === "surf") {
4087
- var x = Chalkboard.real.parse("(s, t) => " + funcORvecfield.definition[0]),
4088
- y = Chalkboard.real.parse("(s, t) => " + funcORvecfield.definition[1]),
4089
- z = Chalkboard.real.parse("(s, t) => " + funcORvecfield.definition[2]);
4090
- var d2xds2 = (x(vec.x + h, vec.y) - 2 * x(vec.x, vec.y) + x(vec.x - h, vec.y)) / (h * h),
4091
- d2xdt2 = (x(vec.x, vec.y + h) - 2 * x(vec.x, vec.y) + x(vec.x, vec.y - h)) / (h * h),
4092
- d2yds2 = (y(vec.x + h, vec.y) - 2 * y(vec.x, vec.y) + y(vec.x - h, vec.y)) / (h * h),
4093
- d2ydt2 = (y(vec.x, vec.y + h) - 2 * y(vec.x, vec.y) + y(vec.x, vec.y - h)) / (h * h),
4094
- d2zds2 = (z(vec.x + h, vec.y) - 2 * z(vec.x, vec.y) + z(vec.x - h, vec.y)) / (h * h),
4095
- d2zdt2 = (z(vec.x, vec.y + h) - 2 * z(vec.x, vec.y) + z(vec.x, vec.y - h)) / (h * h);
4096
- return Chalkboard.matr.new([d2xds2, d2xdt2],
4097
- [d2yds2, d2ydt2],
4098
- [d2zds2, d2zdt2]);
4099
- } else if(funcORvecfield.type === "mult") {
4100
- var f = Chalkboard.real.parse("(x, y) => " + funcORvecfield.definition);
4101
- var d2fdx2 = (f(vec.x + h, vec.y) - 2 * f(vec.x, vec.y) + f(vec.x - h, vec.y)) / (h * h),
4102
- d2fdy2 = (f(vec.x, vec.y + h) - 2 * f(vec.x, vec.y) + f(vec.x, vec.y - h)) / (h * h),
4103
- d2fdxdy = (f(vec.x + h, vec.y + h) - f(vec.x + h, vec.y) - f(vec.x, vec.y + h) + f(vec.x, vec.y)) / (h * h),
4104
- d2fdydx = (f(vec.x + h, vec.y + h) - f(vec.x, vec.y + h) - f(vec.x + h, vec.y) + f(vec.x, vec.y)) / (h * h);
4105
- return Chalkboard.matr.new([d2fdx2, d2fdxdy],
4106
- [d2fdydx, d2fdy2]);
4107
- } else if(funcORvecfield.type === "vec2field") {
4108
- var p = Chalkboard.real.parse("(x, y) => " + funcORvecfield.p),
4109
- q = Chalkboard.real.parse("(x, y) => " + funcORvecfield.q);
4110
- var d2pdx2 = (p(vec.x + h, vec.y) - 2 * p(vec.x, vec.y) + p(vec.x - h, vec.y)) / (h * h),
4111
- d2pdy2 = (p(vec.x, vec.y + h) - 2 * p(vec.x, vec.y) + p(vec.x, vec.y - h)) / (h * h),
4112
- d2qdx2 = (q(vec.x + h, vec.y) - 2 * q(vec.x, vec.y) + q(vec.x - h, vec.y)) / (h * h),
4113
- d2qdy2 = (q(vec.x, vec.y + h) - 2 * q(vec.x, vec.y) + q(vec.x, vec.y - h)) / (h * h);
4114
- return Chalkboard.matr.new([d2pdx2, d2pdy2],
4115
- [d2qdx2, d2qdy2]);
4116
- } else if(funcORvecfield.type === "vec3field") {
4117
- var p = Chalkboard.real.parse("(x, y, z) => " + funcORvecfield.p),
4118
- q = Chalkboard.real.parse("(x, y, z) => " + funcORvecfield.q),
4119
- r = Chalkboard.real.parse("(x, y, z) => " + funcORvecfield.r);
4120
- var d2pdx2 = (p(vec.x + h, vec.y, vec.z) - 2 * p(vec.x, vec.y, vec.z) + p(vec.x - h, vec.y, vec.z)) / (h * h),
4121
- d2pdy2 = (p(vec.x, vec.y + h, vec.z) - 2 * p(vec.x, vec.y, vec.z) + p(vec.x, vec.y - h, vec.z)) / (h * h),
4122
- d2pdz2 = (p(vec.x, vec.y, vec.z + h) - 2 * p(vec.x, vec.y, vec.z) + p(vec.x, vec.y, vec.z - h)) / (h * h),
4123
- d2qdx2 = (q(vec.x + h, vec.y, vec.z) - 2 * q(vec.x, vec.y, vec.z) + q(vec.x - h, vec.y, vec.z)) / (h * h),
4124
- d2qdy2 = (q(vec.x, vec.y + h, vec.z) - 2 * q(vec.x, vec.y, vec.z) + q(vec.x, vec.y - h, vec.z)) / (h * h),
4125
- d2qdz2 = (q(vec.x, vec.y, vec.z + h) - 2 * q(vec.x, vec.y, vec.z) + q(vec.x, vec.y, vec.z - h)) / (h * h),
4126
- d2rdx2 = (r(vec.x + h, vec.y, vec.z) - 2 * r(vec.x, vec.y, vec.z) + r(vec.x - h, vec.y, vec.z)) / (h * h),
4127
- d2rdy2 = (r(vec.x, vec.y + h, vec.z) - 2 * r(vec.x, vec.y, vec.z) + r(vec.x, vec.y - h, vec.z)) / (h * h),
4128
- d2rdz2 = (r(vec.x, vec.y, vec.z + h) - 2 * r(vec.x, vec.y, vec.z) + r(vec.x, vec.y, vec.z - h)) / (h * h);
4129
- return Chalkboard.matr.new([d2pdx2, d2pdy2, d2pdz2],
4130
- [d2qdx2, d2qdy2, d2qdz2],
4131
- [d2rdx2, d2rdy2, d2rdz2]);
4132
- } else if(funcORvecfield.type === "vec4field") {
4133
- var p = Chalkboard.real.parse("(x, y, z, w) => " + funcORvecfield.p),
4134
- q = Chalkboard.real.parse("(x, y, z, w) => " + funcORvecfield.q),
4135
- r = Chalkboard.real.parse("(x, y, z, w) => " + funcORvecfield.r),
4136
- s = Chalkboard.real.parse("(x, y, z, w) => " + funcORvecfield.s);
4137
- var d2pdx2 = (p(vec.x + h, vec.y, vec.z, vec.w) - 2 * p(vec.x, vec.y, vec.z, vec.w) + p(vec.x - h, vec.y, vec.z, vec.w)) / (h * h),
4138
- d2pdy2 = (p(vec.x, vec.y + h, vec.z, vec.w) - 2 * p(vec.x, vec.y, vec.z, vec.w) + p(vec.x, vec.y - h, vec.z, vec.w)) / (h * h),
4139
- d2pdz2 = (p(vec.x, vec.y, vec.z + h, vec.w) - 2 * p(vec.x, vec.y, vec.z, vec.w) + p(vec.x, vec.y, vec.z - h, vec.w)) / (h * h),
4140
- d2pdw2 = (p(vec.x, vec.y, vec.z, vec.w + h) - 2 * p(vec.x, vec.y, vec.z, vec.w) + p(vec.x, vec.y, vec.z, vec.w - h)) / (h * h),
4141
- d2qdx2 = (q(vec.x + h, vec.y, vec.z, vec.w) - 2 * q(vec.x, vec.y, vec.z, vec.w) + q(vec.x - h, vec.y, vec.z, vec.w)) / (h * h),
4142
- d2qdy2 = (q(vec.x, vec.y + h, vec.z, vec.w) - 2 * q(vec.x, vec.y, vec.z, vec.w) + q(vec.x, vec.y - h, vec.z, vec.w)) / (h * h),
4143
- d2qdz2 = (q(vec.x, vec.y, vec.z + h, vec.w) - 2 * q(vec.x, vec.y, vec.z, vec.w) + q(vec.x, vec.y, vec.z - h, vec.w)) / (h * h),
4144
- d2qdw2 = (q(vec.x, vec.y, vec.z, vec.w + h) - 2 * q(vec.x, vec.y, vec.z, vec.w) + q(vec.x, vec.y, vec.z, vec.w - h)) / (h * h),
4145
- d2rdx2 = (r(vec.x + h, vec.y, vec.z, vec.w) - 2 * r(vec.x, vec.y, vec.z, vec.w) + r(vec.x - h, vec.y, vec.z, vec.w)) / (h * h),
4146
- d2rdy2 = (r(vec.x, vec.y + h, vec.z, vec.w) - 2 * r(vec.x, vec.y, vec.z, vec.w) + r(vec.x, vec.y - h, vec.z, vec.w)) / (h * h),
4147
- d2rdz2 = (r(vec.x, vec.y, vec.z + h, vec.w) - 2 * r(vec.x, vec.y, vec.z, vec.w) + r(vec.x, vec.y, vec.z - h, vec.w)) / (h * h),
4148
- d2rdw2 = (r(vec.x, vec.y, vec.z, vec.w + h) - 2 * r(vec.x, vec.y, vec.z, vec.w) + r(vec.x, vec.y, vec.z, vec.w - h)) / (h * h),
4149
- d2sdx2 = (s(vec.x + h, vec.y, vec.z, vec.w) - 2 * s(vec.x, vec.y, vec.z, vec.w) + s(vec.x - h, vec.y, vec.z, vec.w)) / (h * h),
4150
- d2sdy2 = (s(vec.x, vec.y + h, vec.z, vec.w) - 2 * s(vec.x, vec.y, vec.z, vec.w) + s(vec.x, vec.y - h, vec.z, vec.w)) / (h * h),
4151
- d2sdz2 = (s(vec.x, vec.y, vec.z + h, vec.w) - 2 * s(vec.x, vec.y, vec.z, vec.w) + s(vec.x, vec.y, vec.z - h, vec.w)) / (h * h),
4152
- d2sdw2 = (s(vec.x, vec.y, vec.z, vec.w + h) - 2 * s(vec.x, vec.y, vec.z, vec.w) + s(vec.x, vec.y, vec.z, vec.w - h)) / (h * h);
4153
- return Chalkboard.matr.new([d2pdx2, d2pdy2, d2pdz2, d2pdw2],
4154
- [d2qdx2, d2qdy2, d2qdz2, d2qdw2],
4155
- [d2rdx2, d2rdy2, d2rdz2, d2rdw2],
4156
- [d2sdx2, d2sdy2, d2sdz2, d2sdw2]);
4157
- } else {
4158
- return "TypeError: Parameter \"funcORvecfield\" must be of type \"surf\", \"mult\", \"vec2field\", \"vec3field\", or \"vec4field\".";
4159
- }
4160
- },
4161
- div: function(vecfield, vec) {
4162
- if(vecfield.type === "vec2field" || vecfield.type === "vec3field" || vecfield.type === "vec4field") {
4163
- return Chalkboard.matr.trace(Chalkboard.calc.grad(vecfield, vec));
4164
- } else {
4165
- return "TypeError: Parameter \"vecfield\" must be of type \"vec2field\", \"vec3field\", or \"vec4field\".";
4166
- }
4167
- },
4168
- curl: function(vecfield, vec) {
4169
- var h = 0.000000001;
4170
- if(vecfield.type === "vec2field") {
4171
- var p = Chalkboard.real.parse("(x, y) => " + vecfield.p),
4172
- q = Chalkboard.real.parse("(x, y) => " + vecfield.q);
4173
- var dpdy = (p(vec.x, vec.y + h) - p(vec.x, vec.y)) / h,
4174
- dqdx = (q(vec.x + h, vec.y) - q(vec.x, vec.y)) / h;
4175
- return Chalkboard.vec3.new(0, 0, dqdx - dpdy);
4176
- } else if(vecfield.type === "vec3field") {
4177
- var p = Chalkboard.real.parse("(x, y, z) => " + vecfield.p),
4178
- q = Chalkboard.real.parse("(x, y, z) => " + vecfield.q),
4179
- r = Chalkboard.real.parse("(x, y, z) => " + vecfield.r);
4180
- var dpdy = (p(vec.x, vec.y + h, vec.z) - p(vec.x, vec.y, vec.z)) / h,
4181
- dpdz = (p(vec.x, vec.y, vec.z + h) - p(vec.x, vec.y, vec.z)) / h,
4182
- dqdx = (q(vec.x + h, vec.y, vec.z) - q(vec.x, vec.y, vec.z)) / h,
4183
- dqdz = (q(vec.x, vec.y, vec.z + h) - q(vec.x, vec.y, vec.z)) / h,
4184
- drdx = (r(vec.x + h, vec.y, vec.z) - r(vec.x, vec.y, vec.z)) / h,
4185
- drdy = (r(vec.x, vec.y + h, vec.z) - r(vec.x, vec.y, vec.z)) / h;
4186
- return Chalkboard.vec3.new(drdy - dqdz, dpdz - drdx, dqdx - dpdy);
4187
- } else {
4188
- return "TypeError: Parameter \"vecfield\" must be of type \"vec2field\" or \"vec3field\".";
4189
- }
4190
- },
4191
- dfdz: function(func, comp) {
4192
- var h = 0.000000001;
4193
- if(func.type === "comp") {
4194
- var u = Chalkboard.comp.parse("(a, b) => " + func.definition[0]),
4195
- v = Chalkboard.comp.parse("(a, b) => " + func.definition[1]);
4196
- var duda = (u(comp.a + h, comp.b) - u(comp.a, comp.b)) / h,
4197
- dudb = (u(comp.a, comp.b + h) - u(comp.a, comp.b)) / h,
4198
- dvda = (v(comp.a + h, comp.b) - v(comp.a, comp.b)) / h,
4199
- dvdb = (v(comp.a, comp.b + h) - v(comp.a, comp.b)) / h;
4200
- return {a: Chalkboard.comp.new(duda, dvda), b: Chalkboard.comp.new(dudb, dvdb)};
4201
- } else {
4202
- return "TypeError: Parameter \"func\" must be of type \"comp\".";
4203
- }
4204
- },
4205
- d2fdz2: function(func, comp) {
4206
- var h = 0.00001;
4207
- if(func.type === "comp") {
4208
- var u = Chalkboard.comp.parse("(a, b) => " + func.definition[0]),
4209
- v = Chalkboard.comp.parse("(a, b) => " + func.definition[1]);
4210
- var d2uda2 = (u(comp.a + h, comp.b) - 2 * u(comp.a, comp.b) + u(comp.a - h, comp.b)) / (h * h),
4211
- d2udb2 = (u(comp.a, comp.b + h) - 2 * u(comp.a, comp.b) + u(comp.a, comp.b - h)) / (h * h),
4212
- d2vda2 = (v(comp.a + h, comp.b) - 2 * v(comp.a, comp.b) + v(comp.a - h, comp.b)) / (h * h),
4213
- d2vdb2 = (v(comp.a, comp.b + h) - 2 * v(comp.a, comp.b) + v(comp.a, comp.b - h)) / (h * h);
4214
- return {a: Chalkboard.comp.new(d2uda2, d2vda2), b: Chalkboard.comp.new(d2udb2, d2vdb2)};
4215
- } else {
4216
- return "TypeError: Parameter \"func\" must be of type \"comp\".";
4217
- }
4218
- },
4219
- fxdx: function(func, inf, sup) {
4220
- if(func.type === "expl" || func.type === "inve" || func.type === "pola") {
4221
- var f;
4222
- if(func.type === "expl") {
4223
- f = Chalkboard.real.parse("x => " + func.definition);
4224
- } else if(func.type === "inve") {
4225
- f = Chalkboard.real.parse("y => " + func.definition);
4226
- } else if(func.type === "pola") {
4227
- f = Chalkboard.real.parse("O => " + "((" + func.definition + ") * (" + func.definition + ")) / 2");
4228
- }
4229
- var fx = f(inf) + f(sup);
4230
- var dx = (sup - inf) / 1000000;
4231
- for(var i = 1; i < 1000000; i++) {
4232
- fx += i % 2 === 0 ? 2 * f(inf + i * dx) : 4 * f(inf + i * dx);
4233
- }
4234
- return (fx * dx) / 3;
4235
- } else if(func.type === "curv") {
4236
- if(func.definition.length === 2) {
4237
- var x = Chalkboard.real.parse("t => " + func.definition[0]),
4238
- y = Chalkboard.real.parse("t => " + func.definition[1]);
4239
- var xt = x(inf) + x(sup),
4240
- yt = y(inf) + y(sup);
4241
- var dt = (sup - inf) / 1000000;
4242
- for(var i = 1; i < 1000000; i++) {
4243
- xt += i % 2 === 0 ? 2 * x(inf + i * dt) : 4 * x(inf + i * dt);
4244
- yt += i % 2 === 0 ? 2 * y(sup + i * dt) : 4 * y(sup + i * dt);
4245
- }
4246
- return Chalkboard.vec2.new((xt * dt) / 3, (yt * dt) / 3);
4247
- } else if(func.definition.length === 3) {
4248
- var x = Chalkboard.real.parse("t => " + func.definition[0]),
4249
- y = Chalkboard.real.parse("t => " + func.definition[1]),
4250
- z = Chalkboard.real.parse("t => " + func.definition[2]);
4251
- var xt = x(inf) + x(sup),
4252
- yt = y(inf) + y(sup),
4253
- zt = z(inf) + z(sup);
4254
- var dt = (sup - inf) / 1000000;
4255
- for(var i = 1; i < 1000000; i++) {
4256
- xt += i % 2 === 0 ? 2 * x(inf + i * dt) : 4 * x(inf + i * dt);
4257
- yt += i % 2 === 0 ? 2 * y(inf + i * dt) : 4 * y(inf + i * dt);
4258
- zt += i % 2 === 0 ? 2 * z(inf + i * dt) : 4 * z(inf + i * dt);
4259
- }
4260
- return Chalkboard.vec3.new((xt * dt) / 3, (yt * dt) / 3, (zt * dt) / 3);
4261
- }
4262
- } else {
4263
- return "TypeError: Parameter \"func\" must be of type \"expl\", \"inve\", \"pola\", or \"curv\".";
4264
- }
4265
- },
4266
- fxydxdy: function(func, xinf, xsup, yinf, ysup) {
4267
- if(func.type === "mult") {
4268
- var f = Chalkboard.real.parse("(x, y) => " + func.definition);
4269
- var result = 0;
4270
- var dx = (xsup - xinf) / 10000,
4271
- dy = (ysup - yinf) / 10000;
4272
- for(var x = xinf; x <= xsup; x += dx) {
4273
- for(var y = yinf; y <= ysup; y += dy) {
4274
- result += f(x, y);
4275
- }
4276
- }
4277
- return result * dx * dy;
4278
- } else {
4279
- return "TypeError: Parameter \"func\" must be of type \"mult\".";
4280
- }
4281
- },
4282
- fds: function(func, tinf, tsup, sinf, ssup) {
4283
- var result = 0;
4284
- var drdt, drds;
4285
- if(func.type === "curv") {
4286
- var dt = (tsup - tinf) / 10000;
4287
- if(func.definition.length === 2) {
4288
- for(var t = tinf; t <= tsup; t += dt) {
4289
- drdt = Chalkboard.calc.dfdx(func, t);
4290
- result += Chalkboard.vec2.mag(drdt);
4291
- }
4292
- return result * dt;
4293
- } else if(func.definition.length === 3) {
4294
- for(var t = tinf; t <= tsup; t += dt) {
4295
- drdt = Chalkboard.calc.dfdx(func, t);
4296
- result += Chalkboard.vec3.mag(drdt);
4297
- }
4298
- return result * dt;
4299
- }
4300
- } else if(func.type === "surf") {
4301
- var dt = (tsup - tinf) / 100,
4302
- ds = (ssup - sinf) / 100;
4303
- for(var s = sinf; s <= ssup; s += ds) {
4304
- for(var t = tinf; t <= tsup; t += dt) {
4305
- drds = Chalkboard.matr.toVector(Chalkboard.calc.grad(func, Chalkboard.vec2.new(s, t)), "vec3", "col", 1);
4306
- drdt = Chalkboard.matr.toVector(Chalkboard.calc.grad(func, Chalkboard.vec2.new(s, t)), "vec3", "col", 2);
4307
- result += Chalkboard.vec3.mag(Chalkboard.vec3.cross(drds, drdt));
4308
- }
4309
- }
4310
- return result * ds * dt;
4311
- } else {
4312
- return "TypeError: Parameter \"func\" must be of type \"curv\" or \"surf\".";
4313
- }
4314
- },
4315
- frds: function(funcORvecfield, func, inf, sup) {
4316
- if(func.type === "curv") {
4317
- var result = 0;
4318
- var dt = (sup - inf) / 10000;
4319
- if(funcORvecfield.type === "mult") {
4320
- for(var t = inf; t <= sup; t += dt) {
4321
- result += Chalkboard.real.val(funcORvecfield, Chalkboard.real.val(func, t)) * Chalkboard.vec2.mag(Chalkboard.calc.dfdx(func, t));
4322
- }
4323
- return result * dt;
4324
- } else if(funcORvecfield.type === "vec2field") {
4325
- for(var t = inf; t <= sup; t += dt) {
4326
- result += Chalkboard.vec2.dot(Chalkboard.vec2.fromField(funcORvecfield, Chalkboard.real.val(func, t)), Chalkboard.calc.dfdx(func, t));
4327
- }
4328
- return result * dt;
4329
- } else if(funcORvecfield.type === "vec3field") {
4330
- for(var t = inf; t <= sup; t += dt) {
4331
- result += Chalkboard.vec3.dot(Chalkboard.vec3.fromField(funcORvecfield, Chalkboard.real.val(func, t)), Chalkboard.calc.dfdx(func, t));
4332
- }
4333
- return result * dt;
4334
- } else {
4335
- return "TypeError: Parameter \"funcORvecfield\" must be of type \"mult\", \"vec2field\", or \"vec3field\".";
4336
- }
4337
- } else {
4338
- return "TypeError: Parameter \"func\" must be of type \"curv\".";
4339
- }
4340
- },
4341
- fnds: function(vecfield, func, tinf, tsup, sinf, ssup) {
4342
- var result = 0;
4343
- var drdt, drds;
4344
- if(func.type === "curv") {
4345
- var dt = (tsup - tinf) / 10000;
4346
- if(func.definition.length === 2) {
4347
- for(var t = tinf; t <= tsup; t += dt) {
4348
- drdt = Chalkboard.calc.dfdx(func, t);
4349
- result += Chalkboard.vec2.dot(Chalkboard.vec2.fromField(vecfield, Chalkboard.real.val(func, t)), Chalkboard.vec2.new(-drdt.y, drdt.x)) * Chalkboard.vec2.mag(drdt);
4350
- }
4351
- return result * dt;
4352
- } else if(func.definition.length === 3) {
4353
- for(var t = tinf; t <= tsup; t += dt) {
4354
- drdt = Chalkboard.calc.dfdx(func, t);
4355
- result += Chalkboard.vec3.dot(Chalkboard.vec3.fromField(vecfield, Chalkboard.real.val(func, t)), Chalkboard.calc.normal(func, t)) * Chalkboard.vec3.mag(drdt);
4356
- }
4357
- return result * dt;
4358
- }
4359
- } else if(func.type === "surf") {
4360
- var dt = (tsup - tinf) / 100,
4361
- ds = (ssup - sinf) / 100;
4362
- for(var s = sinf; s <= ssup; s += ds) {
4363
- for(var t = tinf; t <= tsup; t += dt) {
4364
- drds = Chalkboard.matr.toVector(Chalkboard.calc.grad(func, Chalkboard.vec2.new(s, t)), "vec3", "col", 1);
4365
- drdt = Chalkboard.matr.toVector(Chalkboard.calc.grad(func, Chalkboard.vec2.new(s, t)), "vec3", "col", 2);
4366
- result += Chalkboard.vec3.scalarTriple(Chalkboard.vec3.fromField(vecfield, Chalkboard.real.val(func, Chalkboard.vec2.new(s, t))), drds, drdt);
4367
- }
4368
- }
4369
- return result * ds * dt;
4370
- } else {
4371
- return "TypeError: Parameter \"func\" must be of type \"curv\" or \"surf\".";
4372
- }
4373
- },
4374
- fzdz: function(func_1, func_2, inf, sup) {
4375
- if(func_1.type === "comp") {
4376
- if(func_2.type === "curv") {
4377
- var result = Chalkboard.comp.new(0, 0);
4378
- var dt = (sup - inf) / 10000;
4379
- for(var t = inf; t <= sup; t += dt) {
4380
- var fz = Chalkboard.comp.val(func_1, Chalkboard.vec2.toComplex(Chalkboard.real.val(func_2, t)));
4381
- var rt = Chalkboard.calc.dfdx(func_2, t);
4382
- result = Chalkboard.comp.add(result, Chalkboard.comp.new((fz.a * rt.x) - (fz.b * rt.y), (fz.b * rt.x) + (fz.a * rt.y)));
4383
- }
4384
- return Chalkboard.comp.scl(result, dt);
4385
- } else {
4386
- return "TypeError: Parameter \"func_2\" must be of type \"curv\".";
4387
- }
4388
- } else {
4389
- return "TypeError: Parameter \"func_1\" must be of type \"comp\".";
4390
- }
4391
- },
4392
- extrema: function(func, domain) {
4393
- var result = [];
4394
- for(var i = domain[0]; i <= domain[1]; i++) {
4395
- if(Math.round(Chalkboard.calc.dfdx(func, i)) === 0) {
4396
- result.push(i);
4397
- }
4398
- }
4399
- return result;
4400
- },
4401
- mean: function(func, a, b) {
4402
- return (Chalkboard.calc.fxdx(func, a, b)) / (b - a);
4403
- },
4404
- curvature: function(func, val) {
4405
- if(func.type === "curv") {
4406
- if(func.definition.length === 2) {
4407
- var dxdt = Chalkboard.calc.dfdx(func, val).x,
4408
- dydt = Chalkboard.calc.dfdx(func, val).y,
4409
- d2xdt2 = Chalkboard.calc.d2fdx2(func, val).x,
4410
- d2ydt2 = Chalkboard.calc.d2fdx2(func, val).y;
4411
- return Math.abs(dxdt * d2ydt2 - dydt * d2xdt2) / Math.sqrt((dxdt * dxdt + dydt * dydt) * (dxdt * dxdt + dydt * dydt) * (dxdt * dxdt + dydt * dydt));
4412
- } else if(func.definition.length === 3) {
4413
- return Chalkboard.vec3.mag(Chalkboard.calc.normal(func, val)) / Chalkboard.vec3.mag(Chalkboard.calc.dfdx(func, val));
4414
- }
4415
- } else {
4416
- return "TypeError: Parameter \"func\" must be of type \"curv\".";
4417
- }
4418
- },
4419
- convolution: function(func_1, func_2, val) {
4420
- return Chalkboard.calc.fxdx(Chalkboard.real.function("(" + func_1.definition + ") * (" + func_2.definition.replace(/x/g, "(" + val + " - x)") + ")"), -100, 100);
4421
- },
4422
- correlation: function(func_1, func_2, val) {
4423
- return Chalkboard.calc.fxdx(Chalkboard.real.function("(" + func_1.definition + ") * (" + func_2.definition.replace(/x/g, "(" + val + " + x)") + ")"), -100, 100);
4424
- },
4425
- autocorrelation: function(func, val) {
4426
- return Chalkboard.calc.correlation(func, func, val);
4427
- },
4428
- Taylor: function(func, val, n, a) {
4429
- if(func.type === "expl") {
4430
- if(n === 0) {
4431
- return Chalkboard.real.val(func, a);
4432
- } else if(n === 1) {
4433
- return Chalkboard.real.val(func, a) + Chalkboard.calc.dfdx(func, a) * (val - a);
4434
- } else if(n === 2) {
4435
- return Chalkboard.real.val(func, a) + Chalkboard.calc.dfdx(func, a) * (val - a) + (Chalkboard.calc.d2fdx2(func, a) * (val - a) * (val - a)) / 2;
4436
- }
4437
- } else {
4438
- return "TypeError: Parameter \"func\" must be of type \"expl\".";
4439
- }
4440
- },
4441
- Laplace: function(func, val) {
4442
- if(val > 0) {
4443
- return Chalkboard.calc.fxdx(Chalkboard.real.function("(" + func.definition + ") * Math.exp(-" + val + " * x)"), 0, 10);
4444
- } else {
4445
- return undefined;
4446
- }
4447
- },
4448
- Fourier: function(func, val) {
4449
- return (2 * Chalkboard.calc.fxdx(Chalkboard.real.function("(" + func.definition + ") * Math.cos(" + val + " * x)"), 0, 10)) / Chalkboard.PI();
4450
- },
4451
- Newton: function(func, domain) {
4452
- domain = domain || [-1, 1];
4453
- var x = Chalkboard.numb.random(domain[0], domain[1]);
4454
- for(var i = 0; i < 10; i++) {
4455
- x = x - Chalkboard.real.val(func, x) / Chalkboard.calc.dfdx(func, x);
4456
- }
4457
- return x;
4458
- }
4459
- }
4460
- };