pygeodesy 24.9.29__py2.py3-none-any.whl → 24.10.10__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.9.29.dist-info → PyGeodesy-24.10.10.dist-info}/METADATA +9 -9
- {PyGeodesy-24.9.29.dist-info → PyGeodesy-24.10.10.dist-info}/RECORD +12 -12
- pygeodesy/__init__.py +10 -9
- pygeodesy/errors.py +11 -6
- pygeodesy/fmath.py +185 -173
- pygeodesy/fstats.py +54 -56
- pygeodesy/fsums.py +283 -255
- pygeodesy/internals.py +1 -0
- pygeodesy/streprs.py +7 -4
- pygeodesy/vector3d.py +5 -5
- {PyGeodesy-24.9.29.dist-info → PyGeodesy-24.10.10.dist-info}/WHEEL +0 -0
- {PyGeodesy-24.9.29.dist-info → PyGeodesy-24.10.10.dist-info}/top_level.txt +0 -0
pygeodesy/fsums.py
CHANGED
|
@@ -40,15 +40,14 @@ results may differ from Python's C{math.fsum} results.
|
|
|
40
40
|
from __future__ import division as _; del _ # PYCHOK semicolon
|
|
41
41
|
|
|
42
42
|
from pygeodesy.basics import isbool, iscomplex, isint, isscalar, \
|
|
43
|
-
_signOf, itemsorted, signOf, _xiterable
|
|
44
|
-
_xiterablen
|
|
43
|
+
_signOf, itemsorted, signOf, _xiterable
|
|
45
44
|
from pygeodesy.constants import INF, INT0, MANT_DIG, NEG0, NINF, _0_0, \
|
|
46
45
|
_1_0, _N_1_0, _isfinite, _pos_self, \
|
|
47
46
|
Float, Int
|
|
48
47
|
from pygeodesy.errors import _AssertionError, _OverflowError, _TypeError, \
|
|
49
|
-
_ValueError, _xError, _xError2,
|
|
50
|
-
|
|
51
|
-
_xsError
|
|
48
|
+
_ValueError, _xError, _xError2, _xkwds, \
|
|
49
|
+
_xkwds_get, _xkwds_get1, _xkwds_not, \
|
|
50
|
+
_xkwds_pop, _xsError
|
|
52
51
|
from pygeodesy.internals import _enquote, _passarg
|
|
53
52
|
from pygeodesy.interns import NN, _arg_, _COMMASPACE_, _DOT_, _from_, \
|
|
54
53
|
_not_finite_, _SPACE_, _std_, _UNDER_
|
|
@@ -65,7 +64,7 @@ from math import fabs, isinf, isnan, \
|
|
|
65
64
|
ceil as _ceil, floor as _floor # PYCHOK used! .ltp
|
|
66
65
|
|
|
67
66
|
__all__ = _ALL_LAZY.fsums
|
|
68
|
-
__version__ = '24.09
|
|
67
|
+
__version__ = '24.10.09'
|
|
69
68
|
|
|
70
69
|
from pygeodesy.interns import (
|
|
71
70
|
_PLUS_ as _add_op_, # in .auxilats.auxAngle
|
|
@@ -78,16 +77,13 @@ from pygeodesy.interns import (
|
|
|
78
77
|
_DASH_ as _sub_op_, # in .auxilats.auxAngle
|
|
79
78
|
_SLASH_ as _truediv_op_
|
|
80
79
|
)
|
|
81
|
-
_eq_op_ = _fset_op_ * 2 # _DEQUAL_
|
|
82
80
|
_floordiv_op_ = _truediv_op_ * 2 # _DSLASH_
|
|
83
81
|
_divmod_op_ = _floordiv_op_ + _mod_op_
|
|
84
82
|
_F2PRODUCT = _getenv('PYGEODESY_FSUM_F2PRODUCT', NN)
|
|
85
|
-
_ge_op_ = _gt_op_ + _fset_op_
|
|
86
83
|
_iadd_op_ = _add_op_ + _fset_op_ # in .auxilats.auxAngle, .fstats
|
|
87
84
|
_integer_ = 'integer'
|
|
88
85
|
_isub_op_ = _sub_op_ + _fset_op_ # in .auxilats.auxAngle
|
|
89
|
-
|
|
90
|
-
_NONFINITEr = _0_0
|
|
86
|
+
_NONFINITEr = _0_0 # NOT INT0!
|
|
91
87
|
_NONFINITES = _getenv('PYGEODESY_FSUM_NONFINITES', NN)
|
|
92
88
|
_non_zero_ = 'non-zero'
|
|
93
89
|
_pow_op_ = _mul_op_ * 2 # _DSTAR_
|
|
@@ -96,10 +92,10 @@ _significant_ = 'significant'
|
|
|
96
92
|
_threshold_ = 'threshold'
|
|
97
93
|
|
|
98
94
|
|
|
99
|
-
def _2finite(x): # in .fstats
|
|
95
|
+
def _2finite(x, _isfine=_isfinite): # in .fstats
|
|
100
96
|
'''(INTERNAL) return C{float(x)} if finite.
|
|
101
97
|
'''
|
|
102
|
-
return (float(x) if
|
|
98
|
+
return (float(x) if _isfine(x) # and isscalar(x)
|
|
103
99
|
else _nfError(x))
|
|
104
100
|
|
|
105
101
|
|
|
@@ -114,28 +110,6 @@ def _2float(index=None, _isfine=_isfinite, **name_x): # in .fmath, .fstats
|
|
|
114
110
|
raise _xError(X, Fmt.INDEX(n, index), x)
|
|
115
111
|
|
|
116
112
|
|
|
117
|
-
def _X_ps(X): # for _2floats only
|
|
118
|
-
return X._ps
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
def _2floats(xs, origin=0, _X=_X_ps, _x=float, _isfine=_isfinite):
|
|
122
|
-
'''(INTERNAL) Yield each B{C{xs}} as a C{float}.
|
|
123
|
-
'''
|
|
124
|
-
try:
|
|
125
|
-
i, x = origin, xs
|
|
126
|
-
_FsT = _Fsum_2Tuple_types
|
|
127
|
-
for x in _xiterable(xs):
|
|
128
|
-
if isinstance(x, _FsT):
|
|
129
|
-
for p in _X(x._Fsum):
|
|
130
|
-
yield p
|
|
131
|
-
else:
|
|
132
|
-
f = _x(x)
|
|
133
|
-
yield f if _isfine(f) else _nfError(f)
|
|
134
|
-
i += 1
|
|
135
|
-
except Exception as X:
|
|
136
|
-
raise _xsError(X, xs, i, x)
|
|
137
|
-
|
|
138
|
-
|
|
139
113
|
try: # MCCABE 26
|
|
140
114
|
from math import fma as _fma
|
|
141
115
|
|
|
@@ -145,8 +119,9 @@ try: # MCCABE 26
|
|
|
145
119
|
# <https://www.TUHH.De/ti3/paper/rump/OgRuOi05.pdf>}
|
|
146
120
|
for y in ys:
|
|
147
121
|
f = x * y
|
|
148
|
-
yield
|
|
149
|
-
|
|
122
|
+
yield f
|
|
123
|
+
if _isfinite(f):
|
|
124
|
+
yield _fma(x, y, -f)
|
|
150
125
|
for z in zs:
|
|
151
126
|
yield z
|
|
152
127
|
|
|
@@ -156,7 +131,7 @@ try: # MCCABE 26
|
|
|
156
131
|
except ImportError: # PYCHOK DSPACE! Python 3.12-
|
|
157
132
|
|
|
158
133
|
if _F2PRODUCT and _F2PRODUCT != _std_:
|
|
159
|
-
#
|
|
134
|
+
# backward to PyGeodesy 24.09.09, with _fmaX
|
|
160
135
|
|
|
161
136
|
def _fma(*a_b_c): # PYCHOK no cover
|
|
162
137
|
# mimick C{math.fma} from Python 3.13+,
|
|
@@ -166,12 +141,13 @@ except ImportError: # PYCHOK DSPACE! Python 3.12-
|
|
|
166
141
|
n += da * db * nc
|
|
167
142
|
d = da * db * dc
|
|
168
143
|
try:
|
|
169
|
-
|
|
144
|
+
n, d = _n_d2(n, d)
|
|
145
|
+
r = float(n / d)
|
|
170
146
|
except OverflowError: # "integer division result too large ..."
|
|
171
147
|
r = NINF if (_signOf(n, 0) * _signOf(d, 0)) < 0 else INF
|
|
172
148
|
return r if _isfinite(r) else _fmaX(r, *a_b_c) # "overflow in fma"
|
|
173
149
|
|
|
174
|
-
def _2n_d(x):
|
|
150
|
+
def _2n_d(x): # PYCHOK no cover
|
|
175
151
|
try: # int.as_integer_ratio in 3.8+
|
|
176
152
|
return x.as_integer_ratio()
|
|
177
153
|
except (AttributeError, OverflowError, TypeError, ValueError):
|
|
@@ -188,18 +164,18 @@ except ImportError: # PYCHOK DSPACE! Python 3.12-
|
|
|
188
164
|
_2n_d = None # redef
|
|
189
165
|
|
|
190
166
|
def _fmaX(r, *a_b_c): # like Python 3.13+ I{Modules/mathmodule.c}:
|
|
191
|
-
# raise a ValueError for a NAN result from non-NAN C{a_b_c}s or
|
|
192
|
-
# OverflowError for a non-NAN
|
|
167
|
+
# raise a ValueError for a NAN result from non-NAN C{a_b_c}s or an
|
|
168
|
+
# OverflowError for a non-NAN non-finite from all finite C{a_b_c}s.
|
|
193
169
|
if isnan(r):
|
|
194
170
|
def _x(x):
|
|
195
171
|
return not isnan(x)
|
|
196
|
-
else:
|
|
172
|
+
else: # non-NAN non-finite
|
|
197
173
|
_x = _isfinite
|
|
198
174
|
if all(map(_x, a_b_c)):
|
|
199
175
|
raise _nfError(r, unstr(_fma, *a_b_c))
|
|
200
176
|
return r
|
|
201
177
|
|
|
202
|
-
def _2products(x, y3s, *zs): # PYCHOK in
|
|
178
|
+
def _2products(x, y3s, *zs): # PYCHOK in _fma, ...
|
|
203
179
|
# yield(x * y3 for y3 in y3s) + yield(z in zs)
|
|
204
180
|
# TwoProduct U{Algorithm 3.3
|
|
205
181
|
# <https://www.TUHH.De/ti3/paper/rump/OgRuOi05.pdf>}
|
|
@@ -209,20 +185,16 @@ except ImportError: # PYCHOK DSPACE! Python 3.12-
|
|
|
209
185
|
for y, c, d in y3s:
|
|
210
186
|
y *= x
|
|
211
187
|
yield y
|
|
212
|
-
if
|
|
213
|
-
yield b * d - (((y - a * c) - b * c) - a * d)
|
|
214
|
-
#
|
|
215
|
-
#
|
|
216
|
-
#
|
|
217
|
-
elif a:
|
|
188
|
+
if _isfinite(y):
|
|
189
|
+
# yield b * d - (((y - a * c) - b * c) - a * d)
|
|
190
|
+
# = b * d + (a * d - ((y - a * c) - b * c))
|
|
191
|
+
# = b * d + (a * d + (b * c - (y - a * c)))
|
|
192
|
+
# = b * d + (a * d + (b * c + (a * c - y)))
|
|
218
193
|
yield a * c - y
|
|
219
194
|
yield b * c
|
|
220
195
|
if d:
|
|
221
196
|
yield a * d
|
|
222
197
|
yield b * d
|
|
223
|
-
else:
|
|
224
|
-
yield b * c - y
|
|
225
|
-
yield b * d
|
|
226
198
|
for z in zs:
|
|
227
199
|
yield z
|
|
228
200
|
|
|
@@ -268,10 +240,10 @@ def _Fsumf_(*xs): # in .auxLat, .ltp, ...
|
|
|
268
240
|
def _Fsum1f_(*xs): # in .albers
|
|
269
241
|
'''(INTERNAL) An C{Fsum(xs)}, all C{scalar}, an L{Fsum} or L{Fsum2Tuple}, 1-primed.
|
|
270
242
|
'''
|
|
271
|
-
return Fsum()._facc_scalarf(_1primed(xs), up=False)
|
|
243
|
+
return Fsum()._facc_scalarf(_1primed(xs), origin=-1, up=False)
|
|
272
244
|
|
|
273
245
|
|
|
274
|
-
def
|
|
246
|
+
def _halfeven(s, r, p):
|
|
275
247
|
'''(INTERNAL) Round half-even.
|
|
276
248
|
'''
|
|
277
249
|
if (p > 0 and r > 0) or \
|
|
@@ -302,19 +274,31 @@ def _isOK(unused):
|
|
|
302
274
|
|
|
303
275
|
|
|
304
276
|
def _isOK_or_finite(x, _isfine=_isfinite):
|
|
305
|
-
'''(INTERNAL) Is C{x} finite or is I{non-finite} OK
|
|
277
|
+
'''(INTERNAL) Is C{x} finite or is I{non-finite} OK?
|
|
306
278
|
'''
|
|
307
279
|
# assert _isfine in (_isOK, _isfinite)
|
|
308
|
-
return _isfine(x)
|
|
280
|
+
return _isfine(x) # C{bool}
|
|
309
281
|
|
|
310
282
|
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
283
|
+
try:
|
|
284
|
+
from math import gcd as _gcd
|
|
285
|
+
|
|
286
|
+
def _n_d2(n, d):
|
|
287
|
+
'''(INTERNAL) Reduce C{n} and C{d} by C{gcd}.
|
|
288
|
+
'''
|
|
289
|
+
if n and d:
|
|
290
|
+
try:
|
|
291
|
+
c = _gcd(n, d)
|
|
292
|
+
if c > 1:
|
|
293
|
+
n, d = (n // c), (d // c)
|
|
294
|
+
except TypeError: # non-int float
|
|
295
|
+
pass
|
|
296
|
+
return n, d
|
|
297
|
+
|
|
298
|
+
except ImportError: # 3.4-
|
|
299
|
+
|
|
300
|
+
def _n_d2(*n_d): # PYCHOK redef
|
|
301
|
+
return n_d
|
|
318
302
|
|
|
319
303
|
|
|
320
304
|
def _nfError(x, *args):
|
|
@@ -327,6 +311,13 @@ def _nfError(x, *args):
|
|
|
327
311
|
raise E(t, txt=None)
|
|
328
312
|
|
|
329
313
|
|
|
314
|
+
def _NonfiniteError(x):
|
|
315
|
+
'''(INTERNAL) Return the Error class for C{x}, I{non-finite}.
|
|
316
|
+
'''
|
|
317
|
+
return _OverflowError if isinf(x) else (
|
|
318
|
+
_ValueError if isnan(x) else _AssertionError)
|
|
319
|
+
|
|
320
|
+
|
|
330
321
|
def nonfiniterrors(*raiser):
|
|
331
322
|
'''Throw C{OverflowError} and C{ValueError} exceptions for or
|
|
332
323
|
handle I{non-finite} C{float}s as C{inf}, C{INF}, C{NINF},
|
|
@@ -344,14 +335,8 @@ def nonfiniterrors(*raiser):
|
|
|
344
335
|
d = Fsum._isfine
|
|
345
336
|
if raiser and raiser[0] is not None:
|
|
346
337
|
Fsum._isfine = {} if bool(raiser[0]) else Fsum._nonfinites_isfine_kwds[True]
|
|
347
|
-
return
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
def _NonfiniteError(x):
|
|
351
|
-
'''(INTERNAL) Return the Error class for C{x}, I{non-finite}.
|
|
352
|
-
'''
|
|
353
|
-
return _OverflowError if isinf(x) else (
|
|
354
|
-
_ValueError if isnan(x) else _AssertionError)
|
|
338
|
+
return (False if d is Fsum._nonfinites_isfine_kwds[True] else
|
|
339
|
+
_xkwds_get1(d, _isfine=_isfinite) is _isfinite) if d else True
|
|
355
340
|
|
|
356
341
|
|
|
357
342
|
def _1primed(xs): # in .fmath
|
|
@@ -377,7 +362,7 @@ def _psum(ps, **_isfine): # PYCHOK used!
|
|
|
377
362
|
if s:
|
|
378
363
|
ps[i:] = r, s
|
|
379
364
|
if i > 0:
|
|
380
|
-
s =
|
|
365
|
+
s = _halfeven(s, r, ps[i-1])
|
|
381
366
|
break # return s
|
|
382
367
|
s = r # PYCHOK no cover
|
|
383
368
|
elif not _isfinite(s): # non-finite OK
|
|
@@ -404,14 +389,38 @@ def _Psum_(*ps, **name_f2product_nonfinites_RESIDUAL): # in .fmath
|
|
|
404
389
|
return _Psum(ps, **name_f2product_nonfinites_RESIDUAL)
|
|
405
390
|
|
|
406
391
|
|
|
407
|
-
def
|
|
392
|
+
def _residue(other):
|
|
393
|
+
'''(INTERNAL) Return the C{residual} or C{None} for C{scalar}.
|
|
394
|
+
'''
|
|
395
|
+
try:
|
|
396
|
+
r = other.residual
|
|
397
|
+
except AttributeError:
|
|
398
|
+
r = None # float, int, other
|
|
399
|
+
return r
|
|
400
|
+
|
|
401
|
+
|
|
402
|
+
def _s_r(s, r):
|
|
403
|
+
'''(INTERNAL) Return C{(s, r)}, I{ordered}.
|
|
404
|
+
'''
|
|
405
|
+
if _isfinite(s):
|
|
406
|
+
if r:
|
|
407
|
+
if fabs(s) < fabs(r):
|
|
408
|
+
s, r = r, (s or INT0)
|
|
409
|
+
else:
|
|
410
|
+
r = INT0
|
|
411
|
+
else:
|
|
412
|
+
r = _NONFINITEr
|
|
413
|
+
return s, r
|
|
414
|
+
|
|
415
|
+
|
|
416
|
+
def _2s_r(other):
|
|
408
417
|
'''(INTERNAL) Return 2-tuple C{(other, r)} with C{other} as C{int},
|
|
409
|
-
C{float} or C{as-is} and C{r} the residual of C{as-is}.
|
|
418
|
+
C{float} or C{as-is} and C{r} the residual of C{as-is} or 0.
|
|
410
419
|
'''
|
|
411
420
|
if _isFsum_2Tuple(other):
|
|
412
421
|
s, r = other._fint2
|
|
413
422
|
if r:
|
|
414
|
-
s, r = other.
|
|
423
|
+
s, r = other._nfprs2
|
|
415
424
|
if r: # PYCHOK no cover
|
|
416
425
|
s = other # L{Fsum} as-is
|
|
417
426
|
else:
|
|
@@ -422,17 +431,6 @@ def _2scalar2(other):
|
|
|
422
431
|
return s, r
|
|
423
432
|
|
|
424
433
|
|
|
425
|
-
def _s_r(s, r):
|
|
426
|
-
'''(INTERNAL) Return C{(s, r)}, I{ordered}.
|
|
427
|
-
'''
|
|
428
|
-
if r and _isfinite(s):
|
|
429
|
-
if fabs(s) < fabs(r):
|
|
430
|
-
s, r = r, (s or INT0)
|
|
431
|
-
else:
|
|
432
|
-
r = INT0
|
|
433
|
-
return s, r
|
|
434
|
-
|
|
435
|
-
|
|
436
434
|
def _strcomplex(s, *args):
|
|
437
435
|
'''(INTERNAL) C{Complex} 2- or 3-arg C{pow} error as C{str}.
|
|
438
436
|
'''
|
|
@@ -519,7 +517,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
519
517
|
C{PYGEODESY_FSUM_NONFINITES} and C{PYGEODESY_FSUM_RESIDUAL}.
|
|
520
518
|
'''
|
|
521
519
|
_f2product = _sys_version_info2 > (3, 12) or bool(_F2PRODUCT)
|
|
522
|
-
_isfine = {} # == _isfinite
|
|
520
|
+
_isfine = {} # == _isfinite, see nonfiniterrors()
|
|
523
521
|
_n = 0
|
|
524
522
|
# _ps = [] # partial sums
|
|
525
523
|
# _ps_max = 0 # max(Fsum._ps_max, len(Fsum._ps)) # 41
|
|
@@ -560,14 +558,22 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
560
558
|
@see: Methods L{Fsum.fadd_} and L{Fsum.fadd}.
|
|
561
559
|
'''
|
|
562
560
|
f = self._copy_2(self.__add__)
|
|
563
|
-
return f._fadd(other
|
|
561
|
+
return f._fadd(other)
|
|
564
562
|
|
|
565
563
|
def __bool__(self): # PYCHOK Python 3+
|
|
566
564
|
'''Return C{bool(B{self})}, C{True} iff C{residual} is zero.
|
|
567
565
|
'''
|
|
568
|
-
s, r = self.
|
|
566
|
+
s, r = self._nfprs2
|
|
569
567
|
return bool(s or r) and s != -r # == self != 0
|
|
570
568
|
|
|
569
|
+
def __call__(self, other, **up): # in .fmath
|
|
570
|
+
'''Reset this C{Fsum} to C{other}, default C{B{up}=True}.
|
|
571
|
+
'''
|
|
572
|
+
self._ps[:] = 0, # clear for errors
|
|
573
|
+
self._fset(other, op=_fset_op_, **up)
|
|
574
|
+
return self
|
|
575
|
+
|
|
576
|
+
|
|
571
577
|
def __ceil__(self): # PYCHOK not special in Python 2-
|
|
572
578
|
'''Return this instance' C{math.ceil} as C{int} or C{float}.
|
|
573
579
|
|
|
@@ -609,7 +615,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
609
615
|
'''Return C{(B{self} == B{other})} as C{bool} where B{C{other}}
|
|
610
616
|
is C{scalar}, an other L{Fsum} or L{Fsum2Tuple}.
|
|
611
617
|
'''
|
|
612
|
-
return self._cmp_0(other,
|
|
618
|
+
return self._cmp_0(other, _fset_op_ + _fset_op_) == 0
|
|
613
619
|
|
|
614
620
|
def __float__(self):
|
|
615
621
|
'''Return this instance' current, precision running sum as C{float}.
|
|
@@ -646,7 +652,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
646
652
|
def __ge__(self, other):
|
|
647
653
|
'''Return C{(B{self} >= B{other})}, see C{__eq__}.
|
|
648
654
|
'''
|
|
649
|
-
return self._cmp_0(other,
|
|
655
|
+
return self._cmp_0(other, _gt_op_ + _fset_op_) >= 0
|
|
650
656
|
|
|
651
657
|
def __gt__(self, other):
|
|
652
658
|
'''Return C{(B{self} > B{other})}, see C{__eq__}.
|
|
@@ -674,7 +680,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
674
680
|
@see: Methods L{Fsum.fadd_} and L{Fsum.fadd}.
|
|
675
681
|
'''
|
|
676
682
|
try:
|
|
677
|
-
return self._fadd(other, _iadd_op_)
|
|
683
|
+
return self._fadd(other, op=_iadd_op_)
|
|
678
684
|
except TypeError:
|
|
679
685
|
pass
|
|
680
686
|
_xiterable(other)
|
|
@@ -834,7 +840,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
834
840
|
def __le__(self, other):
|
|
835
841
|
'''Return C{(B{self} <= B{other})}, see C{__eq__}.
|
|
836
842
|
'''
|
|
837
|
-
return self._cmp_0(other,
|
|
843
|
+
return self._cmp_0(other, _lt_op_ + _fset_op_) <= 0
|
|
838
844
|
|
|
839
845
|
def __len__(self):
|
|
840
846
|
'''Return the number of values accumulated (C{int}).
|
|
@@ -896,7 +902,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
896
902
|
@see: Method L{Fsum.__iadd__}.
|
|
897
903
|
'''
|
|
898
904
|
f = self._copy_2r(other, self.__radd__)
|
|
899
|
-
return f._fadd(self
|
|
905
|
+
return f._fadd(self)
|
|
900
906
|
|
|
901
907
|
def __rdivmod__(self, other):
|
|
902
908
|
'''Return C{divmod(B{other}, B{self})} as 2-tuple
|
|
@@ -1030,9 +1036,8 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1030
1036
|
'''
|
|
1031
1037
|
n, r = self._fint2
|
|
1032
1038
|
if r:
|
|
1033
|
-
i, d =
|
|
1034
|
-
n
|
|
1035
|
-
n += i
|
|
1039
|
+
i, d = float(r).as_integer_ratio()
|
|
1040
|
+
n, d = _n_d2(n * d + i, d)
|
|
1036
1041
|
else: # PYCHOK no cover
|
|
1037
1042
|
d = 1
|
|
1038
1043
|
return n, d
|
|
@@ -1042,7 +1047,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1042
1047
|
'''Get this instance I{as-is} (L{Fsum} with C{non-zero residual},
|
|
1043
1048
|
C{scalar} or I{non-finite}).
|
|
1044
1049
|
'''
|
|
1045
|
-
s, r = self.
|
|
1050
|
+
s, r = self._nfprs2
|
|
1046
1051
|
return self if r else s
|
|
1047
1052
|
|
|
1048
1053
|
@property_RO
|
|
@@ -1089,6 +1094,8 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1089
1094
|
f._n = 1
|
|
1090
1095
|
# assert f._f2product == self._f2product
|
|
1091
1096
|
# assert f._Fsum is f
|
|
1097
|
+
# assert f._isfine is self._isfine
|
|
1098
|
+
# assert f._RESIDUAL is self._RESIDUAL
|
|
1092
1099
|
return f
|
|
1093
1100
|
|
|
1094
1101
|
def _copy_2(self, which, name=NN):
|
|
@@ -1101,6 +1108,8 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1101
1108
|
# assert f._n == self._n
|
|
1102
1109
|
# assert f._f2product == self._f2product
|
|
1103
1110
|
# assert f._Fsum is f
|
|
1111
|
+
# assert f._isfine is self._isfine
|
|
1112
|
+
# assert f._RESIDUAL is self._RESIDUAL
|
|
1104
1113
|
return f
|
|
1105
1114
|
|
|
1106
1115
|
def _copy_2r(self, other, which):
|
|
@@ -1130,15 +1139,17 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1130
1139
|
'''(INTERNAL) Format the caught exception C{X}.
|
|
1131
1140
|
'''
|
|
1132
1141
|
E, t = _xError2(X)
|
|
1133
|
-
u = unstr(self.named3, *xs
|
|
1142
|
+
u = unstr(self.named3, *xs, _ELLIPSIS=4, **kwds)
|
|
1134
1143
|
return E(u, txt=t, cause=X)
|
|
1135
1144
|
|
|
1136
|
-
def _facc(self, xs, up=True, **
|
|
1137
|
-
'''(INTERNAL) Accumulate more C{
|
|
1145
|
+
def _facc(self, xs, up=True, **_X_x_origin):
|
|
1146
|
+
'''(INTERNAL) Accumulate more C{scalar}s or L{Fsum}s.
|
|
1138
1147
|
'''
|
|
1139
1148
|
if xs:
|
|
1140
|
-
kwds
|
|
1141
|
-
|
|
1149
|
+
kwds = self._isfine
|
|
1150
|
+
if _X_x_origin:
|
|
1151
|
+
kwds = _xkwds(_X_x_origin, **kwds)
|
|
1152
|
+
fs = _xs(xs, **kwds) # PYCHOK yield
|
|
1142
1153
|
ps = self._ps
|
|
1143
1154
|
ps[:] = self._ps_acc(list(ps), fs, up=up)
|
|
1144
1155
|
return self
|
|
@@ -1147,8 +1158,8 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1147
1158
|
'''(INTERNAL) Accumulate 0, 1 or more C{xs}, all positional
|
|
1148
1159
|
arguments in the caller of this method.
|
|
1149
1160
|
'''
|
|
1150
|
-
return self.
|
|
1151
|
-
self.
|
|
1161
|
+
return self._fadd(xs[0], **up) if len(xs) == 1 else \
|
|
1162
|
+
self._facc(xs, **up) # origin=1?
|
|
1152
1163
|
|
|
1153
1164
|
def _facc_neg(self, xs, **up_origin):
|
|
1154
1165
|
'''(INTERNAL) Accumulate more C{xs}, negated.
|
|
@@ -1197,7 +1208,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1197
1208
|
f *= _pow(x, r, power, op, **raiser_RESIDUAL)
|
|
1198
1209
|
return f
|
|
1199
1210
|
|
|
1200
|
-
f = self._facc(xs,
|
|
1211
|
+
f = self._facc(xs, _X=_P, _x=_p) # origin=1?
|
|
1201
1212
|
else:
|
|
1202
1213
|
f = self._facc_scalar_(float(len(xs))) # x**0 == 1
|
|
1203
1214
|
return f
|
|
@@ -1206,7 +1217,8 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1206
1217
|
'''(INTERNAL) Accumulate all C{xs}, each C{scalar}.
|
|
1207
1218
|
'''
|
|
1208
1219
|
if xs:
|
|
1209
|
-
|
|
1220
|
+
ps = self._ps
|
|
1221
|
+
ps[:] = self._ps_acc(list(ps), xs, **up)
|
|
1210
1222
|
return self
|
|
1211
1223
|
|
|
1212
1224
|
def _facc_scalar_(self, *xs, **up):
|
|
@@ -1214,16 +1226,14 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1214
1226
|
'''
|
|
1215
1227
|
return self._facc_scalar(xs, **up)
|
|
1216
1228
|
|
|
1217
|
-
def _facc_scalarf(self, xs, **origin_which):
|
|
1229
|
+
def _facc_scalarf(self, xs, up=True, **origin_which):
|
|
1218
1230
|
'''(INTERNAL) Accumulate all C{xs}, each C{scalar}, an L{Fsum} or
|
|
1219
1231
|
L{Fsum2Tuple}, like function C{_xsum}.
|
|
1220
1232
|
'''
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
except (OverflowError, TypeError, ValueError) as X:
|
|
1226
|
-
raise _ixError(X, xs, *i_x, **origin_which)
|
|
1233
|
+
_C = self.__class__
|
|
1234
|
+
fs = _xs(xs, **_x_isfine(self.nonfinitesOK, _Cdot=_C,
|
|
1235
|
+
**origin_which)) # PYCHOK yield
|
|
1236
|
+
return self._facc_scalar(fs, up=up)
|
|
1227
1237
|
|
|
1228
1238
|
# def _facc_up(self, up=True):
|
|
1229
1239
|
# '''(INTERNAL) Update the C{partials}, by removing
|
|
@@ -1242,8 +1252,8 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1242
1252
|
def fadd(self, xs=()):
|
|
1243
1253
|
'''Add an iterable's items to this instance.
|
|
1244
1254
|
|
|
1245
|
-
@arg xs: Iterable of items to add (each C{scalar}
|
|
1246
|
-
|
|
1255
|
+
@arg xs: Iterable of items to add (each C{scalar},
|
|
1256
|
+
an L{Fsum} or L{Fsum2Tuple}).
|
|
1247
1257
|
|
|
1248
1258
|
@return: This instance (L{Fsum}).
|
|
1249
1259
|
|
|
@@ -1265,26 +1275,20 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1265
1275
|
def fadd_(self, *xs):
|
|
1266
1276
|
'''Add all positional items to this instance.
|
|
1267
1277
|
|
|
1268
|
-
@arg xs: Values to add (each C{scalar}
|
|
1269
|
-
or L{Fsum2Tuple}
|
|
1278
|
+
@arg xs: Values to add (each C{scalar}, an L{Fsum}
|
|
1279
|
+
or L{Fsum2Tuple}), all positional.
|
|
1270
1280
|
|
|
1271
1281
|
@see: Method L{Fsum.fadd} for further details.
|
|
1272
1282
|
'''
|
|
1273
1283
|
return self._facc_args(xs)
|
|
1274
1284
|
|
|
1275
|
-
def _fadd(self, other, op, **up):
|
|
1285
|
+
def _fadd(self, other, op=_add_op_, **up):
|
|
1276
1286
|
'''(INTERNAL) Apply C{B{self} += B{other}}.
|
|
1277
1287
|
'''
|
|
1278
1288
|
if _isFsum_2Tuple(other):
|
|
1279
|
-
|
|
1280
|
-
self._facc_scalar(other._ps, **up)
|
|
1281
|
-
else:
|
|
1282
|
-
self._fset(other, op=op, **up)
|
|
1289
|
+
self._facc_scalar(other._ps, **up)
|
|
1283
1290
|
elif self._scalar(other, op):
|
|
1284
|
-
|
|
1285
|
-
self._facc_scalar_(other, **up)
|
|
1286
|
-
else:
|
|
1287
|
-
self._fset(other, op=op, **up)
|
|
1291
|
+
self._facc_scalar_(other, **up)
|
|
1288
1292
|
return self
|
|
1289
1293
|
|
|
1290
1294
|
fcopy = copy # for backward compatibility
|
|
@@ -1310,25 +1314,27 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1310
1314
|
# raise self._Error(op, other, _AssertionError, txt__=signOf)
|
|
1311
1315
|
return DivMod2Tuple(q, self) # q is C{int} in Python 3+, but C{float} in Python 2-
|
|
1312
1316
|
|
|
1313
|
-
def _fhorner(self, x, cs,
|
|
1317
|
+
def _fhorner(self, x, cs, where, incx=True): # in .fmath
|
|
1314
1318
|
'''(INTERNAL) Add an L{Fhorner} evaluation of polynomial
|
|
1315
1319
|
C{sum(cs[i] * B{x}**i for i=0..len(cs)-1) if B{incx}
|
|
1316
1320
|
else sum(... i=len(cs)-1..0)}.
|
|
1317
1321
|
'''
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
else
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
if len(cs) > 1 and x:
|
|
1322
|
+
# assert _xiterablen(cs)
|
|
1323
|
+
try:
|
|
1324
|
+
n = len(cs)
|
|
1325
|
+
H = self._Fsum_as(name__=self._fhorner)
|
|
1326
|
+
_m = H._mul_Fsum if _isFsum_2Tuple(x) else \
|
|
1327
|
+
H._mul_scalar
|
|
1328
|
+
if _2finite(x, **self._isfine) and n > 1:
|
|
1326
1329
|
for c in (reversed(cs) if incx else cs):
|
|
1327
|
-
H.
|
|
1328
|
-
H._fadd(c,
|
|
1330
|
+
H._fset(_m(x, _mul_op_), up=False)
|
|
1331
|
+
H._fadd(c, up=False)
|
|
1329
1332
|
else: # x == 0
|
|
1330
|
-
H = cs[0] if
|
|
1331
|
-
self._fadd(H
|
|
1333
|
+
H = cs[0] if n else 0
|
|
1334
|
+
self._fadd(H)
|
|
1335
|
+
except Exception as X:
|
|
1336
|
+
t = unstr(where, x, *cs, _ELLIPSIS=4, incx=incx)
|
|
1337
|
+
raise self._ErrorX(X, _add_op_, t)
|
|
1332
1338
|
return self
|
|
1333
1339
|
|
|
1334
1340
|
def _finite(self, other, op=None):
|
|
@@ -1380,36 +1386,28 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1380
1386
|
def _fint2(self): # see ._fset
|
|
1381
1387
|
'''(INTERNAL) Get 2-tuple (C{int}, I{integer} residual).
|
|
1382
1388
|
'''
|
|
1383
|
-
s,
|
|
1384
|
-
|
|
1389
|
+
s, r = self._nfprs2
|
|
1390
|
+
if _isfinite(s):
|
|
1385
1391
|
i = int(s)
|
|
1386
1392
|
r = (self._ps_1sum(i) if len(self._ps) > 1 else
|
|
1387
1393
|
float(s - i)) or INT0
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1394
|
+
else: # INF, NAN, NINF
|
|
1395
|
+
i = float(s)
|
|
1396
|
+
# r = _NONFINITEr
|
|
1391
1397
|
return i, r # Fsum2Tuple?
|
|
1392
1398
|
|
|
1393
1399
|
@_fint2.setter_ # PYCHOK setter_UNDERscore!
|
|
1394
1400
|
def _fint2(self, s): # in _fset
|
|
1395
1401
|
'''(INTERNAL) Replace the C{_fint2} value.
|
|
1396
1402
|
'''
|
|
1397
|
-
|
|
1403
|
+
if _isfinite(s):
|
|
1398
1404
|
i = int(s)
|
|
1399
1405
|
r = (s - i) or INT0
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1406
|
+
else: # INF, NAN, NINF
|
|
1407
|
+
i = float(s)
|
|
1408
|
+
r = _NONFINITEr
|
|
1403
1409
|
return i, r # like _fint2.getter
|
|
1404
1410
|
|
|
1405
|
-
def _fintX(self, X, i): # PYCHOK X
|
|
1406
|
-
'''(INTERNAL) Handle I{non-finite} C{int}.
|
|
1407
|
-
'''
|
|
1408
|
-
# "cannot convert float infinity to integer"
|
|
1409
|
-
return i # ignore such Overflow-/ValueErrors
|
|
1410
|
-
# op = int.__name__
|
|
1411
|
-
# return self._nonfiniteX(X, op, i)
|
|
1412
|
-
|
|
1413
1411
|
@deprecated_property_RO
|
|
1414
1412
|
def float_int(self): # PYCHOK no cover
|
|
1415
1413
|
'''DEPRECATED, use method C{Fsum.int_float}.'''
|
|
@@ -1456,16 +1454,19 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1456
1454
|
if r:
|
|
1457
1455
|
f = self._f2mul(self.fma, other1, **nonfinites)
|
|
1458
1456
|
f += other2
|
|
1459
|
-
|
|
1457
|
+
elif _residue(other1) or _residue(other2):
|
|
1460
1458
|
fs = _2split3s(_fs(op, other1))
|
|
1461
1459
|
fs = _2products(s, fs, *_fs(op, other2))
|
|
1462
1460
|
f = _Psum(self._ps_acc([], fs, up=False), name=op)
|
|
1461
|
+
else:
|
|
1462
|
+
f = _fma(s, other1, other2)
|
|
1463
|
+
f = _2finite(f, **self._isfine)
|
|
1463
1464
|
except TypeError as X:
|
|
1464
1465
|
raise self._ErrorX(X, op, (other1, other2))
|
|
1465
1466
|
except (OverflowError, ValueError) as X: # from math.fma
|
|
1466
|
-
f
|
|
1467
|
-
f
|
|
1468
|
-
f
|
|
1467
|
+
f = self._mul_reduce(s, other1) # INF, NAN, NINF
|
|
1468
|
+
f += sum(_fs(op, other2))
|
|
1469
|
+
f = self._nonfiniteX(X, op, f, **nonfinites)
|
|
1469
1470
|
return self._fset(f)
|
|
1470
1471
|
|
|
1471
1472
|
fmul = __imul__
|
|
@@ -1524,7 +1525,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1524
1525
|
except TypeError as X:
|
|
1525
1526
|
raise self._ErrorX(X, op, other)
|
|
1526
1527
|
except (OverflowError, ValueError) as X:
|
|
1527
|
-
r = self._mul_reduce(
|
|
1528
|
+
r = self._mul_reduce(sum(ps), other) # INF, NAN, NINF
|
|
1528
1529
|
r = self._nonfiniteX(X, op, r, **nonfinites_raiser)
|
|
1529
1530
|
f._fset(r)
|
|
1530
1531
|
return f
|
|
@@ -1557,7 +1558,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1557
1558
|
elif self.is_integer():
|
|
1558
1559
|
# return an exact C{int} for C{int}**C{int}
|
|
1559
1560
|
i, _ = self._fint2 # assert _ == 0
|
|
1560
|
-
x, r =
|
|
1561
|
+
x, r = _2s_r(other) # C{int}, C{float} or other
|
|
1561
1562
|
f = self._Fsum_as(i)._pow_Fsum(other, op, **raiser_RESIDUAL) if r else \
|
|
1562
1563
|
self._pow_2_3(i, x, other, op, **raiser_RESIDUAL)
|
|
1563
1564
|
else: # mod[0] is None, power(self, other)
|
|
@@ -1631,10 +1632,11 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1631
1632
|
s = ps[0]
|
|
1632
1633
|
r = INT0 if _isfinite(s) else _NONFINITEr
|
|
1633
1634
|
else: # len(ps) == 0
|
|
1634
|
-
s
|
|
1635
|
+
s = _0_0
|
|
1636
|
+
r = INT0 if _isfinite(s) else _NONFINITEr
|
|
1635
1637
|
ps[:] = s,
|
|
1636
1638
|
except (OverflowError, ValueError) as X:
|
|
1637
|
-
op =
|
|
1639
|
+
op = _fset_op_ # INF, NAN, NINF
|
|
1638
1640
|
ps[:] = sum(ps), # collapse ps
|
|
1639
1641
|
s = self._nonfiniteX(X, op, ps[0])
|
|
1640
1642
|
r = _NONFINITEr
|
|
@@ -1658,8 +1660,9 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1658
1660
|
|
|
1659
1661
|
@see: Method L{Fsum.fadd} for further details.
|
|
1660
1662
|
'''
|
|
1661
|
-
f =
|
|
1662
|
-
|
|
1663
|
+
f = (xs[0] if xs else _0_0) if len(xs) < 2 else \
|
|
1664
|
+
Fsum(*xs, nonfinites=self.nonfinites()) # self._Fsum_as(*xs)
|
|
1665
|
+
return self._fset(f, op=_fset_op_)
|
|
1663
1666
|
|
|
1664
1667
|
def _fset(self, other, n=0, up=True, **op):
|
|
1665
1668
|
'''(INTERNAL) Overwrite this instance with an other or a C{scalar}.
|
|
@@ -1667,6 +1670,8 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1667
1670
|
if other is self:
|
|
1668
1671
|
pass # from ._fmul, ._ftruediv and ._pow_0_1
|
|
1669
1672
|
elif _isFsum_2Tuple(other):
|
|
1673
|
+
if op: # and not self.nonfinitesOK:
|
|
1674
|
+
self._finite(other._fprs, **op)
|
|
1670
1675
|
self._ps[:] = other._ps
|
|
1671
1676
|
self._n = n or other._n
|
|
1672
1677
|
if up: # use or zap the C{Property_RO} values
|
|
@@ -1689,11 +1694,6 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1689
1694
|
raise self._Error(op, other, _TypeError)
|
|
1690
1695
|
return self
|
|
1691
1696
|
|
|
1692
|
-
def _fset_ps(self, other): # in .fmath._Fsum__init__
|
|
1693
|
-
'''(INTERNAL) Set partials from a known C{other}.
|
|
1694
|
-
'''
|
|
1695
|
-
return self._fset(other, up=False)
|
|
1696
|
-
|
|
1697
1697
|
def fsub(self, xs=()):
|
|
1698
1698
|
'''Subtract an iterable's items from this instance.
|
|
1699
1699
|
|
|
@@ -1706,8 +1706,8 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1706
1706
|
|
|
1707
1707
|
@see: Method L{Fsum.fadd_} for further details.
|
|
1708
1708
|
'''
|
|
1709
|
-
return self.
|
|
1710
|
-
self.
|
|
1709
|
+
return self._fsub(xs[0], _sub_op_) if len(xs) == 1 else \
|
|
1710
|
+
self._facc_neg(xs) # origin=1?
|
|
1711
1711
|
|
|
1712
1712
|
def _fsub(self, other, op):
|
|
1713
1713
|
'''(INTERNAL) Apply C{B{self} -= B{other}}.
|
|
@@ -1725,8 +1725,8 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1725
1725
|
'''Add an iterable's items, summate and return the current
|
|
1726
1726
|
precision running sum.
|
|
1727
1727
|
|
|
1728
|
-
@arg xs: Iterable of items to add (each item C{scalar}
|
|
1729
|
-
|
|
1728
|
+
@arg xs: Iterable of items to add (each item C{scalar},
|
|
1729
|
+
an L{Fsum} or L{Fsum2Tuple}).
|
|
1730
1730
|
|
|
1731
1731
|
@return: Precision running sum (C{float} or C{int}).
|
|
1732
1732
|
|
|
@@ -1740,8 +1740,8 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1740
1740
|
'''Add any positional items, summate and return the current
|
|
1741
1741
|
precision running sum.
|
|
1742
1742
|
|
|
1743
|
-
@arg xs: Items to add (each C{scalar}
|
|
1744
|
-
|
|
1743
|
+
@arg xs: Items to add (each C{scalar}, an L{Fsum} or
|
|
1744
|
+
L{Fsum2Tuple}), all positional.
|
|
1745
1745
|
|
|
1746
1746
|
@return: Precision running sum (C{float} or C{int}).
|
|
1747
1747
|
|
|
@@ -1765,10 +1765,10 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1765
1765
|
|
|
1766
1766
|
@return: Precision running sum (L{Fsum2Tuple}).
|
|
1767
1767
|
'''
|
|
1768
|
-
return Fsum2Tuple(self._facc_args(xs).
|
|
1768
|
+
return Fsum2Tuple(self._facc_args(xs)._nfprs2, **name)
|
|
1769
1769
|
|
|
1770
1770
|
@property_RO
|
|
1771
|
-
def _Fsum(self): # like L{Fsum2Tuple._Fsum},
|
|
1771
|
+
def _Fsum(self): # like L{Fsum2Tuple._Fsum}, in .fstats
|
|
1772
1772
|
return self # NOT @Property_RO, see .copy and ._copy_2
|
|
1773
1773
|
|
|
1774
1774
|
def _Fsum_as(self, *xs, **name_f2product_nonfinites_RESIDUAL):
|
|
@@ -1782,17 +1782,17 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1782
1782
|
RESIDUAL =self.RESIDUAL())
|
|
1783
1783
|
if name_f2product_nonfinites_RESIDUAL: # overwrites
|
|
1784
1784
|
kwds.update(name_f2product_nonfinites_RESIDUAL)
|
|
1785
|
-
|
|
1786
|
-
# assert all(v == self.__dict__[n] for n, v in
|
|
1787
|
-
return
|
|
1788
|
-
|
|
1785
|
+
f = Fsum(**kwds)
|
|
1786
|
+
# assert all(v == self.__dict__[n] for n, v in f.__dict__.items())
|
|
1787
|
+
return f._fset(xs[0], op=_fset_op_) if len(xs) == 1 else (
|
|
1788
|
+
f._facc(xs, up=False) if xs else f)
|
|
1789
1789
|
|
|
1790
1790
|
def fsum2(self, xs=(), **name):
|
|
1791
1791
|
'''Add an iterable's items, summate and return the
|
|
1792
1792
|
current precision running sum I{and} the C{residual}.
|
|
1793
1793
|
|
|
1794
|
-
@arg xs: Iterable of items to add (each item C{scalar}
|
|
1795
|
-
|
|
1794
|
+
@arg xs: Iterable of items to add (each item C{scalar},
|
|
1795
|
+
an L{Fsum} or L{Fsum2Tuple}).
|
|
1796
1796
|
@kwarg name: Optional C{B{name}=NN} (C{str}).
|
|
1797
1797
|
|
|
1798
1798
|
@return: L{Fsum2Tuple}C{(fsum, residual)} with C{fsum} the
|
|
@@ -1810,8 +1810,8 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1810
1810
|
'''Add any positional items, summate and return the current
|
|
1811
1811
|
precision running sum and the I{differential}.
|
|
1812
1812
|
|
|
1813
|
-
@arg xs: Values to add (each C{scalar}
|
|
1814
|
-
L{Fsum2Tuple}
|
|
1813
|
+
@arg xs: Values to add (each C{scalar}, an L{Fsum} or
|
|
1814
|
+
L{Fsum2Tuple}), all positional.
|
|
1815
1815
|
|
|
1816
1816
|
@return: 2Tuple C{(fsum, delta)} with the current, precision
|
|
1817
1817
|
running C{fsum} like method L{Fsum.fsum} and C{delta},
|
|
@@ -1838,19 +1838,19 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1838
1838
|
'''Like method L{Fsum.fsum_} iff I{all} C{B{xs}}, each I{known to be}
|
|
1839
1839
|
C{scalar}, an L{Fsum} or L{Fsum2Tuple}.
|
|
1840
1840
|
'''
|
|
1841
|
-
return self._facc_scalarf(xs,
|
|
1841
|
+
return self._facc_scalarf(xs, which=self.fsumf_)._fprs # origin=1?
|
|
1842
1842
|
|
|
1843
1843
|
def Fsumf_(self, *xs):
|
|
1844
1844
|
'''Like method L{Fsum.Fsum_} iff I{all} C{B{xs}}, each I{known to be}
|
|
1845
1845
|
C{scalar}, an L{Fsum} or L{Fsum2Tuple}.
|
|
1846
1846
|
'''
|
|
1847
|
-
return self._facc_scalarf(xs,
|
|
1847
|
+
return self._facc_scalarf(xs, which=self.Fsumf_)._copy_2(self.Fsumf_) # origin=1?
|
|
1848
1848
|
|
|
1849
1849
|
def fsum2f_(self, *xs):
|
|
1850
1850
|
'''Like method L{Fsum.fsum2_} iff I{all} C{B{xs}}, each I{known to be}
|
|
1851
1851
|
C{scalar}, an L{Fsum} or L{Fsum2Tuple}.
|
|
1852
1852
|
'''
|
|
1853
|
-
return self._fsum2(xs, self._facc_scalarf,
|
|
1853
|
+
return self._fsum2(xs, self._facc_scalarf, which=self.fsum2f_) # origin=1?
|
|
1854
1854
|
|
|
1855
1855
|
# ftruediv = __itruediv__ # for naming consistency?
|
|
1856
1856
|
|
|
@@ -1891,8 +1891,9 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1891
1891
|
L{ResidualError}s (C{bool}) and C{B{RESIDUAL}=scalar}
|
|
1892
1892
|
to override the current L{RESIDUAL<Fsum.RESIDUAL>}.
|
|
1893
1893
|
|
|
1894
|
-
@return: This C{int} sum if this instance C{is_integer}
|
|
1895
|
-
the C{float} sum if the residual
|
|
1894
|
+
@return: This C{int} sum if this instance C{is_integer} and
|
|
1895
|
+
I{finite}, otherwise the C{float} sum if the residual
|
|
1896
|
+
is zero or not significant.
|
|
1896
1897
|
|
|
1897
1898
|
@raise ResidualError: Non-zero, significant residual or invalid
|
|
1898
1899
|
B{C{RESIDUAL}}.
|
|
@@ -1951,48 +1952,52 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1951
1952
|
return _sum is _fsum # _fsum.__module__ is fabs.__module__
|
|
1952
1953
|
|
|
1953
1954
|
def is_scalar(self, **raiser_RESIDUAL):
|
|
1954
|
-
'''Is this instance' running sum C{scalar}
|
|
1955
|
+
'''Is this instance' running sum C{scalar} with C{0} residual or with
|
|
1955
1956
|
a residual I{ratio} not exceeding the RESIDUAL threshold?
|
|
1956
1957
|
|
|
1957
1958
|
@kwarg raiser_RESIDUAL: Use C{B{raiser}=False} to ignore
|
|
1958
1959
|
L{ResidualError}s (C{bool}) and C{B{RESIDUAL}=scalar}
|
|
1959
1960
|
to override the current L{RESIDUAL<Fsum.RESIDUAL>}.
|
|
1960
1961
|
|
|
1961
|
-
@return: C{True} if this instance'
|
|
1962
|
-
|
|
1962
|
+
@return: C{True} if this instance' residual is C{0} or C{insignificant},
|
|
1963
|
+
i.e. its residual C{ratio} doesn't exceed the L{RESIDUAL
|
|
1964
|
+
<Fsum.RESIDUAL>} threshold (C{bool}).
|
|
1963
1965
|
|
|
1964
1966
|
@raise ResidualError: Non-zero, significant residual or invalid
|
|
1965
1967
|
B{C{RESIDUAL}}.
|
|
1966
1968
|
|
|
1967
|
-
@see:
|
|
1969
|
+
@see: Methods L{Fsum.RESIDUAL} and L{Fsum.is_integer} and property
|
|
1968
1970
|
L{Fsum.as_iscalar}.
|
|
1969
1971
|
'''
|
|
1970
1972
|
s, r = self._fprs2
|
|
1971
1973
|
return False if r and self._raiser(r, s, **raiser_RESIDUAL) else True
|
|
1972
1974
|
|
|
1973
|
-
def _mul_Fsum(self, other, op
|
|
1975
|
+
def _mul_Fsum(self, other, op):
|
|
1974
1976
|
'''(INTERNAL) Return C{B{self} * B{other}} as L{Fsum} or C{0}.
|
|
1975
1977
|
'''
|
|
1976
1978
|
# assert _isFsum_2Tuple(other)
|
|
1977
1979
|
if self._ps and other._ps:
|
|
1978
|
-
|
|
1980
|
+
try:
|
|
1981
|
+
f = self._ps_mul(op, *other._ps) # NO .as_iscalar!
|
|
1982
|
+
except Exception as X:
|
|
1983
|
+
raise self._ErrorX(X, op, other)
|
|
1979
1984
|
else:
|
|
1980
1985
|
f = _0_0
|
|
1981
1986
|
return f
|
|
1982
1987
|
|
|
1983
|
-
def _mul_reduce(self,
|
|
1984
|
-
'''(INTERNAL) Like fmath.
|
|
1985
|
-
for I{non-finite} C{start} and/or C{others}.
|
|
1988
|
+
def _mul_reduce(self, *others):
|
|
1989
|
+
'''(INTERNAL) Like fmath.fprod for I{non-finite} C{other}s.
|
|
1986
1990
|
'''
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1991
|
+
r = _1_0
|
|
1992
|
+
for f in others:
|
|
1993
|
+
r *= sum(f._ps) if _isFsum_2Tuple(f) else float(f)
|
|
1994
|
+
return r
|
|
1990
1995
|
|
|
1991
|
-
def _mul_scalar(self, factor, op):
|
|
1996
|
+
def _mul_scalar(self, factor, op):
|
|
1992
1997
|
'''(INTERNAL) Return C{B{self} * scalar B{factor}} as L{Fsum}, C{0.0} or C{self}.
|
|
1993
1998
|
'''
|
|
1994
1999
|
# assert isscalar(factor)
|
|
1995
|
-
if self._ps and self._finite(factor, op):
|
|
2000
|
+
if self._ps and self._finite(factor, op=op):
|
|
1996
2001
|
f = self if factor == _1_0 else (
|
|
1997
2002
|
self._neg if factor == _N_1_0 else
|
|
1998
2003
|
self._ps_mul(op, factor).as_iscalar)
|
|
@@ -2011,6 +2016,16 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
2011
2016
|
'''
|
|
2012
2017
|
return _Psum(self._ps_neg) if self._ps else NEG0
|
|
2013
2018
|
|
|
2019
|
+
@property_RO
|
|
2020
|
+
def _nfprs2(self):
|
|
2021
|
+
'''(INTERNAL) Handle I{non-finite} C{_fprs2}.
|
|
2022
|
+
'''
|
|
2023
|
+
try: # to handle nonfiniterrors, etc.
|
|
2024
|
+
t = self._fprs2
|
|
2025
|
+
except (OverflowError, ValueError):
|
|
2026
|
+
t = Fsum2Tuple(sum(self._ps), _NONFINITEr)
|
|
2027
|
+
return t
|
|
2028
|
+
|
|
2014
2029
|
def nonfinites(self, *OK):
|
|
2015
2030
|
'''Handle I{non-finite} C{float}s as C{inf}, C{INF}, C{NINF}, C{nan}
|
|
2016
2031
|
and C{NAN} for this L{Fsum} or throw C{OverflowError} respectively
|
|
@@ -2048,10 +2063,10 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
2048
2063
|
def nonfinitesOK(self):
|
|
2049
2064
|
'''Are I{non-finites} C{OK} for this L{Fsum} or by default? (C{bool}).
|
|
2050
2065
|
'''
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
return
|
|
2066
|
+
# nf = self.nonfinites()
|
|
2067
|
+
# if nf is None:
|
|
2068
|
+
# nf = not nonfiniterrors()
|
|
2069
|
+
return _isOK_or_finite(INF, **self._isfine)
|
|
2055
2070
|
|
|
2056
2071
|
def _nonfiniteX(self, X, op, f, nonfinites=None, raiser=None):
|
|
2057
2072
|
'''(INTERNAL) Handle a I{non-finite} exception.
|
|
@@ -2122,7 +2137,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
2122
2137
|
if _isFsum_2Tuple(other):
|
|
2123
2138
|
f = self._pow_Fsum(other, op, **raiser_RESIDUAL)
|
|
2124
2139
|
elif self._scalar(other, op):
|
|
2125
|
-
x = self._finite(other, op)
|
|
2140
|
+
x = self._finite(other, op=op)
|
|
2126
2141
|
f = self._pow_scalar(x, other, op, **raiser_RESIDUAL)
|
|
2127
2142
|
else:
|
|
2128
2143
|
f = self._pow_0_1(0, other)
|
|
@@ -2149,7 +2164,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
2149
2164
|
return s
|
|
2150
2165
|
|
|
2151
2166
|
b = _s(*(b._fprs2 if m is None else b._fint2))
|
|
2152
|
-
x = _s(*
|
|
2167
|
+
x = _s(*_2s_r(x))
|
|
2153
2168
|
|
|
2154
2169
|
try:
|
|
2155
2170
|
# 0**INF == 0.0, 1**INF == 1.0, -1**2.3 == -(1**2.3)
|
|
@@ -2157,7 +2172,8 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
2157
2172
|
if iscomplex(s):
|
|
2158
2173
|
# neg**frac == complex in Python 3+, but ValueError in 2-
|
|
2159
2174
|
raise ValueError(_strcomplex(s, b, x, *mod))
|
|
2160
|
-
|
|
2175
|
+
_ = _2finite(s, **self._isfine) # ignore float
|
|
2176
|
+
return s
|
|
2161
2177
|
except Exception as X:
|
|
2162
2178
|
raise self._ErrorX(X, op, other, *mod)
|
|
2163
2179
|
|
|
@@ -2258,13 +2274,12 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
2258
2274
|
n += 1
|
|
2259
2275
|
if n:
|
|
2260
2276
|
self._n += n
|
|
2261
|
-
# if _fi: # collapse ps if non-finite
|
|
2262
|
-
# x = sum(ps)
|
|
2263
|
-
# if not _isfinite(x):
|
|
2264
|
-
# ps[:] = x,
|
|
2265
2277
|
# Fsum._ps_max = max(Fsum._ps_max, len(ps))
|
|
2266
2278
|
if up:
|
|
2267
2279
|
self._update()
|
|
2280
|
+
# x = sum(ps)
|
|
2281
|
+
# if not _isOK_or_finite(x, **fi):
|
|
2282
|
+
# ps[:] = x, # collapse ps
|
|
2268
2283
|
return ps
|
|
2269
2284
|
|
|
2270
2285
|
def _ps_mul(self, op, *factors):
|
|
@@ -2285,7 +2300,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
2285
2300
|
|
|
2286
2301
|
for p in ps:
|
|
2287
2302
|
for f in _pfs(p, fs):
|
|
2288
|
-
yield f if _isfine(f) else
|
|
2303
|
+
yield f if _isfine(f) else _nfError(f)
|
|
2289
2304
|
|
|
2290
2305
|
fs = _psfs(self._ps, factors, **self._isfine)
|
|
2291
2306
|
f = _Psum(self._ps_acc([], fs, up=False), name=op)
|
|
@@ -2298,15 +2313,14 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
2298
2313
|
for p in self._ps:
|
|
2299
2314
|
yield -p
|
|
2300
2315
|
|
|
2301
|
-
def _ps_other(self, op,
|
|
2302
|
-
'''(INTERNAL) Yield
|
|
2316
|
+
def _ps_other(self, op, other):
|
|
2317
|
+
'''(INTERNAL) Yield C{other} as C{scalar}s.
|
|
2303
2318
|
'''
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
yield self._scalar(other, op)
|
|
2319
|
+
if _isFsum_2Tuple(other):
|
|
2320
|
+
for p in other._ps:
|
|
2321
|
+
yield p
|
|
2322
|
+
else:
|
|
2323
|
+
yield self._scalar(other, op)
|
|
2310
2324
|
|
|
2311
2325
|
def _ps_1sum(self, *less):
|
|
2312
2326
|
'''(INTERNAL) Return the partials sum, 1-primed C{less} some scalars.
|
|
@@ -2434,7 +2448,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
2434
2448
|
|
|
2435
2449
|
@return: The sign (C{int}, -1, 0 or +1).
|
|
2436
2450
|
'''
|
|
2437
|
-
s, r = self.
|
|
2451
|
+
s, r = self._nfprs2
|
|
2438
2452
|
r = (-r) if res else 0
|
|
2439
2453
|
return _signOf(s, r)
|
|
2440
2454
|
|
|
@@ -2462,7 +2476,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
2462
2476
|
if lenc:
|
|
2463
2477
|
p = Fmt.SQUARE(p, len(self))
|
|
2464
2478
|
n = _enquote(self.name, white=_UNDER_)
|
|
2465
|
-
t = self.
|
|
2479
|
+
t = self._nfprs2.toStr(**prec_sep_fmt)
|
|
2466
2480
|
return NN(p, _SPACE_, n, t)
|
|
2467
2481
|
|
|
2468
2482
|
def _truediv(self, other, op, **raiser_RESIDUAL):
|
|
@@ -2697,7 +2711,7 @@ def fsum_(*xs, **nonfinites):
|
|
|
2697
2711
|
|
|
2698
2712
|
@see: Function L{fsum<fsums.fsum>} for further details.
|
|
2699
2713
|
'''
|
|
2700
|
-
return _xsum(fsum_, xs,
|
|
2714
|
+
return _xsum(fsum_, xs, **nonfinites) if xs else _0_0 # origin=1?
|
|
2701
2715
|
|
|
2702
2716
|
|
|
2703
2717
|
def fsumf_(*xs):
|
|
@@ -2708,7 +2722,7 @@ def fsumf_(*xs):
|
|
|
2708
2722
|
|
|
2709
2723
|
@see: Function L{fsum_<fsums.fsum_>} for further details.
|
|
2710
2724
|
'''
|
|
2711
|
-
return _xsum(fsumf_, xs, nonfinites=True
|
|
2725
|
+
return _xsum(fsumf_, xs, nonfinites=True) if xs else _0_0 # origin=1?
|
|
2712
2726
|
|
|
2713
2727
|
|
|
2714
2728
|
def fsum1(xs, **nonfinites):
|
|
@@ -2730,7 +2744,7 @@ def fsum1_(*xs, **nonfinites):
|
|
|
2730
2744
|
|
|
2731
2745
|
@see: Function L{fsum_<fsums.fsum_>} for further details.
|
|
2732
2746
|
'''
|
|
2733
|
-
return _xsum(fsum1_, xs,
|
|
2747
|
+
return _xsum(fsum1_, xs, primed=1, **nonfinites) if xs else _0_0 # origin=1?
|
|
2734
2748
|
|
|
2735
2749
|
|
|
2736
2750
|
def fsum1f_(*xs):
|
|
@@ -2742,34 +2756,48 @@ def fsum1f_(*xs):
|
|
|
2742
2756
|
return _xsum(fsum1f_, xs, nonfinites=True, primed=1) if xs else _0_0
|
|
2743
2757
|
|
|
2744
2758
|
|
|
2745
|
-
def
|
|
2746
|
-
|
|
2747
|
-
|
|
2748
|
-
|
|
2749
|
-
|
|
2750
|
-
i_x[:] = i, x
|
|
2751
|
-
if _isFsum_2Tuple(x):
|
|
2752
|
-
for p in map(_x, x._ps):
|
|
2753
|
-
yield p
|
|
2754
|
-
else:
|
|
2755
|
-
yield _x(x)
|
|
2759
|
+
def _x_isfine(nfOK, **kwds): # get the C{_x} and C{_isfine} handlers.
|
|
2760
|
+
_x_kwds = dict(_x= (_passarg if nfOK else _2finite),
|
|
2761
|
+
_isfine=(_isOK if nfOK else _isfinite)) # PYCHOK kwds
|
|
2762
|
+
_x_kwds.update(kwds)
|
|
2763
|
+
return _x_kwds
|
|
2756
2764
|
|
|
2757
2765
|
|
|
2758
|
-
def
|
|
2759
|
-
|
|
2766
|
+
def _X_ps(X): # default C{_X} handler
|
|
2767
|
+
return X._ps # lambda X: X._ps
|
|
2768
|
+
|
|
2769
|
+
|
|
2770
|
+
def _xs(xs, _X=_X_ps, _x=float, _isfine=_isfinite, # defaults for Fsum._facc
|
|
2771
|
+
origin=0, which=None, **_Cdot):
|
|
2772
|
+
'''(INTERNAL) Yield each C{xs} item as 1 or more C{float}s.
|
|
2760
2773
|
'''
|
|
2761
|
-
|
|
2774
|
+
i, x = 0, xs
|
|
2762
2775
|
try:
|
|
2763
|
-
|
|
2764
|
-
|
|
2765
|
-
|
|
2766
|
-
|
|
2767
|
-
|
|
2768
|
-
|
|
2776
|
+
for i, x in enumerate(_xiterable(xs)):
|
|
2777
|
+
if isinstance(x, _Fsum_2Tuple_types):
|
|
2778
|
+
for p in _X(x):
|
|
2779
|
+
yield p if _isfine(p) else _nfError(p)
|
|
2780
|
+
else:
|
|
2781
|
+
f = _x(x)
|
|
2782
|
+
yield f if _isfine(f) else _nfError(f)
|
|
2783
|
+
|
|
2769
2784
|
except (OverflowError, TypeError, ValueError) as X:
|
|
2770
|
-
|
|
2771
|
-
|
|
2772
|
-
|
|
2785
|
+
t = _xsError(X, xs, i + origin, x)
|
|
2786
|
+
if which: # prefix invokation
|
|
2787
|
+
w = unstr(which, *xs, _ELLIPSIS=4, **_Cdot)
|
|
2788
|
+
t = _COMMASPACE_(w, t)
|
|
2789
|
+
raise _xError(X, t, txt=None)
|
|
2790
|
+
|
|
2791
|
+
|
|
2792
|
+
def _xsum(which, xs, nonfinites=None, primed=0, **floats): # origin=0
|
|
2793
|
+
'''(INTERNAL) Precision summation of C{xs} with conditions.
|
|
2794
|
+
'''
|
|
2795
|
+
if floats: # for backward compatibility
|
|
2796
|
+
nonfinites = _xkwds_get1(floats, floats=nonfinites)
|
|
2797
|
+
elif nonfinites is None:
|
|
2798
|
+
nonfinites = not nonfiniterrors()
|
|
2799
|
+
fs = _xs(xs, **_x_isfine(nonfinites, which=which))
|
|
2800
|
+
return _fsum(_1primed(fs) if primed else fs)
|
|
2773
2801
|
|
|
2774
2802
|
|
|
2775
2803
|
# delete all decorators, etc.
|