Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
99 changes: 98 additions & 1 deletion itensor/indexset.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,13 +141,110 @@ class IndexSetT : public RangeT<index_type_>

parent const&
range() const { return *this; }

void
dag() { for(auto& J : *this) J.dag(); }

void
swap(IndexSetT & other) { parent::swap(other); }

// Indexset arithmetic & tools
// Useful additions for higher-order tensors index manipulation
// Set union between A and B
// Returns a new IndexSet with all the indices of A and B together
IndexSetT
setUnion(IndexSetT const& other)
{
std::vector< index_type > inds;
for (index_type i : (*this)) inds.push_back(i);
for (index_type i : other)
{
if (!hasindex(*this, i)) inds.push_back(i);
}
return IndexSetT(inds);
}

// Set difference between A and B
// Returns a new IndexSet with indices of A that are not in B
IndexSetT
setDifference(IndexSetT const& other)
{
std::vector< index_type > inds;
for (index_type i : (*this))
{
if (!hasindex(other, i)) inds.push_back(i);
}
return IndexSetT(inds);
}

// Set symmetric difference between A and B
// Returns a new IndexSet with indices which are exclusive to either A or B, but not in both
IndexSetT
setSymmetricDifference(IndexSetT const& other)
{
std::vector< index_type > inds;
for (index_type i : (*this))
{
if (!hasindex(other, i)) inds.push_back(i);
}
for (index_type i : other)
{
if (!hasindex(*this, i)) inds.push_back(i);
}
return IndexSetT(inds);
}

// Set intersection
// Returns a new IndexSet with ALL common indices between A and B
// In contrast, commonIndex() can only get ONE common index of a given type and prime level
IndexSetT
setIntersection(IndexSetT const& other)
{
std::vector< index_type > inds;
for (index_type i : (*this))
{
if (hasindex(other, i)) inds.push_back(i);
}
return IndexSetT(inds);
}

// Select from IndexSet by type
// This generalizes findtype() to multiple indices
IndexSetT
selectType(IndexType type)
{
std::vector< index_type > inds;
for (auto& J : (*this))
{
if (J.type() == type) inds.push_back(J);
}
return IndexSetT(inds);
}

// Filter IndexSet by type
// This generalizes the complement of findtype() to multiple indices
IndexSetT
filterType(IndexType type)
{
std::vector< index_type > inds;
for (auto& J : (*this))
{
if (J.type() != type) inds.push_back(J);
}
return IndexSetT(inds);
}

// Utility function
// some ITensor functions seem to only accept Index vectors as input, but
// not IndexSets. Why not?
// This gives us a handy way to get all the indices as a vector
std::vector< index_type > vector()
{
std::vector< index_type > inds;
for (index_type i : (*this)) inds.push_back(i);
return inds;
}

index_type const&
front() const { return parent::front().ind; }

Expand Down
77 changes: 77 additions & 0 deletions unittest/indexset_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ auto i7 = Index("i7",7);
auto i8 = Index("i8",8);
auto i9 = Index("i9",9);
auto i10 = Index("i10",10);
auto x1 = Index("x2",2,Xtype);
auto v1 = Index("v1",2,Vtype);
auto w1 = Index("w1",2,Wtype);

Expand Down Expand Up @@ -80,6 +81,82 @@ SECTION("Constructors")

}

SECTION("IndexSet Arithmetic")
{
SECTION("A union B")
{
IndexSet A(i1,i2,i3,prime(i3),i4);
IndexSet B(i3,i4,prime(i4),i5,i6);
IndexSet C = A.setUnion(B);
CHECK(hasindex(C,i1));
CHECK(hasindex(C,i2));
CHECK(hasindex(C,i3));
CHECK(hasindex(C,i4));
CHECK(hasindex(C,i5));
CHECK(hasindex(C,i6));
CHECK(hasindex(C,prime(i3)));
CHECK(hasindex(C,prime(i4)));
}
SECTION("A intersection B")
{
IndexSet A(i1,i2,i3,prime(i3),i4);
IndexSet B(i3,i4,prime(i4),i5,i6);
IndexSet C = A.setIntersection(B);
CHECK(!hasindex(C,i1));
CHECK(!hasindex(C,i2));
CHECK(hasindex(C,i3));
CHECK(hasindex(C,i4));
CHECK(!hasindex(C,i5));
CHECK(!hasindex(C,i6));
CHECK(!hasindex(C,prime(i3)));
CHECK(!hasindex(C,prime(i4)));
}
SECTION("A difference B")
{
IndexSet A(i1,i2,i3,prime(i3),i4);
IndexSet B(i3,i4,prime(i4),i5,i6);
IndexSet C = A.setDifference(B);
CHECK(hasindex(C,i1));
CHECK(hasindex(C,i2));
CHECK(!hasindex(C,i3));
CHECK(!hasindex(C,i4));
CHECK(!hasindex(C,i5));
CHECK(!hasindex(C,i6));
CHECK(hasindex(C,prime(i3)));
CHECK(!hasindex(C,prime(i4)));
}
SECTION("A symmetric difference B")
{
IndexSet A(i1,i2,i3,prime(i3),i4,prime(i4));
IndexSet B(i3,i4,prime(i4),i5,i6);
IndexSet C = A.setSymmetricDifference(B);
CHECK(hasindex(C,i1));
CHECK(hasindex(C,i2));
CHECK(!hasindex(C,i3));
CHECK(!hasindex(C,i4));
CHECK(hasindex(C,i5));
CHECK(hasindex(C,i6));
CHECK(hasindex(C,prime(i3)));
CHECK(!hasindex(C,prime(i4)));
}
SECTION("Select")
{
IndexSet A(x1,v1,w1);
IndexSet B = A.selectType(Xtype);
CHECK(hasindex(B,x1));
CHECK(!hasindex(B,v1));
CHECK(!hasindex(B,w1));
}
SECTION("Filter")
{
IndexSet A(x1,v1,w1);
IndexSet B = A.filterType(Xtype);
CHECK(!hasindex(B,x1));
CHECK(hasindex(B,v1));
CHECK(hasindex(B,w1));
}
}

SECTION("PrimeLevelMethods")
{
SECTION("Prime All")
Expand Down