pygeodesy 24.9.24__py2.py3-none-any.whl → 24.9.29__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.24.dist-info → PyGeodesy-24.9.29.dist-info}/METADATA +3 -3
- {PyGeodesy-24.9.24.dist-info → PyGeodesy-24.9.29.dist-info}/RECORD +15 -15
- pygeodesy/__init__.py +1 -1
- pygeodesy/basics.py +5 -5
- pygeodesy/booleans.py +3 -4
- pygeodesy/constants.py +4 -2
- pygeodesy/ellipsoidalBaseDI.py +4 -4
- pygeodesy/errors.py +9 -1
- pygeodesy/fmath.py +20 -19
- pygeodesy/formy.py +2 -1
- pygeodesy/fstats.py +6 -6
- pygeodesy/fsums.py +260 -212
- pygeodesy/streprs.py +14 -7
- {PyGeodesy-24.9.24.dist-info → PyGeodesy-24.9.29.dist-info}/WHEEL +0 -0
- {PyGeodesy-24.9.24.dist-info → PyGeodesy-24.9.29.dist-info}/top_level.txt +0 -0
pygeodesy/fsums.py
CHANGED
|
@@ -47,7 +47,8 @@ from pygeodesy.constants import INF, INT0, MANT_DIG, NEG0, NINF, _0_0, \
|
|
|
47
47
|
Float, Int
|
|
48
48
|
from pygeodesy.errors import _AssertionError, _OverflowError, _TypeError, \
|
|
49
49
|
_ValueError, _xError, _xError2, _xkwds_get, \
|
|
50
|
-
_xkwds, _xkwds_get1, _xkwds_not, _xkwds_pop
|
|
50
|
+
_xkwds, _xkwds_get1, _xkwds_not, _xkwds_pop, \
|
|
51
|
+
_xsError
|
|
51
52
|
from pygeodesy.internals import _enquote, _passarg
|
|
52
53
|
from pygeodesy.interns import NN, _arg_, _COMMASPACE_, _DOT_, _from_, \
|
|
53
54
|
_not_finite_, _SPACE_, _std_, _UNDER_
|
|
@@ -64,7 +65,7 @@ from math import fabs, isinf, isnan, \
|
|
|
64
65
|
ceil as _ceil, floor as _floor # PYCHOK used! .ltp
|
|
65
66
|
|
|
66
67
|
__all__ = _ALL_LAZY.fsums
|
|
67
|
-
__version__ = '24.09.
|
|
68
|
+
__version__ = '24.09.29'
|
|
68
69
|
|
|
69
70
|
from pygeodesy.interns import (
|
|
70
71
|
_PLUS_ as _add_op_, # in .auxilats.auxAngle
|
|
@@ -86,12 +87,12 @@ _iadd_op_ = _add_op_ + _fset_op_ # in .auxilats.auxAngle, .fstats
|
|
|
86
87
|
_integer_ = 'integer'
|
|
87
88
|
_isub_op_ = _sub_op_ + _fset_op_ # in .auxilats.auxAngle
|
|
88
89
|
_le_op_ = _lt_op_ + _fset_op_
|
|
89
|
-
|
|
90
|
+
_NONFINITEr = _0_0
|
|
91
|
+
_NONFINITES = _getenv('PYGEODESY_FSUM_NONFINITES', NN)
|
|
90
92
|
_non_zero_ = 'non-zero'
|
|
91
93
|
_pow_op_ = _mul_op_ * 2 # _DSTAR_
|
|
92
94
|
_RESIDUAL_0_0 = _getenv('PYGEODESY_FSUM_RESIDUAL', _0_0)
|
|
93
95
|
_significant_ = 'significant'
|
|
94
|
-
_2split3s = _passarg
|
|
95
96
|
_threshold_ = 'threshold'
|
|
96
97
|
|
|
97
98
|
|
|
@@ -102,15 +103,15 @@ def _2finite(x): # in .fstats
|
|
|
102
103
|
else _nfError(x))
|
|
103
104
|
|
|
104
105
|
|
|
105
|
-
def _2float(index=None, _isfine=_isfinite, **
|
|
106
|
-
'''(INTERNAL) Raise C{TypeError} or C{ValueError} if not
|
|
106
|
+
def _2float(index=None, _isfine=_isfinite, **name_x): # in .fmath, .fstats
|
|
107
|
+
'''(INTERNAL) Raise C{TypeError} or C{Overflow-/ValueError} if not finite.
|
|
107
108
|
'''
|
|
108
|
-
n,
|
|
109
|
+
n, x = name_x.popitem() # _xkwds_item2(name_x)
|
|
109
110
|
try:
|
|
110
|
-
f = float(
|
|
111
|
-
return f if _isfine(f) else _nfError(
|
|
111
|
+
f = float(x)
|
|
112
|
+
return f if _isfine(f) else _nfError(x)
|
|
112
113
|
except Exception as X:
|
|
113
|
-
raise _xError(X, Fmt.INDEX(n, index),
|
|
114
|
+
raise _xError(X, Fmt.INDEX(n, index), x)
|
|
114
115
|
|
|
115
116
|
|
|
116
117
|
def _X_ps(X): # for _2floats only
|
|
@@ -122,7 +123,7 @@ def _2floats(xs, origin=0, _X=_X_ps, _x=float, _isfine=_isfinite):
|
|
|
122
123
|
'''
|
|
123
124
|
try:
|
|
124
125
|
i, x = origin, xs
|
|
125
|
-
_FsT =
|
|
126
|
+
_FsT = _Fsum_2Tuple_types
|
|
126
127
|
for x in _xiterable(xs):
|
|
127
128
|
if isinstance(x, _FsT):
|
|
128
129
|
for p in _X(x._Fsum):
|
|
@@ -135,32 +136,28 @@ def _2floats(xs, origin=0, _X=_X_ps, _x=float, _isfine=_isfinite):
|
|
|
135
136
|
raise _xsError(X, xs, i, x)
|
|
136
137
|
|
|
137
138
|
|
|
138
|
-
try: # MCCABE
|
|
139
|
+
try: # MCCABE 26
|
|
139
140
|
from math import fma as _fma
|
|
140
|
-
except ImportError: # Python 3.12-
|
|
141
141
|
|
|
142
|
-
|
|
143
|
-
|
|
142
|
+
def _2products(x, ys, *zs):
|
|
143
|
+
# yield(x * y for y in ys) + yield(z in zs)
|
|
144
|
+
# TwoProductFMA U{Algorithm 3.5
|
|
145
|
+
# <https://www.TUHH.De/ti3/paper/rump/OgRuOi05.pdf>}
|
|
146
|
+
for y in ys:
|
|
147
|
+
f = x * y
|
|
148
|
+
yield f
|
|
149
|
+
yield _fma(x, y, -f)
|
|
150
|
+
for z in zs:
|
|
151
|
+
yield z
|
|
144
152
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
# the same accuracy, but ~13x slower
|
|
148
|
-
b3s = _2split3(b),
|
|
149
|
-
r = fsumf_(c, *_2products(a, b3s)) # two=True
|
|
150
|
-
return r if _isfinite(r) else _fmaX(r, a, b, c)
|
|
153
|
+
# _2split3 = \
|
|
154
|
+
_2split3s = _passarg # in Fsum.is_math_fma
|
|
151
155
|
|
|
152
|
-
|
|
153
|
-
# Split U{Algorithm 3.2
|
|
154
|
-
# <https://www.TUHH.De/ti3/paper/rump/OgRuOi05.pdf>}
|
|
155
|
-
a = c = x * _2FACTOR
|
|
156
|
-
a -= c - x
|
|
157
|
-
b = x - a
|
|
158
|
-
return x, a, b
|
|
156
|
+
except ImportError: # PYCHOK DSPACE! Python 3.12-
|
|
159
157
|
|
|
160
|
-
|
|
161
|
-
|
|
158
|
+
if _F2PRODUCT and _F2PRODUCT != _std_:
|
|
159
|
+
# back to PyGeodesy 24.09.09, with _fmaX
|
|
162
160
|
|
|
163
|
-
else:
|
|
164
161
|
def _fma(*a_b_c): # PYCHOK no cover
|
|
165
162
|
# mimick C{math.fma} from Python 3.13+,
|
|
166
163
|
# the same accuracy, but ~14x slower
|
|
@@ -179,51 +176,68 @@ except ImportError: # Python 3.12-
|
|
|
179
176
|
return x.as_integer_ratio()
|
|
180
177
|
except (AttributeError, OverflowError, TypeError, ValueError):
|
|
181
178
|
return (x if isint(x) else float(x)), 1
|
|
179
|
+
else:
|
|
180
|
+
|
|
181
|
+
def _fma(a, b, c): # PYCHOK redef
|
|
182
|
+
# mimick C{math.fma} from Python 3.13+,
|
|
183
|
+
# the same accuracy, but ~13x slower
|
|
184
|
+
b3s = _2split3(b), # 1-tuple of 3-tuple
|
|
185
|
+
r = _fsum(_2products(a, b3s, c))
|
|
186
|
+
return r if _isfinite(r) else _fmaX(r, a, b, c)
|
|
187
|
+
|
|
188
|
+
_2n_d = None # redef
|
|
182
189
|
|
|
183
190
|
def _fmaX(r, *a_b_c): # like Python 3.13+ I{Modules/mathmodule.c}:
|
|
184
191
|
# raise a ValueError for a NAN result from non-NAN C{a_b_c}s or
|
|
185
192
|
# OverflowError for a non-NAN result from all finite C{a_b_c}s.
|
|
186
193
|
if isnan(r):
|
|
187
|
-
def
|
|
194
|
+
def _x(x):
|
|
188
195
|
return not isnan(x)
|
|
189
196
|
else:
|
|
190
|
-
|
|
191
|
-
if all(map(
|
|
197
|
+
_x = _isfinite
|
|
198
|
+
if all(map(_x, a_b_c)):
|
|
192
199
|
raise _nfError(r, unstr(_fma, *a_b_c))
|
|
193
200
|
return r
|
|
194
201
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
def _2products(x, ys, **unused):
|
|
198
|
-
# TwoProductFMA U{Algorithm 3.5
|
|
199
|
-
# <https://www.TUHH.De/ti3/paper/rump/OgRuOi05.pdf>}
|
|
200
|
-
for y in ys:
|
|
201
|
-
f = x * y
|
|
202
|
-
yield f
|
|
203
|
-
yield _fma(x, y, -f)
|
|
204
|
-
|
|
205
|
-
else: # in _std_ _fma(a, b, c)
|
|
206
|
-
|
|
207
|
-
def _2products(x, y3s, two=False): # PYCHOK redef
|
|
202
|
+
def _2products(x, y3s, *zs): # PYCHOK in Fsum._f2mul
|
|
203
|
+
# yield(x * y3 for y3 in y3s) + yield(z in zs)
|
|
208
204
|
# TwoProduct U{Algorithm 3.3
|
|
209
205
|
# <https://www.TUHH.De/ti3/paper/rump/OgRuOi05.pdf>}
|
|
210
|
-
# also in Python 3.13+ C{Modules/
|
|
206
|
+
# also in Python 3.13+ C{Modules/mathmodule.c} under
|
|
211
207
|
# #ifndef UNRELIABLE_FMA ... #else ... #endif
|
|
212
208
|
_, a, b = _2split3(x)
|
|
213
209
|
for y, c, d in y3s:
|
|
214
210
|
y *= x
|
|
215
211
|
yield y
|
|
216
|
-
if
|
|
212
|
+
if False: # no cover
|
|
217
213
|
yield b * d - (((y - a * c) - b * c) - a * d)
|
|
218
214
|
# = b * d + (a * d - ((y - a * c) - b * c))
|
|
219
215
|
# = b * d + (a * d + (b * c - (y - a * c)))
|
|
220
216
|
# = b * d + (a * d + (b * c + (a * c - y)))
|
|
221
|
-
|
|
217
|
+
elif a:
|
|
222
218
|
yield a * c - y
|
|
223
219
|
yield b * c
|
|
224
220
|
if d:
|
|
225
221
|
yield a * d
|
|
226
222
|
yield b * d
|
|
223
|
+
else:
|
|
224
|
+
yield b * c - y
|
|
225
|
+
yield b * d
|
|
226
|
+
for z in zs:
|
|
227
|
+
yield z
|
|
228
|
+
|
|
229
|
+
_2FACTOR = pow(2, (MANT_DIG + 1) // 2) + _1_0 # 134217729 if MANT_DIG == 53
|
|
230
|
+
|
|
231
|
+
def _2split3(x):
|
|
232
|
+
# Split U{Algorithm 3.2
|
|
233
|
+
# <https://www.TUHH.De/ti3/paper/rump/OgRuOi05.pdf>}
|
|
234
|
+
a = c = x * _2FACTOR
|
|
235
|
+
a -= c - x
|
|
236
|
+
b = x - a
|
|
237
|
+
return x, a, b
|
|
238
|
+
|
|
239
|
+
def _2split3s(xs): # in Fsum.is_math_fma
|
|
240
|
+
return map(_2split3, xs)
|
|
227
241
|
|
|
228
242
|
|
|
229
243
|
def f2product(*two):
|
|
@@ -246,15 +260,15 @@ def f2product(*two):
|
|
|
246
260
|
|
|
247
261
|
|
|
248
262
|
def _Fsumf_(*xs): # in .auxLat, .ltp, ...
|
|
249
|
-
'''(INTERNAL) An C{Fsum}
|
|
263
|
+
'''(INTERNAL) An C{Fsum(xs)}, all C{scalar}, an L{Fsum} or L{Fsum2Tuple}.
|
|
250
264
|
'''
|
|
251
|
-
return Fsum().
|
|
265
|
+
return Fsum()._facc_scalarf(xs, up=False)
|
|
252
266
|
|
|
253
267
|
|
|
254
268
|
def _Fsum1f_(*xs): # in .albers
|
|
255
|
-
'''(INTERNAL) An C{Fsum}
|
|
269
|
+
'''(INTERNAL) An C{Fsum(xs)}, all C{scalar}, an L{Fsum} or L{Fsum2Tuple}, 1-primed.
|
|
256
270
|
'''
|
|
257
|
-
return Fsum().
|
|
271
|
+
return Fsum()._facc_scalarf(_1primed(xs), up=False)
|
|
258
272
|
|
|
259
273
|
|
|
260
274
|
def _2halfeven(s, r, p):
|
|
@@ -275,14 +289,14 @@ def _isFsum(x): # in .fmath
|
|
|
275
289
|
return isinstance(x, Fsum)
|
|
276
290
|
|
|
277
291
|
|
|
278
|
-
def
|
|
292
|
+
def _isFsum_2Tuple(x): # in .basics, .constants, .fmath, .fstats
|
|
279
293
|
'''(INTERNAL) Is C{x} an C{Fsum} or C{Fsum2Tuple} instance?
|
|
280
294
|
'''
|
|
281
|
-
return isinstance(x,
|
|
295
|
+
return isinstance(x, _Fsum_2Tuple_types)
|
|
282
296
|
|
|
283
297
|
|
|
284
298
|
def _isOK(unused):
|
|
285
|
-
'''(INTERNAL) Helper for C{
|
|
299
|
+
'''(INTERNAL) Helper for C{Fsum._fsum2} and C{Fsum.nonfinites}.
|
|
286
300
|
'''
|
|
287
301
|
return True
|
|
288
302
|
|
|
@@ -294,12 +308,21 @@ def _isOK_or_finite(x, _isfine=_isfinite):
|
|
|
294
308
|
return _isfine(x)
|
|
295
309
|
|
|
296
310
|
|
|
311
|
+
def _ixError(X, xs, i, x, origin=0, which=None):
|
|
312
|
+
'''(INTERNAL) Error for C{xs} or C{x}, item C{xs[i]}.
|
|
313
|
+
'''
|
|
314
|
+
t = _xsError(X, xs, i + origin, x)
|
|
315
|
+
if which:
|
|
316
|
+
t = _COMMASPACE_(unstr(which, _Cdot=Fsum), t)
|
|
317
|
+
return _xError(X, t, txt=None)
|
|
318
|
+
|
|
319
|
+
|
|
297
320
|
def _nfError(x, *args):
|
|
298
321
|
'''(INTERNAL) Throw a C{not-finite} exception.
|
|
299
322
|
'''
|
|
300
323
|
E = _NonfiniteError(x)
|
|
301
324
|
t = Fmt.PARENSPACED(_not_finite_, x)
|
|
302
|
-
if args: # in
|
|
325
|
+
if args: # in _fmaX, _2sum
|
|
303
326
|
return E(txt=t, *args)
|
|
304
327
|
raise E(t, txt=None)
|
|
305
328
|
|
|
@@ -360,7 +383,7 @@ def _psum(ps, **_isfine): # PYCHOK used!
|
|
|
360
383
|
elif not _isfinite(s): # non-finite OK
|
|
361
384
|
i = 0 # collapse ps
|
|
362
385
|
if ps:
|
|
363
|
-
s +=
|
|
386
|
+
s += sum(ps)
|
|
364
387
|
ps[i:] = s,
|
|
365
388
|
return s
|
|
366
389
|
|
|
@@ -385,7 +408,7 @@ def _2scalar2(other):
|
|
|
385
408
|
'''(INTERNAL) Return 2-tuple C{(other, r)} with C{other} as C{int},
|
|
386
409
|
C{float} or C{as-is} and C{r} the residual of C{as-is}.
|
|
387
410
|
'''
|
|
388
|
-
if
|
|
411
|
+
if _isFsum_2Tuple(other):
|
|
389
412
|
s, r = other._fint2
|
|
390
413
|
if r:
|
|
391
414
|
s, r = other._fprs2
|
|
@@ -447,9 +470,9 @@ def _2sum(a, b, _isfine=_isfinite): # in .testFmath
|
|
|
447
470
|
else:
|
|
448
471
|
r = (a - s) + b
|
|
449
472
|
elif _isfine(s):
|
|
450
|
-
r =
|
|
473
|
+
r = _NONFINITEr
|
|
451
474
|
else: # non-finite and not OK
|
|
452
|
-
t =
|
|
475
|
+
t = unstr(_2sum, a, b)
|
|
453
476
|
raise _nfError(s, t)
|
|
454
477
|
return s, r
|
|
455
478
|
|
|
@@ -477,10 +500,10 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
477
500
|
i.e. any C{type} having method C{__float__}.
|
|
478
501
|
|
|
479
502
|
@note: Handling of I{non-finites} as C{inf}, C{INF}, C{NINF}, C{nan} and C{NAN} is
|
|
480
|
-
determined
|
|
481
|
-
by method L{nonfinites<Fsum.nonfinites>} for individual C{Fsum} instances,
|
|
482
|
-
overruling the
|
|
483
|
-
|
|
503
|
+
determined by function L{nonfiniterrors<fsums.nonfiniterrors>} for the default
|
|
504
|
+
and by method L{nonfinites<Fsum.nonfinites>} for individual C{Fsum} instances,
|
|
505
|
+
overruling the default. For backward compatibility, I{non-finites} raise
|
|
506
|
+
exceptions by default.
|
|
484
507
|
|
|
485
508
|
@see: U{Hettinger<https://GitHub.com/ActiveState/code/tree/master/recipes/Python/
|
|
486
509
|
393090_Binary_floating_point_summatiaccurate_full/recipe-393090.py>},
|
|
@@ -499,7 +522,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
499
522
|
_isfine = {} # == _isfinite
|
|
500
523
|
_n = 0
|
|
501
524
|
# _ps = [] # partial sums
|
|
502
|
-
# _ps_max = 0 # max(Fsum._ps_max, len(Fsum._ps))
|
|
525
|
+
# _ps_max = 0 # max(Fsum._ps_max, len(Fsum._ps)) # 41
|
|
503
526
|
_RESIDUAL = _threshold(_RESIDUAL_0_0)
|
|
504
527
|
|
|
505
528
|
def __init__(self, *xs, **name_f2product_nonfinites_RESIDUAL):
|
|
@@ -1043,7 +1066,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1043
1066
|
def _cmp_0(self, other, op):
|
|
1044
1067
|
'''(INTERNAL) Return C{scalar(self - B{other})} for 0-comparison.
|
|
1045
1068
|
'''
|
|
1046
|
-
if
|
|
1069
|
+
if _isFsum_2Tuple(other):
|
|
1047
1070
|
s = self._ps_1sum(*other._ps)
|
|
1048
1071
|
elif self._scalar(other, op):
|
|
1049
1072
|
s = self._ps_1sum(other)
|
|
@@ -1091,7 +1114,9 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1091
1114
|
def _Error(self, op, other, Error, **txt_cause):
|
|
1092
1115
|
'''(INTERNAL) Format an B{C{Error}} for C{{self} B{op} B{other}}.
|
|
1093
1116
|
'''
|
|
1094
|
-
|
|
1117
|
+
# self.as_iscalar causes RecursionError for ._fprs2 errors
|
|
1118
|
+
s = _Psum(self._ps, nonfinites=True, name=self.name)
|
|
1119
|
+
return Error(_SPACE_(s.as_iscalar, op, other), **txt_cause)
|
|
1095
1120
|
|
|
1096
1121
|
def _ErrorX(self, X, op, other, *mod):
|
|
1097
1122
|
'''(INTERNAL) Format the caught exception C{X}.
|
|
@@ -1113,9 +1138,9 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1113
1138
|
'''
|
|
1114
1139
|
if xs:
|
|
1115
1140
|
kwds = _xkwds(self._isfine, **origin_X_x)
|
|
1116
|
-
|
|
1141
|
+
fs = _2floats(xs, **kwds) # PYCHOK yield
|
|
1117
1142
|
ps = self._ps
|
|
1118
|
-
ps[:] = self._ps_acc(list(ps),
|
|
1143
|
+
ps[:] = self._ps_acc(list(ps), fs, up=up)
|
|
1119
1144
|
return self
|
|
1120
1145
|
|
|
1121
1146
|
def _facc_args(self, xs, **up):
|
|
@@ -1141,7 +1166,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1141
1166
|
'''
|
|
1142
1167
|
def _Pow4(p):
|
|
1143
1168
|
r = 0
|
|
1144
|
-
if
|
|
1169
|
+
if _isFsum_2Tuple(p):
|
|
1145
1170
|
s, r = p._fprs2
|
|
1146
1171
|
if r:
|
|
1147
1172
|
m = Fsum._pow
|
|
@@ -1158,7 +1183,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1158
1183
|
_Pow, p, s, r = _Pow4(power)
|
|
1159
1184
|
if p: # and xs:
|
|
1160
1185
|
op = which.__name__
|
|
1161
|
-
_FsT =
|
|
1186
|
+
_FsT = _Fsum_2Tuple_types
|
|
1162
1187
|
_pow = self._pow_2_3
|
|
1163
1188
|
|
|
1164
1189
|
def _P(X):
|
|
@@ -1178,18 +1203,27 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1178
1203
|
return f
|
|
1179
1204
|
|
|
1180
1205
|
def _facc_scalar(self, xs, **up):
|
|
1181
|
-
'''(INTERNAL) Accumulate all C{xs},
|
|
1206
|
+
'''(INTERNAL) Accumulate all C{xs}, each C{scalar}.
|
|
1182
1207
|
'''
|
|
1183
1208
|
if xs:
|
|
1184
1209
|
_ = self._ps_acc(self._ps, xs, **up)
|
|
1185
1210
|
return self
|
|
1186
1211
|
|
|
1187
1212
|
def _facc_scalar_(self, *xs, **up):
|
|
1188
|
-
'''(INTERNAL) Accumulate all positional C{xs},
|
|
1213
|
+
'''(INTERNAL) Accumulate all positional C{xs}, each C{scalar}.
|
|
1189
1214
|
'''
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1215
|
+
return self._facc_scalar(xs, **up)
|
|
1216
|
+
|
|
1217
|
+
def _facc_scalarf(self, xs, **origin_which):
|
|
1218
|
+
'''(INTERNAL) Accumulate all C{xs}, each C{scalar}, an L{Fsum} or
|
|
1219
|
+
L{Fsum2Tuple}, like function C{_xsum}.
|
|
1220
|
+
'''
|
|
1221
|
+
i_x = [0, xs]
|
|
1222
|
+
try:
|
|
1223
|
+
nf = self.nonfinitesOK
|
|
1224
|
+
return self._facc_scalar(_xs(xs, i_x, nf))
|
|
1225
|
+
except (OverflowError, TypeError, ValueError) as X:
|
|
1226
|
+
raise _ixError(X, xs, *i_x, **origin_which)
|
|
1193
1227
|
|
|
1194
1228
|
# def _facc_up(self, up=True):
|
|
1195
1229
|
# '''(INTERNAL) Update the C{partials}, by removing
|
|
@@ -1219,7 +1253,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1219
1253
|
|
|
1220
1254
|
@raise ValueError: Invalid or I{non-finite} B{C{xs}} value.
|
|
1221
1255
|
'''
|
|
1222
|
-
if
|
|
1256
|
+
if _isFsum_2Tuple(xs):
|
|
1223
1257
|
self._facc_scalar(xs._ps)
|
|
1224
1258
|
elif isscalar(xs): # for backward compatibility # PYCHOK no cover
|
|
1225
1259
|
x = _2float(x=xs, **self._isfine)
|
|
@@ -1241,7 +1275,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1241
1275
|
def _fadd(self, other, op, **up): # in .fmath.Fhorner
|
|
1242
1276
|
'''(INTERNAL) Apply C{B{self} += B{other}}.
|
|
1243
1277
|
'''
|
|
1244
|
-
if
|
|
1278
|
+
if _isFsum_2Tuple(other):
|
|
1245
1279
|
if self._ps:
|
|
1246
1280
|
self._facc_scalar(other._ps, **up)
|
|
1247
1281
|
else:
|
|
@@ -1283,7 +1317,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1283
1317
|
'''
|
|
1284
1318
|
if _xiterablen(cs):
|
|
1285
1319
|
H = self._Fsum_as(name__=self._fhorner)
|
|
1286
|
-
if
|
|
1320
|
+
if _isFsum_2Tuple(x):
|
|
1287
1321
|
_mul = H._mul_Fsum
|
|
1288
1322
|
else:
|
|
1289
1323
|
_mul = H._mul_scalar
|
|
@@ -1352,8 +1386,8 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1352
1386
|
r = (self._ps_1sum(i) if len(self._ps) > 1 else
|
|
1353
1387
|
float(s - i)) or INT0
|
|
1354
1388
|
except (OverflowError, ValueError) as X:
|
|
1355
|
-
r =
|
|
1356
|
-
i =
|
|
1389
|
+
r = _NONFINITEr # INF, NAN, NINF
|
|
1390
|
+
i = self._fintX(X, sum(self._ps))
|
|
1357
1391
|
return i, r # Fsum2Tuple?
|
|
1358
1392
|
|
|
1359
1393
|
@_fint2.setter_ # PYCHOK setter_UNDERscore!
|
|
@@ -1364,8 +1398,8 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1364
1398
|
i = int(s)
|
|
1365
1399
|
r = (s - i) or INT0
|
|
1366
1400
|
except (OverflowError, ValueError) as X:
|
|
1367
|
-
r =
|
|
1368
|
-
i =
|
|
1401
|
+
r = _NONFINITEr # INF, NAN, NINF
|
|
1402
|
+
i = self._fintX(X, float(s))
|
|
1369
1403
|
return i, r # like _fint2.getter
|
|
1370
1404
|
|
|
1371
1405
|
def _fintX(self, X, i): # PYCHOK X
|
|
@@ -1406,31 +1440,32 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1406
1440
|
q = self._ftruediv(other, op, **raiser_RESIDUAL) # == self
|
|
1407
1441
|
return self._fset(q.floor) # floor(q)
|
|
1408
1442
|
|
|
1409
|
-
def fma(self, other1, other2,
|
|
1443
|
+
def fma(self, other1, other2, **nonfinites): # in .fmath.fma
|
|
1410
1444
|
'''Fused-multiply-add C{self *= B{other1}; self += B{other2}}.
|
|
1411
1445
|
|
|
1412
1446
|
@arg other1: Multiplier (C{scalar}, an L{Fsum} or L{Fsum2Tuple}).
|
|
1413
1447
|
@arg other2: Addend (C{scalar}, an L{Fsum} or L{Fsum2Tuple}).
|
|
1414
|
-
@kwarg
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
@note: Uses C{math.fma} in Python 3.13+, provided C{self},
|
|
1418
|
-
B{C{other1}} and B{C{other2}} are all C{scalar}.
|
|
1448
|
+
@kwarg nonfinites: Use C{B{nonfinites}=True} or C{False}, to
|
|
1449
|
+
override L{nonfinites<Fsum.nonfinites>} and
|
|
1450
|
+
L{nonfiniterrors} default (C{bool}).
|
|
1419
1451
|
'''
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1452
|
+
op = self.fma.__name__
|
|
1453
|
+
_fs = self._ps_other
|
|
1454
|
+
try:
|
|
1455
|
+
s, r = self._fprs2
|
|
1456
|
+
if r:
|
|
1457
|
+
f = self._f2mul(self.fma, other1, **nonfinites)
|
|
1458
|
+
f += other2
|
|
1459
|
+
else:
|
|
1460
|
+
fs = _2split3s(_fs(op, other1))
|
|
1461
|
+
fs = _2products(s, fs, *_fs(op, other2))
|
|
1462
|
+
f = _Psum(self._ps_acc([], fs, up=False), name=op)
|
|
1463
|
+
except TypeError as X:
|
|
1464
|
+
raise self._ErrorX(X, op, (other1, other2))
|
|
1465
|
+
except (OverflowError, ValueError) as X: # from math.fma
|
|
1466
|
+
f = self._mul_reduce(op, s, other1) # INF, NAN, NINF
|
|
1467
|
+
f = sum(_fs(op, f, other2))
|
|
1468
|
+
f = self._nonfiniteX(X, op, f, **nonfinites)
|
|
1434
1469
|
return self._fset(f)
|
|
1435
1470
|
|
|
1436
1471
|
fmul = __imul__
|
|
@@ -1438,11 +1473,11 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1438
1473
|
def _fmul(self, other, op):
|
|
1439
1474
|
'''(INTERNAL) Apply C{B{self} *= B{other}}.
|
|
1440
1475
|
'''
|
|
1441
|
-
if
|
|
1476
|
+
if _isFsum_2Tuple(other):
|
|
1442
1477
|
if len(self._ps) != 1:
|
|
1443
1478
|
f = self._mul_Fsum(other, op)
|
|
1444
1479
|
elif len(other._ps) != 1: # and len(self._ps) == 1
|
|
1445
|
-
f = self._ps_mul(op, *other._ps)
|
|
1480
|
+
f = self._ps_mul(op, *other._ps) if other._ps else _0_0
|
|
1446
1481
|
elif self._f2product: # len(other._ps) == 1
|
|
1447
1482
|
f = self._mul_scalar(other._ps[0], op)
|
|
1448
1483
|
else: # len(other._ps) == len(self._ps) == 1
|
|
@@ -1457,39 +1492,41 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1457
1492
|
'''DEPRECATED on 2024.09.13, use method L{f2mul_<Fsum.f2mul_>}.'''
|
|
1458
1493
|
return self._fset(self.f2mul_(*others, **raiser))
|
|
1459
1494
|
|
|
1460
|
-
def f2mul_(self, *others, **
|
|
1495
|
+
def f2mul_(self, *others, **nonfinites): # in .fmath.f2mul
|
|
1461
1496
|
'''Return C{B{self} * B{other} * B{other} ...} for all B{C{others}} using cascaded,
|
|
1462
1497
|
accurate multiplication like with L{f2product<Fsum.f2product>} set to C{True}.
|
|
1463
1498
|
|
|
1464
1499
|
@arg others: Multipliers (each C{scalar}, an L{Fsum} or L{Fsum2Tuple}), all
|
|
1465
1500
|
positional.
|
|
1466
|
-
@kwarg
|
|
1467
|
-
|
|
1501
|
+
@kwarg nonfinites: Use C{B{nonfinites}=True} or C{False}, to override both
|
|
1502
|
+
L{nonfinites<Fsum.nonfinites>} and the L{nonfiniterrors}
|
|
1503
|
+
default (C{bool}).
|
|
1468
1504
|
|
|
1469
1505
|
@return: The cascaded I{TwoProduct} (L{Fsum} or C{float}).
|
|
1470
1506
|
|
|
1471
1507
|
@see: U{Equations 2.3<https://www.TUHH.De/ti3/paper/rump/OzOgRuOi06.pdf>}
|
|
1472
1508
|
'''
|
|
1473
|
-
return self._f2mul(self.f2mul_, *others, **
|
|
1509
|
+
return self._f2mul(self.f2mul_, *others, **nonfinites)
|
|
1474
1510
|
|
|
1475
|
-
def _f2mul(self, where, *others, **
|
|
1511
|
+
def _f2mul(self, where, *others, **nonfinites_raiser):
|
|
1476
1512
|
'''(INTERNAL) See methods C{fma} and C{f2mul_}.
|
|
1477
1513
|
'''
|
|
1478
|
-
f
|
|
1479
|
-
|
|
1514
|
+
f = self._copy_2(where)
|
|
1515
|
+
ps = f._ps
|
|
1516
|
+
if ps and others:
|
|
1480
1517
|
op = where.__name__
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
for p in self._ps_other(op, *others):
|
|
1518
|
+
try:
|
|
1519
|
+
for other in others: # to pinpoint errors
|
|
1520
|
+
for p in self._ps_other(op, other):
|
|
1485
1521
|
pfs = _2products(p, _2split3s(ps))
|
|
1486
1522
|
ps[:] = f._ps_acc([], pfs, up=False)
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1523
|
+
f._update()
|
|
1524
|
+
except TypeError as X:
|
|
1525
|
+
raise self._ErrorX(X, op, other)
|
|
1526
|
+
except (OverflowError, ValueError) as X:
|
|
1527
|
+
r = self._mul_reduce(op, sum(ps), other) # INF, NAN, NINF
|
|
1528
|
+
r = self._nonfiniteX(X, op, r, **nonfinites_raiser)
|
|
1529
|
+
f._fset(r)
|
|
1493
1530
|
return f
|
|
1494
1531
|
|
|
1495
1532
|
def fover(self, over, **raiser_RESIDUAL):
|
|
@@ -1531,8 +1568,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1531
1568
|
|
|
1532
1569
|
def f2product(self, *two):
|
|
1533
1570
|
'''Get and set accurate I{TwoProduct} multiplication for this
|
|
1534
|
-
L{Fsum},
|
|
1535
|
-
L{f2product<fsums.f2product>}.
|
|
1571
|
+
L{Fsum}, overriding the L{f2product} default.
|
|
1536
1572
|
|
|
1537
1573
|
@arg two: If omitted, leave the override unchanged, if C{True},
|
|
1538
1574
|
turn I{TwoProduct} on, if C{False} off, if C{None}e
|
|
@@ -1564,7 +1600,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1564
1600
|
s, _ = self._fprs2
|
|
1565
1601
|
return s # ._fprs2.fsum
|
|
1566
1602
|
|
|
1567
|
-
@_fprs.setter_ # PYCHOK
|
|
1603
|
+
@_fprs.setter_ # PYCHOK setter_UNDERscore!
|
|
1568
1604
|
def _fprs(self, s):
|
|
1569
1605
|
'''(INTERNAL) Replace the C{_fprs} value.
|
|
1570
1606
|
'''
|
|
@@ -1576,30 +1612,36 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1576
1612
|
running sum and residual (L{Fsum2Tuple}).
|
|
1577
1613
|
'''
|
|
1578
1614
|
ps = self._ps
|
|
1615
|
+
n = len(ps)
|
|
1579
1616
|
try:
|
|
1580
|
-
n
|
|
1581
|
-
if n > 0: # len(ps) > 2
|
|
1617
|
+
if n > 2:
|
|
1582
1618
|
s = _psum(ps, **self._isfine)
|
|
1583
|
-
|
|
1584
|
-
|
|
1619
|
+
if not _isfinite(s):
|
|
1620
|
+
ps[:] = s, # collapse ps
|
|
1621
|
+
return Fsum2Tuple(s, _NONFINITEr)
|
|
1622
|
+
n = len(ps)
|
|
1623
|
+
# Fsum._ps_max = max(Fsum._ps_max, n)
|
|
1624
|
+
if n > 2:
|
|
1585
1625
|
r = self._ps_1sum(s)
|
|
1586
1626
|
return Fsum2Tuple(*_s_r(s, r))
|
|
1587
|
-
if n
|
|
1627
|
+
if n > 1: # len(ps) == 2
|
|
1588
1628
|
s, r = _s_r(*_2sum(*ps, **self._isfine))
|
|
1589
1629
|
ps[:] = (r, s) if r else (s,)
|
|
1590
1630
|
elif ps: # len(ps) == 1
|
|
1591
|
-
s
|
|
1631
|
+
s = ps[0]
|
|
1632
|
+
r = INT0 if _isfinite(s) else _NONFINITEr
|
|
1592
1633
|
else: # len(ps) == 0
|
|
1593
1634
|
s, r = _0_0, INT0
|
|
1594
1635
|
ps[:] = s,
|
|
1595
1636
|
except (OverflowError, ValueError) as X:
|
|
1596
|
-
op =
|
|
1597
|
-
|
|
1598
|
-
|
|
1637
|
+
op = sum.__name__ # INF, NAN, NINF
|
|
1638
|
+
ps[:] = sum(ps), # collapse ps
|
|
1639
|
+
s = self._nonfiniteX(X, op, ps[0])
|
|
1640
|
+
r = _NONFINITEr
|
|
1599
1641
|
# assert self._ps is ps
|
|
1600
1642
|
return Fsum2Tuple(s, r)
|
|
1601
1643
|
|
|
1602
|
-
@_fprs2.setter_ # PYCHOK
|
|
1644
|
+
@_fprs2.setter_ # PYCHOK setter_UNDERscore!
|
|
1603
1645
|
def _fprs2(self, s_r):
|
|
1604
1646
|
'''(INTERNAL) Replace the C{_fprs2} value.
|
|
1605
1647
|
'''
|
|
@@ -1616,15 +1658,15 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1616
1658
|
|
|
1617
1659
|
@see: Method L{Fsum.fadd} for further details.
|
|
1618
1660
|
'''
|
|
1619
|
-
|
|
1620
|
-
|
|
1661
|
+
f = self._Fsum_as(*xs)
|
|
1662
|
+
return self._fset(f, up=False, op=_fset_op_)
|
|
1621
1663
|
|
|
1622
1664
|
def _fset(self, other, n=0, up=True, **op):
|
|
1623
1665
|
'''(INTERNAL) Overwrite this instance with an other or a C{scalar}.
|
|
1624
1666
|
'''
|
|
1625
1667
|
if other is self:
|
|
1626
1668
|
pass # from ._fmul, ._ftruediv and ._pow_0_1
|
|
1627
|
-
elif
|
|
1669
|
+
elif _isFsum_2Tuple(other):
|
|
1628
1670
|
self._ps[:] = other._ps
|
|
1629
1671
|
self._n = n or other._n
|
|
1630
1672
|
if up: # use or zap the C{Property_RO} values
|
|
@@ -1670,7 +1712,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1670
1712
|
def _fsub(self, other, op):
|
|
1671
1713
|
'''(INTERNAL) Apply C{B{self} -= B{other}}.
|
|
1672
1714
|
'''
|
|
1673
|
-
if
|
|
1715
|
+
if _isFsum_2Tuple(other):
|
|
1674
1716
|
if other is self: # or other._fprs2 == self._fprs2:
|
|
1675
1717
|
self._fset(_0_0, n=len(self) * 2)
|
|
1676
1718
|
elif other._ps:
|
|
@@ -1680,8 +1722,8 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1680
1722
|
return self
|
|
1681
1723
|
|
|
1682
1724
|
def fsum(self, xs=()):
|
|
1683
|
-
'''Add an iterable's items, summate and return the
|
|
1684
|
-
|
|
1725
|
+
'''Add an iterable's items, summate and return the current
|
|
1726
|
+
precision running sum.
|
|
1685
1727
|
|
|
1686
1728
|
@arg xs: Iterable of items to add (each item C{scalar}
|
|
1687
1729
|
or an L{Fsum} or L{Fsum2Tuple} instance).
|
|
@@ -1695,8 +1737,8 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1695
1737
|
return self._facc(xs)._fprs
|
|
1696
1738
|
|
|
1697
1739
|
def fsum_(self, *xs):
|
|
1698
|
-
'''Add any positional items, summate and return the
|
|
1699
|
-
|
|
1740
|
+
'''Add any positional items, summate and return the current
|
|
1741
|
+
precision running sum.
|
|
1700
1742
|
|
|
1701
1743
|
@arg xs: Items to add (each C{scalar} or an L{Fsum}
|
|
1702
1744
|
or L{Fsum2Tuple} instance), all positional.
|
|
@@ -1742,7 +1784,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1742
1784
|
kwds.update(name_f2product_nonfinites_RESIDUAL)
|
|
1743
1785
|
F = Fsum(**kwds)
|
|
1744
1786
|
# assert all(v == self.__dict__[n] for n, v in F.__dict__.items())
|
|
1745
|
-
return F._fset(xs[0]) if len(xs) == 1 else (
|
|
1787
|
+
return F._fset(xs[0], op=_fset_op_) if len(xs) == 1 else (
|
|
1746
1788
|
F._facc(xs, up=False) if xs else F)
|
|
1747
1789
|
|
|
1748
1790
|
def fsum2(self, xs=(), **name):
|
|
@@ -1779,33 +1821,36 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1779
1821
|
'''
|
|
1780
1822
|
return self._fsum2(xs, self._facc_args)
|
|
1781
1823
|
|
|
1782
|
-
def _fsum2(self, xs, _facc, **
|
|
1824
|
+
def _fsum2(self, xs, _facc, **facc_kwds):
|
|
1783
1825
|
'''(INTERNAL) Helper for L{Fsum.fsum2_} and L{Fsum.fsum2f_}.
|
|
1784
1826
|
'''
|
|
1785
1827
|
p, q = self._fprs2
|
|
1786
1828
|
if xs:
|
|
1787
|
-
s, r = _facc(xs, **
|
|
1829
|
+
s, r = _facc(xs, **facc_kwds)._fprs2
|
|
1788
1830
|
if _isfinite(s): # _fsum(_1primed((s, -p, r, -q))
|
|
1789
1831
|
d, r = _2sum(s - p, r - q, _isfine=_isOK)
|
|
1790
1832
|
r, _ = _s_r(d, r)
|
|
1791
|
-
return s, (r if _isfinite(r) else
|
|
1833
|
+
return s, (r if _isfinite(r) else _NONFINITEr)
|
|
1792
1834
|
else:
|
|
1793
1835
|
return p, _0_0
|
|
1794
1836
|
|
|
1795
1837
|
def fsumf_(self, *xs):
|
|
1796
|
-
'''Like method L{Fsum.fsum_} iff I{all} C{B{xs}}
|
|
1838
|
+
'''Like method L{Fsum.fsum_} iff I{all} C{B{xs}}, each I{known to be}
|
|
1839
|
+
C{scalar}, an L{Fsum} or L{Fsum2Tuple}.
|
|
1797
1840
|
'''
|
|
1798
|
-
return self.
|
|
1841
|
+
return self._facc_scalarf(xs, origin=1, which=self.fsumf_)._fprs
|
|
1799
1842
|
|
|
1800
1843
|
def Fsumf_(self, *xs):
|
|
1801
|
-
'''Like method L{Fsum.Fsum_} iff I{all} C{B{xs}}
|
|
1844
|
+
'''Like method L{Fsum.Fsum_} iff I{all} C{B{xs}}, each I{known to be}
|
|
1845
|
+
C{scalar}, an L{Fsum} or L{Fsum2Tuple}.
|
|
1802
1846
|
'''
|
|
1803
|
-
return self.
|
|
1847
|
+
return self._facc_scalarf(xs, origin=1, which=self.Fsumf_)._copy_2(self.Fsumf_)
|
|
1804
1848
|
|
|
1805
1849
|
def fsum2f_(self, *xs):
|
|
1806
|
-
'''Like method L{Fsum.fsum2_} iff I{all} C{B{xs}}
|
|
1850
|
+
'''Like method L{Fsum.fsum2_} iff I{all} C{B{xs}}, each I{known to be}
|
|
1851
|
+
C{scalar}, an L{Fsum} or L{Fsum2Tuple}.
|
|
1807
1852
|
'''
|
|
1808
|
-
return self._fsum2(xs, self.
|
|
1853
|
+
return self._fsum2(xs, self._facc_scalarf, origin=1, which=self.fsum2f_)
|
|
1809
1854
|
|
|
1810
1855
|
# ftruediv = __itruediv__ # for naming consistency?
|
|
1811
1856
|
|
|
@@ -1813,7 +1858,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1813
1858
|
'''(INTERNAL) Apply C{B{self} /= B{other}}.
|
|
1814
1859
|
'''
|
|
1815
1860
|
n = _1_0
|
|
1816
|
-
if
|
|
1861
|
+
if _isFsum_2Tuple(other):
|
|
1817
1862
|
if other is self or self == other:
|
|
1818
1863
|
return self._fset(n, n=len(self))
|
|
1819
1864
|
d, r = other._fprs2
|
|
@@ -1846,9 +1891,8 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1846
1891
|
L{ResidualError}s (C{bool}) and C{B{RESIDUAL}=scalar}
|
|
1847
1892
|
to override the current L{RESIDUAL<Fsum.RESIDUAL>}.
|
|
1848
1893
|
|
|
1849
|
-
@return: This C{
|
|
1850
|
-
|
|
1851
|
-
zero or not significant.
|
|
1894
|
+
@return: This C{int} sum if this instance C{is_integer}, otherwise
|
|
1895
|
+
the C{float} sum if the residual is zero or not significant.
|
|
1852
1896
|
|
|
1853
1897
|
@raise ResidualError: Non-zero, significant residual or invalid
|
|
1854
1898
|
B{C{RESIDUAL}}.
|
|
@@ -1878,7 +1922,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1878
1922
|
|
|
1879
1923
|
@see: Function L{isfinite<pygeodesy.isfinite>}.
|
|
1880
1924
|
'''
|
|
1881
|
-
return _isfinite(
|
|
1925
|
+
return _isfinite(sum(self._ps)) # == sum(self)
|
|
1882
1926
|
|
|
1883
1927
|
def is_integer(self):
|
|
1884
1928
|
'''Is this instance' running sum C{integer}? (C{bool}).
|
|
@@ -1895,7 +1939,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1895
1939
|
an C{fma} implementation as C{math.fma} or C{None}, a previous
|
|
1896
1940
|
C{PyGeodesy} implementation.
|
|
1897
1941
|
'''
|
|
1898
|
-
return (
|
|
1942
|
+
return (_2split3s is _passarg) or (False if _2n_d is None else None)
|
|
1899
1943
|
|
|
1900
1944
|
def is_math_fsum(self):
|
|
1901
1945
|
'''Are the summation functions L{fsum}, L{fsum_}, L{fsumf_}, L{fsum1},
|
|
@@ -1929,7 +1973,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1929
1973
|
def _mul_Fsum(self, other, op=_mul_op_): # in .fmath.Fhorner
|
|
1930
1974
|
'''(INTERNAL) Return C{B{self} * B{other}} as L{Fsum} or C{0}.
|
|
1931
1975
|
'''
|
|
1932
|
-
# assert
|
|
1976
|
+
# assert _isFsum_2Tuple(other)
|
|
1933
1977
|
if self._ps and other._ps:
|
|
1934
1978
|
f = self._ps_mul(op, *other._ps) # NO .as_iscalar!
|
|
1935
1979
|
else:
|
|
@@ -1970,8 +2014,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1970
2014
|
def nonfinites(self, *OK):
|
|
1971
2015
|
'''Handle I{non-finite} C{float}s as C{inf}, C{INF}, C{NINF}, C{nan}
|
|
1972
2016
|
and C{NAN} for this L{Fsum} or throw C{OverflowError} respectively
|
|
1973
|
-
C{ValueError} exceptions,
|
|
1974
|
-
function L{nonfiniterrors<fsums.nonfiniterrors>}.
|
|
2017
|
+
C{ValueError} exceptions, overriding the L{nonfiniterrors} default.
|
|
1975
2018
|
|
|
1976
2019
|
@arg OK: If omitted, leave the override unchanged, if C{True},
|
|
1977
2020
|
I{non-finites} are C{OK}, if C{False} throw exceptions
|
|
@@ -1981,14 +2024,16 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1981
2024
|
|
|
1982
2025
|
@see: Function L{nonfiniterrors<fsums.nonfiniterrors>}.
|
|
1983
2026
|
|
|
1984
|
-
@note: Use
|
|
1985
|
-
whether
|
|
2027
|
+
@note: Use property L{nonfinitesOK<Fsum.nonfinitesOK>} to determine
|
|
2028
|
+
whether I{non-finites} are C{OK} for this L{Fsum} and by the
|
|
2029
|
+
L{nonfiniterrors} default.
|
|
1986
2030
|
'''
|
|
1987
2031
|
_ks = Fsum._nonfinites_isfine_kwds
|
|
1988
2032
|
if OK: # delattrof(self, _isfine=None)
|
|
1989
2033
|
k = _xkwds_pop(self.__dict__, _isfine=None)
|
|
1990
2034
|
if OK[0] is not None:
|
|
1991
2035
|
self._isfine = _ks[bool(OK[0])]
|
|
2036
|
+
self._update()
|
|
1992
2037
|
else: # getattrof(self, _isfine=None)
|
|
1993
2038
|
k = _xkwds_get(self.__dict__, _isfine=None)
|
|
1994
2039
|
# dict(map(reversed, _ks.items())).get(k, None)
|
|
@@ -1999,10 +2044,21 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
1999
2044
|
_nonfinites_isfine_kwds = {True: dict(_isfine=_isOK),
|
|
2000
2045
|
False: dict(_isfine=_isfinite)}
|
|
2001
2046
|
|
|
2002
|
-
|
|
2047
|
+
@property_RO
|
|
2048
|
+
def nonfinitesOK(self):
|
|
2049
|
+
'''Are I{non-finites} C{OK} for this L{Fsum} or by default? (C{bool}).
|
|
2050
|
+
'''
|
|
2051
|
+
nf = self.nonfinites()
|
|
2052
|
+
if nf is None:
|
|
2053
|
+
nf = not nonfiniterrors()
|
|
2054
|
+
return nf
|
|
2055
|
+
|
|
2056
|
+
def _nonfiniteX(self, X, op, f, nonfinites=None, raiser=None):
|
|
2003
2057
|
'''(INTERNAL) Handle a I{non-finite} exception.
|
|
2004
2058
|
'''
|
|
2005
|
-
if
|
|
2059
|
+
if nonfinites is None:
|
|
2060
|
+
nonfinites = _isOK_or_finite(f, **self._isfine) if raiser is None else (not raiser)
|
|
2061
|
+
if not nonfinites:
|
|
2006
2062
|
raise self._ErrorX(X, op, f)
|
|
2007
2063
|
return f
|
|
2008
2064
|
|
|
@@ -2063,7 +2119,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
2063
2119
|
def _pow(self, other, unused, op, **raiser_RESIDUAL):
|
|
2064
2120
|
'''Return C{B{self} ** B{other}}.
|
|
2065
2121
|
'''
|
|
2066
|
-
if
|
|
2122
|
+
if _isFsum_2Tuple(other):
|
|
2067
2123
|
f = self._pow_Fsum(other, op, **raiser_RESIDUAL)
|
|
2068
2124
|
elif self._scalar(other, op):
|
|
2069
2125
|
x = self._finite(other, op)
|
|
@@ -2084,7 +2140,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
2084
2140
|
|
|
2085
2141
|
if mod: # b, x, mod all C{int}, unless C{mod} is C{None}
|
|
2086
2142
|
m = mod[0]
|
|
2087
|
-
# assert
|
|
2143
|
+
# assert _isFsum_2Tuple(b)
|
|
2088
2144
|
|
|
2089
2145
|
def _s(s, r):
|
|
2090
2146
|
R = self._raiser(r, s, **raiser_RESIDUAL)
|
|
@@ -2106,9 +2162,9 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
2106
2162
|
raise self._ErrorX(X, op, other, *mod)
|
|
2107
2163
|
|
|
2108
2164
|
def _pow_Fsum(self, other, op, **raiser_RESIDUAL):
|
|
2109
|
-
'''(INTERNAL) Return C{B{self} **= B{other}} for C{
|
|
2165
|
+
'''(INTERNAL) Return C{B{self} **= B{other}} for C{_isFsum_2Tuple(other)}.
|
|
2110
2166
|
'''
|
|
2111
|
-
# assert
|
|
2167
|
+
# assert _isFsum_2Tuple(other)
|
|
2112
2168
|
x, r = other._fprs2
|
|
2113
2169
|
f = self._pow_scalar(x, other, op, **raiser_RESIDUAL)
|
|
2114
2170
|
if f and r:
|
|
@@ -2203,7 +2259,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
2203
2259
|
if n:
|
|
2204
2260
|
self._n += n
|
|
2205
2261
|
# if _fi: # collapse ps if non-finite
|
|
2206
|
-
# x =
|
|
2262
|
+
# x = sum(ps)
|
|
2207
2263
|
# if not _isfinite(x):
|
|
2208
2264
|
# ps[:] = x,
|
|
2209
2265
|
# Fsum._ps_max = max(Fsum._ps_max, len(ps))
|
|
@@ -2219,19 +2275,21 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
2219
2275
|
if len(ps) < len(fs):
|
|
2220
2276
|
ps, fs = fs, ps
|
|
2221
2277
|
if self._f2product:
|
|
2222
|
-
|
|
2223
|
-
|
|
2278
|
+
fs, p = _2split3s(fs), fs
|
|
2279
|
+
if len(ps) > 1 and fs is not p:
|
|
2280
|
+
fs = tuple(fs) # several ps
|
|
2281
|
+
_pfs = _2products
|
|
2224
2282
|
else:
|
|
2225
|
-
def
|
|
2226
|
-
return (
|
|
2283
|
+
def _pfs(p, fs):
|
|
2284
|
+
return (p * f for f in fs)
|
|
2227
2285
|
|
|
2228
|
-
for
|
|
2229
|
-
for
|
|
2230
|
-
yield
|
|
2286
|
+
for p in ps:
|
|
2287
|
+
for f in _pfs(p, fs):
|
|
2288
|
+
yield f if _isfine(f) else self._finite(f, op)
|
|
2231
2289
|
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
return
|
|
2290
|
+
fs = _psfs(self._ps, factors, **self._isfine)
|
|
2291
|
+
f = _Psum(self._ps_acc([], fs, up=False), name=op)
|
|
2292
|
+
return f
|
|
2235
2293
|
|
|
2236
2294
|
@property_RO
|
|
2237
2295
|
def _ps_neg(self):
|
|
@@ -2244,7 +2302,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
2244
2302
|
'''(INTERNAL) Yield all C{other}s as C{scalar}.
|
|
2245
2303
|
'''
|
|
2246
2304
|
for other in others:
|
|
2247
|
-
if
|
|
2305
|
+
if _isFsum_2Tuple(other):
|
|
2248
2306
|
for p in other._ps:
|
|
2249
2307
|
yield p
|
|
2250
2308
|
else:
|
|
@@ -2345,7 +2403,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
2345
2403
|
def root(self, root, **raiser_RESIDUAL):
|
|
2346
2404
|
'''Return C{B{self}**(1 / B{root})} as L{Fsum}.
|
|
2347
2405
|
|
|
2348
|
-
@arg root:
|
|
2406
|
+
@arg root: Non-zero order (C{scalar}, an L{Fsum} or L{Fsum2Tuple}).
|
|
2349
2407
|
@kwarg raiser_RESIDUAL: Use C{B{raiser}=False} to ignore any
|
|
2350
2408
|
L{ResidualError}s (C{bool}) or C{B{RESIDUAL}=scalar}
|
|
2351
2409
|
to override the current L{RESIDUAL<Fsum.RESIDUAL>}.
|
|
@@ -2362,7 +2420,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
2362
2420
|
return f._fpow(x, f.name, **raiser_RESIDUAL) # == pow(f, x)
|
|
2363
2421
|
|
|
2364
2422
|
def _scalar(self, other, op, **txt):
|
|
2365
|
-
'''(INTERNAL) Return scalar C{other}.
|
|
2423
|
+
'''(INTERNAL) Return scalar C{other} or throw a C{TypeError}.
|
|
2366
2424
|
'''
|
|
2367
2425
|
if isscalar(other):
|
|
2368
2426
|
return other
|
|
@@ -2371,8 +2429,8 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
2371
2429
|
def signOf(self, res=True):
|
|
2372
2430
|
'''Determine the sign of this instance.
|
|
2373
2431
|
|
|
2374
|
-
@kwarg res: If C{True}, consider
|
|
2375
|
-
the
|
|
2432
|
+
@kwarg res: If C{True}, consider the residual,
|
|
2433
|
+
otherwise ignore the latter (C{bool}).
|
|
2376
2434
|
|
|
2377
2435
|
@return: The sign (C{int}, -1, 0 or +1).
|
|
2378
2436
|
'''
|
|
@@ -2427,7 +2485,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
|
|
|
2427
2485
|
|
|
2428
2486
|
_ROs = _allPropertiesOf_n(3, Fsum, Property_RO) # PYCHOK see Fsum._update
|
|
2429
2487
|
|
|
2430
|
-
if _NONFINITES: # PYCHOK no cover
|
|
2488
|
+
if _NONFINITES == _std_: # PYCHOK no cover
|
|
2431
2489
|
_ = nonfiniterrors(False)
|
|
2432
2490
|
|
|
2433
2491
|
|
|
@@ -2574,7 +2632,7 @@ class Fsum2Tuple(_NamedTuple): # in .fstats
|
|
|
2574
2632
|
'''
|
|
2575
2633
|
return Fmt.PAREN(fstr(self, fmt=fmt, strepr=str, force=False, **prec_sep))
|
|
2576
2634
|
|
|
2577
|
-
|
|
2635
|
+
_Fsum_2Tuple_types = Fsum, Fsum2Tuple # PYCHOK lines
|
|
2578
2636
|
|
|
2579
2637
|
|
|
2580
2638
|
class ResidualError(_ValueError):
|
|
@@ -2603,7 +2661,7 @@ except ImportError:
|
|
|
2603
2661
|
def _fsum(xs):
|
|
2604
2662
|
'''(INTERNAL) Precision summation, Python 2.5-.
|
|
2605
2663
|
'''
|
|
2606
|
-
F = Fsum(name=_fsum.name, nonfinites=True)
|
|
2664
|
+
F = Fsum(name=_fsum.name, f2product=False, nonfinites=True)
|
|
2607
2665
|
return float(F._facc(xs, up=False))
|
|
2608
2666
|
|
|
2609
2667
|
|
|
@@ -2613,8 +2671,7 @@ def fsum(xs, nonfinites=None, **floats):
|
|
|
2613
2671
|
@arg xs: Iterable of items to add (each C{scalar}, an L{Fsum} or L{Fsum2Tuple}).
|
|
2614
2672
|
@kwarg nonfinites: Use C{B{nonfinites}=True} if I{non-finites} are C{OK}, if
|
|
2615
2673
|
C{False} I{non-finites} raise an Overflow-/ValueError or if
|
|
2616
|
-
C{None},
|
|
2617
|
-
(C{bool} or C{None}).
|
|
2674
|
+
C{None}, L{nonfiniterrors} applies (C{bool} or C{None}).
|
|
2618
2675
|
@kwarg floats: DEPRECATED keyword argument C{B{floats}=False} (C{bool}), use
|
|
2619
2676
|
keyword argument C{B{nonfinites}=False} instead.
|
|
2620
2677
|
|
|
@@ -2685,43 +2742,34 @@ def fsum1f_(*xs):
|
|
|
2685
2742
|
return _xsum(fsum1f_, xs, nonfinites=True, primed=1) if xs else _0_0
|
|
2686
2743
|
|
|
2687
2744
|
|
|
2688
|
-
def _xs(xs,
|
|
2745
|
+
def _xs(xs, i_x, nfOK): # in Fsum._facc_scalarf
|
|
2689
2746
|
'''(INTERNAL) Yield all C{xs} as C{scalar}.
|
|
2690
2747
|
'''
|
|
2748
|
+
_x = _passarg if nfOK else _2finite
|
|
2691
2749
|
for i, x in enumerate(xs):
|
|
2692
2750
|
i_x[:] = i, x
|
|
2693
|
-
if
|
|
2751
|
+
if _isFsum_2Tuple(x):
|
|
2694
2752
|
for p in map(_x, x._ps):
|
|
2695
2753
|
yield p
|
|
2696
2754
|
else:
|
|
2697
2755
|
yield _x(x)
|
|
2698
2756
|
|
|
2699
2757
|
|
|
2700
|
-
def _xsError(X, xs, i, x, *n): # in _2floats, ._fstats
|
|
2701
|
-
'''(INTERNAL) Error for C{xs} or C{x}, item C{xs[i]}.
|
|
2702
|
-
'''
|
|
2703
|
-
return ((_xError(X, n[0], xs) if n else
|
|
2704
|
-
_xError(X, xs=xs)) if x is xs else
|
|
2705
|
-
_xError(X, Fmt.INDEX(xs=i), x))
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
2758
|
def _xsum(which, xs, nonfinites=None, origin=0, primed=0, **floats):
|
|
2709
2759
|
'''(INTERNAL) Precision summation of C{xs} with conditions.
|
|
2710
2760
|
'''
|
|
2711
2761
|
i_x = [0, xs]
|
|
2712
2762
|
try:
|
|
2713
|
-
if
|
|
2714
|
-
nonfinites = not nonfiniterrors()
|
|
2715
|
-
elif floats:
|
|
2763
|
+
if floats: # for backward compatibility
|
|
2716
2764
|
nonfinites = _xkwds_get1(floats, floats=nonfinites)
|
|
2717
|
-
|
|
2765
|
+
elif nonfinites is None:
|
|
2766
|
+
nonfinites = not nonfiniterrors()
|
|
2767
|
+
fs = _xs(xs, i_x, nonfinites)
|
|
2718
2768
|
return _fsum(_1primed(fs) if primed else fs)
|
|
2719
2769
|
except (OverflowError, TypeError, ValueError) as X:
|
|
2720
|
-
|
|
2721
|
-
|
|
2722
|
-
|
|
2723
|
-
t = _COMMASPACE_(unstr(which), t)
|
|
2724
|
-
raise _xError(X, t, txt=None)
|
|
2770
|
+
origin -= 1 if primed else 0
|
|
2771
|
+
i_x += [origin, which]
|
|
2772
|
+
raise _ixError(X, xs, *i_x)
|
|
2725
2773
|
|
|
2726
2774
|
|
|
2727
2775
|
# delete all decorators, etc.
|