// Calculates the total probability flux leaving the domain at time t // This is simply the negative of the time derivative of the survival prob. // at time t [-dS(t')/dt' for t'=t]. Real GreensFunction1DRadAbs::flux_tot (Real t) const { Real root_n; const Real D(this->getD()); const Real v(this->getv()); const Real vexpo(-v*v*t/4.0/D - v*r0/2.0/D); const Real D2 = D*D; const Real v2Dv2D = v*v/4.0/D2; double sum = 0, term = 0, prev_term = 0; int n=1; do { if ( n >= MAX_TERMS ) { std::cerr << "Too many terms needed for GF1DRad::flux_tot. N: " << n << std::endl; break; } root_n = this->root_n(n); prev_term = term; term = (root_n * root_n + v2Dv2D) * Cn(root_n, t) * An(root_n) * Bn(root_n); n++; sum += term; } while (fabs(term/sum) > EPSILON*PDENS_TYPICAL || fabs(prev_term/sum) > EPSILON*PDENS_TYPICAL || n <= MIN_TERMS ); return 2.0*D*exp(vexpo)*sum; }
// Calculates the total probability flux leaving the domain at time t const Real FirstPassageGreensFunction1DRad::flux_tot (const Real t) const { Real An; double sum = 0, term = 0, prev_term = 0; const double D(this->getD()); int n=1; do { if ( n >= MAX_TERMEN ) { std::cerr << "Too many terms needed for GF1DRad::flux_tot. N: " << n << std::endl; break; } An = this->a_n(n); prev_term = term; term = An * An * Cn(An, t) * this->An(An) * Bn(An); n++; sum += term; } while (fabs(term/sum) > EPSILON*PDENS_TYPICAL || fabs(prev_term/sum) > EPSILON*PDENS_TYPICAL || n <= MIN_TERMEN ); return sum*2.0*D; }
// Calculates the probability of finding the particle inside the domain at // time t, the survival probability The domein is from -r to r (r0 is in // between!!) const Real FirstPassageGreensFunction1DRad::p_survival (const Real t) const { const Real D(this->getD()); THROW_UNLESS( std::invalid_argument, t >= 0.0 ); if (t == 0 || D == 0) { // if there was no time or no movement the particle was always // in the domain return 1.0; } Real An; Real sum = 0, term = 0, term_prev = 0; int n = 1; do { An = this->a_n(n); term_prev = term; term = Cn(An, t) * this->An(An) * Bn(An); sum += term; n++; } // Is 1.0 a good measure for the scale of probability or will this // fail at some point? while ( fabs(term/sum) > EPSILON*1.0 || fabs(term_prev/sum) > EPSILON*1.0 || n <= MIN_TERMEN); return 2.0*sum; }
uint32_t PrimeMinerShare::GetDifficulty() const { MemoryStream ms; base::WriteHeader(ProtocolWriter(ms).Ref()); HashValue h = Hash(ms); if (h.data()[31] < 0x80) Throw(CoinErr::MINER_REJECTED); BigInteger origin = HashValueToBigInteger(h) * PrimeChainMultiplier; PrimeTester tester; //!!!TODO move to some long-time scope return uint32_t(tester.ProbablePrimeChainTest(Bn(origin)).BestTypeLength().second * 0x1000000); }
/* последовательное применение полуочистителей Bn, Bn / 2, …, B2 сортирует произвольную битоническую последовательность.Эту операцию называют битоническим слиянием и обозначают Mn */ void Mn(long *elements, int k, int direction,int myrank,int nrank,int shift) { MPI_Status status; Bn(elements, k, direction); int child = myrank + shift; if (k>0 && child < nrank) { /* Запрашиваем первый свободный процесс */ /* Поскольку здесь не реализован диспечер задач, то это будет следующий по номеру */ shift <<= 1; /* Отдаём половину массива на обработку этому процессу */ MPI_Send(&k, 1, MPI_INT, child, DATA_TAG, MPI_COMM_WORLD); MPI_Send(&direction, 1, MPI_INT, child, DATA_TAG, MPI_COMM_WORLD); MPI_Send(&elements[1<<k], 1<<k, MPI_LONG, child, DATA_TAG, MPI_COMM_WORLD); MPI_Send(&shift, 1, MPI_INT, child, DATA_TAG, MPI_COMM_WORLD); /* Сами продолжим обработку */ Mn(elements,k-1,direction,myrank,nrank,shift); /* Получим обработанные элементы обратно */ MPI_Recv(&elements[1<<k], 1<<k, MPI_LONG, child, DATA_TAG, MPI_COMM_WORLD, &status); shift >>= 1; } else if (k>0) {