#include <stdio.h>
#include <math.h>

#define MAXTAR  10000
#define MAXNON  100000
#define MAXPTS  120000

#define PMIN    0.0005
#define PMAX    0.5

main (argc, argv)

int argc;
char *argv[];


  {
  FILE *tarfile;
  FILE *nonfile;
  FILE *outfile;
  FILE *bestfile;
  char filename[100];

  double tar[MAXTAR];
  double non[MAXNON];
  double *tarptr = tar;
  double *nonptr = non;
  int i;
  double pts[MAXPTS][2];
  int npts;
  double DCF_best[5];

  tarfile = fopen (argv[1], "r");
  while (fscanf (tarfile, "%lf \n", tarptr) > 0)
    tarptr++;

  fclose (tarfile);

  nonfile = fopen (argv[2], "r");
  while (fscanf (nonfile, "%lf \n", nonptr) > 0)
    nonptr++;
  fclose (nonfile);

  Compute_ROC (tar, tarptr - tar, non, nonptr - non, pts, &npts, DCF_best);

  outfile = fopen (argv[3], "w");
  for (i = 0; i < npts; i++)
    fprintf (outfile, "%lf %lf \n", pts[i][0], pts[i][1]);
    
  fclose (outfile);

  bestfile = fopen (strcat (strcpy (filename, argv[3]), ".points"), "w");

  fprintf (bestfile, "%lf %lf %lf %lf %lf \n", DCF_best[0], DCF_best[1], DCF_best[2],DCF_best[3], DCF_best[4]);
  fclose (bestfile);

  }


/*

The Compute_ROC function that I sent to you has a slight error -- it wasn't computing
the last point on the Pmiss/Pfa probability trade-off curve.  This is corrected in the
version below.  Also, we've been thinking about what to call these plots that makes
better intuitive sense.  I've sort of decided on "DET" or DErT" curves, which stands
for "Detection Error Trade-off" curves.  This really does express what we are plotting,
namely the Trade-off between the two kinds of Errors (Pmiss/Pfa) for Detection tasks.

::::::::::::::
Compute_ROC.m -- corrected
::::::::::::::
function Pdet = Compute_ROC (true_scores, false_scores)
%function Pdet = Compute_ROC (true_scores, false_scores)
%
%  Compute_ROC computes the miss/false_alarm probability trade-off
%  for a set of scores for the true/false detection hypothesis.
%
%  true_scores (false_scores) are detection output scores for a set of
%  detection trials, given that the target hypothesis is true (false).
%  (It is assumed by convention that the more positive the score, the
%  more likely is the target hypothesis.)
%
%  Pdet is a two-column matrix containing the detection probability
%  trade-off.  The first column contains the miss probabilities and
%  the second column contains the corresponding false alarm
%  probabilities.
%
%  See also Make_pROC, Plot_pROC, and Set_DCF.

*/

#define SMAX  9E99

#define Cmiss    10.0
#define Cfa      1.0
#define Ptrue    0.01
#define Pfalse   0.99

Compute_ROC (true_scores, num_true, false_scores, num_false, Pdet, num_Pdet, DCF_best)

double true_scores[];
int num_true;
double false_scores[];
int num_false;
double Pdet[][2];
int *num_Pdet;
double DCF_best[];

/*
clear true_sorted false_sorted

%-------------------------
%Compute ROC

*/

{
double ppndf();
int dlbdiff ();

int ntrue;
int nfalse;
int npts;

double dcf, dcf_miss, dcf_fa;

qsort ((char *) true_scores, num_true, sizeof (double), dlbdiff);
true_scores[num_true] = SMAX;

qsort ((char *) false_scores, num_false, sizeof (double), dlbdiff);
false_scores[num_false] = SMAX;



ntrue = 1;
nfalse = 1;
npts = 0;
Pdet[npts][0] = ppndf (PMIN);
Pdet[npts][1] = ppndf (PMAX);

DCF_best[0] = Cfa * Pfalse;
DCF_best[1] = 0.0;
DCF_best[2] = 1.0;
DCF_best[3] = 0.0;
DCF_best[4] = 0.0;

while ((ntrue < num_true) || (nfalse < num_false))
        {
/* printf ("ntrue = %d, nfalse = %d, npts = %d, trsc = %lf, fasc =%lf\n",
 ntrue, nfalse, npts, true_scores[ntrue], false_scores[nfalse]); */

	if ((true_scores[ntrue] <= false_scores[nfalse]) &&
	    (ntrue < num_true))
		ntrue = ntrue+1;
	else
		nfalse = nfalse+1;
/*	end */
	npts = npts+1;
	Pdet[npts][0] =   ((double) (ntrue-1) / (double) num_true);
	Pdet[npts][1] =   ((double) (num_false - (nfalse-1)) / (double) num_false);

        dcf = (Cmiss * Pdet[npts][0] * Ptrue) + (Cfa * Pdet[npts][1] * Pfalse);
        dcf_miss = (Cmiss * Pdet[npts][0] * Ptrue);
	dcf_fa = (Cfa * Pdet[npts][1] * Pfalse);

        if (dcf < DCF_best[0])
	  {
          DCF_best[3] = dcf_miss;
          DCF_best[4] = dcf_fa;
          DCF_best[0] = dcf;
          DCF_best[1] = Pdet[npts][0];
          DCF_best[2] = Pdet[npts][1];
          }
     
/******** REMOVE BOUNDRIES ************
        if (Pdet[npts][0] < PMIN)
          Pdet[npts][0] = PMIN;
        if (Pdet[npts][0] > PMAX)
          Pdet[npts][0] = PMAX;
        if (Pdet[npts][1] < PMIN)
          Pdet[npts][1] = PMIN;
        if (Pdet[npts][1] > PMAX)
          Pdet[npts][1] = PMAX;
**************************************/
        Pdet[npts][0] = ppndf (Pdet[npts][0]);
        Pdet[npts][1] = ppndf (Pdet[npts][1]);

/* printf ("point %lf %lf\n", Pdet[npts][0], Pdet[npts][1]); */
        }

*num_Pdet = npts + 1;

/******* REMOVE THE LIMITING FUNCTION?  *********
if (DCF_best[1] < PMIN)
  DCF_best[1] = PMIN;
if (DCF_best[1] > PMAX)
  DCF_best[1] = PMAX;
if (DCF_best[2] < PMIN)
  DCF_best[2] = PMIN;
if (DCF_best[2] > PMAX)
  DCF_best[2] = PMAX;
 **
*************************************************/

DCF_best[1] = ppndf (DCF_best[1]);
DCF_best[2] = ppndf (DCF_best[2]);

printf ("ntrue = %d, nfalse = %d, npts = %d\n", ntrue, nfalse, *num_Pdet);
}




/* compare function for qsort */
int dlbdiff (a, b)
 
double *a;
double *b;
 
{
  float val = *a - *b;
 
  if (val < 0)
    return (-1);
 
  if (val == 0)
    return (0);
 
  if (val > 0)
    return (1);
 
}



/*

Convert lines with ROC coordinates to normal deviate scale.

Ignore lines beginning with "#" (9/26/94)

*/


#define abs(x)  (x < 0  ?  -x : x)

#define SPLIT      0.42

#define A0      2.5066282388
#define A1    -18.6150006252
#define A2     41.3911977353
#define A3    -25.4410604963
#define B1     -8.4735109309
#define B2     23.0833674374
#define B3    -21.0622410182
#define B4      3.1308290983
#define C0     -2.7871893113
#define C1     -2.2979647913
#define C2      4.8501412713
#define C3      2.3212127685
#define D1      3.5438892476
#define D2      1.6370678189

#define LL      140

#define eps     2.2204e-16

double ppndf (p)

double p;

  {
  double q;  
  double r;
  double retval;


/* printf ("p = %f\n", p); */

  if (p >= 1.0)
    p = 1 - eps;
  if (p <= 0.0)
    p = eps;

  q = p - 0.5;
  if (abs(q) <= SPLIT)
    {
    r = q * q;
    retval = q * (((A3 * r + A2) * r + A1) * r + A0) /
             ((((B4 * r + B3) * r + B2) * r + B1) * r + 1.0);
    }

  else

    {
/*
    r = sqrt (log (0.5 - abs(q)));
*/

    r = (q > 0.0  ?  1.0 - p : p);
    if (r <= 0.0)
      {
      printf ("Found r = %f\n", r);
      return;
      }
    
    r = sqrt ((-1.0) * log (r));

    retval = (((C3 * r + C2) * r + C1) * r + C0) /
             ((D2 * r + D1) * r + 1.0);
    if (q < 0)
      retval *= -1.0;
    }

    return (retval);

  }
