18 for(rci_t i = 0; i < A->nrows; ++i)
19 for(rci_t j = 0; j < A->ncols; ++j)
20 if(mzd_read_bit(A, i, j))
27 assert(i >=0 && i < A->nrows);
29 for(rci_t j = 0; j < A->ncols; ++j)
30 if(mzd_read_bit(A, i, j))
34 const word *
const truerow = mzd_row_cons(A,i);
35 for(wi_t j = 0; j < A->width - 1; j ++){
36 count += m4ri_bitcount(truerow[j]);
38 for(rci_t j = m4ri_radix * (A-> width - 1) ; j < A->ncols ; ++j)
39 if(mzd_read_bit(A, i, j))
47 for(rci_t i = 0; i < A->nrows; ++i)
48 for(rci_t j = 0; j < A->ncols; ++j)
49 if(mzd_read_bit(A, i, j))
53 for(rci_t i = 0; i < A->nrows; ++i) {
54 const word *
const truerow = mzd_row_cons(A,i);
55 for(wi_t j = 0; j < A->width - 1; j ++){
56 count += m4ri_bitcount(truerow[j]);
60 for(rci_t j = m4ri_radix * (A-> width - 1) ; j < A->ncols ; ++j)
61 if(mzd_read_bit(A, i, j))
75 rci_t startcol=0, startrow = 0;
81 if ((q->length)!=M->ncols){
90 for (rci_t i = startcol; i < M->ncols ; ++i) {
91 for(rci_t j = startrow ; j < M->nrows; ++j) {
92 if (mzd_read_bit(M, j, i)) {
93 mzd_row_swap(M, startrow, j);
96 for(rci_t ii = full ? 0 : startrow + 1; ii < M->nrows; ++ii) {
98 if (mzd_read_bit(M, ii, i)) {
99 mzd_row_add_offset(M, ii, startrow, i);
103 startrow = startrow + 1;
118 for(
int i=0;i<m;i++){
119 int w=(
p->p[i+1])-(
p->p[i]);
134 int rows=
p->rows, cols=
p->cols, nz=
p->p[rows];
137 else if ((dst->
cols != rows) || (dst->
rows != cols) || (dst->
nzmax < MAX(nz, cols+1)))
138 ERROR(
"Wrong size for return matrix.\n");
141 for(
int i=0;i<rows;i++)
142 for(
int j=
p->p[i]; j <
p->p[i+1] ; j++){
157 int m=
p->rows, n=
p->cols, nz=
p->nz;
160 else if ((dst->nrows != m) || (dst->ncols != n))
161 ERROR(
"Wrong size for return matrix.\n");
167 for(
int j=
p->p[i]; j <
p->p[i+1] ; j++)
168 mzd_write_bit(dst, i,
p->i[j], 1);
171 for(
int i=0;i<
p->nz;i++)
172 mzd_write_bit(dst,
p->p[i],
p->i[i],1);
186 mzp_t * pivots = mzp_init(n);
196 if ((G!=NULL) && ((G->ncols!=n) || (G->nrows!=n-ra))){
204 mzd_apply_p_right_trans(mat,pivots);
205 mzd_t *matC = mzd_submatrix(NULL, mat, 0, ra, ra, n);
206 mzd_t * winCT=mzd_init_window(G,0,0,n-ra,ra);
207 mzd_transpose(winCT,matC);
210 for(
int i=0; i<n-ra ; i++)
211 mzd_write_bit(G,i,i+ra,1);
213 mzd_apply_p_right(G,pivots);
225 if (S->
cols != B->nrows)
226 ERROR(
"column dim of S and row dim of B should match, %d=%d",S->
cols,B->nrows);
228 C = mzd_init(S->
rows, B->ncols);
230 if (C->nrows != S->
rows || C->ncols != B->ncols)
231 ERROR(
"Provided return matrix has wrong dimensions.\n");
235 rci_t
const m = S->
rows;
237 for(rci_t i = 0; i < m; ++i)
238 for(
int j=S->
p[i]; j < S->
p[i+1] ; j++)
239 mzd_combine(C,i,0, C,i,0, B,S->
i[j],0);
250 ERROR(
"addto: attempt to get row=%d of %d",i,spaQ->
rows);
251 if (row->ncols != spaQ->
cols)
252 ERROR(
"addto: column number mismatch");
255 for (
int j=spaQ->
p[i]; j<spaQ->
p[i+1]; j++)
256 mzd_flip_bit(row, 0,spaQ->
i[j]);
264static inline void addto_inline(mzd_t *row,
const csr_t *spaQ,
const int i){
267 ERROR(
"addto: attempt to get row=%d of %d",i,spaQ->
rows);
268 if (row->ncols != spaQ->
cols)
269 ERROR(
"addto: column number mismatch");
272 for (
int j=spaQ->
p[i]; j<spaQ->
p[i+1]; j++)
273 mzd_flip_bit(row, 0,spaQ->
i[j]);
282 if (row->ncols != spaQ->
rows)
283 ERROR(
"column dim of row and row dim of spaQ should match, %d=%d",row->ncols,spaQ->
rows);
284 if (syndrome == NULL)
285 syndrome = mzd_init(row->nrows, spaQ->
cols);
287 if (syndrome->nrows != row->nrows || syndrome->ncols != spaQ->
cols)
288 ERROR(
"Provided return matrix has wrong dimensions.\n");
290 mzd_set_ui(syndrome,0);
292 for (rci_t i=0; i< row->nrows; i++){
293 const word *
const rawrow = mzd_row_cons(row,i);
297 j=nextelement(rawrow,row->width,j+1);
301 for (
int j1=spaQ->
p[j]; j1<spaQ->
p[j+1]; j1++)
302 mzd_flip_bit(syndrome, i,spaQ->
i[j1]);
311 ERROR(
"matrix A is NULL");
313 ERROR(
"matrix A shold be in compressed form");
315 ERROR(
"matrix B is NULL");
317 ERROR(
"matrix B should be in compressed form");
319 ERROR(
"col count mismatch: A[%d,%d] and B[%d,%d]",
322 for(
int i=0; i < B->
rows; i++){
323 const int begr = B->
p[i];
324 if(sparse_syndrome_non_zero(A,B->
p[i+1] - begr, & (B->
i[begr])))
337 for(
int i=0;i<m;i++){
339 for (
int j=spaQ->
p[i]; j<spaQ->
p[i+1]; j++){
343 bit ^= mzd_read_bit(row, 0,spaQ->
i[j]);
360 mzd_t *BT=mzd_transpose(NULL,B);
361 Prod=mzd_mul_naive(NULL,mA,BT);
365 Prod=mzd_mul_naive(NULL,mA,B);
378 int divisor = RAND_MAX/(max);
381 retval = rand() / divisor;
382 while (retval >= max);
385 return (
int) floor(max * tinymt64_generate_double(&tinymt));
398 ERROR(
"permutation must be initialized!");
399 if (length>q->length)
400 ERROR(
"mzp_rand_len: second parameter too large, %d > %d", length, q->length);
401 for(
int i=0;i<=length-2;i++){
404 for(
int i=length-1; i< (q-> length); i++)
414 for(rci_t i=0;i<
p->length;i++)
415 printf(
" %d",
p->values[i]);
424mzp_t *
perm_p(mzp_t *q,
const mzp_t *
p,rci_t start){
427 q=mzp_init(
p->length);
428 else if (
p->length != q->length)
429 ERROR(
"mzp length mismatch %d and %d !\n",
p->length , q->length);
430 rci_t length =
p->length;
431 rci_t *perm = q->values;
432 for(rci_t i = start; i < length; ++i)
433 SWAPINT(perm[i], perm[
p->values[i]]);
445 q=mzp_init(
p->length);
446 else if (
p->length != q->length)
447 ERROR(
"mzp length mismatch %d and %d !\n",
p->length , q->length);
448 rci_t length =
p->length;
449 rci_t *perm = q->values;
450 for(rci_t i = start; i < length; ++i)
451 SWAPINT(perm[length-i-1], perm[
p->values[length-i-1]]);
477 if ((mat!=NULL)&&((mat->
nzmax < nzmax)||(mat->
nzmax < rows+1))){
480 mat->
p = realloc(mat->
p,MAX(nzmax,(rows+1))*
sizeof(
int));
481 mat->
i = realloc(mat->
i, nzmax*
sizeof(
int));
482 if ((mat->
p==NULL) || (mat->
i==NULL))
483 ERROR(
"csr_init: failed to reallocate CSR rows=%d cols=%d nzmax=%d",
488 mat=malloc(
sizeof(
csr_t));
489 mat->
p=calloc(MAX(nzmax,(rows+1)),
sizeof(
int));
490 mat->
i=calloc(nzmax,
sizeof(
int));
491 if ((mat == NULL) || (mat->
p==NULL) || (mat->
i==NULL))
492 ERROR(
"csr_init: failed to allocate CSR rows=%d cols=%d nzmax=%d",
503static int cmp_int_pairs(
const void *p1,
const void *p2){
515 ERROR(
"matrix already compressed");
517 for(
int i=0;i<nz;i++){
518 pairs[i].
a=mat->
p[i];
519 pairs[i].
b=mat->
i[i];
521 qsort(pairs,nz,
sizeof(
int_pair),cmp_int_pairs);
523 for(i=0;i<mat->
rows;i++){
525 while ((j<nz)&&(pairs[j].a == i)){
526 mat->
i[j]=pairs[j].
b;
536 mat =
csr_init(mat, nrows, ncols, nz);
537 qsort(prs, nz,
sizeof(
int_pair), cmp_int_pairs);
539 for(i=0; i < nrows; i++){
541 while ((j<nz) && (prs[j].a == i)){
557 printf(
"# binary CSR matrix (%d x %d) in Compressed Row Form: "
558 "nzmax= %d, nz=%d\n",
560 for(
int i=0;i<mat->
rows;i++){
562 for(
int j=mat->
p[i]; j < mat->
p[i+1] ; j++)
563 printf(
" %d",mat->
i[j]+1);
568 printf(
"# binary CSR matrix (%d x %d) in Pair Form: "
569 "nzmax= %d, nz=%d\n",
571 for(
int i=0;i<mat->
nz;i++)
572 printf(
"%d %d\n",mat->
p[i]+1,mat->
i[i]+1);
579 printf(
"matrix %s:\n",str);
599 if ((f = fopen(fin,
"r")) == NULL)
600 ERROR(
"can't open file %s",fin);
603 ERROR(
"Could not process Matrix Market banner.");
606 ERROR(
"Only Matrix Market 'matrix' object is supported.");
619 ERROR(
"Cannot read coordinate size in input file %s", fin);
622 ERROR(
"Cannot read array size in input file %s", fin);
652 mat =
csr_init(mat, rows, cols, nzmax);
656 for (
int i = 0; i < nz; i++) {
660 if (fscanf(f,
"%d %d %d\n", &r, &c, &v) != 3) {
661 ERROR(
"Failed to read coordinate entry %d in %s", i, fin);
664 if (fscanf(f,
"%d %d\n", &r, &c) != 2) {
665 ERROR(
"Failed to read pattern entry %d in %s", i, fin);
671 int r_store = transpose ? c : r;
672 int c_store = transpose ? r : c;
686 for (
int c = 0; c < N; c++) {
687 for (
int r = 0; r < M; r++) {
689 if (fscanf(f,
"%d\n", &v) != 1) {
690 ERROR(
"Failed to read dense general entry at r=%d, c=%d in %s", r, c, fin);
693 int r_store = transpose ? c : r;
694 int c_store = transpose ? r : c;
702 for (
int c = 0; c < N; c++) {
703 for (
int r = c; r < M; r++) {
705 if (fscanf(f,
"%d\n", &v) != 1) {
706 ERROR(
"Failed to read dense symmetric entry at r=%d, c=%d in %s", r, c, fin);
709 int r_store = transpose ? c : r;
710 int c_store = transpose ? r : c;
739 ERROR(
"pair format unsupported, nz=%d; expected \"-1\"",src->
nz);
741 if(src->
cols != perm-> length)
742 ERROR(
"perm length=%d should match cols=%d",perm->length,src->
cols);
745 else if ((dst->
rows != m) || (dst->
cols != n) || (nz > dst->
nzmax))
746 ERROR(
"Wrong size for return matrix.\n");
748 for(
int j=src->
p[i]; j < src->
p[i+1] ; j++){
750 dst->
i[j]= perm->values[src->
i[j]];
770int do_reduce(mzd_t *row,
const mzd_t *matG0,
const rci_t rankG0){
771 word *
const rawrow = mzd_row(row,0);
775 j=nextelement(rawrow,row->width,j);
779 mzd_combine_even_in_place(row,0,0,matG0,j,0);
780 }
while (j < rankG0);
786static inline uint64_t rotl(
const uint64_t x,
int k) {
787 return (x << k) | (x >> (64 - k));
810 const int cutoff=
p*RAND_MAX;
812 ERROR(
"make_err: row vector must be allocated to correct size!");
815 for(rci_t i = 0; i < row->nrows; ++i){
816 mzd_row_clear_offset(row,i,0);
818 for(rci_t j = 0; j < row->ncols; ++j){
821 mzd_write_bit(row,i,j,1);
839 mat =
csr_init(mat, orig->nrows, orig->ncols, nz);
841 for(i=0;i < mat->
rows; i++){
845 const word *
const rawrow = mzd_row_cons(orig,i);
846 while(((idx=nextelement(rawrow,orig->width,idx))!=-1)&&(idx<orig->ncols)){
850 for(
int idx=0; idx< orig->ncols; idx++)
851 if(mzd_read_bit(orig,i,idx)){
875 ERROR(
"unequal number of columns in matrices Hx[%d,%d] and Hz[%d,%d]",
878 mzp_t *pivots = mzp_init(n);
880 mzd_apply_p_right_trans(Mx,pivots);
881 mzp_t *perm =
perm_p( NULL, pivots,0);
887 mzd_t *MxT = mzd_transpose(NULL,Mx);
889 ERROR(
"rows of Hx and Hz should be orthogonal ");
895 mzd_t *mat = mzd_stack(NULL,Mx,MzStar);
898 int rank1=mzd_echelonize(mat,0);
901 mzd_t *window = mzd_init_window(mat,rank,0,rank1,n);
char * mm_typecode_to_str(MM_typecode matcode)
Convert a Matrix Market typecode to a human-readable string.
int mm_read_mtx_array_size(FILE *f, int *M, int *N)
Read dimensions for an array (dense) matrix.
int mm_read_mtx_crd_size(FILE *f, int *M, int *N, int *nz)
Read dimensions and number of non-zero entries for a coordinate matrix.
int mm_read_banner(FILE *f, MM_typecode *matcode)
Read the Matrix Market banner from a file.
#define mm_is_matrix(typecode)
#define mm_is_coordinate(typecode)
#define mm_is_pattern(typecode)
#define mm_is_general(typecode)
#define mm_is_integer(typecode)
#define mm_is_symmetric(typecode)
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.
mzp_t * mzp_rand_len(mzp_t *q, rci_t length)
Generate a random permutation of a given length in-place.
csr_t * csr_from_mzd(csr_t *mat, const mzd_t *const orig)
convert m4ri dense matrix to csr
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.
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 *const A, const 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)
Compute logical generator matrix Lx for a CSS code.
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.
int do_reduce(mzd_t *row, const mzd_t *matG0, const rci_t rankG0)
Reduce a row vector against a matrix in standard form.
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)
return max row weight of CSR matrix p TODO: add code for List of Pairs
rci_t mzd_gauss_naive(mzd_t *M, mzp_t *q, int full)
Perform Gaussian elimination (naive) and return pivot column list.
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 addto(mzd_t *row, const csr_t *spaQ, const int i)
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].