pygeodesy 24.3.24__py2.py3-none-any.whl → 24.4.4__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.3.24.dist-info → PyGeodesy-24.4.4.dist-info}/METADATA +5 -5
- {PyGeodesy-24.3.24.dist-info → PyGeodesy-24.4.4.dist-info}/RECORD +13 -13
- pygeodesy/__init__.py +4 -4
- pygeodesy/azimuthal.py +2 -2
- pygeodesy/basics.py +16 -5
- pygeodesy/constants.py +2 -2
- pygeodesy/fmath.py +187 -194
- pygeodesy/fsums.py +489 -402
- pygeodesy/lazily.py +2 -2
- pygeodesy/resections.py +28 -28
- pygeodesy/utily.py +11 -10
- {PyGeodesy-24.3.24.dist-info → PyGeodesy-24.4.4.dist-info}/WHEEL +0 -0
- {PyGeodesy-24.3.24.dist-info → PyGeodesy-24.4.4.dist-info}/top_level.txt +0 -0
pygeodesy/fmath.py
CHANGED
|
@@ -8,13 +8,13 @@ from __future__ import division as _; del _ # PYCHOK semicolon
|
|
|
8
8
|
|
|
9
9
|
from pygeodesy.basics import _copysign, copysign0, isint, len2
|
|
10
10
|
from pygeodesy.constants import EPS0, EPS02, EPS1, NAN, PI, PI_2, PI_4, \
|
|
11
|
-
_0_0, _0_125, _0_25, _0_5, _1_0,
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
_0_0, _0_125, _0_25, _0_5, _1_0, _1_3rd, \
|
|
12
|
+
_1_5, _1_6th, _2_0, _2_3rd, _3_0, \
|
|
13
|
+
_copysign_0_0, _isfinite, _over, remainder
|
|
14
14
|
from pygeodesy.errors import _IsnotError, LenError, _TypeError, _ValueError, \
|
|
15
15
|
_xError, _xkwds_get, _xkwds_pop2
|
|
16
|
-
from pygeodesy.fsums import _2float,
|
|
17
|
-
|
|
16
|
+
from pygeodesy.fsums import _2float, Fsum, _fsum, fsum, fsum1_, _pow_op_, \
|
|
17
|
+
_1primed, Fmt, unstr
|
|
18
18
|
from pygeodesy.interns import MISSING, _few_, _h_, _invokation_, _negative_, \
|
|
19
19
|
_not_scalar_, _SPACE_, _too_
|
|
20
20
|
from pygeodesy.lazily import _ALL_LAZY, _sys_version_info2
|
|
@@ -25,22 +25,24 @@ from math import fabs, sqrt # pow
|
|
|
25
25
|
import operator as _operator # in .datums, .trf, .utm
|
|
26
26
|
|
|
27
27
|
__all__ = _ALL_LAZY.fmath
|
|
28
|
-
__version__ = '24.
|
|
28
|
+
__version__ = '24.04.04'
|
|
29
29
|
|
|
30
30
|
# sqrt(2) <https://WikiPedia.org/wiki/Square_root_of_2>
|
|
31
|
-
_0_4142
|
|
31
|
+
_0_4142 = 0.41421356237309504880 # ... sqrt(2) - 1
|
|
32
|
+
_h_lt_b_ = 'abs(h) < abs(b)'
|
|
32
33
|
|
|
33
34
|
|
|
34
35
|
class Fdot(Fsum):
|
|
35
36
|
'''Precision dot product.
|
|
36
37
|
'''
|
|
37
|
-
def __init__(self, a, *b, **
|
|
38
|
+
def __init__(self, a, *b, **name_RESIDUAL):
|
|
38
39
|
'''New L{Fdot} precision dot product M{sum(a[i] * b[i]
|
|
39
|
-
for i=0..len(a))}.
|
|
40
|
+
for i=0..len(a)-1)}.
|
|
40
41
|
|
|
41
42
|
@arg a: Iterable, list, tuple, etc. (C{scalar}s).
|
|
42
43
|
@arg b: Other values (C{scalar}s), all positional.
|
|
43
|
-
@kwarg
|
|
44
|
+
@kwarg name_RESIDUAL: Optional C{B{name}=NN} and
|
|
45
|
+
C{B{RESIDUAL}=None}, see L{Fsum.__init__}.
|
|
44
46
|
|
|
45
47
|
@raise OverflowError: Partial C{2sum} overflow.
|
|
46
48
|
|
|
@@ -48,21 +50,22 @@ class Fdot(Fsum):
|
|
|
48
50
|
|
|
49
51
|
@see: Function L{fdot} and method L{Fsum.fadd}.
|
|
50
52
|
'''
|
|
51
|
-
Fsum.__init__(self, **
|
|
53
|
+
Fsum.__init__(self, **name_RESIDUAL)
|
|
52
54
|
self.fadd(_map_mul(a, b, Fdot))
|
|
53
55
|
|
|
54
56
|
|
|
55
57
|
class Fhorner(Fsum):
|
|
56
58
|
'''Precision polynomial evaluation using the Horner form.
|
|
57
59
|
'''
|
|
58
|
-
def __init__(self, x, *cs, **
|
|
59
|
-
'''New L{Fhorner} evaluation of
|
|
60
|
-
|
|
60
|
+
def __init__(self, x, *cs, **name_RESIDUAL):
|
|
61
|
+
'''New L{Fhorner} evaluation of polynomial M{sum(cs[i] * x**i
|
|
62
|
+
for i=0..len(cs)-1)}.
|
|
61
63
|
|
|
62
|
-
@arg x: Polynomial argument (C{scalar}).
|
|
64
|
+
@arg x: Polynomial argument (C{scalar} or C{Fsum} instance).
|
|
63
65
|
@arg cs: Polynomial coeffients (C{scalar} or C{Fsum}
|
|
64
66
|
instances), all positional.
|
|
65
|
-
@kwarg
|
|
67
|
+
@kwarg name_RESIDUAL: Optional C{B{name}=NN} and
|
|
68
|
+
C{B{RESIDUAL}=None}, see L{Fsum.__init__}.
|
|
66
69
|
|
|
67
70
|
@raise OverflowError: Partial C{2sum} overflow.
|
|
68
71
|
|
|
@@ -70,55 +73,65 @@ class Fhorner(Fsum):
|
|
|
70
73
|
|
|
71
74
|
@raise ValueError: Non-finite B{C{x}}.
|
|
72
75
|
|
|
73
|
-
@see: Function L{fhorner} and methods L{Fsum.fadd} and
|
|
76
|
+
@see: Function L{fhorner} and methods L{Fsum.fadd} and
|
|
77
|
+
L{Fsum.fmul}.
|
|
74
78
|
'''
|
|
75
|
-
Fsum.__init__(self,
|
|
76
|
-
if
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
79
|
+
Fsum.__init__(self, **name_RESIDUAL)
|
|
80
|
+
if cs:
|
|
81
|
+
if isinstance(x, Fsum):
|
|
82
|
+
_mul = self._mul_Fsum
|
|
83
|
+
else:
|
|
84
|
+
_mul = self._mul_scalar
|
|
85
|
+
x = _2float(x=x)
|
|
86
|
+
op = Fhorner.__name__
|
|
87
|
+
if len(cs) > 1 and x:
|
|
88
|
+
for c in reversed(cs):
|
|
89
|
+
self._fset_ps(_mul(x, op))
|
|
90
|
+
self._fadd(c, op, up=False)
|
|
91
|
+
self._update()
|
|
92
|
+
else: # x == 0
|
|
93
|
+
self._fadd(cs[0], op)
|
|
94
|
+
else:
|
|
95
|
+
self._fset(_0_0)
|
|
86
96
|
|
|
87
97
|
|
|
88
98
|
class Fhypot(Fsum):
|
|
89
|
-
'''Precision hypotenuse
|
|
99
|
+
'''Precision summation and hypotenuse, default C{power=2}.
|
|
90
100
|
'''
|
|
91
101
|
def __init__(self, *xs, **power_name_RESIDUAL):
|
|
92
|
-
'''New L{Fhypot} hypotenuse of (the I{power} of) several
|
|
93
|
-
C{scalar} or C{Fsum} values.
|
|
102
|
+
'''New L{Fhypot} hypotenuse of (the I{power} of) several components.
|
|
94
103
|
|
|
95
|
-
@arg xs: One or more
|
|
96
|
-
|
|
97
|
-
@kwarg power_name_RESIDUAL: Optional exponent and
|
|
98
|
-
order C{B{power}=2}, C{B{name}=NN} and
|
|
104
|
+
@arg xs: One or more components (each a C{scalar} or an C{Fsum}
|
|
105
|
+
instance).
|
|
106
|
+
@kwarg power_name_RESIDUAL: Optional, C{scalar} exponent and
|
|
107
|
+
root order C{B{power}=2}, a C{B{name}=NN} and
|
|
99
108
|
C{B{RESIDUAL}=None}, see L{Fsum.__init__}.
|
|
100
109
|
'''
|
|
101
110
|
try:
|
|
102
111
|
p, kwds = _xkwds_pop2(power_name_RESIDUAL, power=2)
|
|
103
112
|
Fsum.__init__(self, **kwds)
|
|
104
113
|
if xs:
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
114
|
+
r = _1_0 / p
|
|
115
|
+
self._facc_power(p, xs, Fhypot)
|
|
116
|
+
self._fpow(r, _pow_op_)
|
|
117
|
+
else:
|
|
118
|
+
self._fset(_0_0)
|
|
119
|
+
except Exception as x:
|
|
120
|
+
raise self._ErrorXs(x, xs, power=p)
|
|
109
121
|
|
|
110
122
|
|
|
111
123
|
class Fpolynomial(Fsum):
|
|
112
124
|
'''Precision polynomial evaluation.
|
|
113
125
|
'''
|
|
114
|
-
def __init__(self, x, *cs, **
|
|
126
|
+
def __init__(self, x, *cs, **name_RESIDUAL):
|
|
115
127
|
'''New L{Fpolynomial} evaluation of the polynomial
|
|
116
|
-
M{sum(cs[i] * x**i for i=0..len(cs))}.
|
|
128
|
+
M{sum(cs[i] * x**i for i=0..len(cs)-1)}.
|
|
117
129
|
|
|
118
|
-
@arg x: Polynomial argument (C{scalar}).
|
|
119
|
-
@arg cs: Polynomial coeffients (C{scalar}
|
|
120
|
-
positional.
|
|
121
|
-
@kwarg
|
|
130
|
+
@arg x: Polynomial argument (C{scalar} or L{Fsum}).
|
|
131
|
+
@arg cs: Polynomial coeffients (each a C{scalar} or
|
|
132
|
+
an L{Fsum} instance), all positional.
|
|
133
|
+
@kwarg name_RESIDUAL: Optional C{B{name}=NN} and
|
|
134
|
+
C{B{RESIDUAL}=None}, see L{Fsum.__init__}.
|
|
122
135
|
|
|
123
136
|
@raise OverflowError: Partial C{2sum} overflow.
|
|
124
137
|
|
|
@@ -126,79 +139,81 @@ class Fpolynomial(Fsum):
|
|
|
126
139
|
|
|
127
140
|
@raise ValueError: Non-finite B{C{x}}.
|
|
128
141
|
|
|
129
|
-
@see:
|
|
142
|
+
@see: Class L{Fhorner}, function L{fpolynomial} and
|
|
143
|
+
method L{Fsum.fadd}.
|
|
130
144
|
'''
|
|
131
|
-
Fsum.__init__(self, *cs[:1], **
|
|
145
|
+
Fsum.__init__(self, *cs[:1], **name_RESIDUAL)
|
|
132
146
|
n = len(cs) - 1
|
|
133
147
|
if n > 0:
|
|
134
|
-
self.fadd(
|
|
148
|
+
self.fadd(_1map_mul(cs[1:], _powers(x, n)))
|
|
149
|
+
elif n < 0:
|
|
150
|
+
self._fset(_0_0)
|
|
135
151
|
|
|
136
152
|
|
|
137
153
|
class Fpowers(Fsum):
|
|
138
|
-
'''Precision summation
|
|
154
|
+
'''Precision summation of powers, optimized for C{power=2, 3 and 4}.
|
|
139
155
|
'''
|
|
140
156
|
def __init__(self, power, *xs, **name_RESIDUAL):
|
|
141
|
-
'''New L{Fpowers} sum of (the I{power} of) several
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
@arg
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
order C{B{power}=2}, C{B{name}=NN} and
|
|
149
|
-
C{B{RESIDUAL}=None}, see L{Fsum.__init__}.
|
|
157
|
+
'''New L{Fpowers} sum of (the I{power} of) several values.
|
|
158
|
+
|
|
159
|
+
@arg power: The exponent (C{scalar} or L{Fsum}).
|
|
160
|
+
@arg xs: One or more values (each a C{scalar} or an
|
|
161
|
+
C{Fsum} instance).
|
|
162
|
+
@kwarg name_RESIDUAL: Optional C{B{name}=NN} and
|
|
163
|
+
C{B{RESIDUAL}=None}, see L{Fsum.__init__}.
|
|
150
164
|
'''
|
|
151
165
|
try:
|
|
152
166
|
Fsum.__init__(self, **name_RESIDUAL)
|
|
153
167
|
if xs:
|
|
154
|
-
self.
|
|
155
|
-
|
|
156
|
-
|
|
168
|
+
self._facc_power(power, xs, Fpowers) # x**0 == 1
|
|
169
|
+
else:
|
|
170
|
+
self._fset(_0_0)
|
|
171
|
+
except Exception as x:
|
|
172
|
+
raise self._ErrorXs(x, xs, power=power)
|
|
157
173
|
|
|
158
174
|
|
|
159
175
|
class Fn_rt(Fsum):
|
|
160
|
-
'''
|
|
176
|
+
'''N-th root of a precision summation.
|
|
161
177
|
'''
|
|
162
178
|
def __init__(self, root, *xs, **name_RESIDUAL):
|
|
163
|
-
'''New L{Fn_rt} root of
|
|
164
|
-
C{scalar} or C{Fsum} values.
|
|
179
|
+
'''New L{Fn_rt} root of a precision sum.
|
|
165
180
|
|
|
166
|
-
@arg root: The order (C{scalar} or C{Fsum})
|
|
167
|
-
|
|
168
|
-
|
|
181
|
+
@arg root: The order (C{scalar} or C{Fsum}),
|
|
182
|
+
non-zero.
|
|
183
|
+
@arg xs: Values to summate (each a C{scalar} or
|
|
184
|
+
an C{Fsum} instance).
|
|
169
185
|
@kwarg name_RESIDUAL: See L{Fsum.__init__}.
|
|
170
186
|
'''
|
|
171
187
|
try:
|
|
172
|
-
Fsum.__init__(self,
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
188
|
+
Fsum.__init__(self, **name_RESIDUAL)
|
|
189
|
+
if xs:
|
|
190
|
+
r = _1_0 / root
|
|
191
|
+
self. fadd(xs)
|
|
192
|
+
self._fpow(r, _pow_op_) # self **= r
|
|
193
|
+
else:
|
|
194
|
+
self._fset(_0_0)
|
|
195
|
+
except Exception as x:
|
|
196
|
+
raise self._ErrorXs(x, xs, root=root)
|
|
176
197
|
|
|
177
198
|
|
|
178
199
|
class Fcbrt(Fn_rt):
|
|
179
|
-
'''
|
|
200
|
+
'''Cubic root of a precision summation.
|
|
180
201
|
'''
|
|
181
202
|
def __init__(self, *xs, **name_RESIDUAL):
|
|
182
|
-
'''New L{Fcbrt} cubic root of
|
|
183
|
-
several C{scalar} or C{Fsum} values.
|
|
203
|
+
'''New L{Fcbrt} cubic root of a precision sum.
|
|
184
204
|
|
|
185
|
-
@
|
|
186
|
-
C{Fsum} instance).
|
|
187
|
-
@kwarg name_RESIDUAL: See L{Fsum.__init__}.
|
|
205
|
+
@see: Class L{Fn_rt} for further details.
|
|
188
206
|
'''
|
|
189
207
|
Fn_rt.__init__(self, _3_0, *xs, **name_RESIDUAL)
|
|
190
208
|
|
|
191
209
|
|
|
192
210
|
class Fsqrt(Fn_rt):
|
|
193
|
-
'''
|
|
211
|
+
'''Square root of a precision summation.
|
|
194
212
|
'''
|
|
195
213
|
def __init__(self, *xs, **name_RESIDUAL):
|
|
196
|
-
'''New L{Fsqrt} square root of
|
|
197
|
-
several C{scalar} or C{Fsum} values.
|
|
214
|
+
'''New L{Fsqrt} square root of a precision sum.
|
|
198
215
|
|
|
199
|
-
@
|
|
200
|
-
C{Fsum} instance).
|
|
201
|
-
@kwarg name_RESIDUAL: See L{Fsum.__init__}.
|
|
216
|
+
@see: Class L{Fn_rt} for further details.
|
|
202
217
|
'''
|
|
203
218
|
Fn_rt.__init__(self, _2_0, *xs, **name_RESIDUAL)
|
|
204
219
|
|
|
@@ -344,7 +359,7 @@ def fatan1(x):
|
|
|
344
359
|
# Eq (9): PI_4 * x - x * (abs(x) - 1) * (0.2447 + 0.0663 * abs(x)), for -1 < x < 1
|
|
345
360
|
# PI_4 * x - (x**2 - x) * (0.2447 + 0.0663 * x), for 0 < x - 1
|
|
346
361
|
# x * (1.0300981633974482 + x * (-0.1784 - x * 0.0663))
|
|
347
|
-
H = Fhorner(x, _0_0, 1.
|
|
362
|
+
H = Fhorner(x, _0_0, 1.0300981634, -0.1784, -0.0663)
|
|
348
363
|
return float(H)
|
|
349
364
|
|
|
350
365
|
|
|
@@ -355,12 +370,12 @@ def fatan2(y, x):
|
|
|
355
370
|
master/Source/Shaders/Builtin/Functions/fastApproximateAtan.glsl>}
|
|
356
371
|
and L{fatan1}.
|
|
357
372
|
'''
|
|
358
|
-
|
|
359
|
-
if
|
|
373
|
+
a, b = fabs(x), fabs(y)
|
|
374
|
+
if b > a:
|
|
360
375
|
r = (PI_2 - fatan1(a / b)) if a else PI_2
|
|
361
|
-
elif
|
|
376
|
+
elif a > b:
|
|
362
377
|
r = fatan1(b / a) if b else _0_0
|
|
363
|
-
elif a: # == b != 0
|
|
378
|
+
elif a: # a == b != 0
|
|
364
379
|
r = PI_4
|
|
365
380
|
else: # a == b == 0
|
|
366
381
|
return _0_0
|
|
@@ -407,7 +422,7 @@ def fdot(a, *b):
|
|
|
407
422
|
|
|
408
423
|
def fdot3(a, b, c, start=0):
|
|
409
424
|
'''Return the precision dot product M{start +
|
|
410
|
-
sum(a[i] * b[i] * c[i] for i=0..len(a))}.
|
|
425
|
+
sum(a[i] * b[i] * c[i] for i=0..len(a)-1)}.
|
|
411
426
|
|
|
412
427
|
@arg a: Iterable, list, tuple, etc. (C{scalar}s).
|
|
413
428
|
@arg b: Iterable, list, tuple, etc. (C{scalar}s).
|
|
@@ -424,7 +439,7 @@ def fdot3(a, b, c, start=0):
|
|
|
424
439
|
def _mul3(a, b, c): # map function
|
|
425
440
|
return a * b * c
|
|
426
441
|
|
|
427
|
-
def
|
|
442
|
+
def _mul3_(a, b, c, start):
|
|
428
443
|
yield start
|
|
429
444
|
for abc in map(_mul3, a, b, c):
|
|
430
445
|
yield abc
|
|
@@ -432,12 +447,12 @@ def fdot3(a, b, c, start=0):
|
|
|
432
447
|
if not len(a) == len(b) == len(c):
|
|
433
448
|
raise LenError(fdot3, a=len(a), b=len(b), c=len(c))
|
|
434
449
|
|
|
435
|
-
return fsum(
|
|
450
|
+
return fsum(_mul3_(a, b, c, start) if start else map(_mul3, a, b, c))
|
|
436
451
|
|
|
437
452
|
|
|
438
453
|
def fhorner(x, *cs):
|
|
439
454
|
'''Evaluate the polynomial M{sum(cs[i] * x**i for
|
|
440
|
-
i=0..len(cs))} using the Horner form.
|
|
455
|
+
i=0..len(cs)-1)} using the Horner form.
|
|
441
456
|
|
|
442
457
|
@arg x: Polynomial argument (C{scalar}).
|
|
443
458
|
@arg cs: Polynomial coeffients (C{scalar}s).
|
|
@@ -483,45 +498,37 @@ def fidw(xs, ds, beta=2):
|
|
|
483
498
|
b = -Int_(beta=beta, low=0, high=3)
|
|
484
499
|
if b < 0:
|
|
485
500
|
ws = tuple(float(d)**b for d in ds)
|
|
486
|
-
t = fsum(
|
|
501
|
+
t = fsum(_1map_mul(xs, ws)) # Fdot(xs, *ws)
|
|
487
502
|
x = _over(t, fsum(ws, floats=True))
|
|
488
503
|
else: # b == 0
|
|
489
504
|
x = fsum(xs) / n # fmean(xs)
|
|
490
505
|
elif d < 0: # PYCHOK no cover
|
|
491
|
-
n = Fmt.
|
|
506
|
+
n = Fmt.SQUARE(distance=ds.index(d))
|
|
492
507
|
raise _ValueError(n, d, txt=_negative_)
|
|
493
508
|
return x
|
|
494
509
|
|
|
495
510
|
|
|
496
511
|
def fmean(xs):
|
|
497
|
-
'''Compute the accurate mean M{sum(xs
|
|
498
|
-
i=0..len(xs)) / len(xs)}.
|
|
512
|
+
'''Compute the accurate mean M{sum(xs) / len(xs)}.
|
|
499
513
|
|
|
500
514
|
@arg xs: Values (C{scalar} or L{Fsum} instances).
|
|
501
515
|
|
|
502
516
|
@return: Mean value (C{float}).
|
|
503
517
|
|
|
504
|
-
@raise
|
|
518
|
+
@raise LenError: No B{C{xs}} values.
|
|
505
519
|
|
|
506
|
-
@raise
|
|
520
|
+
@raise OverflowError: Partial C{2sum} overflow.
|
|
507
521
|
'''
|
|
508
522
|
n, xs = len2(xs)
|
|
509
|
-
if n
|
|
510
|
-
|
|
511
|
-
|
|
523
|
+
if n < 1:
|
|
524
|
+
raise LenError(fmean, xs=xs)
|
|
525
|
+
return Fsum(*xs).fover(n) if n > 1 else _2float(index=0, xs=xs[0])
|
|
512
526
|
|
|
513
527
|
|
|
514
528
|
def fmean_(*xs):
|
|
515
|
-
'''Compute the accurate mean M{sum(xs
|
|
516
|
-
i=0..len(xs)) / len(xs)}.
|
|
517
|
-
|
|
518
|
-
@arg xs: Values (C{scalar} or L{Fsum} instances).
|
|
529
|
+
'''Compute the accurate mean M{sum(xs) / len(xs)}.
|
|
519
530
|
|
|
520
|
-
@
|
|
521
|
-
|
|
522
|
-
@raise OverflowError: Partial C{2sum} overflow.
|
|
523
|
-
|
|
524
|
-
@raise ValueError: No B{C{xs}} values.
|
|
531
|
+
@see: Function L{fmean} for further details.
|
|
525
532
|
'''
|
|
526
533
|
return fmean(xs)
|
|
527
534
|
|
|
@@ -533,7 +540,8 @@ def fpolynomial(x, *cs, **over):
|
|
|
533
540
|
@arg x: Polynomial argument (C{scalar}).
|
|
534
541
|
@arg cs: Polynomial coeffients (C{scalar}s), all
|
|
535
542
|
positional.
|
|
536
|
-
@kwarg over: Optional
|
|
543
|
+
@kwarg over: Optional final, I{non-zero} divisor
|
|
544
|
+
(C{scalar}).
|
|
537
545
|
|
|
538
546
|
@return: Polynomial value (C{float}).
|
|
539
547
|
|
|
@@ -553,28 +561,24 @@ def fpolynomial(x, *cs, **over):
|
|
|
553
561
|
def fpowers(x, n, alts=0):
|
|
554
562
|
'''Return a series of powers M{[x**i for i=1..n]}.
|
|
555
563
|
|
|
556
|
-
@arg x: Value (C{scalar}).
|
|
564
|
+
@arg x: Value (C{scalar} or L{Fsum}).
|
|
557
565
|
@arg n: Highest exponent (C{int}).
|
|
558
|
-
@kwarg alts: Only alternating powers, starting with
|
|
559
|
-
|
|
566
|
+
@kwarg alts: Only alternating powers, starting with this
|
|
567
|
+
exponent (C{int}).
|
|
560
568
|
|
|
561
|
-
@return:
|
|
569
|
+
@return: Tuple of powers of B{C{x}} (C{type(B{x})}).
|
|
562
570
|
|
|
563
|
-
@raise TypeError:
|
|
571
|
+
@raise TypeError: Invalid B{C{x}} or B{C{n}} not C{int}.
|
|
564
572
|
|
|
565
|
-
@raise ValueError: Non-finite B{C{x}} or
|
|
573
|
+
@raise ValueError: Non-finite B{C{x}} or invalid B{C{n}}.
|
|
566
574
|
'''
|
|
567
575
|
if not isint(n):
|
|
568
576
|
raise _IsnotError(int.__name__, n=n)
|
|
569
577
|
elif n < 1:
|
|
570
578
|
raise _ValueError(n=n)
|
|
571
579
|
|
|
572
|
-
p =
|
|
573
|
-
ps =
|
|
574
|
-
_a = ps.append
|
|
575
|
-
for _ in range(1, n):
|
|
576
|
-
p *= t
|
|
577
|
-
_a(p)
|
|
580
|
+
p = x if isint(x) or isinstance(x, Fsum) else _2float(x=x)
|
|
581
|
+
ps = tuple(_powers(p, n))
|
|
578
582
|
|
|
579
583
|
if alts > 0: # x**2, x**4, ...
|
|
580
584
|
# ps[alts-1::2] chokes PyChecker
|
|
@@ -618,7 +622,7 @@ def frange(start, number, step=1):
|
|
|
618
622
|
if not isint(number):
|
|
619
623
|
raise _IsnotError(int.__name__, number=number)
|
|
620
624
|
for i in range(number):
|
|
621
|
-
yield start +
|
|
625
|
+
yield start + (step * i)
|
|
622
626
|
|
|
623
627
|
|
|
624
628
|
try:
|
|
@@ -712,7 +716,7 @@ if _sys_version_info2 < (3, 8): # PYCHOK no cover
|
|
|
712
716
|
computed as M{hypot_(*((c1 - c2) for c1, c2 in zip(p1, p2)))},
|
|
713
717
|
provided I{p1} and I{p2} have the same, non-zero length I{n}.
|
|
714
718
|
'''
|
|
715
|
-
h, x2 = _h_x2(xs)
|
|
719
|
+
h, x2 = _h_x2(xs, hypot_)
|
|
716
720
|
return (h * sqrt(x2)) if x2 else _0_0
|
|
717
721
|
|
|
718
722
|
elif _sys_version_info2 < (3, 10):
|
|
@@ -743,20 +747,23 @@ else:
|
|
|
743
747
|
hypot_ = hypot
|
|
744
748
|
|
|
745
749
|
|
|
746
|
-
def _h_x2(xs):
|
|
750
|
+
def _h_x2(xs, which):
|
|
747
751
|
'''(INTERNAL) Helper for L{hypot_} and L{hypot2_}.
|
|
748
752
|
'''
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
753
|
+
n, xs = len2(xs)
|
|
754
|
+
if n > 0:
|
|
755
|
+
h = float(max(map(fabs, xs)))
|
|
756
|
+
if h < EPS0:
|
|
757
|
+
x2 = _0_0
|
|
758
|
+
elif n > 1:
|
|
759
|
+
_h = (_1_0 / h) if h != _1_0 else _1_0
|
|
760
|
+
x2 = _fsum(_1primed((x * _h)**2 for x in xs))
|
|
761
|
+
else:
|
|
762
|
+
x2 = _1_0
|
|
763
|
+
return h, x2
|
|
758
764
|
|
|
759
|
-
|
|
765
|
+
t = Fmt.PAREN(which.__name__, xs)
|
|
766
|
+
raise _ValueError(t, txt=_too_(_few_))
|
|
760
767
|
|
|
761
768
|
|
|
762
769
|
def hypot1(x):
|
|
@@ -777,15 +784,12 @@ def hypot2(x, y):
|
|
|
777
784
|
|
|
778
785
|
@return: C{B{x}**2 + B{y}**2} (C{float}).
|
|
779
786
|
'''
|
|
787
|
+
if fabs(x) < fabs(y):
|
|
788
|
+
x, y = y, x
|
|
780
789
|
if x:
|
|
790
|
+
h2 = x**2
|
|
781
791
|
if y:
|
|
782
|
-
|
|
783
|
-
x, y = y, x
|
|
784
|
-
h2 = x**2 * ((y / x)**2 + _1_0)
|
|
785
|
-
else:
|
|
786
|
-
h2 = x**2
|
|
787
|
-
elif y:
|
|
788
|
-
h2 = y**2
|
|
792
|
+
h2 *= (y / x)**2 + _1_0
|
|
789
793
|
else:
|
|
790
794
|
h2 = _0_0
|
|
791
795
|
return h2
|
|
@@ -804,7 +808,7 @@ def hypot2_(*xs):
|
|
|
804
808
|
|
|
805
809
|
@see: Function L{hypot_}.
|
|
806
810
|
'''
|
|
807
|
-
h, x2 = _h_x2(xs)
|
|
811
|
+
h, x2 = _h_x2(xs, hypot2_)
|
|
808
812
|
return (h**2 * x2) if x2 else _0_0
|
|
809
813
|
|
|
810
814
|
|
|
@@ -814,17 +818,13 @@ def _map_mul(a, b, where):
|
|
|
814
818
|
n = len(b)
|
|
815
819
|
if len(a) != n: # PYCHOK no cover
|
|
816
820
|
raise LenError(where, a=len(a), b=n)
|
|
817
|
-
return map(_operator.mul, a, b) if n > 3 else
|
|
821
|
+
return map(_operator.mul, a, b) if n > 3 else _1map_mul(a, b)
|
|
818
822
|
|
|
819
823
|
|
|
820
|
-
def
|
|
824
|
+
def _1map_mul(a, b):
|
|
821
825
|
'''(INTERNAL) Yield each B{C{a * b}}, 1-primed.
|
|
822
826
|
'''
|
|
823
|
-
|
|
824
|
-
for ab in map(_operator.mul, a, b):
|
|
825
|
-
if ab:
|
|
826
|
-
yield ab
|
|
827
|
-
yield _N_1_0
|
|
827
|
+
return _1primed(map(_operator.mul, a, b))
|
|
828
828
|
|
|
829
829
|
|
|
830
830
|
def norm2(x, y):
|
|
@@ -838,14 +838,15 @@ def norm2(x, y):
|
|
|
838
838
|
@raise ValueError: Invalid B{C{x}} or B{C{y}}
|
|
839
839
|
or zero norm.
|
|
840
840
|
'''
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
x
|
|
847
|
-
|
|
848
|
-
|
|
841
|
+
try:
|
|
842
|
+
h = hypot(x, y)
|
|
843
|
+
if h:
|
|
844
|
+
x, y = (x / h), (y / h)
|
|
845
|
+
else:
|
|
846
|
+
x = _copysign_0_0(x) # pass?
|
|
847
|
+
y = _copysign_0_0(y)
|
|
848
|
+
except Exception as e:
|
|
849
|
+
raise _xError(e, x=x, y=y, h=h)
|
|
849
850
|
return x, y
|
|
850
851
|
|
|
851
852
|
|
|
@@ -859,16 +860,22 @@ def norm_(*xs):
|
|
|
859
860
|
@raise ValueError: Invalid or insufficent B{C{xs}}
|
|
860
861
|
or zero norm.
|
|
861
862
|
'''
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
863
|
+
try:
|
|
864
|
+
h = hypot_(*xs)
|
|
865
|
+
_h = (_1_0 / h) if h else _0_0
|
|
866
|
+
for i, x in enumerate(xs):
|
|
867
|
+
yield x * _h
|
|
868
|
+
except Exception as e:
|
|
869
|
+
raise _xError(e, Fmt.SQUARE(xs=i), x, _h_, h)
|
|
870
|
+
|
|
871
|
+
|
|
872
|
+
def _powers(x, n):
|
|
873
|
+
'''(INTERNAL) Yield C{x**i for i=1..n}.
|
|
874
|
+
'''
|
|
875
|
+
p = 1 # type(p) == type(x)
|
|
876
|
+
for _ in range(n):
|
|
877
|
+
p *= x
|
|
878
|
+
yield p
|
|
872
879
|
|
|
873
880
|
|
|
874
881
|
def _root(x, p, where):
|
|
@@ -931,36 +938,22 @@ def sqrt_a(h, b):
|
|
|
931
938
|
try:
|
|
932
939
|
if not (_isHeight(h) and _isRadius(b)):
|
|
933
940
|
raise TypeError(_not_scalar_)
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
d = c - b
|
|
937
|
-
if d < 0:
|
|
938
|
-
raise ValueError('abs(h) < abs(b)')
|
|
939
|
-
a = copysign0(sqrt((c + b) * d), h) if d > 0 else _0_0
|
|
940
|
-
else:
|
|
941
|
-
c = float(h)
|
|
941
|
+
c = fabs(h)
|
|
942
|
+
if c > EPS0:
|
|
942
943
|
s = _1_0 - (b / c)**2
|
|
943
944
|
if s < 0:
|
|
944
|
-
raise ValueError(
|
|
945
|
+
raise ValueError(_h_lt_b_)
|
|
945
946
|
a = (sqrt(s) * c) if 0 < s < 1 else (c if s else _0_0)
|
|
947
|
+
else: # PYCHOK no cover
|
|
948
|
+
b = fabs(b)
|
|
949
|
+
d = c - b
|
|
950
|
+
if d < 0:
|
|
951
|
+
raise ValueError(_h_lt_b_)
|
|
952
|
+
d *= c + b
|
|
953
|
+
a = sqrt(d) if d else _0_0
|
|
946
954
|
except Exception as x:
|
|
947
955
|
raise _xError(x, h=h, b=b)
|
|
948
|
-
return a
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
def _x2_h2(s, xs, h, e):
|
|
952
|
-
'''(INTERNAL) Yield M{(x / h)**2 for x in xs}.
|
|
953
|
-
'''
|
|
954
|
-
yield s
|
|
955
|
-
if h in (_0_0, _1_0):
|
|
956
|
-
for x in xs:
|
|
957
|
-
if x:
|
|
958
|
-
yield x**2
|
|
959
|
-
else:
|
|
960
|
-
for x in xs:
|
|
961
|
-
if x:
|
|
962
|
-
yield (x / h)**2
|
|
963
|
-
yield e
|
|
956
|
+
return copysign0(a, h)
|
|
964
957
|
|
|
965
958
|
|
|
966
959
|
def zcrt(x):
|