File: fff_gen_stats.c

package info (click to toggle)
nipy 0.1.2%2B20100526-2
  • links: PTS, VCS
  • area: main
  • in suites: squeeze
  • size: 11,992 kB
  • ctags: 13,434
  • sloc: python: 47,720; ansic: 41,334; makefile: 197
file content (122 lines) | stat: -rw-r--r-- 2,442 bytes parent folder | download | duplicates (3)
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
122
#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; 
}