Milena (Olena)  User documentation 2.0a Id
 All Classes Namespaces Functions Variables Typedefs Enumerator Groups Pages
coefficients.hh
1 // Copyright (C) 2001, 2002, 2003, 2004, 2008, 2009 EPITA Research and Development Laboratory (LRDE)
2 //
3 // This file is part of Olena.
4 //
5 // Olena is free software: you can redistribute it and/or modify it under
6 // the terms of the GNU General Public License as published by the Free
7 // Software Foundation, version 2 of the License.
8 //
9 // Olena 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 GNU
12 // General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with Olena. If not, see <http://www.gnu.org/licenses/>.
16 //
17 // As a special exception, you may use this file as part of a free
18 // software project without restriction. Specifically, if other files
19 // instantiate templates or use macros or inline functions from this
20 // file, or you compile this file and link it with other files to produce
21 // an executable, this file does not by itself cause the resulting
22 // executable to be covered by the GNU General Public License. This
23 // exception does not however invalidate any other reasons why the
24 // executable file might be covered by the GNU General Public License.
25 
26 #ifndef MLN_LINEAR_GAUSSIAN_INTERNAL_COEFFICIENTS_HH
27 # define MLN_LINEAR_GAUSSIAN_INTERNAL_COEFFICIENTS_HH
28 
35 
36 # include <vector>
37 # include <cmath>
38 
39 
40 
41 namespace mln
42 {
43 
44  namespace linear
45  {
46 
47  namespace gaussian
48  {
49 
50  namespace internal
51  {
52 
53 
54  typedef double norm_fun(double, double,
55  double, double,
56  double, double,
57  double, double,
58  double, double,
59  int&);
60 
61  struct coefficients
62  {
64  //
65  coefficients(double a0, double a1,
66  double b0, double b1,
67  double c0, double c1,
68  double w0, double w1,
69  double s, norm_fun norm);
70  std::vector<double> n, d, nm, dm;
71  };
72 
73 
74  coefficients coefficients_not_derivative(double sigma);
75  coefficients coefficients_1st_derivative(double sigma);
76  coefficients coefficients_2nd_derivative(double sigma);
77 
78 
79 
80 # ifndef MLN_INCLUDE_ONLY
81 
82 
83  inline
84  coefficients::coefficients(double a0, double a1,
85  double b0, double b1,
86  double c0, double c1,
87  double w0, double w1,
88  double s, norm_fun norm)
89  {
90  n.reserve(5);
91  d.reserve(5);
92  nm.reserve(5);
93  dm.reserve(5);
94 
95  b0 /= s;
96  b1 /= s;
97  w0 /= s;
98  w1 /= s;
99 
100  double sin0 = std::sin(w0);
101  double sin1 = std::sin(w1);
102  double cos0 = std::cos(w0);
103  double cos1 = std::cos(w1);
104 
105  int sign = 1;
106  double n_ = norm(a0, a1, b0, b1, c0, c1, cos0, sin0, cos1, sin1, sign);
107 
108  a0 /= n_;
109  a1 /= n_;
110  c0 /= n_;
111  c1 /= n_;
112 
113  n[3] =
114  std::exp(-b1 - 2*b0) * (c1 * sin1 - cos1 * c0) +
115  std::exp(-b0 - 2*b1) * (a1 * sin0 - cos0 * a0);
116  n[2] =
117  2 * std::exp(-b0 - b1) * ((a0 + c0) * cos1 * cos0 -
118  cos1 * a1 * sin0 -
119  cos0 * c1 * sin1) +
120  c0 * std::exp(-2*b0) + a0 * std::exp(-2*b1);
121  n[1] =
122  std::exp(-b1) * (c1 * sin1 - (c0 + 2 * a0) * cos1) +
123  std::exp(-b0) * (a1 * sin0 - (2 * c0 + a0) * cos0);
124  n[0] =
125  a0 + c0;
126 
127  d[4] =
128  std::exp(-2 * b0 - 2 * b1);
129  d[3] =
130  -2 * cos0 * std::exp(-b0 - 2*b1) -
131  2 * cos1 * std::exp(-b1 - 2*b0);
132  d[2] =
133  4 * cos1 * cos0 * std::exp(-b0 - b1) +
134  std::exp(-2*b1) + std::exp(-2*b0);
135  d[1] =
136  -2 * std::exp(-b1) * cos1 - 2 * std::exp(-b0) * cos0;
137 
138  for (unsigned i = 1; i <= 3; ++i)
139  {
140  dm[i] = d[i];
141  nm[i] = double(sign) * (n[i] - d[i] * n[0]);
142  }
143  dm[4] = d[4];
144  nm[4] = double(sign) * (-d[4] * n[0]);
145  }
146 
147 
148 
149  inline
150  double norm_not_derivative(double a0, double a1,
151  double b0, double b1,
152  double c0, double c1,
153  double cos0, double sin0,
154  double cos1, double sin1,
155  int& sign)
156  {
157  double expb0 = std::exp(b0);
158  double exp2b0 = std::exp(2.f * b0);
159 
160  double scale0 = 1 + exp2b0 - 2 * cos0 * expb0;
161  double scaleA = 2 * a1 * sin0 * expb0 - a0 * (1 - exp2b0);
162 
163  double expb1 = std::exp(b1);
164  double exp2b1 = std::exp(2.f * b1);
165 
166  double scale1 = 1 + exp2b1 - 2 * cos1 * expb1;
167  double scaleC = 2 * c1 * sin1 * expb1 - c0 * (1 - exp2b1);
168 
169  double sumA = scaleA / scale0;
170  double sumC = scaleC / scale1;
171 
172  sign = 1;
173 
174  return sumA + sumC;
175  }
176 
177 
178  inline
179  double norm_1st_derivative(double a0, double a1,
180  double b0, double b1,
181  double c0, double c1,
182  double cos0, double sin0,
183  double cos1, double sin1,
184  int& sign)
185  {
186  double expb0 = std::exp(b0);
187  double exp2b0 = std::exp(2.f * b0);
188 
189  double scale0 = 1 + exp2b0 - 2 * cos0 * expb0;
190  scale0 *= scale0;
191  double scaleA = - 2 * a1 * sin0 * expb0 * (1 - exp2b0) +
192  2 * a0 * expb0 * (2 * expb0 - cos0 * (1 + exp2b0));
193 
194  double expb1 = std::exp(b1);
195  double exp2b1 = std::exp(2.f * b1);
196 
197  double scale1 = 1 + exp2b1 - 2 * cos1 * expb1;
198  scale1 *= scale1;
199  double scaleC = - 2 * c1 * sin1 * expb1 * (1 - exp2b1) +
200  2 * c0 * expb1 * (2 * expb1 - cos1 * (1 + exp2b1));
201 
202  double sumA = scaleA / scale0;
203  double sumC = scaleC / scale1;
204 
205  sign = -1;
206 
207  return sumA + sumC;
208  }
209 
210 
211  inline
212  double norm_2nd_derivative(double a0, double a1,
213  double b0, double b1,
214  double c0, double c1,
215  double cos0, double sin0,
216  double cos1, double sin1,
217  int& sign)
218  {
219  double expb0 = std::exp(b0);
220  double exp2b0 = std::exp(2.f * b0);
221 
222  double scale0 = 1 + exp2b0 - 2 * cos0 * expb0;
223  scale0 *= scale0 * scale0;
224 
225  double scaleA = a1 * sin0 * expb0 *
226  (1 + expb0 * (2 * cos0 * (1 + exp2b0) + exp2b0 - 6)) +
227  a0 * expb0 * (2 * expb0 * (2 - cos0 * cos0) *
228  (1 - exp2b0) - cos0 * (1 - exp2b0 * exp2b0));
229 
230  double expb1 = std::exp(b1);
231  double exp2b1 = std::exp(2.f * b1);
232 
233  double scale1 = 1 + exp2b1 - 2 * cos1 * expb1;
234  scale1 *= scale1 * scale1;
235 
236  double scaleC = c1 * sin1 * expb1 *
237  (1 + expb1 * (2 * cos1 * (1 + exp2b1) + exp2b1 - 6)) +
238  c0 * expb1 * (2 * expb1 * (2 - cos1 * cos1) *
239  (1 - exp2b1) - cos1 * (1 - exp2b1 * exp2b1));
240 
241  double sumA = scaleA / scale0;
242  double sumC = scaleC / scale1;
243  sign = 1;
244 
245  return sumA + sumC;
246  }
247 
248 
249  inline
250  coefficients coefficients_not_derivative(double sigma)
251  {
252  coefficients tmp(+1.6800, +3.7350,
253  +1.7830, +1.7230,
254  -0.6803, -0.2598,
255  +0.6318, +1.9970,
256  sigma,
257  norm_not_derivative);
258  return tmp;
259  }
260 
261 
262  inline
263  coefficients coefficients_1st_derivative(double sigma)
264  {
265  coefficients tmp(-0.6472, -4.5310,
266  +1.5270, +1.5160,
267  +0.6494, +0.9557,
268  +0.6719, +2.0720,
269  sigma,
270  norm_1st_derivative);
271  return tmp;
272  }
273 
274 
275  inline
276  coefficients coefficients_2nd_derivative(double sigma)
277  {
278  coefficients tmp(-1.3310, +3.661,
279  +1.2400, +1.314,
280  +0.3225, -1.738,
281  +0.7480, +2.166,
282  sigma,
283  norm_2nd_derivative);
284  return tmp;
285  }
286 
287 # endif // ! MLN_INCLUDE_ONLY
288 
289  } // end of namespace mln::linear::gaussian::internal
290 
291  } // end of namespace mln::linear::gaussian
292 
293  } // end of namespace mln::linear
294 
295 } // end of namespace mln
296 
297 
298 #endif // ! MLN_LINEAR_GAUSSIAN_INTERNAL_COEFFICIENTS_HH