Note that there are some explanatory texts on larger screens.

plurals
  1. POInterleaving/deinterleaving 3 vectors in C++ STL
    primarykey
    data
    text
    <p><strong>I'm trying to combine three signal waveforms into a single, interleaved waveform. I need to know the best way to do it in C++ STL</strong>. Better solutions would use as much C++ STL style as possible, avoid redundant code, etc. Is there some STL "tuple" type class that would do this for me? I need contiguous storage at all times for backward compatibility with other code (therefore, vector). The best solution would be correct and easy to understand. Space and speed are not as high of a priority as <strong>correctness</strong> and <strong>ease of understanding</strong>.</p> <p>The output waveform must be ordered like this: first sample from first channel, first sample from second channel, first sample from third channel, then continue with the second sample from each channel and repeat for all samples. I know that all three input waveforms have the same number of samples.</p> <p>In Matlab, I would have done it like this:</p> <pre> function outputWaveform=Interleave3(a, b, c) outputWaveform=zeros([1 3*length(a)]); outputWaveform(1:3:end)=a(:); outputWaveform(2:3:end)=b(:); outputWaveform(3:3:end)=c(:); </pre> <p>This is my first C++ STL attempt:</p> <pre> typedef vector&lt;double> dVector; typedef vector&lt;double>::iterator dVectorIT; dVector Interleave3(dVector a, dVector b, dVector c) { dVector result(0, 3*a.size()); dVectorIT aIT=a.begin(), bIT=b.begin(), cIT=c.begin(), rIT=result.begin(); for(; aIT != a.end(); ++aIT, ++bIT, ++cIT) { *rIT++=*aIT; *rIT++=*bIT; *rIT++=*cIT; } return result; } </pre> <p>It works, but is there a better way to do this? I hoped there might be some clever way to do it in one line with <strong>transform()</strong>. Can you append b to a, then c to a, then transform the temporary "a1a2a3...-b1b2b3...-c1c2c3..." vector into "a1b1c1a2b2c2a3b3c3..."?</p> <p>Bonus question: I also need the inverse operation (to split an output waveform of 3*N samples into 3 vectors of N samples each). The Matlab solution is quite easy:</p> <pre> function [a, b, c]=Deinterleave3(outputWaveform) a=outputWaveform(1:3:end); b=outputWaveform(2:3:end); c=outputWaveform(3:3:end); </pre> <p><strong>C++ STL</strong> seems fairly awkward, and I bet there's a better way to do it than this:</p> <pre> typedef vector&lt;double> dVector; typedef vector&lt;double>::iterator dVectorIT; void Deinterleave3(dVector outputWaveform, dVector &a, dVector &b, dVector &c) { ASSERT( !(outputWaveform.size()%3) ); a.clear(); b.clear(); c.clear(); dVectorIT oIT=outputWaveform.begin(); for(; oIT != outputWaveform.end(); ) { a.push_back( *oIT++ ); b.push_back( *oIT++ ); c.push_back( *oIT++ ); } } </pre> <p>Is there some clever combination of <strong>transform()</strong> and <strong>back_inserter()</strong> which would do the inverse operation? Again, using a temporary vector would be acceptable. </p> <p>Boost has a "<a href="http://www.boost.org/doc/libs/1_38_0/libs/iterator/doc/zip_iterator.html" rel="nofollow noreferrer">zip iterator</a>," but I can't figure out if it would perform either the interleaving or deinterleaving operation. </p> <p>EDIT: fixed the missing angle brackets (&lt;&gt;). The HTML filter ate them! Also, I have a new idea about how to fix this with a custom iterator.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload