Optimized low-accuracy approximation to `rootn(x, n)`

前端 未结 1 471
南方客
南方客 2020-12-05 23:29

rootn (float_t x, int_t n) is a function that computes the n-th root x1/n and is supported by some programming languages such as OpenCL. Wh

相关标签:
1条回答
  • 2020-12-05 23:43

    Here's some Octave (MATLAB) code that computes offsets for positive n assuming the conjectures below. Seems to work for 2 and 3, but I suspect that one of the assumptions breaks down when n is too large. No time to investigate right now.

    % finds the best offset for positive n
    % assuming that the conjectures below are true
    function oint = offset(n)
    % find the worst upward error with no offset
    efrac = (1 / log(2) - 1) * n;
    evec = [floor(efrac) ceil(efrac)];
    rootnvec = 2 .^ (evec / n);
    [abserr i] = max((1 + evec / n) ./ rootnvec);
    relerr = abserr - 1;
    rootnx = rootnvec(i);
    % conjecture: z such that approx(z, n) = 1
    % should have the worst downward error
    fun = @(o) relerr - o / rootnx + (1 / (1 + o * n) ^ (1 / n) - 1);
    oreal = fzero(fun, [0 1]);
    oint = round((127 * (1 - 1 / n) - oreal) * 2 ^ 23);
    

    Partial answer for positive n only -- I'm just going to nibble a bit by conjecturing the worst overestimate, assuming that we don't adjust the offset downward.

    Let's define an idealized version of the approximation for x in [1, 2^n).

    rootn-A(x, n) = 1 + floor(lg(x))/n + ((x/2^floor(lg(x))) - 1) / n
                        ^^^^^^^^^^^^^^   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                        contribution of       contribution of the
                         the exponent             significand
    

    We want to maximize rootn-A(x, n) / x^(1/n).

    It seems experimentally that the maximum occurs when x is a power of two. In this case, the significand term is zero and floor(lg(x)) = lg(x), so we can maximize

    (1 + lg(x)/n) / x^(1/n).
    

    Substitute y = lg(x)/n, and we can maximize (1 + y) / 2^y for y in [0, 1) such that n*y is an integer. Dropping the integrality condition, it is a calculus exercise to show that the max of this concave function is at y = 1/log(2) - 1, about 0.4426950408889634. It follows that the maximum for x a power of two is at either x = 2^floor((1/log(2) - 1) * n) or x = 2^ceil((1/log(2) - 1) * n). I conjecture that one of these is in fact the global maximum.

    On the underestimation end, it appears that we want x such that the output of rootn(x, n) is 1, at least for small n. More to come later hopefully.

    0 讨论(0)
提交回复
热议问题