@Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < mTokens.size(); ++i)
            sb.append("token[" + i + "]=" + mTokens.get(i) + "\n");
        sb.append("\n");
        for (int k = 0; k < mTags.size(); ++k)
            sb.append("tag[" + k + "]=" + mTags.get(k) + "\n");
        sb.append("\nlogZ=" + logZ() + "\n");
        sb.append("\nlogFwd[token][tag]\n");
        for (int i = 0; i < mTokens.size(); ++i)
            for (int k = 0; k < mTags.size(); ++k)
                sb.append("logFwd[" + i + "][" + k + "]=" + logForward(i,k) + "\n");
        sb.append("\nlogBk[token][tag]\n");
        for (int i = 0; i < mTokens.size(); ++i)
            for (int k = 0; k < mTags.size(); ++k)
                sb.append("logBk[" + i + "][" + k + "]=" + logBackward(i,k) + "\n");
        sb.append("\nlogTrans[tokenFrom][tagFrom][tagTo]\n");
        for (int i = 1; i < mTokens.size(); ++i)
            for (int kFrom = 0; kFrom < mTags.size(); ++kFrom)
                for (int kTo = 0; kTo < mTags.size(); ++kTo)
                    sb.append("logTrans[" + (i-1) + "][" + kFrom + "][" + kTo + "]=" + logTransition(i-1,kFrom,kTo) + "\n");
        
        return sb.toString();
    }