From 42a684e0bf0c238a80ad40ca1a9612eb4f45cace Mon Sep 17 00:00:00 2001 From: Sylvain Munaut Date: Fri, 8 Mar 2013 17:50:21 +0100 Subject: [PATCH] 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 --- src/iqbal.c | 15 ++++++++------- 1 file 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; imax_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); } }