11#define SWAPINT(a,b) do{ int t=a; a=b; b=t; } while(0)
13#define ERROR(fmt,...) \
15 fprintf (stderr, "%s:%d: *** ERROR in function '%s()' ***\n", __FILE__, __LINE__, __FUNCTION__); \
16 fprintf(stderr, " ␛[31;1m " fmt " ␛[0m\n",##__VA_ARGS__); \
22static inline word
const * mzd_row_cons(
const mzd_t * mat,
const int row){
24#pragma GCC diagnostic push
25#pragma GCC diagnostic ignored "-Wdiscarded-qualifiers"
26 return mzd_row(mat,row);
27#pragma GCC diagnostic pop
34#ifdef __M4RI_MAX_MZD_BLOCKSIZE
35#define MZD_FIRST_ROW(M) mzd_row((M), 0)
37#define MZD_FIRST_ROW(M) ((M)->data)
46#define SETWD(pos) ((pos)>>6)
47#define SETBT(pos) ((pos)&0x3F)
48#define TIMESWORDSIZE(w) ((w)<<6)
50#define FIRSTBIT(x) __builtin_ctzll(x)
81static inline int m4ri_bitcount(word w){
82 return __builtin_popcountll(w);
87#define MASK(c) (((uint64_t)(-1)) / (__M4RI_TWOPOW(__M4RI_TWOPOW(c)) + 1))
88#define COUNT(x,c) ((x) & MASK(c)) + (((x) >> (__M4RI_TWOPOW(c))) & MASK(c))
90static inline int m4ri_bitcount(word w) {
91 uint64_t n = __M4RI_CONVERT_TO_UINT64_T(w);
101static inline int std_bitcount ( uint64_t x) {
102 uint64_t c1 = UINT64_C (0x5555555555555555 );
103 uint64_t c2 = UINT64_C (0x3333333333333333 );
104 uint64_t c4 = UINT64_C (0x0F0F0F0F0F0F0F0F );
106 x = (( x >> 2) & c2) + (x & c2);
107 x = ( x + (x >> 4) ) & c4;
108 x *= UINT64_C (0x0101010101010101 );
109 return (
int) (x >> 56);
159#define SORT_TYPE rci_t
160#define SORT_CMP(x, y) ((x) - (y))
161#define SORT_DEF static inline
165#if defined(__cplusplus) && !defined (_MSC_VER)
201 static inline int nextelement(
const word *
const set1,
const int m,
const int pos){
210 if (w >= m)
return -1;
211 setwd = set1[w] & (m4ri_ffff<<
SETBT(pos));
341 static inline mzp_t * mzp_rand(mzp_t *q){
343 printf(
"mzp_rand: permutation must be initialized!");
363 mzp_t *
perm_p(mzp_t *q,
const mzp_t *
p,rci_t start);
373 mzp_t *
perm_p_trans(mzp_t *q,
const mzp_t *
p,
const rci_t start);
459static inline void mzd_flip_bit(mzd_t *
const M, rci_t
const row, rci_t
const col ) {
460 word *
const rawrow = mzd_row(M,row);
461 __M4RI_FLIP_BIT(rawrow[col/m4ri_radix], col%m4ri_radix);
464#ifdef __M4RI_MAX_MZD_BLOCKSIZE
469int gauss_one_rows_blocks(mzd_t *M,
const int idx,
const int begrow,
const rci_t nrows_eff);
481static inline int gauss_one_rows(mzd_t *M,
const int idx,
const int begrow,
482 const rci_t nrows_eff) {
483 if (begrow >= nrows_eff)
return 0;
484#ifdef __M4RI_MAX_MZD_BLOCKSIZE
487 if (__builtin_expect((uintptr_t)mzd_row(M, nrows_eff - 1) - (uintptr_t)mzd_row(M, 0) !=
488 (uintptr_t)(nrows_eff - 1) * (uintptr_t)M->rowstride *
sizeof(word), 0)) {
489 return gauss_one_rows_blocks(M, idx, begrow, nrows_eff);
492 const wi_t word_idx = idx >> 6;
493 const word bit_mask = (word)1 << (idx & 63);
494 const wi_t width = M->width;
495 const wi_t rowstride = M->rowstride;
496 word *row_j = mzd_row(M, begrow);
497 for (rci_t j = begrow; j < nrows_eff; ++j, row_j += rowstride) {
498 if (row_j[word_idx] & bit_mask) {
500 mzd_row_swap(M, begrow, j);
502 const word *
const __restrict piv_row = mzd_row(M, begrow);
504 for (rci_t ii = 0; ii < begrow; ++ii, dst_row += rowstride) {
505 if (dst_row[word_idx] & bit_mask) {
506 for (wi_t w = 0; w < width; ++w) {
507 dst_row[w] ^= piv_row[w];
511 dst_row += rowstride;
512 for (rci_t ii = begrow + 1; ii < nrows_eff; ++ii, dst_row += rowstride) {
513 if (dst_row[word_idx] & bit_mask) {
514 for (wi_t w = 0; w < width; ++w) {
515 dst_row[w] ^= piv_row[w];
532static inline int gauss_one(mzd_t *M,
const int idx,
const int begrow) {
533 return gauss_one_rows(M, idx, begrow, M->nrows);
547static inline int sparse_syndrome_non_zero(
const csr_t *
const H,
const int cnt,
const int ee[]){
548 for(
int ir=0; ir < H->
rows; ir++){
550 for(
int iL = H->
p[ir], iE = 0; iL < H->
p[ir+1]; iL++){
552 while((iE < cnt) && (ee[iE] < ic))
576static inline int colmask_syndrome_non_zero(
const colmask_t *
const cm,
const int cnt,
const int ee[]) {
577 const int kw = cm->
kw;
578 const word *
const mask = cm->
mask;
581 for (
int i = 0; i < cnt; i++)
585 for (
int w = 0; w < kw; w++) {
587 for (
int i = 0; i < cnt; i++)
588 s ^= mask[(
size_t)ee[i] * kw + w];
626 int do_reduce(mzd_t *row,
const mzd_t *matP0,
const rci_t rankP0);
638 int do_dist_clus(
const csr_t *
const P,
const mzd_t *
const G,
int debug,
int wmax,
int start,
const int rankG);
730 int *visited_cols,
int *visited_checks,
int *col_queue,
731 int *visit_marker, uint64_t *rng_state);
750#if defined(__cplusplus) && !defined (_MSC_VER)
mzd_t * mzd_nullspace(const csr_t *const H)
Compute the null space basis N = ker(H) of dimension nu x n.
cols_ws_t * cols_ws_init(const int m)
Allocate the workspace of csr_cols_rank() and csr_cols_dependency() for a matrix H with m rows.
int syndrome_bit_count(const mzd_t *const row, const csr_t *const spaQ)
Compute the Hamming weight of the syndrome of a dense row vector against spaQ.
colmask_t * colmask_free(colmask_t *cm)
Free the column masks allocated by colmask_from_csr().
cols_ws_t * cols_ws_free(cols_ws_t *ws)
Free the workspace allocated by cols_ws_init().
mzp_t * mzp_rand_len(mzp_t *q, rci_t length)
Generate a random permutation of a given length in-place.
int do_reduce(mzd_t *row, const mzd_t *matP0, const rci_t rankP0)
Reduce a row vector against a matrix in standard form.
int csr_csr_mul_non_zero(const csr_t *const A, const csr_t *const B)
Check if the product of two sparse matrices A * B^T is non-zero.
void make_err(mzd_t *row, double p)
Generate a random binary error vector with error probability p.
int do_dist_clus(const csr_t *const P, const mzd_t *const G, int debug, int wmax, int start, const int rankG)
(Internal) Run cluster distance algorithm on matrices.
int csr_cols_rank(const csr_t *const HT, const int cnt, const int cols[], cols_ws_t *const ws)
Rank of a set of columns of a sparse binary matrix H.
mzd_t * syndrome_vector(mzd_t *syndrome, mzd_t *row, csr_t *spaQ, int clear)
Calculate syndrome vector change.
size_t mzd_weight_row(const mzd_t *A, rci_t i)
Compute the Hamming weight of a specific row in a dense matrix.
csr_t * csr_from_pairs(csr_t *mat, const int nz, int_pair *const prs, const int nrows, const int ncols)
Construct a CSR sparse matrix from an array of coordinate pairs.
mzd_t * mzd_generator_from_csr(mzd_t *G, const csr_t *const H)
Construct the generator matrix from a parity check matrix in CSR form.
csr_t * csr_transpose(csr_t *dst, const csr_t *const p)
Transpose a compressed CSR sparse matrix.
csr_t * csr_mm_read(char *fin, csr_t *mat, int transpose)
Read a sparse matrix from a Matrix Market (.mtx) file into CSR format.
csr_t * Lx_for_CSS_code(const csr_t *const Hx, const csr_t *const Hz)
Construct the logical matrix Lx for a quantum CSS code given Hx and Hz.
csr_t * csr_init(csr_t *mat, int rows, int cols, int nzmax)
Initialize or reallocate a CSR sparse matrix to target size.
mzd_t * mzd_from_csr(mzd_t *dst, const csr_t *p)
Convert a CSR sparse matrix to an MZD dense matrix.
mzp_t * perm_p_trans(mzp_t *q, const mzp_t *p, const rci_t start)
Apply transposed pivot permutation p to permutation q in-place.
void csr_out(const csr_t *mat)
Print raw contents of a CSR matrix to stdout.
void csr_print(const csr_t *const smat, const char str[])
Print a CSR matrix with a label string (formatted output).
csr_t * csr_free(csr_t *p)
Free memory allocated for a CSR sparse matrix.
void csr_compress(csr_t *mat)
Compress CSR matrix (sort indices and remove duplicates/zeros).
int csr_max_row_wght(const csr_t *const p)
Get the maximum row weight of a CSR sparse matrix.
rci_t mzd_gauss_naive(mzd_t *M, mzp_t *q, int full)
Perform Gaussian elimination (naive) and return pivot column list.
void localized_window_perm(mzp_t *perm, int nvar, int seed_col, int kwin, int win_mode, const csr_t *spaH, const csr_t *mHT, int *visited_cols, int *visited_checks, int *col_queue, int *visit_marker, uint64_t *rng_state)
Construct a column permutation with a localized window at the front.
void refresh_nullspace_basis(mzd_t *N, const int *cw_arr, int cw_wt, uint64_t *rng_state)
Refresh the null space basis N under a random column permutation and optionally inject a low-weight c...
colmask_t * colmask_from_csr(const csr_t *const A)
Construct the column bit masks of a sparse binary matrix (see colmask_t).
int csr_all_ones_in_rowspan(const csr_t *const H)
Check whether the all-ones vector lies in the row span of a binary CSR matrix H over GF(2).
size_t mzd_weight(const mzd_t *A)
Compute the number of set bits (Hamming weight) in a dense matrix A.
mzp_t * perm_p(mzp_t *q, const mzp_t *p, rci_t start)
Apply pivot permutation p to permutation q in-place starting from index.
void mzp_out(mzp_t const *p)
Print the permutation to stdout.
size_t mzd_weight_naive(const mzd_t *A)
Naive implementation to compute the Hamming weight of a dense matrix A.
mzd_t * csr_mzd_mul(mzd_t *C, const csr_t *S, const mzd_t *B, int clear)
Multiply a sparse matrix by a dense matrix.
size_t product_weight_csr_mzd(const csr_t *A, const mzd_t *B, int transpose)
Compute the weight of the product of a sparse matrix and a dense matrix.
csr_t * csr_apply_perm(csr_t *dst, const csr_t *const src, const mzp_t *const perm)
Permute columns of a CSR sparse matrix.
int rand_uniform(const int max)
Return a uniformly distributed random integer in the range [0, max-1].
int csr_cols_dependency(const csr_t *const HT, const int cnt, const int cols[], cols_ws_t *const ws, int sub[])
A nonempty proper subset of a set of columns of H with zero sum, if there is one.