/** * aa_dfa_match - traverse @dfa to find state @str stops at * @dfa: the dfa to match @str against (NOT NULL) * @start: the state of the dfa to start matching in * @str: the null terminated string of bytes to match against the dfa (NOT NULL) * * aa_dfa_match will match @str against the dfa and return the state it * finished matching in. The final state can be used to look up the accepting * label, or as the start state of a continuing match. * * Returns: final state reached after input is consumed */ unsigned int aa_dfa_match(struct aa_dfa *dfa, unsigned int start, const char *str) { u16 *def = DEFAULT_TABLE(dfa); u32 *base = BASE_TABLE(dfa); u16 *next = NEXT_TABLE(dfa); u16 *check = CHECK_TABLE(dfa); unsigned int state = start; if (state == 0) return 0; /* current state is <state>, matching character *str */ if (dfa->tables[YYTD_ID_EC]) { /* Equivalence class table defined */ u8 *equiv = EQUIV_TABLE(dfa); /* default is direct to next state */ while (*str) match_char(state, def, base, next, check, equiv[(u8) *str++]); } else { /* default is direct to next state */ while (*str) match_char(state, def, base, next, check, (u8) *str++); } return state; }
unsigned int aa_dfa_next(struct aa_dfa *dfa, unsigned int state, const char c) { u16 *def = DEFAULT_TABLE(dfa); u32 *base = BASE_TABLE(dfa); u16 *next = NEXT_TABLE(dfa); u16 *check = CHECK_TABLE(dfa); unsigned int pos; if (dfa->tables[YYTD_ID_EC]) { u8 *equiv = EQUIV_TABLE(dfa); pos = base[state] + equiv[(u8) c]; if (check[pos] == state) state = next[pos]; else state = def[state]; } else { pos = base[state] + (u8) c; if (check[pos] == state) state = next[pos]; else state = def[state]; } return state; }
/** * aa_dfa_next - step one character to the next state in the dfa * @dfa: the dfa to tranverse (NOT NULL) * @state: the state to start in * @c: the input character to transition on * * aa_dfa_match will step through the dfa by one input character @c * * Returns: state reach after input @c */ unsigned int aa_dfa_next(struct aa_dfa *dfa, unsigned int state, const char c) { u16 *def = DEFAULT_TABLE(dfa); u32 *base = BASE_TABLE(dfa); u16 *next = NEXT_TABLE(dfa); u16 *check = CHECK_TABLE(dfa); unsigned int pos; /* current state is <state>, matching character *str */ if (dfa->tables[YYTD_ID_EC]) { /* Equivalence class table defined */ u8 *equiv = EQUIV_TABLE(dfa); /* default is direct to next state */ pos = base_idx(base[state]) + equiv[(u8) c]; if (check[pos] == state) state = next[pos]; else state = def[state]; } else { /* default is direct to next state */ pos = base_idx(base[state]) + (u8) c; if (check[pos] == state) state = next[pos]; else state = def[state]; } return state; }
/** * aa_dfa_next_state - traverse @dfa to find state @str stops at * @dfa: the dfa to match @str against * @start: the state of the dfa to start matching in * @str: the string to match against the dfa * * aa_dfa_next_state will match @str against the dfa and return the state it * finished matching in. The final state can be used to look up the accepting * label, or as the start state of a continuing match. */ unsigned int aa_dfa_next_state(struct aa_dfa *dfa, unsigned int start, const char *str) { u16 *def = DEFAULT_TABLE(dfa); u32 *base = BASE_TABLE(dfa); u16 *next = NEXT_TABLE(dfa); u16 *check = CHECK_TABLE(dfa); unsigned int state = start, pos; if (state == 0) return 0; /* current state is <state>, matching character *str */ if (dfa->tables[YYTD_ID_EC - 1]) { u8 *equiv = EQUIV_TABLE(dfa); while (*str) { pos = base[state] + equiv[(u8)*str++]; if (check[pos] == state) state = next[pos]; else state = def[state]; } } else { while (*str) { pos = base[state] + (u8)*str++; if (check[pos] == state) state = next[pos]; else state = def[state]; } } return state; }
/** * verify_dfa - verify that all the transitions and states in the dfa tables * are in bounds. * @dfa: dfa to test (NOT NULL) * @flags: flags controlling what type of accept table are acceptable * * Assumes dfa has gone through the first pass verification done by unpacking * NOTE: this does not valid accept table values * * Returns: %0 else error code on failure to verify */ static int verify_dfa(struct aa_dfa *dfa, int flags) { size_t i, state_count, trans_count; int error = -EPROTO; /* check that required tables exist */ if (!(dfa->tables[YYTD_ID_DEF] && dfa->tables[YYTD_ID_BASE] && dfa->tables[YYTD_ID_NXT] && dfa->tables[YYTD_ID_CHK])) goto out; /* accept.size == default.size == base.size */ state_count = dfa->tables[YYTD_ID_BASE]->td_lolen; if (ACCEPT1_FLAGS(flags)) { if (!dfa->tables[YYTD_ID_ACCEPT]) goto out; if (state_count != dfa->tables[YYTD_ID_ACCEPT]->td_lolen) goto out; } if (ACCEPT2_FLAGS(flags)) { if (!dfa->tables[YYTD_ID_ACCEPT2]) goto out; if (state_count != dfa->tables[YYTD_ID_ACCEPT2]->td_lolen) goto out; } if (state_count != dfa->tables[YYTD_ID_DEF]->td_lolen) goto out; /* next.size == chk.size */ trans_count = dfa->tables[YYTD_ID_NXT]->td_lolen; if (trans_count != dfa->tables[YYTD_ID_CHK]->td_lolen) goto out; /* if equivalence classes then its table size must be 256 */ if (dfa->tables[YYTD_ID_EC] && dfa->tables[YYTD_ID_EC]->td_lolen != 256) goto out; if (flags & DFA_FLAG_VERIFY_STATES) { for (i = 0; i < state_count; i++) { if (DEFAULT_TABLE(dfa)[i] >= state_count) goto out; /* TODO: do check that DEF state recursion terminates */ if (BASE_TABLE(dfa)[i] >= trans_count + 256) goto out; } for (i = 0; i < trans_count; i++) { if (NEXT_TABLE(dfa)[i] >= state_count) goto out; if (CHECK_TABLE(dfa)[i] >= state_count) goto out; } } error = 0; out: return error; }
/** * verify_dfa - verify that all the transitions and states in the dfa tables * are in bounds. * @dfa: dfa to test * * assumes dfa has gone through the verification done by unpacking */ int verify_dfa(struct aa_dfa *dfa) { size_t i, state_count, trans_count; int error = -EPROTO; /* check that required tables exist */ if (!(dfa->tables[YYTD_ID_ACCEPT -1 ] && dfa->tables[YYTD_ID_DEF - 1] && dfa->tables[YYTD_ID_BASE - 1] && dfa->tables[YYTD_ID_NXT - 1] && dfa->tables[YYTD_ID_CHK - 1])) goto out; /* accept.size == default.size == base.size */ state_count = dfa->tables[YYTD_ID_BASE - 1]->td_lolen; if (!(state_count == dfa->tables[YYTD_ID_DEF - 1]->td_lolen && state_count == dfa->tables[YYTD_ID_ACCEPT - 1]->td_lolen)) goto out; /* next.size == chk.size */ trans_count = dfa->tables[YYTD_ID_NXT - 1]->td_lolen; if (trans_count != dfa->tables[YYTD_ID_CHK - 1]->td_lolen) goto out; /* if equivalence classes then its table size must be 256 */ if (dfa->tables[YYTD_ID_EC - 1] && dfa->tables[YYTD_ID_EC - 1]->td_lolen != 256) goto out; for (i = 0; i < state_count; i++) { if (DEFAULT_TABLE(dfa)[i] >= state_count) goto out; if (BASE_TABLE(dfa)[i] >= trans_count + 256) goto out; } for (i = 0; i < trans_count ; i++) { if (NEXT_TABLE(dfa)[i] >= state_count) goto out; if (CHECK_TABLE(dfa)[i] >= state_count) goto out; } /* verify accept permissions */ for (i = 0; i < state_count; i++) { int mode = ACCEPT_TABLE(dfa)[i]; if (mode & ~AA_VALID_PERM_MASK) { goto out; } } error = 0; out: return error; }
/** * verify_dfa - verify that transitions and states in the tables are in bounds. * @dfa: dfa to test (NOT NULL) * * Assumes dfa has gone through the first pass verification done by unpacking * NOTE: this does not valid accept table values * * Returns: %0 else error code on failure to verify */ static int verify_dfa(struct aa_dfa *dfa) { size_t i, state_count, trans_count; int error = -EPROTO; state_count = dfa->tables[YYTD_ID_BASE]->td_lolen; trans_count = dfa->tables[YYTD_ID_NXT]->td_lolen; for (i = 0; i < state_count; i++) { if (!(BASE_TABLE(dfa)[i] & MATCH_FLAG_DIFF_ENCODE) && (DEFAULT_TABLE(dfa)[i] >= state_count)) goto out; if (base_idx(BASE_TABLE(dfa)[i]) + 255 >= trans_count) { pr_err("AppArmor DFA next/check upper bounds error\n"); goto out; } } for (i = 0; i < trans_count; i++) { if (NEXT_TABLE(dfa)[i] >= state_count) goto out; if (CHECK_TABLE(dfa)[i] >= state_count) goto out; } /* Now that all the other tables are verified, verify diffencoding */ for (i = 0; i < state_count; i++) { size_t j, k; for (j = i; (BASE_TABLE(dfa)[j] & MATCH_FLAG_DIFF_ENCODE) && !(BASE_TABLE(dfa)[j] & MARK_DIFF_ENCODE); j = k) { k = DEFAULT_TABLE(dfa)[j]; if (j == k) goto out; if (k < j) break; /* already verified */ BASE_TABLE(dfa)[j] |= MARK_DIFF_ENCODE; } } error = 0; out: return error; }
/** * aa_dfa_next - step one character to the next state in the dfa * @dfa: the dfa to tranverse (NOT NULL) * @state: the state to start in * @c: the input character to transition on * * aa_dfa_match will step through the dfa by one input character @c * * Returns: state reach after input @c */ unsigned int aa_dfa_next(struct aa_dfa *dfa, unsigned int state, const char c) { u16 *def = DEFAULT_TABLE(dfa); u32 *base = BASE_TABLE(dfa); u16 *next = NEXT_TABLE(dfa); u16 *check = CHECK_TABLE(dfa); /* current state is <state>, matching character *str */ if (dfa->tables[YYTD_ID_EC]) { /* Equivalence class table defined */ u8 *equiv = EQUIV_TABLE(dfa); match_char(state, def, base, next, check, equiv[(u8) c]); } else match_char(state, def, base, next, check, (u8) c); return state; }
bool bf_core_m::htab::cuckold(bucket* dest, bucket* src, int which, int hashfunc, bfcb_t* &moved) { ADD_BFSTAT(_slots_tried, 1); if(dest->_count < SLOT_COUNT) { ADD_BFSTAT(_cuckolds, 1); // dest has room // Order the lock-grabbing to avoid deadlock bucket* b1 = (src < dest)? src : dest; bucket* b2 = (src < dest)? dest : src; CRITICAL_SECTION(cs1, b1->_lock); CRITICAL_SECTION(cs2, b2->_lock); if(src->_count < SLOT_COUNT) { // src now has room - don't do anything after all return true; } if(dest->_count < SLOT_COUNT) { // good to go : dest still has room. // Copy over src, update slot _count bfcb_t *b; dest->_slots[dest->_count++] = b = src->_slots[which]; b->set_hash_func(hashfunc); b->set_hash(dest-_table); // adjust dest hash info while we have the locks. // // compress src, update slot _count src->_slots[which] = src->_slots[--src->_count]; moved = src->_slots[which]; CHECK_ENTRY(src-_table, true); CHECK_ENTRY(dest-_table, true); return true; } } CHECK_TABLE(); return false; // possibly stale }
/** * aa_dfa_matchn_until - traverse @dfa until accept or @n bytes consumed * @dfa: the dfa to match @str against (NOT NULL) * @start: the state of the dfa to start matching in * @str: the string of bytes to match against the dfa (NOT NULL) * @n: length of the string of bytes to match * @retpos: first character in str after match OR str + n * * aa_dfa_match_len will match @str against the dfa and return the state it * finished matching in. The final state can be used to look up the accepting * label, or as the start state of a continuing match. * * This function will happily match again the 0 byte and only finishes * when @n input is consumed. * * Returns: final state reached after input is consumed */ unsigned int aa_dfa_matchn_until(struct aa_dfa *dfa, unsigned int start, const char *str, int n, const char **retpos) { u16 *def = DEFAULT_TABLE(dfa); u32 *base = BASE_TABLE(dfa); u16 *next = NEXT_TABLE(dfa); u16 *check = CHECK_TABLE(dfa); u32 *accept = ACCEPT_TABLE(dfa); unsigned int state = start, pos; *retpos = NULL; if (state == 0) return 0; /* current state is <state>, matching character *str */ if (dfa->tables[YYTD_ID_EC]) { /* Equivalence class table defined */ u8 *equiv = EQUIV_TABLE(dfa); /* default is direct to next state */ for (; n; n--) { pos = base_idx(base[state]) + equiv[(u8) *str++]; if (check[pos] == state) state = next[pos]; else state = def[state]; if (accept[state]) break; } } else { /* default is direct to next state */ for (; n; n--) { pos = base_idx(base[state]) + (u8) *str++; if (check[pos] == state) state = next[pos]; else state = def[state]; if (accept[state]) break; } } *retpos = str; return state; }
unsigned int aa_dfa_match_len(struct aa_dfa *dfa, unsigned int start, const char *str, int len) { u16 *def = DEFAULT_TABLE(dfa); u32 *base = BASE_TABLE(dfa); u16 *next = NEXT_TABLE(dfa); u16 *check = CHECK_TABLE(dfa); unsigned int state = start, pos; if (state == 0) return 0; if (dfa->tables[YYTD_ID_EC]) { u8 *equiv = EQUIV_TABLE(dfa); for (; len; len--) { pos = base[state] + equiv[(u8) *str++]; if (check[pos] == state) state = next[pos]; else state = def[state]; } } else { for (; len; len--) { pos = base[state] + (u8) *str++; if (check[pos] == state) state = next[pos]; else state = def[state]; } } return state; }
/** * aa_dfa_match_len - traverse @dfa to find state @str stops at * @dfa: the dfa to match @str against (NOT NULL) * @start: the state of the dfa to start matching in * @str: the string of bytes to match against the dfa (NOT NULL) * @len: length of the string of bytes to match * * aa_dfa_match_len will match @str against the dfa and return the state it * finished matching in. The final state can be used to look up the accepting * label, or as the start state of a continuing match. * * This function will happily match again the 0 byte and only finishes * when @len input is consumed. * * Returns: final state reached after input is consumed */ unsigned int aa_dfa_match_len(struct aa_dfa *dfa, unsigned int start, const char *str, int len) { u16 *def = DEFAULT_TABLE(dfa); u32 *base = BASE_TABLE(dfa); u16 *next = NEXT_TABLE(dfa); u16 *check = CHECK_TABLE(dfa); unsigned int state = start, pos; if (state == 0) return 0; /* current state is <state>, matching character *str */ if (dfa->tables[YYTD_ID_EC]) { /* Equivalence class table defined */ u8 *equiv = EQUIV_TABLE(dfa); /* default is direct to next state */ for (; len; len--) { pos = base[state] + equiv[(u8) *str++]; if (check[pos] == state) state = next[pos]; else state = def[state]; } } else { /* default is direct to next state */ for (; len; len--) { pos = base[state] + (u8) *str++; if (check[pos] == state) state = next[pos]; else state = def[state]; } } return state; }
static unsigned int leftmatch_fb(struct aa_dfa *dfa, unsigned int start, const char *str, struct match_workbuf *wb, unsigned int *count) { u16 *def = DEFAULT_TABLE(dfa); u32 *base = BASE_TABLE(dfa); u16 *next = NEXT_TABLE(dfa); u16 *check = CHECK_TABLE(dfa); unsigned int state = start, pos; AA_BUG(!dfa); AA_BUG(!str); AA_BUG(!wb); AA_BUG(!count); *count = 0; if (state == 0) return 0; /* current state is <state>, matching character *str */ if (dfa->tables[YYTD_ID_EC]) { /* Equivalence class table defined */ u8 *equiv = EQUIV_TABLE(dfa); /* default is direct to next state */ while (*str) { unsigned int adjust; wb->history[wb->pos] = state; pos = base_idx(base[state]) + equiv[(u8) *str++]; if (check[pos] == state) state = next[pos]; else state = def[state]; if (is_loop(wb, state, &adjust)) { state = aa_dfa_match(dfa, state, str); *count -= adjust; goto out; } inc_wb_pos(wb); (*count)++; } } else { /* default is direct to next state */ while (*str) { unsigned int adjust; wb->history[wb->pos] = state; pos = base_idx(base[state]) + (u8) *str++; if (check[pos] == state) state = next[pos]; else state = def[state]; if (is_loop(wb, state, &adjust)) { state = aa_dfa_match(dfa, state, str); *count -= adjust; goto out; } inc_wb_pos(wb); (*count)++; } } out: if (!state) *count = 0; return state; }
/************************************************************************* * Scatter plot */ int NumstatHandleSplotI(NUMSTAT *nsPO) { int i,r,c,nrow,ncol; DOUB fD,sD; char labS[DEF_BS],numS[DEF_BS],formS[DEF_BS]; HISTOGRAM *fhisPO, *shisPO; TABLE *tabPO; NumlistToHistogramI(nsPO->vals, -1.0, BAD_D, BAD_D, &fhisPO); NumlistToHistogramI(nsPO->svals, -1.0, BAD_D, BAD_D, &shisPO); ncol = GetHistogramNumBinsI(fhisPO); nrow = GetHistogramNumBinsI(shisPO); tabPO = CreateTablePO(nrow, ncol); if(!tabPO) { CHECK_HISTOGRAM(fhisPO); CHECK_HISTOGRAM(shisPO); return(FALSE); } /*** * Set lables */ HistogramAutoFormatStringI(fhisPO,formS); for(c=0;c<ncol;c++) { HistogramValuesForBinI(fhisPO, c, NULL, &fD, NULL); sprintf(numS,formS,fD); sprintf(labS,"C_%s",numS); ReplaceChars(' ',labS,'_',labS); SetTableColLabI(tabPO,c,labS); } HistogramAutoFormatStringI(shisPO,formS); for(r=0; r<nrow; r++) { HistogramValuesForBinI(shisPO, r, NULL, &fD, NULL); sprintf(numS,formS,fD); sprintf(labS,"Row_%s",numS); ReplaceChars(' ',labS,'_',labS); /* HAM? Why -2 * SetTableRowLabI(tabPO,nrow - r -2,labS); */ SetTableRowLabI(tabPO,nrow - r -1,labS); } /*** * Fill table values */ for(i=0; i<nsPO->num; i++) { GetNumlistDoubI(nsPO->vals,i,&fD); GetNumlistDoubI(nsPO->svals,i,&sD); HistogramBinForValueI(fhisPO, fD, &c, NULL,NULL); HistogramBinForValueI(shisPO, sD, &r, NULL,NULL); /* HAM? Why -2 * r = nrow - r - 2; */ r = nrow - r - 1; GetTableValI(tabPO,r,c,&fD); fD += 1.0; SetTableValI(tabPO,r,c,fD); } fprintf(nsPO->out,"%s#\n",nsPO->echo); AutoTableOutFormattingI(tabPO, TRUE, FALSE); DumpTable(tabPO,FALSE,FALSE,nsPO->out); /*** * Clean up */ CHECK_TABLE(tabPO); CHECK_HISTOGRAM(fhisPO); CHECK_HISTOGRAM(shisPO); return(TRUE); }
static int verify_dfa(struct aa_dfa *dfa, int flags) { size_t i, state_count, trans_count; int error = -EPROTO; if (!(dfa->tables[YYTD_ID_DEF] && dfa->tables[YYTD_ID_BASE] && dfa->tables[YYTD_ID_NXT] && dfa->tables[YYTD_ID_CHK])) goto out; state_count = dfa->tables[YYTD_ID_BASE]->td_lolen; if (ACCEPT1_FLAGS(flags)) { if (!dfa->tables[YYTD_ID_ACCEPT]) goto out; if (state_count != dfa->tables[YYTD_ID_ACCEPT]->td_lolen) goto out; } if (ACCEPT2_FLAGS(flags)) { if (!dfa->tables[YYTD_ID_ACCEPT2]) goto out; if (state_count != dfa->tables[YYTD_ID_ACCEPT2]->td_lolen) goto out; } if (state_count != dfa->tables[YYTD_ID_DEF]->td_lolen) goto out; trans_count = dfa->tables[YYTD_ID_NXT]->td_lolen; if (trans_count != dfa->tables[YYTD_ID_CHK]->td_lolen) goto out; if (dfa->tables[YYTD_ID_EC] && dfa->tables[YYTD_ID_EC]->td_lolen != 256) goto out; if (flags & DFA_FLAG_VERIFY_STATES) { for (i = 0; i < state_count; i++) { if (DEFAULT_TABLE(dfa)[i] >= state_count) goto out; if (BASE_TABLE(dfa)[i] + 255 >= trans_count) { printk(KERN_ERR "AppArmor DFA next/check upper " "bounds error\n"); goto out; } } for (i = 0; i < trans_count; i++) { if (NEXT_TABLE(dfa)[i] >= state_count) goto out; if (CHECK_TABLE(dfa)[i] >= state_count) goto out; } } error = 0; out: return error; }
int NumlistMutInfoI(NUMLIST *nums1PO, NUMLIST *nums2PO, int maxb, DOUB *minfPD, int *nb1PI, int *nb2PI) { int i,r,c,n,nrow,ncol,dis_bin; DOUB vD, bin1D, bin2D, st1D, st2D, en1D, en2D, infoD; HISTOGRAM *his1PO, *his2PO; TABLE *tabPO; DB_MINF DB_PrI(">> NumlistMutInfoI maxb=%d\n",maxb); VALIDATE(nums1PO,NUMLIST_ID); VALIDATE(nums2PO,NUMLIST_ID); if( !NumlistSameLenI(nums1PO,nums2PO) ) { DB_MINF DB_PrI("<< NumlistMutInfoI not same len FALSE\n"); return(FALSE); } n = GetNumlistLengthI(nums1PO); DB_MINF DB_PrI("+ number lists %d long\n",n); /*** * Get histograms from number lists */ dis_bin = FALSE; NumlistNaturalHistBinI(nums1PO, maxb, dis_bin, &bin1D, &st1D, &en1D); NumlistNaturalHistBinI(nums2PO, maxb, dis_bin, &bin2D, &st2D, &en2D); DB_MINF DB_PrI("+ Hist1 bin=%f st=%f en=%f\n",bin1D,st1D,en1D); DB_MINF DB_PrI("+ Hist2 bin=%f st=%f en=%f\n",bin2D,st2D,en2D); his1PO = his2PO = NULL; NumlistToHistogramI(nums1PO, bin1D, st1D, en1D, &his1PO); NumlistToHistogramI(nums2PO, bin2D, st2D, en2D, &his2PO); if( (!his1PO) || (!his2PO) ) { CHECK_HISTOGRAM(his1PO); CHECK_HISTOGRAM(his2PO); DB_MINF DB_PrI("<< NumlistMutInfoI nums to histograms %p %p FALSE\n",his1PO,his2PO); return(FALSE); } nrow = GetHistogramNumBinsI(his1PO); ncol = GetHistogramNumBinsI(his2PO); DB_MINF DB_PrI("+ histogram bins nrow=%d ncol=%d\n",nrow,ncol); if( (nrow < 2) || (ncol < 2) ) { CHECK_HISTOGRAM(his1PO); CHECK_HISTOGRAM(his2PO); DB_MINF DB_PrI("<< NumlistMutInfoI not enough bins FALSE\n"); return(FALSE); } /*** * Allocate space */ tabPO = CreateTablePO(nrow, ncol); if( !tabPO ) { CHECK_HISTOGRAM(his1PO); CHECK_HISTOGRAM(his2PO); DB_MINF DB_PrI("<< NumlistMutInfoI failed table space FALSE\n"); return(FALSE); } /*** * Fill joint probabilities from pairwise screen of input data */ for(i=0;i<n;i++) { GetNumlistIntDoubI(nums1PO,i,NULL,&vD); HistogramBinForValueI(his1PO, vD, &r, NULL,NULL); GetNumlistIntDoubI(nums2PO,i,NULL,&vD); HistogramBinForValueI(his2PO, vD, &c, NULL,NULL); GetTableValI(tabPO,r,c,&vD); vD += 1.0; SetTableValI(tabPO,r,c,vD); } DB_MINF { printf("\n xxxxxxxxxxxxxxxxxxxxxx\n"); DumpNumlist(his1PO->bins,-1,-1, NULL, NULL); DumpNumlist(his2PO->bins,-1,-1, NULL, NULL); AutoTableOutFormattingI(tabPO,TRUE,TRUE); DumpTable(tabPO,TRUE,FALSE,NULL); } /*** * Now the info */ infoD = 0.0; for(r=0;r<nrow;r++) { GetNumlistIntDoubI(his1PO->bins,r,NULL,&bin1D); bin1D = bin1D / DNUM(n); for(c=0;c<ncol;c++) { GetTableValI(tabPO,r,c,&vD); if(vD == 0.0) { continue; } vD = vD / DNUM(n); GetNumlistIntDoubI(his2PO->bins,c,NULL,&bin2D); bin2D = bin2D / DNUM(n); /* printf("[%d][%d]\tbin1=%f\tbin2=%f\tv=%f",r,c,bin1D,bin2D,vD); */ vD = vD * LOG_2(vD / (bin1D * bin2D)); infoD += vD; /* printf("\tV=%f\tinfo=%f\n",vD,infoD); */ SetTableValI(tabPO,r,c,vD); } } DB_MINF { AutoTableOutFormattingI(tabPO,TRUE,TRUE); DumpTable(tabPO,TRUE,FALSE,NULL); } DB_MINF DB_PrI("+ info = %f\n",infoD); /*** * Set values and clean up */ if(nb1PI) { *nb1PI = nrow; } if(nb2PI) { *nb2PI = ncol; } if(minfPD) { *minfPD = infoD; } CHECK_TABLE(tabPO); CHECK_HISTOGRAM(his1PO); CHECK_HISTOGRAM(his2PO); DB_MINF DB_PrI("<< NumlistMutInfoI TRUE\n"); return(TRUE); }