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/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, len2
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, _over, remainder
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, Fmt, unstr
16
- from pygeodesy.interns import MISSING, _few_, _negative_, _not_scalar_, _too_
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.04.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
- for i=0..len(a)-1)}.
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, list, tuple, etc. (C{scalar}s).
41
- @arg b: Other values (C{scalar}s), all positional.
42
- @kwarg name_RESIDUAL: Optional C{B{name}=NN} and C{B{RESIDUAL}=None},
43
- see L{Fsum<Fsum.__init__>}.
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 LenError: Unequal C{len(B{a})} and C{len(B{b})}.
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
- for i=0..len(cs)-1)}.
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 C{Fsum} instance).
63
- @arg cs: Polynomial coeffients (C{scalar} or C{Fsum}
64
- instances), all positional.
65
- @kwarg name_RESIDUAL: Optional C{B{name}=NN} and C{B{RESIDUAL}=None},
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: Non-scalar B{C{x}}.
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 isinstance(x, Fsum):
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
- @arg xs: One or more components (each a C{scalar} or an C{Fsum} instance).
103
- @kwarg root_name_RESIDUAL_raiser: Optional, exponent and C{B{root}=2} order,
104
- C{B{name}=NN}, C{B{RESIDUAL}=None} and C{B{raiser}=True}, see
105
- class L{Fsum<Fsum.__init__>} and method L{root<Fsum.root>}.
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 a C{scalar} or an L{Fsum} instance),
128
- all positional.
129
- @kwarg name_RESIDUAL: Optional C{B{name}=NN} and C{B{RESIDUAL}=None},
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: Non-scalar B{C{x}}.
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 values.
154
-
155
- @arg power: The exponent (C{scalar} or L{Fsum}).
156
- @arg xs: One or more values (each a C{scalar} or an C{Fsum} instance).
157
- @kwarg name_RESIDUAL_raiser: Optional C{B{name}=NN}, C{B{RESIDUAL}=None} and
158
- C{B{raiser}=True}, see L{Fsum<Fsum.__init__>} and L{fpow<Fsum.fpow>}.
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 C{Fsum}), non-zero.
175
- @arg xs: Values to summate (each a C{scalar} or an C{Fsum} instance).
176
- @kwarg name_RESIDUAL_raiser: Optional C{B{name}=NN}, C{B{RESIDUAL}=None} and
177
- C{B{raiser}=True}, see L{Fsum<Fsum.__init__>} and L{fpow<Fsum.fpow>}.
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} instance).
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
- @return: I{Quartic} root (C{float} or L{Fsum}).
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} instance).
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 isinstance(x, Fsum):
257
- r = (-(-x).pow(_1_3rd)) if x < 0 else x.pow(_1_3rd)
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} instance).
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).pow(_2_3rd) if isinstance(x, Fsum) else _cbrt(x**2)
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 x < y:
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, positional (C{scalar}s or L{Fsum} instances).
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(v1, v2, f=_0_5):
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 v1: One value (C{scalar} or L{Fsum} instance).
397
- @arg v2: Other value (C{scalar} or L{Fsum} instance).
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{v1 + f * (v2 - v1)} (C{float}).
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
- # v1 + f * (v2 - v1) == v1 * (1 - f) + v2 * f
407
- return fsum1_(v1, -f * v1, f * v2)
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, list, tuple, etc. (C{scalar}s).
415
- @arg b: All positional arguments (C{scalar}s).
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(a, b, c, start=0):
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 a: Iterable, list, tuple, etc. (C{scalar}s).
432
- @arg b: Iterable, list, tuple, etc. (C{scalar}s).
433
- @arg c: Iterable, list, tuple, etc. (C{scalar}s).
434
- @kwarg start: Optional bias (C{scalar}).
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{a})}, C{len(B{b})}
439
- and/or C{len(B{c})}.
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(a, b, c): # map function
444
- return a * b * c
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
- def _mul3_(a, b, c, start):
447
- yield start
448
- for abc in map(_mul3, a, b, c):
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
- if not len(a) == len(b) == len(c):
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
- @arg x: Polynomial argument (C{scalar}).
462
- @arg cs: Polynomial coeffients (C{scalar}s).
463
-
464
- @return: Horner value (C{float}).
487
+ @return: Horner sum (C{float}).
465
488
 
466
- @raise OverflowError: Partial C{2sum} overflow.
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}s).
483
- @arg ds: Non-negative distances (C{scalar}s).
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 ValueError: Invalid B{C{beta}}, negative B{C{ds}} value,
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
- d, ds = len2(ds)
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
- ws = tuple(float(d)**b for d in ds)
505
- t = fsum(_1map_mul(xs, ws)) # Fdot(xs, *ws)
506
- x = _over(t, fsum(ws, floats=True))
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
- elif d < 0: # PYCHOK no cover
510
- n = Fmt.SQUARE(distance=ds.index(d))
511
- raise _ValueError(n, d, txt=_negative_)
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
- @arg x: Polynomial argument (C{scalar}).
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
- @raise OverflowError: Partial C{2sum} overflow.
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 isinstance(x, Fsum) else _2float(x=x)
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
- _, R = _h_xs2(xs, True, hypot_)
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 (float(Fhypot(x, y, raiser=False)) if y else
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} instance).
815
+ @arg x: Argument (C{scalar} or L{Fsum} or L{Fsum2Tuple}).
808
816
 
809
817
  @return: Norm (C{float}).
810
818
  '''
811
- return hypot(_1_0, x) if x else _1_0
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 argument (C{scalar} or L{Fsum} instance).
818
- @arg y: Y argument (C{scalar} or L{Fsum} instance).
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} or L{Fsum}).
832
+ @return: C{B{x}**2 + B{y}**2} (C{float}).
821
833
  '''
822
- if abs(x) < abs(y): # NOT fabs!
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: X arguments (C{scalar}s or L{Fsum} instances),
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
- @raise OverflowError: Partial C{2sum} overflow.
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
- _, R = _h_xs2(xs, False, hypot2_)
848
- return float(R)
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(a, b, where):
852
- '''(INTERNAL) Yield each B{C{a * b}}.
865
+ def _map_mul(xs, ys, where):
866
+ '''(INTERNAL) Yield each B{C{x * y}}.
853
867
  '''
854
- n = len(b)
855
- if len(a) != n: # PYCHOK no cover
856
- raise LenError(where, a=len(a), b=n)
857
- return _1map_mul(a, b) if n < 4 else map(_operator.mul, a, b)
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(a, b):
861
- '''(INTERNAL) Yield each B{C{a * b}}, 1-primed.
875
+ def _1map_mul(xs, ys):
876
+ '''(INTERNAL) Yield each B{C{x * y}}, 1-primed.
862
877
  '''
863
- return _1primed(map(_operator.mul, a, b))
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 pow(x, p)
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} instance).
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} instance).
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} instance).
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} instance).
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)