/********************************************************************************************************
 * QRNA - Comparative analysis of biological sequences 
 *         with pair hidden Markov models, pair stochastic context-free
 *        grammars, and probabilistic evolutionary  models.
 *       
 * Version 2.0.0 (JUN 2003)
 *
 * Copyright (C) 2000-2003 Howard Hughes Medical Institute/Washington University School of Medicine
 * All Rights Reserved
 * 
 *     This source code is distributed under the terms of the
 *     GNU General Public License. See the files COPYING and LICENSE
 *     for details.
 ***********************************************************************************************************/

/* posterior.c
 *
 * E. Rivas [St. Louis]
 * 
 * 9 april 1999.
 * 
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <limits.h>

#include "funcs.h"
#include "globals.h"
#include "squid.h"
#include "structs.h"

#ifdef MEMDEBUG
#include "dbmalloc.h"
#endif


/* Function: Posterior()
 * Date:     SRE, Thu Jun 11 09:26:43 1998 [St. Louis]
 *
 * Purpose:  Calculate the posterior probability of a model.
 *           Done in log space for numerical stability reasons.
 *           (do the algebra)
 *
 * Args:     sc1     - log P(D|M) of the model under consideration
 *           sc2,sc3 - log P(D|M) of the other two models
 *
 * Returns:  Posterior P(M|D)
 */
double
Posterior(double sc1, double sc2, double sc3)
{
  double d[3];

  d[0] = 0.0;
  d[1] = sc2 - sc1;
  d[2] = sc3 - sc1;

  return 1.0 / EXP2(DLog2Sum(d, 3));
}


/* Function: PosteriorLog2()
 * Date:     ER, Tue Jun  8 12:22:20 CDT 1999 [St. Louis]
 *
 * Purpose:  Calculate the posterior probability of a model.
 *           Done in log2 space for numerical stability reasons.
 *           (do the algebra)
 *
 * Args:     sc1     - log2 P(D|M) of the given model
 *           sc2,sc3 - log2 P(D|M) of the other two models
 *
 * Returns:   log2 P(M|D) 
 */
double
PosteriorLog2(double sc1, double sc2, double sc3)
{
  double d[3];
  double score;

  d[0] = 0.0;
  d[1] = sc2 - sc1;
  d[2] = sc3 - sc1;

  if (sc1 < -BIGFLOAT) { score = -BIGFLOAT; return score; }

  score = -DLog2Sum(d, 3);

  /* do not get the posteriors get too small; gnuplot will complain otherwise
   */
  if (score < -BIGFLOAT) score = -BIGFLOAT;

  return score;
}

/* Function: SigmoidalLog2()
 * Date:     ER, Mon Feb 17 11:45:01 CST 2003 [St. Louis]
 *
 * Purpose:  Calculate the sigmoidal score a model with flat priors.
 *           Done in log2 space for numerical stability reasons.
 *           (do the algebra)
 *
 *           relationship between the posterior and the sigmoidal score of a model:
 *
 *           P(M_i|D) = exp(sigm_i) / ( 1 + exp(sigm_i) )
 *
 *           relationship between the prob of the date given the model r and the sigmoidal score of a model:
 *
 *           exp(sigm_i)  = P[D|M_i] * P[M_i] / sum_{j\ ne i} ( P[D|M_j]* P[M_j] )
 *
 *
 * Args:     sc1     - log2 P(D|M) of the given model
 *           sc2,sc3 - log2 P(D|M) of the other two models
 *
 * Returns:   log2 P(M|D) 
 */
double
SigmoidalLog2(double sc1, double sc2, double sc3)
{
  double d[2];
  double score;

  d[0] = sc2;
  d[1] = sc3;

  score = sc1 - DLog2Sum(d, 2);

  /* do not get the posteriors get too small; gnuplot will complain otherwise
   */
  if (score < -BIGFLOAT) score = -BIGFLOAT;

  return score;
}

