pygeodesy 24.5.2__py2.py3-none-any.whl → 24.5.8__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.2.dist-info → PyGeodesy-24.5.8.dist-info}/METADATA +4 -4
- {PyGeodesy-24.5.2.dist-info → PyGeodesy-24.5.8.dist-info}/RECORD +17 -17
- pygeodesy/__init__.py +3 -3
- pygeodesy/basics.py +12 -3
- pygeodesy/ecef.py +12 -13
- pygeodesy/errors.py +2 -3
- pygeodesy/fmath.py +201 -178
- pygeodesy/fstats.py +292 -227
- pygeodesy/fsums.py +312 -239
- pygeodesy/interns.py +9 -6
- pygeodesy/named.py +18 -6
- pygeodesy/props.py +8 -7
- pygeodesy/streprs.py +16 -7
- pygeodesy/vector2d.py +2 -2
- pygeodesy/vector3d.py +2 -2
- {PyGeodesy-24.5.2.dist-info → PyGeodesy-24.5.8.dist-info}/WHEEL +0 -0
- {PyGeodesy-24.5.2.dist-info → PyGeodesy-24.5.8.dist-info}/top_level.txt +0 -0
pygeodesy/fmath.py
CHANGED
|
@@ -6,14 +6,16 @@ u'''Utilities using precision floating point summation.
|
|
|
6
6
|
# make sure int/int division yields float quotient, see .basics
|
|
7
7
|
from __future__ import division as _; del _ # PYCHOK semicolon
|
|
8
8
|
|
|
9
|
-
from pygeodesy.basics import _copysign, copysign0, isbool, isint, isscalar,
|
|
9
|
+
from pygeodesy.basics import _copysign, copysign0, isbool, isint, isscalar, \
|
|
10
|
+
len2, map1
|
|
10
11
|
from pygeodesy.constants import EPS0, EPS02, EPS1, NAN, PI, PI_2, PI_4, \
|
|
11
12
|
_0_0, _0_125, _1_6th, _0_25, _1_3rd, _0_5, _1_0, \
|
|
12
|
-
_1_5, _copysign_0_0, _isfinite,
|
|
13
|
+
_N_1_0, _1_5, _copysign_0_0, _isfinite, remainder
|
|
13
14
|
from pygeodesy.errors import _IsnotError, LenError, _TypeError, _ValueError, \
|
|
14
15
|
_xError, _xkwds_get, _xkwds_pop2
|
|
15
|
-
from pygeodesy.fsums import _2float, Fsum, fsum, fsum1_, _1primed,
|
|
16
|
-
|
|
16
|
+
from pygeodesy.fsums import _2float, Fsum, fsum, fsum1_, _isFsumTuple, _1primed, \
|
|
17
|
+
Fmt, unstr
|
|
18
|
+
from pygeodesy.interns import MISSING, _negative_, _not_scalar_
|
|
17
19
|
from pygeodesy.lazily import _ALL_LAZY, _sys_version_info2
|
|
18
20
|
# from pygeodesy.streprs import Fmt, unstr # from .fsums
|
|
19
21
|
from pygeodesy.units import Int_, _isHeight, _isRadius, Float_ # PYCHOK for .heights
|
|
@@ -22,7 +24,7 @@ from math import fabs, sqrt # pow
|
|
|
22
24
|
import operator as _operator # in .datums, .trf, .utm
|
|
23
25
|
|
|
24
26
|
__all__ = _ALL_LAZY.fmath
|
|
25
|
-
__version__ = '24.
|
|
27
|
+
__version__ = '24.05.07'
|
|
26
28
|
|
|
27
29
|
# sqrt(2) <https://WikiPedia.org/wiki/Square_root_of_2>
|
|
28
30
|
_0_4142 = 0.41421356237309504880 # ... sqrt(2) - 1
|
|
@@ -34,17 +36,23 @@ class Fdot(Fsum):
|
|
|
34
36
|
'''Precision dot product.
|
|
35
37
|
'''
|
|
36
38
|
def __init__(self, a, *b, **name_RESIDUAL):
|
|
37
|
-
'''New L{Fdot} precision dot product M{sum(a[i] * b[i]
|
|
38
|
-
|
|
39
|
+
'''New L{Fdot} precision dot product M{sum(a[i] * b[i] for
|
|
40
|
+
i=0..len(a)-1)}.
|
|
39
41
|
|
|
40
|
-
@arg a: Iterable
|
|
41
|
-
|
|
42
|
-
@
|
|
43
|
-
|
|
42
|
+
@arg a: Iterable of values (each C{scalar} or an L{Fsum} or
|
|
43
|
+
L{Fsum2Tuple} instance).
|
|
44
|
+
@arg b: Other values (each C{scalar} or an L{Fsum} or L{Fsum2Tuple}
|
|
45
|
+
instance), all positional.
|
|
46
|
+
@kwarg name_RESIDUAL: Optional C{B{name}=NN} and C{B{RESIDUAL}=0.0}
|
|
47
|
+
threshold, see L{Fsum<Fsum.__init__>}.
|
|
48
|
+
|
|
49
|
+
@raise LenError: Unequal C{len(B{a})} and C{len(B{b})}.
|
|
44
50
|
|
|
45
51
|
@raise OverflowError: Partial C{2sum} overflow.
|
|
46
52
|
|
|
47
|
-
@raise
|
|
53
|
+
@raise TypeError: Invalid B{C{x}}.
|
|
54
|
+
|
|
55
|
+
@raise ValueError: Non-finite B{C{x}}.
|
|
48
56
|
|
|
49
57
|
@see: Function L{fdot} and method L{Fsum.fadd}.
|
|
50
58
|
'''
|
|
@@ -56,27 +64,26 @@ class Fhorner(Fsum):
|
|
|
56
64
|
'''Precision polynomial evaluation using the Horner form.
|
|
57
65
|
'''
|
|
58
66
|
def __init__(self, x, *cs, **name_RESIDUAL):
|
|
59
|
-
'''New L{Fhorner} evaluation of polynomial M{sum(cs[i] * x**i
|
|
60
|
-
|
|
67
|
+
'''New L{Fhorner} evaluation of polynomial M{sum(cs[i] * x**i for
|
|
68
|
+
i=0..len(cs)-1)}.
|
|
61
69
|
|
|
62
|
-
@arg x: Polynomial argument (C{scalar} or
|
|
63
|
-
@arg cs: Polynomial coeffients (C{scalar} or
|
|
64
|
-
|
|
65
|
-
@kwarg name_RESIDUAL: Optional C{B{name}=NN} and C{B{RESIDUAL}=
|
|
66
|
-
see L{Fsum<Fsum.__init__>}.
|
|
70
|
+
@arg x: Polynomial argument (C{scalar} or an L{Fsum} or L{Fsum2Tuple}).
|
|
71
|
+
@arg cs: Polynomial coeffients (each C{scalar} or an L{Fsum} or
|
|
72
|
+
L{Fsum2Tuple} instance), all positional.
|
|
73
|
+
@kwarg name_RESIDUAL: Optional C{B{name}=NN} and C{B{RESIDUAL}=0.0}
|
|
74
|
+
threshold, see L{Fsum<Fsum.__init__>}.
|
|
67
75
|
|
|
68
76
|
@raise OverflowError: Partial C{2sum} overflow.
|
|
69
77
|
|
|
70
|
-
@raise TypeError:
|
|
78
|
+
@raise TypeError: Invalid B{C{x}}.
|
|
71
79
|
|
|
72
80
|
@raise ValueError: Non-finite B{C{x}}.
|
|
73
81
|
|
|
74
|
-
@see: Function L{fhorner} and methods L{Fsum.fadd} and
|
|
75
|
-
L{Fsum.fmul}.
|
|
82
|
+
@see: Function L{fhorner} and methods L{Fsum.fadd} and L{Fsum.fmul}.
|
|
76
83
|
'''
|
|
77
84
|
Fsum.__init__(self, **name_RESIDUAL)
|
|
78
85
|
if cs:
|
|
79
|
-
if
|
|
86
|
+
if _isFsumTuple(x):
|
|
80
87
|
_mul = self._mul_Fsum
|
|
81
88
|
else:
|
|
82
89
|
_mul = self._mul_scalar
|
|
@@ -97,12 +104,15 @@ class Fhypot(Fsum):
|
|
|
97
104
|
'''Precision summation and hypotenuse, default C{root=2}.
|
|
98
105
|
'''
|
|
99
106
|
def __init__(self, *xs, **root_name_RESIDUAL_raiser):
|
|
100
|
-
'''New L{Fhypot} hypotenuse of (the I{root} of) several components
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
@
|
|
104
|
-
|
|
105
|
-
|
|
107
|
+
'''New L{Fhypot} hypotenuse of (the I{root} of) several components
|
|
108
|
+
(raised to the power I{root}).
|
|
109
|
+
|
|
110
|
+
@arg xs: Components (each C{scalar} or an L{Fsum} or L{Fsum2Tuple}
|
|
111
|
+
instance), all positional.
|
|
112
|
+
@kwarg root_name_RESIDUAL_raiser: Optional, exponent and C{B{root}=2}
|
|
113
|
+
order, C{B{name}=NN}, C{B{RESIDUAL}=0.0} threshold and
|
|
114
|
+
C{B{raiser}=True}, see class L{Fsum<Fsum.__init__>} and
|
|
115
|
+
method L{root<Fsum.root>}.
|
|
106
116
|
'''
|
|
107
117
|
r = None # _xkwds_pop2 error
|
|
108
118
|
try:
|
|
@@ -123,20 +133,19 @@ class Fpolynomial(Fsum):
|
|
|
123
133
|
'''New L{Fpolynomial} evaluation of the polynomial
|
|
124
134
|
M{sum(cs[i] * x**i for i=0..len(cs)-1)}.
|
|
125
135
|
|
|
126
|
-
@arg x: Polynomial argument (C{scalar} or L{Fsum}).
|
|
127
|
-
@arg cs: Polynomial coeffients (each
|
|
128
|
-
all positional.
|
|
129
|
-
@kwarg name_RESIDUAL: Optional C{B{name}=NN} and C{B{RESIDUAL}=
|
|
130
|
-
see L{Fsum<Fsum.__init__>}.
|
|
136
|
+
@arg x: Polynomial argument (C{scalar} or an L{Fsum} or L{Fsum2Tuple}).
|
|
137
|
+
@arg cs: Polynomial coeffients (each C{scalar} or an L{Fsum} or
|
|
138
|
+
L{Fsum2Tuple} instance), all positional.
|
|
139
|
+
@kwarg name_RESIDUAL: Optional C{B{name}=NN} and C{B{RESIDUAL}=0.0}
|
|
140
|
+
threshold, see L{Fsum<Fsum.__init__>}.
|
|
131
141
|
|
|
132
142
|
@raise OverflowError: Partial C{2sum} overflow.
|
|
133
143
|
|
|
134
|
-
@raise TypeError:
|
|
144
|
+
@raise TypeError: Invalid B{C{x}}.
|
|
135
145
|
|
|
136
146
|
@raise ValueError: Non-finite B{C{x}}.
|
|
137
147
|
|
|
138
|
-
@see: Class L{Fhorner}, function L{fpolynomial} and
|
|
139
|
-
method L{Fsum.fadd}.
|
|
148
|
+
@see: Class L{Fhorner}, function L{fpolynomial} and method L{Fsum.fadd}.
|
|
140
149
|
'''
|
|
141
150
|
Fsum.__init__(self, *cs[:1], **name_RESIDUAL)
|
|
142
151
|
n = len(cs) - 1
|
|
@@ -150,12 +159,14 @@ class Fpowers(Fsum):
|
|
|
150
159
|
'''Precision summation of powers, optimized for C{power=2, 3 and 4}.
|
|
151
160
|
'''
|
|
152
161
|
def __init__(self, power, *xs, **name_RESIDUAL_raiser):
|
|
153
|
-
'''New L{Fpowers} sum of (the I{power} of) several
|
|
154
|
-
|
|
155
|
-
@arg power: The exponent (C{scalar} or L{Fsum}).
|
|
156
|
-
@arg xs: One or more
|
|
157
|
-
|
|
158
|
-
|
|
162
|
+
'''New L{Fpowers} sum of (the I{power} of) several bases.
|
|
163
|
+
|
|
164
|
+
@arg power: The exponent (C{scalar} or an L{Fsum} or L{Fsum2Tuple}).
|
|
165
|
+
@arg xs: One or more bases (each C{scalar} or an L{Fsum} or L{Fsum2Tuple}
|
|
166
|
+
instance), all positional.
|
|
167
|
+
@kwarg name_RESIDUAL_raiser: Optional C{B{name}=NN}, C{B{RESIDUAL}=0.0}
|
|
168
|
+
threshold and C{B{raiser}=True}, see L{Fsum<Fsum.__init__>}
|
|
169
|
+
and L{fpow<Fsum.fpow>}.
|
|
159
170
|
'''
|
|
160
171
|
try:
|
|
161
172
|
raiser = _Fsum__init__(self, **name_RESIDUAL_raiser)
|
|
@@ -171,10 +182,12 @@ class Froot(Fsum):
|
|
|
171
182
|
def __init__(self, root, *xs, **name_RESIDUAL_raiser):
|
|
172
183
|
'''New L{Froot} root of a precision sum.
|
|
173
184
|
|
|
174
|
-
@arg root: The order (C{scalar} or
|
|
175
|
-
@arg xs:
|
|
176
|
-
|
|
177
|
-
|
|
185
|
+
@arg root: The order (C{scalar} or an L{Fsum} or L{Fsum2Tuple}), non-zero.
|
|
186
|
+
@arg xs: Items to summate (each a C{scalar} or an L{Fsum} or L{Fsum2Tuple}
|
|
187
|
+
instance), all positional.
|
|
188
|
+
@kwarg name_RESIDUAL_raiser: Optional C{B{name}=NN}, C{B{RESIDUAL}=0.0}
|
|
189
|
+
threshold and C{B{raiser}=True}, see L{Fsum<Fsum.__init__>}
|
|
190
|
+
and L{fpow<Fsum.fpow>}.
|
|
178
191
|
'''
|
|
179
192
|
try:
|
|
180
193
|
raiser = _Fsum__init__(self, **name_RESIDUAL_raiser)
|
|
@@ -219,9 +232,11 @@ def bqrt(x):
|
|
|
219
232
|
'''Return the 4-th, I{bi-quadratic} or I{quartic} root, M{x**(1 / 4)},
|
|
220
233
|
preserving C{type(B{x})}.
|
|
221
234
|
|
|
222
|
-
@arg x: Value (C{scalar} or L{Fsum}
|
|
235
|
+
@arg x: Value (C{scalar} or an L{Fsum} or L{Fsum2Tuple}).
|
|
236
|
+
|
|
237
|
+
@return: I{Quartic} root (C{float} or an L{Fsum}).
|
|
223
238
|
|
|
224
|
-
@
|
|
239
|
+
@raise TypeeError: Invalid B{C{x}}.
|
|
225
240
|
|
|
226
241
|
@raise ValueError: Negative B{C{x}}.
|
|
227
242
|
|
|
@@ -247,14 +262,16 @@ except ImportError: # Python 3.10-
|
|
|
247
262
|
def cbrt(x):
|
|
248
263
|
'''Compute the cube root M{x**(1/3)}, preserving C{type(B{x})}.
|
|
249
264
|
|
|
250
|
-
@arg x: Value (C{scalar} or L{Fsum}
|
|
265
|
+
@arg x: Value (C{scalar} or an L{Fsum} or L{Fsum2Tuple}).
|
|
251
266
|
|
|
252
267
|
@return: Cubic root (C{float} or L{Fsum}).
|
|
253
268
|
|
|
254
269
|
@see: Functions L{cbrt2} and L{sqrt3}.
|
|
255
270
|
'''
|
|
256
|
-
if
|
|
257
|
-
r = (
|
|
271
|
+
if _isFsumTuple(x):
|
|
272
|
+
r = abs(x).fpow(_1_3rd)
|
|
273
|
+
if x.signOf() < 0:
|
|
274
|
+
r = -r
|
|
258
275
|
else:
|
|
259
276
|
r = _cbrt(x)
|
|
260
277
|
return r # cbrt(-0.0) == -0.0
|
|
@@ -263,13 +280,13 @@ def cbrt(x):
|
|
|
263
280
|
def cbrt2(x): # PYCHOK attr
|
|
264
281
|
'''Compute the cube root I{squared} M{x**(2/3)}, preserving C{type(B{x})}.
|
|
265
282
|
|
|
266
|
-
@arg x: Value (C{scalar} or L{Fsum}
|
|
283
|
+
@arg x: Value (C{scalar} or an L{Fsum} or L{Fsum2Tuple}).
|
|
267
284
|
|
|
268
285
|
@return: Cube root I{squared} (C{float} or L{Fsum}).
|
|
269
286
|
|
|
270
287
|
@see: Functions L{cbrt} and L{sqrt3}.
|
|
271
288
|
'''
|
|
272
|
-
return abs(x).
|
|
289
|
+
return abs(x).fpow(_2_3rd) if _isFsumTuple(x) else _cbrt(x**2)
|
|
273
290
|
|
|
274
291
|
|
|
275
292
|
def euclid(x, y):
|
|
@@ -284,7 +301,7 @@ def euclid(x, y):
|
|
|
284
301
|
@see: Function L{euclid_}.
|
|
285
302
|
'''
|
|
286
303
|
x, y = abs(x), abs(y) # NOT fabs!
|
|
287
|
-
if
|
|
304
|
+
if y > x:
|
|
288
305
|
x, y = y, x
|
|
289
306
|
return x + y * _0_4142 # XXX * _0_5 before 20.10.02
|
|
290
307
|
|
|
@@ -293,7 +310,8 @@ def euclid_(*xs):
|
|
|
293
310
|
'''I{Appoximate} the norm M{sqrt(sum(x**2 for x in xs))} by
|
|
294
311
|
cascaded L{euclid}.
|
|
295
312
|
|
|
296
|
-
@arg xs: X arguments
|
|
313
|
+
@arg xs: X arguments (each C{scalar} or an L{Fsum}
|
|
314
|
+
instance), all positional.
|
|
297
315
|
|
|
298
316
|
@return: Appoximate norm (C{float} or L{Fsum}).
|
|
299
317
|
|
|
@@ -390,29 +408,29 @@ def fatan2(y, x):
|
|
|
390
408
|
return r
|
|
391
409
|
|
|
392
410
|
|
|
393
|
-
def favg(
|
|
394
|
-
'''Return the average of two values.
|
|
411
|
+
def favg(a, b, f=_0_5):
|
|
412
|
+
'''Return the precision average of two values.
|
|
395
413
|
|
|
396
|
-
@arg
|
|
397
|
-
@arg
|
|
414
|
+
@arg a: One (C{scalar} or an L{Fsum} or L{Fsum2Tuple}).
|
|
415
|
+
@arg b: Other (C{scalar} or an L{Fsum} or L{Fsum2Tuple}).
|
|
398
416
|
@kwarg f: Optional fraction (C{float}).
|
|
399
417
|
|
|
400
|
-
@return: M{
|
|
418
|
+
@return: M{a + f * (b - a)} (C{float}).
|
|
401
419
|
'''
|
|
402
420
|
# @raise ValueError: Fraction out of range.
|
|
403
421
|
# '''
|
|
404
422
|
# if not 0 <= f <= 1: # XXX restrict fraction?
|
|
405
423
|
# raise _ValueError(fraction=f)
|
|
406
|
-
#
|
|
407
|
-
return fsum1_(
|
|
424
|
+
# a + f * (b - a) == a * (1 - f) + b * f
|
|
425
|
+
return fsum1_(a, a * (-f), b * f)
|
|
408
426
|
|
|
409
427
|
|
|
410
428
|
def fdot(a, *b):
|
|
411
429
|
'''Return the precision dot product M{sum(a[i] * b[i] for
|
|
412
430
|
i=0..len(a))}.
|
|
413
431
|
|
|
414
|
-
@arg a: Iterable
|
|
415
|
-
@arg b:
|
|
432
|
+
@arg a: Iterable of values (each C{scalar}).
|
|
433
|
+
@arg b: Other values (each C{scalar}), all positional.
|
|
416
434
|
|
|
417
435
|
@return: Dot product (C{float}).
|
|
418
436
|
|
|
@@ -424,52 +442,51 @@ def fdot(a, *b):
|
|
|
424
442
|
return fsum(_map_mul(a, b, fdot))
|
|
425
443
|
|
|
426
444
|
|
|
427
|
-
def fdot3(
|
|
445
|
+
def fdot3(xs, ys, zs, start=0):
|
|
428
446
|
'''Return the precision dot product M{start +
|
|
429
447
|
sum(a[i] * b[i] * c[i] for i=0..len(a)-1)}.
|
|
430
448
|
|
|
431
|
-
@arg
|
|
432
|
-
|
|
433
|
-
@arg
|
|
434
|
-
|
|
449
|
+
@arg xs: Iterable (each C{scalar} or an L{Fsum} or
|
|
450
|
+
L{Fsum2Tuple} instance).
|
|
451
|
+
@arg ys: Iterable (each C{scalar} or an L{Fsum} or
|
|
452
|
+
L{Fsum2Tuple} instance).
|
|
453
|
+
@arg zs: Iterable (each C{scalar} or an L{Fsum} or
|
|
454
|
+
L{Fsum2Tuple} instance).
|
|
455
|
+
@kwarg start: Optional bias (C{scalar} or an L{Fsum}
|
|
456
|
+
or L{Fsum2Tuple}).
|
|
435
457
|
|
|
436
458
|
@return: Dot product (C{float}).
|
|
437
459
|
|
|
438
|
-
@raise LenError: Unequal C{len(B{
|
|
439
|
-
and/or C{len(B{
|
|
460
|
+
@raise LenError: Unequal C{len(B{xs})}, C{len(B{ys})}
|
|
461
|
+
and/or C{len(B{zs})}.
|
|
440
462
|
|
|
441
463
|
@raise OverflowError: Partial C{2sum} overflow.
|
|
442
464
|
'''
|
|
443
|
-
def _mul3(
|
|
444
|
-
|
|
465
|
+
def _mul3(xs, ys, zs, s, p):
|
|
466
|
+
if s:
|
|
467
|
+
yield s
|
|
468
|
+
if p:
|
|
469
|
+
yield _1_0
|
|
470
|
+
_F = Fsum
|
|
471
|
+
for x, y, z in zip(xs, ys, zs):
|
|
472
|
+
yield (_F(x) * y) * z
|
|
473
|
+
if p:
|
|
474
|
+
yield _N_1_0
|
|
445
475
|
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
yield abc
|
|
476
|
+
n = len(xs)
|
|
477
|
+
if not n == len(ys) == len(zs):
|
|
478
|
+
raise LenError(fdot3, xs=n, ys=len(ys), zs=len(zs))
|
|
450
479
|
|
|
451
|
-
|
|
452
|
-
raise LenError(fdot3, a=len(a), b=len(b), c=len(c))
|
|
453
|
-
|
|
454
|
-
return fsum(_mul3_(a, b, c, start) if start else map(_mul3, a, b, c))
|
|
480
|
+
return fsum(_mul3(xs, ys, zs, start, n < 4))
|
|
455
481
|
|
|
456
482
|
|
|
457
483
|
def fhorner(x, *cs):
|
|
458
484
|
'''Evaluate the polynomial M{sum(cs[i] * x**i for
|
|
459
485
|
i=0..len(cs)-1)} using the Horner form.
|
|
460
486
|
|
|
461
|
-
@
|
|
462
|
-
@arg cs: Polynomial coeffients (C{scalar}s).
|
|
463
|
-
|
|
464
|
-
@return: Horner value (C{float}).
|
|
487
|
+
@return: Horner sum (C{float}).
|
|
465
488
|
|
|
466
|
-
@
|
|
467
|
-
|
|
468
|
-
@raise TypeError: Non-scalar B{C{x}}.
|
|
469
|
-
|
|
470
|
-
@raise ValueError: No B{C{cs}} coefficients or B{C{x}} is not finite.
|
|
471
|
-
|
|
472
|
-
@see: Function L{fpolynomial} and class L{Fhorner}.
|
|
489
|
+
@see: Class L{Fhorner} for further details.
|
|
473
490
|
'''
|
|
474
491
|
H = Fhorner(x, *cs)
|
|
475
492
|
return float(H)
|
|
@@ -479,36 +496,61 @@ def fidw(xs, ds, beta=2):
|
|
|
479
496
|
'''Interpolate using U{Inverse Distance Weighting
|
|
480
497
|
<https://WikiPedia.org/wiki/Inverse_distance_weighting>} (IDW).
|
|
481
498
|
|
|
482
|
-
@arg xs: Known values (C{scalar}
|
|
483
|
-
|
|
499
|
+
@arg xs: Known values (each C{scalar} or an L{Fsum} or
|
|
500
|
+
L{Fsum2Tuple} instance).
|
|
501
|
+
@arg ds: Non-negative distances (each C{scalar} or an L{Fsum}
|
|
502
|
+
or L{Fsum2Tuple} instance).
|
|
484
503
|
@kwarg beta: Inverse distance power (C{int}, 0, 1, 2, or 3).
|
|
485
504
|
|
|
486
505
|
@return: Interpolated value C{x} (C{float}).
|
|
487
506
|
|
|
488
507
|
@raise LenError: Unequal or zero C{len(B{ds})} and C{len(B{xs})}.
|
|
489
508
|
|
|
490
|
-
@raise
|
|
509
|
+
@raise TypeError: An invalid B{C{ds}} or B{C{xs}}.
|
|
510
|
+
|
|
511
|
+
@raise ValueError: Invalid B{C{beta}}, negative B{C{ds}} or
|
|
491
512
|
weighted B{C{ds}} below L{EPS}.
|
|
492
513
|
|
|
493
514
|
@note: Using C{B{beta}=0} returns the mean of B{C{xs}}.
|
|
494
515
|
'''
|
|
495
516
|
n, xs = len2(xs)
|
|
496
|
-
|
|
497
|
-
if n != d or n < 1:
|
|
498
|
-
raise LenError(fidw, xs=n, ds=d)
|
|
499
|
-
|
|
500
|
-
d, x = min(zip(ds, xs))
|
|
501
|
-
if d > EPS0 and n > 1:
|
|
517
|
+
if n > 1:
|
|
502
518
|
b = -Int_(beta=beta, low=0, high=3)
|
|
503
519
|
if b < 0:
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
520
|
+
try: # weighted
|
|
521
|
+
_F = Fsum
|
|
522
|
+
W = _F()
|
|
523
|
+
X = _F()
|
|
524
|
+
for i, d in enumerate(ds):
|
|
525
|
+
x = xs[i]
|
|
526
|
+
if d < EPS0:
|
|
527
|
+
if d < 0:
|
|
528
|
+
raise ValueError(_negative_)
|
|
529
|
+
x = float(x)
|
|
530
|
+
i = n
|
|
531
|
+
break
|
|
532
|
+
D = _F(d).fpow(b)
|
|
533
|
+
W += D
|
|
534
|
+
X += D.fmul(x)
|
|
535
|
+
else:
|
|
536
|
+
x = X.fover(W, raiser=False)
|
|
537
|
+
i += 1 # len(xs) >= len(ds)
|
|
538
|
+
except IndexError:
|
|
539
|
+
i += 1 # len(xs) < i < len(ds)
|
|
540
|
+
except Exception as X:
|
|
541
|
+
_I = Fmt.INDEX
|
|
542
|
+
raise _xError(X, _I(xs=i), x, _I(ds=i), d)
|
|
507
543
|
else: # b == 0
|
|
508
544
|
x = fsum(xs) / n # fmean(xs)
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
545
|
+
i = n
|
|
546
|
+
elif n:
|
|
547
|
+
x = float(xs[0])
|
|
548
|
+
i = n
|
|
549
|
+
else:
|
|
550
|
+
x = _0_0
|
|
551
|
+
i, _ = len2(ds)
|
|
552
|
+
if i != n:
|
|
553
|
+
raise LenError(fidw, xs=n, ds=i)
|
|
512
554
|
return x
|
|
513
555
|
|
|
514
556
|
|
|
@@ -541,21 +583,11 @@ def fpolynomial(x, *cs, **over):
|
|
|
541
583
|
'''Evaluate the polynomial M{sum(cs[i] * x**i for
|
|
542
584
|
i=0..len(cs)) [/ over]}.
|
|
543
585
|
|
|
544
|
-
@
|
|
545
|
-
@arg cs: Polynomial coeffients (C{scalar}s), all
|
|
546
|
-
positional.
|
|
547
|
-
@kwarg over: Optional final, I{non-zero} divisor
|
|
548
|
-
(C{scalar}).
|
|
586
|
+
@kwarg over: Optional final, I{non-zero} divisor (C{scalar}).
|
|
549
587
|
|
|
550
588
|
@return: Polynomial value (C{float}).
|
|
551
589
|
|
|
552
|
-
@
|
|
553
|
-
|
|
554
|
-
@raise TypeError: Non-scalar B{C{x}}.
|
|
555
|
-
|
|
556
|
-
@raise ValueError: No B{C{cs}} coefficients or B{C{x}} is not finite.
|
|
557
|
-
|
|
558
|
-
@see: Function L{fhorner} and class L{Fpolynomial}.
|
|
590
|
+
@see: Class L{Fpolynomial} for further details.
|
|
559
591
|
'''
|
|
560
592
|
P = Fpolynomial(x, *cs)
|
|
561
593
|
d = _xkwds_get(over, over=0) if over else 0
|
|
@@ -565,12 +597,12 @@ def fpolynomial(x, *cs, **over):
|
|
|
565
597
|
def fpowers(x, n, alts=0):
|
|
566
598
|
'''Return a series of powers M{[x**i for i=1..n]}.
|
|
567
599
|
|
|
568
|
-
@arg x: Value (C{scalar} or L{Fsum}).
|
|
600
|
+
@arg x: Value (C{scalar} or an L{Fsum} or L{Fsum2Tuple}).
|
|
569
601
|
@arg n: Highest exponent (C{int}).
|
|
570
602
|
@kwarg alts: Only alternating powers, starting with this
|
|
571
603
|
exponent (C{int}).
|
|
572
604
|
|
|
573
|
-
@return: Tuple of powers of B{C{x}} (C{type(B{x})}).
|
|
605
|
+
@return: Tuple of powers of B{C{x}} (each C{type(B{x})}).
|
|
574
606
|
|
|
575
607
|
@raise TypeError: Invalid B{C{x}} or B{C{n}} not C{int}.
|
|
576
608
|
|
|
@@ -581,7 +613,7 @@ def fpowers(x, n, alts=0):
|
|
|
581
613
|
elif n < 1:
|
|
582
614
|
raise _ValueError(n=n)
|
|
583
615
|
|
|
584
|
-
p = x if isint(x) or
|
|
616
|
+
p = x if isint(x) or _isFsumTuple(x) else _2float(x=x)
|
|
585
617
|
ps = tuple(_powers(p, n))
|
|
586
618
|
|
|
587
619
|
if alts > 0: # x**2, x**4, ...
|
|
@@ -753,8 +785,7 @@ if _sys_version_info2 < (3, 8): # PYCHOK no cover
|
|
|
753
785
|
computed as M{hypot_(*((c1 - c2) for c1, c2 in zip(p1, p2)))},
|
|
754
786
|
provided I{p1} and I{p2} have the same, non-zero length I{n}.
|
|
755
787
|
'''
|
|
756
|
-
|
|
757
|
-
return float(R)
|
|
788
|
+
return float(Fhypot(*xs, raiser=False))
|
|
758
789
|
|
|
759
790
|
elif _sys_version_info2 < (3, 10):
|
|
760
791
|
# In Python 3.8 and 3.9 C{math.hypot} is inaccurate, see
|
|
@@ -770,8 +801,7 @@ elif _sys_version_info2 < (3, 10):
|
|
|
770
801
|
|
|
771
802
|
@return: C{sqrt(B{x}**2 + B{y}**2)} (C{float}).
|
|
772
803
|
'''
|
|
773
|
-
return
|
|
774
|
-
fabs(x)) if x else fabs(y)
|
|
804
|
+
return float(Fhypot(x, y, raiser=False))
|
|
775
805
|
|
|
776
806
|
from math import hypot as hypot_ # PYCHOK in Python 3.8 and 3.9
|
|
777
807
|
else:
|
|
@@ -779,52 +809,36 @@ else:
|
|
|
779
809
|
hypot_ = hypot
|
|
780
810
|
|
|
781
811
|
|
|
782
|
-
def _h_xs2(xs, pot_, which):
|
|
783
|
-
'''(INTERNAL) Helper for L{hypot_} and L{hypot2_}.
|
|
784
|
-
'''
|
|
785
|
-
n, xs = len2(xs)
|
|
786
|
-
if n > 0:
|
|
787
|
-
h = float(max(map(abs, xs))) # NOT fabs!
|
|
788
|
-
if h < EPS0:
|
|
789
|
-
R = _0_0
|
|
790
|
-
elif n > 1:
|
|
791
|
-
if pot_:
|
|
792
|
-
if h != _1_0:
|
|
793
|
-
xs = ((x / h) for x in xs)
|
|
794
|
-
R = Fhypot(*xs, raiser=False) * h
|
|
795
|
-
else:
|
|
796
|
-
R = Fpowers(2, *xs)
|
|
797
|
-
else:
|
|
798
|
-
R = h if pot_ else (h**2)
|
|
799
|
-
return h, R
|
|
800
|
-
|
|
801
|
-
raise _ValueError(unstr(which, xs), txt=_too_(_few_))
|
|
802
|
-
|
|
803
|
-
|
|
804
812
|
def hypot1(x):
|
|
805
813
|
'''Compute the norm M{sqrt(1 + x**2)}.
|
|
806
814
|
|
|
807
|
-
@arg x: Argument (C{scalar} or L{Fsum}
|
|
815
|
+
@arg x: Argument (C{scalar} or L{Fsum} or L{Fsum2Tuple}).
|
|
808
816
|
|
|
809
817
|
@return: Norm (C{float}).
|
|
810
818
|
'''
|
|
811
|
-
|
|
819
|
+
if _isFsumTuple(x):
|
|
820
|
+
h = float(Fhypot(_1_0, x)) if x else _1_0
|
|
821
|
+
else:
|
|
822
|
+
h = hypot(_1_0, x) if x else _1_0
|
|
823
|
+
return h
|
|
812
824
|
|
|
813
825
|
|
|
814
826
|
def hypot2(x, y):
|
|
815
827
|
'''Compute the I{squared} norm M{x**2 + y**2}.
|
|
816
828
|
|
|
817
|
-
@arg x: X
|
|
818
|
-
@arg y: Y
|
|
829
|
+
@arg x: X (C{scalar} or L{Fsum} or L{Fsum2Tuple}).
|
|
830
|
+
@arg y: Y (C{scalar} or L{Fsum} or L{Fsum2Tuple}).
|
|
819
831
|
|
|
820
|
-
@return: C{B{x}**2 + B{y}**2} (C{float}
|
|
832
|
+
@return: C{B{x}**2 + B{y}**2} (C{float}).
|
|
821
833
|
'''
|
|
822
|
-
|
|
834
|
+
x, y = map1(abs, x, y) # NOT fabs!
|
|
835
|
+
if y > x:
|
|
823
836
|
x, y = y, x
|
|
824
837
|
if x:
|
|
825
838
|
h2 = x**2
|
|
826
839
|
if y:
|
|
827
840
|
h2 *= (y / x)**2 + _1_0
|
|
841
|
+
h2 = float(h2)
|
|
828
842
|
else:
|
|
829
843
|
h2 = _0_0
|
|
830
844
|
return h2
|
|
@@ -833,34 +847,35 @@ def hypot2(x, y):
|
|
|
833
847
|
def hypot2_(*xs):
|
|
834
848
|
'''Compute the I{squared} norm C{fsum(x**2 for x in B{xs})}.
|
|
835
849
|
|
|
836
|
-
@arg xs:
|
|
837
|
-
all positional.
|
|
850
|
+
@arg xs: Components (each C{scalar} or an L{Fsum} or
|
|
851
|
+
L{Fsum2Tuple} instance), all positional.
|
|
838
852
|
|
|
839
853
|
@return: Squared norm (C{float}).
|
|
840
854
|
|
|
841
|
-
@
|
|
842
|
-
|
|
843
|
-
@raise ValueError: Invalid or no B{C{xs}} value.
|
|
844
|
-
|
|
845
|
-
@see: Function L{hypot_}.
|
|
855
|
+
@see: Class L{Fpowers} for further details.
|
|
846
856
|
'''
|
|
847
|
-
|
|
848
|
-
|
|
857
|
+
h2 = float(max(map(abs, xs))) if xs else _0_0
|
|
858
|
+
if h2:
|
|
859
|
+
_h = _1_0 / h2
|
|
860
|
+
h2 = Fpowers(2, *((x * _h) for x in xs))
|
|
861
|
+
h2 = h2.fover(_h**2)
|
|
862
|
+
return h2
|
|
849
863
|
|
|
850
864
|
|
|
851
|
-
def _map_mul(
|
|
852
|
-
'''(INTERNAL) Yield each B{C{
|
|
865
|
+
def _map_mul(xs, ys, where):
|
|
866
|
+
'''(INTERNAL) Yield each B{C{x * y}}.
|
|
853
867
|
'''
|
|
854
|
-
n = len(
|
|
855
|
-
if len(
|
|
856
|
-
raise LenError(where,
|
|
857
|
-
return _1map_mul(
|
|
868
|
+
n = len(ys)
|
|
869
|
+
if len(xs) != n: # PYCHOK no cover
|
|
870
|
+
raise LenError(where, xs=len(xs), ys=n)
|
|
871
|
+
return _1map_mul(xs, ys) if n < 4 else map(
|
|
872
|
+
_operator.mul, map(Fsum, xs), ys)
|
|
858
873
|
|
|
859
874
|
|
|
860
|
-
def _1map_mul(
|
|
861
|
-
'''(INTERNAL) Yield each B{C{
|
|
875
|
+
def _1map_mul(xs, ys):
|
|
876
|
+
'''(INTERNAL) Yield each B{C{x * y}}, 1-primed.
|
|
862
877
|
'''
|
|
863
|
-
return _1primed(map(_operator.mul,
|
|
878
|
+
return _1primed(map(_operator.mul, map(Fsum, xs), ys))
|
|
864
879
|
|
|
865
880
|
|
|
866
881
|
def norm2(x, y):
|
|
@@ -920,7 +935,7 @@ def _root(x, p, where):
|
|
|
920
935
|
'''
|
|
921
936
|
try:
|
|
922
937
|
if x > 0:
|
|
923
|
-
return
|
|
938
|
+
return Fsum(x).fpow(p).as_iscalar
|
|
924
939
|
elif x < 0:
|
|
925
940
|
raise ValueError(_negative_)
|
|
926
941
|
except Exception as X:
|
|
@@ -932,11 +947,13 @@ def sqrt0(x, Error=None):
|
|
|
932
947
|
'''Return the square root C{sqrt(B{x})} iff C{B{x} > }L{EPS02},
|
|
933
948
|
preserving C{type(B{x})}.
|
|
934
949
|
|
|
935
|
-
@arg x: Value (C{scalar} or L{Fsum}
|
|
950
|
+
@arg x: Value (C{scalar} or an L{Fsum} or L{Fsum2Tuple}).
|
|
936
951
|
@kwarg Error: Error to raise for negative B{C{x}}.
|
|
937
952
|
|
|
938
953
|
@return: Square root (C{float} or L{Fsum}) or C{0.0}.
|
|
939
954
|
|
|
955
|
+
@raise TypeeError: Invalid B{C{x}}.
|
|
956
|
+
|
|
940
957
|
@note: Any C{B{x} < }L{EPS02} I{including} C{B{x} < 0}
|
|
941
958
|
returns C{0.0}.
|
|
942
959
|
'''
|
|
@@ -949,10 +966,12 @@ def sqrt3(x):
|
|
|
949
966
|
'''Return the square root, I{cubed} M{sqrt(x)**3} or M{sqrt(x**3)},
|
|
950
967
|
preserving C{type(B{x})}.
|
|
951
968
|
|
|
952
|
-
@arg x: Value (C{scalar} or L{Fsum}
|
|
969
|
+
@arg x: Value (C{scalar} or an L{Fsum} or L{Fsum2Tuple}).
|
|
953
970
|
|
|
954
971
|
@return: Square root I{cubed} (C{float} or L{Fsum}).
|
|
955
972
|
|
|
973
|
+
@raise TypeeError: Invalid B{C{x}}.
|
|
974
|
+
|
|
956
975
|
@raise ValueError: Negative B{C{x}}.
|
|
957
976
|
|
|
958
977
|
@see: Functions L{cbrt} and L{cbrt2}.
|
|
@@ -1003,12 +1022,14 @@ def zcrt(x):
|
|
|
1003
1022
|
'''Return the 6-th, I{zenzi-cubic} root, M{x**(1 / 6)},
|
|
1004
1023
|
preserving C{type(B{x})}.
|
|
1005
1024
|
|
|
1006
|
-
@arg x: Value (C{scalar} or L{Fsum}
|
|
1025
|
+
@arg x: Value (C{scalar} or an L{Fsum} or L{Fsum2Tuple}).
|
|
1007
1026
|
|
|
1008
1027
|
@return: I{Zenzi-cubic} root (C{float} or L{Fsum}).
|
|
1009
1028
|
|
|
1010
1029
|
@see: Functions L{bqrt} and L{zqrt}.
|
|
1011
1030
|
|
|
1031
|
+
@raise TypeeError: Invalid B{C{x}}.
|
|
1032
|
+
|
|
1012
1033
|
@raise ValueError: Negative B{C{x}}.
|
|
1013
1034
|
'''
|
|
1014
1035
|
return _root(x, _1_6th, zcrt)
|
|
@@ -1018,12 +1039,14 @@ def zqrt(x):
|
|
|
1018
1039
|
'''Return the 8-th, I{zenzi-quartic} or I{squared-quartic} root,
|
|
1019
1040
|
M{x**(1 / 8)}, preserving C{type(B{x})}.
|
|
1020
1041
|
|
|
1021
|
-
@arg x: Value (C{scalar} or L{Fsum}
|
|
1042
|
+
@arg x: Value (C{scalar} or an L{Fsum} or L{Fsum2Tuple}).
|
|
1022
1043
|
|
|
1023
1044
|
@return: I{Zenzi-quartic} root (C{float} or L{Fsum}).
|
|
1024
1045
|
|
|
1025
1046
|
@see: Functions L{bqrt} and L{zcrt}.
|
|
1026
1047
|
|
|
1048
|
+
@raise TypeeError: Invalid B{C{x}}.
|
|
1049
|
+
|
|
1027
1050
|
@raise ValueError: Negative B{C{x}}.
|
|
1028
1051
|
'''
|
|
1029
1052
|
return _root(x, _0_125, zqrt)
|