Stdpolar Function In C++ - C++ Programming Tutorial
C++ Course / Functions / Stdpolar Function In C++

Stdpolar Function In C++

BLUF: Mastering Stdpolar Function In C++ is a critical step in becoming a proficient C++ developer. This lesson provides a deep dive into the syntax, performance considerations, and real-world applications of this concept.
Key Performance Insight: Stdpolar Function In C++

C++ is renowned for its efficiency. Learn how Stdpolar Function In C++ enables low-level control and high-performance computing in the tutorial below.

Introduction

When it comes to C++ programming, the Standard Template Library (STL) offers a range of functionalities to aid in handling intricate numbers and their connections. Among these features, the std::polar function is notable for its ability to transform a number's polar coordinate representation into its associated complex number. Polar coordinates allow the depiction of a point using two values: the radial coordinate (magnitude) and the angular coordinate (phase). This geometric representation is beneficial in fields like signal processing, physics, engineering, and various other scientific and mathematical applications.

In this guide, our focus will be on the std::polar function in C++, exploring its practical applications, syntax, and providing code examples to demonstrate the transformation of polar coordinates.

Problem Statement

Various mathematical and engineering systems rely on the use of complex numbers in a polar representation where a specific area of the complex plane can be characterized by two values:

  • r (also known as radius): Indicating the distance of the point from the origin.
  • θ (also known as phase): Representing the angle formed between the point and the x-axis, measured in a clockwise direction from the positive x-axis.

Nevertheless, it is important to highlight that within the C++ programming language, there are no built-in capabilities to handle operations within a polar coordinate system that includes complex numbers. Therefore, whenever there arises a situation where complex numbers need to be utilized in C++, it becomes essential to convert the polar coordinates into the standard rectangular form, which consists of the real and imaginary components.

The std::polar function offers a distinct and standardized method for converting coordinates from polar form to a complex number without the necessity of individually indicating the real and imaginary components.

The polar function

The std::polar function originates from the cluster-templated class within the C++ library. It serves the purpose of constructing a complex number based on polar coordinates. In a broader sense, the function can be represented as:

Example

#include <complex>
std::complex<double> std::polar(double r, double theta = 0.0);
  • r: It refers to the size (radial) of the complex number.
  • theta: It refers to the angle of phase shift in radians relative to the horizontal side of the x-axis. If it is omitted, it becomes 0.0.

The output of this function is an instance of std::complex, represented in the format of a complex number a+bi, where 'a' represents the real part and 'b' represents the imaginary part. These real and imaginary components are obtained from polar coordinates as follows:

Example

real_part = r * cosine(θ)
imaginary_part = r * sine(θ)

Main Importances of polar function:

  • This feature has simplified the process of determining the real and imaginary parts of the number with the use of trigonometric functions.
  • It has maintained the correctness as the conversion is performed in double precision floating point in the background.
  • The default value for the angle makes the case that there is only an amount supplied easier in that there is no provision for both the angle and the amount.
  • Program 1:

Example

#include <iostream>
#include <complex>
#include <cmath> // for M_PI

int main() {
    // Polar coordinates: magnitude = 5, angle = pi/4 radians
    double r = 5.0;
    double theta = M_PI / 4.0;

    // Convert polar coordinates to complex number
    std::complex<double> complex_num = std::polar(r, theta);

    // Display the result
    std::cout << "Complex number (Cartesian form): " << complex_num << std::endl;
    std::cout << "Real part: " << complex_num.real() << std::endl;
    std::cout << "Imaginary part: " << complex_num.imag() << std::endl;

    return 0;
}

Output:

Output

Complex number (Cartesian form): (3.53553,3.53553)
Real part: 3.53553
Imaginary part: 3.53553

Explanation:

  • r = 5.0: It is the magnitude of the complex number.
  • theta = M_PI / 4.0: It is the angle (in radians) equivalent to 45 degrees.
  • The std::polar(r, theta) converts the polar coordinates (r, θ) into a complex number (real, imaginary).
  • The result is printed, where both the real and imaginary parts are approximately 3.5355.
  • Time and Space Complexities:

Time Complexity: O(1)

  • Constant time complexity is observed for the std::polar and std::cout operations.

Space Complexity: O(1)

  • Constant memory allocation for variables r, theta, and the complex number.
  • Program 2:

Example

#include <iostream>
#include <complex>

int main() {
    // Polar coordinates: magnitude = 4, angle = 0 (default)
    double r = 4.0;

    // Convert polar coordinates to complex number
    std::complex<double> complex_num = std::polar(r);

    // Display the result
    std::cout << "Complex number (Cartesian form): " << complex_num << std::endl;
    return 0;
}

Output:

Output

Complex number (Cartesian form): (4,0)

Explanation:

  • r = 4.0: This is the magnitude.
  • The std::polar(r) uses the default angle θ = 0, so the resulting complex number is purely real (4 + 0i).
  • The output shows the real part as 4, and the imaginary part as 0.
  • Time and Space Complexities:

Time Complexity: Constant

  • Utilizing the std::polar method and displaying the output both operate in constant time.

Space Complexity: O(1)

  • Constant space is allocated for both the magnitude (r) and the complex number, without any need for dynamic memory allocation.
  • Advanced Testing Features

  • While utilizing the std::polar function, a few edge cases must also be taken into account: Assuming a Negative Radius: Depending on the dimension, the negative radius may pose some undesired outcomes since the ratio is usually regarded as a positive number. It's advisable to avoid r< 0 in your code unless you're assuming unconventional definitions.
  • Precision Issues: Because of the nature of numbers, the rounding of a very tiny or large magnitude value or even an angle should be avoided, which may apparently appear in this formulation. C++ handles this quite well and comfortably for most practical applications, but still, this is something that has to be kept in mind while dealing with very extreme values.
  • Program 3:

Example

#include <iostream>
#include <complex>
#include <cmath> // for trigonometric functions and M_PI

int main() {
    const int size = 5;
    double magnitudes[size] = {3.0, 4.0, 5.0, 6.0, 7.0};  // Magnitudes (r)
    double angles[size] = {M_PI/6, M_PI/4, M_PI/3, M_PI/2, M_PI};  // Angles (θ in radians)
    
    std::complex<double> complex_numbers[size];

    // Create an array of complex numbers using polar coordinates
    for (int i = 0; i < size; ++i) {
        complex_numbers[i] = std::polar(magnitudes[i], angles[i]);
    }

    // Display the complex numbers in Cartesian form
    std::cout << "Complex numbers (Cartesian form):" << std::endl;
    for (int i = 0; i < size; ++i) {
        std::cout << "Complex number " << i+1 << ": " << complex_numbers[i] << std::endl;
    }

    // Perform mathematical operations: Calculate the sum of all complex numbers
    std::complex<double> sum = 0;
    for (int i = 0; i < size; ++i) {
        sum += complex_numbers[i];
    }

    // Display the sum
    std::cout << "\nSum of all complex numbers: " << sum << std::endl;

    // Perform mathematical operations: Calculate the product of all complex numbers
    std::complex<double> product = 1;
    for (int i = 0; i < size; ++i) {
        product *= complex_numbers[i];
    }

    // Display the product
    std::cout << "Product of all complex numbers: " << product << std::endl;

    return 0;
}

Output:

Output

Complex numbers (Cartesian form):
Complex number 1: (2.59808,1.5)
Complex number 2: (2.82843,2.82843)
Complex number 3: (2.5,4.33013)
Complex number 4: (3.67394e-16,6)
Complex number 5: (-7,8.57253e-16)

Sum of all complex numbers: (0.926503,14.6586)
Product of all complex numbers: (1781.91,1781.91)

Explanation:

  • Array of Complex Numbers: We introduce two arrays, which are the magnitudes and the angles, where the magnitude and the angle join to have denoted in polar coordinates.
  • Creating Complex Numbers: A loop is employed where, for each set of polar coordinates, a respective complex number is formed with std::polar.
  • Displaying Cartesian Form: The resultant complex numbers are brought out in Cartesian form.
  • Sum and Product: The sum of all the complex numbers and the product of all those complex numbers are computed, showing how manipulations can be done with complex numbers in C++.
  • Time and Space Complexities:

Time Complexity: O(n)

  • Iterations for generating, showcasing, totaling, and calculating complex numbers occur n times in each iteration.

Space Complexity: O(n)

  • Arrays representing magnitudes, angles, and complex numbers all require memory in direct proportion to the size of n.
  • Program 4:

Example

#include <iostream>
#include <vector>
#include <complex>
#include <cmath>  // For sin, cos, and M_PI
#include <iomanip> // For controlling the precision of output

const double PI = M_PI;

// Function to compute the DFT of a given signal
std::vector<std::complex<double>> computeDFT(const std::vector<std::complex<double>>& inputSignal) {
    int N = inputSignal.size();
    std::vector<std::complex<double>> dftResult(N);

    // DFT formula: X(k) = sum( x(n) * exp(-2 * pi * i * k * n / N) )
    for (int k = 0; k < N; ++k) {
        std::complex<double> sum(0.0, 0.0);

        for (int n = 0; n < N; ++n) {
            double angle = -2 * PI * k * n / N;
            std::complex<double> expTerm = std::polar(1.0, angle); // e^(i * angle)
            sum += inputSignal[n] * expTerm;
        }
        dftResult[k] = sum;
    }
    return dftResult;
}

// Function to convert complex numbers to polar coordinates (magnitude and phase)
void displayPolarForm(const std::vector<std::complex<double>>& complexNumbers) {
    std::cout << "\nDFT Result in Polar Form (Magnitude, Phase in Radians):\n";
    for (size_t i = 0; i < complexNumbers.size(); ++i) {
        double magnitude = std::abs(complexNumbers[i]);
        double phase = std::arg(complexNumbers[i]);
        std::cout << "X(" << i << "): Magnitude = " << magnitude
                  << ", Phase = " << phase << " radians\n";
    }
}

int main() {
    // Input signal (in time domain)
    std::vector<std::complex<double>> inputSignal = {
        {1.0, 0.0}, {2.0, 0.0}, {3.0, 0.0}, {4.0, 0.0}
    };

    // Display the input signal
    std::cout << "Input Signal (Time Domain):\n";
    for (size_t i = 0; i < inputSignal.size(); ++i) {
        std::cout << "x(" << i << ") = " << inputSignal[i] << "\n";
    }

    // Compute the DFT
    std::vector<std::complex<double>> dftResult = computeDFT(inputSignal);

    // Display the DFT result in Cartesian form
    std::cout << "\nDFT Result (Frequency Domain, Cartesian Form):\n";
    for (size_t i = 0; i < dftResult.size(); ++i) {
        std::cout << "X(" << i << ") = " << dftResult[i] << "\n";
    }

    // Display the DFT result in Polar Form
    displayPolarForm(dftResult);

    return 0;
}

Output:

Output

Input Signal (Time Domain):
x(0) = (1,0)
x(1) = (2,0)
x(2) = (3,0)
x(3) = (4,0)

DFT Result (Frequency Domain, Cartesian Form):
X(0) = (10,0)
X(1) = (-2,2)
X(2) = (-2,-9.79717e-16)
X(3) = (-2,-2)

DFT Result in Polar Form (Magnitude, Phase in Radians):
X(0): Magnitude = 10, Phase = 0 radians
X(1): Magnitude = 2.82843, Phase = 2.35619 radians
X(2): Magnitude = 2, Phase = -3.14159 radians
X(3): Magnitude = 2.82843, Phase = -2.35619 radians

Explanation:

  • Input Signal: A signal in the time domain is called the inputSignal and can be represented as a vector of complex numbers. Basically, all of these values are usually (1.0, 2.0, 3.0, and 4.0), but the DFT works for complex values as well.
  • Discrete Fourier Transform (DFT):
  • A signal in the time domain is called the inputSignal and can be represented as a vector of complex numbers. Basically, all of these values are usually (1.0, 2.0, 3.0, and 4.0), but the DFT works for complex values as well.
  • The output of the transformed signal or the DFT result is portrayed in a cartesian form (real + imaginary).
  • Components of DFT are also presented in polar values, using magnitude and phase of frequency components' standard form using std::abs and std::arg, respectively.
  • std::polar: Analyzes an angle and gives the result in a complex exponential representation.
  • std::abs: This function is similar to a complex modulus in that it determines the length or the modulus of a complex number in terms of e.
  • std::arg: This is an operator , which enables solving the arguments of the complex number of which some of the operations have been done.
  • Time and Space Complexities:

For every frequency bin k, the inner loop iterates through N times to calculate a sum, and since there are N frequency bins, the overall time complexity amounts to O(N²).

Space Complexity: O(N)

The storage required for the input signal, DFT outcome, total, and the temporary variable expTerm is proportional to N. Therefore, the space complexity is O(N).

Conclusion

In summary, the std::polar function serves as a valuable tool for C++ developers when converting polar coordinates to complex numbers. This functionality simplifies the manipulation of complex numbers in mathematical and engineering applications. One key advantage of using this function is its ability to extract both real and imaginary components directly from the modulus and phase, streamlining the development process.

Utilizing std::polar enables C++ developers to extend their capabilities beyond C++ by effortlessly switching between polar and Cartesian coordinates of complex numbers, facilitating complex computations in various domains.

Input Required

This code uses input(). Please provide values below:

Logic Practice
Install Logic Practice
Add to home screen for a faster app-like experience