Elliptic filter
I just pushed some thinking. The mainline is based on SciPy package (elllipk, ellipkm1) methods. https://docs.scipy.org/doc/scipy/reference/generated/scipy.special.ellipk.html Clang++ do not implement any elliptic integral at this time, AFAIK.
I pick up the calculation of angles from : https://people.math.sc.edu/Burkardt/cpp_src/elliptic_integral/elliptic_integral.html This library looked good, but it seems it have an issue with m~1. So I included the real calculation of the integral from CEPHES library (elliptic_k, elliptic_km1). This is using a polynomial approximation with precomputed coefficients. So I think this should be quite fast.
Nevertheless, my implementation still lag of calculation for the inverse jacobian integral due to double precision limitation
(https://github.com/xKZL/kfr/blob/d315de7daa3889de0ef763daacc8409191aa2dcc/include/kfr/math/elliptic.hpp#L253)
I just point where the issue start to appear, but I think we might try to replace inv_jacobi_sn
to fix the issue
I have no more time to dedicate, but please feel free to try something.. this would be extremely useful in the future for my usage.
To put this in a nutshell, here is the outcome of my test below:
- This is comparing the k coefficient from zpk representation.
- I have compared different orders ( 0 and 1 are special cases so they are safe)
- As the order increase, the precision limitation starts to increase and the result is very completely limited in the last orders
Test #0 : 0.89125093813374556273032567332848 (python SciPy/stdc++) <> 0.89125093813374556273032567332848 = 1 (1e-0)
Test #1 : 1.96522672836027156861860021308530 (python SciPy/stdc++) <> 1.96522672836027156861860021308530 = 1 (1e-0)
Test #2 : 0.50118723362727279901918109317194 (python SciPy/stdc++) <> 0.50118723362727179981845893053105 = 0 (1e-16)
Test #3 : 0.98794734469230960360874860270997 (python SciPy/stdc++) <> 0.98794734469230882645263136510038 = 0 (1e-16)
Test #4 : 0.50118723362727934933502638159553 (python SciPy/stdc++) <> 0.50118723362725281500473784035421 = 0 (1e-15)
Test #5 : 0.97538440598394993141795339397504 (python SciPy/stdc++) <> 0.97538440598390829805452995060477 = 0 (1e-15)
Test #6 : 0.50118723362745221105996051846887 (python SciPy/stdc++) <> 0.50118723362739070470439628479653 = 0 (1e-14)
Test #7 : 0.97511086984454220516482791936141 (python SciPy/stdc++) <> 0.97511086985267536597632442862959 = 0 (1e-12)
Test #8 : 0.50118723362753969663430098080426 (python SciPy/stdc++) <> 0.50118723359427075347838353991392 = 0 (1e-11)
Test #9 : 0.97510485666884338940008092322387 (python SciPy/stdc++) <> 0.97510484997981838883873706436133 = 0 (1e-9)
Test #10: 0.50118723375847462619958605500869 (python SciPy/stdc++) <> 0.50118672696715338421569185811677 = 0 (1e-7)
Test #11: 0.97510467362126196366745034538326 (python SciPy/stdc++) <> 0.97502524988276029205280792666599 = 0 (1e-5)
Test #12: 0.50118498126436306083775207298459 (python SciPy/stdc++) <> 0.49903983562735582113489840594411 = 0 (1e-2)
Test #13: 0.97482310868854160634811023555812 (python SciPy/stdc++) <> 0.88735287300246623587440808478277 = 0 (1e-2)
Test #14: 0.49486370015702924041178789593687 (python SciPy/stdc++) <> 0.32953759545438848777010321100533 = 0 (1e-2)
Test #15: 0.83465109606081722137815859241528 (python SciPy/stdc++) <> 0.49342000704387722898047741182381 = 0 (1e-2)
Test #16: 0.30887740092250570711485124775209 (python SciPy/stdc++) <> 0.14213035309011415319169202575722 = 0 (1e-2)
Test #17: 0.48361023745374215332404332912120 (python SciPy/stdc++) <> 0.24555920485643306649947703590442 = 0 (1e-2)
Test #18: 0.14515935341003305403262402251130 (python SciPy/stdc++) <> 0.05455482844115393248340950549391 = 0 (1e-2)
Test #19: 0.26007573487724366945172960186028 (python SciPy/stdc++) <> 0.11009230039696740743870861933828 = 0 (1e-2)
Test #20: 0.06214721652055405637371521265777 (python SciPy/stdc++) <> 0.01915810306404193072427055710704 = 0 (1e-3)
Test #21: 0.12856256785699293754277050538803 (python SciPy/stdc++) <> 0.04456440191168813819144745025369 = 0 (1e-2)
Test #22: 0.02471231445727731929062898075244 (python SciPy/stdc++) <> 0.00621417411672309152187443359594 = 0 (1e-3)
Test #23: 0.05842982129840767341333318540819 (python SciPy/stdc++) <> 0.01641719101767708313688309829103 = 0 (1e-3)
Test #24: 0.00919341192048158013794267873209 (python SciPy/stdc++) <> 0.00187271832797217328663019753065 = 0 (1e-4)
Test #25: 0.02453838324842558954452798047896 (python SciPy/stdc++) <> 0.00554806695055968385199562931120 = 0 (1e-3)
Test #26: 0.00321322302422841340682757582670 (python SciPy/stdc++) <> 0.00052696377910764501985296792696 = 0 (1e-4)
Test #27: 0.00957488847253192346120620470629 (python SciPy/stdc++) <> 0.00173220837320768204434240367106 = 0 (1e-4)
Test #28: 0.00105876470543555894175680176517 (python SciPy/stdc++) <> 0.00013908931851696425111876431746 = 0 (1e-4)
Test #29: 0.00348895553891140223004563303277 (python SciPy/stdc++) <> 0.00050281167427838478929669197015 = 0 (1e-4)
Test #30: 0.00032993230118648272106499086398 (python SciPy/stdc++) <> 0.00003458250633305212775941636649 = 0 (1e-5)
Test #31: 0.00119263844932737412413148447854 (python SciPy/stdc++) <> 0.00013645609690712717548995158711 = 0 (1e-4)