diff --git a/vlib/cmath/complex.v b/vlib/cmath/complex.v index 178bd0059d..43f15055d5 100644 --- a/vlib/cmath/complex.v +++ b/vlib/cmath/complex.v @@ -187,6 +187,27 @@ pub fn (c Complex) tan() Complex { return c.sin().divide(c.cos()) } +// Complex Cotangent +// Based on +// http://www.suitcaseofdreams.net/Trigonometric_Functions.htm +pub fn (c Complex) cot() Complex { + return c.cos().divide(c.sin()) +} + +// Complex Secant +// Based on +// http://www.suitcaseofdreams.net/Trigonometric_Functions.htm +pub fn (c Complex) sec() Complex { + return complex(1,0).divide(c.cos()) +} + +// Complex Cosecant +// Based on +// http://www.suitcaseofdreams.net/Trigonometric_Functions.htm +pub fn (c Complex) csc() Complex { + return complex(1,0).divide(c.sin()) +} + // Complex Arc Sin / Sin Inverse // Based on // http://www.milefoot.com/math/complex/summaryops.htm @@ -234,6 +255,27 @@ pub fn (c Complex) atan() Complex { ) } +// Complex Arc Cotangent / Cotangent Inverse +// Based on +// http://www.suitcaseofdreams.net/Inverse_Functions.htm +pub fn (c Complex) acot() Complex { + return complex(1,0).divide(c).atan() +} + +// Complex Arc Secant / Secant Inverse +// Based on +// http://www.suitcaseofdreams.net/Inverse_Functions.htm +pub fn (c Complex) asec() Complex { + return complex(1,0).divide(c).acos() +} + +// Complex Arc Cosecant / Cosecant Inverse +// Based on +// http://www.suitcaseofdreams.net/Inverse_Functions.htm +pub fn (c Complex) acsc() Complex { + return complex(1,0).divide(c).asin() +} + // Complex Hyperbolic Sin // Based on // http://www.milefoot.com/math/complex/functionsofi.htm @@ -261,6 +303,27 @@ pub fn (c Complex) tanh() Complex { return c.sinh().divide(c.cosh()) } +// Complex Hyperbolic Cotangent +// Based on +// http://www.suitcaseofdreams.net/Hyperbolic_Functions.htm +pub fn (c Complex) coth() Complex { + return c.cosh().divide(c.sinh()) +} + +// Complex Hyperbolic Secant +// Based on +// http://www.suitcaseofdreams.net/Hyperbolic_Functions.htm +pub fn (c Complex) sech() Complex { + return complex(1,0).divide(c.cosh()) +} + +// Complex Hyperbolic Cosecant +// Based on +// http://www.suitcaseofdreams.net/Hyperbolic_Functions.htm +pub fn (c Complex) csch() Complex { + return complex(1,0).divide(c.sinh()) +} + // Complex Hyperbolic Arc Sin / Sin Inverse // Based on // http://www.suitcaseofdreams.net/Inverse__Hyperbolic_Functions.htm @@ -300,8 +363,8 @@ pub fn (c Complex) acosh() Complex { // Based on // http://www.suitcaseofdreams.net/Inverse__Hyperbolic_Functions.htm pub fn (c Complex) atanh() Complex { + one := complex(1,0) if(c.re < 1) { - one := complex(1,0) return complex(1.0/2,0).multiply( one .add(c) @@ -313,7 +376,6 @@ pub fn (c Complex) atanh() Complex { ) } else { - one := complex(1,0) return complex(1.0/2,0).multiply( one .add(c) @@ -327,7 +389,92 @@ pub fn (c Complex) atanh() Complex { } } +// Complex Hyperbolic Arc Cotangent / Cotangent Inverse +// Based on +// http://www.suitcaseofdreams.net/Inverse__Hyperbolic_Functions.htm +pub fn (c Complex) acoth() Complex { + one := complex(1,0) + if(c.re < 0 || c.re > 1) { + return complex(1.0/2,0).multiply( + c + .add(one) + .divide( + c.subtract(one) + ) + .ln() + ) + } + else { + div := one.divide(c) + return complex(1.0/2,0).multiply( + one + .add(div) + .ln() + .subtract( + one + .subtract(div) + .ln() + ) + ) + } +} + +// Complex Hyperbolic Arc Secant / Secant Inverse +// Based on +// http://www.suitcaseofdreams.net/Inverse__Hyperbolic_Functions.htm +// For certain scenarios, Result mismatch in crossverification with Wolfram Alpha - analysis pending +// pub fn (c Complex) asech() Complex { +// one := complex(1,0) + // if(c.re < -1.0) { + // return one.subtract( + // one.subtract( + // c.pow(2) + // ) + // .root(2) + // ) + // .divide(c) + // .ln() + // } + // else { + // return one.add( + // one.subtract( + // c.pow(2) + // ) + // .root(2) + // ) + // .divide(c) + // .ln() + // } +// } + +// Complex Hyperbolic Arc Cosecant / Cosecant Inverse +// Based on +// http://www.suitcaseofdreams.net/Inverse__Hyperbolic_Functions.htm +pub fn (c Complex) acsch() Complex { + one := complex(1,0) + if(c.re < 0) { + return one.subtract( + one.add( + c.pow(2) + ) + .root(2) + ) + .divide(c) + .ln() + } + if(c.re > 0) { + return one.add( + one.add( + c.pow(2) + ) + .root(2) + ) + .divide(c) + .ln() + } +} + // Complex Equals pub fn (c1 Complex) equals(c2 Complex) bool { return (c1.re == c2.re) && (c1.im == c2.im) -} +} \ No newline at end of file diff --git a/vlib/cmath/complex_test.v b/vlib/cmath/complex_test.v index 26cf40012d..50b19930a9 100644 --- a/vlib/cmath/complex_test.v +++ b/vlib/cmath/complex_test.v @@ -311,6 +311,63 @@ fn test_complex_tan() { assert result.str().eq(c2.str()) } +fn test_complex_cot() { + // Tests were also verified on Wolfram Alpha + mut c1 := cmath.complex(5,7) + mut c2 := cmath.complex(-0.000001,-0.999999) + mut result := c1.cot() + // Some issue with precision comparison in f64 using == operator hence serializing to string + assert result.str().eq(c2.str()) + c1 = cmath.complex(-3,4) + c2 = cmath.complex(0.000188,-1.000644) + result = c1.cot() + // Some issue with precision comparison in f64 using == operator hence serializing to string + assert result.str().eq(c2.str()) + c1 = cmath.complex(-1,-2) + c2 = cmath.complex(-0.032798,0.984329) + result = c1.cot() + // Some issue with precision comparison in f64 using == operator hence serializing to string + assert result.str().eq(c2.str()) +} + +fn test_complex_sec() { + // Tests were also verified on Wolfram Alpha + mut c1 := cmath.complex(5,7) + mut c2 := cmath.complex(0.000517,-0.001749) + mut result := c1.sec() + // Some issue with precision comparison in f64 using == operator hence serializing to string + assert result.str().eq(c2.str()) + c1 = cmath.complex(-3,4) + c2 = cmath.complex(-0.036253,-0.005164) + result = c1.sec() + // Some issue with precision comparison in f64 using == operator hence serializing to string + assert result.str().eq(c2.str()) + c1 = cmath.complex(-1,-2) + c2 = cmath.complex(0.151176,0.226974) + result = c1.sec() + // Some issue with precision comparison in f64 using == operator hence serializing to string + assert result.str().eq(c2.str()) +} + +fn test_complex_csc() { + // Tests were also verified on Wolfram Alpha + mut c1 := cmath.complex(5,7) + mut c2 := cmath.complex(-0.001749,-0.000517) + mut result := c1.csc() + // Some issue with precision comparison in f64 using == operator hence serializing to string + assert result.str().eq(c2.str()) + c1 = cmath.complex(-3,4) + c2 = cmath.complex(-0.005174,0.036276) + result = c1.csc() + // Some issue with precision comparison in f64 using == operator hence serializing to string + assert result.str().eq(c2.str()) + c1 = cmath.complex(-1,-2) + c2 = cmath.complex(-0.228375,0.141363) + result = c1.csc() + // Some issue with precision comparison in f64 using == operator hence serializing to string + assert result.str().eq(c2.str()) +} + fn test_complex_asin() { // Tests were also verified on Wolfram Alpha mut c1 := cmath.complex(5,7) @@ -368,6 +425,63 @@ fn test_complex_atan() { assert result.str().eq(c2.str()) } +fn test_complex_acot() { + // Tests were also verified on Wolfram Alpha + mut c1 := cmath.complex(5,7) + mut c2 := cmath.complex(0.068069,-0.094441) + mut result := c1.acot() + // Some issue with precision comparison in f64 using == operator hence serializing to string + assert result.str().eq(c2.str()) + c1 = cmath.complex(-3,4) + c2 = cmath.complex(-0.122489,-0.158997) + result = c1.acot() + // Some issue with precision comparison in f64 using == operator hence serializing to string + assert result.str().eq(c2.str()) + c1 = cmath.complex(-1,-2) + c2 = cmath.complex(-0.231824,0.402359) + result = c1.acot() + // Some issue with precision comparison in f64 using == operator hence serializing to string + assert result.str().eq(c2.str()) +} + +fn test_complex_asec() { + // Tests were also verified on Wolfram Alpha + mut c1 := cmath.complex(5,7) + mut c2 := cmath.complex(1.503480,0.094668) + mut result := c1.asec() + // Some issue with precision comparison in f64 using == operator hence serializing to string + assert result.str().eq(c2.str()) + c1 = cmath.complex(-3,4) + c2 = cmath.complex(1.689547,0.160446) + result = c1.asec() + // Some issue with precision comparison in f64 using == operator hence serializing to string + assert result.str().eq(c2.str()) + c1 = cmath.complex(-1,-2) + c2 = cmath.complex(1.757114,-0.396568) + result = c1.asec() + // Some issue with precision comparison in f64 using == operator hence serializing to string + assert result.str().eq(c2.str()) +} + +fn test_complex_acsc() { + // Tests were also verified on Wolfram Alpha + mut c1 := cmath.complex(5,7) + mut c2 := cmath.complex(0.067317,-0.094668) + mut result := c1.acsc() + // Some issue with precision comparison in f64 using == operator hence serializing to string + assert result.str().eq(c2.str()) + c1 = cmath.complex(-3,4) + c2 = cmath.complex(-0.118751,-0.160446) + result = c1.acsc() + // Some issue with precision comparison in f64 using == operator hence serializing to string + assert result.str().eq(c2.str()) + c1 = cmath.complex(-1,-2) + c2 = cmath.complex(-0.186318,0.396568) + result = c1.acsc() + // Some issue with precision comparison in f64 using == operator hence serializing to string + assert result.str().eq(c2.str()) +} + fn test_complex_sinh() { // Tests were also verified on Wolfram Alpha mut c1 := cmath.complex(5,7) @@ -424,7 +538,64 @@ fn test_complex_tanh() { // Some issue with precision comparison in f64 using == operator hence serializing to string assert result.str().eq(c2.str()) } + +fn test_complex_coth() { + // Tests were also verified on Wolfram Alpha + mut c1 := cmath.complex(5,7) + mut c2 := cmath.complex(1.000012,-0.000090) + mut result := c1.coth() + // Some issue with precision comparison in f64 using == operator hence serializing to string + assert result.str().eq(c2.str()) + c1 = cmath.complex(-3,4) + c2 = cmath.complex(-0.999267,-0.004901) + result = c1.coth() + // Some issue with precision comparison in f64 using == operator hence serializing to string + assert result.str().eq(c2.str()) + c1 = cmath.complex(-1,-2) + c2 = cmath.complex(-0.821330,-0.171384) + result = c1.coth() + // Some issue with precision comparison in f64 using == operator hence serializing to string + assert result.str().eq(c2.str()) +} +fn test_complex_sech() { + // Tests were also verified on Wolfram Alpha + mut c1 := cmath.complex(5,7) + mut c2 := cmath.complex(0.010160,-0.008853) + mut result := c1.sech() + // Some issue with precision comparison in f64 using == operator hence serializing to string + assert result.str().eq(c2.str()) + c1 = cmath.complex(-3,4) + c2 = cmath.complex(-0.065294,-0.075225) + result = c1.sech() + // Some issue with precision comparison in f64 using == operator hence serializing to string + assert result.str().eq(c2.str()) + c1 = cmath.complex(-1,-2) + c2 = cmath.complex(-0.413149,-0.687527) + result = c1.sech() + // Some issue with precision comparison in f64 using == operator hence serializing to string + assert result.str().eq(c2.str()) +} + +fn test_complex_csch() { + // Tests were also verified on Wolfram Alpha + mut c1 := cmath.complex(5,7) + mut c2 := cmath.complex(0.010159,-0.008854) + mut result := c1.csch() + // Some issue with precision comparison in f64 using == operator hence serializing to string + assert result.str().eq(c2.str()) + c1 = cmath.complex(-3,4) + c2 = cmath.complex(0.064877,0.075490) + result = c1.csch() + // Some issue with precision comparison in f64 using == operator hence serializing to string + assert result.str().eq(c2.str()) + c1 = cmath.complex(-1,-2) + c2 = cmath.complex(0.221501,0.635494) + result = c1.csch() + // Some issue with precision comparison in f64 using == operator hence serializing to string + assert result.str().eq(c2.str()) +} + fn test_complex_asinh() { // Tests were also verified on Wolfram Alpha mut c1 := cmath.complex(5,7) @@ -480,4 +651,61 @@ fn test_complex_atanh() { result = c1.atanh() // Some issue with precision comparison in f64 using == operator hence serializing to string assert result.str().eq(c2.str()) +} + +fn test_complex_acoth() { + // Tests were also verified on Wolfram Alpha + mut c1 := cmath.complex(5,7) + mut c2 := cmath.complex(0.067066,-0.094740) + mut result := c1.acoth() + // Some issue with precision comparison in f64 using == operator hence serializing to string + assert result.str().eq(c2.str()) + c1 = cmath.complex(-3,4) + c2 = cmath.complex(-0.117501,-0.160875) + result = c1.acoth() + // Some issue with precision comparison in f64 using == operator hence serializing to string + assert result.str().eq(c2.str()) + c1 = cmath.complex(-1,-2) + c2 = cmath.complex(-0.173287,0.392699) + result = c1.acoth() + // Some issue with precision comparison in f64 using == operator hence serializing to string + assert result.str().eq(c2.str()) +} + +// fn test_complex_asech() { +// // Tests were also verified on Wolfram Alpha +// mut c1 := cmath.complex(5,7) +// mut c2 := cmath.complex(0.094668,-1.503480) +// mut result := c1.asech() +// // Some issue with precision comparison in f64 using == operator hence serializing to string +// assert result.str().eq(c2.str()) +// c1 = cmath.complex(-3,4) +// c2 = cmath.complex(0.160446,-1.689547) +// result = c1.asech() +// // Some issue with precision comparison in f64 using == operator hence serializing to string +// assert result.str().eq(c2.str()) +// c1 = cmath.complex(-1,-2) +// c2 = cmath.complex(0.396568,1.757114) +// result = c1.asech() +// // Some issue with precision comparison in f64 using == operator hence serializing to string +// assert result.str().eq(c2.str()) +// } + +fn test_complex_acsch() { + // Tests were also verified on Wolfram Alpha + mut c1 := cmath.complex(5,7) + mut c2 := cmath.complex(0.067819,-0.094518) + mut result := c1.acsch() + // Some issue with precision comparison in f64 using == operator hence serializing to string + assert result.str().eq(c2.str()) + c1 = cmath.complex(-3,4) + c2 = cmath.complex(-0.121246,-0.159507) + result = c1.acsch() + // Some issue with precision comparison in f64 using == operator hence serializing to string + assert result.str().eq(c2.str()) + c1 = cmath.complex(-1,-2) + c2 = cmath.complex(-0.215612,0.401586) + result = c1.acsch() + // Some issue with precision comparison in f64 using == operator hence serializing to string + assert result.str().eq(c2.str()) } \ No newline at end of file