WSTester updated to work plus hopefully all the other changes that need to go into...
[jabaws.git] / binaries / src / ViennaRNA / lib / LPfold.c
diff --git a/binaries/src/ViennaRNA/lib/LPfold.c b/binaries/src/ViennaRNA/lib/LPfold.c
new file mode 100644 (file)
index 0000000..4b46278
--- /dev/null
@@ -0,0 +1,1379 @@
+/* Last changed Time-stamp: <2009-02-18 14:19:51 ivo> */
+/*
+  local pair probabilities for RNA secondary structures
+
+  Stephan Bernhart, Ivo L Hofacker
+  Vienna RNA package
+*/
+/*
+  todo: compute energy z-score for each window
+
+*/
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <float.h>    /* #defines FLT_MAX ... */
+#include "utils.h"
+#include "energy_par.h"
+#include "fold_vars.h"
+#include "pair_mat.h"
+#include "PS_dot.h"
+#include "part_func.h"
+#include "params.h"
+#include "loop_energies.h"
+#include "LPfold.h"
+#include "Lfold.h"
+
+#ifdef _OPENMP
+#include <omp.h>
+#endif
+
+
+/*@unused@*/
+PRIVATE char rcsid[] UNUSED = "$Id: LPfold.c,v 1.8 2009/02/18 20:34:38 ivo Exp $";
+
+#define ISOLATED  256.0
+
+/*
+#################################
+# GLOBAL VARIABLES              #
+#################################
+*/
+
+/*
+#################################
+# PRIVATE VARIABLES             #
+#################################
+*/
+
+PRIVATE float       cutoff;
+PRIVATE int         num_p=0; /* for counting basepairs in pairlist pl, can actually be moved into pfl_fold */
+PRIVATE FLT_OR_DBL  *expMLbase=NULL;
+PRIVATE FLT_OR_DBL  **q=NULL, **qb=NULL, **qm=NULL, *qqm=NULL, *qqm1=NULL, *qq=NULL, *qq1=NULL, **pR=NULL, **qm2=NULL, **QI5=NULL,  **q2l=NULL, **qmb=NULL;/*,**QI3,*/
+PRIVATE FLT_OR_DBL  *prml=NULL, *prm_l=NULL, *prm_l1=NULL, *q1k=NULL, *qln=NULL;
+PRIVATE FLT_OR_DBL  *scale=NULL;
+PRIVATE char        **ptype=NULL; /* precomputed array of pair types */
+PRIVATE int         *jindx=NULL;
+PRIVATE int         *my_iindx=NULL;
+PRIVATE int         init_length = 0;  /* length in last call to init_pf_fold() */
+PRIVATE pf_paramT   *pf_params=NULL;
+PRIVATE short       *S=NULL, *S1=NULL;
+PRIVATE int         unpaired;
+PRIVATE int         ulength;
+PRIVATE int         pUoutput;
+PRIVATE double      alpha = 1.0;
+
+#ifdef _OPENMP
+
+/* NOTE: all variables are assumed to be uninitialized if they are declared as threadprivate
+*/
+#pragma omp threadprivate(cutoff, num_p, scale, ptype, jindx, my_iindx, init_length, pf_params,\
+                          expMLbase, q, qb, qm, qqm, qqm1, qq, qq1, pR, qm2, QI5, q2l, qmb,\
+                          prml, prm_l, prm_l1, q1k, qln,\
+                          S, S1, unpaired, ulength, pUoutput, alpha)
+
+#endif
+
+/*
+#################################
+# PRIVATE FUNCTION DECLARATIONS #
+#################################
+*/
+
+PRIVATE void  init_partfunc_L(int length, pf_paramT *parameters);
+PRIVATE void  get_arrays_L(unsigned int length);
+PRIVATE void  free_pf_arrays_L(void);
+PRIVATE void  scale_pf_params(unsigned int length, pf_paramT *parameters);
+PRIVATE void  GetPtype(int j, int pairsize, const short *S, int n);
+PRIVATE void  FreeOldArrays(int i);
+PRIVATE void  GetNewArrays(int j, int winSize);
+PRIVATE void  printpbar(FLT_OR_DBL **prb,int winSize, int i, int n);
+PRIVATE plist *get_deppp(struct plist *pl, int start, int pairsize, int length);
+PRIVATE plist *get_plistW(struct plist *pl, int length, int start, FLT_OR_DBL **Tpr, int winSize);
+PRIVATE void  print_plist(int length, int start, FLT_OR_DBL **Tpr, int winSize, FILE *fp);
+PRIVATE void  compute_pU(int k, int ulength, double **pU, int winSize, int n, char *sequence);
+PRIVATE void  putoutpU(double **pU,int k, int ulength, FILE *fp);
+/*PRIVATE void make_ptypes(const short *S, const char *structure);*/
+
+PRIVATE void putoutpU_splitup(double **pUx, int k, int ulength, FILE *fp, char ident);
+PRIVATE void compute_pU_splitup(int k, int ulength, double **pU,  double **pUO, double **pUH, double **pUI, double **pUM, int winSize,int n, char *sequence);
+
+/*
+#################################
+# BEGIN OF FUNCTION DEFINITIONS #
+#################################
+*/
+
+PRIVATE void init_partfunc_L(int length, pf_paramT *parameters){
+  if (length<1) nrerror("init_partfunc_L: length must be greater 0");
+#ifdef _OPENMP
+/* Explicitly turn off dynamic threads */
+  omp_set_dynamic(0);
+  free_pf_arrays_L(); /* free previous allocation */
+#else
+  if (init_length>0) free_pf_arrays_L(); /* free previous allocation */
+#endif
+
+#ifdef SUN4
+  nonstandard_arithmetic();
+#else
+#ifdef HP9
+  fpsetfastmode(1);
+#endif
+#endif
+  make_pair_matrix();
+  get_arrays_L((unsigned) length);
+  scale_pf_params((unsigned) length, parameters);
+
+#ifndef _OPENMP
+  init_length = length;
+#endif
+}
+
+PRIVATE void get_arrays_L(unsigned int length){
+  /*arrays in 2 dimensions*/
+
+  q         = (FLT_OR_DBL **) space(sizeof(FLT_OR_DBL *)*(length+1));
+  qb        = (FLT_OR_DBL **) space(sizeof(FLT_OR_DBL *)*(length+1));
+  qm        = (FLT_OR_DBL **) space(sizeof(FLT_OR_DBL *)*(length+1));
+  pR        = (FLT_OR_DBL **) space(sizeof(FLT_OR_DBL *)*(length+1));
+  q1k       = (FLT_OR_DBL *)  space(sizeof(FLT_OR_DBL)  *(length+1));
+  qln       = (FLT_OR_DBL *)  space(sizeof(FLT_OR_DBL)  *(length+2));
+  qq        = (FLT_OR_DBL *)  space(sizeof(FLT_OR_DBL)  *(length+2));
+  qq1       = (FLT_OR_DBL *)  space(sizeof(FLT_OR_DBL)  *(length+2));
+  qqm       = (FLT_OR_DBL *)  space(sizeof(FLT_OR_DBL)  *(length+2));
+  qqm1      = (FLT_OR_DBL *)  space(sizeof(FLT_OR_DBL)  *(length+2));
+  prm_l     = (FLT_OR_DBL *)  space(sizeof(FLT_OR_DBL)  *(length+2));
+  prm_l1    = (FLT_OR_DBL *)  space(sizeof(FLT_OR_DBL)  *(length+2));
+  prml      = (FLT_OR_DBL *)  space(sizeof(FLT_OR_DBL)  *(length+2));
+  expMLbase = (FLT_OR_DBL *)  space(sizeof(FLT_OR_DBL)  *(length+1));
+  scale     = (FLT_OR_DBL *)  space(sizeof(FLT_OR_DBL)  *(length+1));
+  ptype     = (char **)       space(sizeof(char *)      *(length+2));
+
+  if (ulength>0) {
+    /* QI3 = (FLT_OR_DBL **) space((length+1)*sizeof(FLT_OR_DBL *));*/
+    QI5 = (FLT_OR_DBL **) space((length+1)*sizeof(FLT_OR_DBL *));
+    qmb = (FLT_OR_DBL **) space((length+1)*sizeof(FLT_OR_DBL *));
+    qm2 = (FLT_OR_DBL **) space((length+1)*sizeof(FLT_OR_DBL *));
+    q2l = (FLT_OR_DBL **) space((length+1)*sizeof(FLT_OR_DBL *));
+  }
+  my_iindx  = get_iindx(length);
+  iindx     = get_iindx(length); /* for backward compatibility and Perl wrapper */
+  jindx     = get_indx(length);
+}
+
+PRIVATE void free_pf_arrays_L(void){
+  if(q)         free(q);
+  if(qb)        free(qb);
+  if(qm)        free(qm);
+  if(pR)        free(pR);
+  if(qm2)       free(qm2);
+  if(qq)        free(qq);
+  if(qq1)       free(qq1);
+  if(qqm)       free(qqm);
+  if(qqm1)      free(qqm1);
+  if(q1k)       free(q1k);
+  if(qln)       free(qln);
+  if(prm_l)     free(prm_l);
+  if(prm_l1)    free(prm_l1);
+  if(prml)      free(prml);
+  if(expMLbase) free(expMLbase);
+  if(scale)     free(scale);
+  if(my_iindx)  free(my_iindx);
+  if(iindx)     free(iindx); /* for backward compatibility and Perl wrapper */
+  if(jindx)     free(jindx);
+  if(ptype)     free(ptype);
+  if(QI5)       free(QI5);
+  if(qmb)       free(qmb);
+  if(q2l)       free(q2l);
+  if(pf_params) free(pf_params);
+
+  q = qb = qm = pR = QI5 = qmb = qm2 = q2l = NULL;
+  qq = qq1 = qqm = qqm1 = q1k = qln = prml = prm_l = prm_l1 = expMLbase = NULL;
+  my_iindx = jindx = iindx = NULL;
+  pf_params = NULL;
+  ptype     = NULL;
+  scale = NULL;
+
+#ifdef SUN4
+  standard_arithmetic();
+#else
+#ifdef HP9
+  fpsetfastmode(0);
+#endif
+#endif
+
+#ifndef _OPENMP
+  init_length=0;
+#endif
+}
+
+PUBLIC void update_pf_paramsLP(int length){
+  update_pf_paramsLP_par(length, NULL);
+}
+
+PUBLIC void update_pf_paramsLP_par(int length, pf_paramT *parameters){
+#ifdef _OPENMP
+  init_partfunc_L(length, parameters);
+#else
+  if(parameters) init_partfunc_L(length, parameters);
+  else if (length > init_length) init_partfunc_L(length, parameters);
+  else {
+    /*   make_pair_matrix();*/
+    scale_pf_params((unsigned) length, parameters);
+  }
+#endif
+}
+
+PUBLIC plist *pfl_fold( char *sequence,
+                        int winSize,
+                        int pairSize,
+                        float cutoffb,
+                        double **pU,
+                        struct plist **dpp2,
+                        FILE *pUfp,
+                        FILE *spup){
+  return pfl_fold_par(sequence, winSize, pairSize, cutoffb, pU, dpp2, pUfp, spup, NULL);
+}
+
+PUBLIC plist *pfl_fold_par( char *sequence,
+                            int winSize,
+                            int pairSize,
+                            float cutoffb,
+                            double **pU,
+                            struct plist **dpp2,
+                            FILE *pUfp,
+                            FILE *spup,
+                            pf_paramT *parameters){
+
+  int         n, m, i, j, k, l, u, u1, ii, type, type_2, tt, ov, do_dpp, simply_putout, noGUclosure;
+  double      max_real;
+  FLT_OR_DBL  temp, Qmax, prm_MLb, prmt, prmt1, qbt1, *tmp, expMLclosing;
+  plist       *dpp, *pl;
+  int split=0;
+
+  ov            = 0;
+  Qmax          = 0;
+  do_dpp        = 0;
+  simply_putout = 0;
+  dpp           = NULL;
+  pl            = NULL;
+  pUoutput      = 0;
+  ulength       = 0;
+  cutoff        = cutoffb;
+
+  if(pU != NULL)  ulength       = (int)pU[0][0]+0.49;
+  if(spup !=NULL) simply_putout = 1; /*can't have one without the other*/
+  if(pUfp!=NULL)  pUoutput      = 1;
+  else if((pUoutput)&&(ulength!=0)){
+    fprintf(stderr, "There was a problem with non existing File Pointer for unpaireds, terminating process\n");
+    return pl;
+  }
+  dpp = *dpp2;
+  if(dpp !=NULL)  do_dpp=1;
+
+  n = (int) strlen(sequence);
+  if (n<TURN+2) return 0;
+
+#ifdef _OPENMP
+  /* always init everything since all global static variables are uninitialized when entering a thread */
+  init_partfunc_L(n, parameters);
+#else
+  if(parameters) init_partfunc_L(n, parameters);
+  else if (n > init_length) init_partfunc_L(n, parameters);
+  else if (fabs(pf_params->temperature - temperature)>1e-6) update_pf_paramsLP_par(n, parameters);
+#endif
+
+  expMLclosing  = pf_params->expMLclosing;
+  noGUclosure   = pf_params->model_details.noGUclosure;
+
+
+  max_real = (sizeof(FLT_OR_DBL) == sizeof(float)) ? FLT_MAX : DBL_MAX;
+
+  S   = encode_sequence(sequence, 0);
+  S1  = encode_sequence(sequence, 1);
+
+  /*  make_ptypes(S, structure); das machmadochlieber lokal, ey!*/
+
+  /*here, I allocate memory for pU, if has to be saved, I allocate all in one go,
+    if pU is put out and freed, I only allocate what I really need*/
+
+  if (ulength>0){
+    if (pUoutput) {
+      for (i=1; i<=ulength; i++) pU[i]=(double *)space((MAX2(MAXLOOP,ulength)+2)*sizeof(double));
+    }
+    else {
+      for (i=1; i<=n; i++) pU[i]=(double *)space((MAX2(MAXLOOP,ulength)+2)*sizeof(double));
+     }
+  }
+
+  /*array initialization ; qb,qm,q
+    qb,qm,q (i,j) are stored as ((n+1-i)*(n-i) div 2 + n+1-j */
+  num_p = 0;
+  pl    = (struct plist *)space(1000*sizeof(struct plist));
+
+
+  /*ALWAYS q[i][j] => i>j!!*/
+  for (j=1; j<MIN2(TURN+2,n); j++) { /*allocate start*/
+    GetNewArrays(j, winSize);
+    GetPtype(j,pairSize,S,n);
+    for (i=1; i<=j; i++) q[i][j]=scale[(j-i+1)];
+  }
+  for (j=TURN+2;j<=n+winSize; j++) {
+    if (j<=n) {
+      GetNewArrays(j, winSize);
+      GetPtype(j,pairSize,S,n);
+      for (i=MAX2(1,j-winSize); i<=j/*-TURN*/; i++)
+        q[i][j]=scale[(j-i+1)];
+      for (i=j-TURN-1;i>=MAX2(1,(j-winSize+1)); i--) {
+        /* construction of partition function of segment i,j*/
+        /*firstly that given i bound to j : qb(i,j) */
+        u = j-i-1;
+        type = ptype[i][j];
+        if (type!=0) {
+          /*hairpin contribution*/
+          if (((type==3)||(type==4))&&noGUclosure) qbt1 = 0;
+          else
+            qbt1 = exp_E_Hairpin(u, type, S1[i+1], S1[j-1], sequence+i-1, pf_params) * scale[u+2];
+
+          /* interior loops with interior pair k,l */
+          for (k=i+1; k<=MIN2(i+MAXLOOP+1,j-TURN-2); k++) {
+            u1 = k-i-1;
+            for (l=MAX2(k+TURN+1,j-1-MAXLOOP+u1); l<j; l++) {
+              type_2 = ptype[k][l];
+              if (type_2) {
+                type_2 = rtype[type_2];
+                qbt1 += qb[k][l] *
+                  exp_E_IntLoop(u1, j-l-1, type, type_2,
+                                S1[i+1], S1[j-1], S1[k-1], S1[l+1], pf_params) * scale[k-i+j-l];
+              }
+            }
+          }
+          /*multiple stem loop contribution*/
+          ii = my_iindx[i+1]; /* ii-k=[i+1,k-1] */
+          temp = 0.0;
+          for (k=i+2; k<=j-1; k++) temp += qm[i+1][k-1]*qqm1[k];
+          tt = rtype[type];
+          qbt1 += temp * expMLclosing * exp_E_MLstem(tt, S1[j-1], S1[i+1], pf_params) * scale[2];
+
+          qb[i][j] = qbt1;
+        } /* end if (type!=0) */
+        else qb[i][j] = 0.0;
+
+        /* construction of qqm matrix containing final stem
+           contributions to multiple loop partition function
+           from segment i,j */
+        qqm[i] = qqm1[i]*expMLbase[1];
+        if (type) {
+          qbt1 = qb[i][j] * exp_E_MLstem(type, (i>1) ? S1[i-1] : -1, (j<n) ? S1[j+1] : -1, pf_params);
+          qqm[i] += qbt1;
+        }
+
+        /*construction of qm matrix containing multiple loop
+          partition function contributions from segment i,j */
+        temp = 0.0;
+        /*ii = my_iindx[i];   ii-k=[i,k-1] */
+        /*new qm2 computation done here*/
+        for (k=i+1; k<=j; k++) temp += (qm[i][k-1])*qqm[k];
+        if (ulength>0) qm2[i][j]=temp;/*new qm2 computation done here*/
+        for (k=i+1; k<=j; k++) temp += expMLbase[k-i] * qqm[k];
+        qm[i][j] = (temp + qqm[i]);
+
+        /*auxiliary matrix qq for cubic order q calculation below */
+        qbt1 = qb[i][j];
+        if (type) {
+          qbt1 *= exp_E_ExtLoop(type, (i>1) ? S1[i-1] : -1, (j < n) ? S1[j+1] : -1, pf_params);
+        }
+        qq[i] = qq1[i]*scale[1] + qbt1;
+
+        /*construction of partition function for segment i,j */
+        temp = 1.0*scale[1+j-i] + qq[i];
+        for (k=i; k<=j-1; k++) temp += q[i][k]*qq[k+1];
+        q[i][j] = temp;
+
+        if (temp>Qmax) {
+          Qmax = temp;
+          if (Qmax>max_real/10.)
+            fprintf(stderr, "Q close to overflow: %d %d %g\n", i,j,temp);
+        }
+        if (temp>=max_real) {
+          PRIVATE char msg[128];
+          snprintf(msg, 128, "overflow in pf_fold while calculating q[%d,%d]\n"
+                  "use larger pf_scale", i,j);
+          nrerror(msg);
+        }
+      } /*end for i*/
+      tmp = qq1;  qq1 =qq;  qq =tmp;
+      tmp = qqm1; qqm1=qqm; qqm=tmp;
+    }
+
+    /* just as a general service, I save here the free energy of the windows
+       no output is generated, however,...
+    */
+    if ((j>=winSize) && (j<=n) && (ulength) && !(pUoutput)) {
+      double Fwindow=0.;
+      Fwindow=(-log(q[j-winSize+1][j])-winSize*log(pf_params->pf_scale))*pf_params->kT/1000.0;
+
+      pU[j][0]=Fwindow;
+      /*
+      if (ulength>=winSize)
+        pU[j][winSize]=scale[winSize]/q[j-winSize+1][j];
+      */
+    }
+    if (j>winSize) {
+      Qmax=0;
+      /* i=j-winSize; */
+      /* initialize multiloopfs */
+      for (k=j-winSize; k<=MIN2(n,j); k++) {
+        prml[k]=0;
+        prm_l[k]=0;
+        /*        prm_l1[k]=0;  others stay*/
+      }
+      prm_l1[j-winSize]=0;
+      k=j-winSize;
+      for (l=k+TURN+1; l<=MIN2(n,k+winSize-1); l++) {
+        int a;
+        pR[k][l] = 0; /* set zero at start */
+        type=ptype[k][l];
+        if (qb[k][l]==0) continue;
+
+        for (a=MAX2(1,l-winSize+2); a<MIN2(k,n-winSize+2);a++)
+          pR[k][l]+=q[a][k-1]*q[l+1][a+winSize-1]/q[a][a+winSize-1];
+
+        if (l-k+1==winSize)
+          pR[k][l]+=1./q[k][l];
+        else {
+          if (k+winSize-1<=n)          /* k outermost */
+            pR[k][l]+=q[l+1][k+winSize-1]/q[k][k+winSize-1];
+          if (l-winSize+1>=1)  /*l outermost*/
+            pR[k][l]+=q[l-winSize+1][k-1]/q[l-winSize+1][l];
+        }
+        pR[k][l] *= exp_E_ExtLoop(type, (k>1) ? S1[k-1] : -1, (l<n) ? S1[l+1] : -1, pf_params);
+
+        type_2 = ptype[k][l];
+        type_2 = rtype[type_2];
+
+        for (i=MAX2(MAX2(l-winSize+1,k-MAXLOOP-1),1); i<=k-1; i++) {
+          for (m=l+1; m<=MIN2(MIN2(l+ MAXLOOP -k+i+2,i+winSize-1),n); m++) {
+            type = ptype[i][m];
+            if ((pR[i][m]>0))
+              pR[k][l] += pR[i][m]*exp_E_IntLoop(k-i-1, m-l-1, type, type_2,
+                                                 S1[i+1], S1[m-1], S1[k-1], S1[l+1], pf_params) * scale[k-i+m-l];
+          }
+        }
+        if (ulength) { /* NOT IF WITHIN INNER LOOP */
+          for (i=MAX2(MAX2(l-winSize+1,k-MAXLOOP-1),1); i<=k-1; i++) {
+            for (m=l+1; m<=MIN2(MIN2(l+ MAXLOOP -k+i+2,i+winSize-1),n); m++) {
+              type = ptype[i][m];
+              if ((pR[i][m]>0)){
+                temp=pR[i][m]*qb[k][l]*exp_E_IntLoop(k-i-1, m-l-1, type, type_2,
+                                                     S1[i+1], S1[m-1], S1[k-1], S1[l+1], pf_params) * scale[k-i+m-l];
+                QI5[l][m-l-1]+=temp;
+                QI5[i][k-i-1]+=temp;
+              }
+            }
+           }
+        }
+      }
+      /* 3. bonding k,l as substem of multi-loop enclosed by i,m */
+      prm_MLb = 0.;
+      if(k>1) /*sonst nix!*/
+        for (l=MIN2(n-1,k+winSize-2); l>=k+TURN+1; l--) { /* opposite direction */
+          m=l+1;
+          prmt = prmt1 = 0.0;
+          tt = ptype[k-1][m]; tt=rtype[tt];
+          prmt1 = pR[k-1][m] * expMLclosing * exp_E_MLstem(tt, S1[l], S1[k], pf_params);
+          for (i=MAX2(1,l-winSize+2); i<k-1/*TURN*/; i++) {
+            tt = ptype[i][m]; tt = rtype[tt];
+            prmt += pR[i][m] * exp_E_MLstem(tt, S1[m-1], S1[i+1], pf_params) * qm[i+1][k-1];
+          }
+          tt = ptype[k][l];
+          prmt *= expMLclosing;
+          prml[ m] = prmt;
+          prm_l[m] = prm_l1[m]*expMLbase[1]+prmt1;
+
+          prm_MLb = prm_MLb*expMLbase[1] + prml[m];
+          /* same as:    prm_MLb = 0;
+             for (i=n; i>k; i--)  prm_MLb += prml[i]*expMLbase[k-i-1];
+          */
+          prml[m] = prml[ m] + prm_l[m];
+
+          if (qb[k][l] == 0.) continue;
+
+          temp = prm_MLb;
+
+          if (ulength) {
+            double dang;
+            /* coefficient for computations of unpairedarrays */
+            dang  =   qb[k][l] * exp_E_MLstem(tt, S1[k-1], S1[l+1], pf_params) * scale[2];
+            for (m=MIN2(k+winSize-2,n);m>=l+2; m--){
+              qmb[l][m-l-1] +=  prml[m]*dang;
+              q2l[l][m-l-1] +=  (prml[m]-prm_l[m])*dang;
+            }
+          }
+
+          for (m=MIN2(k+winSize-2,n);m>=l+2; m--)
+            temp += prml[m]*qm[l+1][m-1];
+
+          temp      *= exp_E_MLstem(tt, (k>1) ? S1[k-1] : -1, (l<n) ? S1[l+1] : -1, pf_params) * scale[2];
+          pR[k][l]  += temp;
+
+          if (pR[k][l]>Qmax) {
+            Qmax = pR[k][l];
+            if (Qmax>max_real/10.)
+              fprintf(stderr, "P close to overflow: %d %d %g %g\n",
+                      i, m, pR[k][l], qb[k][l]);
+          }
+          if (pR[k][l]>=max_real) {
+            ov++;
+            pR[k][l]=FLT_MAX;
+          }
+
+        } /* end for (l=..) */
+      tmp = prm_l1; prm_l1=prm_l; prm_l=tmp;
+
+      /* end for (l=..)   */
+      if ((ulength)&&(k-MAXLOOP-1>0)){
+        /* if (pUoutput) pU[k-MAXLOOP-1]=(double *)space((ulength+2)*sizeof(double)); */
+        if(split){ /*generate the new arrays, if you want them somewhere else, you have to generate them and overgive them ;)*/
+          double **pUO;
+          double **pUI;
+          double **pUM;
+          double **pUH;
+          pUO= (double **)  space((n+1)*sizeof(double *));
+          pUI= (double **)  space((n+1)*sizeof(double *));
+          pUM= (double **)  space((n+1)*sizeof(double *));
+          pUH= (double **)  space((n+1)*sizeof(double *));
+          if (pUoutput) {
+            for (i=1; i<=ulength; i++) {
+              pUH[i]=(double *)space((MAX2(MAXLOOP,ulength)+2)*sizeof(double));
+              pUI[i]=(double *)space((MAX2(MAXLOOP,ulength)+2)*sizeof(double));
+              pUO[i]=(double *)space((MAX2(MAXLOOP,ulength)+2)*sizeof(double));
+              pUM[i]=(double *)space((MAX2(MAXLOOP,ulength)+2)*sizeof(double));
+            }
+          }
+          //dont want to have that yet?
+          /*  else {
+            for (i=1; i<=n; i++) pU[i]=(double *)space((MAX2(MAXLOOP,ulength)+2)*sizeof(double));
+            }*/
+          compute_pU_splitup(k-MAXLOOP-1,ulength,pU,pUO,pUH, pUI, pUM, winSize, n, sequence);
+          if (pUoutput) {
+            putoutpU_splitup(pUO,k-MAXLOOP-1, ulength, pUfp,'E');
+            putoutpU_splitup(pUH,k-MAXLOOP-1, ulength, pUfp,'H');
+            putoutpU_splitup(pUI,k-MAXLOOP-1, ulength, pUfp,'I');
+            putoutpU_splitup(pUM,k-MAXLOOP-1, ulength, pUfp,'M');
+          }
+        }
+        else {
+        compute_pU(k-MAXLOOP-1,ulength,pU, winSize, n, sequence);
+
+        /* here, we put out and free pUs not in use any more (hopefully) */
+        if (pUoutput)
+          putoutpU(pU,k-MAXLOOP-1, ulength, pUfp);
+      }
+      }
+
+      if (j-(2*winSize+MAXLOOP+1)>0) {
+        printpbar(pR,winSize,j-(2*winSize+MAXLOOP+1),n);
+        if (simply_putout) {
+          print_plist(n, j-(2*winSize+MAXLOOP+1), pR, winSize, spup);
+        }
+        else{
+          pl=get_plistW(pl, n, j-(2*winSize+MAXLOOP+1), pR, winSize);
+        }
+        if (do_dpp)dpp=get_deppp(dpp,j-(2*winSize-MAXLOOP),pairSize, n);
+        FreeOldArrays(j-(2*winSize+MAXLOOP+1));
+      }
+    }   /* end if (do_backtrack)*/
+
+  }/* end for j */
+
+  /* finish output and free */
+  for (j=MAX2(1,n-MAXLOOP); j<=n;j++) {
+    /* if (pUoutput) pU[j]=(double *)space((ulength+2)*sizeof(double)); */
+    if (ulength) compute_pU(j,ulength,pU, winSize, n, sequence);
+    /*here, we put out and free pUs not in use any more (hopefully)*/
+    if (pUoutput) putoutpU(pU,j, ulength, pUfp);
+  }
+  for (j=MAX2(n-winSize-MAXLOOP,1); j<=n; j++) {
+    printpbar(pR,winSize,j,n);
+    if (simply_putout) {
+      print_plist(n, j, pR, winSize, spup);
+    }
+    else {
+      pl=get_plistW(pl, n, j, pR, winSize);
+    }
+    if ((do_dpp)&&j<n) dpp=get_deppp(dpp,j,pairSize, n);
+    FreeOldArrays(j);
+  }
+  /* free_pf_arrays_L(); */
+  free(S);
+  free(S1);
+  S = S1 = NULL;
+  if (ov>0) fprintf(stderr, "%d overflows occurred while backtracking;\n"
+                    "you might try a smaller pf_scale than %g\n",
+                    ov, pf_params->pf_scale);
+  *dpp2=dpp;
+
+  return pl;
+}
+
+PRIVATE void scale_pf_params(unsigned int length, pf_paramT *parameters){
+  unsigned int i;
+  double  kT, scaling_factor;
+
+  if(pf_params) free(pf_params);
+
+  if(parameters){
+    pf_params = get_boltzmann_factor_copy(parameters);
+  } else {
+    model_detailsT  md;
+    set_model_details(&md);
+    pf_params = get_boltzmann_factors(temperature, alpha, md, pf_scale);
+  }
+
+  scaling_factor = pf_params->pf_scale;
+  kT = pf_params->kT;   /* kT in cal/mol  */
+
+   /* scaling factors (to avoid overflows) */
+  if (scaling_factor == -1) { /* mean energy for random sequences: 184.3*length cal */
+    scaling_factor = exp(-(-185+(pf_params->temperature-37.)*7.27)/kT);
+    if (scaling_factor<1) scaling_factor=1;
+    pf_params->pf_scale = scaling_factor;
+  }
+  scale[0] = 1.;
+  scale[1] = 1./scaling_factor;
+  expMLbase[0] = 1;
+  expMLbase[1] = pf_params->expMLbase/scaling_factor;
+  for (i=2; i<=length; i++) {
+    scale[i] = scale[i/2]*scale[i-(i/2)];
+    expMLbase[i] = pow(pf_params->expMLbase, (double)i) * scale[i];
+  }
+}
+
+PRIVATE void printpbar(FLT_OR_DBL **prb,int winSize, int i, int n) {
+  int j;
+  int howoften=0; /* how many samples do we have for this pair */
+  int pairdist;
+
+  for (j=i+TURN; j<MIN2(i+winSize,n+1); j++) {
+    pairdist=(j-i+1);
+    /*4cases*/
+    howoften=MIN2(winSize-pairdist+1,i); /*pairdist,start*/
+    howoften=MIN2(howoften,n-j+1);       /*end*/
+    howoften=MIN2(howoften,n-winSize+1); /*windowsize*/
+    prb[i][j] *= qb[i][j]/howoften;
+  }
+  return;
+}
+
+PRIVATE void FreeOldArrays(int i) {
+  /*free arrays no longer needed*/
+  free(pR[i]+i);
+  free(q[i]+i);
+  free(qb[i]+i);
+  free(qm[i]+i);
+  if (ulength!=0) {
+    free(qm2[i]+i);
+    free(QI5[i]);
+    free(qmb[i]);
+    free(q2l[i]);
+  }
+  free(ptype[i]+i);
+  return;
+}
+
+PRIVATE void GetNewArrays(int j, int winSize) {
+  /*allocate new part of arrays*/
+  pR[j]=(FLT_OR_DBL *)space((winSize+1)*sizeof(FLT_OR_DBL));
+  pR[j]-=j;
+  q[j]=(FLT_OR_DBL *)space((winSize+1)*sizeof(FLT_OR_DBL));
+  q[j]-=j;
+  qb[j]=(FLT_OR_DBL *)space((winSize+1)*sizeof(FLT_OR_DBL));
+  qb[j]-=j;
+  qm[j]=(FLT_OR_DBL *)space((winSize+1)*sizeof(FLT_OR_DBL));
+  qm[j]-=j;
+  if (ulength!=0) {
+    qm2[j]=(FLT_OR_DBL *)space((winSize+1)*sizeof(FLT_OR_DBL));
+    qm2[j]-=j;
+    QI5[j]=(FLT_OR_DBL *)space((winSize+1)*sizeof(FLT_OR_DBL));
+    qmb[j]=(FLT_OR_DBL *)space((winSize+1)*sizeof(FLT_OR_DBL));
+    q2l[j]=(FLT_OR_DBL *)space((winSize+1)*sizeof(FLT_OR_DBL));
+  }
+  ptype[j]=(char *)space((winSize+1)*sizeof(char));
+  ptype[j]-=j;
+  return;
+}
+
+
+PRIVATE void GetPtype(int i, int winSize,const short *S,int n) {
+  /*make new entries in ptype array*/
+  int j;
+  int type;
+  for (j=i; j<=MIN2(i+winSize,n); j++) {
+    type = pair[S[i]][S[j]];
+    ptype[i][j] = (char) type;
+  }
+  return;
+}
+
+
+PRIVATE plist *get_plistW(plist *pl, int length,
+                                 int start, FLT_OR_DBL **Tpr, int winSize) {
+  /* get pair probibilities out of pr array */
+  int  j,  max_p;
+  max_p=1000;
+  while (max_p<num_p)
+    max_p*=2;
+
+  for (j=start+1; j<=MIN2(start+winSize, length); j++) {
+    if (Tpr[start][j]<cutoff) continue;
+    if (num_p==max_p-1) {
+      max_p*=2;
+      pl=(plist *)xrealloc(pl,max_p*sizeof(plist));
+    }
+    pl[num_p].i=start;
+    pl[num_p].j=j;
+    pl[num_p++].p=Tpr[start][j];
+  }
+
+  /* mark end of data with zeroes */
+  pl[num_p].i=0;
+  pl[num_p].j=0;
+  pl[num_p].p=0.;
+  /* pl=(struct plist *)xrealloc(pl,(count)*sizeof(struct plist)); */
+  return pl;
+}
+
+
+PRIVATE plist *get_deppp(plist *pl, int start, int pairsize, int length) {
+  /* compute dependent pair probabilities */
+  int i, j, count=0;
+  double tmp;
+  plist *temp;
+  temp=(plist *)space(pairsize*sizeof(plist)); /* holds temporary deppp */
+  for (j=start+TURN; j<MIN2(start+pairsize,length); j++) {
+
+    if ((qb[start][j]*qb[start-1][(j+1)])>10e-200) {
+      int type=ptype[start-1][j+1];
+      int type_2=rtype[ptype[start][j]];
+      tmp=qb[start][j]/qb[start-1][(j+1)]*exp_E_IntLoop(0, 0, type, type_2,
+                                                        S1[start], S1[j], S1[start-1], S1[j+1], pf_params) * scale[2];
+       temp[count].i=start;
+      temp[count].j=j;
+      temp[count++].p=tmp;
+    }
+  }
+  /* write it to list of deppps */
+  for (i=0; pl[i].i!=0; i++);
+  pl=(plist *)xrealloc(pl,(i+count+1)*sizeof(plist));
+  for (j=0; j<count; j++) {
+    pl[i+j].i=temp[j].i;
+    pl[i+j].j=temp[j].j;
+    pl[i+j].p=temp[j].p;
+  }
+  pl[i+count].i=0;
+  pl[i+count].j=0;
+  pl[i+count].p=0;
+  free(temp);
+  return pl;
+}
+
+
+PRIVATE void print_plist(int length,int start, FLT_OR_DBL **Tpr, int winSize, FILE *fp) {
+  /* print out of pr array, do not save */
+  int  j;
+
+
+  for (j=start+1; j<=MIN2(start+winSize, length); j++) {
+    if (Tpr[start][j]<cutoff) continue;
+    fprintf(fp,"%d  %d  %g\n",start,j,Tpr[start][j]);
+  }
+
+  /* mark end of data with zeroes */
+
+  return ;
+}
+
+PRIVATE void compute_pU(int k, int ulength, double **pU, int winSize,int n, char *sequence) {
+/*  here, we try to add a function computing all unpaired probabilities starting at some i,
+    going down to $unpaired, to be unpaired, i.e. a list with entries from 1 to unpaired for
+    every i, with the probability of a stretch of length x, starting at i-x+1, to be unpaired
+*/
+  int startu;
+  int i5;
+  int j3, len, obp;
+  double temp;
+  double *QBE;
+  FLT_OR_DBL  expMLclosing      = pf_params->expMLclosing;
+
+  QBE=(double *) space((MAX2(ulength,MAXLOOP)+2)*sizeof(double));
+
+  /* first, we will */
+  /* for k<=ulength, pU[k][k]=0, because no bp can enclose it */
+  if (pUoutput&&k+ulength<=n)  pU[k+ulength]=(double *)space((ulength+2)*sizeof(double));
+  /*compute pu[k+ulength][ulength] */
+   for (i5=MAX2(k+ulength-winSize+1,1);i5<=k;i5++) {
+    for (j3=k+ulength+1; j3<=MIN2(n,i5+winSize-1); j3++) {
+      /*  if (k>400) {
+        printf("i%d j%d  ",i5,j3);
+        fflush(stdout);
+        } */
+      if (ptype[i5][j3]!=0) {/**/
+        /* (.. >-----|..........)
+          i5  j     j+ulength  j3              */
+        /*Multiloops*/
+        temp = (i5<k) ? qm2[i5+1][k] * expMLbase[j3-k-1] : 0.; /* (..{}{}-----|......) */
+
+        if(j3-1>k+ulength)
+          temp  +=  qm2[k+ulength+1][j3-1] * expMLbase[k+ulength-i5]; /* (..|-----|{}{}) */
+
+        if((i5<k)&&(j3-1>k+ulength))
+          temp  +=  qm[i5+1][k] * qm[k+ulength+1][j3-1] * expMLbase[ulength]; /* ({}|-----|{}) */
+
+        /* add dangles, multloopclosing etc. */
+        temp  *=  exp_E_MLstem(rtype[ptype[i5][j3]], S1[j3-1], S1[i5+1], pf_params) * scale[2] * expMLclosing;
+        /*add hairpins*/
+        temp  +=  exp_E_Hairpin(j3-i5-1, ptype[i5][j3], S1[i5+1], S1[j3-1], sequence+i5-1, pf_params) * scale[j3-i5+1];
+        /*add outer probability*/
+        temp *= pR[i5][j3];
+        pU[k+ulength][ulength] += temp;
+
+      }
+    }
+   }
+   /* code doubling to avoid if within loop */
+#if 0
+  /*initialization for interior loops,
+    it is not recomended to have verysmall ulengths!!*/
+  if (ulength<MAXLOOP) {
+    int k5;
+    int l3;
+    int outype;
+    /* kl bp is 5' */
+    /* MAXLOOP>((l5-k5-1)+(j3-l3-1)
+      k-winSize+ulength<i5<k-TURN-1;
+      k+ulength<j3<=k+MAXLOOP+1
+      if i then use l3, it is easier by far:
+      j3-MAXLOOP<=l3<=k
+      i5<k5<k-TURN k5<=i5+l3+2+MAXLOOP-j3
+      k5+TURN<l3<=k
+    */
+    for (i5=MAX2(k+ulength-winSize,1);i5<k-TURN-1;i5++) {
+
+      for (j3=k+ulength+1; j3<=MIN2(n,MIN2(i5+winSize-1,k+MAXLOOP+1)); j3++) {
+        double temp=0;
+        if (outype=ptype[i5][j3]>0) /* oder so halt */
+          for (l3=MAX2(i5+TURN+1,j3-MAXLOOP-1); l3<=k; l3++){
+            for (k5=i5+1; k5<=MIN2(l3-TURN-1,MAXLOOP+i5+l3+2-j3); k5++){
+              if (ptype[k5][l3]) {
+                temp+= qb[k5][l3]*expLoopEnergy(k5-i5-1, j3-l3-1, outype, rtype[ptype[k5][l3]], S1[i5+1], S1[j3-1], S1[k5-1], S1[l3+1]);
+              }
+            }
+          }
+        temp*=pR[i5][j3];
+        pU[k+ulength][ulength]+= temp;
+      }
+    }
+    /* kl bp is 3' */
+    /*
+      k+ulength-MAXLOOP<=i5<=k
+      k+ulength+1+TURN<j3<i5+winSize
+      k+ulength+1<=k5<i5+MAXLOOP+2 || k5<j3-TURN
+      k5<l3<j3 || j3-k5-i5-2-ML<=l3<j3
+    */
+    for (i5=MAX2(1,MAX2(k+ulength-winSize,k+ulength-MAXLOOP));i5<=k; i5++){
+      for (j3=k+ulength+TURN+2; j3<MIN2(n+1,i5+winSize); j3++) {
+        double temp = 0;
+        if (outype=ptype[i5][j3]>0) /* oder so halt */
+          for (k5=k+ulength+1; k5<MIN2(j3-TURN-1,i5+MAXLOOP+2); k5++) {
+            for (l3=MAX2(k5+TURN+1,j3+k5-i5-2-MAXLOOP); l3<j3; l3++) {
+              if (ptype[k5][l3])
+                temp += qb[k5][l3]*expLoopEnergy(k5-i5-1, j3-l3-1, outype, rtype[ptype[k5][l3]], S1[i5+1], S1[j3-1], S1[k5-1], S1[l3+1]);
+            }
+          }
+        temp*=pR[i5][j3];
+        pU[k+ulength][ulength]+= temp;
+      }
+    }
+  }
+  /* Add up Is QI5[l][m-l-1] QI3 */
+  /* Add up Interior loop terms */
+  temp=0.;
+
+  for (len=winSize; len>=ulength; len--) temp+=QI3[k][len];
+  for (;len>0; len--) {
+    temp += QI3[k][len];
+    QBE[len] += temp;
+  }
+#endif
+  temp=0.;
+  for (len=winSize; len>=MAX2(ulength,MAXLOOP); len--) temp+=QI5[k][len];
+  for (;len>0; len--) {
+    temp += QI5[k][len];
+    QBE[len] += temp;  /* replace QBE with QI */
+  }
+  /* Add Hairpinenergy to QBE */
+  temp=0.;
+  for(obp = MIN2(n, k + winSize - 1); obp > k + ulength; obp--)
+    if(ptype[k][obp])
+      temp += pR[k][obp] * exp_E_Hairpin(obp-k-1, ptype[k][obp], S1[k+1], S1[obp-1], sequence+k-1, pf_params) * scale[obp-k+1];
+  for(obp = MIN2(n, MIN2(k + winSize - 1, k + ulength)); obp > k + 1; obp--){
+    if (ptype[k][obp])
+      temp += pR[k][obp] * exp_E_Hairpin(obp-k-1, ptype[k][obp], S1[k+1], S1[obp-1], sequence+k-1, pf_params) * scale[obp-k+1];
+    QBE[obp-k-1] += temp;  /* add hairpins to QBE (all in one array) */
+  }
+  /* doubling the code to get the if out of the loop */
+
+  /* Add up Multiloopterms  qmb[l][m]+=prml[m]*dang;
+    q2l[l][m]+=(prml[m]-prm_l[m])*dang; */
+
+  temp=0.;
+  for(len = winSize; len >= ulength; len--)
+    temp += q2l[k][len] * expMLbase[len];
+  for( ; len > 0; len--){
+    temp += q2l[k][len] * expMLbase[len];
+    QBE[len] += temp; /* add (()()____) type cont. to I3 */
+  }
+  for(len = 1; len < ulength; len++){
+    for(obp = k + len + TURN; obp <= MIN2(n, k + winSize - 1); obp++){
+      /* add (()___()) */
+      QBE[len] += qmb[k][obp-k-1] * qm[k+len+1/*2*/][obp-1] * expMLbase[len];
+    }
+  }
+  for (len=1; len<ulength; len++) {
+    for (obp=k+len+TURN+TURN; obp<=MIN2(n,k+winSize-1); obp++) {
+      if (ptype[k][obp]) {
+        temp      =   exp_E_MLstem(rtype[ptype[k][obp]], S1[obp-1], S1[k+1], pf_params) * scale[2] * expMLbase[len] * expMLclosing; /* k:obp */
+        QBE[len]  +=  pR[k][obp] * temp * qm2[k+len+1][obp-1]; /* add (___()()) */
+      }
+    }
+  }
+  /* After computing all these contributions in QBE[len], that k is paired
+    and the unpaired stretch is AT LEAST len long, we start to add that to
+    the old unpaired thingies; */
+  for(len = 1; len < MIN2(MAX2(ulength, MAXLOOP), n - k); len++){
+    pU[k+len][len] += pU[k+len][len+1] + QBE[len];
+  }
+
+  /*open chain*/
+  if ((ulength>=winSize)&&(k>=ulength)) {
+    pU[k][winSize]=scale[winSize]/q[k-winSize+1][k];
+  }
+  /* now the not enclosed by any base pair terms for whatever it is we do not need anymore...
+    ... which should be e.g; k, again */
+  for(startu = MIN2(ulength, k); startu > 0; startu--){
+    temp=0.;
+    for(i5 = MAX2(1, k - winSize + 2); i5 <= MIN2(k - startu, n - winSize + 1); i5++){
+      temp += q[i5][k - startu] * q[k + 1][i5 + winSize - 1] * scale[startu]/q[i5][i5 + winSize - 1];
+    }
+    /* the 2 Cases where the borders are on the edge of the interval */
+    if((k >= winSize) && (startu + 1 <= winSize))
+      temp += q[k - winSize + 1][k - startu]*scale[startu]/q[k - winSize + 1][k];
+    if((k <= n - winSize+ startu) && (k - startu >= 0) && (k < n) && (startu + 1 <= winSize))
+      temp += q[k + 1][k - startu + winSize] * scale[startu] / q[k - startu + 1][k - startu + winSize];
+
+    /* Divide by number of possible windows */
+    pU[k][startu] += temp;
+    {
+      int leftmost, rightmost;
+
+      leftmost      = MAX2(1, k - winSize + 1);
+      rightmost     = MIN2(n - winSize + 1, k - startu + 1);
+      pU[k][startu] /= (rightmost - leftmost + 1);
+    }
+  }
+  free(QBE);
+  return;
+}
+
+
+PRIVATE void putoutpU(double **pUx, int k, int ulength, FILE *fp) {
+  /*put out unpaireds for k, and free pU[k], make sure we don't need pU[k] any more!!*/
+  /*could use that for hairpins, also!*/
+  int i;
+  fprintf(fp,"%d\t",k);
+  for (i=1; i<=MIN2(ulength,k); i++) {
+    fprintf(fp,"%.5g\t",pUx[k][i]);
+  }
+  fprintf(fp,"\n");
+  free(pUx[k]);
+}
+PRIVATE void putoutpU_splitup(double **pUx, int k, int ulength, FILE *fp, char ident) {
+  /*put out unpaireds for k, and free pU[k], make sure we don't need pU[k] any more!!*/
+  /*could use that for hairpins, also!*/
+  int i;
+  fprintf(fp,"%d\t",k);
+  for (i=1; i<=MIN2(ulength,k); i++) {
+    fprintf(fp,"%.5g\t",pUx[k][i]);
+  }
+  fprintf(fp,"\t%s\n",ident);
+  free(pUx[k]);
+}
+
+PUBLIC void putoutpU_prob(double **pU,int length, int ulength, FILE *fp, int energies) {
+  putoutpU_prob_par(pU, length, ulength, fp, energies, pf_params);
+}
+
+
+PUBLIC void putoutpU_prob_par(double **pU,int length, int ulength, FILE *fp, int energies, pf_paramT *parameters){
+  /*put out unpaireds */
+  int i,k;
+  double kT = parameters->kT/1000.0;
+  double temp;
+  if (energies) fprintf(fp,"#opening energies\n #i$\tl=");
+  else  fprintf(fp,"#unpaired probabilities\n #i$\tl=");
+  for (i=1; i<=ulength; i++) {
+    fprintf(fp,"%d\t", i);
+  }
+  fprintf(fp,"\n");
+
+  for (k=1; k<=length; k++){
+    fprintf(fp,"%d\t",k);
+    for (i=1; i<=ulength; i++) {
+      if (i>k) {
+        fprintf(fp,"NA\t");
+        continue;
+      }
+      if (energies) temp=-log(pU[k][i])*kT;
+      else temp=pU[k][i];
+      fprintf(fp,"%.7g\t",temp);
+    }
+    fprintf(fp,"\n");
+    free(pU[k]);
+  }
+  fflush(fp);
+}
+
+PUBLIC void putoutpU_prob_bin(double **pU,int length, int ulength, FILE *fp, int energies) {
+  putoutpU_prob_bin_par(pU, length, ulength, fp, energies, pf_params);
+}
+
+PUBLIC void putoutpU_prob_bin_par(double **pU,int length, int ulength, FILE *fp, int energies, pf_paramT *parameters) {
+
+  /*put out unpaireds */
+  int i,k;
+  double kT= parameters->kT/1000.0;
+  double temp;
+  int *p;
+  p = (int*) space(sizeof(int)*1);
+  /* write first line */
+  p[0]=ulength; /* u length */
+  fwrite(p,sizeof(int),1,fp);
+  p[0]=length; /* seq length */
+  fwrite(p,sizeof(int),1,fp);
+  for (k=3; k<=(length+20); k++){ /* all the other lines are set to 1000000 because we are at ulength=0 */
+    p[0]=1000000;
+    fwrite(p,sizeof(int),1,fp);
+  }
+  /* data */
+  for (i=1; i<=ulength; i++) {
+    for (k=1; k<=11; k++){/* write first ten entries to 1000000 */
+      p[0]=1000000;
+      fwrite(p,sizeof(int),1,fp);
+    }
+    for (k=1; k<=length; k++){/* write data now */
+      if (i>k) {
+        p[0]=1000000;         /* check if u > pos */
+        fwrite(p,sizeof(int),1,fp);
+        continue;
+      }
+      else{
+        p[0]= (int) rint(100 *(-log(pU[k][i])*kT));
+        fwrite(p,sizeof(int),1,fp);
+      }
+    }
+    for (k=1; k<=9; k++){/* finish by writing the last 10 entries */
+      p[0]=1000000;
+      fwrite(p,sizeof(int),1,fp);
+    }
+  }
+  /* free pU array; */
+  for (k=1; k<=length; k++){
+    free(pU[k]);
+  }
+  free(p);
+  fflush(fp);
+}
+
+
+/*
+ Here: Space for questions...
+*/
+PRIVATE void compute_pU_splitup(int k, int ulength, double **pU,  double **pUO, double **pUH, double **pUI, double **pUM, int winSize,int n, char *sequence) {
+/*  here, we try to add a function computing all unpaired probabilities starting at some i,
+    going down to $unpaired, to be unpaired, i.e. a list with entries from 1 to unpaired for
+    every i, with the probability of a stretch of length x, starting at i-x+1, to be unpaired
+*/
+  int startu;
+  int i5;
+  int j3, len, obp;
+  double temp;
+  double *QBE;
+  double *QBI;
+  double *QBM;
+  double *QBH;
+  
+  FLT_OR_DBL  expMLclosing      = pf_params->expMLclosing;
+
+  QBE=(double *) space((MAX2(ulength,MAXLOOP)+2)*sizeof(double));
+  QBM=(double *) space((MAX2(ulength,MAXLOOP)+2)*sizeof(double));
+  QBI=(double *) space((MAX2(ulength,MAXLOOP)+2)*sizeof(double));
+  QBH=(double *) space((MAX2(ulength,MAXLOOP)+2)*sizeof(double));
+
+  /* first, we will */
+  /* for k<=ulength, pU[k][k]=0, because no bp can enclose it */
+  if (pUoutput&&k+ulength<=n)  pU[k+ulength]=(double *)space((ulength+2)*sizeof(double));
+  /*compute pu[k+ulength][ulength] */
+   for (i5=MAX2(k+ulength-winSize+1,1);i5<=k;i5++) {
+    for (j3=k+ulength+1; j3<=MIN2(n,i5+winSize-1); j3++) {
+      /*  if (k>400) {
+        printf("i%d j%d  ",i5,j3);
+        fflush(stdout);
+        } */
+      if (ptype[i5][j3]!=0) {/**/
+        /* (.. >-----|..........)
+          i5  j     j+ulength  j3              */
+        /*Multiloops*/
+        temp = (i5<k) ? qm2[i5+1][k] * expMLbase[j3-k-1] : 0.; /* (..{}{}-----|......) */
+
+        if(j3-1>k+ulength)
+          temp  +=  qm2[k+ulength+1][j3-1] * expMLbase[k+ulength-i5]; /* (..|-----|{}{}) */
+
+        if((i5<k)&&(j3-1>k+ulength))
+          temp  +=  qm[i5+1][k] * qm[k+ulength+1][j3-1] * expMLbase[ulength]; /* ({}|-----|{}) */
+
+        /* add dangles, multloopclosing etc. */
+        temp  *=  exp_E_MLstem(rtype[ptype[i5][j3]], S1[j3-1], S1[i5+1], pf_params) * scale[2] * expMLclosing;
+        /*add hairpins*/
+        temp  +=  exp_E_Hairpin(j3-i5-1, ptype[i5][j3], S1[i5+1], S1[j3-1], sequence+i5-1, pf_params) * scale[j3-i5+1];
+        /*add outer probability*/
+        temp *= pR[i5][j3];
+        pU[k+ulength][ulength] += temp;
+
+      }
+    }
+   }
+   /* code doubling to avoid if within loop */
+  temp=0.;
+  for (len=winSize; len>=MAX2(ulength,MAXLOOP); len--) temp+=QI5[k][len];
+  for (;len>0; len--) {
+    temp += QI5[k][len];
+    QBI[len] += temp; 
+    QBE[len] += temp;  /* replace QBE with QI */
+  }
+  /* Add Hairpinenergy to QBE */
+  temp=0.;
+  for(obp = MIN2(n, k + winSize - 1); obp > k + ulength; obp--)
+    if(ptype[k][obp])
+      temp += pR[k][obp] * exp_E_Hairpin(obp-k-1, ptype[k][obp], S1[k+1], S1[obp-1], sequence+k-1, pf_params) * scale[obp-k+1];
+  for(obp = MIN2(n, MIN2(k + winSize - 1, k + ulength)); obp > k + 1; obp--){
+    if (ptype[k][obp])
+      temp += pR[k][obp] * exp_E_Hairpin(obp-k-1, ptype[k][obp], S1[k+1], S1[obp-1], sequence+k-1, pf_params) * scale[obp-k+1];
+    QBH[obp-k-1] += temp;
+    QBE[obp-k-1] += temp;  /* add hairpins to QBE (all in one array) */
+  }
+  /* doubling the code to get the if out of the loop */
+
+  /* Add up Multiloopterms  qmb[l][m]+=prml[m]*dang;
+    q2l[l][m]+=(prml[m]-prm_l[m])*dang; */
+
+  temp=0.;
+  for(len = winSize; len >= ulength; len--)
+    temp += q2l[k][len] * expMLbase[len];
+  for( ; len > 0; len--){
+    temp += q2l[k][len] * expMLbase[len];
+    QBM[len] += temp; 
+    QBE[len] += temp; /* add (()()____) type cont. to I3 */
+  }
+  for(len = 1; len < ulength; len++){
+    for(obp = k + len + TURN; obp <= MIN2(n, k + winSize - 1); obp++){
+      /* add (()___()) */
+      QBM[len] += qmb[k][obp-k-1] * qm[k+len+1/*2*/][obp-1] * expMLbase[len];
+      QBE[len] += qmb[k][obp-k-1] * qm[k+len+1/*2*/][obp-1] * expMLbase[len];
+    }
+  }
+  for (len=1; len<ulength; len++) {
+    for (obp=k+len+TURN+TURN; obp<=MIN2(n,k+winSize-1); obp++) {
+      if (ptype[k][obp]) {
+        temp      =   exp_E_MLstem(rtype[ptype[k][obp]], S1[obp-1], S1[k+1], pf_params) * scale[2] * expMLbase[len] * expMLclosing; /* k:obp */
+        QBE[len]  +=  pR[k][obp] * temp * qm2[k+len+1][obp-1]; /* add (___()()) */
+        QBM[len]  +=  pR[k][obp] * temp * qm2[k+len+1][obp-1]; /* add (___()()) */
+      }
+    }
+  }
+  /* After computing all these contributions in QBE[len], that k is paired
+    and the unpaired stretch is AT LEAST len long, we start to add that to
+    the old unpaired thingies; */
+  for(len = 1; len < MIN2(MAX2(ulength, MAXLOOP), n - k); len++){
+    pU[k+len][len] += pU[k+len][len+1] + QBE[len];
+    pUH[k+len][len] += pUH[k+len][len+1] + QBH[len];
+    pUM[k+len][len] += pUM[k+len][len+1] + QBM[len];
+    pUI[k+len][len] += pUI[k+len][len+1] + QBI[len];
+    
+  }
+
+  /* open chain */
+  if ((ulength>=winSize)&&(k>=ulength)) {
+    pUO[k][winSize]=scale[winSize]/q[k-winSize+1][k];
+  }
+  /*open chain*/
+  if ((ulength>=winSize)&&(k>=ulength)) {
+    pU[k][winSize]=scale[winSize]/q[k-winSize+1][k];
+  }
+  /* now the not enclosed by any base pair terms for whatever it is we do not need anymore...
+    ... which should be e.g; k, again */
+  for(startu = MIN2(ulength, k); startu > 0; startu--){
+    temp=0.;
+    for(i5 = MAX2(1, k - winSize + 2); i5 <= MIN2(k - startu, n - winSize + 1); i5++){
+      temp += q[i5][k - startu] * q[k + 1][i5 + winSize - 1] * scale[startu]/q[i5][i5 + winSize - 1];
+    }
+    /* the 2 Cases where the borders are on the edge of the interval */
+    if((k >= winSize) && (startu + 1 <= winSize))
+      temp += q[k - winSize + 1][k - startu]*scale[startu]/q[k - winSize + 1][k];
+    if((k <= n - winSize+ startu) && (k - startu >= 0) && (k < n) && (startu + 1 <= winSize))
+      temp += q[k + 1][k - startu + winSize] * scale[startu] / q[k - startu + 1][k - startu + winSize];
+
+    /* Divide by number of possible windows */
+    pU[k][startu] += temp;
+    pUO[k][startu] += temp;
+    
+    {
+      int leftmost, rightmost;
+
+      leftmost      = MAX2(1, k - winSize + 1);
+      rightmost     = MIN2(n - winSize + 1, k - startu + 1);
+      pU[k][startu] /= (rightmost - leftmost + 1);
+      /*Do we want to make a distinction between those?*/
+      pUH[k][startu] /= (rightmost - leftmost + 1);
+      pUO[k][startu] /= (rightmost - leftmost + 1);
+      pUI[k][startu] /= (rightmost - leftmost + 1);
+      pUM[k][startu] /= (rightmost - leftmost + 1);
+    }
+  }
+  free(QBE);
+  free(QBI);
+  free(QBH);
+  free(QBM);
+  return;
+}
+PUBLIC void putoutpU_prob_splitup(double **pU, double **pUO, double **pUH, double **pUI, double **pUM, int length, int ulength, FILE *fp, int energies) {
+  /*put out unpaireds */
+  int i,k;
+  double kT= (temperature+K0)*GASCONST/1000.0;
+  double temp;
+  if (energies) fprintf(fp,"#opening energies\n #i$\tl=");
+  else  fprintf(fp,"#unpaired probabilities\n #i$\tl=");
+  
+  fprintf(fp,"Total\n");
+  for (i=1; i<=ulength; i++) {
+    fprintf(fp,"%d\t", i);
+  }
+  fprintf(fp,"\n");
+
+  for (k=1; k<=length; k++){
+    fprintf(fp,"%d\t",k);
+    for (i=1; i<=ulength; i++) {
+      if (i>k) {
+        fprintf(fp,"NA\t");
+        continue;
+      }
+      if (energies) temp=-log(pU[k][i])*kT;
+      else temp=pU[k][i];
+      fprintf(fp,"%.7g\t",temp);
+    }
+    fprintf(fp,"\tT\n");
+    free(pU[k]);
+  }
+  fprintf(fp,"\n###################################################################\nHairpin\n");
+  for (i=1; i<=ulength; i++) {
+    fprintf(fp,"%d\t", i);
+  }
+  fprintf(fp,"\n");
+
+  for (k=1; k<=length; k++){
+    fprintf(fp,"%d\t",k);
+    for (i=1; i<=ulength; i++) {
+      if (i>k) {
+        fprintf(fp,"NA\t");
+        continue;
+      }
+      if (energies) temp=-log(pUH[k][i])*kT;
+      else temp=pUH[k][i];
+      fprintf(fp,"%.7g\t",temp);
+    }
+    fprintf(fp,"\tH\n");
+    free(pUH[k]);
+  }
+  fprintf(fp,"\n###################################################################\nInterior\n");
+  for (i=1; i<=ulength; i++) {
+    fprintf(fp,"%d\t", i);
+  }
+  fprintf(fp,"\n");
+
+  for (k=1; k<=length; k++){
+    fprintf(fp,"%d\t",k);
+    for (i=1; i<=ulength; i++) {
+      if (i>k) {
+        fprintf(fp,"NA\t");
+        continue;
+      }
+      if (energies) temp=-log(pUI[k][i])*kT;
+      else temp=pUI[k][i];
+      fprintf(fp,"%.7g\t",temp);
+    }
+    fprintf(fp,"\tI\n");
+    free(pUI[k]);
+  }
+  fprintf(fp,"\n###################################################################\nMultiloop\n");
+  for (i=1; i<=ulength; i++) {
+    fprintf(fp,"%d\t", i);
+  }
+  fprintf(fp,"\n");
+
+  for (k=1; k<=length; k++){
+    fprintf(fp,"%d\t",k);
+    for (i=1; i<=ulength; i++) {
+      if (i>k) {
+        fprintf(fp,"NA\t");
+        continue;
+      }
+      if (energies) temp=-log(pUM[k][i])*kT;
+      else temp=pUM[k][i];
+      fprintf(fp,"%.7g\t",temp);
+    }
+    fprintf(fp,"\tM\n");
+    free(pUM[k]);
+  }
+  fprintf(fp,"\n###################################################################\nExterior\n");
+  for (i=1; i<=ulength; i++) {
+    fprintf(fp,"%d\t", i);
+  }
+  fprintf(fp,"\t E\n");
+
+  for (k=1; k<=length; k++){
+    fprintf(fp,"%d\t",k);
+    for (i=1; i<=ulength; i++) {
+      if (i>k) {
+        fprintf(fp,"NA\t");
+        continue;
+      }
+      if (energies) temp=-log(pUO[k][i])*kT;
+      else temp=pUO[k][i];
+      fprintf(fp,"%.7g\t",temp);
+    }
+    fprintf(fp,"\n");
+    free(pU[k]);
+  }
+  fflush(fp);
+}
+
+
+/*###########################################*/
+/*# deprecated functions below              #*/
+/*###########################################*/
+
+PUBLIC void init_pf_foldLP(int length){ /* DO NOTHING */}
+