From: Andras V. <and...@ui...> - 2012-02-15 10:53:33
|
Hi Raimar, In this case, your *LazyDensityOperator* will be binary only, which means that it can be indexed with 4 indices (2 instances of *TTD_IDXTINY(2)* ). You have to copy the whole thing into a * quantumdata::Types<2>::DensityOperatorLow* . This is actually rather wasteful, because even in the case when the underlying data is just a state vector, it is treated in the same way as a full density operator. You could maybe think about a nice general solution to this problem (I have just added a tracker #3487814 on this issue). Anyway, once you have your *DensityOperatorLow*, I think you have to apply FFT on *all of its indices individually,* the FFT's sign depending on whether it is a ‘left’ or ‘right’ index. So, * blitzplusplus::vfmsi::fullRange* will not be of much use in this case, and you have to apply the more general *blitzplusplus::basi::fullRange*iteration. I think the code is something pretty much like this: // left: for_each(fullRange(rhotemp,Vector<0>()),bind(&ffTransform,_1,FFTDIR_KX)); for_each(fullRange(rhotemp,Vector<1>()),bind(&ffTransform,_1,FFTDIR_KX)); // right: for_each(fullRange(rhotemp,Vector<2>()),bind(&ffTransform,_1,FFTDIR_XK)); for_each(fullRange(rhotemp,Vector<3>()),bind(&ffTransform,_1,FFTDIR_XK)); Where *Vector* stands for *tmptools::Vector*. (This is not the only class that works with the slice iterators, because e.g. *boost::mpl::range_c*also works, but here you need this.) Keep in touch. Best regards, András |
From: Raimar S. <rai...@ui...> - 2012-02-15 11:48:45
|
Dear András, thanks for your reply. So you are saying blitzplusplus::vfmsi::fullRange could always only give me the two-particle (left or right) state vector from my DensityOperatorLow, this is why I have to use blitzplusplus::basi::fullRange. Actually, your code snippet is pretty much what I also had in mind. On a related note, would it be possible that, given a blitzplusplus::basi::Iterator with two or more retained index positions, to slice it even further? This would somehow be related to the concept that a slice of a multi-array is again a multi-array and can be sliced. On Wednesday 15 February 2012 11:53:02 Andras Vukics wrote: > This is actually rather wasteful, because even in the case when the > underlying data is just a state vector, it is treated in the same way as a > full density operator. You could maybe think about a nice general solution > to this problem (I have just added a tracker #3487814 on this issue). Yes I have noticed the tracker :). So in principle the slicing would occur in the fft function, not in the average function anymore. How would such a fft function with specialized implementation determine the type of the passed LazyDensityOperator, by dynamic_cast? > // left: > for_each(fullRange(rhotemp,Vector<0>()),bind(&ffTransform,_1,FFTDIR_KX)); > for_each(fullRange(rhotemp,Vector<1>()),bind(&ffTransform,_1,FFTDIR_KX)); > // right: > for_each(fullRange(rhotemp,Vector<2>()),bind(&ffTransform,_1,FFTDIR_XK)); > for_each(fullRange(rhotemp,Vector<3>()),bind(&ffTransform,_1,FFTDIR_XK)); > > Where Vector stands for tmptools::Vector. (This is not the only class that > works with the slice iterators, because e.g. boost::mpl::range_c also > works, but here you need this.) Wouldn't boost::mpl::range_c<int,0,1>, boost::mpl::range_c<int,1,2> etc work, although of course a bit awkward? Best regards Raimar |
From: Andras V. <and...@ui...> - 2012-02-15 14:28:52
|
Hi Raimar, thanks for your reply. So you are saying blitzplusplus::vfmsi::fullRange > could > always only give me the two-particle (left or right) state vector from my > DensityOperatorLow, this is why I have to use > blitzplusplus::basi::fullRange. > That's right. On a related note, would it be possible that, given a > blitzplusplus::basi::Iterator with two or more retained index positions, to > slice it even further? This would somehow be related to the concept that a > slice of a multi-array is again a multi-array and can be sliced. > Yes, a sliced multi-array (e.g. a dereferenced slice iterator) can be further sliced (can be used to initialize a slice iterator). This actually does occur in ModeCorrelations::average, which in general gets a sliced LazyDensityOperator, and slices it further when calculating the averages for the individual Modes relying on mode::AveragedQuadratures (cf. ModeCorrelations.cc:38-39). You should take ModeCorrelations as an example, because also with the particle correlations, some functionalities could (perhaps) be delegated to particle::Averaged. So in principle the slicing would occur in > the fft function, not in the average function anymore. How would such a fft > function with specialized implementation determine the type of the passed > LazyDensityOperator, by dynamic_cast? > Yes, I think this is a paradigmatic example of dynamic_cast. The function should have roughly this signature: template<int RANK, int IDX> const LazyDensityOperator<RANK> ffTransformLazyDensityOperator(const LazyDensityOperator<RANK>&, fft::Direction, mpl::int_<IDX>); IDX is the index position on which the transformation should occur. And in the density-operator case, the transformation occurs on the index position RANK+IDX as well, only with opposit Copying is of course still necessary, because we do not want to touch the original one (in fact, we cannot). But in case of a state vector, only this needs to be copied. Wouldn't boost::mpl::range_c<int,0,1>, boost::mpl::range_c<int,1,2> etc > work, > although of course a bit awkward? > They should indeed work, but it's an overkill :) . Best regards, András |