Dist m4ri 0.16.1
Computing distance of a classical or quantum CSS code
Loading...
Searching...
No Matches
dist_cc.c
Go to the documentation of this file.
1
17// #include <m4ri/config.h>
18#include <inttypes.h>
19#include <strings.h>
20#include <stdlib.h>
21#include <time.h>
22#include <m4ri/m4ri.h>
23
24#include "mmio.h"
25#include "uthash.h"
26#include "util_hash.h"
27#include "util_m4ri.h"
28#include "util_io.h"
29#include "dist_cc.h"
30
32void one_vec_print(const one_vec_t * const pvec){
33 printf(" w=%d [ ",pvec->wei);
34 for(int i=0; i < pvec->wei; i++)
35 printf("%d ",pvec->vec[i]);
36 printf("]\n");
37}
38
40
55int start_CC_recurs(one_vec_t *err, one_vec_t *urr, one_vec_t * const syn[],
56 const int w_limit, const int max_col_wt,
57 const csr_t * const mH, const csr_t * const mHT,
58 params_t * const p){
59 const int w=err->wei;
60 assert(urr->wei == err->wei);
61 int row = syn[w]->vec[0];
62 const csr_t * const mL = p->spaL;
63 int *p_swei = p->swei;
64 const int smax = p->smax;
65 const int debug = p->debug;
66#ifndef NDEBUG
67 if(debug & DBG_LEGACY){
68 printf("starting CC recurs w=%d row=%d:\n urr: ",w,row);
69 one_vec_print(urr);
70 printf(" err: ");
71 one_vec_print(err);
72 for(int i=0; i <= w; i++){
73 printf("# syn[i=%d] ",i);
74 one_vec_print(syn[i]);
75 }
76 }
77#endif
80 const int col_min = (p->start_num > 0 && !p->start_scan) ? -1 : urr->vec[0];
81 int current_limit = w_limit;
82 if (p->min_w != INT_MAX && p->dW >= 0) {
83 current_limit = minint(w_limit, p->min_w + p->dW);
84 }
85 const int syn_w_wei = syn[w]->wei;
86 const int rem = current_limit - (w + 1);
87 const int max_reach = rem * max_col_wt + (smax > 0 ? smax : 0);
88
89 for(int i1 = mH->p[row]; i1 < mH->p[row+1]; i1++){
90 const int col = mH->i[i1];
91 if(col > col_min){
92 const int col_wt = mHT->p[col+1] - mHT->p[col];
93 if (w + 1 == current_limit) {
94 if (abs(syn_w_wei - col_wt) > (smax > 0 ? smax : 0)) continue;
95 } else {
96 if (syn_w_wei - col_wt > max_reach) continue;
97 }
98 int pos = one_ordered_search(err, col);
99 if(pos == -1){
100 urr->vec[w] = col;
101 urr->wei++;
102#ifndef NDEBUG
103 if(debug & DBG_LEGACY){
104 printf(" pos=%d urr: ",pos);
105 one_vec_print(urr);
106 }
107#endif
108 pos = one_ordered_ins(err,col);
109 syn[w+1]->wei=0;
110 int swei = one_csr_row_combine(syn[w+1],syn[w], mHT, col);
111 if(debug & DBG_LEGACY){
112 printf(" syn: ");
113 one_vec_print(syn[w+1]);
114 }
115 int result = 0;
116 if (p->min_w != INT_MAX && p->dW >= 0) {
117 current_limit = minint(w_limit, p->min_w + p->dW);
118 }
119 if (err->wei < current_limit){
120 if (swei > 0 && swei <= (current_limit - err->wei) * max_col_wt + (smax > 0 ? smax : 0)){
121 result = start_CC_recurs(err,urr,syn,w_limit,max_col_wt,
122 mH,mHT,p);
123 if(result == 1)
124 return 1;
125 }
126 // swei == 0 means it is a degenerate vector
127 // do not go up in this case
128 }
129 else{ // wei >= current_limit
130 assert(err->wei == current_limit);
131 if(!swei){
132 if((!mL) ||
133 (sparse_syndrome_non_zero(mL, err->wei, err->vec))){
134 if(debug & DBG_LEGACY){
135 printf("swei=%d *** success ***\n",swei);
136 one_vec_print(err);
137 one_vec_print(syn[w+1]);
138 }
139 p->codewords = codeword_add_maybe(p, err->vec, err->wei, CW_SRC_OTHER);
141 return 1;
142 }
143 if (!p->outC && p->maxC == 0) {
144 return 1;
145 }
146 }
147 }
148 else if(swei <= smax){
149 if(debug & DBG_LEGACY){
150 printf("# try adding to the hash ewei=%d swei=%d smax=%d p_swei[%d]=%d\n",err->wei,swei,smax,w+1,p_swei[w+1]);
151 }
152 //
153 errors = hash_add_maybe(syn[w+1],err,errors, p_swei, debug);
154 }
155 }
156 urr->wei--;
157 one_ordered_pos_del(err,col,pos);
158 if(debug & DBG_LEGACY){
159 printf("xerr: ");
160 one_vec_print(err);
161 }
162 }
163 }
164 }
165 if(debug & DBG_LEGACY)
166 printf("exiting CC recurs\n\n");
167 return 0;
168}
169
173int do_CC_dist(params_t * const p){
174 const csr_t * const mH = p->spaH;
175 const csr_t * const mL = p->spaL;
176 const int wmax = p->wmax;
177 const int noscan = p->noscan;
178 int *p_swei = p->swei;
179 const int smax = p->smax;
180 const int debug = p->debug;
181
182 const int nvar = mH->cols;
183
184 csr_t * const mHT = csr_transpose(NULL,mH);
185 csr_dump(stderr, mHT, "HT", debug);
186 int max_col_W = csr_max_row_wght(mHT);
187
188 one_vec_t *err = calloc(1, sizeof(one_vec_t)+sizeof(int)*wmax);
189 one_vec_t *urr = calloc(1, sizeof(one_vec_t)+sizeof(int)*wmax);
190 one_vec_t **syn = calloc(wmax+1, sizeof(one_vec_t *));
191 if((!syn) || (!err) || (!urr))
192 ERROR("memory allocation");
193 // err->max = wmax;
194 for(int i=0; i <= wmax; i++){
195 syn[i]=calloc(1, sizeof(one_vec_t)+sizeof(int)*mH->rows);
196 if(!syn[i]) ERROR("i=%d memory allocation",i);
197 // syn[i]->max = mH->rows;
198 }
199 int result = 0;
200 const int w_start = noscan ? wmax : (p->dmin > 1 ? p->dmin : 1);
203 const int d0 = (p->dmin > 1) ? p->dmin : 1;
204 const int certified = (w_start <= d0);
205 int w_limit_dynamic = wmax;
206 if (p->dmax > 0) {
207 if (p->outC && p->dW > 0) {
208 w_limit_dynamic = minint(wmax > 0 ? wmax : p->dmax + p->dW, p->dmax + p->dW);
209 } else {
210 w_limit_dynamic = minint(wmax > 0 ? wmax : p->dmax, p->dmax);
211 }
212 }
213 for(int w=w_start; w <= w_limit_dynamic; w++){ /* cluster weight */
214 if (p->min_w != INT_MAX && p->dW >= 0) {
215 w_limit_dynamic = minint(wmax > 0 ? wmax : p->min_w + p->dW, p->min_w + p->dW);
216 }
217 if (w > w_limit_dynamic) {
218 break;
219 }
220 int beg, end;
221 if (p->start_num > 0) {
222 beg = 0;
223 end = p->start_num - 1;
224 if(debug & DBG_PROGRESS)
225 printf("# recursively searching for w=%d codewords wmax=%d from %d listed start column(s)\n",
226 w, wmax, p->start_num);
227 }
228 else {
229 beg = (p->cbeg >= 0) ? p->cbeg : 0;
230 end = (p->cend >= 0) ? minint(p->cend, nvar - w) : nvar - w;
231 if(debug & DBG_PROGRESS)
232 printf("# recursively searching for w=%d codewords wmax=%d beg=%d end=%d\n",w,wmax,beg,end);
233 }
234 for(int k = beg; k <= end; k++){ /* start column position (or its index in the `start` list) */
235 const int i = (p->start_num > 0) ? p->start_list[k] : k;
237 err->vec[0] = urr->vec[0] = i;
238 err->wei = urr->wei = 1;
239 syn[1]->wei=0;
240 int swei = one_csr_row_combine(syn[1], syn[0], mHT, i);
241 if (w>1){
242 if (swei){
243 result = start_CC_recurs(err,urr,syn,w,max_col_W,mH,mHT,p);
244 if(result == 1)
245 break;
246 }
247 }
248 else{ // w==1
249 if(!swei){
250 if((!mL) ||
251 (sparse_syndrome_non_zero(mL, err->wei, err->vec))){
252 p->codewords = codeword_add_maybe(p, err->vec, err->wei, CW_SRC_OTHER);
254 result = 1;
255 break;
256 }
257 if (!p->outC && p->maxC == 0) {
258 result = 1;
259 break;
260 }
261 }
262 }
263 else if(swei <= smax)
264 errors = hash_add_maybe(syn[1],err,errors,p_swei, debug);
265 }
266 err->wei = urr->wei = 0;
267 }
268 if(result == 1)
269 break;
270
271 if (p->min_w > w && w < w_limit_dynamic) {
272 printf("-%d\n", w);
273 fflush(stdout);
274 } else if (p->min_w <= w && p->dW >= 0 && w <= w_limit_dynamic) {
275 if (debug & DBG_SUMMARY) {
276 fprintf(stderr, "# CC round w=%d finished: searched with dW=%d (min_w=%d, total %lld codewords)\n",
277 w, p->dW, p->min_w, p->num_cws);
278 }
279 }
280 }
281
282 if(result==1){
283 result = err->wei;
284#ifndef NDEBUG
285 assert( 0 == sparse_syndrome_non_zero(mH, err->wei, err->vec));
286 if(mL) assert(sparse_syndrome_non_zero(mL, err->wei, err->vec));
287#endif
288 if (debug & DBG_CODEWORDS){
289 printf("# wmax=%d found cw of weight %d: [",wmax,result);
290 int max = ((result<50) || (debug & DBG_LARGE)) ? result : 50 ;
291 for(int i=0; i< max; i++)
292 printf("%d%s",err->vec[i], i+1!=max?" ": (result==max ? "]\n" : "...]\n"));
293 }
294 }
295 else {
296 if (p->min_w <= wmax) {
297 result = p->min_w;
298 } else if (certified) {
299 result = -wmax;
300 } else {
301 result = -(d0 - 1);
302 }
303 }
304
305 if(smax){
306 int skipped = 0;
307 if (debug & DBG_SUMMARY){
308 for(int i=1;i<=wmax; i++) {
309 if(p_swei[i] <= mH->rows) {
310 printf("# w=%d min non-zero syndrome weight %d\n",i,p_swei[i]);
311 } else {
312 skipped = 1;
313 }
314 }
315 }
316 else{
317 printf("# confinement: ");
318 for(int i=1;i<=wmax; i++) {
319 if(p_swei[i] <= mH->rows) {
320 printf("%d%s",p_swei[i],i<wmax?",":"");
321 } else {
322 skipped = 1;
323 printf("?%s",i<wmax?",":"");
324 }
325 }
326 printf("\n");
327 }
328 if (skipped) {
329 printf("# Note: Some weights were skipped in confinement profile. Try increasing smax (current: %d)\n", smax);
330 }
331 }
332
333 for(int i=0; i<= wmax; i++)
334 free(syn[i]);
335 free(syn);
336 free(err);
337 free(urr);
338 csr_free(mHT);
339
341 two_vec_t *terr, *tmp;
342 HASH_ITER(hh, errors, terr, tmp) {
343 // two_vec_print(terr);
344 HASH_DEL(errors, terr);
345 free(terr);
346 }
347
348 return result;
349}
350
351
int do_CC_dist(params_t *const p)
Definition dist_cc.c:173
void one_vec_print(const one_vec_t *const pvec)
distance of a classical or quantum CSS code
Definition dist_cc.c:32
int start_CC_recurs(one_vec_t *err, one_vec_t *urr, one_vec_t *const syn[], const int w_limit, const int max_col_wt, const csr_t *const mH, const csr_t *const mHT, params_t *const p)
recursively construct codewords
Definition dist_cc.c:55
two_vec_t * errors
Definition dist_cc.c:39
int vec[0]
Definition util_hash.h:48
int * p
Definition util_m4ri.h:125
int * i
Definition util_m4ri.h:126
int rows
Definition util_m4ri.h:121
int cols
Definition util_m4ri.h:122
#define HASH_DEL(head, delptr)
Definition uthash.h:507
#define HASH_ITER(hh, head, el, tmp)
Definition uthash.h:1060
Utility functions for use with uthash.h.
struct TWO_VEC_T two_vec_t
structure to hold two sparse vectors (syndrome,error) in a hash
struct ONE_VEC_T one_vec_t
params_t *const p
Definition util_io.c:93
int codeword_maxc_reached(const params_t *const p)
Returns 1 if maxC > 0 and maxC codewords of the collection window are collected.
Definition util_io.c:2644
cw_vec_t * codeword_add_maybe(params_t *const p, const int arr[], int weight, int src)
Add a candidate codeword to the hash table, or count one more hit of a known codeword.
Definition util_io.c:2693
void csr_dump(FILE *stream, const csr_t *const M, const char name[], const int debug)
Print a binary CSR matrix row by row ('1': nonzero, '.': zero), for DBG_MATRICES.
Definition util_io.c:186
#define DBG_LEGACY
Definition util_io.h:41
#define DBG_PROGRESS
Definition util_io.h:32
#define DBG_SUMMARY
Definition util_io.h:31
#define DBG_CODEWORDS
Definition util_io.h:36
#define DBG_LARGE
Definition util_io.h:40
@ CW_SRC_OTHER
Definition util_io.h:253
csr_t * csr_transpose(csr_t *dst, const csr_t *const p)
Transpose a compressed CSR sparse matrix.
Definition util_m4ri.c:163
csr_t * csr_free(csr_t *p)
Free memory allocated for a CSR sparse matrix.
Definition util_m4ri.c:522
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
Definition util_m4ri.c:145
#define ERROR(fmt,...)
Definition util_m4ri.h:13