@zushah/chalkboard 1.6.0 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/Chalkboard.js CHANGED
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  The Chalkboard Library
3
- Version 1.6.0 released 12/25/2023
3
+ Version 1.7.0 Descartes released 01/01/2024
4
4
  Authored by Zushah ===> https://www.github.com/Zushah
5
5
  Available under the MIT License ===> https://www.opensource.org/license/mit/
6
6
 
@@ -11,13 +11,13 @@
11
11
  */
12
12
  var Chalkboard = {
13
13
  README: function() {
14
- console.log("The Chalkboard Library\nVersion 1.6.0 released 12/25/2023\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");
14
+ console.log("The Chalkboard Library\nVersion 1.7.0 Descartes released 01/01/2024\nAuthored by Zushah ===> https://www.github.com/Zushah\nAvailable under the MIT License ===> https://www.opensource.org/license/mit/\n\nThe Chalkboard library is a JavaScript namespace that provides a plethora of both practical and abstract mathematical functionalities for its user.\n\nRepository ===> https://www.github.com/Zushah/Chalkboard\nWebsite ===> https://zushah.github.io/Chalkboard/home.html");
15
15
  },
16
16
  LOGO: function(x, y, s, context) {
17
- x = x || Chalkboard.real.parse(Chalkboard.plot.CONTEXT).canvas.width / 2;
18
- y = y || Chalkboard.real.parse(Chalkboard.plot.CONTEXT).canvas.height / 2;
17
+ x = x || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.width / 2;
18
+ y = y || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.height / 2;
19
19
  s = s || 1;
20
- context = context || Chalkboard.real.parse(Chalkboard.plot.CONTEXT);
20
+ context = context || Chalkboard.real.parse(Chalkboard.CONTEXT);
21
21
  context.save();
22
22
  context.translate(x, y);
23
23
  context.scale(s, s);
@@ -50,6 +50,8 @@ var Chalkboard = {
50
50
  exponent = exponent || 1;
51
51
  return Math.pow(Math.pow(10, 1 / Math.log(10)), exponent);
52
52
  },
53
+ CONTEXT: "ctx",
54
+ PARSEPREFIX: "",
53
55
  numb: {
54
56
  random: function(inf, sup) {
55
57
  if(inf === undefined) {
@@ -264,11 +266,23 @@ var Chalkboard = {
264
266
  }
265
267
  },
266
268
  binomial: function(n, k) {
269
+ if(k < 0 || k > n) {
270
+ return 0;
271
+ }
267
272
  if(k === 0 || k === n) {
268
273
  return 1;
269
- } else {
270
- return Chalkboard.numb.binomial(n - 1, k - 1) + Chalkboard.numb.binomial(n - 1, k);
271
274
  }
275
+ if(k === 1 || k === n - 1) {
276
+ return n;
277
+ }
278
+ if(n - k < k) {
279
+ k = n - k;
280
+ }
281
+ var result = n;
282
+ for(var i = 2; i <= k; i++) {
283
+ result *= (n - i + 1) / i;
284
+ }
285
+ return Math.round(result);
272
286
  },
273
287
  Fibonacci: function(num) {
274
288
  var sequence = [0, 1];
@@ -331,9 +345,8 @@ var Chalkboard = {
331
345
  return "TypeError: Parameter \"type\" must be either \"expl\", \"inve\", \"pola\", \"curv\", \"surf\", or \"mult\".";
332
346
  }
333
347
  },
334
- parse: function(str, init) {
335
- init = init || '';
336
- return Function('"use strict"; ' + init + ' return (' + str + ')')();
348
+ parse: function(str) {
349
+ return Function('"use strict"; ' + Chalkboard.PARSEPREFIX + ' return (' + str + ')')();
337
350
  },
338
351
  val: function(func, val) {
339
352
  if(func.type === "expl") {
@@ -515,14 +528,20 @@ var Chalkboard = {
515
528
  },
516
529
  comp: {
517
530
  new: function(a, b) {
518
- return {a: a, b: b, type: "comp"};
531
+ if(b === undefined) {
532
+ return {a: a, b: 0, type: "comp"};
533
+ } else {
534
+ return {a: a, b: b, type: "comp"};
535
+ }
536
+ },
537
+ copy: function(comp) {
538
+ return Object.create(Object.getPrototypeOf(comp), Object.getOwnPropertyDescriptors(comp));
519
539
  },
520
540
  function: function(realDefinition, imagDefinition) {
521
541
  return {definition: [realDefinition, imagDefinition], type: "comp"};
522
542
  },
523
- parse: function(str, init) {
524
- init = init || '';
525
- return Function('"use strict"; ' + init + ' return (' + str + ')')();
543
+ parse: function(str) {
544
+ return Function('"use strict"; ' + Chalkboard.PARSEPREFIX + ' return (' + str + ')')();
526
545
  },
527
546
  val: function(func, comp) {
528
547
  if(func.type === "comp") {
@@ -623,9 +642,21 @@ var Chalkboard = {
623
642
  return Chalkboard.comp.new(comp.a, -comp.b);
624
643
  },
625
644
  dist: function(comp_1, comp_2) {
645
+ if(typeof comp_1 === "number") {
646
+ comp_1 = Chalkboard.comp.new(comp_1, 0);
647
+ }
648
+ if(typeof comp_2 === "number") {
649
+ comp_2 = Chalkboard.comp.new(comp_2, 0);
650
+ }
626
651
  return Chalkboard.real.sqrt(((comp_2.a - comp_1.a) * (comp_2.a - comp_1.a)) + ((comp_2.b - comp_1.b) * (comp_2.b - comp_1.b)));
627
652
  },
628
653
  distsq: function(comp_1, comp_2) {
654
+ if(typeof comp_1 === "number") {
655
+ comp_1 = Chalkboard.comp.new(comp_1, 0);
656
+ }
657
+ if(typeof comp_2 === "number") {
658
+ comp_2 = Chalkboard.comp.new(comp_2, 0);
659
+ }
629
660
  return ((comp_2.a - comp_1.a) * (comp_2.a - comp_1.a)) + ((comp_2.b - comp_1.b) * (comp_2.b - comp_1.b));
630
661
  },
631
662
  scl: function(comp, num) {
@@ -635,15 +666,39 @@ var Chalkboard = {
635
666
  return Chalkboard.comp.new(Chalkboard.numb.constrain(comp.a, range), Chalkboard.numb.constrain(comp.b, range));
636
667
  },
637
668
  add: function(comp_1, comp_2) {
669
+ if(typeof comp_1 === "number") {
670
+ comp_1 = Chalkboard.comp.new(comp_1, 0);
671
+ }
672
+ if(typeof comp_2 === "number") {
673
+ comp_2 = Chalkboard.comp.new(comp_2, 0);
674
+ }
638
675
  return Chalkboard.comp.new(comp_1.a + comp_2.a, comp_1.b + comp_2.b);
639
676
  },
640
677
  sub: function(comp_1, comp_2) {
678
+ if(typeof comp_1 === "number") {
679
+ comp_1 = Chalkboard.comp.new(comp_1, 0);
680
+ }
681
+ if(typeof comp_2 === "number") {
682
+ comp_2 = Chalkboard.comp.new(comp_2, 0);
683
+ }
641
684
  return Chalkboard.comp.new(comp_1.a - comp_2.a, comp_1.b - comp_2.b);
642
685
  },
643
686
  mul: function(comp_1, comp_2) {
687
+ if(typeof comp_1 === "number") {
688
+ comp_1 = Chalkboard.comp.new(comp_1, 0);
689
+ }
690
+ if(typeof comp_2 === "number") {
691
+ comp_2 = Chalkboard.comp.new(comp_2, 0);
692
+ }
644
693
  return Chalkboard.comp.new((comp_1.a * comp_2.a) - (comp_1.b * comp_2.b), (comp_1.a * comp_2.b) + (comp_1.b * comp_2.a));
645
694
  },
646
695
  div: function(comp_1, comp_2) {
696
+ if(typeof comp_1 === "number") {
697
+ comp_1 = Chalkboard.comp.new(comp_1, 0);
698
+ }
699
+ if(typeof comp_2 === "number") {
700
+ comp_2 = Chalkboard.comp.new(comp_2, 0);
701
+ }
647
702
  return Chalkboard.comp.new(((comp_1.a * comp_2.a) - (comp_1.b * comp_2.b)) / Chalkboard.comp.magsq(comp_2), ((comp_1.a * comp_2.b) + (comp_1.b * comp_2.a)) / Chalkboard.comp.magsq(comp_2));
648
703
  },
649
704
  toVector: function(comp) {
@@ -665,7 +720,14 @@ var Chalkboard = {
665
720
  },
666
721
  quat: {
667
722
  new: function(a, b, c, d) {
668
- return {a: a, b: b, c: c, d: d, type: "quat"};
723
+ if(b === undefined && c === undefined && d === undefined) {
724
+ return {a: a, b: 0, c: 0, d: 0, type: "quat"};
725
+ } else {
726
+ return {a: a, b: b, c: c, d: d, type: "quat"};
727
+ }
728
+ },
729
+ copy: function(quat) {
730
+ return Object.create(Object.getPrototypeOf(quat), Object.getOwnPropertyDescriptors(quat));
669
731
  },
670
732
  random: function(inf, sup) {
671
733
  return Chalkboard.quat.new(Chalkboard.numb.random(inf, sup), Chalkboard.numb.random(inf, sup), Chalkboard.numb.random(inf, sup), Chalkboard.numb.random(inf, sup));
@@ -707,9 +769,21 @@ var Chalkboard = {
707
769
  return Chalkboard.quat.new(quat.a, -quat.b, -quat.c, -quat.d);
708
770
  },
709
771
  dist: function(quat_1, quat_2) {
772
+ if(typeof quat_1 === "number") {
773
+ quat_1 = Chalkboard.quat.new(quat_1, 0, 0, 0);
774
+ }
775
+ if(typeof quat_2 === "number") {
776
+ quat_2 = Chalkboard.quat.new(quat_2, 0, 0, 0);
777
+ }
710
778
  return Chalkboard.real.sqrt(((quat_2.a - quat_1.a) * (quat_2.a - quat_1.a)) + ((quat_2.b - quat_1.b) * (quat_2.b - quat_1.b)) + ((quat_2.c - quat_1.c) * (quat_2.c - quat_1.c)) + ((quat_2.d - quat_1.d) * (quat_2.d - quat_1.d)));
711
779
  },
712
780
  distsq: function(quat_1, quat_2) {
781
+ if(typeof quat_1 === "number") {
782
+ quat_1 = Chalkboard.quat.new(quat_1, 0, 0, 0);
783
+ }
784
+ if(typeof quat_2 === "number") {
785
+ quat_2 = Chalkboard.quat.new(quat_2, 0, 0, 0);
786
+ }
713
787
  return ((quat_2.a - quat_1.a) * (quat_2.a - quat_1.a)) + ((quat_2.b - quat_1.b) * (quat_2.b - quat_1.b)) + ((quat_2.c - quat_1.c) * (quat_2.c - quat_1.c)) + ((quat_2.d - quat_1.d) * (quat_2.d - quat_1.d));
714
788
  },
715
789
  scl: function(quat, num) {
@@ -719,14 +793,41 @@ var Chalkboard = {
719
793
  return Chalkboard.quat.new(Chalkboard.numb.constrain(quat.a, range), Chalkboard.numb.constrain(quat.b, range), Chalkboard.numb.constrain(quat.c, range), Chalkboard.numb.constrain(quat.d, range));
720
794
  },
721
795
  add: function(quat_1, quat_2) {
796
+ if(typeof quat_1 === "number") {
797
+ quat_1 = Chalkboard.quat.new(quat_1, 0, 0, 0);
798
+ }
799
+ if(typeof quat_2 === "number") {
800
+ quat_2 = Chalkboard.quat.new(quat_2, 0, 0, 0);
801
+ }
722
802
  return Chalkboard.quat.new(quat_1.a + quat_2.a, quat_1.b + quat_2.b, quat_1.c + quat_2.c, quat_1.d + quat_2.d);
723
803
  },
724
804
  sub: function(quat_1, quat_2) {
805
+ if(typeof quat_1 === "number") {
806
+ quat_1 = Chalkboard.quat.new(quat_1, 0, 0, 0);
807
+ }
808
+ if(typeof quat_2 === "number") {
809
+ quat_2 = Chalkboard.quat.new(quat_2, 0, 0, 0);
810
+ }
725
811
  return Chalkboard.quat.new(quat_1.a - quat_2.a, quat_1.b - quat_2.b, quat_1.c - quat_2.c, quat_1.d - quat_2.d);
726
812
  },
727
813
  mul: function(quat_1, quat_2) {
814
+ if(typeof quat_1 === "number") {
815
+ quat_1 = Chalkboard.quat.new(quat_1, 0, 0, 0);
816
+ }
817
+ if(typeof quat_2 === "number") {
818
+ quat_2 = Chalkboard.quat.new(quat_2, 0, 0, 0);
819
+ }
728
820
  return Chalkboard.quat.new((quat_1.a * quat_2.a) - (quat_1.b * quat_2.b) - (quat_1.c * quat_2.c) - (quat_1.d * quat_2.d), (quat_1.a * quat_2.b) + (quat_1.b * quat_2.a) + (quat_1.c * quat_2.d) - (quat_1.d * quat_2.c), (quat_1.a * quat_2.c) - (quat_1.b * quat_2.d) + (quat_1.c * quat_2.a) + (quat_1.d * quat_2.b), (quat_1.a * quat_2.d) + (quat_1.b * quat_2.c) - (quat_1.c * quat_2.b) + (quat_1.d * quat_2.a));
729
821
  },
822
+ div: function(quat_1, quat_2) {
823
+ if(typeof quat_1 === "number") {
824
+ quat_1 = Chalkboard.quat.new(quat_1, 0, 0, 0);
825
+ }
826
+ if(typeof quat_2 === "number") {
827
+ quat_2 = Chalkboard.quat.new(quat_2, 0, 0, 0);
828
+ }
829
+ return Chalkboard.quat.new((quat_1.a * quat_2.a + quat_1.b * quat_2.b + quat_1.c * quat_2.c + quat_1.d * quat_2.d) / Chalkboard.quat.magsq(quat_2), (quat_1.b * quat_2.a - quat_1.a * quat_2.b - quat_1.d * quat_2.c + quat_1.c * quat_2.d) / Chalkboard.quat.magsq(quat_2), (quat_1.c * quat_2.a + quat_1.d * quat_2.b - quat_1.a * quat_2.c - quat_1.b * quat_2.d) / Chalkboard.quat.magsq(quat_2), (quat_1.d * quat_2.a - quat_1.c * quat_2.b + quat_1.b * quat_2.c - quat_1.a * quat_2.d) / Chalkboard.quat.magsq(quat_2));
830
+ },
730
831
  fromAxis: function(vec3, rad) {
731
832
  return Chalkboard.quat.new(Chalkboard.trig.cos(rad / 2), vec3.x * Chalkboard.trig.sin(rad / 2), vec3.y * Chalkboard.trig.sin(rad / 2), vec3.z * Chalkboard.trig.sin(rad / 2));
732
833
  },
@@ -771,58 +872,55 @@ var Chalkboard = {
771
872
  }
772
873
  },
773
874
  plot: {
774
- CONTEXT: "ctx",
775
875
  xyplane: function(config) {
776
- config = config || {};
777
- config = {
876
+ (config = {
877
+ x: (config = config || {}).x || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.width / 2,
878
+ y: config.y || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.height / 2,
778
879
  size: config.size || 1,
779
880
  strokeStyle: config.strokeStyle || "black",
780
- origin: config.origin || [Chalkboard.real.parse(Chalkboard.plot.CONTEXT).canvas.width / 2, Chalkboard.real.parse(Chalkboard.plot.CONTEXT).canvas.height / 2],
781
881
  lineWidth: config.lineWidth || 2,
782
- context: config.context || Chalkboard.real.parse(Chalkboard.plot.CONTEXT)
783
- };
784
- config.size /= 100;
785
- var cw = Chalkboard.real.parse(Chalkboard.plot.CONTEXT).canvas.width;
882
+ context: config.context || Chalkboard.real.parse(Chalkboard.CONTEXT)
883
+ }).size /= 100;
884
+ var cw = Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.width;
786
885
  config.context.save();
787
- config.context.translate(config.origin[0], config.origin[1]);
886
+ config.context.translate(config.x, config.y);
788
887
  config.context.strokeStyle = config.strokeStyle;
789
888
  config.context.lineWidth = config.lineWidth / 4;
790
889
  config.context.beginPath();
791
- for(var i = Math.floor(-config.origin[0] / config.size); i <= (cw - config.origin[0]) / config.size; i++) {
792
- config.context.moveTo(i / config.size, -config.origin[1]);
793
- config.context.lineTo(i / config.size, cw - config.origin[1]);
890
+ for(var i = Math.floor(-config.x / config.size); i <= (cw - config.x) / config.size; i++) {
891
+ config.context.moveTo(i / config.size, -config.y);
892
+ config.context.lineTo(i / config.size, cw - config.y);
794
893
  }
795
894
  config.context.stroke();
796
895
  config.context.beginPath();
797
- for(var i = Math.floor(-config.origin[1] / config.size); i <= (cw - config.origin[1]) / config.size; i++) {
798
- config.context.moveTo(-config.origin[0], i / config.size);
799
- config.context.lineTo(cw - config.origin[0], i / config.size);
896
+ for(var i = Math.floor(-config.y / config.size); i <= (cw - config.y) / config.size; i++) {
897
+ config.context.moveTo(-config.x, i / config.size);
898
+ config.context.lineTo(cw - config.x, i / config.size);
800
899
  }
801
900
  config.context.stroke();
802
901
  config.context.lineWidth = config.lineWidth;
803
902
  config.context.beginPath();
804
- config.context.moveTo(-config.origin[0], 0);
805
- config.context.lineTo(cw - config.origin[0], 0);
903
+ config.context.moveTo(-config.x, 0);
904
+ config.context.lineTo(cw - config.x, 0);
806
905
  config.context.stroke();
807
906
  config.context.beginPath();
808
- config.context.moveTo(0, -config.origin[1]);
809
- config.context.lineTo(0, cw - config.origin[1]);
907
+ config.context.moveTo(0, -config.y);
908
+ config.context.lineTo(0, cw - config.y);
810
909
  config.context.stroke();
811
910
  config.context.restore();
812
911
  },
813
912
  rOplane: function(config) {
814
- config = config || {};
815
- config = {
913
+ (config = {
914
+ x: (config = config || {}).x || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.width / 2,
915
+ y: config.y || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.height / 2,
816
916
  size: config.size || 1,
817
917
  strokeStyle: config.strokeStyle || "black",
818
- origin: config.origin || [Chalkboard.real.parse(Chalkboard.plot.CONTEXT).canvas.width / 2, Chalkboard.real.parse(Chalkboard.plot.CONTEXT).canvas.height / 2],
819
918
  lineWidth: config.lineWidth || 2,
820
- context: config.context || Chalkboard.real.parse(Chalkboard.plot.CONTEXT)
821
- };
822
- config.size /= 100;
823
- var cw = Chalkboard.real.parse(Chalkboard.plot.CONTEXT).canvas.width;
919
+ context: config.context || Chalkboard.real.parse(Chalkboard.CONTEXT)
920
+ }).size /= 100;
921
+ var cw = Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.width;
824
922
  config.context.save();
825
- config.context.translate(config.origin[0], config.origin[1]);
923
+ config.context.translate(config.x, config.y);
826
924
  config.context.strokeStyle = config.strokeStyle;
827
925
  config.context.lineWidth = config.lineWidth / 4;
828
926
  config.context.beginPath();
@@ -832,29 +930,28 @@ var Chalkboard = {
832
930
  config.context.stroke();
833
931
  config.context.lineWidth = config.lineWidth;
834
932
  config.context.beginPath();
835
- config.context.moveTo(-config.origin[0], 0);
836
- config.context.lineTo(cw - config.origin[0], 0);
933
+ config.context.moveTo(-config.x, 0);
934
+ config.context.lineTo(cw - config.x, 0);
837
935
  config.context.stroke()
838
936
  config.context.beginPath();
839
- config.context.moveTo(0, -config.origin[1]);
840
- config.context.lineTo(0, cw - config.origin[1]);
937
+ config.context.moveTo(0, -config.y);
938
+ config.context.lineTo(0, cw - config.y);
841
939
  config.context.stroke();
842
940
  config.context.restore();
843
941
  },
844
942
  function: function(func, config) {
845
- config = config || {};
846
- config = {
943
+ (config = {
944
+ x: (config = config || {}).x || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.width / 2,
945
+ y: config.y || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.height / 2,
847
946
  size: config.size || 1,
848
947
  strokeStyle: config.strokeStyle || "black",
849
- domain: config.domain || (func.type === "comp" ? [[-10, 10], [-10, 10]] : [-10, 10]),
850
- origin: config.origin || [Chalkboard.real.parse(Chalkboard.plot.CONTEXT).canvas.width / 2, Chalkboard.real.parse(Chalkboard.plot.CONTEXT).canvas.height / 2],
851
948
  lineWidth: config.lineWidth || 2,
852
- context: config.context || Chalkboard.real.parse(Chalkboard.plot.CONTEXT)
853
- };
854
- config.size /= 100;
949
+ domain: config.domain || (func.type === "comp" ? [[-10, 10], [-10, 10]] : [-10, 10]),
950
+ context: config.context || Chalkboard.real.parse(Chalkboard.CONTEXT)
951
+ }).size /= 100;
855
952
  var data = [];
856
953
  config.context.save();
857
- config.context.translate(config.origin[0], config.origin[1]);
954
+ config.context.translate(config.x, config.y);
858
955
  config.context.lineWidth = config.lineWidth;
859
956
  config.context.strokeStyle = config.strokeStyle;
860
957
  config.context.beginPath();
@@ -908,18 +1005,17 @@ var Chalkboard = {
908
1005
  return data;
909
1006
  },
910
1007
  barplot: function(arr, bins, config) {
911
- config = config || {};
912
- config = {
1008
+ (config = {
1009
+ x: (config = config || {}).x || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.width / 2,
1010
+ y: config.y || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.height / 2,
913
1011
  size: config.size || 1,
914
- strokeStyle: config.strokeStyle || "black",
915
1012
  fillStyle: config.fillStyle || "white",
916
- origin: config.origin || [Chalkboard.real.parse(Chalkboard.plot.CONTEXT).canvas.width / 2, Chalkboard.real.parse(Chalkboard.plot.CONTEXT).canvas.height / 2],
1013
+ strokeStyle: config.strokeStyle || "black",
917
1014
  lineWidth: config.lineWidth || 2,
918
- context: config.context || Chalkboard.real.parse(Chalkboard.plot.CONTEXT)
919
- };
920
- config.size /= 100;
1015
+ context: config.context || Chalkboard.real.parse(Chalkboard.CONTEXT)
1016
+ }).size /= 100;
921
1017
  config.context.save();
922
- config.context.translate(config.origin[0], config.origin[1]);
1018
+ config.context.translate(config.x, config.y);
923
1019
  config.context.lineWidth = config.lineWidth;
924
1020
  config.context.strokeStyle = config.strokeStyle;
925
1021
  config.context.fillStyle = config.fillStyle;
@@ -947,17 +1043,16 @@ var Chalkboard = {
947
1043
  return bars;
948
1044
  },
949
1045
  lineplot: function(arr, bins, config) {
950
- config = config || {};
951
- config = {
1046
+ (config = {
1047
+ x: (config = config || {}).x || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.width / 2,
1048
+ y: config.y || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.height / 2,
952
1049
  size: config.size || 1,
953
1050
  strokeStyle: config.strokeStyle || "black",
954
- origin: config.origin || [Chalkboard.real.parse(Chalkboard.plot.CONTEXT).canvas.width / 2, Chalkboard.real.parse(Chalkboard.plot.CONTEXT).canvas.height / 2],
955
1051
  lineWidth: config.lineWidth || 2,
956
- context: config.context || Chalkboard.real.parse(Chalkboard.plot.CONTEXT)
957
- };
958
- config.size /= 100;
1052
+ context: config.context || Chalkboard.real.parse(Chalkboard.CONTEXT)
1053
+ }).size /= 100;
959
1054
  config.context.save();
960
- config.context.translate(config.origin[0], config.origin[1]);
1055
+ config.context.translate(config.x, config.y);
961
1056
  config.context.lineWidth = config.lineWidth;
962
1057
  config.context.strokeStyle = config.strokeStyle;
963
1058
  var verts = [];
@@ -983,18 +1078,17 @@ var Chalkboard = {
983
1078
  return verts;
984
1079
  },
985
1080
  scatterplot: function(arr1, arr2, config) {
986
- config = config || {};
987
- config = {
1081
+ (config = {
1082
+ x: (config = config || {}).x || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.width / 2,
1083
+ y: config.y || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.height / 2,
988
1084
  size: config.size || 1,
989
1085
  fillStyle: config.fillStyle || "black",
990
- origin: config.origin || [Chalkboard.real.parse(Chalkboard.plot.CONTEXT).canvas.width / 2, Chalkboard.real.parse(Chalkboard.plot.CONTEXT).canvas.height / 2],
991
1086
  lineWidth: config.lineWidth || 5,
992
- context: config.context || Chalkboard.real.parse(Chalkboard.plot.CONTEXT)
993
- };
994
- config.size /= 100;
1087
+ context: config.context || Chalkboard.real.parse(Chalkboard.CONTEXT)
1088
+ }).size /= 100;
995
1089
  var data = [];
996
1090
  config.context.save();
997
- config.context.translate(config.origin[0], config.origin[1]);
1091
+ config.context.translate(config.x, config.y);
998
1092
  config.context.fillStyle = config.fillStyle;
999
1093
  if(arr1.length === arr2.length) {
1000
1094
  for(var i = 0; i < arr1.length; i++) {
@@ -1008,18 +1102,17 @@ var Chalkboard = {
1008
1102
  return data;
1009
1103
  },
1010
1104
  comp: function(comp, config) {
1011
- config = config || {};
1012
- config = {
1105
+ (config = {
1106
+ x: (config = config || {}).x || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.width / 2,
1107
+ y: config.y || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.height / 2,
1013
1108
  size: config.size || 1,
1014
1109
  fillStyle: config.fillStyle || "black",
1015
- origin: config.origin || [Chalkboard.real.parse(Chalkboard.plot.CONTEXT).canvas.width / 2, Chalkboard.real.parse(Chalkboard.plot.CONTEXT).canvas.height / 2],
1016
1110
  lineWidth: config.lineWidth || 5,
1017
- context: config.context || Chalkboard.real.parse(Chalkboard.plot.CONTEXT)
1018
- };
1019
- config.size /= 100;
1111
+ context: config.context || Chalkboard.real.parse(Chalkboard.CONTEXT)
1112
+ }).size /= 100;
1020
1113
  config.context.fillStyle = config.fillStyle;
1021
1114
  config.context.save();
1022
- config.context.translate(config.origin[0], config.origin[1]);
1115
+ config.context.translate(config.x, config.y);
1023
1116
  config.context.beginPath();
1024
1117
  config.context.ellipse(comp.a / config.size, -comp.b / config.size, config.lineWidth, config.lineWidth, 0, 0, Chalkboard.PI(2));
1025
1118
  config.context.fill();
@@ -1027,19 +1120,18 @@ var Chalkboard = {
1027
1120
  return [[comp.a], [comp.b]];
1028
1121
  },
1029
1122
  vec2: function(vec2, config) {
1030
- config = config || {};
1031
- config = {
1123
+ (config = {
1124
+ x: (config = config || {}).x || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.width / 2,
1125
+ y: config.y || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.height / 2,
1032
1126
  size: config.size || 1,
1033
1127
  strokeStyle: config.strokeStyle || "black",
1034
- origin: config.origin || [Chalkboard.real.parse(Chalkboard.plot.CONTEXT).canvas.width / 2, Chalkboard.real.parse(Chalkboard.plot.CONTEXT).canvas.height / 2],
1035
1128
  lineWidth: config.lineWidth || 5,
1036
- context: config.context || Chalkboard.real.parse(Chalkboard.plot.CONTEXT)
1037
- };
1038
- config.size /= 100;
1129
+ context: config.context || Chalkboard.real.parse(Chalkboard.CONTEXT)
1130
+ }).size /= 100;
1039
1131
  config.context.strokeStyle = config.strokeStyle;
1040
1132
  config.context.lineWidth = config.lineWidth;
1041
1133
  config.context.save();
1042
- config.context.translate(config.origin[0], config.origin[1]);
1134
+ config.context.translate(config.x, config.y);
1043
1135
  config.context.beginPath();
1044
1136
  config.context.moveTo(0, 0);
1045
1137
  config.context.lineTo(vec2.x / config.size, -vec2.y / config.size);
@@ -1048,22 +1140,21 @@ var Chalkboard = {
1048
1140
  return [[vec2.x], [vec2.y]];
1049
1141
  },
1050
1142
  field: function(vec2field, config) {
1051
- config = config || {};
1052
- config = {
1143
+ (config = {
1144
+ x: (config = config || {}).x || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.width / 2,
1145
+ y: config.y || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.height / 2,
1053
1146
  size: config.size || 1,
1054
1147
  strokeStyle: config.strokeStyle || "black",
1055
- domain: config.domain || [[-10, 10], [-10, 10]],
1056
- origin: config.origin || [Chalkboard.real.parse(Chalkboard.plot.CONTEXT).canvas.width / 2, Chalkboard.real.parse(Chalkboard.plot.CONTEXT).canvas.height / 2],
1057
- lineWidth: config.lineWidth || 5,
1148
+ lineWidth: config.lineWidth || 2,
1149
+ domain: config.domain || [[-10, 10], [10, 10]],
1058
1150
  res: config.res || 25,
1059
- context: config.context || Chalkboard.real.parse(Chalkboard.plot.CONTEXT)
1060
- };
1061
- config.size /= 100;
1151
+ context: config.context || Chalkboard.real.parse(Chalkboard.CONTEXT)
1152
+ }).size /= 100;
1062
1153
  var data = [];
1063
1154
  config.context.strokeStyle = config.strokeStyle;
1064
1155
  config.context.lineWidth = config.lineWidth;
1065
1156
  config.context.save();
1066
- config.context.translate(config.origin[0], config.origin[1]);
1157
+ config.context.translate(config.x, config.y);
1067
1158
  for(var i = config.domain[0][0] / config.size; i <= config.domain[0][1] / config.size; i += config.res) {
1068
1159
  for(var j = config.domain[1][0] / config.size; j <= config.domain[1][1] / config.size; j += config.res) {
1069
1160
  var v = Chalkboard.vec2.fromField(vec2field, Chalkboard.vec2.new(i, j));
@@ -1078,19 +1169,18 @@ var Chalkboard = {
1078
1169
  return data;
1079
1170
  },
1080
1171
  vec3: function(vec3, config) {
1081
- config = config || {};
1082
- config = {
1172
+ (config = {
1173
+ x: (config = config || {}).x || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.width / 2,
1174
+ y: config.y || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.height / 2,
1083
1175
  size: config.size || 1,
1084
1176
  strokeStyle: config.strokeStyle || "black",
1085
- origin: config.origin || [Chalkboard.real.parse(Chalkboard.plot.CONTEXT).canvas.width / 2, Chalkboard.real.parse(Chalkboard.plot.CONTEXT).canvas.height / 2],
1086
1177
  lineWidth: config.lineWidth || 5,
1087
- context: config.context || Chalkboard.real.parse(Chalkboard.plot.CONTEXT)
1088
- };
1089
- config.size /= 100;
1178
+ context: config.context || Chalkboard.real.parse(Chalkboard.CONTEXT)
1179
+ }).size /= 100;
1090
1180
  config.context.strokeStyle = config.strokeStyle;
1091
1181
  config.context.lineWidth = config.lineWidth;
1092
1182
  config.context.save();
1093
- config.context.translate(config.origin[0], config.origin[1]);
1183
+ config.context.translate(config.x, config.y);
1094
1184
  config.context.beginPath();
1095
1185
  config.context.moveTo(0, 0);
1096
1186
  config.context.lineTo((vec3.x / config.size) / (vec3.z * 0.25 + 1), (-vec3.y / config.size) / (vec3.z * 0.25 + 1));
@@ -1099,50 +1189,41 @@ var Chalkboard = {
1099
1189
  return [[vec3.x], [vec3.y], [vec3.z]];
1100
1190
  },
1101
1191
  matr: function(matr, config) {
1102
- config = config || {};
1103
- config = {
1192
+ (config = {
1193
+ x: (config = config || {}).x || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.width / 2,
1194
+ y: config.y || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.height / 2,
1104
1195
  size: config.size || 1,
1105
1196
  strokeStyle: config.strokeStyle || "black",
1106
- origin: config.origin || [Chalkboard.real.parse(Chalkboard.plot.CONTEXT).canvas.width / 2, Chalkboard.real.parse(Chalkboard.plot.CONTEXT).canvas.height / 2],
1107
1197
  lineWidth: config.lineWidth || 2,
1108
- context: config.context || Chalkboard.real.parse(Chalkboard.plot.CONTEXT)
1109
- };
1110
- config.size /= 100;
1111
- var plotposx = Chalkboard.vec2.new(matr[0][0], matr[1][0]);
1112
- var plotnegx = Chalkboard.vec2.new(-matr[0][0], -matr[1][0]);
1113
- var plotposy = Chalkboard.vec2.new(matr[0][1], matr[1][1]);
1114
- var plotnegy = Chalkboard.vec2.new(-matr[0][1], -matr[1][1]);
1115
- for(var i = -10; i <= 10; i++) {
1116
- Chalkboard.vec2.plot(plotposx, {origin: [config.origin[0], config.origin[1] + (i / config.size) * matr[1][1]], lineWidth: config.lineWidth / 4});
1117
- Chalkboard.vec2.plot(plotnegx, {origin: [config.origin[0], config.origin[1] + (i / config.size) * matr[1][1]], lineWidth: config.lineWidth / 4});
1118
- Chalkboard.vec2.plot(plotposy, {origin: [config.origin[0] + (i / config.size) * matr[0][0], config.origin[1]], lineWidth: config.lineWidth / 4});
1119
- Chalkboard.vec2.plot(plotnegy, {origin: [config.origin[0] + (i / config.size) * matr[0][0], config.origin[1]], lineWidth: config.lineWidth / 4});
1120
- }
1121
- var plotposaxisx = Chalkboard.vec2.new(matr[0][0], matr[1][0]);
1122
- var plotnegaxisx = Chalkboard.vec2.new(-matr[0][0], -matr[1][0]);
1123
- var plotposaxisy = Chalkboard.vec2.new(matr[0][1], matr[1][1]);
1124
- var plotnegaxisy = Chalkboard.vec2.new(-matr[0][1], -matr[1][1]);
1125
- Chalkboard.vec2.plot(plotposaxisx, config);
1126
- Chalkboard.vec2.plot(plotnegaxisx, config);
1127
- Chalkboard.vec2.plot(plotposaxisy, config);
1128
- Chalkboard.vec2.plot(plotnegaxisy, config);
1198
+ domain: config.domain || [-10, 10],
1199
+ context: config.context || Chalkboard.real.parse(Chalkboard.CONTEXT)
1200
+ }).size /= 100;
1201
+ for(var i = config.domain[0]; i <= config.domain[1]; i++) {
1202
+ Chalkboard.plot.vec2(Chalkboard.vec2.new(matr[0][0], matr[1][0]), {x: config.x, y: config.y + (i / config.size) * matr[1][1], size: config.size, strokeStyle: config.strokeStyle, lineWidth: config.lineWidth / 4, context: config.context});
1203
+ Chalkboard.plot.vec2(Chalkboard.vec2.new(-matr[0][0], -matr[1][0]), {x: config.x, y: config.y + (i / config.size) * matr[1][1], size: config.size, strokeStyle: config.strokeStyle, lineWidth: config.lineWidth / 4, context: config.context});
1204
+ Chalkboard.plot.vec2(Chalkboard.vec2.new(matr[0][1], matr[1][1]), {x: config.x + (i / config.size) * matr[0][0], y: config.y, size: config.size, strokeStyle: config.strokeStyle, lineWidth: config.lineWidth / 4, context: config.context});
1205
+ Chalkboard.plot.vec2(Chalkboard.vec2.new(-matr[0][1], -matr[1][1]), {x: config.x + (i / config.size) * matr[0][0], y: config.y, size: config.size, strokeStyle: config.strokeStyle, lineWidth: config.lineWidth / 4, context: config.context});
1206
+ }
1207
+ Chalkboard.plot.vec2(Chalkboard.vec2.new(matr[0][0], matr[1][0]), config);
1208
+ Chalkboard.plot.vec2(Chalkboard.vec2.new(-matr[0][0], -matr[1][0]), config);
1209
+ Chalkboard.plot.vec2(Chalkboard.vec2.new(matr[0][1], matr[1][1]), config);
1210
+ Chalkboard.plot.vec2(Chalkboard.vec2.new(-matr[0][1], -matr[1][1]), config);
1129
1211
  return matr;
1130
1212
  },
1131
1213
  dfdx: function(func, config) {
1132
- config = config || {};
1133
- config = {
1214
+ (config = {
1215
+ x: (config = config || {}).x || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.width / 2,
1216
+ y: config.y || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.height / 2,
1134
1217
  size: config.size || 1,
1135
1218
  strokeStyle: config.strokeStyle || "black",
1136
- domain: config.domain || [-10, 10],
1137
- origin: config.origin || [Chalkboard.real.parse(Chalkboard.plot.CONTEXT).canvas.width / 2, Chalkboard.real.parse(Chalkboard.plot.CONTEXT).canvas.height / 2],
1138
1219
  lineWidth: config.lineWidth || 2,
1220
+ domain: config.domain || [-10, 10],
1139
1221
  res: config.res || 25,
1140
- context: config.context || Chalkboard.real.parse(Chalkboard.plot.CONTEXT)
1141
- };
1142
- config.size /= 100;
1222
+ context: config.context || Chalkboard.real.parse(Chalkboard.CONTEXT)
1223
+ }).size /= 100;
1143
1224
  var data = [];
1144
1225
  config.context.save();
1145
- config.context.translate(config.origin[0], config.origin[1]);
1226
+ config.context.translate(config.x, config.y);
1146
1227
  config.context.lineWidth = config.lineWidth;
1147
1228
  config.context.strokeStyle = config.strokeStyle;
1148
1229
  config.context.beginPath();
@@ -1160,20 +1241,19 @@ var Chalkboard = {
1160
1241
  return data;
1161
1242
  },
1162
1243
  d2fdx2: function(func, config) {
1163
- config = config || {};
1164
- config = {
1244
+ (config = {
1245
+ x: (config = config || {}).x || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.width / 2,
1246
+ y: config.y || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.height / 2,
1165
1247
  size: config.size || 1,
1166
1248
  strokeStyle: config.strokeStyle || "black",
1167
- domain: config.domain || [-10, 10],
1168
- origin: config.origin || [Chalkboard.real.parse(Chalkboard.plot.CONTEXT).canvas.width / 2, Chalkboard.real.parse(Chalkboard.plot.CONTEXT).canvas.height / 2],
1169
1249
  lineWidth: config.lineWidth || 2,
1250
+ domain: config.domain || [-10, 10],
1170
1251
  res: config.res || 25,
1171
- context: config.context || Chalkboard.real.parse(Chalkboard.plot.CONTEXT)
1172
- };
1173
- config.size /= 100;
1252
+ context: config.context || Chalkboard.real.parse(Chalkboard.CONTEXT)
1253
+ }).size /= 100;
1174
1254
  var data = [];
1175
1255
  config.context.save();
1176
- config.context.translate(config.origin[0], config.origin[1]);
1256
+ config.context.translate(config.x, config.y);
1177
1257
  config.context.lineWidth = config.lineWidth;
1178
1258
  config.context.strokeStyle = config.strokeStyle;
1179
1259
  config.context.beginPath();
@@ -1191,20 +1271,19 @@ var Chalkboard = {
1191
1271
  return data;
1192
1272
  },
1193
1273
  fxdx: function(func, config) {
1194
- config = config || {};
1195
- config = {
1274
+ (config = {
1275
+ x: (config = config || {}).x || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.width / 2,
1276
+ y: config.y || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.height / 2,
1196
1277
  size: config.size || 1,
1197
1278
  strokeStyle: config.strokeStyle || "black",
1198
- domain: config.domain || [-10, 10],
1199
- origin: config.origin || [Chalkboard.real.parse(Chalkboard.plot.CONTEXT).canvas.width / 2, Chalkboard.real.parse(Chalkboard.plot.CONTEXT).canvas.height / 2],
1200
1279
  lineWidth: config.lineWidth || 2,
1280
+ domain: config.domain || [-10, 10],
1201
1281
  res: config.res || 25,
1202
- context: config.context || Chalkboard.real.parse(Chalkboard.plot.CONTEXT)
1203
- };
1204
- config.size /= 100;
1282
+ context: config.context || Chalkboard.real.parse(Chalkboard.CONTEXT)
1283
+ }).size /= 100;
1205
1284
  var data = [];
1206
1285
  config.context.save();
1207
- config.context.translate(config.origin[0], config.origin[1]);
1286
+ config.context.translate(config.x, config.y);
1208
1287
  config.context.lineWidth = config.lineWidth;
1209
1288
  config.context.strokeStyle = config.strokeStyle;
1210
1289
  config.context.beginPath();
@@ -1222,20 +1301,19 @@ var Chalkboard = {
1222
1301
  return data;
1223
1302
  },
1224
1303
  convolution: function(func_1, func_2, config) {
1225
- config = config || {};
1226
- config = {
1304
+ (config = {
1305
+ x: (config = config || {}).x || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.width / 2,
1306
+ y: config.y || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.height / 2,
1227
1307
  size: config.size || 1,
1228
1308
  strokeStyle: config.strokeStyle || "black",
1229
- domain: config.domain || [-10, 10],
1230
- origin: config.origin || [Chalkboard.real.parse(Chalkboard.plot.CONTEXT).canvas.width / 2, Chalkboard.real.parse(Chalkboard.plot.CONTEXT).canvas.height / 2],
1231
1309
  lineWidth: config.lineWidth || 2,
1310
+ domain: config.domain || [-10, 10],
1232
1311
  res: config.res || 25,
1233
- context: config.context || Chalkboard.real.parse(Chalkboard.plot.CONTEXT)
1234
- };
1235
- config.size /= 100;
1312
+ context: config.context || Chalkboard.real.parse(Chalkboard.CONTEXT)
1313
+ }).size /= 100;
1236
1314
  var data = [];
1237
1315
  config.context.save();
1238
- config.context.translate(config.origin[0], config.origin[1]);
1316
+ config.context.translate(config.x, config.y);
1239
1317
  config.context.lineWidth = config.lineWidth;
1240
1318
  config.context.strokeStyle = config.strokeStyle;
1241
1319
  config.context.beginPath();
@@ -1248,20 +1326,19 @@ var Chalkboard = {
1248
1326
  return data;
1249
1327
  },
1250
1328
  correlation: function(func_1, func_2, config) {
1251
- config = config || {};
1252
- config = {
1329
+ (config = {
1330
+ x: (config = config || {}).x || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.width / 2,
1331
+ y: config.y || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.height / 2,
1253
1332
  size: config.size || 1,
1254
1333
  strokeStyle: config.strokeStyle || "black",
1255
- domain: config.domain || [-10, 10],
1256
- origin: config.origin || [Chalkboard.real.parse(Chalkboard.plot.CONTEXT).canvas.width / 2, Chalkboard.real.parse(Chalkboard.plot.CONTEXT).canvas.height / 2],
1257
1334
  lineWidth: config.lineWidth || 2,
1335
+ domain: config.domain || [-10, 10],
1258
1336
  res: config.res || 25,
1259
- context: config.context || Chalkboard.real.parse(Chalkboard.plot.CONTEXT)
1260
- };
1261
- config.size /= 100;
1337
+ context: config.context || Chalkboard.real.parse(Chalkboard.CONTEXT)
1338
+ }).size /= 100;
1262
1339
  var data = [];
1263
1340
  config.context.save();
1264
- config.context.translate(config.origin[0], config.origin[1]);
1341
+ config.context.translate(config.x, config.y);
1265
1342
  config.context.lineWidth = config.lineWidth;
1266
1343
  config.context.strokeStyle = config.strokeStyle;
1267
1344
  config.context.beginPath();
@@ -1274,20 +1351,19 @@ var Chalkboard = {
1274
1351
  return data;
1275
1352
  },
1276
1353
  autocorrelation: function(func, config) {
1277
- config = config || {};
1278
- config = {
1354
+ (config = {
1355
+ x: (config = config || {}).x || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.width / 2,
1356
+ y: config.y || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.height / 2,
1279
1357
  size: config.size || 1,
1280
1358
  strokeStyle: config.strokeStyle || "black",
1281
- domain: config.domain || [-10, 10],
1282
- origin: config.origin || [Chalkboard.real.parse(Chalkboard.plot.CONTEXT).canvas.width / 2, Chalkboard.real.parse(Chalkboard.plot.CONTEXT).canvas.height / 2],
1283
1359
  lineWidth: config.lineWidth || 2,
1360
+ domain: config.domain || [-10, 10],
1284
1361
  res: config.res || 25,
1285
- context: config.context || Chalkboard.real.parse(Chalkboard.plot.CONTEXT)
1286
- };
1287
- config.size /= 100;
1362
+ context: config.context || Chalkboard.real.parse(Chalkboard.CONTEXT)
1363
+ }).size /= 100;
1288
1364
  var data = [];
1289
1365
  config.context.save();
1290
- config.context.translate(config.origin[0], config.origin[1]);
1366
+ config.context.translate(config.x, config.y);
1291
1367
  config.context.lineWidth = config.lineWidth;
1292
1368
  config.context.strokeStyle = config.strokeStyle;
1293
1369
  config.context.beginPath();
@@ -1300,20 +1376,19 @@ var Chalkboard = {
1300
1376
  return data;
1301
1377
  },
1302
1378
  Taylor: function(func, n, a, config) {
1303
- config = config || {};
1304
- config = {
1379
+ (config = {
1380
+ x: (config = config || {}).x || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.width / 2,
1381
+ y: config.y || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.height / 2,
1305
1382
  size: config.size || 1,
1306
1383
  strokeStyle: config.strokeStyle || "black",
1307
- domain: config.domain || [-10, 10],
1308
- origin: config.origin || [Chalkboard.real.parse(Chalkboard.plot.CONTEXT).canvas.width / 2, Chalkboard.real.parse(Chalkboard.plot.CONTEXT).canvas.height / 2],
1309
1384
  lineWidth: config.lineWidth || 2,
1385
+ domain: config.domain || [-10, 10],
1310
1386
  res: config.res || 25,
1311
- context: config.context || Chalkboard.real.parse(Chalkboard.plot.CONTEXT)
1312
- };
1313
- config.size /= 100;
1387
+ context: config.context || Chalkboard.real.parse(Chalkboard.CONTEXT)
1388
+ }).size /= 100;
1314
1389
  var data = [];
1315
1390
  config.context.save();
1316
- config.context.translate(config.origin[0], config.origin[1]);
1391
+ config.context.translate(config.x, config.y);
1317
1392
  config.context.lineWidth = config.lineWidth;
1318
1393
  config.context.strokeStyle = config.strokeStyle;
1319
1394
  config.context.beginPath();
@@ -1326,20 +1401,19 @@ var Chalkboard = {
1326
1401
  return data;
1327
1402
  },
1328
1403
  Laplace: function(func, config) {
1329
- config = config || {};
1330
- config = {
1404
+ (config = {
1405
+ x: (config = config || {}).x || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.width / 2,
1406
+ y: config.y || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.height / 2,
1331
1407
  size: config.size || 1,
1332
1408
  strokeStyle: config.strokeStyle || "black",
1333
- domain: config.domain || [-10, 10],
1334
- origin: config.origin || [Chalkboard.real.parse(Chalkboard.plot.CONTEXT).canvas.width / 2, Chalkboard.real.parse(Chalkboard.plot.CONTEXT).canvas.height / 2],
1335
1409
  lineWidth: config.lineWidth || 2,
1410
+ domain: config.domain || [-10, 10],
1336
1411
  res: config.res || 25,
1337
- context: config.context || Chalkboard.real.parse(Chalkboard.plot.CONTEXT)
1338
- };
1339
- config.size /= 100;
1412
+ context: config.context || Chalkboard.real.parse(Chalkboard.CONTEXT)
1413
+ }).size /= 100;
1340
1414
  var data = [];
1341
1415
  config.context.save();
1342
- config.context.translate(config.origin[0], config.origin[1]);
1416
+ config.context.translate(config.x, config.y);
1343
1417
  config.context.lineWidth = config.lineWidth;
1344
1418
  config.context.strokeStyle = config.strokeStyle;
1345
1419
  config.context.beginPath();
@@ -1359,20 +1433,19 @@ var Chalkboard = {
1359
1433
  return data;
1360
1434
  },
1361
1435
  Fourier: function(func, config) {
1362
- config = config || {};
1363
- config = {
1436
+ (config = {
1437
+ x: (config = config || {}).x || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.width / 2,
1438
+ y: config.y || Chalkboard.real.parse(Chalkboard.CONTEXT).canvas.height / 2,
1364
1439
  size: config.size || 1,
1365
1440
  strokeStyle: config.strokeStyle || "black",
1366
- domain: config.domain || [-10, 10],
1367
- origin: config.origin || [Chalkboard.real.parse(Chalkboard.plot.CONTEXT).canvas.width / 2, Chalkboard.real.parse(Chalkboard.plot.CONTEXT).canvas.height / 2],
1368
1441
  lineWidth: config.lineWidth || 2,
1442
+ domain: config.domain || [-10, 10],
1369
1443
  res: config.res || 25,
1370
- context: config.context || Chalkboard.real.parse(Chalkboard.plot.CONTEXT)
1371
- };
1372
- config.size /= 100;
1444
+ context: config.context || Chalkboard.real.parse(Chalkboard.CONTEXT)
1445
+ }).size /= 100;
1373
1446
  var data = [];
1374
1447
  config.context.save();
1375
- config.context.translate(config.origin[0], config.origin[1]);
1448
+ config.context.translate(config.x, config.y);
1376
1449
  config.context.lineWidth = config.lineWidth;
1377
1450
  config.context.strokeStyle = config.strokeStyle;
1378
1451
  config.context.beginPath();
@@ -1529,7 +1602,7 @@ var Chalkboard = {
1529
1602
  return h * (Chalkboard.real.sqrt(-(a * a * a * a) + 2 * (a * b) * (a * b) + 2 * (a * c) * (a * c) - (b * b * b * b) + 2 * (b * c) * (b * c) - (c * c * c * c))) / 4;
1530
1603
  },
1531
1604
  line3D: function(x1, y1, z1, x2, y2, z2, context) {
1532
- context = context || Chalkboard.real.parse(Chalkboard.plot.CONTEXT);
1605
+ context = context || Chalkboard.real.parse(Chalkboard.CONTEXT);
1533
1606
  context.beginPath();
1534
1607
  context.moveTo(x1 / (z1 * 0.0025 + 1), y1 / (z1 * 0.0025 + 1));
1535
1608
  context.lineTo(x2 / (z2 * 0.0025 + 1), y2 / (z2 * 0.0025 + 1));
@@ -1796,7 +1869,7 @@ var Chalkboard = {
1796
1869
  },
1797
1870
  eq: function(arr, arrORnum) {
1798
1871
  var result = [];
1799
- if(arrORnum.constructor === Array) {
1872
+ if(Array.isArray(arrORnum)) {
1800
1873
  if(arr.length === arrORnum.length) {
1801
1874
  for(var i = 0; i < arr.length; i++) {
1802
1875
  if(arr[i] === arrORnum[i]) {
@@ -1817,7 +1890,7 @@ var Chalkboard = {
1817
1890
  includeInf = includeInf || false;
1818
1891
  includeSup = includeSup || false;
1819
1892
  var result = [];
1820
- if(inf.constructor === Array && sup.constructor === Array) {
1893
+ if(Array.isArray(inf) && Array.isArray(sup)) {
1821
1894
  if(arr.length === inf.length && arr.length === sup.length) {
1822
1895
  for(var i = 0; i < arr.length; i++) {
1823
1896
  if(includeInf) {
@@ -1873,7 +1946,7 @@ var Chalkboard = {
1873
1946
  lt: function(arr, arrORnum, includeEnd) {
1874
1947
  includeEnd = includeEnd || false;
1875
1948
  var result = [];
1876
- if(arrORnum.constructor === Array) {
1949
+ if(Array.isArray(arrORnum)) {
1877
1950
  if(arr.length === arrORnum.length) {
1878
1951
  for(var i = 0; i < arr.length; i++) {
1879
1952
  if(includeEnd) {
@@ -1905,7 +1978,7 @@ var Chalkboard = {
1905
1978
  gt: function(arr, arrORnum, includeEnd) {
1906
1979
  includeEnd = includeEnd || false;
1907
1980
  var result = [];
1908
- if(arrORnum.constructor === Array) {
1981
+ if(Array.isArray(arrORnum)) {
1909
1982
  if(arr.length === arrORnum.length) {
1910
1983
  for(var i = 0; i < arr.length; i++) {
1911
1984
  if(includeEnd) {
@@ -2228,13 +2301,14 @@ var Chalkboard = {
2228
2301
  return "TypeError: Parameter \"type\" must be either \"linear\", \"polynomial\", \"power\", \"exponential\", or \"logarithmic\".";
2229
2302
  }
2230
2303
  },
2231
- toVector: function(arr, type) {
2304
+ toVector: function(arr, type, index) {
2305
+ if(index === undefined) { index = 0; }
2232
2306
  if(type === "vec2") {
2233
- return Chalkboard.vec2.new(arr[0], arr[1]);
2307
+ return Chalkboard.vec2.new(arr[index], arr[index + 1]);
2234
2308
  } else if(type === "vec3") {
2235
- return Chalkboard.vec3.new(arr[0], arr[1], arr[2]);
2309
+ return Chalkboard.vec3.new(arr[index], arr[index + 1], arr[index + 2]);
2236
2310
  } else if(type === "vec4") {
2237
- return Chalkboard.vec4.new(arr[0], arr[1], arr[2], arr[3]);
2311
+ return Chalkboard.vec4.new(arr[index], arr[index + 1], arr[index + 2], arr[index + 3]);
2238
2312
  } else {
2239
2313
  return "TypeError: Parameter \"type\" should be \"vec2\", \"vec3\", or \"vec4\".";
2240
2314
  }
@@ -2255,6 +2329,12 @@ var Chalkboard = {
2255
2329
  }
2256
2330
  return result;
2257
2331
  },
2332
+ toTensor: function(arr, size) {
2333
+ if(!Array.isArray(size)) {
2334
+ size = Array.from(arguments).slice(1);
2335
+ }
2336
+ return Chalkboard.tens.resize(arr, size);
2337
+ },
2258
2338
  toObject: function(arr) {
2259
2339
  var result = {};
2260
2340
  for(var i = 0; i < arr.length; i++) {
@@ -2277,6 +2357,9 @@ var Chalkboard = {
2277
2357
  return {x: x, y: y, type: "vec2"};
2278
2358
  }
2279
2359
  },
2360
+ copy: function(vec2) {
2361
+ return Object.create(Object.getPrototypeOf(vec2), Object.getOwnPropertyDescriptors(vec2));
2362
+ },
2280
2363
  random: function(inf, sup) {
2281
2364
  return Chalkboard.vec2.new(Chalkboard.numb.random(inf, sup), Chalkboard.numb.random(inf, sup));
2282
2365
  },
@@ -2421,6 +2504,9 @@ var Chalkboard = {
2421
2504
  return {x: x, y: y, z: z, type: "vec3"};
2422
2505
  }
2423
2506
  },
2507
+ copy: function(vec3) {
2508
+ return Object.create(Object.getPrototypeOf(vec3), Object.getOwnPropertyDescriptors(vec3));
2509
+ },
2424
2510
  random: function(inf, sup) {
2425
2511
  return Chalkboard.vec3.new(Chalkboard.numb.random(inf, sup), Chalkboard.numb.random(inf, sup), Chalkboard.numb.random(inf, sup));
2426
2512
  },
@@ -2572,6 +2658,9 @@ var Chalkboard = {
2572
2658
  return {x: x, y: y, z: z, w: w, type: "vec4"};
2573
2659
  }
2574
2660
  },
2661
+ copy: function(vec4) {
2662
+ return Object.create(Object.getPrototypeOf(vec4), Object.getOwnPropertyDescriptors(vec4));
2663
+ },
2575
2664
  random: function(inf, sup) {
2576
2665
  return Chalkboard.vec4.new(Chalkboard.numb.random(inf, sup), Chalkboard.numb.random(inf, sup), Chalkboard.numb.random(inf, sup), Chalkboard.numb.random(inf, sup));
2577
2666
  },
@@ -2706,8 +2795,23 @@ var Chalkboard = {
2706
2795
  },
2707
2796
  matr: {
2708
2797
  new: function(matrix) {
2709
- matrix = Array.from(arguments);
2710
- return matrix;
2798
+ if(arguments.length === 0) {
2799
+ return [];
2800
+ } else if(Array.isArray(matrix) && Array.isArray(matrix[0])) {
2801
+ return matrix;
2802
+ } else {
2803
+ return Array.from(arguments);
2804
+ }
2805
+ },
2806
+ copy: function(matr) {
2807
+ var result = Chalkboard.matr.new();
2808
+ for(var i = 0; i < Chalkboard.matr.rows(matr); i++) {
2809
+ result.push([]);
2810
+ for(var j = 0; j < Chalkboard.matr.cols(matr); j++) {
2811
+ result[i].push(matr[i][j]);
2812
+ }
2813
+ }
2814
+ return result;
2711
2815
  },
2712
2816
  rows: function(matr) {
2713
2817
  return matr.length;
@@ -2715,6 +2819,21 @@ var Chalkboard = {
2715
2819
  cols: function(matr) {
2716
2820
  return matr[0].length;
2717
2821
  },
2822
+ resize: function(matr, rows, cols) {
2823
+ if(cols === undefined) {
2824
+ cols = rows;
2825
+ }
2826
+ var result = Chalkboard.matr.new();
2827
+ var flat = Chalkboard.matr.toArray(matr);
2828
+ var index = 0;
2829
+ for(var i = 0; i < rows; i++) {
2830
+ result.push([]);
2831
+ for(var j = 0; j < cols; j++) {
2832
+ result[i].push(index < flat.length ? flat[index++] : 0);
2833
+ }
2834
+ }
2835
+ return result;
2836
+ },
2718
2837
  push: function(matr, type, rowORcol, elements) {
2719
2838
  rowORcol -= 1;
2720
2839
  if(type === "row") {
@@ -2744,6 +2863,9 @@ var Chalkboard = {
2744
2863
  }
2745
2864
  },
2746
2865
  fill: function(element, rows, cols) {
2866
+ if(cols === undefined) {
2867
+ cols = rows;
2868
+ }
2747
2869
  if(Number.isInteger(rows) && Number.isInteger(cols) && rows > 0 && cols > 0) {
2748
2870
  var result = Chalkboard.matr.new();
2749
2871
  for(var i = 0; i < rows; i++) {
@@ -2758,6 +2880,9 @@ var Chalkboard = {
2758
2880
  }
2759
2881
  },
2760
2882
  empty: function(rows, cols) {
2883
+ if(cols === undefined) {
2884
+ cols = rows;
2885
+ }
2761
2886
  if(Number.isInteger(rows) && Number.isInteger(cols) && rows > 0 && cols > 0) {
2762
2887
  var result = Chalkboard.matr.new();
2763
2888
  for(var i = 0; i < rows; i++) {
@@ -2783,7 +2908,25 @@ var Chalkboard = {
2783
2908
  return undefined;
2784
2909
  }
2785
2910
  },
2786
- random: function(rows, cols, inf, sup) {
2911
+ exchange: function(size) {
2912
+ if(Number.isInteger(size) && size > 0) {
2913
+ var result = Chalkboard.matr.fill(0, size, size);
2914
+ for(var i = 0; i < size; i++) {
2915
+ for(var j = 0; j < size; j++) {
2916
+ if(i + j === size - 1) {
2917
+ result[i][j] = 1;
2918
+ }
2919
+ }
2920
+ }
2921
+ return result;
2922
+ } else {
2923
+ return undefined;
2924
+ }
2925
+ },
2926
+ random: function(inf, sup, rows, cols) {
2927
+ if(cols === undefined) {
2928
+ cols = rows;
2929
+ }
2787
2930
  if(Number.isInteger(rows) && Number.isInteger(cols) && rows > 0 && cols > 0) {
2788
2931
  var result = Chalkboard.matr.new();
2789
2932
  for(var i = 0; i < rows; i++) {
@@ -2797,6 +2940,73 @@ var Chalkboard = {
2797
2940
  return undefined;
2798
2941
  }
2799
2942
  },
2943
+ shift: function(size, shiftAmount) {
2944
+ shiftAmount = shiftAmount || 1;
2945
+ if(Number.isInteger(size) && size > 0) {
2946
+ var result = Chalkboard.matr.fill(0, size, size);
2947
+ for(var i = 0; i < size; i++) {
2948
+ for(var j = 0; j < size; j++) {
2949
+ result[i][j] = Chalkboard.numb.Kronecker(i + shiftAmount, j);
2950
+ }
2951
+ }
2952
+ return result;
2953
+ } else {
2954
+ return undefined;
2955
+ }
2956
+ },
2957
+ binomial: function(size, type) {
2958
+ type = type || "lower";
2959
+ if(Number.isInteger(size) && size > 0) {
2960
+ var result = Chalkboard.matr.new();
2961
+ for(var i = 0; i < size; i++) {
2962
+ result.push([]);
2963
+ for(var j = 0; j < size; j++) {
2964
+ if(type === "lower") {
2965
+ result[i].push(Chalkboard.numb.binomial(i, j));
2966
+ } else if(type === "upper") {
2967
+ result[i].push(Chalkboard.numb.binomial(j, i));
2968
+ }
2969
+ }
2970
+ }
2971
+ if(type === "symmetric") {
2972
+ return Chalkboard.matr.mul(Chalkboard.matr.binomial(size, "lower"), Chalkboard.matr.binomial(size, "upper"));
2973
+ } else if(type !== "lower" && type !== "upper") {
2974
+ return "TypeError: Parameter \"type\" must be either \"lower\", \"upper\", or \"symmetric\".";
2975
+ } else {
2976
+ return result;
2977
+ }
2978
+ } else {
2979
+ return undefined;
2980
+ }
2981
+ },
2982
+ Hilbert: function(size) {
2983
+ if(Number.isInteger(size) && size > 0) {
2984
+ var result = Chalkboard.matr.new();
2985
+ for(var i = 0; i < size; i++) {
2986
+ result.push([]);
2987
+ for(var j = 0; j < size; j++) {
2988
+ result[i].push(1 / (i + j + 1));
2989
+ }
2990
+ }
2991
+ return result;
2992
+ } else {
2993
+ return undefined;
2994
+ }
2995
+ },
2996
+ Lehmer: function(size) {
2997
+ if(Number.isInteger(size) && size > 0) {
2998
+ var result = Chalkboard.matr.new();
2999
+ for(var i = 0; i < size; i++) {
3000
+ result.push([]);
3001
+ for(var j = 0; j < size; j++) {
3002
+ result[i].push(Math.min(i + 1, j + 1) / Math.max(i + 1, j + 1));
3003
+ }
3004
+ }
3005
+ return result;
3006
+ } else {
3007
+ return undefined;
3008
+ }
3009
+ },
2800
3010
  cofactor: function(matr, row, col) {
2801
3011
  return matr.slice(0, row - 1).concat(matr.slice(row)).map(function(row) {
2802
3012
  return row.slice(0, col - 1).concat(row.slice(col));
@@ -2919,7 +3129,7 @@ var Chalkboard = {
2919
3129
  LUdecomp: function(matr) {
2920
3130
  if(Chalkboard.matr.rows(matr) === Chalkboard.matr.cols(matr)) {
2921
3131
  var L = Chalkboard.matr.identity(Chalkboard.matr.rows(matr)),
2922
- U = Chalkboard.matr.zero(Chalkboard.matr.empty(Chalkboard.matr.rows(matr)));
3132
+ U = Chalkboard.matr.fill(0, Chalkboard.matr.rows(matr));
2923
3133
  for(var j = 0; j < Chalkboard.matr.cols(matr); j++) {
2924
3134
  for(var i = 0; i <= j; i++) {
2925
3135
  var sum = 0;
@@ -2942,51 +3152,51 @@ var Chalkboard = {
2942
3152
  }
2943
3153
  },
2944
3154
  QRdecomp: function(matr) {
2945
- if(Chalkboard.matr.rows(matr) === Chalkboard.matr.cols(matr)) {
2946
- var Q = Chalkboard.matr.zero(Chalkboard.matr.empty(Chalkboard.matr.rows(matr))),
2947
- R = Chalkboard.matr.zero(Chalkboard.matr.empty(Chalkboard.matr.rows(matr)));
2948
- var dot = function(v1, v2) {
2949
- var result = 0;
2950
- for(var i = 0; i < v1.length; i++) {
2951
- result += v1[i] * v2[i];
3155
+ var Q = Chalkboard.matr.identity(Chalkboard.matr.rows(matr)),
3156
+ R = Chalkboard.matr.copy(matr);
3157
+ for(var j = 0; j < Math.min(Chalkboard.matr.rows(matr), Chalkboard.matr.cols(matr)) - (Chalkboard.matr.rows(matr) > Chalkboard.matr.cols(matr) ? 0 : 1); j++) {
3158
+ var norm = 0;
3159
+ for(var i = j; i < Chalkboard.matr.rows(matr); i++) {
3160
+ norm += R[i][j] * R[i][j];
3161
+ }
3162
+ norm = Chalkboard.real.sqrt(norm);
3163
+ var v = [];
3164
+ v[0] = norm - R[j][j];
3165
+ var normalizer = v[0] * v[0];
3166
+ for(var i = 1; i < Chalkboard.matr.rows(matr) - j; i++) {
3167
+ v[i] = -R[i + j][j];
3168
+ normalizer += v[i] * v[i];
3169
+ }
3170
+ normalizer = 1 / Chalkboard.real.sqrt(normalizer);
3171
+ for(var i = 0; i < v.length; i++) {
3172
+ v[i] *= normalizer;
3173
+ }
3174
+ R[j][j] = norm;
3175
+ for(var i = j + 1; i < Chalkboard.matr.rows(R); i++) {
3176
+ R[i][j] = 0;
3177
+ }
3178
+ for(var k = j + 1; k < Chalkboard.matr.cols(R); k++) {
3179
+ var dot = 0;
3180
+ for(var i = 0; i < v.length; i++) {
3181
+ dot += v[i] * R[i + j][k];
2952
3182
  }
2953
- return result;
2954
- }
2955
- var mag = function(v) {
2956
- var result = 0;
3183
+ dot *= 2;
2957
3184
  for(var i = 0; i < v.length; i++) {
2958
- result += v[i] * v[i];
3185
+ R[i + j][k] -= dot * v[i];
2959
3186
  }
2960
- return Math.sqrt(result);
2961
3187
  }
2962
- for(var j = 0; j < Chalkboard.matr.rows(matr); j++) {
2963
- var v = matr.map(function(row) {
2964
- return row[j];
2965
- });
2966
- for(var i = 0; i < j; i++) {
2967
- var q = Q.map(function(row) {
2968
- return row[i];
2969
- });
2970
- var coeff = dot(v, q) / (mag(q) * mag(q));
2971
- v = v.map(function(e, index) {
2972
- return e - coeff * q[index];
2973
- });
2974
- }
2975
- for(var i = 0; i < Chalkboard.matr.rows(matr); i++) {
2976
- Q[i][j] = v[i] / mag(v);
3188
+ for(var k = 0; k < Chalkboard.matr.cols(Q); k++) {
3189
+ var dot = 0;
3190
+ for(var i = 0; i < v.length; i++) {
3191
+ dot += v[i] * Q[k][i + j];
2977
3192
  }
2978
- for(var i = 0; i < Chalkboard.matr.rows(matr); i++) {
2979
- R[j][i] = i < j ? 0 : matr.map(function(row) {
2980
- return row[i];
2981
- }).reduce(function(a, v, index) {
2982
- return a + v * Q[index][j];
2983
- }, 0);
3193
+ dot *= 2;
3194
+ for(var i = 0; i < v.length; i++) {
3195
+ Q[k][i + j] -= dot * v[i];
2984
3196
  }
2985
3197
  }
2986
- return {Q: Q, R: R};
2987
- } else {
2988
- return undefined;
2989
3198
  }
3199
+ return {Q: Q, R: R};
2990
3200
  },
2991
3201
  zero: function(matr) {
2992
3202
  var result = Chalkboard.matr.new();
@@ -3088,6 +3298,28 @@ var Chalkboard = {
3088
3298
  }
3089
3299
  return result;
3090
3300
  },
3301
+ concat: function(matr_1, matr_2, type) {
3302
+ type = type || "row";
3303
+ if(type === "row") {
3304
+ if(Chalkboard.matr.rows(matr_1) === Chalkboard.matr.rows(matr_2)) {
3305
+ return Chalkboard.matr.new(matr_1.concat(matr_2));
3306
+ } else {
3307
+ return undefined;
3308
+ }
3309
+ } else if(type === "col") {
3310
+ if(Chalkboard.matr.cols(matr_1) === Chalkboard.matr.cols(matr_2)) {
3311
+ var result = Chalkboard.matr.new();
3312
+ for(var i = 0; i < Chalkboard.matr.rows(matr_1); i++) {
3313
+ result.push(matr_1[i].concat(matr_2[i]));
3314
+ }
3315
+ return result;
3316
+ } else {
3317
+ return undefined;
3318
+ }
3319
+ } else {
3320
+ return "TypeError: Parameter \"type\" should be either \"row\" or \"col\".";
3321
+ }
3322
+ },
3091
3323
  add: function(matr_1, matr_2) {
3092
3324
  if(Chalkboard.matr.rows(matr_1) === Chalkboard.matr.rows(matr_2) && Chalkboard.matr.cols(matr_1) === Chalkboard.matr.cols(matr_2)) {
3093
3325
  var result = Chalkboard.matr.new();
@@ -3133,6 +3365,29 @@ var Chalkboard = {
3133
3365
  return undefined;
3134
3366
  }
3135
3367
  },
3368
+ mulvec: function(matr, vec) {
3369
+ if(vec.type === "vec2") {
3370
+ if(Chalkboard.matr.rows(matr) === 2) {
3371
+ return Chalkboard.matr.toVector(Chalkboard.matr.mul(matr, Chalkboard.vec2.toMatrix(vec)), "vec2");
3372
+ } else {
3373
+ return Chalkboard.matr.mul(matr, Chalkboard.vec2.toMatrix(vec));
3374
+ }
3375
+ } else if(vec.type === "vec3") {
3376
+ if(Chalkboard.matr.rows(matr) === 3) {
3377
+ return Chalkboard.matr.toVector(Chalkboard.matr.mul(matr, Chalkboard.vec3.toMatrix(vec)), "vec3");
3378
+ } else {
3379
+ return Chalkboard.matr.mul(matr, Chalkboard.vec2.toMatrix(vec));
3380
+ }
3381
+ } else if(vec.type === "vec4") {
3382
+ if(Chalkboard.matr.rows(matr) === 4) {
3383
+ return Chalkboard.matr.toVector(Chalkboard.matr.mul(matr, Chalkboard.vec4.toMatrix(vec)), "vec4");
3384
+ } else {
3385
+ return Chalkboard.matr.mul(matr, Chalkboard.vec2.toMatrix(vec));
3386
+ }
3387
+ } else {
3388
+ return "TypeError: Parameter \"vec\" should be \"vec2\", \"vec3\", or \"vec4\".";
3389
+ }
3390
+ },
3136
3391
  pow: function(matr, num) {
3137
3392
  if(Chalkboard.matr.rows(matr) === Chalkboard.matr.cols(matr)) {
3138
3393
  if(Number.isInteger(num) && num >= 0) {
@@ -3152,6 +3407,29 @@ var Chalkboard = {
3152
3407
  return undefined;
3153
3408
  }
3154
3409
  },
3410
+ addKronecker: function(matr_1, matr_2) {
3411
+ if(Chalkboard.matr.rows(matr_1) === Chalkboard.matr.cols(matr_1) && Chalkboard.matr.rows(matr_2) === Chalkboard.matr.cols(matr_2)) {
3412
+ return Chalkboard.matr.add(Chalkboard.matr.mulKronecker(matr_1, Chalkboard.matr.identity(Chalkboard.matr.rows(matr_1))), Chalkboard.matr.mulKronecker(Chalkboard.matr.identity(Chalkboard.matr.rows(matr_2)), matr_2));
3413
+ } else {
3414
+ return undefined;
3415
+ }
3416
+ },
3417
+ mulKronecker: function(matr_1, matr_2) {
3418
+ var result = Chalkboard.matr.new();
3419
+ for(var i = 0; i < Chalkboard.matr.rows(matr_1); i++) {
3420
+ for(var j = 0; j < Chalkboard.matr.cols(matr_1); j++) {
3421
+ for(var k = 0; k < Chalkboard.matr.rows(matr_2); k++) {
3422
+ for(var l = 0; l < Chalkboard.matr.cols(matr_2); l++) {
3423
+ if(!result[i * Chalkboard.matr.rows(matr_2) + k]) {
3424
+ result[i * Chalkboard.matr.rows(matr_2) + k] = [];
3425
+ }
3426
+ result[i * Chalkboard.matr.rows(matr_2) + k][j * Chalkboard.matr.cols(matr_2) + l] = matr_1[i][j] * matr_2[k][l];
3427
+ }
3428
+ }
3429
+ }
3430
+ }
3431
+ return result;
3432
+ },
3155
3433
  reduce: function(matr) {
3156
3434
  var lead = 0;
3157
3435
  for(var row = 0; row < Chalkboard.matr.rows(matr); row++) {
@@ -3235,6 +3513,12 @@ var Chalkboard = {
3235
3513
  return "TypeError: Parameter \"vec\" should be \"vec2\", \"vec3\", or \"vec4\".";
3236
3514
  }
3237
3515
  },
3516
+ toTensor: function(matr, size) {
3517
+ if(!Array.isArray(size)) {
3518
+ size = Array.from(arguments).slice(1);
3519
+ }
3520
+ return Chalkboard.tens.resize(matr, size);
3521
+ },
3238
3522
  toArray: function(matr) {
3239
3523
  var result = [];
3240
3524
  for(var i = 0; i < Chalkboard.matr.rows(matr); i++) {
@@ -3244,6 +3528,16 @@ var Chalkboard = {
3244
3528
  }
3245
3529
  return result;
3246
3530
  },
3531
+ toObject: function(matr) {
3532
+ var result = {};
3533
+ for(var i = 0; i < Chalkboard.matr.rows(matr); i++) {
3534
+ result["i" + (i + 1)] = {};
3535
+ for(var j = 0; j < Chalkboard.matr.cols(matr); j++) {
3536
+ result["i" + (i + 1)]["j" + (j + 1)] = matr[i][j];
3537
+ }
3538
+ }
3539
+ return result;
3540
+ },
3247
3541
  toString: function(matr) {
3248
3542
  var result = "";
3249
3543
  for(var i = 0; i < Chalkboard.matr.rows(matr); i++) {
@@ -3255,18 +3549,369 @@ var Chalkboard = {
3255
3549
  }
3256
3550
  return result;
3257
3551
  },
3258
- toObject: function(matr) {
3259
- var result = {};
3260
- for(var i = 0; i < Chalkboard.matr.rows(matr); i++) {
3261
- result["i" + (i + 1)] = {};
3262
- for(var j = 0; j < Chalkboard.matr.cols(matr); j++) {
3263
- result["i" + (i + 1)]["j" + (j + 1)] = matr[i][j];
3552
+ print: function(matr) {
3553
+ console.log(Chalkboard.matr.toString(matr));
3554
+ }
3555
+ },
3556
+ tens: {
3557
+ new: function(tensor) {
3558
+ if(arguments.length === 0) {
3559
+ return [];
3560
+ } else if(arguments.length === 1 && Array.isArray(arguments[0])) {
3561
+ tensor = arguments[0];
3562
+ } else {
3563
+ tensor = Array.from(arguments);
3564
+ }
3565
+ var newNDArray = function(arr) {
3566
+ return arr.map(function(subarr) {
3567
+ if(Array.isArray(subarr)) {
3568
+ return newNDArray(subarr);
3569
+ } else {
3570
+ return subarr;
3571
+ }
3572
+ });
3573
+ };
3574
+ return newNDArray(tensor);
3575
+ },
3576
+ copy: function(tens) {
3577
+ if(Array.isArray(tens)) {
3578
+ var result = Chalkboard.tens.new();
3579
+ for(var i = 0; i < tens.length; i++) {
3580
+ result[i] = Chalkboard.tens.copy(tens[i]);
3581
+ }
3582
+ return result;
3583
+ } else {
3584
+ return tens;
3585
+ }
3586
+ },
3587
+ rank: function(tens) {
3588
+ if(Array.isArray(tens)) {
3589
+ var result = 0;
3590
+ for(var i = 0; i < tens.length; i++) {
3591
+ result = Math.max(result, Chalkboard.tens.rank(tens[i]));
3592
+ }
3593
+ return result + 1;
3594
+ } else {
3595
+ return 0;
3596
+ }
3597
+ },
3598
+ size: function(tens) {
3599
+ if(Array.isArray(tens)) {
3600
+ var result = [tens.length];
3601
+ if(Array.isArray(tens[0])) {
3602
+ result = result.concat(Chalkboard.tens.size(tens[0]));
3264
3603
  }
3604
+ return result;
3605
+ } else {
3606
+ return [];
3607
+ }
3608
+ },
3609
+ resize: function(tens, size) {
3610
+ if(!Array.isArray(size)) {
3611
+ size = Array.from(arguments).slice(1);
3265
3612
  }
3613
+ var result = Chalkboard.tens.fill(0, size);
3614
+ var refill = function(arr1, arr2) {
3615
+ for(var i = 0; i < arr2.length; i++) {
3616
+ if(Array.isArray(arr2[i])) {
3617
+ refill(arr1, arr2[i]);
3618
+ } else {
3619
+ arr2[i] = arr1.length > 0 ? arr1.shift() : 0;
3620
+ }
3621
+ }
3622
+ };
3623
+ refill(Chalkboard.tens.toArray(tens), result);
3266
3624
  return result;
3267
3625
  },
3268
- print: function(matr) {
3269
- console.log(Chalkboard.matr.toString(matr));
3626
+ push: function(tens, rank, index, elements) {
3627
+ if(rank === 0) {
3628
+ tens.splice(index, 0, elements);
3629
+ return tens;
3630
+ } else {
3631
+ for(var i = 0; i < tens.length; i++) {
3632
+ Chalkboard.tens.push(tens[i], rank - 1, index, elements[i]);
3633
+ }
3634
+ return tens;
3635
+ }
3636
+ },
3637
+ pull: function(tens, rank, index) {
3638
+ if(rank === 0) {
3639
+ tens.splice(index, 1);
3640
+ return tens;
3641
+ } else {
3642
+ for(var i = 0; i < tens.length; i++) {
3643
+ Chalkboard.tens.pull(tens[i], rank - 1, index);
3644
+ }
3645
+ return tens;
3646
+ }
3647
+ },
3648
+ fill: function(element, size) {
3649
+ if(!Array.isArray(size)) {
3650
+ size = Array.from(arguments).slice(1);
3651
+ }
3652
+ var newNDArray = function(size) {
3653
+ if(size.length === 0) {
3654
+ return element;
3655
+ }
3656
+ var curr = size[0];
3657
+ var rest = size.slice(1);
3658
+ var result = [];
3659
+ for(var i = 0; i < curr; i++) {
3660
+ result[i] = newNDArray(rest);
3661
+ }
3662
+ return result;
3663
+ }
3664
+ return newNDArray(size);
3665
+ },
3666
+ empty: function(size) {
3667
+ if(!Array.isArray(size)) {
3668
+ size = Array.from(arguments);
3669
+ }
3670
+ var newNDArray = function(size) {
3671
+ if(size.length === 0) {
3672
+ return null;
3673
+ }
3674
+ var curr = size[0];
3675
+ var rest = size.slice(1);
3676
+ var result = [];
3677
+ for(var i = 0; i < curr; i++) {
3678
+ result[i] = newNDArray(rest);
3679
+ }
3680
+ return result;
3681
+ }
3682
+ return newNDArray(size);
3683
+ },
3684
+ random: function(inf, sup, size) {
3685
+ if(!Array.isArray(size)) {
3686
+ size = Array.from(arguments).slice(2);
3687
+ }
3688
+ var newNDArray = function(size) {
3689
+ if(size.length === 0) {
3690
+ return Chalkboard.numb.random(inf, sup);
3691
+ }
3692
+ var curr = size[0];
3693
+ var rest = size.slice(1);
3694
+ var result = [];
3695
+ for(var i = 0; i < curr; i++) {
3696
+ result[i] = newNDArray(rest);
3697
+ }
3698
+ return result;
3699
+ }
3700
+ return newNDArray(size);
3701
+ },
3702
+ contract: function(tens) {
3703
+ if(Chalkboard.tens.rank(tens) > 2) {
3704
+ return Chalkboard.tens.resize(tens, Chalkboard.tens.size(tens)[0], Chalkboard.tens.size(tens).slice(1).reduce(function(a, b) { return a * b; }) / Chalkboard.tens.size(tens)[0]);
3705
+ } else if(Chalkboard.tens.rank(tens) === 2) {
3706
+ return Chalkboard.matr.trace(tens);
3707
+ }
3708
+ },
3709
+ transpose: function(tens) {
3710
+ return Chalkboard.tens.resize(tens, Chalkboard.tens.size(tens).reverse());
3711
+ },
3712
+ zero: function(tens) {
3713
+ var result = Chalkboard.tens.new();
3714
+ if(Array.isArray(tens)) {
3715
+ for(var i = 0; i < tens.length; i++) {
3716
+ result[i] = Chalkboard.tens.zero(tens[i]);
3717
+ }
3718
+ return result;
3719
+ } else {
3720
+ return 0;
3721
+ }
3722
+ },
3723
+ negate: function(tens) {
3724
+ var result = Chalkboard.tens.new();
3725
+ if(Array.isArray(tens)) {
3726
+ for(var i = 0; i < tens.length; i++) {
3727
+ result[i] = Chalkboard.tens.negate(tens[i]);
3728
+ }
3729
+ return result;
3730
+ } else {
3731
+ return -tens;
3732
+ }
3733
+ },
3734
+ reciprocate: function(tens) {
3735
+ var result = Chalkboard.tens.new();
3736
+ if(Array.isArray(tens)) {
3737
+ for(var i = 0; i < tens.length; i++) {
3738
+ result[i] = Chalkboard.tens.reciprocate(tens[i]);
3739
+ }
3740
+ return result;
3741
+ } else {
3742
+ return 1 / tens;
3743
+ }
3744
+ },
3745
+ absolute: function(tens) {
3746
+ var result = Chalkboard.tens.new();
3747
+ if(Array.isArray(tens)) {
3748
+ for(var i = 0; i < tens.length; i++) {
3749
+ result[i] = Chalkboard.tens.absolute(tens[i]);
3750
+ }
3751
+ return result;
3752
+ } else {
3753
+ return Math.abs(tens);
3754
+ }
3755
+ },
3756
+ round: function(tens) {
3757
+ var result = Chalkboard.tens.new();
3758
+ if(Array.isArray(tens)) {
3759
+ for(var i = 0; i < tens.length; i++) {
3760
+ result[i] = Chalkboard.tens.round(tens[i]);
3761
+ }
3762
+ return result;
3763
+ } else {
3764
+ return Math.round(tens);
3765
+ }
3766
+ },
3767
+ scl: function(tens, num) {
3768
+ var result = Chalkboard.tens.new();
3769
+ if(Array.isArray(tens)) {
3770
+ for(var i = 0; i < tens.length; i++) {
3771
+ result[i] = Chalkboard.tens.scl(tens[i], num);
3772
+ }
3773
+ return result;
3774
+ } else {
3775
+ return tens * num;
3776
+ }
3777
+ },
3778
+ constrain: function(tens, range) {
3779
+ var result = Chalkboard.tens.new();
3780
+ if(Array.isArray(tens)) {
3781
+ for(var i = 0; i < tens.length; i++) {
3782
+ result[i] = Chalkboard.tens.constrain(tens[i], range);
3783
+ }
3784
+ return result;
3785
+ } else {
3786
+ return Chalkboard.numb.constrain(tens, range);
3787
+ }
3788
+ },
3789
+ concat: function(tens_1, tens_2, rank) {
3790
+ rank = rank || 1;
3791
+ var concatAtRank = function(arr1, arr2, currentRank) {
3792
+ if(currentRank === rank) {
3793
+ return Chalkboard.tens.new(arr1.concat(arr2));
3794
+ }
3795
+ return arr1.map(function(element, index) {
3796
+ return concatAtRank(element, arr2[index], currentRank);
3797
+ });
3798
+ }
3799
+ return concatAtRank(tens_1, tens_2, 1);
3800
+ },
3801
+ add: function(tens_1, tens_2) {
3802
+ var result = Chalkboard.tens.new();
3803
+ if(Array.isArray(tens_1) && Array.isArray(tens_2)) {
3804
+ for(var i = 0; i < Math.max(tens_1.length, tens_2.length); i++) {
3805
+ result[i] = Chalkboard.tens.add(tens_1[i] !== undefined ? tens_1[i] : 0, tens_2[i] !== undefined ? tens_2[i] : 0);
3806
+ }
3807
+ return result;
3808
+ } else {
3809
+ return tens_1 + tens_2;
3810
+ }
3811
+ },
3812
+ sub: function(tens_1, tens_2) {
3813
+ var result = Chalkboard.tens.new();
3814
+ if(Array.isArray(tens_1) && Array.isArray(tens_2)) {
3815
+ for(var i = 0; i < Math.max(tens_1.length, tens_2.length); i++) {
3816
+ result[i] = Chalkboard.tens.sub(tens_1[i] !== undefined ? tens_1[i] : 0, tens_2[i] !== undefined ? tens_2[i] : 0);
3817
+ }
3818
+ return result;
3819
+ } else {
3820
+ return tens_1 - tens_2;
3821
+ }
3822
+ },
3823
+ mul: function(tens_1, tens_2) {
3824
+ var result = Chalkboard.tens.new();
3825
+ if(Array.isArray(tens_1) && Array.isArray(tens_2)) {
3826
+ for(var i = 0; i < tens_1.length; i++) {
3827
+ var subarr = Chalkboard.tens.new();
3828
+ for(var j = 0; j < tens_2.length; j++) {
3829
+ subarr[j] = Chalkboard.tens.mul(tens_1[i], tens_2[j]);
3830
+ }
3831
+ result.push(subarr);
3832
+ }
3833
+ return result;
3834
+ } else {
3835
+ return tens_1 * tens_2;
3836
+ }
3837
+ },
3838
+ toVector: function(tens, type, index) {
3839
+ if(index === undefined) { index = 0; }
3840
+ var arr = Chalkboard.tens.toArray(tens);
3841
+ if(type === "vec2") {
3842
+ return Chalkboard.vec2.new(arr[index], arr[index + 1]);
3843
+ } else if(type === "vec3") {
3844
+ return Chalkboard.vec3.new(arr[index], arr[index + 1], arr[index + 2]);
3845
+ } else if(type === "vec4") {
3846
+ return Chalkboard.vec4.new(arr[index], arr[index + 1], arr[index + 2], arr[index + 3]);
3847
+ } else {
3848
+ return "TypeError: Parameter \"type\" should be \"vec2\", \"vec3\", or \"vec4\".";
3849
+ }
3850
+ },
3851
+ toMatrix: function(tens) {
3852
+ var result = Chalkboard.matr.new();
3853
+ var flatten = function(tens, result) {
3854
+ for(var i = 0; i < tens.length; i++) {
3855
+ if(Array.isArray(tens[i])) {
3856
+ flatten(tens[i], result);
3857
+ } else {
3858
+ result.push(tens[i]);
3859
+ }
3860
+ }
3861
+ }
3862
+ var matr = Chalkboard.matr.new();
3863
+ flatten(tens, matr);
3864
+ var rows = tens.length || 1;
3865
+ for(var j = 0; j < rows; j++) {
3866
+ result.push(matr.slice(j * matr.length / rows, (j + 1) * matr.length / rows));
3867
+ }
3868
+ return result;
3869
+ },
3870
+ toArray: function(tens) {
3871
+ var result = [];
3872
+ var flatten = function(tens) {
3873
+ for(var i = 0; i < tens.length; i++) {
3874
+ if(Array.isArray(tens[i])) {
3875
+ flatten(tens[i]);
3876
+ } else {
3877
+ result.push(tens[i]);
3878
+ }
3879
+ }
3880
+ }
3881
+ flatten(tens);
3882
+ return result;
3883
+ },
3884
+ toObject: function(tens) {
3885
+ if(Array.isArray(tens)) {
3886
+ var result = {};
3887
+ for(var i = 0; i < tens.length; i++) {
3888
+ result["_" + (i + 1)] = Chalkboard.tens.toObject(tens[i]);
3889
+ }
3890
+ return result;
3891
+ } else {
3892
+ return tens;
3893
+ }
3894
+ },
3895
+ toString: function(tens, indentation) {
3896
+ if(indentation === undefined) { indentation = 0; }
3897
+ if(Array.isArray(tens[0])) {
3898
+ var result = "\t".repeat(indentation) + "[\n";
3899
+ for(var i = 0; i < tens.length; i++) {
3900
+ result += Chalkboard.tens.toString(tens[i], indentation + 1);
3901
+ }
3902
+ result += "\t".repeat(indentation) + "]\n";
3903
+ return result;
3904
+ } else {
3905
+ var result = "\t".repeat(indentation) + "[ ";
3906
+ for(var i = 0; i < tens.length; i++) {
3907
+ result += tens[i].toString() + " ";
3908
+ }
3909
+ result += "]\n";
3910
+ return result;
3911
+ }
3912
+ },
3913
+ print: function(tens) {
3914
+ return console.log(Chalkboard.tens.toString(tens));
3270
3915
  }
3271
3916
  },
3272
3917
  calc: {
@@ -3617,7 +4262,7 @@ var Chalkboard = {
3617
4262
  return "TypeError: Parameter \"func\" must be of type \"comp\".";
3618
4263
  }
3619
4264
  },
3620
- fxdx: function(func, a, b) {
4265
+ fxdx: function(func, inf, sup) {
3621
4266
  if(func.type === "expl" || func.type === "inve" || func.type === "pola") {
3622
4267
  var f;
3623
4268
  if(func.type === "expl") {
@@ -3627,36 +4272,36 @@ var Chalkboard = {
3627
4272
  } else if(func.type === "pola") {
3628
4273
  f = Chalkboard.real.parse("O => " + "((" + func.definition + ") * (" + func.definition + ")) / 2");
3629
4274
  }
3630
- var fx = f(a) + f(b);
3631
- var dx = (b - a) / 1000000;
4275
+ var fx = f(inf) + f(sup);
4276
+ var dx = (sup - inf) / 1000000;
3632
4277
  for(var i = 1; i < 1000000; i++) {
3633
- fx += i % 2 === 0 ? 2 * f(a + i * dx) : 4 * f(a + i * dx);
4278
+ fx += i % 2 === 0 ? 2 * f(inf + i * dx) : 4 * f(inf + i * dx);
3634
4279
  }
3635
4280
  return (fx * dx) / 3;
3636
4281
  } else if(func.type === "curv") {
3637
4282
  if(func.definition.length === 2) {
3638
4283
  var x = Chalkboard.real.parse("t => " + func.definition[0]),
3639
4284
  y = Chalkboard.real.parse("t => " + func.definition[1]);
3640
- var xt = x(a) + x(b),
3641
- yt = y(a) + y(b);
3642
- var dt = (b - a) / 1000000;
4285
+ var xt = x(inf) + x(sup),
4286
+ yt = y(inf) + y(sup);
4287
+ var dt = (sup - inf) / 1000000;
3643
4288
  for(var i = 1; i < 1000000; i++) {
3644
- xt += i % 2 === 0 ? 2 * x(a + i * dt) : 4 * x(a + i * dt);
3645
- yt += i % 2 === 0 ? 2 * y(a + i * dt) : 4 * y(a + i * dt);
4289
+ xt += i % 2 === 0 ? 2 * x(inf + i * dt) : 4 * x(inf + i * dt);
4290
+ yt += i % 2 === 0 ? 2 * y(sup + i * dt) : 4 * y(sup + i * dt);
3646
4291
  }
3647
4292
  return Chalkboard.vec2.new((xt * dt) / 3, (yt * dt) / 3);
3648
4293
  } else if(func.definition.length === 3) {
3649
4294
  var x = Chalkboard.real.parse("t => " + func.definition[0]),
3650
4295
  y = Chalkboard.real.parse("t => " + func.definition[1]),
3651
4296
  z = Chalkboard.real.parse("t => " + func.definition[2]);
3652
- var xt = x(a) + x(b),
3653
- yt = y(a) + y(b),
3654
- zt = z(a) + z(b);
3655
- var dt = (b - a) / 1000000;
4297
+ var xt = x(inf) + x(sup),
4298
+ yt = y(inf) + y(sup),
4299
+ zt = z(inf) + z(sup);
4300
+ var dt = (sup - inf) / 1000000;
3656
4301
  for(var i = 1; i < 1000000; i++) {
3657
- xt += i % 2 === 0 ? 2 * x(a + i * dt) : 4 * x(a + i * dt);
3658
- yt += i % 2 === 0 ? 2 * y(a + i * dt) : 4 * y(a + i * dt);
3659
- zt += i % 2 === 0 ? 2 * z(a + i * dt) : 4 * z(a + i * dt);
4302
+ xt += i % 2 === 0 ? 2 * x(inf + i * dt) : 4 * x(inf + i * dt);
4303
+ yt += i % 2 === 0 ? 2 * y(inf + i * dt) : 4 * y(inf + i * dt);
4304
+ zt += i % 2 === 0 ? 2 * z(inf + i * dt) : 4 * z(inf + i * dt);
3660
4305
  }
3661
4306
  return Chalkboard.vec3.new((xt * dt) / 3, (yt * dt) / 3, (zt * dt) / 3);
3662
4307
  }
@@ -3664,14 +4309,14 @@ var Chalkboard = {
3664
4309
  return "TypeError: Parameter \"func\" must be of type \"expl\", \"inve\", \"pola\", or \"curv\".";
3665
4310
  }
3666
4311
  },
3667
- fxydxdy: function(func, a, b, c, d) {
4312
+ fxydxdy: function(func, xinf, xsup, yinf, ysup) {
3668
4313
  if(func.type === "mult") {
3669
4314
  var f = Chalkboard.real.parse("(x, y) => " + func.definition);
3670
4315
  var result = 0;
3671
- var dx = (b - a) / 10000,
3672
- dy = (d - c) / 10000;
3673
- for(var x = a; x <= b; x += dx) {
3674
- for(var y = c; y <= d; y += dy) {
4316
+ var dx = (xsup - xinf) / 10000,
4317
+ dy = (ysup - yinf) / 10000;
4318
+ for(var x = xinf; x <= xsup; x += dx) {
4319
+ for(var y = yinf; y <= ysup; y += dy) {
3675
4320
  result += f(x, y);
3676
4321
  }
3677
4322
  }
@@ -3680,29 +4325,29 @@ var Chalkboard = {
3680
4325
  return "TypeError: Parameter \"func\" must be of type \"mult\".";
3681
4326
  }
3682
4327
  },
3683
- fds: function(func, a, b, c, d) {
4328
+ fds: function(func, tinf, tsup, sinf, ssup) {
3684
4329
  var result = 0;
3685
4330
  var drdt, drds;
3686
4331
  if(func.type === "curv") {
3687
- var dt = (b - a) / 10000;
4332
+ var dt = (tsup - tinf) / 10000;
3688
4333
  if(func.definition.length === 2) {
3689
- for(var t = a; t <= b; t += dt) {
4334
+ for(var t = tinf; t <= tsup; t += dt) {
3690
4335
  drdt = Chalkboard.calc.dfdx(func, t);
3691
4336
  result += Chalkboard.vec2.mag(drdt);
3692
4337
  }
3693
4338
  return result * dt;
3694
4339
  } else if(func.definition.length === 3) {
3695
- for(var t = a; t <= b; t += dt) {
4340
+ for(var t = tinf; t <= tsup; t += dt) {
3696
4341
  drdt = Chalkboard.calc.dfdx(func, t);
3697
4342
  result += Chalkboard.vec3.mag(drdt);
3698
4343
  }
3699
4344
  return result * dt;
3700
4345
  }
3701
4346
  } else if(func.type === "surf") {
3702
- var dt = (b - a) / 100,
3703
- ds = (d - c) / 100;
3704
- for(var s = c; s <= d; s += ds) {
3705
- for(var t = a; t <= b; t += dt) {
4347
+ var dt = (tsup - tinf) / 100,
4348
+ ds = (ssup - sinf) / 100;
4349
+ for(var s = sinf; s <= ssup; s += ds) {
4350
+ for(var t = tinf; t <= tsup; t += dt) {
3706
4351
  drds = Chalkboard.matr.toVector(Chalkboard.calc.grad(func, Chalkboard.vec2.new(s, t)), "vec3", "col", 1);
3707
4352
  drdt = Chalkboard.matr.toVector(Chalkboard.calc.grad(func, Chalkboard.vec2.new(s, t)), "vec3", "col", 2);
3708
4353
  result += Chalkboard.vec3.mag(Chalkboard.vec3.cross(drds, drdt));
@@ -3713,22 +4358,22 @@ var Chalkboard = {
3713
4358
  return "TypeError: Parameter \"func\" must be of type \"curv\" or \"surf\".";
3714
4359
  }
3715
4360
  },
3716
- frds: function(funcORvecfield, func, a, b) {
4361
+ frds: function(funcORvecfield, func, inf, sup) {
3717
4362
  if(func.type === "curv") {
3718
4363
  var result = 0;
3719
- var dt = (b - a) / 10000;
4364
+ var dt = (sup - inf) / 10000;
3720
4365
  if(funcORvecfield.type === "mult") {
3721
- for(var t = a; t <= b; t += dt) {
3722
- result += Chalkboard.real.val(funcORvecfield, Chalkboard.vec2.toArray(Chalkboard.real.val(func, t))) * Chalkboard.vec2.mag(Chalkboard.calc.dfdx(func, t));
4366
+ for(var t = inf; t <= sup; t += dt) {
4367
+ result += Chalkboard.real.val(funcORvecfield, Chalkboard.real.val(func, t)) * Chalkboard.vec2.mag(Chalkboard.calc.dfdx(func, t));
3723
4368
  }
3724
4369
  return result * dt;
3725
4370
  } else if(funcORvecfield.type === "vec2field") {
3726
- for(var t = a; t <= b; t += dt) {
4371
+ for(var t = inf; t <= sup; t += dt) {
3727
4372
  result += Chalkboard.vec2.dot(Chalkboard.vec2.fromField(funcORvecfield, Chalkboard.real.val(func, t)), Chalkboard.calc.dfdx(func, t));
3728
4373
  }
3729
4374
  return result * dt;
3730
4375
  } else if(funcORvecfield.type === "vec3field") {
3731
- for(var t = a; t <= b; t += dt) {
4376
+ for(var t = inf; t <= sup; t += dt) {
3732
4377
  result += Chalkboard.vec3.dot(Chalkboard.vec3.fromField(funcORvecfield, Chalkboard.real.val(func, t)), Chalkboard.calc.dfdx(func, t));
3733
4378
  }
3734
4379
  return result * dt;
@@ -3739,29 +4384,29 @@ var Chalkboard = {
3739
4384
  return "TypeError: Parameter \"func\" must be of type \"curv\".";
3740
4385
  }
3741
4386
  },
3742
- fnds: function(vecfield, func, a, b, c, d) {
4387
+ fnds: function(vecfield, func, tinf, tsup, sinf, ssup) {
3743
4388
  var result = 0;
3744
4389
  var drdt, drds;
3745
4390
  if(func.type === "curv") {
3746
- var dt = (b - a) / 10000;
4391
+ var dt = (tsup - tinf) / 10000;
3747
4392
  if(func.definition.length === 2) {
3748
- for(var t = a; t <= b; t += dt) {
4393
+ for(var t = tinf; t <= tsup; t += dt) {
3749
4394
  drdt = Chalkboard.calc.dfdx(func, t);
3750
4395
  result += Chalkboard.vec2.dot(Chalkboard.vec2.fromField(vecfield, Chalkboard.real.val(func, t)), Chalkboard.vec2.new(-drdt.y, drdt.x)) * Chalkboard.vec2.mag(drdt);
3751
4396
  }
3752
4397
  return result * dt;
3753
4398
  } else if(func.definition.length === 3) {
3754
- for(var t = a; t <= b; t += dt) {
4399
+ for(var t = tinf; t <= tsup; t += dt) {
3755
4400
  drdt = Chalkboard.calc.dfdx(func, t);
3756
4401
  result += Chalkboard.vec3.dot(Chalkboard.vec3.fromField(vecfield, Chalkboard.real.val(func, t)), Chalkboard.calc.normal(func, t)) * Chalkboard.vec3.mag(drdt);
3757
4402
  }
3758
4403
  return result * dt;
3759
4404
  }
3760
4405
  } else if(func.type === "surf") {
3761
- var dt = (b - a) / 100,
3762
- ds = (d - c) / 100;
3763
- for(var s = c; s <= d; s += ds) {
3764
- for(var t = a; t <= b; t += dt) {
4406
+ var dt = (tsup - tinf) / 100,
4407
+ ds = (ssup - sinf) / 100;
4408
+ for(var s = sinf; s <= ssup; s += ds) {
4409
+ for(var t = tinf; t <= tsup; t += dt) {
3765
4410
  drds = Chalkboard.matr.toVector(Chalkboard.calc.grad(func, Chalkboard.vec2.new(s, t)), "vec3", "col", 1);
3766
4411
  drdt = Chalkboard.matr.toVector(Chalkboard.calc.grad(func, Chalkboard.vec2.new(s, t)), "vec3", "col", 2);
3767
4412
  result += Chalkboard.vec3.scalarTriple(Chalkboard.vec3.fromField(vecfield, Chalkboard.real.val(func, Chalkboard.vec2.new(s, t))), drds, drdt);
@@ -3772,12 +4417,12 @@ var Chalkboard = {
3772
4417
  return "TypeError: Parameter \"func\" must be of type \"curv\" or \"surf\".";
3773
4418
  }
3774
4419
  },
3775
- fzdz: function(func_1, func_2, a, b) {
4420
+ fzdz: function(func_1, func_2, inf, sup) {
3776
4421
  if(func_1.type === "comp") {
3777
4422
  if(func_2.type === "curv") {
3778
4423
  var result = Chalkboard.comp.new(0, 0);
3779
- var dt = (b - a) / 10000;
3780
- for(var t = a; t <= b; t += dt) {
4424
+ var dt = (sup - inf) / 10000;
4425
+ for(var t = inf; t <= sup; t += dt) {
3781
4426
  var fz = Chalkboard.comp.val(func_1, Chalkboard.vec2.toComplex(Chalkboard.real.val(func_2, t)));
3782
4427
  var rt = Chalkboard.calc.dfdx(func_2, t);
3783
4428
  result = Chalkboard.comp.add(result, Chalkboard.comp.new((fz.a * rt.x) - (fz.b * rt.y), (fz.b * rt.x) + (fz.a * rt.y)));