1 /* This file is part of the hkl library.
3 * The hkl library is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 3 of the License, or
6 * (at your option) any later version.
8 * The hkl library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with the hkl library. If not, see <http://www.gnu.org/licenses/>.
16 * Copyright (C) 2003-2017 Synchrotron SOLEIL
17 * L'Orme des Merisiers Saint-Aubin
18 * BP 48 91192 GIF-sur-YVETTE CEDEX
20 * Authors: Picca Frédéric-Emmanuel <picca@synchrotron-soleil.fr>
23 #include <gsl/gsl_sf_trig.h>
24 #include <math.h> // for floor, M_PI_2, acos, asin, etc
25 #include <stdlib.h> // for free, NULL
26 #include "hkl-interval-private.h" // for HklInterval
27 #include "hkl-macros-private.h" // for HKL_MALLOC
28 #include "hkl.h" // for FALSE, TRUE
31 * hkl_interval_dup: (skip)
34 * copy an #HklInterval
38 HklInterval
*hkl_interval_dup(const HklInterval
*self
)
43 HklInterval
*dup
= HKL_MALLOC(HklInterval
);
51 * hkl_interval_free: (skip)
54 * delete an #HklInterval
56 void hkl_interval_free(HklInterval
*self
)
63 * hkl_interval_cmp: (skip)
67 * compare two intervals
71 int hkl_interval_cmp(const HklInterval
*self
, const HklInterval
*interval
)
73 return (fabs(self
->min
- interval
->min
) > HKL_EPSILON
)
74 || (fabs(self
->max
- interval
->max
) > HKL_EPSILON
);
78 * hkl_interval_plus_interval: (skip)
84 void hkl_interval_plus_interval(HklInterval
*self
, const HklInterval
*interval
)
86 self
->min
+= interval
->min
;
87 self
->max
+= interval
->max
;
91 * hkl_interval_plus_double: (skip)
95 * add to an interval a double
97 void hkl_interval_plus_double(HklInterval
*self
, double const d
)
105 * hkl_interval_minus_interval: (skip)
109 * substract two #HklInterval
111 void hkl_interval_minus_interval(HklInterval
*self
, const HklInterval
*interval
)
113 self
->min
-= interval
->max
;
114 self
->max
-= interval
->min
;
119 * hkl_interval_minus_double: (skip)
123 * subst a double to an #HklInterval
125 void hkl_interval_minus_double(HklInterval
*self
, double const d
)
132 * hkl_interval_times_interval: (skip)
136 * multiply two #HklInterval
138 void hkl_interval_times_interval(HklInterval
*self
, const HklInterval
*interval
)
142 double m1
= self
->min
* interval
->min
;
143 double m2
= self
->min
* interval
->max
;
144 double m3
= self
->max
* interval
->min
;
145 double m4
= self
->max
* interval
->max
;
168 * hkl_interval_times_double: (skip)
172 * multiply an #HklInterval by a double
174 void hkl_interval_times_double(HklInterval
*self
, double const d
)
190 * hkl_interval_divides_double: (skip)
194 * divide an #HklInterval by a double
196 void hkl_interval_divides_double(HklInterval
*self
, double const d
)
198 double min
= self
->min
/ d
;
199 double max
= self
->max
/ d
;
210 * hkl_interval_contain_zero: (skip)
213 * check if an #HklInterval contain zero
217 int hkl_interval_contain_zero(HklInterval
const *self
)
219 if (self
->min
<= 0 && self
->max
>= 0)
226 * hkl_interval_cos: (skip)
229 * compute the cosinus of an #HklInterval
231 void hkl_interval_cos(HklInterval
*self
)
238 cmin
= cos(self
->min
);
239 cmax
= cos(self
->max
);
241 if (self
->max
- self
->min
>= 2 * M_PI
) {
248 quad_min
= (int)floor(self
->min
/ M_PI_2
) % 4;
252 quad_max
= (int)floor(self
->max
/ M_PI_2
) % 4;
374 * hkl_interval_acos: (skip)
377 * compute the arc cosinus of an #HklInterval
379 void hkl_interval_acos(HklInterval
*self
)
384 self
->min
= acos(self
->max
);
385 self
->max
= acos(tmp
);
390 * hkl_interval_sin: (skip)
393 * compute the sin of an #HklInterval
395 void hkl_interval_sin(HklInterval
*self
)
402 smin
= sin(self
->min
);
403 smax
= sin(self
->max
);
405 /* if there is at least one period in b, then a = [-1, 1] */
406 if ( self
->max
- self
->min
>= 2 * M_PI
) {
413 quad_min
= (int)floor(self
->min
/ M_PI_2
) % 4;
417 quad_max
= (int)floor(self
->max
/ M_PI_2
) % 4;
546 * hkl_interval_asin: (skip)
549 * compute the arc sinus of an #HklInterval
551 void hkl_interval_asin(HklInterval
*self
)
553 self
->min
= asin(self
->min
);
554 self
->max
= asin(self
->max
);
558 * hkl_interval_tan: (skip)
561 * compute the tangente of an #HklInterval
563 void hkl_interval_tan(HklInterval
*self
)
565 int quadrant_down
= (int)floor(self
->min
/ M_PI_2
);
566 int quadrant_up
= (int)floor(self
->max
/ M_PI_2
);
568 /* if there is at least one period in b or if b contains a Pi/2 + k*Pi, */
569 /* then a = ]-oo, +oo[ */
570 if ( ((quadrant_up
- quadrant_down
) >= 2)
571 || (!(quadrant_down
% 2) && (quadrant_up
% 2)) ) {
572 self
->min
= -INFINITY
;
573 self
->max
= INFINITY
;
575 self
->min
= tan(self
->min
);
576 self
->max
= tan(self
->max
);
581 * hkl_interval_atan: (skip)
584 * compute the arc tangente of an #HklInterval
586 void hkl_interval_atan(HklInterval
*self
)
588 self
->min
= atan(self
->min
);
589 self
->max
= atan(self
->max
);
593 * hkl_interval_length: (skip)
596 * compute the length of an #HklInterval
600 double hkl_interval_length(const HklInterval
*self
)
602 return self
->max
- self
->min
;
606 * hkl_interval_angle_restrict_symm: (skip)
609 * restrict an #HklInterval into -pi, pi
611 void hkl_interval_angle_restrict_symm(HklInterval
*self
)
613 gsl_sf_angle_restrict_symm_e(&self
->min
);
614 gsl_sf_angle_restrict_symm_e(&self
->max
);