import matplotlib.pyplot as plt
import numpy as np
%matplotlib inline
np.set_printoptions(precision=3, suppress=True)


if(1j**2==-1):
  print("Complex Number")
else:
  print("Not a Complex Number")

x = 3.5 + 2.1j
print("Type of x:" , type(x))
print("Real part of x:", x.real)
print("Imaginary part of x:", x.imag)

def plot_complex(a):
    for x in range(len(a)):
        plt.plot([0,a[x].real], [0,a[x].imag], 'r-o')
    plt.axhline(y=0, color='k')
    plt.axvline(x=0, color='k')
    plt.ylabel('Imaginary')
    plt.xlabel('Real')
    limit = np.max(np.ceil(np.absolute(a)))
    plt.xlim((-limit,limit))
    plt.ylim((-limit,limit))    
    plt.show()

plot_complex([x])

abs(x)

r = abs(x)
φ = np.arctan2(x.imag, x.real)
z = r*np.exp(1j*φ)
z == x

print(x.conjugate())
plot_complex([x.conjugate()])

a = np.array([[1+2j], [2+2j]])
a

a.T.conj()

b = np.array([[0.1], [2j]])
b.T.conj() @ a

c = np.array([[1], [0]])
d = np.array([[0], [1]])
c.T.conj() @ d

print("The square of the l2 norm of a:", np.linalg.norm(a)**2)
print("The same thing calculated as an inner product:", a.T.conj() @ a)

sum(a != 0), sum(c != 0)

np.linalg.norm(a, ord=1)

np.kron(c, d)

A = np.array([[1+2j, 2], [1j, 3+4j]])
A

A.T.conj()

A @ a

a @ a.T.conj()

λs, eigenvectors = np.linalg.eig(A)

np.all(A == A.T.conj())

B = a @ a.T.conj()
np.all(B == B.T.conj())