pygeodesy 25.1.9__py2.py3-none-any.whl → 25.4.25__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/__init__.py +35 -31
- pygeodesy/__main__.py +3 -3
- pygeodesy/albers.py +29 -36
- pygeodesy/auxilats/_CX_4.py +2 -2
- pygeodesy/auxilats/_CX_6.py +2 -2
- pygeodesy/auxilats/_CX_8.py +2 -2
- pygeodesy/auxilats/_CX_Rs.py +59 -40
- pygeodesy/auxilats/__init__.py +3 -3
- pygeodesy/auxilats/__main__.py +9 -7
- pygeodesy/auxilats/auxAngle.py +2 -2
- pygeodesy/auxilats/auxLat.py +13 -13
- pygeodesy/auxilats/auxily.py +13 -9
- pygeodesy/azimuthal.py +7 -6
- pygeodesy/basics.py +65 -22
- pygeodesy/booleans.py +12 -10
- pygeodesy/cartesianBase.py +21 -20
- pygeodesy/clipy.py +11 -10
- pygeodesy/constants.py +11 -10
- pygeodesy/css.py +14 -11
- pygeodesy/datums.py +8 -8
- pygeodesy/deprecated/bases.py +2 -2
- pygeodesy/deprecated/classes.py +2 -2
- pygeodesy/deprecated/consterns.py +4 -4
- pygeodesy/dms.py +8 -8
- pygeodesy/ecef.py +10 -7
- pygeodesy/elevations.py +9 -8
- pygeodesy/ellipsoidalBase.py +19 -8
- pygeodesy/ellipsoidalBaseDI.py +17 -15
- pygeodesy/ellipsoidalNvector.py +6 -3
- pygeodesy/ellipsoidalVincenty.py +4 -1
- pygeodesy/ellipsoids.py +167 -138
- pygeodesy/elliptic.py +9 -9
- pygeodesy/errors.py +44 -43
- pygeodesy/etm.py +9 -9
- pygeodesy/fmath.py +10 -9
- pygeodesy/formy.py +11 -12
- pygeodesy/frechet.py +216 -109
- pygeodesy/fstats.py +5 -4
- pygeodesy/fsums.py +107 -122
- pygeodesy/gars.py +7 -7
- pygeodesy/geodesici.py +15 -14
- pygeodesy/geodesicw.py +34 -32
- pygeodesy/geodesicx/__init__.py +1 -1
- pygeodesy/geodesicx/__main__.py +12 -10
- pygeodesy/geodesicx/gx.py +30 -33
- pygeodesy/geodesicx/gxarea.py +2 -2
- pygeodesy/geodesicx/gxline.py +5 -5
- pygeodesy/geodsolve.py +18 -17
- pygeodesy/geohash.py +7 -8
- pygeodesy/geoids.py +35 -34
- pygeodesy/hausdorff.py +17 -13
- pygeodesy/heights.py +2 -4
- pygeodesy/internals.py +31 -46
- pygeodesy/interns.py +12 -9
- pygeodesy/iters.py +8 -8
- pygeodesy/karney.py +73 -66
- pygeodesy/ktm.py +5 -5
- pygeodesy/latlonBase.py +14 -18
- pygeodesy/lazily.py +73 -74
- pygeodesy/lcc.py +11 -9
- pygeodesy/ltp.py +8 -7
- pygeodesy/ltpTuples.py +2 -2
- pygeodesy/mgrs.py +7 -6
- pygeodesy/named.py +47 -31
- pygeodesy/nvectorBase.py +7 -7
- pygeodesy/osgr.py +9 -8
- pygeodesy/points.py +12 -10
- pygeodesy/props.py +25 -25
- pygeodesy/resections.py +11 -10
- pygeodesy/rhumb/__init__.py +1 -1
- pygeodesy/rhumb/aux_.py +14 -14
- pygeodesy/rhumb/bases.py +22 -20
- pygeodesy/rhumb/ekx.py +6 -6
- pygeodesy/rhumb/solve.py +15 -15
- pygeodesy/solveBase.py +3 -3
- pygeodesy/sphericalBase.py +6 -6
- pygeodesy/sphericalNvector.py +6 -5
- pygeodesy/sphericalTrigonometry.py +8 -7
- pygeodesy/streprs.py +14 -14
- pygeodesy/trf.py +14 -12
- pygeodesy/triaxials.py +29 -26
- pygeodesy/units.py +5 -4
- pygeodesy/unitsBase.py +5 -4
- pygeodesy/ups.py +3 -3
- pygeodesy/utily.py +4 -4
- pygeodesy/utmups.py +4 -4
- pygeodesy/utmupsBase.py +88 -18
- pygeodesy/vector2d.py +18 -11
- pygeodesy/vector3d.py +7 -6
- pygeodesy/webmercator.py +6 -5
- pygeodesy/wgrs.py +6 -5
- {pygeodesy-25.1.9.dist-info → pygeodesy-25.4.25.dist-info}/METADATA +35 -31
- pygeodesy-25.4.25.dist-info/RECORD +118 -0
- pygeodesy-25.1.9.dist-info/RECORD +0 -118
- {pygeodesy-25.1.9.dist-info → pygeodesy-25.4.25.dist-info}/WHEEL +0 -0
- {pygeodesy-25.1.9.dist-info → pygeodesy-25.4.25.dist-info}/top_level.txt +0 -0
pygeodesy/fsums.py
CHANGED
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
# -*- coding: utf-8 -*-
|
|
3
3
|
|
|
4
4
|
u'''Class L{Fsum} for precision floating point summation similar to
|
|
5
|
-
Python's C{math.fsum} enhanced with I{running} summation
|
|
6
|
-
|
|
5
|
+
Python's C{math.fsum}, but enhanced with I{precision running} summation
|
|
6
|
+
plus optionally, accurate I{TwoProduct} multiplication.
|
|
7
7
|
|
|
8
|
-
Accurate multiplication is based on the C{math.fma} function
|
|
9
|
-
Python 3.13 and newer or
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
Accurate multiplication is based on the C{math.fma} function from
|
|
9
|
+
Python 3.13 and newer or an equivalent C{fma} implementation for
|
|
10
|
+
Python 3.12 and older. To enable accurate multiplication, set env
|
|
11
|
+
variable C{PYGEODESY_FSUM_F2PRODUCT} to C{"std"} or any non-empty
|
|
12
12
|
string or invoke function C{pygeodesy.f2product(True)} or set. With
|
|
13
13
|
C{"std"} the C{fma} implemention follows the C{math.fma} function,
|
|
14
14
|
otherwise the C{PyGeodesy 24.09.09} release.
|
|
@@ -39,8 +39,8 @@ results may differ from Python's C{math.fsum} results.
|
|
|
39
39
|
# make sure int/int division yields float quotient, see .basics
|
|
40
40
|
from __future__ import division as _; del _ # PYCHOK semicolon
|
|
41
41
|
|
|
42
|
-
from pygeodesy.basics import isbool, iscomplex, isint, isscalar, \
|
|
43
|
-
|
|
42
|
+
from pygeodesy.basics import _gcd, isbool, iscomplex, isint, isscalar, \
|
|
43
|
+
_signOf, itemsorted, signOf, _xiterable
|
|
44
44
|
from pygeodesy.constants import INF, INT0, MANT_DIG, NEG0, NINF, _0_0, \
|
|
45
45
|
_1_0, _N_1_0, _isfinite, _pos_self, \
|
|
46
46
|
Float, Int
|
|
@@ -48,12 +48,12 @@ from pygeodesy.errors import _AssertionError, _OverflowError, _TypeError, \
|
|
|
48
48
|
_ValueError, _xError, _xError2, _xkwds, \
|
|
49
49
|
_xkwds_get, _xkwds_get1, _xkwds_not, \
|
|
50
50
|
_xkwds_pop, _xsError
|
|
51
|
-
from pygeodesy.internals import _enquote,
|
|
52
|
-
from pygeodesy.interns import NN, _arg_, _COMMASPACE_, _DOT_, _from_, \
|
|
51
|
+
from pygeodesy.internals import _enquote, _envPYGEODESY, _passarg, typename
|
|
52
|
+
from pygeodesy.interns import NN, _arg_, _COMMASPACE_, _DMAIN_, _DOT_, _from_, \
|
|
53
53
|
_not_finite_, _SPACE_, _std_, _UNDER_
|
|
54
|
-
# from pygeodesy.lazily import _ALL_LAZY # from .named
|
|
54
|
+
# from pygeodesy.lazily import _ALL_LAZY, _ALL_MODS as _MODS # from .named
|
|
55
55
|
from pygeodesy.named import _name__, _name2__, _Named, _NamedTuple, \
|
|
56
|
-
_NotImplemented, _ALL_LAZY
|
|
56
|
+
_NotImplemented, _ALL_LAZY, _MODS
|
|
57
57
|
from pygeodesy.props import _allPropertiesOf_n, deprecated_method, \
|
|
58
58
|
deprecated_property_RO, Property, \
|
|
59
59
|
Property_RO, property_RO
|
|
@@ -64,30 +64,30 @@ from math import fabs, isinf, isnan, \
|
|
|
64
64
|
ceil as _ceil, floor as _floor # PYCHOK used! .ltp
|
|
65
65
|
|
|
66
66
|
__all__ = _ALL_LAZY.fsums
|
|
67
|
-
__version__ = '
|
|
67
|
+
__version__ = '25.04.14'
|
|
68
68
|
|
|
69
69
|
from pygeodesy.interns import (
|
|
70
70
|
_PLUS_ as _add_op_, # in .auxilats.auxAngle
|
|
71
|
+
_DSLASH_ as _floordiv_op_,
|
|
71
72
|
_EQUAL_ as _fset_op_,
|
|
72
73
|
_RANGLE_ as _gt_op_,
|
|
73
74
|
_LANGLE_ as _lt_op_,
|
|
74
75
|
_PERCENT_ as _mod_op_,
|
|
75
76
|
_STAR_ as _mul_op_,
|
|
76
77
|
_NOTEQUAL_ as _ne_op_,
|
|
78
|
+
_DSTAR_ as _pow_op_,
|
|
77
79
|
_DASH_ as _sub_op_, # in .auxilats.auxAngle
|
|
78
80
|
_SLASH_ as _truediv_op_
|
|
79
81
|
)
|
|
80
|
-
_floordiv_op_ = _truediv_op_ * 2 # _DSLASH_
|
|
81
82
|
_divmod_op_ = _floordiv_op_ + _mod_op_
|
|
82
|
-
_F2PRODUCT =
|
|
83
|
+
_F2PRODUCT = _envPYGEODESY('FSUM_F2PRODUCT')
|
|
83
84
|
_iadd_op_ = _add_op_ + _fset_op_ # in .auxilats.auxAngle, .fstats
|
|
84
85
|
_integer_ = 'integer'
|
|
85
86
|
_isub_op_ = _sub_op_ + _fset_op_ # in .auxilats.auxAngle
|
|
86
87
|
_NONFINITEr = _0_0 # NOT INT0!
|
|
87
|
-
_NONFINITES =
|
|
88
|
+
_NONFINITES = _envPYGEODESY('FSUM_NONFINITES')
|
|
88
89
|
_non_zero_ = 'non-zero'
|
|
89
|
-
|
|
90
|
-
_RESIDUAL_0_0 = _getPYGEODESY('FSUM_RESIDUAL', _0_0)
|
|
90
|
+
_RESIDUAL_0_0 = _envPYGEODESY('FSUM_RESIDUAL', _0_0)
|
|
91
91
|
_significant_ = 'significant'
|
|
92
92
|
_threshold_ = 'threshold'
|
|
93
93
|
|
|
@@ -96,7 +96,7 @@ def _2finite(x, _isfine=_isfinite): # in .fstats
|
|
|
96
96
|
'''(INTERNAL) return C{float(x)} if finite.
|
|
97
97
|
'''
|
|
98
98
|
return (float(x) if _isfine(x) # and isscalar(x)
|
|
99
|
-
|
|
99
|
+
else _nfError(x))
|
|
100
100
|
|
|
101
101
|
|
|
102
102
|
def _2float(index=None, _isfine=_isfinite, **name_x): # in .fmath, .fstats
|
|
@@ -132,27 +132,25 @@ except ImportError: # PYCHOK DSPACE! Python 3.12-
|
|
|
132
132
|
|
|
133
133
|
if _F2PRODUCT and _F2PRODUCT != _std_:
|
|
134
134
|
# backward to PyGeodesy 24.09.09, with _fmaX
|
|
135
|
+
from pygeodesy.basics import _integer_ratio2
|
|
135
136
|
|
|
136
137
|
def _fma(*a_b_c): # PYCHOK no cover
|
|
137
138
|
# mimick C{math.fma} from Python 3.13+,
|
|
138
139
|
# the same accuracy, but ~14x slower
|
|
139
|
-
(
|
|
140
|
-
n
|
|
141
|
-
|
|
142
|
-
|
|
140
|
+
(n, d), (nb, db), (nc, dc) = map(_integer_ratio2, a_b_c)
|
|
141
|
+
# n, d = (n * nb * dc + d * db * nc), (d * db * dc)
|
|
142
|
+
d *= db
|
|
143
|
+
n *= nb * dc
|
|
144
|
+
n += nc * d
|
|
145
|
+
d *= dc
|
|
143
146
|
try:
|
|
144
|
-
n, d = _n_d2(n,
|
|
147
|
+
n, d = _n_d2(n, d)
|
|
145
148
|
r = float(n / d)
|
|
146
149
|
except OverflowError: # "integer division result too large ..."
|
|
147
150
|
r = NINF if (_signOf(n, 0) * _signOf(d, 0)) < 0 else INF
|
|
148
151
|
return r if _isfinite(r) else _fmaX(r, *a_b_c) # "overflow in fma"
|
|
149
|
-
|
|
150
|
-
def _2n_d(x): # PYCHOK no cover
|
|
151
|
-
try: # int.as_integer_ratio in 3.8+
|
|
152
|
-
return x.as_integer_ratio()
|
|
153
|
-
except (AttributeError, OverflowError, TypeError, ValueError):
|
|
154
|
-
return (x if isint(x) else float(x)), 1
|
|
155
152
|
else:
|
|
153
|
+
_integer_ratio2 = None # redef, in Fsum.is_math_fma
|
|
156
154
|
|
|
157
155
|
def _fma(a, b, c): # PYCHOK redef
|
|
158
156
|
# mimick C{math.fma} from Python 3.13+,
|
|
@@ -161,17 +159,15 @@ except ImportError: # PYCHOK DSPACE! Python 3.12-
|
|
|
161
159
|
r = _fsum(_2products(a, b3s, c))
|
|
162
160
|
return r if _isfinite(r) else _fmaX(r, a, b, c)
|
|
163
161
|
|
|
164
|
-
_2n_d = None # redef
|
|
165
|
-
|
|
166
162
|
def _fmaX(r, *a_b_c): # PYCHOK no cover
|
|
167
|
-
# handle non-finite as Python 3.13+ C-function U{math_fma_impl
|
|
168
|
-
# GitHub.com/python/cpython/blob/main/Modules/mathmodule.c#L2305>}:
|
|
169
|
-
#
|
|
170
|
-
#
|
|
163
|
+
# handle non-finite fma result as Python 3.13+ C-function U{math_fma_impl
|
|
164
|
+
# <https://GitHub.com/python/cpython/blob/main/Modules/mathmodule.c#L2305>}:
|
|
165
|
+
# raise a ValueError for a NAN result from non-NAN C{a_b_c}s otherwise an
|
|
166
|
+
# OverflowError for a non-finite, non-NAN result from all finite C{a_b_c}s.
|
|
171
167
|
if isnan(r):
|
|
172
168
|
def _x(x):
|
|
173
169
|
return not isnan(x)
|
|
174
|
-
else: # non-
|
|
170
|
+
else: # non-finite, non-NAN
|
|
175
171
|
_x = _isfinite
|
|
176
172
|
if all(map(_x, a_b_c)):
|
|
177
173
|
raise _nfError(r, unstr(_fma, *a_b_c))
|
|
@@ -179,10 +175,8 @@ except ImportError: # PYCHOK DSPACE! Python 3.12-
|
|
|
179
175
|
|
|
180
176
|
def _2products(x, y3s, *zs): # PYCHOK in _fma, ...
|
|
181
177
|
# yield(x * y3 for y3 in y3s) + yield(z in zs)
|
|
182
|
-
# TwoProduct U{Algorithm 3.3
|
|
183
|
-
#
|
|
184
|
-
# also in Python 3.13+ C{Modules/mathmodule.c} under
|
|
185
|
-
# #ifndef UNRELIABLE_FMA ... #else ... #endif
|
|
178
|
+
# TwoProduct U{Algorithm 3.3<https://www.TUHH.De/ti3/paper/rump/OgRuOi05.pdf>}, also
|
|
179
|
+
# in Python 3.13+ C{Modules/mathmodule.c} under #ifndef UNRELIABLE_FMA ... #else ...
|
|
186
180
|
_, a, b = _2split3(x)
|
|
187
181
|
for y, c, d in y3s:
|
|
188
182
|
y *= x
|
|
@@ -278,29 +272,20 @@ def _isOK(unused):
|
|
|
278
272
|
def _isOK_or_finite(x, _isfine=_isfinite):
|
|
279
273
|
'''(INTERNAL) Is C{x} finite or is I{non-finite} OK?
|
|
280
274
|
'''
|
|
281
|
-
# assert _isfine
|
|
275
|
+
# assert _isin(_isfine, _isOK, _isfinite)
|
|
282
276
|
return _isfine(x) # C{bool}
|
|
283
277
|
|
|
284
278
|
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
n, d = (n // c), (d // c)
|
|
296
|
-
except TypeError: # non-int float
|
|
297
|
-
pass
|
|
298
|
-
return n, d
|
|
299
|
-
|
|
300
|
-
except ImportError: # 3.4-
|
|
301
|
-
|
|
302
|
-
def _n_d2(*n_d): # PYCHOK redef
|
|
303
|
-
return n_d
|
|
279
|
+
def _n_d2(n, d):
|
|
280
|
+
'''(INTERNAL) Reduce C{n} and C{d} by C{gcd}.
|
|
281
|
+
'''
|
|
282
|
+
try:
|
|
283
|
+
c = _gcd(n, d)
|
|
284
|
+
if c > 1:
|
|
285
|
+
return (n // c), (d // c)
|
|
286
|
+
except TypeError: # non-int float
|
|
287
|
+
pass
|
|
288
|
+
return n, d
|
|
304
289
|
|
|
305
290
|
|
|
306
291
|
def _nfError(x, *args):
|
|
@@ -418,7 +403,7 @@ def _s_r2(s, r):
|
|
|
418
403
|
def _strcomplex(s, *args):
|
|
419
404
|
'''(INTERNAL) C{Complex} 2- or 3-arg C{pow} error as C{str}.
|
|
420
405
|
'''
|
|
421
|
-
c =
|
|
406
|
+
c = typename(_strcomplex)[4:]
|
|
422
407
|
n = _sub_op_(len(args), _arg_)
|
|
423
408
|
t = unstr(pow, *args)
|
|
424
409
|
return _SPACE_(c, s, _from_, n, t)
|
|
@@ -427,8 +412,8 @@ def _strcomplex(s, *args):
|
|
|
427
412
|
def _stresidual(prefix, residual, R=0, **mod_ratio):
|
|
428
413
|
'''(INTERNAL) Residual error txt C{str}.
|
|
429
414
|
'''
|
|
430
|
-
p = _stresidual
|
|
431
|
-
t =
|
|
415
|
+
p = typename(_stresidual)[3:]
|
|
416
|
+
t = Fmt.PARENSPACED(p, Fmt(residual))
|
|
432
417
|
for n, v in itemsorted(mod_ratio):
|
|
433
418
|
p = Fmt.PARENSPACED(n, Fmt(v))
|
|
434
419
|
t = _COMMASPACE_(t, p)
|
|
@@ -548,7 +533,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
548
533
|
'''Return C{abs(self)} as an L{Fsum}.
|
|
549
534
|
'''
|
|
550
535
|
s = self.signOf() # == self._cmp_0(0)
|
|
551
|
-
return (-self) if s < 0 else self.
|
|
536
|
+
return (-self) if s < 0 else self._copyd(self.__abs__)
|
|
552
537
|
|
|
553
538
|
def __add__(self, other):
|
|
554
539
|
'''Return C{B{self} + B{other}} as an L{Fsum}.
|
|
@@ -559,7 +544,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
559
544
|
|
|
560
545
|
@see: Methods L{Fsum.fadd_} and L{Fsum.fadd}.
|
|
561
546
|
'''
|
|
562
|
-
f = self.
|
|
547
|
+
f = self._copyd(self.__add__)
|
|
563
548
|
return f._fadd(other)
|
|
564
549
|
|
|
565
550
|
def __bool__(self): # PYCHOK Python 3+
|
|
@@ -592,7 +577,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
592
577
|
|
|
593
578
|
@raise TypeError: Incompatible B{C{other}} C{type}.
|
|
594
579
|
'''
|
|
595
|
-
s = self._cmp_0(other, self.cmp
|
|
580
|
+
s = self._cmp_0(other, typename(self.cmp))
|
|
596
581
|
return _signOf(s, 0)
|
|
597
582
|
|
|
598
583
|
def __divmod__(self, other, **raiser_RESIDUAL):
|
|
@@ -610,7 +595,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
610
595
|
|
|
611
596
|
@see: Method L{Fsum.fdiv}.
|
|
612
597
|
'''
|
|
613
|
-
f = self.
|
|
598
|
+
f = self._copyd(self.__divmod__)
|
|
614
599
|
return f._fdivmod2(other, _divmod_op_, **raiser_RESIDUAL)
|
|
615
600
|
|
|
616
601
|
def __eq__(self, other):
|
|
@@ -644,7 +629,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
644
629
|
|
|
645
630
|
@see: Methods L{Fsum.__ifloordiv__}.
|
|
646
631
|
'''
|
|
647
|
-
f = self.
|
|
632
|
+
f = self._copyd(self.__floordiv__)
|
|
648
633
|
return f._floordiv(other, _floordiv_op_)
|
|
649
634
|
|
|
650
635
|
def __ge__(self, other):
|
|
@@ -859,7 +844,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
859
844
|
|
|
860
845
|
@see: Method L{Fsum.__imod__}.
|
|
861
846
|
'''
|
|
862
|
-
f = self.
|
|
847
|
+
f = self._copyd(self.__mod__)
|
|
863
848
|
return f._fdivmod2(other, _mod_op_).mod
|
|
864
849
|
|
|
865
850
|
def __mul__(self, other):
|
|
@@ -867,7 +852,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
867
852
|
|
|
868
853
|
@see: Method L{Fsum.__imul__}.
|
|
869
854
|
'''
|
|
870
|
-
f = self.
|
|
855
|
+
f = self._copyd(self.__mul__)
|
|
871
856
|
return f._fmul(other, _mul_op_)
|
|
872
857
|
|
|
873
858
|
def __ne__(self, other):
|
|
@@ -878,20 +863,20 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
878
863
|
def __neg__(self):
|
|
879
864
|
'''Return C{copy(B{self})}, I{negated}.
|
|
880
865
|
'''
|
|
881
|
-
f = self.
|
|
866
|
+
f = self._copyd(self.__neg__)
|
|
882
867
|
return f._fset(self._neg)
|
|
883
868
|
|
|
884
869
|
def __pos__(self):
|
|
885
870
|
'''Return this instance I{as-is}, like C{float.__pos__()}.
|
|
886
871
|
'''
|
|
887
|
-
return self if _pos_self else self.
|
|
872
|
+
return self if _pos_self else self._copyd(self.__pos__)
|
|
888
873
|
|
|
889
874
|
def __pow__(self, other, *mod): # PYCHOK 2 vs 3 args
|
|
890
875
|
'''Return C{B{self}**B{other}} as an L{Fsum}.
|
|
891
876
|
|
|
892
877
|
@see: Method L{Fsum.__ipow__}.
|
|
893
878
|
'''
|
|
894
|
-
f = self.
|
|
879
|
+
f = self._copyd(self.__pow__)
|
|
895
880
|
return f._fpow(other, _pow_op_, *mod)
|
|
896
881
|
|
|
897
882
|
def __radd__(self, other):
|
|
@@ -899,7 +884,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
899
884
|
|
|
900
885
|
@see: Method L{Fsum.__iadd__}.
|
|
901
886
|
'''
|
|
902
|
-
f = self.
|
|
887
|
+
f = self._rcopyd(other, self.__radd__)
|
|
903
888
|
return f._fadd(self)
|
|
904
889
|
|
|
905
890
|
def __rdivmod__(self, other):
|
|
@@ -908,7 +893,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
908
893
|
|
|
909
894
|
@see: Method L{Fsum.__divmod__}.
|
|
910
895
|
'''
|
|
911
|
-
f = self.
|
|
896
|
+
f = self._rcopyd(other, self.__rdivmod__)
|
|
912
897
|
return f._fdivmod2(self, _divmod_op_)
|
|
913
898
|
|
|
914
899
|
# turned off, called by _deepcopy and _copy
|
|
@@ -917,7 +902,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
917
902
|
# <https://docs.Python.org/3/library/pickle.html#object.__reduce__>}
|
|
918
903
|
# '''
|
|
919
904
|
# dict_ = self._Fsum_as().__dict__ # no __setstate__
|
|
920
|
-
# return (self
|
|
905
|
+
# return (type(self), self.partials, dict_)
|
|
921
906
|
|
|
922
907
|
# def __repr__(self):
|
|
923
908
|
# '''Return the default C{repr(this)}.
|
|
@@ -929,7 +914,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
929
914
|
|
|
930
915
|
@see: Method L{Fsum.__ifloordiv__}.
|
|
931
916
|
'''
|
|
932
|
-
f = self.
|
|
917
|
+
f = self._rcopyd(other, self.__rfloordiv__)
|
|
933
918
|
return f._floordiv(self, _floordiv_op_)
|
|
934
919
|
|
|
935
920
|
def __rmatmul__(self, other): # PYCHOK no coveS
|
|
@@ -941,7 +926,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
941
926
|
|
|
942
927
|
@see: Method L{Fsum.__imod__}.
|
|
943
928
|
'''
|
|
944
|
-
f = self.
|
|
929
|
+
f = self._rcopyd(other, self.__rmod__)
|
|
945
930
|
return f._fdivmod2(self, _mod_op_).mod
|
|
946
931
|
|
|
947
932
|
def __rmul__(self, other):
|
|
@@ -949,7 +934,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
949
934
|
|
|
950
935
|
@see: Method L{Fsum.__imul__}.
|
|
951
936
|
'''
|
|
952
|
-
f = self.
|
|
937
|
+
f = self._rcopyd(other, self.__rmul__)
|
|
953
938
|
return f._fmul(self, _mul_op_)
|
|
954
939
|
|
|
955
940
|
def __round__(self, *ndigits): # PYCHOK Python 3+
|
|
@@ -957,7 +942,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
957
942
|
|
|
958
943
|
@arg ndigits: Optional number of digits (C{int}).
|
|
959
944
|
'''
|
|
960
|
-
f = self.
|
|
945
|
+
f = self._copyd(self.__round__)
|
|
961
946
|
# <https://docs.Python.org/3.12/reference/datamodel.html?#object.__round__>
|
|
962
947
|
return f._fset(round(float(self), *ndigits)) # can be C{int}
|
|
963
948
|
|
|
@@ -966,7 +951,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
966
951
|
|
|
967
952
|
@see: Method L{Fsum.__ipow__}.
|
|
968
953
|
'''
|
|
969
|
-
f = self.
|
|
954
|
+
f = self._rcopyd(other, self.__rpow__)
|
|
970
955
|
return f._fpow(self, _pow_op_, *mod)
|
|
971
956
|
|
|
972
957
|
def __rsub__(self, other):
|
|
@@ -974,7 +959,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
974
959
|
|
|
975
960
|
@see: Method L{Fsum.__isub__}.
|
|
976
961
|
'''
|
|
977
|
-
f = self.
|
|
962
|
+
f = self._rcopyd(other, self.__rsub__)
|
|
978
963
|
return f._fsub(self, _sub_op_)
|
|
979
964
|
|
|
980
965
|
def __rtruediv__(self, other, **raiser_RESIDUAL):
|
|
@@ -982,7 +967,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
982
967
|
|
|
983
968
|
@see: Method L{Fsum.__itruediv__}.
|
|
984
969
|
'''
|
|
985
|
-
f = self.
|
|
970
|
+
f = self._rcopyd(other, self.__rtruediv__)
|
|
986
971
|
return f._ftruediv(self, _truediv_op_, **raiser_RESIDUAL)
|
|
987
972
|
|
|
988
973
|
def __str__(self):
|
|
@@ -999,7 +984,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
999
984
|
|
|
1000
985
|
@see: Method L{Fsum.__isub__}.
|
|
1001
986
|
'''
|
|
1002
|
-
f = self.
|
|
987
|
+
f = self._copyd(self.__sub__)
|
|
1003
988
|
return f._fsub(other, _sub_op_)
|
|
1004
989
|
|
|
1005
990
|
def __truediv__(self, other, **raiser_RESIDUAL):
|
|
@@ -1104,10 +1089,10 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1104
1089
|
# assert f._RESIDUAL is self._RESIDUAL
|
|
1105
1090
|
return f
|
|
1106
1091
|
|
|
1107
|
-
def
|
|
1092
|
+
def _copyd(self, which, name=NN):
|
|
1108
1093
|
'''(INTERNAL) Copy for I{dyadic} operators.
|
|
1109
1094
|
'''
|
|
1110
|
-
n = name or which
|
|
1095
|
+
n = name or typename(which)
|
|
1111
1096
|
# NOT .classof due to .Fdot(a, *b) args, etc.
|
|
1112
1097
|
f = _Named.copy(self, deep=False, name=n)
|
|
1113
1098
|
f._ps = list(self._ps) # separate list
|
|
@@ -1118,12 +1103,6 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1118
1103
|
# assert f._RESIDUAL is self._RESIDUAL
|
|
1119
1104
|
return f
|
|
1120
1105
|
|
|
1121
|
-
def _copy_2r(self, other, which):
|
|
1122
|
-
'''(INTERNAL) Copy for I{reverse-dyadic} operators.
|
|
1123
|
-
'''
|
|
1124
|
-
return other._copy_2(which) if _isFsum(other) else \
|
|
1125
|
-
self._copy_2(which)._fset(other)
|
|
1126
|
-
|
|
1127
1106
|
divmod = __divmod__
|
|
1128
1107
|
|
|
1129
1108
|
def _Error(self, op, other, Error, **txt_cause):
|
|
@@ -1209,7 +1188,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1209
1188
|
|
|
1210
1189
|
_Pow, p, s, r = _Pow4(power)
|
|
1211
1190
|
if p: # and xs:
|
|
1212
|
-
op = which
|
|
1191
|
+
op = typename(which)
|
|
1213
1192
|
_FsT = _Fsum_2Tuple_types
|
|
1214
1193
|
_pow = self._pow_2_3
|
|
1215
1194
|
|
|
@@ -1246,8 +1225,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1246
1225
|
'''(INTERNAL) Accumulate all C{xs}, each C{scalar}, an L{Fsum} or
|
|
1247
1226
|
L{Fsum2Tuple}, like function C{_xsum}.
|
|
1248
1227
|
'''
|
|
1249
|
-
|
|
1250
|
-
fs = _xs(xs, **_x_isfine(self.nonfinitesOK, _Cdot=_C,
|
|
1228
|
+
fs = _xs(xs, **_x_isfine(self.nonfinitesOK, _Cdot=type(self),
|
|
1251
1229
|
**origin_which)) # PYCHOK yield
|
|
1252
1230
|
return self._facc_scalar(fs, up=up)
|
|
1253
1231
|
|
|
@@ -1332,16 +1310,16 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1332
1310
|
|
|
1333
1311
|
def _fhorner(self, x, cs, where, incx=True): # in .fmath
|
|
1334
1312
|
'''(INTERNAL) Add an L{Fhorner} evaluation of polynomial
|
|
1335
|
-
C{sum(
|
|
1336
|
-
|
|
1313
|
+
C{sum(c * B{x}**i for i, c in _e(cs))} where C{_e =
|
|
1314
|
+
enumerate if B{incx} else _enumereverse}.
|
|
1337
1315
|
'''
|
|
1338
1316
|
# assert _xiterablen(cs)
|
|
1339
1317
|
try:
|
|
1340
|
-
n
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1318
|
+
n = len(cs)
|
|
1319
|
+
if n > 1 and _2finite(x, **self._isfine):
|
|
1320
|
+
H = self._Fsum_as(name__=self._fhorner)
|
|
1321
|
+
_m = H._mul_Fsum if _isFsum_2Tuple(x) else \
|
|
1322
|
+
H._mul_scalar
|
|
1345
1323
|
for c in (reversed(cs) if incx else cs):
|
|
1346
1324
|
H._fset(_m(x, _mul_op_), up=False)
|
|
1347
1325
|
H._fadd(c, up=False)
|
|
@@ -1463,7 +1441,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1463
1441
|
override L{nonfinites<Fsum.nonfinites>} and
|
|
1464
1442
|
L{nonfiniterrors} default (C{bool}).
|
|
1465
1443
|
'''
|
|
1466
|
-
op = self.fma
|
|
1444
|
+
op = typename(self.fma)
|
|
1467
1445
|
_fs = self._ps_other
|
|
1468
1446
|
try:
|
|
1469
1447
|
s, r = self._fprs2
|
|
@@ -1528,7 +1506,8 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1528
1506
|
def _f2mul(self, where, others, f2product=True, **nonfinites_raiser):
|
|
1529
1507
|
'''(INTERNAL) See methods C{fma} and C{f2mul_}.
|
|
1530
1508
|
'''
|
|
1531
|
-
|
|
1509
|
+
n = typename(where)
|
|
1510
|
+
f = _Psum(self._ps, f2product=f2product, name=n)
|
|
1532
1511
|
if others and f:
|
|
1533
1512
|
if f.f2product():
|
|
1534
1513
|
def _pfs(f, ps):
|
|
@@ -1537,7 +1516,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1537
1516
|
def _pfs(f, ps): # PYCHOK redef
|
|
1538
1517
|
return (f * p for p in ps)
|
|
1539
1518
|
|
|
1540
|
-
op, ps =
|
|
1519
|
+
op, ps = n, f._ps
|
|
1541
1520
|
try: # as if self.f2product(True)
|
|
1542
1521
|
for other in others: # to pinpoint errors
|
|
1543
1522
|
for p in self._ps_other(op, other):
|
|
@@ -1776,7 +1755,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1776
1755
|
|
|
1777
1756
|
@return: Copy of this updated instance (L{Fsum}).
|
|
1778
1757
|
'''
|
|
1779
|
-
return self._facc_args(xs).
|
|
1758
|
+
return self._facc_args(xs)._copyd(self.Fsum_, **name)
|
|
1780
1759
|
|
|
1781
1760
|
def Fsum2Tuple_(self, *xs, **name):
|
|
1782
1761
|
'''Like method L{Fsum.fsum_} but returning a named L{Fsum2Tuple}.
|
|
@@ -1789,7 +1768,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1789
1768
|
|
|
1790
1769
|
@property_RO
|
|
1791
1770
|
def _Fsum(self): # like L{Fsum2Tuple._Fsum}, in .fstats
|
|
1792
|
-
return self # NOT @Property_RO, see .copy and .
|
|
1771
|
+
return self # NOT @Property_RO, see .copy and ._copyd
|
|
1793
1772
|
|
|
1794
1773
|
def _Fsum_as(self, *xs, **name_f2product_nonfinites_RESIDUAL):
|
|
1795
1774
|
'''(INTERNAL) Return an C{Fsum} with this C{Fsum}'s C{.f2product},
|
|
@@ -1804,8 +1783,8 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1804
1783
|
kwds.update(name_f2product_nonfinites_RESIDUAL)
|
|
1805
1784
|
f = Fsum(**kwds)
|
|
1806
1785
|
# assert all(v == self.__dict__[n] for n, v in f.__dict__.items())
|
|
1807
|
-
return f.
|
|
1808
|
-
|
|
1786
|
+
return (f._facc(xs, up=False) if len(xs) > 1 else
|
|
1787
|
+
f._fset(xs[0], op=_fset_op_)) if xs else f
|
|
1809
1788
|
|
|
1810
1789
|
def fsum2(self, xs=(), **name):
|
|
1811
1790
|
'''Add an iterable's items, summate and return the
|
|
@@ -1864,7 +1843,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1864
1843
|
'''Like method L{Fsum.Fsum_} iff I{all} C{B{xs}}, each I{known to be}
|
|
1865
1844
|
C{scalar}, an L{Fsum} or L{Fsum2Tuple}.
|
|
1866
1845
|
'''
|
|
1867
|
-
return self._facc_scalarf(xs, which=self.Fsumf_).
|
|
1846
|
+
return self._facc_scalarf(xs, which=self.Fsumf_)._copyd(self.Fsumf_) # origin=1?
|
|
1868
1847
|
|
|
1869
1848
|
def fsum2f_(self, *xs):
|
|
1870
1849
|
'''Like method L{Fsum.fsum2_} iff I{all} C{B{xs}}, each I{known to be}
|
|
@@ -1960,7 +1939,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1960
1939
|
an C{fma} implementation as C{math.fma} or C{None}, a previous
|
|
1961
1940
|
C{PyGeodesy} implementation.
|
|
1962
1941
|
'''
|
|
1963
|
-
return (_2split3s is _passarg) or (False if
|
|
1942
|
+
return (_2split3s is _passarg) or (False if _integer_ratio2 is None else None)
|
|
1964
1943
|
|
|
1965
1944
|
def is_math_fsum(self):
|
|
1966
1945
|
'''Are the summation functions L{fsum}, L{fsum_}, L{fsumf_}, L{fsum1},
|
|
@@ -2148,7 +2127,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
2148
2127
|
@see: Methods L{Fsum.__ipow__}, L{Fsum.fint}, L{Fsum.is_integer}
|
|
2149
2128
|
and L{Fsum.root}.
|
|
2150
2129
|
'''
|
|
2151
|
-
f = self.
|
|
2130
|
+
f = self._copyd(self.pow)
|
|
2152
2131
|
return f._fpow(x, _pow_op_, *mod, **raiser_RESIDUAL) # f = pow(f, x, *mod)
|
|
2153
2132
|
|
|
2154
2133
|
def _pow(self, other, unused, op, **raiser_RESIDUAL):
|
|
@@ -2370,6 +2349,12 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
2370
2349
|
return dict(ratio=q, R=t)
|
|
2371
2350
|
return {}
|
|
2372
2351
|
|
|
2352
|
+
def _rcopyd(self, other, which):
|
|
2353
|
+
'''(INTERNAL) Copy for I{reverse-dyadic} operators.
|
|
2354
|
+
'''
|
|
2355
|
+
return other._copyd(which) if _isFsum(other) else \
|
|
2356
|
+
self._copyd(which)._fset(other)
|
|
2357
|
+
|
|
2373
2358
|
rdiv = __rtruediv__
|
|
2374
2359
|
|
|
2375
2360
|
@property_RO
|
|
@@ -2450,7 +2435,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
2450
2435
|
@see: Method L{Fsum.pow}.
|
|
2451
2436
|
'''
|
|
2452
2437
|
x = self._1_Over(root, _truediv_op_, **raiser_RESIDUAL)
|
|
2453
|
-
f = self.
|
|
2438
|
+
f = self._copyd(self.root)
|
|
2454
2439
|
return f._fpow(x, f.name, **raiser_RESIDUAL) # == pow(f, x)
|
|
2455
2440
|
|
|
2456
2441
|
def _scalar(self, other, op, **txt):
|
|
@@ -2502,7 +2487,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
2502
2487
|
def _truediv(self, other, op, **raiser_RESIDUAL):
|
|
2503
2488
|
'''(INTERNAL) Return C{B{self} / B{other}} as an L{Fsum}.
|
|
2504
2489
|
'''
|
|
2505
|
-
f = self.
|
|
2490
|
+
f = self._copyd(self.__truediv__)
|
|
2506
2491
|
return f._ftruediv(other, op, **raiser_RESIDUAL)
|
|
2507
2492
|
|
|
2508
2493
|
def _update(self, updated=True): # see ._fset
|
|
@@ -2549,8 +2534,8 @@ class Fsum2Tuple(_NamedTuple): # in .fstats
|
|
|
2549
2534
|
@note: If the C{residual is INT0}, the C{fsum} is considered
|
|
2550
2535
|
to be I{exact}, see method L{Fsum2Tuple.is_exact}.
|
|
2551
2536
|
'''
|
|
2552
|
-
_Names_ = ( Fsum.fsum
|
|
2553
|
-
_Units_ = (_Float_Int,
|
|
2537
|
+
_Names_ = ( typename(Fsum.fsum), Fsum.residual.name)
|
|
2538
|
+
_Units_ = (_Float_Int, _Float_Int)
|
|
2554
2539
|
|
|
2555
2540
|
def __abs__(self): # in .fmath
|
|
2556
2541
|
return self._Fsum.__abs__()
|
|
@@ -2642,7 +2627,7 @@ class Fsum2Tuple(_NamedTuple): # in .fstats
|
|
|
2642
2627
|
|
|
2643
2628
|
def _other_op(self, other, which):
|
|
2644
2629
|
C, s = (tuple, self) if isinstance(other, tuple) else (Fsum, self._Fsum)
|
|
2645
|
-
return getattr(C, which
|
|
2630
|
+
return getattr(C, typename(which))(s, other)
|
|
2646
2631
|
|
|
2647
2632
|
@property_RO
|
|
2648
2633
|
def _ps(self):
|
|
@@ -2823,9 +2808,9 @@ def _xsum(which, xs, nonfinites=None, primed=0, **floats): # origin=0
|
|
|
2823
2808
|
# delete all decorators, etc.
|
|
2824
2809
|
del _allPropertiesOf_n, deprecated_method, deprecated_property_RO, \
|
|
2825
2810
|
Property, Property_RO, property_RO, _ALL_LAZY, _F2PRODUCT, \
|
|
2826
|
-
MANT_DIG, _NONFINITES, _RESIDUAL_0_0,
|
|
2811
|
+
MANT_DIG, _NONFINITES, _RESIDUAL_0_0, _envPYGEODESY, _std_
|
|
2827
2812
|
|
|
2828
|
-
if __name__ ==
|
|
2813
|
+
if __name__ == _DMAIN_:
|
|
2829
2814
|
|
|
2830
2815
|
# usage: python3 -m pygeodesy.fsums
|
|
2831
2816
|
|
|
@@ -2833,8 +2818,8 @@ if __name__ == '__main__':
|
|
|
2833
2818
|
# copied from Hettinger, see L{Fsum} reference
|
|
2834
2819
|
from pygeodesy import frandoms, printf
|
|
2835
2820
|
|
|
2836
|
-
printf(_fsum
|
|
2837
|
-
printf(_psum
|
|
2821
|
+
printf(typename(_fsum), end=_COMMASPACE_)
|
|
2822
|
+
printf(typename(_psum), end=_COMMASPACE_)
|
|
2838
2823
|
|
|
2839
2824
|
F = Fsum()
|
|
2840
2825
|
if F.is_math_fsum():
|
pygeodesy/gars.py
CHANGED
|
@@ -14,14 +14,14 @@ Transcoded from I{Charles Karney}'s C++ class U{GARS
|
|
|
14
14
|
(GARS)<https://Earth-Info.NGA.mil/GandG/coordsys/grids/gars.html>}.
|
|
15
15
|
'''
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
from pygeodesy.basics import isstr, _splituple, typename
|
|
18
18
|
from pygeodesy.constants import _off90, _1_over, _0_5, \
|
|
19
19
|
_1_0 # PYCHOK used!
|
|
20
20
|
from pygeodesy.errors import _ValueError, _xkwds, _xStrError
|
|
21
|
-
from pygeodesy.
|
|
22
|
-
|
|
21
|
+
# from pygeodesy.internals import typename # from .basics
|
|
22
|
+
from pygeodesy.interns import NN, _0to9_, _AtoZnoIO_, _INV_
|
|
23
23
|
from pygeodesy.lazily import _ALL_DOCS, _ALL_LAZY
|
|
24
|
-
from pygeodesy.named import _name__, Fmt,
|
|
24
|
+
from pygeodesy.named import _name__, Fmt, Property_RO
|
|
25
25
|
from pygeodesy.namedTuples import LatLon2Tuple, LatLonPrec3Tuple
|
|
26
26
|
# from pygeodesy.props import Property_RO # from .named
|
|
27
27
|
# from pygeodesy.streprs import Fmt # from .named
|
|
@@ -30,7 +30,7 @@ from pygeodesy.units import Int_, Lat, Lon, Precision_, Scalar_, Str
|
|
|
30
30
|
from math import floor
|
|
31
31
|
|
|
32
32
|
__all__ = _ALL_LAZY.gars
|
|
33
|
-
__version__ = '
|
|
33
|
+
__version__ = '25.04.14'
|
|
34
34
|
|
|
35
35
|
_Digits = _0to9_
|
|
36
36
|
_LatLen = 2
|
|
@@ -93,7 +93,7 @@ def _2garstr2(garef):
|
|
|
93
93
|
return garstr, _2Precision(n - _MinLen)
|
|
94
94
|
|
|
95
95
|
except (AttributeError, TypeError, ValueError) as x:
|
|
96
|
-
raise GARSError(Garef
|
|
96
|
+
raise GARSError(typename(Garef), garef, cause=x)
|
|
97
97
|
|
|
98
98
|
|
|
99
99
|
def _2Precision(precision):
|
|
@@ -136,7 +136,7 @@ class Garef(Str):
|
|
|
136
136
|
if isinstance(lat_gll, Garef):
|
|
137
137
|
g, ll, p = str(lat_gll), lat_gll.latlon, lat_gll.precision
|
|
138
138
|
elif isstr(lat_gll):
|
|
139
|
-
ll = lat_gll
|
|
139
|
+
ll = _splituple(lat_gll)
|
|
140
140
|
if len(ll) > 1:
|
|
141
141
|
g, ll, p = _encode3(ll[0], ll[1], precision)
|
|
142
142
|
else:
|