C++
STL
convolution
programming
standard library

c stl convolution

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

C++ Standard Library (STL) offers a rich set of data structures and algorithms that facilitate efficient programming. Among various operations, convolution is a fundamental concept in many domains such as signal processing, image processing, and machine learning. Though C++ STL doesn't provide a direct function for convolution, it is possible to implement this operation using STL constructs effectively.

Understanding Convolution

Convolution is a mathematical operation that combines two sequences to produce a third sequence. It is defined as follows:

Given two sequences, a[n] and b[m], the convolution c[k] is defined by:

c[k] = sum_{i=0}^{n} a[i] * b[k - i]

Convolution involves multiplying a flipped version of one of the sequences with another and integrating the result.

Implementing Convolution in C++ STL

Basic Implementation

Let's start with a basic C++ implementation of convolution using vectors. We assume the two sequences are represented by vectors, and the result is also stored in a vector.

cpp
1#include <iostream>
2#include <vector>
3
4std::vector<double> convolution(const std::vector<double>& a, const std::vector<double>& b) {
5    int n = a.size();
6    int m = b.size();
7    int size = n + m - 1;
8    std::vector<double> c(size, 0.0);
9
10    for (int i = 0; i < n; ++i) {
11        for (int j = 0; j < m; ++j) {
12            c[i + j] += a[i] * b[j];
13        }
14    }
15
16    return c;
17}
18
19int main() {
20    std::vector<double> a = {1, 2, 3};
21    std::vector<double> b = {4, 5, 6};
22    std::vector<double> result = convolution(a, b);
23
24    for (double num : result) {
25        std::cout << num << " ";
26    }
27
28    return 0;
29}

Explanation

The function convolution takes two vectors a and b as input and calculates their convolution, returning a new vector c. The size of the resulting vector c is n + m - 1, where n and m are the sizes of a and b. The double loop iteratively multiplies and adds the elements to compute the convolution.

Optimizing Convolution

While the above method works, it has a time complexity of O(n2)O(n^2), which can be inefficient for large sequences. To optimize this, techniques like the Fast Fourier Transform (FFT) can be used. C++ does not provide a native FFT, but libraries such as fftw3 and std::valarray with complex numbers can be utilized for efficient convolution.

Example of Convolution Using FFT

Here's how you might set up convolution using FFT in C++ using the fftw3 library:

cpp
1#include <iostream>
2#include <vector>
3#include <complex>
4#include <fftw3.h>
5
6std::vector<std::complex<double>> fftConvolution(const std::vector<double>& a, const std::vector<double>& b) {
7    int size = 1;
8    while (size < a.size() + b.size()) size <<= 1;
9    
10    std::vector<std::complex<double>> A(size), B(size);
11    for (int i = 0; i < a.size(); ++i) A[i] = a[i];
12    for (int i = 0; i < b.size(); ++i) B[i] = b[i];
13
14    fftw_plan pA = fftw_plan_dft_1d(size, reinterpret_cast<fftw_complex*>(A.data()), 
15                                    reinterpret_cast<fftw_complex*>(A.data()), FFTW_FORWARD, FFTW_ESTIMATE);
16    fftw_plan pB = fftw_plan_dft_1d(size, reinterpret_cast<fftw_complex*>(B.data()), 
17                                    reinterpret_cast<fftw_complex*>(B.data()), FFTW_FORWARD, FFTW_ESTIMATE);
18
19    fftw_execute(pA);
20    fftw_execute(pB);
21    fftw_destroy_plan(pA);
22    fftw_destroy_plan(pB);
23
24    for (int i = 0; i < size; ++i) {
25        A[i] *= B[i];
26    }
27
28    fftw_plan pC = fftw_plan_dft_1d(size, reinterpret_cast<fftw_complex*>(A.data()), 
29                                    reinterpret_cast<fftw_complex*>(A.data()), FFTW_BACKWARD, FFTW_ESTIMATE);
30    fftw_execute(pC);
31    fftw_destroy_plan(pC);
32
33    std::vector<std::complex<double>> result(size);
34    for (int i = 0; i < size; ++i) {
35        result[i] = A[i] / static_cast<double>(size);
36    }
37
38    return result;
39}

Summary Table

Here is a summary of the methods for performing convolution in C++:

MethodDescriptionExample CodeComplexity
Naive ApproachDirect iteration method using nested loops.See Basic Implementation above.O(n2)O(n^2)
FFT ApproachUses Fast Fourier Transform for efficient convolution. Requires additional library.See FFT Example above.O(nlogn)O(n log n) for FFT, O(n)O(n) to combine results

Additional Details

Applications of Convolution

  1. Signal Processing: Used for filtering signals, smoothing, and extracting features.
  2. Image Processing: Convolution is integral to operations such as edge detection, sharpening, and blurring.
  3. Machine Learning: Convolutional Neural Networks (CNNs) leverage convolution to detect patterns in data.

Key Considerations

  • Boundary Effects: Depending on the sequences, convolution may introduce boundary artifacts, often addressed by padding before computation.
  • Complexity: Naive implementation can become a bottleneck for large sequences, hence FFT approaches are favored for substantial performance improvements.

Through proper understanding and application of C++ STL along with external libraries, efficient convolution can be achieved, supporting a wide range of scientific and engineering applications.


Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.