Example #1
0
/**
 * 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;
}
Example #3
0
/**
 * 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;
}
Example #4
0
/**
 * 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;
}
Example #5
0
/**
 * 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;
}
Example #6
0
/**
 * 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;
}
Example #7
0
/**
 * 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;
}
Example #8
0
/**
 * 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;
}
Example #9
0
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
}
Example #10
0
/**
 * 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;
}
Example #12
0
/**
 * 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;
}
Example #13
0
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;
}
Example #14
0
/*************************************************************************
*   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;
}
Example #16
0
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);
}