From 7701be22424b036d77eb8de268607f18d891e9ab Mon Sep 17 00:00:00 2001 From: Archan Patkar Date: Thu, 11 Jul 2019 19:05:06 +0530 Subject: [PATCH] cmath: added inverse trig operations --- vlib/cmath/complex.v | 113 ++++++++++++++++++++++++++++++++++++++ vlib/cmath/complex_test.v | 112 +++++++++++++++++++++++++++++++++++++ 2 files changed, 225 insertions(+) diff --git a/vlib/cmath/complex.v b/vlib/cmath/complex.v index 90242d072e..178bd0059d 100644 --- a/vlib/cmath/complex.v +++ b/vlib/cmath/complex.v @@ -187,6 +187,53 @@ pub fn (c Complex) tan() Complex { return c.sin().divide(c.cos()) } +// Complex Arc Sin / Sin Inverse +// Based on +// http://www.milefoot.com/math/complex/summaryops.htm +pub fn (c Complex) asin() Complex { + return complex(0,-1).multiply( + complex(0,1) + .multiply(c) + .add( + complex(1,0) + .subtract(c.pow(2)) + .root(2) + ) + .ln() + ) +} + +// Complex Arc Consine / Consine Inverse +// Based on +// http://www.milefoot.com/math/complex/summaryops.htm +pub fn (c Complex) acos() Complex { + return complex(0,-1).multiply( + c.add( + complex(0,1) + .multiply( + complex(1,0) + .subtract(c.pow(2)) + .root(2) + ) + ) + .ln() + ) +} + +// Complex Arc Tangent / Tangent Inverse +// Based on +// http://www.milefoot.com/math/complex/summaryops.htm +pub fn (c Complex) atan() Complex { + i := complex(0,1) + return complex(0,1.0/2).multiply( + i.add(c) + .divide( + i.subtract(c) + ) + .ln() + ) +} + // Complex Hyperbolic Sin // Based on // http://www.milefoot.com/math/complex/functionsofi.htm @@ -214,6 +261,72 @@ pub fn (c Complex) tanh() Complex { return c.sinh().divide(c.cosh()) } +// Complex Hyperbolic Arc Sin / Sin Inverse +// Based on +// http://www.suitcaseofdreams.net/Inverse__Hyperbolic_Functions.htm +pub fn (c Complex) asinh() Complex { + return c.add( + c.pow(2) + .add(complex(1,0)) + .root(2) + ).ln() +} + +// Complex Hyperbolic Arc Consine / Consine Inverse +// Based on +// http://www.suitcaseofdreams.net/Inverse__Hyperbolic_Functions.htm +pub fn (c Complex) acosh() Complex { + if(c.re > 1) { + return c.add( + c.pow(2) + .subtract(complex(1,0)) + .root(2) + ).ln() + } + else { + one := complex(1,0) + return c.add( + c.add(one) + .root(2) + .multiply( + c.subtract(one) + .root(2) + ) + ).ln() + } +} + +// Complex Hyperbolic Arc Tangent / Tangent Inverse +// Based on +// http://www.suitcaseofdreams.net/Inverse__Hyperbolic_Functions.htm +pub fn (c Complex) atanh() Complex { + if(c.re < 1) { + one := complex(1,0) + return complex(1.0/2,0).multiply( + one + .add(c) + .divide( + one + .subtract(c) + ) + .ln() + ) + } + else { + one := complex(1,0) + return complex(1.0/2,0).multiply( + one + .add(c) + .ln() + .subtract( + one + .subtract(c) + .ln() + ) + ) + } +} + // Complex Equals pub fn (c1 Complex) equals(c2 Complex) bool { return (c1.re == c2.re) && (c1.im == c2.im) diff --git a/vlib/cmath/complex_test.v b/vlib/cmath/complex_test.v index 9218d172fd..26cf40012d 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_asin() { + // Tests were also verified on Wolfram Alpha + mut c1 := cmath.complex(5,7) + mut c2 := cmath.complex(0.617064,2.846289) + mut result := c1.asin() + // 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.633984,2.305509) + result = c1.asin() + // 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.427079,-1.528571) + result = c1.asin() + // Some issue with precision comparison in f64 using == operator hence serializing to string + assert result.str().eq(c2.str()) +} + +fn test_complex_acos() { + // Tests were also verified on Wolfram Alpha + mut c1 := cmath.complex(5,7) + mut c2 := cmath.complex(0.953732,-2.846289) + mut result := c1.acos() + // 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(2.204780,-2.305509) + result = c1.acos() + // 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.997875,1.528571) + result = c1.acos() + // Some issue with precision comparison in f64 using == operator hence serializing to string + assert result.str().eq(c2.str()) +} + +fn test_complex_atan() { + // Tests were also verified on Wolfram Alpha + mut c1 := cmath.complex(5,7) + mut c2 := cmath.complex(1.502727,0.094441) + mut result := c1.atan() + // 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.448307,0.158997) + result = c1.atan() + // 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.338973,-0.402359) + result = c1.atan() + // 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) @@ -368,4 +425,59 @@ fn test_complex_tanh() { assert result.str().eq(c2.str()) } +fn test_complex_asinh() { + // Tests were also verified on Wolfram Alpha + mut c1 := cmath.complex(5,7) + mut c2 := cmath.complex(2.844098,0.947341) + mut result := c1.asinh() + // 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(-2.299914,0.917617) + result = c1.asinh() + // 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.469352,-1.063440) + result = c1.asinh() + // Some issue with precision comparison in f64 using == operator hence serializing to string + assert result.str().eq(c2.str()) +} +fn test_complex_acosh() { + // Tests were also verified on Wolfram Alpha + mut c1 := cmath.complex(5,7) + mut c2 := cmath.complex(2.846289,0.953732) + mut result := c1.acosh() + // 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(2.305509,2.204780) + result = c1.acosh() + // 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.528571,-1.997875) + result = c1.acosh() + // Some issue with precision comparison in f64 using == operator hence serializing to string + assert result.str().eq(c2.str()) +} + +fn test_complex_atanh() { + // Tests were also verified on Wolfram Alpha + mut c1 := cmath.complex(5,7) + mut c2 := cmath.complex(0.067066,1.476056) + mut result := c1.atanh() + // 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,1.409921) + result = c1.atanh() + // 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,-1.178097) + result = c1.atanh() + // 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