yojimbos_law icon

expected queue contents computer

yojimbos_law | PRO | 02/20/22 05:32:16 PM UTC (Edited) | 0 ⭐ | 606 👁️ | Never ⏰ | []
text |

4.82 KB

|

None

|

0 👍

/

0 👎

 //my stupid expectation formula requires iterating over all sequences in {0,...,n-1}^k.
//the following two functions let us do that by iterating instead over {0,...,n^k -1},
//which is significantly easier.
  //this takes a number a between 0 and base^power - 1 (inclusive) and converts it into
//the corresponding natural sequence embedded in {0,...,base}^power.
int[int] to_sequence(int a, int base, int power){
	int[int] seq;
	int leftovers = a;
 	//doesn't matter for our purposes whether we preserve orientation, so we might not.
	for i from 1 to (power){
		seq[power-i] = leftovers/(base**(power - i));
		//debugging.
		//print((base**(power - i))+" goes into "+leftovers+" this many times: "+seq[power-i]);
		leftovers -= seq[power-i]* (base**(power - i));
	}
	return seq;
}
 //turns those sequences into sets for cleaner use in foreach loops.
boolean[int] to_set(int[int] seq){
		boolean[int] set;
		foreach i in seq{
			set[seq[i]] = true;
		}
		return set;
}
 //for any appropriate number X, "foreach i in X.to_sequence(base,power).to_set()" iterates
//i over precisely the unique digits found in the sequence corresponding to X.
//if you don't discard the multiplicity here, the iteration becomes quite a bit messier.
//Coding natural morphisms is tricky, huh?
  //the formula includes the multiplicity function, so we write that here.
//this'll return the number of times a digit j appears in the sequence seq.
int mult(int[int] seq, int j){
	int count;
	foreach i in seq{
		if(seq[i] == j){
			count++;
		}
	}
	return count;
}
 //phi is the underlying probability distribution. I guess we'll normalize it in this function
//for ease of use (so any proportional distribution could be input).
//r will be the rejection rate array with positions corresponding to entries in phi.
//k will be queue length, since this can't be deduced from r and phi.
float expectation(float[int] phi, float[int] r, int k){
	//deduce size of outcome set from input rather than requiring that input.
	int n = count(phi);
	//normalize phi.
	float phisum = 0.0;
	foreach i in phi{
		phisum += phi[i];
	}
	foreach i in phi{
		phi[i] /= phisum;
	}
	//so now phi is a probability distribution unless some sick fart put negative/complex values in.
 	//so now we have to do this. https://i.imgur.com/DsYTyrd.png
	//the top and bottom are nearly identical, so we'll be computing these simultaneously
	//while leaving out that factor of #a from the summands on the bottom.
	float top_outer_sum = 0.0;
	float bottom_outer_sum = 0.0;
	float inner_sum;
	float indexed_product;
	int[int] index_seq;
	boolean[int] index_set;
	for index from 0 to ((n**k) -1){
		clear(index_seq);
		clear(index_set);
		inner_sum = 0.0;
		indexed_product = 1.0;
		index_seq = to_sequence(index,n,k);
		index_set = to_set(index_seq);
 		//make the inner sum.
		foreach j in index_set{
			inner_sum += phi[j]*r[j];
		}
		//do the 1- thing.
		inner_sum = 1 - inner_sum;
 		//now make the indexed product.
 		foreach j in index_set{
			indexed_product *= ( ( phi[j]*(1-r[j]) ) ** mult(index_seq,j) ) / ( 1 - r[j] );
		}
 		//now we increment the bottom by those two things multiplied together.
		bottom_outer_sum += inner_sum * indexed_product ;
 		//and increment the top by the same thing but with a factor of #a.
		top_outer_sum += inner_sum * indexed_product * count(index_set);
 	}
 	//smush the top and bottom together and return it.
	return (top_outer_sum / bottom_outer_sum );
}
 /*
 //check that this works by looking at dice.
float[int] fee = {1,1,1,1,1,1};
float[int] arrr = {0,0,0,0,0,0};
float[int] herman_cain = {0.999,0.999,0.999,0.999,0.999,0.999};
print(expectation(fee , arrr ,1));
//the above should print the average number of unique die roll outcomes occurring
//in the last 1 die rolls. If it's not 1.0, we're very sad.
//dear lord it returns exactly 1.0.
 debugging stuff
print("let\'s write "+122+" in base 5 with 4 digits");
int[int] boop = 122.to_sequence(5,4);
foreach i in boop{
print(i+": "+boop[i]);
}
 print("let\'s write "+69+" in base 3 with 11 digits");
boop = 69.to_sequence(3,11);
foreach i in boop{
print(i+": "+boop[i]);
}
*/
  //let's make data for some very pretty graphs.
float[float] data;
float[int] fee = {1,1,1,1,1};
float[int] arrr = {0,0,0,0,0};
 //graphing how much rejection rate matters to steady state frequency.
for i from 1 to 8{
	arrr[4] = 0.0;
	for j from 0 to 999{
		arrr[4] += 0.001;
		data[arrr[4]] = expectation(fee,arrr,i)/(i.to_float());
	}
	//when i is 1, this should generate a text file with a column of 1000 1.0's.
	//only letting script do that for debugging.
	map_to_file(data,"plot of normalized expected variety in uniform phi with rejection on one outcome for n=5 k="+i+".txt");
	clear(data);
	print("done with making graph number "+i);
}
 

Comments