Matrix* unproject_rates(TreeModel *mod_tuples, TreeModel *mod_single) {
  int dim = mod_tuples->rate_matrix->size;
  int alph_size = (int)strlen(mod_tuples->rate_matrix->states);
  char tuple_i[mod_tuples->order+1], tuple_j[mod_tuples->order+1];
  int position, i, j;
  Matrix *retval = mat_new(dim, dim);
  mat_zero(retval);
  for (i = 0; i < dim; i++) {
    get_tuple_str(tuple_i, i, mod_tuples->order+1, 
                  mod_tuples->rate_matrix->states);
    for (j = 0; j < dim; j++) {
      if (i == j || mm_get(mod_tuples->rate_matrix, i, j) == 0) continue;
      /* WARNING: we'll ignore any rate matrix elements that have
         *actually been estimated* to be zero */

      get_tuple_str(tuple_j, j, mod_tuples->order+1, 
                    mod_tuples->rate_matrix->states);
      position = mod_tuples->order - (int)(floor(log(abs(i - j))/log(alph_size)));
      mat_set(retval, i, j, 
                     mm_get(mod_single->rate_matrix, 
                            mod_single->rate_matrix->inv_states[(int)tuple_i[position]],
                            mod_single->rate_matrix->inv_states[(int)tuple_j[position]]));
    }
  }
  return retval;
}
Ejemplo n.º 2
0
int main(){

	srand(time(0));
	//Creating memory managers
	mm_t *MM = malloc(sizeof(mm_t));
	mm_init(MM,1500,sizeof(node));
	
	mm_t *MM2 = malloc(sizeof(mm_t));
	mm_init(MM2,3,sizeof(dl_list));
	
	//Creating Lists
    dl_list *dl_1 = mm_get(MM2);
    dl_list *dl_2 = mm_get(MM2);
    dl_list *dl_3 = mm_get(MM2);
    
    dl_list_init(dl_1);
    dl_list_init(dl_2);
    dl_list_init(dl_3);
	
	int i;
	for(i = 0; i<500; i++)
		insert_item(dl_1,i,MM);
	
	print_list(dl_1);
	
	for(i = 0; i<500; i++)
		insert_item(dl_2,rand()%500,MM);

	print_list(dl_2);
	
	for(i = 0; i<500; i++)
		insert_item(dl_3,get_element(dl_1,i)+get_element(dl_2,i),MM);
		
	print_list(dl_3);
	
	//Deleting items from list 1
	for(i = 0; i<100; i++)
		delete_item(dl_1,get_element(dl_3,i),MM);
	
	print_list(dl_1);
	
	//Joining lists
	join_lists(dl_2,dl_1);
	join_lists(dl_3,dl_2);
	
	print_list(dl_3);
	
	empty_list(dl_3,MM);
	
	//Deallocating and freeing
	mm_put(MM,dl_1);
	mm_put(MM,dl_2);
	mm_put(MM,dl_3);
	free(MM);
	free(MM2);

    return 0;
}
Ejemplo n.º 3
0
Archivo: mm.c Proyecto: LeiFengCN/xOS
void* malloc(u32 size){
	if (size <= 0){
		return NULL;
	}
	if(size <= 64){
		return mm_get(mm_64);
	}else if(size <= 128){
		return mm_get(mm_128);
	}else if(size <= 256){
		return mm_get(mm_256);
	}else if(size <= 512){
		return mm_get(mm_512);
	}else if(size <= 1024){
		return mm_get(mm_1024);
	}
	return NULL;
}
Ejemplo n.º 4
0
void packet_handler(int sig) {
	packet_t pkt;
	fprintf(stderr, "IN PACKET HANDLER, sig=%d %s \t\t pkt counter so far %d\n",
			sig, strsignal(sig), pkt_cnt);

	pkt = get_packet(cnt_msg); // the messages are of variable length. So, the 1st message consists of 1 packet, the 2nd message consists of 2 packets and so on..
	pkt_total = pkt.how_many;

	if (pkt_cnt == 0) { // when the 1st packet arrives, the size of the whole message is allocated.
		message.num_packets = pkt_total;
		message.data = (char*) mm_get(&MM,
				message.num_packets * PACKET_DATA_SIZE + 1); // +1 for ending 0
		fprintf(stderr, "=========Message address start \t %p \n",
				message.data);
//		message.data[pkt_total * PACKET_DATA_SIZE] = 0;
		memset(message.data, 0, message.num_packets * PACKET_DATA_SIZE + 1);
	}

//	fprintf(stderr, "After get %d: \t|%s| \t\t%p\n", cnt_msg, message.data,
//			message.data);

	fprintf(stderr, "CURRENT MESSAGE %d with message total number %d, which %d and stuff %s\n",
			cnt_msg, message.num_packets, pkt.which, pkt.data);

//	fprintf(stderr, "Dest: ~%p~; \t Src: %p \t Size %d \t Offset %d (%d) \t @cnt %d\n",
//			&message.data[0] + (PACKET_DATA_SIZE * pkt.which), pkt.data,
//			PACKET_DATA_SIZE, pkt.which, PACKET_DATA_SIZE * pkt.which,pkt_cnt);

	/* insert your code here ... stick packet in memory, make sure to handle duplicates appropriately */
	if (message.data[PACKET_DATA_SIZE * pkt.which] == (char) 0) {
		memcpy(message.data + (PACKET_DATA_SIZE * pkt.which), pkt.data,
				PACKET_DATA_SIZE);
	} else { // duplicated message deleted, skip this round
		return;
	}

	++pkt_cnt;
	if (pkt_cnt == message.num_packets) {
		int i;
		fputs("--------->",stderr);
		for (i=0;i<(PACKET_DATA_SIZE*message.num_packets);++i){
//			fputs("%d ",message.data[i],stderr);
			fprintf(stderr,"%d ",(int)message.data[i]);
		}
		fputs("\n",stderr);
		/*Print the packets in the correct order.*/
		fprintf(stderr, "MSG %d: \t|%s| \t\t%p\n\n", cnt_msg, message.data,
				message.data);
		mm_put(&MM, (void*) message.data);
	}
	/*Deallocate message*/

}
Ejemplo n.º 5
0
void timer_mm() {

	struct timeval time_start, time_end;
	int j,i;

	j = gettimeofday (&time_start, (void *)NULL);
	mm_t MM;
	if(mm_init (&MM, 10000, 64) == -1){
		perror("failed to initialize mm");
	}
	for (i = 0; i < 10000; i++){
		mm_get (&MM);
	}
	for (i = 0; i < 10000; i++){
		mm_put (&MM, (void*) (MM.blocks + i * MM.size));
	}
	mm_release(&MM);
	j = gettimeofday (&time_end, (void *)NULL);
	fprintf (stderr, "Time taken for MM =  %f msec\n",
		 comp_time (time_start, time_end)/1000.0);
}
Ejemplo n.º 6
0
/*
   Handles the incoming packet. 
   Store the packet in a chunk from memory manager.
   The packets for given message will come out of order. 
   Hence you need to take care to store and assemble it correctly.
   Example, message "aaabbb" can come as bbb -> aaa, hence, you need to assemble it
   as aaabbb.
   Hint: "which" field in the packet will be useful.
 */
static void packet_handler(int sig) {
  
  packet_t pkt;
  
 
  mm_t mm2 = mm;
  
  void * chunk = mm_get(&mm);
      
  // get the "packet_queue_msg" from the queue.
  packet_queue_msg pkq;
  msgrcv(msqid, &pkq, sizeof(packet_t), QUEUE_MSG_TYPE, 0);
  
  
  // extract the packet from "packet_queue_msg" and store it in the memory from memory manager
  pkt = pkq.pkt;
  memcpy(chunk, &pkt, MSGSIZE);
  message.data[pkt_cnt] = chunk;
  message.num_packets++;
  pkt_total = pkt.how_many;
  pkt_cnt++;
}
Ejemplo n.º 7
0
/* Main driver that tests the
 * clock time for our dynamic
 * memory allocator */
int main (int argc, char **argv)
{
	int i, j;
	struct timeval times, timee;
	mm_t MM;
	void *chunk = NULL;

	
	
	if (mm_init(&MM,NUM_CHUNKS, CHUNK_SIZE) < 0)
		fprintf(stderr, "Error in mm_init\n");
	j = gettimeofday (&times, (void *)NULL);
	for (i=0; i< ITERS; i++) { 
		chunk = mm_get(&MM);
		mm_put(&MM,chunk);
	}
	
	
	
	j = gettimeofday (&timee, (void *)NULL);
	mm_release(&MM);			/* release stuff on heap*/
	fprintf (stderr, "MM time took %f msec\n",comp_time (times, timee)/1000.0);
	return 0;
}
Ejemplo n.º 8
0
int main()
{
	mm_t mm;
	if(mm_init(&mm, 1000000, 64) == 0)
	{
		printf("success\n");
	}
  	gettimeofday (&time_s, NULL);
	mm_t *mmArray[1000000];
	int i;
	for (i = 0; i < 1000000; i++){
		if ((mmArray[i] = mm_get(&mm)) == NULL){
			printf("Failed to allocate i = %d\n", i);
		}
	}
	while (i > 0){
		i--;
		mm_put(&mm, mmArray[i]);
	}
  	gettimeofday(&time_e, NULL);
	mm_release(&mm);
  	fprintf(stderr, "main_mm duration = %f msec\n", comp_time(time_s, time_e) / 1000.0);
	return 0;
}
Ejemplo n.º 9
0
int main() {

  typedef struct {
    int val;
  } chunk_t;

  mm_t MM;
  mm_t MM1;
  mm_t MM2;

  int i;
  int j;
  int found;

  void* address;

  unsigned long int* addresses = (unsigned long int*) malloc(NUM_CHUNKS * sizeof(unsigned long int));
  unsigned long int* free_addresses = (unsigned long int*) malloc(NUM_CHUNKS * sizeof(unsigned long int));

  srand(time(NULL));


  /*
   * Initialize memory
   */

  if (mm_init(&MM, NUM_CHUNKS, CHUNK_SIZE) == -1) {
	printf("Failed to initialize memory!\n");
        exit(-1);
  }


  /*
   * Allocate all chunks
   */

  for (i = 0; i < NUM_CHUNKS; i++) {
    if (!(address = mm_get(&MM))) {
      printf("Failed to allocate a chunk %d while chunks available!\n", i);
      return 1;
    } else {
      addresses[i] = (unsigned long int) address;
    }
  }



  /*
   * Sort Address in ascending order
   */

  unsigned long int temp;

  for (i = 0; i < NUM_CHUNKS; i++) {
    for (j = i; j < NUM_CHUNKS; j++) {
      if (addresses[i] > addresses[j]) {
        temp = addresses[i];
        addresses[i] = addresses[j];
        addresses[j] = temp;
      }
    }
  }


  /*
   * Addresses are distinct
   */

  for (i = 1; i < NUM_CHUNKS; i++) {
    if (addresses[i] == addresses[i-1]) {
      printf("Not all chunk addresses are Distinct!\n");
      break;
    }
  }


  /*
   * Memory is contiguous
   * Chunk size OK
   */

  for (i = 1; i < NUM_CHUNKS; i++) {
    if (addresses[i] != addresses[i-1] + CHUNK_SIZE) {
      printf("Contiguity and Chunk Size NOT OK!\n");
      break;
    }
  }


  /*
   * Does not allocate more than NUM_CHUNKS
   */

  if (mm_get(&MM) != NULL) {
    printf("Allocating more than %d\n possible chunks!", NUM_CHUNKS);
  }


  /*
   * Deallocate a random number of chunks
   * Reallocate only these
   */

  for (i = 0; i < NUM_CHUNKS; i += (rand() % (NUM_CHUNKS/5)) + 1) {
    mm_put(&MM, (void*) addresses[i]);
    free_addresses[i] = addresses[i];
  }

  while (address == mm_get(&MM)) {
    found = 0;
    for (i = 0; i < NUM_CHUNKS; i++) {
      if (free_addresses[i] == (unsigned long int) address) {
        found = 1;
        break;
      }
    }
    if (found == 0) {
      printf("A chunk in use (or unmanaged) is being Allocated!\n");
      break;
    }
  }

  mm_release(&MM);
  free(free_addresses);
  free(addresses);


  /*
   * What about allocation and
   * deallocation of just a few chunks?
   */

  addresses = (unsigned long int*) malloc(10 * sizeof(unsigned long int));

  if (mm_init(&MM1, 10, 20) == -1) {
	printf("Failed to initialize memory!\n");
        exit(-1);
  }

  for (i = 0; i < 4; i++)
    addresses[i] = (unsigned long int) mm_get(&MM1);

  mm_put(&MM1, (void*) addresses[1]);
  addresses[1] = 0;

  while (address == mm_get(&MM1)) {
    found = 0;
    for (i = 0; i < 4; i++) {
      if (addresses[i] == (unsigned long int) address) {
        printf("A chunk in use is being reallocated!\n");
        break;
      }
    }
  }

  mm_release(&MM1);
  free(addresses);

  /*
   * Finally, Can we use the chunks?
   * Expect no segmentation fault.
   */

  if (mm_init(&MM2, NUM_CHUNKS, sizeof(chunk_t)) == -1) {
	printf("Failed to initialize memory!\n");
        exit(-1);
  }

  chunk_t *my_chunk;
  for (i = 0; i < NUM_CHUNKS; i++) {
    chunk_t new_chunk;
    new_chunk.val = i;
    my_chunk = (chunk_t*) mm_get(&MM2);
    memcpy(my_chunk, &new_chunk, sizeof(chunk_t));
  }

  mm_release(&MM2);

  return 0;
}
int main(int argc, char* argv[]) {
  FILE* F;
  TreeModel *model;
  int i, j, k, alph_size, nstates, do_eqfreqs = 0, exch_mode = 0, 
    list_mode = 0, latex_mode = 0, suppress_diag = 0, ti_tv = 0, 
    scientific_mode = 0,
    induced_aa = 0, do_stop_codons = 0, do_zeroes = 0, symmetric = 0, 
    context_ti_tv = 0, all_branches = 0;
  int startcol, endcol, ncols, branch_no = 0, matrix_idx = 0;
/*   int aa_inv[256]; */
  double t = -1, total_ti = 0, total_tv = 0, rho_s = 0, cpg_ti = 0, 
    cpg_tv = 0, non_cpg_ti = 0, non_cpg_tv = 0, cpg_eqfreq = 0;
  char *rate_format_string = "%8.6f";
  MarkovMatrix *M;
  char c;
  char tuple[5], tuple2[5]; /* , aa_alph[50]; */
  char *subst_mat_fname = NULL, *subst_score_fname = NULL, 
    *subst_mat_fname_paml = NULL, *order1_mod_fname = NULL;
  Matrix *subst_mat = NULL;
  List *matrix_list = lst_new_ptr(20), *traversal = NULL;

  while ((c = (char)getopt(argc, argv, "t:fedlLiM:N:A:B:aszSECh")) != -1) {
   switch(c) {
    case 't':
      if (optarg[0] == 'A') all_branches = 1;
      else t = get_arg_dbl_bounds(optarg, 0, INFTY);
      break;
    case 'f':
      do_eqfreqs = 1;
      break;
    case 'e':
      exch_mode = 1;
      break;
    case 'd':
      suppress_diag = 1;
      break;
    case 'l':
      list_mode = 1;
      break;
    case 'L':
      latex_mode = 1;
      break;
    case 'i':
      ti_tv = 1;
      break;
    case 'M':
      subst_mat_fname = optarg;
      induced_aa = 1;
      break;
    case 'N':
      subst_mat_fname_paml = optarg;
      induced_aa = 1;
      break;
    case 'A':
      subst_score_fname = optarg;
      break;
    case 'B':
      order1_mod_fname = optarg;
      break;
    case 'a':
      induced_aa = 1;
      do_zeroes = 1;
      break;
    case 's':
      do_stop_codons = 1;
      break;
    case 'z':
      do_zeroes = 1;
      break;
    case 'S':
      symmetric = 1;
      break;
    case 'E':
      scientific_mode = 1;
      rate_format_string = "%13.6e";
      break;
    case 'C':
      context_ti_tv = 1;
      break;
    case 'h':
      print_usage();
      exit(0);
    case '?':
      die("Unrecognized option.  Try \"display_rate_matrix -h\" for help.\n");
    }
  }

  set_seed(-1);

  if ((t >= 0 && exch_mode) || (latex_mode && list_mode) || 
      ((ti_tv || subst_mat_fname != NULL || subst_score_fname != NULL || 
        subst_mat_fname_paml != NULL || scientific_mode) && !list_mode) || 
      (subst_mat_fname != NULL && subst_score_fname != NULL) || 
      (subst_score_fname != NULL && subst_mat_fname_paml != NULL) || 
      (subst_mat_fname != NULL && subst_mat_fname_paml != NULL) || 
      optind != argc - 1) {
    die("ERROR: missing required arguments or illegal combination of arguments.\nTry \"display_rate_matrix -h\" for help.\n");
  }

  F = phast_fopen(argv[optind], "r");
  model = tm_new_from_file(F, 1);

  if (context_ti_tv) {
    /* this option requires completely different handling from the others */
    if (model->order != 2) { 
      die("ERROR: -C requires a model of order 3.\n");
    }
    do_context_dependent_ti_tv(model);
    exit(0);
  }

  if (induced_aa) {
    TreeModel *aa_model = tm_induced_aa(model);
    char *codon_to_aa = get_codon_mapping(model->rate_matrix->states);

    /* before freeing model, grab the expected rate of synonymous
       subst, rho_s */
    for (i = 0; i < model->rate_matrix->size; i++)
      for (j = 0; j < model->rate_matrix->size; j++)
        if (i != j && codon_to_aa[i] == codon_to_aa[j])
          rho_s += mm_get(model->rate_matrix, i, j) * 
            vec_get(model->backgd_freqs, i);

    sfree(codon_to_aa);

    tm_free(model);
    model = aa_model;
  }

  if (all_branches) {
    traversal = tr_inorder(model->tree);
    for (matrix_idx = 0; matrix_idx < lst_size(traversal); matrix_idx++) {
      TreeNode *n = lst_get_ptr(traversal, matrix_idx);
      if (n->parent == NULL) { lst_push_ptr(matrix_list, NULL); continue; }
      M = mm_new(model->rate_matrix->size, model->rate_matrix->states, DISCRETE);
      mm_exp(M, model->rate_matrix, n->dparent);
      lst_push_ptr(matrix_list, M);      
    }
  }
  else if (t >= 0) {
    M = mm_new(model->rate_matrix->size, model->rate_matrix->states, DISCRETE);
    mm_exp(M, model->rate_matrix, t);
    lst_push_ptr(matrix_list, M);
  }
  else 
    lst_push_ptr(matrix_list, model->rate_matrix);

  alph_size = (int)strlen(model->rate_matrix->states);
  nstates = model->rate_matrix->size;

  if (subst_mat_fname != NULL) {
    if ((F = fopen(subst_mat_fname, "r")) == NULL) {
      die("ERROR: Can't open %s.\n", subst_mat_fname);
    }    
    subst_mat = read_subst_mat(F, AA_ALPHABET); 
  }
  else if (subst_mat_fname_paml != NULL) {
    if ((F = fopen(subst_mat_fname_paml, "r")) == NULL) {
      die("ERROR: Can't open %s.\n", subst_mat_fname_paml);
    }    
    subst_mat = read_paml_matrix(F, AA_ALPHABET); 
  }
  else if (subst_score_fname != NULL) {
    if ((F = fopen(subst_score_fname, "r")) == NULL) {
      die("ERROR: Can't open %s.\n", subst_score_fname);
    }    
    subst_mat = read_subst_scores(model, F);
  }
  else if (order1_mod_fname != NULL) {
    if ((F = fopen(order1_mod_fname, "r")) == NULL) {
      die("ERROR: Can't open %s.\n", order1_mod_fname);
    }    
    subst_mat = unproject_rates(model, tm_new_from_file(F, 1));
  }

  /* loop through matrices to print */
  for (matrix_idx = 0; matrix_idx < lst_size(matrix_list); matrix_idx++) {
    M = lst_get_ptr(matrix_list, matrix_idx);

    if (all_branches) {
      if (M == NULL) continue;  /* root */
      printf("BRANCH %d (t = %.6f)\n", ++branch_no,
             ((TreeNode*)lst_get_ptr(traversal, matrix_idx))->dparent);
    }

  /* print no more than 16 columns at a time (except with -a) */
  ncols = (induced_aa ? nstates : 16);
  for (startcol = 0; startcol < nstates; startcol += ncols) {
    endcol = min(nstates, startcol+ncols);

    /* table header */
    if (! list_mode) {
      if (latex_mode) {
        printf("\\begin{tabular}{|c|");
        for (i = startcol; i < endcol; i++) printf("r");
        printf("|}\n\\hline\n");
      }
      printf("%-5s ", "");
      if (latex_mode) printf("& ");
      for (i = startcol; i < endcol; i++) {
        get_state_tuple(model, tuple, i);
        if (latex_mode) {
          printf("{\\bf %s}", tuple);
          if (i < endcol-1) printf("& ");
        }
        else printf("%8s ", tuple);
    }
      if (latex_mode) printf("\\\\\n\\hline\n");
      else printf("\n");
    }

    /* table or list contents */
    for (i = 0; i < nstates; i++) {
      if (induced_aa && AA_ALPHABET[i] == '$' && !do_stop_codons) continue;
      get_state_tuple(model, tuple, i);

      /* get total eq freq of tuples containing CpG dinucs */
      for (k = 0; k < model->order; k++) {
        if (tuple[k] == 'C' && tuple[k+1] == 'G') {
          cpg_eqfreq += vec_get(model->backgd_freqs, i);
/*           printf("***CPG***"); */
          break;
        }
      }

      if (latex_mode) printf("{\\bf %s}& ", tuple);
      else if (!list_mode) printf("%-5s ", tuple);
      for (j = startcol; j < endcol; j++) {
        if (induced_aa && AA_ALPHABET[j] == '$' && !do_stop_codons) continue;
        if (latex_mode) printf("$");
        if (list_mode) {
          if (symmetric && j <= i) continue;
          else if ((t < 0 && ! all_branches) 
		   && (i == j || (!do_zeroes && mm_get(M, i, j) == 0))) 
            continue;
          get_state_tuple(model, tuple2, j);
          printf("%-5s %-5s ", tuple, tuple2);
        }
        if (i == j && suppress_diag && !list_mode) printf("%-7s", "-");
        else { 
	  /* get rate or probability */
	  double val = exch_mode == 0 ? mm_get(M, i, j) : 
	    safediv(mm_get(M, i, j), vec_get(model->backgd_freqs,j));
	  /* print value in format %8.6f or %13.6e */
	  printf(rate_format_string, val); 
	  printf(" ");
	}
        if (latex_mode) {
          printf("$");
          if (j < endcol-1) printf("& ");
        }
        else if (list_mode) {
          int ti, is_cpg;
          if (ti_tv) {
            ti = -1;
            is_cpg = 0;
            for (k = 0; k <= model->order; k++) {
              int dig_i = (i % int_pow(alph_size, k+1)) / int_pow(alph_size, k);
              int dig_j = (j % int_pow(alph_size, k+1)) / int_pow(alph_size, k);
              char next_char = '\0', prev_char = '\0';
              if (dig_i != dig_j) {
                ti = is_transition(M->states[dig_i], M->states[dig_j]);
                if (k != model->order)
                  prev_char = M->states[(i % int_pow(alph_size, k+2)) / 
                                        int_pow(alph_size, k+1)];
                if (k != 0)
                  next_char = M->states[(i % int_pow(alph_size, k)) / 
                                        int_pow(alph_size, k-1)];
                if ((M->states[dig_i] == 'C' && next_char == 'G') || 
                    (M->states[dig_i] == 'G' && prev_char == 'C')) 
                  is_cpg = 1;
              }
            }
	    if (ti == -1)
	      die("ERROR ti=-1\n");
            printf("%5s ", ti ? "ti" : "tv");
/*             printf("%5s ", is_cpg ? "CPG" : "-"); */
            if (ti) {
              total_ti += mm_get(M, i, j) * 
                vec_get(model->backgd_freqs, i);
              if (is_cpg) 
                cpg_ti += mm_get(M, i, j) * 
                  vec_get(model->backgd_freqs, i);
              else non_cpg_ti += mm_get(M, i, j) * 
                     vec_get(model->backgd_freqs, i);
            }
            else {
              total_tv += mm_get(M, i, j) * 
                vec_get(model->backgd_freqs, i);
              if (is_cpg)
                cpg_tv += mm_get(M, i, j) * 
                  vec_get(model->backgd_freqs, i);
              else non_cpg_tv += mm_get(M, i, j) * 
                     vec_get(model->backgd_freqs, i);
            }
          }
          if (subst_mat != NULL) {
            if (mat_get(subst_mat, i, j) == NEGINFTY) 
              printf("%8s", "-"); 
            else printf("%8.4f", mat_get(subst_mat, i, j)); 
          }
          printf("\n");
        }
      }
      if (latex_mode) printf("\\\\\n");
      else if (!list_mode) printf("\n");
    }
    
    /* equilibrium freqs (table case only) */
    if (do_eqfreqs && ! list_mode) {
      if (latex_mode) 
        printf("\\hline\n$\\boldsymbol{\\mathbf{\\pi}}$&");
      else 
        printf("%-5s ", "pi");
      for (i = startcol; i < endcol; i++) {
        if (latex_mode) 
          printf("$%8.4f$ ", vec_get(model->backgd_freqs, i));      
        else 
          printf("%8.4f ", vec_get(model->backgd_freqs, i));      
        if (latex_mode && i < endcol-1) printf("& ");
      }
      if (latex_mode) printf("\\\\\n");
      else printf("\n");
    }

    if (latex_mode) printf("\\hline\n\\end{tabular}\n\n");
  }

  /* equilibrium freqs (list case only) */
  if (do_eqfreqs &&  list_mode) {
    for (i = 0; i < nstates; i++) {
      get_state_tuple(model, tuple, i);
      printf("%-5s %-5s ", "-", tuple); //!!
      printf(rate_format_string, vec_get(model->backgd_freqs, i)); 
      printf("\n");
    }
  }
  
  if (ti_tv && list_mode) {
    printf("\n#Total ti/tv = %.4f\n", total_ti/total_tv);
    printf("#CpG ti ratio = %.4f, CpG tv ratio = %.4f\n", 
           cpg_ti/non_cpg_ti /* * (1 - cpg_eqfreq) */ / cpg_eqfreq, 
           cpg_tv/non_cpg_tv /* * (1 - cpg_eqfreq) */ / cpg_eqfreq);
  }
  else if (induced_aa) 
    printf("\n#Total rho_s/rho_v = %.4f\n", rho_s/(3-rho_s));

  if (all_branches == 1) printf("\n\n");
  }

  tm_free(model);
  lst_free(matrix_list);

  return 0;
}
/* this function implements the -C option */
void do_context_dependent_ti_tv(TreeModel *mod) {
  char *alph = mod->rate_matrix->states;
  int alph_size = (int)strlen(alph);
  char tuple_i[mod->order+2], tuple_j[mod->order+2];
  double context_ti[alph_size][alph_size], context_tv[alph_size][alph_size],
    ti_AT_5_pyrim[3][3], tv_AT_5_pyrim[3][3],
    all_ti, all_tv, expected_rate;
  int mid_src, mid_targ, first, last, at_states[2], gc_states[2], i, j, 
    num_5_pyrim;
  if (mod->order != 2)
    die("ERROR do_context_dependent_ti_tv: mod->order (%i) should be 2\n",
	mod->order);
  if (alph_size != 4)
    die("ERROR do_contect_dependent_ti_tv: alph_size (%i) should be 4\n", 
	alph_size);

  tuple_i[mod->order+1] = tuple_j[mod->order+1] = '\0';

  /* We only care about substitutions at the middle position */
  for (first = 0; first < alph_size; first++) {
    for (last = 0; last < alph_size; last++) {
      context_ti[first][last] = context_tv[first][last] = 0;
      for (mid_src = 0; mid_src < alph_size; mid_src++) {
        for (mid_targ = 0; mid_targ < alph_size; mid_targ++) {
          if (mid_src == mid_targ) continue;

          i = last + mid_src*alph_size + first*alph_size*alph_size;
          j = last + mid_targ*alph_size + first*alph_size*alph_size;
          expected_rate = mm_get(mod->rate_matrix, i, j) * 
            vec_get(mod->backgd_freqs, i);

/*           get_tuple_str(tuple_i, i, mod->order+1,  */
/*                         mod->rate_matrix->states); */
/*           get_tuple_str(tuple_j, j, mod->order+1,  */
/*                         mod->rate_matrix->states); */

/*           if ((tuple_i[1] == 'C' && tuple_i[2] == 'G') || tuple_i[0] == 'C' && tuple_i[1] == 'G') continue; */

          if (is_transition(alph[mid_src], alph[mid_targ]))
            context_ti[first][last] += expected_rate;
          else if (i != j)
            context_tv[first][last] += expected_rate;
        }
      }
    }
  }

  /* first print equivalent of table 2 */

  /* get "states" associated with A+T bases and G+C bases */
  at_states[0] = mod->rate_matrix->inv_states['A'];
  at_states[1] = mod->rate_matrix->inv_states['T'];
  gc_states[0] = mod->rate_matrix->inv_states['C'];
  gc_states[1] = mod->rate_matrix->inv_states['G'];

  /* header */
  printf("%5s %5s %5s %8s %8s %8s\n", "A+T", "5'", "3'", "Ts", "Tv", "Tv/(Tv+Ts)");

  for (i = 0; i < 3; i++)
    for (j = 0; j < 3; j++)
      ti_AT_5_pyrim[i][j] = tv_AT_5_pyrim[i][j] = 0;

  /* AT content 0 (GC either side) */
  all_ti = all_tv = 0;
  for (first = 0; first < 2; first++) {
    for (last = 0; last < 2; last++) {
      printf("%5d %5c %5c %8.4f %8.4f %8.4f\n", 0, 
             alph[(int)gc_states[first]], 
             alph[(int)gc_states[last]], 
             context_ti[gc_states[first]][gc_states[last]],
             context_tv[gc_states[first]][gc_states[last]],
             context_tv[gc_states[first]][gc_states[last]] /
             (context_ti[gc_states[first]][gc_states[last]] +
              context_tv[gc_states[first]][gc_states[last]]));
      all_ti += context_ti[gc_states[first]][gc_states[last]];
      all_tv += context_tv[gc_states[first]][gc_states[last]];
      
      num_5_pyrim = IS_PYRIMIDINE(alph[(int)gc_states[first]]);
      num_5_pyrim += IS_PYRIMIDINE(msa_compl_char(alph[(int)gc_states[last]]));
      ti_AT_5_pyrim[0][num_5_pyrim] += 
        context_ti[gc_states[first]][gc_states[last]];
      tv_AT_5_pyrim[0][num_5_pyrim] += 
        context_tv[gc_states[first]][gc_states[last]];
    }
  }
  printf("%5d %5s %5s %8.4f %8.4f %8.4f\n", 0, "all", "all", all_ti, 
         all_tv, all_tv / (all_ti + all_tv));
      
  /* AT content 1 (AT one side, GC other side) */
  all_ti = all_tv = 0;
  for (first = 0; first < 2; first++) {
    for (last = 0; last < 2; last++) {
      printf("%5d %5c %5c %8.4f %8.4f %8.4f\n", 1, 
             alph[(int)at_states[first]], 
             alph[(int)gc_states[last]], 
             context_ti[at_states[first]][gc_states[last]],
             context_tv[at_states[first]][gc_states[last]],
             context_tv[at_states[first]][gc_states[last]] /
             (context_ti[at_states[first]][gc_states[last]] +
              context_tv[at_states[first]][gc_states[last]]));
      printf("%5d %5c %5c %8.4f %8.4f %8.4f\n", 1, 
             alph[(int)gc_states[first]], 
             alph[(int)at_states[last]], 
             context_ti[gc_states[first]][at_states[last]],
             context_tv[gc_states[first]][at_states[last]],
             context_tv[gc_states[first]][at_states[last]] /
             (context_ti[gc_states[first]][at_states[last]] +
              context_tv[gc_states[first]][at_states[last]]));
      all_ti += context_ti[at_states[first]][gc_states[last]] +
        context_ti[gc_states[first]][at_states[last]];
      all_tv += context_tv[at_states[first]][gc_states[last]] +
        context_tv[gc_states[first]][at_states[last]];

      num_5_pyrim = IS_PYRIMIDINE(alph[(int)at_states[first]]);
      num_5_pyrim += IS_PYRIMIDINE(msa_compl_char(alph[(int)gc_states[last]]));
      ti_AT_5_pyrim[1][num_5_pyrim] += 
        context_ti[at_states[first]][gc_states[last]];
      tv_AT_5_pyrim[1][num_5_pyrim] += 
        context_tv[at_states[first]][gc_states[last]];

      num_5_pyrim = IS_PYRIMIDINE(alph[(int)gc_states[first]]);
      num_5_pyrim += IS_PYRIMIDINE(msa_compl_char(alph[(int)at_states[last]]));
      ti_AT_5_pyrim[1][num_5_pyrim] += 
        context_ti[gc_states[first]][at_states[last]];
      tv_AT_5_pyrim[1][num_5_pyrim] += 
        context_tv[gc_states[first]][at_states[last]];
    }
  }
  printf("%5d %5s %5s %8.4f %8.4f %8.4f\n", 1, "all", "all", all_ti, 
         all_tv, all_tv / (all_ti + all_tv));

  /* AT content 2 (AT both sides) */
  all_ti = all_tv = 0;
  for (first = 0; first < 2; first++) {
    for (last = 0; last < 2; last++) {
      printf("%5d %5c %5c %8.4f %8.4f %8.4f\n", 2, 
             alph[(int)at_states[first]], 
             alph[(int)at_states[last]], 
             context_ti[at_states[first]][at_states[last]],
             context_tv[at_states[first]][at_states[last]],
             context_tv[at_states[first]][at_states[last]] /
             (context_ti[at_states[first]][at_states[last]] +
              context_tv[at_states[first]][at_states[last]]));
      all_ti += context_ti[at_states[first]][at_states[last]];
      all_tv += context_tv[at_states[first]][at_states[last]];

      num_5_pyrim = IS_PYRIMIDINE(alph[(int)at_states[first]]);
      num_5_pyrim += IS_PYRIMIDINE(msa_compl_char(alph[(int)at_states[last]]));
      ti_AT_5_pyrim[2][num_5_pyrim] += 
        context_ti[at_states[first]][at_states[last]];
      tv_AT_5_pyrim[2][num_5_pyrim] += 
        context_tv[at_states[first]][at_states[last]];
    }
  }
  printf("%5d %5s %5s %8.4f %8.4f %8.4f\n", 2, "all", "all", all_ti, 
         all_tv, all_tv / (all_ti + all_tv));

  /* now print equivalent of table 3 */
  printf("\n\n%5s %5s %8s %8s %8s\n", "A+T", "5'Y", "Ts", "Tv", "Tv/(Tv+Ts)");
  for (i = 0; i < 3; i++) 
    for (j = 0; j < 3; j++) 
      printf("%5d %5d %8.4f %8.4f %8.4f\n", i, j, ti_AT_5_pyrim[i][j], tv_AT_5_pyrim[i][j], tv_AT_5_pyrim[i][j]/(tv_AT_5_pyrim[i][j] + ti_AT_5_pyrim[i][j]));
  for (j = 0; j < 3; j++) {
    double all_ti = ti_AT_5_pyrim[0][j] + ti_AT_5_pyrim[1][j] + 
      ti_AT_5_pyrim[2][j];
    double all_tv = tv_AT_5_pyrim[0][j] + tv_AT_5_pyrim[1][j] + 
      tv_AT_5_pyrim[2][j];
    printf("%5s %5d %8.4f %8.4f %8.4f\n", "all", j, all_ti, all_tv, all_tv/(all_tv + all_ti));
  }
}