Fixed a bug in the nth root that affects speed of computation. Also started playing with retaining decimal places of root computation
This commit is contained in:
@@ -30,26 +30,27 @@ library LibMath {
|
||||
///// See https://en.wikipedia.org/wiki/Nth_root#nth_root_algorithm
|
||||
|
||||
// 1. Find greatest power-of-2 <= `value`
|
||||
let nearestPowerOf2 := 0x80000000000000000000000000000000
|
||||
let nearestPowerOf2 := 0x100000000000000000000000000000000
|
||||
let m := 128
|
||||
for {let p := 64}
|
||||
gt(p, 0)
|
||||
{ p := div(p, 2) }
|
||||
{
|
||||
|
||||
switch gt(nearestPowerOf2, base)
|
||||
case 1 {
|
||||
nearestPowerOf2 := shr(p, nearestPowerOf2)
|
||||
m := sub(m, p)
|
||||
}
|
||||
case 0 {
|
||||
switch lt(nearestPowerOf2, base)
|
||||
case 0 {
|
||||
p := 0
|
||||
}
|
||||
case 1 {
|
||||
nearestPowerOf2 := shl(p, nearestPowerOf2)
|
||||
m := add(m, p)
|
||||
}
|
||||
}
|
||||
case 1 {
|
||||
nearestPowerOf2 := shr(p, nearestPowerOf2)
|
||||
m := sub(m, p)
|
||||
case 0 {
|
||||
p := 0
|
||||
}
|
||||
}
|
||||
}
|
||||
if gt(nearestPowerOf2, base) {
|
||||
@@ -57,21 +58,32 @@ library LibMath {
|
||||
m := sub(m, 1)
|
||||
}
|
||||
|
||||
|
||||
// 2. Find greatest power-of-2 that, when raised to the power of `n`,
|
||||
// is <= `value`
|
||||
let x := exp(2, div(m, n))
|
||||
|
||||
// 3. Find y such that `x` + `y` = `value`
|
||||
let y := xor(base, exp(2, mul(div(m, n), n)))
|
||||
// 3. Find y such that `x` + `y` = `base`
|
||||
let y := sub(base, exp2(x, n))
|
||||
|
||||
// 4. Run Newton's Approximation to approximate the root
|
||||
root := add(x, div(y, mul(n, exp(2, mul(div(m, n), sub(n, 1))))))
|
||||
let denominator := mul(n, exp2(x, sub(n, 1)))
|
||||
|
||||
// -- playing with turning root into fixed point to retain decimals --
|
||||
//let numerator := y
|
||||
//let fixedPointScaleFactor := exp2(10, 18)
|
||||
//let fixedPointNumerator := mul(y, fixedPointScaleFactor)
|
||||
//let fixedPointX := mul(x, fixedPointScaleFactor)
|
||||
//let fixedPointRoot := add(fixedPointX, div(fixedPointNumerator, denominator))
|
||||
|
||||
root := add(x, div(y, denominator))
|
||||
|
||||
|
||||
// 5. Run Newton's nth Root Algorithm
|
||||
let delta := 1 // run at least once
|
||||
for {let i := 0}
|
||||
and(lt(i, 20), gt(delta, 0))
|
||||
{i := add(i,1)}
|
||||
for {}
|
||||
gt(delta, 0)
|
||||
{}
|
||||
{
|
||||
// compute lhs
|
||||
let lhsDenominator := exp2(root, sub(n, 1))
|
||||
|
@@ -551,6 +551,7 @@ describe('Staking Core', () => {
|
||||
it('nth root #3 with fixed point (integer nth root would fail here)', async () => {
|
||||
const decimals = 18;
|
||||
const base = stakingWrapper.toFixedPoint(5429503678976, decimals);
|
||||
console.log(base);
|
||||
const n = new BigNumber(9);
|
||||
const decimalsAsBn = new BigNumber(decimals);
|
||||
const root = await stakingWrapper.nthRootFixedPoint(base, n, decimalsAsBn);
|
||||
@@ -559,6 +560,19 @@ describe('Staking Core', () => {
|
||||
expect(rootAsFloatingPoint).to.be.bignumber.equal(expectedResult);
|
||||
});
|
||||
|
||||
it.skip('nth root #4 with fixed point (integer nth root would fail here) (max number of decimals - currently does not retain)', async () => {
|
||||
const decimals = 18;
|
||||
const base = stakingWrapper.toFixedPoint(new BigNumber('5429503678976.295036789761543678', 10), decimals);
|
||||
console.log(base);
|
||||
const n = new BigNumber(9);
|
||||
const decimalsAsBn = new BigNumber(decimals);
|
||||
const root = await stakingWrapper.nthRootFixedPoint(base, n, decimalsAsBn);
|
||||
console.log(`root - ${root}`);
|
||||
const rootAsFloatingPoint = stakingWrapper.toFloatingPoint(root, decimals);
|
||||
const expectedResult = new BigNumber(26);
|
||||
expect(rootAsFloatingPoint).to.be.bignumber.equal(expectedResult);
|
||||
});
|
||||
|
||||
it('cobb douglas - approximate', async() => {
|
||||
const totalRewards = stakingWrapper.toBaseUnitAmount(57.154398);
|
||||
const ownerFees = stakingWrapper.toBaseUnitAmount(5.64375);
|
||||
|
@@ -330,6 +330,7 @@ export class StakingWrapper {
|
||||
return balance;
|
||||
}
|
||||
public async nthRoot(value: BigNumber, n: BigNumber): Promise<BigNumber> {
|
||||
//const txReceipt = await this.getLibMathTestContract().nthRoot.await(value, n);
|
||||
const output = await this.getLibMathTestContract().nthRoot.callAsync(value, n);
|
||||
return output;
|
||||
}
|
||||
@@ -365,6 +366,15 @@ export class StakingWrapper {
|
||||
totalStake: BigNumber,
|
||||
alphaDenominator: BigNumber
|
||||
) {
|
||||
const txReceipt = await this.getLibMathTestContract().cobbDouglasSimplifiedInverse.awaitTransactionSuccessAsync(
|
||||
totalRewards,
|
||||
ownerFees,
|
||||
totalFees,
|
||||
ownerStake,
|
||||
totalStake,
|
||||
alphaDenominator
|
||||
);
|
||||
console.log(`Gas Used: ${txReceipt.gasUsed}`);
|
||||
const output = await this.getLibMathTestContract().cobbDouglasSimplified.callAsync(
|
||||
totalRewards,
|
||||
ownerFees,
|
||||
|
Reference in New Issue
Block a user