Dist m4ri 0.0.1.alpha
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
54int start_CC_recurs(one_vec_t *err, one_vec_t *urr, one_vec_t * const syn[],
55 const int w_limit, const int max_col_wt,
56 const csr_t * const mH, const csr_t * const mHT,
57 params_t * const p){
58 const int w=err->wei;
59 assert(urr->wei == err->wei);
60 int row = syn[w]->vec[0];
61 const csr_t * const mL = p->spaL;
62 int *p_swei = p->swei;
63 const int smax = p->smax;
64 const int debug = p->debug;
65#ifndef NDEBUG
66 if(debug&64){
67 printf("starting CC recurs w=%d row=%d:\n urr: ",w,row);
68 one_vec_print(urr);
69 printf(" err: ");
70 one_vec_print(err);
71 for(int i=0; i <= w; i++){
72 printf("# syn[i=%d] ",i);
73 one_vec_print(syn[i]);
74 }
75 }
76#endif
77 const int col_min=urr->vec[0];
78 for(int i1 = mH->p[row]; i1 < mH->p[row+1]; i1++){
79 const int col = mH->i[i1];
80 if(col > col_min){
81 int pos = one_ordered_search(err, col);
82 if(pos == -1){
83 urr->vec[w] = col;
84 urr->wei++;
85#ifndef NDEBUG
86 if(debug&64){
87 printf(" pos=%d urr: ",pos);
88 one_vec_print(urr);
89 }
90#endif
91 pos = one_ordered_ins(err,col);
92 syn[w+1]->wei=0;
93 int swei = one_csr_row_combine(syn[w+1],syn[w], mHT, col);
94 if(debug&64){
95 printf(" syn: ");
96 one_vec_print(syn[w+1]);
97 }
98 int result = 0;
99 int current_limit = w_limit;
100 if (p->min_w != INT_MAX && p->dW >= 0) {
101 current_limit = minint(w_limit, p->min_w + p->dW);
102 }
103 if (err->wei < current_limit){
104 if (swei){
105// if(swei <= (w_limit - err->wei)*max_col_wt){ /** reachable goal? */
106 result = start_CC_recurs(err,urr,syn,w_limit,max_col_wt,
107 mH,mHT,p);
108 if(result == 1)
109 return 1;
110// }
111 }
112 // swei == 0 means it is a degenerate vector
113 // do not go up in this case
114 }
115 else{ // wei >= current_limit
116 assert(err->wei == current_limit);
117 if(!swei){
118 if((!mL) ||
119 (sparse_syndrome_non_zero(mL, err->wei, err->vec))){
120 if(debug&32){
121 printf("swei=%d *** success ***\n",swei);
122 one_vec_print(err);
123 one_vec_print(syn[w+1]);
124 }
125 p->codewords = codeword_add_maybe(p, err->vec, err->wei);
126 if (p->maxC && p->num_cws >= p->maxC) {
127 return 1;
128 }
129 if (!p->outC && p->maxC == 0) {
130 return 1;
131 }
132 }
133 }
134 else if(swei <= smax){
135 if(debug&64){
136 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]);
137 }
138 //
139 errors = hash_add_maybe(syn[w+1],err,errors, p_swei, debug);
140 }
141 }
142 urr->wei--;
143 one_ordered_pos_del(err,col,pos);
144 if(debug&32){
145 printf("xerr: ");
146 one_vec_print(err);
147 }
148 }
149 }
150 }
151 if(debug&32)
152 printf("exiting CC recurs\n\n");
153 return 0;
154}
155
159int do_CC_dist(params_t * const p){
160 const csr_t * const mH = p->spaH;
161 const csr_t * const mL = p->spaL;
162 const int wmax = p->wmax;
163 const int noscan = p->noscan;
164 int *p_swei = p->swei;
165 const int smax = p->smax;
166 const int debug = p->debug;
167
168 const int nvar = mH->cols;
169
170 csr_t * const mHT = csr_transpose(NULL,mH);
171 if(debug&32){
172 if((mHT->cols<150)||(debug&2048))
173 csr_print(mHT,"HT");
174 }
175 int max_col_W = csr_max_row_wght(mHT);
176
177 one_vec_t *err = calloc(1, sizeof(one_vec_t)+sizeof(int)*wmax);
178 one_vec_t *urr = calloc(1, sizeof(one_vec_t)+sizeof(int)*wmax);
179 one_vec_t **syn = calloc(wmax+1, sizeof(one_vec_t *));
180 if((!syn) || (!err) || (!urr))
181 ERROR("memory allocation");
182 // err->max = wmax;
183 for(int i=0; i <= wmax; i++){
184 syn[i]=calloc(1, sizeof(one_vec_t)+sizeof(int)*mH->rows);
185 if(!syn[i]) ERROR("i=%d memory allocation",i);
186 // syn[i]->max = mH->rows;
187 }
188 int result = 0;
189 const int w_start = noscan ? wmax : (p->dmin > 1 ? p->dmin : 1);
190 int w_limit_dynamic = wmax;
191 if (p->dmax > 0) {
192 if (p->outC && p->dW > 0) {
193 w_limit_dynamic = minint(wmax > 0 ? wmax : p->dmax + p->dW, p->dmax + p->dW);
194 } else {
195 w_limit_dynamic = minint(wmax > 0 ? wmax : p->dmax, p->dmax);
196 }
197 }
198 for(int w=w_start; w <= w_limit_dynamic; w++){ /* cluster weight */
199 if (p->min_w != INT_MAX && p->dW >= 0) {
200 w_limit_dynamic = minint(wmax > 0 ? wmax : p->min_w + p->dW, p->min_w + p->dW);
201 }
202 if (w > w_limit_dynamic) {
203 break;
204 }
205 int beg = (p->cbeg >= 0) ? p->cbeg : 0;
206 int end = (p->cend >= 0) ? minint(p->cend, nvar - w) : nvar - w;
207 if(debug&2)
208 printf("# recursively searching for w=%d codewords wmax=%d beg=%d end=%d\n",w,wmax,beg,end);
209 for(int i = beg; i <= end; i++){ /* start column position */
211 err->vec[0] = urr->vec[0] = i;
212 err->wei = urr->wei = 1;
213 syn[1]->wei=0;
214 int swei = one_csr_row_combine(syn[1], syn[0], mHT, i);
215 if (w>1){
216 if (swei){
217 result = start_CC_recurs(err,urr,syn,w,max_col_W,mH,mHT,p);
218 if(result == 1)
219 break;
220 }
221 }
222 else{ // w==1
223 if(!swei){
224 if((!mL) ||
225 (sparse_syndrome_non_zero(mL, err->wei, err->vec))){
226 p->codewords = codeword_add_maybe(p, err->vec, err->wei);
227 if (p->maxC && p->num_cws >= p->maxC) {
228 result = 1;
229 break;
230 }
231 if (!p->outC && p->maxC == 0) {
232 result = 1;
233 break;
234 }
235 }
236 }
237 else if(swei <= smax)
238 errors = hash_add_maybe(syn[1],err,errors,p_swei, debug);
239 }
240 err->wei = urr->wei = 0;
241 }
242 if(result == 1)
243 break;
244
245 if (p->min_w > w && w < w_limit_dynamic) {
246 printf("-%d\n", w);
247 fflush(stdout);
248 } else if (p->min_w <= w && p->dW >= 0 && w <= w_limit_dynamic) {
249 if (debug & 1) {
250 fprintf(stderr, "# CC round w=%d finished: searched with dW=%d (min_w=%d, total %lld codewords)\n",
251 w, p->dW, p->min_w, p->num_cws);
252 }
253 }
254 }
255
256 if(result==1){
257 result = err->wei;
258#ifndef NDEBUG
259 assert( 0 == sparse_syndrome_non_zero(mH, err->wei, err->vec));
260 if(mL) assert(sparse_syndrome_non_zero(mL, err->wei, err->vec));
261#endif
262 if(debug&16){
263 printf("# wmax=%d found cw of weight %d: [",wmax,result);
264 int max = ((result<50) || (debug&2048)) ? result : 50 ;
265 for(int i=0; i< max; i++)
266 printf("%d%s",err->vec[i], i+1!=max?" ": (result==max ? "]\n" : "...]\n"));
267 }
268 }
269 else {
270 if (p->min_w <= wmax) {
271 result = p->min_w;
272 } else {
273 result = -wmax;
274 }
275 }
276
277 if(smax){
278 int skipped = 0;
279 if(debug){
280 for(int i=1;i<=wmax; i++) {
281 if(p_swei[i] <= mH->rows) {
282 printf("# w=%d min non-zero syndrome weight %d\n",i,p_swei[i]);
283 } else {
284 skipped = 1;
285 }
286 }
287 }
288 else{
289 printf("# confinement: ");
290 for(int i=1;i<=wmax; i++) {
291 if(p_swei[i] <= mH->rows) {
292 printf("%d%s",p_swei[i],i<wmax?",":"");
293 } else {
294 skipped = 1;
295 printf("?%s",i<wmax?",":"");
296 }
297 }
298 printf("\n");
299 }
300 if (skipped) {
301 printf("# Note: Some weights were skipped in confinement profile. Try increasing smax (current: %d)\n", smax);
302 }
303 }
304
305 for(int i=0; i<= wmax; i++)
306 free(syn[i]);
307 free(syn);
308 free(err);
309 free(urr);
310 csr_free(mHT);
311
313 two_vec_t *terr, *tmp;
314 HASH_ITER(hh, errors, terr, tmp) {
315 // two_vec_print(terr);
316 HASH_DEL(errors, terr);
317 free(terr);
318 }
319
320 return result;
321}
322
323
int do_CC_dist(params_t *const p)
Definition dist_cc.c:159
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:54
two_vec_t * errors
Definition dist_cc.c:39
int vec[0]
Definition util_hash.h:46
structure to hold two sparse vectors (syndrome,error) in a hash
Definition util_hash.h:25
int * p
Definition util_m4ri.h:115
int * i
Definition util_m4ri.h:116
int rows
Definition util_m4ri.h:111
int cols
Definition util_m4ri.h:112
long long int maxC
Definition util_io.h:64
int dmin
Definition util_io.h:42
int noscan
Definition util_io.h:48
csr_t * spaL
Definition util_io.h:79
char * outC
Definition util_io.h:67
csr_t * spaH
Definition util_io.h:77
int min_w
Definition util_io.h:70
int cbeg
Definition util_io.h:58
int smax
Definition util_io.h:37
int wmax
Definition util_io.h:41
int dmax
Definition util_io.h:43
int cend
Definition util_io.h:59
int dW
Definition util_io.h:65
int debug
Definition util_io.h:32
long long int num_cws
Definition util_io.h:69
cw_vec_t * codewords
Definition util_io.h:68
int swei[MAX_W]
int max_row_wt; /* WARNING: this is defined in util_io.h as static const int *‍/
Definition util_io.h:56
#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
params_t *const p
Definition util_io.c:52
cw_vec_t * codeword_add_maybe(params_t *const p, const int arr[], int weight)
Add a candidate codeword to the hash table if it meets weight limits.
Definition util_io.c:797
csr_t * csr_transpose(csr_t *dst, const csr_t *const p)
Transpose a compressed CSR sparse matrix.
Definition util_m4ri.c:133
void csr_print(const csr_t *const smat, const char str[])
Print a CSR matrix with a label string (formatted output).
Definition util_m4ri.c:576
csr_t * csr_free(csr_t *p)
Free memory allocated for a CSR sparse matrix.
Definition util_m4ri.c:459
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:115
#define ERROR(fmt,...)
Definition util_m4ri.h:13