robotic 0.2.9.dev2__cp38-cp38-manylinux2014_x86_64.whl → 0.3.1__cp38-cp38-manylinux2014_x86_64.whl

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.
Files changed (77) hide show
  1. robotic/__init__.py +3 -3
  2. robotic/_robotic.pyi +17 -11
  3. robotic/_robotic.so +0 -0
  4. robotic/include/rai/Algo/rungeKutta.h +1 -1
  5. robotic/include/rai/Control/TimingMPC.h +2 -2
  6. robotic/include/rai/Core/array.h +64 -40
  7. robotic/include/rai/Core/array.ipp +244 -80
  8. robotic/include/rai/Core/arrayDouble.h +10 -13
  9. robotic/include/rai/Core/graph.h +23 -2
  10. robotic/include/rai/Core/h5.h +3 -1
  11. robotic/include/rai/Geo/fclInterface.h +3 -1
  12. robotic/include/rai/Geo/geo.h +4 -1
  13. robotic/include/rai/Geo/mesh.h +11 -5
  14. robotic/include/rai/Geo/pairCollision.h +4 -4
  15. robotic/include/rai/Gui/RenderData.h +4 -3
  16. robotic/include/rai/Gui/opengl.h +1 -1
  17. robotic/include/rai/KOMO/komo.h +1 -0
  18. robotic/include/rai/KOMO/manipTools.h +1 -1
  19. robotic/include/rai/Kin/F_forces.h +1 -1
  20. robotic/include/rai/Kin/dof_forceExchange.h +4 -4
  21. robotic/include/rai/Kin/frame.h +4 -3
  22. robotic/include/rai/Kin/kin.h +24 -15
  23. robotic/include/rai/Kin/kin_physx.h +2 -2
  24. robotic/include/rai/Kin/simulation.h +1 -0
  25. robotic/include/rai/Logic/folWorld.h +1 -1
  26. robotic/include/rai/Optim/testProblems_Opt.h +2 -2
  27. robotic/include/rai/Optim/utils.h +2 -2
  28. robotic/include/rai/PathAlgos/ConfigurationProblem.h +3 -2
  29. robotic/include/rai/PathAlgos/RRT_PathFinder.h +1 -1
  30. robotic/librai.so +0 -0
  31. robotic/meshTool +0 -0
  32. robotic/mujoco-import.py +5 -7
  33. robotic/rai-robotModels/g1/g1.g +11 -2
  34. robotic/rai-robotModels/g1/g1_29dof_conv.yml +64 -0
  35. robotic/rai-robotModels/objects/shelf.g +1 -1
  36. robotic/rai-robotModels/panda/panda.g +1 -1
  37. robotic/rai-robotModels/panda/panda_arm_hand_conv.g +22 -22
  38. robotic/rai-robotModels/panda/panda_arm_hand_conv.yml +24 -0
  39. robotic/rai-robotModels/pr2/pr2.g +6 -6
  40. robotic/rai-robotModels/pr2/pr2_clean.g +114 -114
  41. robotic/rai-robotModels/pr2/pr2_modifications.g +2 -2
  42. robotic/rai-robotModels/ranger/ranger.g +3 -3
  43. robotic/rai-robotModels/robotiq/robotiq.g +1 -1
  44. robotic/rai-robotModels/robotiq/robotiq_arg2f_85_model_conv.yml +19 -0
  45. robotic/rai-robotModels/scenarios/panda_fixRobotiq.g +3 -3
  46. robotic/rai-robotModels/tests/arm.g +11 -11
  47. robotic/rai-robotModels/ur10/ur10.g +1 -1
  48. robotic/rai-robotModels/ur10/ur10_clean.g +8 -8
  49. robotic/ry-h5info +2 -2
  50. robotic/ry-test +2 -1
  51. robotic/ry-urdfConvert.py +3 -2
  52. robotic/src/__init__.py +0 -0
  53. robotic/{cleanMeshes.py → src/cleanMeshes.py} +0 -0
  54. robotic/src/meshlabFilters.mlx +20 -0
  55. robotic/src/{config_mujoco.py → mujoco_io.py} +21 -16
  56. robotic/src/{config_urdf.py → urdf_io.py} +0 -0
  57. robotic/src/yaml_helper.py +0 -0
  58. robotic/test.py +15 -0
  59. robotic/version.py +1 -1
  60. {robotic-0.2.9.dev2.data → robotic-0.3.1.data}/scripts/ry-h5info +2 -2
  61. {robotic-0.2.9.dev2.data → robotic-0.3.1.data}/scripts/ry-test +2 -1
  62. robotic-0.3.1.data/scripts/ry-urdfConvert.py +74 -0
  63. {robotic-0.2.9.dev2.dist-info → robotic-0.3.1.dist-info}/METADATA +9 -15
  64. {robotic-0.2.9.dev2.dist-info → robotic-0.3.1.dist-info}/RECORD +70 -69
  65. robotic/rai-robotModels/g1/g1_29dof_conv.g +0 -77
  66. robotic/rai-robotModels/robotiq/robotiq_arg2f_85_model_conv.g +0 -21
  67. robotic/ry-urdf2rai +0 -222
  68. robotic/ry-urdf2yaml +0 -250
  69. robotic-0.2.9.dev2.data/scripts/ry-urdf2rai +0 -222
  70. robotic-0.2.9.dev2.data/scripts/ry-urdf2yaml +0 -250
  71. {robotic-0.2.9.dev2.data → robotic-0.3.1.data}/scripts/ry-bot +0 -0
  72. {robotic-0.2.9.dev2.data → robotic-0.3.1.data}/scripts/ry-info +0 -0
  73. {robotic-0.2.9.dev2.data → robotic-0.3.1.data}/scripts/ry-meshTool +0 -0
  74. {robotic-0.2.9.dev2.data → robotic-0.3.1.data}/scripts/ry-view +0 -0
  75. {robotic-0.2.9.dev2.dist-info → robotic-0.3.1.dist-info}/LICENSE +0 -0
  76. {robotic-0.2.9.dev2.dist-info → robotic-0.3.1.dist-info}/WHEEL +0 -0
  77. {robotic-0.2.9.dev2.dist-info → robotic-0.3.1.dist-info}/top_level.txt +0 -0
@@ -11,14 +11,13 @@
11
11
  #include "array.h"
12
12
 
13
13
  #include <algorithm>
14
+ #include <type_traits>
14
15
 
15
16
  #define ARRAY_flexiMem true
16
17
 
17
18
  namespace rai {
18
19
 
19
20
  //fwd declarations
20
- extern int64_t globalMemoryTotal, globalMemoryBound;
21
- extern bool globalMemoryStrict;
22
21
 
23
22
  extern uint lineCount;
24
23
  char skip(std::istream& is, const char* skipSymbols, const char* stopSymbols, bool skipCommentLines);
@@ -77,7 +76,9 @@ template<class T> Array<T>::Array(Array<T>&& a)
77
76
  isReference(a.isReference),
78
77
  M(a.M),
79
78
  special(a.special) {
80
- //if(a.jac) jac = std::move(a.jac);
79
+ if constexpr(std::is_same_v<T, double>){
80
+ if(a.jac) jac = std::move(a.jac);
81
+ }
81
82
  // CHECK_EQ(a.d, &a.d0, "NIY for larger tensors");
82
83
  if(a.d!=&a.d0) { d=a.d; a.d=&a.d0; }
83
84
  a.p=NULL;
@@ -101,6 +102,8 @@ template<class T> Array<T>::Array(std::initializer_list<T> values) : Array() { o
101
102
  /// initialization via {1., 2., 3., ...} lists, with certain dimensionality
102
103
  template<class T> Array<T>::Array(std::initializer_list<uint> dim, std::initializer_list<T> values) : Array() { operator=(values); reshape(dim); }
103
104
 
105
+ template<class T> Array<T>::Array(const T* p, uint size, bool byReference) : Array() { if(byReference) referTo(p, size); else setCarray(p, size); }
106
+
104
107
  template<class T> Array<T>::~Array() {
105
108
  #if 0
106
109
  clear();
@@ -249,11 +252,6 @@ template<class T> Array<T>& Array<T>::reshapeAs(const Array<T>& a) {
249
252
  return *this;
250
253
  }
251
254
 
252
- template<class T> Array<T>& Array<T>::reshapeFlat() {
253
- reshape(N);
254
- return *this;
255
- }
256
-
257
255
  /// return the k-th dimensionality
258
256
  template<class T> uint Array<T>::dim(uint k) const {
259
257
  CHECK(k<nd, "dimensionality range check error: " <<k <<"!<" <<nd);
@@ -643,10 +641,10 @@ template<class T> void Array<T>::delColumns(int i, uint k) {
643
641
  }
644
642
 
645
643
  /// inserts k columns at the i-th column [must be 2D]
646
- template<class T> void Array<T>::insColumns(int i, uint k) {
644
+ template<class T> Array<T>& Array<T>::insColumns(int i, uint k) {
647
645
  CHECK(memMove, "only with memMove");
648
646
  CHECK_EQ(nd, 2, "only for matricies");
649
- if(!k) return;
647
+ if(!k) return *this;
650
648
  if(i<0) i+=d1+1;
651
649
  CHECK_LE(i, (int)d1, "range check error");
652
650
  uint n=d1;
@@ -656,6 +654,7 @@ template<class T> void Array<T>::insColumns(int i, uint k) {
656
654
  memset(p+j*d1+i, 0, sizeT*k);
657
655
  if(i) memmove(p+j*d1, p+j*n, sizeT*i);
658
656
  }
657
+ return *this;
659
658
  }
660
659
 
661
660
  /// changes the range of one dimension (generalization of ins/delColumn to arbitrary tensors)
@@ -712,8 +711,15 @@ template<class T> T& Array<T>::elem(int i, int j) {
712
711
  if(j<0) j += d1;
713
712
  CHECK(nd==2 && (uint)i<d0 && (uint)j<d1,
714
713
  "2D range error (" <<nd <<"=2, " <<i <<"<" <<d0 <<", " <<j <<"<" <<d1 <<")");
714
+ if constexpr(std::is_same_v<T, double>){
715
+ if(isSparseMatrix(*this)) {
716
+ return sparse().addEntry(i, j);
717
+ }
718
+ if(isRowShifted(*this)) {
719
+ return rowShifted().elemNew(i, j);
720
+ }
721
+ }
715
722
  return p[i*d1+j];
716
-
717
723
  }
718
724
 
719
725
  /// multi-dimensional (tensor) access
@@ -769,7 +775,7 @@ template<class T> Array<T> Array<T>::ref() const {
769
775
 
770
776
  template<class T> Array<T> Array<T>::operator()(std::pair<int, int> I) const {
771
777
  Array<T> z;
772
- z.referToRange(*this, I.first, I.second);
778
+ z.referToRange(*this, I);
773
779
  // if(I.size()==2) z.referToRange(*this, I.begin()[0], I.begin()[1]);
774
780
  // else if(I.size()==0) z.referTo(*this);
775
781
  // else if(I.size()==1) z.referToDim(*this, I.begin()[0]);
@@ -779,9 +785,8 @@ template<class T> Array<T> Array<T>::operator()(std::pair<int, int> I) const {
779
785
 
780
786
  /// range reference access
781
787
  template<class T> Array<T> Array<T>::operator()(int i, std::pair<int, int> J) const {
782
- if(i<0) i += d0;
783
788
  Array<T> z;
784
- z.referToRange(*this, i, J.first, J.second);
789
+ z.referToRange(*this, i, J);
785
790
  // if(J.size()==2)
786
791
  // else if(J.size()==0) z.referToDim(*this, i);
787
792
  // else if(J.size()==1) z.referToDim(*this, i, J.begin()[0]);
@@ -791,10 +796,8 @@ template<class T> Array<T> Array<T>::operator()(int i, std::pair<int, int> J) co
791
796
 
792
797
  /// range reference access
793
798
  template<class T> Array<T> Array<T>::operator()(int i, int j, std::initializer_list<int> K) const {
794
- if(i<0) i += d0;
795
- if(j<0) j += d1;
796
799
  Array<T> z;
797
- if(K.size()==2) z.referToRange(*this, i, j, K.begin()[0], K.begin()[1]);
800
+ if(K.size()==2) z.referToRange(*this, i, j, {K.begin()[0], K.begin()[1]});
798
801
  else if(K.size()==0) z.referToDim(*this, i, j);
799
802
  else if(K.size()==1) z.referToDim(*this, i, j, K.begin()[0]);
800
803
  else HALT("range list needs 0,1, or 2 entries exactly");
@@ -829,8 +832,9 @@ template<class T> Array<T> Array<T>::copy() const { return Array<T>(*this); }
829
832
  /** @brief a sub array of a 1D Array (corresponds to matlab [i:I]); when
830
833
  the upper limit I is -1, it is replaced by the max limit (like
831
834
  [i:]) */
832
- template<class T> Array<T> Array<T>::sub(int i, int I) const {
835
+ template<class T> Array<T> Array<T>::sub(std::pair<int, int> _I) const {
833
836
  CHECK_EQ(nd, 1, "1D range error ");
837
+ int i=_I.first, I=_I.second-1;
834
838
  Array<T> x;
835
839
  if(i<0) i+=d0;
836
840
  if(I<0) I+=d0;
@@ -847,8 +851,9 @@ template<class T> Array<T> Array<T>::sub(int i, int I) const {
847
851
  /** @brief copies a sub array of a 2D Array (corresponds to matlab [i:I, j:J]);
848
852
  when the upper limits I or J are -1, they are replaced by the
849
853
  max limit (like [i:, j:]) */
850
- template<class T> Array<T> Array<T>::sub(int i, int I, int j, int J) const {
854
+ template<class T> Array<T> Array<T>::sub(std::pair<int, int> _I, std::pair<int, int> _J) const {
851
855
  CHECK_EQ(nd, 2, "2D range error ");
856
+ int i=_I.first, I=_I.second-1, j=_J.first, J=_J.second-1;
852
857
  Array<T> x;
853
858
  if(i<0) i+=d0;
854
859
  if(j<0) j+=d1;
@@ -867,8 +872,9 @@ template<class T> Array<T> Array<T>::sub(int i, int I, int j, int J) const {
867
872
  /** @brief copies a sub array of a 3D Array (corresponds to matlab [i:I, j:J]);
868
873
  when the upper limits I or J are -1, they are replaced by the
869
874
  max limit (like [i:, j:]) */
870
- template<class T> Array<T> Array<T>::sub(int i, int I, int j, int J, int k, int K) const {
875
+ template<class T> Array<T> Array<T>::sub(std::pair<int, int> _I, std::pair<int, int> _J, std::pair<int, int> _K) const {
871
876
  CHECK_EQ(nd, 3, "3D range error ");
877
+ int i=_I.first, I=_I.second-1, j=_J.first, J=_J.second-1, k=_K.first, K=_K.second-1;
872
878
  Array<T> x;
873
879
  if(i<0) i+=d0;
874
880
  if(j<0) j+=d1;
@@ -893,8 +899,9 @@ template<class T> Array<T> Array<T>::sub(int i, int I, int j, int J, int k, int
893
899
  runs from i to I (as explained above) while the second index runs
894
900
  over the columns explicitly referred to by cols. (col doesn't have
895
901
  to be ordered or could also contain some columns multiply) */
896
- template<class T> Array<T> Array<T>::sub(int i, int I, Array<uint> cols) const {
902
+ template<class T> Array<T> Array<T>::pick(std::pair<int, int> _I, Array<uint> cols) const {
897
903
  CHECK_EQ(nd, 2, "2D range error ");
904
+ int i=_I.first, I=_I.second-1;
898
905
  Array<T> x;
899
906
  if(i<0) i+=d0;
900
907
  if(I<0) I+=d0;
@@ -904,7 +911,7 @@ template<class T> Array<T> Array<T>::sub(int i, int I, Array<uint> cols) const {
904
911
  return x;
905
912
  }
906
913
 
907
- template<class T> Array<T> Array<T>::sub(Array<uint> elems) const {
914
+ template<class T> Array<T> Array<T>::pick(Array<uint> elems) const {
908
915
  Array<T> x;
909
916
  if(nd==1) {
910
917
  x.resize(elems.N);
@@ -932,7 +939,7 @@ template<class T> Array<T> Array<T>::sub(Array<uint> elems) const {
932
939
  */
933
940
  template<class T>
934
941
  Array<T> Array<T>::row(uint row_index) const {
935
- return sub(row_index, row_index, 0, d1 - 1);
942
+ return sub({row_index, row_index+1},{ 0, d1 - 1+1});
936
943
  }
937
944
 
938
945
  /**
@@ -947,7 +954,7 @@ Array<T> Array<T>::row(uint row_index) const {
947
954
  */
948
955
  template<class T>
949
956
  Array<T> Array<T>::col(uint col_index) const {
950
- return sub(0, d0 - 1, col_index, col_index).reshape(d0);
957
+ return sub({0, d0 - 1+1},{ col_index, col_index+1}).reshape(d0);
951
958
  }
952
959
 
953
960
  /**
@@ -963,7 +970,7 @@ Array<T> Array<T>::col(uint col_index) const {
963
970
  */
964
971
  template<class T>
965
972
  Array<T> Array<T>::rows(uint start_row, uint end_row) const {
966
- return sub(start_row, end_row - 1, 0, d1 - 1);
973
+ return sub({start_row, end_row - 1+1},{ 0, d1 - 1+1});
967
974
  }
968
975
 
969
976
  /**
@@ -979,7 +986,7 @@ Array<T> Array<T>::rows(uint start_row, uint end_row) const {
979
986
  */
980
987
  template<class T>
981
988
  Array<T> Array<T>::cols(uint start_col, uint end_col) const {
982
- return sub(0, d0 - 1, start_col, end_col - 1);
989
+ return sub({0, d0 - 1+1},{ start_col, end_col - 1+1});
983
990
  }
984
991
 
985
992
  /// makes this array a reference to the C buffer
@@ -1015,6 +1022,10 @@ template<class T> Array<T>& Array<T>::operator=(const Array<T>& a) {
1015
1022
  if(memMove) memmove(p, a.p, sizeT*N);
1016
1023
  else for(uint i=0; i<N; i++) p[i]=a.p[i];
1017
1024
  if(special) { delete special; special=NULL; }
1025
+ if constexpr(std::is_same_v<T, double>){
1026
+ if(isSpecial(a)) special_copy(*this, a);
1027
+ if(a.jac) jac = std::make_unique<arr>(*a.jac);
1028
+ }
1018
1029
  return *this;
1019
1030
  }
1020
1031
 
@@ -1049,7 +1060,7 @@ template<class T> Array<T> catCol(const Array<Array<T>*>& X) {
1049
1060
  // d1+=x->d1;
1050
1061
  // }
1051
1062
  } else {
1052
- z.resize(d0, d1);
1063
+ z.resize(d0, d1).setZero();
1053
1064
  d1=0;
1054
1065
  for(const Array<T>* x: X) { z.setMatrixBlock(*x, 0, d1); d1+=x->nd==2?x->d1:1; }
1055
1066
  }
@@ -1070,7 +1081,7 @@ template<class T> Array<T> catCol(const Array<Array<T>>& X) {
1070
1081
  }
1071
1082
 
1072
1083
  /// set all entries to same value x [default: don't change dimension]
1073
- template<class T> void Array<T>::setUni(const T& x, int d) {
1084
+ template<class T> void Array<T>::setConst(const T& x, int d) {
1074
1085
  if(d!=-1) resize(d);
1075
1086
  uint i;
1076
1087
  for(i=0; i<N; i++) elem(i)=x;
@@ -1082,7 +1093,9 @@ template<class T> void Array<T>::setId(int d) {
1082
1093
  CHECK(d!=-1 || (nd==2 && d0==d1), "need squared matrix to set to identity");
1083
1094
  if(d!=-1) resize(d, d);
1084
1095
  setZero();
1085
- for(uint i=0; i<d0; i++) operator()(i, i)=(T)1;
1096
+ if constexpr(std::is_scalar_v<T>){
1097
+ for(uint i=0; i<d0; i++) operator()(i, i)=(T)1;
1098
+ }else NIY;
1086
1099
  }
1087
1100
 
1088
1101
  template<class T> void Array<T>::setDiag(const T& x, int d) {
@@ -1119,13 +1132,38 @@ template<class T> void Array<T>::setBlockMatrix(const Array<T>& A, const Array<T
1119
1132
  template<class T> void Array<T>::setBlockMatrix(const Array<T>& A, const Array<T>& B) {
1120
1133
  CHECK(A.nd==2 && B.nd==2, "");
1121
1134
  CHECK(A.d1==B.d1, "");
1122
- resize(A.d0+B.d0, A.d1);
1135
+
1136
+ if constexpr(std::is_same_v<T, double>){
1137
+ if(isSparse(A)){
1138
+ CHECK(isSparse(B), "");
1139
+ sparse().resize(A.d0+B.d0, A.d1, 0);
1140
+ }else{
1141
+ resize(A.d0+B.d0, A.d1).setZero();
1142
+ }
1143
+ }else{
1144
+ resize(A.d0+B.d0, A.d1).setZero();
1145
+ }
1146
+
1123
1147
  setMatrixBlock(A, 0, 0);
1124
1148
  setMatrixBlock(B, A.d0, 0);
1125
1149
  }
1126
1150
 
1127
1151
  /// constructs a vector x=[a, b]
1128
1152
  template<class T> void Array<T>::setBlockVector(const Array<T>& a, const Array<T>& b) {
1153
+
1154
+ if constexpr(std::is_same_v<T, double>){
1155
+ if(a.jac || b.jac) {
1156
+ const Array<T>& A=*a.jac;
1157
+ const Array<T>& B=*b.jac;
1158
+ if(isSparse(A)){
1159
+ CHECK(isSparse(B), "");
1160
+ J().sparse().resize(A.d0+B.d0, A.d1, 0);
1161
+ }else{
1162
+ CHECK(!isSparse(B), "");
1163
+ J().resize(A.d0+B.d0, A.d1).setZero();
1164
+ }
1165
+ }
1166
+ }
1129
1167
  CHECK(a.nd==1 && b.nd==1, "");
1130
1168
  resize(a.N+b.N);
1131
1169
  setVectorBlock(a, 0); //for(i=0;i<a.N;i++) operator()(i )=a(i);
@@ -1134,6 +1172,13 @@ template<class T> void Array<T>::setBlockVector(const Array<T>& a, const Array<T
1134
1172
 
1135
1173
  /// write the matrix B into 'this' matrix at location lo0, lo1
1136
1174
  template<class T> void Array<T>::setMatrixBlock(const Array<T>& B, uint lo0, uint lo1) {
1175
+ if constexpr(std::is_same_v<T, double>){
1176
+ if(isSparse(*this)){
1177
+ sparse().add(B, lo0, lo1);
1178
+ return;
1179
+ }
1180
+ }
1181
+
1137
1182
  CHECK(!special && !B.special, "");
1138
1183
  CHECK(B.nd==1 || B.nd==2, "");
1139
1184
  if(B.nd==2) {
@@ -1157,18 +1202,29 @@ template<class T> void Array<T>::setVectorBlock(const Array<T>& B, uint lo) {
1157
1202
  CHECK(nd==1 && B.nd==1 && lo+B.N<=N, "");
1158
1203
  uint i;
1159
1204
  for(i=0; i<B.N; i++) elem(lo+i)=B.elem(i);
1205
+ if constexpr(std::is_same_v<T, double>){
1206
+ if(B.jac) {
1207
+ CHECK(jac && jac->d1==B.jac->d1, "Jacobian needs to be pre-sized");
1208
+ CHECK(!B.jac->jac, "NOT HANDLED YET");
1209
+ jac->setMatrixBlock(*B.jac, lo, 0);
1210
+ }
1211
+ }
1160
1212
  }
1161
1213
 
1162
1214
  /// sorted permutation of length \c n
1163
1215
  template<class T> void Array<T>::setStraightPerm(int n) {
1164
1216
  if(n!=-1) resize(n);
1165
- for(uint i=0; i<N; i++) elem(i)=(T)i;
1217
+ if constexpr(std::is_arithmetic_v<T>){
1218
+ for(uint i=0; i<N; i++) elem(i)=static_cast<T>(i);
1219
+ } else NIY;
1166
1220
  }
1167
1221
 
1168
1222
  /// reverse sorted permutation of lenth \c N
1169
1223
  template<class T> void Array<T>::setReversePerm(int n) {
1170
1224
  if(n!=-1) resize(n);
1171
- for(uint i=0; i<N; i++) elem(N-1-i)=(T)i;
1225
+ if constexpr(std::is_arithmetic_v<T>){
1226
+ for(uint i=0; i<N; i++) elem(N-1-i)=static_cast<T>(i);
1227
+ } else NIY;
1172
1228
  }
1173
1229
 
1174
1230
  /// permute all elements randomly
@@ -1211,8 +1267,9 @@ template<class T> void Array<T>::referTo(const Array<T>& a) {
1211
1267
  }
1212
1268
 
1213
1269
  /// make this array a subarray reference to \c a
1214
- template<class T> void Array<T>::referToRange(const Array<T>& a, int i_lo, int i_up) {
1270
+ template<class T> void Array<T>::referToRange(const Array<T>& a, std::pair<int, int> I) {
1215
1271
  CHECK_LE(a.nd, 3, "not implemented yet");
1272
+ int i_lo=I.first, i_up=I.second-1;
1216
1273
  if(i_lo<0) i_lo+=a.d0;
1217
1274
  if(i_up<0) i_up+=a.d0;
1218
1275
  if(i_lo>i_up) { clear(); return; }
@@ -1230,9 +1287,10 @@ template<class T> void Array<T>::referToRange(const Array<T>& a, int i_lo, int i
1230
1287
  }
1231
1288
 
1232
1289
  /// make this array a subarray reference to \c a
1233
- template<class T> void Array<T>::referToRange(const Array<T>& a, int i, int j_lo, int j_up) {
1290
+ template<class T> void Array<T>::referToRange(const Array<T>& a, int i, std::pair<int, int> J) {
1234
1291
  CHECK(a.nd>1, "does not make sense");
1235
1292
  CHECK_LE(a.nd, 3, "not implemented yet");
1293
+ int j_lo=J.first, j_up=J.second-1;
1236
1294
  if(i<0) i+=a.d0;
1237
1295
  if(j_lo<0) j_lo+=a.d1;
1238
1296
  if(j_up<0) j_up+=a.d1;
@@ -1249,9 +1307,10 @@ template<class T> void Array<T>::referToRange(const Array<T>& a, int i, int j_lo
1249
1307
  }
1250
1308
 
1251
1309
  /// make this array a subarray reference to \c a
1252
- template<class T> void Array<T>::referToRange(const Array<T>& a, int i, int j, int k_lo, int k_up) {
1310
+ template<class T> void Array<T>::referToRange(const Array<T>& a, int i, int j, std::pair<int, int> K) {
1253
1311
  CHECK(a.nd>2, "does not make sense");
1254
1312
  CHECK_LE(a.nd, 3, "not implemented yet");
1313
+ int k_lo=K.first, k_up=K.second-1;
1255
1314
  if(i<0) i+=a.d0;
1256
1315
  if(j<0) j+=a.d1;
1257
1316
  if(k_lo<0) k_lo+=a.d2;
@@ -1338,47 +1397,6 @@ template<class T> void Array<T>::takeOver(Array<T>& a) {
1338
1397
  #endif
1339
1398
  }
1340
1399
 
1341
- /** @brief return a `dim'-dimensional grid with `steps' intervals
1342
- filling the range [lo, hi] in each dimension. Note: returned array is
1343
- `flat', rather than grid-shaped. */
1344
- template<class T> Array<T>& Array<T>::setGrid(uint dim, T lo, T hi, uint steps) {
1345
- CHECK(steps, "steps needs to be >0");
1346
- uint i, j, k;
1347
- if(dim==1) {
1348
- resize(steps+1, 1);
1349
- for(i=0; i<d0; i++) elem(i)=lo+(hi-lo)*i/steps;
1350
- return *this;
1351
- }
1352
- if(dim==2) {
1353
- resize(steps+1, steps+1, 2);
1354
- for(i=0; i<d0; i++) for(j=0; j<d1; j++) {
1355
- operator()(i, j, 0)=lo+(hi-lo)*i/steps;
1356
- operator()(i, j, 1)=lo+(hi-lo)*j/steps;
1357
- }
1358
- reshape(d0*d1, 2);
1359
- return *this;
1360
- }
1361
- if(dim==3) {
1362
- resize(uintA{steps+1, steps+1, steps+1, 3});
1363
- T dx = (hi-lo)/steps;
1364
- for(i=0; i<d0; i++) for(j=0; j<d1; j++) {
1365
- T* p = &elem(uintA{i, j, 0, 0});
1366
- for(k=0; k<d2; k++) {
1367
- *(p++) = lo+dx*i;
1368
- *(p++) = lo+dx*j;
1369
- *(p++) = lo+dx*k;
1370
- // elem(uintA{i, j, k, 0}) = lo+dx*i;
1371
- // elem(uintA{i, j, k, 1}) = lo+dx*j;
1372
- // elem(uintA{i, j, k, 2}) = lo+dx*k;
1373
- }
1374
- }
1375
- reshape(d0*d1*d2, 3);
1376
- return *this;
1377
- }
1378
- NIY;
1379
- return *this;
1380
- }
1381
-
1382
1400
  template<class T> T rai::Array<T>::median_nonConst() {
1383
1401
  CHECK_GE(N, 1, "");
1384
1402
  std::nth_element(p, p+N/2, p+N);
@@ -1500,7 +1518,7 @@ template<class T> void Array<T>::permuteInv(const Array<uint>& permutation) {
1500
1518
  template<class T> void Array<T>::permuteRowsInv(const Array<uint>& permutation) {
1501
1519
  CHECK_LE(permutation.N, d0, "array smaller than permutation ("<<N<<"<"<<permutation.N<<")");
1502
1520
  Array<T> b=(*this);
1503
- for(uint i=0; i<d0; i++) operator[](permutation(i))()=b[i];
1521
+ for(uint i=0; i<d0; i++) operator[](permutation(i))=b[i];
1504
1522
  }
1505
1523
 
1506
1524
  /// randomly permute all entries of 'this'
@@ -1533,9 +1551,28 @@ template<class T> void Array<T>::shift(int offset, bool wrapAround) {
1533
1551
 
1534
1552
  //==================================================================================
1535
1553
 
1554
+ /// return fraction of non-zeros in the array
1555
+ template<class T> double Array<T>::sparsity() {
1556
+ uint i, m=0;
1557
+ for(i=0; i<N; i++) if(elem(i)) m++;
1558
+ return ((double)m)/N;
1559
+ }
1560
+
1561
+ //==================================================================================
1562
+
1536
1563
  /** @brief prototype for operator<<, writes the array by separating elements with ELEMSEP, separating rows with LINESEP, using BRACKETS[0] and BRACKETS[1] to brace the data, optionally writs a dimensionality tag before the data (see below), and optinally in binary format */
1537
1564
  template<class T> void Array<T>::write(std::ostream& os, const char* ELEMSEP, const char* LINESEP, const char* BRACKETS, bool dimTag, bool binary) const {
1538
- CHECK(!special, "");
1565
+
1566
+ if constexpr(std::is_same_v<T, double>){
1567
+ if(special){
1568
+ special_write(os, *this);
1569
+ if(jac) os <<" -- JACOBIAN:\n" <<*jac <<endl;
1570
+ return;
1571
+ }
1572
+ }else{
1573
+ CHECK(!special, "");
1574
+ }
1575
+
1539
1576
  CHECK(!binary || memMove, "binary write works only for memMoveable data");
1540
1577
  uint i, j, k;
1541
1578
  if(!ELEMSEP) ELEMSEP=arrayElemsep;
@@ -1583,6 +1620,10 @@ template<class T> void Array<T>::write(std::ostream& os, const char* ELEMSEP, co
1583
1620
  }
1584
1621
  if(BRACKETS[1]) os <<BRACKETS[1];
1585
1622
  }
1623
+
1624
+ if constexpr(std::is_same_v<T, double>){
1625
+ if(jac) os <<" -- JACOBIAN:\n" <<*jac <<endl;
1626
+ }
1586
1627
  }
1587
1628
 
1588
1629
  /** @brief prototype for operator>>, if there is a dimensionality tag: fast reading of ascii (if there is brackets[]) or binary (if there is \\0\\0 brackets) data; otherwise slow ascii read */
@@ -1609,7 +1650,9 @@ template<class T> Array<T>& Array<T>::read(std::istream& is) {
1609
1650
  } else { //fast ascii read
1610
1651
  for(uint i=0; i<N; i++) {
1611
1652
  if(is.fail()) PARSERR("could not read " <<i <<"-th element of an array");
1612
- is >>p[i];
1653
+ if constexpr(!std::is_pointer_v<T>){
1654
+ is >>p[i];
1655
+ } else NIY;
1613
1656
  }
1614
1657
  }
1615
1658
  if(expectBracket) {
@@ -1634,7 +1677,9 @@ template<class T> Array<T>& Array<T>::read(std::istream& is) {
1634
1677
  continue;
1635
1678
  }
1636
1679
  if(c!=',') is.putback(c);
1637
- is >>x;
1680
+ if constexpr(!std::is_pointer_v<T>){
1681
+ is >>x;
1682
+ }else NIY;
1638
1683
  if(!is.good()) {
1639
1684
  if(!expectBracket) is.clear(); //ok
1640
1685
  else PARSERR("failed reading ending bracket ]");
@@ -1827,6 +1872,7 @@ template<class T> void writeConsecutiveConstant(std::ostream& os, const Array<T>
1827
1872
 
1828
1873
  /// contatenation of two arrays
1829
1874
  template<class T> Array<T> operator, (const Array<T>& y, const Array<T>& z) { Array<T> x(y); x.append(z); return x; }
1875
+
1830
1876
  /// calls Array<T>::read
1831
1877
  template<class T> std::istream& operator>>(std::istream& is, Array<T>& x) { x.read(is); return is; }
1832
1878
 
@@ -1871,4 +1917,122 @@ template<class T> bool operator<(const Array<T>& v, const Array<T>& w) {
1871
1917
  return v.N<w.N;
1872
1918
  }
1873
1919
 
1920
+ //core for matrix-matrix (elem-wise) update
1921
+ #define UpdateOperator_MM( op ) \
1922
+ if constexpr(std::is_same_v<T, double>){ \
1923
+ if(isNoArr(x)){ return; } \
1924
+ if(isSparseMatrix(x) && isSparseMatrix(y)){ x.sparse() op y.sparse(); return; } \
1925
+ if(isRowShifted(x) && isRowShifted(y)){ x.rowShifted() op y.rowShifted(); return; } \
1926
+ } \
1927
+ CHECK(!x.special, ""); \
1928
+ CHECK(!y.special, ""); \
1929
+ CHECK_EQ(x.N, y.N, "update operator on different array dimensions (" <<x.N <<", " <<y.N <<")"); \
1930
+ T *xp=x.p, *xstop=xp+x.N; \
1931
+ const T *yp=y.p; \
1932
+ for(; xp!=xstop; xp++, yp++) *xp op *yp;
1933
+
1934
+ //core for matrix-scalar update
1935
+ #define UpdateOperator_MS( op ) \
1936
+ if constexpr(std::is_same_v<T, double>){ \
1937
+ if(isNoArr(x)){ return; } \
1938
+ if(isSparseMatrix(x)){ x.sparse() op y; return; } \
1939
+ if(isRowShifted(x)){ x.rowShifted() op y; return; } \
1940
+ } \
1941
+ CHECK(!x.special, ""); \
1942
+ T *xp=x.p, *xstop=xp+x.N; \
1943
+ for(; xp!=xstop; xp++) *xp op y;
1944
+
1945
+
1946
+ template<class T> void operator+=(Array<T>& x, const Array<T>& y) {
1947
+ UpdateOperator_MM(+=);
1948
+ if constexpr(std::is_same_v<T, double>){
1949
+ if(y.jac) {
1950
+ if(x.jac) *x.jac += *y.jac;
1951
+ else x.J() = *y.jac;
1952
+ }
1953
+ }
1954
+ // CHECK_EQ(x.N, y.N, "update operator on different array dimensions (" <<x.N <<", " <<y.N <<")");
1955
+ // T* xp=x.p, *xstop=xp+x.N;
1956
+ // const T* yp=y.p;
1957
+ // for(; xp!=xstop; xp++, yp++) *xp += *yp;
1958
+ }
1959
+ template<class T> void operator+=(Array<T>& x, const T& y) {
1960
+ UpdateOperator_MS(+=);
1961
+ // T* xp=x.p, *xstop=xp+x.N;
1962
+ // for(; xp!=xstop; xp++) *xp += y;
1963
+ }
1964
+ template<class T> void operator-=(Array<T>& x, const Array<T>& y) {
1965
+ UpdateOperator_MM(-=);
1966
+ if constexpr(std::is_same_v<T, double>){
1967
+ if(y.jac) {
1968
+ if(x.jac) *x.jac -= *y.jac;
1969
+ else x.J() = -(*y.jac);
1970
+ }
1971
+ }
1972
+ // CHECK_EQ(x.N, y.N, "update operator on different array dimensions (" <<x.N <<", " <<y.N <<")");
1973
+ // T* xp=x.p, *xstop=xp+x.N;
1974
+ // const T* yp=y.p;
1975
+ // for(; xp!=xstop; xp++, yp++) *xp -= *yp;
1976
+ }
1977
+ template<class T> void operator-=(Array<T>& x, const T& y) {
1978
+ UpdateOperator_MS(-=);
1979
+ // T* xp=x.p, *xstop=xp+x.N;
1980
+ // for(; xp!=xstop; xp++) *xp -= y;
1981
+ }
1982
+ template<class T> void operator*=(Array<T>& x, const T& y) {
1983
+ if constexpr(std::is_same_v<T, double>){
1984
+ if(x.jac) *x.jac *= y;
1985
+ }
1986
+ UpdateOperator_MS(*=);
1987
+ // T* xp=x.p, *xstop=xp+x.N;
1988
+ // for(; xp!=xstop; xp++) *xp *= y;
1989
+ }
1990
+
1991
+ #undef UpdateOperator_MM
1992
+ #undef UpdateOperator_MS
1993
+
1994
+ //===========================================================================
1995
+
1996
+ /** @brief return a `dim'-dimensional grid with `steps' intervals
1997
+ filling the range [lo, hi] in each dimension. Note: returned array is
1998
+ `flat', rather than grid-shaped. */
1999
+ template<class T> Array<T> grid(uint dim, T lo, T hi, uint steps) {
2000
+ Array<T> x;
2001
+ CHECK(steps, "steps needs to be >0");
2002
+ uint i, j, k;
2003
+ if(dim==1) {
2004
+ x.resize(steps+1, 1);
2005
+ for(i=0; i<x.d0; i++) x.elem(i)=lo+(hi-lo)*i/steps;
2006
+ return x;
2007
+ }
2008
+ if(dim==2) {
2009
+ x.resize(steps+1, steps+1, 2);
2010
+ for(i=0; i<x.d0; i++) for(j=0; j<x.d1; j++) {
2011
+ x(i, j, 0)=lo+(hi-lo)*i/steps;
2012
+ x(i, j, 1)=lo+(hi-lo)*j/steps;
2013
+ }
2014
+ x.reshape(x.d0*x.d1, 2);
2015
+ return x;
2016
+ }
2017
+ if(dim==3) {
2018
+ x.resize(uintA{steps+1, steps+1, steps+1, 3});
2019
+ T dx = (hi-lo)/steps;
2020
+ for(i=0; i<x.d0; i++) for(j=0; j<x.d1; j++) {
2021
+ T* p = &x.elem(uintA{i, j, 0, 0});
2022
+ for(k=0; k<x.d2; k++) {
2023
+ *(p++) = lo+dx*i;
2024
+ *(p++) = lo+dx*j;
2025
+ *(p++) = lo+dx*k;
2026
+ // elem(uintA{i, j, k, 0}) = lo+dx*i;
2027
+ // elem(uintA{i, j, k, 1}) = lo+dx*j;
2028
+ // elem(uintA{i, j, k, 2}) = lo+dx*k;
2029
+ }
2030
+ }
2031
+ x.reshape(x.d0*x.d1*x.d2, 3);
2032
+ return x;
2033
+ }
2034
+ NIY;
2035
+ return x;
2036
+ }
2037
+
1874
2038
  } //namespace