def get_response_content(fs): parental_state = multiline_state_to_ndarray(fs.parental_state) nchromosomes, npositions = parental_state.shape if nchromosomes * npositions > 10: raise ValueError('at most 2^10 states are allowed') # mutation = 0.5 * fs.mutation_param recombination = 0.5 * fs.recombination_param selection = fs.selection_param # out = StringIO() print >> out, 'number of chromosomes:' print >> out, nchromosomes print >> out print >> out, 'number of positions per chromosome:' print >> out, npositions print >> out # define the transition matrix P = get_transition_matrix( selection, mutation, recombination, nchromosomes, npositions) # sample the endpoint conditioned path initial_integer_state = popgenmarkov.bin2d_to_int(initial_state) final_integer_state = popgenmarkov.bin2d_to_int(final_state) path = sample_endpoint_conditioned_path( initial_integer_state, final_integer_state, fs.ngenerations, P) print >> out, 'sampled endpoint conditioned path, including endpoints:' print >> out for integer_state in path: # print integer_state print >> out, ndarray_to_multiline_state( popgenmarkov.int_to_bin2d( integer_state, nchromosomes, npositions)) print >> out return out.getvalue()
def get_transition_matrix( selection, mutation, recombination, nchromosomes, npositions): """ This factors into the product of two transition matrices. The first transition matrix accounts for selection and recombination. The second transition matrix independently accounts for mutation. @param selection: a fitness ratio @param mutation: a state change probability @param recombination: a linkage phase change probability @param nchromosomes: number of chromosomes in the population @param npositions: number of positions per chromosome @return: a numpy array """ nstates = 1 << (nchromosomes * npositions) # define the mutation transition matrix P_mutation = np.zeros((nstates, nstates)) for source in range(nstates): for sink in range(nstates): ndiff = gmpy.hamdist(source, sink) nsame = nchromosomes * npositions - ndiff P_mutation[source, sink] = (mutation**ndiff)*((1-mutation)**nsame) """ print 'mutation transition matrix row sums:' for value in np.sum(P_mutation, axis=1): print value print """ # init the unnormalized selection and recombination transition matrix M = np.zeros((nstates, nstates)) for source_index in range(nstates): K_source = popgenmarkov.int_to_bin2d( source_index, nchromosomes, npositions) chromosome_distn = popgenmarkov.get_chromosome_distn( selection, recombination, K_source) for x in product(range(1<<npositions), repeat=nchromosomes): weight = 1 for index in x: weight *= chromosome_distn[index] sink_index = 0 for i, index in enumerate(x): sink_index <<= npositions sink_index |= index M[source_index, sink_index] = weight M_row_sums = np.sum(M, axis=1) P_selection_recombination = (M.T / M_row_sums).T """ print 'selection-recombination matrix row sums:' for value in np.sum(P_selection_recombination, axis=1): print value print """ # define the state transition probability matrix P = np.dot(P_selection_recombination, P_mutation) return P