void s_energy_matrix::compute_energy_restricted (int i, int j, str_features *fres) // compute the V(i,j) value, if the structure must be restricted { PARAMTYPE min, min_en[4]; int k, min_rank; char type; min_rank = -1; min = INF/2; min_en[0] = INF; min_en[1] = INF; min_en[2] = INF; min_en[3] = INF; if (can_pair (sequence[i], sequence[j])) { if (fres[i].pair == i+1) min_en[0] = 0; else { if (!exists_restricted (i, j, fres)) min_en[0] = H->compute_energy_restricted (i, j, fres); // there was a stupid bug here, I was calling H->compute_energy instead of the restricted version. Fixed on June 30, 2007. min_en[1] = S->compute_energy (i, j); min_en[2] = VBI->compute_energy_restricted (i, j, fres); min_en[3] = VM->compute_energy_restricted (i, j, fres); } } for (k=0; k<4; k++) { if (min_en[k] < min) { min = min_en[k]; min_rank = k; } } switch (min_rank) { case 0: type = HAIRP; break; case 1: type = STACK; break; case 2: type = INTER; break; case 3: type = MULTI; break; default: type = NONE; } if (min_rank > -1) { if (debug) printf ("V(%d,%d) type %c energy %d\n", i, j, type, min); } if (min < INF/2) { int ij = index[i]+j-i; nodes[ij].energy = min; nodes[ij].type = type; } }
void s_energy_matrix::compute_energy_sub (int i, int j) // suboptimals computation for V(i,j) { PARAMTYPE min, min_en[4]; int k, min_rank; char type; int ij; min = INF; min_rank = -1; min_en[0] = INF; min_en[1] = INF; min_en[2] = INF; min_en[3] = INF; if (can_pair (sequence[i], sequence[j])) { min_en[0] = H->compute_energy (i, j); if (i<=j-TURN-1) { min_en[1] = S->compute_energy (i, j); // TODO: uncomment if (!ignore_internal) min_en[2] = VBI->compute_energy (i, j); if (!ignore_multi) min_en[3] = VM_sub->compute_energy (i, j); } } for (k=0; k<4; k++) { if (min_en[k] < min) { min = min_en[k]; min_rank = k; } } switch (min_rank) { case 0: type = HAIRP; break; case 1: type = STACK; break; case 2: type = INTER; break; case 3: type = MULTI; break; default: type = NONE; } if (min < INF/2) { ij = index[i]+j-i; nodes[ij].energy = min; nodes[ij].type = type; // printf ("V(%d,%d) = %d, type=%c\n", i,j, nodes[ij].energy, nodes[ij].type); } }
void s_energy_matrix::compute_energy_sub_restricted (int i, int j, str_features *fres) // compute the V(i,j) value - suboptimals and restricted { PARAMTYPE min, min_en[4]; int k, min_rank; char type; min_rank = -1; min = INF/2; min_en[0] = INF; min_en[1] = INF; min_en[2] = INF; min_en[3] = INF; if (can_pair (sequence[i], sequence[j])) { min_en[0] = H->compute_energy_restricted (i, j, fres); min_en[1] = S->compute_energy (i, j); min_en[2] = VBI->compute_energy_restricted (i, j, fres); // I don't need restricted for VM_sub because I include dangling ends all the time min_en[3] = VM_sub->compute_energy (i, j); } for (k=0; k<4; k++) { if (min_en[k] < min) { min = min_en[k]; min_rank = k; } } switch (min_rank) { case 0: type = HAIRP; break; case 1: type = STACK; break; case 2: type = INTER; break; case 3: type = MULTI; break; default: type = NONE; } if (min_rank > -1) { if (debug) printf ("V(%d,%d) type %c energy %d\n", i, j, type, min); } if (min < INF/2) { int ij = index[i]+j-i; nodes[ij].energy = min; nodes[ij].type = type; } }
void s_energy_matrix::compute_energy (int i, int j) // compute the V(i,j) value { PARAMTYPE min, min_en[4]; int k, min_rank; char type; min_rank = -1; min = INF/2; min_en[0] = INF; min_en[1] = INF; min_en[2] = INF; min_en[3] = INF; if (can_pair (sequence[i], sequence[j])) // if i and j can pair { // compute free energy of hairpin loop, stack pair, internal loop and multi-loop min_en[0] = H->compute_energy (i, j); if (i<=j-TURN-1) { min_en[1] = S->compute_energy (i, j); // TODO: uncomment if (!ignore_internal) min_en[2] = VBI->compute_energy (i, j); if (!ignore_multi) min_en[3] = VM->compute_energy (i, j); } } // see which of them is the minimum for (k=0; k<4; k++) { if (min_en[k] < min) { min = min_en[k]; min_rank = k; } } switch (min_rank) { case 0: type = HAIRP; break; case 1: type = STACK; break; case 2: type = INTER; break; case 3: type = MULTI; break; default: type = NONE; } if (min_rank > -1) { if (debug) printf ("V(%d,%d) type %c energy %d\n", i, j, type, min); } if (min < INF/2) { int ij = index[i]+j-i; nodes[ij].energy = min; nodes[ij].type = type; } }
void match_pair(vector<Indiv> &population, bool (can_pair)(const Indiv*), unsigned (select_age_group) (const vector< unsigned >, const Indiv*), unsigned (generate_weight)(const Indiv*)) { // Initialize cumulative probability arrays // Shuffle indices into population of individuals array vector< size_t > indices; indices.reserve(population.size()); for(size_t i = 0; i < population.size(); ++i) indices.push_back(i); random_shuffle(indices.begin(), indices.end(), rand_int_to_open); // Set the CPA sizes and initialize the CPAs unsigned cpa_sizes[NUM_CPA] = {0}; for(vector<Indiv>::iterator i = population.begin(); i !=population.end(); ++i) { if( can_pair(&*i) ) { ++cpa_sizes[ index(i->sex, i->risk_group, i->age_group) ]; i->eligible = true; } else { i->eligible = false; } } Cpa *cpa[NUM_CPA]; Cpa_iterator cpa_iterator[NUM_CPA]; for(size_t j = 0; j < NUM_CPA; ++j) { cpa[j] = cpa_new(cpa_sizes[j], NULL, NULL); cpa_iterator[j].stack_size = 0; cpa_iterator[j].started = 0; } // Assign each eligible individual to one of the CPAs. for(size_t i = 0; i != indices.size(); ++i) { Indiv *ind = &population[indices[i]]; if (ind->eligible) { cpa_append(cpa[index(ind->sex, ind->risk_group, ind->age_group)], (Indiv *) ind, generate_weight(ind)); } } // Make vectors of 4 non empty CPAs from which potential mates can be drawn // Each element of these vectors is an index to a CPA age group // Index of MALE, LOW = 0 // MALE, HIGH = 1 // FEMALE, LOW = 2 // FEMALE, HIGH = 3 vector < unsigned > age_groups[4]; age_groups[MALE * 2 + HIGH] = non_empty_cpa(cpa, MALE, HIGH); age_groups[FEMALE * 2 + HIGH] = non_empty_cpa(cpa, FEMALE, HIGH); age_groups[MALE * 2 + LOW] = non_empty_cpa(cpa, MALE, LOW); age_groups[FEMALE * 2 + LOW] = non_empty_cpa(cpa, FEMALE, LOW); unsigned iterations = 0; while( age_groups[ MALE * 2 + HIGH ].size() + age_groups[ FEMALE * 2 + HIGH ].size() ) { ++iterations; // Choose a high risk cpa // randomly select sex unsigned from_sex; if (age_groups[ MALE * 2 + HIGH ].size() && age_groups[ FEMALE * 2 + HIGH ].size()) { from_sex = rand_int_to(1); } else { from_sex = age_groups[ MALE * 2 + HIGH ].size() ? MALE : FEMALE; } // randomly select age group unsigned from_age_group_index = rand_int_to(age_groups[from_sex * 2 + HIGH].size() - 1); unsigned from_age_group = age_groups[from_sex * 2 + HIGH][from_age_group_index]; unsigned cpa_from = index(from_sex, HIGH, from_age_group); Indiv *ind_from = (Indiv *) cpa_iterate(cpa[cpa_from], &cpa_iterator[cpa_from]); // Before finding partner, check if we have to update the non-empty CPAs if (cpa_all_found(cpa[cpa_from])) { // No people left in this CPA age_groups[from_sex * 2 + HIGH]. erase(age_groups[from_sex * 2 + HIGH].begin() + from_age_group_index); } assert(ind_from); // Now find partner unsigned to_sex = ~from_sex & 1; unsigned to_risk_group = age_groups[to_sex * 2 + HIGH].size() ? HIGH : LOW; unsigned to_age_group_index = select_age_group(age_groups[to_sex * 2 + to_risk_group], ind_from); unsigned to_age_group = age_groups[to_sex * 2 + to_risk_group][to_age_group_index]; unsigned cpa_to = index(to_sex, to_risk_group, to_age_group); double weight = rand_int_to_open(cpa[cpa_to]->cumulative_weight); Indiv* ind_to = (Indiv *) cpa_binary_search(cpa[cpa_to], weight); assert(ind_to); // Check if we have to update the non-empty CPAs if (cpa_all_found(cpa[cpa_to])) { // No people left in this CPA age_groups[to_sex * 2 + to_risk_group]. erase(age_groups[to_sex * 2 + to_risk_group].begin() + to_age_group_index); } if(ind_from->partner) ind_from->partner->partner = NULL; ind_from->partner = ind_to; if(ind_to->partner) ind_to->partner->partner = NULL; ind_to->partner = ind_from; } for(size_t i = 0; i < NUM_CPA; ++i) cpa_free(cpa[i]); }