pygeodesy 24.5.8__py2.py3-none-any.whl → 24.5.15__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-24.5.8.dist-info → PyGeodesy-24.5.15.dist-info}/METADATA +2 -2
- {PyGeodesy-24.5.8.dist-info → PyGeodesy-24.5.15.dist-info}/RECORD +51 -50
- pygeodesy/__init__.py +16 -12
- pygeodesy/__main__.py +9 -10
- pygeodesy/albers.py +2 -2
- pygeodesy/auxilats/__main__.py +7 -10
- pygeodesy/auxilats/auxLat.py +2 -1
- pygeodesy/basics.py +158 -171
- pygeodesy/booleans.py +4 -4
- pygeodesy/constants.py +8 -6
- pygeodesy/datums.py +9 -8
- pygeodesy/ecef.py +5 -4
- pygeodesy/elevations.py +2 -2
- pygeodesy/ellipsoidalBaseDI.py +7 -5
- pygeodesy/elliptic.py +10 -7
- pygeodesy/errors.py +6 -6
- pygeodesy/etm.py +3 -2
- pygeodesy/fmath.py +13 -12
- pygeodesy/fstats.py +32 -33
- pygeodesy/fsums.py +103 -89
- pygeodesy/geodesicw.py +14 -14
- pygeodesy/geodesicx/__main__.py +4 -4
- pygeodesy/geodesicx/gxarea.py +4 -4
- pygeodesy/geodsolve.py +3 -2
- pygeodesy/geoids.py +6 -6
- pygeodesy/heights.py +4 -4
- pygeodesy/internals.py +571 -0
- pygeodesy/interns.py +4 -202
- pygeodesy/iters.py +3 -2
- pygeodesy/karney.py +4 -4
- pygeodesy/ktm.py +7 -7
- pygeodesy/lazily.py +139 -217
- pygeodesy/mgrs.py +3 -2
- pygeodesy/named.py +13 -10
- pygeodesy/nvectorBase.py +4 -3
- pygeodesy/osgr.py +14 -12
- pygeodesy/points.py +5 -5
- pygeodesy/props.py +7 -7
- pygeodesy/rhumb/bases.py +3 -2
- pygeodesy/rhumb/solve.py +2 -2
- pygeodesy/solveBase.py +3 -2
- pygeodesy/streprs.py +5 -4
- pygeodesy/trf.py +4 -4
- pygeodesy/units.py +15 -17
- pygeodesy/ups.py +7 -6
- pygeodesy/utily.py +4 -4
- pygeodesy/utm.py +5 -4
- pygeodesy/utmupsBase.py +4 -3
- pygeodesy/vector3dBase.py +2 -1
- {PyGeodesy-24.5.8.dist-info → PyGeodesy-24.5.15.dist-info}/WHEEL +0 -0
- {PyGeodesy-24.5.8.dist-info → PyGeodesy-24.5.15.dist-info}/top_level.txt +0 -0
pygeodesy/fsums.py
CHANGED
|
@@ -23,16 +23,18 @@ and L{Fsum.__itruediv__}.
|
|
|
23
23
|
# make sure int/int division yields float quotient, see .basics
|
|
24
24
|
from __future__ import division as _; del _ # PYCHOK semicolon
|
|
25
25
|
|
|
26
|
-
from pygeodesy.basics import isbool, iscomplex, isint, isscalar,
|
|
27
|
-
|
|
26
|
+
from pygeodesy.basics import isbool, iscomplex, isint, isscalar, \
|
|
27
|
+
_signOf, itemsorted, signOf, _xiterable, \
|
|
28
|
+
_enquote
|
|
28
29
|
from pygeodesy.constants import INT0, _isfinite, NEG0, _pos_self, \
|
|
29
30
|
_0_0, _1_0, _N_1_0, Float, Int
|
|
30
31
|
from pygeodesy.errors import _OverflowError, _TypeError, _ValueError, \
|
|
31
32
|
_xError, _xError2, _xkwds_get
|
|
33
|
+
# from pygeodesy.internals import _enquote # from .basics
|
|
32
34
|
from pygeodesy.interns import NN, _arg_, _COMMASPACE_, _DASH_, _DOT_, \
|
|
33
|
-
|
|
34
|
-
_not_finite_, _PERCENT_, _PLUS_,
|
|
35
|
-
_SLASH_, _SPACE_, _STAR_, _UNDER_
|
|
35
|
+
_EQUAL_, _from_, _LANGLE_, _NOTEQUAL_, \
|
|
36
|
+
_not_finite_, _PERCENT_, _PLUS_, \
|
|
37
|
+
_RANGLE_, _SLASH_, _SPACE_, _STAR_, _UNDER_
|
|
36
38
|
from pygeodesy.lazily import _ALL_LAZY, _getenv, _sys_version_info2
|
|
37
39
|
from pygeodesy.named import _Named, _NamedTuple, _NotImplemented
|
|
38
40
|
from pygeodesy.props import _allPropertiesOf_n, deprecated_property_RO, \
|
|
@@ -43,23 +45,18 @@ from pygeodesy.streprs import Fmt, fstr, unstr
|
|
|
43
45
|
from math import ceil as _ceil, fabs, floor as _floor # PYCHOK used! .ltp
|
|
44
46
|
|
|
45
47
|
__all__ = _ALL_LAZY.fsums
|
|
46
|
-
__version__ = '24.05.
|
|
48
|
+
__version__ = '24.05.13'
|
|
47
49
|
|
|
48
|
-
_abs = abs
|
|
49
50
|
_add_op_ = _PLUS_ # in .auxilats.auxAngle
|
|
50
51
|
_eq_op_ = _EQUAL_ * 2 # _DEQUAL_
|
|
51
52
|
_div_ = 'div'
|
|
52
|
-
_Float = float # in .fstats
|
|
53
53
|
_floordiv_op_ = _SLASH_ * 2 # _DSLASH_
|
|
54
54
|
_fset_op_ = _EQUAL_
|
|
55
55
|
_ge_op_ = _RANGLE_ + _EQUAL_
|
|
56
56
|
_gt_op_ = _RANGLE_
|
|
57
57
|
_iadd_op_ = _add_op_ + _EQUAL_ # in .auxilats.auxAngle, .fstats
|
|
58
58
|
_integer_ = 'integer'
|
|
59
|
-
_isAn = isinstance # in .fstats
|
|
60
59
|
_le_op_ = _LANGLE_ + _EQUAL_
|
|
61
|
-
_len = len
|
|
62
|
-
_List = list
|
|
63
60
|
_lt_op_ = _LANGLE_
|
|
64
61
|
_mod_ = 'mod'
|
|
65
62
|
_mod_op_ = _PERCENT_
|
|
@@ -71,7 +68,6 @@ _significant_ = 'significant'
|
|
|
71
68
|
_sub_op_ = _DASH_ # in .auxilats.auxAngle
|
|
72
69
|
_threshold_ = 'threshold'
|
|
73
70
|
_truediv_op_ = _SLASH_
|
|
74
|
-
_Tuple = tuple # in .fstats
|
|
75
71
|
_divmod_op_ = _floordiv_op_ + _mod_op_
|
|
76
72
|
_isub_op_ = _sub_op_ + _fset_op_ # in .auxilats.auxAngle
|
|
77
73
|
|
|
@@ -83,7 +79,7 @@ def _2delta(*ab):
|
|
|
83
79
|
a, b = _2sum(*ab)
|
|
84
80
|
except _OverflowError:
|
|
85
81
|
a, b = ab
|
|
86
|
-
return
|
|
82
|
+
return float(a if fabs(a) > fabs(b) else b)
|
|
87
83
|
|
|
88
84
|
|
|
89
85
|
def _2error(unused): # in .fstats
|
|
@@ -95,7 +91,7 @@ def _2error(unused): # in .fstats
|
|
|
95
91
|
def _2finite(x):
|
|
96
92
|
'''(INTERNAL) return C{float(x)} if finite.
|
|
97
93
|
'''
|
|
98
|
-
x =
|
|
94
|
+
x = float(x)
|
|
99
95
|
return x if _isfinite(x) else _2error(x)
|
|
100
96
|
|
|
101
97
|
|
|
@@ -113,16 +109,16 @@ def _X_ps(X): # for _2floats only
|
|
|
113
109
|
return X._ps
|
|
114
110
|
|
|
115
111
|
|
|
116
|
-
def _2floats(xs, origin=0, _X=_X_ps, _x=
|
|
112
|
+
def _2floats(xs, origin=0, _X=_X_ps, _x=float):
|
|
117
113
|
'''(INTERNAL) Yield each B{C{xs}} as a C{float}.
|
|
118
114
|
'''
|
|
119
115
|
try:
|
|
120
|
-
i, x = origin,
|
|
116
|
+
i, x = origin, _X
|
|
121
117
|
_fin = _isfinite
|
|
122
118
|
_FsT = _Fsum_Fsum2Tuple_types
|
|
123
|
-
|
|
124
|
-
for x in xs:
|
|
125
|
-
if
|
|
119
|
+
_isa = isinstance
|
|
120
|
+
for x in _xiterable(xs):
|
|
121
|
+
if _isa(x, _FsT):
|
|
126
122
|
for p in _X(x._Fsum):
|
|
127
123
|
yield p
|
|
128
124
|
else:
|
|
@@ -130,7 +126,8 @@ def _2floats(xs, origin=0, _X=_X_ps, _x=_Float):
|
|
|
130
126
|
yield f if _fin(f) else _2error(f)
|
|
131
127
|
i += 1
|
|
132
128
|
except Exception as X:
|
|
133
|
-
raise _xError(X,
|
|
129
|
+
raise _xError(X, xs=xs) if x is _X else \
|
|
130
|
+
_xError(X, Fmt.INDEX(xs=i), x)
|
|
134
131
|
|
|
135
132
|
|
|
136
133
|
def _Fsumf_(*xs): # floats=True, in .auxLat, ...
|
|
@@ -160,13 +157,13 @@ def _2halfeven(s, r, p):
|
|
|
160
157
|
def _isFsum(x): # in .fmath
|
|
161
158
|
'''(INTERNAL) Is C{x} an C{Fsum} instance?
|
|
162
159
|
'''
|
|
163
|
-
return
|
|
160
|
+
return isinstance(x, Fsum)
|
|
164
161
|
|
|
165
162
|
|
|
166
163
|
def _isFsumTuple(x): # in .fmath
|
|
167
164
|
'''(INTERNAL) Is C{x} an C{Fsum} or C{Fsum2Tuple} instance?
|
|
168
165
|
'''
|
|
169
|
-
return
|
|
166
|
+
return isinstance(x, _Fsum_Fsum2Tuple_types)
|
|
170
167
|
|
|
171
168
|
|
|
172
169
|
def _1_Over(x, op, **raiser_RESIDUAL): # vs _1_over
|
|
@@ -188,8 +185,8 @@ def _1primed(xs): # in .fmath
|
|
|
188
185
|
def _psum(ps): # PYCHOK used!
|
|
189
186
|
'''(INTERNAL) Partials summation, updating C{ps}.
|
|
190
187
|
'''
|
|
191
|
-
# assert
|
|
192
|
-
i =
|
|
188
|
+
# assert isinstance(ps, list)
|
|
189
|
+
i = len(ps) - 1
|
|
193
190
|
s = _0_0 if i < 0 else ps[i]
|
|
194
191
|
_2s = _2sum
|
|
195
192
|
while i > 0:
|
|
@@ -212,7 +209,7 @@ def _Psum(ps, **name_RESIDUAL):
|
|
|
212
209
|
f = Fsum(**name_RESIDUAL) if name_RESIDUAL else Fsum()
|
|
213
210
|
if ps:
|
|
214
211
|
f._ps[:] = ps
|
|
215
|
-
f._n =
|
|
212
|
+
f._n = len(f._ps)
|
|
216
213
|
return f
|
|
217
214
|
|
|
218
215
|
|
|
@@ -255,7 +252,7 @@ def _strcomplex(s, *args):
|
|
|
255
252
|
'''(INTERNAL) C{Complex} 2- or 3-arg C{pow} error as C{str}.
|
|
256
253
|
'''
|
|
257
254
|
c = _strcomplex.__name__[4:]
|
|
258
|
-
n = _DASH_(
|
|
255
|
+
n = _DASH_(len(args), _arg_)
|
|
259
256
|
t = unstr(pow, *args)
|
|
260
257
|
return _SPACE_(c, s, _from_, n, t)
|
|
261
258
|
|
|
@@ -288,8 +285,7 @@ def _threshold(threshold):
|
|
|
288
285
|
'''(INTERNAL) Get the L{ResidualError}s threshold.
|
|
289
286
|
'''
|
|
290
287
|
try:
|
|
291
|
-
|
|
292
|
-
return t if _isfinite(t) else _2error(t) # PYCHOK None
|
|
288
|
+
return _2finite(threshold) # PYCHOK None
|
|
293
289
|
except Exception as x:
|
|
294
290
|
raise ResidualError(threshold=threshold, cause=x)
|
|
295
291
|
|
|
@@ -318,7 +314,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
318
314
|
_math_fsum = None
|
|
319
315
|
_n = 0
|
|
320
316
|
# _ps = [] # partial sums
|
|
321
|
-
# _ps_max = 0 # max(Fsum._ps_max,
|
|
317
|
+
# _ps_max = 0 # max(Fsum._ps_max, len(Fsum._ps))
|
|
322
318
|
_RESIDUAL = _threshold(_getenv('PYGEODESY_FSUM_RESIDUAL', _0_0))
|
|
323
319
|
|
|
324
320
|
def __init__(self, *xs, **name_RESIDUAL):
|
|
@@ -417,7 +413,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
417
413
|
|
|
418
414
|
@see: Methods L{Fsum.fsum} and L{Fsum.int_float}.
|
|
419
415
|
'''
|
|
420
|
-
return
|
|
416
|
+
return float(self._fprs)
|
|
421
417
|
|
|
422
418
|
def __floor__(self): # PYCHOK not special in Python 2-
|
|
423
419
|
'''Return this instance' C{math.floor} as C{int} or C{float}.
|
|
@@ -462,7 +458,8 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
462
458
|
def __iadd__(self, other):
|
|
463
459
|
'''Apply C{B{self} += B{other}} to this instance.
|
|
464
460
|
|
|
465
|
-
@arg other: An L{Fsum}, L{Fsum2Tuple} or C{scalar}
|
|
461
|
+
@arg other: An L{Fsum}, L{Fsum2Tuple} or C{scalar} value or
|
|
462
|
+
an iterable of several of the former.
|
|
466
463
|
|
|
467
464
|
@return: This instance, updated (L{Fsum}).
|
|
468
465
|
|
|
@@ -471,7 +468,10 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
471
468
|
|
|
472
469
|
@see: Methods L{Fsum.fadd_} and L{Fsum.fadd}.
|
|
473
470
|
'''
|
|
474
|
-
|
|
471
|
+
try:
|
|
472
|
+
return self._fadd(other, _iadd_op_)
|
|
473
|
+
except TypeError:
|
|
474
|
+
return self._facc_inplace(other, _iadd_op_, self._facc)
|
|
475
475
|
|
|
476
476
|
def __ifloordiv__(self, other):
|
|
477
477
|
'''Apply C{B{self} //= B{other}} to this instance.
|
|
@@ -578,7 +578,8 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
578
578
|
def __isub__(self, other):
|
|
579
579
|
'''Apply C{B{self} -= B{other}} to this instance.
|
|
580
580
|
|
|
581
|
-
@arg other: An L{Fsum}, L{Fsum2Tuple} or C{scalar}
|
|
581
|
+
@arg other: An L{Fsum}, L{Fsum2Tuple} or C{scalar} value or
|
|
582
|
+
an iterable of several of the former.
|
|
582
583
|
|
|
583
584
|
@return: This instance, updated (L{Fsum}).
|
|
584
585
|
|
|
@@ -586,7 +587,10 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
586
587
|
|
|
587
588
|
@see: Methods L{Fsum.fsub_} and L{Fsum.fsub}.
|
|
588
589
|
'''
|
|
589
|
-
|
|
590
|
+
try:
|
|
591
|
+
return self._fsub(other, _isub_op_)
|
|
592
|
+
except TypeError:
|
|
593
|
+
return self._facc_inplace(other, _isub_op_, self._facc_neg)
|
|
590
594
|
|
|
591
595
|
def __iter__(self):
|
|
592
596
|
'''Return an C{iter}ator over a C{partials} duplicate.
|
|
@@ -734,7 +738,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
734
738
|
'''
|
|
735
739
|
f = self._copy_2(self.__round__)
|
|
736
740
|
# <https://docs.Python.org/3.12/reference/datamodel.html?#object.__round__>
|
|
737
|
-
return f._fset(round(
|
|
741
|
+
return f._fset(round(float(self), *ndigits)) # can be C{int}
|
|
738
742
|
|
|
739
743
|
def __rpow__(self, other, *mod):
|
|
740
744
|
'''Return C{B{other}**B{self}} as an L{Fsum}.
|
|
@@ -815,7 +819,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
815
819
|
'''
|
|
816
820
|
n, r = self._fint2
|
|
817
821
|
if r:
|
|
818
|
-
i, d =
|
|
822
|
+
i, d = float(r).as_integer_ratio()
|
|
819
823
|
n *= d
|
|
820
824
|
n += i
|
|
821
825
|
else: # PYCHOK no cover
|
|
@@ -866,7 +870,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
866
870
|
'''
|
|
867
871
|
f = _Named.copy(self, deep=deep, name=name)
|
|
868
872
|
if f._ps is self._ps:
|
|
869
|
-
f._ps =
|
|
873
|
+
f._ps = list(self._ps) # separate list
|
|
870
874
|
if not deep:
|
|
871
875
|
f._n = 1
|
|
872
876
|
# assert f._Fsum is f
|
|
@@ -878,7 +882,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
878
882
|
n = name or which.__name__
|
|
879
883
|
# NOT .classof due to .Fdot(a, *b) args, etc.
|
|
880
884
|
f = _Named.copy(self, deep=False, name=n)
|
|
881
|
-
f._ps =
|
|
885
|
+
f._ps = list(self._ps) # separate list
|
|
882
886
|
# assert f._n == self._n
|
|
883
887
|
# assert f._Fsum is f
|
|
884
888
|
return f
|
|
@@ -915,7 +919,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
915
919
|
'''(INTERNAL) Format the caught exception C{X}.
|
|
916
920
|
'''
|
|
917
921
|
E, t = _xError2(X)
|
|
918
|
-
u = unstr(self.named3, *xs[:3], _ELLIPSIS=
|
|
922
|
+
u = unstr(self.named3, *xs[:3], _ELLIPSIS=len(xs) > 3, **kwds)
|
|
919
923
|
return E(u, txt=t, cause=X)
|
|
920
924
|
|
|
921
925
|
def _facc(self, xs, up=True, **origin_X_x):
|
|
@@ -924,16 +928,24 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
924
928
|
if xs:
|
|
925
929
|
_xs = _2floats(xs, **origin_X_x) # PYCHOK yield
|
|
926
930
|
ps = self._ps
|
|
927
|
-
ps[:] = self._ps_acc(
|
|
931
|
+
ps[:] = self._ps_acc(list(ps), _xs, up=up)
|
|
928
932
|
return self
|
|
929
933
|
|
|
930
934
|
def _facc_1(self, xs, **up):
|
|
931
935
|
'''(INTERNAL) Accumulate 0, 1 or more C{scalars} or L{Fsum}s,
|
|
932
936
|
all positional C{xs} in the caller of this method.
|
|
933
937
|
'''
|
|
934
|
-
return self._fadd(xs[0], _add_op_, **up) if
|
|
938
|
+
return self._fadd(xs[0], _add_op_, **up) if len(xs) == 1 else \
|
|
935
939
|
self._facc(xs, origin=1, **up)
|
|
936
940
|
|
|
941
|
+
def _facc_inplace(self, other, op, _facc):
|
|
942
|
+
'''(INTERNAL) Accumulate from an iterable.
|
|
943
|
+
'''
|
|
944
|
+
try:
|
|
945
|
+
return _facc(other, origin=1) if _xiterable(other) else self
|
|
946
|
+
except Exception as X:
|
|
947
|
+
raise self._ErrorX(X, op, other)
|
|
948
|
+
|
|
937
949
|
def _facc_neg(self, xs, **up_origin):
|
|
938
950
|
'''(INTERNAL) Accumulate more C{scalars} or L{Fsum}s, negated.
|
|
939
951
|
'''
|
|
@@ -941,7 +953,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
941
953
|
return X._ps_neg
|
|
942
954
|
|
|
943
955
|
def _n(x):
|
|
944
|
-
return -
|
|
956
|
+
return -float(x)
|
|
945
957
|
|
|
946
958
|
return self._facc(xs, _X=_N, _x=_n, **up_origin)
|
|
947
959
|
|
|
@@ -967,16 +979,17 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
967
979
|
_Pow, p, s, r = _Pow4(power)
|
|
968
980
|
if p: # and xs:
|
|
969
981
|
op = which.__name__
|
|
982
|
+
_flt = float
|
|
970
983
|
_Fs = Fsum
|
|
971
|
-
|
|
984
|
+
_isa = isinstance
|
|
972
985
|
_pow = self._pow_2_3
|
|
973
986
|
|
|
974
987
|
def _P(X):
|
|
975
988
|
f = _Pow(X, p, power, op, **raiser_RESIDUAL)
|
|
976
|
-
return f._ps if
|
|
989
|
+
return f._ps if _isa(f, _Fs) else (f,)
|
|
977
990
|
|
|
978
991
|
def _p(x):
|
|
979
|
-
x =
|
|
992
|
+
x = _flt(x)
|
|
980
993
|
f = _pow(x, s, power, op, **raiser_RESIDUAL)
|
|
981
994
|
if f and r:
|
|
982
995
|
f *= _pow(x, r, power, op, **raiser_RESIDUAL)
|
|
@@ -984,7 +997,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
984
997
|
|
|
985
998
|
f = self._facc(xs, origin=1, _X=_P, _x=_p)
|
|
986
999
|
else:
|
|
987
|
-
f = self._facc_scalar_(
|
|
1000
|
+
f = self._facc_scalar_(float(len(xs))) # x**0 == 1
|
|
988
1001
|
return f
|
|
989
1002
|
|
|
990
1003
|
def _facc_scalar(self, xs, **up):
|
|
@@ -1006,7 +1019,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1006
1019
|
# and re-accumulating the final C{partial}.
|
|
1007
1020
|
# '''
|
|
1008
1021
|
# ps = self._ps
|
|
1009
|
-
# while
|
|
1022
|
+
# while len(ps) > 1:
|
|
1010
1023
|
# p = ps.pop()
|
|
1011
1024
|
# if p:
|
|
1012
1025
|
# n = self._n
|
|
@@ -1030,10 +1043,10 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1030
1043
|
@raise ValueError: Invalid or non-finite B{C{xs}} value.
|
|
1031
1044
|
'''
|
|
1032
1045
|
if _isFsumTuple(xs):
|
|
1033
|
-
self._facc_scalar(xs._ps)
|
|
1046
|
+
self._facc_scalar(xs._ps)
|
|
1034
1047
|
elif isscalar(xs): # for backward compatibility
|
|
1035
1048
|
self._facc_scalar_(_2float(x=xs)) # PYCHOK no cover
|
|
1036
|
-
elif xs: #
|
|
1049
|
+
elif xs: # _xiterable(xs)
|
|
1037
1050
|
self._facc(xs)
|
|
1038
1051
|
return self
|
|
1039
1052
|
|
|
@@ -1051,9 +1064,9 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1051
1064
|
'''(INTERNAL) Apply C{B{self} += B{other}}.
|
|
1052
1065
|
'''
|
|
1053
1066
|
if not self._ps: # new Fsum(x)
|
|
1054
|
-
self._fset(other,
|
|
1067
|
+
self._fset(other, op=op, **up)
|
|
1055
1068
|
elif _isFsumTuple(other):
|
|
1056
|
-
self._facc_scalar(other._ps, **up)
|
|
1069
|
+
self._facc_scalar(other._ps, **up)
|
|
1057
1070
|
elif self._scalar(other, op):
|
|
1058
1071
|
self._facc_scalar_(other, **up)
|
|
1059
1072
|
return self
|
|
@@ -1131,9 +1144,9 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1131
1144
|
'''(INTERNAL) Get 2-tuple (C{int}, I{integer} residual).
|
|
1132
1145
|
'''
|
|
1133
1146
|
s, r = self._fprs2
|
|
1134
|
-
i =
|
|
1135
|
-
n =
|
|
1136
|
-
r =
|
|
1147
|
+
i = int(s)
|
|
1148
|
+
n = len(self._ps)
|
|
1149
|
+
r = self._ps_1sum(i) if r and n > 1 else float(s - i)
|
|
1137
1150
|
return i, (r or INT0) # Fsum2Tuple?
|
|
1138
1151
|
|
|
1139
1152
|
@deprecated_property_RO
|
|
@@ -1172,16 +1185,16 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1172
1185
|
'''(INTERNAL) Apply C{B{self} *= B{other}}.
|
|
1173
1186
|
'''
|
|
1174
1187
|
if _isFsumTuple(other):
|
|
1175
|
-
if
|
|
1188
|
+
if len(self._ps) != 1:
|
|
1176
1189
|
f = self._mul_Fsum(other, op)
|
|
1177
|
-
elif
|
|
1190
|
+
elif len(other._ps) != 1: # and len(self._ps) == 1
|
|
1178
1191
|
f = other._mul_scalar(self._ps[0], op)
|
|
1179
|
-
else: #
|
|
1192
|
+
else: # len(other._ps) == len(self._ps) == 1
|
|
1180
1193
|
f = self._finite(self._ps[0] * other._ps[0])
|
|
1181
1194
|
else:
|
|
1182
1195
|
s = self._scalar(other, op)
|
|
1183
1196
|
f = self._mul_scalar(s, op)
|
|
1184
|
-
return self._fset(f) # n=
|
|
1197
|
+
return self._fset(f) # n=len(self) + 1
|
|
1185
1198
|
|
|
1186
1199
|
def fover(self, over, **raiser_RESIDUAL):
|
|
1187
1200
|
'''Apply C{B{self} /= B{over}} and summate.
|
|
@@ -1198,7 +1211,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1198
1211
|
|
|
1199
1212
|
@see: Methods L{Fsum.fsum} and L{Fsum.__itruediv__}.
|
|
1200
1213
|
'''
|
|
1201
|
-
return
|
|
1214
|
+
return float(self.fdiv(over, **raiser_RESIDUAL)._fprs)
|
|
1202
1215
|
|
|
1203
1216
|
fpow = __ipow__
|
|
1204
1217
|
|
|
@@ -1218,7 +1231,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1218
1231
|
f = self._pow(other, other, op, **raiser_RESIDUAL)
|
|
1219
1232
|
else: # pow(self, other)
|
|
1220
1233
|
f = self._pow(other, other, op, **raiser_RESIDUAL)
|
|
1221
|
-
return self._fset(f
|
|
1234
|
+
return self._fset(f) # n=max(len(self), 1)
|
|
1222
1235
|
|
|
1223
1236
|
@Property_RO
|
|
1224
1237
|
def _fprs(self):
|
|
@@ -1236,20 +1249,20 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1236
1249
|
'''(INTERNAL) Get and cache this instance' precision
|
|
1237
1250
|
running sum and residual (L{Fsum2Tuple}).
|
|
1238
1251
|
'''
|
|
1239
|
-
ps =
|
|
1240
|
-
n =
|
|
1241
|
-
if n > 0: #
|
|
1252
|
+
ps = self._ps
|
|
1253
|
+
n = len(ps) - 2
|
|
1254
|
+
if n > 0: # len(ps) > 2
|
|
1242
1255
|
s = _psum(ps)
|
|
1243
|
-
n =
|
|
1256
|
+
n = len(ps) - 2
|
|
1244
1257
|
if n > 0:
|
|
1245
1258
|
r = self._ps_1sum(s)
|
|
1246
1259
|
return Fsum2Tuple(*_s_r(s, r))
|
|
1247
|
-
if n == 0: #
|
|
1260
|
+
if n == 0: # len(ps) == 2
|
|
1248
1261
|
s, r = _s_r(*_2sum(*ps))
|
|
1249
1262
|
ps[:] = (r, s) if r else (s,)
|
|
1250
|
-
elif ps: #
|
|
1263
|
+
elif ps: # len(ps) == 1
|
|
1251
1264
|
s, r = ps[0], INT0
|
|
1252
|
-
else: #
|
|
1265
|
+
else: # len(ps) == 0
|
|
1253
1266
|
s, r = _0_0, INT0
|
|
1254
1267
|
ps[:] = s,
|
|
1255
1268
|
# assert self._ps is ps
|
|
@@ -1270,7 +1283,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1270
1283
|
Fsum(*xs) if xs else _0_0)
|
|
1271
1284
|
return self._fset(f)
|
|
1272
1285
|
|
|
1273
|
-
def _fset(self, other,
|
|
1286
|
+
def _fset(self, other, n=0, up=True, **op):
|
|
1274
1287
|
'''(INTERNAL) Overwrite this instance with an other or a C{scalar}.
|
|
1275
1288
|
'''
|
|
1276
1289
|
if other is self:
|
|
@@ -1284,7 +1297,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1284
1297
|
Fsum._fprs ._update_from(self, other)
|
|
1285
1298
|
Fsum._fprs2._update_from(self, other)
|
|
1286
1299
|
elif isscalar(other):
|
|
1287
|
-
s = other if
|
|
1300
|
+
s = float(self._finite(other, **op)) if op else other
|
|
1288
1301
|
self._ps[:] = s,
|
|
1289
1302
|
self._n = n or 1
|
|
1290
1303
|
if up:
|
|
@@ -1294,7 +1307,8 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1294
1307
|
# Property's _fset zaps the value just set by the @setter
|
|
1295
1308
|
self.__dict__.update(_fint2=t, _fprs=s, _fprs2=Fsum2Tuple(s, INT0))
|
|
1296
1309
|
else: # PYCHOK no cover
|
|
1297
|
-
|
|
1310
|
+
op = _xkwds_get(op, op=_fset_op_)
|
|
1311
|
+
raise self._Error(op, other, _TypeError)
|
|
1298
1312
|
return self
|
|
1299
1313
|
|
|
1300
1314
|
def _fset_ps(self, other, n=0): # in .fmath
|
|
@@ -1320,7 +1334,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1320
1334
|
|
|
1321
1335
|
@see: Method L{Fsum.fadd_} for further details.
|
|
1322
1336
|
'''
|
|
1323
|
-
return self._fsub(xs[0], _sub_op_) if
|
|
1337
|
+
return self._fsub(xs[0], _sub_op_) if len(xs) == 1 else \
|
|
1324
1338
|
self._facc_neg(xs, origin=1)
|
|
1325
1339
|
|
|
1326
1340
|
def _fsub(self, other, op):
|
|
@@ -1328,7 +1342,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1328
1342
|
'''
|
|
1329
1343
|
if _isFsumTuple(other):
|
|
1330
1344
|
if other is self: # or other._fprs2 == self._fprs2:
|
|
1331
|
-
self._fset(_0_0, n=
|
|
1345
|
+
self._fset(_0_0, n=len(self) * 2)
|
|
1332
1346
|
elif other._ps:
|
|
1333
1347
|
self._facc_scalar(other._ps_neg)
|
|
1334
1348
|
elif self._scalar(other, op):
|
|
@@ -1419,12 +1433,12 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1419
1433
|
'''
|
|
1420
1434
|
return self._fsum2(xs, self._facc_1)
|
|
1421
1435
|
|
|
1422
|
-
def _fsum2(self, xs,
|
|
1436
|
+
def _fsum2(self, xs, _facc, **origin):
|
|
1423
1437
|
'''(INTERNAL) Helper for L{Fsum.fsum2_} and L{Fsum.fsum2f_}.
|
|
1424
1438
|
'''
|
|
1425
1439
|
p, q = self._fprs2
|
|
1426
1440
|
if xs:
|
|
1427
|
-
s, r =
|
|
1441
|
+
s, r = _facc(xs, **origin)._fprs2
|
|
1428
1442
|
return s, _2delta(s - p, r - q) # _fsum(_1primed((s, -p, r, -q))
|
|
1429
1443
|
else:
|
|
1430
1444
|
return p, _0_0
|
|
@@ -1452,7 +1466,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1452
1466
|
n = _1_0
|
|
1453
1467
|
if _isFsumTuple(other):
|
|
1454
1468
|
if other is self or self == other:
|
|
1455
|
-
return self._fset(n
|
|
1469
|
+
return self._fset(n, n=len(self))
|
|
1456
1470
|
d, r = other._fprs2
|
|
1457
1471
|
if r:
|
|
1458
1472
|
R = self._raiser(r, d, **raiser_RESIDUAL)
|
|
@@ -1466,7 +1480,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1466
1480
|
except Exception as X:
|
|
1467
1481
|
raise self._ErrorX(X, op, other)
|
|
1468
1482
|
f = self._mul_scalar(s, _mul_op_) # handles 0, INF, NAN
|
|
1469
|
-
return self._fset(f)
|
|
1483
|
+
return self._fset(f)
|
|
1470
1484
|
|
|
1471
1485
|
@property_RO
|
|
1472
1486
|
def imag(self):
|
|
@@ -1501,7 +1515,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1501
1515
|
if R:
|
|
1502
1516
|
t = _stresidual(_non_zero_, r, **R)
|
|
1503
1517
|
raise ResidualError(int_float=s, txt=t)
|
|
1504
|
-
s =
|
|
1518
|
+
s = float(s)
|
|
1505
1519
|
return s
|
|
1506
1520
|
|
|
1507
1521
|
def is_exact(self):
|
|
@@ -1589,7 +1603,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1589
1603
|
def partials(self):
|
|
1590
1604
|
'''Get this instance' current, partial sums (C{tuple} of C{float}s).
|
|
1591
1605
|
'''
|
|
1592
|
-
return
|
|
1606
|
+
return tuple(self._ps)
|
|
1593
1607
|
|
|
1594
1608
|
def pow(self, x, *mod, **raiser_RESIDUAL):
|
|
1595
1609
|
'''Return C{B{self}**B{x}} as L{Fsum}.
|
|
@@ -1677,7 +1691,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1677
1691
|
'''
|
|
1678
1692
|
# assert isint(x) and x >= 0
|
|
1679
1693
|
ps = self._ps
|
|
1680
|
-
if
|
|
1694
|
+
if len(ps) > 1:
|
|
1681
1695
|
_mul_Fsum = Fsum._mul_Fsum
|
|
1682
1696
|
if x > 4:
|
|
1683
1697
|
p = self
|
|
@@ -1709,8 +1723,8 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1709
1723
|
if r:
|
|
1710
1724
|
# assert s != 0
|
|
1711
1725
|
if isint(x, both=True): # self**int
|
|
1712
|
-
x =
|
|
1713
|
-
y =
|
|
1726
|
+
x = int(x)
|
|
1727
|
+
y = abs(x)
|
|
1714
1728
|
if y > 1:
|
|
1715
1729
|
f = self._pow_int(y, other, op, **raiser_RESIDUAL)
|
|
1716
1730
|
if x > 0: # i.e. > 1
|
|
@@ -1734,7 +1748,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1734
1748
|
if R:
|
|
1735
1749
|
raise self._ResidualError(op, other, r, **R)
|
|
1736
1750
|
n, d = self.as_integer_ratio()
|
|
1737
|
-
if
|
|
1751
|
+
if abs(n) > abs(d):
|
|
1738
1752
|
n, d, x = d, n, (-x)
|
|
1739
1753
|
s = n / d
|
|
1740
1754
|
# assert isscalar(s) and isscalar(x)
|
|
@@ -1745,7 +1759,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1745
1759
|
'''
|
|
1746
1760
|
n = 0
|
|
1747
1761
|
_2s = _2sum
|
|
1748
|
-
for x in (
|
|
1762
|
+
for x in (tuple(xs) if xs is ps else xs):
|
|
1749
1763
|
# assert isscalar(x) and _isfinite(x)
|
|
1750
1764
|
if x:
|
|
1751
1765
|
i = 0
|
|
@@ -1758,7 +1772,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1758
1772
|
n += 1
|
|
1759
1773
|
if n:
|
|
1760
1774
|
self._n += n
|
|
1761
|
-
# Fsum._ps_max = max(Fsum._ps_max,
|
|
1775
|
+
# Fsum._ps_max = max(Fsum._ps_max, len(ps))
|
|
1762
1776
|
if up:
|
|
1763
1777
|
self._update()
|
|
1764
1778
|
return ps
|
|
@@ -1768,7 +1782,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1768
1782
|
each scalar C{factor} and accumulate into an C{Fsum}.
|
|
1769
1783
|
'''
|
|
1770
1784
|
def _pfs(ps, fs):
|
|
1771
|
-
if
|
|
1785
|
+
if len(ps) < len(fs):
|
|
1772
1786
|
ps, fs = fs, ps
|
|
1773
1787
|
_fin = _isfinite
|
|
1774
1788
|
for f in fs:
|
|
@@ -1823,7 +1837,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1823
1837
|
and properties L{Fsum.ceil}, L{Fsum.floor},
|
|
1824
1838
|
L{Fsum.imag} and L{Fsum.residual}.
|
|
1825
1839
|
'''
|
|
1826
|
-
return
|
|
1840
|
+
return float(self._fprs)
|
|
1827
1841
|
|
|
1828
1842
|
@property_RO
|
|
1829
1843
|
def residual(self):
|
|
@@ -1937,7 +1951,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1937
1951
|
'''
|
|
1938
1952
|
p = self.classname
|
|
1939
1953
|
if lenc:
|
|
1940
|
-
p = Fmt.SQUARE(p,
|
|
1954
|
+
p = Fmt.SQUARE(p, len(self))
|
|
1941
1955
|
n = _enquote(self.name, white=_UNDER_)
|
|
1942
1956
|
t = self._fprs2.toStr(**prec_sep_fmt)
|
|
1943
1957
|
return NN(p, _SPACE_, n, t)
|
|
@@ -2075,7 +2089,7 @@ class Fsum2Tuple(_NamedTuple): # in .fstats
|
|
|
2075
2089
|
return self._Fsum._n
|
|
2076
2090
|
|
|
2077
2091
|
def _other_op(self, other, which):
|
|
2078
|
-
C, s = (
|
|
2092
|
+
C, s = (tuple, self) if isinstance(other, tuple) else (Fsum, self._Fsum)
|
|
2079
2093
|
return getattr(C, which.__name__)(s, other)
|
|
2080
2094
|
|
|
2081
2095
|
@property_RO
|
|
@@ -2232,7 +2246,7 @@ if __name__ == '__main__':
|
|
|
2232
2246
|
F = Fsum()
|
|
2233
2247
|
if F.is_math_fsum():
|
|
2234
2248
|
for t in frandoms(n, seeded=True):
|
|
2235
|
-
assert
|
|
2249
|
+
assert float(F.fset_(*t)) == _fsum(t)
|
|
2236
2250
|
printf(_DOT_, end=NN)
|
|
2237
2251
|
printf(NN)
|
|
2238
2252
|
|
pygeodesy/geodesicw.py
CHANGED
|
@@ -20,8 +20,8 @@ from pygeodesy.datums import _earth_datum, _WGS84, _EWGS84
|
|
|
20
20
|
# from pygeodesy.ellipsoids import _EWGS84 # from .datums
|
|
21
21
|
from pygeodesy.errors import IntersectionError, GeodesicError, _xkwds_pop2
|
|
22
22
|
from pygeodesy.fsums import Fsum, Fmt, unstr
|
|
23
|
-
from pygeodesy.
|
|
24
|
-
|
|
23
|
+
from pygeodesy.internals import _dunder_nameof, _under
|
|
24
|
+
from pygeodesy.interns import NN, _DOT_, _SPACE_, _to_, _too_
|
|
25
25
|
from pygeodesy.karney import _atan2d, Caps, Direct9Tuple, GDict, \
|
|
26
26
|
_kWrapped, Inverse10Tuple
|
|
27
27
|
from pygeodesy.latlonBase import LatLonBase as _LLB, F_D, Radius_
|
|
@@ -37,7 +37,7 @@ from contextlib import contextmanager
|
|
|
37
37
|
# from math import fabs # from .utily
|
|
38
38
|
|
|
39
39
|
__all__ = _ALL_LAZY.geodesicw
|
|
40
|
-
__version__ = '24.
|
|
40
|
+
__version__ = '24.05.14'
|
|
41
41
|
|
|
42
42
|
_plumb_ = 'plumb'
|
|
43
43
|
_TRIPS = 65
|
|
@@ -353,17 +353,17 @@ class _gWrapped(_kWrapped):
|
|
|
353
353
|
@arg radius: Radius of the circle (C{meter}, conventionally).
|
|
354
354
|
@kwarg tol: Convergence tolerance (C{scalar}).
|
|
355
355
|
|
|
356
|
-
@return: 2-Tuple C{(P, Q)} with both intersections (representing
|
|
357
|
-
geodesic chord), each a L{GDict} from method L{Position}
|
|
358
|
-
extended to 14 items
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
and this line at the
|
|
364
|
-
|
|
365
|
-
tangential to the circle, both
|
|
366
|
-
L{GDict} instance.
|
|
356
|
+
@return: 2-Tuple C{(P, Q)} with both intersections points (representing
|
|
357
|
+
a geodesic chord), each a L{GDict} from method L{Position} and
|
|
358
|
+
extended to 14 items C{lat1, lon1, azi1, lat2, lon2, azi2, a12,
|
|
359
|
+
s12, lat0, lon0, azi0, a02, s02, at} with the circle center
|
|
360
|
+
C{lat0}, C{lon0}, azimuth C{azi0} at the intersection, distance
|
|
361
|
+
C{a02} in C{degrees} and C{s02} in C{meter} along the geodesic
|
|
362
|
+
from the circle center to the intersection C{lat2, lon2} and
|
|
363
|
+
the angle C{at} between the geodesic and this line at the
|
|
364
|
+
intersection. The I{geodesic} azimuth at the intersection is
|
|
365
|
+
C{(at + azi2)}. If this line is tangential to the circle, both
|
|
366
|
+
intersections are the same L{GDict} instance.
|
|
367
367
|
|
|
368
368
|
@raise IntersectionError: The circle and this geodesic line do not
|
|
369
369
|
intersect.
|