import numpy as np
# Vector dot product: (3,) @ (3,) -> scalar
v1 = np.array([1.0, 2.0, 3.0], dtype=np.float32)
v2 = np.array([4.0, 5.0, 6.0], dtype=np.float32)
vec_dot_result = np.dot(v1, v2)
print("Vector dot product result:", vec_dot_result) # scalar
print("---")
# Matrix multiply: (2,3) @ (3,2) -> (2,2)
A = np.array([1, 2, 3, 4, 5, 6], dtype=np.float32).reshape(2, 3, order='F')
B = np.array([7, 8, 9, 10, 11, 12], dtype=np.float32).reshape(3, 2, order='F')
mat_mul_result = np.matmul(A, B)
print("Shape:", mat_mul_result.shape)
print(mat_mul_result.flatten(order='F')) # column major flat
print("---")
# Vector-matrix multiply: (3,) @ (3,2) -> (2,)
C = np.array([4, 5, 6], dtype=np.float32)
D = np.array([7, 8, 9, 10, 11, 12], dtype=np.float32).reshape(3, 2, order='F')
mat_mul_result2 = np.matmul(C, D)
print("Shape:", mat_mul_result2.shape)
print(mat_mul_result2.flatten(order='F'))
print("---")
# Matrix-vector multiply: (4,5) @ (5,) -> (4,)
E = np.array(range(1, 21), dtype=np.float32).reshape(4, 5, order='F')
F = np.array([2, 3, 4, 5, 6], dtype=np.float32)
mat_mul_result3 = np.matmul(E, F)
print("Shape:", mat_mul_result3.shape)
print(mat_mul_result3.flatten(order='F'))
print("---")
# Batched matmul: (2,2,3) @ (2,3,2) -> (2,2,2)
a = np.array([1,2,3,4,5,6,7,8,9,10,11,12], dtype=np.float32).reshape(2, 2, 3, order='F')
b = np.array([1,2,3,4,5,6,7,8,9,10,11,12], dtype=np.float32).reshape(2, 3, 2, order='F')
mat_mul_result4 = np.matmul(a, b)
print("Shape:", mat_mul_result4.shape)
print(mat_mul_result4.flatten(order='F'))
print("---")
# Broadcasting example: (3,1,2,3) @ (1,4,3,2) -> (3,4,2,2)
c = np.array(list(range(1, 19)), dtype=np.float32).reshape(3, 1, 2, 3, order='F')
d = np.array(list(range(1, 25)), dtype=np.float32).reshape(1, 4, 3, 2, order='F')
mat_mul_result5 = np.matmul(c, d)
print("Shape:", mat_mul_result5.shape)
print(mat_mul_result5.flatten(order='F'))
print("---")
# Vector @ ND: (3,) @ (2,3,4) -> (2,4)
vec = np.array([1, 2, 3], dtype=np.float32)
mat = np.array(list(range(1, 25)), dtype=np.float32).reshape(2, 3, 4, order='F')
mat_mul_result6 = np.matmul(vec, mat)
print("Shape:", mat_mul_result6.shape)
print(mat_mul_result6.flatten(order='F'))
print("---")
# ND @ Vector: (2,3,4) @ (4,) -> (2,3)
vec2 = np.array([1, 2, 3, 4], dtype=np.float32)
mat2 = np.array(list(range(1, 25)), dtype=np.float32).reshape(2, 3, 4, order='F')
mat_mul_result7 = np.matmul(mat2, vec2)
print("Shape:", mat_mul_result7.shape)
print(mat_mul_result7.flatten(order='F'))
aW1wb3J0IG51bXB5IGFzIG5wCgojIFZlY3RvciBkb3QgcHJvZHVjdDogKDMsKSBAICgzLCkgLT4gc2NhbGFyCnYxID0gbnAuYXJyYXkoWzEuMCwgMi4wLCAzLjBdLCBkdHlwZT1ucC5mbG9hdDMyKQp2MiA9IG5wLmFycmF5KFs0LjAsIDUuMCwgNi4wXSwgZHR5cGU9bnAuZmxvYXQzMikKdmVjX2RvdF9yZXN1bHQgPSBucC5kb3QodjEsIHYyKQpwcmludCgiVmVjdG9yIGRvdCBwcm9kdWN0IHJlc3VsdDoiLCB2ZWNfZG90X3Jlc3VsdCkgICMgc2NhbGFyCgpwcmludCgiLS0tIikKCiMgTWF0cml4IG11bHRpcGx5OiAoMiwzKSBAICgzLDIpIC0+ICgyLDIpCkEgPSBucC5hcnJheShbMSwgMiwgMywgNCwgNSwgNl0sIGR0eXBlPW5wLmZsb2F0MzIpLnJlc2hhcGUoMiwgMywgb3JkZXI9J0YnKQpCID0gbnAuYXJyYXkoWzcsIDgsIDksIDEwLCAxMSwgMTJdLCBkdHlwZT1ucC5mbG9hdDMyKS5yZXNoYXBlKDMsIDIsIG9yZGVyPSdGJykKbWF0X211bF9yZXN1bHQgPSBucC5tYXRtdWwoQSwgQikKcHJpbnQoIlNoYXBlOiIsIG1hdF9tdWxfcmVzdWx0LnNoYXBlKQpwcmludChtYXRfbXVsX3Jlc3VsdC5mbGF0dGVuKG9yZGVyPSdGJykpICAjIGNvbHVtbiBtYWpvciBmbGF0CgpwcmludCgiLS0tIikKCiMgVmVjdG9yLW1hdHJpeCBtdWx0aXBseTogKDMsKSBAICgzLDIpIC0+ICgyLCkKQyA9IG5wLmFycmF5KFs0LCA1LCA2XSwgZHR5cGU9bnAuZmxvYXQzMikKRCA9IG5wLmFycmF5KFs3LCA4LCA5LCAxMCwgMTEsIDEyXSwgZHR5cGU9bnAuZmxvYXQzMikucmVzaGFwZSgzLCAyLCBvcmRlcj0nRicpCm1hdF9tdWxfcmVzdWx0MiA9IG5wLm1hdG11bChDLCBEKQpwcmludCgiU2hhcGU6IiwgbWF0X211bF9yZXN1bHQyLnNoYXBlKQpwcmludChtYXRfbXVsX3Jlc3VsdDIuZmxhdHRlbihvcmRlcj0nRicpKQoKcHJpbnQoIi0tLSIpCgojIE1hdHJpeC12ZWN0b3IgbXVsdGlwbHk6ICg0LDUpIEAgKDUsKSAtPiAoNCwpCkUgPSBucC5hcnJheShyYW5nZSgxLCAyMSksIGR0eXBlPW5wLmZsb2F0MzIpLnJlc2hhcGUoNCwgNSwgb3JkZXI9J0YnKQpGID0gbnAuYXJyYXkoWzIsIDMsIDQsIDUsIDZdLCBkdHlwZT1ucC5mbG9hdDMyKQptYXRfbXVsX3Jlc3VsdDMgPSBucC5tYXRtdWwoRSwgRikKcHJpbnQoIlNoYXBlOiIsIG1hdF9tdWxfcmVzdWx0My5zaGFwZSkKcHJpbnQobWF0X211bF9yZXN1bHQzLmZsYXR0ZW4ob3JkZXI9J0YnKSkKCnByaW50KCItLS0iKQoKIyBCYXRjaGVkIG1hdG11bDogKDIsMiwzKSBAICgyLDMsMikgLT4gKDIsMiwyKQphID0gbnAuYXJyYXkoWzEsMiwzLDQsNSw2LDcsOCw5LDEwLDExLDEyXSwgZHR5cGU9bnAuZmxvYXQzMikucmVzaGFwZSgyLCAyLCAzLCBvcmRlcj0nRicpCmIgPSBucC5hcnJheShbMSwyLDMsNCw1LDYsNyw4LDksMTAsMTEsMTJdLCBkdHlwZT1ucC5mbG9hdDMyKS5yZXNoYXBlKDIsIDMsIDIsIG9yZGVyPSdGJykKbWF0X211bF9yZXN1bHQ0ID0gbnAubWF0bXVsKGEsIGIpCnByaW50KCJTaGFwZToiLCBtYXRfbXVsX3Jlc3VsdDQuc2hhcGUpCnByaW50KG1hdF9tdWxfcmVzdWx0NC5mbGF0dGVuKG9yZGVyPSdGJykpCgpwcmludCgiLS0tIikKCiMgQnJvYWRjYXN0aW5nIGV4YW1wbGU6ICgzLDEsMiwzKSBAICgxLDQsMywyKSAtPiAoMyw0LDIsMikKYyA9IG5wLmFycmF5KGxpc3QocmFuZ2UoMSwgMTkpKSwgZHR5cGU9bnAuZmxvYXQzMikucmVzaGFwZSgzLCAxLCAyLCAzLCBvcmRlcj0nRicpCmQgPSBucC5hcnJheShsaXN0KHJhbmdlKDEsIDI1KSksIGR0eXBlPW5wLmZsb2F0MzIpLnJlc2hhcGUoMSwgNCwgMywgMiwgb3JkZXI9J0YnKQptYXRfbXVsX3Jlc3VsdDUgPSBucC5tYXRtdWwoYywgZCkKcHJpbnQoIlNoYXBlOiIsIG1hdF9tdWxfcmVzdWx0NS5zaGFwZSkKcHJpbnQobWF0X211bF9yZXN1bHQ1LmZsYXR0ZW4ob3JkZXI9J0YnKSkKCnByaW50KCItLS0iKQoKIyBWZWN0b3IgQCBORDogKDMsKSBAICgyLDMsNCkgLT4gKDIsNCkKdmVjID0gbnAuYXJyYXkoWzEsIDIsIDNdLCBkdHlwZT1ucC5mbG9hdDMyKQptYXQgPSBucC5hcnJheShsaXN0KHJhbmdlKDEsIDI1KSksIGR0eXBlPW5wLmZsb2F0MzIpLnJlc2hhcGUoMiwgMywgNCwgb3JkZXI9J0YnKQptYXRfbXVsX3Jlc3VsdDYgPSBucC5tYXRtdWwodmVjLCBtYXQpCnByaW50KCJTaGFwZToiLCBtYXRfbXVsX3Jlc3VsdDYuc2hhcGUpCnByaW50KG1hdF9tdWxfcmVzdWx0Ni5mbGF0dGVuKG9yZGVyPSdGJykpCgpwcmludCgiLS0tIikKCiMgTkQgQCBWZWN0b3I6ICgyLDMsNCkgQCAoNCwpIC0+ICgyLDMpCnZlYzIgPSBucC5hcnJheShbMSwgMiwgMywgNF0sIGR0eXBlPW5wLmZsb2F0MzIpCm1hdDIgPSBucC5hcnJheShsaXN0KHJhbmdlKDEsIDI1KSksIGR0eXBlPW5wLmZsb2F0MzIpLnJlc2hhcGUoMiwgMywgNCwgb3JkZXI9J0YnKQptYXRfbXVsX3Jlc3VsdDcgPSBucC5tYXRtdWwobWF0MiwgdmVjMikKcHJpbnQoIlNoYXBlOiIsIG1hdF9tdWxfcmVzdWx0Ny5zaGFwZSkKcHJpbnQobWF0X211bF9yZXN1bHQ3LmZsYXR0ZW4ob3JkZXI9J0YnKSkK