/*---------------------------------------------------------------------------*/ void mult_booth(mpz_t M) { FILE *File; /* Si M = 0 */ if(mpz_cmp_ui(M,0)==0) add_operation_int(SETUI,label_var(1),NULL,0); /* Si M = 1 */ else if(mpz_cmp_ui(M,1)==0) add_operation_str(SET,label_var(1),NULL,label_var(0)); else { char *bits=NULL; int *booth_code; int num_bits; int len_code; /* On récupère l'écriture binaire de M et le nombre de bits */ num_bits = M_to_bit_array(M, &bits); /* on calcule le codage de booth de M */ len_code = M_to_Booth(bits, num_bits, &booth_code); generate_mult(booth_code, len_code); } /* On génère le programme */ File = fopen(FilePath,"wt"); generate(File, M, algo); fclose(File); }
/*-----------------------------------------------------------------------------*/ void tree_to_ops(tree_t tree, int var_res) { int i; char* var[2]; var[0] = label_var(1); var[1] = "tmp"; if(!mpz_cmp_ui(tree->M_red, 1)) { add_operation_str(SET, var[var_res], NULL, label_var(0)); if(tree->shift) add_operation_int(SHF, var[var_res], var[var_res], tree->shift); } else { for(i=3; i>0; i--) if(tree->node[i] && mpz_cmp_si(tree->node[i]->max_add, -1) != 0) break; switch(i) { case 0: tree_to_ops(tree->node[i], var_res); add_operation_str(ADD, var[var_res], var[var_res], label_var(0)); if(tree->shift) add_operation_int(SHF, var[var_res], var[var_res], tree->shift); break; case 1: tree_to_ops(tree->node[i], var_res); add_operation_str(SUB, var[var_res], var[var_res], label_var(0)); if(tree->shift) add_operation_int(SHF, var[var_res], var[var_res], tree->shift); break; case 2: tree_to_ops(tree->node[i], 1-var_res); add_operation_str(SET, var[var_res], NULL, var[1-var_res]); add_operation_int(SHF, var[1-var_res], var[1-var_res], tree->k); add_operation_str(ADD, var[var_res], var[var_res], var[1-var_res]); if(tree->shift) add_operation_int(SHF, var[var_res], var[var_res], tree->shift); break; case 3: tree_to_ops(tree->node[i], 1-var_res); add_operation_str(SET, var[var_res], NULL, var[1-var_res]); add_operation_int(SHF, var[var_res], var[var_res], tree->k); add_operation_str(SUB, var[var_res], var[var_res], var[1-var_res]); if(tree->shift) add_operation_int(SHF, var[var_res], var[var_res], tree->shift); break; } } }
/*---------------------------------------------------------------------------*/ void generate_mult(int *booth_code, int len_code) { int first_i,last_i,i; char *x = label_var(0); char *res = label_var(1); /* on cherche le premier bit de poids fort non nul */ i=0; while(i<len_code && booth_code[i]==0) i++; first_i=i; last_i=i; i++; while(i<len_code) { /* on cherche le prochain 1 */ while(i<len_code && booth_code[i]==0) i++; /* on quitte la boucle */ if(i==len_code) break; /* on décale de i-last_i */ add_operation_int(SHF,res,last_i==first_i?x:res,i-last_i); /* on ajoute 'x' à 'res' */ if(booth_code[i]<0) add_operation_str(SUB,res,res,x); else add_operation_str(ADD,res,res,x); last_i=i; i++; } /* en fin de génération, il ne faut pas oublier le dernier décalage */ /* qui peut ne pas avoir été fait si l'écriture binaire de M fini par des 0 */ if(i-last_i-1 != 0) /* on décale de i-last_i-1 */ add_operation_int(SHF,res,last_i==first_i?x:res,i-last_i-1); }
typename std::enable_if<is_dataset<Dataset>::value, real_type>::type accuracy(const dataset_type& ds) const { argument_type label = label_var(); real_type result(0); real_type weight(0); assignment_type a; F posterior; for (const auto& p : ds.assignments(arguments())) { joint(p.first, posterior); posterior.maximum(a); result += p.second * (a.at(label) == p.first[label]); weight += p.second; } return result / weight; }
/*---------------------------------------------------------------------------*/ void mult_bernstein(mpz_t M) { FILE *File; /* Si M = 0 */ if(mpz_cmp_ui(M,0)==0) add_operation_int(SETUI,label_var(1),NULL,0); else generate_mult(M); /* On génère le programme */ File = fopen(FilePath,"wt"); generate(File, M, algo); fclose(File); }