/* ===========================================================================
*
*                            PUBLIC DOMAIN NOTICE
*               National Center for Biotechnology Information
*
*  This software/database is a "United States Government Work" under the
*  terms of the United States Copyright Act.  It was written as part of
*  the author's official duties as a United States Government employee and
*  thus cannot be copyrighted.  This software/database is freely available
*  to the public for use. The National Library of Medicine and the U.S.
*  Government have not placed any restriction on its use or reproduction.
*
*  Although all reasonable efforts have been taken to ensure the accuracy
*  and reliability of the software and data, the NLM and the U.S.
*  Government do not and cannot warrant the performance or results that
*  may be obtained by using this software or data. The NLM and the U.S.
*  Government disclaim all warranties, express or implied, including
*  warranties of performance, merchantability or fitness for any particular
*  purpose.
*
*  Please cite the author in any work or product based on this material.
*
* ===========================================================================*/
#ifndef __BLAST_KARLIN__
#define __BLAST_KARLIN__
#ifdef __cplusplus
extern "C" {
#endif

#define BLAST_REFINED_STATS_DEFAULT TRUE
#define BLAST_CONSISTENCY_DEFAULT	TRUE

/****************************************************************************
For more accuracy in the calculation of K, set K_SUMLIMIT to 0.00001.
For high speed in the calculation of K, use a K_SUMLIMIT of 0.001
Note:  statistical significance is often not greatly affected by the value
of K, so high accuracy is generally unwarranted.
*****************************************************************************/
/* K_SUMLIMIT_DEFAULT == sumlimit used in BlastKarlinLHtoK() */
#define BLAST_KARLIN_K_SUMLIMIT_DEFAULT 0.01

/****************************************************************************
CAUTION:  when the range of potential single-letter substitution score values
is large, the K_STACKP option may demand more stack space than is available.
(See function BlastKarlinLHtoK and macros BLAST_SCORE_1MIN & BLAST_SCORE_1MAX).
*****************************************************************************/
/* BLAST_KARLIN_K_STACKP ==> allocate P0 on the stack to avoid malloc/free */
#if defined(OS_DOS) && !defined(BLAST_KARLIN_K_STACKP)
#define BLAST_KARLIN_K_STACKP
#endif

/* K_ITER_DEFAULT == number of iterations in BlastKarlinLHtoK() */
#define BLAST_KARLIN_K_ITER_DEFAULT	20
/* K_ITER_MAX == max. storage to reserve */
#if defined(OS_DOS) || defined(BLAST_KARLIN_K_STACKP)
#define BLAST_KARLIN_K_ITER_MAX	BLAST_KARLIN_K_ITER_DEFAULT
#else
#define BLAST_KARLIN_K_ITER_MAX	100
#endif


/* LAMBDA_ACCURACY_DEFAULT == accuracy to which Lambda should be calc'd */
#define BLAST_KARLIN_LAMBDA_ACCURACY_DEFAULT	(1.e-5)
/* LAMBDA_ITER_DEFAULT == no. of iterations in LambdaBis = ln(accuracy)/ln(2) */
#define BLAST_KARLIN_LAMBDA_ITER_DEFAULT	17
/* Initial guess for the value of Lambda in BlastKarlinLambdaNR */
#define BLAST_KARLIN_LAMBDA0_DEFAULT	0.5

#define BLAST_SUMP_EPSILON_DEFAULT 0.002 /* accuracy for SumP calculations */

/* accuracy for EtoPoissonP calculations */
#define BLAST_POISSONP_ACCURACY_DEFAULT 0.01
/* accuracy for EtoConsistP calculations */
#define BLAST_CONSISTP_ACCURACY_DEFAULT 0.01
/* common ratio between terms in geometric progression */
#define BLAST_GAPDECAYRATE_DEFAULT	0.5


typedef struct {
		double	Lambda; /* Lambda value used in statistics */
		double	K, logK; /* K value used in statistics */
		double	H; /* H value used in statistics */
		/* "real" values are ones actually found, may be replaced by above */
		double	Lambda_real, K_real, logK_real, H_real;
		BLAST_ScoreBlkPtr	sbp;
		BLAST_Score	gap0, gap1;
		int		q_frame, s_frame;
		ValNode	id;
		ValNode	user;
	} BLAST_KarlinBlk, PNTR BLAST_KarlinBlkPtr;

#define BLAST_INFO_BASIC(k,s)	((k)->Lambda * (s) - (k)->logK)

enum blast_sensitivity {
	BLAST_SENSITIVITY_LOW = 1,
	BLAST_SENSITIVITY_MEDIUM = 2,
	BLAST_SENSITIVITY_HIGH = 3
	};


BLAST_KarlinBlkPtr BlastKarlinBlkNew PROTO((void));
void	BlastKarlinBlkDestruct PROTO((BLAST_KarlinBlkPtr));
BLAST_Error	BlastKarlinBlkCalc PROTO((BLAST_KarlinBlkPtr, BLAST_ScoreFreqPtr));
double	BlastKarlinLambdaBis PROTO((BLAST_ScoreFreqPtr));
double	BlastKarlinLambdaNR PROTO((BLAST_ScoreFreqPtr));
double	BlastKarlinLambda0 PROTO((double));
double	BlastKarlinLambdaAccuracy PROTO((double digits));
double	BlastKarlinLtoH PROTO((BLAST_ScoreFreqPtr, double lambda));
double	BlastKarlinLHtoK PROTO((BLAST_ScoreFreqPtr, double lambda, double H));
BLAST_Score	BlastKarlinEtoS PROTO((double, BLAST_KarlinBlkPtr, double, double));
double	BlastKarlinStoE PROTO((BLAST_Score, BLAST_KarlinBlkPtr, double, double));
BLAST_Score	BlastKarlinBtoS PROTO((double bits, BLAST_KarlinBlkPtr kbp));
double	BlastKarlinEtoP PROTO((double Expect));
double	BlastKarlinEtoLogP PROTO((double Expect));
double	BlastKarlinPtoE PROTO((double Probability));
double	BlastKarlinStoLen PROTO((BLAST_KarlinBlkPtr, BLAST_Score));
double	BlastEtoPoissonP PROTO((unsigned cnt, double expect));
double	BlastGapDecay PROTO((double pvalue, unsigned nsegs, double decayrate));
double	BlastSumP PROTO((int r, double natscore));
double	BlastSumPStd PROTO((int r, double natscore));
double	BlastSumPCalc PROTO((int r, double natscore));
double	BlastLogSumPCalc PROTO((int r, double natscore));
BLAST_Error	BlastCutoffs PROTO((BLAST_ScorePtr, double PNTR, BLAST_KarlinBlkPtr, double, double, Nlm_Boolean));
double	BlastKarlinStoP PROTO((BLAST_Score, BLAST_KarlinBlkPtr, double, double));
BLAST_Score	BlastExpHighScore PROTO((BLAST_KarlinBlkPtr, double, double));
BLAST_Score BlastNWSThreshold PROTO((BLAST_KarlinBlkPtr, int wordsize, enum blast_sensitivity sens));
Nlm_Boolean	BlastRefinedStats	PROTO((Nlm_Boolean));

/* Datatypes */
#define KarlinBlk	BLAST_KarlinBlk
#define KarlinBlkPtr	BLAST_KarlinBlkPtr

/* Functions */
#define KarlinBlkNew	BlastKarlinBlkNew
#define KarlinBlkDestruct	BlastKarlinBlkDestruct
#define KarlinBlkCalc	BlastKarlinBlkCalc
#define KarlinLambdaBis	BlastKarlinLambdaBis
#define KarlinLambdaNR	BlastKarlinLambdaNR
#define KarlinLambda0	BlastKarlinLambda0
#define KarlinLambdaAccuracy	BlastKarlinLambdaAccuracy
#define KarlinLtoH	BlastKarlinLtoH
#define KarlinLHtoK	BlastKarlinLHtoK
#define KarlinEtoS	BlastKarlinEtoS
#define KarlinStoE	BlastKarlinStoE
#define KarlinStoP	BlastKarlinStoP
#define KarlinStoLen	BlastKarlinStoLen
#define KarlinBtoS	BlastKarlinBtoS
#define KarlinEtoP	BlastKarlinEtoP
#define KarlinEtoLogP	BlastKarlinEtoLogP
#define KarlinPtoE	BlastKarlinPtoE
#define EtoPoissonP	BlastEtoPoissonP
#define SumP		BlastSumP
#define SumPStd		BlastSumPStd
#define SumPCalc	BlastSumPCalc
#define Cutoffs	BlastCutoffs
#define ExpHighScore	BlastExpHighScore
#define NWSThreshold	BlastNWSThreshold
#define RefinedStats	BlastRefinedStats

#ifdef __cplusplus
}
#endif
#endif /* !__BLAST_KARLIN__ */
