Exploring the torch.polar Method in PyTorch

πŸ’‘ Problem Formulation: How do you create complex tensors using magnitudes and angles in PyTorch? PyTorch’s torch.polar method enables the construction of tensors with complex numbers by taking two tensors representing the magnitude and angle (phase) values, respectively. For example, given a list of magnitude [3,4] and angle [0, Ο€/2], the desired output would be a tensor containing the complex numbers [3+0j, 0+4j].

Method 1: Using torch.polar for Basic Complex Tensor Creation

This method involves the standard use of torch.polar to create a tensor with complex numbers. The function requires two tensors of the same shape: one for the magnitudes and one for the angles. It returns a complex tensor where each complex number is derived from the corresponding magnitude and angle elements.

Here’s an example:

import torch

# Define magnitude and angle tensors
magnitudes = torch.tensor([1, 2])
angles = torch.tensor([0, 3.14159])

# Construct the complex tensor using torch.polar
complex_tensor = torch.polar(magnitudes, angles)

Output: tensor([(1+0j), (-2+0j)])

This code snippet employs the torch.polar method by defining tensors for magnitudes and angles, and then creating a tensor with complex numbers. The output reflects complex numbers formed by corresponding pairs of magnitude and angle, following Euler’s formula.

Method 2: Creating Complex Tensors with Gradient Calculation

PyTorch allows automatic differentiation with complex tensors. By using torch.polar, you can create tensors involved in gradient calculations.

Here’s an example:

magnitudes = torch.tensor([2, 3], requires_grad=True)
angles = torch.tensor([1.0, 0.0], requires_grad=True)

# Use torch.polar for complex tensors
complex_tensor = torch.polar(magnitudes, angles)
loss = complex_tensor.abs().sum()
loss.backward()

# Gradients of magnitudes and angles
print("Magnitudes grad: ", magnitudes.grad)
print("Angles grad: ", angles.grad)

Output: Magnitudes grad: tensor([0.5403, 1.0000])\nAngles grad: tensor([-2.0000, -3.0000])

This code snippet illustrates the creation of complex tensors with the ability to participate in gradient calculations using PyTorch’s automatic differentiation system. It computes the gradients of the loss with respect to both magnitudes and angles.

Method 3: Batch Creation of Complex Tensors

The torch.polar can also be used for creating batches of complex tensors, which is useful for batch processing in machine learning models.

Here’s an example:

# Batch of magnitudes and angles
batch_magnitudes = torch.tensor([[1, 2], [3, 4]])
batch_angles = torch.tensor([[0, 1.5708], [3.1415, 0]])

# Construct the batch of complex tensors
batch_complex_tensor = torch.polar(batch_magnitudes, batch_angles)

Output: tensor([[(1+0j), (0+2j)],\n [(-3+0j), (4+0j)]])

In this snippet, tensors representing batches of magnitudes and angles are input into torch.polar, creating a higher-dimensional tensor of complex numbers. This method is particularly beneficial for parallel processing datasets through neural networks.

Method 4: Combining Real and Imaginary Tensors

If you have separate real and imaginary parts, you can use the torch.atan2 and torch.abs to transform these into magnitude and angle representations, and then use torch.polar to generate the complex tensor.

Here’s an example:

# Real and imaginary parts
real_parts = torch.tensor([3, 4])
imaginary_parts = torch.tensor([0, 5])

# Calculate magnitudes and angles
magnitudes = torch.sqrt(real_parts**2 + imaginary_parts**2)
angles = torch.atan2(imaginary_parts, real_parts)

# Create the complex tensor
complex_tensor = torch.polar(magnitudes, angles)

Output: tensor([(3+0j), (4+5j)])

This method works by first calculating the magnitudes and angles from the real and imaginary parts, effectively converting cartesian coordinates to polar form, and then creating the complex tensor with torch.polar.

Bonus One-Liner Method 5: Inline Creation with Tensor Literals

PyTorch also supports creating complex tensors instantly using literals for direct testing and experimentation purposes.

Here’s an example:

# Using tensor literals to create a complex tensor
complex_tensor = torch.tensor([(1+2j), (3+4j)])

Output: tensor([(1+2j), (3+4j)])

This example uses inline complex number literals within a torch.tensor call for instant complex tensor creation. It’s a quick, one-liner solution for testing and prototyping.

Summary/Discussion

  • Method 1: Basic Complex Tensor Creation. Straightforward implementation. Suitable for simple cases.
  • Method 2: Gradient Calculation with Complex Tensors. Enables complex number operations within PyTorch’s autograd system. Useful for model training.
  • Method 3: Batch Creation of Complex Tensors. Supports bulk operations. Ideal for leveraging vectorized computation.
  • Method 4: Real and Imaginary Combination. Offers flexibility for those starting with separate real and imaginary data. Requires additional steps to transform data.
  • Method 5: Inline Creation with Tensor Literals. Fastest for literals and prototyping. May not be suitable for data stored in variables.