Skip to content

Matrices

A matrix is a rectangular grid of numbers. In panchi, Matrix represents an m×n matrix and supports the arithmetic and structural operations you would expect from a mathematical matrix.

Construction

import panchi as pan

A = pan.Matrix([[1, 2, 3],
                [4, 5, 6]])

print(A.shape)  # (2, 3)
print(A.rows)   # 2
print(A.cols)   # 3

Every row must have the same number of columns. Inconsistent rows raise a ValueError.

Arithmetic

A = pan.Matrix([[1, 2], [3, 4]])
B = pan.Matrix([[5, 6], [7, 8]])

print(A + B)   # element-wise addition
print(A - B)   # element-wise subtraction
print(2 * A)   # scalar multiplication
print(-A)      # negation

Matrix multiplication

Matrix multiplication uses the @ operator, following Python convention:

print(A @ B)   # [[19, 22], [43, 50]]

* is reserved for scalar multiplication. Using * between two matrices raises a TypeError — this is intentional, since it avoids a common source of confusion.

Multiplying a matrix by a vector also uses @ and returns a Vector:

v = pan.Vector([1, 0])
print(A @ v)   # [1, 3]

Matrix powers

print(A ** 2)  # A @ A
print(A ** 0)  # identity matrix of matching size

Powers are only defined for square matrices.

Transpose

print(A.T)          # shorthand property
print(A.transpose()) # equivalent method

Properties

A = pan.Matrix([[1, 2], [3, 4]])

print(A.trace)        # 5       — sum of diagonal (square only)
print(A.determinant)  # -2      — cofactor expansion (square only)
print(A.is_square)    # True

Identity matrices

Every matrix has a left and right identity — the square identity matrices of the appropriate size for multiplication on each side:

A = pan.Matrix([[1, 2, 3], [4, 5, 6]])  # 2×3

print(A.left_identity)   # 2×2 identity
print(A.right_identity)  # 3×3 identity

# These satisfy:
assert A.left_identity @ A == A
assert A @ A.right_identity == A

Row and column access

row() and col() mirror the mathematical operators Row(A) and Col(A), returning the row and column vectors of a matrix respectively.

A = pan.Matrix([[1, 2, 3], [4, 5, 6]])

A.row()      # [Vector([1, 2, 3]), Vector([4, 5, 6])]
A.col()      # [Vector([1, 4]), Vector([2, 5]), Vector([3, 6])]

A.row()[0]   # Vector([1, 2, 3])
A.col()[1]   # Vector([2, 5])

Both methods return copies — modifying the result does not affect the original matrix.

Factory functions

pan.identity(3)            # 3×3 identity
pan.zero_matrix(2, 3)      # 2×3 matrix of zeros
pan.one_matrix(2, 3)       # 2×3 matrix of ones
pan.diagonal([1, 2, 3])    # 3×3 diagonal matrix
pan.random_matrix(3, 3)    # random entries

Conversion and copying

A.to_list()  # returns a 2D list copy of the data
A.copy()     # returns an independent Matrix copy