MSSM<Two_scale> setup_MSSM() { const double ALPHASMZ = 0.1176; const double ALPHAMZ = 1.0 / 127.918; const double sinthWsq = 0.23122; const double alpha1 = 5 * ALPHAMZ / (3 * (1 - sinthWsq)); const double alpha2 = ALPHAMZ / sinthWsq; const double g1 = sqrt(4 * Pi * alpha1); const double g2 = sqrt(4 * Pi * alpha2); const double g3 = sqrt(4 * Pi * ALPHASMZ); const double tanBeta = 10; const double sinBeta = sin(atan(tanBeta)); const double cosBeta = cos(atan(tanBeta)); const double M12 = 100.0; const double m0 = 250.0; const double a0 = 50.0; const double root2 = sqrt(2.0); const double vev = 246.0; const double vu = vev * sinBeta; const double vd = vev * cosBeta; const double susyMu = 120.0; const double BMu = Sqr(2.0 * susyMu); Eigen::Matrix<double,3,3> Yu(Eigen::Matrix<double,3,3>::Zero()), Yd(Eigen::Matrix<double,3,3>::Zero()), Ye(Eigen::Matrix<double,3,3>::Zero()), mm0(Eigen::Matrix<double,3,3>::Zero()); Yu(2,2) = 165.0 * root2 / (vev * sinBeta); Yd(2,2) = 2.9 * root2 / (vev * cosBeta); Ye(2,2) = 1.77699 * root2 / (vev * cosBeta); mm0 = Sqr(m0) * Eigen::Matrix<double,3,3>::Identity(); MSSM<Two_scale> m; m.set_scale(91); m.set_loops(1); m.set_g1(g1); m.set_g2(g2); m.set_g3(g3); m.set_Yu(Yu); m.set_Yd(Yd); m.set_Ye(Ye); m.set_MassB(M12); m.set_MassG(M12); m.set_MassWB(M12); m.set_mq2(mm0); m.set_ml2(mm0); m.set_md2(mm0); m.set_mu2(mm0); m.set_me2(mm0); m.set_mHd2(Sqr(m0)); m.set_mHu2(Sqr(m0)); m.set_TYu(a0 * Yu); m.set_TYd(a0 * Yd); m.set_TYe(a0 * Ye); m.set_Mu(susyMu); m.set_BMu(BMu); m.set_vu(vu); m.set_vd(vd); return m; }
double get_Yd(int i, int k) const { return Yd(i,k); }
EmbeddingResult spe_embedding(RandomAccessIterator begin, RandomAccessIterator end, PairwiseCallback callback, const Neighbors& neighbors, unsigned int target_dimension, bool global_strategy, DefaultScalarType tolerance, int nupdates) { timed_context context("SPE embedding computation"); unsigned int k = 0; if (!global_strategy) k = neighbors[0].size(); // The number of data points int N = end-begin; while (nupdates > N/2) nupdates = N/2; // Look for the maximum distance DefaultScalarType max = 0.0; for (RandomAccessIterator i_iter=begin; i_iter!=end; ++i_iter) { for (RandomAccessIterator j_iter=i_iter+1; j_iter!=end; ++j_iter) { max = std::max(max, callback(*i_iter,*j_iter)); } } // Distances normalizer used in global strategy DefaultScalarType alpha = 0.0; if (global_strategy) alpha = 1.0 / max * std::sqrt(2.0); // Random embedding initialization, Y is the short for embedding_feature_matrix std::srand(std::time(0)); DenseMatrix Y = (DenseMatrix::Random(target_dimension,N) + DenseMatrix::Ones(target_dimension,N)) / 2; // Auxiliary diffference embedding feature matrix DenseMatrix Yd(target_dimension,nupdates); // SPE's main loop typedef std::vector<int> Indices; typedef std::vector<int>::iterator IndexIterator; // Maximum number of iterations int max_iter = 2000 + round(0.04 * N*N); if (!global_strategy) max_iter *= 3; // Learning parameter DefaultScalarType lambda = 1.0; // Vector of indices used for shuffling Indices indices(N); for (int i=0; i<N; ++i) indices[i] = i; // Vector with distances in the original space of the points to update DenseVector Rt(nupdates); DenseVector scale(nupdates); DenseVector D(nupdates); // Pointers to the indices of the elements to update IndexIterator ind1; IndexIterator ind2; // Helper used in local strategy Indices ind1Neighbors; if (!global_strategy) ind1Neighbors.resize(k*nupdates); for (int i=0; i<max_iter; ++i) { // Shuffle to select the vectors to update in this iteration std::random_shuffle(indices.begin(),indices.end()); ind1 = indices.begin(); ind2 = indices.begin()+nupdates; // With local strategy, the seecond set of indices is selected among // neighbors of the first set if (!global_strategy) { // Neighbors of interest for(int j=0; j<nupdates; ++j) { const LocalNeighbors& current_neighbors = neighbors[*ind1++]; for(unsigned int kk=0; kk<k; ++kk) ind1Neighbors[kk + j*k] = current_neighbors[kk]; } // Restore ind1 ind1 = indices.begin(); // Generate pseudo-random indices and select final indices for(int j=0; j<nupdates; ++j) { unsigned int r = round( std::rand()*1.0/RAND_MAX*(k-1) ) + k*j; indices[nupdates+j] = ind1Neighbors[r]; } } // Compute distances between the selected points in the embedded space for(int j=0; j<nupdates; ++j) { //FIXME it seems that here Euclidean distance is forced D[j] = (Y.col(*ind1) - Y.col(*ind2)).norm(); ++ind1, ++ind2; } // Get the corresponding distances in the original space if (global_strategy) Rt.fill(alpha); else // local_strategy Rt.fill(1); ind1 = indices.begin(); ind2 = indices.begin()+nupdates; for (int j=0; j<nupdates; ++j) Rt[j] *= callback(*(begin + *ind1++), *(begin + *ind2++)); // Compute some terms for update // Scale factor D.array() += tolerance; scale = (Rt-D).cwiseQuotient(D); ind1 = indices.begin(); ind2 = indices.begin()+nupdates; // Difference matrix for (int j=0; j<nupdates; ++j) { Yd.col(j).noalias() = Y.col(*ind1) - Y.col(*ind2); ++ind1, ++ind2; } ind1 = indices.begin(); ind2 = indices.begin()+nupdates; // Update the location of the vectors in the embedded space for (int j=0; j<nupdates; ++j) { Y.col(*ind1) += lambda / 2 * scale[j] * Yd.col(j); Y.col(*ind2) -= lambda / 2 * scale[j] * Yd.col(j); ++ind1, ++ind2; } // Update the learning parameter lambda = lambda - ( lambda / max_iter ); } return EmbeddingResult(Y.transpose(),DenseVector()); };
void set_Yd(int i, int k, double value) { Yd(i,k) = value; }