ToPS
GHMMStates.cpp
00001 /*
00002  *       GHMMStates.cpp
00003  *
00004  *       Copyright 2011 Andre Yoshiaki Kashiwabara <akashiwabara@usp.br>
00005  *                      Ígor Bonádio <ibonadio@ime.usp.br>
00006  *                      Vitor Onuchic <vitoronuchic@gmail.com>
00007  *                      Alan Mitchell Durham <aland@usp.br>
00008  *
00009  *       This program is free software; you can redistribute it and/or modify
00010  *       it under the terms of the GNU  General Public License as published by
00011  *       the Free Software Foundation; either version 3 of the License, or
00012  *       (at your option) any later version.
00013  *
00014  *       This program is distributed in the hope that it will be useful,
00015  *       but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  *       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  *       GNU General Public License for more details.
00018  *
00019  *       You should have received a copy of the GNU General Public License
00020  *       along with this program; if not, write to the Free Software
00021  *       Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
00022  *       MA 02110-1301, USA.
00023  */
00024 
00025 #include "GHMMStates.hpp"
00026 #include "ProbabilisticModel.hpp"
00027 #include "DiscreteIIDModel.hpp"
00028 #include "InhomogeneousFactorableModel.hpp"
00029 #include "Symbol.hpp"
00030 #include <list>
00031 
00032 namespace tops{
00033     GHMMState::GHMMState() {
00034         _start = 0;
00035         _stop = 0;
00036         isRightJoinable(0);
00037         isLeftJoinable(0);
00038     }
00039 
00040     GHMMState:: ~GHMMState() {
00041     }
00042 
00043     void GHMMState::findBestPredecessor (Matrix & gamma, Matrix &psi, Matrix &psilen, const Sequence & s, int base, const GHMMStates & all_states, std::map < int, std::list<int> >  & valid_positions){
00044         int d = 1;
00045         if(predecessors().size() <= 0)
00046             return;
00047 
00048         int from = _predecessors[0];
00049         double gmax = gamma(from, base-d) + all_states[from]->transition()->log_probability_of(id());
00050         int pmax = from;
00051         for (int p = 1; p < (int)_predecessors.size();p++){
00052             int from = _predecessors[p];
00053             double g = gamma(from, base-d) + all_states[from]->transition()->log_probability_of(id());
00054             if(gmax < g){
00055                 gmax = g;
00056                 pmax = from;
00057             }
00058         }
00059         int phase = getInputPhase();
00060         gmax = gmax + duration_probability(d) + observation()->prefix_sum_array_compute(base-d +1, base, phase);
00061 
00062         if(gamma(id(), base) < gmax){
00063             gamma(id(), base) = gmax;
00064             psi(id(), base) = pmax;
00065             psilen(id(), base) = d;
00066         }
00067     }
00068 
00069     void GHMMState::choosePredecessor (Matrix & alpha, int base, int & state, int & position, const GHMMStates & all_states) {
00070         double sum = 0;
00071 
00072 
00073         double random = ((double)rand())/ ((double) RAND_MAX + 1.0) ;
00074 #if 0
00075         std::cerr << base << " " << std::endl;
00076         for (int k = 0; k < (int)predecessors().size(); k++)
00077             {
00078                 int p = predecessors()[k];
00079                 std::cerr << " " << all_states[p]->name () << " " << base - 1 << " " << exp(alpha(p, base - 1) + all_states[p]->transition()->log_probability_of(id()) + all_states[id()]->observation()->prefix_sum_array_compute(base, base, all_states[id()]->getInputPhase()) - alpha(id(), base)) << " "  << exp(alpha(p, base -1 )) << std::endl;
00080 
00081             }
00082 #endif
00083         for (int k = 0; k < (int)predecessors().size(); k++)
00084             {
00085                 int choosed = predecessors()[k];
00086                 sum += exp(alpha(choosed, base - 1) + all_states[choosed]->transition()->log_probability_of(id()) + observation()->prefix_sum_array_compute(base, base, getInputPhase()) - alpha(id(), base));
00087                 if(sum >= random){
00088                     state = choosed;
00089                     position = base - 1;
00090                     return;
00091                 }
00092             }
00093     }
00094 
00095 
00096     void GHMMState::observationModelName(std::string name) {
00097         _observationModelName = name;
00098     }
00099   void GHMMState::durationModelName(std::string name) {
00100 
00101   }
00102 
00103   std::string GHMMState::observationModelName() const {
00104     return _observationModelName;
00105   }
00106   std::string GHMMState::durationModelName() const {
00107     std::string n;
00108     return n;
00109   }
00110 
00111 
00112 
00113 
00114   void GHMMState::setObservation(ProbabilisticModelPtr obs) {
00115     _observation = obs;
00116   }
00117   ProbabilisticModelPtr GHMMState::observation() const {
00118     return _observation;
00119   }
00120   void GHMMState::setTransition(DiscreteIIDModelPtr trans) {
00121     _transition = trans;
00122   }
00123   DiscreteIIDModelPtr GHMMState::transition() const {
00124     return _transition;
00125   }
00126   int GHMMState::chooseDuration() const {
00127     return 1;
00128   }
00129   std::string GHMMState::name() const {
00130     return _name->name();
00131   }
00132   int GHMMState::id() const {
00133     return _name->id();
00134   }
00135   void GHMMState::addPredecessor(int id) {
00136     _predecessors.push_back(id);
00137   }
00138   std::vector<int> & GHMMState::predecessors() {
00139     return _predecessors;
00140   }
00141   void GHMMState::addSuccessor(int id) {
00142     _successors.push_back(id);
00143   }
00144   std::vector<int> & GHMMState::successors() {
00145     return _successors;
00146   }
00147   std::vector<int> & GHMMState::classes() {
00148     return _classes;
00149   }
00150   double GHMMState::duration_probability(int l) const {
00151     if (l == 1)
00152       return 0.0;
00153     else
00154       return -HUGE;
00155   }
00156   bool GHMMState::isGeometricDuration() const {
00157     return true;
00158   }
00159   std::string GHMMState::str() const {
00160     std::stringstream out;
00161     out << name() << " = [ observation = " << observationModelName() << "]" << std::endl;
00162     return out.str();
00163   }
00164 
00165   ProbabilisticModelParameters GHMMState::parameters() const{
00166     ProbabilisticModelParameters answer;
00167     answer.add("observation", StringParameterValuePtr(new StringParameterValue(observationModelName())));
00168     return answer;
00169   }
00170 
00171   int GHMMState::getInputPhase() const {
00172     return _inputPhase;
00173   }
00174 
00175   void GHMMState::setInputPhase(int _inputPhase) {
00176     this->_inputPhase = _inputPhase;
00177   }
00178 
00179 
00180   int GHMMState::getStart() const {
00181     return _start;
00182   }
00183 
00184   void GHMMState::setStart(int start) {
00185     this->_start = start;
00186   }
00187 
00188   void GHMMState::setClasses(std::vector<int> &classes){
00189     _classes = classes;
00190   }
00191 
00192   int GHMMState::getStop() const {
00193     return _stop;
00194   }
00195 
00196   void GHMMState::setStop(int stop) {
00197     this->_stop = stop;
00198   }
00199 
00200     int GHMMState::getOutputPhase() const {
00201     return _outputPhase;
00202   }
00203 
00204   void GHMMState::setOutputPhase(int _outputPhase) {
00205     this->_outputPhase = _outputPhase;
00206   }
00207 
00208 
00209 
00210   GHMMSignalState::GHMMSignalState() {
00211     setStart(0);
00212     setStop(0);
00213     isRightJoinable(0);
00214     isLeftJoinable(0);
00215   }
00216   int GHMMSignalState::size() const {
00217     return _size;
00218   }
00219   void GHMMSignalState::setSize(int s) {
00220     _size = s;
00221   }
00222 
00223 
00224 
00225 
00226 
00227 
00228   int GHMMSignalState::chooseDuration() const {
00229     return _size;
00230   }
00231   double GHMMSignalState::getThreshold() const {
00232     return _threshold;
00233   }
00234   void GHMMSignalState::setThreshold(double threshold) {
00235     _threshold = threshold;
00236   }
00237   double GHMMSignalState::duration_probability(int l) const {
00238     if (l == _size)
00239         return 0.0;
00240     else
00241       return -HUGE;
00242   }
00243   std::string GHMMSignalState::str() const {
00244     std::stringstream out;
00245     out << name() << " = [\n observation = " << GHMMState::observationModelName() << std::endl;
00246     out << "sequence_length = " << _size << "]" << std::endl;
00247 
00248     return out.str();
00249   }
00250 
00251   ProbabilisticModelParameters GHMMSignalState::parameters() const{
00252     ProbabilisticModelParameters answer;
00253     answer.add("observation", StringParameterValuePtr(new StringParameterValue(GHMMState::observationModelName())));
00254     answer.add("sequence_length", IntParameterValuePtr(new IntParameterValue(_size)));
00255     return answer;
00256   }
00257 
00258 
00259   GHMMExplicitDurationState::~GHMMExplicitDurationState() {
00260   }
00261   GHMMExplicitDurationState::GHMMExplicitDurationState() {
00262     setStart(0);
00263     setStop(0);
00264   }
00265   void GHMMExplicitDurationState::durationModelName(std::string name){
00266     _durationModelName = name;
00267   }
00268   std::string GHMMExplicitDurationState::durationModelName() const {
00269     return _durationModelName;
00270   }
00271 
00272   void GHMMExplicitDurationState::setDuration(ProbabilisticModelPtr d) {
00273       _duration = d;
00274       ProbabilisticModelParameters p = d->parameters();
00275       ProbabilisticModelParameterValuePtr par = p.getOptionalParameterValue("number_of_phases");
00276       if(par != NULL)
00277           _number_of_phases = par->getInt();
00278       else
00279           _number_of_phases = 1;
00280     }
00281    ProbabilisticModelPtr GHMMExplicitDurationState::duration() const {
00282      return _duration;
00283    }
00284 
00285     int GHMMExplicitDurationState::chooseDuration() const {
00286       return _duration->choose();
00287     }
00288      bool GHMMExplicitDurationState::isGeometricDuration() const {
00289       return false;
00290     }
00291     double GHMMExplicitDurationState::duration_probability(int l) const {
00292       return _duration->log_probability_of(l);
00293     }
00294 
00295     std::string GHMMExplicitDurationState::str() const {
00296       std::stringstream out;
00297       out << name() << " = [\n observation = " << GHMMState::observationModelName() << std::endl;
00298       if((getStart() > 0) || (getStop() > 0)) {
00299         out << "extend_emission = 1" << std::endl;
00300         out << "start = " << getStart() <<  std::endl;
00301         out << "stop = " << getStop() << std::endl;
00302       }
00303       if(isLeftJoinable()) {
00304         out << "left_joinable = " << isLeftJoinable() << std::endl;
00305       }
00306       if(isRightJoinable()) {
00307         out << "right_joinable = " << isRightJoinable() << std::endl;
00308       }
00309 
00310       out << "duration = " << durationModelName() << "]" << std::endl;
00311 
00312       return out.str();
00313     }
00314 
00315   ProbabilisticModelParameters GHMMExplicitDurationState::parameters() const {
00316       ProbabilisticModelParameters answer;
00317       answer.add("observation" , StringParameterValuePtr(new StringParameterValue(GHMMState::observationModelName())));
00318       answer.add("duration", StringParameterValuePtr(new StringParameterValue(durationModelName())));
00319       return answer;
00320     }
00321   void GHMMState::isLeftJoinable(int joinable){
00322     this->_left_joinable = joinable;
00323   }
00324   int GHMMState::isLeftJoinable() const {
00325     return this->_left_joinable;
00326   }
00327 
00328   void GHMMState::isRightJoinable(int joinable){
00329     this->_right_joinable = joinable;
00330   }
00331   int GHMMState::isRightJoinable() const {
00332     return this->_right_joinable;
00333   }
00334 
00335 
00336 
00337     void GHMMSignalState::findBestPredecessor (Matrix & gamma, Matrix &psi, Matrix &psilen, const Sequence & s, int base, const GHMMStates & all_states, std::map < int, std::list<int> >  & valid_positions){
00338         int d = size();
00339         if(predecessors().size() <= 0)
00340             return;
00341 
00342         int from = predecessors()[0];
00343         if((base - d ) < 0)
00344             return;
00345         double gmax = gamma(from, base-d) + all_states[from]->transition()->log_probability_of(id());
00346         int pmax = from;
00347         for (int p = 1; p < (int)predecessors().size();p++){
00348             int from = predecessors()[p];
00349             double g = gamma(from, base-d) + all_states[from]->transition()->log_probability_of(id());
00350             if(gmax < g){
00351                 gmax = g;
00352                 pmax = from;
00353             }
00354         }
00355         int phase = getInputPhase();
00356         gmax = gmax + duration_probability(d) + observation()->prefix_sum_array_compute(base-d +1, base, phase);
00357         if(gamma(id(), base) < gmax){
00358             gamma(id(), base) = gmax;
00359             psi(id(), base) = pmax;
00360             psilen(id(), base) = d;
00361 
00362         }
00363     }
00364 
00365 
00366 
00367 
00368     void GHMMSignalState::choosePredecessor (Matrix & alpha, int base, int & state, int & position, const GHMMStates & all_states) {
00369         double sum = 0;
00370         double random = ((double)rand())/ ((double) RAND_MAX + 1.0) ;
00371         position = base - size() ;
00372         if(position < 0)
00373             position = 0;
00374         for(int k  = 0; k < (int)predecessors().size(); k++)
00375             {
00376                 int choosed = predecessors()[k];
00377                 sum += exp(alpha(choosed, position) + all_states[choosed]->transition()->log_probability_of(id()) + observation()->prefix_sum_array_compute(position + 1, base, getInputPhase())  - alpha(id(), base)+ duration_probability(base - position) ) ;
00378                 if(sum >= random){
00379                     state = choosed;
00380                     return;
00381                 }
00382             }
00383     }
00384 
00385 
00386 
00387 
00388   void GHMMSignalState::fixTransitionDistribution () const {
00389     DiscreteIIDModelPtr trans = transition();
00390     DoubleVector probabilities = (trans->parameters()).getMandatoryParameterValue("probabilities")->getDoubleVector();
00391     int j = id();
00392     if(probabilities.size() <= 0) {
00393       return;
00394     }
00395     probabilities[j] = 0.0;
00396     double sum = 0.0;
00397     for(int i = 0; i < (int)probabilities.size(); i++)
00398       {
00399           if (i == j)
00400               continue;
00401           sum += probabilities[i];
00402       }
00403     for(int i = 0; i < (int)probabilities.size(); i++)
00404       {
00405           if (i == j)
00406               continue;
00407           probabilities[i]  = probabilities[i]/sum;
00408       }
00409     trans->setProbabilities(probabilities);
00410   }
00411 
00412     void GHMMExplicitDurationState::choosePredecessor (Matrix & alpha, int base, int & state, int & position, const GHMMStates & all_states) {
00413         double sum = 0;
00414         double random = ((double)rand())/ ((double) RAND_MAX + 1.0) ;
00415         int diff  = 0;
00416         if(_number_of_phases  > 1)
00417             diff = mod(getOutputPhase() - getInputPhase(),_number_of_phases);
00418         if(_number_of_phases <= 0)
00419             _number_of_phases = 1;
00420         int offset = duration()->size();
00421 
00422         if(offset > 15000)
00423             offset = 15000;
00424         int minbase = (base - diff - offset) ;
00425         if(minbase < 0) minbase = 0;
00426 
00427         for (int d = base - diff; d > minbase; d-=_number_of_phases)
00428             {
00429                 position = d - 1;
00430                 for(int k  = 0; k < (int)predecessors().size(); k++)
00431                     {
00432                         int choosed = predecessors()[k];
00433                         sum += exp(alpha(choosed, position) + all_states[choosed]->transition()->log_probability_of(id()) + observation()->prefix_sum_array_compute(d, base, getInputPhase())  - alpha(id(), base) + duration_probability(base - d + 1 ) ) ;
00434                         if(sum >= random){
00435                             state = choosed;
00436                             return;
00437                         }
00438                     }
00439             }
00440     }
00441 
00442     void GHMMExplicitDurationState::findBestPredecessor (Matrix & gamma, Matrix &psi, Matrix &psilen, const Sequence & s, int base, const GHMMStates & all_states, std::map < int, std::list<int> >  & valid_positions){
00443         int diff = 0;
00444         if(_number_of_phases  > 1)
00445             diff = mod(getOutputPhase() - getInputPhase(),_number_of_phases);
00446         if(_number_of_phases <= 0)
00447             _number_of_phases = 1;
00448         int offset = duration()->size();
00449         if(offset > 15000)
00450             offset = 15000;
00451 
00452 
00453         bool toContinue = false;
00454 
00455         for(int suc = 0; suc < (int)successors().size(); suc++)
00456             {
00457                 if(!all_states[successors()[suc]]->isGeometricDuration()){
00458                     toContinue = true;
00459                     break;
00460                 }
00461                 if((base + 1 < (int)s.size()) && (all_states[successors()[suc]]->observation()->prefix_sum_array_compute(base+1, base+1) > -HUGE)) {
00462                     toContinue = true;
00463                     break;
00464                 }
00465             }
00466         if(!toContinue){
00467             return;
00468         }
00469 
00470         std::list<int>::iterator it;
00471         it =  (valid_positions.find(id())->second).begin();
00472         //      std::cerr << base << " " << all_states[id()]->name() << " " << (valid_positions.find(id())->second).size() << std::endl;
00473         while(it != (valid_positions.find(id())->second).end()) {
00474             int d = (*it)+ 1;
00475             if(predecessors().size() <= 0)
00476               return;
00477             int from = predecessors()[0];
00478             if((base - d ) < 0)
00479               return;
00480             if(base-d+1 >= offset)
00481                 {
00482                     it = (valid_positions.find(id())->second).erase(it);
00483                     continue;
00484                 }
00485             if(duration_probability(base-d+1) <= -HUGE) {
00486               it++;
00487               continue;
00488             }
00489 
00490             double emission = observation()->prefix_sum_array_compute(d, base, getInputPhase());
00491             if(emission <= -HUGE) {
00492                 it = (valid_positions.find(id())->second).erase(it);
00493                 continue;
00494             }
00495 
00496       // check if it can emmit the current state given the boundaries
00497       int nphase = getInputPhase();
00498       if(observation()->inhomogeneous() != NULL)
00499         nphase = observation()->inhomogeneous()->maximumTimeValue() + 1;
00500       if(getStart() > 0 && getStop() > 0) {
00501         if((d-getStart() >= 0) && (base + getStop () < s.size())) {
00502     double joinable = observation()->prefix_sum_array_compute(d-getStart(),base+getStop(), mod(getInputPhase()-getStart(), nphase));
00503     //std::cerr << all_states[id()]->name() << " " << base << " " << d-getStart() << " " << base + getStop() << " " << getInputPhase() << " " << mod(getInputPhase() - getStart(), nphase) << " " << nphase << std::endl;
00504     if(joinable <= -HUGE) {
00505       it++;
00506       continue;
00507     }
00508         }
00509       }
00510             double gmax = gamma(from, d-1) + all_states[from]->transition()->log_probability_of(id());
00511             int pmax = from;
00512             for (int p = 1; p < (int)predecessors().size();p++){
00513                 int from = predecessors()[p];
00514                 double g = gamma(from, d-1) + all_states[from]->transition()->log_probability_of(id());
00515                 if(gmax < g){
00516                     gmax = g;
00517                     pmax = from;
00518                 }
00519             }
00520 
00521             gmax = gmax +  duration_probability(base-d+1) + observation()->prefix_sum_array_compute(d, base, getInputPhase());
00522 
00523             if(gamma(id(), base) < gmax){
00524                 gamma(id(), base) = gmax;
00525                 psi(id(), base) = pmax;
00526                 psilen(id(), base) = base-d+1;
00527             }
00528             it++;
00529         }
00530     }
00531 
00532   double GHMMState::backwardSum(Matrix &beta, const Sequence &s, int base, std::vector< std::list<int> > &valid_positions){
00533     int phase = getInputPhase();
00534     double result = _observation->prefix_sum_array_compute(base+1, base+1, phase) + beta(id(), base+1);
00535     return result;
00536   }
00537 
00538   double GHMMSignalState::backwardSum(Matrix &beta, const Sequence &s, int base, std::vector< std::list<int> > &valid_positions){
00539     int d = size();
00540     if(base+d >= (int)s.size())
00541       return -HUGE;
00542     int phase = getInputPhase();
00543     double result = _observation->prefix_sum_array_compute(base+1,base+d,phase) + beta(id(),base+d);
00544     return result;
00545   }
00546 
00547   double GHMMExplicitDurationState::backwardSum(Matrix &beta, const Sequence &s, int base, std::vector< std::list<int> > &valid_positions){
00548     int diff = 0;
00549     if(_number_of_phases  > 1)
00550       diff = mod(getOutputPhase() - getInputPhase(),_number_of_phases);
00551     if(_number_of_phases <= 0)
00552       _number_of_phases = 1;
00553     int offset = _duration->size();
00554     if(offset > 15000)
00555       offset = 15000;
00556     int maxbase = (base + diff + offset) ;
00557     if(maxbase > (int)s.size()-1) maxbase = s.size()-1;
00558     int phase = getInputPhase();
00559 
00560     std::list<int>::iterator it;
00561     it = valid_positions[id()].begin();
00562     double sum = -HUGE;
00563     while(it != valid_positions[id()].end()){
00564       if((*it) > maxbase){
00565   it = valid_positions[id()].erase(it);
00566   continue;
00567       }
00568       if((*it) < base + diff){
00569   it++;
00570   continue;
00571       }
00572       double duration = duration_probability((*it)-base);
00573       if(duration <= -2e20){
00574   it++;
00575   continue;
00576       }
00577       if(_observation->inhomogeneous() != NULL)
00578   phase = _observation->inhomogeneous()->maximumTimeValue() + 1;
00579       if(getStart() > 0 && getStop() > 0) {
00580   if((base+1-getStart() >= 0) && ((*it) + getStop() < s.size())) {
00581     double joinable = _observation->prefix_sum_array_compute(base+1-getStart(),(*it)+getStop(), mod(getInputPhase()-getStart(), phase));
00582     if(joinable <= -2e20) {
00583       it = valid_positions[id()].erase(it);
00584       continue;
00585     }
00586   }
00587       }
00588       sum = log_sum(sum, _observation->prefix_sum_array_compute(base+1,(*it),getInputPhase()) + duration + beta(id(),(*it)));
00589       it++;
00590     }
00591     return sum;
00592   }
00593 
00594   void GHMMState::forwardSum (Matrix & alpha, const Sequence & s, int base, const GHMMStates & all_states, std::vector< std::list<int> > &valid_positions){
00595     alpha(id(), base) = -HUGE;
00596     if(predecessors().size() <= 0)
00597       return;
00598     int from = predecessors()[0];
00599     int phase = getInputPhase();
00600     double emission = observation()->prefix_sum_array_compute(base, base, phase);
00601     alpha(id(), base) =  alpha(from, base-1) + all_states[from]->transition()->log_probability_of(id()) + emission;
00602     for (int k = 1; k < (int)predecessors().size(); k++)
00603       {
00604   from = predecessors()[k];
00605   alpha(id(), base) =  log_sum(alpha(from, base - 1) + all_states[from]->transition()->log_probability_of(id()) +  emission, alpha(id(), base));
00606       }
00607   }
00608 
00609   void GHMMSignalState::forwardSum (Matrix & alpha, const Sequence & s, int base, const GHMMStates & all_states, std::vector< std::list<int> > &valid_positions){
00610     alpha(id(), base)  = -HUGE;
00611     int d = size();
00612     if(predecessors().size() <= 0)
00613       return;
00614 
00615     int from = predecessors()[0];
00616     if((base - d ) < 0)
00617       return;
00618     int phase = getInputPhase();
00619     double emission = observation()->prefix_sum_array_compute(base - d+ 1, base, phase);
00620 
00621     alpha(id(), base) =  alpha(from, base-d) + all_states[from]->transition()->log_probability_of(id())  + emission;
00622     for (int k = 1; k < (int)predecessors().size(); k++)
00623       {
00624   from = predecessors()[k];
00625   alpha(id(), base) =  log_sum(alpha(from, base -d) + all_states[from]->transition()->log_probability_of(id()) + emission, alpha(id(), base));
00626       }
00627     if(alpha(id(),base) > -HUGE){
00628       std::vector<int> succ = successors();
00629       for(int p = 0; p < (int)succ.size(); p++){
00630   int id = succ[p];
00631   if(!all_states[id]->isGeometricDuration())
00632     valid_positions[id].push_front(base);
00633       }
00634     }
00635   }
00636 
00637 
00638   void GHMMExplicitDurationState::forwardSum (Matrix & alpha, const Sequence & s, int base, const GHMMStates & all_states, std::vector< std::list<int> > &valid_positions){
00639     alpha(id(), base) = -HUGE;
00640     if(predecessors().size() <= 0)
00641       return;
00642     int diff = 0;
00643     if(_number_of_phases  > 1)
00644       diff = mod(getOutputPhase() - getInputPhase(),_number_of_phases);
00645     if(_number_of_phases <= 0)
00646       _number_of_phases = 1;
00647     int offset = duration()->size();
00648     if(offset > 15000)
00649       offset = 15000;
00650     int minbase = (base - diff - offset) ;
00651     if(minbase < 0) minbase = 0;
00652     int phase = getInputPhase();
00653 
00654     std::list<int>::iterator it;
00655     it = valid_positions[id()].begin();
00656     while(it != valid_positions[id()].end()){
00657       if((*it) < minbase){
00658   it = valid_positions[id()].erase(it);
00659   continue;
00660       }
00661       if((*it) > base - diff){
00662   it++;
00663   continue;
00664       }
00665       double duration = duration_probability(base-(*it));
00666       if(duration <= -HUGE){
00667   it++;
00668   continue;
00669       }
00670       if(observation()->inhomogeneous() != NULL)
00671   phase = observation()->inhomogeneous()->maximumTimeValue() + 1;
00672       if(getStart() > 0 && getStop() > 0) {
00673   if(((*it)+1-getStart() >= 0) && (base + getStop() < (int)s.size())) {
00674     double joinable = observation()->prefix_sum_array_compute((*it)+1-getStart(),base+getStop(), mod(getInputPhase()-getStart(), phase));
00675     if(joinable <= -HUGE) {
00676       it = valid_positions[id()].erase(it);
00677       continue;
00678     }
00679   }
00680       }
00681       int from = predecessors()[0];
00682       double emission = observation()->prefix_sum_array_compute((*it)+1, base, getInputPhase());
00683       alpha(id(), base) = log_sum(alpha(from, (*it)) + all_states[from]->transition()->log_probability_of(id()) + duration + emission, alpha(id(), base));
00684       for (int k = 1; k < (int)predecessors().size(); k++){
00685     from = predecessors()[k];
00686     alpha(id(), base) =  log_sum(alpha(from, (*it)) + all_states[from]->transition()->log_probability_of(id()) + duration + emission, alpha(id(), base));
00687       }
00688       it++;
00689     }
00690   }
00691 
00692   void GHMMState::posteriorSum (Matrix & alpha, Matrix & beta, fMatrix &postProbs, const Sequence & s, int base, const GHMMStates & all_states, std::vector< std::list<int> > &valid_positions, double prob, int stateNumber){
00693     alpha(id(), base) = -HUGE;
00694     if(predecessors().size() <= 0)
00695       return;
00696     int phase = getInputPhase();
00697     double emission = _observation->prefix_sum_array_compute(base, base, phase);
00698     for (int k = 0; k < (int)predecessors().size(); k++)
00699       {
00700   int from = predecessors()[k];
00701   alpha(id(), base) =  log_sum(alpha(from, base - 1) + all_states[from]->transition()->log_probability_of(id()) +  emission, alpha(id(), base));
00702       }
00703     if(stateNumber == -1){
00704       for(int c = 0; c < (int)classes().size(); c++){
00705   postProbs(base,classes()[c]) += exp(alpha(id(),base) + beta(id(),base) - prob);
00706       }
00707     }
00708     else if(stateNumber != -1)
00709       postProbs(base,id()) = exp(alpha(id(),base) + beta(id(),base) - prob);
00710   }
00711 
00712   void GHMMSignalState::posteriorSum (Matrix & alpha, Matrix & beta, fMatrix &postProbs, const Sequence & s, int base, const GHMMStates & all_states, std::vector< std::list<int> > &valid_positions, double prob, int stateNumber){
00713     alpha(id(), base)  = -HUGE;
00714     int d = size();
00715     if(predecessors().size() <= 0)
00716       return;
00717 
00718     if((base - d ) < 0)
00719       return;
00720     int phase = getInputPhase();
00721     double emission = _observation->prefix_sum_array_compute(base - d+ 1, base, phase);
00722     if(emission <= -HUGE)
00723       return;
00724 
00725     for (int k = 0; k < (int)predecessors().size(); k++)
00726       {
00727   int from = predecessors()[k];
00728   double w = alpha(from, base -d) + all_states[from]->transition()->log_probability_of(id()) + emission;
00729   alpha(id(), base) =  log_sum(w, alpha(id(), base));
00730   if(w > -HUGE && stateNumber == -1){
00731     int c = 0;
00732     float pp = exp(w + beta(id(),base) - prob);
00733     for(int i = base-d+1; i <= base; i++){
00734       postProbs(i,classes()[c]) += pp;
00735       c++;
00736       if(c == (int)classes().size())
00737         c = 0;
00738     }
00739   }
00740   else if(w > -HUGE && stateNumber != -1){
00741     float pp = exp(w + beta(id(),base) - prob);
00742     for(int i = base-d+1; i <= base; i++){
00743       postProbs(i,id()) += pp;
00744     }
00745   }
00746       }
00747     if(alpha(id(),base) > -HUGE){
00748       std::vector<int> succ = successors();
00749       for(int p = 0; p < (int)succ.size(); p++){
00750   int id = succ[p];
00751   if(!all_states[id]->isGeometricDuration())
00752     valid_positions[id].push_front(base);
00753       }
00754     }
00755   }
00756 
00757   void GHMMExplicitDurationState::posteriorSum (Matrix & alpha, Matrix &beta, fMatrix &postProbs, const Sequence & s, int base, const GHMMStates & all_states, std::vector< std::list<int> > &valid_positions, double prob, int stateNumber){
00758     alpha(id(), base) = -HUGE;
00759     if(predecessors().size() <= 0)
00760       return;
00761     int diff = 0;
00762     if(_number_of_phases  > 1)
00763       diff = mod(getOutputPhase() - getInputPhase(),_number_of_phases);
00764     if(_number_of_phases <= 0)
00765       _number_of_phases = 1;
00766     int offset = duration()->size();
00767     if(offset > 15000)
00768       offset = 15000;
00769     int minbase = (base - diff - offset) ;
00770     if(minbase < 0) minbase = 0;
00771     int phase = getInputPhase();
00772 
00773     std::list<int>::iterator it;
00774     it = valid_positions[id()].begin();
00775     while(it != valid_positions[id()].end()){
00776       if((*it) < minbase){
00777   it = valid_positions[id()].erase(it);
00778   continue;
00779       }
00780       if((*it) > base - diff){
00781   it++;
00782   continue;
00783       }
00784       double duration = duration_probability(base-(*it));
00785       if(duration <= -HUGE){
00786   it++;
00787   continue;
00788       }
00789       if(observation()->inhomogeneous() != NULL)
00790   phase = observation()->inhomogeneous()->maximumTimeValue() + 1;
00791       if(getStart() > 0 && getStop() > 0) {
00792   if(((*it)+1-getStart() >= 0) && (base + getStop() < (int)s.size())) {
00793     double joinable = observation()->prefix_sum_array_compute((*it)+1-getStart(),base+getStop(), mod(getInputPhase()-getStart(), phase));
00794     if(joinable <= -HUGE) {
00795       it = valid_positions[id()].erase(it);
00796       continue;
00797     }
00798   }
00799       }
00800       double emission = observation()->prefix_sum_array_compute((*it)+1, base, getInputPhase());
00801       for (int k = 0; k < (int)predecessors().size(); k++){
00802   int from = predecessors()[k];
00803   double w = alpha(from, (*it)) + all_states[from]->transition()->log_probability_of(id()) + duration + emission;
00804   alpha(id(), base) = log_sum(w, alpha(id(), base));
00805   if(w > -HUGE && stateNumber == -1){
00806     int c = 0;
00807     float pp = exp(w + beta(id(),base) - prob);
00808     for(int i = (*it)+1; i <= base; i++){
00809       postProbs(i,classes()[c]) += pp;
00810       c++;
00811       if(c == (int)classes().size())
00812         c = 0;
00813     }
00814   }
00815   else if(w > -HUGE && stateNumber != -1){
00816     float pp = exp(w + beta(id(),base) - prob);
00817     for(int i = (*it)+1; i <= base; i++){
00818       postProbs(i,id()) += pp;
00819     }
00820   }
00821       }
00822       it++;
00823     }
00824   }
00825 
00826   void GHMMExplicitDurationState::fixTransitionDistribution () const {
00827     DiscreteIIDModelPtr trans = transition();
00828     DoubleVector probabilities = (trans->parameters()).getMandatoryParameterValue("probabilities")->getDoubleVector();
00829     int j = id();
00830     if(probabilities.size() <= 0) {
00831       return;
00832     }
00833     probabilities[j] = 0.0;
00834     double sum = 0.0;
00835     for(int i = 0; i < (int)probabilities.size(); i++)
00836       {
00837         if (i == j)
00838           continue;
00839         sum += probabilities[i];
00840       }
00841     for(int i = 0; i <(int) probabilities.size(); i++)
00842       {
00843         if (i == j)
00844           continue;
00845         probabilities[i]  = probabilities[i]/sum;
00846       }
00847     trans->setProbabilities(probabilities);
00848   }
00849 }