pygeodesy 24.8.24__py2.py3-none-any.whl → 24.9.24__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.8.24.dist-info → PyGeodesy-24.9.24.dist-info}/METADATA +7 -7
- {PyGeodesy-24.8.24.dist-info → PyGeodesy-24.9.24.dist-info}/RECORD +49 -48
- pygeodesy/__init__.py +7 -5
- pygeodesy/__main__.py +46 -47
- pygeodesy/auxilats/_CX_4.py +104 -181
- pygeodesy/auxilats/_CX_6.py +152 -277
- pygeodesy/auxilats/_CX_8.py +211 -438
- pygeodesy/auxilats/_CX_Rs.py +222 -0
- pygeodesy/auxilats/__init__.py +2 -2
- pygeodesy/auxilats/__main__.py +30 -38
- pygeodesy/auxilats/auxLat.py +28 -36
- pygeodesy/auxilats/auxily.py +30 -50
- pygeodesy/basics.py +24 -14
- pygeodesy/booleans.py +13 -14
- pygeodesy/clipy.py +7 -7
- pygeodesy/constants.py +44 -31
- pygeodesy/deprecated/__init__.py +1 -1
- pygeodesy/deprecated/functions.py +9 -1
- pygeodesy/elliptic.py +154 -88
- pygeodesy/errors.py +32 -5
- pygeodesy/etm.py +71 -59
- pygeodesy/fmath.py +125 -96
- pygeodesy/fstats.py +8 -12
- pygeodesy/fsums.py +802 -355
- pygeodesy/geodesici.py +6 -5
- pygeodesy/geodesicx/_C4_24.py +1 -3
- pygeodesy/geodesicx/_C4_27.py +1 -3
- pygeodesy/geodesicx/_C4_30.py +1 -3
- pygeodesy/geodesicx/__init__.py +1 -1
- pygeodesy/geodesicx/__main__.py +44 -46
- pygeodesy/geodesicx/gxarea.py +3 -3
- pygeodesy/geodesicx/gxbases.py +32 -18
- pygeodesy/internals.py +50 -9
- pygeodesy/interns.py +3 -2
- pygeodesy/karney.py +79 -60
- pygeodesy/ktm.py +4 -4
- pygeodesy/lazily.py +10 -5
- pygeodesy/mgrs.py +47 -42
- pygeodesy/named.py +4 -1
- pygeodesy/points.py +3 -3
- pygeodesy/props.py +7 -6
- pygeodesy/resections.py +2 -2
- pygeodesy/rhumb/__init__.py +1 -1
- pygeodesy/rhumb/aux_.py +42 -60
- pygeodesy/sphericalNvector.py +4 -4
- pygeodesy/sphericalTrigonometry.py +2 -2
- pygeodesy/triaxials.py +3 -3
- {PyGeodesy-24.8.24.dist-info → PyGeodesy-24.9.24.dist-info}/WHEEL +0 -0
- {PyGeodesy-24.8.24.dist-info → PyGeodesy-24.9.24.dist-info}/top_level.txt +0 -0
pygeodesy/fmath.py
CHANGED
|
@@ -10,11 +10,11 @@ from pygeodesy.basics import _copysign, copysign0, isbool, isint, isscalar, \
|
|
|
10
10
|
len2, map1, _xiterable
|
|
11
11
|
from pygeodesy.constants import EPS0, EPS02, EPS1, NAN, PI, PI_2, PI_4, \
|
|
12
12
|
_0_0, _0_125, _1_6th, _0_25, _1_3rd, _0_5, _1_0, \
|
|
13
|
-
_N_1_0, _1_5, _copysign_0_0,
|
|
13
|
+
_N_1_0, _1_5, _copysign_0_0, isfinite, remainder
|
|
14
14
|
from pygeodesy.errors import _IsnotError, LenError, _TypeError, _ValueError, \
|
|
15
15
|
_xError, _xkwds_get1, _xkwds_pop2
|
|
16
|
-
from pygeodesy.fsums import _2float, Fsum, fsum, fsum1_, _isFsumTuple,
|
|
17
|
-
|
|
16
|
+
from pygeodesy.fsums import _2float, Fsum, fsum, fsum1_, _isFsumTuple, \
|
|
17
|
+
_1primed, _Psum_, Fmt, unstr
|
|
18
18
|
from pygeodesy.interns import MISSING, _negative_, _not_scalar_
|
|
19
19
|
from pygeodesy.lazily import _ALL_LAZY, _sys_version_info2
|
|
20
20
|
# from pygeodesy.streprs import Fmt, unstr # from .fsums
|
|
@@ -24,10 +24,10 @@ from math import fabs, sqrt # pow
|
|
|
24
24
|
import operator as _operator # in .datums, .trf, .utm
|
|
25
25
|
|
|
26
26
|
__all__ = _ALL_LAZY.fmath
|
|
27
|
-
__version__ = '24.
|
|
27
|
+
__version__ = '24.09.19'
|
|
28
28
|
|
|
29
|
-
# sqrt(2) <https://WikiPedia.org/wiki/Square_root_of_2>
|
|
30
|
-
_0_4142 = 0.41421356237309504880 # ...
|
|
29
|
+
# sqrt(2) - 1 <https://WikiPedia.org/wiki/Square_root_of_2>
|
|
30
|
+
_0_4142 = 0.41421356237309504880 # ... ~ 3730904090310553 / 9007199254740992
|
|
31
31
|
_2_3rd = _1_3rd * 2
|
|
32
32
|
_h_lt_b_ = 'abs(h) < abs(b)'
|
|
33
33
|
|
|
@@ -36,13 +36,10 @@ class Fdot(Fsum):
|
|
|
36
36
|
'''Precision dot product.
|
|
37
37
|
'''
|
|
38
38
|
def __init__(self, a, *b, **name_RESIDUAL):
|
|
39
|
-
'''New L{Fdot} precision dot product M{sum(a[i] * b[i] for
|
|
40
|
-
i=0..len(a)-1)}.
|
|
39
|
+
'''New L{Fdot} precision dot product M{sum(a[i] * b[i] for i=0..len(a)-1)}.
|
|
41
40
|
|
|
42
|
-
@arg a: Iterable of values (each C{scalar}
|
|
43
|
-
|
|
44
|
-
@arg b: Other values (each C{scalar} or an L{Fsum} or L{Fsum2Tuple} instance),
|
|
45
|
-
all positional.
|
|
41
|
+
@arg a: Iterable of values (each C{scalar}, an L{Fsum} or L{Fsum2Tuple}).
|
|
42
|
+
@arg b: Other values (each C{scalar}, an L{Fsum} or L{Fsum2Tuple}), all positional.
|
|
46
43
|
@kwarg name_RESIDUAL: Optional C{B{name}=NN} (C{str}) and the C{B{RESIDUAL}=0.0}
|
|
47
44
|
threshold (C{scalar}) for raising L{ResidualError}s, see class
|
|
48
45
|
L{Fsum<Fsum.__init__>}.
|
|
@@ -64,14 +61,16 @@ class Fdot(Fsum):
|
|
|
64
61
|
class Fhorner(Fsum):
|
|
65
62
|
'''Precision polynomial evaluation using the Horner form.
|
|
66
63
|
'''
|
|
67
|
-
def __init__(self, x, *cs, **
|
|
68
|
-
'''New L{Fhorner} evaluation of polynomial M{sum(cs[i] * x**i for
|
|
69
|
-
i=0
|
|
64
|
+
def __init__(self, x, *cs, **incx_name_RESIDUAL):
|
|
65
|
+
'''New L{Fhorner} evaluation of polynomial M{sum(cs[i] * x**i for i=0..n)} if
|
|
66
|
+
C{B{incx}=False} for decreasing exponent M{sum(... i=n..0)} where C{n =
|
|
67
|
+
len(cs) - 1}.
|
|
70
68
|
|
|
71
|
-
@arg x: Polynomial argument (C{scalar}
|
|
72
|
-
@arg cs: Polynomial coeffients (each C{scalar}
|
|
73
|
-
|
|
74
|
-
@kwarg
|
|
69
|
+
@arg x: Polynomial argument (C{scalar}, an L{Fsum} or L{Fsum2Tuple}).
|
|
70
|
+
@arg cs: Polynomial coeffients (each C{scalar}, an L{Fsum} or L{Fsum2Tuple}),
|
|
71
|
+
all positional.
|
|
72
|
+
@kwarg incx_name_RESIDUAL: Optional C{B{name}=NN} (C{str}), C{B{incx}=True}
|
|
73
|
+
for in-/decreasing exponents (C{bool}) and the C{B{RESIDUAL}=0.0}
|
|
75
74
|
threshold (C{scalar}) for raising L{ResidualError}s, see class
|
|
76
75
|
L{Fsum<Fsum.__init__>}.
|
|
77
76
|
|
|
@@ -83,9 +82,10 @@ class Fhorner(Fsum):
|
|
|
83
82
|
|
|
84
83
|
@see: Function L{fhorner} and methods L{Fsum.fadd} and L{Fsum.fmul}.
|
|
85
84
|
'''
|
|
85
|
+
incx, name_RESIDUAL = _xkwds_pop2(incx_name_RESIDUAL, incx=True)
|
|
86
86
|
Fsum.__init__(self, **name_RESIDUAL)
|
|
87
87
|
if cs:
|
|
88
|
-
self._fhorner(x, cs, Fhorner.__name__)
|
|
88
|
+
self._fhorner(x, cs, Fhorner.__name__, incx=incx)
|
|
89
89
|
else:
|
|
90
90
|
self._fset_ps(_0_0)
|
|
91
91
|
|
|
@@ -94,11 +94,11 @@ class Fhypot(Fsum):
|
|
|
94
94
|
'''Precision summation and hypotenuse, default C{root=2}.
|
|
95
95
|
'''
|
|
96
96
|
def __init__(self, *xs, **root_name_RESIDUAL_raiser):
|
|
97
|
-
'''New L{Fhypot} hypotenuse of (the I{root} of) several components
|
|
98
|
-
|
|
97
|
+
'''New L{Fhypot} hypotenuse of (the I{root} of) several components (raised
|
|
98
|
+
to the power I{root}).
|
|
99
99
|
|
|
100
|
-
@arg xs: Components (each C{scalar}
|
|
101
|
-
|
|
100
|
+
@arg xs: Components (each C{scalar}, an L{Fsum} or L{Fsum2Tuple}), all
|
|
101
|
+
positional.
|
|
102
102
|
@kwarg root_name_RESIDUAL_raiser: Optional, exponent and C{B{root}=2} order
|
|
103
103
|
(C{scalar}), C{B{name}=NN} (C{str}), the C{B{RESIDUAL}=0.0}
|
|
104
104
|
threshold (C{scalar}) and C{B{raiser}=True} (C{bool}) for
|
|
@@ -121,12 +121,12 @@ class Fpolynomial(Fsum):
|
|
|
121
121
|
'''Precision polynomial evaluation.
|
|
122
122
|
'''
|
|
123
123
|
def __init__(self, x, *cs, **name_RESIDUAL):
|
|
124
|
-
'''New L{Fpolynomial} evaluation of the polynomial
|
|
125
|
-
|
|
124
|
+
'''New L{Fpolynomial} evaluation of the polynomial M{sum(cs[i] * x**i for
|
|
125
|
+
i=0..len(cs)-1)}.
|
|
126
126
|
|
|
127
|
-
@arg x: Polynomial argument (C{scalar}
|
|
128
|
-
@arg cs: Polynomial coeffients (each C{scalar}
|
|
129
|
-
|
|
127
|
+
@arg x: Polynomial argument (C{scalar}, an L{Fsum} or L{Fsum2Tuple}).
|
|
128
|
+
@arg cs: Polynomial coeffients (each C{scalar}, an L{Fsum} or L{Fsum2Tuple}),
|
|
129
|
+
all positional.
|
|
130
130
|
@kwarg name_RESIDUAL: Optional C{B{name}=NN} (C{str}) and the C{B{RESIDUAL}=0.0}
|
|
131
131
|
threshold (C{scalar}) for raising L{ResidualError}s, see class
|
|
132
132
|
L{Fsum<Fsum.__init__>}.
|
|
@@ -153,9 +153,9 @@ class Fpowers(Fsum):
|
|
|
153
153
|
def __init__(self, power, *xs, **name_RESIDUAL_raiser):
|
|
154
154
|
'''New L{Fpowers} sum of (the I{power} of) several bases.
|
|
155
155
|
|
|
156
|
-
@arg power: The exponent (C{scalar}
|
|
157
|
-
@arg xs: One or more bases (each C{scalar}
|
|
158
|
-
|
|
156
|
+
@arg power: The exponent (C{scalar}, an L{Fsum} or L{Fsum2Tuple}).
|
|
157
|
+
@arg xs: One or more bases (each C{scalar}, an L{Fsum} or L{Fsum2Tuple}), all
|
|
158
|
+
positional.
|
|
159
159
|
@kwarg name_RESIDUAL_raiser: Optional C{B{name}=NN} (C{str}), the C{B{RESIDUAL}=0.0}
|
|
160
160
|
threshold (C{scalar}) and C{B{raiser}=True} (C{bool}) for raising
|
|
161
161
|
L{ResidualError}s, see class L{Fsum<Fsum.__init__>} and method
|
|
@@ -175,9 +175,9 @@ class Froot(Fsum):
|
|
|
175
175
|
def __init__(self, root, *xs, **name_RESIDUAL_raiser):
|
|
176
176
|
'''New L{Froot} root of a precision sum.
|
|
177
177
|
|
|
178
|
-
@arg root: The order (C{scalar}
|
|
179
|
-
@arg xs: Items to summate (each a C{scalar}
|
|
180
|
-
|
|
178
|
+
@arg root: The order (C{scalar}, an L{Fsum} or L{Fsum2Tuple}), non-zero.
|
|
179
|
+
@arg xs: Items to summate (each a C{scalar}, an L{Fsum} or L{Fsum2Tuple}), all
|
|
180
|
+
positional.
|
|
181
181
|
@kwarg name_RESIDUAL_raiser: Optional C{B{name}=NN} (C{str}), the C{B{RESIDUAL}=0.0}
|
|
182
182
|
threshold (C{scalar}) and C{B{raiser}=True} (C{bool}) for raising
|
|
183
183
|
L{ResidualError}s, see class L{Fsum<Fsum.__init__>} and method
|
|
@@ -226,7 +226,7 @@ def bqrt(x):
|
|
|
226
226
|
'''Return the 4-th, I{bi-quadratic} or I{quartic} root, M{x**(1 / 4)},
|
|
227
227
|
preserving C{type(B{x})}.
|
|
228
228
|
|
|
229
|
-
@arg x: Value (C{scalar}
|
|
229
|
+
@arg x: Value (C{scalar}, an L{Fsum} or L{Fsum2Tuple}).
|
|
230
230
|
|
|
231
231
|
@return: I{Quartic} root (C{float} or an L{Fsum}).
|
|
232
232
|
|
|
@@ -256,7 +256,7 @@ except ImportError: # Python 3.10-
|
|
|
256
256
|
def cbrt(x):
|
|
257
257
|
'''Compute the cube root M{x**(1/3)}, preserving C{type(B{x})}.
|
|
258
258
|
|
|
259
|
-
@arg x: Value (C{scalar}
|
|
259
|
+
@arg x: Value (C{scalar}, an L{Fsum} or L{Fsum2Tuple}).
|
|
260
260
|
|
|
261
261
|
@return: Cubic root (C{float} or L{Fsum}).
|
|
262
262
|
|
|
@@ -274,7 +274,7 @@ def cbrt(x):
|
|
|
274
274
|
def cbrt2(x): # PYCHOK attr
|
|
275
275
|
'''Compute the cube root I{squared} M{x**(2/3)}, preserving C{type(B{x})}.
|
|
276
276
|
|
|
277
|
-
@arg x: Value (C{scalar}
|
|
277
|
+
@arg x: Value (C{scalar}, an L{Fsum} or L{Fsum2Tuple}).
|
|
278
278
|
|
|
279
279
|
@return: Cube root I{squared} (C{float} or L{Fsum}).
|
|
280
280
|
|
|
@@ -284,11 +284,11 @@ def cbrt2(x): # PYCHOK attr
|
|
|
284
284
|
|
|
285
285
|
|
|
286
286
|
def euclid(x, y):
|
|
287
|
-
'''I{Appoximate} the norm M{sqrt(x**2 + y**2)} by
|
|
288
|
-
|
|
287
|
+
'''I{Appoximate} the norm M{sqrt(x**2 + y**2)} by M{max(abs(x),
|
|
288
|
+
abs(y)) + min(abs(x), abs(y)) * 0.4142...}.
|
|
289
289
|
|
|
290
|
-
@arg x: X component (C{scalar}
|
|
291
|
-
@arg y: Y component (C{scalar}
|
|
290
|
+
@arg x: X component (C{scalar}, an L{Fsum} or L{Fsum2Tuple}).
|
|
291
|
+
@arg y: Y component (C{scalar}, an L{Fsum} or L{Fsum2Tuple}).
|
|
292
292
|
|
|
293
293
|
@return: Appoximate norm (C{float} or L{Fsum}).
|
|
294
294
|
|
|
@@ -301,11 +301,11 @@ def euclid(x, y):
|
|
|
301
301
|
|
|
302
302
|
|
|
303
303
|
def euclid_(*xs):
|
|
304
|
-
'''I{Appoximate} the norm M{sqrt(sum(x**2 for x in xs))} by
|
|
305
|
-
|
|
304
|
+
'''I{Appoximate} the norm M{sqrt(sum(x**2 for x in xs))} by cascaded
|
|
305
|
+
L{euclid}.
|
|
306
306
|
|
|
307
|
-
@arg xs: X arguments (each C{scalar}
|
|
308
|
-
|
|
307
|
+
@arg xs: X arguments (each C{scalar}, an L{Fsum} or L{Fsum2Tuple}),
|
|
308
|
+
all positional.
|
|
309
309
|
|
|
310
310
|
@return: Appoximate norm (C{float} or L{Fsum}).
|
|
311
311
|
|
|
@@ -404,10 +404,10 @@ def fatan2(y, x):
|
|
|
404
404
|
|
|
405
405
|
|
|
406
406
|
def favg(a, b, f=_0_5):
|
|
407
|
-
'''Return the
|
|
407
|
+
'''Return the precise average of two values.
|
|
408
408
|
|
|
409
|
-
@arg a: One (C{scalar}
|
|
410
|
-
@arg b: Other (C{scalar}
|
|
409
|
+
@arg a: One (C{scalar}, an L{Fsum} or L{Fsum2Tuple}).
|
|
410
|
+
@arg b: Other (C{scalar}, an L{Fsum} or L{Fsum2Tuple}).
|
|
411
411
|
@kwarg f: Optional fraction (C{float}).
|
|
412
412
|
|
|
413
413
|
@return: M{a + f * (b - a)} (C{float}).
|
|
@@ -421,39 +421,35 @@ def favg(a, b, f=_0_5):
|
|
|
421
421
|
|
|
422
422
|
|
|
423
423
|
def fdot(a, *b):
|
|
424
|
-
'''Return the precision dot product M{sum(a[i] * b[i] for
|
|
425
|
-
i=0..len(a))}.
|
|
424
|
+
'''Return the precision dot product M{sum(a[i] * b[i] for ni=0..len(a))}.
|
|
426
425
|
|
|
427
|
-
@arg a: Iterable of values (each C{scalar}).
|
|
428
|
-
@arg b: Other values (each C{scalar}), all
|
|
426
|
+
@arg a: Iterable of values (each C{scalar}, an L{Fsum} or L{Fsum2Tuple}).
|
|
427
|
+
@arg b: Other values (each C{scalar}, an L{Fsum} or L{Fsum2Tuple}), all
|
|
428
|
+
positional.
|
|
429
429
|
|
|
430
430
|
@return: Dot product (C{float}).
|
|
431
431
|
|
|
432
432
|
@raise LenError: Unequal C{len(B{a})} and C{len(B{b})}.
|
|
433
433
|
|
|
434
|
-
@see: Class L{Fdot}
|
|
435
|
-
<https://www.TUHH.De/ti3/paper/rump/OgRuOi05.pdf>}
|
|
434
|
+
@see: Class L{Fdot}, U{Algorithm 5.10 B{DotK}
|
|
435
|
+
<https://www.TUHH.De/ti3/paper/rump/OgRuOi05.pdf>} and function
|
|
436
|
+
C{math.sumprod} in Python 3.12 and later.
|
|
436
437
|
'''
|
|
437
438
|
return fsum(_map_mul(a, b, fdot))
|
|
438
439
|
|
|
439
440
|
|
|
440
441
|
def fdot3(xs, ys, zs, start=0):
|
|
441
|
-
'''Return the precision dot product M{start +
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
@arg xs: Iterable (each C{scalar}
|
|
445
|
-
|
|
446
|
-
@arg
|
|
447
|
-
|
|
448
|
-
@arg zs: Iterable (each C{scalar} or an L{Fsum} or
|
|
449
|
-
L{Fsum2Tuple} instance).
|
|
450
|
-
@kwarg start: Optional bias (C{scalar} or an L{Fsum}
|
|
451
|
-
or L{Fsum2Tuple}).
|
|
442
|
+
'''Return the precision dot product M{start + sum(a[i] * b[i] * c[i]
|
|
443
|
+
for i=0..len(a)-1)}.
|
|
444
|
+
|
|
445
|
+
@arg xs: Iterable (each C{scalar}, an L{Fsum} or L{Fsum2Tuple}).
|
|
446
|
+
@arg ys: Iterable (each C{scalar}, an L{Fsum} or L{Fsum2Tuple}).
|
|
447
|
+
@arg zs: Iterable (each C{scalar}, an L{Fsum} or L{Fsum2Tuple}).
|
|
448
|
+
@kwarg start: Optional bias (C{scalar}, an L{Fsum} or L{Fsum2Tuple}).
|
|
452
449
|
|
|
453
450
|
@return: Dot product (C{float}).
|
|
454
451
|
|
|
455
|
-
@raise LenError: Unequal C{len(B{xs})}, C{len(B{ys})}
|
|
456
|
-
and/or C{len(B{zs})}.
|
|
452
|
+
@raise LenError: Unequal C{len(B{xs})}, C{len(B{ys})} and/or C{len(B{zs})}.
|
|
457
453
|
|
|
458
454
|
@raise OverflowError: Partial C{2sum} overflow.
|
|
459
455
|
'''
|
|
@@ -462,9 +458,8 @@ def fdot3(xs, ys, zs, start=0):
|
|
|
462
458
|
yield s
|
|
463
459
|
if p:
|
|
464
460
|
yield _1_0
|
|
465
|
-
_F = Fsum
|
|
466
461
|
for x, y, z in zip(xs, ys, zs):
|
|
467
|
-
yield (
|
|
462
|
+
yield (Fsum(x) * y) * z
|
|
468
463
|
if p:
|
|
469
464
|
yield _N_1_0
|
|
470
465
|
|
|
@@ -475,15 +470,16 @@ def fdot3(xs, ys, zs, start=0):
|
|
|
475
470
|
return fsum(_mul3(xs, ys, zs, start, n < 4))
|
|
476
471
|
|
|
477
472
|
|
|
478
|
-
def fhorner(x, *cs):
|
|
479
|
-
'''Evaluate
|
|
480
|
-
i=0..
|
|
473
|
+
def fhorner(x, *cs, **incx):
|
|
474
|
+
'''Evaluate a polynomial using the Horner form M{sum(cs[i] * x**i
|
|
475
|
+
for i=0..n)} or if C{B{incx}=False} for decreasing exponent
|
|
476
|
+
M{sum(... i=n..0)} where C{n = len(cs) - 1}.
|
|
481
477
|
|
|
482
478
|
@return: Horner sum (C{float}).
|
|
483
479
|
|
|
484
480
|
@see: Class L{Fhorner} for further details.
|
|
485
481
|
'''
|
|
486
|
-
H = Fhorner(x, *cs)
|
|
482
|
+
H = Fhorner(x, *cs, **incx)
|
|
487
483
|
return float(H)
|
|
488
484
|
|
|
489
485
|
|
|
@@ -491,10 +487,9 @@ def fidw(xs, ds, beta=2):
|
|
|
491
487
|
'''Interpolate using U{Inverse Distance Weighting
|
|
492
488
|
<https://WikiPedia.org/wiki/Inverse_distance_weighting>} (IDW).
|
|
493
489
|
|
|
494
|
-
@arg xs: Known values (each C{scalar}
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
or L{Fsum2Tuple} instance).
|
|
490
|
+
@arg xs: Known values (each C{scalar}, an L{Fsum} or L{Fsum2Tuple}).
|
|
491
|
+
@arg ds: Non-negative distances (each C{scalar}, an L{Fsum} or
|
|
492
|
+
L{Fsum2Tuple}).
|
|
498
493
|
@kwarg beta: Inverse distance power (C{int}, 0, 1, 2, or 3).
|
|
499
494
|
|
|
500
495
|
@return: Interpolated value C{x} (C{float}).
|
|
@@ -550,10 +545,26 @@ def fidw(xs, ds, beta=2):
|
|
|
550
545
|
return x
|
|
551
546
|
|
|
552
547
|
|
|
548
|
+
def fma(x, y, z, **raiser):
|
|
549
|
+
'''Fused-multiply-add, using C{math.fma(x, y, z)} from Python 3.13+
|
|
550
|
+
or an equivalent implementation.
|
|
551
|
+
|
|
552
|
+
@arg x: Multiplicand (C{scalar}, an L{Fsum} or L{Fsum2Tuple}).
|
|
553
|
+
@arg y: Multiplier (C{scalar}, an L{Fsum} or L{Fsum2Tuple}).
|
|
554
|
+
@arg z: Addend (C{scalar}, an L{Fsum} or L{Fsum2Tuple}).
|
|
555
|
+
@kwarg raiser: Keyword argument C{B{raiser}=False}, if C{True},
|
|
556
|
+
throw an exception, otherwise pass any non-finite
|
|
557
|
+
result (C{bool}).
|
|
558
|
+
|
|
559
|
+
@return: C{(x * y) + z} (L{Fsum} or C{float}).
|
|
560
|
+
'''
|
|
561
|
+
return _Psum_(x).fma(y, z, raiser=raiser).as_iscalar
|
|
562
|
+
|
|
563
|
+
|
|
553
564
|
def fmean(xs):
|
|
554
565
|
'''Compute the accurate mean M{sum(xs) / len(xs)}.
|
|
555
566
|
|
|
556
|
-
@arg xs: Values (C{scalar} or L{Fsum}
|
|
567
|
+
@arg xs: Values (each C{scalar}, or L{Fsum} or L{Fsum2Tuple}).
|
|
557
568
|
|
|
558
569
|
@return: Mean value (C{float}).
|
|
559
570
|
|
|
@@ -575,9 +586,25 @@ def fmean_(*xs):
|
|
|
575
586
|
return fmean(xs)
|
|
576
587
|
|
|
577
588
|
|
|
589
|
+
def f2mul_(x, *ys, **raiser):
|
|
590
|
+
'''Cascaded, accurate multiplication C{B{x} * B{y} * B{y} ...} for all B{C{ys}}.
|
|
591
|
+
|
|
592
|
+
@arg x: Multiplicand (C{scalar}, an L{Fsum} or L{Fsum2Tuple}).
|
|
593
|
+
@arg ys: Multipliers (each C{scalar}, an L{Fsum} or L{Fsum2Tuple}), all
|
|
594
|
+
positional.
|
|
595
|
+
@kwarg raiser: Keyword argument C{B{raiser}=False}, if C{True}, throw an
|
|
596
|
+
exception, otherwise pass any non-finite result (C{bool}).
|
|
597
|
+
|
|
598
|
+
@return: The cascaded I{TwoProduct} (L{Fsum}, C{float} or C{int}).
|
|
599
|
+
|
|
600
|
+
@see: U{Equations 2.3<https://www.TUHH.De/ti3/paper/rump/OzOgRuOi06.pdf>}
|
|
601
|
+
'''
|
|
602
|
+
return _Psum_(x).f2mul_(*ys, **raiser).as_iscalar
|
|
603
|
+
|
|
604
|
+
|
|
578
605
|
def fpolynomial(x, *cs, **over):
|
|
579
|
-
'''Evaluate the polynomial M{sum(cs[i] * x**i for
|
|
580
|
-
|
|
606
|
+
'''Evaluate the polynomial M{sum(cs[i] * x**i for i=0..len(cs))
|
|
607
|
+
[/ over]}.
|
|
581
608
|
|
|
582
609
|
@kwarg over: Optional final, I{non-zero} divisor (C{scalar}).
|
|
583
610
|
|
|
@@ -593,7 +620,7 @@ def fpolynomial(x, *cs, **over):
|
|
|
593
620
|
def fpowers(x, n, alts=0):
|
|
594
621
|
'''Return a series of powers M{[x**i for i=1..n]}.
|
|
595
622
|
|
|
596
|
-
@arg x: Value (C{scalar}
|
|
623
|
+
@arg x: Value (C{scalar}, an L{Fsum} or L{Fsum2Tuple}).
|
|
597
624
|
@arg n: Highest exponent (C{int}).
|
|
598
625
|
@kwarg alts: Only alternating powers, starting with this
|
|
599
626
|
exponent (C{int}).
|
|
@@ -609,7 +636,7 @@ def fpowers(x, n, alts=0):
|
|
|
609
636
|
elif n < 1:
|
|
610
637
|
raise _ValueError(n=n)
|
|
611
638
|
|
|
612
|
-
p = x if
|
|
639
|
+
p = x if isscalar(x) or _isFsumTuple(x) else _2float(x=x)
|
|
613
640
|
ps = tuple(_powers(p, n))
|
|
614
641
|
|
|
615
642
|
if alts > 0: # x**2, x**4, ...
|
|
@@ -627,7 +654,7 @@ except ImportError:
|
|
|
627
654
|
'''Iterable product, like C{math.prod} or C{numpy.prod}.
|
|
628
655
|
|
|
629
656
|
@arg xs: Iterable of values to be multiplied (each
|
|
630
|
-
C{scalar}
|
|
657
|
+
C{scalar}, an L{Fsum} or L{Fsum2Tuple}).
|
|
631
658
|
@kwarg start: Initial value, also the value returned
|
|
632
659
|
for an empty B{C{xs}} (C{scalar}).
|
|
633
660
|
|
|
@@ -746,7 +773,7 @@ def fremainder(x, y):
|
|
|
746
773
|
# On Windows 32-bit with python 2.7, math.fmod(-0.0, 360)
|
|
747
774
|
# == +0.0. This fixes this bug. See also Math::AngNormalize
|
|
748
775
|
# in the C++ library, Math.sincosd has a similar fix.
|
|
749
|
-
if
|
|
776
|
+
if isfinite(x):
|
|
750
777
|
try:
|
|
751
778
|
r = remainder(x, y) if x else x
|
|
752
779
|
except Exception as e:
|
|
@@ -822,8 +849,8 @@ def hypot1(x):
|
|
|
822
849
|
def hypot2(x, y):
|
|
823
850
|
'''Compute the I{squared} norm M{x**2 + y**2}.
|
|
824
851
|
|
|
825
|
-
@arg x: X (C{scalar}
|
|
826
|
-
@arg y: Y (C{scalar}
|
|
852
|
+
@arg x: X (C{scalar}, an L{Fsum} or L{Fsum2Tuple}).
|
|
853
|
+
@arg y: Y (C{scalar}, an L{Fsum} or L{Fsum2Tuple}).
|
|
827
854
|
|
|
828
855
|
@return: C{B{x}**2 + B{y}**2} (C{float}).
|
|
829
856
|
'''
|
|
@@ -843,8 +870,8 @@ def hypot2(x, y):
|
|
|
843
870
|
def hypot2_(*xs):
|
|
844
871
|
'''Compute the I{squared} norm C{fsum(x**2 for x in B{xs})}.
|
|
845
872
|
|
|
846
|
-
@arg xs: Components (each C{scalar}
|
|
847
|
-
L{Fsum2Tuple}
|
|
873
|
+
@arg xs: Components (each C{scalar}, an L{Fsum} or
|
|
874
|
+
L{Fsum2Tuple}), all positional.
|
|
848
875
|
|
|
849
876
|
@return: Squared norm (C{float}).
|
|
850
877
|
|
|
@@ -899,9 +926,10 @@ def norm2(x, y):
|
|
|
899
926
|
|
|
900
927
|
|
|
901
928
|
def norm_(*xs):
|
|
902
|
-
'''Normalize
|
|
929
|
+
'''Normalize the components of an n-dimensional vector.
|
|
903
930
|
|
|
904
|
-
@arg xs: Components (C{scalar}
|
|
931
|
+
@arg xs: Components (each C{scalar}, an L{Fsum} or
|
|
932
|
+
L{Fsum2Tuple}), all positional.
|
|
905
933
|
|
|
906
934
|
@return: Yield each component, normalized.
|
|
907
935
|
|
|
@@ -944,7 +972,7 @@ def sqrt0(x, Error=None):
|
|
|
944
972
|
'''Return the square root C{sqrt(B{x})} iff C{B{x} > }L{EPS02},
|
|
945
973
|
preserving C{type(B{x})}.
|
|
946
974
|
|
|
947
|
-
@arg x: Value (C{scalar}
|
|
975
|
+
@arg x: Value (C{scalar}, an L{Fsum} or L{Fsum2Tuple}).
|
|
948
976
|
@kwarg Error: Error to raise for negative B{C{x}}.
|
|
949
977
|
|
|
950
978
|
@return: Square root (C{float} or L{Fsum}) or C{0.0}.
|
|
@@ -956,14 +984,15 @@ def sqrt0(x, Error=None):
|
|
|
956
984
|
'''
|
|
957
985
|
if Error and x < 0:
|
|
958
986
|
raise Error(unstr(sqrt0, x))
|
|
959
|
-
return _root(x, _0_5, sqrt0) if x > EPS02 else (
|
|
987
|
+
return _root(x, _0_5, sqrt0) if x > EPS02 else (
|
|
988
|
+
_0_0 if x < EPS02 else EPS0)
|
|
960
989
|
|
|
961
990
|
|
|
962
991
|
def sqrt3(x):
|
|
963
992
|
'''Return the square root, I{cubed} M{sqrt(x)**3} or M{sqrt(x**3)},
|
|
964
993
|
preserving C{type(B{x})}.
|
|
965
994
|
|
|
966
|
-
@arg x: Value (C{scalar}
|
|
995
|
+
@arg x: Value (C{scalar}, an L{Fsum} or L{Fsum2Tuple}).
|
|
967
996
|
|
|
968
997
|
@return: Square root I{cubed} (C{float} or L{Fsum}).
|
|
969
998
|
|
|
@@ -1019,7 +1048,7 @@ def zcrt(x):
|
|
|
1019
1048
|
'''Return the 6-th, I{zenzi-cubic} root, M{x**(1 / 6)},
|
|
1020
1049
|
preserving C{type(B{x})}.
|
|
1021
1050
|
|
|
1022
|
-
@arg x: Value (C{scalar}
|
|
1051
|
+
@arg x: Value (C{scalar}, an L{Fsum} or L{Fsum2Tuple}).
|
|
1023
1052
|
|
|
1024
1053
|
@return: I{Zenzi-cubic} root (C{float} or L{Fsum}).
|
|
1025
1054
|
|
|
@@ -1036,7 +1065,7 @@ def zqrt(x):
|
|
|
1036
1065
|
'''Return the 8-th, I{zenzi-quartic} or I{squared-quartic} root,
|
|
1037
1066
|
M{x**(1 / 8)}, preserving C{type(B{x})}.
|
|
1038
1067
|
|
|
1039
|
-
@arg x: Value (C{scalar}
|
|
1068
|
+
@arg x: Value (C{scalar}, an L{Fsum} or L{Fsum2Tuple}).
|
|
1040
1069
|
|
|
1041
1070
|
@return: I{Zenzi-quartic} root (C{float} or L{Fsum}).
|
|
1042
1071
|
|
pygeodesy/fstats.py
CHANGED
|
@@ -10,9 +10,10 @@ from __future__ import division as _; del _ # PYCHOK semicolon
|
|
|
10
10
|
from pygeodesy.basics import isscalar, isodd, _xinstanceof, \
|
|
11
11
|
_xiterable, _xsubclassof, _zip
|
|
12
12
|
from pygeodesy.constants import _0_0, _1_0, _2_0, _3_0, _4_0, _6_0
|
|
13
|
-
from pygeodesy.errors import
|
|
13
|
+
from pygeodesy.errors import _ValueError, _xError, _xkwds_item2
|
|
14
14
|
from pygeodesy.fmath import Fsqrt, Fmt
|
|
15
|
-
from pygeodesy.fsums import _2finite, Fsum, _iadd_op_,
|
|
15
|
+
from pygeodesy.fsums import _2finite, Fsum, _iadd_op_, \
|
|
16
|
+
_isFsumTuple, _xsError
|
|
16
17
|
from pygeodesy.interns import _odd_, _SPACE_
|
|
17
18
|
from pygeodesy.lazily import _ALL_DOCS, _ALL_LAZY
|
|
18
19
|
from pygeodesy.named import _name__, _Named, _NotImplemented, \
|
|
@@ -21,24 +22,19 @@ from pygeodesy.named import _name__, _Named, _NotImplemented, \
|
|
|
21
22
|
# from pygeodesy.streprs import Fmt # from .fmath
|
|
22
23
|
|
|
23
24
|
__all__ = _ALL_LAZY.fstats
|
|
24
|
-
__version__ = '24.
|
|
25
|
+
__version__ = '24.09.23'
|
|
25
26
|
|
|
26
27
|
|
|
27
28
|
def _2Floats(**xs):
|
|
28
|
-
'''(INTERNAL) Yield
|
|
29
|
+
'''(INTERNAL) Yield all C{xs} as C{float} or L{Fsum}.
|
|
29
30
|
'''
|
|
31
|
+
name, xs = _xkwds_item2(xs)
|
|
30
32
|
try:
|
|
31
|
-
|
|
32
|
-
except Exception as X:
|
|
33
|
-
raise _AssertionError(xs=xs, cause=X)
|
|
34
|
-
|
|
35
|
-
try:
|
|
36
|
-
i = None
|
|
33
|
+
i, x = None, xs
|
|
37
34
|
for i, x in enumerate(_xiterable(xs)): # don't unravel Fsums
|
|
38
35
|
yield x._Fsum if _isFsumTuple(x) else _2finite(x)
|
|
39
36
|
except Exception as X:
|
|
40
|
-
raise
|
|
41
|
-
_xError(X, Fmt.INDEX(name, i), x)
|
|
37
|
+
raise _xsError(X, xs, i, x, name)
|
|
42
38
|
|
|
43
39
|
|
|
44
40
|
def _sampled(n, sample):
|