#ifndef frb_correlations_H
#define frb_correlations_H

/* Prototypes and definitions for {frb_correlations.c} */
/* Last edited on 2007-01-04 00:13:47 by stolfi */

#include <frb_types.h>
#include <frb_signal.h>
#include <frb_segment.h>
#include <frb_candidate.h>
#include <frb_curve.h>
#include <frb_match.h>

#include <argparser.h>
#include <r3.h>

#include <stdio.h>
#include <values.h>

/* 
  A /curve/ is a string of points of {R^2}, possibly circular.
  
  A /signal/ is a list of real values.
  
  A /segment/ is a substring of a curve.
  
  A /candidate/ is a pair of segments.
  
*/

typedef struct frb_options_t
  { 
    /* Arguments for correlation analysis: */
    char **xFile;      /* Input {X} signal file names (WITH extensions). */
    int ixMin;         /* First sample to consider in each {X} signal.  */
    int ixMax;         /* Last sample to consider in each {X} signal.  */
    char **yFile;      /* Input {Y} signal file names (WITH extensions). */
    int iyMin;         /* First sample to consider in each {Y} signal.  */
    int iyMax;         /* Last sample to consider in each {Y} signal.  */
    char *avgFile;     /* Input average file name (WITH extension) or "". */
  } frb_options_t; 

void frb_analyze_correlations
  (
    frb_signal_t *sx,   /* Signals to use as the {X} axis. */
    frb_signal_t *avgx, /* {avgx->el[i]} is mean value of {sx[k].el[i]} */
    int ixMin,               /* Minimum index {i} for {sx} signals. */
    int ixMax,               /* Maximum index {i} for {sx} signals. */
    frb_signal_t *sy,   /* Signals to use as the {Y} axis. */
    frb_signal_t *avgy, /* {avgy->el[j]} is mean value of {sy[k].el[j]}. */
    int iyMin,               /* Minimum index {j} for {sy} signals. */
    int iyMax,               /* Maximum index {j} for {sy} signals. */
    int nf                   /* Number of signals. */
  );
  /* Computes and prints the covariance matrices {cov[i,j]} between
     the sequences {x[k] = sx[k].el[i]} and {y[k] = sy[k].el[j]}.
     Assumes that their average values are {avgx->el[i]} and
     {avgy->el[j]}, respectively; if either of these vectors is empty,
     assumes that the corresponding means are 0. */

  /* Computes the covariances between elements of a bunch of real signals. */

  /*
    Given a set of signals {p_k}, all with the same number {ns} of elements,
    this program prints the covariance and correlation matrices
    for pairs of elements.

    The covariance {cov[i,j]} of elements {i} and {j} is defined as the
    average of the products {(p_k[i]-m[i])*(p_k[j]-m[j])},
    over all signals {p_k}, where {m[i]} is a user-provided
    average signal (all zero by default).

    The correlation {r[i,j]} between elements {i} and {j}
    is defined as {cov[i,j]/sqrt(cov[i,i]*cov[j,j])}.  It can be
    thought of as the co-sine of the angle between the vector
    {u}, consisting of the {i}th elements of all signals {p_k},
    and the vector {v} consisting of the {j}th elements of
    all those signals.

    Due to memory and time limitations, it is usually necessary
    to consider only a subset of the elements present in the input
    signals. Thus the program considers only elements {p_k[iMin..iMax]}
    where {iMin} and {iMax} are specified by the user.

    The element indices are taken modulo {ns}; thus if the input signals
    are Fourier transforms in the `smart' basis (see PZFourier.i3), one
    would usually want to specify {iMin = -iMax} in order to get all
    Fourier components with frequency up to iMax.
  */

void frb_extract_elements
  ( frb_signal_t *s,
    frb_signal_t *avg,
    int iMin,
    int iMax,
    double *v
  );
  /* Stores in {v[0..iMax-iMin]} the elements {s->el[iMin..imax]}
    minus the corresponding means {avg->el[iMin..iMax]}. */

void frb_print_covariances
  ( double *cov,    /* Matrix of covariances. */
    double *varx,   /* Variances of {X} variables. */
    int ixMin,      /* Actual initial {X} index. */
    int ixMax,      /* Actual final {X} index. */
    double *vary,   /* Variances of {Y} variables. */
    int iyMin,      /* Actual initial {Y} index. */
    int iyMax       /* Actual final {Y} index. */
  );
  /* ??? */

void frb_print_correlations
  ( double *cov,    /* Matrix of covariances. */
    double *varx,   /* Variances of {X} variables. */
    int ixMin,      /* Actual initial {X} index. */
    int ixMax,      /* Actual final {X} index. */
    double *vary,   /* Variances of {Y} variables. */
    int iyMin,      /* Actual initial {Y} index. */
    int iyMax       /* Actual final {Y} index. */
  );
  /* ??? */

void frb_print_headers(char *title, int iMin, int iMax, int width, bool_t vars);
  /* Prints headers for correlation/covariance matrices. */

void frb_choose_element_format
  (
    double *cov,
    double *varx,
    int nx,
    double *vary,
    int ny,
    int *widthp,
    int *precp,
    char **fmtp
  );
  /* ??? */

frb_options_t *frb_get_options(int argc, char **argv);
  /* Parses the command line options. */

frb_signal_t *frb_read_n_signals
  ( int nFiles,
    int nSamples,
    char **file,
    bool_t log
  );
  /* Reads files {file[0..nFiles-1]}, which must all contain signals
    with {nSamples} samples. */

#endif
