Minimize error function with integer constraints

313 Views Asked by At

Much time has passed since I studied any form of math so I wanted to take this cheap shot of asking someone else to think for me.

I need to write some software that, for any given real number argument y between 0.0 and 510.0 (approximated by a float) finds two natural numbers h and m (expressed as integers between 0-255) that minimise the difference between y and h * m / 128.

I think that the following code is a brute force solver of the problem but it is excruciatingly inefficient:

function errFunc (y, h, m) { return Math.abs (y - (h * m / 128.0)); } function fit (y) { var minError = 2; // y <= 510, h <= 255, h <= 255. So errFunc(y) < 2 var h; var m; for (h = 0; h < 256; h++) { for (m = 0; m < 256; m++) { e = errFunc (y, h, m); if (e < minError) { minError = e; optimalH = h; optimalM = m; } } } }

Any help would be appreciated.

2

There are 2 best solutions below

0
On BEST ANSWER

Instead of trying all combinations of $h$ and $m$ values you could loop through all the possible $h$ and try just $m=\left\lfloor \frac{128y}{h} +\frac12 \right\rfloor$ for each of them.

You'll need to special-case $h=0$, but zeroes will be involved if and only if $y\le\frac1{256}$, so you can handle that once and for all at the beginning.

You can optimize further by trying only $h$ in the interval $1$ to $\Bigl\lfloor \sqrt{128y}\Bigr\rfloor$.

2
On

Let $k=128y$ and assume $k \lt 128y$ (you will have to test, and the update should be obvious). Then let $p=\text{int}(k)$
Test in order $p,p+1,p-1,p+2,p-2\dots$ for being able to be factored into two numbers less than $255$
Having a list of primes up to $255$ will make the factorization quick. If there is a factor greater than $255$ you fail and go on to the next one.

The hard part comes with numbers like $y=229.46$ We get $p=29391=3\cdot 97 \cdot 101$, which has no factors greater than $255$, but cannot be split into two factors less than $255$. If $p$ has lots of factors it will be easy, otherwise you may have to search all the combinations.