Isis 3 Developer Reference
Ransac.h
Go to the documentation of this file.
1 #ifndef Ransac_h
2 #define Ransac_h
3 
4 #include <math.h>
5 
6 namespace Isis {
7  //functions for solving the normal equations
8  int choleski_solve(double *a, double *b, int nsize, int flag); //solves the normal
9  int inverse (double *a, int nsize); //inverses ata (only to be used after ata has been choleski decomposed by choleski_sovle)
10  int isymp(int row, int col); //used for memory optimized symetric matricies, returns the single dimensional array location equivalent to the 2D location in the symetric matrix
11 
12  int indeces_from_set(int *indeces,int set, int set_size,int n);
13  int binomial_coeficient(int n, int k);
14 
15  inline int isymp(int row, int col)
16  {
17  /* returns the index position of ellement [i][j] in the memory optimized symetric matrix a
18  row -> row in square symetric matrix
19  col -> column in square symetric matrix
20  */
21  int k;
22  ++row;
23  ++col;
24  if(row < col) k= row + col *(col -1)/2;
25  else k= col + row * (row - 1)/2;
26  --k;
27  return k;
28 
29  }
30 
31  inline int binomial_coeficient(int n, int k)
32  {
33  if( k > n)
34  return 0;
35 
36  if( n < 1)
37  return 0;
38 
39  int i,j,bc;
40  bc=1;
41  j=k;
42 
43  for(i=k-1;i>0;i--)
44  {
45  j *= i;
46  }
47 
48 
49  for(i=n-k+1;i<=n;i++)
50  bc *=i;
51 
52  bc/=j;
53 
54  return bc;
55  }
56 
57 
58  /* given a desired set size, and the number of items in the population this function returns the indeces
59  of set number set. For example:
60 
61  set_size = 3 n=5
62 
63  Set Index0 Index1 Index2
64  1 0 1 2
65  2 0 1 3
66  3 0 1 4
67  4 0 1 5
68  5 0 2 3
69  6 0 2 4
70  7 0 2 5
71  8 0 3 4
72  9 0 3 5
73  so indeces_from_set( , 5, 3, 6) would return 0, 2, 3
74 
75  set -> the number of the set starting from 1
76  set_size-> how many are in each set
77  n -> the population size
78  indeces <- the set_size indeces for set number set
79 
80  return 1 if successfuly, otherwise -1
81 
82  */
83  inline int indeces_from_set(int *indeces,int set, int set_size,int n)
84  {
85  //frist set_size must not be greater than n
86  if( set_size > n)
87  return -1;
88 
89  //set must be >= 0
90  if( set < 0)
91  return -1;
92 
93  //set must also be less than or equal to the number of possible sets
94  if( set > binomial_coeficient(n, set_size) )
95  return -1;
96 
97  int i,j,k;
98 
99  for( i =0,j=0;i<set_size-1;i++,j=indeces[i-1]+1)
100  {
101  k = binomial_coeficient( n - j - 1, set_size - i - 1);
102  while( set > k)
103  {
104  j++;
105  set -= k;
106  k = binomial_coeficient( n - j - 1, set_size - i - 1);
107  }
108  indeces[i] = j;
109  }
110 
111  indeces[i] = j+set-1;
112 
113  return 1;
114  }
115 
116 
117  int decompose (double *, int);
118  int foresub (double *,double *, int);
119  int backsub (double *,double *, int);
120 
121 #define SOLVED 1
122 #define NOT_SOLVABLE 0
123 #define NO_ERRORS -1
124 
125 
126  inline int choleski_solve (double *a, double *b, int nsize, int flag)
127  {
128  /* solves the set of linear equations square_matrix(a)delta = b
129  a <-> positive definite symetric matrix a becomes L of the LLt choleski decomposition or the inverse of a (a symetric matrix still in memory optimized mode)
130  b <-> array of doubles of size nsize, the constant part of the system of linear equations
131  nsize -> number of unkowns, also lenght of b, also square(a) is nsize x nsize
132  flag -> type of solutions sought: 1 decomposition only, 2 decomposition and solve, 3 decompose solve and inverse a
133  */
134 
135  if (flag < 1 && flag > 3)
136  return NOT_SOLVABLE;
137 
138  /*************** STEP 1: DECOMPOSE THE A MATRIX ***************/
139  if (! decompose (a, nsize)) return NOT_SOLVABLE;
140 
141  if (flag == 1) return SOLVED;
142 
143  /*************** STEP 2: FORWARD SUBSTITUTION *****************/
144  if (! foresub (a, b, nsize)) return NOT_SOLVABLE;
145 
146 
147  /*************** STEP 2: BACKWARD SUBSTITUTION ****************/
148  if (! backsub (a, b, nsize)) return NOT_SOLVABLE;
149 
150  if (flag == 2) return SOLVED;
151 
152  /*************** STEP 4: INVERSE THE A MATRIX *****************/
153  inverse (a, nsize);
154  return SOLVED;
155  }
156 
157  /*******************************************************************
158  FUNCTION DECOMPOSE
159  *******************************************************************/
160  inline int decompose (double *a, int nsize)
161  {
162  /* decomposes the memory optimized symetric matirx a into LLt (Choleski decomposition)
163  a <-> positive definite symetric matrix a becomes L of the LLt choleski decomposition
164  n -> size of the square matrix a represents or number of unknowns
165  */
166  double sum;
167  double *ap1 = a - 1;
168  double *ap2;
169  double *ap3;
170  double *ap4;
171  double *ap5;
172  double *ap6 = a;
173  double *ap7;
174  int i, j, k, m, n = 2;
175 
176  ap7 = a;
177  for (k = 0; k < nsize; k++)
178  {
179  ap2 = a;
180  ap3 = ap7 + 1;
181  ap4 = a -1;
182  m = 2;
183  for (i = 0; i < k; i++)
184  {
185  sum = 0.0;
186  ap5 = ap1 + 1;
187  ap4++;
188  for (j = 0; j < i; j++)
189  {
190  sum += *ap4++ * *ap5++;
191  }
192  if (*ap2 == 0.0)
193  return NOT_SOLVABLE;
194  *ap3 = (*ap3 - sum) / *ap2;ap3++;
195  ap2 += m++;
196  }
197  sum = 0.0;
198  ap1++;
199  for (j = 0; j < k; j++)
200  {
201  sum += *ap1 * *ap1;ap1++;
202  }
203  /*if ((*ap6 - sum) <= 0.0)
204  return (errcode (06));
205  *ap6 = sqrt(*ap6 - sum);*/
206 
207 
208  //if ((*ap6 - sum) <= 1e-20)
209  if ((*ap6 - sum) <= 0)
210  *ap6 = sqrt(-(*ap6 - sum));
211  else
212  *ap6 = sqrt(*ap6 - sum);
213 
214 
215  ap7 = ap6;
216  ap6 += n++;
217  }
218  return SOLVED;
219  }
220 
221  /*******************************************************************
222  FUNCTION FORESUB
223  *******************************************************************/
224  inline int foresub (double *a,double *b,int nsize)
225  {
226  int i, j;
227  double sum;
228  double *ap1 = a;
229  double *bp1 = b;
230  double *bp2;
231 
232  if (*ap1 == 0.0)
233  return NOT_SOLVABLE;
234  *bp1++ /= *ap1++;
235  for (i = 1; i < nsize; i++)
236  {
237  sum = 0.0;
238  for (j = 0, bp2 = b; j < i; j++)
239  {
240  sum += *ap1++ * *bp2++;
241  }
242  if (*ap1 == 0.0)
243  return NOT_SOLVABLE;
244  *bp1 = (*bp1 - sum) / *ap1;bp1++;ap1++;
245  }
246  return SOLVED;
247  }
248 
249  /*******************************************************************
250  FUNCTION BACKSUB
251  *******************************************************************/
252  inline int backsub (double *a,double *b,int nsize)
253  //double *a,*b;
254  //int nsize;
255  {
256  int i,j;
257  int k = nsize - 1;
258  int m = nsize;
259  int n;
260  double sum;
261  double *ap1 = a + (k + k * (k + 1) / 2);
262  double *ap2 = ap1 - 1;
263  double *ap3;
264  double *bp1 = b + k;
265  double *bp2 = bp1;
266  double *bp3;
267 
268  if (*ap1 == 0.0)
269  return NOT_SOLVABLE;
270  *bp1 = *bp1 / *ap1;bp1--;
271  for (i = k - 1; i >= 0; i--)
272  {
273  sum = 0.0;
274  n = nsize - 1;
275  for (j = nsize - 1, ap3 = ap2--, bp3 = bp2; j >= i + 1; j--)
276  {
277  sum += *ap3 * *bp3--;
278  ap3 -= n--;
279  }
280  ap1 -= m--;
281  if (*ap1 == 0.0)
282  return NOT_SOLVABLE;
283  *bp1 = (*bp1 - sum) / *ap1;bp1--;
284  }
285  return SOLVED;
286  }
287 
288  /*******************************************************************
289  FUNCTION INVERSE
290  *******************************************************************/
291  inline int inverse (double *a, int nsize)
292  //double *a;
293  //int nsize;
294  {
295  int i, j, k, m, n;
296  double sum;
297  double *ap1 = a;
298  double *ap2;
299  double *ap3;
300  double *ap4;
301  double *ap5;
302 
303  /* FIRST INVERSE ALL DIAGONAL ELEMENTS */
304  m = 2;
305  while (ap1 < (a + (nsize * (nsize + 1)/2)))
306  {
307  *ap1 = 1. / *ap1;
308  ap1 += m++;
309  }
310 
311  /* DO FIRST SET OF MANIPULATIONS */
312  ap5 = a + 1;
313  for (i = 1; i < nsize; i++)
314  {
315  ap4 = ap5 - 1;
316  m = i + 1;
317  n = i;
318  for (j = m; j <= nsize; j++)
319  {
320  ap1 = ap5 - 1;
321  ap2 = ap3 = ap4 + i;
322  sum = 0.0;
323  for (k = i; k <= n;)
324  {
325  sum += *ap1 * *ap2++;
326  ap1 += k++;
327  }
328  ap4 += j;
329  *ap3 = -(*ap4) * sum;
330  n = j;
331  }
332  ap5 += m;
333  }
334 
335  /* DO SECOND SET OF MANIPULATIONS */
336  n = 0;
337  ap1 = ap2 = ap3 = ap4 = a;
338  for (i = 0; i < nsize;)
339  {
340  ap5 = ap4;
341  m = 0;
342  for (j = i; j < nsize;)
343  {
344  ap5 += j;
345  ap1 = ap3 = ap5 + i + n;
346  ap2 = ap5 + m++;
347  sum = 0.0;
348  for (k = j; k < nsize;)
349  {
350  sum += *ap1 * *ap2;
351  ap1 += ++k;
352  ap2 += k;
353  }
354  *ap3 = sum;
355  j++;
356  }
357  ap4 += ++i;
358  n--;
359  }
360  return SOLVED;
361  }
362 }
363 
364 #endif
int backsub(double *, double *, int)
Definition: Ransac.h:252
int choleski_solve(double *a, double *b, int nsize, int flag)
Definition: Ransac.h:126
int binomial_coeficient(int n, int k)
Definition: Ransac.h:31
#define NOT_SOLVABLE
Definition: Ransac.h:122
int decompose(double *, int)
Definition: Ransac.h:160
int inverse(double *a, int nsize)
Definition: Ransac.h:291
int isymp(int row, int col)
Definition: Ransac.h:15
int foresub(double *, double *, int)
Definition: Ransac.h:224
int indeces_from_set(int *indeces, int set, int set_size, int n)
Definition: Ransac.h:83
#define SOLVED
Definition: Ransac.h:121
Namespace for ISIS/Bullet specific routines.
Definition: Apollo.h:31