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(); }
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(); }
/** * * @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; }
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); } }
/*! 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 ; }
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); }
// 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)); }
/* * 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; }
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; } }
// 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(); }
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(); }
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(); }