示例#1
0
FILE *fopentmpfile(PCStr(path),int remove)
{	FILE *fp;
	int fd;

	if( isWindowsCE() ){
		fp = fopen_tmpfile(path);
		add_FILEY(FL_ARG,"fopentmpfile",fp);
	}else
	if( ACT_UNLINKABLE ){
		if( fp = fopen(path,FOPEN_RWB) )
			if( remove )
				unlink(path);
	}else{
		fd = newtmp(path);
		if( 0 <= fd ){
			if( fp = fdopen(fd,FOPEN_RWB) ){
				addtmp(fd,path);
				add_FILEY(FL_ARG,"fopentmpfile",fp);
				LV("fopentmpfile(%s) %x/%d",path,p2i(fp),fileno(fp));
			}else	LE("cannot fdopen(%d) %s",fd,path);
		}else{
			LE("cannot open tmpfile(%s)",path);
			fp = NULL;
		}
	}
	return fp;
}
示例#2
0
static int ppm_show(char* filename)
{
    uint32_t size;
    if( FIO_GetFileSize( filename, &size ) != 0 ) return 0;
    char * buf = fio_malloc(size);

    size_t rc = read_file( filename, buf, size );
    if( rc != size ) goto err;

    struct vram_info * vram = get_yuv422_vram();
    uint32_t * lvram = (uint32_t *)vram->vram;
    if (!lvram) goto err;

    /* only ML screenshots are supported for now, to keep things simple */
    char* ml_header = "P6\n720 480\n255\n";
    if (strncmp(buf, ml_header, strlen(ml_header)))
        goto err;
    
    char* rgb = buf + strlen(ml_header);
    for (int y = 0; y < 480; y++)
    {
        for (int x = 0; x < 720; x++)
        {
            int R = rgb[(y*720 + x)*3    ];
            int G = rgb[(y*720 + x)*3 + 1];
            int B = rgb[(y*720 + x)*3 + 2];
            uint32_t uyvy = rgb2yuv422(R, G, B);

            int pixoff_dst = LV(x,y) / 2;
            uint32_t* dst = &lvram[pixoff_dst / 2];
            uint32_t mask = (pixoff_dst % 2 ? 0xffFF00FF : 0x00FFffFF);
            *(dst) = (uyvy & mask) | (*(dst) & ~mask);
        }
    }

    fio_free(buf);
    return 1;

err:
    fio_free(buf);
    return 0;
}
示例#3
0
void deltmpfiles()
{	int ti;
	const char *path;
	int rcode;
	int fd;

	for( fd = 3; fd < 256; fd++ )
		if( closetmpf1(fd) == 0 )
			LW("exit: close(%d) = 0",fd);

	for( ti = 0;  ti < MAXFD_SETSIZE; ti++ ){
	    if( path = tmpfiles[ti] ){
		if( *path == ' ' ){
			continue;
		}
		errno = 0;
		rcode = unlink(path);
		LV("unlink(%s) = %d, errno=%d",path,rcode,errno);
	    }
	}
}
int Ifpack_CrsRiluk::InitAllValues(const Epetra_RowMatrix & OverlapA, int MaxNumEntries) {

  int ierr = 0;
  int i, j;
  int NumIn, NumL, NumU;
  bool DiagFound;
  int NumNonzeroDiags = 0;


  vector<int> InI(MaxNumEntries); // Allocate temp space
  vector<int> LI(MaxNumEntries);
  vector<int> UI(MaxNumEntries);
  vector<double> InV(MaxNumEntries);
  vector<double> LV(MaxNumEntries);
  vector<double> UV(MaxNumEntries);

  bool ReplaceValues = (L_->StaticGraph() || L_->IndicesAreLocal()); // Check if values should be inserted or replaced

  if (ReplaceValues) {
    L_->PutScalar(0.0); // Zero out L and U matrices
    U_->PutScalar(0.0);
  }

  D_->PutScalar(0.0); // Set diagonal values to zero
  double *DV;
  EPETRA_CHK_ERR(D_->ExtractView(&DV)); // Get view of diagonal
    

  // First we copy the user's matrix into L and U, regardless of fill level

  for (i=0; i< NumMyRows(); i++) {

    EPETRA_CHK_ERR(OverlapA.ExtractMyRowCopy(i, MaxNumEntries, NumIn, &InV[0], &InI[0])); // Get Values and Indices
    
    // Split into L and U (we don't assume that indices are ordered).
    
    NumL = 0; 
    NumU = 0; 
    DiagFound = false;
    
    for (j=0; j< NumIn; j++) {
      int k = InI[j];

      if (k==i) {
	DiagFound = true;
	DV[i] += Rthresh_ * InV[j] + EPETRA_SGN(InV[j]) * Athresh_; // Store perturbed diagonal in Epetra_Vector D_
      }

      else if (k < 0) {EPETRA_CHK_ERR(-1);} // Out of range

      else if (k < i) {
	LI[NumL] = k;
	LV[NumL] = InV[j];
	NumL++;
      }
      else if (k<NumMyRows()) {
	UI[NumU] = k;
	UV[NumU] = InV[j];
	NumU++;
      }
    }
    
    // Check in things for this row of L and U

    if (DiagFound) NumNonzeroDiags++;
    else DV[i] = Athresh_;

    if (NumL) {
      if (ReplaceValues) {
	EPETRA_CHK_ERR(L_->ReplaceMyValues(i, NumL, &LV[0], &LI[0]));
      }
      else {
	EPETRA_CHK_ERR(L_->InsertMyValues(i, NumL, &LV[0], &LI[0]));
      }
    }

    if (NumU) {
      if (ReplaceValues) {
	EPETRA_CHK_ERR(U_->ReplaceMyValues(i, NumU, &UV[0], &UI[0]));
      }
      else {
	EPETRA_CHK_ERR(U_->InsertMyValues(i, NumU, &UV[0], &UI[0]));
      }
    }
    
  }

  if (!ReplaceValues) {
    // The domain of L and the range of U are exactly their own row maps (there is no communication).
    // The domain of U and the range of L must be the same as those of the original matrix,
    // However if the original matrix is a VbrMatrix, these two latter maps are translation from
    // a block map to a point map.
    EPETRA_CHK_ERR(L_->FillComplete(L_->RowMatrixColMap(), *L_RangeMap_));
    EPETRA_CHK_ERR(U_->FillComplete(*U_DomainMap_, U_->RowMatrixRowMap()));
  }

  // At this point L and U have the values of A in the structure of L and U, and diagonal vector D

  SetValuesInitialized(true);
  SetFactored(false);

  int TotalNonzeroDiags = 0;
  EPETRA_CHK_ERR(Graph_.L_Graph().RowMap().Comm().SumAll(&NumNonzeroDiags, &TotalNonzeroDiags, 1));
  NumMyDiagonals_ = NumNonzeroDiags;
  if (NumNonzeroDiags != NumMyRows()) ierr = 1; // Diagonals are not right, warn user

  return(ierr);
}
示例#5
0
double Controller::update(Angle angle, double speed, double inReward, vec inLmr, int color) {
	if(t%inv_sampling_rate == 0 && !SILENT){
		pi_array = join_rows(pi_array, pin->get_output());
		if(gvlearn_on){
			gv_array = join_rows(gv_array, gvl->w(0));
		}
		if(lvlearn_on){
			for(int i = 0; i < lv_array.size(); i++)
				lv_array.at(i) = join_rows(lv_array.at(i), lvl->w(i));
			ref_array = join_rows(ref_array, lvl->RefPI());
		}
	}
	t++;

	/*** Check, if inward ***/
	if(t > t_home || accum_reward(0) > 1.){
		inward = 1.;
		//printf("t= %u > %u or sum(R)= %g\n", t, t_home, accum_reward(0));
	}

	/*** Path Integration Mechanism ***/
	if(pin_on)
		pin->update(angle, speed);

	if(gvlearn_on && gl_w > 0.)
		pi_w = HV().len() * (1. - expl_factor(0))*(1.-accu(lv_value));
	else
		pi_w = 0.0;
	pi_m =  ((HV().ang()).i() - angle).S();		//NEW PI COMMAND
	if(homing_on && inward!=0.){
		//printf("this should not be! %g\n", inward);
		pi_w = 0.5;
		pi_m = ((HV().ang()).i() - angle).S();
		rand_m = 0.0;//0.25;
	}
	if(pi_w < 0.)
		pi_w = 0.;
	output_hv = pi_w * pi_m;



	/*** Reward and value update ***/
	if(lvlearn_on){
		for(int i = 0; i < num_lv_units; i++)
			lv_value(i) = 1. - exp(-0.5*lvl->eligibility_value(i));
	}
	delta_beta = mu_beta*((1./expl_beta) + lambda * value(0) * expl_factor(0));
	if(beta_on)
		expl_beta += delta_beta;
	if(expl_factor(0) < 0.0001 && delta_beta < 0.01)
		beta_on = false;

	for(int i = 0; i < num_colors; i++){
		if(i == color){
			reward(i) = inReward;
			if(inward==0.){
				value(i) = (reward(i) /*+ accu(lv_value)*/) + disc_factor * value(i);
				if(!const_expl)
					expl_factor(i) = exp(- expl_beta * value(i));
				else
					expl_factor(i) += d_expl_factor(i);
				expl_factor.elem( find(expl_factor > 1.) ).ones();    //clip expl
				expl_factor.elem( find(expl_factor < 0.) ).zeros();   //clip expl
			}
		}
		else{
			reward(i) = 0.0;
		}
	}
	accum_reward += reward;

	/*** Global Vector Learning Circuits TODO ***/
	if(gvlearn_on){
		for(int i = 0; i < num_colors; i++){
			gvl->update(pin->get_output(), reward(i), expl_factor(i));
			cGV.at(i) = (GV(i) - HV());
		}

		gl_w = (1. - inward)*GV(0).len() * (1.-expl_factor(0));
		gl_m = (GV(0).ang() - angle).S();			//NEW GV COMMAND
	}
	//stream << cGV.at(0).ang().deg() << endl;
	output_gv = gl_w * gl_m;

	/*** Local Vector Learning Circuits TODO ***/
	if(lvlearn_on){

		lvl->update(angle, speed, inReward, inLmr);

		rl_m = 0.0;
		rl_w = (1. - inward);
		for(int i = 0; i < num_lv_units; i++){
			//cLV.at(i) = (LV(i) - HV());
			if(inward == 0.){
				gl_w = 0.0;
				pi_w = 0.0;
				rl_m += lv_value(i) * (LV().len()*(LV().ang() - angle).S() + RV().len()*(RV().ang().i() - angle).S());
			}
		}
		//if(VERBOSE && t%100==0)
			//printf("t = %u\tHV = (%f, %f)\tLV = (%f, %f)\tRV = (%f, %f)\n", t, HV().ang().deg(), HV().len(), LV().ang().deg(), LV().len(), RV().ang().deg(), RV().len());
		output_lv = rl_w * rl_m;
	}
	else
		output_lv = 0.;

	/*** Random foraging ***/
	if(lvlearn_on){
		rand_w = (1. - inward)*0.6*expl_factor(0)*(1.-accu(lv_value));
	}
	else
		rand_w = (1. - inward)*0.6*expl_factor(0);
	rand_m = randn(0.0, 1.);
	if(inward == 1)
		rand_m = 0.;

	output_rand = rand_w * rand_m;

	/*** Navigation Control Output ***/
	output = output_rand + output_hv + output_gv + output_lv;
	//output = output_rand + output_hv + 0.0 + output_lv; // Route formation

	return output;
}
示例#6
0
文件: client.c 项目: kulhos/pip
/*
*	   ClGetMsg:
*
*	   Description:
*	   $ZCall to allow a PROFILE MUMPS client process to exchange
*	   (i.e. send/recv) a message between a client and a server.
*
*/
void
ClGetMsg(int count,
	STR_DESCRIPTOR *reply,
	SLONG timeout,
	SLONG *return_code)
{
	RETURNSTATUS	rc = SUCCESS;
	char		len_field[32]; /* a reasonable string length */
	SLONG		msg_length = 0;
	SLONG		bytes_recv = 0;
	SLONG		recv_flags = 0;
	char		*ptr = (char *)NULL;
	char		no_srv_str [MAX_NAME_LEN + 1];
	int		header_size;
	int		len_length = 0;
	int		extended_hdr_flg=0;

	if(MTMClientSd == DISCONNECTED)
	{
		MTM_LOG(ENOTCONN);
		*return_code = ENOTCONN;
		return;
	}

	if (ClMsgBuffer == NULL)
		ClMsgBuffer = (char *) malloc (MAX_MSG_SIZE);
	if (ClMsgBuffer == NULL)
	{
		MTM_LOG (errno);
		*return_code = errno;
		return;
	}

	ClTimeout.value = timeout;

	/*
	*	First, peek for the message size
	*/
	sca_SetupTimer((void *)ClGetMsg, &ClTimeout, (void *)cl_signal_catcher);

	header_size = ClLength.hsize;

	rc = sca_recv(MTMClientSd,
			     len_field,
			     header_size,
			     MSG_PEEK, &ClTimeout, return_code);

	sca_CancelTimer((void *)ClGetMsg, &ClTimeout);

	if (rc<=0) 
	{
#ifdef DEBUG
	fprintf(stdout,
		"ClExchmsg: message header sca_recv rc %d errno %d\n",rc,*return_code);
	(void)sca_fflush(stdout);
#endif
		MTM_LOG(*return_code);
		if ((*return_code == ENOTCONN) || 
		    (*return_code == ECONNRESET) ||
		    (*return_code == ENOMSG) ||
		    (*return_code == EWOULDBLOCK))
		{
#ifdef DEBUG
	fprintf(stdout,
		"ClExchmsg: Disconnect occurred - current socket will be closed\n");
	(void)sca_fflush(stdout);
#endif
			/*
			*	Disconnect has occurred.
			*	Release the socket.
			*/
			(void)close(MTMClientSd);
			MTMClientSd = DISCONNECTED;
		}
		return;
	}

	msg_length = mtm_length (len_field, &ClLength);

	/* 
	 If we are in a standard bby MTM and the message approaches 64K, use special header format. 
	 At this time, only Big Endian is supported, because it is the default header format and the 
	 existing client tools all use Big Endian.
	*/
	if ((header_size==2) && (msg_length==0) && (ClLength.format=='b')) 
	{
		int j;
		char len_read[256];

		/* Using non-standard header format within bby MTM. */
		extended_hdr_flg=1;
		sca_SetupTimer((void *)ClGetMsg, &ClTimeout, (void *)cl_signal_catcher);
		
		/* Get next byte.  It will be the length of the length. */
		/* However, the last read was non-destructive, thus we need to grab 3 bytes total */
		rc = sca_recv(MTMClientSd,
			len_read,
			3,
			MSG_PEEK,
			&ClTimeout,
			return_code);

		sca_CancelTimer((void *)ClGetMsg, &ClTimeout);

		if (rc <= 0) 
		{
			if ((*return_code == ENOTCONN) || 
			    (*return_code == ECONNRESET) ||
			    (*return_code == ENOMSG) ||
			    (*return_code == EWOULDBLOCK) ||
			    (rc == 0))
			{
				/*
				*	Disconnect has occurred.
				*	Release the socket.
				*/
			(void)close(MTMClientSd);
			MTMClientSd = DISCONNECTED;
			}

			return;
		}

		len_length = len_length << 8;
		len_length = len_length | (len_read[2] & 0xFF);

#ifdef DEBUG
	fprintf(stdout,"ClGetMsg: 64k section - len_length is %d\n",len_length);
	fflush(stdout);
#endif

		/* Now read the next len_length bytes for true message size. */

		memset(len_read,0,sizeof(len_read));

		sca_SetupTimer((void *)ClGetMsg, &ClTimeout, (void *)cl_signal_catcher);
		
		rc = sca_recv(MTMClientSd,
			len_read,
			len_length+3,
			MSG_PEEK,
			&ClTimeout,
			return_code);

		sca_CancelTimer((void *)ClGetMsg, &ClTimeout);

		if (rc <= 0) 
		{
			if ((*return_code == ENOTCONN) || 
			    (*return_code == ECONNRESET) ||
			    (*return_code == ENOMSG) ||
			    (*return_code == EWOULDBLOCK) ||
			    (rc == 0))
			{
				/*
				*	Disconnect has occurred.
				*	Release the socket.
				*/
			(void)close(MTMClientSd);
			MTMClientSd = DISCONNECTED;
			}

			return;
		}

		msg_length=0;
		for (j = 0; j < len_length; j++)
		{
			msg_length = msg_length << 8;
			msg_length = msg_length | (len_read[j+3] & 0xFF);
		}

#ifdef DEBUG
	fprintf(stdout,"ClGetMsg: 64k section - msg_length is %d\n",msg_length);
	fflush(stdout);
#endif
	}


#ifdef DEBUG
	(void)fprintf(stdout,"ClGetMsg: After recv rc = %d\n",rc);
	(void)fprintf(stdout,"ClGetMsg: Msg Length %d\n",msg_length);
	(void)fflush(stdout);
#endif

	/*
	*	Return if message length is invalid
	*/
	if (msg_length < header_size)
	{
#ifdef DEBUG
	(void)fprintf(stdout,"ClGetMsg: Invalid message length %d, header length %d\n",msg_length, header_size);
	(void)fflush(stdout);
#endif
		return;
	}

	/*
	*	Now get the message off the socket
	*/
	sca_SetupTimer((void *)ClGetMsg, &ClTimeout, (void *)cl_signal_catcher);

	ptr = ClMsgBuffer;

	rc = sca_recv(	MTMClientSd,
			ClMsgBuffer,
			msg_length,
			recv_flags, &ClTimeout, return_code);

	sca_CancelTimer((void *)ClGetMsg, &ClTimeout);

	if (rc<=0) 
	{
#ifdef DEBUG
	fprintf(stdout,
		"ClExchmsg: message body sca_recv rc %d errno %d\n",rc,*return_code);
	(void)sca_fflush(stdout);
#endif
		MTM_LOG(*return_code);
		if ((*return_code == ENOTCONN) || 
		    (*return_code == ECONNRESET) ||
		    (*return_code == ENOMSG) ||
		    (*return_code == EWOULDBLOCK))
		{
#ifdef DEBUG
	(void)fprintf(stdout,"ClGetMsg: Disconnect occurred - current socket will be closed\n");
	(void)fflush(stdout);
#endif
			/*
			*	Disconnect has occurred.
			*	Release the socket.
			*/
			(void)close(MTMClientSd);
			MTMClientSd = DISCONNECTED;
		}
		return;
	}

	/*
	*	Read is ok, process the message
	*/
	if ((ClLength.lcount == 0) && (ClLength.tcount == 0))
	{
		/*
		*	strip the length from message
		*/
		if (extended_hdr_flg==1)
		{
			reply->str = &ClMsgBuffer[len_length+3];
			/* Remove the non-standard header length from the length of total message. */
			reply->length = msg_length - (len_length+3);
		}
		else
		{
			reply->str = &ClMsgBuffer[header_size];
			reply->length = msg_length - header_size;
		}
	}
	else
	{
		/*
		*	Length is embedded - return the whole enchilada
		*/
		reply->str = ClMsgBuffer;
		reply->length = msg_length;
	}

#ifdef DEBUG
	(void)fprintf(stdout,"ClGetMsg: message contents:\n");
	LV(reply->length,reply->str);
	(void)fflush(stdout);
#endif

	/*
	*	If reply length is 0, we probably have a heartbeat message.
	*	This is allowable under asynchronous mode, so don't bother
	*	to do the string compare here. The strncmp result would
	*	always be 0 (since there is nothing to compare), and the !
	*	will make it non-zero, and then we get the MTM_NO_SRV_TYPE
	*	error.
	*/
	if (reply->length > 0)
	{
		sprintf (no_srv_str, "1%s", MTM_NO_SRV_TYPE_STR);
		if (!strncmp (reply->str, no_srv_str, reply->length))
			*return_code = MTM_NO_SRV_TYPE;
	}

	return;
}
示例#7
0
文件: client.c 项目: kulhos/pip
/*
*	   ClSendMsg:
*
*	   Description:
*	   $ZCall to allow a PROFILE MUMPS client process to send
*	   a message between a client and a server.
*
*/
void
ClSendMsg(	int count,
		STR_DESCRIPTOR *request,
		SLONG timeout,
		SLONG *return_code)
{
	RETURNSTATUS	rc = SUCCESS;
	char		len_field[32]; /* a reasonable string length */
	SLONG		msg_length = 0;
	char		*ptr = (char *)NULL;

	if(MTMClientSd == DISCONNECTED)
	{
		MTM_LOG(ENOTCONN);
		*return_code = ENOTCONN;
#ifdef DEBUG
	(void)fprintf(stdout,"ClSendMsg: ENOTCONN\n");
	(void)fflush(stdout);
#endif
		return;
	}

	if (request->length > MAX_MSG_SIZE)
	{
		*return_code = EFBIG;
		MTM_LOG(*return_code);
		return;
	}

	if (ClMsgBuffer == NULL)
		ClMsgBuffer = (char *) malloc (MAX_MSG_SIZE);
	if (ClMsgBuffer == NULL)
	{
		MTM_LOG (errno);
		*return_code = errno;
		return;
	}
	if ((ClLength.lcount == 0) && (ClLength.tcount == 0))
	{
		/*
		*	Build the length before the start of message
		*/
		int len_length;
		
		msg_length = request->length+ClLength.hsize;

		/* 
		 If we are in a standard bby MTM and the message approaches 64K, use special header format. 
		 At this time, only Big Endian is supported, because it is the default header format and the 
		 existing client tools all use Big Endian.
		*/
		if ((ClLength.hsize==2) && (msg_length>65530) && (ClLength.format=='b'))
		{
			/* We don't know entire msg length until header is constructed. */
			msg_length = request->length;
			len_length=mtm_s64klength(len_field, msg_length, &ClLength);
			msg_length+=len_length;
#ifdef DEBUG
	(void)fprintf(stdout,"ClSendMsg: After call to s64k, msg_length is %d and len_length is %d\n",msg_length,len_length);
	(void)fflush(stdout);
#endif
		}
		else 
		{
			msg_length = request->length+ClLength.hsize;
			mtm_slength(len_field, msg_length, &ClLength);
			len_length = ClLength.hsize;
		}

		memcpy(ClMsgBuffer, len_field, len_length);
		(void)memcpy((char *)&ClMsgBuffer[len_length],request->str,msg_length);	
	}
	else
	{
		/*
		*	Length is built in to message
		*/
		msg_length = request->length;
		memcpy(ClMsgBuffer,request->str,msg_length);	
	}

	ptr = ClMsgBuffer;
	ClTimeout.value = timeout;

#ifdef DEBUG
	(void)fprintf(stdout,"ClSendMsg: Send Message\n");
	LV(msg_length, ptr);
	(void)fflush(stdout);
#endif

	sca_SetupTimer((void *)ClSendMsg, &ClTimeout, (void *)cl_signal_catcher);

	rc = sca_send(  MTMClientSd,
			ptr,
			msg_length,
			(int)NULL, &ClTimeout, return_code);

	sca_CancelTimer((void *)ClSendMsg, &ClTimeout);

	if (rc <= 0)
	{
#ifdef DEBUG
	(void)fprintf(stdout,"ClExchmsg: Send errno %d\n",*return_code);
	(void)fflush(stdout);
#endif
		MTM_LOG(*return_code);
	}

	return;
}
示例#8
0
MEM::Object::Object(){ 
  p = LV(1e-06,0.,0.,1e-06); 
  t = ObjectType::Unknown; 
} 
示例#9
0
LV MEM::PS::lv(const MEM::PSPart::PSPart& p) const { 
  return val.find(p)!=val.end() ? (val.find(p)->second).lv : LV() ; 
}
示例#10
0
文件: utils.c 项目: kulhos/pip
/*
*	mtm_s64klength
*
*	Converts a numeric length to a literal string for 64k IBS messages.
*	Do not call mtm_s64klength if leading or trailing count is other than 0.
*	It's assumed that the application will format the length by itself.
*	Also, be sure that string a is at least l->size in
*	length. Otherwise, it's very easy to get SIGSEGV error.
*
*/
int mtm_s64klength(char *a, SLONG length, st_length *l)
{
	SLONG temp;
	int i;
	int len_length=2;
	int prot_length;

	/*
	*	Check for valid input pointer
	*/
	if ((a == NULL) || (l == NULL))
	{
		MTM_LOG(EFAULT);
		return;
	}

	/*
	*	Make an adjustment to the overall message length
	*	if the header length is not to be included
	*/
	if (l->header != 'y')
		length -= l->hsize;

	if (length < 0)
	{
		/*
		*	We can't do a negative length
		*/
		/* MTM_LOG(MTM_INVALID_MSG); */
		MTM_LOG(EFAULT);
		return;
	}

#ifdef DEBUG
	fprintf(stdout,"mtm_slength: start - length is %d\n",length);
	fflush(stdout);
#endif

	/* Add 3 byte leader to length */
	length+=3;

	/* 
	 Now add 2 for minimum length of length. This is for protection
	 of the length calculation near the cusp of powers of 2.
	*/
	prot_length=length+2;

	/* First determine how many bytes we need for the length */
	for (i=2; i<256; i++)
	{
		long itemp = (long)pow((double)256,(double)i);
		if (((int)((prot_length+i)/itemp))>=1) continue;
		len_length = i;
		break;
	}

#ifdef DEBUG
	fprintf(stdout,"mtm_s64klength: len_length is %d\n",len_length);
	fflush(stdout);
#endif

	/* Allocate enough memory for complete header */
	memset(a, 0, len_length+3);
	/* First two bytes are 0x00; third byte is length of length */
	a[2]=len_length;

	/* 
	 The length of the entire message should now include the 
	 number of bytes being used to indicate the total length.  Got it?
	*/
	length+=len_length; 

	/* Create length in string format - big Endian */
	for (i = 0; i < len_length; i++)
	{
	  temp = (SLONG)pow((double)2, (double)(8*(len_length-i-1)));
	  a[i+3] = 0xFF & (int)(length/temp);
	  length = length % temp;
	}

#ifdef DEBUG
	fprintf(stdout,"mtm_slength: end\n");
	LV(len_length+3, a);
	fflush(stdout);
#endif

	return(len_length+3);
}
示例#11
0
文件: utils.c 项目: kulhos/pip
/*
*	mtm_slength
*
*	Converts a numeric length to a literal string.
*	Do not call mtm_slength if leading or trailing count is other than 0.
*	It's assumed that the application will format the
*	length by itself.
*	Also, be sure that string a is at least l->size in
*	length. Otherwise, it's very easy to get SIGSEGV error.
*
*/
void mtm_slength(char *a, SLONG length, st_length *l)
{
	SLONG temp;
	int i;

	/*
	*	Check for valid input pointer
	*/
	if ((a == NULL) || (l == NULL))
	{
		MTM_LOG(EFAULT);
		return;
	}

	/*
	*	Make an adjustment to the overall message length
	*	if the header length is not to be included
	*/
	if (l->header != 'y')
		length -= l->hsize;

	if (length < 0)
	{
		/*
		*	We can't do a negative length
		*/
		/* MTM_LOG(MTM_INVALID_MSG); */
		MTM_LOG(EFAULT);
		return;
	}

#ifdef DEBUG
	fprintf(stdout,"mtm_slength: start - length is %d\n",length);
	fflush(stdout);
#endif

	memset(a, 0, l->hsize);

	switch (l->format)
	{
	   case 'l':
		/* little endian */
		for (i = l->hsize-1; i >= 0; i--)
		{
			temp = (SLONG)pow((double)2, (double)8*i);
			a[i] = 0xFF & (int)(length/temp);
			length = length % temp;
		}
		break;
	   case 'b':
		/* big endian */
		for (i = 0; i < l->hsize; i++)
		{
			temp = (SLONG)pow((double)2, (double)(8*(l->hsize-i-1)));
			a[i] = 0xFF & (int)(length/temp);
			length = length % temp;
		}
		break;
	   case 'p':
		/* packed decimal, right justified, zero filled */
		for (i=0; i < l->hsize; i++)
		{
			temp = (SLONG)pow((double)10, (double)(l->hsize-i-1));
			a[i] = '0' + (int)(length/temp);
			length = length % temp;
		}
		break;
	   case 'd':
		/* packed decimal, left justified, space filled */
		memset(a, ' ', l->hsize);
		sprintf(a,"%-d",length);
		temp = strlen(a);
		a[temp]= ' ';
		break;
	   default:
		/* should not be here */
		break;
	}

#ifdef DEBUG
	fprintf(stdout,"mtm_slength: end\n");
	LV(l->hsize, a);
	fflush(stdout);
#endif

	return;
}
示例#12
0
文件: utils.c 项目: kulhos/pip
/*
*	mtm_length
*
*	Converts a literal length string to numeric length.
*	Before calling mtm_length, you have to be sure that
*	string a is at least l->hsize in length.
*	Otherwise, it's very easy to get SIGSEGV error.
*
*/
SLONG mtm_length(char *a, st_length *l)
{
	SLONG length = 0;
	int i;
	char temp[32];

	/*
	*	Check for valid input pointer
	*/
	if ((a == NULL) || (l == NULL))
	{
		MTM_LOG(EFAULT);
		return(-1);
	}

#ifdef DEBUG
	fprintf(stdout,"mtm_length: Start of routine\n");
	LV(l->hsize,a);
#endif

	/*
	*	Make a local copy of input string
	*	Shift left the number of leading "don't care" characters.
	*/
	memset(temp,0,sizeof(temp));
	memcpy(temp,&a[l->lcount],l->lsize);

	switch (l->format)
	{
	   case 'l':
		/* little endian */
		for (i = l->lsize-1; i >= 0; i--)
		{
			length = length << 8;
			length = length | (temp[i] & 0xFF);
		}
		break;
	   case 'b':
		/* big endian */
		for (i = 0; i < l->lsize; i++)
		{
			length = length << 8;
			length = length | (temp[i] & 0xFF);
		}
		break;
	   case 'p':
	   case 'd':
		/* packed decimal */
		length = atoi(temp);
		break;
	   default:
		/* should not be here */
		break;
	}

	/*
	*	Make an adjustment to the overall message length if
	*	the header length wasn't included.
	*/
	if (l->header != 'y')
		length += l->hsize;

#ifdef DEBUG
	fprintf(stdout,"mtm_length: end - length is %d\n",length);
	fflush(stdout);
#endif

	return(length);
}
示例#13
0
IGL_INLINE bool igl::lu_lagrange(
  const Eigen::SparseMatrix<T> & ATA,
  const Eigen::SparseMatrix<T> & C,
  Eigen::SparseMatrix<T> & L,
  Eigen::SparseMatrix<T> & U)
{
#if EIGEN_VERSION_AT_LEAST(3,0,92)
#if defined(_WIN32)
  #pragma message("lu_lagrange has not yet been implemented for your Eigen Version")
#else
  #warning lu_lagrange has not yet been implemented for your Eigen Version
#endif

  return false;
#else
  // number of unknowns
  int n = ATA.rows();
  // number of lagrange multipliers
  int m = C.cols();

  assert(ATA.cols() == n);
  if(m != 0)
  {
    assert(C.rows() == n);
    if(C.nonZeros() == 0)
    {
      // See note above about empty columns in C
      fprintf(stderr,"Error: lu_lagrange() C has columns but no entries\n");
      return false;
    }
  }

  // Check that each column of C has at least one entry
  std::vector<bool> has_entry; has_entry.resize(C.cols(),false);
  // Iterate over outside
  for(int k=0; k<C.outerSize(); ++k)
  {
    // Iterate over inside
    for(typename Eigen::SparseMatrix<T>::InnerIterator it (C,k); it; ++it)
    {
      has_entry[it.col()] = true;
    }
  }
  for(int i=0;i<(int)has_entry.size();i++)
  {
    if(!has_entry[i])
    {
      // See note above about empty columns in C
      fprintf(stderr,"Error: lu_lagrange() C(:,%d) has no entries\n",i);
      return false;
    }
  }



  // Cholesky factorization of ATA
  //// Eigen fails if you give a full view of the matrix like this:
  //Eigen::SparseLLT<SparseMatrix<T> > ATA_LLT(ATA);
  Eigen::SparseMatrix<T> ATA_LT = ATA.template triangularView<Eigen::Lower>();
  Eigen::SparseLLT<Eigen::SparseMatrix<T> > ATA_LLT(ATA_LT);

  Eigen::SparseMatrix<T> J = ATA_LLT.matrixL();

  //if(!ATA_LLT.succeeded())
  if(!((J*0).eval().nonZeros() == 0))
  {
    fprintf(stderr,"Error: lu_lagrange() failed to factor ATA\n");
    return false;
  }

  if(m == 0)
  {
    // If there are no constraints (C is empty) then LU decomposition is just L
    // and L' from cholesky decomposition
    L = J;
    U = J.transpose();
  }else
  {
    // Construct helper matrix M
    Eigen::SparseMatrix<T> M = C;
    J.template triangularView<Eigen::Lower>().solveInPlace(M);

    // Compute cholesky factorizaiton of M'*M
    Eigen::SparseMatrix<T> MTM = M.transpose() * M;

    Eigen::SparseLLT<Eigen::SparseMatrix<T> > MTM_LLT(MTM.template triangularView<Eigen::Lower>());

    Eigen::SparseMatrix<T> K = MTM_LLT.matrixL();

    //if(!MTM_LLT.succeeded())
    if(!((K*0).eval().nonZeros() == 0))
    {
      fprintf(stderr,"Error: lu_lagrange() failed to factor MTM\n");
      return false;
    }

    // assemble LU decomposition of Q
    Eigen::Matrix<int,Eigen::Dynamic,1> MI;
    Eigen::Matrix<int,Eigen::Dynamic,1> MJ;
    Eigen::Matrix<T,Eigen::Dynamic,1> MV;
    igl::find(M,MI,MJ,MV);

    Eigen::Matrix<int,Eigen::Dynamic,1> KI;
    Eigen::Matrix<int,Eigen::Dynamic,1> KJ;
    Eigen::Matrix<T,Eigen::Dynamic,1> KV;
    igl::find(K,KI,KJ,KV);

    Eigen::Matrix<int,Eigen::Dynamic,1> JI;
    Eigen::Matrix<int,Eigen::Dynamic,1> JJ;
    Eigen::Matrix<T,Eigen::Dynamic,1> JV;
    igl::find(J,JI,JJ,JV);

    int nnz = JV.size()  + MV.size() + KV.size();

    Eigen::Matrix<int,Eigen::Dynamic,1> UI(nnz);
    Eigen::Matrix<int,Eigen::Dynamic,1> UJ(nnz);
    Eigen::Matrix<T,Eigen::Dynamic,1> UV(nnz);
    UI << JJ,                        MI, (KJ.array() + n).matrix();
    UJ << JI, (MJ.array() + n).matrix(), (KI.array() + n).matrix(); 
    UV << JV,                        MV,                     KV*-1;
    igl::sparse(UI,UJ,UV,U);

    Eigen::Matrix<int,Eigen::Dynamic,1> LI(nnz);
    Eigen::Matrix<int,Eigen::Dynamic,1> LJ(nnz);
    Eigen::Matrix<T,Eigen::Dynamic,1> LV(nnz);
    LI << JI, (MJ.array() + n).matrix(), (KI.array() + n).matrix();
    LJ << JJ,                        MI, (KJ.array() + n).matrix(); 
    LV << JV,                        MV,                        KV;
    igl::sparse(LI,LJ,LV,L);
  }

  return true;
  #endif
}
void igl::crouzeix_raviart_cotmatrix(
  const Eigen::MatrixBase<DerivedV> & V, 
  const Eigen::MatrixBase<DerivedF> & F, 
  const Eigen::MatrixBase<DerivedE> & E,
  const Eigen::MatrixBase<DerivedEMAP> & EMAP,
  Eigen::SparseMatrix<LT> & L)
{
  // number of rows
  const int m = F.rows();
  // Element simplex size
  const int ss = F.cols();
  // Mesh should be edge-manifold
  assert(F.cols() != 3 || is_edge_manifold(F));
  typedef Eigen::Matrix<LT,Eigen::Dynamic,Eigen::Dynamic> MatrixXS;
  MatrixXS C;
  cotmatrix_entries(V,F,C);
  Eigen::MatrixXi F2E(m,ss);
  {
    int k =0;
    for(int c = 0;c<ss;c++)
    {
      for(int f = 0;f<m;f++)
      {
        F2E(f,c) = k++;
      }
    }
  }
  // number of entries inserted per facet
  const int k = ss*(ss-1)*2;
  std::vector<Eigen::Triplet<LT> > LIJV;LIJV.reserve(k*m);
  Eigen::VectorXi LI(k),LJ(k),LV(k);
  // Compensation factor to match scales in matlab version
  double factor = 2.0;

  switch(ss)
  {
    default: assert(false && "unsupported simplex size");
    case 3:
      factor = 4.0;
      LI<<0,1,2,1,2,0,0,1,2,1,2,0;
      LJ<<1,2,0,0,1,2,0,1,2,1,2,0;
      LV<<2,0,1,2,0,1,2,0,1,2,0,1;
      break;
    case 4:
      factor *= -1.0;
      LI<<0,3,3,3,1,2,1,0,1,2,2,0,0,3,3,3,1,2,1,0,1,2,2,0;
      LJ<<1,0,1,2,2,0,0,3,3,3,1,2,0,3,3,3,1,2,1,0,1,2,2,0;
      LV<<2,3,4,5,0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3,4,5,0,1;
      break;
  }

  for(int f=0;f<m;f++)
  {
    for(int c = 0;c<k;c++)
    {
      LIJV.emplace_back(
        EMAP(F2E(f,LI(c))),
        EMAP(F2E(f,LJ(c))),
        (c<(k/2)?-1.:1.) * factor *C(f,LV(c)));
    }
  }
  L.resize(E.rows(),E.rows());
  L.setFromTriplets(LIJV.begin(),LIJV.end());
}
示例#15
0
文件: mtmserver.c 项目: kulhos/pip
/*
*	mtm_server_msg
*	[module number i.e. Future] [module name]
*
*	Description:
*	Processes a server reply msg and sets up the MTMSrvTbl with the
*	necessary management and statistical tracking data.
*
*	Returns:
*	SUCCESS or FAILURE
*/
RETURNSTATUS
mtm_server_msg(void)
{
	RETURNSTATUS 	rc = SUCCESS;
	register int	i = 0;
	float		resp_time = 0;
	struct timeval	time_value;
	struct timezone time_zone;
	int		srv_type;
	SLONG		return_code;
	MTM_MSG_HEADER	*pHeader;
	SLONG wait_time;


	/*
	*	Loop until all reply msgs are read off of the Server receive queue.
	*/
	for(;;)
	{
		/*
		*	Set timer here
		*/
		MTMTimeout.value = 10;
		sca_SetupTimer((void *)mtm_server_msg, &MTMTimeout, (void *)mtm_alarm_catcher);

		/*
		*	Receive message on reply queue
		*/
		rc = sca_msgrcv(MTMServerReplyQid,
				(struct msgbuf *)MTMMsg,
				MTMMaxMsgSize,
				0,
				IPC_NOWAIT,
				&MTMTimeout,
				&return_code);

		/* Calculate the current time in microseconds to find out 
		*  the wait time for the message in the queue
		*/

		gettimeofday(&time_value,&time_zone);
		time_value.tv_usec = (time_value.tv_sec * 1000 * 1000) + time_value.tv_usec;

		/*
		*	Cancel timer here
		*/
		sca_CancelTimer((void *)mtm_server_msg, &MTMTimeout);

		/*
		*	Check for error
		*/
		if (rc <= 0)
		{
			if(return_code != ENOMSG)
			{
				MTM_EFD(return_code);
				if (return_code == E2BIG)
					continue;
				return FAILURE;
			}
			break;
		}
		else
		{
			/*
			*	Check if message header is usable
			*/
			pHeader = (MTM_MSG_HEADER *)MTMMsg;
			if (pHeader == NULL)
			{
				MTM_EFD(EFAULT);
				return FAILURE;
			}
#ifdef DEBUG
	(void)fprintf(stdout,"mtm_server_msg: Msg Length rc %d len %d\n",
						rc,
						pHeader->length);
	LV(rc,MTMMsg);
#endif
			pHeader->return_code = SUCCESS;
			/*
			*	Send server reply msg to the MTM Process.
			*/
			if (mtm_skt_send(MTMMsg) == FAILURE)
			{
				continue;
			}

			TotalActiveReqst--;

			srv_type = pHeader->srv_type;
#ifdef DEBUG
	fprintf(stdout,"mtm_server_msg: Service Class %d\n", srv_type);
	(void)fflush(stdout);
#endif

			/* Update the MTM Stats table*/

			if(MTMStatsTbl[srv_type].mtm_stats_on == TRUE )
			{
				wait_time = (SLONG)time_value.tv_usec - pHeader->time_in;
				MTMStatsTbl[srv_type].total_server_reply++;
				if ( MTMStatsTbl[srv_type].min_reply_time > wait_time || MTMStatsTbl[srv_type].min_reply_time == 0)
					MTMStatsTbl[srv_type].min_reply_time = wait_time;
				if ( MTMStatsTbl[srv_type].max_reply_time < wait_time )
					MTMStatsTbl[srv_type].max_reply_time = wait_time;
				MTMStatsTbl[srv_type].avg_reply_time = (float)MTMStatsTbl[srv_type].avg_reply_time * ( MTMStatsTbl[srv_type].total_server_reply -1 );
				MTMStatsTbl[srv_type].avg_reply_time = (float)( MTMStatsTbl[srv_type].avg_reply_time + wait_time) / MTMStatsTbl[srv_type].total_server_reply;
				if ( MTMStatsTbl[srv_type].min_req_time > pHeader->request_time || MTMStatsTbl[srv_type].min_req_time == 0)
					MTMStatsTbl[srv_type].min_req_time = pHeader->request_time;
				if ( MTMStatsTbl[srv_type].max_req_time < pHeader->request_time )
					MTMStatsTbl[srv_type].max_req_time = pHeader->request_time;
				MTMStatsTbl[srv_type].avg_req_time = (float)MTMStatsTbl[srv_type].avg_req_time * ( MTMStatsTbl[srv_type].total_server_req -1 );
				MTMStatsTbl[srv_type].avg_req_time = (float)( MTMStatsTbl[srv_type].avg_req_time + pHeader->request_time) / MTMStatsTbl[srv_type].total_server_req;
			}


			/*
			*	Find the client table entry
			*/
			for(i=0;i<MTMMaxClient;i++)
			{
				if(MTMSrvTbl[srv_type].cl_tbl[i].sd == pHeader->sd)
				{
					MTMSrvTbl[srv_type].cl_tbl[i].srv_pid = 0; 
					break;
				}
			}
			if(i == MTMMaxClient)
			{
				MTM_EFD(MTM_CLIENT_NOT_CONNECTED);
				return FAILURE;
			}

			(void)mtm_update_jrnl(	RESP_MSG,
						srv_type,
						(void *)&MTMSrvTbl[srv_type].cl_tbl[i]);

			/*
			*	Set up the Statistical data for the 
			*	Servers on a per client basis
			*/
			MTMSrvTbl[srv_type].cl_tbl[i].resp_msgs++;
			MTMSrvTbl[srv_type].total_server_resps++;

			/*
			*	Get the time
			*/
			gettimeofday (&time_value, &time_zone);
			resp_time = time_value.tv_sec -
					MTMSrvTbl[srv_type].cl_tbl[i].recv_time;
			resp_time += (time_value.tv_usec -
					MTMSrvTbl[srv_type].cl_tbl[i].microsecs_recv_time)/1000000.0;

#ifdef DEBUG
	(void)fprintf(stdout,"mtm_server_msg: resp_time %f\n", resp_time);
	fflush(stdout);
#endif
			
			/*	Total resp time	*/
			MTMSrvTbl[srv_type].cl_tbl[i].total_resp_time += resp_time;
			MTMSrvTbl[srv_type].total_resp_time += resp_time;

			/*	Minimum resp time	*/
			if(resp_time < MTMSrvTbl[srv_type].cl_tbl[i].min_resp_time)
				MTMSrvTbl[srv_type].cl_tbl[i].min_resp_time = resp_time;

			/*	Max resp time	*/
			if(resp_time > MTMSrvTbl[srv_type].cl_tbl[i].max_resp_time)
				MTMSrvTbl[srv_type].cl_tbl[i].max_resp_time = resp_time;

			if(resp_time < MTMSrvTbl[srv_type].min_resp_time)
				MTMSrvTbl[srv_type].min_resp_time = resp_time;

			/*	Max resp time	*/
			if(resp_time > MTMSrvTbl[srv_type].max_resp_time)
				MTMSrvTbl[srv_type].max_resp_time = resp_time;

			MTMSrvTbl[srv_type].cl_tbl[i].state = CONNECTED;
		}
	}

	return SUCCESS;
}
示例#16
0
文件: optim.c 项目: paploo/pcc
/*
 * local optimizations, most of which are probably
 * machine independent
 */
NODE *
optim(NODE *p)
{
	int o, ty;
	NODE *sp, *q;
	OFFSZ sz;
	int i;

	if (odebug) return(p);

	ty = coptype(p->n_op);
	if( ty == LTYPE ) return(p);

	if( ty == BITYPE ) p->n_right = optim(p->n_right);
	p->n_left = optim(p->n_left);

	/* collect constants */
again:	o = p->n_op;
	switch(o){

	case SCONV:
		if (concast(p->n_left, p->n_type)) {
			q = p->n_left;
			nfree(p);
			p = q;
			break;
		}
		/* FALLTHROUGH */
	case PCONV:
		if (p->n_type != VOID)
			p = clocal(p);
		break;

	case FORTCALL:
		p->n_right = fortarg( p->n_right );
		break;

	case ADDROF:
		if (LO(p) == TEMP)
			break;
		if( LO(p) != NAME ) cerror( "& error" );

		if( !andable(p->n_left) && !statinit)
			break;

		LO(p) = ICON;

		setuleft:
		/* paint over the type of the left hand side with the type of the top */
		p->n_left->n_type = p->n_type;
		p->n_left->n_df = p->n_df;
		p->n_left->n_ap = p->n_ap;
		q = p->n_left;
		nfree(p);
		p = q;
		break;

	case NOT:
	case UMINUS:
	case COMPL:
		if (LCON(p) && conval(p->n_left, o, p->n_left))
			p = nfree(p);
		break;

	case UMUL:
		/* Do not discard ADDROF TEMP's */
		if (LO(p) == ADDROF && LO(p->n_left) != TEMP) {
			q = p->n_left->n_left;
			nfree(p->n_left);
			nfree(p);
			p = q;
			break;
		}
		if( LO(p) != ICON ) break;
		LO(p) = NAME;
		goto setuleft;

	case RS:
		if (LCON(p) && RCON(p) && conval(p->n_left, o, p->n_right))
			goto zapright;

		sz = tsize(p->n_type, p->n_df, p->n_ap);

		if (LO(p) == RS && RCON(p->n_left) && RCON(p) &&
		    (RV(p) + RV(p->n_left)) < sz) {
			/* two right-shift  by constants */
			RV(p) += RV(p->n_left);
			p->n_left = zapleft(p->n_left);
		}
#if 0
		  else if (LO(p) == LS && RCON(p->n_left) && RCON(p)) {
			RV(p) -= RV(p->n_left);
			if (RV(p) < 0)
				o = p->n_op = LS, RV(p) = -RV(p);
			p->n_left = zapleft(p->n_left);
		}
#endif
		if (RO(p) == ICON) {
			if (RV(p) < 0) {
				RV(p) = -RV(p);
				p->n_op = LS;
				goto again;
			}
#ifdef notyet /* must check for side effects, --a >> 32; */
			if (RV(p) >= tsize(p->n_type, p->n_df, p->n_sue) &&
			    ISUNSIGNED(p->n_type)) { /* ignore signed shifts */
				/* too many shifts */
				tfree(p->n_left);
				nfree(p->n_right);
				p->n_op = ICON; p->n_lval = 0; p->n_sp = NULL;
			} else
#endif
			/* avoid larger shifts than type size */
			if (RV(p) >= sz) {
				RV(p) = RV(p) % sz;
				werror("shift larger than type");
			}
			if (RV(p) == 0)
				p = zapleft(p);
		}
		break;

	case LS:
		if (LCON(p) && RCON(p) && conval(p->n_left, o, p->n_right))
			goto zapright;

		sz = tsize(p->n_type, p->n_df, p->n_ap);

		if (LO(p) == LS && RCON(p->n_left) && RCON(p)) {
			/* two left-shift  by constants */
			RV(p) += RV(p->n_left);
			p->n_left = zapleft(p->n_left);
		}
#if 0
		  else if (LO(p) == RS && RCON(p->n_left) && RCON(p)) {
			RV(p) -= RV(p->n_left);
			p->n_left = zapleft(p->n_left);
		}
#endif
		if (RO(p) == ICON) {
			if (RV(p) < 0) {
				RV(p) = -RV(p);
				p->n_op = RS;
				goto again;
			}
#ifdef notyet /* must check for side effects */
			if (RV(p) >= tsize(p->n_type, p->n_df, p->n_sue)) {
				/* too many shifts */
				tfree(p->n_left);
				nfree(p->n_right);
				p->n_op = ICON; p->n_lval = 0; p->n_sp = NULL;
			} else
#endif
			/* avoid larger shifts than type size */
			if (RV(p) >= sz) {
				RV(p) = RV(p) % sz;
				werror("shift larger than type");
			}
			if (RV(p) == 0)  
				p = zapleft(p);
		}
		break;

	case QUEST:
		if (LCON(p) == 0)
			break;
		if (LV(p) == 0) {
			q = p->n_right->n_right;
		} else {
			q = p->n_right->n_left;
			p->n_right->n_left = p->n_right->n_right;
		}
		p->n_right->n_op = UMUL; /* for tfree() */
		tfree(p);
		p = q;
		break;

	case MINUS:
		if (LCON(p) && RCON(p) && p->n_left->n_sp == p->n_right->n_sp) {
			/* link-time constants, but both are the same */
			/* solve it now by forgetting the symbols */
			p->n_left->n_sp = p->n_right->n_sp = NULL;
		}
		if( !nncon(p->n_right) ) break;
		RV(p) = -RV(p);
		o = p->n_op = PLUS;

	case MUL:
		/*
		 * Check for u=(x-y)+z; where all vars are pointers to
		 * the same struct. This has two advantages:
		 * 1: avoid a mul+div
		 * 2: even if not allowed, people may get surprised if this
		 *    calculation do not give correct result if using
		 *    unaligned structs.
		 */
		if (p->n_type == INTPTR && RCON(p) &&
		    LO(p) == DIV && RCON(p->n_left) &&
		    RV(p) == RV(p->n_left) &&
		    LO(p->n_left) == MINUS) {
			q = p->n_left->n_left;
			if (q->n_left->n_type == PTR+STRTY &&
			    q->n_right->n_type == PTR+STRTY &&
			    strmemb(q->n_left->n_ap) ==
			    strmemb(q->n_right->n_ap)) {
				p = zapleft(p);
				p = zapleft(p);
			}
		}
		/* FALLTHROUGH */
	case PLUS:
	case AND:
	case OR:
	case ER:
		/* commutative ops; for now, just collect constants */
		/* someday, do it right */
		if( nncon(p->n_left) || ( LCON(p) && !RCON(p) ) )
			SWAP( p->n_left, p->n_right );
		/* make ops tower to the left, not the right */
		if( RO(p) == o ){
			NODE *t1, *t2, *t3;
			t1 = p->n_left;
			sp = p->n_right;
			t2 = sp->n_left;
			t3 = sp->n_right;
			/* now, put together again */
			p->n_left = sp;
			sp->n_left = t1;
			sp->n_right = t2;
			sp->n_type = p->n_type;
			p->n_right = t3;
			}
		if(o == PLUS && LO(p) == MINUS && RCON(p) && RCON(p->n_left) &&
		   conval(p->n_right, MINUS, p->n_left->n_right)){
			zapleft:

			q = p->n_left->n_left;
			nfree(p->n_left->n_right);
			nfree(p->n_left);
			p->n_left = q;
		}
		if( RCON(p) && LO(p)==o && RCON(p->n_left) &&
		    conval( p->n_right, o, p->n_left->n_right ) ){
			goto zapleft;
			}
		else if( LCON(p) && RCON(p) && conval( p->n_left, o, p->n_right ) ){
			zapright:
			nfree(p->n_right);
			q = makety(p->n_left, p->n_type, p->n_qual,
			    p->n_df, p->n_ap);
			nfree(p);
			p = clocal(q);
			break;
			}

		/* change muls to shifts */

		if( o == MUL && nncon(p->n_right) && (i=ispow2(RV(p)))>=0){
			if( i == 0 ) { /* multiplication by 1 */
				goto zapright;
				}
			o = p->n_op = LS;
			p->n_right->n_type = INT;
			p->n_right->n_df = NULL;
			RV(p) = i;
			}

		/* change +'s of negative consts back to - */
		if( o==PLUS && nncon(p->n_right) && RV(p)<0 ){
			RV(p) = -RV(p);
			o = p->n_op = MINUS;
			}

		/* remove ops with RHS 0 */
		if ((o == PLUS || o == MINUS || o == OR || o == ER) &&
		    nncon(p->n_right) && RV(p) == 0) {
			goto zapright;
		}
		break;

	case DIV:
		if( nncon( p->n_right ) && p->n_right->n_lval == 1 )
			goto zapright;
		if (LCON(p) && RCON(p) && conval(p->n_left, DIV, p->n_right))
			goto zapright;
		if (RCON(p) && ISUNSIGNED(p->n_type) && (i=ispow2(RV(p))) > 0) {
			p->n_op = RS;
			RV(p) = i;
			q = p->n_right;
			if(tsize(q->n_type, q->n_df, q->n_ap) > SZINT)
				p->n_right = makety(q, INT, 0, 0, 0);

			break;
		}
		break;

	case MOD:
		if (RCON(p) && ISUNSIGNED(p->n_type) && ispow2(RV(p)) > 0) {
			p->n_op = AND;
			RV(p) = RV(p) -1;
			break;
		}
		break;

	case EQ:
	case NE:
	case LT:
	case LE:
	case GT:
	case GE:
	case ULT:
	case ULE:
	case UGT:
	case UGE:
		if (LCON(p) && RCON(p) &&
		    !ISPTR(p->n_left->n_type) && !ISPTR(p->n_right->n_type)) {
			/* Do constant evaluation */
			q = p->n_left;
			if (conval(q, o, p->n_right)) {
				nfree(p->n_right);
				nfree(p);
				p = q;
				break;
			}
		}

		if( !LCON(p) ) break;

		/* exchange operands */

		sp = p->n_left;
		p->n_left = p->n_right;
		p->n_right = sp;
		p->n_op = revrel[p->n_op - EQ ];
		break;

#ifdef notyet
	case ASSIGN:
		/* Simple test to avoid two branches */
		if (RO(p) != NE)
			break;
		q = p->n_right;
		if (RCON(q) && RV(q) == 0 && LO(q) == AND &&
		    RCON(q->n_left) && (i = ispow2(RV(q->n_left))) &&
		    q->n_left->n_type == INT) {
			q->n_op = RS;
			RV(q) = i;
		}
		break;
#endif
	}

	return(p);
	}