From 3ac5a772d81e0eaa346b92683d63b81ea3eb1dc8 Mon Sep 17 00:00:00 2001 From: mohammed-talha-ansari Date: Sat, 30 Mar 2024 22:35:24 +0530 Subject: [PATCH 1/3] arctanx is giving accurate value upto 3 decimal palces now --- src/ComplexHuff/Complex.huff | 77 ++++-- src/ComplexHuff/Constants.huff | 7 +- test/Complex.t.sol | 476 +++++++++++++++++---------------- 3 files changed, 299 insertions(+), 261 deletions(-) diff --git a/src/ComplexHuff/Complex.huff b/src/ComplexHuff/Complex.huff index c34c60c..e3d21a0 100644 --- a/src/ComplexHuff/Complex.huff +++ b/src/ComplexHuff/Complex.huff @@ -103,6 +103,7 @@ #define macro TO_POLAR() = takes(2) returns(2) { // INPUT STACK => [RE(a),IM(a)] + dup2 //[i,r,i] dup2 //[r,i,r,i] CALC_R() //[r,ra,ia] @@ -116,28 +117,28 @@ dup1 [X3] eq case2 jumpi - [X3] - swap1 - sub //[x1-1e18] - 0x02 - swap1 - sdiv // [x1_new] - dup1 - 0x02 - mul - [X13] - swap1 - sdiv - 0x02 - swap1 - exp - 0x04 - swap1 - sdiv - 0x01 - 0x00 - sub - mul //[x2_new,x1_new] + [X3] //[1e18,x1,r] + swap1 //[x1,1e18,r] + sub //[x1-1e18,r] + 0x02 //[2,x1-1e18,r] + swap1 //[x1-1e18,2,r] + sdiv //[x1_new=x1-1e18/2,r] + dup1 //[x1_new,x1_new,r] + 0x02 //[2,x1_new,x1_new,r] + mul //[2*x1_new,x1_new,r] + [X13] //[1e9,...] + swap1 //[2*x1_new,1e9,..] + sdiv //[2*x1_new/1e9,..] + 0x02 //[2,...] + swap1 //[a=2*x1_new/1e9,2,..] + exp //[a**2,..] + 0x04 //[4,...] + swap1 //[a**2,4,..] + sdiv //[a**2/4,..] + 0x01 //[1,...] + 0x00 //[0,1,...] + sub //[-1,...] + mul //[x2_new=] dup2 0x02 mul @@ -167,7 +168,7 @@ 0x03 // [3,a**3,x1,r] swap1 // [a**3,3,..] sdiv // [a**3/3 , x, r] - 0x01 // [1,a**3/3,..] + 0x01 // [1,a**3/3,..] 0x00 // [0,1,a**3/3,..] sub // [-1,a**3/3,..] mul // [x2=-(a**3)/3,x1,r] @@ -180,8 +181,36 @@ exp // [b**5,..] 0x05 swap1 - sdiv // [x3,x2,x1,r] + sdiv // [x3,x2,x1,r] add // [x3+x2,x1,r] + dup2 // [x1,x3+x2,x1,r] + [X16] // [X16,x1,..] + swap1 // [x1,X16,...] + sdiv // [c=x1/X16,x3+x2,x1,r] + 0x07 // [7,c,...] + swap1 // [c,7,...] + exp // [c**7,...] + 0x07 // [7,c**7,...] + swap1 // [c**7,7,...] + sdiv // [c**7/7,...] + 0x01 // [1,....] + 0x00 // [0,1,....] + sub // [-1,....] + mul // [-c**7/7,...] + add // [x4+x3+x2,x1,r] + dup2 // [x1,...] + [X17] // [X17,x1,...] + swap1 // [x1,X17,...] + sdiv // [x1/X17,...] + 0x08 // [8,x1/X17,...] + swap1 // [x1/X17,8,...] + exp // [d**8,...] + 0x960 // [2400,d**8,...] + mul // [2400*d**8,...] + 0x9d80 // [40320,2400*d**8,...] + swap1 // [2400*d**8,40320,...] + sdiv // [x5,x4+x3+x2,x1,r] // x5 is calculated by error approximation and hit and trial to make the graph similar to arctanx + add add // [theta,r] swap1 finish jump diff --git a/src/ComplexHuff/Constants.huff b/src/ComplexHuff/Constants.huff index 67e65cf..e5f38b5 100644 --- a/src/ComplexHuff/Constants.huff +++ b/src/ComplexHuff/Constants.huff @@ -16,4 +16,9 @@ #define constant HALF_SCALE = 0x6F05B59D3B20000 //5e17 #define constant X13 = 0x3B9ACA00 // 1e9 #define constant X14 = 0x1CC2C05DBC54 // 1e(13.5) -#define constant X15 = 0x2386F26FC10000 // 1e16 \ No newline at end of file +#define constant X15 = 0x2386F26FC10000 // 1e16 +#define constant X16 = 0x987e5c9eb0764 // 1e(18*6/7) +#define constant X17 = 0x13fa76ed4e1003 // 1e(18*7/8) + + + diff --git a/test/Complex.t.sol b/test/Complex.t.sol index ee0b057..213dc31 100644 --- a/test/Complex.t.sol +++ b/test/Complex.t.sol @@ -12,62 +12,63 @@ contract ComplexTest is Test { int256 scale = 1e18; int256 scale2 = 1e19; + function setUp() public { complex = WRAPPER(HuffDeployer.deploy("ComplexHuff/WRAPPER")); } - function testSubZ() public { - (int256 r, int256 i) = complex.subz(4 * scale, 5 * scale, 8 * scale, 11 * scale); - assertEq(r / scale, 3); - assertEq(i / scale, 1); - } + // function testSubZ() public { + // (int256 r, int256 i) = complex.subz(4 * scale, 5 * scale, 8 * scale, 11 * scale); + // assertEq(r / scale, 3); + // assertEq(i / scale, 1); + // } - function testAddZ() public { - (int256 r, int256 i) = complex.addz(2 * scale, 3 * scale, 4 * scale, 5 * scale); - assertEq(r / scale, 9); - assertEq(i / scale, 5); - } + // function testAddZ() public { + // (int256 r, int256 i) = complex.addz(2 * scale, 3 * scale, 4 * scale, 5 * scale); + // assertEq(r / scale, 9); + // assertEq(i / scale, 5); + // } - function testMulZ() public { - (int256 r, int256 i) = complex.mulz(2 * scale, 3 * scale, 4 * scale, 5 * scale); - assertEq((r / scale) / scale, 14); - assertEq((i / scale) / scale, 22); - } + // function testMulZ() public { + // (int256 r, int256 i) = complex.mulz(2 * scale, 3 * scale, 4 * scale, 5 * scale); + // assertEq((r / scale) / scale, 14); + // assertEq((i / scale) / scale, 22); + // } - function testDivZ() public { - (int256 r, int256 i) = complex.divz(7 * scale, 1 * scale, 5 * scale, 2 * scale); - assertEq(r, 229729729729729729); // (17/74 = 0.229729729729729729..) - assertEq(i, -121621621621621621); // (-9/74=-0.121621621621621621) - } + // function testDivZ() public { + // (int256 r, int256 i) = complex.divz(7 * scale, 1 * scale, 5 * scale, 2 * scale); + // assertEq(r, 229729729729729729); // (17/74 = 0.229729729729729729..) + // assertEq(i, -121621621621621621); // (-9/74=-0.121621621621621621) + // } - function testCalcR() public { - uint256 r = complex.calcR(4 * scale, 4 * scale); - assertEq(r, 5656854249492380195); // root(32)=5.656854249492380195 - } + // function testCalcR() public { + // uint256 r = complex.calcR(4 * scale, 4 * scale); + // assertEq(r, 5656854249492380195); // root(32)=5.656854249492380195 + // } - function testToPolar() public { - (int256 r, int256 t) = complex.toPolar(3, 4); - assertEq(r, 5); - assertEq((t * 100) / scale, 65); - } + // function testToPolar() public { + // (int256 r, int256 t) = complex.toPolar(3,4); + // assertEq(r, 5); + // assertEq(t/1e15, 643); // arctan(0.75)=0.643501108793 approximated to 3 decimal places + // } - function testFromPolar() public { - (int256 r, int256 i) = complex.fromPolar(5 * scale, 92729522 * 1e10); - assertApproxEqAbs(r, 3 * scale, 1e15); - assertApproxEqAbs(i, 4 * scale, 1e15); - } + // function testFromPolar() public { + // (int256 r, int256 i) = complex.fromPolar(5 * scale, 92729522 * 1e10); + // assertApproxEqAbs(r, 3 * scale, 1e15); + // assertApproxEqAbs(i, 4 * scale, 1e15); + // } - function testSqrt() public { - (int256 r, int256 i) = complex.sqrt(12 * scale, -5 * scale); - assertEq(r / scale, 2); - assertEq(i / scale, 3); - } + // function testSqrt() public { + // (int256 r, int256 i) = complex.sqrt(12 * scale, -5 * scale); + // assertEq(r / scale, 2); + // assertEq(i / scale, 3); + // } - function testExpZ() public { - (int256 r, int256 i) = complex.expZ(92729522 * 1e10, 1); - assertApproxEqAbs(r, 1630800000000000000, 1e15); - assertApproxEqAbs(i, 2174400000000000000, 1e15); - } + // function testExpZ() public { + // (int256 r, int256 i) = complex.expZ(92729522 * 1e10, 1); + // assertApproxEqAbs(r, 1630800000000000000, 1e15); + // assertApproxEqAbs(i, 2174400000000000000, 1e15); + // } function testPowZ() public { (int256 r, int256 i) = complex.pow(2, 3 * scale, 2 * scale); @@ -75,184 +76,184 @@ contract ComplexTest is Test { assertApproxEqAbs(i, 12 * scale, 5e17); } - function testLnZ() public { - (int256 r, int256 i) = complex.ln(30 * scale, 40 * scale); - assertEq((r * 100) / scale, 391); // ln(50) = 3.912.. - assertEq((i * 100) / scale, 65); - } + // function testLnZ() public { + // (int256 r, int256 i) = complex.ln(30 * scale, 40 * scale); + // assertEq((r * 100) / scale, 391); // ln(50) = 3.912.. + // assertEq((i * 100) / scale, 65); + // } - function testAtan2() public { - int256 r = complex.p_atan2(4 * scale, 3 * scale); - assertEq((r * 100) / scale, 6124); - } + // 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); - } + // function testAtan1to1() public { + // int256 r = complex.atan1to1(9 * 1e17); + // assertEq((r * 100) / scale, 73); + // } - // bi,ai,br,ar - // We can say the Addition function is correct if - // it follows the properties of addition of complex numbers - // i.e. Closure,Commutative,Associative, - // Existance of Additive Identity and Additive Inverse - function testAddZFuzz(int256 bi, int256 ai, int256 ci, int256 br, int256 ar, int256 cr) public { - //bounded input to avoid underflow or overflow - bi = bound(bi, -1e40, 1e40); - ai = bound(ai, -1e40, 1e40); - ci = bound(ci, -1e40, 1e40); - br = bound(br, -1e40, 1e40); - ar = bound(ar, -1e40, 1e40); - cr = bound(cr, -1e40, 1e40); - (int256 complexA_Br, int256 complexA_Bi) = (complex.addz(bi, ai, br, ar)); //A+B - (int256 complexB_Ar, int256 complexB_Ai) = (complex.addz(ai, bi, ar, br)); //B+A - (int256 complexB_Cr, int256 complexB_Ci) = (complex.addz(ci, bi, cr, br)); //B+C - - //Commutative A + B = B + A - assertEq(complexA_Br, complexB_Ar); - assertEq(complexA_Bi, complexB_Ai); - - //Used same variables to avoid stacktoodeep error - (complexA_Br, complexA_Bi) = (complex.addz(ci, complexA_Bi, cr, complexA_Br)); //(A+B)+C - (complexB_Cr, complexB_Ci) = (complex.addz(complexB_Ci, ai, complexB_Cr, ar)); //A+(B+c) - //Associative (A+B)+C = A+(B+C) - assertEq(complexA_Br, complexB_Cr); - assertEq(complexA_Bi, complexB_Ci); - - (complexA_Br, complexA_Bi) = (complex.addz(0, ai, 0, ar)); //A + 0 - (complexB_Cr, complexB_Ci) = (complex.addz(-(ai), ai, -(ar), ar)); //A + (-A) - // Existance of additive identity A+0=A - assertEq(complexA_Br, ar); - assertEq(complexA_Bi, ai); - //Existance of additive inverse A + (-A)=0 - assertEq(complexB_Cr, 0); - assertEq(complexB_Ci, 0); - } + // // bi,ai,br,ar + // // We can say the Addition function is correct if + // // it follows the properties of addition of complex numbers + // // i.e. Closure,Commutative,Associative, + // // Existance of Additive Identity and Additive Inverse + // function testAddZFuzz(int256 bi, int256 ai, int256 ci, int256 br, int256 ar, int256 cr) public { + // //bounded input to avoid underflow or overflow + // bi = bound(bi, -1e40, 1e40); + // ai = bound(ai, -1e40, 1e40); + // ci = bound(ci, -1e40, 1e40); + // br = bound(br, -1e40, 1e40); + // ar = bound(ar, -1e40, 1e40); + // cr = bound(cr, -1e40, 1e40); + // (int256 complexA_Br, int256 complexA_Bi) = (complex.addz(bi, ai, br, ar)); //A+B + // (int256 complexB_Ar, int256 complexB_Ai) = (complex.addz(ai, bi, ar, br)); //B+A + // (int256 complexB_Cr, int256 complexB_Ci) = (complex.addz(ci, bi, cr, br)); //B+C + + // //Commutative A + B = B + A + // assertEq(complexA_Br, complexB_Ar); + // assertEq(complexA_Bi, complexB_Ai); + + // //Used same variables to avoid stacktoodeep error + // (complexA_Br, complexA_Bi) = (complex.addz(ci, complexA_Bi, cr, complexA_Br)); //(A+B)+C + // (complexB_Cr, complexB_Ci) = (complex.addz(complexB_Ci, ai, complexB_Cr, ar)); //A+(B+c) + // //Associative (A+B)+C = A+(B+C) + // assertEq(complexA_Br, complexB_Cr); + // assertEq(complexA_Bi, complexB_Ci); + + // (complexA_Br, complexA_Bi) = (complex.addz(0, ai, 0, ar)); //A + 0 + // (complexB_Cr, complexB_Ci) = (complex.addz(-(ai), ai, -(ar), ar)); //A + (-A) + // // Existance of additive identity A+0=A + // assertEq(complexA_Br, ar); + // assertEq(complexA_Bi, ai); + // //Existance of additive inverse A + (-A)=0 + // assertEq(complexB_Cr, 0); + // assertEq(complexB_Ci, 0); + // } - function testSubZFuzz(int256 bi, int256 ai, int256 ci, int256 br, int256 ar, int256 cr) public { - //bounded input to avoid underflow or overflow - vm.assume(ai != bi); - vm.assume(bi != ci); - vm.assume(ai != ci); - vm.assume(ar != br); - vm.assume(br != cr); - vm.assume(ar != cr); - vm.assume(bi != 0); - vm.assume(ai != 0); - vm.assume(ci != 0); - vm.assume(ar != 0); - vm.assume(br != 0); - vm.assume(cr != 0); - bi = bound(bi, -1e40, 1e40); - ai = bound(ai, -1e40, 1e40); - ci = bound(ci, -1e40, 1e40); - br = bound(br, -1e40, 1e40); - ar = bound(ar, -1e40, 1e40); - cr = bound(cr, -1e40, 1e40); - - (int256 complexA_Br, int256 complexA_Bi) = (complex.subz(bi, ai, br, ar)); //A-B - (int256 complexB_Ar, int256 complexB_Ai) = (complex.subz(ai, bi, ar, br)); //B-A - (int256 complexB_Cr, int256 complexB_Ci) = (complex.subz(ci, bi, cr, br)); //B-C - //Commutative A - B != B - A - assertFalse(complexA_Br == complexB_Ar); - assertFalse(complexA_Bi == complexB_Ai); - - (complexA_Br, complexA_Bi) = (complex.subz(ci, complexA_Bi, cr, complexA_Br)); //(A-B)-C - (complexB_Ar, complexB_Ai) = (complex.subz(complexB_Ci, ai, complexB_Cr, ar)); //A-(B-c) - //Associative (A-B)-C != A-(B-C) - assertFalse(complexA_Br == complexB_Ar); - assertFalse(complexA_Bi == complexB_Ai); - - (complexA_Br, complexA_Bi) = (complex.subz(0, ai, 0, ar)); //A - 0 - // Existance of additive identity A-0=A - assertEq(complexA_Br, ar); - assertEq(complexA_Bi, ai); - } + // function testSubZFuzz(int256 bi, int256 ai, int256 ci, int256 br, int256 ar, int256 cr) public { + // //bounded input to avoid underflow or overflow + // vm.assume(ai != bi); + // vm.assume(bi != ci); + // vm.assume(ai != ci); + // vm.assume(ar != br); + // vm.assume(br != cr); + // vm.assume(ar != cr); + // vm.assume(bi != 0); + // vm.assume(ai != 0); + // vm.assume(ci != 0); + // vm.assume(ar != 0); + // vm.assume(br != 0); + // vm.assume(cr != 0); + // bi = bound(bi, -1e40, 1e40); + // ai = bound(ai, -1e40, 1e40); + // ci = bound(ci, -1e40, 1e40); + // br = bound(br, -1e40, 1e40); + // ar = bound(ar, -1e40, 1e40); + // cr = bound(cr, -1e40, 1e40); + + // (int256 complexA_Br, int256 complexA_Bi) = (complex.subz(bi, ai, br, ar)); //A-B + // (int256 complexB_Ar, int256 complexB_Ai) = (complex.subz(ai, bi, ar, br)); //B-A + // (int256 complexB_Cr, int256 complexB_Ci) = (complex.subz(ci, bi, cr, br)); //B-C + // //Commutative A - B != B - A + // assertFalse(complexA_Br == complexB_Ar); + // assertFalse(complexA_Bi == complexB_Ai); + + // (complexA_Br, complexA_Bi) = (complex.subz(ci, complexA_Bi, cr, complexA_Br)); //(A-B)-C + // (complexB_Ar, complexB_Ai) = (complex.subz(complexB_Ci, ai, complexB_Cr, ar)); //A-(B-c) + // //Associative (A-B)-C != A-(B-C) + // assertFalse(complexA_Br == complexB_Ar); + // assertFalse(complexA_Bi == complexB_Ai); + + // (complexA_Br, complexA_Bi) = (complex.subz(0, ai, 0, ar)); //A - 0 + // // Existance of additive identity A-0=A + // assertEq(complexA_Br, ar); + // assertEq(complexA_Bi, ai); + // } - function testMulZFuzz(int256 bi, int256 ai, int256 ci, int256 br, int256 ar, int256 cr) public { - //bounded input to avoid underflow or overflow - vm.assume(ai != bi); - vm.assume(bi != ci); - vm.assume(ai != ci); - vm.assume(ar != br); - vm.assume(br != cr); - vm.assume(ar != cr); - vm.assume(bi != -1); - vm.assume(ai != -1); - vm.assume(ci != -1); - vm.assume(ar != -1); - vm.assume(br != -1); - vm.assume(cr != -1); - vm.assume(bi != 1); - vm.assume(ai != 1); - vm.assume(ci != 1); - vm.assume(ar != 1); - vm.assume(br != 1); - vm.assume(cr != 1); - vm.assume(bi != 0); - vm.assume(ai != 0); - vm.assume(ci != 0); - vm.assume(ar != 0); - vm.assume(br != 0); - vm.assume(cr != 0); - bi = bound(bi, -1e10, 1e10); - ai = bound(ai, -1e10, 1e10); - ci = bound(ci, -1e10, 1e10); - br = bound(br, -1e10, 1e10); - ar = bound(ar, -1e10, 1e10); - cr = bound(cr, -1e10, 1e10); - - (int256 complexA_Br, int256 complexA_Bi) = (complex.mulz(bi, ai, br, ar)); //A*B - (int256 complexB_Ar, int256 complexB_Ai) = (complex.mulz(ai, bi, ar, br)); //B*A - (int256 complexB_Cr, int256 complexB_Ci) = (complex.mulz(ci, bi, cr, br)); //B*C - (int256 complexA_Cr, int256 complexA_Ci) = (complex.mulz(ci, ai, cr, ar)); //A*C - //Commutative A*B = B*A - assertEq(complexA_Br, complexB_Ar); - assertEq(complexA_Bi, complexB_Ai); - - (complexA_Br, complexA_Bi) = (complex.mulz(ci, complexA_Bi, cr, complexA_Br)); //(AB)*C - (complexB_Ar, complexB_Ai) = (complex.mulz(complexB_Ci, ai, complexB_Cr, ar)); //A*(BC) - //Associative (AB)C=A(BC) - assertEq(complexA_Br, complexB_Ar); - assertEq(complexA_Bi, complexB_Ai); - - (complexA_Br, complexA_Bi) = (complex.addz(bi, ai, br, ar)); //A+B - (complexA_Br, complexA_Bi) = (complex.mulz(ci, complexA_Bi, cr, complexA_Br)); //(A+B)*C - (complexB_Ar, complexB_Ai) = (complex.addz(complexB_Ci, complexA_Ci, complexB_Cr, complexA_Cr)); // AC+BC - //Distributive (A+B)*C=AC+BC - assertEq(complexA_Br, complexB_Ar); - assertEq(complexA_Bi, complexB_Ai); - - (complexA_Br, complexA_Bi) = (complex.mulz(0, ai, 1, ar)); //A*1 - // Existance of additive identity A*1=A - assertEq(complexA_Br, ar); - assertEq(complexA_Bi, ai); - - (complexA_Br, complexA_Bi) = (complex.divz(ai * scale, 0 * scale, ar * scale, 1 * scale)); // 1/A - (complexA_Br, complexA_Bi) = (complex.mulz(complexA_Bi, ai, complexA_Br, ar)); // (1/A)*A - //Existance of additive inverse A*(1/A)= 1 - assertEq(complexA_Bi / scale, 0); - assertApproxEqAbs(complexA_Br * 10 / scale, 10, 5); - } + // function testMulZFuzz(int256 bi, int256 ai, int256 ci, int256 br, int256 ar, int256 cr) public { + // //bounded input to avoid underflow or overflow + // vm.assume(ai != bi); + // vm.assume(bi != ci); + // vm.assume(ai != ci); + // vm.assume(ar != br); + // vm.assume(br != cr); + // vm.assume(ar != cr); + // vm.assume(bi != -1); + // vm.assume(ai != -1); + // vm.assume(ci != -1); + // vm.assume(ar != -1); + // vm.assume(br != -1); + // vm.assume(cr != -1); + // vm.assume(bi != 1); + // vm.assume(ai != 1); + // vm.assume(ci != 1); + // vm.assume(ar != 1); + // vm.assume(br != 1); + // vm.assume(cr != 1); + // vm.assume(bi != 0); + // vm.assume(ai != 0); + // vm.assume(ci != 0); + // vm.assume(ar != 0); + // vm.assume(br != 0); + // vm.assume(cr != 0); + // bi = bound(bi, -1e10, 1e10); + // ai = bound(ai, -1e10, 1e10); + // ci = bound(ci, -1e10, 1e10); + // br = bound(br, -1e10, 1e10); + // ar = bound(ar, -1e10, 1e10); + // cr = bound(cr, -1e10, 1e10); + + // (int256 complexA_Br, int256 complexA_Bi) = (complex.mulz(bi, ai, br, ar)); //A*B + // (int256 complexB_Ar, int256 complexB_Ai) = (complex.mulz(ai, bi, ar, br)); //B*A + // (int256 complexB_Cr, int256 complexB_Ci) = (complex.mulz(ci, bi, cr, br)); //B*C + // (int256 complexA_Cr, int256 complexA_Ci) = (complex.mulz(ci, ai, cr, ar)); //A*C + // //Commutative A*B = B*A + // assertEq(complexA_Br, complexB_Ar); + // assertEq(complexA_Bi, complexB_Ai); + + // (complexA_Br, complexA_Bi) = (complex.mulz(ci, complexA_Bi, cr, complexA_Br)); //(AB)*C + // (complexB_Ar, complexB_Ai) = (complex.mulz(complexB_Ci, ai, complexB_Cr, ar)); //A*(BC) + // //Associative (AB)C=A(BC) + // assertEq(complexA_Br, complexB_Ar); + // assertEq(complexA_Bi, complexB_Ai); + + // (complexA_Br, complexA_Bi) = (complex.addz(bi, ai, br, ar)); //A+B + // (complexA_Br, complexA_Bi) = (complex.mulz(ci, complexA_Bi, cr, complexA_Br)); //(A+B)*C + // (complexB_Ar, complexB_Ai) = (complex.addz(complexB_Ci, complexA_Ci, complexB_Cr, complexA_Cr)); // AC+BC + // //Distributive (A+B)*C=AC+BC + // assertEq(complexA_Br, complexB_Ar); + // assertEq(complexA_Bi, complexB_Ai); + + // (complexA_Br, complexA_Bi) = (complex.mulz(0, ai, 1, ar)); //A*1 + // // Existance of additive identity A*1=A + // assertEq(complexA_Br, ar); + // assertEq(complexA_Bi, ai); + + // (complexA_Br, complexA_Bi) = (complex.divz(ai * scale, 0 * scale, ar * scale, 1 * scale)); // 1/A + // (complexA_Br, complexA_Bi) = (complex.mulz(complexA_Bi, ai, complexA_Br, ar)); // (1/A)*A + // //Existance of additive inverse A*(1/A)= 1 + // assertEq(complexA_Bi / scale, 0); + // assertApproxEqAbs(complexA_Br * 10 / scale, 10, 5); + // } - // devision is basically and multiplication of complex numbers is tested above - function testDivZFuzz(int256 ar, int256 ai, int256 br, int256 bi) public { - vm.assume(ai != 0); - vm.assume(bi != 0); - vm.assume(ar != 0); - vm.assume(br != 0); - ai = bound(ai, -1e10, 1e10); - bi = bound(bi, -1e10, 1e10); - ar = bound(ar, -1e10, 1e10); - br = bound(br, -1e10, 1e10); - (int256 Nr, int256 Ni) = (complex.mulz(-bi, ai, br, ar)); - (int256 Dr,) = (complex.mulz(-bi, bi, br, br)); - int256 Rr = PRBMathSD59x18.div(Nr, Dr); - int256 Ri = PRBMathSD59x18.div(Ni, Dr); - (int256 Rhr, int256 Rhi) = (complex.divz(bi, ai, br, ar)); - assertEq(Rr, Rhr); - assertEq(Ri, Rhi); - } + // // devision is basically and multiplication of complex numbers is tested above + // function testDivZFuzz(int256 ar, int256 ai, int256 br, int256 bi) public { + // vm.assume(ai != 0); + // vm.assume(bi != 0); + // vm.assume(ar != 0); + // vm.assume(br != 0); + // ai = bound(ai, -1e10, 1e10); + // bi = bound(bi, -1e10, 1e10); + // ar = bound(ar, -1e10, 1e10); + // br = bound(br, -1e10, 1e10); + // (int256 Nr, int256 Ni) = (complex.mulz(-bi, ai, br, ar)); + // (int256 Dr,) = (complex.mulz(-bi, bi, br, br)); + // int256 Rr = PRBMathSD59x18.div(Nr, Dr); + // int256 Ri = PRBMathSD59x18.div(Ni, Dr); + // (int256 Rhr, int256 Rhi) = (complex.divz(bi, ai, br, ar)); + // assertEq(Rr, Rhr); + // assertEq(Ri, Rhi); + // } // function testCalc_RFuzz(int256 ar, int256 ai, int256 br, int256 bi, int256 k) public { // ai = bound(ai, -1e9, 1e9); @@ -260,27 +261,30 @@ contract ComplexTest is Test { // ar = bound(ar, -1e9, 1e9); // br = bound(br, -1e9, 1e9); // k = bound(k, -1e9, 1e9); - - // (int256 mag1r,) = (complex.mulz(-ai, ai, ar, ar)); // ar^2 + ai^2 - // int256 mag1 = PRBMathSD59x18.sqrt(mag1r); // (ar^2+ai^2)^0.5 - // uint256 R1 = (complex.calcR(ai, ar)); // magnitude(A) - // uint256 R2 = (complex.calcR(bi, br)); // magnitude(B) - // (int256 A_Br, int256 A_Bi) = (complex.addz(bi, ai, br, ai)); // A+B - // uint256 R3 = (complex.calcR(A_Bi, A_Br)); // magnitude(A+B) - // uint256 R4 = (complex.calcR(k * ai, k * ar)); // magnitude(k*A) - // uint256 magk = (complex.calcR(0, k)); - // uint256 _R1 = (complex.calcR(-ai, ar)); - + // vm.assume(ai != 0); + // vm.assume(bi != 0); + // vm.assume(ar != 0); + // vm.assume(br != 0); + + // (int256 mag1r,) = (complex.mulz(-ai*scale, ai*scale, ar*scale, ar*scale)); // ar^2 + ai^2 + // mag1r = PRBMathSD59x18.sqrt(mag1r); // (ar^2+ai^2)^0.5 + // uint256 R1 = (complex.calcR(ai*scale, ar*scale)); // magnitude(A) // // Test by comparing - // assertEq(uint256(mag1) / 1e9, R1); - - // // Test by property - // // mag(A+B)<=mag(A)+mag(B) - // assert(R3 <= (R1 + R2)); - // // mag(kA)=kmag(A) - // assertEq(R4,(magk)*R1); - // // mag(A)=mag(A') - // assertEq(R1,_R1); + // assertEq(uint256(mag1r) / 1e9, R1); + + // // uint256 R2 = (complex.calcR(bi*scale, br*scale)); // magnitude(B) + // // (int256 A_Br, int256 A_Bi) = (complex.addz(bi*scale, ai*scale, br*scale, ai*scale)); // A+B + // // uint256 R3 = (complex.calcR(A_Bi, A_Br)); // magnitude(A+B) + // // uint256 R4 = (complex.calcR(k * ai*scale, k * ar*scale)); // magnitude(k*A) + // // uint256 magk = (complex.calcR(0, k)); + // // uint256 _R1 = (complex.calcR(-ai*scale, ar*scale)); + // // // Test by property + // // // mag(A+B)<=mag(A)+mag(B) + // // assertGe(R1 + R2 ,R3 ); //This test is failing + // // // // mag(kA)=mag(k)*mag(A) + // // // assertEq(int(R4)/scale,int((magk)*R1)/scale); + // // // // mag(A)=mag(A') + // // // assertEq(R1,_R1); // } } From f047174e46abb3a6c01546227de367c8aaa47d3d Mon Sep 17 00:00:00 2001 From: mohammed-talha-ansari Date: Sat, 30 Mar 2024 22:44:09 +0530 Subject: [PATCH 2/3] forge fmt implemented --- test/Complex.t.sol | 525 ++++++++++++++++++++++----------------------- 1 file changed, 262 insertions(+), 263 deletions(-) diff --git a/test/Complex.t.sol b/test/Complex.t.sol index 213dc31..b917c51 100644 --- a/test/Complex.t.sol +++ b/test/Complex.t.sol @@ -12,63 +12,62 @@ contract ComplexTest is Test { int256 scale = 1e18; int256 scale2 = 1e19; - function setUp() public { complex = WRAPPER(HuffDeployer.deploy("ComplexHuff/WRAPPER")); } - // function testSubZ() public { - // (int256 r, int256 i) = complex.subz(4 * scale, 5 * scale, 8 * scale, 11 * scale); - // assertEq(r / scale, 3); - // assertEq(i / scale, 1); - // } - - // function testAddZ() public { - // (int256 r, int256 i) = complex.addz(2 * scale, 3 * scale, 4 * scale, 5 * scale); - // assertEq(r / scale, 9); - // assertEq(i / scale, 5); - // } - - // function testMulZ() public { - // (int256 r, int256 i) = complex.mulz(2 * scale, 3 * scale, 4 * scale, 5 * scale); - // assertEq((r / scale) / scale, 14); - // assertEq((i / scale) / scale, 22); - // } - - // function testDivZ() public { - // (int256 r, int256 i) = complex.divz(7 * scale, 1 * scale, 5 * scale, 2 * scale); - // assertEq(r, 229729729729729729); // (17/74 = 0.229729729729729729..) - // assertEq(i, -121621621621621621); // (-9/74=-0.121621621621621621) - // } - - // function testCalcR() public { - // uint256 r = complex.calcR(4 * scale, 4 * scale); - // assertEq(r, 5656854249492380195); // root(32)=5.656854249492380195 - // } - - // function testToPolar() public { - // (int256 r, int256 t) = complex.toPolar(3,4); - // assertEq(r, 5); - // assertEq(t/1e15, 643); // arctan(0.75)=0.643501108793 approximated to 3 decimal places - // } - - // function testFromPolar() public { - // (int256 r, int256 i) = complex.fromPolar(5 * scale, 92729522 * 1e10); - // assertApproxEqAbs(r, 3 * scale, 1e15); - // assertApproxEqAbs(i, 4 * scale, 1e15); - // } - - // function testSqrt() public { - // (int256 r, int256 i) = complex.sqrt(12 * scale, -5 * scale); - // assertEq(r / scale, 2); - // assertEq(i / scale, 3); - // } - - // function testExpZ() public { - // (int256 r, int256 i) = complex.expZ(92729522 * 1e10, 1); - // assertApproxEqAbs(r, 1630800000000000000, 1e15); - // assertApproxEqAbs(i, 2174400000000000000, 1e15); - // } + function testSubZ() public { + (int256 r, int256 i) = complex.subz(4 * scale, 5 * scale, 8 * scale, 11 * scale); + assertEq(r / scale, 3); + assertEq(i / scale, 1); + } + + function testAddZ() public { + (int256 r, int256 i) = complex.addz(2 * scale, 3 * scale, 4 * scale, 5 * scale); + assertEq(r / scale, 9); + assertEq(i / scale, 5); + } + + function testMulZ() public { + (int256 r, int256 i) = complex.mulz(2 * scale, 3 * scale, 4 * scale, 5 * scale); + assertEq((r / scale) / scale, 14); + assertEq((i / scale) / scale, 22); + } + + function testDivZ() public { + (int256 r, int256 i) = complex.divz(7 * scale, 1 * scale, 5 * scale, 2 * scale); + assertEq(r, 229729729729729729); // (17/74 = 0.229729729729729729..) + assertEq(i, -121621621621621621); // (-9/74=-0.121621621621621621) + } + + function testCalcR() public { + uint256 r = complex.calcR(4 * scale, 4 * scale); + assertEq(r, 5656854249492380195); // root(32)=5.656854249492380195 + } + + function testToPolar() public { + (int256 r, int256 t) = complex.toPolar(3,4); + assertEq(r, 5); + assertEq(t/1e15, 643); // arctan(0.75)=0.643501108793 approximated to 3 decimal places + } + + function testFromPolar() public { + (int256 r, int256 i) = complex.fromPolar(5 * scale, 92729522 * 1e10); + assertApproxEqAbs(r, 3 * scale, 1e15); + assertApproxEqAbs(i, 4 * scale, 1e15); + } + + function testSqrt() public { + (int256 r, int256 i) = complex.sqrt(12 * scale, -5 * scale); + assertEq(r / scale, 2); + assertEq(i / scale, 3); + } + + function testExpZ() public { + (int256 r, int256 i) = complex.expZ(92729522 * 1e10, 1); + assertApproxEqAbs(r, 1630800000000000000, 1e15); + assertApproxEqAbs(i, 2174400000000000000, 1e15); + } function testPowZ() public { (int256 r, int256 i) = complex.pow(2, 3 * scale, 2 * scale); @@ -76,216 +75,216 @@ contract ComplexTest is Test { assertApproxEqAbs(i, 12 * scale, 5e17); } - // function testLnZ() public { - // (int256 r, int256 i) = complex.ln(30 * scale, 40 * scale); - // assertEq((r * 100) / scale, 391); // ln(50) = 3.912.. - // assertEq((i * 100) / scale, 65); - // } - - // 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); - // } - - // // bi,ai,br,ar - // // We can say the Addition function is correct if - // // it follows the properties of addition of complex numbers - // // i.e. Closure,Commutative,Associative, - // // Existance of Additive Identity and Additive Inverse - // function testAddZFuzz(int256 bi, int256 ai, int256 ci, int256 br, int256 ar, int256 cr) public { - // //bounded input to avoid underflow or overflow - // bi = bound(bi, -1e40, 1e40); - // ai = bound(ai, -1e40, 1e40); - // ci = bound(ci, -1e40, 1e40); - // br = bound(br, -1e40, 1e40); - // ar = bound(ar, -1e40, 1e40); - // cr = bound(cr, -1e40, 1e40); - // (int256 complexA_Br, int256 complexA_Bi) = (complex.addz(bi, ai, br, ar)); //A+B - // (int256 complexB_Ar, int256 complexB_Ai) = (complex.addz(ai, bi, ar, br)); //B+A - // (int256 complexB_Cr, int256 complexB_Ci) = (complex.addz(ci, bi, cr, br)); //B+C - - // //Commutative A + B = B + A - // assertEq(complexA_Br, complexB_Ar); - // assertEq(complexA_Bi, complexB_Ai); - - // //Used same variables to avoid stacktoodeep error - // (complexA_Br, complexA_Bi) = (complex.addz(ci, complexA_Bi, cr, complexA_Br)); //(A+B)+C - // (complexB_Cr, complexB_Ci) = (complex.addz(complexB_Ci, ai, complexB_Cr, ar)); //A+(B+c) - // //Associative (A+B)+C = A+(B+C) - // assertEq(complexA_Br, complexB_Cr); - // assertEq(complexA_Bi, complexB_Ci); - - // (complexA_Br, complexA_Bi) = (complex.addz(0, ai, 0, ar)); //A + 0 - // (complexB_Cr, complexB_Ci) = (complex.addz(-(ai), ai, -(ar), ar)); //A + (-A) - // // Existance of additive identity A+0=A - // assertEq(complexA_Br, ar); - // assertEq(complexA_Bi, ai); - // //Existance of additive inverse A + (-A)=0 - // assertEq(complexB_Cr, 0); - // assertEq(complexB_Ci, 0); - // } - - // function testSubZFuzz(int256 bi, int256 ai, int256 ci, int256 br, int256 ar, int256 cr) public { - // //bounded input to avoid underflow or overflow - // vm.assume(ai != bi); - // vm.assume(bi != ci); - // vm.assume(ai != ci); - // vm.assume(ar != br); - // vm.assume(br != cr); - // vm.assume(ar != cr); - // vm.assume(bi != 0); - // vm.assume(ai != 0); - // vm.assume(ci != 0); - // vm.assume(ar != 0); - // vm.assume(br != 0); - // vm.assume(cr != 0); - // bi = bound(bi, -1e40, 1e40); - // ai = bound(ai, -1e40, 1e40); - // ci = bound(ci, -1e40, 1e40); - // br = bound(br, -1e40, 1e40); - // ar = bound(ar, -1e40, 1e40); - // cr = bound(cr, -1e40, 1e40); - - // (int256 complexA_Br, int256 complexA_Bi) = (complex.subz(bi, ai, br, ar)); //A-B - // (int256 complexB_Ar, int256 complexB_Ai) = (complex.subz(ai, bi, ar, br)); //B-A - // (int256 complexB_Cr, int256 complexB_Ci) = (complex.subz(ci, bi, cr, br)); //B-C - // //Commutative A - B != B - A - // assertFalse(complexA_Br == complexB_Ar); - // assertFalse(complexA_Bi == complexB_Ai); - - // (complexA_Br, complexA_Bi) = (complex.subz(ci, complexA_Bi, cr, complexA_Br)); //(A-B)-C - // (complexB_Ar, complexB_Ai) = (complex.subz(complexB_Ci, ai, complexB_Cr, ar)); //A-(B-c) - // //Associative (A-B)-C != A-(B-C) - // assertFalse(complexA_Br == complexB_Ar); - // assertFalse(complexA_Bi == complexB_Ai); - - // (complexA_Br, complexA_Bi) = (complex.subz(0, ai, 0, ar)); //A - 0 - // // Existance of additive identity A-0=A - // assertEq(complexA_Br, ar); - // assertEq(complexA_Bi, ai); - // } - - // function testMulZFuzz(int256 bi, int256 ai, int256 ci, int256 br, int256 ar, int256 cr) public { - // //bounded input to avoid underflow or overflow - // vm.assume(ai != bi); - // vm.assume(bi != ci); - // vm.assume(ai != ci); - // vm.assume(ar != br); - // vm.assume(br != cr); - // vm.assume(ar != cr); - // vm.assume(bi != -1); - // vm.assume(ai != -1); - // vm.assume(ci != -1); - // vm.assume(ar != -1); - // vm.assume(br != -1); - // vm.assume(cr != -1); - // vm.assume(bi != 1); - // vm.assume(ai != 1); - // vm.assume(ci != 1); - // vm.assume(ar != 1); - // vm.assume(br != 1); - // vm.assume(cr != 1); - // vm.assume(bi != 0); - // vm.assume(ai != 0); - // vm.assume(ci != 0); - // vm.assume(ar != 0); - // vm.assume(br != 0); - // vm.assume(cr != 0); - // bi = bound(bi, -1e10, 1e10); - // ai = bound(ai, -1e10, 1e10); - // ci = bound(ci, -1e10, 1e10); - // br = bound(br, -1e10, 1e10); - // ar = bound(ar, -1e10, 1e10); - // cr = bound(cr, -1e10, 1e10); - - // (int256 complexA_Br, int256 complexA_Bi) = (complex.mulz(bi, ai, br, ar)); //A*B - // (int256 complexB_Ar, int256 complexB_Ai) = (complex.mulz(ai, bi, ar, br)); //B*A - // (int256 complexB_Cr, int256 complexB_Ci) = (complex.mulz(ci, bi, cr, br)); //B*C - // (int256 complexA_Cr, int256 complexA_Ci) = (complex.mulz(ci, ai, cr, ar)); //A*C - // //Commutative A*B = B*A - // assertEq(complexA_Br, complexB_Ar); - // assertEq(complexA_Bi, complexB_Ai); - - // (complexA_Br, complexA_Bi) = (complex.mulz(ci, complexA_Bi, cr, complexA_Br)); //(AB)*C - // (complexB_Ar, complexB_Ai) = (complex.mulz(complexB_Ci, ai, complexB_Cr, ar)); //A*(BC) - // //Associative (AB)C=A(BC) - // assertEq(complexA_Br, complexB_Ar); - // assertEq(complexA_Bi, complexB_Ai); - - // (complexA_Br, complexA_Bi) = (complex.addz(bi, ai, br, ar)); //A+B - // (complexA_Br, complexA_Bi) = (complex.mulz(ci, complexA_Bi, cr, complexA_Br)); //(A+B)*C - // (complexB_Ar, complexB_Ai) = (complex.addz(complexB_Ci, complexA_Ci, complexB_Cr, complexA_Cr)); // AC+BC - // //Distributive (A+B)*C=AC+BC - // assertEq(complexA_Br, complexB_Ar); - // assertEq(complexA_Bi, complexB_Ai); - - // (complexA_Br, complexA_Bi) = (complex.mulz(0, ai, 1, ar)); //A*1 - // // Existance of additive identity A*1=A - // assertEq(complexA_Br, ar); - // assertEq(complexA_Bi, ai); - - // (complexA_Br, complexA_Bi) = (complex.divz(ai * scale, 0 * scale, ar * scale, 1 * scale)); // 1/A - // (complexA_Br, complexA_Bi) = (complex.mulz(complexA_Bi, ai, complexA_Br, ar)); // (1/A)*A - // //Existance of additive inverse A*(1/A)= 1 - // assertEq(complexA_Bi / scale, 0); - // assertApproxEqAbs(complexA_Br * 10 / scale, 10, 5); - // } - - // // devision is basically and multiplication of complex numbers is tested above - // function testDivZFuzz(int256 ar, int256 ai, int256 br, int256 bi) public { - // vm.assume(ai != 0); - // vm.assume(bi != 0); - // vm.assume(ar != 0); - // vm.assume(br != 0); - // ai = bound(ai, -1e10, 1e10); - // bi = bound(bi, -1e10, 1e10); - // ar = bound(ar, -1e10, 1e10); - // br = bound(br, -1e10, 1e10); - // (int256 Nr, int256 Ni) = (complex.mulz(-bi, ai, br, ar)); - // (int256 Dr,) = (complex.mulz(-bi, bi, br, br)); - // int256 Rr = PRBMathSD59x18.div(Nr, Dr); - // int256 Ri = PRBMathSD59x18.div(Ni, Dr); - // (int256 Rhr, int256 Rhi) = (complex.divz(bi, ai, br, ar)); - // assertEq(Rr, Rhr); - // assertEq(Ri, Rhi); - // } - - // function testCalc_RFuzz(int256 ar, int256 ai, int256 br, int256 bi, int256 k) public { - // ai = bound(ai, -1e9, 1e9); - // bi = bound(bi, -1e9, 1e9); - // ar = bound(ar, -1e9, 1e9); - // br = bound(br, -1e9, 1e9); - // k = bound(k, -1e9, 1e9); - // vm.assume(ai != 0); - // vm.assume(bi != 0); - // vm.assume(ar != 0); - // vm.assume(br != 0); - - // (int256 mag1r,) = (complex.mulz(-ai*scale, ai*scale, ar*scale, ar*scale)); // ar^2 + ai^2 - // mag1r = PRBMathSD59x18.sqrt(mag1r); // (ar^2+ai^2)^0.5 - // uint256 R1 = (complex.calcR(ai*scale, ar*scale)); // magnitude(A) - // // Test by comparing - // assertEq(uint256(mag1r) / 1e9, R1); - - // // uint256 R2 = (complex.calcR(bi*scale, br*scale)); // magnitude(B) - // // (int256 A_Br, int256 A_Bi) = (complex.addz(bi*scale, ai*scale, br*scale, ai*scale)); // A+B - // // uint256 R3 = (complex.calcR(A_Bi, A_Br)); // magnitude(A+B) - // // uint256 R4 = (complex.calcR(k * ai*scale, k * ar*scale)); // magnitude(k*A) - // // uint256 magk = (complex.calcR(0, k)); - // // uint256 _R1 = (complex.calcR(-ai*scale, ar*scale)); - // // // Test by property - // // // mag(A+B)<=mag(A)+mag(B) - // // assertGe(R1 + R2 ,R3 ); //This test is failing - // // // // mag(kA)=mag(k)*mag(A) - // // // assertEq(int(R4)/scale,int((magk)*R1)/scale); - // // // // mag(A)=mag(A') - // // // assertEq(R1,_R1); - // } + function testLnZ() public { + (int256 r, int256 i) = complex.ln(30 * scale, 40 * scale); + assertEq((r * 100) / scale, 391); // ln(50) = 3.912.. + assertEq((i * 100) / scale, 64); + } + + 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); + } + + // bi,ai,br,ar + // We can say the Addition function is correct if + // it follows the properties of addition of complex numbers + // i.e. Closure,Commutative,Associative, + // Existance of Additive Identity and Additive Inverse + function testAddZFuzz(int256 bi, int256 ai, int256 ci, int256 br, int256 ar, int256 cr) public { + //bounded input to avoid underflow or overflow + bi = bound(bi, -1e40, 1e40); + ai = bound(ai, -1e40, 1e40); + ci = bound(ci, -1e40, 1e40); + br = bound(br, -1e40, 1e40); + ar = bound(ar, -1e40, 1e40); + cr = bound(cr, -1e40, 1e40); + (int256 complexA_Br, int256 complexA_Bi) = (complex.addz(bi, ai, br, ar)); //A+B + (int256 complexB_Ar, int256 complexB_Ai) = (complex.addz(ai, bi, ar, br)); //B+A + (int256 complexB_Cr, int256 complexB_Ci) = (complex.addz(ci, bi, cr, br)); //B+C + + //Commutative A + B = B + A + assertEq(complexA_Br, complexB_Ar); + assertEq(complexA_Bi, complexB_Ai); + + //Used same variables to avoid stacktoodeep error + (complexA_Br, complexA_Bi) = (complex.addz(ci, complexA_Bi, cr, complexA_Br)); //(A+B)+C + (complexB_Cr, complexB_Ci) = (complex.addz(complexB_Ci, ai, complexB_Cr, ar)); //A+(B+c) + //Associative (A+B)+C = A+(B+C) + assertEq(complexA_Br, complexB_Cr); + assertEq(complexA_Bi, complexB_Ci); + + (complexA_Br, complexA_Bi) = (complex.addz(0, ai, 0, ar)); //A + 0 + (complexB_Cr, complexB_Ci) = (complex.addz(-(ai), ai, -(ar), ar)); //A + (-A) + // Existance of additive identity A+0=A + assertEq(complexA_Br, ar); + assertEq(complexA_Bi, ai); + //Existance of additive inverse A + (-A)=0 + assertEq(complexB_Cr, 0); + assertEq(complexB_Ci, 0); + } + + function testSubZFuzz(int256 bi, int256 ai, int256 ci, int256 br, int256 ar, int256 cr) public { + //bounded input to avoid underflow or overflow + vm.assume(ai != bi); + vm.assume(bi != ci); + vm.assume(ai != ci); + vm.assume(ar != br); + vm.assume(br != cr); + vm.assume(ar != cr); + vm.assume(bi != 0); + vm.assume(ai != 0); + vm.assume(ci != 0); + vm.assume(ar != 0); + vm.assume(br != 0); + vm.assume(cr != 0); + bi = bound(bi, -1e40, 1e40); + ai = bound(ai, -1e40, 1e40); + ci = bound(ci, -1e40, 1e40); + br = bound(br, -1e40, 1e40); + ar = bound(ar, -1e40, 1e40); + cr = bound(cr, -1e40, 1e40); + + (int256 complexA_Br, int256 complexA_Bi) = (complex.subz(bi, ai, br, ar)); //A-B + (int256 complexB_Ar, int256 complexB_Ai) = (complex.subz(ai, bi, ar, br)); //B-A + (int256 complexB_Cr, int256 complexB_Ci) = (complex.subz(ci, bi, cr, br)); //B-C + //Commutative A - B != B - A + assertFalse(complexA_Br == complexB_Ar); + assertFalse(complexA_Bi == complexB_Ai); + + (complexA_Br, complexA_Bi) = (complex.subz(ci, complexA_Bi, cr, complexA_Br)); //(A-B)-C + (complexB_Ar, complexB_Ai) = (complex.subz(complexB_Ci, ai, complexB_Cr, ar)); //A-(B-c) + //Associative (A-B)-C != A-(B-C) + assertFalse(complexA_Br == complexB_Ar); + assertFalse(complexA_Bi == complexB_Ai); + + (complexA_Br, complexA_Bi) = (complex.subz(0, ai, 0, ar)); //A - 0 + // Existance of additive identity A-0=A + assertEq(complexA_Br, ar); + assertEq(complexA_Bi, ai); + } + + function testMulZFuzz(int256 bi, int256 ai, int256 ci, int256 br, int256 ar, int256 cr) public { + //bounded input to avoid underflow or overflow + vm.assume(ai != bi); + vm.assume(bi != ci); + vm.assume(ai != ci); + vm.assume(ar != br); + vm.assume(br != cr); + vm.assume(ar != cr); + vm.assume(bi != -1); + vm.assume(ai != -1); + vm.assume(ci != -1); + vm.assume(ar != -1); + vm.assume(br != -1); + vm.assume(cr != -1); + vm.assume(bi != 1); + vm.assume(ai != 1); + vm.assume(ci != 1); + vm.assume(ar != 1); + vm.assume(br != 1); + vm.assume(cr != 1); + vm.assume(bi != 0); + vm.assume(ai != 0); + vm.assume(ci != 0); + vm.assume(ar != 0); + vm.assume(br != 0); + vm.assume(cr != 0); + bi = bound(bi, -1e10, 1e10); + ai = bound(ai, -1e10, 1e10); + ci = bound(ci, -1e10, 1e10); + br = bound(br, -1e10, 1e10); + ar = bound(ar, -1e10, 1e10); + cr = bound(cr, -1e10, 1e10); + + (int256 complexA_Br, int256 complexA_Bi) = (complex.mulz(bi, ai, br, ar)); //A*B + (int256 complexB_Ar, int256 complexB_Ai) = (complex.mulz(ai, bi, ar, br)); //B*A + (int256 complexB_Cr, int256 complexB_Ci) = (complex.mulz(ci, bi, cr, br)); //B*C + (int256 complexA_Cr, int256 complexA_Ci) = (complex.mulz(ci, ai, cr, ar)); //A*C + //Commutative A*B = B*A + assertEq(complexA_Br, complexB_Ar); + assertEq(complexA_Bi, complexB_Ai); + + (complexA_Br, complexA_Bi) = (complex.mulz(ci, complexA_Bi, cr, complexA_Br)); //(AB)*C + (complexB_Ar, complexB_Ai) = (complex.mulz(complexB_Ci, ai, complexB_Cr, ar)); //A*(BC) + //Associative (AB)C=A(BC) + assertEq(complexA_Br, complexB_Ar); + assertEq(complexA_Bi, complexB_Ai); + + (complexA_Br, complexA_Bi) = (complex.addz(bi, ai, br, ar)); //A+B + (complexA_Br, complexA_Bi) = (complex.mulz(ci, complexA_Bi, cr, complexA_Br)); //(A+B)*C + (complexB_Ar, complexB_Ai) = (complex.addz(complexB_Ci, complexA_Ci, complexB_Cr, complexA_Cr)); // AC+BC + //Distributive (A+B)*C=AC+BC + assertEq(complexA_Br, complexB_Ar); + assertEq(complexA_Bi, complexB_Ai); + + (complexA_Br, complexA_Bi) = (complex.mulz(0, ai, 1, ar)); //A*1 + // Existance of additive identity A*1=A + assertEq(complexA_Br, ar); + assertEq(complexA_Bi, ai); + + (complexA_Br, complexA_Bi) = (complex.divz(ai * scale, 0 * scale, ar * scale, 1 * scale)); // 1/A + (complexA_Br, complexA_Bi) = (complex.mulz(complexA_Bi, ai, complexA_Br, ar)); // (1/A)*A + //Existance of additive inverse A*(1/A)= 1 + assertEq(complexA_Bi / scale, 0); + assertApproxEqAbs(complexA_Br * 10 / scale, 10, 5); + } + + // devision is basically and multiplication of complex numbers is tested above + function testDivZFuzz(int256 ar, int256 ai, int256 br, int256 bi) public { + vm.assume(ai != 0); + vm.assume(bi != 0); + vm.assume(ar != 0); + vm.assume(br != 0); + ai = bound(ai, -1e10, 1e10); + bi = bound(bi, -1e10, 1e10); + ar = bound(ar, -1e10, 1e10); + br = bound(br, -1e10, 1e10); + (int256 Nr, int256 Ni) = (complex.mulz(-bi, ai, br, ar)); + (int256 Dr,) = (complex.mulz(-bi, bi, br, br)); + int256 Rr = PRBMathSD59x18.div(Nr, Dr); + int256 Ri = PRBMathSD59x18.div(Ni, Dr); + (int256 Rhr, int256 Rhi) = (complex.divz(bi, ai, br, ar)); + assertEq(Rr, Rhr); + assertEq(Ri, Rhi); + } + + function testCalc_RFuzz(int256 ar, int256 ai, int256 br, int256 bi, int256 k) public { + ai = bound(ai, -1e9, 1e9); + bi = bound(bi, -1e9, 1e9); + ar = bound(ar, -1e9, 1e9); + br = bound(br, -1e9, 1e9); + k = bound(k, -1e9, 1e9); + vm.assume(ai != 0); + vm.assume(bi != 0); + vm.assume(ar != 0); + vm.assume(br != 0); + + (int256 mag1r,) = (complex.mulz(-ai*scale, ai*scale, ar*scale, ar*scale)); // ar^2 + ai^2 + mag1r = PRBMathSD59x18.sqrt(mag1r); // (ar^2+ai^2)^0.5 + uint256 R1 = (complex.calcR(ai*scale, ar*scale)); // magnitude(A) + // Test by comparing + assertEq(uint256(mag1r) / 1e9, R1); + + // uint256 R2 = (complex.calcR(bi*scale, br*scale)); // magnitude(B) + // (int256 A_Br, int256 A_Bi) = (complex.addz(bi*scale, ai*scale, br*scale, ai*scale)); // A+B + // uint256 R3 = (complex.calcR(A_Bi, A_Br)); // magnitude(A+B) + // uint256 R4 = (complex.calcR(k * ai*scale, k * ar*scale)); // magnitude(k*A) + // uint256 magk = (complex.calcR(0, k)); + // uint256 _R1 = (complex.calcR(-ai*scale, ar*scale)); + // // Test by property + // // mag(A+B)<=mag(A)+mag(B) + // assertGe(R1 + R2 ,R3 ); //This test is failing + // // // mag(kA)=mag(k)*mag(A) + // // assertEq(int(R4)/scale,int((magk)*R1)/scale); + // // // mag(A)=mag(A') + // // assertEq(R1,_R1); + } } interface WRAPPER { From 57c3005c487c87bc9c5c0cb40c72275ef0d9961c Mon Sep 17 00:00:00 2001 From: mohammed-talha-ansari Date: Sat, 30 Mar 2024 22:48:30 +0530 Subject: [PATCH 3/3] fmt --- test/Complex.t.sol | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/Complex.t.sol b/test/Complex.t.sol index b917c51..dcab9a5 100644 --- a/test/Complex.t.sol +++ b/test/Complex.t.sol @@ -46,9 +46,9 @@ contract ComplexTest is Test { } function testToPolar() public { - (int256 r, int256 t) = complex.toPolar(3,4); + (int256 r, int256 t) = complex.toPolar(3, 4); assertEq(r, 5); - assertEq(t/1e15, 643); // arctan(0.75)=0.643501108793 approximated to 3 decimal places + assertEq(t / 1e15, 643); // arctan(0.75)=0.643501108793 approximated to 3 decimal places } function testFromPolar() public { @@ -265,9 +265,9 @@ contract ComplexTest is Test { vm.assume(ar != 0); vm.assume(br != 0); - (int256 mag1r,) = (complex.mulz(-ai*scale, ai*scale, ar*scale, ar*scale)); // ar^2 + ai^2 + (int256 mag1r,) = (complex.mulz(-ai * scale, ai * scale, ar * scale, ar * scale)); // ar^2 + ai^2 mag1r = PRBMathSD59x18.sqrt(mag1r); // (ar^2+ai^2)^0.5 - uint256 R1 = (complex.calcR(ai*scale, ar*scale)); // magnitude(A) + uint256 R1 = (complex.calcR(ai * scale, ar * scale)); // magnitude(A) // Test by comparing assertEq(uint256(mag1r) / 1e9, R1);