diff options
| author | Jaron Kent-Dobias <jaron@kent-dobias.com> | 2017-11-02 23:00:48 -0400 | 
|---|---|---|
| committer | Jaron Kent-Dobias <jaron@kent-dobias.com> | 2017-11-02 23:00:48 -0400 | 
| commit | f3d53bac095fd47f7c10f54007ffa11ab0f1ac1f (patch) | |
| tree | f940e6255b77a76051b4464db9972f400fc89699 /lib | |
| parent | 30534606d5690e176d168f640f55162fa15f0a19 (diff) | |
| download | c++-f3d53bac095fd47f7c10f54007ffa11ab0f1ac1f.tar.gz c++-f3d53bac095fd47f7c10f54007ffa11ab0f1ac1f.tar.bz2 c++-f3d53bac095fd47f7c10f54007ffa11ab0f1ac1f.zip | |
added new method for computing autocorrelation
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/convex.c | 93 | ||||
| -rw-r--r-- | lib/convex.h | 21 | ||||
| -rw-r--r-- | lib/wolff.h | 1 | 
3 files changed, 115 insertions, 0 deletions
| diff --git a/lib/convex.c b/lib/convex.c new file mode 100644 index 0000000..33af1b4 --- /dev/null +++ b/lib/convex.c @@ -0,0 +1,93 @@ + +#include "convex.h" + +double slope(point_t *P, point_t *Q) { +  return (Q->y - P->y) / ((double)(Q->x) - (double)(P->x)); +} + +double *get_convex_minorant(uint64_t n, double *Gammas) { +  list_t *L = (list_t *)calloc(1, sizeof(list_t)); +  L->p = (point_t *)calloc(1, sizeof(point_t)); +  L->p->x = 0; +  L->p->y = Gammas[0]; + +  list_t *pos = L; + +  for (uint64_t i = 1; i < n; i++) { +    pos->next = (list_t *)calloc(1, sizeof(list_t)); +    pos->next->p = (point_t *)calloc(1, sizeof(point_t)); +    pos->next->p->x = i; +    pos->next->p->y = Gammas[i]; +    pos->next->prev = pos; +    pos = pos->next; +  } + +  pos->next = (list_t *)calloc(1, sizeof(list_t)); +  pos->next->p = (point_t *)calloc(1, sizeof(point_t)); +  pos->next->p->x = n; +  pos->next->p->y = 0; +  pos->next->prev = pos; + +  list_t *X = L; +  list_t *Y = L->next; +  list_t *Z = Y->next; + +  while (true) { +    if (slope(X->p, Y->p) <= slope(Y->p, Z->p)) { +      X = Y; +      Y = Z; +      if (Z->next == NULL) { +        break; +      } else { +        Z = Z->next; +      } +    } else { +      Y->prev->next = Y->next; +      Y->next->prev = Y->prev; +      free(Y->p); +      free(Y); +      if (X->prev != NULL) { +        Y = X; +        X = X->prev; +      } else { +        if (Z->next != NULL) { +          Y = Z; +          Z = Z->next; +        } else { +          break; +        } +      } +    } +  } + +  pos = L; + +  double *g = (double *)calloc(n, sizeof(double)); +  double rho = 0; + +  for (uint64_t i = 0; i < n; i++) { +    if (i > pos->next->p->x) { +      pos = pos->next; +    } + +    g[i] = pos->p->y + ((double)i - (double)(pos->p->x)) *  (pos->next->p->y - pos->p->y) / ((double)(pos->next->p->x) - (double)(pos->p->x)); + +    if (Gammas[i] - g[i] > rho) { +      rho = Gammas[i] - g[i]; +    } +  } + +  for (uint64_t i = 0; i < n; i++) { +    g[i] += rho / 2; +  } + +  while (L != NULL) { +    free(L->p); +    list_t *L_save = L; +    L = L->next; +    free(L); +  } + +  return g; +} + diff --git a/lib/convex.h b/lib/convex.h new file mode 100644 index 0000000..29f4ae0 --- /dev/null +++ b/lib/convex.h @@ -0,0 +1,21 @@ + +#pragma once + +#include <inttypes.h> +#include <stdbool.h> +#include <stdlib.h> +#include <string.h> + +typedef struct { +  uint64_t x; +  double y; +} point_t; + +typedef struct list_tag { +  struct list_tag *prev; +  struct list_tag *next; +  point_t *p; +} list_t; + +double *get_convex_minorant(uint64_t n, double *Gammas); + diff --git a/lib/wolff.h b/lib/wolff.h index 66ce493..dfe7b1c 100644 --- a/lib/wolff.h +++ b/lib/wolff.h @@ -17,6 +17,7 @@  #include <jst/rand.h>  #include "queue.h" +#include "convex.h"  typedef enum {    WOLFF, | 
