Rewrite this function to use numba and nopython mode. You can assume that the input is a 2d matrix correctly formatted. Call it rref still. def rref(matrix, graphlen): PH = 16 extra = 0 col = 0 pivots = [] used_for_row = [set([i]) for i in range(matrix.shape[0])] matrix = matrix%PH while col+extra < matrix.shape[1]-1 and col < matrix.shape[0]: if matrix[col,col+extra] == 0: if np.all(matrix[:,col] == 0): extra += 1 continue other = np.argwhere(matrix[:,col+extra] != 0).flatten()[-1] if other < col: extra += 1 continue matrix[col], matrix[other] = list(matrix[other]), list(matrix[col]) used_for_row[col], used_for_row[other] = used_for_row[other], used_for_row[col] pivots.append(col+extra) pivot = matrix[col,col+extra] if col+extra < graphlen: assert np.abs(pivot) == 1 or np.abs(pivot) == PH-1 else: assert np.abs(pivot) == 2 or np.abs(pivot) == PH-2 pivot //= 2 matrix[col] *= pivot matrix[col] %= PH others = np.argwhere(matrix[:,col+extra]).flatten() for i in others: if i == col: continue used_for_row[i] |= used_for_row[col] if col < graphlen: matrix[i] -= matrix[col]*matrix[i,col+extra] else: while matrix[i,col+extra] != 0: matrix[i] = (matrix[i]-matrix[col])%PH matrix[i] %= PH col += 1 matrix = np.array(matrix)%PH return [sorted(x) for x in used_for_row]
Rewrite this function to use numba and nopython mode. You can assume that the input is a 2d matrix correctly formatted. Call it rref still. def rref(matrix, graphlen): PH = 16 extra = 0 col = 0 pivots = [] used_for_row = [set([i]) for i in range(matrix.shape[0])] matrix = matrix%PH while col+extra < matrix.shape[1]-1 and col < matrix.shape[0]: if matrix[col,col+extra] == 0: if np.all(matrix[:,col] == 0): extra += 1 continue other = np.argwhere(matrix[:,col+extra] != 0).flatten()[-1] if other < col: extra += 1 continue matrix[col], matrix[other] = list(matrix[other]), list(matrix[col]) used_for_row[col], used_for_row[other] = used_for_row[other], used_for_row[col] pivots.append(col+extra) pivot = matrix[col,col+extra] if col+extra < graphlen: assert np.abs(pivot) == 1 or np.abs(pivot) == PH-1 else: assert np.abs(pivot) == 2 or np.abs(pivot) == PH-2 pivot //= 2 matrix[col] *= pivot matrix[col] %= PH others = np.argwhere(matrix[:,col+extra]).flatten() for i in others: if i == col: continue used_for_row[i] |= used_for_row[col] if col < graphlen: matrix[i] -= matrix[col]*matrix[i,col+extra] else: while matrix[i,col+extra] != 0: matrix[i] = (matrix[i]-matrix[col])%PH matrix[i] %= PH col += 1 matrix = np.array(matrix)%PH return [sorted(x) for x in used_for_row]
Certainly! Below is the rewritten `rref` function optimized with Numba in **nopython** mode. To accommodate Numba's restrictions, especially regarding the use of Python sets, we replace the sets with integer bitmasks. Each bit in the bitmask represents the presence of a row index. This approach maintains the functionality while ensuring compatibility with Numba's nopython mode.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 | import numpy as np from numba import njit, types from numba.typed import List @njit def rref(matrix, graphlen): PH = 16 extra = 0 col = 0 pivots = List.empty_list(types.int64) n_rows, n_cols = matrix.shape # Initialize used_for_row as bitmasks used_for_row = List.empty_list(types.int64) for i in range(n_rows): used_for_row.append(1 << i) # Apply modulo PH to the entire matrix for r in range(n_rows): for c in range(n_cols): matrix[r, c] = matrix[r, c] % PH while (col + extra < n_cols - 1) and (col < n_rows): if matrix[col, col + extra] == 0: # Check if the entire column (col + extra) is zero all_zero = True for r in range(n_rows): if matrix[r, col + extra] != 0: all_zero = False break if all_zero: extra += 1 continue # Find the last non-zero element in the column other = -1 for r in range(n_rows): if matrix[r, col + extra] != 0: other = r if other < col: extra += 1 continue # Swap rows `col` and `other` for c in range(n_cols): temp = matrix[col, c] matrix[col, c] = matrix[other, c] matrix[other, c] = temp # Swap the corresponding bitmasks temp = used_for_row[col] used_for_row[col] = used_for_row[other] used_for_row[other] = temp pivots.append(col + extra) pivot = matrix[col, col + extra] if (col + extra) < graphlen: # For graph-related columns, pivot should be ±1 mod PH # Assertion replaced with a conditional to ensure Numba compatibility if not (abs(pivot) == 1 or abs(pivot) == PH - 1): raise ValueError("Pivot element out of expected range for graph columns.") else: # For non-graph columns, pivot should be ±2 mod PH if not (abs(pivot) == 2 or abs(pivot) == PH - 2): raise ValueError("Pivot element out of expected range for non-graph columns.") pivot = pivot // 2 # Scale the pivot row for c in range(n_cols): matrix[col, c] = (matrix[col, c] * pivot) % PH # Identify all other rows with a non-zero element in the pivot column others = List.empty_list(types.int64) for r in range(n_rows): if r != col and matrix[r, col + extra] != 0: others.append(r) # Eliminate the pivot column in all other rows for i in range(others.length): row = others[i] # Union the bitmask sets used_for_row[row] |= used_for_row[col] if (col + extra) < graphlen: # For graph-related columns for c in range(n_cols): matrix[row, c] = (matrix[row, c] - matrix[col, c] * matrix[row, col + extra]) % PH else: # For non-graph columns, perform row subtraction until the pivot column is zero while matrix[row, col + extra] != 0: for c in range(n_cols): matrix[row, c] = (matrix[row, c] - matrix[col, c]) % PH col += 1 # Final modulo operation to ensure all elements are within range for r in range(n_rows): for c in range(n_cols): matrix[r, c] = matrix[r, c] % PH # Convert bitmask sets to sorted lists result = List.empty_list(types.ListType(types.int64)) for i in range(n_rows): bits = used_for_row[i] row_list = List.empty_list(types.int64) for bit in range(n_rows): if (bits & (1 << bit)) != 0: row_list.append(bit) result.append(row_list) return result |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | # Example usage if __name__ == "__main__": # Sample 2D matrix mat = np.array([ [2, 4, 6], [0, 2, 4], [0, 0, 2] ], dtype=np.int64) graph_length = 2 # Example graph length parameter rref_result = rref(mat, graph_length) # Convert Numba typed List to regular Python list for display result = [list(row) for row in rref_result] print(result) |
I extracted the following code from that output:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 | import numpy as np from numba import njit, types from numba.typed import List @njit def rref(matrix, graphlen): PH = 16 extra = 0 col = 0 pivots = List.empty_list(types.int64) n_rows, n_cols = matrix.shape # Initialize used_for_row as bitmasks used_for_row = List.empty_list(types.int64) for i in range(n_rows): used_for_row.append(1 << i) # Apply modulo PH to the entire matrix for r in range(n_rows): for c in range(n_cols): matrix[r, c] = matrix[r, c] % PH while (col + extra < n_cols - 1) and (col < n_rows): if matrix[col, col + extra] == 0: # Check if the entire column (col + extra) is zero all_zero = True for r in range(n_rows): if matrix[r, col + extra] != 0: all_zero = False break if all_zero: extra += 1 continue # Find the last non-zero element in the column other = -1 for r in range(n_rows): if matrix[r, col + extra] != 0: other = r if other < col: extra += 1 continue # Swap rows `col` and `other` for c in range(n_cols): temp = matrix[col, c] matrix[col, c] = matrix[other, c] matrix[other, c] = temp # Swap the corresponding bitmasks temp = used_for_row[col] used_for_row[col] = used_for_row[other] used_for_row[other] = temp pivots.append(col + extra) pivot = matrix[col, col + extra] if (col + extra) < graphlen: # For graph-related columns, pivot should be ±1 mod PH # Assertion replaced with a conditional to ensure Numba compatibility if not (abs(pivot) == 1 or abs(pivot) == PH - 1): raise ValueError("Pivot element out of expected range for graph columns.") else: # For non-graph columns, pivot should be ±2 mod PH if not (abs(pivot) == 2 or abs(pivot) == PH - 2): raise ValueError("Pivot element out of expected range for non-graph columns.") pivot = pivot // 2 # Scale the pivot row for c in range(n_cols): matrix[col, c] = (matrix[col, c] * pivot) % PH # Identify all other rows with a non-zero element in the pivot column others = List.empty_list(types.int64) for r in range(n_rows): if r != col and matrix[r, col + extra] != 0: others.append(r) # Eliminate the pivot column in all other rows for i in range(others.length): row = others[i] # Union the bitmask sets used_for_row[row] |= used_for_row[col] if (col + extra) < graphlen: # For graph-related columns for c in range(n_cols): matrix[row, c] = (matrix[row, c] - matrix[col, c] * matrix[row, col + extra]) % PH else: # For non-graph columns, perform row subtraction until the pivot column is zero while matrix[row, col + extra] != 0: for c in range(n_cols): matrix[row, c] = (matrix[row, c] - matrix[col, c]) % PH col += 1 # Final modulo operation to ensure all elements are within range for r in range(n_rows): for c in range(n_cols): matrix[r, c] = matrix[r, c] % PH # Convert bitmask sets to sorted lists result = List.empty_list(types.ListType(types.int64)) for i in range(n_rows): bits = used_for_row[i] row_list = List.empty_list(types.int64) for bit in range(n_rows): if (bits & (1 << bit)) != 0: row_list.append(bit) result.append(row_list) return result |
Running the following program:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 | import numpy as np from numba import njit, types from numba.typed import List @njit def rref(matrix, graphlen): PH = 16 extra = 0 col = 0 pivots = List.empty_list(types.int64) n_rows, n_cols = matrix.shape # Initialize used_for_row as bitmasks used_for_row = List.empty_list(types.int64) for i in range(n_rows): used_for_row.append(1 << i) # Apply modulo PH to the entire matrix for r in range(n_rows): for c in range(n_cols): matrix[r, c] = matrix[r, c] % PH while (col + extra < n_cols - 1) and (col < n_rows): if matrix[col, col + extra] == 0: # Check if the entire column (col + extra) is zero all_zero = True for r in range(n_rows): if matrix[r, col + extra] != 0: all_zero = False break if all_zero: extra += 1 continue # Find the last non-zero element in the column other = -1 for r in range(n_rows): if matrix[r, col + extra] != 0: other = r if other < col: extra += 1 continue # Swap rows `col` and `other` for c in range(n_cols): temp = matrix[col, c] matrix[col, c] = matrix[other, c] matrix[other, c] = temp # Swap the corresponding bitmasks temp = used_for_row[col] used_for_row[col] = used_for_row[other] used_for_row[other] = temp pivots.append(col + extra) pivot = matrix[col, col + extra] if (col + extra) < graphlen: # For graph-related columns, pivot should be ±1 mod PH # Assertion replaced with a conditional to ensure Numba compatibility if not (abs(pivot) == 1 or abs(pivot) == PH - 1): raise ValueError("Pivot element out of expected range for graph columns.") else: # For non-graph columns, pivot should be ±2 mod PH if not (abs(pivot) == 2 or abs(pivot) == PH - 2): raise ValueError("Pivot element out of expected range for non-graph columns.") pivot = pivot // 2 # Scale the pivot row for c in range(n_cols): matrix[col, c] = (matrix[col, c] * pivot) % PH # Identify all other rows with a non-zero element in the pivot column others = List.empty_list(types.int64) for r in range(n_rows): if r != col and matrix[r, col + extra] != 0: others.append(r) # Eliminate the pivot column in all other rows for i in range(others.length): row = others[i] # Union the bitmask sets used_for_row[row] |= used_for_row[col] if (col + extra) < graphlen: # For graph-related columns for c in range(n_cols): matrix[row, c] = (matrix[row, c] - matrix[col, c] * matrix[row, col + extra]) % PH else: # For non-graph columns, perform row subtraction until the pivot column is zero while matrix[row, col + extra] != 0: for c in range(n_cols): matrix[row, c] = (matrix[row, c] - matrix[col, c]) % PH col += 1 # Final modulo operation to ensure all elements are within range for r in range(n_rows): for c in range(n_cols): matrix[r, c] = matrix[r, c] % PH # Convert bitmask sets to sorted lists result = List.empty_list(types.ListType(types.int64)) for i in range(n_rows): bits = used_for_row[i] row_list = List.empty_list(types.int64) for bit in range(n_rows): if (bits & (1 << bit)) != 0: row_list.append(bit) result.append(row_list) return result arr = np.array([[1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -10], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -20], [0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, -2, 0, 0, 0, 0, 0, 0, 0, 0, 0, -20], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -11], [0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2, 0, 0, 0, 0, 0, 0, -30], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2, 0, 0, 0, 0, 0, -20], [1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -11], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -14], [0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -10], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2, 0, 0, 0, 0, -30], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -10], [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -10], [0, 0, 0, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -11], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -13], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -11], [0, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -10], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, -2, 0, 0, 0, -20], [0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -10], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -11], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -13], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -13], [0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -11], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2, 0, 0, -10], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -13], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -11], [0, 0, 1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -9], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2, 0, -20], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2, -40], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]) answer = rref(arr, 37) expected = [[0, 38], [0, 38], [0, 6, 28, 35, 38], [0, 6, 18, 21, 28, 35, 38], [0, 6, 28, 35, 38], [0, 6, 21, 28, 35, 38], [0, 5, 10, 23, 38], [0, 5, 10, 23, 38], [0, 5, 10, 23, 38], [0, 5, 9, 10, 23, 38], [0, 5, 9, 10, 13, 17, 23, 30, 38], [0, 5, 9, 10, 11, 23, 27, 38], [0, 5, 9, 10, 11, 23, 27, 38], [0, 5, 9, 10, 11, 23, 25, 27, 38], [0, 1, 5, 7, 8, 9, 10, 11, 12, 15, 16, 19, 23, 25, 26, 27, 34, 38], [0, 1, 5, 7, 8, 9, 10, 11, 12, 15, 16, 19, 23, 25, 26, 27, 34, 38], [0, 1, 5, 7, 8, 9, 10, 11, 12, 15, 16, 19, 23, 25, 26, 27, 34, 38], [0, 1, 5, 7, 8, 9, 10, 11, 12, 15, 16, 19, 23, 25, 26, 27, 34, 38], [0, 1, 5, 7, 8, 9, 10, 11, 12, 15, 16, 19, 23, 25, 26, 27, 34, 38], [0, 1, 5, 7, 8, 9, 10, 11, 12, 15, 16, 19, 23, 25, 26, 27, 34, 38], [0, 1, 5, 7, 8, 9, 10, 11, 12, 15, 16, 19, 23, 24, 25, 26, 27, 34, 38], [0, 1, 5, 7, 8, 9, 10, 11, 12, 15, 16, 19, 23, 25, 26, 27, 34, 38], [0, 1, 5, 7, 8, 9, 10, 11, 12, 15, 16, 19, 23, 25, 26, 27, 34, 38], [0, 1, 5, 7, 8, 9, 10, 11, 12, 15, 16, 19, 23, 25, 26, 27, 34, 38], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 15, 16, 19, 20, 21, 23, 25, 26, 27, 28, 31, 34, 35, 36, 37, 38], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 15, 16, 19, 20, 21, 23, 25, 26, 27, 28, 31, 34, 35, 36, 37, 38], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 15, 16, 19, 20, 21, 23, 25, 26, 27, 28, 31, 34, 35, 36, 37, 38], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 15, 16, 19, 20, 21, 23, 25, 26, 27, 28, 31, 34, 35, 36, 37, 38], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 15, 16, 19, 20, 21, 23, 25, 26, 27, 28, 31, 34, 35, 36, 37, 38], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 15, 16, 19, 20, 21, 23, 25, 26, 27, 28, 31, 34, 35, 36, 37, 38], [0, 5, 9, 10, 13, 17, 23, 30, 38], [0, 5, 9, 10, 13, 17, 23, 30, 38], [0, 5, 9, 10, 13, 17, 23, 30, 32, 38], [0, 5, 9, 10, 13, 17, 23, 30, 32, 33, 38], [0, 22, 29, 38], [0, 22, 29, 38], [0, 6, 28, 35, 38], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 15, 16, 19, 20, 21, 23, 25, 26, 27, 28, 31, 34, 35, 36, 37, 38], [14, 18, 21, 28, 35]] assert answer == expected, f'Wrong answer; got {answer} instead of {expected}' print('All tests passed') |
Traceback (most recent call last):
File "/usr/src/app/main.py", line 122, in <module>
answer = rref(arr, 37)
File "/usr/local/lib/python3.10/dist-packages/numba/core/dispatcher.py", line 468, in _compile_for_args
error_rewrite(e, 'typing')
File "/usr/local/lib/python3.10/dist-packages/numba/core/dispatcher.py", line 409, in error_rewrite
raise e.with_traceback(None)
numba.core.errors.TypingError: Failed in nopython mode pipeline (step: nopython frontend)
Unknown attribute 'length' of type ListType[int64]
File "main.py", line 84:
def rref(matrix, graphlen):
<source elided>
# Eliminate the pivot column in all other rows
for i in range(others.length):
^
During: typing of get attribute at /usr/src/app/main.py (84)
File "main.py", line 84:
def rref(matrix, graphlen):
<source elided>
# Eliminate the pivot column in all other rows
for i in range(others.length):
^
Testing if the previous output contains the string All tests passed
: False
Testing if the previous output contains the string njit
: True
Testing if the previous output contains the string nopython
: False
Testing if the previous output contains the string import numba
: False
Testing if the previous output contains the string from numba
: True
Rewrite this function to use numba and nopython mode. You can assume that the input is a 2d matrix correctly formatted. Call it rref still. def rref(matrix, graphlen): PH = 16 extra = 0 col = 0 pivots = [] used_for_row = [set([i]) for i in range(matrix.shape[0])] matrix = matrix%PH while col+extra < matrix.shape[1]-1 and col < matrix.shape[0]: if matrix[col,col+extra] == 0: if np.all(matrix[:,col] == 0): extra += 1 continue other = np.argwhere(matrix[:,col+extra] != 0).flatten()[-1] if other < col: extra += 1 continue matrix[col], matrix[other] = list(matrix[other]), list(matrix[col]) used_for_row[col], used_for_row[other] = used_for_row[other], used_for_row[col] pivots.append(col+extra) pivot = matrix[col,col+extra] if col+extra < graphlen: assert np.abs(pivot) == 1 or np.abs(pivot) == PH-1 else: assert np.abs(pivot) == 2 or np.abs(pivot) == PH-2 pivot //= 2 matrix[col] *= pivot matrix[col] %= PH others = np.argwhere(matrix[:,col+extra]).flatten() for i in others: if i == col: continue used_for_row[i] |= used_for_row[col] if col < graphlen: matrix[i] -= matrix[col]*matrix[i,col+extra] else: while matrix[i,col+extra] != 0: matrix[i] = (matrix[i]-matrix[col])%PH matrix[i] %= PH col += 1 matrix = np.array(matrix)%PH return [sorted(x) for x in used_for_row]
Rewrite this function to use numba and nopython mode. You can assume that the input is a 2d matrix correctly formatted. Call it rref still. def rref(matrix, graphlen): PH = 16 extra = 0 col = 0 pivots = [] used_for_row = [set([i]) for i in range(matrix.shape[0])] matrix = matrix%PH while col+extra < matrix.shape[1]-1 and col < matrix.shape[0]: if matrix[col,col+extra] == 0: if np.all(matrix[:,col] == 0): extra += 1 continue other = np.argwhere(matrix[:,col+extra] != 0).flatten()[-1] if other < col: extra += 1 continue matrix[col], matrix[other] = list(matrix[other]), list(matrix[col]) used_for_row[col], used_for_row[other] = used_for_row[other], used_for_row[col] pivots.append(col+extra) pivot = matrix[col,col+extra] if col+extra < graphlen: assert np.abs(pivot) == 1 or np.abs(pivot) == PH-1 else: assert np.abs(pivot) == 2 or np.abs(pivot) == PH-2 pivot //= 2 matrix[col] *= pivot matrix[col] %= PH others = np.argwhere(matrix[:,col+extra]).flatten() for i in others: if i == col: continue used_for_row[i] |= used_for_row[col] if col < graphlen: matrix[i] -= matrix[col]*matrix[i,col+extra] else: while matrix[i,col+extra] != 0: matrix[i] = (matrix[i]-matrix[col])%PH matrix[i] %= PH col += 1 matrix = np.array(matrix)%PH return [sorted(x) for x in used_for_row]
Certainly! Here's the rewritten `rref` function optimized with Numba using `nopython` mode. This version leverages Numba's just-in-time (JIT) compilation to accelerate performance. To handle the `used_for_row` logic, which originally used Python sets, we replace them with sorted lists and implement a helper function to merge these lists without duplicates.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 | import numpy as np from numba import njit, types from numba.typed import List @njit def merge_sorted_lists(a, b): """ Merge two sorted lists into one sorted list without duplicates. """ i = 0 j = 0 merged = List() len_a = len(a) len_b = len(b) while i < len_a and j < len_b: if a[i] < b[j]: merged.append(a[i]) i += 1 elif a[i] > b[j]: merged.append(b[j]) j += 1 else: merged.append(a[i]) i += 1 j += 1 while i < len_a: merged.append(a[i]) i += 1 while j < len_b: merged.append(b[j]) j += 1 return merged @njit def rref(matrix, graphlen): """ Compute the Reduced Row Echelon Form (RREF) of a matrix using modular arithmetic with modulus PH=16. Tracks the rows used to form each row in the RREF. Parameters: - matrix: 2D numpy array of integers. - graphlen: Integer parameter influencing pivot normalization. Returns: - A list of sorted lists, where each sublist contains the original row indices that contribute to the corresponding row in the RREF. """ PH = 16 extra = 0 col = 0 nrows, ncols = matrix.shape # Initialize used_for_row with each row containing only itself used_for_row = List() for i in range(nrows): row = List() row.append(i) used_for_row.append(row) # Apply modulus to the entire matrix initially for r in range(nrows): for c in range(ncols): matrix[r, c] %= PH while (col + extra < ncols - 1) and (col < nrows): if matrix[col, col + extra] == 0: # Check if the entire column (col + extra) is zero all_zero = True for r in range(nrows): if matrix[r, col + extra] != 0: all_zero = False break if all_zero: extra += 1 continue # Find the last row with a non-zero entry in the current column other = -1 for r in range(nrows): if matrix[r, col + extra] != 0: other = r if other < col: extra += 1 continue # Swap the current row with the 'other' row if other != col: for c in range(ncols): temp = matrix[col, c] matrix[col, c] = matrix[other, c] matrix[other, c] = temp # Swap the used_for_row entries temp_row = used_for_row[col] used_for_row[col] = used_for_row[other] used_for_row[other] = temp_row # Record the pivot column (optional, not returned) # pivots.append(col + extra) pivot = matrix[col, col + extra] if col + extra < graphlen: # Ensure pivot is ±1 modulo PH # (Assertions are not supported in nopython, so they are omitted) pass else: # Ensure pivot is ±2 modulo PH and adjust pivot = pivot // 2 # Normalize the pivot row for c in range(ncols): matrix[col, c] = (matrix[col, c] * pivot) % PH # Find all other rows with a non-zero entry in the pivot column others = List() for r in range(nrows): if r != col and matrix[r, col + extra] != 0: others.append(r) # Eliminate the pivot column entries in other rows for i in others: # Merge the contributing rows used_for_row[i] = merge_sorted_lists(used_for_row[i], used_for_row[col]) if col < graphlen: factor = matrix[i, col + extra] for c in range(ncols): matrix[i, c] = (matrix[i, c] - matrix[col, c] * factor) % PH else: while matrix[i, col + extra] != 0: for c in range(ncols): matrix[i, c] = (matrix[i, c] - matrix[col, c]) % PH col += 1 # Ensure all matrix entries are within modulo PH for r in range(nrows): for c in range(ncols): matrix[r, c] %= PH return used_for_row |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | # Sample matrix matrix = np.array([ [2, 1, -1, -4], [-3, -1, 2, -11], [-2, 1, 2, -3] ], dtype=np.int64) graphlen = 2 # Example graphlen value # Convert the matrix to a mutable type for Numba matrix_nb = matrix.copy() # Compute RREF used_rows = rref(matrix_nb, graphlen) # Display the result for i, row in enumerate(used_rows): print(f"Row {i} is formed by original rows: {list(row)}") |
I extracted the following code from that output:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 | import numpy as np from numba import njit, types from numba.typed import List @njit def merge_sorted_lists(a, b): """ Merge two sorted lists into one sorted list without duplicates. """ i = 0 j = 0 merged = List() len_a = len(a) len_b = len(b) while i < len_a and j < len_b: if a[i] < b[j]: merged.append(a[i]) i += 1 elif a[i] > b[j]: merged.append(b[j]) j += 1 else: merged.append(a[i]) i += 1 j += 1 while i < len_a: merged.append(a[i]) i += 1 while j < len_b: merged.append(b[j]) j += 1 return merged @njit def rref(matrix, graphlen): """ Compute the Reduced Row Echelon Form (RREF) of a matrix using modular arithmetic with modulus PH=16. Tracks the rows used to form each row in the RREF. Parameters: - matrix: 2D numpy array of integers. - graphlen: Integer parameter influencing pivot normalization. Returns: - A list of sorted lists, where each sublist contains the original row indices that contribute to the corresponding row in the RREF. """ PH = 16 extra = 0 col = 0 nrows, ncols = matrix.shape # Initialize used_for_row with each row containing only itself used_for_row = List() for i in range(nrows): row = List() row.append(i) used_for_row.append(row) # Apply modulus to the entire matrix initially for r in range(nrows): for c in range(ncols): matrix[r, c] %= PH while (col + extra < ncols - 1) and (col < nrows): if matrix[col, col + extra] == 0: # Check if the entire column (col + extra) is zero all_zero = True for r in range(nrows): if matrix[r, col + extra] != 0: all_zero = False break if all_zero: extra += 1 continue # Find the last row with a non-zero entry in the current column other = -1 for r in range(nrows): if matrix[r, col + extra] != 0: other = r if other < col: extra += 1 continue # Swap the current row with the 'other' row if other != col: for c in range(ncols): temp = matrix[col, c] matrix[col, c] = matrix[other, c] matrix[other, c] = temp # Swap the used_for_row entries temp_row = used_for_row[col] used_for_row[col] = used_for_row[other] used_for_row[other] = temp_row # Record the pivot column (optional, not returned) # pivots.append(col + extra) pivot = matrix[col, col + extra] if col + extra < graphlen: # Ensure pivot is ±1 modulo PH # (Assertions are not supported in nopython, so they are omitted) pass else: # Ensure pivot is ±2 modulo PH and adjust pivot = pivot // 2 # Normalize the pivot row for c in range(ncols): matrix[col, c] = (matrix[col, c] * pivot) % PH # Find all other rows with a non-zero entry in the pivot column others = List() for r in range(nrows): if r != col and matrix[r, col + extra] != 0: others.append(r) # Eliminate the pivot column entries in other rows for i in others: # Merge the contributing rows used_for_row[i] = merge_sorted_lists(used_for_row[i], used_for_row[col]) if col < graphlen: factor = matrix[i, col + extra] for c in range(ncols): matrix[i, c] = (matrix[i, c] - matrix[col, c] * factor) % PH else: while matrix[i, col + extra] != 0: for c in range(ncols): matrix[i, c] = (matrix[i, c] - matrix[col, c]) % PH col += 1 # Ensure all matrix entries are within modulo PH for r in range(nrows): for c in range(ncols): matrix[r, c] %= PH return used_for_row |
Running the following program:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 | import numpy as np from numba import njit, types from numba.typed import List @njit def merge_sorted_lists(a, b): """ Merge two sorted lists into one sorted list without duplicates. """ i = 0 j = 0 merged = List() len_a = len(a) len_b = len(b) while i < len_a and j < len_b: if a[i] < b[j]: merged.append(a[i]) i += 1 elif a[i] > b[j]: merged.append(b[j]) j += 1 else: merged.append(a[i]) i += 1 j += 1 while i < len_a: merged.append(a[i]) i += 1 while j < len_b: merged.append(b[j]) j += 1 return merged @njit def rref(matrix, graphlen): """ Compute the Reduced Row Echelon Form (RREF) of a matrix using modular arithmetic with modulus PH=16. Tracks the rows used to form each row in the RREF. Parameters: - matrix: 2D numpy array of integers. - graphlen: Integer parameter influencing pivot normalization. Returns: - A list of sorted lists, where each sublist contains the original row indices that contribute to the corresponding row in the RREF. """ PH = 16 extra = 0 col = 0 nrows, ncols = matrix.shape # Initialize used_for_row with each row containing only itself used_for_row = List() for i in range(nrows): row = List() row.append(i) used_for_row.append(row) # Apply modulus to the entire matrix initially for r in range(nrows): for c in range(ncols): matrix[r, c] %= PH while (col + extra < ncols - 1) and (col < nrows): if matrix[col, col + extra] == 0: # Check if the entire column (col + extra) is zero all_zero = True for r in range(nrows): if matrix[r, col + extra] != 0: all_zero = False break if all_zero: extra += 1 continue # Find the last row with a non-zero entry in the current column other = -1 for r in range(nrows): if matrix[r, col + extra] != 0: other = r if other < col: extra += 1 continue # Swap the current row with the 'other' row if other != col: for c in range(ncols): temp = matrix[col, c] matrix[col, c] = matrix[other, c] matrix[other, c] = temp # Swap the used_for_row entries temp_row = used_for_row[col] used_for_row[col] = used_for_row[other] used_for_row[other] = temp_row # Record the pivot column (optional, not returned) # pivots.append(col + extra) pivot = matrix[col, col + extra] if col + extra < graphlen: # Ensure pivot is ±1 modulo PH # (Assertions are not supported in nopython, so they are omitted) pass else: # Ensure pivot is ±2 modulo PH and adjust pivot = pivot // 2 # Normalize the pivot row for c in range(ncols): matrix[col, c] = (matrix[col, c] * pivot) % PH # Find all other rows with a non-zero entry in the pivot column others = List() for r in range(nrows): if r != col and matrix[r, col + extra] != 0: others.append(r) # Eliminate the pivot column entries in other rows for i in others: # Merge the contributing rows used_for_row[i] = merge_sorted_lists(used_for_row[i], used_for_row[col]) if col < graphlen: factor = matrix[i, col + extra] for c in range(ncols): matrix[i, c] = (matrix[i, c] - matrix[col, c] * factor) % PH else: while matrix[i, col + extra] != 0: for c in range(ncols): matrix[i, c] = (matrix[i, c] - matrix[col, c]) % PH col += 1 # Ensure all matrix entries are within modulo PH for r in range(nrows): for c in range(ncols): matrix[r, c] %= PH return used_for_row arr = np.array([[1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -10], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -20], [0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, -2, 0, 0, 0, 0, 0, 0, 0, 0, 0, -20], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -11], [0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2, 0, 0, 0, 0, 0, 0, -30], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2, 0, 0, 0, 0, 0, -20], [1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -11], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -14], [0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -10], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2, 0, 0, 0, 0, -30], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -10], [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -10], [0, 0, 0, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -11], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -13], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -11], [0, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -10], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, -2, 0, 0, 0, -20], [0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -10], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -11], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -13], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -13], [0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -11], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2, 0, 0, -10], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -13], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -11], [0, 0, 1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -9], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2, 0, -20], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2, -40], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]) answer = rref(arr, 37) expected = [[0, 38], [0, 38], [0, 6, 28, 35, 38], [0, 6, 18, 21, 28, 35, 38], [0, 6, 28, 35, 38], [0, 6, 21, 28, 35, 38], [0, 5, 10, 23, 38], [0, 5, 10, 23, 38], [0, 5, 10, 23, 38], [0, 5, 9, 10, 23, 38], [0, 5, 9, 10, 13, 17, 23, 30, 38], [0, 5, 9, 10, 11, 23, 27, 38], [0, 5, 9, 10, 11, 23, 27, 38], [0, 5, 9, 10, 11, 23, 25, 27, 38], [0, 1, 5, 7, 8, 9, 10, 11, 12, 15, 16, 19, 23, 25, 26, 27, 34, 38], [0, 1, 5, 7, 8, 9, 10, 11, 12, 15, 16, 19, 23, 25, 26, 27, 34, 38], [0, 1, 5, 7, 8, 9, 10, 11, 12, 15, 16, 19, 23, 25, 26, 27, 34, 38], [0, 1, 5, 7, 8, 9, 10, 11, 12, 15, 16, 19, 23, 25, 26, 27, 34, 38], [0, 1, 5, 7, 8, 9, 10, 11, 12, 15, 16, 19, 23, 25, 26, 27, 34, 38], [0, 1, 5, 7, 8, 9, 10, 11, 12, 15, 16, 19, 23, 25, 26, 27, 34, 38], [0, 1, 5, 7, 8, 9, 10, 11, 12, 15, 16, 19, 23, 24, 25, 26, 27, 34, 38], [0, 1, 5, 7, 8, 9, 10, 11, 12, 15, 16, 19, 23, 25, 26, 27, 34, 38], [0, 1, 5, 7, 8, 9, 10, 11, 12, 15, 16, 19, 23, 25, 26, 27, 34, 38], [0, 1, 5, 7, 8, 9, 10, 11, 12, 15, 16, 19, 23, 25, 26, 27, 34, 38], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 15, 16, 19, 20, 21, 23, 25, 26, 27, 28, 31, 34, 35, 36, 37, 38], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 15, 16, 19, 20, 21, 23, 25, 26, 27, 28, 31, 34, 35, 36, 37, 38], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 15, 16, 19, 20, 21, 23, 25, 26, 27, 28, 31, 34, 35, 36, 37, 38], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 15, 16, 19, 20, 21, 23, 25, 26, 27, 28, 31, 34, 35, 36, 37, 38], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 15, 16, 19, 20, 21, 23, 25, 26, 27, 28, 31, 34, 35, 36, 37, 38], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 15, 16, 19, 20, 21, 23, 25, 26, 27, 28, 31, 34, 35, 36, 37, 38], [0, 5, 9, 10, 13, 17, 23, 30, 38], [0, 5, 9, 10, 13, 17, 23, 30, 38], [0, 5, 9, 10, 13, 17, 23, 30, 32, 38], [0, 5, 9, 10, 13, 17, 23, 30, 32, 33, 38], [0, 22, 29, 38], [0, 22, 29, 38], [0, 6, 28, 35, 38], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 15, 16, 19, 20, 21, 23, 25, 26, 27, 28, 31, 34, 35, 36, 37, 38], [14, 18, 21, 28, 35]] assert answer == expected, f'Wrong answer; got {answer} instead of {expected}' print('All tests passed') |
Traceback (most recent call last):
File "/usr/src/app/main.py", line 154, in <module>
assert answer == expected, f'Wrong answer; got {answer} instead of {expected}'
File "/usr/local/lib/python3.10/dist-packages/numba/typed/typedlist.py", line 324, in __eq__
return _eq(self, other)
File "/usr/local/lib/python3.10/dist-packages/numba/core/dispatcher.py", line 487, in _compile_for_args
raise e
File "/usr/local/lib/python3.10/dist-packages/numba/core/dispatcher.py", line 420, in _compile_for_args
return_val = self.compile(tuple(argtypes))
File "/usr/local/lib/python3.10/dist-packages/numba/core/dispatcher.py", line 957, in compile
cres = self._compiler.compile(args, return_type)
File "/usr/local/lib/python3.10/dist-packages/numba/core/dispatcher.py", line 125, in compile
status, retval = self._compile_cached(args, return_type)
File "/usr/local/lib/python3.10/dist-packages/numba/core/dispatcher.py", line 139, in _compile_cached
retval = self._compile_core(args, return_type)
File "/usr/local/lib/python3.10/dist-packages/numba/core/dispatcher.py", line 152, in _compile_core
cres = compiler.compile_extra(self.targetdescr.typing_context,
File "/usr/local/lib/python3.10/dist-packages/numba/core/compiler.py", line 751, in compile_extra
return pipeline.compile_extra(func)
File "/usr/local/lib/python3.10/dist-packages/numba/core/compiler.py", line 445, in compile_extra
return self._compile_bytecode()
File "/usr/local/lib/python3.10/dist-packages/numba/core/compiler.py", line 513, in _compile_bytecode
return self._compile_core()
File "/usr/local/lib/python3.10/dist-packages/numba/core/compiler.py", line 492, in _compile_core
raise e
File "/usr/local/lib/python3.10/dist-packages/numba/core/compiler.py", line 479, in _compile_core
pm.run(self.state)
File "/usr/local/lib/python3.10/dist-packages/numba/core/compiler_machinery.py", line 368, in run
raise patched_exception
File "/usr/local/lib/python3.10/dist-packages/numba/core/compiler_machinery.py", line 356, in run
self._runPass(idx, pass_inst, state)
File "/usr/local/lib/python3.10/dist-packages/numba/core/compiler_lock.py", line 35, in _acquire_compile_lock
return func(*args, **kwargs)
File "/usr/local/lib/python3.10/dist-packages/numba/core/compiler_machinery.py", line 311, in _runPass
mutated |= check(pss.run_pass, internal_state)
File "/usr/local/lib/python3.10/dist-packages/numba/core/compiler_machinery.py", line 273, in check
mangled = func(compiler_state)
File "/usr/local/lib/python3.10/dist-packages/numba/core/typed_passes.py", line 470, in run_pass
lower.create_cpython_wrapper(flags.release_gil)
File "/usr/local/lib/python3.10/dist-packages/numba/core/lowering.py", line 282, in create_cpython_wrapper
self.context.create_cpython_wrapper(self.library, self.fndesc,
File "/usr/local/lib/python3.10/dist-packages/numba/core/cpu.py", line 190, in create_cpython_wrapper
builder.build()
File "/usr/local/lib/python3.10/dist-packages/numba/core/callwrapper.py", line 122, in build
self.build_wrapper(api, builder, closure, args, kws)
File "/usr/local/lib/python3.10/dist-packages/numba/core/callwrapper.py", line 158, in build_wrapper
val = cleanup_manager.add_arg(builder.load(obj), ty)
File "/usr/local/lib/python3.10/dist-packages/numba/core/callwrapper.py", line 58, in add_arg
cleanup_arg()
File "/usr/local/lib/python3.10/dist-packages/numba/core/callwrapper.py", line 40, in cleanup_arg
self.api.reflect_native_value(ty, native.value, self.env_manager)
File "/usr/local/lib/python3.10/dist-packages/numba/core/pythonapi.py", line 1470, in reflect_native_value
impl(typ, val, c)
File "/usr/local/lib/python3.10/dist-packages/numba/core/boxing.py", line 791, in reflect_list
raise TypeError(msg)
TypeError: Failed in nopython mode pipeline (step: native lowering)
cannot reflect element of reflected container: reflected list(reflected list(int64)<iv=None>)<iv=None>
Testing if the previous output contains the string All tests passed
: False
Testing if the previous output contains the string njit
: True
Testing if the previous output contains the string nopython
: True
Testing if the previous output contains the string import numba
: False
Testing if the previous output contains the string from numba
: True