Advertisement
Guest User

Untitled

a guest
Apr 20th, 2019
101
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.11 KB | None | 0 0
  1. #include "itensor/all.h"
  2.  
  3. using namespace itensor;
  4.  
  5. IQIndex
  6. directSum(IQIndex const& i, IQIndex const& j, Args const& args = Args::global())
  7. {
  8. auto name = args.getString("IndexName","sum");
  9. #ifdef DEBUG
  10. if( i.dir() != j.dir() ) Error("In directSum(IQIndex, IQIndex), input indices must have same arrow direction");
  11. #endif
  12. auto siq = stdx::reserve_vector<IndexQN>(i.nindex()+j.nindex());
  13. for(auto iq1 : i)
  14. {
  15. auto s1 = Index(iq1.index.rawname(),iq1.m(),iq1.type());
  16. siq.emplace_back(s1,iq1.qn);
  17. }
  18. for(auto iq2 : j)
  19. {
  20. auto s2 = Index(iq2.index.rawname(),iq2.m(),iq2.type());
  21. siq.emplace_back(s2,iq2.qn);
  22. }
  23. #ifdef DEBUG
  24. if(siq.empty()) Error("siq is empty in plussers");
  25. #endif
  26. auto ij = IQIndex(name,std::move(siq),i.dir());
  27. return ij;
  28. }
  29.  
  30. IQIndex
  31. directSumTensors(IQIndex const& i,
  32. IQIndex const& j,
  33. IQTensor& D1, IQTensor& D2,
  34. Args const& args = Args::global())
  35. {
  36. auto ij = directSum(i,j,args);
  37. D1 = IQTensor(dag(i),ij);
  38. int n = 1;
  39. for(auto iq1 : i)
  40. {
  41. auto s1 = ij.index(n);
  42. auto D = Matrix(iq1.index.m(),s1.m());
  43. auto minsize = std::min(iq1.index.m(),s1.m());
  44. for(auto ii : range(minsize)) D(ii,ii) = 1.0;
  45. D1 += matrixTensor(std::move(D),iq1.index,s1);
  46. ++n;
  47. }
  48. D2 = IQTensor(dag(j),ij);
  49. for(auto iq2 : j)
  50. {
  51. auto s2 = ij.index(n);
  52. auto D = Matrix(iq2.index.m(),s2.m());
  53. auto minsize = std::min(iq2.index.m(),s2.m());
  54. for(auto jj : range(minsize)) D(jj,jj) = 1.0;
  55. D2 += matrixTensor(std::move(D),iq2.index,s2);
  56. ++n;
  57. }
  58. return ij;
  59. }
  60.  
  61. IQTensor
  62. directSum(IQTensor const& A, IQTensor const& B,
  63. IQIndexSet const& I, IQIndexSet const& J,
  64. IQIndexSet& IJ, Args const& args = Args::global())
  65. {
  66. if( I.size() != J.size() ) Error("In directSum(IQTensor, IQTensor, ...), must sum equal number of indices");
  67. auto AD = A;
  68. auto BD = B;
  69. auto newinds = IQIndexSetBuilder(I.size());
  70. for( auto n : range1(I.size()) )
  71. {
  72. auto In = I.index(n);
  73. auto Jn = J.index(n);
  74. if( dir(A,In) != In.dir() ) In.dag();
  75. if( dir(B,Jn) != Jn.dir() ) Jn.dag();
  76. IQTensor D1, D2;
  77. auto IJn = directSumTensors(In,Jn,D1,D2,args);
  78. newinds.nextIndex(IJn);
  79. AD *= D1;
  80. BD *= D2;
  81. }
  82. IJ = newinds.build();
  83. auto C = AD+BD;
  84. return C;
  85. }
  86.  
  87. // Direct sum A and B over indices i on A and j on B
  88. IQTensor
  89. directSum(IQTensor const& A, IQTensor const& B,
  90. IQIndex const& i, IQIndex const& j,
  91. IQIndex& ij, Args const& args = Args::global())
  92. {
  93. IQIndexSet IJ;
  94. auto C = directSum(A,B,IQIndexSet(i),IQIndexSet(j),IJ,args);
  95. ij = IJ.index(1);
  96. return C;
  97. }
  98.  
  99. void
  100. test()
  101. {
  102. auto a1 = Index("a1",2);
  103. auto a2 = Index("a2",2);
  104. auto a3 = Index("a3",2);
  105. auto a = IQIndex("a",
  106. a1,QN(-1),
  107. a2,QN(0),
  108. a3,QN(+1));
  109.  
  110. auto b1 = Index("b1",2);
  111. auto b2 = Index("b2",2);
  112. auto b3 = Index("b3",2);
  113. auto b = IQIndex("b",
  114. b1,QN(-1),
  115. b2,QN(0),
  116. b3,QN(+1));
  117.  
  118. auto i1 = Index("i1",2);
  119. auto i2 = Index("i2",2);
  120. auto i3 = Index("i2",2);
  121. auto i = IQIndex("i",
  122. i1,QN(-1),
  123. i2,QN(0),
  124. i3,QN(+1));
  125.  
  126. auto j1 = Index("j1",2);
  127. auto j2 = Index("j2",2);
  128. auto j3 = Index("j3",2);
  129. auto j = IQIndex("j",
  130. j1,QN(-1),
  131. j2,QN(0),
  132. j3,QN(+1));
  133.  
  134. auto A = randomTensor(QN(0),a,b,dag(i));
  135. auto B = randomTensor(QN(0),a,b,dag(j));
  136.  
  137. PrintData(A);
  138. PrintData(B);
  139.  
  140. // Version accepting an index on A and an index on B to be direct summed
  141. // Here we create a new IQTensor C with indices {a,b,i+j}
  142. // Indices that are not specified must be shared by A and B
  143. IQIndex ij;
  144. auto C = directSum(A,B,i,j,ij,{"IndexName=","i+j"});
  145.  
  146. // Version accepting sets of indices on A and B to be direct summed
  147. // Here we create a new IQTensor C with indices {a,i+j,b+b}
  148. //IQIndexSet ij;
  149. //auto C = directSum(A,B,{i,b},{j,b},ij,{"IndexName=","sum"});
  150.  
  151. PrintData(C);
  152. PrintData(ij);
  153. }
  154.  
  155. int
  156. main()
  157. {
  158. test();
  159. return 0;
  160. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement