aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSylvain Munaut <tnt@246tNt.com>2013-03-08 17:50:21 +0100
committerSylvain Munaut <tnt@246tNt.com>2013-03-08 17:50:21 +0100
commit42a684e0bf0c238a80ad40ca1a9612eb4f45cace (patch)
tree19adc9d69a42077aacb800f46dfabbfae06d6398
parent2e8cef8f61fdec3aa374ff167c95ebe8058ef04b (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>
-rw-r--r--src/iqbal.c15
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);
}
}