|
| 1 | +import numpy as np |
| 2 | + |
| 3 | + |
| 4 | +def gauss_jordan( |
| 5 | + coefficients: np.ndarray, vertices: np.ndarray |
| 6 | +) -> tuple[np.ndarray, np.ndarray]: |
| 7 | + """ |
| 8 | + Performs Gauss-Jordan elimination on the system Ax = b to reduce A to its |
| 9 | + Reduced Row Echelon Form (RREF) and transform b accordingly. |
| 10 | +
|
| 11 | + Args: |
| 12 | + coefficients: A 2D NumPy array representing the coefficient matrix A. |
| 13 | + vertices: A column vector (2D NumPy array) representing the RHS b. |
| 14 | +
|
| 15 | + Returns: |
| 16 | + A tuple containing: |
| 17 | + - RREF of matrix A |
| 18 | + - Transformed RHS vector b |
| 19 | +
|
| 20 | + Raises: |
| 21 | + ValueError: If shapes of A and b are incompatible. |
| 22 | +
|
| 23 | + Examples: |
| 24 | + >>> import numpy as np |
| 25 | + >>> A = np.array([[1, 2, -1], [2, 4, -2], [3, 6, -3]]) |
| 26 | + >>> b = np.array([[1], [2], [3]]) |
| 27 | + >>> rref_A, rref_b = gauss_jordan(A, b) |
| 28 | + >>> np.allclose(rref_A, np.array([[1., 2., -1.], [0., 0., 0.], [0., 0., 0.]])) |
| 29 | + True |
| 30 | + >>> np.allclose(rref_b, np.array([[1.], [0.], [0.]])) |
| 31 | + True |
| 32 | +
|
| 33 | + """ |
| 34 | + if coefficients.ndim != 2 or vertices.ndim != 2: |
| 35 | + raise ValueError("Both inputs must be 2D arrays.") |
| 36 | + if coefficients.shape[0] != vertices.shape[0]: |
| 37 | + raise ValueError("Number of rows in coefficients and vertices must match.") |
| 38 | + |
| 39 | + coefficients = coefficients.astype(float).copy() |
| 40 | + vertices = vertices.astype(float).copy() |
| 41 | + rows, cols = coefficients.shape |
| 42 | + |
| 43 | + for col in range(cols): |
| 44 | + pivot_row = None |
| 45 | + for row in range(col, rows): |
| 46 | + if not np.isclose(coefficients[row, col], 0): |
| 47 | + pivot_row = row |
| 48 | + break |
| 49 | + |
| 50 | + if pivot_row is None: |
| 51 | + continue |
| 52 | + |
| 53 | + if pivot_row != col: |
| 54 | + coefficients[[col, pivot_row]] = coefficients[[pivot_row, col]] |
| 55 | + vertices[[col, pivot_row]] = vertices[[pivot_row, col]] |
| 56 | + |
| 57 | + pivot_val = coefficients[col, col] |
| 58 | + coefficients[col] /= pivot_val |
| 59 | + vertices[col] /= pivot_val |
| 60 | + |
| 61 | + for row in range(rows): |
| 62 | + if row == col: |
| 63 | + continue |
| 64 | + factor = coefficients[row, col] |
| 65 | + coefficients[row] -= factor * coefficients[col] |
| 66 | + vertices[row] -= factor * vertices[col] |
| 67 | + |
| 68 | + return coefficients, vertices |
| 69 | + |
| 70 | + |
| 71 | +if __name__ == "__main__": |
| 72 | + import doctest |
| 73 | + |
| 74 | + doctest.testmod() |
0 commit comments