bancorprotocol / contracts-solidity

Bancor Protocol Contracts

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

optimalLog function not entirely clear

alexpArtos opened this issue · comments

I have gone over the code in the BancorFormula.sol contract (https://github.com/bancorprotocol/contracts/blob/master/solidity/contracts/converter/BancorFormula.sol) and although there is some high-level documentation that helped me understand most of the hard-wired constants, there is half a function I need help with.

In the function optimalLog, lines 444-457 (as of commit 63480ca) compute the most significant 8 bits of the logarithm. But how are the following bits computed? The rest of the code seems to implement a series. If I'm not mistaken, term n is

[ 2n/(2n-1) - (x-1) ] / 2n * (x-1)^(2n - 1).

I can't match this to a Taylor / McLaurin series, as you have done elsewhere. Can anyone give a reference to what series is being used here?

Thanks.

@alexpArtos:

I apologize for the delayed response.

We are using Taylor series for calculating the natural logarithm of (1 + x), where x < 1 (see here).

However, as with function optimalExp, we split the calculation into two parts.

In function optimalExp(x), we handle the part of x which is smaller than 0.125 and the part of x which is larger than 0.125 separately:

  • First, we take y to be the part of x which is smaller than 0.125 (using modulo), and calculate e^y using Taylor series.
  • Then, for n = -3 to 3, we multiply the result of the previous step - if needed - by e^2^n.

Hence we are able to calculate e^x for any x < 2^4.

In function optimalLog(x), we handle the part of x which is larger than e^(1/256) and the part of x which is smaller than e^(1/256) separately:

  • First, for n = 1 to 8, we divide x by e^(1/2^n) and add 1/2^n to the result.
  • Then, for the remaining part of x, we calculate the natural logarithm of it by taking y = x - 1 and applying Taylor series on it, and finally add it to the result.

Hence we are able to calculate log(x) for any x < e^(1/2).

In short:

  • In function optimalExp, we rely on the fact that e ^ (x + y) = e ^ x * e ^ y.
  • In function optimalLog, we rely on the fact that log(x * y) = log(x) + log(y).

Note that the entire code is auto-generated in Python, based on constant values defined in this file.

These values were chosen under the attempt of processing as much input as possible in the Optimal path instead of in the General path (thus optimizing the overall average gas consumption).

So technically speaking, if you have a system with different expected input range, then you can take this exponentiation infrastructure and "reconfigure" it in order to optimize gas consumption on your system.

These two function could definitely "use" a more extended documentation, and I will try to add it as soon as I find a free time-slot.

Thank you for your comment!

Hi @barakman. Thanks for your answer, it did put me on the right track with regards to what Taylor formula was used. I could then verify that you' re collapsing two terms of the Taylor series in each of the final lines in optimalLog, in essence computing log x with 16 terms of the Taylor series.

Thanks.

@alexpArtos:
You're welcome.
Again, please note that you can change this specific number of terms and "reconfigure" the module for your needs, if necessary, by changing the values in constants.py, and then running PrintFunctionOptimalLog.py.

BTW, following your query, I have updated the documentation of both functions (optimalLog and optimalExp). See branch 0.4.4.