conj(), conj_physical(), is_conj() and resolve_conj() in PyTorch
Tags: pytorch, conj, conjphysical, isconj
Published: 2024-05-18 16:42:54

*[My post](https://dev.to/hyperkai/real-frac-viewasreal-viewascomplex-and-complex-in-pytorch-57bi) explains [real()](https://pytorch.org/docs/stable/generated/torch.real.html), [frac()](https://pytorch.org/docs/stable/generated/torch.frac.html), [view_as_real()](https://pytorch.org/docs/stable/generated/torch.view_as_real.html) and [view_as_complex()](https://pytorch.org/docs/stable/generated/torch.view_as_complex.html).

[conj()](https://pytorch.org/docs/stable/generated/torch.conj.html) or [conj_physical()](https://pytorch.org/docs/stable/generated/torch.conj_physical.html) can get the 0D or more D tensor of zero or more conjugated elements from the 0D or more D tensor of zero or more elements as shown below:

*Memos:
- `conj()` or `conj_physical()` can be used with [torch](https://pytorch.org/docs/stable/torch.html) or a tensor.
- The 1st argument with `torch` is `input`(Required-Type:`tensor` of `int`, `float`, `complex` or `bool`). *If `input` is not `complex` type, `input` is just returned.
- For `conj_physical()`, there is `out` argument with `torch`(Optional-Type:`tensor`):
  *Memos:
  - `out=` must be used.
  - [My post](https://dev.to/hyperkai/set-out-with-out-argument-functions-pytorch-3ee) explains `out` argument.
- `conj()` can work with [is_conj()](https://pytorch.org/docs/stable/generated/torch.is_conj.html) and [resolve_conj](https://pytorch.org/docs/stable/generated/torch.resolve_conj.html) which I explain later while `conj_physical()` cannot work with them.

```python
import torch

my_tensor = torch.tensor(4.7352+6.1584j)

torch.conj(input=my_tensor)
my_tensor.conj()
torch.conj_physical(input=my_tensor)
my_tensor.conj_physical()
# tensor(4.7352-6.1584j)

my_tensor = torch.tensor([4.7352+6.1584j,
                          2.3706-8.4339j,
                          -9.1648-3.0342j])
torch.conj(input=my_tensor)
torch.conj_physical(input=my_tensor)
# tensor([4.7352-6.1584j,
#         2.3706+8.4339j,
#         -9.1648+3.0342j])

my_tensor = torch.tensor([[4.7352+6.1584j,
                           2.3706-8.4339j,
                           -9.1648-3.0342j],
                          [1.5885+7.2316j,
                           -6.4314+3.9501j,
                           5.7923-4.1148j]])
torch.conj(input=my_tensor)
torch.conj_physical(input=my_tensor)
# tensor([[4.7352-6.1584j,
#          2.3706+8.4339j,
#          -9.1648+3.0342j],
#         [1.5885-7.2316j,
#          -6.4314-3.9501j,
#          5.7923+4.1148j]])

my_tensor = torch.tensor([[4, 2, -9], [1, -6, 5]])

torch.conj(input=my_tensor)
torch.conj_physical(input=my_tensor)
# tensor([[4, 2, -9], [1, -6, 5]])

my_tensor = torch.tensor([[4., 2., -9.], [1., -6., 5.]])

torch.conj(input=my_tensor)
torch.conj_physical(input=my_tensor)
# tensor([[4., 2., -9.], [1., -6., 5.]])

my_tensor = torch.tensor([[True, False, True], [False, True, False]])

torch.conj(input=my_tensor)
torch.conj_physical(input=my_tensor)
# tensor([[True, False, True], [False, True, False]])
```

[is_conj()](https://pytorch.org/docs/stable/generated/torch.is_conj.html) can check if the 0D or more D tensor of zero or more elements outputted by `conj()` is conjugated, getting the scalar of `True` of `False` as shown below:

*Memos:
- `is_conj()` can be used with `torch` or a tensor.
- The 1st argument with `torch` is `input`(Required-Type:`tensor` of `int`, `float`, `complex` or `bool`).

```python
import torch

my_tensor = torch.tensor(4.7352+6.1584j)

torch.is_conj(input=my_tensor)
my_tensor.is_conj()
# False

""" conj() """

c_tensor = torch.conj(input=my_tensor)
c_tensor
# tensor(4.7352-6.1584j)

torch.is_conj(input=c_tensor)
# True

c_c_tensor = torch.conj(input=c_tensor)
c_c_tensor
# tensor(4.7352+6.1584j)

torch.is_conj(input=c_c_tensor)
# False

""" End """

""" conj_physical """

cp_tensor = torch.conj_physical(input=my_tensor)
cp_tensor
# tensor(4.7352-6.1584j)

torch.is_conj(input=cp_tensor)
# False

cp_cp_tensor = torch.conj_physical(input=cp_tensor)
cp_cp_tensor
# tensor(4.7352+6.1584j)

torch.is_conj(input=cp_cp_tensor)
# False

""" End """

my_tensor = torch.tensor([4.7352+6.1584j,
                          2.3706-8.4339j,
                          -9.1648-3.0342j])
torch.is_conj(input=my_tensor)
# False

my_tensor = torch.tensor([[4.7352+6.1584j,
                           2.3706-8.4339j,
                           -9.1648-3.0342j],
                          [1.5885+7.2316j,
                           -6.4314+3.9501j,
                           5.7923-4.1148j]])
torch.is_conj(input=my_tensor)
# False

my_tensor = torch.tensor([[4, 2, -9], [1, -6, 5]])

torch.is_conj(input=my_tensor)
# False

my_tensor = torch.tensor([[4., 2., -9.], [1., -6., 5.]])

torch.is_conj(input=my_tensor)
# False

my_tensor = torch.tensor([[True, False, True], [False, True, False]])

torch.is_conj(input=my_tensor)
# False
```

[resolve_conj()](https://pytorch.org/docs/stable/generated/torch.resolve_conj.html) can get the new 0D or more D tensor of zero or more elements from the 0D or more D tensor of the zero or more elements conjugated from `conj()` as shown below:

*Memos:
- `resolve_conj()` can be used with `torch` or a tensor.
- The 1st argument with `torch` is `input`(Required-Type:`tensor` of `int`, `float`, `complex` or `bool`). *If `input` is not conjugated by `conj()`, `input` is just returned.

```python
import torch

my_tensor = torch.tensor(4.7352+6.1584j)

torch.resolve_conj(input=my_tensor)
my_tensor.resolve_conj()
# tensor(4.7352+6.1584j)

c_tensor = torch.conj(input=my_tensor)
c_tensor
# tensor(4.7352-6.1584j)

torch.is_conj(input=c_tensor)
# True

rc_tensor = torch.resolve_conj(input=c_tensor)
rc_tensor
# tensor(4.7352-6.1584j)

rc_tensor.is_conj(input=rc_tensor)
# False

my_tensor = torch.tensor([4.7352+6.1584j,
                          2.3706-8.4339j,
                          -9.1648-3.0342j])
torch.resolve_conj(input=my_tensor)
# tensor([4.7352+6.1584j,
#         2.3706-8.4339j,
#         -9.1648-3.0342j])

my_tensor = torch.tensor([[4.7352+6.1584j,
                           2.3706-8.4339j,
                           -9.1648-3.0342j],
                          [1.5885+7.2316j,
                           -6.4314+3.9501j,
                           5.7923-4.1148j]])
torch.resolve_conj(input=my_tensor)
# tensor([[4.7352+6.1584j,
#          2.3706-8.4339j,
#          -9.1648-3.0342j],
#         [1.5885+7.2316j,
#          -6.4314+3.9501j,
#          5.7923-4.1148j]])

my_tensor = torch.tensor([[4, 2, -9], [1, -6, 5]])

torch.resolve_conj(input=my_tensor)
# tensor([[4, 2, -9], [1, -6, 5]])

my_tensor = torch.tensor([[4., 2., -9.], [1., -6., 5.]])

torch.resolve_conj(input=my_tensor)
# tensor([[4., 2., -9.], [1., -6., 5.]])

my_tensor = torch.tensor([[True, False, True], [False, True, False]])

torch.resolve_conj(input=my_tensor)
# tensor([[True, False, True], [False, True, False]])
```