diff options
author | Sylvain Munaut <tnt@246tNt.com> | 2013-03-08 17:50:21 +0100 |
---|---|---|
committer | Sylvain Munaut <tnt@246tNt.com> | 2013-03-08 17:50:21 +0100 |
commit | 42a684e0bf0c238a80ad40ca1a9612eb4f45cace (patch) | |
tree | 19adc9d69a42077aacb800f46dfabbfae06d6398 /src/iqbal.c | |
parent | 2e8cef8f61fdec3aa374ff167c95ebe8058ef04b (diff) |
iqbal: Improve convergence of the optimization
- We need to only take the general direction of the gradient
and not the actual value (hence the division by sum of abs)
- We take new values even if the score is equal, it might get
us out of a dead lock
- When reducing the step size, we look at how much we overshoot
to get a better new step size
- If the gain was lower than 1%, we quit, but we still take the
new value
Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
Diffstat (limited to 'src/iqbal.c')
-rw-r--r-- | src/iqbal.c | 15 |
1 files changed, 8 insertions, 7 deletions
diff --git a/src/iqbal.c b/src/iqbal.c index f4c29c6..0bb6a54 100644 --- a/src/iqbal.c +++ b/src/iqbal.c @@ -319,26 +319,27 @@ osmo_iqbal_cxvec_optimize(const struct osmo_cxvec *sig, float *mag, float *phase } cv = _iqbal_objfn_val_gradient(state, cx, cgrad); - step = 0.1f * cv / (fabs(cgrad[0]) + fabs(cgrad[1])); + step = cv / (fabs(cgrad[0]) + fabs(cgrad[1])); for (i=0; i<opts->max_iter; i++) { - nx[0] = cx[0] - step * cgrad[0]; - nx[1] = cx[1] - step * cgrad[1]; + nx[0] = cx[0] - step * (cgrad[0] / (fabs(cgrad[0]) + fabs(cgrad[1]))); + nx[1] = cx[1] - step * (cgrad[1] / (fabs(cgrad[0]) + fabs(cgrad[1]))); nv = _iqbal_objfn_value(state, nx); - if (nv < cv) { + if (nv <= cv) { p = (cv - nv) / cv; - if (p < 0.01f) - break; cx[0] = nx[0]; cx[1] = nx[1]; cv = nv; _iqbal_objfn_gradient(state, cx, cv, cgrad); + + if (p < 0.01f) + break; } else { - step /= 2.0f; + step /= 2.0 * (nv / cv); } } |