StochHMM  v0.34
Flexible Hidden Markov Model C++ Library and Application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
lexicalTable.cpp
Go to the documentation of this file.
1 //
2 // Lexical.cpp
3 // StochHMM
4 //
5 // Created by Paul Lott on 4/2/12.
6 // Copyright (c) 2012 University of California, Davis. All rights reserved.
7 //
8 
9 #include "lexicalTable.h"
10 
11 
12 
13 namespace StochHMM{
14 
16  max_order=0;
17 
18  logProb=NULL;
19  counts = NULL;
20  prob = NULL;
21  log_emission = NULL;
22  x_subarray=NULL;
23  y_subarray=NULL;
24 
25 
27  unknownDefinedScore=-INFINITY;
28 
29  return;
30  }
31 
33  delete logProb;
34  delete prob;
35  delete counts;
36  delete log_emission;
37  delete x_subarray;
38  delete y_subarray;
39 
40  logProb=NULL;
41  prob=NULL;
42  counts=NULL;
43  log_emission = NULL;
44  x_subarray=NULL;
45  y_subarray=NULL;
46  }
47 
48  void lexicalTable::createTable(int rows, int columns, int pseudocount, valueType typ){
49  if (typ==COUNTS){
50  if (counts!=NULL){
51  delete counts;
52  }
53  std::vector<double> temp_columns(columns,pseudocount);
54  counts=new(std::nothrow) std::vector<std::vector<double> > (rows,temp_columns);
55 
56  if (counts==NULL){
57  std::cerr << "OUT OF MEMORY\nFile" << __FILE__ << "Line:\t"<< __LINE__ << std::endl;
58  exit(1);
59  }
60  }
61  return;
62  }
63 
65  std::cout << stringify() << std::endl;
66  }
67 
68 
69  std::vector<std::vector<double> >* lexicalTable::getCountsTable(){
70  if (counts==NULL){
71  counts = new(std::nothrow) std::vector<std::vector<double> >;
72 
73  if (counts==NULL){
74  std::cerr << "OUT OF MEMORY\nFile" << __FILE__ << "Line:\t"<< __LINE__ << std::endl;
75  exit(1);
76  }
77 
78  }
79 
80  return counts;
81  }
82 
83 
84  std::vector<std::vector<double> >* lexicalTable::getProbabilityTable(){
85  if (prob==NULL){
86  prob = new(std::nothrow) std::vector<std::vector<double> >;
87 
88  if (prob==NULL){
89  std::cerr << "OUT OF MEMORY\nFile" << __FILE__ << "Line:\t"<< __LINE__ << std::endl;
90  exit(1);
91  }
92 
93  }
94 
95  return prob;
96  }
97 
98 
99  std::vector<std::vector<double> >* lexicalTable::getLogProbabilityTable(){
100  if (logProb==NULL){
101  logProb = new(std::nothrow) std::vector<std::vector<double> >;
102 
103  if (logProb==NULL){
104  std::cerr << "OUT OF MEMORY\nFile" << __FILE__ << "Line:\t"<< __LINE__ << std::endl;
105  exit(1);
106  }
107  }
108 
109  return logProb;
110  }
111 
112  //Return emission probability of sequences
113  double lexicalTable::getValue(sequences& seqs, size_t pos){
114 
115  if (max_order>pos){
116  return getReducedOrder(seqs, pos);
117  }
118 
119  size_t index(seqs[subarray_sequence[0]][pos - subarray_position[0]] * subarray_value[0]);
120 
121  for(size_t i=1;i<dimensions;i++){
122  index += seqs[subarray_sequence[i]][pos - subarray_position[i]] * subarray_value[i];
123  }
124 
125  if (index > array_size){
126  std::cerr << "Index is out of range of lookup table in lexicalTable" << std::endl;
127  exit(2);
128  }
129 
130  return (*log_emission)[index];
131  }
132 
133  //Return emission probability of sequences
134  double lexicalTable::getValue(sequence& seq, size_t pos){
135 
136  if (max_order>pos){
137  return getReducedOrder(seq, pos);
138  }
139 
140  size_t index(seq[pos - subarray_position[0]] * subarray_value[0]);
141 
142  for(size_t i=1;i<dimensions;i++){
143  index += seq[pos - subarray_position[i]] * subarray_value[i];
144  }
145 
146  if (index > array_size){
147  std::cerr << "Index is out of range of lookup table in lexicalTable" << std::endl;
148  exit(2);
149  }
150 
151  return (*log_emission)[index];
152  }
153 
154 
155  //!Add a track to an emission
156  //!\param trk Pointer to track
157  //!\param orderValue order of emission from track
158  void lexicalTable::addTrack(track* trk,int orderValue){
159  trcks.push_back(trk);
160  alphabets.push_back(trk->getAlphaSize());
161  order.push_back(orderValue);
162  if (orderValue>max_order){
163  max_order=orderValue;
164  }
165 
166  }
167 
168  //!Set the type of counts in the emission 2D table provided by the user
169  //!\param temp vector of vectors of doubles
170  //!\param emmType Type of value (COUNTS, PROBABILITY, LOG_PROB)
171  void lexicalTable::assignTable(std::vector<std::vector<double > >* temp, valueType emmType){
172  if (emmType==COUNTS){
173  counts=temp;
174  }
175  else if (emmType == PROBABILITY){
176  prob=temp;
177  }
178  else if (emmType == LOG_PROB){
179  logProb=temp;
181  }
182  }
183 
184 
186  std::string tbl("");
187 
188  size_t tracks_size = trcks.size();
189 
190  if(tracks_size==0){
191  std::cerr << "Can't print out table without track and order being set for lexicalTable\n";
192  exit(1);
193  }
194 
195  //Calculate the Number of Column Headers and get alphabet for each track
196  //This is the complete unambiguous and ambiguous
197 
198  std::vector<std::vector<std::string> > complete_alphabet(tracks_size, std::vector<std::string>());
199 
200  size_t columns(1);
201  std::vector<size_t> alphaSizes;
202 
203  //Calculate the columns size
204  for(size_t i = 0;i<trcks.size();i++){
205  size_t alphaSz = (trcks[i]->isAmbiguousSet()) ? trcks[i]->getMaxAmbiguous()+1 : trcks[i]->getAlphaSize();
206  columns*=alphaSz;
207  alphaSizes.push_back(alphaSz);
208 
209  //Get complete alphabet for each track
210  for(size_t j=0; j < alphaSz; ++j){
211  complete_alphabet[i].push_back(trcks[i]->getAlpha(j));
212  }
213  }
214 
215  reverse(alphaSizes.begin(),alphaSizes.end());
216 
217  std::string colHeader("@");
218 
219  //Compose column heading
220  for(size_t i = 0; i < columns; ++i){
221  size_t indexValue = i;
222  for(size_t tr=0;tr<trcks.size();tr++){
223 
224  if (tr>0){
225  colHeader+= "|";
226  }
227 
228  size_t val(0);
229  if (tr<trcks.size()-1){
230  val= floor(indexValue/alphaSizes[tr]);
231  indexValue-=val*alphaSizes[tr];
232  }
233  else{
234  val = indexValue;
235  }
236 
237  colHeader+=complete_alphabet[tr][val];
238  }
239  colHeader+="\t";
240  }
241 
242  tbl+=colHeader + "\n";
243 
244 
245 // for (size_t i=0; i< log_emission->size();i++){
246 // std::cout << (*log_emission)[i] << std::endl;
247 // }
248 
249 
250  // bool rowHeader = (temp->size()>1) ? true : false;
251 //
252 // for(size_t i=0;i<temp->size();i++){
253 // std::string header("");
254 //
255 // if (rowHeader){
256 // size_t indexValue = i;
257 //
258 // for(size_t tr=0;tr<trcks.size();tr++){
259 //
260 // if (tr>0 && order[tr]>0){
261 // header+= "|";
262 // }
263 //
264 //
265 // size_t val(0);
266 // if (tr<trcks.size()-1){
267 // double pwr = POWER[order[tr+1]][trcks[tr+1]->getAlphaSize()-1];
268 // val= floor(indexValue/pwr);
269 // indexValue-=val*pwr;
270 // }
271 // else{
272 // val = indexValue;
273 // }
274 //
275 // header+=trcks[tr]->convertIndexToWord(val, order[tr]);
276 // }
277 // tbl+="@" + header + "\t";
278 //
279 // }
280 //
281 // for(size_t j=0;j<(*temp)[i].size();j++){
282 // if (j>0){
283 // tbl+="\t";
284 // }
285 // tbl+=double_to_string((*temp)[i][j]);
286 // }
287 // tbl+="\n";
288 // }
289 
290 
291  return tbl;
292  }
293 
294 
295 
296 
297  std::string lexicalTable::stringify(){
298  std::string tbl("");
299  size_t tracks_size = trcks.size();
300 
301  if(tracks_size==0){
302  std::cerr << "Can't print out table without track and order being set for lexicalTable\n";
303  exit(1);
304  }
305 
306  //Output Column Headers
307  size_t columns(1);
308  std::vector<size_t> alphaSizes;
309  //alphaSizes.push_back(0);
310 
311  for(size_t i = 0;i<trcks.size();i++){
312  size_t alphaSz = trcks[i]->getAlphaSize();
313  columns*=alphaSz;
314  alphaSizes.push_back(alphaSz);
315  }
316 
317 
318  reverse(alphaSizes.begin(),alphaSizes.end());
319 
320  std::string colHeader("@");
321 
322  for(size_t i = 0;i<columns;i++){
323  size_t indexValue = i;
324  for(size_t tr=0;tr<trcks.size();tr++){
325 
326  if (tr>0){
327  colHeader+= "|";
328  }
329 
330  size_t val(0);
331  if (tr<trcks.size()-1){
332  val= floor(indexValue/alphaSizes[tr]);
333  indexValue-=val*alphaSizes[tr];
334  }
335  else{
336  val = indexValue;
337  }
338 
339  colHeader+=trcks[tr]->convertIndexToWord(val, 1);
340  }
341  colHeader+="\t";
342  }
343 
344  tbl+=colHeader + "\n";
345 
346  std::vector<std::vector<double> >* temp;
347 
348  if (logProb!=NULL){
349  temp=logProb;
350  }
351  else if (prob!=NULL){
352  temp=prob;
353  }
354  else if (counts!=NULL){
355  temp=counts;
356  }
357  else{
358  std::cerr << "No table is defined\n";
359  return "";
360  }
361 
362  //TODO: Fix row header for other orders
363  bool rowHeader = (temp->size()>1) ? true : false;
364  for(size_t i=0;i<temp->size();i++){
365  std::string header("");
366 
367  if (rowHeader){
368  size_t indexValue = i;
369 
370  for(size_t tr=0;tr<trcks.size();tr++){
371 
372  if (tr>0 && order[tr]>0){
373  header+= "|";
374  }
375 
376 
377  size_t val(0);
378  if (tr<trcks.size()-1){
379  double pwr = POWER[order[tr+1]][trcks[tr+1]->getAlphaSize()-1];
380  val= floor(indexValue/pwr);
381  indexValue-=val*pwr;
382  }
383  else{
384  val = indexValue;
385  }
386 
387  header+=trcks[tr]->convertIndexToWord(val, order[tr]);
388  }
389  tbl+="@" + header + "\t";
390 
391  }
392 
393  for(size_t j=0;j<(*temp)[i].size();j++){
394  if (j>0){
395  tbl+="\t";
396  }
397  tbl+=double_to_string((*temp)[i][j]);
398  }
399  tbl+="\n";
400  }
401  return tbl;
402  }
403 
404 
405 
406 
407 
409  number_of_tracks = trcks.size();
410  y_dim = sumVector(order);
411 
412 
413  //Calculate subarray dimensions for logProb and new log_emission table (includes ambiguous character)
414  x_subarray = new size_t[number_of_tracks];
415  y_subarray = new size_t[y_dim];
416 
417  //Calculate Old subarray x_dimension values
418  for(size_t i=0;i<number_of_tracks;++i){
419  size_t value(1);
420  for(size_t j=i+1;j<number_of_tracks;++j){
421  value*=alphabets[j];
422  }
423  x_subarray[i]=value;
424  }
425 
426  //Calcuate Old subarray y_dimension values
427  std::vector<size_t> index(order[0],alphabets[0]);
428  for(size_t i=1;i<order.size();i++){
429  for(size_t j=0;j<order[i];j++){
430  index.push_back(alphabets[i]);
431  }
432  }
433 
434  for (size_t i=0;i<y_dim;i++){
435  size_t val = 1;
436  for(size_t j=i+1;j<y_dim;j++){
437  val*=index[j];
438  }
439  y_subarray[i]=val;
440  }
441 
442  return;
443  }
444 
445  //TODO: NEED TO COMPLETE THIS FUNCTION
446 // size_t lexicalTable::convertIndex(size_t old_row, size_t old_column){
447 // //Decompose previous value from indices to digital letter value
448 //
449 // }
450 
451 
455  subarray_value.resize(dimensions);
456  subarray_value.resize(dimensions);
457 
460 
461  //Calculate total size of emission table needed with ambiguous characters
462  array_size = 1;
463  std::vector<size_t> complete_alphabet_size;
464  size_t current_dim(0);
465  for(size_t i=0;i<number_of_tracks;i++){
466 
467  //Get alphabet size and store it
468  size_t alpha_size = trcks[i]->getTotalAlphabetSize();
469  complete_alphabet_size.push_back(alpha_size);
470  array_size*=integerPower(alpha_size, (size_t) order[i]+1);
471 
472  for(size_t j=0;j<=order[i];++j){
473  subarray_sequence[current_dim]=i;
474  current_dim++;
475  }
476  }
477 
478  //Calculate the Sequence positions
479  for (size_t i=0;i<number_of_tracks;i++){
480  for (size_t j=0;j<=order[i];++j){
481  subarray_position.push_back(order[i]-j);
482  }
483  }
484 
485 
486  //Compute the decomposing values
487  //Used to convert from index to word
488  std::vector<size_t> decompose_index;
489  for(size_t i=0;i<number_of_tracks;++i){
490  for(size_t j=0;j<order[i];++j){
491  decompose_index.push_back(complete_alphabet_size[i]);
492  }
493  }
494  for(size_t i=0;i<number_of_tracks;++i){
495  decompose_index.push_back(complete_alphabet_size[i]);
496  }
497 
498  //Calculate subarray values
499  for(size_t i=0;i<dimensions;++i){
500  decompose_values[i]=1;
501  for(size_t j=i+1;j<dimensions;++j){
502  decompose_values[i]*=decompose_index[j];
503  }
504  }
505 
506 
507  //Rearrange decompose values for subarray values;
508  //Final values in subarray_value will correspond to sequence AAA(A)B(B).
509  //Where A is 3rd order and B is 1st order;
510  size_t array_index(0);
511  size_t index(0);
512  for(size_t i=0;i<number_of_tracks;++i){
513  for(size_t j=0;j<order[i];++j){
514  subarray_value[array_index] = decompose_values[index];
515  array_index++;
516  index++;
517  }
518  subarray_value[array_index] = decompose_values[dimensions-number_of_tracks-i];
519  array_index++;
520  }
521 
522 
523  //Finalize decompose_sequence
524  std::vector<size_t> temp;
525  for(size_t i=0;i<number_of_tracks;++i){
526  for(size_t j=0;j<order[i];++j){
527  temp.push_back(i);
528  }
529  }
530  for(size_t i=0;i<number_of_tracks;++i){
531  temp.push_back(i);
532  }
533 
534  for(size_t i=0;i<dimensions;++i){
535  decompose_sequence[i]=temp[i];
536  }
537 
538  return;
539  }
540 
541 
542  //Transfer values from 2d table to array and also compute the ambiguous score
543  void lexicalTable::transferValues(std::vector<bool>& transferred){
544 
545  //Transfer unambiguous scores
546  for(size_t row=0;row<logProb->size();++row){
547  for(size_t column=0;column<(*logProb)[row].size();++column){
548  std::vector<uint8_t> alphabet;
549  decompose(row, column, alphabet);
550  size_t index = calculateArrayIndex(alphabet);
551  (*log_emission)[index] = (*logProb)[row][column];
552  transferred[index] = true;
553  }
554  }
555 
556  //Compute all ambiguous scores
557  for(size_t i=0;i<transferred.size();i++){
558  if (transferred[i]){
559  continue;
560  }
561 
563  (*log_emission)[i] = unknownDefinedScore;
564  continue;
565  }
566  else if (unknownScoreType == NO_SCORE){
567  continue;
568  }
569 
570  //Get the letters for index
571  std::vector<uint8_t> letters;
572  decompose(i,letters);
573 
574  //Expand the unambiguous words and get all the possible values
575  //std::vector<double> expanded;
576  //expand_ambiguous(letters,expanded);
577 
578  (*log_emission)[i] = getAmbiguousScore(letters);
579 
580 // //Assign the values accordint the Score Type
581 // if (unknownScoreType == AVERAGE_SCORE){
582 // (*log_emission)[i] = avgLogVector(expanded);
583 // }
584 // else if (unknownScoreType == LOWEST_SCORE){
585 // (*log_emission)[i] = minVector(expanded);
586 // }
587 // else if (unknownScoreType == HIGHEST_SCORE){
588 // (*log_emission)[i] = maxVector(expanded);
589 // }
590  }
591 
592 // for (size_t i=0;i<log_emission->size();++i){
593 // std::vector<uint8_t> letters;
594 // decompose(i,letters);
595 // for (size_t j = 0; j< letters.size();j++){
596 // std::cout << (int) letters[j];
597 // }
598 // std::cout << "\t" ;
599 // std::cout << (*log_emission)[i] << std::endl;
600 // }
601  return;
602  }
603 
604  //Calculate lower order emission from the current table values
605  //Given order and position/sequence
606  //Calculate the values using Index and [all alphabets] for higher orders
607  double lexicalTable::getReducedOrder(sequences& seqs, size_t position){
608  Index indices;
609  for(size_t i=0;i<dimensions;i++){
610  Index subtotal;
611  size_t seq = subarray_sequence[i];
612  size_t pos = subarray_position[i];
613 
614  if (subarray_position[i] > position){
615  subtotal.setAmbiguous(trcks[seq]->getUnambiguousSet());
616  }
617  else if (seqs[seq][position - pos] > max_unambiguous[seq]){
618  subtotal.setAmbiguous(trcks[seq]->getAmbiguousSet(seqs[seq][position-pos]));
619  }
620  else{
621  subtotal+=seqs[seq][position-pos];
622  }
623 
624  subtotal *= subarray_value[i];
625  indices += subtotal;
626  }
627 
629  double temp(0);
630  for(size_t i=0;i<indices.size();i++){
631  temp+=exp((*log_emission)[indices[i]]);
632  }
633  temp /= indices.size();
634  temp = log(temp);
635  return temp;
636  }
637  else if (unknownScoreType == LOWEST_SCORE){
638  double temp(INFINITY);
639  for(size_t i=0;i<indices.size();i++){
640  double val = (*log_emission)[indices[i]];
641  if (val < temp){
642  temp = val;
643  }
644  }
645  return temp;
646  }
647  else if (unknownScoreType == HIGHEST_SCORE){
648  double temp(-INFINITY);
649  for(size_t i=0;i<indices.size();i++){
650  double val = (*log_emission)[indices[i]];
651  if (val > temp){
652  temp = val;
653  }
654  }
655  return temp;
656  }
657  return -INFINITY;
658  }
659 
660 
661  //Calculate lower order emission from the current table values
662  //Given order and position/sequence
663  //Calculate the values using Index and [all alphabets] for higher orders
664  double lexicalTable::getReducedOrder(sequence& seq, size_t position){
665  Index indices;
666  for(size_t i=0;i<dimensions;i++){
667  Index subtotal;
668  size_t sq = subarray_sequence[i];
669  size_t pos = subarray_position[i];
670 
671  if (subarray_position[i] > position){
672  subtotal.setAmbiguous(trcks[sq]->getUnambiguousSet());
673  }
674  else if (seq[position - pos] > max_unambiguous[sq]){
675  subtotal.setAmbiguous(trcks[sq]->getAmbiguousSet(seq[position-pos]));
676  }
677  else{
678  subtotal+=seq[position-pos];
679  }
680 
681  subtotal *= subarray_value[i];
682  indices += subtotal;
683  }
684 
686  double temp(0);
687  for(size_t i=0;i<indices.size();i++){
688  temp+=exp((*log_emission)[indices[i]]);
689  }
690  temp /= indices.size();
691  temp = log(temp);
692  return temp;
693  }
694  else if (unknownScoreType == LOWEST_SCORE){
695  double temp(INFINITY);
696  for(size_t i=0;i<indices.size();i++){
697  double val = (*log_emission)[indices[i]];
698  if (val < temp){
699  temp = val;
700  }
701  }
702  return temp;
703  }
704  else if (unknownScoreType == HIGHEST_SCORE){
705  double temp(-INFINITY);
706  for(size_t i=0;i<indices.size();i++){
707  double val = (*log_emission)[indices[i]];
708  if (val > temp){
709  temp = val;
710  }
711  }
712  return temp;
713  }
714  return -INFINITY;
715  }
716 
717 
718  double lexicalTable::getAmbiguousScore(std::vector<uint8_t>& letters){
719  Index indices;
720  for(size_t i=0;i<dimensions;++i){
721  Index subtotal;
722  if (letters[i]>max_unambiguous[decompose_sequence[i]]){
723  subtotal.setAmbiguous(trcks[decompose_sequence[i]]->getAmbiguousSet(letters[i]));
724  }
725  else{
726  subtotal+= letters[i];
727  }
728 
729  subtotal *= decompose_values[i];
730  indices += subtotal;
731  }
732 
734  double temp(0);
735  for(size_t i=0;i<indices.size();i++){
736  temp+=exp((*log_emission)[indices[i]]);
737  }
738  temp /= indices.size();
739  temp = log(temp);
740 
741  return temp;
742  }
743  else if (unknownScoreType == LOWEST_SCORE){
744  double temp(INFINITY);
745  for(size_t i=0;i<indices.size();i++){
746  double val = (*log_emission)[indices[i]];
747  if (val < temp){
748  temp = val;
749  }
750  }
751  return temp;
752  }
753  else if (unknownScoreType == HIGHEST_SCORE){
754  double temp(-INFINITY);
755  for(size_t i=0;i<indices.size();i++){
756  double val = (*log_emission)[indices[i]];
757  if (val > temp){
758  temp = val;
759  }
760  }
761  return temp;
762  }
763 
764  return -INFINITY;
765  }
766 
767 
768  //Use index instead much faster than expanding the letters and then reverse computing
769 // void lexicalTable::expand_ambiguous(std::vector<uint8_t>& letters, std::vector<double>& expanded){
770 //
771 // std::vector<std::vector<uint8_t> >* temp_words = new std::vector<std::vector<uint8_t> >;
772 // temp_words->push_back(letters);
773 // for(size_t i=0;i<dimensions;i++){
774 // temp_words = expand_ambiguous(temp_words, i);
775 // }
776 //
777 // for(size_t i=0;i<temp_words->size();i++){
778 // size_t index = calculateIndexFromDecomposed((*temp_words)[i]);
779 // expanded.push_back((*log_emission)[index]);
780 // }
781 //
782 // return;
783 // }
784 //
785 // std::vector<std::vector<uint8_t> >* lexicalTable::expand_ambiguous(std::vector<std::vector<uint8_t> >* words, size_t letter){
786 //
787 // std::vector<std::vector<uint8_t> >* temp_words= new std::vector<std::vector<uint8_t> >;
788 // for(size_t i=0; i < words->size(); ++i){
789 // if ((*words)[i][letter] > max_unambiguous[decompose_sequence[letter]]){
790 // std::vector<uint8_t>& set = trcks[decompose_sequence[letter]]->getAmbiguousSet((*words)[i][letter]);
791 // for(size_t j=0;j<set.size();++j){
792 // (*words)[i][letter] = set[j];
793 // temp_words->push_back((*words)[i]);
794 // }
795 // }
796 // else{
797 // temp_words->push_back((*words)[i]);
798 // }
799 // }
800 //
801 // delete words;
802 // words = NULL;
803 // return temp_words;
804 // }
805 
806  size_t lexicalTable::calculateIndexFromDecomposed(std::vector<uint8_t>& word){
807  size_t index(0);
808  for(size_t i=0;i<dimensions;++i){
809  index += decompose_values[i] * word[i];
810  }
811  return index;
812  }
813 
814  size_t lexicalTable::calculateArrayIndex(std::vector<uint8_t>& kmer){
815  size_t index(0);
816  for(size_t i=0;i<dimensions;++i){
817  index += subarray_value[i] * kmer[i];
818  }
819  return index;
820  }
821 
822  void lexicalTable::decompose(size_t row, size_t column, std::vector<uint8_t>& letters){
823  //Decompose the row into the preceding letters
824  for(size_t i=0;i<y_dim;++i){
825  size_t val = floor(row/y_subarray[i]);
826  row -= val*y_subarray[i];
827  letters.push_back(val);
828  }
829 
830  //Decompose the column into the emitted letters
831  for(size_t i=0;i<number_of_tracks;++i){
832  size_t val = floor(column/x_subarray[i]);
833  column-=val*x_subarray[i];
834  letters.push_back(val);
835  }
836 
837  return;
838  }
839 
840 
841  void lexicalTable::decompose(size_t index, std::vector<uint8_t>& letters){
842 
843  //Decompose the index into the emitted letters
844  for(size_t i=0;i<dimensions;++i){
845  size_t val = floor(index/subarray_value[i]);
846  index-=val*subarray_value[i];
847  letters.push_back(val);
848  }
849 
850  return;
851  }
852 
853  //Todo
854  //Convert table to simpleNtable compatible format
855  //with ambiguous characters
857  if (logProb == NULL){
858  std::cerr << "Cannot initialize emission table until after the tables have been assigned";
859  exit(2);
860  }
863 
864  for(size_t i = 0; i < number_of_tracks ; ++i){
865  max_unambiguous.push_back(trcks[i]->getMaxUnambiguous());
866  }
867 
869  log_emission = new std::vector<double> (array_size,unknownDefinedScore);
870  }
871  else{
872  log_emission = new std::vector<double> (array_size,-INFINITY);
873  }
874 
875  //Transfer values to emission_table
876  std::vector<bool> transferred (array_size,false);
877  transferValues(transferred);
878  }
879 
880 
881 
882 }