⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cmac.cpp

📁 CMAC小脑模型神经网络的具体实现算法。
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include <stdlib.h>
#include <fcntl.h>
#include <io.h>
#include <sys\stat.h>
#include <malloc.h>

#include "unh_cmac.h"

#define TRUE  1
#define FALSE  0

#define NUM_CMACS 8
#define MAX_STATE_SIZE 64 
#define MAX_RESPONSE_SIZE 8 
#define MAX_GEN_SIZE 256 
#define RF_TABLE_SIZE 128 

static int first_call=TRUE; 		/* is set to FALSE after init      */
static int in_learn=FALSE;			/* is set to TRUE while in learn  */
static int *ap_a[NUM_CMACS+1];		/* pointers to all cmac memories   */
static int *ap;						/* pointer to current cmac memory  */
static int ap_size[NUM_CMACS+1];	/* sizes in bytes of cmac memories */
static int rsp_size;          		/* dimension of response vector    */
static int gen_size;          		/* generalization parameter        */
static int st_size;           		/* dimension of input state vector */
static int mem_size;          		/* # of response vectors in memory */ 
static int rf_shape;				/* code for the receptive field shape */
static int collide;					/* TRUE/FALSE control of hash collisions */
static int *qnt;					/* pointer to input quantization   */
static int *disp;					/* pointer to the displacement vector */
static int *rfieldt;				/* pointer to the rfield function table */
static unsigned int rndseq[2048];	/* Random number table for hashing */
static unsigned int rndseq2[2048];	/* Random number table for hashing */
static int indexes[MAX_GEN_SIZE];	/* CMAC mapping indexes            */
static long rfield[MAX_GEN_SIZE];	/* RF function magnitudes */
static long sum_rfield = 0;			/* summed RF function magnitudes */
static long sum2_rfield = 0;		/* summed squared RF function magnitudes */

static void stoap(int *state)
{
	int i,j,k;
	long index,min_d,test_d,rf_index;
	long sum;
	int hash_tag;
	static long base[MAX_STATE_SIZE],qstate[MAX_STATE_SIZE];

	if((rf_shape==ALBUS)||(rf_shape==RECTANGULAR)) 
	{
		for(i=0;i<st_size;i++) 
		{
			if(state[i]>=0) 
			{
				qstate[i]=state[i]/qnt[i];
			} 
			else 
			{
				qstate[i]=(state[i]-qnt[i]+1)/qnt[i];
			}
			base[i]=0;
		}

	    for(j=0;j<gen_size;j++) 
		{
			sum = 0;
			hash_tag = 0;
			 
		    for(i=0;i<st_size;i++) 
			{ 
		    	if(qstate[i]>=base[i])
	        		index=qstate[i]-((qstate[i]-base[i])%gen_size);
	        	else
    				index=(qstate[i]+1)+((base[i]-(qstate[i]+1))%gen_size)-gen_size;

			 	index+=(449*i);
	            index%=2048;
	            while(index<0) 
					index+=2048;

			 	sum+=(long)rndseq[(int)index];
			 	if(!collide) 
					hash_tag+=(int)rndseq2[(int)index];
				 	
			 	base[i]+=disp[i];

			}
			if(hash_tag==0) 
				hash_tag=1;

		    indexes[j]=(int)(sum%mem_size);
		    while(indexes[j]<0) 
				indexes[j]+=mem_size; 
		    
		    if(!collide) 
			{
				--indexes[j];
				k=0;
			    i=(indexes[j]*(rsp_size+1))+rsp_size;
			    do 
				{
			    	if(++indexes[j]>=mem_size) 
					{
			    		indexes[j]=0;
			    		i=rsp_size;
			    	} 
					else 
					{
			    		i+=rsp_size+1;
			    	}
				}while((ap[i]!=hash_tag)&&(ap[i]!=0)&&(++k<mem_size));
			} 
			else 
			{
			    i=(indexes[j]*(rsp_size+1))+rsp_size;
			}
   
			if((in_learn)&&(ap[i]==0)) 
				ap[i]=hash_tag;  
	    
		}

		return;
	}

	for(i = 0; i < st_size; i++)
	{
		if(state[i]>=0) 
		{
			qstate[i]=(long)(state[i] / qnt[i]);
		} 
		else 
		{
			qstate[i] = (long)((state[i] - qnt[i] + 1) / qnt[i]);
		}
		base[i] = 0; /* first RF layer aligned with origen */
	}

	/* init RF function sums */
	
	sum_rfield = 0;
	sum2_rfield = 0;

	/* compute a new hashed RF index for each RF layer */
    for (j = 0; j < gen_size; j++) 
	{
	
		sum = 0;
		hash_tag = 0;
		min_d = (long)1 << ((8 * sizeof(long)) - 2);
		
		/* loop over all dimensions of this RF */
	    for (i = 0; i < st_size; i++) 
		{

	    	/* find corner coordinate of excited RF in quantized space */ 
	    	if (qstate[i] >= base[i])
        		index = qstate[i] - ((qstate[i] - base[i]) % gen_size);
        	else
    			index = (qstate[i] + 1) + ((base[i] - (qstate[i] + 1)) % gen_size) - gen_size;
			 	
            /* update physical distance to closest side of RF, 
               and index into RF function table */
            test_d = (long)state[i] - (index * (long)qnt[i]);
            if (test_d < min_d) 
			{
            	min_d = test_d;
            	rf_index = (RF_TABLE_SIZE * min_d) / ((gen_size * qnt[i]) >> 1);
            }
            test_d = (((long)gen_size + index) * (long)qnt[i]) - state[i] - 1;
            if (test_d < min_d) 
			{
            	min_d = test_d;
            	rf_index = (RF_TABLE_SIZE * min_d) / ((gen_size * qnt[i]) >> 1);
            }
	            
        	/* add table offset for this dimension and wrap around */
		 	index += (449 * i);
            index %= 2048;
            while (index < 0) 
				index += 2048;
	
			/* add selected random number to sum */
		 	sum += (long)rndseq[(int)index];
			if (!collide) 
				hash_tag += (int)rndseq2[(int)index];

		 	/* compute displacement of next RF layer in quantized space */
		 	base[i] += disp[i];

		}
		if (hash_tag == 0) hash_tag = 1;
	
	    /* compute psuedo-random index */
	    indexes[j] = (int)(sum % mem_size);
	    while (indexes[j] < 0) 
			indexes[j] += mem_size;

	    /* now search for hash tag match or open slot */
		if (!collide) 
		{
			--indexes[j];
			k = 0;
		    i = (indexes[j] * (rsp_size + 1)) + rsp_size;
		    do 
			{
		    	if (++indexes[j] >= mem_size) 
				{
		    		indexes[j] = 0;
		    		i = rsp_size;
		    	} 
				else 
				{
		    		i += rsp_size + 1;
		    	}
			} while ((ap[i] != hash_tag) && (ap[i] != 0) && (++k < mem_size));
		} 
		else 
		{
		    i = (indexes[j] * (rsp_size + 1)) + rsp_size;
		}

		/* mark used memory location */	    
		if ((in_learn) && (ap[i] == 0)) 
			ap[i] = hash_tag;  

	    /* update RF function parameters */
	    if (rf_index >= RF_TABLE_SIZE) 
			rf_index = RF_TABLE_SIZE - 1;
	    rfield[j] = rfieldt[rf_index];
	    sum_rfield += rfieldt[rf_index];
	    sum2_rfield += ((long)rfieldt[rf_index] * (long)rfieldt[rf_index]);
	}
}

static void setup(int cmac_id)
{
	ap=ap_a[cmac_id];     /* pointer to cmac storage         */
	st_size=*ap++;        /* size of input state vector      */
	rsp_size=*ap++;       /* dimension of response vector    */
	gen_size=*ap++;       /* generalization parameter        */
	mem_size=*ap++;       /* # of response vectors in memory */
	rf_shape=*ap++;		/* receptive field code 		   */
	collide=*ap++;		/* allow hashing collisions	???    */
	qnt=ap;               /* pointer to quantization vector  */
	ap+=st_size;
	disp=ap;				/* pointer to displacement vector  */
	ap+=st_size;
	rfieldt=ap;			/* pointer to rf function table    */
	ap+=RF_TABLE_SIZE;	/* pointer to CMAC weights         */  		
}

static void genmap(void)
{
	int i, k;
	srand(1);

	for(k=0;k<2048;k++) 
	{
		rndseq[k]=0;
		for(i=0;i<sizeof(int);++i)
	    	rndseq[k]=(rndseq[k]<<8)|(rand()&0xff);    
	}

	for(k=0;k<2048;k++) 
	{
		rndseq2[k] = 0;
		for(i=0;i<sizeof(int);++i)
	    	rndseq2[k]=(rndseq2[k]<<8)|(rand()&0xff);    
	}
}

/***************************************************************************
 *      Purpose:        Initialize lattice displacement vector             *
 ***************************************************************************/


static void init_disp_vector(int dv[],int num_state,int field_shape)
{
	int i;
	
	if(field_shape==ALBUS) 
	{
		for(i=0;i<num_state;++i) 
			dv[i]=1;
	} 
	else 
	{
		for(i=0;i<num_state;++i) 
			dv[i]=1+(2*i);
	}
}

static void init_rfield_table(int rf[],int table_size,int field_shape)
{
	int i;
	long il;

	/* set default constant field magnitude */	
	for (i=0; i<table_size; ++i) rf[i] = 1;
			
	/* now handle special non-constant cases */
	if (field_shape == LINEAR) 
	{
		for (i=0; i<table_size; ++i) 
			rf[i] = (i + 1);
	}

	/* now handle special non-constant cases */
	if (field_shape == SPLINE) 
	{
		for (i=0; i<table_size; ++i) 
		{ 
			il = (long)(i + 1);
			rf[i] = (int)((((long)-2 * il * il * il) + ((long)3  * il * il * (long)table_size)) 
					/ (long)table_size / (long)table_size); 
		}
	}
}

//分配内存,初始化CMAC的参数//
int allocate_cmac(int num_state,int *qnt_state,int num_resp,
				int num_cell,int memory,int field_shape, int collide_flag)
{
	int i,j;
	int *pntr;

	/* initialize data structures on first call to driver */

	if (first_call) 
	{
		genmap();
		for (i = 0; i <= NUM_CMACS; i++) 
			ap_a[i] = 0;
		first_call = FALSE;
	}

	/* find an empty id */

	for (i = 1; i <= NUM_CMACS; i++) if (ap_a[i] == 0) break;
	if (i > NUM_CMACS) return(FALSE);  /* return 0 for no more cmacs */

	/* allocate CMAC storage */

	ap_size[i] = ((memory * (num_resp + 1)) + num_state + num_state + RF_TABLE_SIZE + 6) * sizeof(int);
	if (ap_a[i] = (int *)malloc(ap_size[i])) 
	{
		pntr = ap_a[i];
		*pntr++ = num_state;        /* size of input state vector      	*/
		*pntr++ = num_resp;         /* dimension of response vector    	*/
		*pntr++ = num_cell;         /* generalization parameter        	*/
		*pntr++ = memory;           /* # of response vectors in memory 	*/ 
		*pntr++ = field_shape;		/* receptive field code				*/
		*pntr++ = collide_flag;		/* hashing collisions flag			*/
		for (j = 0; j < num_state; ++j)
		    *pntr++ = qnt_state[j]; /* input vector quantization 		*/
		init_disp_vector(pntr, num_state, field_shape); /* displacement vector */
		pntr += num_state;
		init_rfield_table(pntr, RF_TABLE_SIZE, field_shape); /* RF function */
		return(i);                  /* return cmac id number */
	} 
	else 
	{
		return(FALSE);
	}
}

int train_cmac(int cmac_id,int *state,int *respns,int beta1,int beta2)
{
	int i, j, *weights;
	static long sum[MAX_RESPONSE_SIZE], error[MAX_RESPONSE_SIZE];
	static long delta1[MAX_RESPONSE_SIZE], delta2;

	if ((cmac_id < 1)|(cmac_id > NUM_CMACS)|(ap_a[cmac_id] == 0))
		return(FALSE);  /* reject bad ID */ 
		
	in_learn = TRUE;

	setup(cmac_id);  	/* init CMAC parameters */

	stoap(state);  	/* generate indices into ap[][] */

	for (j = 0; j < rsp_size; j++) 
	{
		sum[j] = 0;
		delta1[j] = 0;
	}
	delta2 = 0;
	
	/* Process CMACs with rectangular RF field functions */
	
	if ((rf_shape == ALBUS) || (rf_shape == RECTANGULAR)) 
	{
	
		for (i = 0; i < gen_size; i++) 
		{
			
			/* point to the weight vector for this RF */
						
			weights = &ap[indexes[i] * (rsp_size + 1)];
					
	        /* compute the experience sum */
		
	    	for (j = 0; j < rsp_size; j++)
				sum[j] += (long)weights[j];
		}
	
	    for (j = 0; j < rsp_size; j++)
			sum[j] /= gen_size;
				
    	/* compute adjustment due to reponse error */

		if (beta1 < 32) 
		{
	    	for (j = 0; j < rsp_size; j++) 
			{
				delta1[j] = ((long)respns[j] - sum[j]);
				if (delta1[j] >= 0)
					delta1[j] >>= beta1;
				else
					delta1[j] = -((-delta1[j])>>beta1);
		    	if (delta1[j] == 0) 
				{
					if ((long)respns[j] > sum[j]) 
					{
		        		delta1[j] = 1;
					} 
					else if ((long)respns[j] < sum[j]) 
					{
		        		delta1[j] = -1;
		        	}
				}
			}
		}

		/* adjust all weights of all RFs for response */
	
		for (i = 0; i < gen_size; i++) 
		{

			weights = &ap[indexes[i] * (rsp_size + 1)];
			for (j = 0; j < rsp_size; j++) 
			{
	    	
    			/* compute weight normalization adjustment */
	
				if (beta2 < 32) 
				{
					delta2 = (long)(respns[j] - weights[j]);
					if (delta2 >= 0)
						delta2 = (delta2 >> beta2);
					else
						delta2 = -((-delta2) >> beta2);
				} 
				
				/* adjust the weight */
					
				weights[j] += (int)delta1[j] + (int)delta2;
			}
		}
		
		in_learn = FALSE;
		return(TRUE);
	
	} 
	
	/* Process CMACs with non-rectangular RF field functions */
	
	/* get old response */
	
	for (i = 0; i < gen_size; i++) 
	{
			
		/* point to the weight vector for this RF */
						
		weights = &ap[indexes[i] * (rsp_size + 1)];
					

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -