Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New Gaussian Accelerated Billiard Walk #317

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ test/Testing/Temporary/CTestCostData.txt
build/
.vscode
.DS_Store
test/.cache
1 change: 1 addition & 0 deletions examples/crhmc_sampling/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ CRHMC_SIMD_*
sampling_functions
simple_crhmc
libQD_LIB.a
liblp_solve.a
14 changes: 13 additions & 1 deletion include/convex_bodies/hpolytope.h
Original file line number Diff line number Diff line change
Expand Up @@ -541,7 +541,6 @@ class HPolytope {

NT lamda = 0;
VT sum_nom;
unsigned int j;
int m = num_of_hyperplanes(), facet;

Ar.noalias() += lambda_prev*Av;
Expand Down Expand Up @@ -909,6 +908,19 @@ class HPolytope {
v += a;
}

template <typename update_parameters>
NT compute_reflection(Point &v, const Point &, MT const &AE, VT const &AEA, NT const &vEv, update_parameters const &params) const {

Point a((-2.0 * params.inner_vi_ak) * A.row(params.facet_prev));
VT x = v.getCoefficients();
NT new_vEv = vEv - (4.0 * params.inner_vi_ak) * (AE.row(params.facet_prev).dot(x))
+ (4.0 * params.inner_vi_ak * params.inner_vi_ak) * AEA(params.facet_prev);
v += a;
NT coeff = std::sqrt(vEv / new_vEv);
v = v * coeff;
return coeff;
}

void update_position_internal(NT&){}

template <class bfunc, class NonLinearOracle>
Expand Down
6 changes: 6 additions & 0 deletions include/convex_bodies/orderpolytope.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,12 @@ class OrderPolytope {
return _A.sparseView();
}

// return the matrix A
MT get_full_mat() const
{
return _A;
}


VT get_vec() const
{
Expand Down
79 changes: 75 additions & 4 deletions include/generators/order_polytope_generator.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,25 @@
#ifndef ORDER_POLYTOPES_GEN_H
#define ORDER_POLYTOPES_GEN_H

#include <chrono>
#include <sstream>
#include <type_traits>
#include <unordered_map>
#include "misc.h"
#include <vector>
#include <algorithm>

#include "misc/misc.h"
#include "misc/poset.h"

#include <boost/random.hpp>
#include <boost/random/uniform_int.hpp>
#include <boost/random/normal_distribution.hpp>
#include <boost/random/uniform_real_distribution.hpp>

#include "generators/boost_random_number_generator.hpp"

#include "convex_bodies/orderpolytope.h"


// Instances taken from: https://github.com/ttalvitie/le-counting-practice
static const std::unordered_map<std::string, std::string> instances =
Expand All @@ -38,14 +52,29 @@ static const std::unordered_map<std::string, std::string> instances =

};

// generates a Polytope from a poset
/// @tparam Polytope Type of returned polytope
template <class Polytope>
Polytope get_orderpoly(Poset &poset) {
typedef typename Polytope::PointType Point;

OrderPolytope<Point> OP(poset);
if constexpr (std::is_same< Polytope, OrderPolytope<Point> >::value ) {
return OP;
} else {
Polytope HP(OP.dimension(), OP.get_full_mat(), OP.get_vec());
return HP;
}
}

// generates an Order Polytope from an instance name
// Instances taken from: https://github.com/ttalvitie/le-counting-practice
/// @tparam Polytope Type of returned polytope
template <class Polytope>
Polytope generate_orderpoly(std::string& instance_name) {
std::stringstream in_ss(instances.at(instance_name));
Poset poset = read_poset_from_file_adj_matrix(in_ss).second;
return Polytope(poset);
return get_orderpoly<Polytope>(poset);
}

// Generates a cube as an Order Polytope
Expand All @@ -56,8 +85,50 @@ Polytope generate_cube_orderpoly(unsigned int dim) {

RV order_relations;
Poset poset(dim, order_relations);
Polytope OP(poset);
return OP;
return get_orderpoly<Polytope>(poset);
}

// Generates a random Order Polytope with given dimension and number of facets
/// @tparam Polytope Type of returned polytope
/// @tparam RNGType RNGType Type
template <class Polytope, typename NT>
Polytope random_orderpoly(unsigned int dim, unsigned int m, int seed = std::numeric_limits<int>::signaling_NaN()) {

typedef typename Poset::RV RV;

int rng_seed = std::chrono::system_clock::now().time_since_epoch().count();
if (!isnan(seed)) {
rng_seed = seed;
}

typedef BoostRandomNumberGenerator<boost::mt19937, NT> RNG;
RNG rng(dim);
rng.set_seed(rng_seed);


std::vector<unsigned int> order(dim);
for(int i = 0; i < dim; ++i) {
order[i] = i;
}
boost::mt19937 shuffle_rng(rng_seed);
std::shuffle(order.begin(), order.end(), shuffle_rng);


RV order_relations;
for(int i = 0; i < m - 2 * dim; ++i) {
unsigned int x = rng.sample_uidist();
unsigned int y = rng.sample_uidist();
while(x == y) {
y = rng.sample_uidist();
}
if(x > y)
std::swap(x, y);
order_relations.push_back(std::make_pair(order[x], order[y]));
}


Poset poset(dim, order_relations);
return get_orderpoly<Polytope>(poset);
}

#endif
66 changes: 38 additions & 28 deletions include/misc/poset.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
// Copyright (c) 2020-2021 Vaibhav Thakkar

// Contributed and/or modified by Vaibhav Thakkar, as part of Google Summer of Code 2021 program.
// Contributed and/or modified by Luca Perju, as part of Google Summer of Code 2024 program.

// Licensed under GNU LGPL.3, see LICENCE file

Expand All @@ -25,6 +26,36 @@ class Poset {
unsigned int n; // elements will be from 0 to n-1
RV order_relations; // pairs of form a <= b

static void sorted_list(std::vector<unsigned int> &res, const unsigned int &n, const RV &relations)
{
std::vector<std::vector<unsigned int> > adjList(n);
std::vector<unsigned int> indegree(n, 0);

for(auto x: relations) {
adjList[x.first].push_back(x.second);
indegree[x.second] += 1;
}

std::queue<unsigned int> q;
for(unsigned int i=0; i<n; ++i) {
if(indegree[i] == 0)
q.push(i);
}

while(!q.empty()) {
unsigned int curr = q.front();
res.push_back(curr);
q.pop();

for(unsigned int i=0; i<adjList[curr].size(); ++i) {
unsigned int adj_idx = adjList[curr][i];
indegree[adj_idx] -= 1;
if(indegree[adj_idx] == 0)
q.push(adj_idx);
}
}
}

public:
Poset() {}

Expand All @@ -44,7 +75,12 @@ class Poset {
throw "invalid elements in order relations";
}

// TODO: Check if corresponding DAG is actually acyclic
std::vector<unsigned int> order;
sorted_list(order, n, relations);

if(order.size() < n) {
throw "corresponding DAG is not acyclic";
}

return relations;
}
Expand Down Expand Up @@ -96,34 +132,8 @@ class Poset {

std::vector<unsigned int> topologically_sorted_list() const
{
std::vector<std::vector<unsigned int> > adjList(n);
std::vector<unsigned int> indegree(n, 0);

for(auto x: order_relations) {
adjList[x.first].push_back(x.second);
indegree[x.second] += 1;
}

std::queue<unsigned int> q;
for(unsigned int i=0; i<n; ++i) {
if(indegree[i] == 0)
q.push(i);
}

std::vector<unsigned int> res;
while(!q.empty()) {
unsigned int curr = q.front();
res.push_back(curr);
q.pop();

for(unsigned int i=0; i<adjList[curr].size(); ++i) {
unsigned int adj_idx = adjList[curr][i];
indegree[adj_idx] -= 1;
if(indegree[adj_idx] == 0)
q.push(adj_idx);
}
}

sorted_list(res, n, order_relations);
return res;
}
};
Expand Down
Loading
Loading