It looks like right now .set()
is not defined for diagonal storage, i.e.:
auto i = Index("i",2);
auto j = Index("j",2);
auto A = delta(i,j);
A.set(i(1),j(1),2.0);
throws an error:
terminate called after throwing an instance of 'itensor::ITError'
what(): doTask not defined for task SetElt and storage type DiagReal
From what I can tell, right now the only methods for actually modifying ITensors with Diag storage are .apply()
and .fill()
, so for example:
A.apply([](Real x){ return 2*x; });
would double all of the values of the diagonals, and
A.fill(3.);
would set all of the values to 3.
For more complicated element setting, you may have to store the original diagonal values (for example in a vector), manipulate them, and then use them in a diagTensor
constructor to make a new ITensor with the diagonal values you want.
I think it would be good for us to define .set()
for Diag/QDiag storage, and have it throw an error if a user tries to set an off-diagonal element. But I think many current cases can be covered by the current functionality, and worse case would be making a new diagTensor.
What is your particular use-case? Note that there is also a new iterInds
function (http://www.itensor.org/support/1361/iterating-over-non-zero-elements-of-a-sparse-itensor) that can help you visit all of the elements of an ITensor, in case that helps.
Cheers,
Matt