TBTK
Need a break? Support the development by playing Polarity Puzzles
AbstractProperty.h
1 /* Copyright 2017 Kristofer Bj√∂rnson
2  *
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
23 #ifndef COM_DAFER45_TBTK_ABSTRACT_PROPERTY
24 #define COM_DAFER45_TBTK_ABSTRACT_PROPERTY
25 
26 #include "TBTK/Model.h"
27 #include "TBTK/Property/Property.h"
29 #include "TBTK/SparseMatrix.h"
30 #include "TBTK/SpinMatrix.h"
31 #include "TBTK/TBTKMacros.h"
32 
33 #include "TBTK/json.hpp"
34 
35 namespace TBTK{
36 namespace Property{
37 
100 template<typename DataType>
101 class AbstractProperty : public Property, public Serializable, public Streamable{
102 public:
106  unsigned int getBlockSize() const;
107 
112  unsigned int getSize() const;
113 
118  const std::vector<DataType>& getData() const;
119 
125  std::vector<DataType>& getDataRW();
126 
131  unsigned int getDimensions() const;
132 
138  std::vector<int> getRanges() const;
139 
146  int getOffset(const Index &index) const;
147 
152  const IndexDescriptor& getIndexDescriptor() const;
153 
160  bool contains(const Index &index) const;
161 
190  void reduce(
191  const std::vector<Index> &targetPatterns,
192  const std::vector<Index> &newPatterns
193  );
194 
198  void hermitianConjugate();
199 
211  std::vector<SparseMatrix<DataType>> toSparseMatrices(
212  const Model &model
213  ) const;
214 
231  virtual const DataType& operator()(
232  const Index &index,
233  unsigned int offset = 0
234  ) const;
235 
253  virtual DataType& operator()(
254  const Index &index,
255  unsigned int offset = 0
256  );
257 
267  DataType& operator()(const std::initializer_list<Subindex> &index);
268 
278  const DataType& operator()(
279  const std::initializer_list<Subindex> &index
280  ) const;
281 
291 // DataType& operator()(const std::initializer_list<unsigned int> &index);
292 
302 /* const DataType& operator()(
303  const std::initializer_list<unsigned int> &index
304  ) const;*/
305 
313  virtual const DataType& operator()(unsigned int offset) const;
314 
322  virtual DataType& operator()(unsigned int offset);
323 
333  void setAllowIndexOutOfBoundsAccess(bool allowIndexOutOfBoundsAccess);
334 
343  void setDefaultValue(const DataType &defaultValue);
344 
351  void replaceValues(
352  const DataType &targetValue,
353  const DataType &replacementValue
354  );
355 
357  virtual std::string toString() const;
358 
360  virtual std::string serialize(Mode mode) const;
361 protected:
364 
369  AbstractProperty(unsigned int blockSize);
370 
379  unsigned int blockSize,
380  const DataType *data
381  );
382 
391  const std::vector<int> &ranges,
392  unsigned int blockSize
393  );
394 
406  const std::vector<int> &ranges,
407  unsigned int blockSize,
408  const DataType *data
409  );
410 
418  const IndexTree &indexTree,
419  unsigned int blockSize
420  );
421 
431  const IndexTree &indexTree,
432  unsigned int blockSize,
433  const DataType *data
434  );
435 
439  AbstractProperty(const AbstractProperty &abstractProperty);
440 
444  AbstractProperty(AbstractProperty &&abstractProperty);
445 
454  const std::string &serialization,
455  Mode mode
456  );
457 
459  virtual ~AbstractProperty();
460 
466  AbstractProperty& operator=(const AbstractProperty &abstractProperty);
467 
473  AbstractProperty& operator=(AbstractProperty &&abstractProperty);
474 
486 
499 
510  AbstractProperty& operator*=(const DataType &rhs);
511 
522  AbstractProperty& operator/=(const DataType &rhs);
523 private:
525  IndexDescriptor indexDescriptor;
526 
530  unsigned int blockSize;
531 
533  std::vector<DataType> data;
534 
536  bool allowIndexOutOfBoundsAccess;
537 
539  DataType defaultValue;
540 
551  virtual void calculateDynamically(const Index &index, DataType *block);
552 };
553 
554 template<typename DataType>
555 inline unsigned int AbstractProperty<DataType>::getBlockSize() const{
556  return blockSize;
557 }
558 
559 template<typename DataType>
560 inline unsigned int AbstractProperty<DataType>::getSize() const{
561  return data.size();
562 }
563 
564 template<typename DataType>
565 inline const std::vector<
566  DataType
568  return data;
569 }
570 
571 template<typename DataType>
572 inline std::vector<DataType>& AbstractProperty<DataType>::getDataRW(){
573  return data;
574 }
575 
576 template<typename DataType>
577 inline unsigned int AbstractProperty<DataType>::getDimensions() const{
578  return indexDescriptor.getRanges().size();
579 }
580 
581 template<typename DataType>
582 inline std::vector<int> AbstractProperty<DataType>::getRanges() const{
583  return indexDescriptor.getRanges();
584 }
585 
586 template<typename DataType>
588  const Index &index
589 ) const{
590  return blockSize*indexDescriptor.getLinearIndex(
591  index,
592  allowIndexOutOfBoundsAccess
593  );
594 }
595 
596 template<typename DataType>
598 ) const{
599  return indexDescriptor;
600 }
601 
602 template<typename DataType>
604  const Index &index
605 ) const{
606  return indexDescriptor.contains(index);
607 }
608 
609 template<typename DataType>
611  const std::vector<Index> &targetPatterns,
612  const std::vector<Index> &newPatterns
613 ){
614  TBTKAssert(
615  targetPatterns.size() == newPatterns.size(),
616  "AbstractProperty::reduce()",
617  "The size of targetPatterns '" << targetPatterns.size() << "'"
618  << " must be the same as the size of newPatterns '"
619  << newPatterns.size() << "'.",
620  ""
621  );
622 
623  IndexTree newIndexTree;
624  const IndexTree &oldIndexTree = indexDescriptor.getIndexTree();
625  IndexedDataTree<Index> indexMap;
626  IndexedDataTree<Index> reverseIndexMap;
627  for(
628  IndexTree::ConstIterator iterator = oldIndexTree.cbegin();
629  iterator != oldIndexTree.cend();
630  ++iterator
631  ){
632 
633  int matchingPattern = -1;
634  for(unsigned int n = 0; n < targetPatterns.size(); n++){
635  if(targetPatterns[n].equals(*iterator, true)){
636  matchingPattern = n;
637  break;
638  }
639  }
640  if(matchingPattern == -1)
641  continue;
642 
643  Index newIndex = newPatterns[matchingPattern];
644  for(unsigned int n = 0; n < newIndex.getSize(); n++){
645  if(newIndex[n].isLabeledWildcard()){
646  for(
647  unsigned int c = 0;
648  c < targetPatterns[
649  matchingPattern
650  ].getSize();
651  c++
652  ){
653  if(
654  targetPatterns[
655  matchingPattern
656  ][c] == newIndex[n]
657  ){
658  newIndex[n] = (*iterator)[c];
659  break;
660  }
661  }
662  }
663  }
664  TBTKAssert(
665  !newIndexTree.contains(newIndex),
666  "AbstractProperty::reduce()",
667  "Conflicting index reductions. The indices '"
668  << (*iterator).toString() << "' and '"
669  << reverseIndexMap.get(newIndex).toString() << "' both"
670  << " reduce to '" << newIndex.toString() << "'.",
671  ""
672  );
673  indexMap.add(newIndex, (*iterator));
674  reverseIndexMap.add((*iterator), newIndex);
675  newIndexTree.add(newIndex);
676  }
677  newIndexTree.generateLinearMap();
678 
679  IndexDescriptor newIndexDescriptor(newIndexTree);
680  std::vector<DataType> newData;
681  for(unsigned int n = 0; n < indexDescriptor.getSize()*blockSize; n++)
682  newData.push_back(0.);
683 
684  for(
686  = indexMap.cbegin();
687  iterator != indexMap.cend();
688  ++iterator
689  ){
690  const Index &oldIndex = iterator.getCurrentIndex();
691  const Index &newIndex = *iterator;
692  for(unsigned int n = 0; n < blockSize; n++){
693  newData[
694  blockSize*newIndexDescriptor.getLinearIndex(
695  newIndex
696  ) + n
697  ] = data[
698  blockSize*indexDescriptor.getLinearIndex(
699  oldIndex
700  ) + n
701  ];
702  }
703  }
704 
705  indexDescriptor = newIndexDescriptor;
706  data = newData;
707 }
708 
709 template<typename DataType>
711  IndexTree newIndexTree;
712  const IndexTree &oldIndexTree = indexDescriptor.getIndexTree();
713  IndexedDataTree<Index> indexMap;
714  IndexedDataTree<Index> transposedIndexMap;
715  for(
716  IndexTree::ConstIterator iterator = oldIndexTree.cbegin();
717  iterator != oldIndexTree.cend();
718  ++iterator
719  ){
720  std::vector<Index> components = (*iterator).split();
721  TBTKAssert(
722  components.size() == 2,
723  "AbstractProperty<DataType>::hermitianConjugate()",
724  "Invalid Index structure. Unable to performorm the"
725  << " Hermitian conjugation because the Index '"
726  << (*iterator).toString() << "' is not a compound"
727  << " Index with two component Indices.",
728  ""
729  );
730  newIndexTree.add({components[1], components[0]});
731  }
732  newIndexTree.generateLinearMap();
733 
734  IndexDescriptor newIndexDescriptor(newIndexTree);
735  std::vector<DataType> newData;
736  for(unsigned int n = 0; n < indexDescriptor.getSize()*blockSize; n++)
737  newData.push_back(0.);
738 
739  for(
740  IndexTree::ConstIterator iterator = oldIndexTree.cbegin();
741  iterator != oldIndexTree.cend();
742  ++iterator
743  ){
744  for(unsigned int n = 0; n < blockSize; n++){
745  std::vector<Index> components = (*iterator).split();
746  newData[
747  blockSize*newIndexDescriptor.getLinearIndex(
748  {components[1], components[0]}
749  ) + n
750  ] = conj(
751  data[
752  blockSize*indexDescriptor.getLinearIndex(
753  *iterator
754  ) + n
755  ]
756  );
757  }
758  }
759 
760  indexDescriptor = newIndexDescriptor;
761  data = newData;
762 }
763 
764 template<typename DataType>
765 inline std::vector<SparseMatrix<DataType>> AbstractProperty<
766  DataType
768  const Model &model
769 ) const{
770  const HoppingAmplitudeSet &hoppingAmplitudeSet
771  = model.getHoppingAmplitudeSet();
772 
773  std::vector<SparseMatrix<DataType>> sparseMatrices;
774  for(unsigned int n = 0; n < blockSize; n++){
775  sparseMatrices.push_back(
778  model.getBasisSize(),
779  model.getBasisSize()
780  )
781  );
782  }
783  const IndexTree &indexTree = indexDescriptor.getIndexTree();
784  for(
785  IndexTree::ConstIterator iterator = indexTree.cbegin();
786  iterator != indexTree.cend();
787  ++iterator
788  ){
789  std::vector<Index> components = (*iterator).split();
790  TBTKAssert(
791  components.size() == 2,
792  "AbstractProperty<DataType>::toSparseMatrices()",
793  "Invalid Index structure. Unable to convert to"
794  << "SparseMatrices because the Index '"
795  << (*iterator).toString() << "' is not a compound"
796  << " Index with two component Indices.",
797  ""
798  );
799  unsigned int row
800  = hoppingAmplitudeSet.getBasisIndex(components[0]);
801  unsigned int column
802  = hoppingAmplitudeSet.getBasisIndex(components[1]);
803  unsigned int offset
804  = blockSize*indexDescriptor.getLinearIndex(*iterator);
805  for(unsigned int n = 0; n < blockSize; n++)
806  sparseMatrices[n].add(row, column, data[offset + n]);
807  }
808  for(unsigned int n = 0; n < blockSize; n++)
809  sparseMatrices[n].construct();
810 
811  return sparseMatrices;
812 }
813 
814 template<typename DataType>
816  const Index &index,
817  unsigned int offset
818 ) const{
819  int indexOffset = getOffset(index);
820  if(indexOffset < 0)
821  return defaultValue;
822  else
823  return data[indexOffset + offset];
824 }
825 
826 template<typename DataType>
828  const Index &index,
829  unsigned int offset
830 ){
831  int indexOffset = getOffset(index);
832  if(indexOffset < 0){
833  static DataType defaultValueNonConst;
834  defaultValueNonConst = defaultValue;
835  return defaultValueNonConst;
836  }
837  else{
838  return data[indexOffset + offset];
839  }
840 }
841 
842 template<typename DataType>
844  const std::initializer_list<Subindex> &index
845 ){
846  return operator()(index, 0);
847 }
848 
849 template<typename DataType>
851  const std::initializer_list<Subindex> &index
852 ) const{
853  return operator()(index, 0);
854 }
855 
856 /*template<typename DataType>
857 inline DataType& AbstractProperty<DataType>::operator()(
858  const std::initializer_list<unsigned int> &index
859 ){
860  return operator()(index, 0);
861 }
862 
863 template<typename DataType>
864 inline const DataType& AbstractProperty<DataType>::operator()(
865  const std::initializer_list<unsigned int> &index
866 ) const{
867  return operator()(index, 0);
868 }*/
869 
870 template<typename DataType>
872  unsigned int offset
873 ) const{
874  return data[offset];
875 }
876 
877 template<typename DataType>
878 inline DataType& AbstractProperty<DataType>::operator()(unsigned int offset){
879  return data[offset];
880 }
881 
882 template<typename DataType>
884  bool allowIndexOutOfBoundsAccess
885 ){
886  this->allowIndexOutOfBoundsAccess = allowIndexOutOfBoundsAccess;
887 }
888 
889 template<typename DataType>
891  const DataType &defaultValue
892 ){
893  this->defaultValue = defaultValue;
894 }
895 
896 template<typename DataType>
898  const DataType &targetValue,
899  const DataType &replacementValue
900 ){
901  //Handle NaN values.
902  if(targetValue != targetValue){
903  for(unsigned int n = 0; n < data.size(); n++)
904  if(data[n] != data[n])
905  data[n] = replacementValue;
906 
907  return;
908  }
909 
910  for(unsigned int n = 0; n < data.size(); n++)
911  if(data[n] == targetValue)
912  data[n] = replacementValue;
913 }
914 
915 template<typename DataType>
916 inline std::string AbstractProperty<DataType>::toString() const{
917  return "AbstractProperty";
918 }
919 
920 template<typename DataType>
921 inline std::string AbstractProperty<DataType>::serialize(Mode mode) const{
922  switch(mode){
923  case Mode::JSON:
924  {
925  nlohmann::json j;
926  j["id"] = "AbstractProperty";
927  j["indexDescriptor"] = nlohmann::json::parse(
928  indexDescriptor.serialize(mode)
929  );
930  j["blockSize"] = blockSize;
931  for(unsigned int n = 0; n < data.size(); n++){
932  //Convert the reference data[n] to an actual bool to
933  //get the code to compile on Mac. Some issue with the
934  //nlohmann library on Mac. Replace by the single
935  //commented out line when it is working again.
936  j["data"].push_back(
937  Serializable::serialize(data[n], mode)
938  );
939  }
940 
941  j["allowIndexOutOfBoundsAccess"] = allowIndexOutOfBoundsAccess;
942  j["defaultValue"] = Serializable::serialize(defaultValue, mode);
943 
944  return j.dump();
945  }
946  default:
947  TBTKExit(
948  "AbstractProperty<DataType>::serialize()",
949  "Only Serializable::Mode::JSON is supported yet.",
950  ""
951  );
952  }
953 }
954 
955 template<typename DataType>
957  this->blockSize = 0;
958 
959  allowIndexOutOfBoundsAccess = false;
960 }
961 
962 template<typename DataType>
964  unsigned int blockSize
965 ) :
966  indexDescriptor()
967 {
968  this->blockSize = blockSize;
969 
970  unsigned int size = blockSize;
971  data.reserve(size);
972  for(unsigned int n = 0; n < size; n++)
973  data.push_back(0.);
974 
975  allowIndexOutOfBoundsAccess = false;
976 }
977 
978 template<typename DataType>
980  unsigned int blockSize,
981  const DataType *data
982 ) :
983  indexDescriptor()
984 {
985  this->blockSize = blockSize;
986 
987  unsigned int size = blockSize;
988  this->data.reserve(size);
989  for(unsigned int n = 0; n < size; n++)
990  this->data.push_back(data[n]);
991 
992  allowIndexOutOfBoundsAccess = false;
993 }
994 
995 template<typename DataType>
997  const std::vector<int> &ranges,
998  unsigned int blockSize
999 ) :
1000  indexDescriptor(ranges)
1001 {
1002  this->blockSize = blockSize;
1003 
1004  unsigned int size = blockSize*indexDescriptor.getSize();
1005  data.reserve(size);
1006  for(unsigned int n = 0; n < size; n++)
1007  data.push_back(DataType(0.));
1008 
1009  allowIndexOutOfBoundsAccess = false;
1010 }
1011 
1012 template<typename DataType>
1014  const std::vector<int> &ranges,
1015  unsigned int blockSize,
1016  const DataType *data
1017 ) :
1018  indexDescriptor(ranges)
1019 {
1020  this->blockSize = blockSize;
1021 
1022  unsigned int size = blockSize*indexDescriptor.getSize();
1023  this->data.reserve(size);
1024  for(unsigned int n = 0; n < size; n++)
1025  this->data.push_back(data[n]);
1026 
1027  allowIndexOutOfBoundsAccess = false;
1028 }
1029 
1030 template<typename DataType>
1032  const IndexTree &indexTree,
1033  unsigned int blockSize
1034 ) :
1035  indexDescriptor(indexTree)
1036 {
1037  TBTKAssert(
1038  indexTree.getLinearMapIsGenerated(),
1039  "AbstractProperty::AbstractProperty()",
1040  "Linear map not constructed for the IndexTree.",
1041  "Call IndexTree::generateLinearIndex() before passing the"
1042  " IndexTree to the AbstractProperty constructor."
1043  );
1044 
1045  this->blockSize = blockSize;
1046 
1047  unsigned int size = blockSize*indexDescriptor.getSize();
1048  data.reserve(size);
1049  for(unsigned int n = 0; n < size; n++)
1050  data.push_back(DataType(0.));
1051 
1052  allowIndexOutOfBoundsAccess = false;
1053 }
1054 
1055 template<typename DataType>
1057  const IndexTree &indexTree,
1058  unsigned int blockSize,
1059  const DataType *data
1060 ) :
1061  indexDescriptor(indexTree)
1062 {
1063  TBTKAssert(
1064  indexTree.getLinearMapIsGenerated(),
1065  "AbstractProperty::AbstractProperty()",
1066  "Linear map not constructed for the IndexTree.",
1067  "Call IndexTree::generateLinearIndex() before passing the"
1068  " IndexTree to the AbstractProperty constructor."
1069  );
1070 
1071  this->blockSize = blockSize;
1072 
1073  unsigned int size = blockSize*indexDescriptor.getSize();
1074  this->data.reserve(size);
1075  for(unsigned int n = 0; n < size; n++)
1076  this->data.push_back(data[n]);
1077 
1078  allowIndexOutOfBoundsAccess = false;
1079 }
1080 
1081 template<typename DataType>
1083  const AbstractProperty &abstractProperty
1084 ) :
1085  indexDescriptor(abstractProperty.indexDescriptor)
1086 {
1087  blockSize = abstractProperty.blockSize;
1088 
1089  data = abstractProperty.data;
1090 
1091  allowIndexOutOfBoundsAccess
1092  = abstractProperty.allowIndexOutOfBoundsAccess;
1093 }
1094 
1095 template<typename DataType>
1097  AbstractProperty &&abstractProperty
1098 ) :
1099  indexDescriptor(std::move(abstractProperty.indexDescriptor))
1100 {
1101  blockSize = abstractProperty.blockSize;
1102 
1103  data = abstractProperty.data;
1104 
1105  allowIndexOutOfBoundsAccess
1106  = abstractProperty.allowIndexOutOfBoundsAccess;
1107 }
1108 
1109 template<typename DataType>
1111  const std::string &serialization,
1112  Mode mode
1113 ) :
1114  indexDescriptor(
1115  Serializable::extract(serialization, mode, "indexDescriptor"),
1116  mode
1117  )
1118 {
1119  TBTKAssert(
1120  validate(serialization, "AbstractProperty", mode),
1121  "AbstractProperty::AbstractProperty()",
1122  "Unable to parse string as AbstractProperty '" << serialization
1123  << "'.",
1124  ""
1125  );
1126 
1127  switch(mode){
1128  case Mode::JSON:
1129  try{
1130  nlohmann::json j = nlohmann::json::parse(serialization);
1131  blockSize = j.at("blockSize").get<unsigned int>();
1132  nlohmann::json d = j.at("data");
1133  for(
1134  nlohmann::json::iterator it = d.begin();
1135  it < d.end();
1136  ++it
1137  ){
1138  data.push_back(
1139  Serializable::deserialize<DataType>(
1140  it->get<std::string>(),
1141  mode
1142  )
1143  );
1144  }
1145 
1146  allowIndexOutOfBoundsAccess = j.at(
1147  "allowIndexOutOfBoundsAccess"
1148  ).get<bool>();
1149  defaultValue = Serializable::deserialize<DataType>(
1150  j.at("defaultValue").get<std::string>(),
1151  mode
1152  );
1153  }
1154  catch(nlohmann::json::exception &e){
1155  TBTKExit(
1156  "AbstractProperty::AbstractProperty()",
1157  "Unable to parse string as AbstractProperty '"
1158  << serialization << "'.",
1159  ""
1160  );
1161  }
1162 
1163  break;
1164  default:
1165  TBTKExit(
1166  "AbstractProperty::AbstractProperty()",
1167  "Only Serializable::Mode::JSON is supported yet.",
1168  ""
1169  );
1170  }
1171 }
1172 
1173 template<typename DataType>
1175 }
1176 
1177 template<typename DataType>
1179  const AbstractProperty &rhs
1180 ){
1181  if(this != &rhs){
1182  indexDescriptor = rhs.indexDescriptor;
1183 
1184  blockSize = rhs.blockSize;
1185 
1186  data = rhs.data;
1187 
1188  allowIndexOutOfBoundsAccess = rhs.allowIndexOutOfBoundsAccess;
1189  }
1190 
1191  return *this;
1192 }
1193 
1194 template<typename DataType>
1196  AbstractProperty &&rhs
1197 ){
1198  if(this != &rhs){
1199  indexDescriptor = std::move(rhs.indexDescriptor);
1200 
1201  blockSize = rhs.blockSize;
1202 
1203  data = rhs.data;
1204 
1205  allowIndexOutOfBoundsAccess = rhs.allowIndexOutOfBoundsAccess;
1206  }
1207 
1208  return *this;
1209 }
1210 
1211 template<typename DataType>
1214  TBTKAssert(
1215  indexDescriptor == rhs.indexDescriptor,
1216  "AbstractProperty::operator+=()",
1217  "Incompatible Properties. The Properties does not have the"
1218  << " same index structure.",
1219  ""
1220  );
1221 
1222  TBTKAssert(
1223  blockSize == rhs.blockSize,
1224  "AbstractProperty::operator+=()",
1225  "Incompatible Properties. The Properties does not have the"
1226  << " same block size.",
1227  ""
1228  );
1229 
1230  TBTKAssert(
1231  allowIndexOutOfBoundsAccess == rhs.allowIndexOutOfBoundsAccess,
1232  "AbstractProperty::operator+=()",
1233  "Incompatible Properties. The Properties differ in their"
1234  << " 'index out of bounds behavior'.",
1235  "Use AbstractProperty::setAllowIndexOutOfBoundsAccess() to set"
1236  << " the 'index out of bounds' behavior."
1237  );
1238 
1239  if(allowIndexOutOfBoundsAccess){
1240  TBTKAssert(
1241  defaultValue == rhs.defaultValue,
1242  "AbstractProperty::operator+=()",
1243  "Incompatible Properties. The Properties differ in"
1244  << " their default values.",
1245  "Use AbstractProperty::setDefaultValue() to set the"
1246  << " default value."
1247  );
1248  }
1249 
1250  TBTKAssert(
1251  data.size() == rhs.data.size(),
1252  "AbstractProperty::operator+=()",
1253  "Incompatible Properties. The Properties have different data"
1254  << " sizes.",
1255  "This should never happen, contact the developer."
1256  );
1257 
1258  for(unsigned int n = 0; n < data.size(); n++)
1259  data[n] += rhs.data[n];
1260 
1261  return *this;
1262 }
1263 
1264 template<typename DataType>
1267  const AbstractProperty<DataType> &rhs
1268 ){
1269  TBTKAssert(
1270  indexDescriptor == rhs.indexDescriptor,
1271  "AbstractProperty::operator-=()",
1272  "Incompatible Properties. The Properties does not have the"
1273  << " same index structure.",
1274  ""
1275  );
1276 
1277  TBTKAssert(
1278  blockSize == rhs.blockSize,
1279  "AbstractProperty::operator-=()",
1280  "Incompatible Properties. The Properties does not have the"
1281  << " same block size.",
1282  ""
1283  );
1284 
1285  TBTKAssert(
1286  allowIndexOutOfBoundsAccess == rhs.allowIndexOutOfBoundsAccess,
1287  "AbstractProperty::operator-=()",
1288  "Incompatible Properties. The Properties differ in their"
1289  << " 'index out of bounds behavior'.",
1290  "Use AbstractProperty::setAllowIndexOutOfBoundsAccess() to set"
1291  << " the 'index out of bounds' behavior."
1292  );
1293 
1294  if(allowIndexOutOfBoundsAccess){
1295  TBTKAssert(
1296  defaultValue == rhs.defaultValue,
1297  "AbstractProperty::operator-=()",
1298  "Incompatible Properties. The Properties differ in"
1299  << " their default values.",
1300  "Use AbstractProperty::setDefaultValue() to set the"
1301  << " default value."
1302  );
1303  }
1304 
1305  TBTKAssert(
1306  data.size() == rhs.data.size(),
1307  "AbstractProperty::operator-=()",
1308  "Incompatible Properties. The Properties have different data"
1309  << " sizes.",
1310  "This should never happen, contact the developer."
1311  );
1312 
1313  for(unsigned int n = 0; n < data.size(); n++)
1314  data[n] -= rhs.data[n];
1315 
1316  return *this;
1317 }
1318 
1319 template<typename DataType>
1322  const DataType &rhs
1323 ){
1324  if(allowIndexOutOfBoundsAccess)
1325  defaultValue *= rhs;
1326 
1327  for(unsigned int n = 0; n < data.size(); n++)
1328  data[n] *= rhs;
1329 
1330  return *this;
1331 }
1332 
1333 template<typename DataType>
1335  const DataType &rhs
1336 ){
1337  if(allowIndexOutOfBoundsAccess)
1338  defaultValue /= rhs;
1339 
1340  for(unsigned int n = 0; n < data.size(); n++)
1341  data[n] /= rhs;
1342 
1343  return *this;
1344 }
1345 
1346 template<typename DataType>
1348  const Index &index,
1349  DataType *block
1350 ){
1351  TBTKExit(
1352  "AbstractProperty::calculateDynamically()",
1353  "This Property does not support dynamic calculation.",
1354  ""
1355  );
1356 }
1357 
1358 }; //End namespace Property
1359 }; //End namespace TBTK
1360 
1361 #endif
virtual ~AbstractProperty()
Definition: AbstractProperty.h:1174
Definition: Streamable.h:30
void setAllowIndexOutOfBoundsAccess(bool allowIndexOutOfBoundsAccess)
Definition: AbstractProperty.h:883
const IndexTree & getIndexTree() const
Definition: IndexDescriptor.h:240
unsigned int getSize() const
ConstIterator cend() const
Definition: IndexTree.h:414
ConstIterator cbegin() const
Definition: IndexedDataTree.h:822
HoppingAmplitude container.
Definition: HoppingAmplitudeSet.h:50
void hermitianConjugate()
Definition: AbstractProperty.h:710
ConstIterator cend() const
Definition: IndexedDataTree.h:837
Describes the index structure of data stored for several indices.
Definition: IndexDescriptor.h:39
void setDefaultValue(const DataType &defaultValue)
Definition: AbstractProperty.h:890
Precompiler macros.
ConstIterator cbegin() const
Definition: IndexTree.h:406
const std::vector< DataType > & getData() const
Definition: AbstractProperty.h:567
void add(const Data &data, const Index &index)
Definition: IndexedDataTree.h:355
Definition: Serializable.h:43
virtual std::string toString() const
Definition: AbstractProperty.h:916
Container of Model related information.
virtual std::string serialize(Mode mode) const
int getOffset(const Index &index) const
Definition: AbstractProperty.h:587
bool contains(const Index &index) const
Definition: AbstractProperty.h:603
std::string toString() const
Definition: Index.h:349
int getLinearIndex(const Index &index, bool returnNegativeForMissingIndex=false) const
Definition: IndexDescriptor.h:275
Definition: IndexedDataTree.h:183
bool get(Data &data, const Index &index) const
Definition: IndexedDataTree.h:467
unsigned int getDimensions() const
Definition: AbstractProperty.h:577
Sparse matrix.
const IndexDescriptor & getIndexDescriptor() const
Definition: AbstractProperty.h:597
int getBasisIndex(const Index &index) const
std::vector< int > getRanges() const
Definition: AbstractProperty.h:582
void add(const Index &index)
Definition: IndexedDataTree.h:45
AbstractProperty & operator*=(const DataType &rhs)
Definition: AbstractProperty.h:1321
Abstract Property class.
Definition: Property.h:36
void reduce(const std::vector< Index > &targetPatterns, const std::vector< Index > &newPatterns)
Definition: AbstractProperty.h:610
unsigned int getSize() const
Definition: Index.h:482
Describes the index structure of data stored for several indices.
Abstract Property class.
Definition: AbstractProperty.h:101
unsigned int getBlockSize() const
Definition: AbstractProperty.h:555
Data structure for mapping physical indices to linear indices.
Definition: IndexTree.h:35
Physical index.
Definition: Index.h:44
std::vector< DataType > & getDataRW()
Definition: AbstractProperty.h:572
Definition: IndexTree.h:297
AbstractProperty & operator-=(const AbstractProperty &rhs)
Definition: AbstractProperty.h:1266
bool getLinearMapIsGenerated() const
Definition: IndexTree.h:395
void generateLinearMap()
Definition: Boolean.h:32
Definition: SparseMatrix.h:35
unsigned int getSize() const
Definition: AbstractProperty.h:560
Mode
Definition: Serializable.h:47
virtual const DataType & operator()(const Index &index, unsigned int offset=0) const
Definition: AbstractProperty.h:815
std::vector< int > getRanges() const
Definition: IndexDescriptor.h:225
bool contains(const Index &index) const
Definition: IndexDescriptor.h:320
AbstractProperty()
Definition: AbstractProperty.h:956
static std::vector< std::string > split(const std::string &content, Mode mode)
AbstractProperty & operator/=(const DataType &rhs)
Definition: AbstractProperty.h:1334
virtual std::string serialize(Mode mode) const =0
int getBasisSize() const
Definition: Model.h:311
std::vector< SparseMatrix< DataType > > toSparseMatrices(const Model &model) const
Definition: AbstractProperty.h:767
AbstractProperty & operator+=(const AbstractProperty &rhs)
Definition: AbstractProperty.h:1213
virtual std::string serialize(Mode mode) const
Definition: AbstractProperty.h:921
Container of Model related information.
Definition: Model.h:57
AbstractProperty & operator=(const AbstractProperty &abstractProperty)
Definition: AbstractProperty.h:1178
void replaceValues(const DataType &targetValue, const DataType &replacementValue)
Definition: AbstractProperty.h:897
const HoppingAmplitudeSet & getHoppingAmplitudeSet() const
Definition: Model.h:367