import torch
# Create two tensors
# Tensor A: shape (2, 3)
A = torch.tensor([[1, 2, 3], [4, 5, 6]])
# Tensor B: shape (3, 2)
B = torch.tensor([[7, 8], [9, 10], [11, 12]])
print(f"Shape of A: {A.shape}") # Output: torch.Size([2, 3])
print(f"Shape of B: {B.shape}") # Output: torch.Size([3, 2])
# Matrix multiplication: (2,3) x (3,2) -> (2,2)
C = torch.matmul(A, B)
print(f"Result of A x B: {C}")
print(f"Shape of C: {C.shape}") # Output: torch.Size([2, 2])
# Reshape tensor C from (2, 2) to (4,)
C_reshaped = C.view(4)
print(f"Reshaped C: {C_reshaped}")
print(f"Shape of reshaped C: {C_reshaped.shape}")
# Try an incorrect reshape (will raise error if uncommented)
# C.view(3) # Cannot reshape 4 elements into shape (3,)
# Create a tensor D with shape (4, 1, 2)
D = torch.arange(8).view(4, 1, 2)
print(f"Tensor D: {D}")
print(f"Shape of D: {D.shape}")
# Squeeze removes dimensions of size 1
D_squeezed = D.squeeze()
print(f"Shape of D after squeeze: {D_squeezed.shape}") # Output: torch.Size([4, 2])
# Unsqueeze adds a dimension at position 1
D_unsqueezed = D_squeezed.unsqueeze(1)
print(f"Shape of D after unsqueeze: {D_unsqueezed.shape}") # Output: torch.Size([4, 1, 2])