Repository: pytorch
Issue: Reciprocals of complex tensors with infinities are different from NumPy.
Labels: triaged,module: complex,module: numpy,module: NaNs and Infs

## 🐛 Bug

As per title.

## To Reproduce

```python
In [1]: import torch
In [2]: import numpy as np
# interesting part from educational point of view
In [3]: t = torch.tensor(float('inf'), dtype=torch.cdouble)
In [4]: t.pow(-1)
Out[4]: tensor(nan+nanj, dtype=torch.complex128)
In [5]: a = np.array([float('inf') + 0j])
In [6]: np.power(a, -1)
/home/nik/.conda/envs/pytorch-cuda-dev/bin/ipython:1: RuntimeWarning: invalid value encountered in power
  #!/home/nik/.conda/envs/pytorch-cuda-dev/bin/python
Out[6]: array([nan+nanj])
In [7]: (float('inf') + 0j)**(-1)
Out[7]: (nan+nanj)
### THE PITCH OF THE ISSUE IS RIGHT BELOW
In [8]: 1 / ((float('inf') + 0j))
Out[8]: 0j
In [9]: 1 / t
Out[9]: tensor(nan+nanj, dtype=torch.complex128)
In [10]: 1 / a
Out[10]: array([0.+0.j])
```

## Additional context

I just speculate, but after checking some code it seems like in `1 / complex_tensor`, `1` gets promoted to a complex number,
see 
https://github.com/pytorch/pytorch/blob/4e36891e4fc44623be98bd5543b8ffed85e95b90/c10/util/complex.h#L375-L379
Then in the complex division https://github.com/pytorch/pytorch/blob/4e36891e4fc44623be98bd5543b8ffed85e95b90/c10/util/complex.h#L218-L229
we will encounter a product `b * c == 0 * inf == nan` in the imaginary part, and `inf / inf == nan` in the real part, for `a + ib = 1 + i0, c + id = inf + i0`.

Just a bit more of experimentation:
```python
In [1]: inf = float('inf') + 0j

In [2]: 1/ inf
Out[2]: 0j

In [3]: (1 + 0j) / inf
Out[3]: 0j

In [4]: inf
Out[4]: (inf+0j)

In [5]: import numpy as np

In [6]: a = np.array([inf])

In [7]: a
Out[7]: array([inf+0.j])

In [8]: 1 / a
Out[8]: array([0.+0.j])

In [9]: (1 + 0j) / a
Out[9]: array([0.+0.j])

In [10]: (1 + 1j) / a
Out[10]: array([0.+0.j])

In [11]: import torch

In [12]: t = torch.tensor([inf])

In [13]: 1 / t
Out[13]: tensor([nan+nanj])

In [14]: (1 + 0j) / t
Out[14]: tensor([nan+nanj])

In [15]: (1 + 1j) / t
Out[15]: tensor([nan+nanj])

```

An extreme case where Python/Numpy/Pytorch agree, but I am not sure it is correct:
```python
In [1]: import torch
i
In [2]: import numpy as np

In [3]: val = float('inf') + 1j

In [4]: t = torch.tensor([val], dtype=torch.cdouble)

In [5]: a = np.array([val])

In [6]: 1 / t
Out[6]: tensor([nan+nanj], dtype=torch.complex128)

In [7]: 1 / a
Out[7]: array([0.+0.j])

In [8]: 1 / val
Out[8]: 0j

In [9]: import cmath

In [10]: val = cmath.inf + cmath.infj

In [11]: t = torch.tensor([val], dtype=torch.cdouble)

In [12]: a = np.array([val])

In [13]: 1 / t
Out[13]: tensor([nan+nanj], dtype=torch.complex128)

In [14]: 1 / a
/home/nik/.conda/envs/pytorch-cuda-dev/bin/ipython:1: RuntimeWarning: invalid value encountered in true_divide
  #!/home/nik/.conda/envs/pytorch-cuda-dev/bin/python
Out[14]: array([nan+nanj])

In [15]: 1 / val
Out[15]: (nan+nanj)

```

It looks like Python treats the pure imaginary infinity differently from the pure real one:
```python
>>> import cmath
>>> val = cmath.inf + cmath.infj
>>> val * val.conjugate()
(inf+nanj)
>>> cmath.inf * cmath.infj
(nan+infj)

```

cc @ezyang @anjali411 @dylanbespalko @mruberry @rgommers @heitorschueroff