diff --git a/script/Deploy.s.sol b/script/Deploy.s.sol index ba4cb6b..b76a90e 100644 --- a/script/Deploy.s.sol +++ b/script/Deploy.s.sol @@ -14,9 +14,9 @@ interface WRAPPER { function toPolar(int256, int256) external returns (int256, int256); function fromPolar(int256, int256) external returns (int256, int256); - // function p_atan2(int256, int256) external returns (int256); + function p_atan2(int256, int256) external returns (int256); - // function atan1to1(int256) external returns (int256); + function atan1to1(int256) external returns (int256); function ln(int256, int256) external returns (int256, int256); diff --git a/src/ComplexHuff/Complex.huff b/src/ComplexHuff/Complex.huff index ed9b664..bbb1846 100644 --- a/src/ComplexHuff/Complex.huff +++ b/src/ComplexHuff/Complex.huff @@ -307,55 +307,60 @@ 0x40 0x00 return } -// #define macro P_ATAN2() = takes(2) returns(1) { -// // INPUT STACK => [y,x] - -// dup1 // [y,y,x] -// swap2 // [x,y,y] -// P_ATAN2_INNER_CALC() // [T,y] -// swap1 // [y,T] -// 0x00 // [0,y,T] -// sgt // [0>y,T] -// case3 -// jumpi - -// case3: -// PUT_NEG1() // [-1,T] -// mul // [-T] - -// } - -// #define macro ATAN1TO1() = takes(1) returns(1){ -// // INPUT STACK => [x] - -// [X7] // [X7,x] -// dup1 // [x,X7,x] -// mul // [x*X7,x] -// [X3] // [1e18,x*X7,x] -// swap1 // [x*X7,1e18,x] -// sdiv // [x*X7/1e18,x] -// [X6] // [X6,x*X7/1e18,x] -// add // [X6+x*X7/1e18,x] -// [X3] // [1e18,X6+x*X7/1e18,x] -// dup3 // [x,1e18,X6+x*X7/1e18,x] -// sub // [x-1e18,X6+x*X7/1e18,x] -// dup3 // [x,x-1e18,X6+x*X7/1e18,x] -// mul // [x*(x-1e18),X6+x*X7/1e18,x] -// [X3] // [1e18,x*(x-1e18),X6+x*X7/1e18,x] -// swap1 // [x*(x-1e18),1e18,X6+x*X7/1e18,x] -// sdiv // [x*(x-1e18)/1e18,X6+x*X7/1e18,x] -// mul // [(x*(x-1e18)/1e18)*(X6+x*X7/1e18),x] -// swap1 // [x,(x*(x-1e18)/1e18)*(X6+x*X7/1e18)] -// [X5] // [X5,x,(x*(x-1e18)/1e18)*(X6+x*X7/1e18)] -// mul // [X5*x,(x*(x-1e18)/1e18)*(X6+x*X7/1e18)] -// [X3] // [1e18,X5*x,(x*(x-1e18)/1e18)*(X6+x*X7/1e18)] -// swap1 // [X5*x,1e18,(x*(x-1e18)/1e18)*(X6+x*X7/1e18)] -// sdiv // [X5*x/1e18,(x*(x-1e18)/1e18)*(X6+x*X7/1e18)] -// sub // [X5*x/1e18-(x*(x-1e18)/1e18)*(X6+x*X7/1e18)] -// [X3] // [1e18,X5*x/1e18-(x*(x-1e18)/1e18)*(X6+x*X7/1e18)] -// swap1 // [X5*x/1e18-(x*(x-1e18)/1e18)*(X6+x*X7/1e18),1e18] -// sdiv // [X5*x/1e18-(x*(x-1e18)/1e18)*(X6+x*X7/1e18)/1e18] -// } +#define macro P_ATAN2() = takes(2) returns(1) { + // INPUT STACK => [y,x] + + dup1 // [y,y,x] + swap2 // [x,y,y] + P_ATAN2_INNER_CALC() // [T,y] + swap1 // [y,T] + 0x00 // [0,y,T] + sgt // [0>y,T] + case3 + jumpi + 0x01 // [1,T] + finish + jumpi + + + case3: + PUT_NEG1() // [-1,T] + mul // [-T] + + finish: // [Appropriate T] +} + +#define macro ATAN1TO1() = takes(1) returns(1){ + // INPUT STACK => [x] + + [X7] // [X7,x] + dup2 // [x,X7,x] + mul // [x*X7,x] + [X3] // [1e18,x*X7,x] + swap1 // [x*X7,1e18,x] + sdiv // [x*X7/1e18,x] + [X6] // [X6,x*X7/1e18,x] + add // [X6+x*X7/1e18,x] + [X3] // [1e18,X6+x*X7/1e18,x] + dup3 // [x,1e18,X6+x*X7/1e18,x] + sub // [x-1e18,X6+x*X7/1e18,x] + dup3 // [x,x-1e18,X6+x*X7/1e18,x] + mul // [x*(x-1e18),X6+x*X7/1e18,x] + [X3] // [1e18,x*(x-1e18),X6+x*X7/1e18,x] + swap1 // [x*(x-1e18),1e18,X6+x*X7/1e18,x] + sdiv // [x*(x-1e18)/1e18,X6+x*X7/1e18,x] + mul // [(x*(x-1e18)/1e18)*(X6+x*X7/1e18),x] + [X3] // [1e18,(x*(x-1e18)/1e18)*(X6+x*X7/1e18),x] + swap1 // [(x*(x-1e18)/1e18)*(X6+x*X7/1e18),1e18,x] + sdiv // [((x*(x-1e18)/1e18)*(X6+x*X7/1e18))/1e18,x] + swap1 // [x,((x*(x-1e18)/1e18)*(X6+x*X7/1e18))/1e18] + [X5] // [X5,x,((x*(x-1e18)/1e18)*(X6+x*X7/1e18))/1e18] + mul // [X5*x,((x*(x-1e18)/1e18)*(X6+x*X7/1e18))/1e18] + [X3] // [1e18,X5*x,((x*(x-1e18)/1e18)*(X6+x*X7/1e18))/1e18] + swap1 // [X5*x,1e18,((x*(x-1e18)/1e18)*(X6+x*X7/1e18))/1e18] + sdiv // [X5*x/1e18,((x*(x-1e18)/1e18)*(X6+x*X7/1e18))/1e18] + sub // [X5*x/1e18-((x*(x-1e18)/1e18)*(X6+x*X7/1e18))/1e18] +} #define macro LN() = takes(2) returns(1) { //INPUT STACK => [Re(A),Im(A)] diff --git a/src/ComplexHuff/Constants.huff b/src/ComplexHuff/Constants.huff index d893b2e..67e65cf 100644 --- a/src/ComplexHuff/Constants.huff +++ b/src/ComplexHuff/Constants.huff @@ -6,6 +6,7 @@ #define constant X11 = 0xE8D4A51000 // 1e12 #define constant X12 = 0xE47469D8BC6E // 1e(18*4/5) #define constant X4 = 0x9C2007651B2500000 // 180e18 +#define constant X5 = 0xAE4E15744AE8000 // 7.85e17 #define constant e = 0x25B946EBC0B36173 // euler's number #define constant PI_QUARTER = 0xAE4E15744AE8000 // 7.851e17 #define constant X6 = 0x365595A8089C000 // 2.447e17 diff --git a/src/ComplexHuff/Helper.huff b/src/ComplexHuff/Helper.huff index 8552496..26cd12b 100644 --- a/src/ComplexHuff/Helper.huff +++ b/src/ComplexHuff/Helper.huff @@ -52,28 +52,14 @@ dup1 // [x,x,y] 0x00 // [0,x,x,y] - slt // [x<0,x,y] + swap1 // [x,0,x,y] + slt // [x < 0,x,y] diff_case jumpi swap1 // [y,x] P_ATAN2_ABS() // [abs_y,x] dup2 // [x,abs_y,x] dup2 // [abs_y,x,abs_y,x] - sub // [abs_y-x,abs_y,x] - swap2 // [x,abs_y,abs_y-x] - add // [x+abs_y,abs_y-x] - [X3] // [1e18,x+abs_y,abs_y-x] - mul // [1e18*(x+abs_y),abs_y-x] - sdiv // [(1e18*(x+abs_y))/(abs_y-x)] , Let (1e18*(x+abs_y))/(abs_y-x) = r - P_ATAN2_INNER_T() // [T] - PUT_C2() // [c2,T] - add // [c2+T] - - diff_case: // [x,y] and x<0 condition - swap1 // [y,x] - P_ATAN2_ABS() // [abs_y,x] - dup2 // [x,abs_y,x] - dup2 // [abs_y,x,abs_y,x] add // [abs_y+x,abs_y,x] swap2 // [x,abs_y,abs_y+x] sub // [x-abs_y,abs_y+x] @@ -83,14 +69,32 @@ P_ATAN2_INNER_T() // [T] PUT_C1() // [c1,T] add // [c1+T] + 0x01 + finish + jumpi + + diff_case: // [x,y] and x<0 condition + swap1 // [y,x] + P_ATAN2_ABS() // [abs_y,x] + dup2 // [x,abs_y,x] + dup2 // [abs_y,x,abs_y,x] + sub // [abs_y-x,abs_y,x] + swap2 // [x,abs_y,abs_y-x] + add // [x+abs_y,abs_y-x] + [X3] // [1e18,x+abs_y,abs_y-x] + mul // [1e18*(x+abs_y),abs_y-x] + sdiv // [(1e18*(x+abs_y))/(abs_y-x)] , Let (1e18*(x+abs_y))/(abs_y-x) = r + P_ATAN2_INNER_T() // [T] + PUT_C2() // [c2,T] + add // [c2+T] + finish: } #define macro P_ATAN2_INNER_T() = takes(1) returns(1){ //Input Stack => [r] - [X3] // [1e18,r] - dup1 // [r,1e18,r] - [X2] // [X2,r,1e18,r] + dup2 // [r,1e18,r] + [X2] // [X2,r,1e18,r] // x2 == 9817e14 mul // [X2*r,1e18,r] sdiv // [(X2*r)/1e18,r] PUT_X3_CUBE() // [1e54,(X2*r)/1e18,r] diff --git a/src/ComplexHuff/WRAPPER.huff b/src/ComplexHuff/WRAPPER.huff index a056814..16bd132 100644 --- a/src/ComplexHuff/WRAPPER.huff +++ b/src/ComplexHuff/WRAPPER.huff @@ -7,8 +7,8 @@ #define function calcR(int256,int256) view returns (uint256) #define function toPolar(int256,int256) view returns (int256,int256) #define function fromPolar(int256,int256) view returns (int256,int256) -// #define function p_atan2(int256 , int256) returns (int256) -// #define function atan1to1(int256 ) returns (int256) +#define function p_atan2(int256 , int256) view returns (int256) +#define function atan1to1(int256) view returns (int256) #define function ln(int256,int256) view returns (int256,int256) #define function sqrt(int256,int256) view returns (int256,int256) #define function expZ(int256,int256) view returns (int256,int256) @@ -96,22 +96,22 @@ FROM_POLAR() } -// #define macro P_ATAN2_LOCAL() = takes(0) returns(0){ -// 0x04 calldataload -// 0x24 calldataload -// P_ATAN2() -// 0x00 mstore -// 0x20 0x00 return +#define macro P_ATAN2_LOCAL() = takes(0) returns(0){ + 0x04 calldataload + 0x24 calldataload + P_ATAN2() + 0x00 mstore + 0x20 0x00 return -// } +} -// #define macro ATAN1TO1_LOCAL() = takes(0) returns(0){ -// 0x04 calldataload -// ATAN1TO1() -// 0x00 mstore -// 0x20 0x00 return +#define macro ATAN1TO1_LOCAL() = takes(0) returns(0){ + 0x04 calldataload + ATAN1TO1() + 0x00 mstore + 0x20 0x00 return -// } +} #define macro LN_LOCAL() = takes(0) returns(0){ 0x04 calldataload @@ -161,8 +161,8 @@ dup1 __FUNC_SIG(calcR) eq calc_R jumpi dup1 __FUNC_SIG(toPolar) eq to_Polar jumpi dup1 __FUNC_SIG(fromPolar) eq from_Polar jumpi -// dup1 __FUNC_SIG(p_atan2) eq p_atan2 jumpi -// dup1 __FUNC_SIG(atan1to1) eq atan1to1 jumpi + dup1 __FUNC_SIG(p_atan2) eq p__atan2 jumpi + dup1 __FUNC_SIG(atan1to1) eq a_tan1to1 jumpi dup1 __FUNC_SIG(ln) eq ln_Z jumpi dup1 __FUNC_SIG(sqrt) eq sqrt_jump jumpi dup1 __FUNC_SIG(expZ) eq exp_Z jumpi @@ -191,11 +191,11 @@ from_Polar: FROM_POLAR_LOCAL() - // p_atan2: - // P_ATAN2_LOCAL() + p__atan2: + P_ATAN2_LOCAL() - // atan1to1: - // ATAN1TO1_LOCAL() + a_tan1to1: + ATAN1TO1_LOCAL() ln_Z: LN_LOCAL() diff --git a/test/Complex.t.sol b/test/Complex.t.sol index 40e033a..a2ca3a5 100644 --- a/test/Complex.t.sol +++ b/test/Complex.t.sol @@ -78,6 +78,16 @@ contract ComplexTest is Test { assertApproxEqAbs(r, -5 * scale, 5e17); // 5e17 i.e. roundoff precision upto whole no. (precision might inc if calcR is optimized) assertApproxEqAbs(i, 12 * scale, 1e17); // precision : upto 1 decimal point } + + function testAtan2() public { + int256 r = complex.p_atan2(4 * scale, 3 * scale); + assertEq((r * 100) / scale, 6124); + } + + function testAtan1to1() public { + int256 r = complex.atan1to1(9 * 1e17); + assertEq((r * 100) / scale, 73); + } } interface WRAPPER { @@ -95,9 +105,9 @@ interface WRAPPER { function fromPolar(int256, int256) external returns (int256, int256); - // function p_atan2(int256, int256) external returns (int256); + function p_atan2(int256, int256) external returns (int256); - // function atan1to1(int256) external returns (int256); + function atan1to1(int256) external returns (int256); function ln(int256, int256) external returns (int256, int256);