Rewrite this function in C. You can assume that the input is a 2d matrix correctly formatted. Call it rref(int** matrix, int rows, int cols, int graphlen) where the size is matrix[rows][cols]. Return an int** of used_for_row. 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 in C. You can assume that the input is a 2d matrix correctly formatted. Call it rref(int** matrix, int rows, int cols, int graphlen) where the size is matrix[rows][cols]. Return an int** of used_for_row. 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]
Here's a possible implementation of the function `rref` in C:
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 | #include <stdbool.h> #include <stdint.h> #include <stdlib.h> typedef uint16_t matrix_t; typedef uint32_t set_t; // Returns the number of elements in a set. int set_size(set_t *set) { int count = 0; for (int i = 0; i < 32; i++) { if (set[i / 32] & (1 << (i % 32))) { count++; } } return count; } // Swaps two rows in a matrix. void swap_rows(matrix_t **matrix, int row1, int row2, int cols) { matrix_t *tmp = matrix[row1]; matrix[row1] = matrix[row2]; matrix[row2] = tmp; } // Returns the index of the first non-zero element in a row, starting from col. int find_pivot(matrix_t **matrix, int row, int col, int cols) { for (int i = col; i < cols; i++) { if (matrix[row][i] != 0) { return i; } } return -1; } // Returns true if all elements in a row are zero. bool is_zero_row(matrix_t **matrix, int row, int cols) { for (int i = 0; i < cols; i++) { if (matrix[row][i] != 0) { return false; } } return true; } // Computes the reduced row echelon form (RREF) of a matrix and returns an array of sets // indicating which rows are used to eliminate zeros in other rows. The input matrix is // modified in place. int **rref(matrix_t **matrix, int rows, int cols, int graphlen) { const int PH = 16; int *used_for_row = calloc(rows, sizeof(int)); for (int i = 0; i < rows; i++) { used_for_row[i] = 1 << i; } int extra = 0; int col = 0; int pivots[rows]; int num_pivots = 0; while (col + extra < cols - 1 && col < rows) { int pivot_col = find_pivot(matrix, col, col + extra, cols); if (pivot_col == -1) { if (is_zero_row(matrix, col, cols)) { extra++; continue; } int other = find_pivot(matrix, 0, col + extra, cols) + col + extra; if (other <= col) { extra++; continue; } swap_rows(matrix, col, other / cols, cols); used_for_row[col] |= used_for_row[other / cols]; } pivots[num_pivots++] = col + extra; matrix_t pivot = matrix[col][col + extra]; if (col + extra < graphlen) { if (pivot != 1 && pivot != PH - 1) { matrix[col][col + extra] = pivot == 0 ? 1 : (pivot > 0 ? PH - pivot : -pivot); } } else { if (pivot != 2 && pivot != PH - 2) { matrix[col][col + extra] = pivot == 0 ? 2 : (pivot > 0 ? PH - pivot : -pivot) / 2; } } matrix[col][col + extra] %= PH; for (int i = 0; i < rows; i++) { if (i == col) { continue; } matrix_t factor = matrix[i][col + extra]; if (factor != 0) { used_for_row[i] |= used_for_row[col]; if (col < graphlen) { for (int j = 0; j < cols; j++) { matrix[i][j] = (matrix[i][j] - matrix[col][j] * factor + PH) % PH; } } else { while (matrix[i][col + extra] != 0) { for (int j = 0; j < cols; j++) { matrix[i][j] = (matrix[i][j] - matrix[col][j] + PH) % PH; } } } } } col++; } for (int i = 0; i < rows; i++) { used_for_row[i] = set_size(used_for_row + (i >> 5)) - __builtin_popcount((used_for_row[i] >> (i % 32)) & ((1 << (i % 32 + 1)) - 1)); } int **result = malloc(rows * sizeof(int *)); for (int i = 0; i < rows; i++) { result[i] = malloc(used_for_row[i] * sizeof(int)); int *set = result[i]; int j = 0; for (int k = 0; k < rows; k++) { if ((used_for_row[i] >> k) & 1) { set[j++] = k; } } } free(used_for_row); return 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 116 117 118 119 120 121 122 123 124 | #include <stdbool.h> #include <stdint.h> #include <stdlib.h> typedef uint16_t matrix_t; typedef uint32_t set_t; // Returns the number of elements in a set. int set_size(set_t *set) { int count = 0; for (int i = 0; i < 32; i++) { if (set[i / 32] & (1 << (i % 32))) { count++; } } return count; } // Swaps two rows in a matrix. void swap_rows(matrix_t **matrix, int row1, int row2, int cols) { matrix_t *tmp = matrix[row1]; matrix[row1] = matrix[row2]; matrix[row2] = tmp; } // Returns the index of the first non-zero element in a row, starting from col. int find_pivot(matrix_t **matrix, int row, int col, int cols) { for (int i = col; i < cols; i++) { if (matrix[row][i] != 0) { return i; } } return -1; } // Returns true if all elements in a row are zero. bool is_zero_row(matrix_t **matrix, int row, int cols) { for (int i = 0; i < cols; i++) { if (matrix[row][i] != 0) { return false; } } return true; } // Computes the reduced row echelon form (RREF) of a matrix and returns an array of sets // indicating which rows are used to eliminate zeros in other rows. The input matrix is // modified in place. int **rref(matrix_t **matrix, int rows, int cols, int graphlen) { const int PH = 16; int *used_for_row = calloc(rows, sizeof(int)); for (int i = 0; i < rows; i++) { used_for_row[i] = 1 << i; } int extra = 0; int col = 0; int pivots[rows]; int num_pivots = 0; while (col + extra < cols - 1 && col < rows) { int pivot_col = find_pivot(matrix, col, col + extra, cols); if (pivot_col == -1) { if (is_zero_row(matrix, col, cols)) { extra++; continue; } int other = find_pivot(matrix, 0, col + extra, cols) + col + extra; if (other <= col) { extra++; continue; } swap_rows(matrix, col, other / cols, cols); used_for_row[col] |= used_for_row[other / cols]; } pivots[num_pivots++] = col + extra; matrix_t pivot = matrix[col][col + extra]; if (col + extra < graphlen) { if (pivot != 1 && pivot != PH - 1) { matrix[col][col + extra] = pivot == 0 ? 1 : (pivot > 0 ? PH - pivot : -pivot); } } else { if (pivot != 2 && pivot != PH - 2) { matrix[col][col + extra] = pivot == 0 ? 2 : (pivot > 0 ? PH - pivot : -pivot) / 2; } } matrix[col][col + extra] %= PH; for (int i = 0; i < rows; i++) { if (i == col) { continue; } matrix_t factor = matrix[i][col + extra]; if (factor != 0) { used_for_row[i] |= used_for_row[col]; if (col < graphlen) { for (int j = 0; j < cols; j++) { matrix[i][j] = (matrix[i][j] - matrix[col][j] * factor + PH) % PH; } } else { while (matrix[i][col + extra] != 0) { for (int j = 0; j < cols; j++) { matrix[i][j] = (matrix[i][j] - matrix[col][j] + PH) % PH; } } } } } col++; } for (int i = 0; i < rows; i++) { used_for_row[i] = set_size(used_for_row + (i >> 5)) - __builtin_popcount((used_for_row[i] >> (i % 32)) & ((1 << (i % 32 + 1)) - 1)); } int **result = malloc(rows * sizeof(int *)); for (int i = 0; i < rows; i++) { result[i] = malloc(used_for_row[i] * sizeof(int)); int *set = result[i]; int j = 0; for (int k = 0; k < rows; k++) { if ((used_for_row[i] >> k) & 1) { set[j++] = k; } } } free(used_for_row); 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 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 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 | #include <stdbool.h> #include <stdint.h> #include <stdlib.h> typedef uint16_t matrix_t; typedef uint32_t set_t; // Returns the number of elements in a set. int set_size(set_t *set) { int count = 0; for (int i = 0; i < 32; i++) { if (set[i / 32] & (1 << (i % 32))) { count++; } } return count; } // Swaps two rows in a matrix. void swap_rows(matrix_t **matrix, int row1, int row2, int cols) { matrix_t *tmp = matrix[row1]; matrix[row1] = matrix[row2]; matrix[row2] = tmp; } // Returns the index of the first non-zero element in a row, starting from col. int find_pivot(matrix_t **matrix, int row, int col, int cols) { for (int i = col; i < cols; i++) { if (matrix[row][i] != 0) { return i; } } return -1; } // Returns true if all elements in a row are zero. bool is_zero_row(matrix_t **matrix, int row, int cols) { for (int i = 0; i < cols; i++) { if (matrix[row][i] != 0) { return false; } } return true; } // Computes the reduced row echelon form (RREF) of a matrix and returns an array of sets // indicating which rows are used to eliminate zeros in other rows. The input matrix is // modified in place. int **rref(matrix_t **matrix, int rows, int cols, int graphlen) { const int PH = 16; int *used_for_row = calloc(rows, sizeof(int)); for (int i = 0; i < rows; i++) { used_for_row[i] = 1 << i; } int extra = 0; int col = 0; int pivots[rows]; int num_pivots = 0; while (col + extra < cols - 1 && col < rows) { int pivot_col = find_pivot(matrix, col, col + extra, cols); if (pivot_col == -1) { if (is_zero_row(matrix, col, cols)) { extra++; continue; } int other = find_pivot(matrix, 0, col + extra, cols) + col + extra; if (other <= col) { extra++; continue; } swap_rows(matrix, col, other / cols, cols); used_for_row[col] |= used_for_row[other / cols]; } pivots[num_pivots++] = col + extra; matrix_t pivot = matrix[col][col + extra]; if (col + extra < graphlen) { if (pivot != 1 && pivot != PH - 1) { matrix[col][col + extra] = pivot == 0 ? 1 : (pivot > 0 ? PH - pivot : -pivot); } } else { if (pivot != 2 && pivot != PH - 2) { matrix[col][col + extra] = pivot == 0 ? 2 : (pivot > 0 ? PH - pivot : -pivot) / 2; } } matrix[col][col + extra] %= PH; for (int i = 0; i < rows; i++) { if (i == col) { continue; } matrix_t factor = matrix[i][col + extra]; if (factor != 0) { used_for_row[i] |= used_for_row[col]; if (col < graphlen) { for (int j = 0; j < cols; j++) { matrix[i][j] = (matrix[i][j] - matrix[col][j] * factor + PH) % PH; } } else { while (matrix[i][col + extra] != 0) { for (int j = 0; j < cols; j++) { matrix[i][j] = (matrix[i][j] - matrix[col][j] + PH) % PH; } } } } } col++; } for (int i = 0; i < rows; i++) { used_for_row[i] = set_size(used_for_row + (i >> 5)) - __builtin_popcount((used_for_row[i] >> (i % 32)) & ((1 << (i % 32 + 1)) - 1)); } int **result = malloc(rows * sizeof(int *)); for (int i = 0; i < rows; i++) { result[i] = malloc(used_for_row[i] * sizeof(int)); int *set = result[i]; int j = 0; for (int k = 0; k < rows; k++) { if ((used_for_row[i] >> k) & 1) { set[j++] = k; } } } free(used_for_row); return result; } #include<stdio.h> #include<stdlib.h> int main() { int arr0[] = {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}; int arr1[] = {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}; int arr2[] = {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}; int arr3[] = {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}; int arr4[] = {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}; int arr5[] = {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}; int arr6[] = {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}; int arr7[] = {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}; int arr8[] = {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}; int arr9[] = {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}; int arr10[] = {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}; int arr11[] = {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}; int arr12[] = {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}; int arr13[] = {0, 0, 0, 0, 0, 0, 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}; int arr14[] = {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}; int arr15[] = {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}; int arr16[] = {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}; int arr17[] = {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}; int arr18[] = {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}; int arr19[] = {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}; int arr20[] = {0, 0, 0, 0, 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}; int arr21[] = {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}; int arr22[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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}; int arr23[] = {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}; int arr24[] = {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}; int arr25[] = {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}; int arr26[] = {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}; int arr27[] = {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}; int arr28[] = {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}; int arr29[] = {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}; int arr30[] = {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}; int arr31[] = {0, 0, 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}; int arr32[] = {0, 0, 0, 0, 0, 0, 0, 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}; int arr33[] = {0, 0, 0, 0, 0, 0, 0, 0, 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}; int arr34[] = {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}; int arr35[] = {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}; int arr36[] = {0, 0, 0, 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}; int arr37[] = {0, 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}; int arr38[] = {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}; int* arr[] = {arr0, arr1, arr2, arr3, arr4, arr5, arr6, arr7, arr8, arr9, arr10, arr11, arr12, arr13, arr14, arr15, arr16, arr17, arr18, arr19, arr20, arr21, arr22, arr23, arr24, arr25, arr26, arr27, arr28, arr29, arr30, arr31, arr32, arr33, arr34, arr35, arr36, arr37, arr38}; int** got = rref(arr, 39, 49, 37); int answer = got[3][0]+got[3][1]+got[3][2]+got[3][3]+got[3][4]+got[3][5]+got[3][6]; int expected = 146; if (answer != expected) { printf("Wrong answer; got %d instead of %d.\n", answer, expected); exit(1); } printf("All tests passed\n"); } |
main.c: In function 'main':
main.c:173:18: warning: passing argument 1 of 'rref' from incompatible pointer type [-Wincompatible-pointer-types]
173 | int** got = rref(arr, 39, 49, 37);
| ^~~
| |
| int **
main.c:50:23: note: expected 'matrix_t **' {aka 'short unsigned int **'} but argument is of type 'int **'
50 | int **rref(matrix_t **matrix, int rows, int cols, int graphlen) {
| ~~~~~~~~~~~^~~~~~
main.sh: line 2: 16 Segmentation fault (core dumped) ./a.out
Testing if the previous output contains the string All tests passed
: False
Rewrite this function in C. You can assume that the input is a 2d matrix correctly formatted. Call it rref(int** matrix, int rows, int cols, int graphlen) where the size is matrix[rows][cols]. Return an int** of used_for_row. 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 in C. You can assume that the input is a 2d matrix correctly formatted. Call it rref(int** matrix, int rows, int cols, int graphlen) where the size is matrix[rows][cols]. Return an int** of used_for_row. 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]
Here's a possible implementation of the rref function in C:
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 | #include <stdbool.h> #include <stdlib.h> #include <stdio.h> #define PH 16 // Function to swap two rows of a matrix void swap_rows(int** matrix, int i, int j, int cols) { int tmp[cols]; for (int k = 0; k < cols; k++) { tmp[k] = matrix[i][k]; matrix[i][k] = matrix[j][k]; matrix[j][k] = tmp[k]; } } // Function to perform Gaussian elimination on a matrix void gaussian_elimination(int** matrix, int* used_for_row, int rows, int cols, int graphlen) { int extra = 0; int col = 0; int pivots[rows]; int num_pivots = 0; bool row_is_zero[rows]; for (int i = 0; i < rows; i++) { row_is_zero[i] = true; for (int j = col; j < cols; j++) { if (matrix[i][j] != 0) { row_is_zero[i] = false; break; } } } while (col + extra < cols - 1 && col < rows) { int i = 0; for (i = 0; i < rows && row_is_zero[i]; i++); if (i == rows) { extra++; continue; } if (matrix[i][col + extra] == 0) { int j = i + 1; for (; j < rows && matrix[j][col + extra] == 0; j++); if (j == rows) { extra++; continue; } swap_rows(matrix, i, j, cols); used_for_row[i] = used_for_row[j]; } pivots[num_pivots++] = col + extra; int pivot = matrix[i][col + extra]; if (col + extra < graphlen) { if (abs(pivot) != 1 && abs(pivot) != PH - 1) { printf("Error: invalid pivot value\n"); exit(1); } } else { if (abs(pivot) != 2 && abs(pivot) != PH - 2) { printf("Error: invalid pivot value\n"); exit(1); } pivot /= 2; } matrix[i][col + extra] = pivot; for (int j = 0; j < rows; j++) { if (j == i) continue; int factor = matrix[j][col + extra]; if (col + extra < graphlen) { matrix[j][col + extra] = 0; for (int k = col + extra + 1; k < cols; k++) { matrix[j][k] -= matrix[i][k] * factor; } } else { while (matrix[j][col + extra] != 0) { matrix[j] = (matrix[j] - matrix[i]) % PH; } } used_for_row[j] |= used_for_row[i]; } col++; } for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { matrix[i][j] %= PH; } } } // Function to convert a set of integers to an array of integers in C int** set_to_array(int* set, int size) { int* array = malloc(size * sizeof(int)); int* current = array; for (int i = 0; i < size; i++) { if (set[i] / 32 != (*current) / 32) { (*current)++; } int index = set[i] % 32; array[*current] |= 1 << index; } int* length = malloc(sizeof(int)); *length = current - array + 1; int** result = malloc(2 * sizeof(int*)); result[0] = array; result[1] = length; return result; } // Function to perform reduced row echelon form on a matrix int** rref(int** matrix, int rows, int cols, int graphlen) { int** used_for_row = calloc(rows, sizeof(int*)); for (int i = 0; i < rows; i++) { used_for_row[i] = calloc(rows, sizeof(int)); used_for_row[i][i / 32] |= 1 << (i % 32); } gaussian_elimination(matrix, used_for_row, rows, cols, graphlen); int** result = set_to_array(used_for_row[0], rows); for (int i = 1; i < rows; i++) { int* temp = set_to_array(used_for_row[i], rows); for (int j = 0; j < *(result[1]); j++) { result[0][j] |= temp[j]; } free(temp[0]); free(temp[1]); free(temp); } for (int i = 0; i < rows; i++) { free(used_for_row[i]); } free(used_for_row); return 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 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 | #include <stdbool.h> #include <stdlib.h> #include <stdio.h> #define PH 16 // Function to swap two rows of a matrix void swap_rows(int** matrix, int i, int j, int cols) { int tmp[cols]; for (int k = 0; k < cols; k++) { tmp[k] = matrix[i][k]; matrix[i][k] = matrix[j][k]; matrix[j][k] = tmp[k]; } } // Function to perform Gaussian elimination on a matrix void gaussian_elimination(int** matrix, int* used_for_row, int rows, int cols, int graphlen) { int extra = 0; int col = 0; int pivots[rows]; int num_pivots = 0; bool row_is_zero[rows]; for (int i = 0; i < rows; i++) { row_is_zero[i] = true; for (int j = col; j < cols; j++) { if (matrix[i][j] != 0) { row_is_zero[i] = false; break; } } } while (col + extra < cols - 1 && col < rows) { int i = 0; for (i = 0; i < rows && row_is_zero[i]; i++); if (i == rows) { extra++; continue; } if (matrix[i][col + extra] == 0) { int j = i + 1; for (; j < rows && matrix[j][col + extra] == 0; j++); if (j == rows) { extra++; continue; } swap_rows(matrix, i, j, cols); used_for_row[i] = used_for_row[j]; } pivots[num_pivots++] = col + extra; int pivot = matrix[i][col + extra]; if (col + extra < graphlen) { if (abs(pivot) != 1 && abs(pivot) != PH - 1) { printf("Error: invalid pivot value\n"); exit(1); } } else { if (abs(pivot) != 2 && abs(pivot) != PH - 2) { printf("Error: invalid pivot value\n"); exit(1); } pivot /= 2; } matrix[i][col + extra] = pivot; for (int j = 0; j < rows; j++) { if (j == i) continue; int factor = matrix[j][col + extra]; if (col + extra < graphlen) { matrix[j][col + extra] = 0; for (int k = col + extra + 1; k < cols; k++) { matrix[j][k] -= matrix[i][k] * factor; } } else { while (matrix[j][col + extra] != 0) { matrix[j] = (matrix[j] - matrix[i]) % PH; } } used_for_row[j] |= used_for_row[i]; } col++; } for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { matrix[i][j] %= PH; } } } // Function to convert a set of integers to an array of integers in C int** set_to_array(int* set, int size) { int* array = malloc(size * sizeof(int)); int* current = array; for (int i = 0; i < size; i++) { if (set[i] / 32 != (*current) / 32) { (*current)++; } int index = set[i] % 32; array[*current] |= 1 << index; } int* length = malloc(sizeof(int)); *length = current - array + 1; int** result = malloc(2 * sizeof(int*)); result[0] = array; result[1] = length; return result; } // Function to perform reduced row echelon form on a matrix int** rref(int** matrix, int rows, int cols, int graphlen) { int** used_for_row = calloc(rows, sizeof(int*)); for (int i = 0; i < rows; i++) { used_for_row[i] = calloc(rows, sizeof(int)); used_for_row[i][i / 32] |= 1 << (i % 32); } gaussian_elimination(matrix, used_for_row, rows, cols, graphlen); int** result = set_to_array(used_for_row[0], rows); for (int i = 1; i < rows; i++) { int* temp = set_to_array(used_for_row[i], rows); for (int j = 0; j < *(result[1]); j++) { result[0][j] |= temp[j]; } free(temp[0]); free(temp[1]); free(temp); } for (int i = 0; i < rows; i++) { free(used_for_row[i]); } free(used_for_row); 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 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 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 | #include <stdbool.h> #include <stdlib.h> #include <stdio.h> #define PH 16 // Function to swap two rows of a matrix void swap_rows(int** matrix, int i, int j, int cols) { int tmp[cols]; for (int k = 0; k < cols; k++) { tmp[k] = matrix[i][k]; matrix[i][k] = matrix[j][k]; matrix[j][k] = tmp[k]; } } // Function to perform Gaussian elimination on a matrix void gaussian_elimination(int** matrix, int* used_for_row, int rows, int cols, int graphlen) { int extra = 0; int col = 0; int pivots[rows]; int num_pivots = 0; bool row_is_zero[rows]; for (int i = 0; i < rows; i++) { row_is_zero[i] = true; for (int j = col; j < cols; j++) { if (matrix[i][j] != 0) { row_is_zero[i] = false; break; } } } while (col + extra < cols - 1 && col < rows) { int i = 0; for (i = 0; i < rows && row_is_zero[i]; i++); if (i == rows) { extra++; continue; } if (matrix[i][col + extra] == 0) { int j = i + 1; for (; j < rows && matrix[j][col + extra] == 0; j++); if (j == rows) { extra++; continue; } swap_rows(matrix, i, j, cols); used_for_row[i] = used_for_row[j]; } pivots[num_pivots++] = col + extra; int pivot = matrix[i][col + extra]; if (col + extra < graphlen) { if (abs(pivot) != 1 && abs(pivot) != PH - 1) { printf("Error: invalid pivot value\n"); exit(1); } } else { if (abs(pivot) != 2 && abs(pivot) != PH - 2) { printf("Error: invalid pivot value\n"); exit(1); } pivot /= 2; } matrix[i][col + extra] = pivot; for (int j = 0; j < rows; j++) { if (j == i) continue; int factor = matrix[j][col + extra]; if (col + extra < graphlen) { matrix[j][col + extra] = 0; for (int k = col + extra + 1; k < cols; k++) { matrix[j][k] -= matrix[i][k] * factor; } } else { while (matrix[j][col + extra] != 0) { matrix[j] = (matrix[j] - matrix[i]) % PH; } } used_for_row[j] |= used_for_row[i]; } col++; } for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { matrix[i][j] %= PH; } } } // Function to convert a set of integers to an array of integers in C int** set_to_array(int* set, int size) { int* array = malloc(size * sizeof(int)); int* current = array; for (int i = 0; i < size; i++) { if (set[i] / 32 != (*current) / 32) { (*current)++; } int index = set[i] % 32; array[*current] |= 1 << index; } int* length = malloc(sizeof(int)); *length = current - array + 1; int** result = malloc(2 * sizeof(int*)); result[0] = array; result[1] = length; return result; } // Function to perform reduced row echelon form on a matrix int** rref(int** matrix, int rows, int cols, int graphlen) { int** used_for_row = calloc(rows, sizeof(int*)); for (int i = 0; i < rows; i++) { used_for_row[i] = calloc(rows, sizeof(int)); used_for_row[i][i / 32] |= 1 << (i % 32); } gaussian_elimination(matrix, used_for_row, rows, cols, graphlen); int** result = set_to_array(used_for_row[0], rows); for (int i = 1; i < rows; i++) { int* temp = set_to_array(used_for_row[i], rows); for (int j = 0; j < *(result[1]); j++) { result[0][j] |= temp[j]; } free(temp[0]); free(temp[1]); free(temp); } for (int i = 0; i < rows; i++) { free(used_for_row[i]); } free(used_for_row); return result; } #include<stdio.h> #include<stdlib.h> int main() { int arr0[] = {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}; int arr1[] = {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}; int arr2[] = {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}; int arr3[] = {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}; int arr4[] = {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}; int arr5[] = {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}; int arr6[] = {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}; int arr7[] = {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}; int arr8[] = {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}; int arr9[] = {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}; int arr10[] = {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}; int arr11[] = {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}; int arr12[] = {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}; int arr13[] = {0, 0, 0, 0, 0, 0, 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}; int arr14[] = {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}; int arr15[] = {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}; int arr16[] = {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}; int arr17[] = {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}; int arr18[] = {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}; int arr19[] = {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}; int arr20[] = {0, 0, 0, 0, 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}; int arr21[] = {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}; int arr22[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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}; int arr23[] = {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}; int arr24[] = {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}; int arr25[] = {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}; int arr26[] = {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}; int arr27[] = {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}; int arr28[] = {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}; int arr29[] = {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}; int arr30[] = {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}; int arr31[] = {0, 0, 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}; int arr32[] = {0, 0, 0, 0, 0, 0, 0, 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}; int arr33[] = {0, 0, 0, 0, 0, 0, 0, 0, 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}; int arr34[] = {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}; int arr35[] = {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}; int arr36[] = {0, 0, 0, 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}; int arr37[] = {0, 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}; int arr38[] = {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}; int* arr[] = {arr0, arr1, arr2, arr3, arr4, arr5, arr6, arr7, arr8, arr9, arr10, arr11, arr12, arr13, arr14, arr15, arr16, arr17, arr18, arr19, arr20, arr21, arr22, arr23, arr24, arr25, arr26, arr27, arr28, arr29, arr30, arr31, arr32, arr33, arr34, arr35, arr36, arr37, arr38}; int** got = rref(arr, 39, 49, 37); int answer = got[3][0]+got[3][1]+got[3][2]+got[3][3]+got[3][4]+got[3][5]+got[3][6]; int expected = 146; if (answer != expected) { printf("Wrong answer; got %d instead of %d.\n", answer, expected); exit(1); } printf("All tests passed\n"); } |
main.c: In function 'gaussian_elimination':
main.c:76:31: warning: assignment to 'int *' from 'long int' makes pointer from integer without a cast [-Wint-conversion]
76 | matrix[j] = (matrix[j] - matrix[i]) % PH;
| ^
main.c: In function 'rref':
main.c:116:34: warning: passing argument 2 of 'gaussian_elimination' from incompatible pointer type [-Wincompatible-pointer-types]
116 | gaussian_elimination(matrix, used_for_row, rows, cols, graphlen);
| ^~~~~~~~~~~~
| |
| int **
main.c:19:46: note: expected 'int *' but argument is of type 'int **'
19 | void gaussian_elimination(int** matrix, int* used_for_row, int rows, int cols, int graphlen) {
| ~~~~~^~~~~~~~~~~~
main.c:119:21: warning: initialization of 'int *' from incompatible pointer type 'int **' [-Wincompatible-pointer-types]
119 | int* temp = set_to_array(used_for_row[i], rows);
| ^~~~~~~~~~~~
main.c:123:18: warning: passing argument 1 of 'free' makes pointer from integer without a cast [-Wint-conversion]
123 | free(temp[0]);
| ~~~~^~~
| |
| int
In file included from main.c:3:
/usr/include/stdlib.h:555:25: note: expected 'void *' but argument is of type 'int'
555 | extern void free (void *__ptr) __THROW;
| ~~~~~~^~~~~
main.c:124:18: warning: passing argument 1 of 'free' makes pointer from integer without a cast [-Wint-conversion]
124 | free(temp[1]);
| ~~~~^~~
| |
| int
In file included from main.c:3:
/usr/include/stdlib.h:555:25: note: expected 'void *' but argument is of type 'int'
555 | extern void free (void *__ptr) __THROW;
| ~~~~~~^~~~~
main.sh: line 2: 16 Segmentation fault (core dumped) ./a.out
Testing if the previous output contains the string All tests passed
: False
Rewrite this function in C. You can assume that the input is a 2d matrix correctly formatted. Call it rref(int** matrix, int rows, int cols, int graphlen) where the size is matrix[rows][cols]. Return an int** of used_for_row. 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 in C. You can assume that the input is a 2d matrix correctly formatted. Call it rref(int** matrix, int rows, int cols, int graphlen) where the size is matrix[rows][cols]. Return an int** of used_for_row. 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]
Here's a possible C implementation of the `rref` function:
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 | #include <stdbool.h> #include <stdint.h> #include <stdlib.h> #define PH 16 int** rref(int** matrix, int rows, int cols, int graphlen) { int** used_for_row = calloc(rows, sizeof(int*)); for (int i = 0; i < rows; i++) { used_for_row[i] = calloc(rows, sizeof(int)); used_for_row[i][i] = 1; } int extra = 0; int col = 0; int* pivots = calloc(cols, sizeof(int)); while (col + extra < cols - 1 && col < rows) { if (matrix[col][col + extra] == 0) { if (matrix[col][col + extra + 1] == 0 && matrix[col + 1][col + extra] == 0) { extra++; continue; } int other = -1; for (int i = 0; i < rows; i++) { if (matrix[i][col + extra] != 0 && (other == -1 || i < other)) { other = i; } } if (other < col) { extra++; continue; } int tmp = matrix[col][col + extra]; matrix[col][col + extra] = matrix[other][col + extra]; matrix[other][col + extra] = tmp; for (int j = 0; j < cols; j++) { tmp = matrix[col][j]; matrix[col][j] = matrix[other][j]; matrix[other][j] = tmp; } for (int j = 0; j < rows; j++) { tmp = used_for_row[j][col]; used_for_row[j][col] = used_for_row[j][other]; used_for_row[j][other] = tmp; } } pivots[col] = col + extra; int pivot = matrix[col][col + extra]; if (col + extra < graphlen) { if (abs(pivot) != 1 && abs(pivot) != PH - 1) { // Error: pivot is not valid free(used_for_row); free(pivots); return NULL; } } else { if (abs(pivot) != 2 && abs(pivot) != PH - 2) { // Error: pivot is not valid free(used_for_row); free(pivots); return NULL; } pivot /= 2; } matrix[col][col + extra] = pivot; for (int j = 0; j < cols; j++) { matrix[col][j] = matrix[col][j] * pivot % PH; } for (int i = 0; i < rows; i++) { if (i == col) { continue; } int factor = matrix[i][col + extra]; if (col + extra < graphlen) { factor = matrix[col][col + extra] * factor % PH; } else { while (factor != 0) { factor = (factor - matrix[col][col + extra]) % PH; } } for (int j = 0; j < cols; j++) { matrix[i][j] = (matrix[i][j] - matrix[col][j] * factor + PH) % PH; } used_for_row[i][col] = 1; } col++; } free(pivots); return used_for_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 | #include <stdbool.h> #include <stdint.h> #include <stdlib.h> #define PH 16 int** rref(int** matrix, int rows, int cols, int graphlen) { int** used_for_row = calloc(rows, sizeof(int*)); for (int i = 0; i < rows; i++) { used_for_row[i] = calloc(rows, sizeof(int)); used_for_row[i][i] = 1; } int extra = 0; int col = 0; int* pivots = calloc(cols, sizeof(int)); while (col + extra < cols - 1 && col < rows) { if (matrix[col][col + extra] == 0) { if (matrix[col][col + extra + 1] == 0 && matrix[col + 1][col + extra] == 0) { extra++; continue; } int other = -1; for (int i = 0; i < rows; i++) { if (matrix[i][col + extra] != 0 && (other == -1 || i < other)) { other = i; } } if (other < col) { extra++; continue; } int tmp = matrix[col][col + extra]; matrix[col][col + extra] = matrix[other][col + extra]; matrix[other][col + extra] = tmp; for (int j = 0; j < cols; j++) { tmp = matrix[col][j]; matrix[col][j] = matrix[other][j]; matrix[other][j] = tmp; } for (int j = 0; j < rows; j++) { tmp = used_for_row[j][col]; used_for_row[j][col] = used_for_row[j][other]; used_for_row[j][other] = tmp; } } pivots[col] = col + extra; int pivot = matrix[col][col + extra]; if (col + extra < graphlen) { if (abs(pivot) != 1 && abs(pivot) != PH - 1) { // Error: pivot is not valid free(used_for_row); free(pivots); return NULL; } } else { if (abs(pivot) != 2 && abs(pivot) != PH - 2) { // Error: pivot is not valid free(used_for_row); free(pivots); return NULL; } pivot /= 2; } matrix[col][col + extra] = pivot; for (int j = 0; j < cols; j++) { matrix[col][j] = matrix[col][j] * pivot % PH; } for (int i = 0; i < rows; i++) { if (i == col) { continue; } int factor = matrix[i][col + extra]; if (col + extra < graphlen) { factor = matrix[col][col + extra] * factor % PH; } else { while (factor != 0) { factor = (factor - matrix[col][col + extra]) % PH; } } for (int j = 0; j < cols; j++) { matrix[i][j] = (matrix[i][j] - matrix[col][j] * factor + PH) % PH; } used_for_row[i][col] = 1; } col++; } free(pivots); 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 | #include <stdbool.h> #include <stdint.h> #include <stdlib.h> #define PH 16 int** rref(int** matrix, int rows, int cols, int graphlen) { int** used_for_row = calloc(rows, sizeof(int*)); for (int i = 0; i < rows; i++) { used_for_row[i] = calloc(rows, sizeof(int)); used_for_row[i][i] = 1; } int extra = 0; int col = 0; int* pivots = calloc(cols, sizeof(int)); while (col + extra < cols - 1 && col < rows) { if (matrix[col][col + extra] == 0) { if (matrix[col][col + extra + 1] == 0 && matrix[col + 1][col + extra] == 0) { extra++; continue; } int other = -1; for (int i = 0; i < rows; i++) { if (matrix[i][col + extra] != 0 && (other == -1 || i < other)) { other = i; } } if (other < col) { extra++; continue; } int tmp = matrix[col][col + extra]; matrix[col][col + extra] = matrix[other][col + extra]; matrix[other][col + extra] = tmp; for (int j = 0; j < cols; j++) { tmp = matrix[col][j]; matrix[col][j] = matrix[other][j]; matrix[other][j] = tmp; } for (int j = 0; j < rows; j++) { tmp = used_for_row[j][col]; used_for_row[j][col] = used_for_row[j][other]; used_for_row[j][other] = tmp; } } pivots[col] = col + extra; int pivot = matrix[col][col + extra]; if (col + extra < graphlen) { if (abs(pivot) != 1 && abs(pivot) != PH - 1) { // Error: pivot is not valid free(used_for_row); free(pivots); return NULL; } } else { if (abs(pivot) != 2 && abs(pivot) != PH - 2) { // Error: pivot is not valid free(used_for_row); free(pivots); return NULL; } pivot /= 2; } matrix[col][col + extra] = pivot; for (int j = 0; j < cols; j++) { matrix[col][j] = matrix[col][j] * pivot % PH; } for (int i = 0; i < rows; i++) { if (i == col) { continue; } int factor = matrix[i][col + extra]; if (col + extra < graphlen) { factor = matrix[col][col + extra] * factor % PH; } else { while (factor != 0) { factor = (factor - matrix[col][col + extra]) % PH; } } for (int j = 0; j < cols; j++) { matrix[i][j] = (matrix[i][j] - matrix[col][j] * factor + PH) % PH; } used_for_row[i][col] = 1; } col++; } free(pivots); return used_for_row; } #include<stdio.h> #include<stdlib.h> int main() { int arr0[] = {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}; int arr1[] = {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}; int arr2[] = {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}; int arr3[] = {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}; int arr4[] = {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}; int arr5[] = {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}; int arr6[] = {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}; int arr7[] = {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}; int arr8[] = {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}; int arr9[] = {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}; int arr10[] = {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}; int arr11[] = {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}; int arr12[] = {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}; int arr13[] = {0, 0, 0, 0, 0, 0, 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}; int arr14[] = {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}; int arr15[] = {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}; int arr16[] = {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}; int arr17[] = {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}; int arr18[] = {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}; int arr19[] = {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}; int arr20[] = {0, 0, 0, 0, 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}; int arr21[] = {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}; int arr22[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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}; int arr23[] = {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}; int arr24[] = {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}; int arr25[] = {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}; int arr26[] = {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}; int arr27[] = {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}; int arr28[] = {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}; int arr29[] = {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}; int arr30[] = {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}; int arr31[] = {0, 0, 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}; int arr32[] = {0, 0, 0, 0, 0, 0, 0, 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}; int arr33[] = {0, 0, 0, 0, 0, 0, 0, 0, 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}; int arr34[] = {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}; int arr35[] = {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}; int arr36[] = {0, 0, 0, 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}; int arr37[] = {0, 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}; int arr38[] = {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}; int* arr[] = {arr0, arr1, arr2, arr3, arr4, arr5, arr6, arr7, arr8, arr9, arr10, arr11, arr12, arr13, arr14, arr15, arr16, arr17, arr18, arr19, arr20, arr21, arr22, arr23, arr24, arr25, arr26, arr27, arr28, arr29, arr30, arr31, arr32, arr33, arr34, arr35, arr36, arr37, arr38}; int** got = rref(arr, 39, 49, 37); int answer = got[3][0]+got[3][1]+got[3][2]+got[3][3]+got[3][4]+got[3][5]+got[3][6]; int expected = 146; if (answer != expected) { printf("Wrong answer; got %d instead of %d.\n", answer, expected); exit(1); } printf("All tests passed\n"); } |
main.sh: line 2: 16 Segmentation fault (core dumped) ./a.out
Testing if the previous output contains the string All tests passed
: False
Rewrite this function in C. You can assume that the input is a 2d matrix correctly formatted. Call it rref(int** matrix, int rows, int cols, int graphlen) where the size is matrix[rows][cols]. Return an int** of used_for_row. 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 in C. You can assume that the input is a 2d matrix correctly formatted. Call it rref(int** matrix, int rows, int cols, int graphlen) where the size is matrix[rows][cols]. Return an int** of used_for_row. 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]
Here's a possible implementation of the function `rref` in C:
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 155 156 157 158 159 160 161 162 163 164 | #include <stdio.h> #include <stdlib.h> #include <stdbool.h> #include <stdint.h> // Define the constant PH #define PH 16 // Define a struct to represent a set of integers typedef struct { int *elements; int size; int capacity; } Set; // Function to initialize a set Set *create_set() { Set *set = (Set *) malloc(sizeof(Set)); set->elements = (int *) malloc(10 * sizeof(int)); set->size = 0; set->capacity = 10; return set; } // Function to add an element to a set void add_to_set(Set *set, int element) { if (set->size == set->capacity) { set->capacity *= 2; set->elements = (int *) realloc(set->elements, set->capacity * sizeof(int)); } set->elements[set->size++] = element; } // Function to find the union of two sets Set *union_sets(Set *set1, Set *set2) { Set *result = create_set(); for (int i = 0; i < set1->size; i++) { add_to_set(result, set1->elements[i]); } for (int i = 0; i < set2->size; i++) { bool found = false; for (int j = 0; j < result->size; j++) { if (result->elements[j] == set2->elements[i]) { found = true; break; } } if (!found) { add_to_set(result, set2->elements[i]); } } return result; } // Function to free the memory used by a set void free_set(Set *set) { free(set->elements); free(set); } // Function to perform reduced row echelon form on a matrix int **rref(int **matrix, int rows, int cols, int graphlen) { // Create an array of sets to represent used_for_row Set **used_for_row = (Set **) malloc(rows * sizeof(Set *)); for (int i = 0; i < rows; i++) { used_for_row[i] = create_set(); add_to_set(used_for_row[i], i); } int extra = 0; int col = 0; int *pivots = (int *) malloc((cols - graphlen) * sizeof(int)); // Loop through the columns of the matrix while (col + extra < cols - 1 && col < rows) { int pivot_row = -1; int max_abs = -1; // Find the pivot element for (int i = col; i < rows; i++) { int val = abs(matrix[i][col + extra] % PH); if (val > max_abs) { max_abs = val; pivot_row = i; } } if (pivot_row == -1) { extra++; continue; } if (matrix[col][col + extra] == 0) { int tmp = matrix[col][col + extra]; for (int k = col + extra; k < cols; k++) { int t = matrix[col][k]; matrix[col][k] = matrix[pivot_row][k]; matrix[pivot_row][k] = t; } tmp = matrix[col][col + extra]; for (int k = col + extra; k < cols; k++) { int t = matrix[col][k]; matrix[col][k] = matrix[pivot_row][k]; matrix[pivot_row][k] = t; } Set *tmp_set = used_for_row[col]; used_for_row[col] = used_for_row[pivot_row]; used_for_row[pivot_row] = tmp_set; } pivots[col] = col + extra; int pivot = matrix[col][col + extra]; if (col < graphlen) { if (pivot != 1 && pivot != PH - 1) { printf("Error: invalid pivot value\n"); exit(1); } } else { if (pivot != 2 && pivot != PH - 2) { printf("Error: invalid pivot value\n"); exit(1); } pivot /= 2; } matrix[col][col + extra] = pivot; for (int i = 0; i < rows; i++) { if (i == col) { continue; } int factor = matrix[i][col + extra]; if (col < graphlen) { matrix[i][col + extra] = 0; for (int k = col + extra + 1; k < cols; k++) { matrix[i][k] -= matrix[col][k] * factor; } } else { while (matrix[i][col + extra] != 0) { matrix[i][col + extra] -= pivot; if (matrix[i][col + extra] < 0) { matrix[i][col + extra] += PH; } for (int k = col + extra + 1; k < cols; k++) { matrix[i][k] -= matrix[col][k]; if (matrix[i][k] < 0) { matrix[i][k] += PH; } } } } } col++; } // Create an array of arrays to represent the final result int **result = (int **) malloc(rows * sizeof(int *)); for (int i = 0; i < rows; i++) { result[i] = (int *) malloc(used_for_row[i]->size * sizeof(int)); for (int j = 0; j < used_for_row[i]->size; j++) { result[i][j] = used_for_row[i]->elements[j]; } free_set(used_for_row[i]); } free(used_for_row); free(pivots); // Return the result return 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 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 155 156 157 158 159 160 161 162 163 164 | #include <stdio.h> #include <stdlib.h> #include <stdbool.h> #include <stdint.h> // Define the constant PH #define PH 16 // Define a struct to represent a set of integers typedef struct { int *elements; int size; int capacity; } Set; // Function to initialize a set Set *create_set() { Set *set = (Set *) malloc(sizeof(Set)); set->elements = (int *) malloc(10 * sizeof(int)); set->size = 0; set->capacity = 10; return set; } // Function to add an element to a set void add_to_set(Set *set, int element) { if (set->size == set->capacity) { set->capacity *= 2; set->elements = (int *) realloc(set->elements, set->capacity * sizeof(int)); } set->elements[set->size++] = element; } // Function to find the union of two sets Set *union_sets(Set *set1, Set *set2) { Set *result = create_set(); for (int i = 0; i < set1->size; i++) { add_to_set(result, set1->elements[i]); } for (int i = 0; i < set2->size; i++) { bool found = false; for (int j = 0; j < result->size; j++) { if (result->elements[j] == set2->elements[i]) { found = true; break; } } if (!found) { add_to_set(result, set2->elements[i]); } } return result; } // Function to free the memory used by a set void free_set(Set *set) { free(set->elements); free(set); } // Function to perform reduced row echelon form on a matrix int **rref(int **matrix, int rows, int cols, int graphlen) { // Create an array of sets to represent used_for_row Set **used_for_row = (Set **) malloc(rows * sizeof(Set *)); for (int i = 0; i < rows; i++) { used_for_row[i] = create_set(); add_to_set(used_for_row[i], i); } int extra = 0; int col = 0; int *pivots = (int *) malloc((cols - graphlen) * sizeof(int)); // Loop through the columns of the matrix while (col + extra < cols - 1 && col < rows) { int pivot_row = -1; int max_abs = -1; // Find the pivot element for (int i = col; i < rows; i++) { int val = abs(matrix[i][col + extra] % PH); if (val > max_abs) { max_abs = val; pivot_row = i; } } if (pivot_row == -1) { extra++; continue; } if (matrix[col][col + extra] == 0) { int tmp = matrix[col][col + extra]; for (int k = col + extra; k < cols; k++) { int t = matrix[col][k]; matrix[col][k] = matrix[pivot_row][k]; matrix[pivot_row][k] = t; } tmp = matrix[col][col + extra]; for (int k = col + extra; k < cols; k++) { int t = matrix[col][k]; matrix[col][k] = matrix[pivot_row][k]; matrix[pivot_row][k] = t; } Set *tmp_set = used_for_row[col]; used_for_row[col] = used_for_row[pivot_row]; used_for_row[pivot_row] = tmp_set; } pivots[col] = col + extra; int pivot = matrix[col][col + extra]; if (col < graphlen) { if (pivot != 1 && pivot != PH - 1) { printf("Error: invalid pivot value\n"); exit(1); } } else { if (pivot != 2 && pivot != PH - 2) { printf("Error: invalid pivot value\n"); exit(1); } pivot /= 2; } matrix[col][col + extra] = pivot; for (int i = 0; i < rows; i++) { if (i == col) { continue; } int factor = matrix[i][col + extra]; if (col < graphlen) { matrix[i][col + extra] = 0; for (int k = col + extra + 1; k < cols; k++) { matrix[i][k] -= matrix[col][k] * factor; } } else { while (matrix[i][col + extra] != 0) { matrix[i][col + extra] -= pivot; if (matrix[i][col + extra] < 0) { matrix[i][col + extra] += PH; } for (int k = col + extra + 1; k < cols; k++) { matrix[i][k] -= matrix[col][k]; if (matrix[i][k] < 0) { matrix[i][k] += PH; } } } } } col++; } // Create an array of arrays to represent the final result int **result = (int **) malloc(rows * sizeof(int *)); for (int i = 0; i < rows; i++) { result[i] = (int *) malloc(used_for_row[i]->size * sizeof(int)); for (int j = 0; j < used_for_row[i]->size; j++) { result[i][j] = used_for_row[i]->elements[j]; } free_set(used_for_row[i]); } free(used_for_row); free(pivots); // Return the result 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 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 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 | #include <stdio.h> #include <stdlib.h> #include <stdbool.h> #include <stdint.h> // Define the constant PH #define PH 16 // Define a struct to represent a set of integers typedef struct { int *elements; int size; int capacity; } Set; // Function to initialize a set Set *create_set() { Set *set = (Set *) malloc(sizeof(Set)); set->elements = (int *) malloc(10 * sizeof(int)); set->size = 0; set->capacity = 10; return set; } // Function to add an element to a set void add_to_set(Set *set, int element) { if (set->size == set->capacity) { set->capacity *= 2; set->elements = (int *) realloc(set->elements, set->capacity * sizeof(int)); } set->elements[set->size++] = element; } // Function to find the union of two sets Set *union_sets(Set *set1, Set *set2) { Set *result = create_set(); for (int i = 0; i < set1->size; i++) { add_to_set(result, set1->elements[i]); } for (int i = 0; i < set2->size; i++) { bool found = false; for (int j = 0; j < result->size; j++) { if (result->elements[j] == set2->elements[i]) { found = true; break; } } if (!found) { add_to_set(result, set2->elements[i]); } } return result; } // Function to free the memory used by a set void free_set(Set *set) { free(set->elements); free(set); } // Function to perform reduced row echelon form on a matrix int **rref(int **matrix, int rows, int cols, int graphlen) { // Create an array of sets to represent used_for_row Set **used_for_row = (Set **) malloc(rows * sizeof(Set *)); for (int i = 0; i < rows; i++) { used_for_row[i] = create_set(); add_to_set(used_for_row[i], i); } int extra = 0; int col = 0; int *pivots = (int *) malloc((cols - graphlen) * sizeof(int)); // Loop through the columns of the matrix while (col + extra < cols - 1 && col < rows) { int pivot_row = -1; int max_abs = -1; // Find the pivot element for (int i = col; i < rows; i++) { int val = abs(matrix[i][col + extra] % PH); if (val > max_abs) { max_abs = val; pivot_row = i; } } if (pivot_row == -1) { extra++; continue; } if (matrix[col][col + extra] == 0) { int tmp = matrix[col][col + extra]; for (int k = col + extra; k < cols; k++) { int t = matrix[col][k]; matrix[col][k] = matrix[pivot_row][k]; matrix[pivot_row][k] = t; } tmp = matrix[col][col + extra]; for (int k = col + extra; k < cols; k++) { int t = matrix[col][k]; matrix[col][k] = matrix[pivot_row][k]; matrix[pivot_row][k] = t; } Set *tmp_set = used_for_row[col]; used_for_row[col] = used_for_row[pivot_row]; used_for_row[pivot_row] = tmp_set; } pivots[col] = col + extra; int pivot = matrix[col][col + extra]; if (col < graphlen) { if (pivot != 1 && pivot != PH - 1) { printf("Error: invalid pivot value\n"); exit(1); } } else { if (pivot != 2 && pivot != PH - 2) { printf("Error: invalid pivot value\n"); exit(1); } pivot /= 2; } matrix[col][col + extra] = pivot; for (int i = 0; i < rows; i++) { if (i == col) { continue; } int factor = matrix[i][col + extra]; if (col < graphlen) { matrix[i][col + extra] = 0; for (int k = col + extra + 1; k < cols; k++) { matrix[i][k] -= matrix[col][k] * factor; } } else { while (matrix[i][col + extra] != 0) { matrix[i][col + extra] -= pivot; if (matrix[i][col + extra] < 0) { matrix[i][col + extra] += PH; } for (int k = col + extra + 1; k < cols; k++) { matrix[i][k] -= matrix[col][k]; if (matrix[i][k] < 0) { matrix[i][k] += PH; } } } } } col++; } // Create an array of arrays to represent the final result int **result = (int **) malloc(rows * sizeof(int *)); for (int i = 0; i < rows; i++) { result[i] = (int *) malloc(used_for_row[i]->size * sizeof(int)); for (int j = 0; j < used_for_row[i]->size; j++) { result[i][j] = used_for_row[i]->elements[j]; } free_set(used_for_row[i]); } free(used_for_row); free(pivots); // Return the result return result; } #include<stdio.h> #include<stdlib.h> int main() { int arr0[] = {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}; int arr1[] = {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}; int arr2[] = {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}; int arr3[] = {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}; int arr4[] = {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}; int arr5[] = {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}; int arr6[] = {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}; int arr7[] = {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}; int arr8[] = {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}; int arr9[] = {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}; int arr10[] = {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}; int arr11[] = {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}; int arr12[] = {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}; int arr13[] = {0, 0, 0, 0, 0, 0, 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}; int arr14[] = {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}; int arr15[] = {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}; int arr16[] = {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}; int arr17[] = {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}; int arr18[] = {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}; int arr19[] = {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}; int arr20[] = {0, 0, 0, 0, 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}; int arr21[] = {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}; int arr22[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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}; int arr23[] = {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}; int arr24[] = {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}; int arr25[] = {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}; int arr26[] = {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}; int arr27[] = {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}; int arr28[] = {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}; int arr29[] = {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}; int arr30[] = {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}; int arr31[] = {0, 0, 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}; int arr32[] = {0, 0, 0, 0, 0, 0, 0, 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}; int arr33[] = {0, 0, 0, 0, 0, 0, 0, 0, 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}; int arr34[] = {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}; int arr35[] = {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}; int arr36[] = {0, 0, 0, 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}; int arr37[] = {0, 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}; int arr38[] = {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}; int* arr[] = {arr0, arr1, arr2, arr3, arr4, arr5, arr6, arr7, arr8, arr9, arr10, arr11, arr12, arr13, arr14, arr15, arr16, arr17, arr18, arr19, arr20, arr21, arr22, arr23, arr24, arr25, arr26, arr27, arr28, arr29, arr30, arr31, arr32, arr33, arr34, arr35, arr36, arr37, arr38}; int** got = rref(arr, 39, 49, 37); int answer = got[3][0]+got[3][1]+got[3][2]+got[3][3]+got[3][4]+got[3][5]+got[3][6]; int expected = 146; if (answer != expected) { printf("Wrong answer; got %d instead of %d.\n", answer, expected); exit(1); } printf("All tests passed\n"); } |
Error: invalid pivot value
Testing if the previous output contains the string All tests passed
: False
Rewrite this function in C. You can assume that the input is a 2d matrix correctly formatted. Call it rref(int** matrix, int rows, int cols, int graphlen) where the size is matrix[rows][cols]. Return an int** of used_for_row. 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 in C. You can assume that the input is a 2d matrix correctly formatted. Call it rref(int** matrix, int rows, int cols, int graphlen) where the size is matrix[rows][cols]. Return an int** of used_for_row. 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]
Here's a possible C implementation of the function, based on the provided Python code:
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 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 | #include <stdbool.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> #define PH 16 int** rref(int** matrix, int rows, int cols, int graphlen) { int* used_for_row = calloc(rows, sizeof(int)); for (int i = 0; i < rows; i++) { used_for_row[i] = i; } int extra = 0; int col = 0; int pivots[rows]; int num_pivots = 0; bool swap_needed = false; while (col + extra < cols - 1 && col < rows) { if (matrix[col][col + extra] == 0) { if (all_zeroes(matrix[col], cols)) { extra++; continue; } int other = find_first_nonzero(matrix, col + extra, cols); if (other < col) { extra++; continue; } swap_rows(matrix, col, other, cols); swap_ints(&used_for_row[col], &used_for_row[other]); swap_needed = true; } pivots[num_pivots] = col + extra; int pivot = matrix[col][col + extra]; if (col + extra < graphlen) { assert(abs(pivot) == 1 || abs(pivot) == PH - 1); } else { assert(abs(pivot) == 2 || abs(pivot) == PH - 2); pivot /= 2; } matrix[col][col + extra] = pivot; matrix[col] %= PH; int* others = find_nonzeroes(matrix, col + extra, rows, cols); for (int i = 0; others[i] != -1; i++) { int row = others[i]; if (row == col) continue; used_for_row[row] = add_if_not_present(used_for_row[row], used_for_row[col]); if (col < graphlen) { matrix[row] = subtract_rows_mod_PH(matrix[row], matrix[col], matrix[row][col + extra]); } else { while (matrix[row][col + extra] != 0) { matrix[row] = subtract_rows_mod_PH(matrix[row], matrix[col], 1); } } matrix[row] %= PH; } free(others); col++; } if (swap_needed) { for (int i = 0; i < rows; i++) { int tmp = used_for_row[i]; used_for_row[i] = used_for_row[matrix[i][0]]; used_for_row[matrix[i][0]] = tmp; } } int** result = malloc(rows * sizeof(int*)); for (int i = 0; i < rows; i++) { int len = count_set_bits(used_for_row[i]) + 1; result[i] = malloc(len * sizeof(int)); int j = 0; for (int k = 0; k < rows; k++) { if (used_for_row[i] & (1 << k)) { result[i][j++] = k; } } qsort(result[i], len, sizeof(int), compare_ints); } free(used_for_row); return result; } bool all_zeroes(int* row, int cols) { for (int i = 0; i < cols; i++) { if (row[i] != 0) { return false; } } return true; } int find_first_nonzero(int** matrix, int col, int cols) { for (int i = 0; i < cols; i++) { for (int j = col; j < cols; j++) { if (matrix[i][j] != 0) { return i; } } } return -1; } void swap_rows(int** matrix, int i, int j, int cols) { int tmp[cols]; memcpy(tmp, matrix[i], cols * sizeof(int)); memcpy(matrix[i], matrix[j], cols * sizeof(int)); memcpy(matrix[j], tmp, cols * sizeof(int)); } void swap_ints(int* a, int* b) { int tmp = *a; *a = *b; *b = tmp; } int* find_nonzeroes(int** matrix, int col, int rows, int cols) { int count = 0; for (int i = 0; i < rows; i++) { if (matrix[i][col] != 0) { count++; } } int* result = malloc(count * sizeof(int)); int idx = 0; for (int i = 0; i < rows; i++) { if (matrix[i][col] != 0) { result[idx++] = i; } } result[idx] = -1; return result; } int add_if_not_present(int a, int b) { int result = a; if ((result & b) == 0) { result |= b; } return result; } int count_set_bits(int n) { int count = 0; while (n) { n &= (n - 1); count++; } return count; } int compare_ints(const void* a, const void* b) { return (*(int*)a - *(int*)b); } int subtract_rows_mod_PH(int* row1, int* row2, int scalar) { for (int i = 0; i < cols; i++) { row1[i] = ((row1[i] - scalar * row2[i]) % PH + PH) % PH; } return 0; } |
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 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 | #include <stdbool.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> #define PH 16 int** rref(int** matrix, int rows, int cols, int graphlen) { int* used_for_row = calloc(rows, sizeof(int)); for (int i = 0; i < rows; i++) { used_for_row[i] = i; } int extra = 0; int col = 0; int pivots[rows]; int num_pivots = 0; bool swap_needed = false; while (col + extra < cols - 1 && col < rows) { if (matrix[col][col + extra] == 0) { if (all_zeroes(matrix[col], cols)) { extra++; continue; } int other = find_first_nonzero(matrix, col + extra, cols); if (other < col) { extra++; continue; } swap_rows(matrix, col, other, cols); swap_ints(&used_for_row[col], &used_for_row[other]); swap_needed = true; } pivots[num_pivots] = col + extra; int pivot = matrix[col][col + extra]; if (col + extra < graphlen) { assert(abs(pivot) == 1 || abs(pivot) == PH - 1); } else { assert(abs(pivot) == 2 || abs(pivot) == PH - 2); pivot /= 2; } matrix[col][col + extra] = pivot; matrix[col] %= PH; int* others = find_nonzeroes(matrix, col + extra, rows, cols); for (int i = 0; others[i] != -1; i++) { int row = others[i]; if (row == col) continue; used_for_row[row] = add_if_not_present(used_for_row[row], used_for_row[col]); if (col < graphlen) { matrix[row] = subtract_rows_mod_PH(matrix[row], matrix[col], matrix[row][col + extra]); } else { while (matrix[row][col + extra] != 0) { matrix[row] = subtract_rows_mod_PH(matrix[row], matrix[col], 1); } } matrix[row] %= PH; } free(others); col++; } if (swap_needed) { for (int i = 0; i < rows; i++) { int tmp = used_for_row[i]; used_for_row[i] = used_for_row[matrix[i][0]]; used_for_row[matrix[i][0]] = tmp; } } int** result = malloc(rows * sizeof(int*)); for (int i = 0; i < rows; i++) { int len = count_set_bits(used_for_row[i]) + 1; result[i] = malloc(len * sizeof(int)); int j = 0; for (int k = 0; k < rows; k++) { if (used_for_row[i] & (1 << k)) { result[i][j++] = k; } } qsort(result[i], len, sizeof(int), compare_ints); } free(used_for_row); return result; } bool all_zeroes(int* row, int cols) { for (int i = 0; i < cols; i++) { if (row[i] != 0) { return false; } } return true; } int find_first_nonzero(int** matrix, int col, int cols) { for (int i = 0; i < cols; i++) { for (int j = col; j < cols; j++) { if (matrix[i][j] != 0) { return i; } } } return -1; } void swap_rows(int** matrix, int i, int j, int cols) { int tmp[cols]; memcpy(tmp, matrix[i], cols * sizeof(int)); memcpy(matrix[i], matrix[j], cols * sizeof(int)); memcpy(matrix[j], tmp, cols * sizeof(int)); } void swap_ints(int* a, int* b) { int tmp = *a; *a = *b; *b = tmp; } int* find_nonzeroes(int** matrix, int col, int rows, int cols) { int count = 0; for (int i = 0; i < rows; i++) { if (matrix[i][col] != 0) { count++; } } int* result = malloc(count * sizeof(int)); int idx = 0; for (int i = 0; i < rows; i++) { if (matrix[i][col] != 0) { result[idx++] = i; } } result[idx] = -1; return result; } int add_if_not_present(int a, int b) { int result = a; if ((result & b) == 0) { result |= b; } return result; } int count_set_bits(int n) { int count = 0; while (n) { n &= (n - 1); count++; } return count; } int compare_ints(const void* a, const void* b) { return (*(int*)a - *(int*)b); } int subtract_rows_mod_PH(int* row1, int* row2, int scalar) { for (int i = 0; i < cols; i++) { row1[i] = ((row1[i] - scalar * row2[i]) % PH + PH) % PH; } return 0; } |
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 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 | #include <stdbool.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> #define PH 16 int** rref(int** matrix, int rows, int cols, int graphlen) { int* used_for_row = calloc(rows, sizeof(int)); for (int i = 0; i < rows; i++) { used_for_row[i] = i; } int extra = 0; int col = 0; int pivots[rows]; int num_pivots = 0; bool swap_needed = false; while (col + extra < cols - 1 && col < rows) { if (matrix[col][col + extra] == 0) { if (all_zeroes(matrix[col], cols)) { extra++; continue; } int other = find_first_nonzero(matrix, col + extra, cols); if (other < col) { extra++; continue; } swap_rows(matrix, col, other, cols); swap_ints(&used_for_row[col], &used_for_row[other]); swap_needed = true; } pivots[num_pivots] = col + extra; int pivot = matrix[col][col + extra]; if (col + extra < graphlen) { assert(abs(pivot) == 1 || abs(pivot) == PH - 1); } else { assert(abs(pivot) == 2 || abs(pivot) == PH - 2); pivot /= 2; } matrix[col][col + extra] = pivot; matrix[col] %= PH; int* others = find_nonzeroes(matrix, col + extra, rows, cols); for (int i = 0; others[i] != -1; i++) { int row = others[i]; if (row == col) continue; used_for_row[row] = add_if_not_present(used_for_row[row], used_for_row[col]); if (col < graphlen) { matrix[row] = subtract_rows_mod_PH(matrix[row], matrix[col], matrix[row][col + extra]); } else { while (matrix[row][col + extra] != 0) { matrix[row] = subtract_rows_mod_PH(matrix[row], matrix[col], 1); } } matrix[row] %= PH; } free(others); col++; } if (swap_needed) { for (int i = 0; i < rows; i++) { int tmp = used_for_row[i]; used_for_row[i] = used_for_row[matrix[i][0]]; used_for_row[matrix[i][0]] = tmp; } } int** result = malloc(rows * sizeof(int*)); for (int i = 0; i < rows; i++) { int len = count_set_bits(used_for_row[i]) + 1; result[i] = malloc(len * sizeof(int)); int j = 0; for (int k = 0; k < rows; k++) { if (used_for_row[i] & (1 << k)) { result[i][j++] = k; } } qsort(result[i], len, sizeof(int), compare_ints); } free(used_for_row); return result; } bool all_zeroes(int* row, int cols) { for (int i = 0; i < cols; i++) { if (row[i] != 0) { return false; } } return true; } int find_first_nonzero(int** matrix, int col, int cols) { for (int i = 0; i < cols; i++) { for (int j = col; j < cols; j++) { if (matrix[i][j] != 0) { return i; } } } return -1; } void swap_rows(int** matrix, int i, int j, int cols) { int tmp[cols]; memcpy(tmp, matrix[i], cols * sizeof(int)); memcpy(matrix[i], matrix[j], cols * sizeof(int)); memcpy(matrix[j], tmp, cols * sizeof(int)); } void swap_ints(int* a, int* b) { int tmp = *a; *a = *b; *b = tmp; } int* find_nonzeroes(int** matrix, int col, int rows, int cols) { int count = 0; for (int i = 0; i < rows; i++) { if (matrix[i][col] != 0) { count++; } } int* result = malloc(count * sizeof(int)); int idx = 0; for (int i = 0; i < rows; i++) { if (matrix[i][col] != 0) { result[idx++] = i; } } result[idx] = -1; return result; } int add_if_not_present(int a, int b) { int result = a; if ((result & b) == 0) { result |= b; } return result; } int count_set_bits(int n) { int count = 0; while (n) { n &= (n - 1); count++; } return count; } int compare_ints(const void* a, const void* b) { return (*(int*)a - *(int*)b); } int subtract_rows_mod_PH(int* row1, int* row2, int scalar) { for (int i = 0; i < cols; i++) { row1[i] = ((row1[i] - scalar * row2[i]) % PH + PH) % PH; } return 0; } #include<stdio.h> #include<stdlib.h> int main() { int arr0[] = {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}; int arr1[] = {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}; int arr2[] = {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}; int arr3[] = {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}; int arr4[] = {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}; int arr5[] = {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}; int arr6[] = {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}; int arr7[] = {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}; int arr8[] = {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}; int arr9[] = {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}; int arr10[] = {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}; int arr11[] = {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}; int arr12[] = {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}; int arr13[] = {0, 0, 0, 0, 0, 0, 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}; int arr14[] = {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}; int arr15[] = {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}; int arr16[] = {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}; int arr17[] = {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}; int arr18[] = {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}; int arr19[] = {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}; int arr20[] = {0, 0, 0, 0, 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}; int arr21[] = {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}; int arr22[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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}; int arr23[] = {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}; int arr24[] = {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}; int arr25[] = {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}; int arr26[] = {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}; int arr27[] = {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}; int arr28[] = {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}; int arr29[] = {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}; int arr30[] = {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}; int arr31[] = {0, 0, 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}; int arr32[] = {0, 0, 0, 0, 0, 0, 0, 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}; int arr33[] = {0, 0, 0, 0, 0, 0, 0, 0, 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}; int arr34[] = {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}; int arr35[] = {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}; int arr36[] = {0, 0, 0, 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}; int arr37[] = {0, 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}; int arr38[] = {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}; int* arr[] = {arr0, arr1, arr2, arr3, arr4, arr5, arr6, arr7, arr8, arr9, arr10, arr11, arr12, arr13, arr14, arr15, arr16, arr17, arr18, arr19, arr20, arr21, arr22, arr23, arr24, arr25, arr26, arr27, arr28, arr29, arr30, arr31, arr32, arr33, arr34, arr35, arr36, arr37, arr38}; int** got = rref(arr, 39, 49, 37); int answer = got[3][0]+got[3][1]+got[3][2]+got[3][3]+got[3][4]+got[3][5]+got[3][6]; int expected = 146; if (answer != expected) { printf("Wrong answer; got %d instead of %d.\n", answer, expected); exit(1); } printf("All tests passed\n"); } |
main.c: In function 'rref':
main.c:23:17: warning: implicit declaration of function 'all_zeroes' [-Wimplicit-function-declaration]
23 | if (all_zeroes(matrix[col], cols)) {
| ^~~~~~~~~~
main.c:27:25: warning: implicit declaration of function 'find_first_nonzero' [-Wimplicit-function-declaration]
27 | int other = find_first_nonzero(matrix, col + extra, cols);
| ^~~~~~~~~~~~~~~~~~
main.c:33:13: warning: implicit declaration of function 'swap_rows' [-Wimplicit-function-declaration]
33 | swap_rows(matrix, col, other, cols);
| ^~~~~~~~~
main.c:34:13: warning: implicit declaration of function 'swap_ints' [-Wimplicit-function-declaration]
34 | swap_ints(&used_for_row[col], &used_for_row[other]);
| ^~~~~~~~~
main.c:41:13: warning: implicit declaration of function 'assert' [-Wimplicit-function-declaration]
41 | assert(abs(pivot) == 1 || abs(pivot) == PH - 1);
| ^~~~~~
main.c:6:1: note: 'assert' is defined in header '<assert.h>'; did you forget to '#include <assert.h>'?
5 | #include <stdlib.h>
+++ |+#include <assert.h>
6 |
main.c:47:21: error: invalid operands to binary % (have 'int *' and 'int')
47 | matrix[col] %= PH;
| ^~
main.c:49:23: warning: implicit declaration of function 'find_nonzeroes' [-Wimplicit-function-declaration]
49 | int* others = find_nonzeroes(matrix, col + extra, rows, cols);
| ^~~~~~~~~~~~~~
main.c:49:23: warning: initialization of 'int *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
main.c:53:33: warning: implicit declaration of function 'add_if_not_present' [-Wimplicit-function-declaration]
53 | used_for_row[row] = add_if_not_present(used_for_row[row], used_for_row[col]);
| ^~~~~~~~~~~~~~~~~~
main.c:55:31: warning: implicit declaration of function 'subtract_rows_mod_PH' [-Wimplicit-function-declaration]
55 | matrix[row] = subtract_rows_mod_PH(matrix[row], matrix[col], matrix[row][col + extra]);
| ^~~~~~~~~~~~~~~~~~~~
main.c:55:29: warning: assignment to 'int *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
55 | matrix[row] = subtract_rows_mod_PH(matrix[row], matrix[col], matrix[row][col + extra]);
| ^
main.c:58:33: warning: assignment to 'int *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
58 | matrix[row] = subtract_rows_mod_PH(matrix[row], matrix[col], 1);
| ^
main.c:61:25: error: invalid operands to binary % (have 'int *' and 'int')
61 | matrix[row] %= PH;
| ^~
main.c:78:19: warning: implicit declaration of function 'count_set_bits' [-Wimplicit-function-declaration]
78 | int len = count_set_bits(used_for_row[i]) + 1;
| ^~~~~~~~~~~~~~
main.c:86:44: error: 'compare_ints' undeclared (first use in this function)
86 | qsort(result[i], len, sizeof(int), compare_ints);
| ^~~~~~~~~~~~
main.c:86:44: note: each undeclared identifier is reported only once for each function it appears in
main.c: At top level:
main.c:93:6: error: conflicting types for 'all_zeroes'; have '_Bool(int *, int)'
93 | bool all_zeroes(int* row, int cols) {
| ^~~~~~~~~~
main.c:23:17: note: previous implicit declaration of 'all_zeroes' with type 'int()'
23 | if (all_zeroes(matrix[col], cols)) {
| ^~~~~~~~~~
main.c:113:6: warning: conflicting types for 'swap_rows'; have 'void(int **, int, int, int)'
113 | void swap_rows(int** matrix, int i, int j, int cols) {
| ^~~~~~~~~
main.c:33:13: note: previous implicit declaration of 'swap_rows' with type 'void(int **, int, int, int)'
33 | swap_rows(matrix, col, other, cols);
| ^~~~~~~~~
main.c: In function 'swap_rows':
main.c:115:5: warning: implicit declaration of function 'memcpy' [-Wimplicit-function-declaration]
115 | memcpy(tmp, matrix[i], cols * sizeof(int));
| ^~~~~~
main.c:6:1: note: include '<string.h>' or provide a declaration of 'memcpy'
5 | #include <stdlib.h>
+++ |+#include <string.h>
6 |
main.c:115:5: warning: incompatible implicit declaration of built-in function 'memcpy' [-Wbuiltin-declaration-mismatch]
115 | memcpy(tmp, matrix[i], cols * sizeof(int));
| ^~~~~~
main.c:115:5: note: include '<string.h>' or provide a declaration of 'memcpy'
main.c: At top level:
main.c:120:6: warning: conflicting types for 'swap_ints'; have 'void(int *, int *)'
120 | void swap_ints(int* a, int* b) {
| ^~~~~~~~~
main.c:34:13: note: previous implicit declaration of 'swap_ints' with type 'void(int *, int *)'
34 | swap_ints(&used_for_row[col], &used_for_row[other]);
| ^~~~~~~~~
main.c:126:6: error: conflicting types for 'find_nonzeroes'; have 'int *(int **, int, int, int)'
126 | int* find_nonzeroes(int** matrix, int col, int rows, int cols) {
| ^~~~~~~~~~~~~~
main.c:49:23: note: previous implicit declaration of 'find_nonzeroes' with type 'int()'
49 | int* others = find_nonzeroes(matrix, col + extra, rows, cols);
| ^~~~~~~~~~~~~~
main.c: In function 'subtract_rows_mod_PH':
main.c:167:25: error: 'cols' undeclared (first use in this function)
167 | for (int i = 0; i < cols; i++) {
| ^~~~
main.sh: line 2: ./a.out: No such file or directory
Testing if the previous output contains the string All tests passed
: False