⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dynamic.txt

📁 mfold
💻 TXT
📖 第 1 页 / 共 2 页
字号:

#define minloop 3 //The minimum substructure with a basepair possible


//This is the dynamic algorithm of Zuker:
void dynamic(structure* ct, datatable* data, int cntrl6, int cntrl8, int cntrl9,
	     TProgressDialog* update, char* save)
{

  //cout << "2!!!"<<flush;

  //int **v, **w,
  int vmin, d, ip, jp, ii, jj;
  int e[6], i;
  int k, j, l, m, n, o, p;
  int inc[6][6]={{0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 1, 0}, {0, 0, 0, 1, 0, 0}, {0, 0, 1, 0, 1, 0},
		 {0, 1, 0, 1, 0, 0}, {0, 0, 0, 0, 0, 0}};
  bool *lfce; //[maxbases+1][maxbases+1];
  int before, after, key;
  int **fce;
  int **work = NULL, **work2 = NULL;
  int *w5, *w3, **wmb, **wmb2 = NULL;
  register int number, jmt;
  output convert;

  //array *v, *w;
  //inc is an array that saves time by showing which bases can pair before
  //	erg is called

  //number is the number of bases being folded
  //v[i][j] is the best energy for subsequence i to j when i and j are paired
  //w[i][j] is the best energy for subsequence i to j

  number = (ct->numofbases); //place the number of bases in a registered integer
  key = 0;
  //w = new array(number);
  //v = new array(number);


  //////////////////
  //cout << "preallocate\n";



  arrayclass w(number);
  arrayclass v(number);

  //add a second array for intermolecular folding:
  arrayclass *w2 = NULL;
  if (ct->intermolecular) {
    w2 = new arrayclass(number);
    work2 = new int *[2*number+3];
    wmb2 = new int *[2*number+3];
    for (i=0; i<2*number+3; i++) {
      work2[i] = new int [3];
      wmb2[i] = new int [3];
      for (j=0; j<=2; j++) wmb2[i][j] = infinity;
    }

  }


  fce = new int *[2*number+1];
  for (i=0; i<=2*number; i++)
    fce[i] = new int [2*number + 1];

  for (i=1; i<=2*number; i++) {
    for (j=1; j<=2*number; j++) {
      fce[i][j] = 0;
    }
  }


  lfce = new bool [2*number+1];

  for (i=0; i<=2*number; i++) lfce[i] = false;




  work = new int *[2*number+3];
  wmb = new int *[2*number+3];
  for (i=0; i<2*number+3; i++) {
    work[i] = new int [3];
    wmb[i] = new int [3];
    for (j=0; j<=2; j++) wmb[i][j] = infinity;
  }




  w5 = new int [number+1];
  w3 = new int [number+2];

  for (i=0; i<=number; i++) {
    w5[i] = 0;
    w3[i] = 0;
  }
  w3[number+1] = 0;



  force(ct, &v, fce, lfce);


  //This is the fill routine:


  vmin=infinity;
  for (j=1; j<=(2*(number)-1); j++) {

    if (((j%10)==0)&&update) update->update((100*j)/(2*ct->numofbases));

    for (i=min(j, number); i>=max(1, j-(number)+1); i--) {

      //debug
      //if(i==25&&j==26) {
      // 	v.f(0, 0) = 0;
      //}


      wmb[i][j%3] = infinity;

      if (ct->templated) {
   	if (i>ct->numofbases) ii = i - ct->numofbases;
	else ii = i;
	if (j>ct->numofbases) jj = j - ct->numofbases;
	else jj = j;
	if (jj<ii) {
	  p = jj;
	  jj = ii;
	  ii = p;
	}
   	if (!ct->tem[jj][ii]) goto sub2;
      }

      //Compute v[i][j], the minimum energy of the substructure from i to j,
      //inclusive, where i and j are base paired

      //if fce[i][j] = 1 or 3, these need to be set to infinity
      //	because 1 indicates one of the bases should be single-stranded
      //		and 3 indicates one of the bases needs to be paired to a different base

      if (v.f(i, j)==1) {
	v.f(i, j) = infinity + 50;
	goto sub2;
      }
      if (v.f(i, j)==3) {
   	v.f(i, j)= infinity+50;
	//w[i][j]= infinity;
	goto sub3;
      }
      if (v.f(i, j)==2) {//forcing a pair between i and j
   	key = 2;
      }

      //v[i][j] = infinity; //added 8/18/97


      if (j<=(number)) {
	if ((j-i)<=minloop) goto sub3;
      }
      else {
	if (i==(number)||j==((number)+1)) goto sub1;
      }

      if (inc[ct->numseq[i]][ct->numseq[j]]==0) goto sub2;
      //force u's into gu pairs
      for (ip=0; ip<ct->ngu; ip++) {
   	if (ct->gu[ip]==i) {
	  if (ct->numseq[j]!=3) {
	    v.f(i, j) = infinity;
	    goto sub2;
	  }
	}
	//else if ((ct->gu[ip]+number)==i) {
	// 	if (ct->numseq[j]!=3) {
	//   	v.f(i, j) = infinity;
	//      goto sub2;
	//   }
	//}
	else if (ct->gu[ip]==j) {
	  if (ct->numseq[i]!=3) {
	    v.f(i, j) = infinity;
	    goto sub2;
	  }
	}
	else if ((ct->gu[ip]+number)==j) {
	  if (ct->numseq[i]!=3) {
	    v.f(i, j) = infinity;
            goto sub2;
	  }
	}

      }

      //now check to make sure that this isn't an isolated pair:
      //	(consider a pair separated by a bulge as not! stacked)

      //before = 0 if a stacked pair cannot form 5' to i
      if (i>1&&j<(2*number)) {
	before = inc[ct->numseq[i-1]][ct->numseq[j+1]];
	//		What follows is to allow a bulge
	//		if (before == 0) {
	//			if (i>2) {if (incp[ct->numseq[i-2]][ct->numseq[j+1]]==1) before = 1; }
	//			else if (j-1<(2*number)) {if (incp[ct->numseq[i-1]][ct->numseq[j+2]]==1) before = 1; }
	//		}
      }
      else before = 0;

      //after = 0 if a stacked pair cannot form 3' to i
      if ((j-i)>5) {
	after = inc[ct->numseq[i+1]][ct->numseq[j-1]];
	//		What follows is to allow a bulge
	//		if (after == 0) {
	//			if ((incp[ct->numseq[i+2]][ct->numseq[j-1]]==1)&&((j-i)>6)) after = 1;
	//			else if ((incp[ct->numseq[i+1]][ct->numseq[j-2]]==1)&&((j-i)>6)) after = 1;
	//		}
      }
      else after = 0;

      //if there are no stackable pairs to i.j then don't allow a pair i, j
      if ((before==0)&&(after==0)) {
	goto sub2;
      }


      //Perhaps i and j close a hairpin:
      v.f(i, j)=min(v.f(i, j), erg3(i, j, ct, data, fce[i][j]));

      if ((j-i-1)>=(minloop+2)||j>(number))
      	//Perhaps i, j stacks over i+1, j-1
	v.f(i, j)=min(v.f(i, j), (erg1(i, j, i+1, j-1, ct, data)+v.f(i+1, j-1)));
      //Perhaps i, j closes an interior or bulge loop, search for the best
      //possibility
      if (((j-i-1)>=(minloop+3))||(j>(number))) {
      	for (d=(j-i-3); d>=1; d--) {
	  for (ip=(i+1); ip<=(j-1-d); ip++) {
	    jp = d+ip;
	    if ((j-i-2-d)>(data->eparam[7])) goto sub1;
	    if (abs(ip-i+jp-j)<=(data->eparam[8])) {
	      if (ip>(number)) {
		//if (jp<=number) {

		//	v.f(i, j)=min(v.f(i, j), (erg2(i, j, ip, jp, ct, data, fce[i][ip-number],
		//		fce[jp][j])+
		//		v.f(ip-(number), jp)));

		//}
		//else {
		v.f(i, j)=min(v.f(i, j), (erg2(i, j, ip, jp, ct, data, fce[i][ip-number],
					    fce[jp-number][j-number])+
				       v.f(ip-(number), jp-(number))));
		//}
	      }
	      else {
		if (jp<=number) {

		  v.f(i, j)=min(v.f(i, j), (erg2(i, j, ip, jp, ct, data, fce[i][ip],
					      fce[jp][j])+
					 v.f(ip, jp)));
		}
		else {

		  v.f(i, j)=min(v.f(i, j), (erg2(i, j, ip, jp, ct, data, fce[i][ip],
					      fce[jp-number][j-number])+
					 v.f(ip, jp)));

		}
	      }
	    }
	  }
	}
      }

      //Perhaps i, j closes a multi-loop, search for the best possibility

    sub1:

      if (((j-i-1)>=(2*minloop+4))||(j>(number))) {
	for (ii=1; ii<=4; ii++) e[ii]=infinity;

	if (j>number) {
	  e[1] = w3[i+1] + w5[j-number-1] + penalty(i, j, ct, data);
	  //if (e[1]==-1204) {
	  //    	v.f(0, 0) = 0;
	  //}


	  if (i!=number) e[2] = erg4(i, j, i+1, 1, ct, data, lfce[i+1]) + penalty(i, j, ct, data)+w3[i+2] + w5[j-number-1];
	  if (j!=(number+1)) e[3] = erg4(i, j, j-1, 2, ct, data, lfce[j-1]) +penalty(i, j, ct, data)+ w3[i+1] + w5[j-number-2];
	  if ((i!=number)&&(j!=(number+1))) {
	    e[4] = erg4(i, j, i+1, 1, ct, data, lfce[i+1]) +
	      erg4(i, j, j-1, 2, ct, data, lfce[j-1]) + w3[i+2] + w5[j-number-2]
	      +penalty(i, j, ct, data);

	  }
	}




	if ((j-i)>(2*minloop+4)) {
	  //no dangling ends on i-j pair:
	  e[1] = min(e[1], wmb[i+1][(j-1)%3]+data->eparam[5]+data->eparam[10]
		     + penalty(i, j, ct, data));


	  //i+1 dangles on i-j pair:
	  if (i!=number) e[2] = min(e[2], erg4(i, j, i+1, 1, ct, data, lfce[i+1]) + penalty(i, j, ct, data) +
				    wmb[i+2][(j-1)%3] + data->eparam[5] + data->eparam[6] + data->eparam[10]);
	  //j-1 dangles
	  if (j!=(number+1)) e[3] = min(e[3], erg4(i, j, j-1, 2, ct, data, lfce[j-1]) + penalty(i, j, ct, data) +
					wmb[i+1][(j-2)%3] + data->eparam[5] + data->eparam[6] + data->eparam[10]);
	  //both i+1 and j-1 dangle
	  if ((i!=number)&&(j!=(number+1))) {
	    e[4] = min(e[4],
		       erg4(i, j, i+1, 1, ct, data, lfce[i+1]) +  erg4(i, j, j-1, 2, ct, data, lfce[j-1]) +
		       wmb[i+2][(j-2)%3] + data->eparam[5] + 2*data->eparam[6] + data->eparam[10]
		       +penalty(i, j, ct, data));

	  }

	  if (ct->intermolecular) {

	    //intermolecular, so consider wmb2,
	    //don't add the multiloop penalties because this is a exterior loop

	    e[1] = min(e[1], wmb2[i+1][(j-1)%3]
		       + penalty(i, j, ct, data));


	    //i+1 dangles on i-j pair:
	    if (i!=number) e[2] = min(e[2], erg4(i, j, i+1, 1, ct, data, lfce[i+1]) + penalty(i, j, ct, data) +
				      wmb2[i+2][(j-1)%3]);
	    //j-1 dangles
	    if (j!=(number+1)) e[3] = min(e[3], erg4(i, j, j-1, 2, ct, data, lfce[j-1]) + penalty(i, j, ct, data) +
					  wmb2[i+1][(j-2)%3] );
	    //both i+1 and j-1 dangle
	    if ((i!=number)&&(j!=(number+1))) {
	      e[4] = min(e[4],
			 erg4(i, j, i+1, 1, ct, data, lfce[i+1]) +  erg4(i, j, j-1, 2, ct, data, lfce[j-1]) +
			 wmb2[i+2][(j-2)%3]
			 +penalty(i, j, ct, data));

	    }
	  }


	}



	v.f(i, j)=min(v.f(i, j), e[1]);
	v.f(i, j)=min(v.f(i, j), e[2]);
	v.f(i, j)=min(v.f(i, j), e[3]);
	v.f(i, j)=min(v.f(i, j), e[4]);
      }

      //Compute w[i][j]: best energy between i and j where i, j does not have
      //	to be a base pair
      //(an exterior loop when it contains n and 1 (ie:n+1)   )
    sub2:


      //w[i][j]=infinity;

      if (key==2) {//force a pair between i and j
	w.f(i, j) = v.f(i, j);
	key = 0;
	goto sub3;
      }


      for (ii=1; ii<=5; ii++) e[ii] = infinity;


      if (i!=number) {
      	//calculate the energy of i stacked onto the pair of i+1, j

	e[1] = v.f(i+1, j) + data->eparam[10] + data->eparam[6] +
	  erg4(j, i+1, i, 2, ct, data, lfce[i])+penalty(i+1, j, ct, data);


	if (!lfce[i]) {
	  if (fce[i][i]!=2)
	    e[4] = w.f(i+1, j) + data->eparam[6];
	  //this is for when i represents the center of an intermolecular linker:
	  else e[4] = w.f(i+1, j) + data->eparam[6] + infinity;
	}
      }
      if (j!=((number)+1)) {
      	//calculate the energy of j stacked onto the pair of i, j-1
	if (j!=1) {
	  e[2] = v.f(i, j-1) + data->eparam[10] + data->eparam[6] +
	    erg4(j-1, i, j, 1, ct, data, lfce[j])+penalty(i, j-1, ct, data);

	  if (!lfce[j]) {
	    if (fce[j][j]!=2) {
	      e[5] = w.f(i, j-1) + data->eparam[6];
	    }
	    else e[5] = w.f(i, j-1) + data->eparam[6] + infinity;

	  }
	}
      }
      if ((i!=(number))&&(j!=((number)+1))) {
      	//calculate i and j stacked onto the pair of i+1, j-1
	if (j!=1) {
	  e[3] = v.f(i+1, j-1) + data->eparam[10] + 2*(data->eparam[6]) +
	    erg4(j-1, i+1, i, 2, ct, data, lfce[i]) +
	    erg4(j-1, i+1, j, 1, ct, data, lfce[j])
	    +penalty(j-1, i+1, ct, data);
	}
      }
      w.f(i, j) = min(((data->eparam[10])+v.f(i, j)+penalty(j, i, ct, data)), e[1]);
      w.f(i, j) = min(w.f(i, j), e[2]);
      w.f(i, j) = min(w.f(i, j), e[3]);
      w.f(i, j) = min(w.f(i, j), e[4]);
      w.f(i, j) = min(w.f(i, j), e[5]);

      if (ct->intermolecular) {

      	wmb2[i][j%3] = infinity;
      	//keep track of w2:
	for (ii=1; ii<=5; ii++) e[ii] = 2*infinity;


	if (i!=number) {
	  //calculate the energy of i stacked onto the pair of i+1, j

	  e[1] = v.f(i+1, j) +
	    erg4(j, i+1, i, 2, ct, data, lfce[i])+penalty(i+1, j, ct, data)+infinity;


	  if (!lfce[i]) {
	    if (fce[i][i]!=2)
	      e[4] = w2->f(i+1, j);
	    //this is for when i represents the center of an intermolecular linker:
            else e[4] = w2->f(i+1, j) - infinity + data->init;
	  }
	}
      	if (j!=((number)+1)) {
	  //calculate the energy of j stacked onto the pair of i, j-1
	  if (j!=1) {
	    e[2] = v.f(i, j-1)  + infinity +
	      erg4(j-1, i, j, 1, ct, data, lfce[j])+penalty(i, j-1, ct, data);

	    if (!lfce[j]) {
	      if (fce[j][j]!=2) {
		e[5] = w2->f(i, j-1);
	      }
	      else e[5] = w2->f(i, j-1) - infinity + data->init;

	    }
	  }
      	}
      	if ((i!=(number))&&(j!=((number)+1))) {
	  //calculate i and j stacked onto the pair of i+1, j-1
	  if (j!=1) {
	    e[3] = v.f(i+1, j-1)  + infinity +
	      erg4(j-1, i+1, i, 2, ct, data, lfce[i]) +
	      erg4(j-1, i+1, j, 1, ct, data, lfce[j])
	      +penalty(j-1, i+1, ct, data);
	  }
      	}
      	w2->f(i, j) = min((infinity+v.f(i, j)+penalty(j, i, ct, data)), e[1]);
      	w2->f(i, j) = min(w2->f(i, j), e[2]);
      	w2->f(i, j) = min(w2->f(i, j), e[3]);
      	w2->f(i, j) = min(w2->f(i, j), e[4]);
      	w2->f(i, j) = min(w2->f(i, j), e[5]);




      }


      /*if (((j-i-1)>(2*minloop+2))||(j>(number))) {
      // search for an open bifuraction:
      for (k=i; k<=j-1; k++) {
      if (k==(number)) w.f(i, j)=min(w.f(i, j),
      w3[i]+w5[j-(number)]);
      else w.f(i, j) = min(w.f(i, j),
      w.f(i, k)+work[k+1][j%3]);
      }
      }  */
      ////fill wmb:

      if (((j-i-1)>(2*minloop+2))||j>number) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -