1

Assume that I have a vector:

x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]

What I need to do is split this vector into block sizes of blocksize with an overlap

blocksize = 4

overlap = 2

The result, would be a 2D vector with size 4 containing 6 values.

x[0] = [1, 3, 5, 7, 9, 11]

x[1] = [ 2 4 6 8 10 12]

....

I have tried to implement this with the following functions:

std::vector<std::vector<double> > stride_windows(std::vector<double> &data, std::size_t 
NFFT, std::size_t overlap)
{
    std::vector<std::vector<double> > blocks(NFFT); 

    for(unsigned i=0; (i < data.size()); i++)
    {
        blocks[i].resize(NFFT+overlap);
        for(unsigned j=0; (j < blocks[i].size()); j++)
        {
            std::cout << data[i*overlap+j] << std::endl;
        }
    }
}

This is wrong, and, segments.

std::vector<std::vector<double> > frame(std::vector<double> &signal, int N, int M)
{
         unsigned int n = signal.size();
         unsigned int num_blocks = n / N;


         unsigned int maxblockstart = n - N;
         unsigned int lastblockstart = maxblockstart - (maxblockstart % M);
         unsigned int numbblocks = (lastblockstart)/M + 1;

         std::vector<std::vector<double> > blocked(numbblocks);

         for(unsigned i=0; (i < numbblocks); i++)
         {
                 blocked[i].resize(N);

             for(int j=0; (j < N); j++)
            {
                blocked[i][j] = signal[i*M+j];
            }
        }

         return blocked;
}

I wrote this function, thinking that it did the above, however, it will just store:

X[0] = 1, 2, 3, 4

x[1] = 3, 4, 5, 6

.....

Could anyone please explain how I would go about modifying the above function to allow for skips by overlap to take place?

This function is similar to this: Rolling window

EDIT:

I have the following vector:

1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14

I want to split this vector, into sub-blocks (thus creating a 2D vector), with an overlap of the parameter overlap so in this case, the parameters would be: size=4 overlap=2, this would then create the following 2D vector:

`block0 = [ 1  3  5  7  9 11]

 block1 = [ 2  4  6  8 10 12]

 block2 = [ 3  5  7  9 11 13]

 block3 = [ 4  6  8 10 12 14]`

So essentially, 4 blocks have been created, each block contains a value where the element is skipped by the overlap

EDIT 2:

This is where I need to get to:

The value of overlap will overlap the results of x in terms of placements inside the vector:

block1 = [1, 3, 5, 7, 9, 11] 

Notice from the actual vector block:

1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14

Value: 1 -> This is pushed into block "1"

Value 2 -> This is not pushed into block "1" (overlap is skip 2 places in the vector)

Value 3 -> This is pushed into block "1" 

value 4 -> This is not pushed into block "1" (overlap is skip to places in the vector)

value 5 -> This is pushed into block "1"

value 6 -> "This is not pushed into block "1" (overlap is skip 2 places in the vector)

value 7 -> "This value is pushed into block "1"

value 8 -> "This is not pushed into block "1" (overlap is skip 2 places in the vector)"

value 9 -> "This value is pushed into block "1"

value 10 -> This value is not pushed into block "1" (overlap is skip 2 places in the 
                                                     vector)

value 11 -> This value is pushed into block "1"

BLOCK 2

Overlap = 2; 

value 2 - > Pushed back into block "2" 
value 4 -> Pushed back into  block "2"
value 6, 8, 10 etc.. 

So each time, the place in the vector is skipped by the "overlap" in this case, it is the value of 2..

This is what the expected output would be:

[[ 1  3  5  7  9 11]
 [ 2  4  6  8 10 12]
 [ 3  5  7  9 11 13]
 [ 4  6  8 10 12 14]]
Community
  • 1
  • 1
Phorce
  • 4,424
  • 13
  • 57
  • 107
  • 2
    I don't understand how your sample expected output matches your problem description. Could you write it down completely? –  Jan 24 '14 at 23:29
  • So your code does the correct thing, only rows and columns are swapped? –  Jan 24 '14 at 23:39
  • @Nabla - Yes, I believe so. It's just not skipping to the `overlap` element, it's just splitting at the `overlap` element – Phorce Jan 24 '14 at 23:41
  • It doesn't. What would make sense is (a) "This is what I'm starting with." (you have that), (b) "This is what I want." (you have that). (c) This is **how** I get from (a) to (b) (you *don't* have a clear description of that, at least not one that matches your results from your input). Consequently, the important part (d) "This is what i've tried to get from (a) to (b)." is hard to consolidate with the unclear algorithm at-hand. Edit: reading your update now. – WhozCraig Jan 25 '14 at 00:00
  • Ok. It is *much* clearer once you consider your term block "size" is actually a block *count*. I think I understand now. Is it correct that not all values may necessarily be used in the final output matrix from the original vector? With the right (or wrong) block count and overlap, it is possible. – WhozCraig Jan 25 '14 at 00:02
  • @WhozCraig Please see my updated question, I hope this makes more sense.. I've included a full list of how the algorithm SHOULD work.. – Phorce Jan 25 '14 at 00:08
  • @user1326876 No worries. make sense now. Only question I have left, and it may be obvious but I have to ask. Building each block looks trivial, but where does each block *start*? Is it just the next value in the original sequence after the first value in the prior block? Sry if it is obvious and I missed it. – WhozCraig Jan 25 '14 at 00:10
  • @WhozCraig Hey, no, it's fine =)! So the first block would start at "0" so value 1 and then 2, 3, 4.. Etc.. Let me update once again with an expected output (for this vector) – Phorce Jan 25 '14 at 00:12
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/46052/discussion-between-user1326876-and-whozcraig) – Phorce Jan 25 '14 at 00:14

1 Answers1

1

If I understand you correctly, you're pretty close. You need something like the following. I used int because frankly its easier to type than double =P

#include <iostream>
#include <algorithm>
#include <vector>
#include <limits>
#include <iterator>

std::vector<std::vector<int>>
split(const std::vector<int>& data, size_t blocksize, size_t overlap)
{
    // compute maximum block size
    std::vector<std::vector<int>> res;
    size_t minlen = (data.size() - blocksize)/overlap + 1;
    auto start = data.begin();
    for (size_t i=0; i<blocksize; ++i)
    {
        res.emplace_back(std::vector<int>());
        std::vector<int>& block = res.back();

        auto it = start++;
        for (size_t j=0; j<minlen; ++j)
        {
            block.push_back(*it);
            std::advance(it,overlap);
        }
    }
    return res;
}

int main()
{
    std::vector<int> data { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 };

    for (size_t i=2; i<6; ++i)
    {
        for (size_t j=2; j<6; ++j)
        {
            std::vector<std::vector<int>> blocks = split(data, i, j);

            std::cout << "Blocksize = " << i << ", Overlap = " << j << std::endl;
            for (auto const& obj : blocks)
            {
                std::copy(obj.begin(), obj.end(), std::ostream_iterator<int>(std::cout, " "));
                std::cout << std::endl;
            }
            std::cout << std::endl;
        }
    }
    return 0;
}

Output

Blocksize = 2, Overlap = 2
1 3 5 7 9 11 13 
2 4 6 8 10 12 14 

Blocksize = 2, Overlap = 3
1 4 7 10 13 
2 5 8 11 14 

Blocksize = 2, Overlap = 4
1 5 9 13 
2 6 10 14 

Blocksize = 2, Overlap = 5
1 6 11 
2 7 12 

Blocksize = 3, Overlap = 2
1 3 5 7 9 11 
2 4 6 8 10 12 
3 5 7 9 11 13 

Blocksize = 3, Overlap = 3
1 4 7 10 
2 5 8 11 
3 6 9 12 

Blocksize = 3, Overlap = 4
1 5 9 
2 6 10 
3 7 11 

Blocksize = 3, Overlap = 5
1 6 11 
2 7 12 
3 8 13 

Blocksize = 4, Overlap = 2
1 3 5 7 9 11 
2 4 6 8 10 12 
3 5 7 9 11 13 
4 6 8 10 12 14 

Blocksize = 4, Overlap = 3
1 4 7 10 
2 5 8 11 
3 6 9 12 
4 7 10 13 

Blocksize = 4, Overlap = 4
1 5 9 
2 6 10 
3 7 11 
4 8 12 

Blocksize = 4, Overlap = 5
1 6 11 
2 7 12 
3 8 13 
4 9 14 

Blocksize = 5, Overlap = 2
1 3 5 7 9 
2 4 6 8 10 
3 5 7 9 11 
4 6 8 10 12 
5 7 9 11 13 

Blocksize = 5, Overlap = 3
1 4 7 10 
2 5 8 11 
3 6 9 12 
4 7 10 13 
5 8 11 14 

Blocksize = 5, Overlap = 4
1 5 9 
2 6 10 
3 7 11 
4 8 12 
5 9 13 

Blocksize = 5, Overlap = 5
1 6 
2 7 
3 8 
4 9 
5 10 
WhozCraig
  • 65,258
  • 11
  • 75
  • 141