10 #ifdef DROPPINGTHISINRPACKAGE
11 #include <RcppEigen.h>
14 #include <Eigen/Dense>
25 namespace resamplers {
41 template<
size_t nparts,
size_t dimx,
typename float_t >
47 using ssv = Eigen::Matrix<float_t,dimx,1>;
64 rbase(
unsigned long seed);
82 template<
size_t nparts,
size_t dimx,
typename float_t>
84 : m_gen{
static_cast<std::uint32_t
>(
85 std::chrono::high_resolution_clock::now().time_since_epoch().count()
91 template<
size_t nparts,
size_t dimx,
typename float_t>
93 : m_gen{
static_cast<std::uint32_t
>(seed)}
108 template<
size_t nparts,
size_t dimx,
typename float_t>
114 using ssv = Eigen::Matrix<float_t,dimx,1>;
145 template<
size_t nparts,
size_t dimx,
typename float_t>
147 :
rbase<nparts, dimx, float_t>(seed)
152 template<
size_t nparts,
size_t dimx,
typename float_t>
162 float_t m = *std::max_element(oldLogUnNormWts.begin(), oldLogUnNormWts.end());
163 std::transform(oldLogUnNormWts.begin(), oldLogUnNormWts.end(), w.begin(),
164 [&m](float_t& d) -> float_t { return std::exp( d - m ); } );
165 std::discrete_distribution<> idxSampler(w.begin(), w.end());
171 unsigned int whichPart;
172 for(
size_t part = 0; part < nparts; ++part)
174 whichPart = idxSampler(this->m_gen);
175 tmpPartics[part] = oldParts[whichPart];
179 oldParts = std::move(tmpPartics);
180 std::fill(oldLogUnNormWts.begin(), oldLogUnNormWts.end(), 0.0);
195 template<
size_t nparts,
size_t dimsampledx,
typename cfModT,
typename float_t>
201 using ssv = Eigen::Matrix<float_t,dimsampledx,1>;
237 template<
size_t nparts,
size_t dimsampledx,
typename cfModT,
typename float_t>
239 : m_gen{
static_cast<std::uint32_t
>(
240 std::chrono::high_resolution_clock::now().time_since_epoch().count()
246 template<
size_t nparts,
size_t dimsampledx,
typename cfModT,
typename float_t>
248 : m_gen{
static_cast<std::uint32_t
>(seed) }
253 template<
size_t nparts,
size_t dimsampledx,
typename cfModT,
typename float_t>
258 float_t m = *std::max_element(oldLogUnNormWts.begin(), oldLogUnNormWts.end());
259 std::transform(oldLogUnNormWts.begin(), oldLogUnNormWts.end(), w.begin(),
260 [&m](float_t& d) -> float_t { return std::exp( d - m ); } );
261 std::discrete_distribution<> idxSampler(w.begin(), w.end());
268 unsigned int whichPart;
269 for(
size_t part = 0; part < nparts; ++part)
271 whichPart = idxSampler(m_gen);
272 tmpSamps[part] = oldSamps[whichPart];
273 tmpMods[part] = oldMods[whichPart];
277 oldMods = std::move(tmpMods);
278 oldSamps = std::move(tmpSamps);
279 std::fill(oldLogUnNormWts.begin(), oldLogUnNormWts.end(), 0.0);
294 template<
size_t nparts,
size_t dimx,
typename float_t>
300 using ssv = Eigen::Matrix<float_t,dimx,1>;
332 template<
size_t nparts,
size_t dimx,
typename float_t>
334 :
rbase<nparts, dimx, float_t>(seed)
339 template<
size_t nparts,
size_t dimx,
typename float_t>
345 float_t m = *std::max_element(oldLogUnNormWts.begin(), oldLogUnNormWts.end());
346 std::transform(oldLogUnNormWts.begin(), oldLogUnNormWts.end(), w.begin(),
347 [&m](
const float_t& d) -> float_t { return std::exp( d - m ); } );
348 float_t norm_const (0.0);
349 norm_const = std::accumulate(w.begin(), w.end(), norm_const);
350 for(
auto& weight : w)
351 weight = weight/norm_const;
356 float_t numRandomSamples(0.0);
357 for(i = 0; i < nparts; ++i) {
358 unNormWBar[i] = w[i]*nparts - std::floor(w[i]*nparts);
359 numRandomSamples += unNormWBar[i];
363 std::discrete_distribution<> idxSampler(unNormWBar.begin(), unNormWBar.end());
367 for(i = 0; i < nparts; ++i) {
368 sampleCounts[i] =
static_cast<unsigned int>(std::floor(nparts*w[i]));
370 for(i = 0; i < static_cast<unsigned int>(numRandomSamples); ++i) {
371 sampleCounts[idxSampler(this->m_gen)]++;
377 for(i = 0; i < nparts; ++i) {
378 unsigned int num_replicants = sampleCounts[i];
379 if( num_replicants > 0) {
380 for(
size_t j = 0; j < num_replicants; ++j) {
381 tmpPartics[c] = oldParts[i];
388 oldParts = std::move(tmpPartics);
389 std::fill(oldLogUnNormWts.begin(), oldLogUnNormWts.end(), 0.0);
403 template<
size_t nparts,
size_t dimx,
typename float_t>
409 using ssv = Eigen::Matrix<float_t,dimx,1>;
441 template<
size_t nparts,
size_t dimx,
typename float_t>
443 :
rbase<nparts, dimx, float_t>(seed)
448 template<
size_t nparts,
size_t dimx,
typename float_t>
454 float_t m = *std::max_element(oldLogUnNormWts.begin(), oldLogUnNormWts.end());
455 std::transform(oldLogUnNormWts.begin(), oldLogUnNormWts.end(), w.begin(),
456 [&m](
const float_t& d) -> float_t { return std::exp( d - m ); } );
457 float_t norm_const (0.0);
458 norm_const = std::accumulate(w.begin(), w.end(), norm_const);
459 for(
auto& weight : w)
460 weight = weight/norm_const;
464 std::partial_sum(w.begin(), w.end(), cumsums.begin());
467 std::uniform_real_distribution<float_t> u_sampler(0.0, 1.0/nparts);
469 for(
size_t i = 0; i < nparts; ++i) {
470 u_samples[i] = i/nparts + u_sampler(this->m_gen);
475 for(
size_t i = 0; i < nparts; ++i){
479 for(
unsigned int j = 0; j < nparts; ++j){
482 if(cumsums[j] >= u_samples[i]){
489 tmpPartics[i] = oldParts[idx];
493 oldParts = std::move(tmpPartics);
494 std::fill(oldLogUnNormWts.begin(), oldLogUnNormWts.end(), 0.0);
508 template<
size_t nparts,
size_t dimx,
typename float_t>
514 using ssv = Eigen::Matrix<float_t,dimx,1>;
546 template<
size_t nparts,
size_t dimx,
typename float_t>
548 :
rbase<nparts, dimx, float_t>(seed)
553 template<
size_t nparts,
size_t dimx,
typename float_t>
559 float_t m = *std::max_element(oldLogUnNormWts.begin(), oldLogUnNormWts.end());
560 std::transform(oldLogUnNormWts.begin(), oldLogUnNormWts.end(), w.begin(),
561 [&m](
const float_t& d) -> float_t { return std::exp( d - m ); } );
562 float_t norm_const (0.0);
563 norm_const = std::accumulate(w.begin(), w.end(), norm_const);
564 for(
auto& weight : w)
565 weight = weight/norm_const;
569 std::partial_sum(w.begin(), w.end(), cumsums.begin());
572 std::uniform_real_distribution<float_t> u_sampler(0.0, 1.0/nparts);
574 u_samples[0] = u_sampler(this->m_gen);
575 for(
size_t i = 1; i < nparts; ++i) {
576 u_samples[i] = u_samples[i-1] + 1.0/nparts;
584 for(
size_t i = 0; i < nparts; ++i){
590 if(cumsums[j] >= u_samples[i]){
599 tmpPartics[i] = oldParts[idx];
603 oldParts = std::move(tmpPartics);
604 std::fill(oldLogUnNormWts.begin(), oldLogUnNormWts.end(), 0.0);
617 template<
size_t nparts,
size_t dimx,
typename float_t>
623 using ssv = Eigen::Matrix<float_t,dimx,1>;
653 template<
size_t nparts,
size_t dimx,
typename float_t>
655 :
rbase<nparts, dimx, float_t>(seed)
660 template<
size_t nparts,
size_t dimx,
typename float_t>
672 float_t m = *std::max_element(oldLogUnNormWts.begin(), oldLogUnNormWts.end());
673 std::transform(oldLogUnNormWts.begin(), oldLogUnNormWts.end(), unnorm_weights.begin(),
674 [&m](float_t& d) -> float_t { return std::exp( d - m ); } );
677 std::uniform_real_distribution<float_t> u_sampler(0.0, 1.0);
683 float_t weight_norm_const(0.0);
686 for(
size_t i = 0; i < nparts; ++i) {
687 weight_norm_const += unnorm_weights[i];
688 exponentials[i] = -std::log(u_sampler(this->m_gen));
689 G += exponentials[i];
691 G -= std::log(u_sampler(this->m_gen));
695 float_t uniform_order_stat(0.0);
696 float_t running_sum_normalized_weights(unnorm_weights[0]/weight_norm_const);
697 float_t one_less_summand(0.0);
698 unsigned int idx = 0;
699 for(
size_t i = 0; i < nparts; ++i){
700 uniform_order_stat += exponentials[i]/G;
702 if( (one_less_summand < uniform_order_stat) && (uniform_order_stat <= running_sum_normalized_weights) ) {
704 tmpPartics[i] = oldParts[idx];
709 running_sum_normalized_weights += unnorm_weights[idx]/weight_norm_const;
710 one_less_summand += unnorm_weights[idx-1]/weight_norm_const;
716 oldParts = std::move(tmpPartics);
717 std::fill(oldLogUnNormWts.begin(), oldLogUnNormWts.end(), 0.0);
731 template<
size_t num_bits,
size_t num_dims>
732 std::array<std::bitset<num_bits>,num_dims> TransposeToAxes(std::array<std::bitset<num_bits>,num_dims> X)
735 using coord_t = std::bitset<num_bits>;
739 coord_t t = X[num_dims-1] >> 1;
740 for(
int i = num_dims-1; i > 0; i-- )
745 coord_t N = 2 << (num_bits-1);
746 for( coord_t Q = 2; Q != N; Q <<= 1 ) {
747 coord_t P = Q.to_ulong() - 1;
748 for(
int i = num_dims - 1; i >= 0; i--){
749 if( (X[i] & Q).any() ){
773 template<
size_t num_bits,
size_t num_dims>
774 std::array<std::bitset<num_bits>,num_dims> AxesToTranspose(std::array<std::bitset<num_bits>, num_dims> X)
776 using coord_t = std::bitset<num_bits>;
779 coord_t M = 1 << (num_bits-1);
780 for( coord_t Q = M; Q.to_ulong() > 1; Q >>= 1 ) {
781 coord_t P = Q.to_ulong() - 1;
782 for(
size_t i = 0; i < num_dims; i++ ){
783 if( (X[i] & Q).any() )
786 coord_t t = (X[0]^X[i]) & P;
794 for(
size_t i = 1; i < num_dims; i++ )
798 for( coord_t Q = M; Q.to_ulong() > 1; Q >>= 1 ){
799 if( (X[num_dims-1] & Q).any() )
803 for(
size_t i = 0; i < num_dims; i++ )
821 template<
size_t num_bits,
size_t num_dims>
822 std::array<std::bitset<num_bits>,num_dims> makeHTranspose(
unsigned int H)
824 using coord_t = std::bitset<num_bits>;
825 using coords_t = std::array<coord_t, num_dims>;
826 using big_coord_t = std::bitset<num_bits*num_dims>;
830 for(
size_t dim = 0; dim < num_dims; ++dim){
832 coord_t dim_coord_tmp;
833 unsigned start_bit = num_bits*num_dims-1-dim;
834 unsigned int c = num_bits - 1;
835 for(
int bit = start_bit; bit >= 0; bit -= num_dims){
836 dim_coord_tmp[c] = Hb[bit];
839 X[dim] = dim_coord_tmp;
856 template<
size_t num_bits,
size_t num_dims>
857 unsigned int makeH(std::array<std::bitset<num_bits>,num_dims> Htrans)
859 using big_coord_t = std::bitset<num_bits*num_dims>;
862 unsigned int which_dim = 0;
864 for(
int i = num_bits*num_dims - 1; i >= 0; i--){
865 which_bit = i / num_dims;
866 H[i] = Htrans[which_dim][which_bit];
867 which_dim = (which_dim + 1) % num_dims;
887 template<
size_t nparts,
size_t dimx,
size_t dimur,
size_t num_hilb_bits,
typename float_t >
893 using ssv = Eigen::Matrix<float_t,dimx,1>;
899 using usvr = Eigen::Matrix<float_t,dimur,1>;
935 template<
size_t nparts,
size_t dimx,
size_t dimur,
size_t num_hilb_bits,
typename float_t>
945 float_t c = std::pow(2, num_hilb_bits - 1);
946 ssv squashed_first = first * .5;
947 squashed_first = squashed_first.array().tanh()*c + c ;
948 ssv squashed_second = second * .5;
949 squashed_second = squashed_second.array().tanh()*c + c;
953 std::array<std::bitset<num_hilb_bits>, dimx> axes_first;
954 std::array<std::bitset<num_hilb_bits>, dimx> axes_second;
955 for(
size_t dim = 0; dim < dimx; ++dim){
956 axes_first[dim] =
static_cast<unsigned int>(std::floor(squashed_first(dim)));
957 axes_second[dim] =
static_cast<unsigned int>(std::floor(squashed_second(dim)));
962 return makeH(AxesToTranspose(axes_first)) < makeH(AxesToTranspose(axes_second));
966 template<
size_t nparts,
size_t dimx,
size_t dimur,
size_t num_hilb_bits,
typename float_t>
970 std::array<unsigned,nparts> indexes;
971 for(
unsigned i = 0; i < nparts; ++i)
979 sort_indexes(
const arrayVec& prts) : m_unsorted_parts(prts) {};
981 bool operator()(
unsigned i,
unsigned j)
const {
987 std::sort(indexes.begin(), indexes.end(), sort_indexes(unsortedParts));
1002 template<
size_t nparts,
size_t dimx,
size_t num_hilb_bits,
typename float_t>
1008 using ssv = Eigen::Matrix<float_t,dimx,1>;
1016 using usvr = Eigen::Matrix<float_t,1,1>;
1035 template<
size_t nparts,
size_t dimx,
size_t num_hilb_bits,
typename float_t>
1040 float_t m = *std::max_element(oldLogUnNormWts.begin(), oldLogUnNormWts.end());
1041 std::transform(oldLogUnNormWts.begin(), oldLogUnNormWts.end(), w.begin(),
1042 [&m](
const float_t& d) -> float_t { return std::exp( d - m ); } );
1043 float_t norm_const (0.0);
1044 norm_const = std::accumulate(w.begin(), w.end(), norm_const);
1045 for(
auto& weight : w)
1046 weight = weight/norm_const;
1050 ubar_samples[0] = rveval::evalUnivStdNormCDF<float_t>(ur(0))/nparts;
1051 for(
size_t i = 1; i < nparts; ++i) {
1052 ubar_samples[i] = ubar_samples[i-1] + 1.0/nparts;
1057 auto sigmaPermutation = this->get_permutation(oldParts);
1060 for(
size_t i = 0; i < nparts; ++i){
1061 unsigned sigma_i = sigmaPermutation[i];
1062 sortedWeights[i] = w[sigma_i];
1063 sortedParts[i] = oldParts[sigma_i];
1066 std::partial_sum(sortedWeights.begin(), sortedWeights.end(), cumsums.begin());
1073 for(
size_t i = 0; i < nparts; ++i){
1079 if(cumsums[j] >= ubar_samples[i]){
1088 tmpPartics[i] = sortedParts[idx];
1092 oldParts = std::move(tmpPartics);
1093 std::fill(oldLogUnNormWts.begin(), oldLogUnNormWts.end(), 0.0);
1099 #endif // RESAMPLERS_H