#include "mrilib.h"

/*------------------------------------------------------------
  Set the one-sided tail probability at which we will cutoff
  the unusuality test.
--------------------------------------------------------------*/

static float zstar = 0.0 ;            /* the actual cutoff */
static float pstar = 0.0 ;            /* tail probability  */

void set_unusuality_tail( float p )
{
   if( p > 0.0 && p < 1.0 ){
      zstar = qginv(p) ;
      pstar = p ;
   }
   return ;
}

#define NEAR1 0.999

/*------------------------------------------------------------
  Inputs:  rr[0..nr-1] = array of correlation coefficients.
  Outputs: ihi[0..*nhi-1] = indexes of highly correlations
             from rr.  ihi must be declared at least length
             nr to allow for the worst case.
--------------------------------------------------------------*/

void find_unusual_correlations( int nrin  , float * rr ,
                                int * nhi , int * ihi   )
{
   register int ii,jj,nr ;
   register float *zz ;
   float zmid,zsig,zmed , rmid,rcut ;

   if( nhi == NULL ) return ;  /* illegal entry */

   *nhi = 0 ;                  /* default return */

   if( nrin < 1000 || rr == NULL || ihi == NULL  ) return ;  /* illegal entry */

   /*-- make workspace --*/

   zz = (float *) malloc(sizeof(float)*nrin) ;

   if( zstar <= 0.0 ){               /* initialize zstar if needed */
      char * cp = getenv("PTAIL") ;
      float pp = 0.0001 ;
      if( cp != NULL ){
         float xx = strtod( cp , NULL ) ;
         if( xx > 0.0 && xx < 1.0 ) pp = xx ;
      }
      set_unusuality_tail( pp ) ;
   }

   /*-- copy data into workspace (eliding 1's) --*/

   for( ii=jj=0 ; ii < nrin ; ii++ )
      if( rr[ii] <= NEAR1 ) zz[jj++] = rr[ii] ;
   nr = jj ;
   if( nr < 2 ){ free(zz); return; } /* shouldn't happen */

   rmid = qmed_float( nr , zz ) ;  /* median of correlations */
   zmid = atanh(rmid) ;            /* median of atanh(rr) */

   /*-- zz <- fabs( tanh( atanh(zz) - atanh(rmid) ) ) --*/

   for( ii=0 ; ii < nr ; ii++ )
      zz[ii] = fabs( (zz[ii]-rmid)/(1.0-zz[ii]*rmid) ) ;

   /*-- find MAD of atanh(rr) --*/

   zmed = qmed_float( nr , zz ) ; /* MAD = median absolute deviation of rr */
   zmed = atanh(zmed) ;           /* MAD of atanh(rr) */
   zsig = 1.4826 * zmed ;         /* estimate standard dev. of atanh(rr) */
                                  /* 1.4826 = 1/(sqrt(2)*erfinv(0.5))    */
   free(zz) ;

   if( zsig <= 0.0 ) return ; /* shouldn't happen */

   /*-- find values of correlation greater than threshold --*/
   /*-- that is, with (atanh(rr)-zmid)/zsig > zstar       --*/

   rcut = tanh( zsig*zstar + zmid ) ;

   for( ii=jj=0 ; ii < nrin ; ii++ )
      if( rr[ii] >= rcut && rr[ii] <= NEAR1 ) ihi[jj++] = ii ;

   *nhi = jj ; return ;
}


syntax highlighted by Code2HTML, v. 0.9.1