@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.
@@ -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,7 +11,7 @@
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) {
17
17
  x = x || width / 2;
@@ -45,6 +45,8 @@ var Chalkboard = {
45
45
  exponent = exponent || 1;
46
46
  return Math.pow(Math.pow(10, 1 / Math.log(10)), exponent);
47
47
  },
48
+ CONTEXT: "ctx",
49
+ PARSEPREFIX: "",
48
50
  numb: {
49
51
  random: function(inf, sup) {
50
52
  if(inf === undefined) {
@@ -259,11 +261,23 @@ var Chalkboard = {
259
261
  }
260
262
  },
261
263
  binomial: function(n, k) {
264
+ if(k < 0 || k > n) {
265
+ return 0;
266
+ }
262
267
  if(k === 0 || k === n) {
263
268
  return 1;
264
- } else {
265
- return Chalkboard.numb.binomial(n - 1, k - 1) + Chalkboard.numb.binomial(n - 1, k);
266
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);
267
281
  },
268
282
  Fibonacci: function(num) {
269
283
  var sequence = [0, 1];
@@ -326,9 +340,8 @@ var Chalkboard = {
326
340
  return "TypeError: Parameter \"type\" must be either \"expl\", \"inve\", \"pola\", \"curv\", \"surf\", or \"mult\".";
327
341
  }
328
342
  },
329
- parse: function(str, init) {
330
- init = init || '';
331
- return Function('"use strict"; ' + init + ' return (' + str + ')')();
343
+ parse: function(str) {
344
+ return Function('"use strict"; ' + Chalkboard.PARSEPREFIX + ' return (' + str + ')')();
332
345
  },
333
346
  val: function(func, val) {
334
347
  if(func.type === "expl") {
@@ -510,14 +523,20 @@ var Chalkboard = {
510
523
  },
511
524
  comp: {
512
525
  new: function(a, b) {
513
- return {a: a, b: b, type: "comp"};
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));
514
534
  },
515
535
  function: function(realDefinition, imagDefinition) {
516
536
  return {definition: [realDefinition, imagDefinition], type: "comp"};
517
537
  },
518
- parse: function(str, init) {
519
- init = init || '';
520
- return Function('"use strict"; ' + init + ' return (' + str + ')')();
538
+ parse: function(str) {
539
+ return Function('"use strict"; ' + Chalkboard.PARSEPREFIX + ' return (' + str + ')')();
521
540
  },
522
541
  val: function(func, comp) {
523
542
  if(func.type === "comp") {
@@ -618,9 +637,21 @@ var Chalkboard = {
618
637
  return Chalkboard.comp.new(comp.a, -comp.b);
619
638
  },
620
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
+ }
621
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)));
622
647
  },
623
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
+ }
624
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));
625
656
  },
626
657
  scl: function(comp, num) {
@@ -630,15 +661,39 @@ var Chalkboard = {
630
661
  return Chalkboard.comp.new(Chalkboard.numb.constrain(comp.a, range), Chalkboard.numb.constrain(comp.b, range));
631
662
  },
632
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
+ }
633
670
  return Chalkboard.comp.new(comp_1.a + comp_2.a, comp_1.b + comp_2.b);
634
671
  },
635
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
+ }
636
679
  return Chalkboard.comp.new(comp_1.a - comp_2.a, comp_1.b - comp_2.b);
637
680
  },
638
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
+ }
639
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));
640
689
  },
641
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
+ }
642
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));
643
698
  },
644
699
  toVector: function(comp) {
@@ -660,7 +715,14 @@ var Chalkboard = {
660
715
  },
661
716
  quat: {
662
717
  new: function(a, b, c, d) {
663
- return {a: a, b: b, c: c, d: d, type: "quat"};
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));
664
726
  },
665
727
  random: function(inf, sup) {
666
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));
@@ -702,9 +764,21 @@ var Chalkboard = {
702
764
  return Chalkboard.quat.new(quat.a, -quat.b, -quat.c, -quat.d);
703
765
  },
704
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
+ }
705
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)));
706
774
  },
707
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
+ }
708
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));
709
783
  },
710
784
  scl: function(quat, num) {
@@ -714,14 +788,41 @@ var Chalkboard = {
714
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));
715
789
  },
716
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
+ }
717
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);
718
798
  },
719
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
+ }
720
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);
721
807
  },
722
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
+ }
723
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));
724
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
+ },
725
826
  fromAxis: function(vec3, rad) {
726
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));
727
828
  },
@@ -766,42 +867,39 @@ var Chalkboard = {
766
867
  }
767
868
  },
768
869
  plot: {
769
- CONTEXT: "ctx",
770
870
  xyplane: function(config) {
771
- config = config || {};
772
- config = {
871
+ (config = {
872
+ x: (config = config || {}).x || width / 2,
873
+ y: config.y || height / 2,
773
874
  size: config.size || 1,
774
875
  stroke: config.stroke || color(0),
775
- origin: config.origin || [width / 2, height / 2],
776
876
  strokeWeight: config.strokeWeight || 2
777
- };
778
- config.size /= 100;
877
+ }).size /= 100;
779
878
  pushMatrix();
780
- translate(config.origin[0], config.origin[1]);
879
+ translate(config.x, config.y);
781
880
  stroke(config.stroke);
782
881
  strokeWeight(config.strokeWeight / 4);
783
- for(var i = Math.floor(-config.origin[0] / config.size); i <= (width - config.origin[0]) / config.size; i++) {
784
- line(i / config.size, -config.origin[1], i / config.size, width - config.origin[1]);
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);
785
884
  }
786
- for(var i = Math.floor(-config.origin[1] / config.size); i <= (width - config.origin[1]) / config.size; i++) {
787
- line(-config.origin[0], i / config.size, width - config.origin[0], i / config.size);
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);
788
887
  }
789
888
  strokeWeight(config.strokeWeight);
790
- line(-config.origin[0], 0, width - config.origin[0], 0);
791
- line(0, -config.origin[1], 0, width - config.origin[1]);
889
+ line(-config.x, 0, width - config.x, 0);
890
+ line(0, -config.y, 0, width - config.y);
792
891
  popMatrix();
793
892
  },
794
893
  rOplane: function(config) {
795
- config = config || {};
796
- config = {
894
+ (config = {
895
+ x: (config = config || {}).x || width / 2,
896
+ y: config.y || height / 2,
797
897
  size: config.size || 1,
798
898
  stroke: config.stroke || color(0),
799
- origin: config.origin || [width / 2, height / 2],
800
899
  strokeWeight: config.strokeWeight || 2
801
- };
802
- config.size /= 100;
900
+ }).size /= 100;
803
901
  pushMatrix();
804
- translate(config.origin[0], config.origin[1]);
902
+ translate(config.x, config.y);
805
903
  noFill();
806
904
  stroke(config.stroke);
807
905
  strokeWeight(config.strokeWeight / 4);
@@ -809,23 +907,22 @@ var Chalkboard = {
809
907
  ellipse(0, 0, 2 * i / config.size, 2 * i / config.size);
810
908
  }
811
909
  strokeWeight(config.strokeWeight);
812
- line(-config.origin[0], 0, width - config.origin[0], 0);
813
- line(0, -config.origin[1], 0, width - config.origin[1]);
910
+ line(-config.x, 0, width - config.x, 0);
911
+ line(0, -config.y, 0, width - config.y);
814
912
  popMatrix();
815
913
  },
816
914
  function: function(func, config) {
817
- config = config || {};
818
- config = {
915
+ (config = {
916
+ x: (config = config || {}).x || width / 2,
917
+ y: config.y || height / 2,
819
918
  size: config.size || 1,
820
919
  stroke: config.stroke || color(0),
821
- domain: config.domain || (func.type === "comp" ? [[-10, 10], [-10, 10]] : [-10, 10]),
822
- origin: config.origin || [width / 2, height / 2],
823
- strokeWeight: config.strokeWeight || 2
824
- };
825
- config.size /= 100;
920
+ strokeWeight: config.strokeWeight || 2,
921
+ domain: config.domain || (func.type === "comp" ? [[-10, 10], [-10, 10]] : [-10, 10])
922
+ }).size /= 100;
826
923
  var data = [];
827
924
  pushMatrix();
828
- translate(config.origin[0], config.origin[1]);
925
+ translate(config.x, config.y);
829
926
  noFill();
830
927
  strokeWeight(config.strokeWeight);
831
928
  stroke(config.stroke);
@@ -883,17 +980,16 @@ var Chalkboard = {
883
980
  return data;
884
981
  },
885
982
  barplot: function(arr, bins, config) {
886
- config = config || {};
887
- config = {
983
+ (config = {
984
+ x: (config = config || {}).x || width / 2,
985
+ y: config.y || height / 2,
888
986
  size: config.size || 1,
889
- stroke: config.stroke || color(0),
890
987
  fill: config.fill || color(255),
891
- origin: config.origin || [width / 2, height / 2],
988
+ stroke: config.stroke || color(0),
892
989
  strokeWeight: config.strokeWeight || 2
893
- };
894
- config.size /= 100;
990
+ }).size /= 100;
895
991
  pushMatrix();
896
- translate(config.origin[0], config.origin[1]);
992
+ translate(config.x, config.y);
897
993
  strokeWeight(config.strokeWeight);
898
994
  stroke(config.stroke);
899
995
  fill(config.fill);
@@ -920,16 +1016,15 @@ var Chalkboard = {
920
1016
  return bars;
921
1017
  },
922
1018
  lineplot: function(arr, bins, config) {
923
- config = config || {};
924
- config = {
1019
+ (config = {
1020
+ x: (config = config || {}).x || width / 2,
1021
+ y: config.y || height / 2,
925
1022
  size: config.size || 1,
926
1023
  stroke: config.stroke || color(0),
927
- origin: config.origin || [width / 2, height / 2],
928
1024
  strokeWeight: config.strokeWeight || 2
929
- };
930
- config.size /= 100;
1025
+ }).size /= 100;
931
1026
  pushMatrix();
932
- translate(config.origin[0], config.origin[1]);
1027
+ translate(config.x, config.y);
933
1028
  noFill();
934
1029
  strokeWeight(config.strokeWeight);
935
1030
  stroke(config.stroke);
@@ -956,17 +1051,16 @@ var Chalkboard = {
956
1051
  return verts;
957
1052
  },
958
1053
  scatterplot: function(arr1, arr2, config) {
959
- config = config || {};
960
- config = {
1054
+ (config = {
1055
+ x: (config = config || {}).x || width / 2,
1056
+ y: config.y || height / 2,
961
1057
  size: config.size || 1,
962
1058
  stroke: config.stroke || color(0),
963
- origin: config.origin || [width / 2, height / 2],
964
1059
  strokeWeight: config.strokeWeight || 5
965
- };
966
- config.size /= 100;
1060
+ }).size /= 100;
967
1061
  var data = [];
968
1062
  pushMatrix();
969
- translate(config.origin[0], config.origin[1]);
1063
+ translate(config.x, config.y);
970
1064
  strokeWeight(config.strokeWeight);
971
1065
  stroke(config.stroke);
972
1066
  if(arr1.length === arr2.length) {
@@ -979,18 +1073,17 @@ var Chalkboard = {
979
1073
  return data;
980
1074
  },
981
1075
  comp: function(comp, config) {
982
- config = config || {};
983
- config = {
1076
+ (config = {
1077
+ x: (config = config || {}).x || width / 2,
1078
+ y: config.y || height / 2,
984
1079
  size: config.size || 1,
985
1080
  stroke: config.stroke || color(0),
986
- origin: config.origin || [width / 2, height / 2],
987
1081
  strokeWeight: config.strokeWeight || 5
988
- };
989
- config.size /= 100;
1082
+ }).size /= 100;
990
1083
  stroke(config.stroke);
991
1084
  strokeWeight(config.strokeWeight);
992
1085
  pushMatrix();
993
- translate(config.origin[0], config.origin[1]);
1086
+ translate(config.x, config.y);
994
1087
  point(comp.a / config.size, -comp.b / config.size);
995
1088
  popMatrix();
996
1089
  noStroke();
@@ -998,38 +1091,36 @@ var Chalkboard = {
998
1091
  return [[comp.a], [comp.b]];
999
1092
  },
1000
1093
  vec2: function(vec2, config) {
1001
- config = config || {};
1002
- config = {
1094
+ (config = {
1095
+ x: (config = config || {}).x || width / 2,
1096
+ y: config.y || height / 2,
1003
1097
  size: config.size || 1,
1004
1098
  stroke: config.stroke || color(0),
1005
- origin: config.origin || [width / 2, height / 2],
1006
- strokeWeight: config.strokeWeight || 2
1007
- };
1008
- config.size /= 100;
1099
+ strokeWeight: config.strokeWeight || 5
1100
+ }).size /= 100;
1009
1101
  stroke(config.stroke);
1010
1102
  strokeWeight(config.strokeWeight);
1011
1103
  pushMatrix();
1012
- translate(config.origin[0], config.origin[1]);
1104
+ translate(config.x, config.y);
1013
1105
  line(0, 0, vec2.x / config.size, -vec2.y / config.size);
1014
1106
  popMatrix();
1015
1107
  return [[vec2.x], [vec2.y]];
1016
1108
  },
1017
1109
  field: function(vec2field, config) {
1018
- config = config || {};
1019
- config = {
1110
+ (config = {
1111
+ x: (config = config || {}).x || width / 2,
1112
+ y: config.y || height / 2,
1020
1113
  size: config.size || 1,
1021
1114
  stroke: config.stroke || color(0),
1115
+ strokeWeight: config.strokeWeight || 5,
1022
1116
  domain: config.domain || [[-10, 10], [-10, 10]],
1023
- origin: config.origin || [width / 2, height / 2],
1024
- strokeWeight: config.strokeWeight || 2,
1025
1117
  res: config.res || 25
1026
- };
1027
- config.size /= 100;
1118
+ }).size /= 100;
1028
1119
  var data = [];
1029
1120
  stroke(config.stroke);
1030
1121
  strokeWeight(config.strokeWeight);
1031
1122
  pushMatrix();
1032
- translate(config.origin[0], config.origin[1]);
1123
+ translate(config.x, config.y);
1033
1124
  for(var i = config.domain[0][0] / config.size; i <= config.domain[0][1] / config.size; i += config.res) {
1034
1125
  for(var j = config.domain[1][0] / config.size; j <= config.domain[1][1] / config.size; j += config.res) {
1035
1126
  var v = Chalkboard.vec2.fromField(vec2field, Chalkboard.vec2.new(i, j));
@@ -1041,65 +1132,55 @@ var Chalkboard = {
1041
1132
  return data;
1042
1133
  },
1043
1134
  vec3: function(vec3, config) {
1044
- config = config || {};
1045
- config = {
1135
+ (config = {
1136
+ x: (config = config || {}).x || width / 2,
1137
+ y: config.y || height / 2,
1046
1138
  size: config.size || 1,
1047
1139
  stroke: config.stroke || color(0),
1048
- origin: config.origin || [width / 2, height / 2],
1049
- strokeWeight: config.strokeWeight || 2
1050
- };
1051
- config.size /= 100;
1140
+ strokeWeight: config.strokeWeight || 5
1141
+ }).size /= 100;
1052
1142
  stroke(config.stroke);
1053
1143
  strokeWeight(config.strokeWeight);
1054
1144
  pushMatrix();
1055
- translate(config.origin[0], config.origin[1]);
1145
+ translate(config.x, config.y);
1056
1146
  line(0, 0, (vec3.x / config.size) / (vec3.z * 0.25 + 1), (-vec3.y / config.size) / (vec3.z * 0.25 + 1));
1057
1147
  popMatrix();
1058
1148
  return [[vec3.x], [vec3.y], [vec3.z]];
1059
1149
  },
1060
1150
  matr: function(matr, config) {
1061
- config = config || {};
1062
- config = {
1151
+ (config = {
1152
+ x: (config = config || {}).x || width / 2,
1153
+ y: config.y || height / 2,
1063
1154
  size: config.size || 1,
1064
1155
  stroke: config.stroke || color(0),
1065
- origin: config.origin || [width / 2, height / 2],
1066
- strokeWeight: config.strokeWeight || 2
1067
- };
1068
- config.size /= 100;
1069
- var plotposx = Chalkboard.vec2.new(matr[0][0], matr[1][0]);
1070
- var plotnegx = Chalkboard.vec2.new(-matr[0][0], -matr[1][0]);
1071
- var plotposy = Chalkboard.vec2.new(matr[0][1], matr[1][1]);
1072
- var plotnegy = Chalkboard.vec2.new(-matr[0][1], -matr[1][1]);
1073
- for(var i = -10; i <= 10; i++) {
1074
- Chalkboard.vec2.plot(plotposx, {origin: [config.origin[0], config.origin[1] + (i / config.size) * matr[1][1]], strokeWeight: config.strokeWeight / 4});
1075
- Chalkboard.vec2.plot(plotnegx, {origin: [config.origin[0], config.origin[1] + (i / config.size) * matr[1][1]], strokeWeight: config.strokeWeight / 4});
1076
- Chalkboard.vec2.plot(plotposy, {origin: [config.origin[0] + (i / config.size) * matr[0][0], config.origin[1]], strokeWeight: config.strokeWeight / 4});
1077
- Chalkboard.vec2.plot(plotnegy, {origin: [config.origin[0] + (i / config.size) * matr[0][0], config.origin[1]], strokeWeight: config.strokeWeight / 4});
1078
- }
1079
- var plotposaxisx = Chalkboard.vec2.new(matr[0][0], matr[1][0]);
1080
- var plotnegaxisx = Chalkboard.vec2.new(-matr[0][0], -matr[1][0]);
1081
- var plotposaxisy = Chalkboard.vec2.new(matr[0][1], matr[1][1]);
1082
- var plotnegaxisy = Chalkboard.vec2.new(-matr[0][1], -matr[1][1]);
1083
- Chalkboard.vec2.plot(plotposaxisx, config);
1084
- Chalkboard.vec2.plot(plotnegaxisx, config);
1085
- Chalkboard.vec2.plot(plotposaxisy, config);
1086
- Chalkboard.vec2.plot(plotnegaxisy, config);
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);
1087
1169
  return matr;
1088
1170
  },
1089
1171
  dfdx: function(func, config) {
1090
- config = config || {};
1091
- config = {
1172
+ (config = {
1173
+ x: (config = config || {}).x || width / 2,
1174
+ y: config.y || height / 2,
1092
1175
  size: config.size || 1,
1093
1176
  stroke: config.stroke || color(0),
1094
- domain: config.domain || [-10, 10],
1095
- origin: config.origin || [width / 2, height / 2],
1096
1177
  strokeWeight: config.strokeWeight || 2,
1178
+ domain: config.domain || [-10, 10],
1097
1179
  res: config.res || 25
1098
- };
1099
- config.size /= 100;
1180
+ }).size /= 100;
1100
1181
  var data = [];
1101
1182
  pushMatrix();
1102
- translate(config.origin[0], config.origin[1]);
1183
+ translate(config.x, config.y);
1103
1184
  noFill();
1104
1185
  strokeWeight(config.strokeWeight);
1105
1186
  stroke(config.stroke);
@@ -1118,19 +1199,18 @@ var Chalkboard = {
1118
1199
  return data;
1119
1200
  },
1120
1201
  d2fdx2: function(func, config) {
1121
- config = config || {};
1122
- config = {
1202
+ (config = {
1203
+ x: (config = config || {}).x || width / 2,
1204
+ y: config.y || height / 2,
1123
1205
  size: config.size || 1,
1124
1206
  stroke: config.stroke || color(0),
1125
- domain: config.domain || [-10, 10],
1126
- origin: config.origin || [width / 2, height / 2],
1127
1207
  strokeWeight: config.strokeWeight || 2,
1208
+ domain: config.domain || [-10, 10],
1128
1209
  res: config.res || 25
1129
- };
1130
- config.size /= 100;
1210
+ }).size /= 100;
1131
1211
  var data = [];
1132
1212
  pushMatrix();
1133
- translate(config.origin[0], config.origin[1]);
1213
+ translate(config.x, config.y);
1134
1214
  noFill();
1135
1215
  strokeWeight(config.strokeWeight);
1136
1216
  stroke(config.stroke);
@@ -1149,19 +1229,18 @@ var Chalkboard = {
1149
1229
  return data;
1150
1230
  },
1151
1231
  fxdx: function(func, config) {
1152
- config = config || {};
1153
- config = {
1232
+ (config = {
1233
+ x: (config = config || {}).x || width / 2,
1234
+ y: config.y || height / 2,
1154
1235
  size: config.size || 1,
1155
1236
  stroke: config.stroke || color(0),
1156
- domain: config.domain || [-10, 10],
1157
- origin: config.origin || [width / 2, height / 2],
1158
1237
  strokeWeight: config.strokeWeight || 2,
1238
+ domain: config.domain || [-10, 10],
1159
1239
  res: config.res || 25
1160
- };
1161
- config.size /= 100;
1240
+ }).size /= 100;
1162
1241
  var data = [];
1163
1242
  pushMatrix();
1164
- translate(config.origin[0], config.origin[1]);
1243
+ translate(config.x, config.y);
1165
1244
  noFill();
1166
1245
  strokeWeight(config.strokeWeight);
1167
1246
  stroke(config.stroke);
@@ -1180,19 +1259,18 @@ var Chalkboard = {
1180
1259
  return data;
1181
1260
  },
1182
1261
  convolution: function(func_1, func_2, config) {
1183
- config = config || {};
1184
- config = {
1262
+ (config = {
1263
+ x: (config = config || {}).x || width / 2,
1264
+ y: config.y || height / 2,
1185
1265
  size: config.size || 1,
1186
1266
  stroke: config.stroke || color(0),
1187
- domain: config.domain || [-10, 10],
1188
- origin: config.origin || [width / 2, height / 2],
1189
1267
  strokeWeight: config.strokeWeight || 2,
1268
+ domain: config.domain || [-10, 10],
1190
1269
  res: config.res || 25
1191
- };
1192
- config.size /= 100;
1270
+ }).size /= 100;
1193
1271
  var data = [];
1194
1272
  pushMatrix();
1195
- translate(config.origin[0], config.origin[1]);
1273
+ translate(config.x, config.y);
1196
1274
  noFill();
1197
1275
  strokeWeight(config.strokeWeight);
1198
1276
  stroke(config.stroke);
@@ -1206,19 +1284,18 @@ var Chalkboard = {
1206
1284
  return data;
1207
1285
  },
1208
1286
  correlation: function(func_1, func_2, config) {
1209
- config = config || {};
1210
- config = {
1287
+ (config = {
1288
+ x: (config = config || {}).x || width / 2,
1289
+ y: config.y || height / 2,
1211
1290
  size: config.size || 1,
1212
1291
  stroke: config.stroke || color(0),
1213
- domain: config.domain || [-10, 10],
1214
- origin: config.origin || [width / 2, height / 2],
1215
1292
  strokeWeight: config.strokeWeight || 2,
1293
+ domain: config.domain || [-10, 10],
1216
1294
  res: config.res || 25
1217
- };
1218
- config.size /= 100;
1295
+ }).size /= 100;
1219
1296
  var data = [];
1220
1297
  pushMatrix();
1221
- translate(config.origin[0], config.origin[1]);
1298
+ translate(config.x, config.y);
1222
1299
  noFill();
1223
1300
  strokeWeight(config.strokeWeight);
1224
1301
  stroke(config.stroke);
@@ -1232,19 +1309,18 @@ var Chalkboard = {
1232
1309
  return data;
1233
1310
  },
1234
1311
  autocorrelation: function(func, config) {
1235
- config = config || {};
1236
- config = {
1312
+ (config = {
1313
+ x: (config = config || {}).x || width / 2,
1314
+ y: config.y || height / 2,
1237
1315
  size: config.size || 1,
1238
1316
  stroke: config.stroke || color(0),
1239
- domain: config.domain || [-10, 10],
1240
- origin: config.origin || [width / 2, height / 2],
1241
1317
  strokeWeight: config.strokeWeight || 2,
1318
+ domain: config.domain || [-10, 10],
1242
1319
  res: config.res || 25
1243
- };
1244
- config.size /= 100;
1320
+ }).size /= 100;
1245
1321
  var data = [];
1246
1322
  pushMatrix();
1247
- translate(config.origin[0], config.origin[1]);
1323
+ translate(config.x, config.y);
1248
1324
  noFill();
1249
1325
  strokeWeight(config.strokeWeight);
1250
1326
  stroke(config.stroke);
@@ -1258,19 +1334,18 @@ var Chalkboard = {
1258
1334
  return data;
1259
1335
  },
1260
1336
  Taylor: function(func, n, a, config) {
1261
- config = config || {};
1262
- config = {
1337
+ (config = {
1338
+ x: (config = config || {}).x || width / 2,
1339
+ y: config.y || height / 2,
1263
1340
  size: config.size || 1,
1264
1341
  stroke: config.stroke || color(0),
1265
- domain: config.domain || [-10, 10],
1266
- origin: config.origin || [width / 2, height / 2],
1267
1342
  strokeWeight: config.strokeWeight || 2,
1343
+ domain: config.domain || [-10, 10],
1268
1344
  res: config.res || 25
1269
- };
1270
- config.size /= 100;
1345
+ }).size /= 100;
1271
1346
  var data = [];
1272
1347
  pushMatrix();
1273
- translate(config.origin[0], config.origin[1]);
1348
+ translate(config.x, config.y);
1274
1349
  noFill();
1275
1350
  strokeWeight(config.strokeWeight);
1276
1351
  stroke(config.stroke);
@@ -1284,19 +1359,18 @@ var Chalkboard = {
1284
1359
  return data;
1285
1360
  },
1286
1361
  Laplace: function(func, config) {
1287
- config = config || {};
1288
- config = {
1362
+ (config = {
1363
+ x: (config = config || {}).x || width / 2,
1364
+ y: config.y || height / 2,
1289
1365
  size: config.size || 1,
1290
1366
  stroke: config.stroke || color(0),
1291
- domain: config.domain || [-10, 10],
1292
- origin: config.origin || [width / 2, height / 2],
1293
1367
  strokeWeight: config.strokeWeight || 2,
1368
+ domain: config.domain || [-10, 10],
1294
1369
  res: config.res || 25
1295
- };
1296
- config.size /= 100;
1370
+ }).size /= 100;
1297
1371
  var data = [];
1298
1372
  pushMatrix();
1299
- translate(config.origin[0], config.origin[1]);
1373
+ translate(config.x, config.y);
1300
1374
  noFill();
1301
1375
  strokeWeight(config.strokeWeight);
1302
1376
  stroke(config.stroke);
@@ -1317,19 +1391,18 @@ var Chalkboard = {
1317
1391
  return data;
1318
1392
  },
1319
1393
  Fourier: function(func, config) {
1320
- config = config || {};
1321
- config = {
1394
+ (config = {
1395
+ x: (config = config || {}).x || width / 2,
1396
+ y: config.y || height / 2,
1322
1397
  size: config.size || 1,
1323
1398
  stroke: config.stroke || color(0),
1324
- domain: config.domain || [-10, 10],
1325
- origin: config.origin || [width / 2, height / 2],
1326
1399
  strokeWeight: config.strokeWeight || 2,
1400
+ domain: config.domain || [-10, 10],
1327
1401
  res: config.res || 25
1328
- };
1329
- config.size /= 100;
1402
+ }).size /= 100;
1330
1403
  var data = [];
1331
1404
  pushMatrix();
1332
- translate(config.origin[0], config.origin[1]);
1405
+ translate(config.x, config.y);
1333
1406
  noFill();
1334
1407
  strokeWeight(config.strokeWeight);
1335
1408
  stroke(config.stroke);
@@ -1750,7 +1823,7 @@ var Chalkboard = {
1750
1823
  },
1751
1824
  eq: function(arr, arrORnum) {
1752
1825
  var result = [];
1753
- if(arrORnum.constructor === Array) {
1826
+ if(Array.isArray(arrORnum)) {
1754
1827
  if(arr.length === arrORnum.length) {
1755
1828
  for(var i = 0; i < arr.length; i++) {
1756
1829
  if(arr[i] === arrORnum[i]) {
@@ -1771,7 +1844,7 @@ var Chalkboard = {
1771
1844
  includeInf = includeInf || false;
1772
1845
  includeSup = includeSup || false;
1773
1846
  var result = [];
1774
- if(inf.constructor === Array && sup.constructor === Array) {
1847
+ if(Array.isArray(inf) && Array.isArray(sup)) {
1775
1848
  if(arr.length === inf.length && arr.length === sup.length) {
1776
1849
  for(var i = 0; i < arr.length; i++) {
1777
1850
  if(includeInf) {
@@ -1827,7 +1900,7 @@ var Chalkboard = {
1827
1900
  lt: function(arr, arrORnum, includeEnd) {
1828
1901
  includeEnd = includeEnd || false;
1829
1902
  var result = [];
1830
- if(arrORnum.constructor === Array) {
1903
+ if(Array.isArray(arrORnum)) {
1831
1904
  if(arr.length === arrORnum.length) {
1832
1905
  for(var i = 0; i < arr.length; i++) {
1833
1906
  if(includeEnd) {
@@ -1859,7 +1932,7 @@ var Chalkboard = {
1859
1932
  gt: function(arr, arrORnum, includeEnd) {
1860
1933
  includeEnd = includeEnd || false;
1861
1934
  var result = [];
1862
- if(arrORnum.constructor === Array) {
1935
+ if(Array.isArray(arrORnum)) {
1863
1936
  if(arr.length === arrORnum.length) {
1864
1937
  for(var i = 0; i < arr.length; i++) {
1865
1938
  if(includeEnd) {
@@ -2182,13 +2255,14 @@ var Chalkboard = {
2182
2255
  return "TypeError: Parameter \"type\" must be either \"linear\", \"polynomial\", \"power\", \"exponential\", or \"logarithmic\".";
2183
2256
  }
2184
2257
  },
2185
- toVector: function(arr, type) {
2258
+ toVector: function(arr, type, index) {
2259
+ if(index === undefined) { index = 0; }
2186
2260
  if(type === "vec2") {
2187
- return Chalkboard.vec2.new(arr[0], arr[1]);
2261
+ return Chalkboard.vec2.new(arr[index], arr[index + 1]);
2188
2262
  } else if(type === "vec3") {
2189
- return Chalkboard.vec3.new(arr[0], arr[1], arr[2]);
2263
+ return Chalkboard.vec3.new(arr[index], arr[index + 1], arr[index + 2]);
2190
2264
  } else if(type === "vec4") {
2191
- return Chalkboard.vec4.new(arr[0], arr[1], arr[2], arr[3]);
2265
+ return Chalkboard.vec4.new(arr[index], arr[index + 1], arr[index + 2], arr[index + 3]);
2192
2266
  } else {
2193
2267
  return "TypeError: Parameter \"type\" should be \"vec2\", \"vec3\", or \"vec4\".";
2194
2268
  }
@@ -2209,6 +2283,12 @@ var Chalkboard = {
2209
2283
  }
2210
2284
  return result;
2211
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
+ },
2212
2292
  toObject: function(arr) {
2213
2293
  var result = {};
2214
2294
  for(var i = 0; i < arr.length; i++) {
@@ -2231,6 +2311,9 @@ var Chalkboard = {
2231
2311
  return {x: x, y: y, type: "vec2"};
2232
2312
  }
2233
2313
  },
2314
+ copy: function(vec2) {
2315
+ return Object.create(Object.getPrototypeOf(vec2), Object.getOwnPropertyDescriptors(vec2));
2316
+ },
2234
2317
  random: function(inf, sup) {
2235
2318
  return Chalkboard.vec2.new(Chalkboard.numb.random(inf, sup), Chalkboard.numb.random(inf, sup));
2236
2319
  },
@@ -2375,6 +2458,9 @@ var Chalkboard = {
2375
2458
  return {x: x, y: y, z: z, type: "vec3"};
2376
2459
  }
2377
2460
  },
2461
+ copy: function(vec3) {
2462
+ return Object.create(Object.getPrototypeOf(vec3), Object.getOwnPropertyDescriptors(vec3));
2463
+ },
2378
2464
  random: function(inf, sup) {
2379
2465
  return Chalkboard.vec3.new(Chalkboard.numb.random(inf, sup), Chalkboard.numb.random(inf, sup), Chalkboard.numb.random(inf, sup));
2380
2466
  },
@@ -2526,6 +2612,9 @@ var Chalkboard = {
2526
2612
  return {x: x, y: y, z: z, w: w, type: "vec4"};
2527
2613
  }
2528
2614
  },
2615
+ copy: function(vec4) {
2616
+ return Object.create(Object.getPrototypeOf(vec4), Object.getOwnPropertyDescriptors(vec4));
2617
+ },
2529
2618
  random: function(inf, sup) {
2530
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));
2531
2620
  },
@@ -2660,8 +2749,23 @@ var Chalkboard = {
2660
2749
  },
2661
2750
  matr: {
2662
2751
  new: function(matrix) {
2663
- matrix = Array.from(arguments);
2664
- return 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;
2665
2769
  },
2666
2770
  rows: function(matr) {
2667
2771
  return matr.length;
@@ -2669,6 +2773,21 @@ var Chalkboard = {
2669
2773
  cols: function(matr) {
2670
2774
  return matr[0].length;
2671
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
+ },
2672
2791
  push: function(matr, type, rowORcol, elements) {
2673
2792
  rowORcol -= 1;
2674
2793
  if(type === "row") {
@@ -2698,6 +2817,9 @@ var Chalkboard = {
2698
2817
  }
2699
2818
  },
2700
2819
  fill: function(element, rows, cols) {
2820
+ if(cols === undefined) {
2821
+ cols = rows;
2822
+ }
2701
2823
  if(Number.isInteger(rows) && Number.isInteger(cols) && rows > 0 && cols > 0) {
2702
2824
  var result = Chalkboard.matr.new();
2703
2825
  for(var i = 0; i < rows; i++) {
@@ -2712,6 +2834,9 @@ var Chalkboard = {
2712
2834
  }
2713
2835
  },
2714
2836
  empty: function(rows, cols) {
2837
+ if(cols === undefined) {
2838
+ cols = rows;
2839
+ }
2715
2840
  if(Number.isInteger(rows) && Number.isInteger(cols) && rows > 0 && cols > 0) {
2716
2841
  var result = Chalkboard.matr.new();
2717
2842
  for(var i = 0; i < rows; i++) {
@@ -2737,7 +2862,25 @@ var Chalkboard = {
2737
2862
  return undefined;
2738
2863
  }
2739
2864
  },
2740
- random: function(rows, cols, inf, sup) {
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
+ }
2741
2884
  if(Number.isInteger(rows) && Number.isInteger(cols) && rows > 0 && cols > 0) {
2742
2885
  var result = Chalkboard.matr.new();
2743
2886
  for(var i = 0; i < rows; i++) {
@@ -2751,6 +2894,73 @@ var Chalkboard = {
2751
2894
  return undefined;
2752
2895
  }
2753
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
+ },
2754
2964
  cofactor: function(matr, row, col) {
2755
2965
  return matr.slice(0, row - 1).concat(matr.slice(row)).map(function(row) {
2756
2966
  return row.slice(0, col - 1).concat(row.slice(col));
@@ -2873,7 +3083,7 @@ var Chalkboard = {
2873
3083
  LUdecomp: function(matr) {
2874
3084
  if(Chalkboard.matr.rows(matr) === Chalkboard.matr.cols(matr)) {
2875
3085
  var L = Chalkboard.matr.identity(Chalkboard.matr.rows(matr)),
2876
- U = Chalkboard.matr.zero(Chalkboard.matr.empty(Chalkboard.matr.rows(matr)));
3086
+ U = Chalkboard.matr.fill(0, Chalkboard.matr.rows(matr));
2877
3087
  for(var j = 0; j < Chalkboard.matr.cols(matr); j++) {
2878
3088
  for(var i = 0; i <= j; i++) {
2879
3089
  var sum = 0;
@@ -2896,51 +3106,51 @@ var Chalkboard = {
2896
3106
  }
2897
3107
  },
2898
3108
  QRdecomp: function(matr) {
2899
- if(Chalkboard.matr.rows(matr) === Chalkboard.matr.cols(matr)) {
2900
- var Q = Chalkboard.matr.zero(Chalkboard.matr.empty(Chalkboard.matr.rows(matr))),
2901
- R = Chalkboard.matr.zero(Chalkboard.matr.empty(Chalkboard.matr.rows(matr)));
2902
- var dot = function(v1, v2) {
2903
- var result = 0;
2904
- for(var i = 0; i < v1.length; i++) {
2905
- result += v1[i] * v2[i];
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];
2906
3136
  }
2907
- return result;
2908
- }
2909
- var mag = function(v) {
2910
- var result = 0;
3137
+ dot *= 2;
2911
3138
  for(var i = 0; i < v.length; i++) {
2912
- result += v[i] * v[i];
3139
+ R[i + j][k] -= dot * v[i];
2913
3140
  }
2914
- return Math.sqrt(result);
2915
3141
  }
2916
- for(var j = 0; j < Chalkboard.matr.rows(matr); j++) {
2917
- var v = matr.map(function(row) {
2918
- return row[j];
2919
- });
2920
- for(var i = 0; i < j; i++) {
2921
- var q = Q.map(function(row) {
2922
- return row[i];
2923
- });
2924
- var coeff = dot(v, q) / (mag(q) * mag(q));
2925
- v = v.map(function(e, index) {
2926
- return e - coeff * q[index];
2927
- });
2928
- }
2929
- for(var i = 0; i < Chalkboard.matr.rows(matr); i++) {
2930
- Q[i][j] = v[i] / mag(v);
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];
2931
3146
  }
2932
- for(var i = 0; i < Chalkboard.matr.rows(matr); i++) {
2933
- R[j][i] = i < j ? 0 : matr.map(function(row) {
2934
- return row[i];
2935
- }).reduce(function(a, v, index) {
2936
- return a + v * Q[index][j];
2937
- }, 0);
3147
+ dot *= 2;
3148
+ for(var i = 0; i < v.length; i++) {
3149
+ Q[k][i + j] -= dot * v[i];
2938
3150
  }
2939
3151
  }
2940
- return {Q: Q, R: R};
2941
- } else {
2942
- return undefined;
2943
3152
  }
3153
+ return {Q: Q, R: R};
2944
3154
  },
2945
3155
  zero: function(matr) {
2946
3156
  var result = Chalkboard.matr.new();
@@ -3042,6 +3252,28 @@ var Chalkboard = {
3042
3252
  }
3043
3253
  return result;
3044
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
+ },
3045
3277
  add: function(matr_1, matr_2) {
3046
3278
  if(Chalkboard.matr.rows(matr_1) === Chalkboard.matr.rows(matr_2) && Chalkboard.matr.cols(matr_1) === Chalkboard.matr.cols(matr_2)) {
3047
3279
  var result = Chalkboard.matr.new();
@@ -3087,6 +3319,29 @@ var Chalkboard = {
3087
3319
  return undefined;
3088
3320
  }
3089
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
+ },
3090
3345
  pow: function(matr, num) {
3091
3346
  if(Chalkboard.matr.rows(matr) === Chalkboard.matr.cols(matr)) {
3092
3347
  if(Number.isInteger(num) && num >= 0) {
@@ -3106,6 +3361,29 @@ var Chalkboard = {
3106
3361
  return undefined;
3107
3362
  }
3108
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
+ },
3109
3387
  reduce: function(matr) {
3110
3388
  var lead = 0;
3111
3389
  for(var row = 0; row < Chalkboard.matr.rows(matr); row++) {
@@ -3189,6 +3467,12 @@ var Chalkboard = {
3189
3467
  return "TypeError: Parameter \"vec\" should be \"vec2\", \"vec3\", or \"vec4\".";
3190
3468
  }
3191
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
+ },
3192
3476
  toArray: function(matr) {
3193
3477
  var result = [];
3194
3478
  for(var i = 0; i < Chalkboard.matr.rows(matr); i++) {
@@ -3198,6 +3482,16 @@ var Chalkboard = {
3198
3482
  }
3199
3483
  return result;
3200
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
+ },
3201
3495
  toString: function(matr) {
3202
3496
  var result = "";
3203
3497
  for(var i = 0; i < Chalkboard.matr.rows(matr); i++) {
@@ -3209,18 +3503,369 @@ var Chalkboard = {
3209
3503
  }
3210
3504
  return result;
3211
3505
  },
3212
- toObject: function(matr) {
3213
- var result = {};
3214
- for(var i = 0; i < Chalkboard.matr.rows(matr); i++) {
3215
- result["i" + (i + 1)] = {};
3216
- for(var j = 0; j < Chalkboard.matr.cols(matr); j++) {
3217
- result["i" + (i + 1)]["j" + (j + 1)] = matr[i][j];
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]);
3218
3535
  }
3536
+ return result;
3537
+ } else {
3538
+ return tens;
3219
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);
3220
3578
  return result;
3221
3579
  },
3222
- print: function(matr) {
3223
- console.log(Chalkboard.matr.toString(matr));
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));
3224
3869
  }
3225
3870
  },
3226
3871
  calc: {
@@ -3571,7 +4216,7 @@ var Chalkboard = {
3571
4216
  return "TypeError: Parameter \"func\" must be of type \"comp\".";
3572
4217
  }
3573
4218
  },
3574
- fxdx: function(func, a, b) {
4219
+ fxdx: function(func, inf, sup) {
3575
4220
  if(func.type === "expl" || func.type === "inve" || func.type === "pola") {
3576
4221
  var f;
3577
4222
  if(func.type === "expl") {
@@ -3581,36 +4226,36 @@ var Chalkboard = {
3581
4226
  } else if(func.type === "pola") {
3582
4227
  f = Chalkboard.real.parse("O => " + "((" + func.definition + ") * (" + func.definition + ")) / 2");
3583
4228
  }
3584
- var fx = f(a) + f(b);
3585
- var dx = (b - a) / 1000000;
4229
+ var fx = f(inf) + f(sup);
4230
+ var dx = (sup - inf) / 1000000;
3586
4231
  for(var i = 1; i < 1000000; i++) {
3587
- fx += i % 2 === 0 ? 2 * f(a + i * dx) : 4 * f(a + i * dx);
4232
+ fx += i % 2 === 0 ? 2 * f(inf + i * dx) : 4 * f(inf + i * dx);
3588
4233
  }
3589
4234
  return (fx * dx) / 3;
3590
4235
  } else if(func.type === "curv") {
3591
4236
  if(func.definition.length === 2) {
3592
4237
  var x = Chalkboard.real.parse("t => " + func.definition[0]),
3593
4238
  y = Chalkboard.real.parse("t => " + func.definition[1]);
3594
- var xt = x(a) + x(b),
3595
- yt = y(a) + y(b);
3596
- var dt = (b - a) / 1000000;
4239
+ var xt = x(inf) + x(sup),
4240
+ yt = y(inf) + y(sup);
4241
+ var dt = (sup - inf) / 1000000;
3597
4242
  for(var i = 1; i < 1000000; i++) {
3598
- xt += i % 2 === 0 ? 2 * x(a + i * dt) : 4 * x(a + i * dt);
3599
- yt += i % 2 === 0 ? 2 * y(a + i * dt) : 4 * y(a + i * dt);
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);
3600
4245
  }
3601
4246
  return Chalkboard.vec2.new((xt * dt) / 3, (yt * dt) / 3);
3602
4247
  } else if(func.definition.length === 3) {
3603
4248
  var x = Chalkboard.real.parse("t => " + func.definition[0]),
3604
4249
  y = Chalkboard.real.parse("t => " + func.definition[1]),
3605
4250
  z = Chalkboard.real.parse("t => " + func.definition[2]);
3606
- var xt = x(a) + x(b),
3607
- yt = y(a) + y(b),
3608
- zt = z(a) + z(b);
3609
- var dt = (b - a) / 1000000;
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;
3610
4255
  for(var i = 1; i < 1000000; i++) {
3611
- xt += i % 2 === 0 ? 2 * x(a + i * dt) : 4 * x(a + i * dt);
3612
- yt += i % 2 === 0 ? 2 * y(a + i * dt) : 4 * y(a + i * dt);
3613
- zt += i % 2 === 0 ? 2 * z(a + i * dt) : 4 * z(a + i * dt);
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);
3614
4259
  }
3615
4260
  return Chalkboard.vec3.new((xt * dt) / 3, (yt * dt) / 3, (zt * dt) / 3);
3616
4261
  }
@@ -3618,14 +4263,14 @@ var Chalkboard = {
3618
4263
  return "TypeError: Parameter \"func\" must be of type \"expl\", \"inve\", \"pola\", or \"curv\".";
3619
4264
  }
3620
4265
  },
3621
- fxydxdy: function(func, a, b, c, d) {
4266
+ fxydxdy: function(func, xinf, xsup, yinf, ysup) {
3622
4267
  if(func.type === "mult") {
3623
4268
  var f = Chalkboard.real.parse("(x, y) => " + func.definition);
3624
4269
  var result = 0;
3625
- var dx = (b - a) / 10000,
3626
- dy = (d - c) / 10000;
3627
- for(var x = a; x <= b; x += dx) {
3628
- for(var y = c; y <= d; y += dy) {
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) {
3629
4274
  result += f(x, y);
3630
4275
  }
3631
4276
  }
@@ -3634,29 +4279,29 @@ var Chalkboard = {
3634
4279
  return "TypeError: Parameter \"func\" must be of type \"mult\".";
3635
4280
  }
3636
4281
  },
3637
- fds: function(func, a, b, c, d) {
4282
+ fds: function(func, tinf, tsup, sinf, ssup) {
3638
4283
  var result = 0;
3639
4284
  var drdt, drds;
3640
4285
  if(func.type === "curv") {
3641
- var dt = (b - a) / 10000;
4286
+ var dt = (tsup - tinf) / 10000;
3642
4287
  if(func.definition.length === 2) {
3643
- for(var t = a; t <= b; t += dt) {
4288
+ for(var t = tinf; t <= tsup; t += dt) {
3644
4289
  drdt = Chalkboard.calc.dfdx(func, t);
3645
4290
  result += Chalkboard.vec2.mag(drdt);
3646
4291
  }
3647
4292
  return result * dt;
3648
4293
  } else if(func.definition.length === 3) {
3649
- for(var t = a; t <= b; t += dt) {
4294
+ for(var t = tinf; t <= tsup; t += dt) {
3650
4295
  drdt = Chalkboard.calc.dfdx(func, t);
3651
4296
  result += Chalkboard.vec3.mag(drdt);
3652
4297
  }
3653
4298
  return result * dt;
3654
4299
  }
3655
4300
  } else if(func.type === "surf") {
3656
- var dt = (b - a) / 100,
3657
- ds = (d - c) / 100;
3658
- for(var s = c; s <= d; s += ds) {
3659
- for(var t = a; t <= b; t += dt) {
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) {
3660
4305
  drds = Chalkboard.matr.toVector(Chalkboard.calc.grad(func, Chalkboard.vec2.new(s, t)), "vec3", "col", 1);
3661
4306
  drdt = Chalkboard.matr.toVector(Chalkboard.calc.grad(func, Chalkboard.vec2.new(s, t)), "vec3", "col", 2);
3662
4307
  result += Chalkboard.vec3.mag(Chalkboard.vec3.cross(drds, drdt));
@@ -3667,22 +4312,22 @@ var Chalkboard = {
3667
4312
  return "TypeError: Parameter \"func\" must be of type \"curv\" or \"surf\".";
3668
4313
  }
3669
4314
  },
3670
- frds: function(funcORvecfield, func, a, b) {
4315
+ frds: function(funcORvecfield, func, inf, sup) {
3671
4316
  if(func.type === "curv") {
3672
4317
  var result = 0;
3673
- var dt = (b - a) / 10000;
4318
+ var dt = (sup - inf) / 10000;
3674
4319
  if(funcORvecfield.type === "mult") {
3675
- for(var t = a; t <= b; t += dt) {
3676
- result += Chalkboard.real.val(funcORvecfield, Chalkboard.vec2.toArray(Chalkboard.real.val(func, t))) * Chalkboard.vec2.mag(Chalkboard.calc.dfdx(func, t));
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));
3677
4322
  }
3678
4323
  return result * dt;
3679
4324
  } else if(funcORvecfield.type === "vec2field") {
3680
- for(var t = a; t <= b; t += dt) {
4325
+ for(var t = inf; t <= sup; t += dt) {
3681
4326
  result += Chalkboard.vec2.dot(Chalkboard.vec2.fromField(funcORvecfield, Chalkboard.real.val(func, t)), Chalkboard.calc.dfdx(func, t));
3682
4327
  }
3683
4328
  return result * dt;
3684
4329
  } else if(funcORvecfield.type === "vec3field") {
3685
- for(var t = a; t <= b; t += dt) {
4330
+ for(var t = inf; t <= sup; t += dt) {
3686
4331
  result += Chalkboard.vec3.dot(Chalkboard.vec3.fromField(funcORvecfield, Chalkboard.real.val(func, t)), Chalkboard.calc.dfdx(func, t));
3687
4332
  }
3688
4333
  return result * dt;
@@ -3693,29 +4338,29 @@ var Chalkboard = {
3693
4338
  return "TypeError: Parameter \"func\" must be of type \"curv\".";
3694
4339
  }
3695
4340
  },
3696
- fnds: function(vecfield, func, a, b, c, d) {
4341
+ fnds: function(vecfield, func, tinf, tsup, sinf, ssup) {
3697
4342
  var result = 0;
3698
4343
  var drdt, drds;
3699
4344
  if(func.type === "curv") {
3700
- var dt = (b - a) / 10000;
4345
+ var dt = (tsup - tinf) / 10000;
3701
4346
  if(func.definition.length === 2) {
3702
- for(var t = a; t <= b; t += dt) {
4347
+ for(var t = tinf; t <= tsup; t += dt) {
3703
4348
  drdt = Chalkboard.calc.dfdx(func, t);
3704
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);
3705
4350
  }
3706
4351
  return result * dt;
3707
4352
  } else if(func.definition.length === 3) {
3708
- for(var t = a; t <= b; t += dt) {
4353
+ for(var t = tinf; t <= tsup; t += dt) {
3709
4354
  drdt = Chalkboard.calc.dfdx(func, t);
3710
4355
  result += Chalkboard.vec3.dot(Chalkboard.vec3.fromField(vecfield, Chalkboard.real.val(func, t)), Chalkboard.calc.normal(func, t)) * Chalkboard.vec3.mag(drdt);
3711
4356
  }
3712
4357
  return result * dt;
3713
4358
  }
3714
4359
  } else if(func.type === "surf") {
3715
- var dt = (b - a) / 100,
3716
- ds = (d - c) / 100;
3717
- for(var s = c; s <= d; s += ds) {
3718
- for(var t = a; t <= b; t += dt) {
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) {
3719
4364
  drds = Chalkboard.matr.toVector(Chalkboard.calc.grad(func, Chalkboard.vec2.new(s, t)), "vec3", "col", 1);
3720
4365
  drdt = Chalkboard.matr.toVector(Chalkboard.calc.grad(func, Chalkboard.vec2.new(s, t)), "vec3", "col", 2);
3721
4366
  result += Chalkboard.vec3.scalarTriple(Chalkboard.vec3.fromField(vecfield, Chalkboard.real.val(func, Chalkboard.vec2.new(s, t))), drds, drdt);
@@ -3726,12 +4371,12 @@ var Chalkboard = {
3726
4371
  return "TypeError: Parameter \"func\" must be of type \"curv\" or \"surf\".";
3727
4372
  }
3728
4373
  },
3729
- fzdz: function(func_1, func_2, a, b) {
4374
+ fzdz: function(func_1, func_2, inf, sup) {
3730
4375
  if(func_1.type === "comp") {
3731
4376
  if(func_2.type === "curv") {
3732
4377
  var result = Chalkboard.comp.new(0, 0);
3733
- var dt = (b - a) / 10000;
3734
- for(var t = a; t <= b; t += dt) {
4378
+ var dt = (sup - inf) / 10000;
4379
+ for(var t = inf; t <= sup; t += dt) {
3735
4380
  var fz = Chalkboard.comp.val(func_1, Chalkboard.vec2.toComplex(Chalkboard.real.val(func_2, t)));
3736
4381
  var rt = Chalkboard.calc.dfdx(func_2, t);
3737
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)));