# Sliding Window fasion streaming method
```cpp
#include <iostream>
#include <vector>
// define the list of numbers
std::vector<int> numbers = {1, 2, 3, 4, 5};
// define the convolution kernel
std::vector<int> kernel = {1, 0, 1};
// set the size of the sliding window
int window_size = kernel.size();
// initialize the output list
std::vector<int> output;
// slide the window over the numbers
for (int i = 0; i < numbers.size() - window_size + 1; i++) {
// get the current window of numbers
std::vector<int> window(numbers.begin() + i, numbers.begin() + i + window_size);
// perform the convolution
int convolution = 0;
for (int j = 0; j < window_size; j++) {
convolution += window[j] * kernel[j];
}
// add the result to the output list
output.push_back(convolution);
}
// print the output
for (int value : output) {
std::cout << value << " ";
}
std::cout << std::endl;
```
optimize it with ring buffer
```cpp
#include <iostream>
#include <vector>
// define the list of numbers
std::vector<int> numbers = {1, 2, 3, 4, 5};
// define the convolution kernel
std::vector<int> kernel = {1, 0, 1};
// set the size of the sliding window
int window_size = kernel.size();
// initialize the output list
std::vector<int> output;
// initialize the ring buffer
std::vector<int> ring_buffer(window_size);
int buffer_index = 0;
// slide the window over the numbers
for (int i = 0; i < numbers.size(); i++) {
// add the new number to the ring buffer
ring_buffer[buffer_index] = numbers[i];
buffer_index = (buffer_index + 1) % window_size;
// perform the convolution if the buffer is full
if (i >= window_size - 1) {
int convolution = 0;
for (int j = 0; j < window_size; j++) {
convolution += ring_buffer[j] * kernel[j];
}
// add the result to the output list
output.push_back(convolution);
}
}
// print the output
for (int value : output) {
std::cout << value << " ";
}
std::cout << std::endl;
```
This code will perform convolution on the numbers list using the kernel specified. The convolution will be performed using a sliding window of size 3, which matches the length of the kernel. The window will slide over the list of numbers one element at a time, adding each new number to a ring buffer and performing the convolution on the numbers in the buffer when it is full. Once the window has slid over the entire list of numbers, the code will print the output of the convolution, which will be the list [3, 5, 7, 9].
Using a ring buffer avoids the need to allocate a new vector for the window on each iteration of the for loop, which can improve performance.
You can modify the numbers and kernel vectors to use different values, and the code will use the sliding window method to perform convolution on those numbers.
If you want to perform two convolutions on the same input data, you can simply apply the same sliding window method twice, using different convolution kernels each time. Here is an example of a C++ code that uses a ring buffer to perform two convolutions on a list of numbers using the "Sliding Window" streaming method:
```cpp
#include <iostream>
#include <vector>
// define the list of numbers
std::vector<int> numbers = {1, 2, 3, 4, 5};
// define the first convolution kernel
std::vector<int> kernel1 = {1, 0, 1};
// define the second convolution kernel
std::vector<int> kernel2 = {1, -1, 1};
// set the size of the sliding window
int window_size = kernel1.size();
// initialize the output list
std::vector<int> output;
// initialize the ring buffer
std::vector<int> ring_buffer(window_size);
int buffer_index = 0;
// slide the window over the numbers
for (int i = 0; i < numbers.size(); i++) {
// add the new number to the ring buffer
ring_buffer[buffer_index] = numbers[i];
buffer_index = (buffer_index + 1) % window_size;
// perform the convolution if the buffer is full
if (i >= window_size - 1) {
// perform the first convolution
int convolution1 = 0;
for (int j = 0; j < window_size; j++) {
convolution1 += ring_buffer[j] * kernel1[j];
}
// perform the second convolution
int convolution2 = 0;
for (int j = 0; j < window_size; j++) {
convolution2 += ring_buffer[j] * kernel2[j];
}
// add the results to the output list
output.push_back(convolution1);
output.push_back(convolution2);
}
}
// print the output
for (int value : output) {
std::cout << value << " ";
}
std::cout << std::endl;
```
This code will perform two convolutions on the numbers list, using the kernel1 and kernel2 kernels specified. The convolutions will be performed using a sliding window of size 3, which matches the length of the kernels. The window will slide over the list of numbers one element at a time, adding each new number to a ring buffer and performing the convolutions on the numbers in the buffer when it is full. Once the window has slid over the entire list of numbers, the code will print the output of the convolutions, which will be the list [3, 5, 7, 9, 2, 4, 6, 8].
You can modify the numbers, kernel1, and kernel2 vectors to use different values, and the code will use the sliding window method to perform the convolutions on those numbers.
If you want to perform two convolutions on the same input data, and use the output of the first convolution as the input for the second convolution, you can do this by performing the convolutions one after the other using the same sliding window and ring buffer. Here is an example of a C++ code that uses a ring buffer to perform two convolutions on a list of numbers using the "Sliding Window" streaming method, with the output of the first convolution being used as the input for the second convolution:
```cpp
#include <iostream>
#include <vector>
// define the list of numbers
std::vector<int> numbers = {1, 2, 3, 4, 5};
// define the first convolution kernel
std::vector<int> kernel1 = {1, 0, 1};
// define the second convolution kernel
std::vector<int> kernel2 = {1, -1, 1};
// set the size of the sliding window
int window_size = kernel1.size();
// initialize the output list
std::vector<int> output;
// initialize the ring buffer
std::vector<int> ring_buffer(window_size);
int buffer_index = 0;
// slide the window over the numbers
for (int i = 0; i < numbers.size(); i++) {
// add the new number to the ring buffer
ring_buffer[buffer_index] = numbers[i];
buffer_index = (buffer_index + 1) % window_size;
// perform the convolution if the buffer is full
if (i >= window_size - 1) {
// perform the first convolution
int convolution1 = 0;
for (int j = 0; j < window_size; j++) {
convolution1 += ring_buffer[j] * kernel1[j];
}
// update the ring buffer with the result of the first convolution
ring_buffer[buffer_index] = convolution1;
buffer_index = (buffer_index + 1) % window_size;
// perform the second convolution
int convolution2 = 0;
for (int j = 0; j < window_size; j++) {
convolution2 += ring_buffer[j] * kernel2[j];
}
// add the results to the output list
output.push_back(convolution1);
output.push_back(convolution2);
}
}
// print the output
for (int value : output) {
std::cout << value << " ";
}
std::cout << std::endl;
```
overlapped tiling:
```cpp
#include <iostream>
#include <vector>
#include <thread>
// define the input dataset
std::vector<int> data = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
// define the size of the tiles
int tile_size = 3;
// define the overlap between tiles
int tile_overlap = 1;
// define the function to process each tile
void processTile(const std::vector<int>& tile) {
// perform some processing on the tile...
std::cout << "Processing tile: ";
for (int value : tile) {
std::cout << value << " ";
}
std::cout << std::endl;
}
int main() {
// create a list of threads to process the tiles
std::vector<std::thread> threads;
// split the data into tiles and process them in parallel
for (int i = 0; i < data.size(); i += tile_size - tile_overlap) {
// define the start and end indices for the tile
int start = i;
int end = std::min(i + tile_size, (int)data.size());
// create a vector for the tile data
std::vector<int> tile(data.begin() + start, data.begin() + end);
// create a new thread to process the tile
threads.push_back(std::thread(processTile, tile));
}
// wait for all threads to finish
for (std::thread& thread : threads) {
thread.join();
}
return 0;
}
```
apply overlapped tiling on the streamming method
```cpp
#include <iostream>
#include <vector>
#include <thread>
// define the input dataset
std::vector<int> data = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
// define the first convolution kernel
std::vector<int> kernel1 = {1, 0, 1};
// define the second convolution kernel
std::vector<int> kernel2 = {1, -1, 1};
// define the size of the sliding window
int window_size = kernel1.size();
// define the size of the tiles
int tile_size = 3;
// define the overlap between tiles
int tile_overlap = 1;
// define the function to process each tile
void processTile(const std::vector<int>& tile, std::vector<int>& output) {
// initialize the ring buffer
std::vector<int> ring_buffer(window_size);
int buffer_index = 0;
// slide the window over the tile data
for (int i = 0; i < tile.size(); i++) {
// add the new number to the ring buffer
ring_buffer[buffer_index] = tile[i];
buffer_index = (buffer_index + 1) % window_size;
// perform the convolution if the buffer is full
if (i >= window_size - 1) {
// perform the first convolution
int convolution1 = 0;
for (int j = 0; j < window_size; j++) {
convolution1 += ring_buffer[j] * kernel1[j];
}
// update the ring buffer with the result of the first convolution
ring_buffer[buffer_index] = convolution1;
buffer_index = (buffer_index + 1) % window_size;
// perform the second convolution
int convolution2 = 0;
for (int j = 0; j < window_size; j++) {
convolution2 += ring_buffer[j] * kernel2[j];
}
// add the results to the output list
output.push_back(convolution2);
}
}
}
int main() {
// create a list of threads to process the tiles
std::vector<std::thread> threads;
// initialize the output list
std::vector<int> output;
// split the data into tiles and process them in parallel
for (int i = 0; i < data.size(); i += tile_size - tile_overlap) {
// define the start and end indices for the tile
int start = i;
int end = std::min(i + tile_size, (int)data.size());
// create a vector for the tile data
std::vector<int> tile(data.begin() + start, data.begin() + end);
// create a new thread to process the tile
threads.push_back(std::thread(processTile, tile, std::ref(output)));
}
// wait for all threads to finish
for (std::thread& thread : threads) {
thread.join();
}
// print the output list
std::cout << "Output: ";
for (int value : output) {
std::cout << value << " ";
}
std::cout << std::endl;
return 0;
}
```
This code will split the data input dataset into tiles of size 3 with an overlap of 1 between each tile. For each tile, it will create a new thread to process the tile data using the processTile function. This function will perform two convolutions on the tile data using the "Sliding Window" streaming method, with the output of the first convolution being used as the input for the second convolution, but not included in the final result. The output of the second convolution will be added to the output list. Finally, the main function will wait for all threads to finish and print the contents of the output list.