File: fff_gen_stats.c

package info (click to toggle)
nipy 0.6.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 7,352 kB
  • sloc: python: 39,115; ansic: 30,931; makefile: 210; sh: 93
file content (121 lines) | stat: -rw-r--r-- 2,373 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#include "fff_gen_stats.h"
#include "fff_lapack.h"

#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <errno.h>

#include <stdio.h>

/*
  Generate a random permutation from [0..n-1].
*/
extern void fff_permutation(unsigned int* x, unsigned int n, unsigned long magic)
{
  unsigned int* xi, i, ir, j, tmp, nc;
  unsigned long int m = magic;

  /* Initialize x as the identity permutation */
  for(i=0, xi=x; i<n; i++, xi++)
    *xi = i;

  /* Draw numbers iteratively and rearrange the array */
  for(i=0, nc=n; i<n; i++, nc--) {

    /* Draw j in range [i..n[ */
    ir = m % nc;
    m = m / nc;
    j = ir + i;

    /* Move x[j] to i-th index and shift indices in range [i..j[ to
       the right */
    tmp = x[j];
    xi = x + i;
    memmove((void*)(xi+1), (void*)xi, ir*sizeof(unsigned int));
    *xi = tmp;

  }

  return;
}


/*
  Generate a random combination of k elements in [0..n-1].
  x must be pre-allocated with size k.
*/

static unsigned long int _combinations(unsigned int k, unsigned int n)
{
  unsigned long int c, i, aux;

  /* Compute the total number of combinations: Cn,k */
  aux = n - k;
  for (i=1, c=1; i<=k; i++) {
    c *= (aux+i);
    c /= i;
  }

  return FFF_MAX(c, 1);
}

extern void fff_combination(unsigned int* x, unsigned int k, unsigned int n, unsigned long magic)
{
  unsigned long int kk, nn, i;
  unsigned long int m = magic;
  unsigned int *bx = x;
  unsigned long int c;

  /* Ensure 0 <= magic < Cn,k */
  c = _combinations(k, n);
  m = magic % c;

  /* Loop. At the beginning of each iteration, c == Cn-(i+1),k-(i+1). */
  i = 0;
  kk = k;
  nn = n;
  kk = k;
  while( kk > 0 ) {

    nn --;
    c = _combinations(kk-1, nn);

    /* If i is accepted, then store it and do: kk-- */
    if ( m < c ) {
      *bx = i;
      bx ++;
      kk --;
    }
    else
      m = m - c;

     /* Next candidate */
    i ++;

  }

  return;
}


/*
   Squared mahalanobis distance: d2 = x' S^-1 x
   Beware: x is not const
*/
extern double fff_mahalanobis(fff_vector* x, fff_matrix* S, fff_matrix* Saux)
{
  double d2;
  double m = 0.0;

  /* Cholesky decomposition: S = L L^t, L lower triangular */
  fff_lapack_dpotrf(CblasLower, S, Saux);

  /* Compute S^-1 x */
  fff_blas_dtrsv(CblasLower, CblasNoTrans, CblasNonUnit, S, x); /* L^-1 x */

  /* Compute x' S^-1 x */
  d2 = (double) fff_vector_ssd(x, &m, 1);

  return d2;
}