Pytorch Torch Adjoint
## PyTorch torch.adjoint
The `torch.adjoint` function in PyTorch is used to compute the conjugate transpose (also known as the Hermitian transpose or adjoint) of a tensor.
* For **real-valued tensors**, this operation is equivalent to a standard matrix transpose.
* For **complex-valued tensors**, it transposes the dimensions and conjugates each element (negating the imaginary part).
---
### Function Definition
```python
torch.adjoint(input) -> Tensor
```
#### Parameters:
* **`input`** (*Tensor*): The input tensor. It must have at least 2 dimensions.
#### Returns:
* **`Tensor`**: A view of the input tensor with its last two dimensions transposed and conjugated.
> **Note:** `torch.adjoint` returns a view of the original tensor whenever possible. This means modifying the returned tensor will also modify the original tensor.
---
## Code Examples
### Example 1: Real-Valued Matrix
For a real-valued matrix, `torch.adjoint` performs a standard transposition.
```python
import torch
# Create a real-valued matrix
A = torch.tensor([[1, 2, 3], [4, 5, 6]])
# Compute the adjoint (conjugate transpose)
result = torch.adjoint(A)
print("Original Matrix:")
print(A)
print("Shape:", A.shape)
print("\nAdjoint Matrix:")
print(result)
print("Shape:", result.shape)
```
**Output:**
```text
Original Matrix:
tensor([[1, 2, 3],
[4, 5, 6]])
Shape: torch.Size([2, 3])
Adjoint Matrix:
tensor([[1, 4],
[2, 5],
[3, 6]])
Shape: torch.Size([3, 2])
```
---
### Example 2: Complex-Valued Matrix
For a complex-valued matrix, `torch.adjoint` transposes the matrix and negates the imaginary part of each element.
```python
import torch
# Create a complex-valued matrix
A = torch.tensor([[1+1j, 2+2j], [3+3j, 4+4j]])
# Compute the adjoint (conjugate transpose)
result = torch.adjoint(A)
print("Original Matrix:")
print(A)
print("\nAdjoint Matrix:")
print(result)
```
**Output:**
```text
Original Matrix:
tensor([[1.+1.j, 2.+2.j],
[3.+3.j, 4.+4.j]])
Adjoint Matrix:
tensor([[1.-1.j, 3.-3.j],
[2.-2.j, 4.-4.j]])
```
---
### Example 3: Batch Adjoint (Multi-dimensional Tensors)
`torch.adjoint` also supports batched operations. If the input tensor has more than 2 dimensions, the adjoint is computed over the last two dimensions.
```python
import torch
# Create a batched complex tensor of shape (2, 2, 3)
A = torch.randn(2, 2, 3, dtype=torch.complex64)
# Compute the adjoint
result = torch.adjoint(A)
print("Original Shape:", A.shape)
print("Adjoint Shape:", result.shape)
```
**Output:**
```text
Original Shape: torch.Size([2, 2, 3])
Adjoint Shape: torch.Size([2, 3, 2])
```
---
## Key Considerations
1. **Memory Efficiency**: `torch.adjoint` is an extremely efficient $O(1)$ operation because it returns a **view** of the original tensor rather than copying data in memory.
2. **Shorthand Notation**: You can also use the shorthand property `.adjoint()` or `.H` on a PyTorch tensor to achieve the same result:
```python
# These three lines are equivalent:
result = torch.adjoint(A)
result = A.adjoint()
result = A.H
```
3. **Dimensionality**: The input tensor must have at least 2 dimensions. Calling `torch.adjoint` on a 1D tensor (vector) will raise a `RuntimeError`.
YouTip