Esempio n. 1
0
//Méthode toString
QString Complexe::toString() const{
    QString im = getI()->toString();
    if(getI()>0){
        if(im=="1") im="";
        return getR()->toString() + " + " + im + "i";
    }
    else{
        im.remove('-');
        if(im=="1") im="";
        return getR()->toString() + " - " + im + "i";
    }
}
Esempio n. 2
0
bool RigidBody::getAtomVel(Vector3d& vel, unsigned int index) {

    //velRot = $(A\cdot skew(I^{-1}j))^{T}refCoor$

    if (index < atoms_.size()) {

        Vector3d velRot;
        Mat3x3d skewMat;;
        Vector3d ref = refCoords_[index];
        Vector3d ji = getJ();
        Mat3x3d I =  getI();

        skewMat(0, 0) =0;
        skewMat(0, 1) = ji[2] /I(2, 2);
        skewMat(0, 2) = -ji[1] /I(1, 1);

        skewMat(1, 0) = -ji[2] /I(2, 2);
        skewMat(1, 1) = 0;
        skewMat(1, 2) = ji[0]/I(0, 0);

        skewMat(2, 0) =ji[1] /I(1, 1);
        skewMat(2, 1) = -ji[0]/I(0, 0);
        skewMat(2, 2) = 0;

        velRot = (getA() * skewMat).transpose() * ref;

        vel =getVel() + velRot;
        return true;
        
    } else {
        std::cerr << index << " is an invalid index, current rigid body contains " 
                      << atoms_.size() << "atoms" << std::endl;
        return false;
    }
}
 /**
  * @brief OutputSize
  * @param imgIn
  * @param width
  * @param height
  * @param channels
  * @param frames
  */
 void OutputSize(ImageVec imgIn, int &width, int &height, int &channels, int &frames)
 {
     width = imgIn[0]->width;
     height = imgIn[0]->height;
     channels = getp(imgIn)->channels * (getI(imgIn)->channels + 1);
     frames = imgIn[0]->frames;
 }
Esempio n. 4
0
float PID :: getPID (const float pv, const float sp)
{
	m_previousError = m_error;
	m_error = sp - pv;

	return (m_p * getP()) + (m_i * getI(1.0)) + (m_d * getD());
}
Esempio n. 5
0
void Pid::postState(TunerStudioOutputChannels *tsOutputChannels) {
	tsOutputChannels->debugFloatField2 = getIntegration();
	tsOutputChannels->debugFloatField3 = getPrevError();
	tsOutputChannels->debugFloatField4 = getI();
	tsOutputChannels->debugFloatField5 = getD();
	tsOutputChannels->debugIntField1 = getP();
	tsOutputChannels->debugIntField2 = getOffset();
}
Esempio n. 6
0
/* C depende do tipo de trama e, se for positive ou negative acknowledgment, do numero da mensagem R (S se for I)*/
char getC(message_type message, int R) {
	if (message == MESSAGE_SET) return SET;
	else if (message == MESSAGE_DISC) return DISC;
	else if (message == MESSAGE_UA) return UA;
	else if (message == MESSAGE_I) return getI(R);
	else if (message == MESSAGE_RR) return getRR(R);
	else return getREJ(R);
}
bool StereoSensorProcessor::computeVariances(
    const pcl::PointCloud<pcl::PointXYZRGB>::ConstPtr pointCloud,
    const Eigen::Matrix<double, 6, 6>& robotPoseCovariance,
    Eigen::VectorXf& variances)
{
  variances.resize(pointCloud->size());

  // Projection vector (P).
  const Eigen::RowVector3f projectionVector = Eigen::RowVector3f::UnitZ();

  // Sensor Jacobian (J_s).
  const Eigen::RowVector3f sensorJacobian = projectionVector * (rotationMapToBase_.transposed() * rotationBaseToSensor_.transposed()).toImplementation().cast<float>();

  // Robot rotation covariance matrix (Sigma_q).
  Eigen::Matrix3f rotationVariance = robotPoseCovariance.bottomRightCorner(3, 3).cast<float>();

  // Preparations for#include <pcl/common/transforms.h> robot rotation Jacobian (J_q) to minimize computation for every point in point cloud.
  const Eigen::Matrix3f C_BM_transpose = rotationMapToBase_.transposed().toImplementation().cast<float>();
  const Eigen::RowVector3f P_mul_C_BM_transpose = projectionVector * C_BM_transpose;
  const Eigen::Matrix3f C_SB_transpose = rotationBaseToSensor_.transposed().toImplementation().cast<float>();
  const Eigen::Matrix3f B_r_BS_skew = kindr::getSkewMatrixFromVector(Eigen::Vector3f(translationBaseToSensorInBaseFrame_.toImplementation().cast<float>()));

  for (unsigned int i = 0; i < pointCloud->size(); ++i)
  {
    // For every point in point cloud.

    // Preparation.
    pcl::PointXYZRGB point = pointCloud->points[i];
    double disparity = sensorParameters_.at("depth_to_disparity_factor")/point.z;
    Eigen::Vector3f pointVector(point.x, point.y, point.z); // S_r_SP
    float heightVariance = 0.0; // sigma_p

    // Measurement distance.
    float measurementDistance = pointVector.norm();

    // Compute sensor covariance matrix (Sigma_S) with sensor model.
    float varianceNormal = pow(sensorParameters_.at("depth_to_disparity_factor") / pow(disparity, 2), 2)
        * ((sensorParameters_.at("p_5") * disparity + sensorParameters_.at("p_2"))
            * sqrt(pow(sensorParameters_.at("p_3") * disparity + sensorParameters_.at("p_4") - getJ(i), 2)
                    + pow(240 - getI(i), 2)) + sensorParameters_.at("p_1"));
    float varianceLateral = pow(sensorParameters_.at("lateral_factor") * measurementDistance, 2);
    Eigen::Matrix3f sensorVariance = Eigen::Matrix3f::Zero();
    sensorVariance.diagonal() << varianceLateral, varianceLateral, varianceNormal;

    // Robot rotation Jacobian (J_q).
    const Eigen::Matrix3f C_SB_transpose_times_S_r_SP_skew = kindr::getSkewMatrixFromVector(Eigen::Vector3f(C_SB_transpose * pointVector));
    Eigen::RowVector3f rotationJacobian = P_mul_C_BM_transpose * (C_SB_transpose_times_S_r_SP_skew + B_r_BS_skew);

    // Measurement variance for map (error propagation law).
    heightVariance = rotationJacobian * rotationVariance * rotationJacobian.transpose();
    heightVariance += sensorJacobian * sensorVariance * sensorJacobian.transpose();

    // Copy to list.
    variances(i) = heightVariance;
  }

  return true;
}
Esempio n. 8
0
void try_flip_2_edge(int *g, int gsize, int &best_count_2, std::vector<int> &best_K, int best_start, int *nd, bool flip_new){
    int i;
    int j;
    int k;
    int l;
    int cnt;
    size_t m;
    size_t n;
    size_t sz = best_K.size();

    best_count_2 = BIGCOUNT;

    for(m=best_start; m<sz; m++){
        for(n=m+1; n<sz; n++){
            /*
            flip
            */
            i = getI(best_K[m]);
            j = getJ(best_K[m]);
            k = getI(best_K[n]);
            l = getJ(best_K[n]);
            g[ i*gsize + j ] = 1 - g[ i*gsize + j ];
            g[ k*gsize + l ] = 1 - g[ k*gsize + l ];
            cnt = CliqueCount(g, gsize, flip_new);

            if( cnt < best_count_2 ){
                best_count_2 = cnt;
                nd[0] = i;
                nd[1] = j;
                nd[2] = k;
                nd[3] = l;
            }


            /*
            unflip
            */
            g[ i*gsize + j ] = 1 - g[ i*gsize + j ];
            g[ k*gsize + l ] = 1 - g[ k*gsize + l ];            

        }
    }

}
Esempio n. 9
0
static int py_anal(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len, RAnalOpMask mask) {
	PyObject *tmpreg = NULL;
	int size = 0;
	int seize = -1;
	int i = 0;
	if (!op) return -1;
	if (py_anal_cb) {
		memset(op, 0, sizeof (RAnalOp));
		// anal(addr, buf) - returns size + dictionary (structure) for RAnalOp
		Py_buffer pybuf = {
			.buf = (void *) buf, // Warning: const is lost when casting
			.len = len,
			.readonly = 1,
			.ndim = 1,
			.itemsize = 1,
		};
		PyObject *memview = PyMemoryView_FromBuffer (&pybuf);
		PyObject *arglist = Py_BuildValue ("(NK)", memview, addr);
		PyObject *result = PyEval_CallObject (py_anal_cb, arglist);
		if (result && PyList_Check (result)) {
			PyObject *len = PyList_GetItem (result, 0);
			PyObject *dict = PyList_GetItem (result, 1);
			if (dict && PyDict_Check (dict)) {
				seize = PyNumber_AsSsize_t (len, NULL);
				op->type = getI (dict, "type");
				op->cycles = getI (dict, "cycles");
				op->size = seize;
				op->addr = getI (dict, "addr");
				op->jump = getI (dict, "jump");
				op->fail = getI (dict, "fail");
				op->stackop = getI (dict, "stackop");
				op->stackptr = getI (dict, "stackptr");
				op->ptr = getI (dict, "ptr");
				op->eob = getB (dict, "eob");
				// Loading 'src' and 'dst' values
				// SRC is is a list of 3 elements
				PyObject *tmpsrc = getO (dict, "src");
				if (tmpsrc && PyList_Check (tmpsrc)) {
					for (i = 0; i < 3; i++) {
						PyObject *tmplst = PyList_GetItem (tmpsrc, i);
						// Read value and underlying regs
						READ_VAL(tmplst, op->src[i], tmpreg)
					}
				}
				PyObject *tmpdst = getO (dict, "dst");
				// Read value and underlying regs
				READ_VAL(tmpdst, op->dst, tmpreg)
				// Loading 'var' value if presented
				r_strbuf_set (&op->esil, getS (dict, "esil"));
				// TODO: Add opex support here
				Py_DECREF (dict);
			}
			Py_DECREF (result);
		} else {
Esempio n. 10
0
void ServiceWalker::onNewTile()
{
   Walker::onNewTile();

   std::set<Building*> reachedBuildings = getReachedBuildings(getI(), getJ());
   for (std::set<Building*>::iterator itBuilding = reachedBuildings.begin(); itBuilding != reachedBuildings.end(); ++itBuilding)
   {
      Building &building = **itBuilding;
      building.applyService(*this);
   }
}
Esempio n. 11
0
void Screen::displayScreenFirst()
{
    lcdSetCursor0_0();
    printCharge();
    lcdPrintCurrent(getI(),  7);
    lcdPrintSpaces();

    lcdSetCursor0_1();
    printChar_Time();
    analogInputs.printRealValue(AnalogInputs::VoutBalancer,     7);
    lcdPrintSpaces();
}
PIC_INLINE void FilterGuidedAB::ProcessBBox(Image *dst, ImageVec src,
        BBox *box)
{
    Image *I = getI(src);
    Image *p = getp(src);

    if(I->channels == 1) {
        Process1Channel(I, p, dst, box);
    }

    if(I->channels == 3) {
        Process3Channel(I, p, dst, box);
    }
}
Esempio n. 13
0
void Screen::displayScreenR()
{
    lcdSetCursor0_0();
    lcdPrint_P(PSTR("batt. R="));
    lcdPrintResistance(calculateRth_calibrated(theveninMethod.tVout_.Rth_V_, theveninMethod.tVout_.Rth_I_),8);
    lcdPrintSpaces();
    lcdSetCursor0_1();
    if(analogInputs.isConnected(AnalogInputs::Vbalancer)) {
        lcdPrint_P(PSTR("wires R="));
        int16_t Vwires =  analogInputs.getRealValue(AnalogInputs::Vout);
        Vwires -= analogInputs.getRealValue(AnalogInputs::Vbalancer);
        lcdPrintResistance(calculateRth2(Vwires, getI()+1),8);
    }
    lcdPrintSpaces();
}
Esempio n. 14
0
 void Well::setRefDepthFromCompletions() const {
     size_t timeStep = m_creationTimeStep;
     while (true) {
         auto completions = getCompletions( timeStep );
         if (completions->size() > 0) {
             auto firstCompletion = completions->get(0);
             double depth = m_grid->getCellDepth( firstCompletion->getI() , firstCompletion->getJ() , firstCompletion->getK());
             m_refDepth.setValue( depth );
             break;
         } else {
             timeStep++;
             if (timeStep >= m_timeMap->size())
                 throw std::invalid_argument("No completions defined for well: " + name() + " can not infer reference depth");
         }
     }
 }
Esempio n. 15
0
Complexe* Complexe::conjugue(){

    StrategieMultiplication m;
    Numerique* i= getI();
    Entier* neg= new Entier(-1);
    Numerique* pr= dynamic_cast<Numerique*>(getR()->clone());

    if (isEntier(i)){
        Entier* e= dynamic_cast<Entier*>(i);
        return new Complexe(pr,m.Calcul(neg,e));
    }
    else if (isReel(i)){
        Reel* r= dynamic_cast<Reel*>(i);
        return new Complexe(pr,m.Calcul(neg,r));
    }
    else{
        Rationnel* ra= dynamic_cast<Rationnel*>(i);
        return new Complexe(pr,m.Calcul(neg,ra));
    }

}
Esempio n. 16
0
  DirectionalAtom::DirectionalAtom(AtomType* dAtomType) 
    : Atom(dAtomType) {
    objType_= otDAtom;

    DirectionalAdapter da = DirectionalAdapter(dAtomType);
    I_ = da.getI();

    MultipoleAdapter ma = MultipoleAdapter(dAtomType);
    if (ma.isDipole()) {
      dipole_ = ma.getDipole();
    }
    if (ma.isQuadrupole()) {
      quadrupole_ = ma.getQuadrupole();
    }

    // Check if one of the diagonal inertia tensor of this directional
    // atom is zero:
    int nLinearAxis = 0;
    Mat3x3d inertiaTensor = getI();
    for (int i = 0; i < 3; i++) {    
      if (fabs(inertiaTensor(i, i)) < OpenMD::epsilon) {
        linear_ = true;
        linearAxis_ = i;
        ++ nLinearAxis;
      }
    }

    if (nLinearAxis > 1) {
      sprintf( painCave.errMsg,
               "Directional Atom warning.\n"
               "\tOpenMD found more than one axis in this directional atom with a vanishing \n"
               "\tmoment of inertia.");
      painCave.isFatal = 0;
      simError();
    }    
  }
Esempio n. 17
0
//! @brief Returns the local reference system.
Ref3d3d XC::CrdTransf3d::getLocalReference(void) const
  {
    const Vector vI= getI();
    const Vector vJ= getJ();
    return Ref3d3d(getPosNodeI(),Vector3d(vI[0],vI[1],vI[2]),Vector3d(vJ[0],vJ[1],vJ[2]));
  }
Esempio n. 18
0
int ZStr::getAsInt(int x) {
	return getI(x);
}
Esempio n. 19
0
Point Tile::getScreenPos() const
{
  return Point( 30 * ( getI() + getJ()), 15 * (getI() - getJ()) );
}
void ElevatorModule::setP(double p) {
	m_PIDController->SetPID(p, getI(), getD());
}
void ElevatorModule::setD(double d) {
	m_PIDController->SetPID(getP(), getI(), d);
}
Esempio n. 22
0
/*
search
flip new edge first
if stuck
flip all
*/
void tabu_search(){
    int *g;
    int *new_g;
    int gsize;
    int count;
    int i;
    int j;
    int best_count;
    int best_i;
    int best_j;

    /*
    some vars for storing result of flip_2_edge
    */
    int best_count_2;
    int node[4];    


    /*
    start with a graph of size 8
    */
    if( !ReadGraph("204.ce", &g, &gsize) ){
        fprintf(stderr, "cannot read\n" );
        fflush(stderr);
        exit(1);
    }




    bool flip_new_edge_only = true;
    int tabu_size;
    int stuck_num;
    int stuck_cnt;
    int stuck_threshold = 10;


    /*
    tabu list
    */
    std::set<int> ban_s;
    std::queue<int> ban_q;


    /*
    best_count's collector
    */
    std::vector<int> best_K;
    int best_start = 0;


    /*
    search
    */
    int ra1;
    int ra2;
    while(gsize < MAXSIZE){

        count = CliqueCount( g, gsize, flip_new_edge_only );

        best_K.clear();
        best_start = 0;


        if( count == 0 ){
            printf("...Euraka! Counter example FOUND!\n");
            PrintGraph(g, gsize);

            new_g = (int *)malloc((gsize+1)*(gsize+1)*sizeof(int));
            if(new_g == NULL) exit(1);

            CopyGraph( g, gsize, new_g, gsize + 1 );
 
            for(i=0; i<gsize+1; i++){
                ra1 = rand() % 2;
                if(ra1 == 0){
                    new_g[i*(gsize+1) + gsize] = 0;
                    new_g[gsize*(gsize+1) + i] = 0;
                }
                else{
                    new_g[i*(gsize+1) + gsize] = 1;
                    new_g[gsize*(gsize+1) + i] = 1;
                }
            }

            free(g);
            g = new_g;
            gsize++;

            ban_s.clear();
            clearQ(ban_q);


            flip_new_edge_only = true;
            stuck_num = 0;
            stuck_cnt = 0;

            continue;
        }


        best_count = BIGCOUNT;
        int key;
        size_t sz;

        best_count_2 = BIGCOUNT;

        if( flip_new_edge_only ){
            j = gsize - 1;
            for(i=0; i<gsize-1; i++){

                flip_1_edge(g, gsize, i, j, ban_s, best_K, best_start, best_count, true);
              
            }


        }

        else{

            /*
            flip 1 edge
            */
            for(i=0; i<gsize; i++){
                for(j=i+1; j<gsize; j++){
                    ra1 = rand() % 30;
                    if(ra1 == 0){
                        flip_1_edge(g, gsize, i, j, ban_s, best_K, best_start, best_count, false);
                    }
                }

            }

        }


        if(best_count == BIGCOUNT){
            printf("no best found, terminating..\n");
            exit(1);
        }

        
        sz = best_K.size();
        if(best_start < sz - 1){
            try_flip_2_edge(g, gsize, best_count_2, best_K, best_start, node, flip_new_edge_only);
        }



        tabu_size = (flip_new_edge_only)? gsize/4 : gsize + gsize;
        if(best_count <= best_count_2){
            /*
            flip 1 edge
            */

            ra1 = (best_start == sz - 1)? best_start : best_start + rand() % (sz - best_start);
            key = best_K[ra1];
            best_i = getI(key);
            best_j = getJ(key);
            g[ best_i*gsize + best_j ] = 1 - g[ best_i*gsize + best_j ];


            put_to_tabu_list(ban_q, ban_s, tabu_size, key);

            /*
            stuck?
            */
            if( flip_new_edge_only ){
                i = stuck_num - best_count;
                if( i < 0 ) i = -i;
                
                if( i < 3 ){
                    stuck_cnt++;
                    
                    if(stuck_cnt == stuck_threshold){
                        printf("stucked..\n.\n");
                        flip_new_edge_only = false;
                        stuck_cnt = 0;
                        stuck_num = 0;
                    }
                }
                else{
                    stuck_num = best_count;
                    stuck_cnt = 0;
                }
            }

            printf("ce size: %d, best_count: %d, best edge: (%d, %d), new color: %d\n", gsize, best_count, best_i, best_j, g[best_i*gsize + best_j]);

        }
        else{
            /*
            flip 2 edge
            */

            g[ node[0]*gsize + node[1] ] = 1 - g[ node[0]*gsize + node[1] ];
            g[ node[2]*gsize + node[3] ] = 1 - g[ node[2]*gsize + node[3] ];

            put_to_tabu_list(ban_q, ban_s, tabu_size, getKey(node[0], node[1]));
            put_to_tabu_list(ban_q, ban_s, tabu_size, getKey(node[0], node[1]));

            printf("ce size: %d, best_count: %d, best edge: (%d, %d), (%d, %d)\n", gsize, best_count_2, node[0], node[1], node[2], node[3]);

        }


        /*
        rinse and repeat
        */
    }


}
Esempio n. 23
0
Point Tile::getXY() const
{
  return Point( 30 * ( getI() + getJ()), 15 * (getI() - getJ()) );
}
Esempio n. 24
0
int ConfigMap::getI(const char * key_) {
  return getI(const_cast<char*>(key_));
};
Esempio n. 25
0
/*
partial version:
assuming the counter example is embeded
in the graph one size bigger
*/
void tabu_search_part(){
    int *g;
    int *new_g;
    int gsize;
    int count;
    int i;
    int j;
    int best_count;
    int best_i;
    int best_j;
    
    /*
    init tabu list which is made up by 1 set and 1 queue
    */
    std::set<int> ban_s;
    std::queue<int> ban_q;
    

    /*
    best_counts collector
    */
    std::vector<int> best_k;
    int best_start = 0;

    /*
    start with graph of size 8
    */
    gsize = 8;
    g = (int *)malloc(gsize*gsize*sizeof(int));
    if(g == NULL) exit(1);
    
    /*
    start out with a counter example
    */
    memset(g, 0, gsize*gsize*sizeof(int));
    g[0*gsize + 2] = 1;
    g[1*gsize + 4] = 1;
    
    /*
    search
    */
    int ra1;
    while(gsize < MAXSIZE){
        /*
        find how we are doing
        */
        count = CliqueCountPart(g, gsize);
        
        /*
        reset collecor
        */
        best_k.clear();
        best_start = 0;

        /*
        if we get a counter example
        */
        if(count == 0){
            printf("22222....Euraka! Counter found\n");
            PrintGraph(g, gsize);
            
            /*
            make a new graph one size bigger
            */
            new_g = (int *)malloc((gsize+1)*(gsize+1)*sizeof(int));
            if(new_g == NULL) exit(1);
            
            /*
            copy the old graph into the new graph leaving the last row
            and last column alone
            */
            CopyGraph(g, gsize, new_g, gsize+1);
            
            /*
            zero out the last column and last row
            */
            for(i=0; i<gsize+1; i++){
                ra1 = rand() % 2;
                if(ra1 == 0){
                    new_g[i*(gsize+1) + gsize] = 0;
                    new_g[gsize*(gsize+1) + i] = 0;
                }
                else{
                    new_g[i*(gsize+1) + gsize] = 1;
                    new_g[gsize*(gsize+1) + i] = 1;
                }

            }

            /*
            throw away the old graph and make new one
            */
            free(g);
            g = new_g;
            gsize++;

            /*
            reset the taboo list for the new graph
            */
            ban_s.clear();
            clearQ(ban_q);

            /*
            keep going
            */
            continue;
        
        }

        /*
        otherwise, random flip
        */
        best_count = BIGCOUNT;
        int key;
        size_t sz;

        /*
        unlike tabu_search_full, here we only
        flip the new edge, which is the last row
        amd last column
        */
        j = gsize - 1;
        for(i=0; i<gsize-1; i++){
            ra1 = rand() % 2;
            if(ra1 == 0){

                /*
                flip it
                */
                g[i*gsize + j] = 1 - g[i*gsize + j];
                count = CliqueCountPart(g, gsize);

                /*
                is it better and the i,j,count not tabu?
                */
                key = getKey(i, j);

                if(count <= best_count && ban_s.count(key) == 0){

                    if(count == best_count){
                        best_k.push_back(key);
                    }
                    else{
                        sz = best_k.size();
                        if(sz == 0){
                            best_k.push_back(key);
                        }
                        else{
                            best_k[sz-1] = key;
                            best_start = sz - 1;
                        }
                    }

                    best_count = count;

                }

                /*
                flip it back
                */
                g[i*gsize + j] = 1 - g[i*gsize + j];

            }
        }


        if(best_count == BIGCOUNT){
            printf("no best edge found, terminating\n");
            exit(1);
        }

        /*
        keep the best flip we saw
        */
        sz = best_k.size();
        ra1 = rand() % (sz - best_start);
        ra1 += best_start;
        key = best_k[ra1];
        best_i = getI(key);
        best_j = getJ(key);
        g[best_i*gsize + best_j] = 1 - g[best_i*gsize + best_j];


        /*
        tabu this graph configuration so that we do not visit
        it again
        */
        if(ban_q.size() == TABOOSIZE_PART){
            ban_s.erase(ban_q.front());
            ban_q.pop();
        }

        ban_q.push(key);
        ban_s.insert(key);

    
        printf("ce size: %d, best_count: %d, best edge: (%d, %d), new color: %d\n",
        gsize, best_count, best_i, best_j, g[best_i*gsize + best_j]);
        
        /*
        rinse and repeat
        */          
    
    }

}
Esempio n. 26
0
int main (int argc, char *argv[])
{
    char headerless;
    double obstime;

    char string[80];
    long seed=-1;

    float fval;
    unsigned char A,B,C,D;
    char help=0;
    uint_fast32_t i;


    /* set up default variables */
    strcpy(inpfile,"stdin");
    strcpy(outfile,"stdout");
    headerless=0;
    machine_id=telescope_id=0;
    machine_id=10;
    telescope_id=4;
    nchans=1024;
    nbits=2;
    tstart=56000.0;
    tsamp=64.0; // microseconds.. will be converted to seconds later
    fch1=1581.804688;
    foff=-0.390625;
    nifs=1;
    nbeams=1;
    ibeam=1;
    obstime=270.0;
    output=stdout;

    help=getB("--help","-h",argc,argv,0);
    obstime=getF("--tobs","-T",argc,argv,obstime);
    telescope_id=getI("--tid","",argc,argv,telescope_id);
    machine_id=getI("--bid","",argc,argv,machine_id);
    tsamp=getF("--tsamp","-t",argc,argv,tsamp);
    tstart=getF("--mjd","-m",argc,argv,tstart);
    fch1=getF("--fch1","-F",argc,argv,fch1);
    foff=getF("--foff","-f",argc,argv,foff);
    nbits=getI("--nbits","-b",argc,argv,nbits);
    nchans=getI("--nchans","-c",argc,argv,nchans);
    seed=getI("--seed","-S",argc,argv,seed);
    char test_mode=getB("--test","-0",argc,argv,0);
    strcpy(outfile,getS("--out","-o",argc,argv,"stdout"));
    strcpy(source_name,getS("--name","-s",argc,argv,"FAKE"));
    getArgs(&argc,argv);
    if (help || argc > 1){
        for(i=1; i < argc; i++)logerr("Unknown argument '%s'",argv[i]);
        fastfake_help();
    }

    logmsg("FASTFAKE - M.Keith 2014");


    time_t t0 = time(NULL);
    if (seed<0)seed=t0;

    mjk_rand_t *rnd = mjk_rand_init(seed);


    logmsg("tobs          = %lfs",obstime);
    logmsg("tsamp         = %lfus",tsamp);
    logmsg("mjdstart      = %lf",tstart);
    logmsg("freq chan 1   = %lfMHz",fch1);
    logmsg("freq offset   = %lfMHz",foff);
    logmsg("output nbits  = %d",nbits);
    logmsg("random seed   = %ld",seed);
    logmsg("output file   = '%s'",outfile);

    tsamp*=1e-6; // convert tsamp to us

    if(STREQ(outfile,"stdout")){
        output=stdout;
    } else{
        output=fopen(outfile,"w");
    }

    if (!headerless) {
        logmsg("write header");
        send_string("HEADER_START");
        send_string("source_name");
        send_string(source_name);
        send_int("machine_id",machine_id);
        send_int("telescope_id",telescope_id);
        send_int("data_type",1);
        send_double("fch1",fch1);
        send_double("foff",foff);
        send_int("nchans",nchans);
        send_int("nbits",nbits);
        send_int("nbeams",nbeams);
        send_int("ibeam",ibeam);
        send_double("tstart",tstart);
        send_double("tsamp",tsamp);
        send_int("nifs",nifs);
        if (nbits==8){
            send_char("signed",OSIGN);
        }
        send_string("HEADER_END");
    }

    int bits_per_sample = (nbits * nchans * nifs);
    if (bits_per_sample % 8 != 0){
        logerr("bits per sample is not a multiple of 8");
        exit(1);
    }


    int bytes_per_sample = bits_per_sample / 8.0;
    uint64_t nsamples = (uint64_t)(obstime/tsamp+0.5);

    logmsg("Generate %lld samples, %.3lf GiB",nsamples,nsamples*bytes_per_sample/pow(2,30));

    uint64_t onepercent = nsamples/100;
    int percent=0;
    unsigned char* buffer = (unsigned char*) malloc(sizeof(unsigned char)*bytes_per_sample);

    if (nbits==1 || nbits==2 || nbits==4 | nbits==8){
        // integer samples
        for(uint64_t samp = 0; samp < nsamples; samp++){
            if (samp%onepercent ==0){
                double t1=(double)(time(NULL)-t0)+1e-3;
                double bytespersec = samp*bytes_per_sample/t1;
                fprintf(stderr,"Complete: % 3d%%. Sample: % 9lld Real time % 6.1lfs, Sim time % 6.1lfs. Speed % 4.2lfMiB/s\r",percent,samp,t1,(double)samp*tsamp,bytespersec/pow(2,20));
                fflush(stderr);
                percent+=1;
            }
            mjk_rand_gauss_atleast(rnd,nchans);
            const int chanskip = 8/nbits;
            //#pragma omp parallel for schedule(dynamic,1)
            for(uint64_t chan = 0; chan < nchans; chan+=chanskip){
                switch(nbits){
                    case 1:
                        buffer[chan/8] = mjk_rand(rnd)&0xFF; 
                        break;
                    case 2:
                        fval = (mjk_rand_gauss(rnd)+1.5);
                        fval = fmax(fval,0);
                        fval = fmin(fval,3.0);
                        A = (unsigned char)(fval)&0x3;
                        fval = (mjk_rand_gauss(rnd)+1.5);
                        fval = fmax(fval,0);
                        fval = fmin(fval,3.0);
                        B = (unsigned char)(fval)&0x3 << 2;
                        fval = (mjk_rand_gauss(rnd)+1.5);
                        fval = fmax(fval,0);
                        fval = fmin(fval,3.0);
                        C = (unsigned char)(fval)&0x3 << 4;
                        fval = (mjk_rand_gauss(rnd)+1.5);
                        fval = fmax(fval,0);
                        fval = fmin(fval,3.0);
                        D = (unsigned char)(fval)&0x3 << 6;
                        buffer[chan/4]=A|B|C|D;
                        break;
                    case 4:
                        fval = (mjk_rand_gauss(rnd)*3.0+7.5);
                        fval = fmax(fval,0);
                        fval = fmin(fval,15.0);
                        A = (unsigned char)(fval)&0xF;
                        fval = (mjk_rand_gauss(rnd)*3.0+7.5);
                        fval = fmax(fval,0);
                        fval = fmin(fval,15.0);
                        B = ((unsigned char)(fval)&0xF)<<4;
                        buffer[chan/2] = A|B;
                        break;
                    case 8:
                        fval = (mjk_rand_gauss(rnd)*24.0+96.0); // more headroom.
                        fval = fmax(fval,0);
                        fval = fmin(fval,255.0);
                        buffer[chan] = (unsigned char)fval;
                        break;
                }
            }
            if(!test_mode)fwrite(buffer,sizeof(unsigned char),bytes_per_sample,output);
        }
    } else if (nbits==32){
        // float samples
        float* fbuf = (float*)buffer;
        for(uint64_t samp = 0; samp < nsamples; samp++){
            if (samp%onepercent ==0){
                double t1=(double)(time(NULL)-t0)+1e-3;
                double bytespersec = samp*bytes_per_sample/t1;
                fprintf(stderr,"Complete: % 3d%%. Sample: % 9lld Real time % 6.1lfs, Sim time % 6.1lfs. Speed % 4.2lfMiB/s\r",percent,samp,t1,(double)samp*tsamp,bytespersec/pow(2,20));
                fflush(stderr);
                percent+=1;
            }
            for(uint64_t chan = 0; chan < nchans; chan++){
                fbuf[chan] = mjk_rand_gauss(rnd);
            }
            if(!test_mode)fwrite(buffer,sizeof(unsigned char),bytes_per_sample,output);
        }
    }


    fprintf(stderr,"\n");
    free(buffer);
    mjk_rand_free(rnd);
    logmsg("Done!");
    fclose(output);

    return 0;
}