import numpy as np

# Union of two BCNMs
def union(A, B):
    answer = np.zeros_like(A)

    # Apply component-wise operations based on the definition
    answer[:,:,0,0] = np.maximum(A[:,:,0,0], B[:,:,0,0])  # maximum(alpha+ amplitude)
    answer[:,:,0,1] = np.maximum(A[:,:,0,1], B[:,:,0,1])  # maximum(alpha+ angle)

    answer[:,:,1,0] = np.minimum(A[:,:,1,0], B[:,:,1,0])  # minimum(beta+ amplitude)
    answer[:,:,1,1] = np.minimum(A[:,:,1,1], B[:,:,1,1])  # minimum(beta+ angle)

    answer[:,:,2,0] = np.minimum(A[:,:,2,0], B[:,:,2,0])  # minimum(gamma+ amplitude)
    answer[:,:,2,1] = np.minimum(A[:,:,2,1], B[:,:,2,1])  # minimum(gamma+ angle)

    answer[:,:,3,0] = np.minimum(A[:,:,3,0], B[:,:,3,0])  # minimum(alpha- amplitude)
    answer[:,:,3,1] = np.minimum(A[:,:,3,1], B[:,:,3,1])  # minimum(alpha- angle)

    answer[:,:,4,0] = np.maximum(A[:,:,4,0], B[:,:,4,0])  # maximum(beta- amplitude)
    answer[:,:,4,1] = np.maximum(A[:,:,4,1], B[:,:,4,1])  # maximum(beta- angle)

    answer[:,:,5,0] = np.maximum(A[:,:,5,0], B[:,:,5,0])  # maximum(gamma- amplitude)
    answer[:,:,5,1] = np.maximum(A[:,:,5,1], B[:,:,5,1])  # maximum(gamma- angle)

    return answer

# Defining the function to print the final answer
def print_answer(matrix):
    row, column, _, _ = matrix.shape
    for i in range(row):
        print("[")
        for j in range(column):
            element = matrix[i,j]
            format = ", ".join([f"{amplitude:.2f}e^{{i.{angle:.2f}}}" for amplitude, angle in element])
            print(f"<{format}>")
        print("]")

# Entering two example matrix
A = np.array([
    [
        [(0.7, 0.4), (0.6, np.pi), (0.4, 0.2), (-0.5, -np.pi/6), (-0.7, -np.pi/2), (-0.2, -0.8)],
        [(0.8, 0.5), (0.4, np.pi/3), (0.5, 0.3), (-0.6, -np.pi/4), (-0.5, -np.pi/2), (-0.3, -0.1)],
        [(0.9, 0.6), (0.5, np.pi/2), (0.7, 0.4), (-0.7, -np.pi/3), (-0.4, -np.pi/6), (-0.1, -0.1)]
    ],
    [
        [(0.9, 0.8), (0.7, np.pi), (0.4, np.pi), (-0.9, -np.pi/3), (-0.5, -np.pi/4), (-0.8, -0.3)],
        [(0.6, 0.5), (0.9, np.pi/2), (0.8, 0.6), (-0.6, -np.pi/4), (-0.3, -np.pi/2), (-0.5, -0.2)],
        [(0.5, 0.4), (0.7, np.pi/3), (0.3, 0.5), (-0.5, -np.pi/6), (-0.2, -np.pi/4), (-0.6, -0.1)]
    ],
    [
        [(0.5, 0.8), (0.5, np.pi/4), (0.2, np.pi), (-0.2, -np.pi/3), (-0.9, -np.pi/2), (-0.2, 0)],
        [(0.7, 0.6), (0.6, np.pi/2), (0.6, 0.7), (-0.7, -np.pi/2), (-0.5, -np.pi/3), (-0.4, -0.1)],
        [(0.8, 0.7), (0.4, np.pi/3), (0.5, 0.5), (-0.3, -np.pi/4), (-0.6, -np.pi/6), (-0.3, -0.2)]
    ]
])

B = np.array([
    [
        [(0.5, 0.1), (0.8, np.pi), (0.7, 0.9), (-0.2, -np.pi/2), (-0.2, -3*np.pi/4), (-0.2, -0.9)],
        [(0.8, 0.5), (0.4, np.pi/6), (0.6, 0.4), (-0.8, -np.pi/6), (-0.1, -np.pi/3), (-0.7, 2)],
        [(0.5, 0.4), (0.7, np.pi/2), (0.6, 0.7), (-0.2, -np.pi/3), (-0.1, -np.pi/6), (-0.3, -2.1)]
    ],
    [
        [(0.8, 0.6), (0.7, 2*np.pi), (0.7, np.pi/2), (-0.9, -np.pi/4), (-0.2, -np.pi/4), (-0.8, -0.3)],
        [(0.8, 0.7), (0.5, np.pi/2), (0.8, 0.4), (-0.6, -np.pi/6), (-0.3, -np.pi/6), (-0.4, 0.2)],
        [(0.5, 0.2), (0.1, np.pi/3), (0.4, 0.1), (-0.7, -np.pi/3), (-0.4, -np.pi/2), (-0.7, -0.4)]
    ],
    [
        [(0.9, 0.8), (0.1, np.pi/4), (0.8, np.pi/3), (-0.4, -np.pi/2), (-0.4, -np.pi/3), (-0.3, -0.9)],
        [(0.7, 0.9), (0.2, np.pi/6), (0.9, 0.7), (-0.7, -np.pi/6), (-0.3, -np.pi/2), (-0.6, -0.2)],
        [(0.6, 0.9), (0.8, np.pi/4), (0.9, 0.8), (-0.4, -np.pi/3), (-0.6, -np.pi/6), (-0.5, -0.3)]
    ]
])

# Calling the union function
BCNM_union = union(A, B)

# Print the union of the entered matrices
print("Union of the entered BCN matrices is")
print_answer(BCNM_union)


