juanjosegarciaripoll / tensor

C++ library for numerical arrays and tensor objects and operations with them, designed to allow Matlab-style programming.
Other
51 stars 15 forks source link

Implicit index to range conversion #10

Open wavepacket opened 10 years ago

wavepacket commented 10 years ago

The following does not work right now:

CTensor psi = CTensor::random(5, 4, 3); CTensor slice = psi(0, range(), 2);

because this calls the function that takes only ranges, and mixing of ranges and slices is not permittes. Instead, you have to put

CTensor slice = psi(range(0,0), range(), range(2,2));

which is ugly as hell.

The solution is rather trivial: The ranges need an implicit constructor that takes a single integer.

juanjosegarciaripoll commented 1 year ago

The actual syntax for the solution right now is

CTensor slice = psi(range(0), _, 2);

There is a problem with the implicit conversion from integer to Range.

In order not to limit the number of dimensions, I have been using variadic templates and parameter packs for indexing. However, templates do not allow implicit conversions: they require the types of all arguments to be determined in advance.

In this case, the first index being a range() tells the template expander that the rest are to be interpreted as range-like, and automatically converted.

If you wrote

CTensor slice = psi(0, _, 2);

the template expander would expect that the rest of the arguments are integers.

I am closing this issue, assuming that there is no better solution, other than using different methods for integer indexes and slices.

wavepacket commented 1 year ago

I am not quite happy with this solution, to be honest.

The fundamental problem is that the operator() here is overloaded for two completely different use-cases. On one hand, you want to use specific indices to query a particular value of the tensor as in "psi(0,2,2)". On the other hand, you want to use slices to get a part of the tensor as a slice / new tensor as in "psi(range(0),_,2)".

Solutions that I can see: