pygeodesy 24.8.24__py2.py3-none-any.whl → 24.9.9__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
pygeodesy/booleans.py CHANGED
@@ -24,10 +24,10 @@ from pygeodesy.errors import ClipError, _IsnotError, _TypeError, \
24
24
  from pygeodesy.fmath import favg, hypot, hypot2
25
25
  # from pygeodesy.fsums import fsum1 # _MODS
26
26
  from pygeodesy.interns import NN, _BANG_, _clip_, _clipid_, _COMMASPACE_, \
27
- _composite_, _DOT_, _e_, _ELLIPSIS_, _few_, \
28
- _height_, _lat_, _LatLon_, _lon_, _not_, \
29
- _points_, _SPACE_, _too_, _X_, _x_, \
30
- _B_, _d_, _R_ # PYCHOK used!
27
+ _composite_, _DOT_, _duplicate_, _e_, \
28
+ _ELLIPSIS_, _few_, _height_, _lat_, _LatLon_, \
29
+ _lon_, _not_, _points_, _SPACE_, _too_, _X_, \
30
+ _x_, _B_, _d_, _R_ # PYCHOK used!
31
31
  from pygeodesy.lazily import _ALL_DOCS, _ALL_LAZY, _ALL_MODS as _MODS
32
32
  from pygeodesy.latlonBase import LatLonBase, \
33
33
  LatLon2Tuple, Property_RO, property_RO
@@ -43,7 +43,7 @@ from pygeodesy.utily import fabs, _unrollon, _Wrap
43
43
  # from math import fabs # from .utily
44
44
 
45
45
  __all__ = _ALL_LAZY.booleans
46
- __version__ = '24.06.15'
46
+ __version__ = '24.08.30'
47
47
 
48
48
  _0_EPS = EPS # near-zero, positive
49
49
  _EPS_0 = -EPS # near-zero, negative
@@ -51,12 +51,11 @@ _1_EPS = _1_0 + EPS # near-one, over
51
51
  _EPS_1 = _1_0 - EPS # near-one, under
52
52
  _10EPS = EPS * 10 # see ._2Abs, ._10eps
53
53
 
54
- _alpha_ = 'alpha'
55
- _boolean_ = 'boolean'
56
- _case_ = 'case'
57
- _corners_ = 'corners'
58
- _duplicate_ = 'duplicate'
59
- _open_ = 'open'
54
+ _alpha_ = 'alpha'
55
+ _boolean_ = 'boolean'
56
+ _case_ = 'case'
57
+ _corners_ = 'corners'
58
+ _open_ = 'open'
60
59
 
61
60
 
62
61
  def _Enum(txt, enum): # PYCHOK unused
pygeodesy/constants.py CHANGED
@@ -24,7 +24,7 @@ except ImportError: # Python 2-
24
24
  _inf, _nan = float(_INF_), float(_NAN_)
25
25
 
26
26
  __all__ = _ALL_LAZY.constants
27
- __version__ = '24.08.18'
27
+ __version__ = '24.08.26'
28
28
 
29
29
 
30
30
  def _copysign_0_0(y):
@@ -100,7 +100,7 @@ def float0_(*xs):
100
100
  yield float(x) if x else _0_0
101
101
 
102
102
 
103
- def _float0(f): # in .resections, .vector3dBase, ...
103
+ def _float0(f): # in .auxilats.auxily, .resections, .vector3dBase, ...
104
104
  '''(INTERNAL) Return C{float(B{f})} or C{INT0}.
105
105
  '''
106
106
  if f:
@@ -181,6 +181,7 @@ _10_0 = _float( 10) # PYCHOK expected
181
181
  _16_0 = _float( 16) # PYCHOK expected
182
182
  _32_0 = _float( 32) # PYCHOK expected
183
183
  _60_0 = _float( 60) # PYCHOK expected
184
+ _64_0 = _float( 64) # PYCHOK expected
184
185
  _90_0 = _float( 90) # PYCHOK expected
185
186
  _100_0 = _float( 100) # PYCHOK expected
186
187
  _180_0 = _float( 180) # PYCHOK expected
@@ -224,30 +225,30 @@ except ImportError: # PYCHOK no cover
224
225
  MIN_EXP = Int(MIN_EXP =_log2(MIN)) # -307 base 10
225
226
  # RADIX = Int(Radix =2) # base
226
227
 
227
- EPS0 = _Float( EPS0 = EPS**2) # PYCHOK near-/non-zero comparison 4.930381e-32, or EPS or EPS_2
228
- EPS02 = _Float( EPS02 = EPS**4) # PYCHOK near-zero-squared comparison 2.430865e-63
229
- EPS_2 = _Float( EPS_2 = EPS / _2_0) # PYCHOK ≈ 1.110223024625e-16
230
- EPS1 = _Float( EPS1 =_1_0 - EPS) # PYCHOK ≈ 0.9999999999999998
231
- EPS2 = _Float( EPS2 = EPS * _2_0) # PYCHOK ≈ 4.440892098501e-16
232
- EPS4 = _Float( EPS4 = EPS * _4_0) # PYCHOK ≈ 8.881784197001e-16
233
- # _1EPS = _Float(_1EPS =_1_0 + EPS) # PYCHOK ≈ 1.0000000000000002
234
- _1_EPS = _Float(_1_EPS =_1_0 / EPS) # PYCHOK = 4503599627370496.0
235
- # _2_EPS = _Float(_2_EPS =_2_0 / EPS) # PYCHOK = 9007199254740992.0
236
- _EPS2e4 = _Float(_EPS2e4 = EPS2 * 1.e4) # PYCHOK ≈ 4.440892098501e-12
237
- _EPS4e8 = _Float(_EPS4e8 = EPS4 * 1.e8) # PYCHOK ≈ 8.881784197001e-08
238
- _EPSmin = _Float(_EPSmin = sqrt(MIN)) # PYCHOK = 1.49166814624e-154
239
- _EPSqrt = _Float(_EPSqrt = sqrt(EPS)) # PYCHOK = 1.49011611938e5-08
240
- _EPStol = _Float(_EPStol =_EPSqrt * _0_1) # PYCHOK = 1.49011611938e5-09 == sqrt(EPS * _0_01)
241
-
242
- _89_999_ = _Float(_89_999_= EPS1 * _90_0) # just below 90.0
228
+ EPS0 = _Float( EPS0 = EPS**2) # PYCHOK near-/non-zero comparison 4.930381e-32, or EPS or EPS_2
229
+ EPS02 = _Float( EPS02 = EPS**4) # PYCHOK near-zero-squared comparison 2.430865e-63
230
+ EPS_2 = _Float( EPS_2 = EPS / _2_0) # PYCHOK ≈ 1.110223024625e-16
231
+ EPS1 = _Float( EPS1 =_1_0 - EPS) # PYCHOK ≈ 0.9999999999999998
232
+ EPS2 = _Float( EPS2 = EPS * _2_0) # PYCHOK ≈ 4.440892098501e-16
233
+ EPS4 = _Float( EPS4 = EPS * _4_0) # PYCHOK ≈ 8.881784197001e-16
234
+ # _1EPS = _Float(_1EPS =_1_0 + EPS) # PYCHOK ≈ 1.0000000000000002
235
+ _1_EPS = _Float(_1_EPS =_1_0 / EPS) # PYCHOK = 4503599627370496.0
236
+ # _2_EPS = _Float(_2_EPS =_2_0 / EPS) # PYCHOK = 9007199254740992.0
237
+ _EPS2e4 = _Float(_EPS2e4= EPS2 * 1.e4) # PYCHOK ≈ 4.440892098501e-12
238
+ _EPS4e8 = _Float(_EPS4e8= EPS4 * 1.e8) # PYCHOK ≈ 8.881784197001e-08
239
+ _EPSjam = _Float(_EPSjam= pow(EPS, 0.75)) # PYCHOK = 1.818989403546e-12
240
+ _EPSmin = _Float(_EPSmin= sqrt(MIN)) # PYCHOK = 1.49166814624e-154
241
+ _EPSqrt = _Float(_EPSqrt= sqrt(EPS)) # PYCHOK = 1.49011611938e5-08
242
+ _EPStol = _Float(_EPStol=_EPSqrt * _0_1) # PYCHOK = 1.49011611938e5-09 == sqrt(EPS * _0_01)
243
+
244
+ _89_999 = _Float(_89_999=_90_0 * EPS1) # just below 90.0
243
245
  # <https://Numbers.Computation.Free.FR/Constants/Miscellaneous/digits.html>
244
- _1__90 = _Float(_1__90 =_1_0 / _90_0) # PYCHOK = 0.011_111_111_111_111_111_111_111_111_111_111_111_111_111_111_11111
245
- _2__PI = _Float(_2__PI =_2_0 / _pi) # PYCHOK = 0.636_619_772_367_581_343_075_535_053_490_057_448_137_838_582_96182
246
+ _1__90 = _Float(_1__90 =_1_0 / _90_0) # PYCHOK = 0.011_111_111_111_111_111_111_111_111_111_111_111_111_111_111_11111
247
+ _2__PI = _Float(_2__PI =_2_0 / _pi) # PYCHOK = 0.636_619_772_367_581_343_075_535_053_490_057_448_137_838_582_96182
246
248
 
247
- _1_16th = _Float(_1_16th =_1_0 / _16_0) # PYCHOK in .ellipsoids, .karney
248
- _1_64th = _Float(_1_64th =_1_0 / 64) # PYCHOK in .elliptic, pow(2.0, -6)
249
- _1_3rd = _Float(_1_3rd =_1_0 / _3_0) # PYCHOK in .fmath
250
- _1_6th = _Float(_1_6th =_1_0 / _6_0) # PYCHOK in .fmath
249
+ _1_16th = _Float(_1_16th=_1_0 / _16_0) # PYCHOK in .ellipsoids, .karney
250
+ _1_3rd = _Float(_1_3rd =_1_0 / _3_0) # PYCHOK in .fmath
251
+ _1_6th = _Float(_1_6th =_1_0 / _6_0) # PYCHOK in .fmath
251
252
 
252
253
  _K0_UTM = _Float(_K0_UTM = 0.9996) # PYCHOK in .etm, .ktm, .utm, UTM scale at central meridian
253
254
  # sqrt(2) <https://WikiPedia.org/wiki/Square_root_of_2>
@@ -441,7 +442,7 @@ def isnon0(x, eps0=EPS0):
441
442
  def _off90(lat):
442
443
  '''(INTERNAL) Off 90.0 for .gars and .wgrs.
443
444
  '''
444
- return max(min(lat, _89_999_), -_89_999_)
445
+ return max(min(lat, _89_999), -_89_999)
445
446
 
446
447
 
447
448
  try:
pygeodesy/elliptic.py CHANGED
@@ -65,7 +65,8 @@ in U{B. C. Carlson, Computation of real or complex elliptic integrals
65
65
  The computation of the Jacobi elliptic functions uses the algorithm
66
66
  given in U{R. Bulirsch, Numerical Calculation of Elliptic Integrals
67
67
  and Elliptic Functions<https://DOI.org/10.1007/BF01397975>},
68
- Numerische Mathematik 7, 78--90 (1965).
68
+ Numerische Mathematik 7, 78--90 (1965) or optionally the C{Jacobi
69
+ amplitude} in method L{Elliptic.sncndn<pygeodesy.Elliptic.sncndn>}.
69
70
 
70
71
  The notation follows U{NIST Digital Library of Mathematical Functions
71
72
  <https://DLMF.NIST.gov>} chapters U{19<https://DLMF.NIST.gov/19>} and
@@ -75,13 +76,13 @@ U{22<https://DLMF.NIST.gov/22>}.
75
76
  from __future__ import division as _; del _ # PYCHOK semicolon
76
77
 
77
78
  from pygeodesy.basics import copysign0, map2, neg, neg_
78
- from pygeodesy.constants import EPS, INF, NAN, PI, PI_2, PI_4, \
79
- _EPStol as _TolJAC, _0_0, _1_64th, \
80
- _0_25, _0_5, _1_0, _2_0, _N_2_0, \
81
- _3_0, _4_0, _6_0, _8_0, _180_0, \
82
- _360_0, _over
79
+ from pygeodesy.constants import EPS, INF, NAN, PI, PI_2, PI_4, _0_0, \
80
+ _0_25, _0_5, _1_0, _2_0, _N_2_0, _3_0, \
81
+ _4_0, _6_0, _8_0, _64_0, _180_0, _360_0, \
82
+ _EPStol as _TolJAC, _over, \
83
+ _EPSjam as _TolJAM # PYCHOK used!
83
84
  # from pygeodesy.errors import _ValueError # from .fmath
84
- from pygeodesy.fmath import fdot, hypot1, zqrt, _ValueError
85
+ from pygeodesy.fmath import favg, hypot1, zqrt, _ValueError
85
86
  from pygeodesy.fsums import Fsum, _sum
86
87
  # from pygeodesy.internals import _dunder_nameof # from .lazily
87
88
  from pygeodesy.interns import NN, _delta_, _DOT_, _f_, _invalid_, \
@@ -94,16 +95,16 @@ from pygeodesy.props import _allPropertiesOf_n, Property_RO, _update_all
94
95
  from pygeodesy.units import Scalar, Scalar_
95
96
  # from pygeodesy.utily import sincos2 as _sincos2 # from .karney
96
97
 
97
- from math import asinh, atan, atan2, ceil, cosh, fabs, floor, \
98
- radians, sin, sqrt, tanh
98
+ from math import asin, asinh, atan, atan2, ceil, cosh, fabs, floor, \
99
+ radians, sin, sinh, sqrt, tan, tanh
99
100
 
100
101
  __all__ = _ALL_LAZY.elliptic
101
- __version__ = '24.05.18'
102
+ __version__ = '24.09.06'
102
103
 
103
104
  _TolRD = zqrt(EPS * 0.002)
104
105
  _TolRF = zqrt(EPS * 0.030)
105
106
  _TolRG0 = _TolJAC * 2.7
106
- _TRIPS = 21 # Max depth, 7 might be sufficient
107
+ _TRIPS = 25 # Max depth, 6-7 might be sufficient
107
108
 
108
109
 
109
110
  class _Cs(object):
@@ -127,6 +128,19 @@ class _Dsum(list):
127
128
  return self
128
129
 
129
130
 
131
+ class _Dadd(_Dsum):
132
+ '''(INTERNAL) Deferred C{Fsum} for C{_List.amrs4}.
133
+ '''
134
+ def __init__(self, mul):
135
+ self._mul = mul
136
+
137
+ def __add__(self, x):
138
+ self += x
139
+ r = self(self._mul)
140
+ _ = self.pop()
141
+ return r # Fsum or float
142
+
143
+
130
144
  class Elliptic(_Named):
131
145
  '''Elliptic integrals and functions.
132
146
 
@@ -407,7 +421,6 @@ class Elliptic(_Named):
407
421
  # Applied Math. and Computation 218, 7005-7013 (2012)
408
422
  # <https://DOI.org/10.1016/j.amc.2011.12.021>
409
423
  _Phi2 = Phi.fsum2f_ # aggregate
410
- _abs = fabs
411
424
  for i in range(1, _TRIPS): # GEOGRAPHICLIB_PANIC
412
425
  sn, cn, dn = self._sncndn3(phi)
413
426
  if dn:
@@ -415,7 +428,7 @@ class Elliptic(_Named):
415
428
  phi, d = _Phi2((r - sn) / dn)
416
429
  else: # PYCHOK no cover
417
430
  d = _0_0 # XXX continue?
418
- if _abs(d) < _TolJAC: # 3-4 trips
431
+ if fabs(d) < _TolJAC: # 3-4 trips
419
432
  _iterations(self, i)
420
433
  break
421
434
  else: # PYCHOK no cover
@@ -505,7 +518,8 @@ class Elliptic(_Named):
505
518
  return ei
506
519
 
507
520
  return self._fXf(phi_or_sn, cn, dn, self.cE,
508
- self.deltaE, _fE)
521
+ self.deltaE, _fE,
522
+ k2_0=self.k2==0)
509
523
 
510
524
  def fEd(self, deg):
511
525
  '''The incomplete integral of the second kind with
@@ -561,7 +575,8 @@ class Elliptic(_Named):
561
575
  return r
562
576
 
563
577
  return self._fXf(phi_or_sn, cn, dn, self.cK,
564
- self.deltaF, _fF)
578
+ self.deltaF, _fF,
579
+ k2_0=self.k2==0, kp2_0=self.kp2==0)
565
580
 
566
581
  def fG(self, phi_or_sn, cn=None, dn=None):
567
582
  '''Legendre's geodesic longitude integral in terms of
@@ -648,12 +663,16 @@ class Elliptic(_Named):
648
663
 
649
664
  return self._fXf(phi_or_sn, cn, dn, cX, deltaX, _fX)
650
665
 
651
- def _fXf(self, phi_or_sn, cn, dn, cX, deltaX, fX):
666
+ def _fXf(self, phi_or_sn, cn, dn, cX, deltaX, fX, k2_0=False, kp2_0=False):
652
667
  '''(INTERNAL) Helper for C{.fD}, C{.fE}, C{.fF} and C{._fXa}.
653
668
  '''
654
669
  self._iteration = 0 # aggregate
655
670
  phi = sn = phi_or_sn
656
671
  if cn is dn is None: # fX(phi) call
672
+ if k2_0: # C++ version 2.4
673
+ return phi
674
+ elif kp2_0:
675
+ return asinh(tan(phi))
657
676
  sn, cn, dn = self._sncndn3(phi)
658
677
  if fabs(phi) >= PI:
659
678
  return (deltaX(sn, cn, dn) + phi) * cX / PI_2
@@ -668,6 +687,51 @@ class Elliptic(_Named):
668
687
  xi = fX(sn, cn, dn) if cn > 0 else cX
669
688
  return copysign0(xi, sn)
670
689
 
690
+ def _jam(self, x):
691
+ '''Jacobi amplitude function.
692
+
693
+ @return: C{phi} (C{float}).
694
+ '''
695
+ # implements DLMF Sec 22.20(ii), see also U{Sala
696
+ # (1989)<https://doi.org/10.1137/0520100>}, Sec 5
697
+ if self.k2:
698
+ if self.kp2:
699
+ r, ac = self._jamac2
700
+ x *= r # phi
701
+ for a, c in ac:
702
+ p = x
703
+ x = favg(asin(c * sin(x) / a), x)
704
+ if self.k2 < 0: # Sala Eq. 5.8
705
+ x = p - x
706
+ else: # PYCHOK no cover
707
+ x = atan(sinh(x)) # gd(x)
708
+ return x
709
+
710
+ @Property_RO
711
+ def _jamac2(self):
712
+ '''(INTERNAL) Get Jacobi amplitude 2-tuple C{(r, ac)}.
713
+ '''
714
+ a = r = _1_0
715
+ b, c = self.kp2, self.k2
716
+ # assert b and c
717
+ if c < 0: # Sala Eq. 5.8
718
+ r = sqrt(b)
719
+ b = _1_0 / b
720
+ # c *= b # unused
721
+ ac = [] # [(a, sqrt(c))] unused
722
+ for i in range(1, _TRIPS): # GEOGRAPHICLIB_PANIC
723
+ b = sqrt(a * b)
724
+ c = favg(a, -b)
725
+ a = favg(a, b) # == PI_2 / K
726
+ ac.append((a, c))
727
+ if c <= (a * _TolJAM): # 7 trips, quadratic
728
+ _iterations(self, i)
729
+ break
730
+ else: # PYCHOK no cover
731
+ raise _convergenceError(c / a, _TolJAM)
732
+ r *= a * float(1 << i) # 2**i == 2**len(ac)
733
+ return r, tuple(reversed(ac))
734
+
671
735
  @Property_RO
672
736
  def k2(self):
673
737
  '''Get k^2, the square of the modulus (C{float}).
@@ -723,38 +787,46 @@ class Elliptic(_Named):
723
787
  # Pi(alpha2, 1) = inf
724
788
  # G( alpha2, 1) = H(alpha2, 1) = RC(1, alphap2)
725
789
 
726
- def sncndn(self, x):
727
- '''The Jacobi elliptic function.
790
+ def sncndn(self, x, jam=False):
791
+ '''The Jacobi amplitude and elliptic function.
728
792
 
729
793
  @arg x: The argument (C{float}).
794
+ @kwarg jam: If C{True}, use the Jacobi amplitude otherwise the
795
+ Bulirsch' function (C{bool}).
730
796
 
731
- @return: An L{Elliptic3Tuple}C{(sn, cn, dn)} with
732
- C{*n(B{x}, k)}.
797
+ @return: An L{Elliptic3Tuple}C{(sn, cn, dn)} with C{*n(B{x}, k)}.
733
798
 
734
799
  @raise EllipticError: No convergence.
735
800
  '''
736
801
  self._iteration = 0 # reset
737
- try: # Bulirsch's sncndn routine, p 89.
802
+ try:
738
803
  if self.kp2:
739
- c, d, cd, mn = self._sncndn4
740
- dn = _1_0
741
- sn, cn = _sincos2(x * cd)
742
- if sn:
743
- a = cn / sn
744
- c *= a
745
- for m, n in reversed(mn):
746
- a *= c
747
- c *= dn
748
- dn = (n + a) / (m + a)
749
- a = c / m
750
- a = _1_0 / hypot1(c)
751
- sn = neg(a) if _signBit(sn) else a
752
- cn = c * sn
753
- if d and _signBit(self.kp2):
754
- cn, dn = dn, cn
755
- sn = sn / d # /= chokes PyChecker
804
+ if jam: # Jacobi amplitude, C++ version 2.4
805
+ sn, cn, dn = self._sncndn3(self._jam(x))
806
+
807
+ else: # Bulirsch's sncndn routine, p 89 of
808
+ # Numerische Mathematik 7, 78-90 (1965).
809
+ # Implements DLMF Eqs 22.17.2 - 22.17.4,
810
+ # but only good for .k2 > 1 or .kp2 < 0
811
+ c, d, cd, mn = self._sncndn4
812
+ dn = _1_0
813
+ sn, cn = _sincos2(x * cd)
814
+ if sn:
815
+ a = cn / sn
816
+ c *= a
817
+ for m, n in mn:
818
+ a *= c
819
+ c *= dn
820
+ dn = (n + a) / (m + a)
821
+ a = c / m
822
+ a = _1_0 / hypot1(c)
823
+ sn = neg(a) if _signBit(sn) else a
824
+ cn = sn * c
825
+ if d: # and _signBit(self.kp2): # implied
826
+ cn, dn = dn, cn
827
+ sn = sn / d # /= chokes PyChecker
756
828
  else:
757
- sn = tanh(x)
829
+ sn = tanh(x) # accurate for large abs(x)
758
830
  cn = dn = _1_0 / cosh(x)
759
831
 
760
832
  except Exception as e:
@@ -763,7 +835,7 @@ class Elliptic(_Named):
763
835
  return Elliptic3Tuple(sn, cn, dn, iteration=self._iteration)
764
836
 
765
837
  def _sncndn3(self, phi):
766
- '''(INTERNAL) Helper for C{.fEinv} and C{._fXf}.
838
+ '''(INTERNAL) Helper for C{.fEinv}, C{._fXf} and C{.sncndn}.
767
839
  '''
768
840
  sn, cn = _sincos2(phi)
769
841
  return sn, cn, self.fDelta(sn, cn)
@@ -772,29 +844,27 @@ class Elliptic(_Named):
772
844
  def _sncndn4(self):
773
845
  '''(INTERNAL) Get Bulirsch' 4-tuple C{(c, d, cd, mn)}.
774
846
  '''
775
- # Bulirsch's sncndn routine, p 89.
776
- d, mc = 0, self.kp2
777
- if _signBit(mc):
778
- d = _1_0 - mc
779
- mc = neg(mc / d)
780
- d = sqrt(d)
781
-
782
- mn, a = [], _1_0
847
+ d, b = 0, self.kp2
848
+ if _signBit(b):
849
+ d = _1_0 - b
850
+ b = neg(b / d)
851
+ d = sqrt(d)
852
+ ab, a = [], _1_0
783
853
  for i in range(1, _TRIPS): # GEOGRAPHICLIB_PANIC
784
- mc = sqrt(mc)
785
- mn.append((a, mc))
786
- c = (a + mc) * _0_5
787
- r = fabs(mc - a)
788
- t = _TolJAC * a
789
- if r <= t: # 6 trips, quadratic
854
+ b = sqrt(b)
855
+ ab.append((a, b))
856
+ c = favg(a, b)
857
+ r = fabs(a - b)
858
+ if r <= (a * _TolJAC): # 6 trips, quadratic
790
859
  _iterations(self, i)
791
860
  break
792
- mc *= a
793
- a = c
861
+ t = a
862
+ b *= a
863
+ a = c
794
864
  else: # PYCHOK no cover
795
- raise _convergenceError(r, t)
865
+ raise _convergenceError(r / t, _TolJAC)
796
866
  cd = (c * d) if d else c
797
- return c, d, cd, mn
867
+ return c, d, cd, tuple(reversed(ab))
798
868
 
799
869
  @staticmethod
800
870
  def fRC(x, y):
@@ -882,7 +952,7 @@ class Elliptic(_Named):
882
952
  raise _ellipticError(Elliptic._RFRD, x, y, z, m, cause=e)
883
953
  return float(R)
884
954
 
885
- _allPropertiesOf_n(15, Elliptic) # # PYCHOK assert, see Elliptic.reset
955
+ _allPropertiesOf_n(16, Elliptic) # # PYCHOK assert, see Elliptic.reset
886
956
 
887
957
 
888
958
  class EllipticError(_ValueError):
@@ -901,25 +971,18 @@ class Elliptic3Tuple(_NamedTuple):
901
971
  class _List(list):
902
972
  '''(INTERNAL) Helper for C{_RD}, C{_RF3} and C{_RJ}.
903
973
  '''
904
- _a0 = None
905
- # _xyzp = ()
974
+ _a0 = None
906
975
 
907
976
  def __init__(self, *xyzp): # x, y, z [, p]
908
977
  list.__init__(self, xyzp)
909
- self._xyzp = xyzp
910
978
 
911
979
  def a0(self, n):
912
980
  '''Compute the initial C{a}.
913
981
  '''
914
- t = tuple(self)
915
- m = n - len(t)
916
- if m > 0:
917
- t += t[-1:] * m
918
- try:
919
- a = Fsum(*t).fover(n)
920
- except ValueError: # Fsum(NAN) exception
921
- a = _sum(t) / n
922
- self._a0 = a
982
+ A = _Dsum(self)
983
+ while len(A) < n:
984
+ A += A[-1]
985
+ self._a0 = a = float(A(_1_0 / n))
923
986
  return a
924
987
 
925
988
  def amrs4(self, inst, y, Tol):
@@ -929,20 +992,22 @@ class _List(list):
929
992
  L = self
930
993
  a = L.a0(5 if y else 3)
931
994
  m = 1
932
- t = max(fabs(a - _) for _ in L) / Tol
995
+ t = max(fabs(a - _) for _ in L) / Tol # thresh
933
996
  for i in range(_TRIPS):
934
997
  d = fabs(a * m)
935
998
  if d > t: # 3-6 trips
936
999
  _iterations(inst, i)
937
1000
  break
938
1001
  s = map2(sqrt, L) # sqrt(x), srqt(y), sqrt(z) [, sqrt(p)]
939
- try:
940
- r = fdot(s[:3], s[1], s[2], s[0]) # sqrt(x) * sqrt(y) + ...
941
- except ValueError: # Fsum(NAN) exception
942
- r = _sum(s[i] * s[(i + 1) % 3] for i in range(3))
943
- L[:] = ((r + _) * _0_25 for _ in L)
944
- a = (r + a) * _0_25
1002
+ # Deferred fdot(s[:3], s[1], s[2], s[0]) + ...
1003
+ Q = _Dadd(_0_25)
1004
+ Q += s[0] * s[1]
1005
+ Q += s[1] * s[2]
1006
+ Q += s[2] * s[0]
1007
+ L[:] = (float(Q + _) for _ in L)
1008
+ a = float(Q + a)
945
1009
  if y: # yield only if used
1010
+ r = _sum(Q) # fdot
946
1011
  yield a, m, r, s # L[2] is next z
947
1012
  m *= 4
948
1013
  else: # PYCHOK no cover
@@ -967,14 +1032,15 @@ def _ab2(inst, x, y):
967
1032
  b, a = a, b
968
1033
  for i in range(_TRIPS):
969
1034
  yield a, b # xi, yi
970
- d = fabs(a - b)
971
- t = _TolRG0 * a
972
- if d <= t: # 3-4 trips
1035
+ d = fabs(a - b)
1036
+ if d <= (a * _TolRG0): # 3-4 trips
973
1037
  _iterations(inst, i)
974
1038
  break
975
- a, b = ((a + b) * _0_5), sqrt(a * b)
1039
+ t = a
1040
+ a = favg(t, b)
1041
+ b = sqrt(t * b)
976
1042
  else: # PYCHOK no cover
977
- raise _convergenceError(d, t)
1043
+ raise _convergenceError(d / t, _TolRG0)
978
1044
 
979
1045
 
980
1046
  def _convergenceError(d, tol, **thresh):
@@ -1083,10 +1149,10 @@ def _RD(inst, x, y, z, *over):
1083
1149
  z = (x + y) / _3_0
1084
1150
  z2 = z**2
1085
1151
  return _Horner(S(_1_0), sqrt(a) * a * m,
1086
- xy - _6_0 * z2,
1087
- (xy * _3_0 - _8_0 * z2) * z,
1088
- (xy - z2) * _3_0 * z2,
1089
- xy * z2 * z, *over) # Fsum
1152
+ (xy - z2 * _6_0),
1153
+ (xy * _3_0 - z2 * _8_0) * z,
1154
+ (xy - z2) * z2 * _3_0,
1155
+ (xy * z2 * z), *over) # Fsum
1090
1156
 
1091
1157
 
1092
1158
  def _rF2(inst, x, y): # 2-arg version, z=0
@@ -1160,7 +1226,7 @@ def _RJ(inst, x, y, z, p, *over):
1160
1226
  if d:
1161
1227
  if n:
1162
1228
  rc = _rC(inst, _1_0, n / d**2 + _1_0)
1163
- n *= _1_64th # /= chokes PyChecker
1229
+ n = n / _64_0 # /= chokes PyChecker
1164
1230
  else:
1165
1231
  rc = _1_0 # == _rC(None, _1_0, _1_0)
1166
1232
  S += rc / (d * m)