Make use of storage_ptr&

+1 vote
asked Sep 27 by empter (160 points)
edited 5 days ago by empter

Is there a way to use the storage pointer of a tensor like a pointer of std::vector? The .store() method get a pointer of "ITData" type and can not be used directly.
Currently, I can pass the Vector class in ITensor library to other library by .data() method because the data is held by storage_type = std::vector. But this does not work for a vector like ITensor (rank one). Is there a workaround?

Updata1:
Find workaround at http://itensor.org/docs.cgi?page=formulas/extractdense
Can anyone give a template example so there is no need to use isComplex() to determine to call ExtractReal or ExtractCplx.

Remember to use T.scaleTo(1) before Extract the Storage of Tensor T because of the designed feature(see for example https://github.com/ITensor/ITensor/issues/139).

Thanks!

commented Oct 3 by miles (18,230 points)
Hi, I didn't quite follow the part from Update 2 to Update 3. Is it a bug you think? Or was it the expected behavior. Thanks!
commented Oct 4 by empter (160 points)
Thank you for your reply. I think its a bug in the applyFunc and doTask subsystem.
Update 2 is a practice of converting Dense ITensors store to std::vector.
As you can see from the output of mat[i], each element is 8.37(the norm of Tc) times smaller than Tc.  Seems that the applyFunc(extractReal,Tc.store()) normalizes Tc for me (normalize is wrong in my case).

1 Answer

0 votes
answered Oct 3 by miles (18,230 points)
selected 5 days ago by empter
 
Best answer

Hi, glad you have figured it out for the most part.

To answer your question about not needing to check isComplex() to decide to call extractReal or extractComplex, the way around this is rather than defining a function (or a lambda function) which by definition can only take a single set of arguments, you can define a function object: an object which has multiple overloads of the operator()(...) method.

So if you define (outside of your function, although inside may work too):

struct GetSize
{
size_t
operator()(DenseReal & d) { return d.size(); }

size_t
operator()(DenseCplx & d) { return d.size(); }

};

Then doing:
auto size = applyFunc(GetSize(),T.store());

However, your use case of wanting to get the pointer to the data falls outside of this approach more because of a C++ issue rather than an ITensor issue. The reason is that the pointer type would be different anyway between DenseReal and DenseCplx storage, so there can't be a common return type for the function returning the pointer. So you might as well call isComplex() and then specialize to a different function for each case.

(On a side note though, you may be able to define function objects whose operator() overloads return different types and still use them. I forget if I covered that case but I probably did. Try it out!)

Miles

commented Oct 4 by empter (160 points)
edited Oct 5 by empter
Thank you for your sample code. In your case the return type is size_t, what should I use for d.stroe, I tried std::vector<Real> and std::vector<Cplx> but the compiler said "no viable
      overloaded '='
        ret_ = doTask(std::forward<VArgs>(vargs)...);".
Anyway, call isComplex() is enough for me currently.
commented Oct 9 by miles (18,230 points)
Yes, that is what I meant about your case falling outside the approach in my example i.e. because the storage of DenseReal and DenseCplx is of a different type, so you can't return two different types from the same function. So my example was intended just to show how one can define a function object and overload the operator() method then put this overloaded function object into applyFunc. Glad to hear that your code is working!
Welcome to ITensor Support Q&A, where you can ask questions and receive answers from other members of the community.

Formatting Tips:
  • To format code, indent by four spaces
  • To format inline LaTeX, surround it by @@ on both sides
  • To format LaTeX on its own line, surround it by $$ above and below
  • For LaTeX, it may be necessary to backslash-escape underscore characters to obtain proper formatting. So for example writing \sum\_i to represent a sum over i.
If you cannot register due to firewall issues (e.g. you cannot see the capcha box) please email Miles Stoudenmire to ask for an account.

To report ITensor bugs, please use the issue tracker.
...