Example #1
0
void RuntimeDyldMachOCRTPBase<Impl>::registerEHFrames() {

  for (int i = 0, e = UnregisteredEHFrameSections.size(); i != e; ++i) {
    EHFrameRelatedSections &SectionInfo = UnregisteredEHFrameSections[i];
    if (SectionInfo.EHFrameSID == RTDYLD_INVALID_SECTION_ID ||
        SectionInfo.TextSID == RTDYLD_INVALID_SECTION_ID)
      continue;
    SectionEntry *Text = &Sections[SectionInfo.TextSID];
    SectionEntry *EHFrame = &Sections[SectionInfo.EHFrameSID];
    SectionEntry *ExceptTab = nullptr;
    if (SectionInfo.ExceptTabSID != RTDYLD_INVALID_SECTION_ID)
      ExceptTab = &Sections[SectionInfo.ExceptTabSID];

    int64_t DeltaForText = computeDelta(Text, EHFrame);
    int64_t DeltaForEH = 0;
    if (ExceptTab)
      DeltaForEH = computeDelta(ExceptTab, EHFrame);

    uint8_t *P = EHFrame->getAddress();
    uint8_t *End = P + EHFrame->getSize();
    do {
      P = processFDE(P, DeltaForText, DeltaForEH);
    } while (P != End);

    MemMgr.registerEHFrames(EHFrame->getAddress(), EHFrame->getLoadAddress(),
                            EHFrame->getSize());
  }
  UnregisteredEHFrameSections.clear();
}
Example #2
0
void RuntimeDyldMachO::registerEHFrames() {

  if (!MemMgr)
    return;
  for (int i = 0, e = UnregisteredEHFrameSections.size(); i != e; ++i) {
    EHFrameRelatedSections &SectionInfo = UnregisteredEHFrameSections[i];
    if (SectionInfo.EHFrameSID == RTDYLD_INVALID_SECTION_ID ||
        SectionInfo.TextSID == RTDYLD_INVALID_SECTION_ID)
      continue;
    SectionEntry *Text = &Sections[SectionInfo.TextSID];
    SectionEntry *EHFrame = &Sections[SectionInfo.EHFrameSID];
    SectionEntry *ExceptTab = nullptr;
    if (SectionInfo.ExceptTabSID != RTDYLD_INVALID_SECTION_ID)
      ExceptTab = &Sections[SectionInfo.ExceptTabSID];

    intptr_t DeltaForText = computeDelta(Text, EHFrame);
    intptr_t DeltaForEH = 0;
    if (ExceptTab)
      DeltaForEH = computeDelta(ExceptTab, EHFrame);

    unsigned char *P = EHFrame->Address;
    unsigned char *End = P + EHFrame->Size;
    do {
      P = processFDE(P, DeltaForText, DeltaForEH);
    } while (P != End);

    MemMgr->registerEHFrames(EHFrame->Address, EHFrame->LoadAddress,
                             EHFrame->Size);
  }
  UnregisteredEHFrameSections.clear();
}
Example #3
0
/**
 * 
 * @param col
 * @param raw
 * @return 
 */
uint8_t AsciiFilter::findBestMatch(ADMImage *source,int col,int row,int &luma)
{
  int minDelta=0xfffffff;
  int candidate=-1;
  int stride=source->GetPitch (PLANAR_Y);
  uint8_t *p=source->GetReadPtr(PLANAR_Y)+col*REDUCE_WIDTH+row*REDUCE_HEIGHT*stride;
  // 1- create bitmask
  uint16_t bitMask[REDUCE_WIDTH*REDUCE_HEIGHT];
  createBitMask(bitMask,p,stride,luma);
  
  // 32..127
  for(int tries=32;tries<128;tries++)
    {
      int delta=computeDelta(tries,bitMask);
      if(delta<minDelta)
        {
          minDelta=delta;
          candidate=tries;
        }
    }
  if(candidate==-1) 
    {
      luma=128;
      return '*';
    }
  else 
    return candidate;
}
    inline typename UpscalerBase<Traits>::permtensor_t
    UpscalerBase<Traits>::upscaleEffectivePerm(const FluidInterface& fluid)
    {
	int num_cells = ginterf_.numberOfCells();
	// No source or sink.
	std::vector<double> src(num_cells, 0.0);
	// Just water.
	std::vector<double> sat(num_cells, 1.0);
	// Gravity.
	Dune::FieldVector<double, 3> gravity(0.0);
	// gravity[2] = -Dune::unit::gravity;

	permtensor_t upscaled_K(3, 3, (double*)0);
	for (int pdd = 0; pdd < Dimension; ++pdd) {
	    setupUpscalingConditions(ginterf_, bctype_, pdd, 1.0, 1.0, twodim_hack_, bcond_);
	    if (pdd == 0) {
		// Only on first iteration, since we do not change the
		// structure of the system, the way the flow solver is
		// implemented.
		flow_solver_.init(ginterf_, res_prop_, gravity, bcond_);
	    }

	    // Run pressure solver.
            bool same_matrix = (bctype_ != Fixed) && (pdd != 0);
	    flow_solver_.solve(fluid, sat, bcond_, src, residual_tolerance_,
                               linsolver_verbosity_, 
                               linsolver_type_, same_matrix,
                               linsolver_maxit_, linsolver_prolongate_factor_,
                               linsolver_smooth_steps_);
            double max_mod = flow_solver_.postProcessFluxes();
            std::cout << "Max mod = " << max_mod << std::endl;

	    // Compute upscaled K.
	    double Q[Dimension] =  { 0 };
	    switch (bctype_) {
	    case Fixed:
		Q[pdd] = computeAverageVelocity(flow_solver_.getSolution(), pdd, pdd);
		break;
	    case Linear:
	    case Periodic:
		for (int i = 0; i < Dimension; ++i) {
		    Q[i] = computeAverageVelocity(flow_solver_.getSolution(), i, pdd);
		}
		break;
	    default:
		OPM_THROW(std::runtime_error, "Unknown boundary type: " << bctype_);
	    }
	    double delta = computeDelta(pdd);
	    for (int i = 0; i < Dimension; ++i) {
		upscaled_K(i, pdd) = Q[i] * delta;
	    }
	}
	return upscaled_K;
    }
Example #5
0
void ScaleControl3D::drag(osg::Vec3 coord, osg::Vec2 scoord) {
	osg::Vec3 dif = computeDelta(coord);
	osg::Matrix deltaMatrix = osg::Matrix::scale(osg::Vec3(1,1,1)+dif);
    _node->setMatrix(deltaMatrix * _sourceMatrix);
	if (_target.valid()) {
		osg::Vec3d newscale = _scaleSource + dif;
		_target->set( newscale );
	} else if (_targetM.valid()) {
		osg::Matrixd newmat = _matSource * osg::Matrix::scale(osg::Vec3(1,1,1)+dif);
        _targetM->set(newmat);
	}
}
Example #6
0
/*!
	
  Initialization of the tracking. The line is defined thanks to the
  coordinates of two points.

  \param I : Image in which the line appears.
  \param ip1 : Coordinates of the first point.
  \param ip2 : Coordinates of the second point.
*/
void
vpMeLine::initTracking(const vpImage<unsigned char> &I,
                       const vpImagePoint &ip1,
                       const vpImagePoint &ip2)
{
  vpCDEBUG(1) <<" begin vpMeLine::initTracking()"<<std::endl ;

  int i1s, j1s, i2s, j2s;

  i1s = vpMath::round( ip1.get_i() );
  i2s = vpMath::round( ip2.get_i() );
  j1s = vpMath::round( ip1.get_j() );
  j2s = vpMath::round( ip2.get_j() );

  try{

    //  1. On fait ce qui concerne les droites (peut etre vide)
    {
      // Points extremites
      PExt[0].ifloat = (float)ip1.get_i() ;
      PExt[0].jfloat = (float)ip1.get_j() ;
      PExt[1].ifloat = (float)ip2.get_i() ;
      PExt[1].jfloat = (float)ip2.get_j() ;

      double angle_ = atan2((double)(i1s-i2s),(double)(j1s-j2s)) ;
      a = cos(angle_) ;
      b = sin(angle_) ;

      // Real values of a, b can have an other sign. So to get the good values
      // of a and b in order to initialise then c, we call track(I) just below

      computeDelta(delta,i1s,j1s,i2s,j2s) ;
      delta_1 = delta;

      //      vpTRACE("a: %f b: %f c: %f -b/a: %f delta: %f", a, b, c, -(b/a), delta);

      sample(I) ;

    }
    //  2. On appelle ce qui n'est pas specifique
    {
      vpMeTracker::initTracking(I) ;
    }
    // Call track(I) to give the good sign to a and b and to initialise c which can be used for the display
    track(I);
  }
  catch(...)
  {
    vpERROR_TRACE("Error caught") ;
    throw ;
  }
  vpCDEBUG(1) <<" end vpMeLine::initTracking()"<<std::endl ;
}
Example #7
0
void deltaForChange(change& possibleChange, const std::vector<int>& currentPermutation, const Rbyte* rawDist, const std::vector<double>& levels)
{
	R_xlen_t swap1 = possibleChange.swap1, swap2 = possibleChange.swap2;
	std::vector<int> deltaComponents(levels.size());
	R_xlen_t n = currentPermutation.size();
	if(possibleChange.isMove)
	{
		possibleChange.delta = computeMoveDelta(deltaComponents, swap1, swap2, currentPermutation, rawDist, n, levels);
	}
	else
	{
		possibleChange.delta = computeDelta(currentPermutation, swap1, swap2, rawDist, levels, deltaComponents);
	}
}
void computeOdometry(
    double walkStepX1, double walkStepY1, double walkStepTheta1, 
    double walkStepX2, double walkStepY2, double walkStepTheta2, 
    bool isLeftSupportFoot, 
    LWPR_Object* modelX, LWPR_Object* modelY, LWPR_Object* modelTheta,
    double& deltaX, double& deltaY, double& deltaTheta)
{
    //Compute the two last delta
    double deltaX1 = 0.0;
    double deltaY1 = 0.0;
    double deltaTheta1 = 0.0;
    double deltaX2 = 0.0;
    double deltaY2 = 0.0;
    double deltaTheta2 = 0.0;
    computeDelta(
        walkStepX1, walkStepY1, walkStepTheta1, 
        isLeftSupportFoot, 
        deltaX1, deltaY1, deltaTheta1);
    computeDelta(
        walkStepX2, walkStepY2, walkStepTheta2, 
        !isLeftSupportFoot, 
        deltaX2, deltaY2, deltaTheta2);

    //Compute displacement correction
    Eigen::VectorXd in(7);
    in << 
        deltaX1,
        deltaY1,
        deltaTheta1,
        deltaX2,
        deltaY2,
        deltaTheta2,
        (int)isLeftSupportFoot;
    deltaX = modelX->predict(in, 0.0)(0);
    deltaY = modelY->predict(in, 0.0)(0);
    deltaTheta = modelTheta->predict(in, 0.0)(0);
}
Example #9
0
// FIXME: this test no longer valid -- does not take minimum scale contribution into account
void CubicIntersection_ComputeDeltaTest() {
    SkASSERT(deltaTestSetLen == deltaTestSetTLen);
    SkASSERT(expectedTLen == deltaTestSetTLen);
    for (size_t index = 0; index < deltaTestSetLen; index += 2) {
        const Cubic& c1 = deltaTestSet[index];
        const Cubic& c2 = deltaTestSet[index + 1];
        double t1 = deltaTestSetT[index];
        double t2 = deltaTestSetT[index + 1];
        double d1, d2;
        computeDelta(c1, t1, 1, c2, t2, 1, d1, d2);
        SkASSERT(approximately_equal(t1 + d1, expectedT[index])
            || approximately_equal(t1 - d1, expectedT[index]));
        SkASSERT(approximately_equal(t2 + d2, expectedT[index + 1])
            || approximately_equal(t2 - d2, expectedT[index + 1]));
    }
}
static Matrix computeCtcInputDeltas(const std::string& costFunctionName,
    double costFunctionWeight, const Matrix& inputActivations, const LabelVector& inputLabels,
    const IndexVector& inputTimesteps)
{
    auto costFunction = CostFunctionFactory::create(costFunctionName);

    Bundle bundle;

    bundle["outputActivations"] = MatrixVector({inputActivations});
    bundle["referenceLabels"]   = inputLabels;
    bundle["inputTimesteps"]    = inputTimesteps;

    costFunction->computeDelta(bundle);

    auto& outputDeltasVector = bundle["outputDeltas"].get<MatrixVector>();

    auto& outputDeltas = outputDeltasVector.front();

    return apply(outputDeltas, matrix::Multiply(costFunctionWeight));
}
Example #11
0
/*
 * Apply changes represented by GenericXLogState to the actual buffers,
 * and emit a generic xlog record.
 */
XLogRecPtr
GenericXLogFinish(GenericXLogState *state)
{
	XLogRecPtr	lsn;
	int			i;

	if (state->isLogged)
	{
		/* Logged relation: make xlog record in critical section. */
		XLogBeginInsert();

		START_CRIT_SECTION();

		for (i = 0; i < MAX_GENERIC_XLOG_PAGES; i++)
		{
			PageData   *pageData = &state->pages[i];
			Page		page;
			PageHeader	pageHeader;

			if (BufferIsInvalid(pageData->buffer))
				continue;

			page = BufferGetPage(pageData->buffer);
			pageHeader = (PageHeader) pageData->image;

			if (pageData->flags & GENERIC_XLOG_FULL_IMAGE)
			{
				/*
				 * A full-page image does not require us to supply any xlog
				 * data.  Just apply the image, being careful to zero the
				 * "hole" between pd_lower and pd_upper in order to avoid
				 * divergence between actual page state and what replay would
				 * produce.
				 */
				memcpy(page, pageData->image, pageHeader->pd_lower);
				memset(page + pageHeader->pd_lower, 0,
					   pageHeader->pd_upper - pageHeader->pd_lower);
				memcpy(page + pageHeader->pd_upper,
					   pageData->image + pageHeader->pd_upper,
					   BLCKSZ - pageHeader->pd_upper);

				XLogRegisterBuffer(i, pageData->buffer,
								   REGBUF_FORCE_IMAGE | REGBUF_STANDARD);
			}
			else
			{
				/*
				 * In normal mode, calculate delta and write it as xlog data
				 * associated with this page.
				 */
				computeDelta(pageData, page, (Page) pageData->image);

				/* Apply the image, with zeroed "hole" as above */
				memcpy(page, pageData->image, pageHeader->pd_lower);
				memset(page + pageHeader->pd_lower, 0,
					   pageHeader->pd_upper - pageHeader->pd_lower);
				memcpy(page + pageHeader->pd_upper,
					   pageData->image + pageHeader->pd_upper,
					   BLCKSZ - pageHeader->pd_upper);

				XLogRegisterBuffer(i, pageData->buffer, REGBUF_STANDARD);
				XLogRegisterBufData(i, pageData->delta, pageData->deltaLen);
			}
		}

		/* Insert xlog record */
		lsn = XLogInsert(RM_GENERIC_ID, 0);

		/* Set LSN and mark buffers dirty */
		for (i = 0; i < MAX_GENERIC_XLOG_PAGES; i++)
		{
			PageData   *pageData = &state->pages[i];

			if (BufferIsInvalid(pageData->buffer))
				continue;
			PageSetLSN(BufferGetPage(pageData->buffer), lsn);
			MarkBufferDirty(pageData->buffer);
		}
		END_CRIT_SECTION();
	}
	else
	{
		/* Unlogged relation: skip xlog-related stuff */
		START_CRIT_SECTION();
		for (i = 0; i < MAX_GENERIC_XLOG_PAGES; i++)
		{
			PageData   *pageData = &state->pages[i];

			if (BufferIsInvalid(pageData->buffer))
				continue;
			memcpy(BufferGetPage(pageData->buffer),
				   pageData->image,
				   BLCKSZ);
			/* We don't worry about zeroing the "hole" in this case */
			MarkBufferDirty(pageData->buffer);
		}
		END_CRIT_SECTION();
		/* We don't have a LSN to return, in this case */
		lsn = InvalidXLogRecPtr;
	}

	for (i = 0; i < MAX_GENERIC_XLOG_PAGES; i++)
		pfree(state->pages[i].image);
	pfree(state);

	return lsn;
}
Example #12
0
SEXP saltt(SEXP Ssequences, SEXP seqdim, SEXP lenS, SEXP indelS,
		SEXP alphasizeS, SEXP costsS, SEXP normS, SEXP optimS, SEXP pidS, SEXP maxpassS, SEXP retS, SEXP logoddS) {

	SEXP ans, scostmat;
	int nseq = INTEGER(seqdim)[0];
	double pid = REAL(pidS)[0];
	PROTECT(ans = allocVector(REALSXP, nseq * nseq));
	double * distmatrix = REAL(ans);
	//nb �tats
	int alphasize = INTEGER(alphasizeS)[0];
	int optim = INTEGER(optimS)[0];
	int ret = INTEGER(retS)[0];
	int logoddmode = INTEGER(logoddS)[0];
	PROTECT(scostmat = allocVector(REALSXP, (alphasize * alphasize)));
	double * salttcost = REAL(scostmat);

	int i, is, js, liseq, ljseq, fmatsize;
	//longueur des s�quences m=i, n=j

	//normalisation?
	int norm = INTEGER(normS)[0];
	//Nombre de s�quence
	//nb colonnes des s�quences
	int maxlen = INTEGER(seqdim)[1];
	//Matrice des s�quences
	int* sequences = INTEGER(Ssequences);
	//Tailles des s�quences
	int* slen = INTEGER(lenS);
	//indel
	double indel = REAL(indelS)[0];
	double * fmat;
	double * tbmat;
	int maxpass= INTEGER(maxpassS)[0];
	//Matrice des co�ts de substitutions
	double* scost = REAL(costsS);

	double *previousmatrix = new double[alphasize * alphasize];
	double delta = 1;

	std::stack<Alignement>* stackAligne;
	stackAligne = new std::stack<Alignement>;

	SEXP Fmat, TBmat;

	fmatsize=maxlen+1;
    PROTECT(Fmat = allocVector(REALSXP, (fmatsize*fmatsize)));
    fmat=REAL(Fmat);

    PROTECT(TBmat = allocVector(REALSXP, (fmatsize*fmatsize)));
    tbmat=REAL(TBmat);



	for (is = 0; is < nseq; is++) {
		liseq = slen[is] + 1;
		for (js = is+1; js < nseq; js++) {
			ljseq = slen[js] + 1;
			//if(js!=is) {
				Alignement align = Alignement(is, js, 0, liseq, ljseq, maxlen);
				stackAligne->push(align);
			//}
		}
	}

	//REprintf("stack size = %d", stackAligne->size());

	Salttseq seq1 = Salttseq(norm, nseq, slen, maxlen, &indel, alphasize, scost,
			distmatrix, stackAligne, sequences, salttcost, fmat, tbmat, fmatsize, pid, logoddmode);
	int pass = 0;

	if (optim == 1) {
		while (delta > 0.0001) {
			if(pass==maxpass) {
				REprintf("\nWe have reached the maximum number of iteration (%d). We stop here.\n", pass);
				break;
			}



			for (i = 0; i < alphasize * alphasize; i++) {
				previousmatrix[i] = salttcost[i];
			}

			if(seq1.computeDistances(1)==-1) {
				REprintf("\n************************\nWarning\n************************\n");
				REprintf("No alignement has a PID>%f, must stop here\n", pid);
				delta = 0;
			}
			/*REprintf("New cost matrix, after pass #%d \n", pass);
			seq1.printsalttmatrix();
			REprintf("indel = %f\n", indel);
			*/
			delta = computeDelta(previousmatrix, salttcost, alphasize);
			REprintf("\ndelta = %f\n", delta);
			pass++;
		}

		REprintf("Final optimal matching on all sequences\n");
		for (is = 0; is < nseq; is++) {
				liseq = slen[is] + 1;
				for (js = is + 1; js < nseq; js++) {
					ljseq = slen[js] + 1;
					Alignement align = Alignement(is, js, 0, liseq, ljseq, maxlen);
					stackAligne->push(align);
				}
			}

		seq1.computeDistances(0);
	} else {
		seq1.computeDistances(0);
	}
	UNPROTECT(4);
	delete previousmatrix;
	if(ret==1) {
		return ans;
	}
	else {
		return scostmat;
	}
}
Example #13
0
// this flavor approximates the cubics with quads to find the intersecting ts
// OPTIMIZE: if this strategy proves successful, the quad approximations, or the ts used
// to create the approximations, could be stored in the cubic segment
// FIXME: this strategy needs to intersect the convex hull on either end with the opposite to
// account for inset quadratics that cause the endpoint intersection to avoid detection
// the segments can be very short -- the length of the maximum quadratic error (precision)
// FIXME: this needs to recurse on itself, taking a range of T values and computing the new
// t range ala is linear inner. The range can be figured by taking the dx/dy and determining
// the fraction that matches the precision. That fraction is the change in t for the smaller cubic.
static bool intersect2(const Cubic& cubic1, double t1s, double t1e, const Cubic& cubic2,
        double t2s, double t2e, double precisionScale, Intersections& i) {
    Cubic c1, c2;
    sub_divide(cubic1, t1s, t1e, c1);
    sub_divide(cubic2, t2s, t2e, c2);
    SkTDArray<double> ts1;
    cubic_to_quadratics(c1, calcPrecision(c1) * precisionScale, ts1);
    SkTDArray<double> ts2;
    cubic_to_quadratics(c2, calcPrecision(c2) * precisionScale, ts2);
    double t1Start = t1s;
    int ts1Count = ts1.count();
    for (int i1 = 0; i1 <= ts1Count; ++i1) {
        const double tEnd1 = i1 < ts1Count ? ts1[i1] : 1;
        const double t1 = t1s + (t1e - t1s) * tEnd1;
        Cubic part1;
        sub_divide(cubic1, t1Start, t1, part1);
        Quadratic q1;
        demote_cubic_to_quad(part1, q1);
  //      start here;
        // should reduceOrder be looser in this use case if quartic is going to blow up on an
        // extremely shallow quadratic?
        Quadratic s1;
        int o1 = reduceOrder(q1, s1);
        double t2Start = t2s;
        int ts2Count = ts2.count();
        for (int i2 = 0; i2 <= ts2Count; ++i2) {
            const double tEnd2 = i2 < ts2Count ? ts2[i2] : 1;
            const double t2 = t2s + (t2e - t2s) * tEnd2;
            Cubic part2;
            sub_divide(cubic2, t2Start, t2, part2);
            Quadratic q2;
            demote_cubic_to_quad(part2, q2);
            Quadratic s2;
            double o2 = reduceOrder(q2, s2);
            Intersections locals;
            if (o1 == 3 && o2 == 3) {
                intersect2(q1, q2, locals);
            } else if (o1 <= 2 && o2 <= 2) {
                locals.fUsed = intersect((const _Line&) s1, (const _Line&) s2, locals.fT[0],
                        locals.fT[1]);
            } else if (o1 == 3 && o2 <= 2) {
                intersect(q1, (const _Line&) s2, locals);
            } else {
                SkASSERT(o1 <= 2 && o2 == 3);
                intersect(q2, (const _Line&) s1, locals);
                for (int s = 0; s < locals.fUsed; ++s) {
                    SkTSwap(locals.fT[0][s], locals.fT[1][s]);
                }
            }
            for (int tIdx = 0; tIdx < locals.used(); ++tIdx) {
                double to1 = t1Start + (t1 - t1Start) * locals.fT[0][tIdx];
                double to2 = t2Start + (t2 - t2Start) * locals.fT[1][tIdx];
    // if the computed t is not sufficiently precise, iterate
                _Point p1, p2;
                xy_at_t(cubic1, to1, p1.x, p1.y);
                xy_at_t(cubic2, to2, p2.x, p2.y);
                if (p1.approximatelyEqual(p2)) {
                    i.insert(i.swapped() ? to2 : to1, i.swapped() ? to1 : to2);
                } else {
                    double dt1, dt2;
                    computeDelta(cubic1, to1, (t1e - t1s), cubic2, to2, (t2e - t2s), dt1, dt2);
                    double scale = precisionScale;
                    if (dt1 > 0.125 || dt2 > 0.125) {
                        scale /= 2;
                        SkDebugf("%s scale=%1.9g\n", __FUNCTION__, scale);
                    }
#if SK_DEBUG
                    ++debugDepth;
                    assert(debugDepth < 10);
#endif
                    i.swap();
                    intersect2(cubic2, SkTMax(to2 - dt2, 0.), SkTMin(to2 + dt2, 1.),
                            cubic1, SkTMax(to1 - dt1, 0.), SkTMin(to1 + dt1, 1.), scale, i);
                    i.swap();
#if SK_DEBUG
                    --debugDepth;
#endif
                }
            }
            t2Start = t2;
        }
        t1Start = t1;
    }
    return i.intersected();
}
Example #14
0
void arsaRawParallel(arsaRawArgs& args)
{
	long n = args.n;
	Rbyte* rawDist = args.rawDist;
	std::vector<double>& levels = args.levels;
	double cool = args.cool;
	double temperatureMin = args.temperatureMin;
	if(temperatureMin <= 0)
	{
		throw std::runtime_error("Input temperatureMin must be positive");
	}
	
	long nReps = args.nReps;
	std::vector<int>& permutation = args.permutation;
	std::function<void(unsigned long, unsigned long)> progressFunction = args.progressFunction;
	bool randomStart = args.randomStart;

	int maxMove = args.maxMove;
	if(maxMove < 0)
	{
		throw std::runtime_error("Input maxMove must be non-negative");
	}

	double effortMultiplier = args.effortMultiplier;
	if(effortMultiplier <= 0)
	{
		throw std::runtime_error("Input effortMultiplier must be positive");
	}

	permutation.resize(n);
	if(n == 1)
	{
		permutation[0] = 0;
		return;
	}
	else if(n < 1)
	{
		throw std::runtime_error("Input n must be positive");
	}

	//We skip the initialisation of D, R1 and R2 from arsa.f, and the computation of asum. 
	//Next the original arsa.f code creates nReps random permutations, and holds them all at once. This doesn't seem necessary, we create them one at a time and discard them
	double zbestAllReps = -std::numeric_limits<double>::infinity();
	//A copy of the best permutation found
	std::vector<int> bestPermutationThisRep(n);
	//We use this to build the random permutations
	std::vector<int> consecutive(n);
	for(R_xlen_t i = 0; i < n; i++) consecutive[i] = (int)i;
	std::vector<int> deltaComponents(levels.size());
	//We're doing lots of simulation, so we use the old-fashioned approach to dealing with Rs random number generation
	GetRNGstate();

	std::vector<change> stackOfChanges;
	std::vector<bool> dirty(n, false);
	for(int repCounter = 0; repCounter < nReps; repCounter++)
	{
		//create the random permutation, if we decided to use a random initial permutation
		if(randomStart)
		{
			for(R_xlen_t i = 0; i < n; i++)
			{
				double rand = unif_rand();
				R_xlen_t index = (R_xlen_t)(rand*(n-i));
				if(index == n-i) index--;
				bestPermutationThisRep[i] = consecutive[index];
				std::swap(consecutive[index], *(consecutive.rbegin()+i));
			}
		}
		else
		{
			for(R_xlen_t i = 0; i < n; i++)
			{
				bestPermutationThisRep[i] = consecutive[i];
			}
		}
		//calculate value of z
		double z = 0;
		for(R_xlen_t i = 0; i < n-1; i++)
		{
			R_xlen_t k = bestPermutationThisRep[i];
			for(R_xlen_t j = i+1; j < n; j++)
			{
				R_xlen_t l = bestPermutationThisRep[j];
				z += (j-i) * levels[rawDist[l*n + k]];
			}
		}
		double zbestThisRep = z;
		double temperatureMax = 0;
		//Now try 5000 random swaps
		for(R_xlen_t swapCounter = 0; swapCounter < (R_xlen_t)(5000*effortMultiplier); swapCounter++)
		{
			R_xlen_t swap1, swap2;
			getPairForSwap(n, swap1, swap2);
			double delta = computeDelta(bestPermutationThisRep, swap1, swap2, rawDist, levels, deltaComponents);
			if(delta < 0)
			{
				if(fabs(delta) > temperatureMax) temperatureMax = fabs(delta);
			}
		}
		double temperature = temperatureMax;
		std::vector<int> currentPermutation = bestPermutationThisRep;
		int nloop = (int)((log(temperatureMin) - log(temperatureMax)) / log(cool));
		long totalSteps = (long)(nloop * 100 * n * effortMultiplier);
		long done = 0;
		//Rcpp::Rcout << "Steps needed: " << nloop << std::endl;
		for(R_xlen_t idk = 0; idk < nloop; idk++)
		{
			//Rcpp::Rcout << "Temp = " << temperature << std::endl;
			for(R_xlen_t k = 0; k < (R_xlen_t)(100*n*effortMultiplier); k++)
			{
				R_xlen_t swap1, swap2;
				//swap
				if(unif_rand() <= 0.5)
				{
					getPairForSwap(n, swap1, swap2);
					change newChange;
					newChange.isMove = false;
					newChange.swap1 = swap1; newChange.swap2 = swap2;

					if(dirty[swap1] || dirty[swap2])
					{
						#pragma omp parallel for
						for(std::vector<change>::iterator i = stackOfChanges.begin(); i != stackOfChanges.end(); i++)
						{
							deltaForChange(*i, currentPermutation, rawDist, levels);
						}
						for(std::vector<change>::iterator i = stackOfChanges.begin(); i != stackOfChanges.end(); i++)
						{
							makeChange(*i, currentPermutation, rawDist, levels, z, zbestThisRep, bestPermutationThisRep, temperature);
						}
						done += stackOfChanges.size();
						progressFunction(done, totalSteps);
						stackOfChanges.clear();
						std::fill(dirty.begin(), dirty.end(), false);
					}
					else dirty[swap1] = dirty[swap2] = true;
					stackOfChanges.push_back(newChange);
				}
				//insertion
				else
				{
					getPairForMove(n, swap1, swap2, maxMove);
					bool canDefer = true;
					for(R_xlen_t i = std::min(swap1, swap2); i != std::max(swap1, swap2)+1; i++) canDefer &= !dirty[i];
					change newChange;
					newChange.isMove = true;
					newChange.swap1 = swap1; 
					newChange.swap2 = swap2;
					if(canDefer)
					{
						std::fill(dirty.begin() + std::min(swap1, swap2), dirty.begin() + std::max(swap1, swap2)+1, true);
					}
					else
					{
						#pragma omp parallel for
						for(std::vector<change>::iterator i = stackOfChanges.begin(); i != stackOfChanges.end(); i++)
						{
							deltaForChange(*i, currentPermutation, rawDist, levels);
						}
						for(std::vector<change>::iterator i = stackOfChanges.begin(); i != stackOfChanges.end(); i++)
						{
							makeChange(*i, currentPermutation, rawDist, levels, z, zbestThisRep, bestPermutationThisRep, temperature);
						}

						done += stackOfChanges.size();
						progressFunction(done, totalSteps);
						stackOfChanges.clear();
						std::fill(dirty.begin(), dirty.end(), false);
					}
					stackOfChanges.push_back(newChange);
				}
			}
			#pragma omp parallel for
			for(std::vector<change>::iterator i = stackOfChanges.begin(); i != stackOfChanges.end(); i++)
			{
				deltaForChange(*i, currentPermutation, rawDist, levels);
			}
			for(std::vector<change>::iterator i = stackOfChanges.begin(); i != stackOfChanges.end(); i++)
			{
				makeChange(*i, currentPermutation, rawDist, levels, z, zbestThisRep, bestPermutationThisRep, temperature);
			}

			done += stackOfChanges.size();
			progressFunction(done, totalSteps);
			stackOfChanges.clear();
			std::fill(dirty.begin(), dirty.end(), false);
			temperature *= cool;
		}
		if(zbestThisRep > zbestAllReps)
		{
			zbestAllReps = zbestThisRep;
			permutation.swap(bestPermutationThisRep);
		}
	}
	PutRNGstate();
}
Example #15
0
void arsaRaw(arsaRawArgs& args)
{
	long n = args.n;
	Rbyte* rawDist = args.rawDist;
	std::vector<double>& levels = args.levels;
	double cool = args.cool;
	double temperatureMin = args.temperatureMin;
	if(temperatureMin <= 0)
	{
		throw std::runtime_error("Input temperatureMin must be positive");
	}
	
	long nReps = args.nReps;
	std::vector<int>& permutation = args.permutation;
	std::function<void(unsigned long, unsigned long)> progressFunction = args.progressFunction;
	bool randomStart = args.randomStart;

	int maxMove = args.maxMove;
	if(maxMove < 0)
	{
		throw std::runtime_error("Input maxMove must be non-negative");
	}

	double effortMultiplier = args.effortMultiplier;
	if(effortMultiplier <= 0)
	{
		throw std::runtime_error("Input effortMultiplier must be positive");
	}

	permutation.resize(n);
	if(n == 1)
	{
		permutation[0] = 0;
		return;
	}
	else if(n < 1)
	{
		throw std::runtime_error("Input n must be positive");
	}
	//We skip the initialisation of D, R1 and R2 from arsa.f, and the computation of asum. 
	//Next the original arsa.f code creates nReps random permutations, and holds them all at once. This doesn't seem necessary, we create them one at a time and discard them
	double zbestAllReps = -std::numeric_limits<double>::infinity();
	//A copy of the best permutation found
	std::vector<int> bestPermutationThisRep(n);
	//We use this to build the random permutations
	std::vector<int> consecutive(n);
	for(R_xlen_t i = 0; i < n; i++) consecutive[i] = (int)i;
	std::vector<int> deltaComponents(levels.size());
	//We're doing lots of simulation, so we use the old-fashioned approach to dealing with Rs random number generation
	GetRNGstate();

	for(int repCounter = 0; repCounter < nReps; repCounter++)
	{
		//create the random permutation, if we decided to use a random initial permutation
		if(randomStart)
		{
			for(R_xlen_t i = 0; i < n; i++)
			{
				double rand = unif_rand();
				R_xlen_t index = (R_xlen_t)(rand*(n-i));
				if(index == n-i) index--;
				bestPermutationThisRep[i] = consecutive[index];
				std::swap(consecutive[index], *(consecutive.rbegin()+i));
			}
		}
		else
		{
			for(R_xlen_t i = 0; i < n; i++)
			{
				bestPermutationThisRep[i] = consecutive[i];
			}
		}
		//calculate value of z
		double z = 0;
		for(R_xlen_t i = 0; i < n-1; i++)
		{
			R_xlen_t k = bestPermutationThisRep[i];
			for(R_xlen_t j = i+1; j < n; j++)
			{
				R_xlen_t l = bestPermutationThisRep[j];
				z += (j-i) * levels[rawDist[l*n + k]];
			}
		}
		double zbestThisRep = z;
		double temperatureMax = 0;
		//Now try 5000 random swaps
		for(R_xlen_t swapCounter = 0; swapCounter < (R_xlen_t)(5000*effortMultiplier); swapCounter++)
		{
			R_xlen_t swap1, swap2;
			getPairForSwap(n, swap1, swap2);
			double delta = computeDelta(bestPermutationThisRep, swap1, swap2, rawDist, levels, deltaComponents);
			if(delta < 0)
			{
				if(fabs(delta) > temperatureMax) temperatureMax = fabs(delta);
			}
		}
		double temperature = temperatureMax;
		std::vector<int> currentPermutation = bestPermutationThisRep;
		int nloop = (int)((log(temperatureMin) - log(temperatureMax)) / log(cool));
		long totalSteps = (long)(nloop * 100 * n * effortMultiplier);
		long done = 0;
		long threadZeroCounter = 0;
		//Rcpp::Rcout << "Steps needed: " << nloop << std::endl;
		for(R_xlen_t idk = 0; idk < nloop; idk++)
		{
			//Rcpp::Rcout << "Temp = " << temperature << std::endl;
			for(R_xlen_t k = 0; k < (R_xlen_t)(100*n*effortMultiplier); k++)
			{
				R_xlen_t swap1, swap2;
				//swap
				if(unif_rand() <= 0.5)
				{
					getPairForSwap(n, swap1, swap2);
					double delta = computeDelta(currentPermutation, swap1, swap2, rawDist, levels, deltaComponents);
					if(delta > -1e-8)
					{
						z += delta;
						std::swap(currentPermutation[swap1], currentPermutation[swap2]);
						if(z > zbestThisRep)
						{
							zbestThisRep = z;
							bestPermutationThisRep = currentPermutation;
						}
					}
					else
					{
						if(unif_rand() <= exp(delta / temperature))
						{
							z += delta;
							std::swap(currentPermutation[swap1], currentPermutation[swap2]);
						}
					}
				}
				//insertion
				else
				{
					getPairForMove(n, swap1, swap2, maxMove);
					double delta = computeMoveDelta(deltaComponents, swap1, swap2, currentPermutation, rawDist, n, levels);
					int permutedSwap1 = currentPermutation[swap1];
					if(delta > -1e-8 || unif_rand() <= exp(delta / temperature))
					{
						z += delta;
						if(swap2 > swap1)
						{
							for(R_xlen_t i = swap1; i < swap2; i++)
							{
								currentPermutation[i] = currentPermutation[i+1];
							}
							currentPermutation[swap2] = (int)permutedSwap1;
						}
						else
						{
							for(R_xlen_t i = swap1; i > swap2; i--)
							{
								currentPermutation[i] = currentPermutation[i-1];
							}
							currentPermutation[swap2] = (int)permutedSwap1; 
						}
					}
					if(delta > -1e-8 && z > zbestThisRep)
					{
						bestPermutationThisRep = currentPermutation;
						zbestThisRep = z;
					}
				}
				done++;
				threadZeroCounter++;
				if(threadZeroCounter % 100 == 0)
				{
					progressFunction(done, totalSteps);
				}
			}
			temperature *= cool;
		}
		if(zbestThisRep > zbestAllReps)
		{
			zbestAllReps = zbestThisRep;
			permutation.swap(bestPermutationThisRep);
		}
	}
	PutRNGstate();
}