Raw File
variants.hpp
#pragma once

#include <cmath>

struct policy_t {
	std::function<bool(size_t n, size_t m, unsigned level, size_t M)> perform_contraction;
	std::function<size_t(size_t n, size_t m, unsigned level, size_t M)> contract_number;
	std::function<int(size_t n, size_t m, unsigned level, size_t M)> sample_prob_power;
};

inline int nearest_power_reciprocal(size_t n, size_t m) {
	return std::max(1, static_cast<int>(std::floor(std::log2(static_cast<double>(m)/static_cast<double>(n)))));
}

inline size_t threshold_fun_4(size_t n, size_t M) {
	return std::min(4ul, static_cast<size_t>(2.0*(1.0+(2.0*static_cast<double>(M))/static_cast<double>(n))));
}

inline size_t threshold_fun_8(size_t n, size_t M) {
	return std::min(8ul, static_cast<size_t>(2.0*(1.0+(6.0*static_cast<double>(M))/static_cast<double>(n))));
}

policy_t variant_policies[] =
	{
		{ // 0: default; always contract, contract n/2 and sample with p=1/2 (for KKT in particular)
			[](size_t, size_t, unsigned, size_t) {return true;},
			[](size_t n, size_t, unsigned, size_t) {return n/2;},
			[](size_t, size_t, unsigned, size_t) {return 1;},
		},
		{ // 1+: setup for the experiments Rolf suggested
			[](size_t, size_t, unsigned level, size_t) {return level > 0;},
			[](size_t n, size_t, unsigned, size_t) {return n/2;},
			[](size_t, size_t, unsigned, size_t) {return 1;},
		},
		{ // 2
			[](size_t, size_t, unsigned level, size_t) {return level > 0;},
			[](size_t n, size_t, unsigned, size_t) {return n/2;},
			[](size_t, size_t, unsigned, size_t) {return 2;},
		},
		{ // 3
			[](size_t, size_t, unsigned level, size_t) {return level > 0;},
			[](size_t n, size_t, unsigned, size_t) {return n/2;},
			[](size_t, size_t, unsigned, size_t) {return 3;},
		},
		{ // 4
			[](size_t, size_t, unsigned level, size_t) {return level > 0;},
			[](size_t n, size_t, unsigned, size_t) {return n/2;},
			[](size_t, size_t, unsigned, size_t) {return 4;},
		},
		{ // 5
			[](size_t, size_t, unsigned level, size_t) {return level > 0;},
			[](size_t n, size_t, unsigned, size_t) {return n/2;},
			[](size_t, size_t, unsigned, size_t) {return 5;},
		},
		{ // 6+: adaptive (here: threshold 4)
			[](size_t n, size_t m, unsigned, size_t) {return (m/n)<4;},
			[](size_t n, size_t m, unsigned, size_t) {return n-m/4;},
			[](size_t n, size_t m, unsigned, size_t) {return nearest_power_reciprocal(n, m);},
		},
		{ // 7: threshold 8
			[](size_t n, size_t m, unsigned, size_t) {return (m/n)<8;},
			[](size_t n, size_t m, unsigned, size_t) {return n-m/8;},
			[](size_t n, size_t m, unsigned, size_t) {return nearest_power_reciprocal(n, m);},
		},
		{ // 8: threshold 4 for V/M=2, going to 2 as V/M increases
			[](size_t n, size_t m, unsigned, size_t M) {
				const auto threshold = threshold_fun_4(n, M);
				std::cout << "Contraction density threshold: " << threshold << std::endl;
				return (m/n) < threshold;
			},
			[](size_t n, size_t m, unsigned, size_t M) {
				const auto threshold = threshold_fun_4(n, M);
				return n - m/threshold;
			},
			[](size_t n, size_t m, unsigned, size_t) {return nearest_power_reciprocal(n, m);},
		},
		{ // 9: threshold 8 for V/M=2, going to 2 as V/M increases
			[](size_t n, size_t m, unsigned, size_t M) {
				const auto threshold = threshold_fun_8(n, M);
				std::cout << "Contraction density threshold: " << threshold << std::endl;
				return (m/n) < threshold;
			},
			[](size_t n, size_t m, unsigned, size_t M) {
				const auto threshold = threshold_fun_8(n, M);
				return n - m/threshold;
			},
			[](size_t n, size_t m, unsigned, size_t) {return nearest_power_reciprocal(n, m);},
		},
	};
back to top