| [84d0c30] | 1 | #include <m4ri/config.h>
|
|---|
| 2 | #include <stdlib.h>
|
|---|
| 3 | #include <m4ri/m4ri.h>
|
|---|
| 4 |
|
|---|
| 5 | int check_pluq(mzd_t *A, rci_t *r) {
|
|---|
| 6 | mzd_t* Acopy = mzd_copy (NULL,A);
|
|---|
| 7 |
|
|---|
| 8 | const rci_t m = A->nrows;
|
|---|
| 9 | const rci_t n = A->ncols;
|
|---|
| 10 |
|
|---|
| 11 | mzd_t* L = mzd_init(m, m);
|
|---|
| 12 | mzd_t* U = mzd_init(m, n);
|
|---|
| 13 |
|
|---|
| 14 | mzp_t* P = mzp_init(m);
|
|---|
| 15 | mzp_t* Q = mzp_init(n);
|
|---|
| 16 | r[0] = mzd_pluq(A, P, Q, 0);
|
|---|
| 17 |
|
|---|
| 18 | for (rci_t i = 0; i < r[0]; ++i){
|
|---|
| 19 | for (rci_t j = 0; j < i; ++j)
|
|---|
| 20 | mzd_write_bit(L, i, j, mzd_read_bit(A,i,j));
|
|---|
| 21 | for (rci_t j = i + 1; j < n; ++j)
|
|---|
| 22 | mzd_write_bit(U, i, j, mzd_read_bit(A,i,j));
|
|---|
| 23 | }
|
|---|
| 24 | for (rci_t i = r[0]; i < m; ++i)
|
|---|
| 25 | for (rci_t j = 0; j < r[0]; ++j)
|
|---|
| 26 | mzd_write_bit(L, i, j, mzd_read_bit(A,i,j));
|
|---|
| 27 | for (rci_t i = 0; i < r[0]; ++i){
|
|---|
| 28 | mzd_write_bit(L,i,i, 1);
|
|---|
| 29 | mzd_write_bit(U,i,i, 1);
|
|---|
| 30 | }
|
|---|
| 31 |
|
|---|
| 32 | mzd_apply_p_left(Acopy, P);
|
|---|
| 33 | mzd_apply_p_right_trans(Acopy, Q);
|
|---|
| 34 |
|
|---|
| 35 | mzd_addmul(Acopy, L, U, 0);
|
|---|
| 36 |
|
|---|
| 37 | int status = 0;
|
|---|
| 38 | for (rci_t i = 0; i < m; ++i)
|
|---|
| 39 | for (rci_t j = 0; j < n; ++j){
|
|---|
| 40 | if (mzd_read_bit (Acopy,i,j)){
|
|---|
| 41 | status = 1;
|
|---|
| 42 | break;
|
|---|
| 43 | }
|
|---|
| 44 | }
|
|---|
| 45 | mzd_free(U);
|
|---|
| 46 | mzd_free(L);
|
|---|
| 47 | mzd_free(Acopy);
|
|---|
| 48 | mzp_free(P);
|
|---|
| 49 | mzp_free(Q);
|
|---|
| 50 |
|
|---|
| 51 | return status;
|
|---|
| 52 | }
|
|---|
| 53 |
|
|---|
| 54 | int test_pluq_full_rank (rci_t m, rci_t n){
|
|---|
| 55 | printf("pluq: testing full rank m: %5d, n: %5d", m, n);
|
|---|
| 56 |
|
|---|
| 57 | mzd_t* U = mzd_init(m,n);
|
|---|
| 58 | mzd_t* L = mzd_init(m,m);
|
|---|
| 59 | mzd_t* U2 = mzd_init(m,n);
|
|---|
| 60 | mzd_t* L2 = mzd_init(m,m);
|
|---|
| 61 | mzd_t* A = mzd_init(m,n);
|
|---|
| 62 | mzd_randomize (U);
|
|---|
| 63 | mzd_randomize (L);
|
|---|
| 64 |
|
|---|
| 65 | for (rci_t i = 0; i < m; ++i){
|
|---|
| 66 | for (rci_t j = 0; j < i && j < n;++j)
|
|---|
| 67 | mzd_write_bit(U,i,j, 0);
|
|---|
| 68 | for (rci_t j = i + 1; j < m; ++j)
|
|---|
| 69 | mzd_write_bit(L,i,j, 0);
|
|---|
| 70 | if(i<n)
|
|---|
| 71 | mzd_write_bit(U,i,i, 1);
|
|---|
| 72 | mzd_write_bit(L,i,i, 1);
|
|---|
| 73 | }
|
|---|
| 74 |
|
|---|
| 75 | mzd_mul(A, L, U, 2048);
|
|---|
| 76 |
|
|---|
| 77 | mzd_t* Acopy = mzd_copy (NULL,A);
|
|---|
| 78 |
|
|---|
| 79 | mzp_t* P = mzp_init(m);
|
|---|
| 80 | mzp_t* Q = mzp_init(n);
|
|---|
| 81 | mzd_pluq(A, P, Q, 2048);
|
|---|
| 82 |
|
|---|
| 83 | for (rci_t i = 0; i < m; ++i){
|
|---|
| 84 | for (rci_t j = 0; j < i && j < n; ++j)
|
|---|
| 85 | mzd_write_bit (L2, i, j, mzd_read_bit(A,i,j));
|
|---|
| 86 | for (rci_t j = i + 1; j < n; ++j)
|
|---|
| 87 | mzd_write_bit (U2, i, j, mzd_read_bit(A,i,j));
|
|---|
| 88 | }
|
|---|
| 89 |
|
|---|
| 90 | for (rci_t i = 0; i < n && i < m; ++i){
|
|---|
| 91 | mzd_write_bit(L2,i,i, 1);
|
|---|
| 92 | mzd_write_bit(U2,i,i, 1);
|
|---|
| 93 | }
|
|---|
| 94 | mzd_addmul(Acopy,L2,U2,0);
|
|---|
| 95 | int status = 0;
|
|---|
| 96 | for (rci_t i = 0; i < m; ++i)
|
|---|
| 97 | for (rci_t j=0; j < n; ++j){
|
|---|
| 98 | if (mzd_read_bit (Acopy,i,j)){
|
|---|
| 99 | status = 1;
|
|---|
| 100 | }
|
|---|
| 101 | }
|
|---|
| 102 | if (status){
|
|---|
| 103 | printf(" ... FAILED\n");
|
|---|
| 104 | } else
|
|---|
| 105 | printf (" ... passed\n");
|
|---|
| 106 | mzd_free(U);
|
|---|
| 107 | mzd_free(L);
|
|---|
| 108 | mzd_free(U2);
|
|---|
| 109 | mzd_free(L2);
|
|---|
| 110 | mzd_free(A);
|
|---|
| 111 | mzd_free(Acopy);
|
|---|
| 112 | mzp_free(P);
|
|---|
| 113 | mzp_free(Q);
|
|---|
| 114 | return status;
|
|---|
| 115 | }
|
|---|
| 116 |
|
|---|
| 117 | int test_pluq_half_rank(rci_t m, rci_t n) {
|
|---|
| 118 | printf("pluq: testing half rank m: %5d, n: %5d", m, n);
|
|---|
| 119 |
|
|---|
| 120 | mzd_t* U = mzd_init(m, n);
|
|---|
| 121 | mzd_t* L = mzd_init(m, m);
|
|---|
| 122 | mzd_t* U2 = mzd_init(m, n);
|
|---|
| 123 | mzd_t* L2 = mzd_init(m, m);
|
|---|
| 124 | mzd_t* A = mzd_init(m, n);
|
|---|
| 125 | mzd_randomize (U);
|
|---|
| 126 | mzd_randomize (L);
|
|---|
| 127 |
|
|---|
| 128 | for (rci_t i = 0; i < m && i < n; ++i) {
|
|---|
| 129 | mzd_write_bit(U,i,i, 1);
|
|---|
| 130 | for (rci_t j = 0; j < i;++j)
|
|---|
| 131 | mzd_write_bit(U,i,j, 0);
|
|---|
| 132 | if (i%2)
|
|---|
| 133 | for (rci_t j = i; j < n;++j)
|
|---|
| 134 | mzd_write_bit(U,i,j, 0);
|
|---|
| 135 | for (rci_t j = i + 1; j < m; ++j)
|
|---|
| 136 | mzd_write_bit(L,i,j, 0);
|
|---|
| 137 | mzd_write_bit(L,i,i, 1);
|
|---|
| 138 | }
|
|---|
| 139 |
|
|---|
| 140 | mzd_mul(A, L, U, 0);
|
|---|
| 141 |
|
|---|
| 142 | mzd_t* Acopy = mzd_copy (NULL,A);
|
|---|
| 143 |
|
|---|
| 144 | mzp_t* Pt = mzp_init(m);
|
|---|
| 145 | mzp_t* Q = mzp_init(n);
|
|---|
| 146 | rci_t r = mzd_pluq(A, Pt, Q, 0);
|
|---|
| 147 |
|
|---|
| 148 | for (rci_t i = 0; i < r; ++i) {
|
|---|
| 149 | for (rci_t j = 0; j < i; ++j)
|
|---|
| 150 | mzd_write_bit (L2, i, j, mzd_read_bit(A,i,j));
|
|---|
| 151 | for (rci_t j = i + 1; j < n; ++j)
|
|---|
| 152 | mzd_write_bit (U2, i, j, mzd_read_bit(A,i,j));
|
|---|
| 153 | }
|
|---|
| 154 | for (rci_t i = r; i < m; ++i)
|
|---|
| 155 | for (rci_t j = 0; j < r;++j)
|
|---|
| 156 | mzd_write_bit (L2, i, j, mzd_read_bit(A,i,j));
|
|---|
| 157 | for (rci_t i = 0; i < r; ++i){
|
|---|
| 158 | mzd_write_bit(L2,i,i, 1);
|
|---|
| 159 | mzd_write_bit(U2,i,i, 1);
|
|---|
| 160 | }
|
|---|
| 161 |
|
|---|
| 162 | mzd_apply_p_left(Acopy, Pt);
|
|---|
| 163 | mzd_apply_p_right_trans(Acopy, Q);
|
|---|
| 164 |
|
|---|
| 165 | mzd_addmul(Acopy,L2,U2,0);
|
|---|
| 166 |
|
|---|
| 167 | int status = 0;
|
|---|
| 168 | for (rci_t i = 0; i < m; ++i) {
|
|---|
| 169 | for (rci_t j = 0; j < n; ++j){
|
|---|
| 170 | if (mzd_read_bit(Acopy,i,j)){
|
|---|
| 171 | status = 1;
|
|---|
| 172 | }
|
|---|
| 173 | }
|
|---|
| 174 | if(status)
|
|---|
| 175 | break;
|
|---|
| 176 | }
|
|---|
| 177 | if (status)
|
|---|
| 178 | printf(" ... FAILED\n");
|
|---|
| 179 | else
|
|---|
| 180 | printf (" ... passed\n");
|
|---|
| 181 | mzd_free(U);
|
|---|
| 182 | mzd_free(L);
|
|---|
| 183 | mzd_free(U2);
|
|---|
| 184 | mzd_free(L2);
|
|---|
| 185 | mzd_free(A);
|
|---|
| 186 | mzd_free(Acopy);
|
|---|
| 187 | mzp_free(Pt);
|
|---|
| 188 | mzp_free(Q);
|
|---|
| 189 | return status;
|
|---|
| 190 | }
|
|---|
| 191 |
|
|---|
| 192 | int test_pluq_structured(rci_t m, rci_t n) {
|
|---|
| 193 |
|
|---|
| 194 | printf("pluq: testing structured m: %5d, n: %5d", m, n);
|
|---|
| 195 |
|
|---|
| 196 | mzd_t* A = mzd_init(m, n);
|
|---|
| 197 | mzd_t* L = mzd_init(m, m);
|
|---|
| 198 | mzd_t* U = mzd_init(m, n);
|
|---|
| 199 |
|
|---|
| 200 | for(rci_t i = 0; i < m; i += 2)
|
|---|
| 201 | for (rci_t j = i; j < n; ++j)
|
|---|
| 202 | mzd_write_bit(A, i, j, 1);
|
|---|
| 203 |
|
|---|
| 204 | rci_t r = 0;
|
|---|
| 205 | int status = check_pluq(A, &r);
|
|---|
| 206 | printf(", rank: %5d ",r);
|
|---|
| 207 |
|
|---|
| 208 | if (status) {
|
|---|
| 209 | printf(" ... FAILED\n");
|
|---|
| 210 | } else
|
|---|
| 211 | printf (" ... passed\n");
|
|---|
| 212 | mzd_free(A);
|
|---|
| 213 | return status;
|
|---|
| 214 | }
|
|---|
| 215 |
|
|---|
| 216 | int test_pluq_random(rci_t m, rci_t n) {
|
|---|
| 217 | printf("pluq: testing random m: %5d, n: %5d", m, n);
|
|---|
| 218 |
|
|---|
| 219 | mzd_t* A = mzd_init(m, n);
|
|---|
| 220 | mzd_randomize(A);
|
|---|
| 221 |
|
|---|
| 222 | rci_t r = 0;
|
|---|
| 223 | int status = check_pluq(A, &r);
|
|---|
| 224 | printf(", rank: %5d ",r);
|
|---|
| 225 |
|
|---|
| 226 | if (status) {
|
|---|
| 227 | printf(" ... FAILED\n");
|
|---|
| 228 | } else
|
|---|
| 229 | printf (" ... passed\n");
|
|---|
| 230 | mzd_free(A);
|
|---|
| 231 | return status;
|
|---|
| 232 | }
|
|---|
| 233 |
|
|---|
| 234 | int test_pluq_string(rci_t m, rci_t n, const char *str) {
|
|---|
| 235 | printf("pluq: testing string m: %5d, n: %5d", m, n);
|
|---|
| 236 |
|
|---|
| 237 |
|
|---|
| 238 | mzd_t *A = mzd_from_str(m, n, str);
|
|---|
| 239 |
|
|---|
| 240 | mzd_t *Acopy = mzd_copy(NULL, A);
|
|---|
| 241 | mzp_t *P = mzp_init(A->nrows);
|
|---|
| 242 | mzp_t *Q = mzp_init(A->ncols);
|
|---|
| 243 | _mzd_ple_russian(Acopy, P, Q, 0);
|
|---|
| 244 | rci_t r = 0;
|
|---|
| 245 | int status = check_pluq(A, &r);
|
|---|
| 246 | printf(", rank: %5d ",r);
|
|---|
| 247 |
|
|---|
| 248 | if (status) {
|
|---|
| 249 | printf(" ... FAILED\n");
|
|---|
| 250 | } else
|
|---|
| 251 | printf (" ... passed\n");
|
|---|
| 252 | mzd_free(A);
|
|---|
| 253 | return status;
|
|---|
| 254 | }
|
|---|
| 255 |
|
|---|
| 256 |
|
|---|
| 257 | int main() {
|
|---|
| 258 | int status = 0;
|
|---|
| 259 |
|
|---|
| 260 | srandom(17);
|
|---|
| 261 |
|
|---|
| 262 | status += test_pluq_string(4, 4, "0101011100010110");
|
|---|
| 263 |
|
|---|
| 264 | status += test_pluq_structured(37, 37);
|
|---|
| 265 | status += test_pluq_structured(63, 63);
|
|---|
| 266 | status += test_pluq_structured(64, 64);
|
|---|
| 267 | status += test_pluq_structured(65, 65);
|
|---|
| 268 | status += test_pluq_structured(128, 128);
|
|---|
| 269 |
|
|---|
| 270 | status += test_pluq_structured(37, 137);
|
|---|
| 271 | status += test_pluq_structured(65, 5);
|
|---|
| 272 | status += test_pluq_structured(128, 18);
|
|---|
| 273 |
|
|---|
| 274 | status += test_pluq_full_rank(13, 13);
|
|---|
| 275 | status += test_pluq_full_rank(37, 37);
|
|---|
| 276 | status += test_pluq_full_rank(63, 63);
|
|---|
| 277 | status += test_pluq_full_rank(64, 64);
|
|---|
| 278 | status += test_pluq_full_rank(65, 65);
|
|---|
| 279 | status += test_pluq_full_rank(97, 97);
|
|---|
| 280 | status += test_pluq_full_rank(128, 128);
|
|---|
| 281 | status += test_pluq_full_rank(150, 150);
|
|---|
| 282 | status += test_pluq_full_rank(256, 256);
|
|---|
| 283 | status += test_pluq_full_rank(1024, 1024);
|
|---|
| 284 |
|
|---|
| 285 | status += test_pluq_full_rank(13, 11);
|
|---|
| 286 | status += test_pluq_full_rank(37, 39);
|
|---|
| 287 | status += test_pluq_full_rank(64, 164);
|
|---|
| 288 | status += test_pluq_full_rank(97, 92);
|
|---|
| 289 | status += test_pluq_full_rank(128, 121);
|
|---|
| 290 | status += test_pluq_full_rank(150, 153);
|
|---|
| 291 | status += test_pluq_full_rank(256, 258);
|
|---|
| 292 | status += test_pluq_full_rank(1024, 1023);
|
|---|
| 293 |
|
|---|
| 294 | status += test_pluq_half_rank(64, 64);
|
|---|
| 295 | status += test_pluq_half_rank(65, 65);
|
|---|
| 296 | status += test_pluq_half_rank(66, 66);
|
|---|
| 297 | status += test_pluq_half_rank(127, 127);
|
|---|
| 298 | status += test_pluq_half_rank(129, 129);
|
|---|
| 299 | status += test_pluq_half_rank(148, 148);
|
|---|
| 300 | status += test_pluq_half_rank(132, 132);
|
|---|
| 301 | status += test_pluq_half_rank(256, 256);
|
|---|
| 302 | status += test_pluq_half_rank(1024, 1024);
|
|---|
| 303 |
|
|---|
| 304 | status += test_pluq_half_rank(129, 127);
|
|---|
| 305 | status += test_pluq_half_rank(132, 136);
|
|---|
| 306 | status += test_pluq_half_rank(256, 251);
|
|---|
| 307 | status += test_pluq_half_rank(1024, 2100);
|
|---|
| 308 |
|
|---|
| 309 | status += test_pluq_random(63, 63);
|
|---|
| 310 | status += test_pluq_random(64, 64);
|
|---|
| 311 | status += test_pluq_random(65, 65);
|
|---|
| 312 |
|
|---|
| 313 | status += test_pluq_random(128, 128);
|
|---|
| 314 | status += test_pluq_random(128, 131);
|
|---|
| 315 | status += test_pluq_random(132, 731);
|
|---|
| 316 | status += test_pluq_random(150, 150);
|
|---|
| 317 | status += test_pluq_random(252, 24);
|
|---|
| 318 | status += test_pluq_random(256, 256);
|
|---|
| 319 | status += test_pluq_random(1024, 1022);
|
|---|
| 320 | status += test_pluq_random(1024, 1024);
|
|---|
| 321 |
|
|---|
| 322 | status += test_pluq_random(128, 1280);
|
|---|
| 323 | status += test_pluq_random(128, 130);
|
|---|
| 324 | status += test_pluq_random(132, 132);
|
|---|
| 325 | status += test_pluq_random(150, 151);
|
|---|
| 326 | status += test_pluq_random(252, 2);
|
|---|
| 327 | status += test_pluq_random(256, 251);
|
|---|
| 328 | status += test_pluq_random(1024, 1025);
|
|---|
| 329 | status += test_pluq_random(1024, 1021);
|
|---|
| 330 |
|
|---|
| 331 | if (!status) {
|
|---|
| 332 | printf("All tests passed.\n");
|
|---|
| 333 | return 0;
|
|---|
| 334 | } else {
|
|---|
| 335 | return -1;
|
|---|
| 336 | }
|
|---|
| 337 | }
|
|---|