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

#include "RegressionLineaire.h"

RegressionLineaire::RegressionLineaire(void) {
  sz = 100;
  sp = 0;
  x =(double *) calloc(sz,sizeof(double));
  y =(double *) calloc(sz,sizeof(double));
}

RegressionLineaire::RegressionLineaire(int sz) {
  this->sz = sz;
  sp = 0;
  x =(double *) calloc(sz,sizeof(double));
  y =(double *) calloc(sz,sizeof(double));
}

RegressionLineaire::~RegressionLineaire(void) {
  free(x);
  free(y);
}

int RegressionLineaire::add(double v1,double v2) {
  if ( sp < sz ) {
    x[sp] = v1;
    y[sp] = v2;
    sp++;
    return(1); }
    else {
    return(0); }
}

int RegressionLineaire::nombreValeurs(void) {
  return(sp);
}

double RegressionLineaire::getCoefficientDirecteur(void) {
  double mx = 0.0;
  double my = 0.0;
  for ( int i = 0 ; i < sp ; i++ ) {
    mx += x[i];
    my += y[i]; }
  mx /= sp;
  my /= sp;
  double varx = 0.0;
  double vary = 0.0;
  for ( int i = 0 ; i < sp ; i++ ) {
    varx += (x[i]-mx)*(x[i]-mx);
    vary += (y[i]-my)*(y[i]-my); }
  varx /= sp;
  vary /= sp;
  double cov = 0.0;
  for ( int i = 0 ; i < sp ; i++ ) {
    cov += (x[i]-mx)*(y[i]-my); }
  cov /= sp;
  double a = cov/varx;
  return(a);
}

double RegressionLineaire::getZeroOrigine(void) {
  double mx = 0.0;
  double my = 0.0;
  for ( int i = 0 ; i < sp ; i++ ) {
    mx += x[i];
    my += y[i]; }
  mx /= sp;
  my /= sp;
  double varx = 0.0;
  double vary = 0.0;
  for ( int i = 0 ; i < sp ; i++ ) {
    varx += (x[i]-mx)*(x[i]-mx);
    vary += (y[i]-my)*(y[i]-my); }
  varx /= sp;
  vary /= sp;
  double cov = 0.0;
  for ( int i = 0 ; i < sp ; i++ ) {
    cov += (x[i]-mx)*(y[i]-my); }
  cov /= sp;
  double a = cov/varx;
  double b = my-a*mx;
  return(b);
}

double RegressionLineaire::getCoefficientCorrelationLineaire(void) {
  double mx = 0.0;
  double my = 0.0;
  for ( int i = 0 ; i < sp ; i++ ) {
    mx += x[i];
    my += y[i]; }
  mx /= sp;
  my /= sp;
  double varx = 0.0;
  double vary = 0.0;
  for ( int i = 0 ; i < sp ; i++ ) {
    varx += (x[i]-mx)*(x[i]-mx);
    vary += (y[i]-my)*(y[i]-my); }
  varx /= sp;
  vary /= sp;
  double cov = 0.0;
  for ( int i = 0 ; i < sp ; i++ ) {
    cov += (x[i]-mx)*(y[i]-my); }
  cov /= sp;
  double ectx = sqrt(varx);
  double ecty = sqrt(vary);
  double r = cov /(ectx*ecty);
  return(r);
}

void RegressionLineaire::getCoefficients(double *cd,double *zo,double *cc) {
  double mx = 0.0;
  double my = 0.0;
  for ( int i = 0 ; i < sp ; i++ ) {
    mx += x[i];
    my += y[i]; }
  mx /= sp;
  my /= sp;
  double varx = 0.0;
  double vary = 0.0;
  for ( int i = 0 ; i < sp ; i++ ) {
    varx += (x[i]-mx)*(x[i]-mx);
    vary += (y[i]-my)*(y[i]-my); }
  varx /= sp;
  vary /= sp;
  double cov = 0.0;
  for ( int i = 0 ; i < sp ; i++ ) {
    cov += (x[i]-mx)*(y[i]-my); }
  cov /= sp;
  *cd = cov/varx;
  *zo = my-*cd*mx;
  double ectx = sqrt(varx);
  double ecty = sqrt(vary);
  *cc = cov /(ectx*ecty);
}

int RegressionLineaire::nombreValeurs(double min,double max) {
  int cpt = 0;
  for ( int i = 0 ; i < sp ; i++ ) {
    if ( ( x[i] >= min ) && ( x[i] <= max ) )
      cpt++; }
  return(cpt);
}

double RegressionLineaire::getCoefficientDirecteur(double min,double max) {
  double mx = 0.0;
  double my = 0.0;
  int cpt = 0;
  for ( int i = 0 ; i < sp ; i++ ) {
    if ( ( x[i] >= min ) && ( x[i] <= max ) ) {
      cpt++;
      mx += x[i];
      my += y[i]; } }
  mx /= cpt;
  my /= cpt;
  double varx = 0.0;
  double vary = 0.0;
  for ( int i = 0 ; i < sp ; i++ ) {
    if ( ( x[i] >= min ) && ( x[i] <= max ) ) {
      varx += (x[i]-mx)*(x[i]-mx);
      vary += (y[i]-my)*(y[i]-my); } }
  varx /= cpt;
  vary /= cpt;
  double cov = 0.0;
  for ( int i = 0 ; i < sp ; i++ ) {
    if ( ( x[i] >= min ) && ( x[i] <= max ) ) {
      cov += (x[i]-mx)*(y[i]-my); } }
  cov /= cpt;
  double a = cov/varx;
  return(a);
}

double RegressionLineaire::getZeroOrigine(double min,double max) {
  double mx = 0.0;
  double my = 0.0;
  int cpt = 0;
  for ( int i = 0 ; i < sp ; i++ ) {
    if ( ( x[i] >= min ) && ( x[i] <= max ) ) {
      cpt++;
      mx += x[i];
      my += y[i]; } }
  mx /= cpt;
  my /= cpt;
  double varx = 0.0;
  double vary = 0.0;
  for ( int i = 0 ; i < sp ; i++ ) {
    if ( ( x[i] >= min ) && ( x[i] <= max ) ) {
      varx += (x[i]-mx)*(x[i]-mx);
      vary += (y[i]-my)*(y[i]-my); } }
  varx /= cpt;
  vary /= cpt;
  double cov = 0.0;
  for ( int i = 0 ; i < sp ; i++ ) {
    if ( ( x[i] >= min ) && ( x[i] <= max ) ) {
      cov += (x[i]-mx)*(y[i]-my); } }
  cov /= cpt;
  double a = cov/varx;
  double b = my-a*mx;
  return(b);
}

double RegressionLineaire::getCoefficientCorrelationLineaire(double min,double max) {
  double mx = 0.0;
  double my = 0.0;
  int cpt = 0;
  for ( int i = 0 ; i < sp ; i++ ) {
    if ( ( x[i] >= min ) && ( x[i] <= max ) ) {
      cpt++;
      mx += x[i];
      my += y[i]; } }
  mx /= cpt;
  my /= cpt;
  double varx = 0.0;
  double vary = 0.0;
  for ( int i = 0 ; i < sp ; i++ ) {
    if ( ( x[i] >= min ) && ( x[i] <= max ) ) {
      varx += (x[i]-mx)*(x[i]-mx);
      vary += (y[i]-my)*(y[i]-my); } }
  varx /= cpt;
  vary /= cpt;
  double cov = 0.0;
  for ( int i = 0 ; i < sp ; i++ ) {
    if ( ( x[i] >= min ) && ( x[i] <= max ) ) {
      cov += (x[i]-mx)*(y[i]-my); } }
  cov /= cpt;
  double ectx = sqrt(varx);
  double ecty = sqrt(vary);
  double r = cov /(ectx*ecty);
  return(r);
}

void RegressionLineaire::getCoefficients(double min,double max,double *cd,double *zo,double *cc) {
  double mx = 0.0;
  double my = 0.0;
  int cpt = 0;
  for ( int i = 0 ; i < sp ; i++ ) {
    if ( ( x[i] >= min ) && ( x[i] <= max ) ) {
      cpt++;
      mx += x[i];
      my += y[i]; } }
  mx /= cpt;
  my /= cpt;
  double varx = 0.0;
  double vary = 0.0;
  for ( int i = 0 ; i < sp ; i++ ) {
    if ( ( x[i] >= min ) && ( x[i] <= max ) ) {
      varx += (x[i]-mx)*(x[i]-mx);
      vary += (y[i]-my)*(y[i]-my); } }
  varx /= cpt;
  vary /= cpt;
  double cov = 0.0;
  for ( int i = 0 ; i < sp ; i++ ) {
    if ( ( x[i] >= min ) && ( x[i] <= max ) ) {
      cov += (x[i]-mx)*(y[i]-my); } }
  cov /= cpt;
  *cd = cov/varx;
  *zo = my-*cd*mx;
  double ectx = sqrt(varx);
  double ecty = sqrt(vary);
  *cc = cov /(ectx*ecty);
}

void RegressionLineaire::reinitialisation(void) {
  sp = 0;
}
