public OptChar[] Transposize(OptChar[] input,
Dictionary<int,int> transpositions,
int guar)
{
// copy input to new array
OptChar[] output = new OptChar[input.Length];
Array.Copy(input, output, input.Length);
// for each character in the string, sample from the transposition dict
for (int i = 0; i < input.Length; i++)
{
// condition on the number of possible transpositions
// to the right and to the left
// if the character is a "guaranteed transposition", ensure that
// the 0-transposition is not in the distribution
var dist = transpositions.Where(kvp => kvp.Key < input.Length - i
&& kvp.Key >= -i
&& i == guar ? kvp.Key != 0 : true)
.ToDictionary(pair => pair.Key, pair => pair.Value);
var counts = Enumerable.Range(-i, input.Length)
.Select(z => dist.ContainsKey(z) ? dist[z] : 0);
var total = counts.Sum();
if (total != 0)
{
var prs = counts.Select(z => (double)z / total).ToArray();
// sample (in this case, bins always start at zero and are in order,
// so j == # of transpositions to right)
var j = MultinomialSample(prs);
// swap chars
OptChar ith = output[i];
output[i] = output[j];
output[j] = ith;
}
}
return output;
}