Example #1
0
/* Function:  esl_vec_DLogValidate()
 * Synopsis:  Verify that vector is a log-p-vector.           
 * Incept:    ER,  Tue Dec  5 09:46:51 EST 2006 [janelia]
 *
 * Purpose:   Validate a log probability vector <vec> of length <n>.
 *            The exp of each element has to be between 0 and 1, and
 *            the sum of all elements has to be 1.
 *
 * Args:      v      - log p vector to validate.
 *            n      - dimensionality of v
 *            tol    - convergence criterion applied to sum of exp v
 *            errbuf - NULL, or a failure message buffer allocated
 *                     for at least p7_ERRBUFSIZE chars. 
 *
 * Returns:   <eslOK> on success, or <eslFAIL> on failure; upon failure,
 *            if caller provided a non-<NULL> <errbuf>, an informative
 *            message is left there.
 *            
 * Throws:    <eslEMEM> on allocation failure.           
 */
int
esl_vec_DLogValidate(double *vec, int n, double tol, char *errbuf)
{
  int     status;
  double *expvec = NULL;

  if (errbuf) *errbuf = 0;
  if (n == 0) return eslOK;

  ESL_ALLOC(expvec, sizeof(double)*n);
  esl_vec_DCopy(vec, n, expvec);
  esl_vec_DExp(expvec, n); 
  if ((status = esl_vec_DValidate(expvec, n, tol, errbuf)) != eslOK) goto ERROR;
  free(expvec);
  return eslOK;

 ERROR:
  if (expvec != NULL) free(expvec);
  return status;
}
Example #2
0
static void
utest_pvectors(void)
{
  char  *msg   = "pvector unit test failed";
  double p1[4] = { 0.25, 0.25, 0.25, 0.25 };
  double p2[4];
  double p3[4];
  float  p1f[4]; 
  float  p2f[4] = { 0.0,   0.5, 0.5,  0.0  };
  float  p3f[4];
  int    n = 4;
  double result;

  esl_vec_D2F(p1,  n, p1f);
  esl_vec_F2D(p2f, n, p2);  

  if (esl_vec_DValidate(p1,  n, 1e-12, NULL) != eslOK) esl_fatal(msg);
  if (esl_vec_FValidate(p1f, n, 1e-7,  NULL) != eslOK) esl_fatal(msg);

  result = esl_vec_DEntropy(p1,  n);          if (esl_DCompare(2.0, result, 1e-9) != eslOK) esl_fatal(msg);
  result = esl_vec_FEntropy(p1f, n);          if (esl_DCompare(2.0, result, 1e-9) != eslOK) esl_fatal(msg);
  result = esl_vec_DEntropy(p2,  n);          if (esl_DCompare(1.0, result, 1e-9) != eslOK) esl_fatal(msg);
  result = esl_vec_FEntropy(p2f, n);          if (esl_DCompare(1.0, result, 1e-9) != eslOK) esl_fatal(msg);

  result = esl_vec_DRelEntropy(p2,  p1,  n);  if (esl_DCompare(1.0, result, 1e-9) != eslOK) esl_fatal(msg);
  result = esl_vec_FRelEntropy(p2f, p1f, n);  if (esl_DCompare(1.0, result, 1e-9) != eslOK) esl_fatal(msg);

  result = esl_vec_DRelEntropy(p1,  p2,  n);  if (result != eslINFINITY)  esl_fatal(msg);
  result = esl_vec_FRelEntropy(p1f, p2f, n);  if (result != eslINFINITY)  esl_fatal(msg);

  esl_vec_DLog(p2, n);
  if (esl_vec_DLogValidate(p2, n, 1e-12, NULL) != eslOK) esl_fatal(msg);
  esl_vec_DExp(p2, n);
  if (p2[0] != 0.) esl_fatal(msg);

  esl_vec_FLog(p2f, n);
  if (esl_vec_FLogValidate(p2f, n, 1e-7, NULL) != eslOK) esl_fatal(msg);
  esl_vec_FExp(p2f, n);
  if (p2f[0] != 0.) esl_fatal(msg);

  esl_vec_DCopy(p2, n, p3);
  esl_vec_DScale(p3, n, 10.);
  esl_vec_DNorm(p3, n);
  if (esl_vec_DCompare(p2, p3, n, 1e-12) != eslOK) esl_fatal(msg);

  esl_vec_DLog(p3, n);
  result = esl_vec_DLogSum(p3, n); if (esl_DCompare(0.0, result, 1e-12) != eslOK) esl_fatal(msg);
  esl_vec_DIncrement(p3, n, 2.0);
  esl_vec_DLogNorm(p3, n);
  if (esl_vec_DCompare(p2, p3, n, 1e-12) != eslOK) esl_fatal(msg);

  esl_vec_FCopy(p2f, n, p3f);
  esl_vec_FScale(p3f, n, 10.);
  esl_vec_FNorm(p3f, n);
  if (esl_vec_FCompare(p2f, p3f, n, 1e-7) != eslOK) esl_fatal(msg);

  esl_vec_FLog(p3f, n);
  result = esl_vec_FLogSum(p3f, n); if (esl_DCompare(0.0, result, 1e-7) != eslOK) esl_fatal(msg);
  esl_vec_FIncrement(p3f, n, 2.0);
  esl_vec_FLogNorm(p3f, n);
  if (esl_vec_FCompare(p2f, p3f, n, 1e-7) != eslOK) esl_fatal(msg);

  return;
}
Example #3
0
/* Function:  p7_profile_Validate()
 *
 * Purpose:   Validates the internals of the generic profile structure
 *            <gm>.
 *            
 * Returns:   <eslOK> if <gm> internals look fine. Returns <eslFAIL>
 *            if something is wrong, and leaves an error message in
 *            <errbuf> if caller passed it non-<NULL>.
 */
int
p7_profile_Validate(const P7_PROFILE *gm, char *errbuf, float tol)
{
  int     k;
  int     M      = gm->M;
  double *pstart = NULL;
  int     status;

  ESL_ALLOC(pstart, sizeof(double) * (gm->M+1));

  /* Validate tsc[0] boundary condition: 
   * tLM, tGM, tDGE are valid transitions at nonexistent node k=0, 
   * because of their off-by-one storage (i.e. tsc[k-1,LM] = tLk->M)
   */
  if (P7P_TSC(gm, 0, p7P_MM)  != -eslINFINITY ||
      P7P_TSC(gm, 0, p7P_IM)  != -eslINFINITY ||
      P7P_TSC(gm, 0, p7P_DM)  != -eslINFINITY ||
      // LM, GM skipped past...
      P7P_TSC(gm, 0, p7P_MD)  != -eslINFINITY ||
      P7P_TSC(gm, 0, p7P_DD)  != -eslINFINITY ||
      P7P_TSC(gm, 0, p7P_MI)  != -eslINFINITY ||
      P7P_TSC(gm, 0, p7P_II)  != -eslINFINITY) ESL_XFAIL(eslFAIL, errbuf, "transition probs at 0 not set properly");
      // DGE skipped.
      
  /* Validate tsc[M] boundary conditions.
   *  t(Mm->D) = 0   as an initialization condition to make Backward work
   *  t(Dm->D) = 0   ditto
   *  t(DGE,k) = t(Dk+1->..->Dm->E) = 0 at k=M and k=M-1
   */  
  if (P7P_TSC(gm, M, p7P_MM)  != -eslINFINITY ||
      P7P_TSC(gm, M, p7P_IM)  != -eslINFINITY ||
      P7P_TSC(gm, M, p7P_DM)  != -eslINFINITY ||
      P7P_TSC(gm, M, p7P_LM)  != -eslINFINITY ||
      P7P_TSC(gm, M, p7P_GM)  != -eslINFINITY ||
      /*... MD DD ... */
      P7P_TSC(gm, M, p7P_MI)  != -eslINFINITY ||
      P7P_TSC(gm, M, p7P_II)  != -eslINFINITY) ESL_XFAIL(eslFAIL, errbuf, "transition probs at M not set properly");

  if (P7P_TSC(gm, M, p7P_MD)  != 0.0f ||  
      P7P_TSC(gm, M, p7P_DD)  != 0.0f ||  
      P7P_TSC(gm, M, p7P_DGE) != 0.0f)  ESL_XFAIL(eslFAIL, errbuf, "transition probs at M not set properly");

  if (M>1 && P7P_TSC(gm, M-1, p7P_DGE) != 0.0f)  ESL_XFAIL(eslFAIL, errbuf, "transition probs at M not set properly");

  /* Validate local entry distribution.
   * this is an implicit probability distribution,
   * corresponding to the implicit local alignment model, and we have
   * to calculate the M(M+1)/2 fragment probabilities accordingly.
   */
  pstart[0] = 0.0;
  for (k = 1; k <= gm->M; k++) {
    pstart[k] = exp(P7P_TSC(gm, k-1, p7P_LM)) * (gm->M - k + 1);     /* multiply p_ij by the number of exits j; note off-by-one storage, L->Mk in tsc[k-1] */
    if (pstart[k] > 1.0 && pstart[k] <= 1.0 + tol) pstart[k] = 1.0;  // There's a special case, where only one M state is occupiable, with entry prob 1.0/(M-k+1). (M-k+1)*exp(log(1.0/M-k+1)) can give 1+epsilon. 
  }
  if (esl_vec_DValidate(pstart, gm->M+1, tol, NULL) != eslOK) ESL_XFAIL(eslFAIL, errbuf, "local entry distribution is not normalized properly");

  /* Validate the glocal entry distribution.  This is an explicit
   * probability distribution, corresponding to left wing retraction.
   * To make it sum to one, we also have to add in the probability
   * of the mute cycle G->D1...Dm->E; we put this in pstart[0].
   * [SRE:J9/98].
   */
  for (k = 1; k <= gm->M; k++)
    pstart[k] = exp(P7P_TSC(gm, k-1, p7P_GM));
  /* mute path probability */
  p7_profile_GetMutePathLogProb(gm, &(pstart[0]));
  pstart[0] = exp(pstart[0]);	/* this will often underflow, but when it does, it means that path's negligible in p, and the validation of the sum will still succeed */

  if (esl_vec_DValidate(pstart, gm->M+1, tol, NULL) != eslOK) ESL_XFAIL(eslFAIL, errbuf, "glocal entry distribution is not normalized properly");

  free(pstart);
  return eslOK;

 ERROR:
  if (pstart != NULL) free(pstart);
  return eslFAIL;
}