LAL  7.5.0.1-08ee4f4
EllipsoidOverlapTools.c
Go to the documentation of this file.
1 /*
2 * Copyright (C) 2007 Anand Sengupta, Craig Robinson
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with with program; see the file COPYING. If not, write to the
16 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17 * MA 02110-1301 USA
18 */
19 
20 /*-----------------------------------------------------------------------
21  *
22  * File Name: EllipsoidOverlapTools.c
23  *
24  * Author: Anand S. Sengupta and Craig Robinson
25  *
26  *
27  *-----------------------------------------------------------------------
28  */
29 
30 #include <lal/EllipsoidOverlapTools.h>
31 
32 static REAL8 fContact (REAL8 x, void *params);
33 
34 /* ---------------------------------------------------------------------------
35  * This function return the contact function of two ellipsoids as defined in
36  * the paper by Perram & Wertheim, JCP, v58, pp 409-416, eq 3.7 with a
37  * negative sign. This is minimised to figure out if the ellipsoids
38  * intersect.
39  * --------------------------------------------------------------------------*/
40 
41 
42 
43 static REAL8 fContact (REAL8 x, void *params)
44 {
46  = (fContactWorkSpace *)params;
47 
48  gsl_permutation *p1 = p->p1;
49  gsl_vector *tmpV = p->tmpV;
50  gsl_matrix *C = p->C;
51  gsl_matrix *A = p->tmpA;
52  gsl_matrix *B = p->tmpB;
53 
54  INT4 s1;
55  REAL8 result;
56 
57  gsl_matrix_memcpy ( A, p->invQ1);
58  gsl_matrix_memcpy ( B, p->invQ2);
59 
60  gsl_matrix_scale (B, x);
61  gsl_matrix_scale (A, (1.0L-x));
62 
63  gsl_matrix_add (A, B);
64 
65  gsl_linalg_LU_decomp( A, p1, &s1 );
66  gsl_linalg_LU_invert( A, p1, C );
67 
68  /* Evaluate the product C x r_AB */
69  gsl_blas_dsymv (CblasUpper, 1.0, C, p->r_AB, 0.0, tmpV);
70 
71  /* Now evaluate transpose(r_AB) x (C x r_AB) */
72  gsl_blas_ddot (p->r_AB, tmpV, &result);
73 
74  result *= (x*(1.0L-x));
75 
76  return (-result);
77 }
78 
79 /*
80 -------------------------------------------------------------------------
81  * This function allocates and initialises the memory and parameters for
82  * the workspace used for determining whether the two ellipsoids intersect.
83  * If the shape matrices a and b are not null, these will be used in the
84  * workspace; otherwise they will point to null, and will have to be
85  * set by hand.
86  * ------------------------------------------------------------------------*/
88  UINT4 n,
89  const gsl_matrix *a,
90  const gsl_matrix *b,
91  const gsl_min_fminimizer_type *T,
92  REAL8 conv
93  )
94 {
95  fContactWorkSpace *workSpace = NULL;
96 
97  /* Check the parameters passed in are sensible */
98  if ( n <= 0 )
100 
101  if ( conv <= 0.0 )
103 
104  if ( !T )
106 
107  /* The matrices a and b should be both supplied or both null */
108  if ((!( a && b )) && ( a || b ))
110 
111  /* Check the matrices conform to the expected sizes */
112  if ( a )
113  {
114  if ( a->size1 != n || a->size2 != n || b->size1 != n || b->size2 != n )
115  {
117  }
118  }
119 
120 
121  /* Allocate the workspace */
122  workSpace = (fContactWorkSpace *) LALCalloc( 1, sizeof(fContactWorkSpace) );
123  if ( !workSpace )
125 
126  if ( a )
127  {
128  workSpace->invQ1 = a;
129  workSpace->invQ2 = b;
130  }
131 
132  XLAL_CALLGSL( workSpace->tmpA = gsl_matrix_calloc( n, n ) );
133  XLAL_CALLGSL( workSpace->tmpB = gsl_matrix_calloc( n, n ) );
134  XLAL_CALLGSL( workSpace->C = gsl_matrix_calloc( n, n ) );
135  XLAL_CALLGSL( workSpace->p1 = gsl_permutation_alloc( n ) );
136  XLAL_CALLGSL( workSpace->tmpV = gsl_vector_calloc( n ) );
137  XLAL_CALLGSL( workSpace->r_AB = gsl_vector_calloc( n ) );
138  XLAL_CALLGSL( workSpace->s = gsl_min_fminimizer_alloc( T ) );
139 
140  /* Check all of the above were allocated properly */
141  if (!workSpace->tmpA || !workSpace->tmpB || !workSpace->C ||
142  !workSpace->p1 || !workSpace->tmpV || !workSpace->r_AB
143  || !workSpace->s )
144  {
145  XLALFreeFContactWorkSpace( workSpace );
147  }
148 
149  /* Now set the rest of the parameters to the correct values */
150  workSpace->T = T;
151  workSpace->convParam = conv;
152  workSpace->n = n;
153 
154  return workSpace;
155 }
156 
157 /*
158 -------------------------------------------------------------------------
159  * This function minimises fContact defined above using the
160  * Brent method. It returns the minima with a negative sign (which then
161  * becomes the maxima of the actual contact function. This can be compared
162  * to 1 to check if two ellipsoids indeed overlap.
163  * ------------------------------------------------------------------------*/
165  const gsl_vector *ra,
166  const gsl_vector *rb,
167  fContactWorkSpace *workSpace )
168 {
169  gsl_function F;
170  INT4 min_status;
171  INT4 iter = 0, max_iter = 100;
172  REAL8 m = 0.6180339887;
173  REAL8 a = 0.0L, b = 1.0L;
174  gsl_min_fminimizer *s = workSpace->s;
175 
176  /* Sanity check on input arguments */
177  if ( !ra || !rb || !workSpace )
179 
180  if ( ra->size != rb->size || ra->size != workSpace->n )
182 
183 
184  /* Set r_AB to be rb - ra */
185  XLAL_CALLGSL( gsl_vector_memcpy( workSpace->r_AB, rb) );
186  XLAL_CALLGSL( gsl_vector_sub (workSpace->r_AB, ra) );
187 
188  if ( gsl_vector_isnull( workSpace->r_AB ))
189  {
190  XLALPrintWarning("Position vectors ra and rb are identical.\n");
191  return 0;
192  }
193 
194  F.function = &fContact;
195  F.params = workSpace;
196 
197  XLAL_CALLGSL( min_status = gsl_min_fminimizer_set (s, &F, m, a, b) );
198  if ( min_status != GSL_SUCCESS )
200 
201  do
202  {
203  iter++;
204  XLAL_CALLGSL( min_status = gsl_min_fminimizer_iterate (s) );
205  if (min_status != GSL_SUCCESS )
206  {
207  if (min_status == GSL_EBADFUNC)
209  else if (min_status == GSL_EZERODIV)
211  else
213  }
214 
215  m = gsl_min_fminimizer_x_minimum (s);
216  a = gsl_min_fminimizer_x_lower (s);
217  b = gsl_min_fminimizer_x_upper (s);
218 
219  XLAL_CALLGSL( min_status = gsl_min_test_interval (a, b, workSpace->convParam, 0.0) );
220  if (min_status != GSL_CONTINUE && min_status != GSL_SUCCESS )
222  }
223  while (min_status == GSL_CONTINUE && iter < max_iter );
224  /* End of minimization routine */
225 
226  /* Throw an error if max iterations would have been exceeded */
227  if ( iter == max_iter && min_status == GSL_CONTINUE )
228  {
230  }
231 
232  return ( -(s->f_minimum) );
233 }
234 
235 
236 /*
237 -------------------------------------------------------------------------
238  * This function frees the memory allocated using XLALInitFContactWorkSpace.
239  * ------------------------------------------------------------------------*/
241 {
242  if ( !workSpace )
244 
245  /* Free all the allocated memory */
246  if (workSpace->tmpA) XLAL_CALLGSL( gsl_matrix_free( workSpace->tmpA ));
247  if (workSpace->tmpB) XLAL_CALLGSL( gsl_matrix_free( workSpace->tmpB ));
248  if (workSpace->C) XLAL_CALLGSL( gsl_matrix_free( workSpace->C ));
249  if (workSpace->p1) XLAL_CALLGSL( gsl_permutation_free( workSpace->p1 ));
250  if (workSpace->tmpV) XLAL_CALLGSL( gsl_vector_free( workSpace->tmpV ));
251  if (workSpace->r_AB) XLAL_CALLGSL( gsl_vector_free( workSpace->r_AB ));
252  if (workSpace->s) XLAL_CALLGSL( gsl_min_fminimizer_free( workSpace->s ));
253 
254  LALFree( workSpace );
255  return;
256 }
void XLALFreeFContactWorkSpace(fContactWorkSpace *workSpace)
REAL8 XLALCheckOverlapOfEllipsoids(const gsl_vector *ra, const gsl_vector *rb, fContactWorkSpace *workSpace)
static REAL8 fContact(REAL8 x, void *params)
fContactWorkSpace * XLALInitFContactWorkSpace(UINT4 n, const gsl_matrix *a, const gsl_matrix *b, const gsl_min_fminimizer_type *T, REAL8 conv)
#define LALCalloc(m, n)
Definition: LALMalloc.h:94
#define LALFree(p)
Definition: LALMalloc.h:96
int XLALPrintWarning(const char *fmt,...)
Definition: XLALError.c:79
#define XLAL_CALLGSL(statement)
Definition: XLALGSL.h:33
double REAL8
Double precision real floating-point number (8 bytes).
uint32_t UINT4
Four-byte unsigned integer.
int32_t INT4
Four-byte signed integer.
static const INT4 m
Definition: Random.c:80
static const INT4 a
Definition: Random.c:79
#define XLAL_ERROR_VOID(...)
Macro to invoke a failure from a XLAL routine returning void.
Definition: XLALError.h:726
#define XLAL_ERROR_REAL8(...)
Macro to invoke a failure from a XLAL routine returning a REAL8.
Definition: XLALError.h:752
#define XLAL_ERROR_NULL(...)
Macro to invoke a failure from a XLAL routine returning a pointer.
Definition: XLALError.h:713
@ XLAL_EBADLEN
Inconsistent or invalid length.
Definition: XLALError.h:419
@ XLAL_ENOMEM
Memory allocation error.
Definition: XLALError.h:407
@ XLAL_EFPINVAL
IEEE Invalid floating point operation, eg sqrt(-1), 0/0.
Definition: XLALError.h:448
@ XLAL_EFAULT
Invalid pointer.
Definition: XLALError.h:408
@ XLAL_EFUNC
Internal function call failed bit: "or" this with existing error number.
Definition: XLALError.h:462
@ XLAL_EMAXITER
Exceeded maximum number of iterations.
Definition: XLALError.h:455
@ XLAL_EINVAL
Invalid argument.
Definition: XLALError.h:409
@ XLAL_EFPDIV0
IEEE Division by zero floating point error.
Definition: XLALError.h:449
const gsl_min_fminimizer_type * T
gsl_permutation * p1
const gsl_matrix * invQ1
const gsl_matrix * invQ2
gsl_min_fminimizer * s