/* Code generated by HMMoC version 1.3, Copyright (C) 2006 Gerton Lunter */
/* Generated from file nucleotide_indel2.xml (author:  Robert K. Bradley ) on Tue Dec 23 01:04:17 CST 2008 */

/*
This file is a work based on HMMoC 1.3, a hidden Markov model compiler.
Copyright (C) 2006 by Gerton Lunter, Oxford University.

HMMoC and works based on it are free software; you can redistribute 
it and/or modify it under the terms of the GNU General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.

HMMOC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with HMMoC; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/


#include "nucleotide_indel2dp.h"

#include "mybanding.h"

const extern string _NucleotideIndel2AlignstateId[];
const extern string _NucleotideIndel2AlignemissionId[];
const extern string _NucleotideIndel2AligntransitionId[];
const extern string _NucleotideIndel2AligntransF[];
const extern string _NucleotideIndel2AligntransT[];
const extern string _NucleotideIndel2AligntransP[];
const extern string _NucleotideIndel2AligntransE[];
const extern string _NucleotideIndel2AlignoutputId[];
const extern string _NucleotideIndel2Alignempty;
const extern int _NucleotideIndel2AlignstateNum;
const extern int _NucleotideIndel2AlignemitNum;
const extern int _NucleotideIndel2AligntransNum;
const extern int _NucleotideIndel2AlignoutputNum;

NucleotideIndel2AlignDPTable::NucleotideIndel2AlignDPTable(int iLen1,int iLen2) : isInCharge(true), stateId(_NucleotideIndel2AlignstateId), emissionId(_NucleotideIndel2AlignemissionId), transitionId(_NucleotideIndel2AligntransitionId), transitionFrom(_NucleotideIndel2AligntransF), transitionTo(_NucleotideIndel2AligntransT), transitionProb(_NucleotideIndel2AligntransP), transitionEmit(_NucleotideIndel2AligntransE), outputId(_NucleotideIndel2AlignoutputId) {
    // init code:
    this->iLen1 = iLen1;
    this->iLen2 = iLen2;
    StateMemorynucIndel2Block2.allocate(1+iLen1, 1+iLen2);
    StateMemorynucIndel2Block1.allocate();
    StateMemorynucIndel2Block3.allocate();
}


NucleotideIndel2AlignDPTable::~NucleotideIndel2AlignDPTable() {
    if (!isInCharge) {
        // make sure data does not get deleted:
        StateMemorynucIndel2Block2.absolve();
        StateMemorynucIndel2Block1.absolve();
        StateMemorynucIndel2Block3.absolve();
    } // if(!isInCharge)
} // destructor

const string& NucleotideIndel2AlignDPTable::getTransitionId(int id) { return id>=0 && id<_NucleotideIndel2AligntransNum ? _NucleotideIndel2AligntransitionId[id] : _NucleotideIndel2Alignempty; }
const string& NucleotideIndel2AlignDPTable::getEmissionId(int id) { return id>=0 && id<_NucleotideIndel2AlignemitNum ? _NucleotideIndel2AlignemissionId[id] : _NucleotideIndel2Alignempty; }
const string& NucleotideIndel2AlignDPTable::getStateId(int id) { return id>=0 && id<_NucleotideIndel2AlignstateNum ? _NucleotideIndel2AlignstateId[id] : _NucleotideIndel2Alignempty; }
const string& NucleotideIndel2AlignDPTable::getOutputId(int id) { return id>=0 && id<_NucleotideIndel2AlignoutputNum ? _NucleotideIndel2AlignoutputId[id] : _NucleotideIndel2Alignempty; }
int NucleotideIndel2AlignDPTable::getId(const string& sId)
{
    static bool bInit = false;
    static map<string,int>* pmId;
    if (!bInit) {
        pmId = new map<string,int>();
        for (int i=0;i<_NucleotideIndel2AlignstateNum;i++) {
            (*pmId)[_NucleotideIndel2AlignstateId[i]] = i;         // add state identifiers
        }
        for (int i=0; i<_NucleotideIndel2AlignemitNum; i++) {
            (*pmId)[_NucleotideIndel2AlignemissionId[i]] = i;      // add emission identifiers
        }
        for (int i=0; i<_NucleotideIndel2AligntransNum; i++) {  
            (*pmId)[_NucleotideIndel2AligntransitionId[i]] = i;    // add transition identifiers
        }
        for (int i=0; i<_NucleotideIndel2AlignoutputNum; i++) {
            (*pmId)[_NucleotideIndel2AlignoutputId[i]] = i;        // finally, add output identifiers
        }
        bInit = true;
    }
    map<string,int>::iterator iter = pmId->find(sId);
    if (iter == pmId->end()) {
        if (sId == "_cleanup_") {
            delete pmId;
            } else {
            cout << "NucleotideIndel2AlignDPTable::getId: WARNING: identifier '" << sId << "' not found." << endl;
        }
        return -1;
    }
    return iter->second;
}


bfloat NucleotideIndel2AlignDPTable::getProb(const string sState ,int iPos0,int iPos1) const
{
    return getProb(getId(sState) ,iPos0,iPos1);
}


bfloat NucleotideIndel2AlignDPTable::getProb(int iState ,int iPos0,int iPos1) const
{
    const bfloat *CurStateMemorynucIndel2Block1Secondary;
    const bfloat *CurStateMemorynucIndel2Block2Secondary;
    const bfloat *CurStateMemorynucIndel2Block3Secondary;
    static const int blockTable[] = {0, 1, 1, 1, 1, 1, 2};
    static const int stateTable[] = {0, 0, 1, 2, 3, 4, 0};
    switch (blockTable[iState]) {
        default:
        return 0.0;
        break;
        case 0:
        if ((iPos0+0>=0)&&(iPos0+0<=0)&&(iPos1+0>=0)&&(iPos1+0<=0)) {
            CurStateMemorynucIndel2Block1Secondary = this->StateMemorynucIndel2Block1.read();
            return CurStateMemorynucIndel2Block1Secondary[stateTable[iState]];
        } 
        else { 
            return 0.0;
            
        }
        break;
        case 1:
        if ((iPos0+0>=0)&&(iPos0+0<=iLen1+0)&&(iPos1+0>=0)&&(iPos1+0<=iLen2+0)) {
            CurStateMemorynucIndel2Block2Secondary = this->StateMemorynucIndel2Block2.read((iPos0-(0))-(0), (iPos1-(0))-(0));
            return CurStateMemorynucIndel2Block2Secondary[stateTable[iState]];
        } 
        else { 
            return 0.0;
            
        }
        break;
        case 2:
        if ((iPos0+0>=iLen1+0)&&(iPos0+0<=iLen1+0)&&(iPos1+0>=iLen2+0)&&(iPos1+0<=iLen2+0)) {
            CurStateMemorynucIndel2Block3Secondary = this->StateMemorynucIndel2Block3.read();
            return CurStateMemorynucIndel2Block3Secondary[stateTable[iState]];
        } 
        else { 
            return 0.0;
            
        }
    } // switch
} // DPTable...::getProb(int,...)

const extern string _NucleotideIndel2AlignstateId[];
const extern string _NucleotideIndel2AlignemissionId[];
const extern string _NucleotideIndel2AligntransitionId[];
const extern string _NucleotideIndel2AligntransF[];
const extern string _NucleotideIndel2AligntransT[];
const extern string _NucleotideIndel2AligntransP[];
const extern string _NucleotideIndel2AligntransE[];
const extern string _NucleotideIndel2AlignoutputId[];
const extern string _NucleotideIndel2Alignempty;
const extern int _NucleotideIndel2AlignstateNum;
const extern int _NucleotideIndel2AlignemitNum;
const extern int _NucleotideIndel2AligntransNum;
const extern int _NucleotideIndel2AlignoutputNum;

NucleotideIndel2AlignFoldedDPTable::NucleotideIndel2AlignFoldedDPTable(int iLen1,int iLen2) : isInCharge(true), stateId(_NucleotideIndel2AlignstateId), emissionId(_NucleotideIndel2AlignemissionId), transitionId(_NucleotideIndel2AligntransitionId), transitionFrom(_NucleotideIndel2AligntransF), transitionTo(_NucleotideIndel2AligntransT), transitionProb(_NucleotideIndel2AligntransP), transitionEmit(_NucleotideIndel2AligntransE), outputId(_NucleotideIndel2AlignoutputId) {
    // init code:
    this->iLen1 = iLen1;
    this->iLen2 = iLen2;
    StateMemorynucIndel2Block2.allocate(1+iLen1, 1+iLen2);
    StateMemorynucIndel2Block3.allocate();
    StateMemorynucIndel2Block1.allocate();
}


NucleotideIndel2AlignFoldedDPTable::~NucleotideIndel2AlignFoldedDPTable() {
    if (!isInCharge) {
        // make sure data does not get deleted:
        StateMemorynucIndel2Block2.absolve();
        StateMemorynucIndel2Block3.absolve();
        StateMemorynucIndel2Block1.absolve();
    } // if(!isInCharge)
} // destructor

const string& NucleotideIndel2AlignFoldedDPTable::getTransitionId(int id) { return id>=0 && id<_NucleotideIndel2AligntransNum ? _NucleotideIndel2AligntransitionId[id] : _NucleotideIndel2Alignempty; }
const string& NucleotideIndel2AlignFoldedDPTable::getEmissionId(int id) { return id>=0 && id<_NucleotideIndel2AlignemitNum ? _NucleotideIndel2AlignemissionId[id] : _NucleotideIndel2Alignempty; }
const string& NucleotideIndel2AlignFoldedDPTable::getStateId(int id) { return id>=0 && id<_NucleotideIndel2AlignstateNum ? _NucleotideIndel2AlignstateId[id] : _NucleotideIndel2Alignempty; }
const string& NucleotideIndel2AlignFoldedDPTable::getOutputId(int id) { return id>=0 && id<_NucleotideIndel2AlignoutputNum ? _NucleotideIndel2AlignoutputId[id] : _NucleotideIndel2Alignempty; }
int NucleotideIndel2AlignFoldedDPTable::getId(const string& sId)
{
    static bool bInit = false;
    static map<string,int>* pmId;
    if (!bInit) {
        pmId = new map<string,int>();
        for (int i=0;i<_NucleotideIndel2AlignstateNum;i++) {
            (*pmId)[_NucleotideIndel2AlignstateId[i]] = i;         // add state identifiers
        }
        for (int i=0; i<_NucleotideIndel2AlignemitNum; i++) {
            (*pmId)[_NucleotideIndel2AlignemissionId[i]] = i;      // add emission identifiers
        }
        for (int i=0; i<_NucleotideIndel2AligntransNum; i++) {  
            (*pmId)[_NucleotideIndel2AligntransitionId[i]] = i;    // add transition identifiers
        }
        for (int i=0; i<_NucleotideIndel2AlignoutputNum; i++) {
            (*pmId)[_NucleotideIndel2AlignoutputId[i]] = i;        // finally, add output identifiers
        }
        bInit = true;
    }
    map<string,int>::iterator iter = pmId->find(sId);
    if (iter == pmId->end()) {
        if (sId == "_cleanup_") {
            delete pmId;
            } else {
            cout << "NucleotideIndel2AlignFoldedDPTable::getId: WARNING: identifier '" << sId << "' not found." << endl;
        }
        return -1;
    }
    return iter->second;
}


bfloat NucleotideIndel2AlignFoldedDPTable::getProb(const string sState ,int iPos0,int iPos1) const
{
    return getProb(getId(sState) ,iPos0,iPos1);
}


bfloat NucleotideIndel2AlignFoldedDPTable::getProb(int iState ,int iPos0,int iPos1) const
{
    const bfloat *CurStateMemorynucIndel2Block1Secondary;
    const bfloat *CurStateMemorynucIndel2Block2Secondary;
    const bfloat *CurStateMemorynucIndel2Block3Secondary;
    static const int blockTable[] = {0, 1, 1, 1, 1, 1, 2};
    static const int stateTable[] = {0, 0, 1, 2, 3, 4, 0};
    switch (blockTable[iState]) {
        default:
        return 0.0;
        break;
        case 0:
        if ((iPos0+0>=0)&&(iPos0+0<=0)&&(iPos1+0>=0)&&(iPos1+0<=0)) {
            CurStateMemorynucIndel2Block1Secondary = this->StateMemorynucIndel2Block1.read();
            return CurStateMemorynucIndel2Block1Secondary[stateTable[iState]];
        } 
        else { 
            return 0.0;
            
        }
        break;
        case 1:
        if ((iPos0+0>=0)&&(iPos0+0<=iLen1+0)&&(iPos1+0>=0)&&(iPos1+0<=iLen2+0)) {
            CurStateMemorynucIndel2Block2Secondary = this->StateMemorynucIndel2Block2.read((iPos0-(0))-(0), (iPos1-(0))-(0));
            return CurStateMemorynucIndel2Block2Secondary[stateTable[iState]];
        } 
        else { 
            return 0.0;
            
        }
        break;
        case 2:
        if ((iPos0+0>=iLen1+0)&&(iPos0+0<=iLen1+0)&&(iPos1+0>=iLen2+0)&&(iPos1+0<=iLen2+0)) {
            CurStateMemorynucIndel2Block3Secondary = this->StateMemorynucIndel2Block3.read();
            return CurStateMemorynucIndel2Block3Secondary[stateTable[iState]];
        } 
        else { 
            return 0.0;
            
        }
    } // switch
} // DPTable...::getProb(int,...)

int NucleotideIndel2AlignBaumWelch::transitionIndex(string strId) const {
    map<const string,int>::const_iterator iter = mId.find(strId);
    if (iter == mId.end()) {
        cout << "NucleotideIndel2AlignBaumWelch::transitionIndex: WARNING: identifier '" << strId << "' not found." << endl;
        return -1;
    }
    return iter->second;
}


int NucleotideIndel2AlignBaumWelch::emissionIndex(string strId) const {
    map<const string,int>::const_iterator iter = mId.find(strId);
    if (iter == mId.end()) {
        cout << "NucleotideIndel2AlignBaumWelch::emissionIndex: WARNING: identifier '" << strId << "' not found." << endl;
        return -1;
    }
    return iter->second;
}


void NucleotideIndel2AlignBaumWelch::resetCounts() {
    static bool bInited = false;
    if (!bInited) {
        static const int aTemp[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22};
        for (int i=0; i<23; i++) {
            transitionIdentifier00[i] = aTemp[i];
            atransitionIdx[aTemp[i]] = i;
            mId[_NucleotideIndel2AligntransitionId[aTemp[i]]] = i;
        }
    }
    for (int i=0; i<23; i++) {
        
        transitionBaumWelchCount00[i] = 0.0;
    }
    if (!bInited) {
        static const int aTemp[] = {2};
        for (int i=0; i<1; i++) {
            emissionIdentifier00[i] = aTemp[i];
            aemissionIdx[aTemp[i]] = i;
            mId[_NucleotideIndel2AlignemissionId[aTemp[i]]] = i;
        }
    }
    for (int i=0; i<1; i++) {
        
        emissionBaumWelchCount00[i] = 0.0;
    }
    if (!bInited) {
        static const int aTemp[] = {1};
        for (int i=0; i<1; i++) {
            emissionIdentifier01[i] = aTemp[i];
            aemissionIdx[aTemp[i]] = i;
            mId[_NucleotideIndel2AlignemissionId[aTemp[i]]] = i;
        }
    }
    for (int i=0; i<1; i++) {
        for(int v10=0;v10<4;v10++)
        emissionBaumWelchCount01[v10][i] = 0.0;
    }
    if (!bInited) {
        static const int aTemp[] = {3};
        for (int i=0; i<1; i++) {
            emissionIdentifier10[i] = aTemp[i];
            aemissionIdx[aTemp[i]] = i;
            mId[_NucleotideIndel2AlignemissionId[aTemp[i]]] = i;
        }
    }
    for (int i=0; i<1; i++) {
        for(int v00=0;v00<4;v00++)
        emissionBaumWelchCount10[v00][i] = 0.0;
    }
    if (!bInited) {
        static const int aTemp[] = {0};
        for (int i=0; i<1; i++) {
            emissionIdentifier11[i] = aTemp[i];
            aemissionIdx[aTemp[i]] = i;
            mId[_NucleotideIndel2AlignemissionId[aTemp[i]]] = i;
        }
    }
    for (int i=0; i<1; i++) {
        for(int v00=0;v00<4;v00++)for(int v10=0;v10<4;v10++)
        emissionBaumWelchCount11[v00][v10][i] = 0.0;
    }
    bInited = true;
};


int NucleotideIndel2AlignBaumWelch::transitionIdentifier00[];
int NucleotideIndel2AlignBaumWelch::emissionIdentifier00[];
int NucleotideIndel2AlignBaumWelch::emissionIdentifier01[];
int NucleotideIndel2AlignBaumWelch::emissionIdentifier10[];
int NucleotideIndel2AlignBaumWelch::emissionIdentifier11[];

void NucleotideIndel2AlignBaumWelch::scaleCounts(bfloat scale) {
    for (int i=0; i<23; i++) {
        
        transitionBaumWelchCount00[i] *= scale;
    }
    for (int i=0; i<1; i++) {
        
        emissionBaumWelchCount00[i] *= scale;
    }
    for (int i=0; i<1; i++) {
        for(int v10=0;v10<4;v10++)
        emissionBaumWelchCount01[v10][i] *= scale;
    }
    for (int i=0; i<1; i++) {
        for(int v00=0;v00<4;v00++)
        emissionBaumWelchCount10[v00][i] *= scale;
    }
    for (int i=0; i<1; i++) {
        for(int v00=0;v00<4;v00++)for(int v10=0;v10<4;v10++)
        emissionBaumWelchCount11[v00][v10][i] *= scale;
    }
}


map<const string,int> NucleotideIndel2AlignBaumWelch::mId;
int NucleotideIndel2AlignBaumWelch::atransitionIdx[];
int NucleotideIndel2AlignBaumWelch::aemissionIdx[];

const extern string _NucleotideIndel2AlignWithBandingstateId[];
const extern string _NucleotideIndel2AlignWithBandingemissionId[];
const extern string _NucleotideIndel2AlignWithBandingtransitionId[];
const extern string _NucleotideIndel2AlignWithBandingtransF[];
const extern string _NucleotideIndel2AlignWithBandingtransT[];
const extern string _NucleotideIndel2AlignWithBandingtransP[];
const extern string _NucleotideIndel2AlignWithBandingtransE[];
const extern string _NucleotideIndel2AlignWithBandingoutputId[];
const extern string _NucleotideIndel2AlignWithBandingempty;
const extern int _NucleotideIndel2AlignWithBandingstateNum;
const extern int _NucleotideIndel2AlignWithBandingemitNum;
const extern int _NucleotideIndel2AlignWithBandingtransNum;
const extern int _NucleotideIndel2AlignWithBandingoutputNum;

NucleotideIndel2AlignWithBandingDPTable::NucleotideIndel2AlignWithBandingDPTable(int iLen1,int iLen2) : isInCharge(true), stateId(_NucleotideIndel2AlignWithBandingstateId), emissionId(_NucleotideIndel2AlignWithBandingemissionId), transitionId(_NucleotideIndel2AlignWithBandingtransitionId), transitionFrom(_NucleotideIndel2AlignWithBandingtransF), transitionTo(_NucleotideIndel2AlignWithBandingtransT), transitionProb(_NucleotideIndel2AlignWithBandingtransP), transitionEmit(_NucleotideIndel2AlignWithBandingtransE), outputId(_NucleotideIndel2AlignWithBandingoutputId) {
    // init code:
    this->iLen1 = iLen1;
    this->iLen2 = iLen2;
    StateMemorynucIndel2Block2withbanding.allocate(1+iLen1, 1+iLen2);
    StateMemorynucIndel2Block1.allocate();
    StateMemorynucIndel2Block3.allocate();
}


NucleotideIndel2AlignWithBandingDPTable::~NucleotideIndel2AlignWithBandingDPTable() {
    if (!isInCharge) {
        // make sure data does not get deleted:
        StateMemorynucIndel2Block2withbanding.absolve();
        StateMemorynucIndel2Block1.absolve();
        StateMemorynucIndel2Block3.absolve();
    } // if(!isInCharge)
} // destructor

const string& NucleotideIndel2AlignWithBandingDPTable::getTransitionId(int id) { return id>=0 && id<_NucleotideIndel2AlignWithBandingtransNum ? _NucleotideIndel2AlignWithBandingtransitionId[id] : _NucleotideIndel2AlignWithBandingempty; }
const string& NucleotideIndel2AlignWithBandingDPTable::getEmissionId(int id) { return id>=0 && id<_NucleotideIndel2AlignWithBandingemitNum ? _NucleotideIndel2AlignWithBandingemissionId[id] : _NucleotideIndel2AlignWithBandingempty; }
const string& NucleotideIndel2AlignWithBandingDPTable::getStateId(int id) { return id>=0 && id<_NucleotideIndel2AlignWithBandingstateNum ? _NucleotideIndel2AlignWithBandingstateId[id] : _NucleotideIndel2AlignWithBandingempty; }
const string& NucleotideIndel2AlignWithBandingDPTable::getOutputId(int id) { return id>=0 && id<_NucleotideIndel2AlignWithBandingoutputNum ? _NucleotideIndel2AlignWithBandingoutputId[id] : _NucleotideIndel2AlignWithBandingempty; }
int NucleotideIndel2AlignWithBandingDPTable::getId(const string& sId)
{
    static bool bInit = false;
    static map<string,int>* pmId;
    if (!bInit) {
        pmId = new map<string,int>();
        for (int i=0;i<_NucleotideIndel2AlignWithBandingstateNum;i++) {
            (*pmId)[_NucleotideIndel2AlignWithBandingstateId[i]] = i;         // add state identifiers
        }
        for (int i=0; i<_NucleotideIndel2AlignWithBandingemitNum; i++) {
            (*pmId)[_NucleotideIndel2AlignWithBandingemissionId[i]] = i;      // add emission identifiers
        }
        for (int i=0; i<_NucleotideIndel2AlignWithBandingtransNum; i++) {  
            (*pmId)[_NucleotideIndel2AlignWithBandingtransitionId[i]] = i;    // add transition identifiers
        }
        for (int i=0; i<_NucleotideIndel2AlignWithBandingoutputNum; i++) {
            (*pmId)[_NucleotideIndel2AlignWithBandingoutputId[i]] = i;        // finally, add output identifiers
        }
        bInit = true;
    }
    map<string,int>::iterator iter = pmId->find(sId);
    if (iter == pmId->end()) {
        if (sId == "_cleanup_") {
            delete pmId;
            } else {
            cout << "NucleotideIndel2AlignWithBandingDPTable::getId: WARNING: identifier '" << sId << "' not found." << endl;
        }
        return -1;
    }
    return iter->second;
}


bfloat NucleotideIndel2AlignWithBandingDPTable::getProb(const string sState ,int iPos0,int iPos1) const
{
    return getProb(getId(sState) ,iPos0,iPos1);
}


bfloat NucleotideIndel2AlignWithBandingDPTable::getProb(int iState ,int iPos0,int iPos1) const
{
    const bfloat *CurStateMemorynucIndel2Block1Secondary;
    const bfloat *CurStateMemorynucIndel2Block2withbandingSecondary;
    const bfloat *CurStateMemorynucIndel2Block3Secondary;
    static const int blockTable[] = {0, 1, 1, 1, 1, 1, 2};
    static const int stateTable[] = {0, 0, 1, 2, 3, 4, 0};
    switch (blockTable[iState]) {
        default:
        return 0.0;
        break;
        case 0:
        if ((iPos0+0>=0)&&(iPos0+0<=0)&&(iPos1+0>=0)&&(iPos1+0<=0)) {
            CurStateMemorynucIndel2Block1Secondary = this->StateMemorynucIndel2Block1.read();
            return CurStateMemorynucIndel2Block1Secondary[stateTable[iState]];
        } 
        else { 
            return 0.0;
            
        }
        break;
        case 1:
        if ((iPos0+0>=0)&&(iPos0+0<=iLen1+0)&&(iPos1+0>=0)&&(iPos1+0<=iLen2+0)) {
            CurStateMemorynucIndel2Block2withbandingSecondary = this->StateMemorynucIndel2Block2withbanding.read((iPos0-(0))-(0), (iPos1-(0))-(0));
            return CurStateMemorynucIndel2Block2withbandingSecondary[stateTable[iState]];
        } 
        else { 
            return 0.0;
            
        }
        break;
        case 2:
        if ((iPos0+0>=iLen1+0)&&(iPos0+0<=iLen1+0)&&(iPos1+0>=iLen2+0)&&(iPos1+0<=iLen2+0)) {
            CurStateMemorynucIndel2Block3Secondary = this->StateMemorynucIndel2Block3.read();
            return CurStateMemorynucIndel2Block3Secondary[stateTable[iState]];
        } 
        else { 
            return 0.0;
            
        }
    } // switch
} // DPTable...::getProb(int,...)

const extern string _NucleotideIndel2AlignWithBandingstateId[];
const extern string _NucleotideIndel2AlignWithBandingemissionId[];
const extern string _NucleotideIndel2AlignWithBandingtransitionId[];
const extern string _NucleotideIndel2AlignWithBandingtransF[];
const extern string _NucleotideIndel2AlignWithBandingtransT[];
const extern string _NucleotideIndel2AlignWithBandingtransP[];
const extern string _NucleotideIndel2AlignWithBandingtransE[];
const extern string _NucleotideIndel2AlignWithBandingoutputId[];
const extern string _NucleotideIndel2AlignWithBandingempty;
const extern int _NucleotideIndel2AlignWithBandingstateNum;
const extern int _NucleotideIndel2AlignWithBandingemitNum;
const extern int _NucleotideIndel2AlignWithBandingtransNum;
const extern int _NucleotideIndel2AlignWithBandingoutputNum;

NucleotideIndel2AlignWithBandingFoldedDPTable::NucleotideIndel2AlignWithBandingFoldedDPTable(int iLen1,int iLen2) : isInCharge(true), stateId(_NucleotideIndel2AlignWithBandingstateId), emissionId(_NucleotideIndel2AlignWithBandingemissionId), transitionId(_NucleotideIndel2AlignWithBandingtransitionId), transitionFrom(_NucleotideIndel2AlignWithBandingtransF), transitionTo(_NucleotideIndel2AlignWithBandingtransT), transitionProb(_NucleotideIndel2AlignWithBandingtransP), transitionEmit(_NucleotideIndel2AlignWithBandingtransE), outputId(_NucleotideIndel2AlignWithBandingoutputId) {
    // init code:
    this->iLen1 = iLen1;
    this->iLen2 = iLen2;
    StateMemorynucIndel2Block2withbanding.allocate(1+iLen1, 1+iLen2);
    StateMemorynucIndel2Block3.allocate();
    StateMemorynucIndel2Block1.allocate();
}


NucleotideIndel2AlignWithBandingFoldedDPTable::~NucleotideIndel2AlignWithBandingFoldedDPTable() {
    if (!isInCharge) {
        // make sure data does not get deleted:
        StateMemorynucIndel2Block2withbanding.absolve();
        StateMemorynucIndel2Block3.absolve();
        StateMemorynucIndel2Block1.absolve();
    } // if(!isInCharge)
} // destructor

const string& NucleotideIndel2AlignWithBandingFoldedDPTable::getTransitionId(int id) { return id>=0 && id<_NucleotideIndel2AlignWithBandingtransNum ? _NucleotideIndel2AlignWithBandingtransitionId[id] : _NucleotideIndel2AlignWithBandingempty; }
const string& NucleotideIndel2AlignWithBandingFoldedDPTable::getEmissionId(int id) { return id>=0 && id<_NucleotideIndel2AlignWithBandingemitNum ? _NucleotideIndel2AlignWithBandingemissionId[id] : _NucleotideIndel2AlignWithBandingempty; }
const string& NucleotideIndel2AlignWithBandingFoldedDPTable::getStateId(int id) { return id>=0 && id<_NucleotideIndel2AlignWithBandingstateNum ? _NucleotideIndel2AlignWithBandingstateId[id] : _NucleotideIndel2AlignWithBandingempty; }
const string& NucleotideIndel2AlignWithBandingFoldedDPTable::getOutputId(int id) { return id>=0 && id<_NucleotideIndel2AlignWithBandingoutputNum ? _NucleotideIndel2AlignWithBandingoutputId[id] : _NucleotideIndel2AlignWithBandingempty; }
int NucleotideIndel2AlignWithBandingFoldedDPTable::getId(const string& sId)
{
    static bool bInit = false;
    static map<string,int>* pmId;
    if (!bInit) {
        pmId = new map<string,int>();
        for (int i=0;i<_NucleotideIndel2AlignWithBandingstateNum;i++) {
            (*pmId)[_NucleotideIndel2AlignWithBandingstateId[i]] = i;         // add state identifiers
        }
        for (int i=0; i<_NucleotideIndel2AlignWithBandingemitNum; i++) {
            (*pmId)[_NucleotideIndel2AlignWithBandingemissionId[i]] = i;      // add emission identifiers
        }
        for (int i=0; i<_NucleotideIndel2AlignWithBandingtransNum; i++) {  
            (*pmId)[_NucleotideIndel2AlignWithBandingtransitionId[i]] = i;    // add transition identifiers
        }
        for (int i=0; i<_NucleotideIndel2AlignWithBandingoutputNum; i++) {
            (*pmId)[_NucleotideIndel2AlignWithBandingoutputId[i]] = i;        // finally, add output identifiers
        }
        bInit = true;
    }
    map<string,int>::iterator iter = pmId->find(sId);
    if (iter == pmId->end()) {
        if (sId == "_cleanup_") {
            delete pmId;
            } else {
            cout << "NucleotideIndel2AlignWithBandingFoldedDPTable::getId: WARNING: identifier '" << sId << "' not found." << endl;
        }
        return -1;
    }
    return iter->second;
}


bfloat NucleotideIndel2AlignWithBandingFoldedDPTable::getProb(const string sState ,int iPos0,int iPos1) const
{
    return getProb(getId(sState) ,iPos0,iPos1);
}


bfloat NucleotideIndel2AlignWithBandingFoldedDPTable::getProb(int iState ,int iPos0,int iPos1) const
{
    const bfloat *CurStateMemorynucIndel2Block1Secondary;
    const bfloat *CurStateMemorynucIndel2Block2withbandingSecondary;
    const bfloat *CurStateMemorynucIndel2Block3Secondary;
    static const int blockTable[] = {0, 1, 1, 1, 1, 1, 2};
    static const int stateTable[] = {0, 0, 1, 2, 3, 4, 0};
    switch (blockTable[iState]) {
        default:
        return 0.0;
        break;
        case 0:
        if ((iPos0+0>=0)&&(iPos0+0<=0)&&(iPos1+0>=0)&&(iPos1+0<=0)) {
            CurStateMemorynucIndel2Block1Secondary = this->StateMemorynucIndel2Block1.read();
            return CurStateMemorynucIndel2Block1Secondary[stateTable[iState]];
        } 
        else { 
            return 0.0;
            
        }
        break;
        case 1:
        if ((iPos0+0>=0)&&(iPos0+0<=iLen1+0)&&(iPos1+0>=0)&&(iPos1+0<=iLen2+0)) {
            CurStateMemorynucIndel2Block2withbandingSecondary = this->StateMemorynucIndel2Block2withbanding.read((iPos0-(0))-(0), (iPos1-(0))-(0));
            return CurStateMemorynucIndel2Block2withbandingSecondary[stateTable[iState]];
        } 
        else { 
            return 0.0;
            
        }
        break;
        case 2:
        if ((iPos0+0>=iLen1+0)&&(iPos0+0<=iLen1+0)&&(iPos1+0>=iLen2+0)&&(iPos1+0<=iLen2+0)) {
            CurStateMemorynucIndel2Block3Secondary = this->StateMemorynucIndel2Block3.read();
            return CurStateMemorynucIndel2Block3Secondary[stateTable[iState]];
        } 
        else { 
            return 0.0;
            
        }
    } // switch
} // DPTable...::getProb(int,...)

int NucleotideIndel2AlignWithBandingBaumWelch::transitionIndex(string strId) const {
    map<const string,int>::const_iterator iter = mId.find(strId);
    if (iter == mId.end()) {
        cout << "NucleotideIndel2AlignWithBandingBaumWelch::transitionIndex: WARNING: identifier '" << strId << "' not found." << endl;
        return -1;
    }
    return iter->second;
}


int NucleotideIndel2AlignWithBandingBaumWelch::emissionIndex(string strId) const {
    map<const string,int>::const_iterator iter = mId.find(strId);
    if (iter == mId.end()) {
        cout << "NucleotideIndel2AlignWithBandingBaumWelch::emissionIndex: WARNING: identifier '" << strId << "' not found." << endl;
        return -1;
    }
    return iter->second;
}


void NucleotideIndel2AlignWithBandingBaumWelch::resetCounts() {
    static bool bInited = false;
    if (!bInited) {
        static const int aTemp[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22};
        for (int i=0; i<23; i++) {
            transitionIdentifier00[i] = aTemp[i];
            atransitionIdx[aTemp[i]] = i;
            mId[_NucleotideIndel2AlignWithBandingtransitionId[aTemp[i]]] = i;
        }
    }
    for (int i=0; i<23; i++) {
        
        transitionBaumWelchCount00[i] = 0.0;
    }
    if (!bInited) {
        static const int aTemp[] = {2};
        for (int i=0; i<1; i++) {
            emissionIdentifier00[i] = aTemp[i];
            aemissionIdx[aTemp[i]] = i;
            mId[_NucleotideIndel2AlignWithBandingemissionId[aTemp[i]]] = i;
        }
    }
    for (int i=0; i<1; i++) {
        
        emissionBaumWelchCount00[i] = 0.0;
    }
    if (!bInited) {
        static const int aTemp[] = {1};
        for (int i=0; i<1; i++) {
            emissionIdentifier01[i] = aTemp[i];
            aemissionIdx[aTemp[i]] = i;
            mId[_NucleotideIndel2AlignWithBandingemissionId[aTemp[i]]] = i;
        }
    }
    for (int i=0; i<1; i++) {
        for(int v10=0;v10<4;v10++)
        emissionBaumWelchCount01[v10][i] = 0.0;
    }
    if (!bInited) {
        static const int aTemp[] = {3};
        for (int i=0; i<1; i++) {
            emissionIdentifier10[i] = aTemp[i];
            aemissionIdx[aTemp[i]] = i;
            mId[_NucleotideIndel2AlignWithBandingemissionId[aTemp[i]]] = i;
        }
    }
    for (int i=0; i<1; i++) {
        for(int v00=0;v00<4;v00++)
        emissionBaumWelchCount10[v00][i] = 0.0;
    }
    if (!bInited) {
        static const int aTemp[] = {0};
        for (int i=0; i<1; i++) {
            emissionIdentifier11[i] = aTemp[i];
            aemissionIdx[aTemp[i]] = i;
            mId[_NucleotideIndel2AlignWithBandingemissionId[aTemp[i]]] = i;
        }
    }
    for (int i=0; i<1; i++) {
        for(int v00=0;v00<4;v00++)for(int v10=0;v10<4;v10++)
        emissionBaumWelchCount11[v00][v10][i] = 0.0;
    }
    bInited = true;
};


int NucleotideIndel2AlignWithBandingBaumWelch::transitionIdentifier00[];
int NucleotideIndel2AlignWithBandingBaumWelch::emissionIdentifier00[];
int NucleotideIndel2AlignWithBandingBaumWelch::emissionIdentifier01[];
int NucleotideIndel2AlignWithBandingBaumWelch::emissionIdentifier10[];
int NucleotideIndel2AlignWithBandingBaumWelch::emissionIdentifier11[];

void NucleotideIndel2AlignWithBandingBaumWelch::scaleCounts(bfloat scale) {
    for (int i=0; i<23; i++) {
        
        transitionBaumWelchCount00[i] *= scale;
    }
    for (int i=0; i<1; i++) {
        
        emissionBaumWelchCount00[i] *= scale;
    }
    for (int i=0; i<1; i++) {
        for(int v10=0;v10<4;v10++)
        emissionBaumWelchCount01[v10][i] *= scale;
    }
    for (int i=0; i<1; i++) {
        for(int v00=0;v00<4;v00++)
        emissionBaumWelchCount10[v00][i] *= scale;
    }
    for (int i=0; i<1; i++) {
        for(int v00=0;v00<4;v00++)for(int v10=0;v10<4;v10++)
        emissionBaumWelchCount11[v00][v10][i] *= scale;
    }
}


map<const string,int> NucleotideIndel2AlignWithBandingBaumWelch::mId;
int NucleotideIndel2AlignWithBandingBaumWelch::atransitionIdx[];
int NucleotideIndel2AlignWithBandingBaumWelch::aemissionIdx[];

const string _NucleotideIndel2AlignstateId[] = {"start","delete2","delete1","insert1","match","insert2","end"};
const string _NucleotideIndel2AlignemissionId[] = {"emit12","emit2","empty","emit1"};
const string _NucleotideIndel2AligntransitionId[] = {"trSM","trSI1","trSD1","trSI2","trSD2","trMM","trMI1","trMD1","trMI2","trMD2","trME","trI1M","trI1I1","trI1E","trD1M","trD1D1","trD1E","trI2M","trI2I2","trI2E","trD2M","trD2D2","trD2E"};
const string _NucleotideIndel2AligntransF[] = {"start","start","start","start","start","match","match","match","match","match","match","insert1","insert1","insert1","delete1","delete1","delete1","insert2","insert2","insert2","delete2","delete2","delete2"};
const string _NucleotideIndel2AligntransT[] = {"match","insert1","delete1","insert2","delete2","match","insert1","delete1","insert2","delete2","end","match","insert1","end","match","delete1","end","match","insert2","end","match","delete2","end"};
const string _NucleotideIndel2AligntransP[] = {"probSM","probSI1","probSD1","probSI2","probSD2","probMM","probMI1","probMD1","probMI2","probMD2","probME","probI1M","probI1I1","probI1E","probD1M","probD1D1","probD1E","probI2M","probI2I2","probI2E","probD2M","probD2D2","probD2E"};
const string _NucleotideIndel2AligntransE[] = {"emit12","emit1","emit2","emit1","emit2","emit12","emit1","emit2","emit1","emit2","empty","emit12","emit1","empty","emit12","emit2","empty","emit12","emit1","empty","emit12","emit2","empty"};
const string _NucleotideIndel2AlignoutputId[] = {"sequence1","sequence2"};
const string _NucleotideIndel2Alignempty = "";
const int _NucleotideIndel2AlignstateNum = 7;
const int _NucleotideIndel2AlignemitNum = 4;
const int _NucleotideIndel2AligntransNum = 23;
const int _NucleotideIndel2AlignoutputNum = 2;




bfloat Forward(NucleotideIndel2AlignDPTable** ppOutTable,const std::string& iSequence1,const std::string& iSequence2,const vector<double>& iSingleDistribution,const vector<vector<double> >& iPairDistribution,const vector<vector<double> >& iT) {
    bfloat iTransition[23];
    bfloat *CurStateMemorynucIndel2Block2To;
    const bfloat *CurStateMemorynucIndel2Block1From;
    const bfloat *CurStateMemorynucIndel2Block2From;
    bfloat *CurStateMemorynucIndel2Block3To;
    const bfloat *CurStateMemorynucIndel2Block3From;
    int iPrevSlowCoord;
    int iLen1 = iSequence1.size();   // The sequence lengths are not passed as parameters, but are
    int iLen2 = iSequence2.size();   // computed from the vector<char> itself
    
    // indexing for emission probs
    unsigned char iTranslate[256];
    for (int i=0; i<256; i++) {
        iTranslate[i]= 0;
    }
    iTranslate[(unsigned)'A'] = 0;   // It is important that this is in alphabetical order, to
    iTranslate[(unsigned)'a'] = 0;   // make the indices correspond to those used for Baum-Welch
    iTranslate[(unsigned)'C'] = 1;
    iTranslate[(unsigned)'c'] = 1;
    iTranslate[(unsigned)'G'] = 2;
    iTranslate[(unsigned)'g'] = 2;
    iTranslate[(unsigned)'T'] = 3;
    iTranslate[(unsigned)'t'] = 3;
    int iSymbol[2];
    if (false && iSymbol[0] == iSymbol[0]) {}   // avoid 'unused variable' warnings
    bfloat iEmission[1];
    /* temporary storage for ordinary reals */
    register double iTempResult[1];
    /* temporary storage for extended-exponent reals */
    register bfloat iTempProb[1];
    NucleotideIndel2AlignDPTable dp(iLen1,iLen2);
    iTransition[0] = iT[0][1];
    
    iTransition[1] = iT[0][2];
    
    iTransition[2] = iT[0][3];
    
    iTransition[3] = iT[0][4];
    
    iTransition[4] = iT[0][5];
    
    iTransition[5] = iT[1][1];
    
    iTransition[6] = iT[1][2];
    
    iTransition[7] = iT[1][3];
    
    iTransition[8] = iT[1][4];
    
    iTransition[9] = iT[1][5];
    
    iTransition[10] = iT[1][6];
    
    iTransition[11] = iT[2][1];
    
    iTransition[12] = iT[2][2];
    
    iTransition[13] = iT[2][6];
    
    iTransition[14] = iT[3][1];
    
    iTransition[15] = iT[3][3];
    
    iTransition[16] = iT[3][6];
    
    iTransition[17] = iT[4][1];
    
    iTransition[18] = iT[4][4];
    
    iTransition[19] = iT[4][6];
    
    iTransition[20] = iT[5][1];
    
    iTransition[21] = iT[5][5];
    
    iTransition[22] = iT[5][6];
    dp.StateMemorynucIndel2Block1.write()[0] = 1.0;
    dp.StateMemorynucIndel2Block1.written();
    iPrevSlowCoord = -1;
    for (int iPos1=0; iPos1<iLen2+1; ++iPos1) {
        for (int iPos0=0; iPos0<iLen1+1; ++iPos0) {
            if ((iPos0+0<=0)&&(iPos1+0<=0)) {
            }
            if (1) {
                if ((iPos1+-1>=0)) {
                    iSymbol[0] = iSequence2[iPos1+-1];
                } 
                else { 
                    iSymbol[0] = 'A' /* dummy value */;
                    
                }
                if ((iPos0+-1>=0)) {
                    iSymbol[1] = iSequence1[iPos0+-1];
                } 
                else { 
                    iSymbol[1] = 'A' /* dummy value */;
                    
                }
                CurStateMemorynucIndel2Block2To = dp.StateMemorynucIndel2Block2.write((iPos0-(0))-(0), (iPos1-(0))-(0));
                iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[0]]];
                iEmission[0] = iTempResult[0];
                if ((iPos0+0<=0)&&(iPos1+-1>=0)&&(iPos1+-1<=0)) {
                    CurStateMemorynucIndel2Block1From = dp.StateMemorynucIndel2Block1.read();
                    CurStateMemorynucIndel2Block2To[1] = ((iTransition[2])*(iEmission[0]))*CurStateMemorynucIndel2Block1From[0];
                    CurStateMemorynucIndel2Block2To[0] = ((iTransition[4])*(iEmission[0]))*CurStateMemorynucIndel2Block1From[0];
                }
                if ((iPos1+-1>=0)) {
                    CurStateMemorynucIndel2Block2From = dp.StateMemorynucIndel2Block2.read((iPos0-(0))-(0), (iPos1-(1))-(0));
                    CurStateMemorynucIndel2Block2To[1] += ((iTransition[7])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[3];
                    CurStateMemorynucIndel2Block2To[1] += ((iTransition[15])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[1];
                    CurStateMemorynucIndel2Block2To[0] += ((iTransition[9])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[3];
                    CurStateMemorynucIndel2Block2To[0] += ((iTransition[21])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[0];
                }
                iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[1]]];
                iEmission[0] = iTempResult[0];
                if ((iPos0+-1>=0)&&(iPos0+-1<=0)&&(iPos1+0<=0)) {
                    CurStateMemorynucIndel2Block1From = dp.StateMemorynucIndel2Block1.read();
                    CurStateMemorynucIndel2Block2To[2] = ((iTransition[1])*(iEmission[0]))*CurStateMemorynucIndel2Block1From[0];
                    CurStateMemorynucIndel2Block2To[4] = ((iTransition[3])*(iEmission[0]))*CurStateMemorynucIndel2Block1From[0];
                }
                if ((iPos0+-1>=0)) {
                    CurStateMemorynucIndel2Block2From = dp.StateMemorynucIndel2Block2.read((iPos0-(1))-(0), (iPos1-(0))-(0));
                    CurStateMemorynucIndel2Block2To[2] += ((iTransition[6])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[3];
                    CurStateMemorynucIndel2Block2To[2] += ((iTransition[12])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[2];
                    CurStateMemorynucIndel2Block2To[4] += ((iTransition[8])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[3];
                    CurStateMemorynucIndel2Block2To[4] += ((iTransition[18])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[4];
                }
                iTempResult[0] = iPairDistribution[iTranslate[iSymbol[1]]][iTranslate[iSymbol[0]]];
                iEmission[0] = iTempResult[0];
                if ((iPos0+-1>=0)&&(iPos0+-1<=0)&&(iPos1+-1>=0)&&(iPos1+-1<=0)) {
                    CurStateMemorynucIndel2Block1From = dp.StateMemorynucIndel2Block1.read();
                    CurStateMemorynucIndel2Block2To[3] = ((iTransition[0])*(iEmission[0]))*CurStateMemorynucIndel2Block1From[0];
                }
                if ((iPos0+-1>=0)&&(iPos1+-1>=0)) {
                    CurStateMemorynucIndel2Block2From = dp.StateMemorynucIndel2Block2.read((iPos0-(1))-(0), (iPos1-(1))-(0));
                    CurStateMemorynucIndel2Block2To[3] += ((iTransition[5])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[3];
                    CurStateMemorynucIndel2Block2To[3] += ((iTransition[11])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[2];
                    CurStateMemorynucIndel2Block2To[3] += ((iTransition[20])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[0];
                    CurStateMemorynucIndel2Block2To[3] += ((iTransition[14])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[1];
                    CurStateMemorynucIndel2Block2To[3] += ((iTransition[17])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[4];
                }
                dp.StateMemorynucIndel2Block2.written();
            }
            if ((iPos0+0>=iLen1+0)&&(iPos1+0>=iLen2+0)) {
                CurStateMemorynucIndel2Block3To = dp.StateMemorynucIndel2Block3.write();
                iEmission[0] = 1.0;
                if (1) {
                    CurStateMemorynucIndel2Block2From = dp.StateMemorynucIndel2Block2.read((iPos0-(0))-(0), (iPos1-(0))-(0));
                    CurStateMemorynucIndel2Block3To[0] = ((iTransition[10])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[3];
                    CurStateMemorynucIndel2Block3To[0] += ((iTransition[13])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[2];
                    CurStateMemorynucIndel2Block3To[0] += ((iTransition[22])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[0];
                    CurStateMemorynucIndel2Block3To[0] += ((iTransition[16])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[1];
                    CurStateMemorynucIndel2Block3To[0] += ((iTransition[19])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[4];
                }
                dp.StateMemorynucIndel2Block3.written();
            }
            iPrevSlowCoord = iPos1;
        }
    }
    iPrevSlowCoord = -1;
    {
        int iPos1=iLen2+0;
        if (iPos1==iPos1) {} // avoid 'unused variable' warnings
        {
            int iPos0=iLen1+0;
            if (iPos0==iPos0) {} // avoid 'unused variable' warnings
            CurStateMemorynucIndel2Block3From = dp.StateMemorynucIndel2Block3.read();
            iTempProb[0] = CurStateMemorynucIndel2Block3From[0];
        }
    }
    *ppOutTable = new NucleotideIndel2AlignDPTable(dp);
    // make sure tables don't get deleted
    dp.isInCharge = false;
    return iTempProb[0];
};





bfloat BackwardBaumWelch(NucleotideIndel2AlignBaumWelch& bw,NucleotideIndel2AlignDPTable* pInTable,const std::string& iSequence1,const std::string& iSequence2,const vector<double>& iSingleDistribution,const vector<vector<double> >& iPairDistribution,const vector<vector<double> >& iT) {
    const bfloat *CurStateMemorynucIndel2Block3Secondary;
    bfloat iTransition[23];
    bfloat *CurStateMemorynucIndel2Block2To;
    const bfloat *CurStateMemorynucIndel2Block2Secondary;
    const bfloat *CurStateMemorynucIndel2Block2From;
    unsigned char alphaSymbolnucleotide[4] = {'A', 'C', 'G', 'T'};
    unsigned char alphaIndexnucleotide[256];
    const bfloat *CurStateMemorynucIndel2Block3From;
    bfloat *CurStateMemorynucIndel2Block1To;
    const bfloat *CurStateMemorynucIndel2Block1Secondary;
    const bfloat *CurStateMemorynucIndel2Block1From;
    int iPrevSlowCoord;
    int iLen1 = iSequence1.size();   // The sequence lengths are not passed as parameters, but are
    int iLen2 = iSequence2.size();   // computed from the vector<char> itself
    
    // indexing for emission probs
    unsigned char iTranslate[256];
    for (int i=0; i<256; i++) {
        iTranslate[i]= 0;
    }
    iTranslate[(unsigned)'A'] = 0;   // It is important that this is in alphabetical order, to
    iTranslate[(unsigned)'a'] = 0;   // make the indices correspond to those used for Baum-Welch
    iTranslate[(unsigned)'C'] = 1;
    iTranslate[(unsigned)'c'] = 1;
    iTranslate[(unsigned)'G'] = 2;
    iTranslate[(unsigned)'g'] = 2;
    iTranslate[(unsigned)'T'] = 3;
    iTranslate[(unsigned)'t'] = 3;
    int iSymbol[2];
    if (false && iSymbol[0] == iSymbol[0]) {}   // avoid 'unused variable' warnings
    bfloat iEmission[1];
    /* temporary storage for ordinary reals */
    register double iTempResult[1];
    /* temporary storage for extended-exponent reals */
    register bfloat iTempProb[3];
    NucleotideIndel2AlignFoldedDPTable dp(iLen1,2);
    NucleotideIndel2AlignDPTable dp2(*pInTable);
    // make sure tables don't get deleted
    dp2.isInCharge = false;
    iTransition[0] = iT[0][1];
    
    iTransition[1] = iT[0][2];
    
    iTransition[2] = iT[0][3];
    
    iTransition[3] = iT[0][4];
    
    iTransition[4] = iT[0][5];
    
    iTransition[5] = iT[1][1];
    
    iTransition[6] = iT[1][2];
    
    iTransition[7] = iT[1][3];
    
    iTransition[8] = iT[1][4];
    
    iTransition[9] = iT[1][5];
    
    iTransition[10] = iT[1][6];
    
    iTransition[11] = iT[2][1];
    
    iTransition[12] = iT[2][2];
    
    iTransition[13] = iT[2][6];
    
    iTransition[14] = iT[3][1];
    
    iTransition[15] = iT[3][3];
    
    iTransition[16] = iT[3][6];
    
    iTransition[17] = iT[4][1];
    
    iTransition[18] = iT[4][4];
    
    iTransition[19] = iT[4][6];
    
    iTransition[20] = iT[5][1];
    
    iTransition[21] = iT[5][5];
    
    iTransition[22] = iT[5][6];
    for (int i=0; i<256; i++) {
        alphaIndexnucleotide[i]=0;
    }

//    for (int i=0; i<4; i++) {
//        alphaIndexnucleotide[alphaSymbolnucleotide[i]]=i;
//    }
    for (int i=0; i<4; i++) {
      alphaIndexnucleotide[tolower (alphaSymbolnucleotide[i])] = i;
      alphaIndexnucleotide[toupper (alphaSymbolnucleotide[i])] = i;
    }
    // treat lower and upper-case characters as equivalent during Baum-Welch
    // -- RKB

    dp.StateMemorynucIndel2Block3.write()[0] = 1.0;
    dp.StateMemorynucIndel2Block3.written();
    iPrevSlowCoord = -1;
    {
        int iPos1=iLen2+0;
        if (iPos1==iPos1) {} // avoid 'unused variable' warnings
        {
            int iPos0=iLen1+0;
            if (iPos0==iPos0) {} // avoid 'unused variable' warnings
            CurStateMemorynucIndel2Block3Secondary = dp2.StateMemorynucIndel2Block3.read();
            iTempProb[2] = CurStateMemorynucIndel2Block3Secondary[0];
            bw.scaleCounts(iTempProb[2]);
        }
    }
    iPrevSlowCoord = -1;
    for (int iPos1=(iLen2+1)-1; iPos1>=0; --iPos1) {
        for (int iPos0=(iLen1+1)-1; iPos0>=0; --iPos0) {
            if (iPrevSlowCoord != -1 && iPrevSlowCoord != iPos1) {
                dp.StateMemorynucIndel2Block2.clear(iPos1);
            }
            if ((iPos0+0>=iLen1+0)&&(iPos1+0>=iLen2+0)) {
            }
            if (1) {
                if ((iPos1+0<=iLen2+-1)) {
                    iSymbol[0] = iSequence2[iPos1+0];
                } 
                else { 
                    iSymbol[0] = 'A' /* dummy value */;
                    
                }
                if ((iPos0+0<=iLen1+-1)) {
                    iSymbol[1] = iSequence1[iPos0+0];
                } 
                else { 
                    iSymbol[1] = 'A' /* dummy value */;
                    
                }
                CurStateMemorynucIndel2Block2To = dp.StateMemorynucIndel2Block2.write((iPos0-(0))-(0), (iPos1-(0))-(0));
                CurStateMemorynucIndel2Block2Secondary = dp2.StateMemorynucIndel2Block2.read((iPos0-(0))-(0), (iPos1-(0))-(0));
                iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[0]]];
                iEmission[0] = iTempResult[0];
                if ((iPos1+1<=iLen2+0)) {
                    CurStateMemorynucIndel2Block2From = dp.StateMemorynucIndel2Block2.read((iPos0-(0))-(0), (iPos1-(-1))-(0));
                    CurStateMemorynucIndel2Block2To[3] = iTempProb[1] = ((iTransition[7])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[1];
                    iTempProb[1] *= CurStateMemorynucIndel2Block2Secondary[3];
                    bw.transitionBaumWelchCount00[7] += iTempProb[1];
                    bw.emissionBaumWelchCount01[alphaIndexnucleotide[iSymbol[0]]][0] += iTempProb[1];
                    CurStateMemorynucIndel2Block2To[3] += iTempProb[1] = ((iTransition[9])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[0];
                    iTempProb[1] *= CurStateMemorynucIndel2Block2Secondary[3];
                    bw.transitionBaumWelchCount00[9] += iTempProb[1];
                    bw.emissionBaumWelchCount01[alphaIndexnucleotide[iSymbol[0]]][0] += iTempProb[1];
                    CurStateMemorynucIndel2Block2To[1] = iTempProb[1] = ((iTransition[15])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[1];
                    iTempProb[1] *= CurStateMemorynucIndel2Block2Secondary[1];
                    bw.transitionBaumWelchCount00[15] += iTempProb[1];
                    bw.emissionBaumWelchCount01[alphaIndexnucleotide[iSymbol[0]]][0] += iTempProb[1];
                    CurStateMemorynucIndel2Block2To[0] = iTempProb[1] = ((iTransition[21])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[0];
                    iTempProb[1] *= CurStateMemorynucIndel2Block2Secondary[0];
                    bw.transitionBaumWelchCount00[21] += iTempProb[1];
                    bw.emissionBaumWelchCount01[alphaIndexnucleotide[iSymbol[0]]][0] += iTempProb[1];
                }
                iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[1]]];
                iEmission[0] = iTempResult[0];
                if ((iPos0+1<=iLen1+0)) {
                    CurStateMemorynucIndel2Block2From = dp.StateMemorynucIndel2Block2.read((iPos0-(-1))-(0), (iPos1-(0))-(0));
                    CurStateMemorynucIndel2Block2To[2] = iTempProb[1] = ((iTransition[12])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[2];
                    iTempProb[1] *= CurStateMemorynucIndel2Block2Secondary[2];
                    bw.transitionBaumWelchCount00[12] += iTempProb[1];
                    bw.emissionBaumWelchCount10[alphaIndexnucleotide[iSymbol[1]]][0] += iTempProb[1];
                    CurStateMemorynucIndel2Block2To[3] += iTempProb[1] = ((iTransition[6])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[2];
                    iTempProb[1] *= CurStateMemorynucIndel2Block2Secondary[3];
                    bw.transitionBaumWelchCount00[6] += iTempProb[1];
                    bw.emissionBaumWelchCount10[alphaIndexnucleotide[iSymbol[1]]][0] += iTempProb[1];
                    CurStateMemorynucIndel2Block2To[3] += iTempProb[1] = ((iTransition[8])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[4];
                    iTempProb[1] *= CurStateMemorynucIndel2Block2Secondary[3];
                    bw.transitionBaumWelchCount00[8] += iTempProb[1];
                    bw.emissionBaumWelchCount10[alphaIndexnucleotide[iSymbol[1]]][0] += iTempProb[1];
                    CurStateMemorynucIndel2Block2To[4] = iTempProb[1] = ((iTransition[18])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[4];
                    iTempProb[1] *= CurStateMemorynucIndel2Block2Secondary[4];
                    bw.transitionBaumWelchCount00[18] += iTempProb[1];
                    bw.emissionBaumWelchCount10[alphaIndexnucleotide[iSymbol[1]]][0] += iTempProb[1];
                }
                iTempResult[0] = iPairDistribution[iTranslate[iSymbol[1]]][iTranslate[iSymbol[0]]];
                iEmission[0] = iTempResult[0];
                if ((iPos0+1<=iLen1+0)&&(iPos1+1<=iLen2+0)) {
                    CurStateMemorynucIndel2Block2From = dp.StateMemorynucIndel2Block2.read((iPos0-(-1))-(0), (iPos1-(-1))-(0));
                    CurStateMemorynucIndel2Block2To[2] += iTempProb[1] = ((iTransition[11])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[3];
                    iTempProb[1] *= CurStateMemorynucIndel2Block2Secondary[2];
                    bw.transitionBaumWelchCount00[11] += iTempProb[1];
                    bw.emissionBaumWelchCount11[alphaIndexnucleotide[iSymbol[1]]][alphaIndexnucleotide[iSymbol[0]]][0] += iTempProb[1];
                    CurStateMemorynucIndel2Block2To[1] += iTempProb[1] = ((iTransition[14])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[3];
                    iTempProb[1] *= CurStateMemorynucIndel2Block2Secondary[1];
                    bw.transitionBaumWelchCount00[14] += iTempProb[1];
                    bw.emissionBaumWelchCount11[alphaIndexnucleotide[iSymbol[1]]][alphaIndexnucleotide[iSymbol[0]]][0] += iTempProb[1];
                    CurStateMemorynucIndel2Block2To[4] += iTempProb[1] = ((iTransition[17])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[3];
                    iTempProb[1] *= CurStateMemorynucIndel2Block2Secondary[4];
                    bw.transitionBaumWelchCount00[17] += iTempProb[1];
                    bw.emissionBaumWelchCount11[alphaIndexnucleotide[iSymbol[1]]][alphaIndexnucleotide[iSymbol[0]]][0] += iTempProb[1];
                    CurStateMemorynucIndel2Block2To[0] += iTempProb[1] = ((iTransition[20])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[3];
                    iTempProb[1] *= CurStateMemorynucIndel2Block2Secondary[0];
                    bw.transitionBaumWelchCount00[20] += iTempProb[1];
                    bw.emissionBaumWelchCount11[alphaIndexnucleotide[iSymbol[1]]][alphaIndexnucleotide[iSymbol[0]]][0] += iTempProb[1];
                    CurStateMemorynucIndel2Block2To[3] += iTempProb[1] = ((iTransition[5])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[3];
                    iTempProb[1] *= CurStateMemorynucIndel2Block2Secondary[3];
                    bw.transitionBaumWelchCount00[5] += iTempProb[1];
                    bw.emissionBaumWelchCount11[alphaIndexnucleotide[iSymbol[1]]][alphaIndexnucleotide[iSymbol[0]]][0] += iTempProb[1];
                }
                iEmission[0] = 1.0;
                if ((iPos0+0>=iLen1+0)&&(iPos1+0>=iLen2+0)) {
                    CurStateMemorynucIndel2Block3From = dp.StateMemorynucIndel2Block3.read();
                    CurStateMemorynucIndel2Block2To[2] += iTempProb[1] = ((iTransition[13])*(iEmission[0]))*CurStateMemorynucIndel2Block3From[0];
                    iTempProb[1] *= CurStateMemorynucIndel2Block2Secondary[2];
                    bw.transitionBaumWelchCount00[13] += iTempProb[1];
                    bw.emissionBaumWelchCount00[0] += iTempProb[1];
                    CurStateMemorynucIndel2Block2To[1] += iTempProb[1] = ((iTransition[16])*(iEmission[0]))*CurStateMemorynucIndel2Block3From[0];
                    iTempProb[1] *= CurStateMemorynucIndel2Block2Secondary[1];
                    bw.transitionBaumWelchCount00[16] += iTempProb[1];
                    bw.emissionBaumWelchCount00[0] += iTempProb[1];
                    CurStateMemorynucIndel2Block2To[4] += iTempProb[1] = ((iTransition[19])*(iEmission[0]))*CurStateMemorynucIndel2Block3From[0];
                    iTempProb[1] *= CurStateMemorynucIndel2Block2Secondary[4];
                    bw.transitionBaumWelchCount00[19] += iTempProb[1];
                    bw.emissionBaumWelchCount00[0] += iTempProb[1];
                    CurStateMemorynucIndel2Block2To[0] += iTempProb[1] = ((iTransition[22])*(iEmission[0]))*CurStateMemorynucIndel2Block3From[0];
                    iTempProb[1] *= CurStateMemorynucIndel2Block2Secondary[0];
                    bw.transitionBaumWelchCount00[22] += iTempProb[1];
                    bw.emissionBaumWelchCount00[0] += iTempProb[1];
                    CurStateMemorynucIndel2Block2To[3] += iTempProb[1] = ((iTransition[10])*(iEmission[0]))*CurStateMemorynucIndel2Block3From[0];
                    iTempProb[1] *= CurStateMemorynucIndel2Block2Secondary[3];
                    bw.transitionBaumWelchCount00[10] += iTempProb[1];
                    bw.emissionBaumWelchCount00[0] += iTempProb[1];
                }
                dp.StateMemorynucIndel2Block2.written();
            }
            if ((iPos0+0<=0)&&(iPos1+0<=0)) {
                if ((iPos1+0<=iLen2+-1)) {
                    iSymbol[0] = iSequence2[iPos1+0];
                } 
                else { 
                    iSymbol[0] = 'A' /* dummy value */;
                    
                }
                if ((iPos0+0<=iLen1+-1)) {
                    iSymbol[1] = iSequence1[iPos0+0];
                } 
                else { 
                    iSymbol[1] = 'A' /* dummy value */;
                    
                }
                CurStateMemorynucIndel2Block1To = dp.StateMemorynucIndel2Block1.write();
                CurStateMemorynucIndel2Block1Secondary = dp2.StateMemorynucIndel2Block1.read();
                iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[0]]];
                iEmission[0] = iTempResult[0];
                if ((iPos1+1<=iLen2+0)) {
                    CurStateMemorynucIndel2Block2From = dp.StateMemorynucIndel2Block2.read((iPos0-(0))-(0), (iPos1-(-1))-(0));
                    CurStateMemorynucIndel2Block1To[0] = iTempProb[1] = ((iTransition[2])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[1];
                    iTempProb[1] *= CurStateMemorynucIndel2Block1Secondary[0];
                    bw.transitionBaumWelchCount00[2] += iTempProb[1];
                    bw.emissionBaumWelchCount01[alphaIndexnucleotide[iSymbol[0]]][0] += iTempProb[1];
                    CurStateMemorynucIndel2Block1To[0] += iTempProb[1] = ((iTransition[4])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[0];
                    iTempProb[1] *= CurStateMemorynucIndel2Block1Secondary[0];
                    bw.transitionBaumWelchCount00[4] += iTempProb[1];
                    bw.emissionBaumWelchCount01[alphaIndexnucleotide[iSymbol[0]]][0] += iTempProb[1];
                }
                iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[1]]];
                iEmission[0] = iTempResult[0];
                if ((iPos0+1<=iLen1+0)) {
                    CurStateMemorynucIndel2Block2From = dp.StateMemorynucIndel2Block2.read((iPos0-(-1))-(0), (iPos1-(0))-(0));
                    CurStateMemorynucIndel2Block1To[0] += iTempProb[1] = ((iTransition[1])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[2];
                    iTempProb[1] *= CurStateMemorynucIndel2Block1Secondary[0];
                    bw.transitionBaumWelchCount00[1] += iTempProb[1];
                    bw.emissionBaumWelchCount10[alphaIndexnucleotide[iSymbol[1]]][0] += iTempProb[1];
                    CurStateMemorynucIndel2Block1To[0] += iTempProb[1] = ((iTransition[3])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[4];
                    iTempProb[1] *= CurStateMemorynucIndel2Block1Secondary[0];
                    bw.transitionBaumWelchCount00[3] += iTempProb[1];
                    bw.emissionBaumWelchCount10[alphaIndexnucleotide[iSymbol[1]]][0] += iTempProb[1];
                }
                iTempResult[0] = iPairDistribution[iTranslate[iSymbol[1]]][iTranslate[iSymbol[0]]];
                iEmission[0] = iTempResult[0];
                if ((iPos0+1<=iLen1+0)&&(iPos1+1<=iLen2+0)) {
                    CurStateMemorynucIndel2Block2From = dp.StateMemorynucIndel2Block2.read((iPos0-(-1))-(0), (iPos1-(-1))-(0));
                    CurStateMemorynucIndel2Block1To[0] += iTempProb[1] = ((iTransition[0])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[3];
                    iTempProb[1] *= CurStateMemorynucIndel2Block1Secondary[0];
                    bw.transitionBaumWelchCount00[0] += iTempProb[1];
                    bw.emissionBaumWelchCount11[alphaIndexnucleotide[iSymbol[1]]][alphaIndexnucleotide[iSymbol[0]]][0] += iTempProb[1];
                }
                dp.StateMemorynucIndel2Block1.written();
            }
            iPrevSlowCoord = iPos1;
        }
    }
    bw.scaleCounts(1.0 / iTempProb[2]);
    iPrevSlowCoord = -1;
    {
        int iPos1=0;
        if (iPos1==iPos1) {} // avoid 'unused variable' warnings
        {
            int iPos0=0;
            if (iPos0==iPos0) {} // avoid 'unused variable' warnings
            CurStateMemorynucIndel2Block1From = dp.StateMemorynucIndel2Block1.read();
            iTempProb[0] = CurStateMemorynucIndel2Block1From[0];
        }
    }
    return iTempProb[0];
};





bfloat Backward(NucleotideIndel2AlignDPTable** ppOutTable,const std::string& iSequence1,const std::string& iSequence2,const vector<double>& iSingleDistribution,const vector<vector<double> >& iPairDistribution,const vector<vector<double> >& iT) {
    bfloat iTransition[23];
    bfloat *CurStateMemorynucIndel2Block2To;
    const bfloat *CurStateMemorynucIndel2Block2From;
    const bfloat *CurStateMemorynucIndel2Block3From;
    bfloat *CurStateMemorynucIndel2Block1To;
    const bfloat *CurStateMemorynucIndel2Block1From;
    int iPrevSlowCoord;
    int iLen1 = iSequence1.size();   // The sequence lengths are not passed as parameters, but are
    int iLen2 = iSequence2.size();   // computed from the vector<char> itself
    
    // indexing for emission probs
    unsigned char iTranslate[256];
    for (int i=0; i<256; i++) {
        iTranslate[i]= 0;
    }
    iTranslate[(unsigned)'A'] = 0;   // It is important that this is in alphabetical order, to
    iTranslate[(unsigned)'a'] = 0;   // make the indices correspond to those used for Baum-Welch
    iTranslate[(unsigned)'C'] = 1;
    iTranslate[(unsigned)'c'] = 1;
    iTranslate[(unsigned)'G'] = 2;
    iTranslate[(unsigned)'g'] = 2;
    iTranslate[(unsigned)'T'] = 3;
    iTranslate[(unsigned)'t'] = 3;
    int iSymbol[2];
    if (false && iSymbol[0] == iSymbol[0]) {}   // avoid 'unused variable' warnings
    bfloat iEmission[1];
    /* temporary storage for ordinary reals */
    register double iTempResult[1];
    /* temporary storage for extended-exponent reals */
    register bfloat iTempProb[1];
    NucleotideIndel2AlignDPTable dp(iLen1,iLen2);
    iTransition[0] = iT[0][1];
    
    iTransition[1] = iT[0][2];
    
    iTransition[2] = iT[0][3];
    
    iTransition[3] = iT[0][4];
    
    iTransition[4] = iT[0][5];
    
    iTransition[5] = iT[1][1];
    
    iTransition[6] = iT[1][2];
    
    iTransition[7] = iT[1][3];
    
    iTransition[8] = iT[1][4];
    
    iTransition[9] = iT[1][5];
    
    iTransition[10] = iT[1][6];
    
    iTransition[11] = iT[2][1];
    
    iTransition[12] = iT[2][2];
    
    iTransition[13] = iT[2][6];
    
    iTransition[14] = iT[3][1];
    
    iTransition[15] = iT[3][3];
    
    iTransition[16] = iT[3][6];
    
    iTransition[17] = iT[4][1];
    
    iTransition[18] = iT[4][4];
    
    iTransition[19] = iT[4][6];
    
    iTransition[20] = iT[5][1];
    
    iTransition[21] = iT[5][5];
    
    iTransition[22] = iT[5][6];
    dp.StateMemorynucIndel2Block3.write()[0] = 1.0;
    dp.StateMemorynucIndel2Block3.written();
    iPrevSlowCoord = -1;
    for (int iPos1=(iLen2+1)-1; iPos1>=0; --iPos1) {
        for (int iPos0=(iLen1+1)-1; iPos0>=0; --iPos0) {
            if ((iPos0+0>=iLen1+0)&&(iPos1+0>=iLen2+0)) {
            }
            if (1) {
                if ((iPos1+0<=iLen2+-1)) {
                    iSymbol[0] = iSequence2[iPos1+0];
                } 
                else { 
                    iSymbol[0] = 'A' /* dummy value */;
                    
                }
                if ((iPos0+0<=iLen1+-1)) {
                    iSymbol[1] = iSequence1[iPos0+0];
                } 
                else { 
                    iSymbol[1] = 'A' /* dummy value */;
                    
                }
                CurStateMemorynucIndel2Block2To = dp.StateMemorynucIndel2Block2.write((iPos0-(0))-(0), (iPos1-(0))-(0));
                iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[0]]];
                iEmission[0] = iTempResult[0];
                if ((iPos1+1<=iLen2+0)) {
                    CurStateMemorynucIndel2Block2From = dp.StateMemorynucIndel2Block2.read((iPos0-(0))-(0), (iPos1-(-1))-(0));
                    CurStateMemorynucIndel2Block2To[0] = ((iTransition[21])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[0];
                    CurStateMemorynucIndel2Block2To[3] = ((iTransition[9])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[0];
                    CurStateMemorynucIndel2Block2To[3] += ((iTransition[7])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[1];
                    CurStateMemorynucIndel2Block2To[1] = ((iTransition[15])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[1];
                }
                iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[1]]];
                iEmission[0] = iTempResult[0];
                if ((iPos0+1<=iLen1+0)) {
                    CurStateMemorynucIndel2Block2From = dp.StateMemorynucIndel2Block2.read((iPos0-(-1))-(0), (iPos1-(0))-(0));
                    CurStateMemorynucIndel2Block2To[2] = ((iTransition[12])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[2];
                    CurStateMemorynucIndel2Block2To[3] += ((iTransition[6])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[2];
                    CurStateMemorynucIndel2Block2To[3] += ((iTransition[8])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[4];
                    CurStateMemorynucIndel2Block2To[4] = ((iTransition[18])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[4];
                }
                iTempResult[0] = iPairDistribution[iTranslate[iSymbol[1]]][iTranslate[iSymbol[0]]];
                iEmission[0] = iTempResult[0];
                if ((iPos0+1<=iLen1+0)&&(iPos1+1<=iLen2+0)) {
                    CurStateMemorynucIndel2Block2From = dp.StateMemorynucIndel2Block2.read((iPos0-(-1))-(0), (iPos1-(-1))-(0));
                    CurStateMemorynucIndel2Block2To[2] += ((iTransition[11])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[3];
                    CurStateMemorynucIndel2Block2To[0] += ((iTransition[20])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[3];
                    CurStateMemorynucIndel2Block2To[3] += ((iTransition[5])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[3];
                    CurStateMemorynucIndel2Block2To[4] += ((iTransition[17])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[3];
                    CurStateMemorynucIndel2Block2To[1] += ((iTransition[14])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[3];
                }
                iEmission[0] = 1.0;
                if ((iPos0+0>=iLen1+0)&&(iPos1+0>=iLen2+0)) {
                    CurStateMemorynucIndel2Block3From = dp.StateMemorynucIndel2Block3.read();
                    CurStateMemorynucIndel2Block2To[2] += ((iTransition[13])*(iEmission[0]))*CurStateMemorynucIndel2Block3From[0];
                    CurStateMemorynucIndel2Block2To[0] += ((iTransition[22])*(iEmission[0]))*CurStateMemorynucIndel2Block3From[0];
                    CurStateMemorynucIndel2Block2To[3] += ((iTransition[10])*(iEmission[0]))*CurStateMemorynucIndel2Block3From[0];
                    CurStateMemorynucIndel2Block2To[4] += ((iTransition[19])*(iEmission[0]))*CurStateMemorynucIndel2Block3From[0];
                    CurStateMemorynucIndel2Block2To[1] += ((iTransition[16])*(iEmission[0]))*CurStateMemorynucIndel2Block3From[0];
                }
                dp.StateMemorynucIndel2Block2.written();
            }
            if ((iPos0+0<=0)&&(iPos1+0<=0)) {
                if ((iPos1+0<=iLen2+-1)) {
                    iSymbol[0] = iSequence2[iPos1+0];
                } 
                else { 
                    iSymbol[0] = 'A' /* dummy value */;
                    
                }
                if ((iPos0+0<=iLen1+-1)) {
                    iSymbol[1] = iSequence1[iPos0+0];
                } 
                else { 
                    iSymbol[1] = 'A' /* dummy value */;
                    
                }
                CurStateMemorynucIndel2Block1To = dp.StateMemorynucIndel2Block1.write();
                iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[0]]];
                iEmission[0] = iTempResult[0];
                if ((iPos1+1<=iLen2+0)) {
                    CurStateMemorynucIndel2Block2From = dp.StateMemorynucIndel2Block2.read((iPos0-(0))-(0), (iPos1-(-1))-(0));
                    CurStateMemorynucIndel2Block1To[0] = ((iTransition[4])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[0];
                    CurStateMemorynucIndel2Block1To[0] += ((iTransition[2])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[1];
                }
                iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[1]]];
                iEmission[0] = iTempResult[0];
                if ((iPos0+1<=iLen1+0)) {
                    CurStateMemorynucIndel2Block2From = dp.StateMemorynucIndel2Block2.read((iPos0-(-1))-(0), (iPos1-(0))-(0));
                    CurStateMemorynucIndel2Block1To[0] += ((iTransition[1])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[2];
                    CurStateMemorynucIndel2Block1To[0] += ((iTransition[3])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[4];
                }
                iTempResult[0] = iPairDistribution[iTranslate[iSymbol[1]]][iTranslate[iSymbol[0]]];
                iEmission[0] = iTempResult[0];
                if ((iPos0+1<=iLen1+0)&&(iPos1+1<=iLen2+0)) {
                    CurStateMemorynucIndel2Block2From = dp.StateMemorynucIndel2Block2.read((iPos0-(-1))-(0), (iPos1-(-1))-(0));
                    CurStateMemorynucIndel2Block1To[0] += ((iTransition[0])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[3];
                }
                dp.StateMemorynucIndel2Block1.written();
            }
            iPrevSlowCoord = iPos1;
        }
    }
    iPrevSlowCoord = -1;
    {
        int iPos1=0;
        if (iPos1==iPos1) {} // avoid 'unused variable' warnings
        {
            int iPos0=0;
            if (iPos0==iPos0) {} // avoid 'unused variable' warnings
            CurStateMemorynucIndel2Block1From = dp.StateMemorynucIndel2Block1.read();
            iTempProb[0] = CurStateMemorynucIndel2Block1From[0];
        }
    }
    *ppOutTable = new NucleotideIndel2AlignDPTable(dp);
    // make sure tables don't get deleted
    dp.isInCharge = false;
    return iTempProb[0];
};



const string _NucleotideIndel2AlignWithBandingstateId[] = {"start","delete2","delete1","insert1","match","insert2","end"};
const string _NucleotideIndel2AlignWithBandingemissionId[] = {"emit12","emit2","empty","emit1"};
const string _NucleotideIndel2AlignWithBandingtransitionId[] = {"trSM","trSI1","trSD1","trSI2","trSD2","trMM","trMI1","trMD1","trMI2","trMD2","trME","trI1M","trI1I1","trI1E","trD1M","trD1D1","trD1E","trI2M","trI2I2","trI2E","trD2M","trD2D2","trD2E"};
const string _NucleotideIndel2AlignWithBandingtransF[] = {"start","start","start","start","start","match","match","match","match","match","match","insert1","insert1","insert1","delete1","delete1","delete1","insert2","insert2","insert2","delete2","delete2","delete2"};
const string _NucleotideIndel2AlignWithBandingtransT[] = {"match","insert1","delete1","insert2","delete2","match","insert1","delete1","insert2","delete2","end","match","insert1","end","match","delete1","end","match","insert2","end","match","delete2","end"};
const string _NucleotideIndel2AlignWithBandingtransP[] = {"probSM","probSI1","probSD1","probSI2","probSD2","probMM","probMI1","probMD1","probMI2","probMD2","probME","probI1M","probI1I1","probI1E","probD1M","probD1D1","probD1E","probI2M","probI2I2","probI2E","probD2M","probD2D2","probD2E"};
const string _NucleotideIndel2AlignWithBandingtransE[] = {"emit12","emit1","emit2","emit1","emit2","emit12","emit1","emit2","emit1","emit2","empty","emit12","emit1","empty","emit12","emit2","empty","emit12","emit1","empty","emit12","emit2","empty"};
const string _NucleotideIndel2AlignWithBandingoutputId[] = {"sequence1","sequence2"};
const string _NucleotideIndel2AlignWithBandingempty = "";
const int _NucleotideIndel2AlignWithBandingstateNum = 7;
const int _NucleotideIndel2AlignWithBandingemitNum = 4;
const int _NucleotideIndel2AlignWithBandingtransNum = 23;
const int _NucleotideIndel2AlignWithBandingoutputNum = 2;




bfloat ForwardBanding(NucleotideIndel2AlignWithBandingDPTable** ppOutTable,const std::string& iSequence1,const std::string& iSequence2,const vector<double>& iSingleDistribution,const vector<vector<double> >& iPairDistribution,const vector<vector<double> >& iT,int iWidth) {
    bfloat iTransition[23];
    bfloat *CurStateMemorynucIndel2Block2withbandingTo;
    const bfloat *CurStateMemorynucIndel2Block1From;
    const bfloat *CurStateMemorynucIndel2Block2withbandingFrom;
    bfloat *CurStateMemorynucIndel2Block3To;
    const bfloat *CurStateMemorynucIndel2Block3From;
    int iPrevSlowCoord;
    int iLen1 = iSequence1.size();   // The sequence lengths are not passed as parameters, but are
    int iLen2 = iSequence2.size();   // computed from the vector<char> itself
    
    // indexing for emission probs
    unsigned char iTranslate[256];
    for (int i=0; i<256; i++) {
        iTranslate[i]= 0;
    }
    iTranslate[(unsigned)'A'] = 0;   // It is important that this is in alphabetical order, to
    iTranslate[(unsigned)'a'] = 0;   // make the indices correspond to those used for Baum-Welch
    iTranslate[(unsigned)'C'] = 1;
    iTranslate[(unsigned)'c'] = 1;
    iTranslate[(unsigned)'G'] = 2;
    iTranslate[(unsigned)'g'] = 2;
    iTranslate[(unsigned)'T'] = 3;
    iTranslate[(unsigned)'t'] = 3;
    MyBanding bandingInstance (iSequence1.size(), iSequence2.size(), iWidth);
    int iSymbol[2];
    if (false && iSymbol[0] == iSymbol[0]) {}   // avoid 'unused variable' warnings
    bfloat iEmission[1];
    /* temporary storage for ordinary reals */
    register double iTempResult[1];
    /* temporary storage for extended-exponent reals */
    register bfloat iTempProb[1];
    NucleotideIndel2AlignWithBandingDPTable dp(iLen1,iLen2);
    iTransition[0] = iT[0][1];
    
    iTransition[1] = iT[0][2];
    
    iTransition[2] = iT[0][3];
    
    iTransition[3] = iT[0][4];
    
    iTransition[4] = iT[0][5];
    
    iTransition[5] = iT[1][1];
    
    iTransition[6] = iT[1][2];
    
    iTransition[7] = iT[1][3];
    
    iTransition[8] = iT[1][4];
    
    iTransition[9] = iT[1][5];
    
    iTransition[10] = iT[1][6];
    
    iTransition[11] = iT[2][1];
    
    iTransition[12] = iT[2][2];
    
    iTransition[13] = iT[2][6];
    
    iTransition[14] = iT[3][1];
    
    iTransition[15] = iT[3][3];
    
    iTransition[16] = iT[3][6];
    
    iTransition[17] = iT[4][1];
    
    iTransition[18] = iT[4][4];
    
    iTransition[19] = iT[4][6];
    
    iTransition[20] = iT[5][1];
    
    iTransition[21] = iT[5][5];
    
    iTransition[22] = iT[5][6];
    dp.StateMemorynucIndel2Block1.write()[0] = 1.0;
    dp.StateMemorynucIndel2Block1.written();
    iPrevSlowCoord = -1;
    {
        int iPos1=0;
        if (iPos1==iPos1) {} // avoid 'unused variable' warnings
        {
            int iPos0=0;
            if (iPos0==iPos0) {} // avoid 'unused variable' warnings
            if (1) {
            }
        }
    }
    iPrevSlowCoord = -1;
    {
        Banding<2>::Position& position = bandingInstance.forwardIterator();
        bool bLastSlowCoordInited = false;
        int iLastSlowCoord = -1;  
        do {
            if (bLastSlowCoordInited) {
                if (iLastSlowCoord > position[1]) {
                    cout << "WARNING: Banding (forward): Slowest coordinate should be nondecreasing.  Perhaps forgot to specify speed of output coordinates?" << endl;
                }
                } else {
                bLastSlowCoordInited = true;
            }
            iLastSlowCoord = position[1];
            if ((position[0]+0>=0)&&(position[0]+0<=iLen1+0)&&(position[1]+0>=0)&&(position[1]+0<=iLen2+0)) {
                if (1) {
                    if ((position[1]+-1>=0)) {
                        iSymbol[0] = iSequence2[position[1]+-1];
                    } 
                    else { 
                        iSymbol[0] = 'A' /* dummy value */;
                        
                    }
                    if ((position[0]+-1>=0)) {
                        iSymbol[1] = iSequence1[position[0]+-1];
                    } 
                    else { 
                        iSymbol[1] = 'A' /* dummy value */;
                        
                    }
                    CurStateMemorynucIndel2Block2withbandingTo = dp.StateMemorynucIndel2Block2withbanding.write((position[0]-(0))-(0), (position[1]-(0))-(0));
                    iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[0]]];
                    iEmission[0] = iTempResult[0];
                    if ((position[0]+0<=0)&&(position[1]+-1>=0)&&(position[1]+-1<=0)) {
                        CurStateMemorynucIndel2Block1From = dp.StateMemorynucIndel2Block1.read();
                        CurStateMemorynucIndel2Block2withbandingTo[0] = ((iTransition[4])*(iEmission[0]))*CurStateMemorynucIndel2Block1From[0];
                        CurStateMemorynucIndel2Block2withbandingTo[1] = ((iTransition[2])*(iEmission[0]))*CurStateMemorynucIndel2Block1From[0];
                    }
                    if ((position[1]+-1>=0)) {
                        CurStateMemorynucIndel2Block2withbandingFrom = dp.StateMemorynucIndel2Block2withbanding.read((position[0]-(0))-(0), (position[1]-(1))-(0));
                        CurStateMemorynucIndel2Block2withbandingTo[0] += ((iTransition[9])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[3];
                        CurStateMemorynucIndel2Block2withbandingTo[0] += ((iTransition[21])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[0];
                        CurStateMemorynucIndel2Block2withbandingTo[1] += ((iTransition[7])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[3];
                        CurStateMemorynucIndel2Block2withbandingTo[1] += ((iTransition[15])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[1];
                    }
                    iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[1]]];
                    iEmission[0] = iTempResult[0];
                    if ((position[0]+-1>=0)&&(position[0]+-1<=0)&&(position[1]+0<=0)) {
                        CurStateMemorynucIndel2Block1From = dp.StateMemorynucIndel2Block1.read();
                        CurStateMemorynucIndel2Block2withbandingTo[2] = ((iTransition[1])*(iEmission[0]))*CurStateMemorynucIndel2Block1From[0];
                        CurStateMemorynucIndel2Block2withbandingTo[4] = ((iTransition[3])*(iEmission[0]))*CurStateMemorynucIndel2Block1From[0];
                    }
                    if ((position[0]+-1>=0)) {
                        CurStateMemorynucIndel2Block2withbandingFrom = dp.StateMemorynucIndel2Block2withbanding.read((position[0]-(1))-(0), (position[1]-(0))-(0));
                        CurStateMemorynucIndel2Block2withbandingTo[2] += ((iTransition[12])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[2];
                        CurStateMemorynucIndel2Block2withbandingTo[2] += ((iTransition[6])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[3];
                        CurStateMemorynucIndel2Block2withbandingTo[4] += ((iTransition[8])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[3];
                        CurStateMemorynucIndel2Block2withbandingTo[4] += ((iTransition[18])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[4];
                    }
                    iTempResult[0] = iPairDistribution[iTranslate[iSymbol[1]]][iTranslate[iSymbol[0]]];
                    iEmission[0] = iTempResult[0];
                    if ((position[0]+-1>=0)&&(position[0]+-1<=0)&&(position[1]+-1>=0)&&(position[1]+-1<=0)) {
                        CurStateMemorynucIndel2Block1From = dp.StateMemorynucIndel2Block1.read();
                        CurStateMemorynucIndel2Block2withbandingTo[3] = ((iTransition[0])*(iEmission[0]))*CurStateMemorynucIndel2Block1From[0];
                    }
                    if ((position[0]+-1>=0)&&(position[1]+-1>=0)) {
                        CurStateMemorynucIndel2Block2withbandingFrom = dp.StateMemorynucIndel2Block2withbanding.read((position[0]-(1))-(0), (position[1]-(1))-(0));
                        CurStateMemorynucIndel2Block2withbandingTo[3] += ((iTransition[11])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[2];
                        CurStateMemorynucIndel2Block2withbandingTo[3] += ((iTransition[20])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[0];
                        CurStateMemorynucIndel2Block2withbandingTo[3] += ((iTransition[17])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[4];
                        CurStateMemorynucIndel2Block2withbandingTo[3] += ((iTransition[14])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[1];
                        CurStateMemorynucIndel2Block2withbandingTo[3] += ((iTransition[5])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[3];
                    }
                    dp.StateMemorynucIndel2Block2withbanding.written();
                }
                iPrevSlowCoord = position[1];
            } 
            else { 
                bandingInstance.warning();
                
            }
        } while (bandingInstance.hasNextForward());
    }
    iPrevSlowCoord = -1;
    {
        int iPos1=iLen2+0;
        if (iPos1==iPos1) {} // avoid 'unused variable' warnings
        {
            int iPos0=iLen1+0;
            if (iPos0==iPos0) {} // avoid 'unused variable' warnings
            if (1) {
                CurStateMemorynucIndel2Block3To = dp.StateMemorynucIndel2Block3.write();
                iEmission[0] = 1.0;
                if (1) {
                    CurStateMemorynucIndel2Block2withbandingFrom = dp.StateMemorynucIndel2Block2withbanding.read((iPos0-(0))-(0), (iPos1-(0))-(0));
                    CurStateMemorynucIndel2Block3To[0] = ((iTransition[13])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[2];
                    CurStateMemorynucIndel2Block3To[0] += ((iTransition[22])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[0];
                    CurStateMemorynucIndel2Block3To[0] += ((iTransition[19])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[4];
                    CurStateMemorynucIndel2Block3To[0] += ((iTransition[16])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[1];
                    CurStateMemorynucIndel2Block3To[0] += ((iTransition[10])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[3];
                }
                dp.StateMemorynucIndel2Block3.written();
            }
            iPrevSlowCoord = iPos1;
        }
    }
    iPrevSlowCoord = -1;
    {
        int iPos1=iLen2+0;
        if (iPos1==iPos1) {} // avoid 'unused variable' warnings
        {
            int iPos0=iLen1+0;
            if (iPos0==iPos0) {} // avoid 'unused variable' warnings
            CurStateMemorynucIndel2Block3From = dp.StateMemorynucIndel2Block3.read();
            iTempProb[0] = CurStateMemorynucIndel2Block3From[0];
        }
    }
    *ppOutTable = new NucleotideIndel2AlignWithBandingDPTable(dp);
    // make sure tables don't get deleted
    dp.isInCharge = false;
    return iTempProb[0];
};





bfloat BackwardBaumWelchBanding(NucleotideIndel2AlignWithBandingBaumWelch& bw,NucleotideIndel2AlignWithBandingDPTable* pInTable,const std::string& iSequence1,const std::string& iSequence2,const vector<double>& iSingleDistribution,const vector<vector<double> >& iPairDistribution,const vector<vector<double> >& iT,int iWidth) {
    const bfloat *CurStateMemorynucIndel2Block3Secondary;
    bfloat iTransition[23];
    bfloat *CurStateMemorynucIndel2Block2withbandingTo;
    const bfloat *CurStateMemorynucIndel2Block2withbandingSecondary;
    const bfloat *CurStateMemorynucIndel2Block2withbandingFrom;
    unsigned char alphaSymbolnucleotide[4] = {'A', 'C', 'G', 'T'};
    unsigned char alphaIndexnucleotide[256];
    const bfloat *CurStateMemorynucIndel2Block3From;
    bfloat *CurStateMemorynucIndel2Block1To;
    const bfloat *CurStateMemorynucIndel2Block1Secondary;
    const bfloat *CurStateMemorynucIndel2Block1From;
    int iPrevSlowCoord;
    int iLen1 = iSequence1.size();   // The sequence lengths are not passed as parameters, but are
    int iLen2 = iSequence2.size();   // computed from the vector<char> itself
    
    // indexing for emission probs
    unsigned char iTranslate[256];
    for (int i=0; i<256; i++) {
        iTranslate[i]= 0;
    }
    iTranslate[(unsigned)'A'] = 0;   // It is important that this is in alphabetical order, to
    iTranslate[(unsigned)'a'] = 0;   // make the indices correspond to those used for Baum-Welch
    iTranslate[(unsigned)'C'] = 1;
    iTranslate[(unsigned)'c'] = 1;
    iTranslate[(unsigned)'G'] = 2;
    iTranslate[(unsigned)'g'] = 2;
    iTranslate[(unsigned)'T'] = 3;
    iTranslate[(unsigned)'t'] = 3;
    MyBanding bandingInstance (iSequence1.size(), iSequence2.size(), iWidth);
    int iSymbol[2];
    if (false && iSymbol[0] == iSymbol[0]) {}   // avoid 'unused variable' warnings
    bfloat iEmission[1];
    /* temporary storage for ordinary reals */
    register double iTempResult[1];
    /* temporary storage for extended-exponent reals */
    register bfloat iTempProb[3];
    NucleotideIndel2AlignWithBandingFoldedDPTable dp(iLen1,2);
    NucleotideIndel2AlignWithBandingDPTable dp2(*pInTable);
    // make sure tables don't get deleted
    dp2.isInCharge = false;
    iTransition[0] = iT[0][1];
    
    iTransition[1] = iT[0][2];
    
    iTransition[2] = iT[0][3];
    
    iTransition[3] = iT[0][4];
    
    iTransition[4] = iT[0][5];
    
    iTransition[5] = iT[1][1];
    
    iTransition[6] = iT[1][2];
    
    iTransition[7] = iT[1][3];
    
    iTransition[8] = iT[1][4];
    
    iTransition[9] = iT[1][5];
    
    iTransition[10] = iT[1][6];
    
    iTransition[11] = iT[2][1];
    
    iTransition[12] = iT[2][2];
    
    iTransition[13] = iT[2][6];
    
    iTransition[14] = iT[3][1];
    
    iTransition[15] = iT[3][3];
    
    iTransition[16] = iT[3][6];
    
    iTransition[17] = iT[4][1];
    
    iTransition[18] = iT[4][4];
    
    iTransition[19] = iT[4][6];
    
    iTransition[20] = iT[5][1];
    
    iTransition[21] = iT[5][5];
    
    iTransition[22] = iT[5][6];
    for (int i=0; i<256; i++) {
        alphaIndexnucleotide[i]=0;
    }

//    for (int i=0; i<4; i++) {
//        alphaIndexnucleotide[alphaSymbolnucleotide[i]]=i;
//    }
    for (int i=0; i<4; i++) {
      alphaIndexnucleotide[tolower (alphaSymbolnucleotide[i])] = i;
      alphaIndexnucleotide[toupper (alphaSymbolnucleotide[i])] = i;
    }
    // treat lower and upper-case characters as equivalent during Baum-Welch
    // -- RKB

    dp.StateMemorynucIndel2Block3.write()[0] = 1.0;
    dp.StateMemorynucIndel2Block3.written();
    iPrevSlowCoord = -1;
    {
        int iPos1=iLen2+0;
        if (iPos1==iPos1) {} // avoid 'unused variable' warnings
        {
            int iPos0=iLen1+0;
            if (iPos0==iPos0) {} // avoid 'unused variable' warnings
            CurStateMemorynucIndel2Block3Secondary = dp2.StateMemorynucIndel2Block3.read();
            iTempProb[2] = CurStateMemorynucIndel2Block3Secondary[0];
            bw.scaleCounts(iTempProb[2]);
        }
    }
    iPrevSlowCoord = -1;
    {
        int iPos1=iLen2+0;
        if (iPos1==iPos1) {} // avoid 'unused variable' warnings
        {
            int iPos0=iLen1+0;
            if (iPos0==iPos0) {} // avoid 'unused variable' warnings
            if (1) {
            }
        }
    }
    iPrevSlowCoord = -1;
    {
        Banding<2>::Position& position = bandingInstance.backwardIterator();
        int iCheckSlowCoordTraversal = -1;  
        do {
            if (iCheckSlowCoordTraversal != -1 && iCheckSlowCoordTraversal < position[1]) {
                cout << "WARNING: Banding (backward): Slowest coordinate be nonincreasing.  Perhaps forgot to specify speed of output coordinates?" << endl;
            }
            iCheckSlowCoordTraversal = position[1];
            if ((position[0]+0>=0)&&(position[0]+0<=iLen1+0)&&(position[1]+0>=0)&&(position[1]+0<=iLen2+0)) {
                if (iPrevSlowCoord != -1 && iPrevSlowCoord != position[1]) {
                    dp.StateMemorynucIndel2Block2withbanding.clear(position[1]);
                }
                if (1) {
                    if ((position[1]+0<=iLen2+-1)) {
                        iSymbol[0] = iSequence2[position[1]+0];
                    } 
                    else { 
                        iSymbol[0] = 'A' /* dummy value */;
                        
                    }
                    if ((position[0]+0<=iLen1+-1)) {
                        iSymbol[1] = iSequence1[position[0]+0];
                    } 
                    else { 
                        iSymbol[1] = 'A' /* dummy value */;
                        
                    }
                    CurStateMemorynucIndel2Block2withbandingTo = dp.StateMemorynucIndel2Block2withbanding.write((position[0]-(0))-(0), (position[1]-(0))-(0));
                    CurStateMemorynucIndel2Block2withbandingSecondary = dp2.StateMemorynucIndel2Block2withbanding.read((position[0]-(0))-(0), (position[1]-(0))-(0));
                    iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[0]]];
                    iEmission[0] = iTempResult[0];
                    if ((position[1]+1<=iLen2+0)) {
                        CurStateMemorynucIndel2Block2withbandingFrom = dp.StateMemorynucIndel2Block2withbanding.read((position[0]-(0))-(0), (position[1]-(-1))-(0));
                        CurStateMemorynucIndel2Block2withbandingTo[0] = iTempProb[1] = ((iTransition[21])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[0];
                        iTempProb[1] *= CurStateMemorynucIndel2Block2withbandingSecondary[0];
                        bw.transitionBaumWelchCount00[21] += iTempProb[1];
                        bw.emissionBaumWelchCount01[alphaIndexnucleotide[iSymbol[0]]][0] += iTempProb[1];
                        CurStateMemorynucIndel2Block2withbandingTo[1] = iTempProb[1] = ((iTransition[15])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[1];
                        iTempProb[1] *= CurStateMemorynucIndel2Block2withbandingSecondary[1];
                        bw.transitionBaumWelchCount00[15] += iTempProb[1];
                        bw.emissionBaumWelchCount01[alphaIndexnucleotide[iSymbol[0]]][0] += iTempProb[1];
                        CurStateMemorynucIndel2Block2withbandingTo[3] = iTempProb[1] = ((iTransition[7])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[1];
                        iTempProb[1] *= CurStateMemorynucIndel2Block2withbandingSecondary[3];
                        bw.transitionBaumWelchCount00[7] += iTempProb[1];
                        bw.emissionBaumWelchCount01[alphaIndexnucleotide[iSymbol[0]]][0] += iTempProb[1];
                        CurStateMemorynucIndel2Block2withbandingTo[3] += iTempProb[1] = ((iTransition[9])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[0];
                        iTempProb[1] *= CurStateMemorynucIndel2Block2withbandingSecondary[3];
                        bw.transitionBaumWelchCount00[9] += iTempProb[1];
                        bw.emissionBaumWelchCount01[alphaIndexnucleotide[iSymbol[0]]][0] += iTempProb[1];
                    }
                    iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[1]]];
                    iEmission[0] = iTempResult[0];
                    if ((position[0]+1<=iLen1+0)) {
                        CurStateMemorynucIndel2Block2withbandingFrom = dp.StateMemorynucIndel2Block2withbanding.read((position[0]-(-1))-(0), (position[1]-(0))-(0));
                        CurStateMemorynucIndel2Block2withbandingTo[4] = iTempProb[1] = ((iTransition[18])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[4];
                        iTempProb[1] *= CurStateMemorynucIndel2Block2withbandingSecondary[4];
                        bw.transitionBaumWelchCount00[18] += iTempProb[1];
                        bw.emissionBaumWelchCount10[alphaIndexnucleotide[iSymbol[1]]][0] += iTempProb[1];
                        CurStateMemorynucIndel2Block2withbandingTo[3] += iTempProb[1] = ((iTransition[6])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[2];
                        iTempProb[1] *= CurStateMemorynucIndel2Block2withbandingSecondary[3];
                        bw.transitionBaumWelchCount00[6] += iTempProb[1];
                        bw.emissionBaumWelchCount10[alphaIndexnucleotide[iSymbol[1]]][0] += iTempProb[1];
                        CurStateMemorynucIndel2Block2withbandingTo[3] += iTempProb[1] = ((iTransition[8])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[4];
                        iTempProb[1] *= CurStateMemorynucIndel2Block2withbandingSecondary[3];
                        bw.transitionBaumWelchCount00[8] += iTempProb[1];
                        bw.emissionBaumWelchCount10[alphaIndexnucleotide[iSymbol[1]]][0] += iTempProb[1];
                        CurStateMemorynucIndel2Block2withbandingTo[2] = iTempProb[1] = ((iTransition[12])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[2];
                        iTempProb[1] *= CurStateMemorynucIndel2Block2withbandingSecondary[2];
                        bw.transitionBaumWelchCount00[12] += iTempProb[1];
                        bw.emissionBaumWelchCount10[alphaIndexnucleotide[iSymbol[1]]][0] += iTempProb[1];
                    }
                    iTempResult[0] = iPairDistribution[iTranslate[iSymbol[1]]][iTranslate[iSymbol[0]]];
                    iEmission[0] = iTempResult[0];
                    if ((position[0]+1<=iLen1+0)&&(position[1]+1<=iLen2+0)) {
                        CurStateMemorynucIndel2Block2withbandingFrom = dp.StateMemorynucIndel2Block2withbanding.read((position[0]-(-1))-(0), (position[1]-(-1))-(0));
                        CurStateMemorynucIndel2Block2withbandingTo[3] += iTempProb[1] = ((iTransition[5])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[3];
                        iTempProb[1] *= CurStateMemorynucIndel2Block2withbandingSecondary[3];
                        bw.transitionBaumWelchCount00[5] += iTempProb[1];
                        bw.emissionBaumWelchCount11[alphaIndexnucleotide[iSymbol[1]]][alphaIndexnucleotide[iSymbol[0]]][0] += iTempProb[1];
                        CurStateMemorynucIndel2Block2withbandingTo[0] += iTempProb[1] = ((iTransition[20])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[3];
                        iTempProb[1] *= CurStateMemorynucIndel2Block2withbandingSecondary[0];
                        bw.transitionBaumWelchCount00[20] += iTempProb[1];
                        bw.emissionBaumWelchCount11[alphaIndexnucleotide[iSymbol[1]]][alphaIndexnucleotide[iSymbol[0]]][0] += iTempProb[1];
                        CurStateMemorynucIndel2Block2withbandingTo[1] += iTempProb[1] = ((iTransition[14])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[3];
                        iTempProb[1] *= CurStateMemorynucIndel2Block2withbandingSecondary[1];
                        bw.transitionBaumWelchCount00[14] += iTempProb[1];
                        bw.emissionBaumWelchCount11[alphaIndexnucleotide[iSymbol[1]]][alphaIndexnucleotide[iSymbol[0]]][0] += iTempProb[1];
                        CurStateMemorynucIndel2Block2withbandingTo[2] += iTempProb[1] = ((iTransition[11])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[3];
                        iTempProb[1] *= CurStateMemorynucIndel2Block2withbandingSecondary[2];
                        bw.transitionBaumWelchCount00[11] += iTempProb[1];
                        bw.emissionBaumWelchCount11[alphaIndexnucleotide[iSymbol[1]]][alphaIndexnucleotide[iSymbol[0]]][0] += iTempProb[1];
                        CurStateMemorynucIndel2Block2withbandingTo[4] += iTempProb[1] = ((iTransition[17])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[3];
                        iTempProb[1] *= CurStateMemorynucIndel2Block2withbandingSecondary[4];
                        bw.transitionBaumWelchCount00[17] += iTempProb[1];
                        bw.emissionBaumWelchCount11[alphaIndexnucleotide[iSymbol[1]]][alphaIndexnucleotide[iSymbol[0]]][0] += iTempProb[1];
                    }
                    iEmission[0] = 1.0;
                    if ((position[0]+0>=iLen1+0)&&(position[1]+0>=iLen2+0)) {
                        CurStateMemorynucIndel2Block3From = dp.StateMemorynucIndel2Block3.read();
                        CurStateMemorynucIndel2Block2withbandingTo[3] += iTempProb[1] = ((iTransition[10])*(iEmission[0]))*CurStateMemorynucIndel2Block3From[0];
                        iTempProb[1] *= CurStateMemorynucIndel2Block2withbandingSecondary[3];
                        bw.transitionBaumWelchCount00[10] += iTempProb[1];
                        bw.emissionBaumWelchCount00[0] += iTempProb[1];
                        CurStateMemorynucIndel2Block2withbandingTo[0] += iTempProb[1] = ((iTransition[22])*(iEmission[0]))*CurStateMemorynucIndel2Block3From[0];
                        iTempProb[1] *= CurStateMemorynucIndel2Block2withbandingSecondary[0];
                        bw.transitionBaumWelchCount00[22] += iTempProb[1];
                        bw.emissionBaumWelchCount00[0] += iTempProb[1];
                        CurStateMemorynucIndel2Block2withbandingTo[1] += iTempProb[1] = ((iTransition[16])*(iEmission[0]))*CurStateMemorynucIndel2Block3From[0];
                        iTempProb[1] *= CurStateMemorynucIndel2Block2withbandingSecondary[1];
                        bw.transitionBaumWelchCount00[16] += iTempProb[1];
                        bw.emissionBaumWelchCount00[0] += iTempProb[1];
                        CurStateMemorynucIndel2Block2withbandingTo[2] += iTempProb[1] = ((iTransition[13])*(iEmission[0]))*CurStateMemorynucIndel2Block3From[0];
                        iTempProb[1] *= CurStateMemorynucIndel2Block2withbandingSecondary[2];
                        bw.transitionBaumWelchCount00[13] += iTempProb[1];
                        bw.emissionBaumWelchCount00[0] += iTempProb[1];
                        CurStateMemorynucIndel2Block2withbandingTo[4] += iTempProb[1] = ((iTransition[19])*(iEmission[0]))*CurStateMemorynucIndel2Block3From[0];
                        iTempProb[1] *= CurStateMemorynucIndel2Block2withbandingSecondary[4];
                        bw.transitionBaumWelchCount00[19] += iTempProb[1];
                        bw.emissionBaumWelchCount00[0] += iTempProb[1];
                    }
                    dp.StateMemorynucIndel2Block2withbanding.written();
                }
                iPrevSlowCoord = position[1];
            } 
            else { 
                bandingInstance.warning();
                
            }
        } while (bandingInstance.hasNextBackward());
    }
    iPrevSlowCoord = -1;
    {
        int iPos1=0;
        if (iPos1==iPos1) {} // avoid 'unused variable' warnings
        {
            int iPos0=0;
            if (iPos0==iPos0) {} // avoid 'unused variable' warnings
            if (1) {
                if ((iPos1+0<=iLen2+-1)) {
                    iSymbol[0] = iSequence2[iPos1+0];
                } 
                else { 
                    iSymbol[0] = 'A' /* dummy value */;
                    
                }
                if ((iPos0+0<=iLen1+-1)) {
                    iSymbol[1] = iSequence1[iPos0+0];
                } 
                else { 
                    iSymbol[1] = 'A' /* dummy value */;
                    
                }
                CurStateMemorynucIndel2Block1To = dp.StateMemorynucIndel2Block1.write();
                CurStateMemorynucIndel2Block1Secondary = dp2.StateMemorynucIndel2Block1.read();
                iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[0]]];
                iEmission[0] = iTempResult[0];
                if ((iPos1+1<=iLen2+0)) {
                    CurStateMemorynucIndel2Block2withbandingFrom = dp.StateMemorynucIndel2Block2withbanding.read((iPos0-(0))-(0), (iPos1-(-1))-(0));
                    CurStateMemorynucIndel2Block1To[0] = iTempProb[1] = ((iTransition[2])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[1];
                    iTempProb[1] *= CurStateMemorynucIndel2Block1Secondary[0];
                    bw.transitionBaumWelchCount00[2] += iTempProb[1];
                    bw.emissionBaumWelchCount01[alphaIndexnucleotide[iSymbol[0]]][0] += iTempProb[1];
                    CurStateMemorynucIndel2Block1To[0] += iTempProb[1] = ((iTransition[4])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[0];
                    iTempProb[1] *= CurStateMemorynucIndel2Block1Secondary[0];
                    bw.transitionBaumWelchCount00[4] += iTempProb[1];
                    bw.emissionBaumWelchCount01[alphaIndexnucleotide[iSymbol[0]]][0] += iTempProb[1];
                }
                iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[1]]];
                iEmission[0] = iTempResult[0];
                if ((iPos0+1<=iLen1+0)) {
                    CurStateMemorynucIndel2Block2withbandingFrom = dp.StateMemorynucIndel2Block2withbanding.read((iPos0-(-1))-(0), (iPos1-(0))-(0));
                    CurStateMemorynucIndel2Block1To[0] += iTempProb[1] = ((iTransition[1])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[2];
                    iTempProb[1] *= CurStateMemorynucIndel2Block1Secondary[0];
                    bw.transitionBaumWelchCount00[1] += iTempProb[1];
                    bw.emissionBaumWelchCount10[alphaIndexnucleotide[iSymbol[1]]][0] += iTempProb[1];
                    CurStateMemorynucIndel2Block1To[0] += iTempProb[1] = ((iTransition[3])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[4];
                    iTempProb[1] *= CurStateMemorynucIndel2Block1Secondary[0];
                    bw.transitionBaumWelchCount00[3] += iTempProb[1];
                    bw.emissionBaumWelchCount10[alphaIndexnucleotide[iSymbol[1]]][0] += iTempProb[1];
                }
                iTempResult[0] = iPairDistribution[iTranslate[iSymbol[1]]][iTranslate[iSymbol[0]]];
                iEmission[0] = iTempResult[0];
                if ((iPos0+1<=iLen1+0)&&(iPos1+1<=iLen2+0)) {
                    CurStateMemorynucIndel2Block2withbandingFrom = dp.StateMemorynucIndel2Block2withbanding.read((iPos0-(-1))-(0), (iPos1-(-1))-(0));
                    CurStateMemorynucIndel2Block1To[0] += iTempProb[1] = ((iTransition[0])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[3];
                    iTempProb[1] *= CurStateMemorynucIndel2Block1Secondary[0];
                    bw.transitionBaumWelchCount00[0] += iTempProb[1];
                    bw.emissionBaumWelchCount11[alphaIndexnucleotide[iSymbol[1]]][alphaIndexnucleotide[iSymbol[0]]][0] += iTempProb[1];
                }
                dp.StateMemorynucIndel2Block1.written();
            }
            iPrevSlowCoord = iPos1;
        }
    }
    bw.scaleCounts(1.0 / iTempProb[2]);
    iPrevSlowCoord = -1;
    {
        int iPos1=0;
        if (iPos1==iPos1) {} // avoid 'unused variable' warnings
        {
            int iPos0=0;
            if (iPos0==iPos0) {} // avoid 'unused variable' warnings
            CurStateMemorynucIndel2Block1From = dp.StateMemorynucIndel2Block1.read();
            iTempProb[0] = CurStateMemorynucIndel2Block1From[0];
        }
    }
    return iTempProb[0];
};





bfloat BackwardBanding(NucleotideIndel2AlignWithBandingDPTable** ppOutTable,const std::string& iSequence1,const std::string& iSequence2,const vector<double>& iSingleDistribution,const vector<vector<double> >& iPairDistribution,const vector<vector<double> >& iT,int iWidth) {
    bfloat iTransition[23];
    bfloat *CurStateMemorynucIndel2Block2withbandingTo;
    const bfloat *CurStateMemorynucIndel2Block2withbandingFrom;
    const bfloat *CurStateMemorynucIndel2Block3From;
    bfloat *CurStateMemorynucIndel2Block1To;
    const bfloat *CurStateMemorynucIndel2Block1From;
    int iPrevSlowCoord;
    int iLen1 = iSequence1.size();   // The sequence lengths are not passed as parameters, but are
    int iLen2 = iSequence2.size();   // computed from the vector<char> itself
    
    // indexing for emission probs
    unsigned char iTranslate[256];
    for (int i=0; i<256; i++) {
        iTranslate[i]= 0;
    }
    iTranslate[(unsigned)'A'] = 0;   // It is important that this is in alphabetical order, to
    iTranslate[(unsigned)'a'] = 0;   // make the indices correspond to those used for Baum-Welch
    iTranslate[(unsigned)'C'] = 1;
    iTranslate[(unsigned)'c'] = 1;
    iTranslate[(unsigned)'G'] = 2;
    iTranslate[(unsigned)'g'] = 2;
    iTranslate[(unsigned)'T'] = 3;
    iTranslate[(unsigned)'t'] = 3;
    MyBanding bandingInstance (iSequence1.size(), iSequence2.size(), iWidth);
    int iSymbol[2];
    if (false && iSymbol[0] == iSymbol[0]) {}   // avoid 'unused variable' warnings
    bfloat iEmission[1];
    /* temporary storage for ordinary reals */
    register double iTempResult[1];
    /* temporary storage for extended-exponent reals */
    register bfloat iTempProb[1];
    NucleotideIndel2AlignWithBandingDPTable dp(iLen1,iLen2);
    iTransition[0] = iT[0][1];
    
    iTransition[1] = iT[0][2];
    
    iTransition[2] = iT[0][3];
    
    iTransition[3] = iT[0][4];
    
    iTransition[4] = iT[0][5];
    
    iTransition[5] = iT[1][1];
    
    iTransition[6] = iT[1][2];
    
    iTransition[7] = iT[1][3];
    
    iTransition[8] = iT[1][4];
    
    iTransition[9] = iT[1][5];
    
    iTransition[10] = iT[1][6];
    
    iTransition[11] = iT[2][1];
    
    iTransition[12] = iT[2][2];
    
    iTransition[13] = iT[2][6];
    
    iTransition[14] = iT[3][1];
    
    iTransition[15] = iT[3][3];
    
    iTransition[16] = iT[3][6];
    
    iTransition[17] = iT[4][1];
    
    iTransition[18] = iT[4][4];
    
    iTransition[19] = iT[4][6];
    
    iTransition[20] = iT[5][1];
    
    iTransition[21] = iT[5][5];
    
    iTransition[22] = iT[5][6];
    dp.StateMemorynucIndel2Block3.write()[0] = 1.0;
    dp.StateMemorynucIndel2Block3.written();
    iPrevSlowCoord = -1;
    {
        int iPos1=iLen2+0;
        if (iPos1==iPos1) {} // avoid 'unused variable' warnings
        {
            int iPos0=iLen1+0;
            if (iPos0==iPos0) {} // avoid 'unused variable' warnings
            if (1) {
            }
        }
    }
    iPrevSlowCoord = -1;
    {
        Banding<2>::Position& position = bandingInstance.backwardIterator();
        int iCheckSlowCoordTraversal = -1;  
        do {
            if (iCheckSlowCoordTraversal != -1 && iCheckSlowCoordTraversal < position[1]) {
                cout << "WARNING: Banding (backward): Slowest coordinate be nonincreasing.  Perhaps forgot to specify speed of output coordinates?" << endl;
            }
            iCheckSlowCoordTraversal = position[1];
            if ((position[0]+0>=0)&&(position[0]+0<=iLen1+0)&&(position[1]+0>=0)&&(position[1]+0<=iLen2+0)) {
                if (1) {
                    if ((position[1]+0<=iLen2+-1)) {
                        iSymbol[0] = iSequence2[position[1]+0];
                    } 
                    else { 
                        iSymbol[0] = 'A' /* dummy value */;
                        
                    }
                    if ((position[0]+0<=iLen1+-1)) {
                        iSymbol[1] = iSequence1[position[0]+0];
                    } 
                    else { 
                        iSymbol[1] = 'A' /* dummy value */;
                        
                    }
                    CurStateMemorynucIndel2Block2withbandingTo = dp.StateMemorynucIndel2Block2withbanding.write((position[0]-(0))-(0), (position[1]-(0))-(0));
                    iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[0]]];
                    iEmission[0] = iTempResult[0];
                    if ((position[1]+1<=iLen2+0)) {
                        CurStateMemorynucIndel2Block2withbandingFrom = dp.StateMemorynucIndel2Block2withbanding.read((position[0]-(0))-(0), (position[1]-(-1))-(0));
                        CurStateMemorynucIndel2Block2withbandingTo[3] = ((iTransition[9])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[0];
                        CurStateMemorynucIndel2Block2withbandingTo[3] += ((iTransition[7])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[1];
                        CurStateMemorynucIndel2Block2withbandingTo[0] = ((iTransition[21])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[0];
                        CurStateMemorynucIndel2Block2withbandingTo[1] = ((iTransition[15])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[1];
                    }
                    iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[1]]];
                    iEmission[0] = iTempResult[0];
                    if ((position[0]+1<=iLen1+0)) {
                        CurStateMemorynucIndel2Block2withbandingFrom = dp.StateMemorynucIndel2Block2withbanding.read((position[0]-(-1))-(0), (position[1]-(0))-(0));
                        CurStateMemorynucIndel2Block2withbandingTo[3] += ((iTransition[6])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[2];
                        CurStateMemorynucIndel2Block2withbandingTo[3] += ((iTransition[8])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[4];
                        CurStateMemorynucIndel2Block2withbandingTo[2] = ((iTransition[12])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[2];
                        CurStateMemorynucIndel2Block2withbandingTo[4] = ((iTransition[18])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[4];
                    }
                    iTempResult[0] = iPairDistribution[iTranslate[iSymbol[1]]][iTranslate[iSymbol[0]]];
                    iEmission[0] = iTempResult[0];
                    if ((position[0]+1<=iLen1+0)&&(position[1]+1<=iLen2+0)) {
                        CurStateMemorynucIndel2Block2withbandingFrom = dp.StateMemorynucIndel2Block2withbanding.read((position[0]-(-1))-(0), (position[1]-(-1))-(0));
                        CurStateMemorynucIndel2Block2withbandingTo[3] += ((iTransition[5])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[3];
                        CurStateMemorynucIndel2Block2withbandingTo[0] += ((iTransition[20])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[3];
                        CurStateMemorynucIndel2Block2withbandingTo[2] += ((iTransition[11])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[3];
                        CurStateMemorynucIndel2Block2withbandingTo[1] += ((iTransition[14])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[3];
                        CurStateMemorynucIndel2Block2withbandingTo[4] += ((iTransition[17])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[3];
                    }
                    iEmission[0] = 1.0;
                    if ((position[0]+0>=iLen1+0)&&(position[1]+0>=iLen2+0)) {
                        CurStateMemorynucIndel2Block3From = dp.StateMemorynucIndel2Block3.read();
                        CurStateMemorynucIndel2Block2withbandingTo[3] += ((iTransition[10])*(iEmission[0]))*CurStateMemorynucIndel2Block3From[0];
                        CurStateMemorynucIndel2Block2withbandingTo[0] += ((iTransition[22])*(iEmission[0]))*CurStateMemorynucIndel2Block3From[0];
                        CurStateMemorynucIndel2Block2withbandingTo[2] += ((iTransition[13])*(iEmission[0]))*CurStateMemorynucIndel2Block3From[0];
                        CurStateMemorynucIndel2Block2withbandingTo[1] += ((iTransition[16])*(iEmission[0]))*CurStateMemorynucIndel2Block3From[0];
                        CurStateMemorynucIndel2Block2withbandingTo[4] += ((iTransition[19])*(iEmission[0]))*CurStateMemorynucIndel2Block3From[0];
                    }
                    dp.StateMemorynucIndel2Block2withbanding.written();
                }
                iPrevSlowCoord = position[1];
            } 
            else { 
                bandingInstance.warning();
                
            }
        } while (bandingInstance.hasNextBackward());
    }
    iPrevSlowCoord = -1;
    {
        int iPos1=0;
        if (iPos1==iPos1) {} // avoid 'unused variable' warnings
        {
            int iPos0=0;
            if (iPos0==iPos0) {} // avoid 'unused variable' warnings
            if (1) {
                if ((iPos1+0<=iLen2+-1)) {
                    iSymbol[0] = iSequence2[iPos1+0];
                } 
                else { 
                    iSymbol[0] = 'A' /* dummy value */;
                    
                }
                if ((iPos0+0<=iLen1+-1)) {
                    iSymbol[1] = iSequence1[iPos0+0];
                } 
                else { 
                    iSymbol[1] = 'A' /* dummy value */;
                    
                }
                CurStateMemorynucIndel2Block1To = dp.StateMemorynucIndel2Block1.write();
                iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[0]]];
                iEmission[0] = iTempResult[0];
                if ((iPos1+1<=iLen2+0)) {
                    CurStateMemorynucIndel2Block2withbandingFrom = dp.StateMemorynucIndel2Block2withbanding.read((iPos0-(0))-(0), (iPos1-(-1))-(0));
                    CurStateMemorynucIndel2Block1To[0] = ((iTransition[4])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[0];
                    CurStateMemorynucIndel2Block1To[0] += ((iTransition[2])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[1];
                }
                iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[1]]];
                iEmission[0] = iTempResult[0];
                if ((iPos0+1<=iLen1+0)) {
                    CurStateMemorynucIndel2Block2withbandingFrom = dp.StateMemorynucIndel2Block2withbanding.read((iPos0-(-1))-(0), (iPos1-(0))-(0));
                    CurStateMemorynucIndel2Block1To[0] += ((iTransition[1])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[2];
                    CurStateMemorynucIndel2Block1To[0] += ((iTransition[3])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[4];
                }
                iTempResult[0] = iPairDistribution[iTranslate[iSymbol[1]]][iTranslate[iSymbol[0]]];
                iEmission[0] = iTempResult[0];
                if ((iPos0+1<=iLen1+0)&&(iPos1+1<=iLen2+0)) {
                    CurStateMemorynucIndel2Block2withbandingFrom = dp.StateMemorynucIndel2Block2withbanding.read((iPos0-(-1))-(0), (iPos1-(-1))-(0));
                    CurStateMemorynucIndel2Block1To[0] += ((iTransition[0])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[3];
                }
                dp.StateMemorynucIndel2Block1.written();
            }
            iPrevSlowCoord = iPos1;
        }
    }
    iPrevSlowCoord = -1;
    {
        int iPos1=0;
        if (iPos1==iPos1) {} // avoid 'unused variable' warnings
        {
            int iPos0=0;
            if (iPos0==iPos0) {} // avoid 'unused variable' warnings
            CurStateMemorynucIndel2Block1From = dp.StateMemorynucIndel2Block1.read();
            iTempProb[0] = CurStateMemorynucIndel2Block1From[0];
        }
    }
    *ppOutTable = new NucleotideIndel2AlignWithBandingDPTable(dp);
    // make sure tables don't get deleted
    dp.isInCharge = false;
    return iTempProb[0];
};



/* --- end of HMMoC-generated file --- */
