// -------------------------------------------------------------------------------------------------
// Draw IDs with a uniform probability over [1, M]
// -------------------------------------------------------------------------------------------------
	clear all

// -------------------------------------------------------------------------------------------------
// Programs
// -------------------------------------------------------------------------------------------------

// Uniform draw
capture program drop smpl
program define smpl
	syntax newvarname, size(integer)
	gen long `varlist' = 1 + int(uniform() * `size')
	compress `varlist'
end


// -------------------------------------------------------------------------------------------------
// Easy scenario: one dimension only has a few categories (e.g. time fixed effect)
// -------------------------------------------------------------------------------------------------
	clear
	set trace off
	set more off
	timer clear

	local M1 250000
	local q = 1
	local M2 = 20 // We don't want M1 and M2 to grow at the same rate
	local d = 2
	local N = ceil(`M1' * `d') // If we require -d- to stay small, then the dataset should be proportional to the Ms

	set obs `N'
	set seed 1234
	gen double x1 = rnormal()
	gen double x2 = uniform()

	smpl id1, size(`M1')
	smpl id2, size(`M2')

	gen double y = 10 + x1 + x2 + sin(id1) + log(10+id2) + 100 * rnormal()
	assert !missing(y)

	su id1 id2
	sort id1 id2

	saveold dataset_easy, version(12) replace
	outsheet using dataset_easy.txt, nolabel noquote replace // tab-separated

	* Benchmark
	set rmsg on
	reghdfe y x1 x2, a(id1 id2) accel(cg) transform(sym) noprune keepsing nosample
	set rmsg off
	di `e(ic)' char(9) `M1' char(9) `e(N)'
	
	// IMPORTANT NOTE:
	// The number of iteration scales proportionally to ln(`M1')
	// So the total work scales proportionally to N*log(M)
	
	// For some reason, the faster command is:
	// reghdfe y x1 x2, a(id1 id2) accel(hyb) transform(kac) noprune

exit

