17#ifndef __math_rician_h__
18#define __math_rician_h__
22#include "math/vector.h"
31 template <
typename T>
inline T
lnP (
const T measured,
const T actual,
const T one_over_noise_squared)
33 T nm = one_over_noise_squared * measured;
39 template <
typename T>
inline T
lnP (
const T measured, T actual,
const T one_over_noise_squared, T& dP_dactual)
41 assert (measured >= 0.0);
42 assert (one_over_noise_squared > 0.0);
44 actual =
abs (actual);
45 T nm = one_over_noise_squared * measured;
48 T m_a = measured - actual;
49 T nm_a = one_over_noise_squared * m_a;
52 dP_dactual = -nm_a - nm * F1_F0;
53 return 0.5 * nm_a * m_a - log (nm * F0);
59 template <
typename T>
inline T
lnP (
const T measured,
const T actual,
const T one_over_noise_squared, T& dP_dactual, T& dP_dN)
61 assert (measured >= 0.0);
62 assert (one_over_noise_squared > 0.0);
64 bool actual_is_positive = (actual >= 0.0);
65 T actual_pos =
abs (actual);
66 T nm = one_over_noise_squared * measured;
67 T nms = nm * actual_pos;
69 T m_a = measured - actual_pos;
70 T nm_a = one_over_noise_squared * m_a;
72 if (nms < 0.0) F1_F0 = -F1_F0;
73 dP_dactual = -nm_a - nm * F1_F0;
74 actual_pos *= measured * F1_F0;
75 dP_dN = 0.5 *
pow2 (m_a) - 1.0/one_over_noise_squared + (actual_is_positive ? -actual_pos : actual_pos);
76 return 0.5 * nm_a * m_a - log (nm * F0);
83 template <
typename T>
inline T
lnP (
const int N,
const T* measured,
const T* actual,
const T one_over_noise_squared, T* dP_dactual, T& dP_dN)
85 assert (one_over_noise_squared > 0.0);
88 dP_dN = -T (N) / one_over_noise_squared;
90 for (
int i = 0; i < N; i++) {
91 assert (measured[i] >= 0.0);
93 T actual_pos =
abs (actual[i]);
94 T nm = one_over_noise_squared * measured[i];
95 T nms = nm * actual_pos;
97 T m_a = measured[i] - actual_pos;
98 T nm_a = one_over_noise_squared * m_a;
100 dP_dactual[i] = -nm_a - nm * F1_F0;
101 if (actual[i] < 0.0) dP_dactual[i] = -dP_dactual[i];
102 dP_dN += 0.5 *
pow2 (m_a) - measured[i] * actual_pos * F1_F0;
103 lnP += 0.5 * nm_a * m_a - log (nm * F0);
111 template <
typename T>
inline T
lnP (
const Vector<T>& measured,
const Vector<T>& actual,
const T one_over_noise_squared, Vector<T>& dP_dactual)
113 assert (one_over_noise_squared > 0.0);
114 assert (measured.size() == actual.size());
115 assert (measured.size() == dP_dactual.size());
119 for (
size_t i = 0; i < measured.size(); i++) {
120 assert (measured[i] > 0.0);
122 T actual_pos =
abs (actual[i]);
123 T nm = one_over_noise_squared * measured[i];
124 T nms = nm * actual_pos;
126 T m_a = measured[i] - actual_pos;
127 T nm_a = one_over_noise_squared * m_a;
129 dP_dactual[i] = -nm_a - nm * F1_F0;
130 if (actual[i] < 0.0) dP_dactual[i] = -dP_dactual[i];
131 lnP += 0.5 * nm_a * m_a - log (nm * F0);
132 assert (std::isfinite (
lnP));
139 template <
typename T>
inline T
lnP (
const Vector<T>& measured,
const Vector<T>& actual,
const T one_over_noise_squared, Vector<T>& dP_dactual, T& dP_dN)
141 assert (one_over_noise_squared > 0.0);
142 assert (measured.size() == actual.size());
143 assert (measured.size() == dP_dactual.size());
146 dP_dN = -T (measured.size()) / one_over_noise_squared;
148 for (
size_t i = 0; i < measured.size(); i++) {
149 assert (measured[i] > 0.0);
151 T actual_pos =
abs (actual[i]);
152 T nm = one_over_noise_squared * measured[i];
153 T nms = nm * actual_pos;
155 T m_a = measured[i] - actual_pos;
156 T nm_a = one_over_noise_squared * m_a;
158 dP_dactual[i] = -nm_a - nm * F1_F0;
159 if (actual[i] < 0.0) dP_dactual[i] = -dP_dactual[i];
160 dP_dN += 0.5 *
pow2 (m_a) - measured[i] * actual_pos * F1_F0;
161 lnP += 0.5 * nm_a * m_a - std::log (nm * F0);
162 assert (std::isfinite (dP_dN));
163 assert (std::isfinite (
lnP));
constexpr T pow2(const T &v)
T lnP(const T measured, const T actual, const T one_over_noise_squared)
constexpr std::enable_if< std::is_arithmetic< X >::value &&std::is_unsigned< X >::value, X >::type abs(X x)