pygeodesy 24.5.2__py2.py3-none-any.whl → 24.5.8__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {PyGeodesy-24.5.2.dist-info → PyGeodesy-24.5.8.dist-info}/METADATA +4 -4
- {PyGeodesy-24.5.2.dist-info → PyGeodesy-24.5.8.dist-info}/RECORD +17 -17
- pygeodesy/__init__.py +3 -3
- pygeodesy/basics.py +12 -3
- pygeodesy/ecef.py +12 -13
- pygeodesy/errors.py +2 -3
- pygeodesy/fmath.py +201 -178
- pygeodesy/fstats.py +292 -227
- pygeodesy/fsums.py +312 -239
- pygeodesy/interns.py +9 -6
- pygeodesy/named.py +18 -6
- pygeodesy/props.py +8 -7
- pygeodesy/streprs.py +16 -7
- pygeodesy/vector2d.py +2 -2
- pygeodesy/vector3d.py +2 -2
- {PyGeodesy-24.5.2.dist-info → PyGeodesy-24.5.8.dist-info}/WHEEL +0 -0
- {PyGeodesy-24.5.2.dist-info → PyGeodesy-24.5.8.dist-info}/top_level.txt +0 -0
pygeodesy/fsums.py
CHANGED
|
@@ -27,36 +27,39 @@ from pygeodesy.basics import isbool, iscomplex, isint, isscalar, itemsorted, \
|
|
|
27
27
|
signOf, _signOf
|
|
28
28
|
from pygeodesy.constants import INT0, _isfinite, NEG0, _pos_self, \
|
|
29
29
|
_0_0, _1_0, _N_1_0, Float, Int
|
|
30
|
-
from pygeodesy.errors import
|
|
31
|
-
|
|
32
|
-
_ZeroDivisionError
|
|
30
|
+
from pygeodesy.errors import _OverflowError, _TypeError, _ValueError, \
|
|
31
|
+
_xError, _xError2, _xkwds_get
|
|
33
32
|
from pygeodesy.interns import NN, _arg_, _COMMASPACE_, _DASH_, _DOT_, \
|
|
34
|
-
_EQUAL_, _from_, _LANGLE_, _NOTEQUAL_, \
|
|
33
|
+
_enquote, _EQUAL_, _from_, _LANGLE_, _NOTEQUAL_, \
|
|
35
34
|
_not_finite_, _PERCENT_, _PLUS_, _RANGLE_, \
|
|
36
35
|
_SLASH_, _SPACE_, _STAR_, _UNDER_
|
|
37
36
|
from pygeodesy.lazily import _ALL_LAZY, _getenv, _sys_version_info2
|
|
38
|
-
from pygeodesy.named import _Named, _NamedTuple, _NotImplemented
|
|
37
|
+
from pygeodesy.named import _Named, _NamedTuple, _NotImplemented
|
|
39
38
|
from pygeodesy.props import _allPropertiesOf_n, deprecated_property_RO, \
|
|
40
39
|
Property_RO, property_RO
|
|
41
|
-
|
|
40
|
+
from pygeodesy.streprs import Fmt, fstr, unstr
|
|
42
41
|
# from pygeodesy.units import Float, Int # from .constants
|
|
43
42
|
|
|
44
43
|
from math import ceil as _ceil, fabs, floor as _floor # PYCHOK used! .ltp
|
|
45
44
|
|
|
46
45
|
__all__ = _ALL_LAZY.fsums
|
|
47
|
-
__version__ = '24.05.
|
|
46
|
+
__version__ = '24.05.08'
|
|
48
47
|
|
|
48
|
+
_abs = abs
|
|
49
49
|
_add_op_ = _PLUS_ # in .auxilats.auxAngle
|
|
50
50
|
_eq_op_ = _EQUAL_ * 2 # _DEQUAL_
|
|
51
51
|
_div_ = 'div'
|
|
52
|
+
_Float = float # in .fstats
|
|
52
53
|
_floordiv_op_ = _SLASH_ * 2 # _DSLASH_
|
|
53
54
|
_fset_op_ = _EQUAL_
|
|
54
55
|
_ge_op_ = _RANGLE_ + _EQUAL_
|
|
55
56
|
_gt_op_ = _RANGLE_
|
|
56
57
|
_iadd_op_ = _add_op_ + _EQUAL_ # in .auxilats.auxAngle, .fstats
|
|
57
58
|
_integer_ = 'integer'
|
|
58
|
-
|
|
59
|
+
_isAn = isinstance # in .fstats
|
|
59
60
|
_le_op_ = _LANGLE_ + _EQUAL_
|
|
61
|
+
_len = len
|
|
62
|
+
_List = list
|
|
60
63
|
_lt_op_ = _LANGLE_
|
|
61
64
|
_mod_ = 'mod'
|
|
62
65
|
_mod_op_ = _PERCENT_
|
|
@@ -68,6 +71,7 @@ _significant_ = 'significant'
|
|
|
68
71
|
_sub_op_ = _DASH_ # in .auxilats.auxAngle
|
|
69
72
|
_threshold_ = 'threshold'
|
|
70
73
|
_truediv_op_ = _SLASH_
|
|
74
|
+
_Tuple = tuple # in .fstats
|
|
71
75
|
_divmod_op_ = _floordiv_op_ + _mod_op_
|
|
72
76
|
_isub_op_ = _sub_op_ + _fset_op_ # in .auxilats.auxAngle
|
|
73
77
|
|
|
@@ -79,22 +83,28 @@ def _2delta(*ab):
|
|
|
79
83
|
a, b = _2sum(*ab)
|
|
80
84
|
except _OverflowError:
|
|
81
85
|
a, b = ab
|
|
82
|
-
return
|
|
86
|
+
return _Float(a if fabs(a) > fabs(b) else b)
|
|
83
87
|
|
|
84
88
|
|
|
85
|
-
def _2error(unused):
|
|
89
|
+
def _2error(unused): # in .fstats
|
|
86
90
|
'''(INTERNAL) Throw a C{not-finite} exception.
|
|
87
91
|
'''
|
|
88
92
|
raise ValueError(_not_finite_)
|
|
89
93
|
|
|
90
94
|
|
|
95
|
+
def _2finite(x):
|
|
96
|
+
'''(INTERNAL) return C{float(x)} if finite.
|
|
97
|
+
'''
|
|
98
|
+
x = _Float(x)
|
|
99
|
+
return x if _isfinite(x) else _2error(x)
|
|
100
|
+
|
|
101
|
+
|
|
91
102
|
def _2float(index=None, **name_value): # in .fmath, .fstats
|
|
92
103
|
'''(INTERNAL) Raise C{TypeError} or C{ValueError} if not scalar or infinite.
|
|
93
104
|
'''
|
|
94
105
|
n, v = name_value.popitem() # _xkwds_item2(name_value)
|
|
95
106
|
try:
|
|
96
|
-
|
|
97
|
-
return v if _isfinite(v) else _2error(v)
|
|
107
|
+
return _2finite(v)
|
|
98
108
|
except Exception as X:
|
|
99
109
|
raise _xError(X, Fmt.INDEX(n, index), v)
|
|
100
110
|
|
|
@@ -103,14 +113,14 @@ def _X_ps(X): # for _2floats only
|
|
|
103
113
|
return X._ps
|
|
104
114
|
|
|
105
115
|
|
|
106
|
-
def _2floats(xs, origin=0, _X=_X_ps, _x=
|
|
116
|
+
def _2floats(xs, origin=0, _X=_X_ps, _x=_Float):
|
|
107
117
|
'''(INTERNAL) Yield each B{C{xs}} as a C{float}.
|
|
108
118
|
'''
|
|
109
119
|
try:
|
|
110
120
|
i, x = origin, None
|
|
111
121
|
_fin = _isfinite
|
|
112
122
|
_FsT = _Fsum_Fsum2Tuple_types
|
|
113
|
-
_is =
|
|
123
|
+
_is = _isAn
|
|
114
124
|
for x in xs:
|
|
115
125
|
if _is(x, _FsT):
|
|
116
126
|
for p in _X(x._Fsum):
|
|
@@ -147,16 +157,16 @@ def _2halfeven(s, r, p):
|
|
|
147
157
|
return s
|
|
148
158
|
|
|
149
159
|
|
|
150
|
-
def _isFsum(x):
|
|
160
|
+
def _isFsum(x): # in .fmath
|
|
151
161
|
'''(INTERNAL) Is C{x} an C{Fsum} instance?
|
|
152
162
|
'''
|
|
153
|
-
return
|
|
163
|
+
return _isAn(x, Fsum)
|
|
154
164
|
|
|
155
165
|
|
|
156
|
-
def _isFsumTuple(x):
|
|
166
|
+
def _isFsumTuple(x): # in .fmath
|
|
157
167
|
'''(INTERNAL) Is C{x} an C{Fsum} or C{Fsum2Tuple} instance?
|
|
158
168
|
'''
|
|
159
|
-
return
|
|
169
|
+
return _isAn(x, _Fsum_Fsum2Tuple_types)
|
|
160
170
|
|
|
161
171
|
|
|
162
172
|
def _1_Over(x, op, **raiser_RESIDUAL): # vs _1_over
|
|
@@ -167,7 +177,7 @@ def _1_Over(x, op, **raiser_RESIDUAL): # vs _1_over
|
|
|
167
177
|
|
|
168
178
|
def _1primed(xs): # in .fmath
|
|
169
179
|
'''(INTERNAL) 1-Primed summation of iterable C{xs}
|
|
170
|
-
items, all I{known} to be C{
|
|
180
|
+
items, all I{known} to be C{scalar}.
|
|
171
181
|
'''
|
|
172
182
|
yield _1_0
|
|
173
183
|
for x in xs:
|
|
@@ -178,8 +188,8 @@ def _1primed(xs): # in .fmath
|
|
|
178
188
|
def _psum(ps): # PYCHOK used!
|
|
179
189
|
'''(INTERNAL) Partials summation, updating C{ps}.
|
|
180
190
|
'''
|
|
181
|
-
# assert
|
|
182
|
-
i =
|
|
191
|
+
# assert _isAn(ps, _List)
|
|
192
|
+
i = _len(ps) - 1
|
|
183
193
|
s = _0_0 if i < 0 else ps[i]
|
|
184
194
|
_2s = _2sum
|
|
185
195
|
while i > 0:
|
|
@@ -196,20 +206,20 @@ def _psum(ps): # PYCHOK used!
|
|
|
196
206
|
return s
|
|
197
207
|
|
|
198
208
|
|
|
199
|
-
def _Psum(ps, **
|
|
209
|
+
def _Psum(ps, **name_RESIDUAL):
|
|
200
210
|
'''(INTERNAL) Return an C{Fsum} from I{ordered} partials C{ps}.
|
|
201
211
|
'''
|
|
202
|
-
|
|
212
|
+
f = Fsum(**name_RESIDUAL) if name_RESIDUAL else Fsum()
|
|
203
213
|
if ps:
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
return
|
|
214
|
+
f._ps[:] = ps
|
|
215
|
+
f._n = _len(f._ps)
|
|
216
|
+
return f
|
|
207
217
|
|
|
208
218
|
|
|
209
|
-
def _Psum_(*ps, **
|
|
219
|
+
def _Psum_(*ps, **name_RESIDUAL):
|
|
210
220
|
'''(INTERNAL) Return an C{Fsum} from 1 or 2 known scalar(s) C{ps}.
|
|
211
221
|
'''
|
|
212
|
-
return _Psum(ps, **
|
|
222
|
+
return _Psum(ps, **name_RESIDUAL)
|
|
213
223
|
|
|
214
224
|
|
|
215
225
|
def _2scalar2(other):
|
|
@@ -245,7 +255,7 @@ def _strcomplex(s, *args):
|
|
|
245
255
|
'''(INTERNAL) C{Complex} 2- or 3-arg C{pow} error as C{str}.
|
|
246
256
|
'''
|
|
247
257
|
c = _strcomplex.__name__[4:]
|
|
248
|
-
n = _DASH_(
|
|
258
|
+
n = _DASH_(_len(args), _arg_)
|
|
249
259
|
t = unstr(pow, *args)
|
|
250
260
|
return _SPACE_(c, s, _from_, n, t)
|
|
251
261
|
|
|
@@ -278,7 +288,7 @@ def _threshold(threshold):
|
|
|
278
288
|
'''(INTERNAL) Get the L{ResidualError}s threshold.
|
|
279
289
|
'''
|
|
280
290
|
try:
|
|
281
|
-
t =
|
|
291
|
+
t = _Float(threshold) or _0_0
|
|
282
292
|
return t if _isfinite(t) else _2error(t) # PYCHOK None
|
|
283
293
|
except Exception as x:
|
|
284
294
|
raise ResidualError(threshold=threshold, cause=x)
|
|
@@ -305,10 +315,10 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
305
315
|
file I{Modules/mathmodule.c} and the issue log U{Full precision summation
|
|
306
316
|
<https://Bugs.Python.org/issue2819>}.
|
|
307
317
|
'''
|
|
308
|
-
_math_fsum =
|
|
318
|
+
_math_fsum = None
|
|
309
319
|
_n = 0
|
|
310
320
|
# _ps = [] # partial sums
|
|
311
|
-
# _ps_max = 0 # max(Fsum._ps_max,
|
|
321
|
+
# _ps_max = 0 # max(Fsum._ps_max, _len(Fsum._ps))
|
|
312
322
|
_RESIDUAL = _threshold(_getenv('PYGEODESY_FSUM_RESIDUAL', _0_0))
|
|
313
323
|
|
|
314
324
|
def __init__(self, *xs, **name_RESIDUAL):
|
|
@@ -323,12 +333,12 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
323
333
|
'''
|
|
324
334
|
if name_RESIDUAL:
|
|
325
335
|
|
|
326
|
-
def
|
|
336
|
+
def _n_R(name=NN, RESIDUAL=None):
|
|
327
337
|
return name, RESIDUAL
|
|
328
338
|
|
|
329
|
-
n,
|
|
330
|
-
if
|
|
331
|
-
self.RESIDUAL(
|
|
339
|
+
n, R = _n_R(**name_RESIDUAL)
|
|
340
|
+
if R is not None:
|
|
341
|
+
self.RESIDUAL(R)
|
|
332
342
|
if n:
|
|
333
343
|
self.name = n
|
|
334
344
|
|
|
@@ -349,12 +359,12 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
349
359
|
|
|
350
360
|
@return: The sum (L{Fsum}).
|
|
351
361
|
|
|
352
|
-
@see:
|
|
362
|
+
@see: Methods L{Fsum.fadd_} and L{Fsum.fadd}.
|
|
353
363
|
'''
|
|
354
364
|
f = self._copy_2(self.__add__)
|
|
355
365
|
return f._fadd(other, _add_op_)
|
|
356
366
|
|
|
357
|
-
def __bool__(self): # PYCHOK
|
|
367
|
+
def __bool__(self): # PYCHOK Python 3+
|
|
358
368
|
'''Return C{True} if this instance is I{exactly} non-zero.
|
|
359
369
|
'''
|
|
360
370
|
s, r = self._fprs2
|
|
@@ -392,7 +402,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
392
402
|
@raise ResidualError: Non-zero, significant residual or invalid
|
|
393
403
|
B{C{RESIDUAL}}.
|
|
394
404
|
|
|
395
|
-
@see: Method L{Fsum.
|
|
405
|
+
@see: Method L{Fsum.fdiv}.
|
|
396
406
|
'''
|
|
397
407
|
f = self._copy_2(self.__divmod__)
|
|
398
408
|
return f._fdivmod2(other, _divmod_op_, **raiser_RESIDUAL)
|
|
@@ -407,7 +417,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
407
417
|
|
|
408
418
|
@see: Methods L{Fsum.fsum} and L{Fsum.int_float}.
|
|
409
419
|
'''
|
|
410
|
-
return
|
|
420
|
+
return _Float(self._fprs)
|
|
411
421
|
|
|
412
422
|
def __floor__(self): # PYCHOK not special in Python 2-
|
|
413
423
|
'''Return this instance' C{math.floor} as C{int} or C{float}.
|
|
@@ -459,7 +469,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
459
469
|
@raise TypeError: Invalid B{C{other}}, not
|
|
460
470
|
C{scalar} nor L{Fsum}.
|
|
461
471
|
|
|
462
|
-
@see: Methods L{Fsum.
|
|
472
|
+
@see: Methods L{Fsum.fadd_} and L{Fsum.fadd}.
|
|
463
473
|
'''
|
|
464
474
|
return self._fadd(other, _iadd_op_)
|
|
465
475
|
|
|
@@ -516,9 +526,8 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
516
526
|
def __int__(self):
|
|
517
527
|
'''Return this instance as an C{int}.
|
|
518
528
|
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
L{Fsum.ceil} and L{Fsum.floor}.
|
|
529
|
+
@see: Method L{Fsum.int_float} and properties L{Fsum.ceil}
|
|
530
|
+
and L{Fsum.floor}.
|
|
522
531
|
'''
|
|
523
532
|
i, _ = self._fint2
|
|
524
533
|
return i
|
|
@@ -575,7 +584,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
575
584
|
|
|
576
585
|
@raise TypeError: Invalid B{C{other}} type.
|
|
577
586
|
|
|
578
|
-
@see:
|
|
587
|
+
@see: Methods L{Fsum.fsub_} and L{Fsum.fsub}.
|
|
579
588
|
'''
|
|
580
589
|
return self._fsub(other, _isub_op_)
|
|
581
590
|
|
|
@@ -725,7 +734,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
725
734
|
'''
|
|
726
735
|
f = self._copy_2(self.__round__)
|
|
727
736
|
# <https://docs.Python.org/3.12/reference/datamodel.html?#object.__round__>
|
|
728
|
-
return f._fset(round(
|
|
737
|
+
return f._fset(round(_Float(self), *ndigits)) # can be C{int}
|
|
729
738
|
|
|
730
739
|
def __rpow__(self, other, *mod):
|
|
731
740
|
'''Return C{B{other}**B{self}} as an L{Fsum}.
|
|
@@ -783,8 +792,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
783
792
|
|
|
784
793
|
@see: Method L{Fsum.__itruediv__}.
|
|
785
794
|
'''
|
|
786
|
-
|
|
787
|
-
return f._ftruediv(other, _truediv_op_, **raiser_RESIDUAL)
|
|
795
|
+
return self._truediv(other, _truediv_op_, **raiser_RESIDUAL)
|
|
788
796
|
|
|
789
797
|
__trunc__ = __int__
|
|
790
798
|
|
|
@@ -799,14 +807,15 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
799
807
|
def as_integer_ratio(self):
|
|
800
808
|
'''Return this instance as the ratio of 2 integers.
|
|
801
809
|
|
|
802
|
-
@return: 2-Tuple C{(numerator, denominator)} both
|
|
803
|
-
C{
|
|
810
|
+
@return: 2-Tuple C{(numerator, denominator)} both C{int}
|
|
811
|
+
with C{numerator} signed and C{denominator}
|
|
812
|
+
non-zero, positive.
|
|
804
813
|
|
|
805
|
-
@see: Standard C{float.as_integer_ratio} in Python
|
|
814
|
+
@see: Standard C{float.as_integer_ratio} in Python 2.7+.
|
|
806
815
|
'''
|
|
807
816
|
n, r = self._fint2
|
|
808
817
|
if r:
|
|
809
|
-
i, d =
|
|
818
|
+
i, d = _Float(r).as_integer_ratio()
|
|
810
819
|
n *= d
|
|
811
820
|
n += i
|
|
812
821
|
else: # PYCHOK no cover
|
|
@@ -815,17 +824,18 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
815
824
|
|
|
816
825
|
@property_RO
|
|
817
826
|
def as_iscalar(self):
|
|
818
|
-
'''Get this instance I{as-is} (L{Fsum}
|
|
827
|
+
'''Get this instance I{as-is} (L{Fsum} or C{scalar}), the
|
|
828
|
+
latter only if the C{residual} equals C{zero}.
|
|
819
829
|
'''
|
|
820
830
|
s, r = self._fprs2
|
|
821
831
|
return self if r else s
|
|
822
832
|
|
|
823
833
|
@property_RO
|
|
824
834
|
def ceil(self):
|
|
825
|
-
'''Get this instance' C{ceil} value (C{int} in Python 3+,
|
|
826
|
-
|
|
835
|
+
'''Get this instance' C{ceil} value (C{int} in Python 3+, but
|
|
836
|
+
C{float} in Python 2-).
|
|
827
837
|
|
|
828
|
-
@note:
|
|
838
|
+
@note: This C{ceil} takes the C{residual} into account.
|
|
829
839
|
|
|
830
840
|
@see: Method L{Fsum.int_float} and properties L{Fsum.floor},
|
|
831
841
|
L{Fsum.imag} and L{Fsum.real}.
|
|
@@ -834,7 +844,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
834
844
|
c = _ceil(s) + int(r) - 1
|
|
835
845
|
while r > (c - s): # (s + r) > c
|
|
836
846
|
c += 1
|
|
837
|
-
return c
|
|
847
|
+
return c # _ceil(self._n_d)
|
|
838
848
|
|
|
839
849
|
cmp = __cmp__
|
|
840
850
|
|
|
@@ -842,11 +852,11 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
842
852
|
'''(INTERNAL) Return C{scalar(self - B{other})} for 0-comparison.
|
|
843
853
|
'''
|
|
844
854
|
if _isFsumTuple(other):
|
|
845
|
-
s =
|
|
855
|
+
s = self._ps_1sum(*other._ps)
|
|
846
856
|
elif self._scalar(other, op):
|
|
847
|
-
s =
|
|
857
|
+
s = self._ps_1sum(other)
|
|
848
858
|
else:
|
|
849
|
-
s =
|
|
859
|
+
s = self.signOf() # res=True
|
|
850
860
|
return s
|
|
851
861
|
|
|
852
862
|
def copy(self, deep=False, name=NN):
|
|
@@ -856,9 +866,10 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
856
866
|
'''
|
|
857
867
|
f = _Named.copy(self, deep=deep, name=name)
|
|
858
868
|
if f._ps is self._ps:
|
|
859
|
-
f._ps =
|
|
869
|
+
f._ps = _List(self._ps) # separate list
|
|
860
870
|
if not deep:
|
|
861
871
|
f._n = 1
|
|
872
|
+
# assert f._Fsum is f
|
|
862
873
|
return f
|
|
863
874
|
|
|
864
875
|
def _copy_2(self, which, name=NN):
|
|
@@ -867,8 +878,9 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
867
878
|
n = name or which.__name__
|
|
868
879
|
# NOT .classof due to .Fdot(a, *b) args, etc.
|
|
869
880
|
f = _Named.copy(self, deep=False, name=n)
|
|
881
|
+
f._ps = _List(self._ps) # separate list
|
|
870
882
|
# assert f._n == self._n
|
|
871
|
-
|
|
883
|
+
# assert f._Fsum is f
|
|
872
884
|
return f
|
|
873
885
|
|
|
874
886
|
def _copy_2r(self, other, which):
|
|
@@ -903,7 +915,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
903
915
|
'''(INTERNAL) Format the caught exception C{X}.
|
|
904
916
|
'''
|
|
905
917
|
E, t = _xError2(X)
|
|
906
|
-
u = unstr(self.named3, *xs[:3], _ELLIPSIS=
|
|
918
|
+
u = unstr(self.named3, *xs[:3], _ELLIPSIS=_len(xs) > 3, **kwds)
|
|
907
919
|
return E(u, txt=t, cause=X)
|
|
908
920
|
|
|
909
921
|
def _facc(self, xs, up=True, **origin_X_x):
|
|
@@ -912,14 +924,14 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
912
924
|
if xs:
|
|
913
925
|
_xs = _2floats(xs, **origin_X_x) # PYCHOK yield
|
|
914
926
|
ps = self._ps
|
|
915
|
-
ps[:] = self._ps_acc(
|
|
927
|
+
ps[:] = self._ps_acc(_List(ps), _xs, up=up)
|
|
916
928
|
return self
|
|
917
929
|
|
|
918
930
|
def _facc_1(self, xs, **up):
|
|
919
931
|
'''(INTERNAL) Accumulate 0, 1 or more C{scalars} or L{Fsum}s,
|
|
920
932
|
all positional C{xs} in the caller of this method.
|
|
921
933
|
'''
|
|
922
|
-
return self._fadd(xs[0], _add_op_, **up) if
|
|
934
|
+
return self._fadd(xs[0], _add_op_, **up) if _len(xs) == 1 else \
|
|
923
935
|
self._facc(xs, origin=1, **up)
|
|
924
936
|
|
|
925
937
|
def _facc_neg(self, xs, **up_origin):
|
|
@@ -929,7 +941,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
929
941
|
return X._ps_neg
|
|
930
942
|
|
|
931
943
|
def _n(x):
|
|
932
|
-
return -
|
|
944
|
+
return -_Float(x)
|
|
933
945
|
|
|
934
946
|
return self._facc(xs, _X=_N, _x=_n, **up_origin)
|
|
935
947
|
|
|
@@ -955,15 +967,16 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
955
967
|
_Pow, p, s, r = _Pow4(power)
|
|
956
968
|
if p: # and xs:
|
|
957
969
|
op = which.__name__
|
|
958
|
-
|
|
970
|
+
_Fs = Fsum
|
|
971
|
+
_is = _isAn
|
|
959
972
|
_pow = self._pow_2_3
|
|
960
973
|
|
|
961
974
|
def _P(X):
|
|
962
975
|
f = _Pow(X, p, power, op, **raiser_RESIDUAL)
|
|
963
|
-
return f._ps if
|
|
976
|
+
return f._ps if _is(f, _Fs) else (f,)
|
|
964
977
|
|
|
965
978
|
def _p(x):
|
|
966
|
-
x =
|
|
979
|
+
x = _Float(x)
|
|
967
980
|
f = _pow(x, s, power, op, **raiser_RESIDUAL)
|
|
968
981
|
if f and r:
|
|
969
982
|
f *= _pow(x, r, power, op, **raiser_RESIDUAL)
|
|
@@ -971,7 +984,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
971
984
|
|
|
972
985
|
f = self._facc(xs, origin=1, _X=_P, _x=_p)
|
|
973
986
|
else:
|
|
974
|
-
f = self._facc_scalar_(
|
|
987
|
+
f = self._facc_scalar_(_Float(_len(xs))) # x**0 == 1
|
|
975
988
|
return f
|
|
976
989
|
|
|
977
990
|
def _facc_scalar(self, xs, **up):
|
|
@@ -993,7 +1006,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
993
1006
|
# and re-accumulating the final C{partial}.
|
|
994
1007
|
# '''
|
|
995
1008
|
# ps = self._ps
|
|
996
|
-
# while
|
|
1009
|
+
# while _len(ps) > 1:
|
|
997
1010
|
# p = ps.pop()
|
|
998
1011
|
# if p:
|
|
999
1012
|
# n = self._n
|
|
@@ -1003,7 +1016,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1003
1016
|
# return self._update() if up else self
|
|
1004
1017
|
|
|
1005
1018
|
def fadd(self, xs=()):
|
|
1006
|
-
'''Add
|
|
1019
|
+
'''Add an iterable's items to this instance.
|
|
1007
1020
|
|
|
1008
1021
|
@arg xs: Iterable of items to add (each C{scalar}
|
|
1009
1022
|
or an L{Fsum} or L{Fsum2Tuple} instance).
|
|
@@ -1017,7 +1030,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1017
1030
|
@raise ValueError: Invalid or non-finite B{C{xs}} value.
|
|
1018
1031
|
'''
|
|
1019
1032
|
if _isFsumTuple(xs):
|
|
1020
|
-
self._facc_scalar(xs._ps) #
|
|
1033
|
+
self._facc_scalar(xs._ps) # _Tuple(xs._ps)
|
|
1021
1034
|
elif isscalar(xs): # for backward compatibility
|
|
1022
1035
|
self._facc_scalar_(_2float(x=xs)) # PYCHOK no cover
|
|
1023
1036
|
elif xs: # assert isiterable(xs)
|
|
@@ -1025,7 +1038,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1025
1038
|
return self
|
|
1026
1039
|
|
|
1027
1040
|
def fadd_(self, *xs):
|
|
1028
|
-
'''Add all positional
|
|
1041
|
+
'''Add all positional items to this instance.
|
|
1029
1042
|
|
|
1030
1043
|
@arg xs: Values to add (each C{scalar} or an L{Fsum}
|
|
1031
1044
|
or L{Fsum2Tuple} instance), all positional.
|
|
@@ -1037,15 +1050,17 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1037
1050
|
def _fadd(self, other, op, **up): # in .fmath.Fhorner
|
|
1038
1051
|
'''(INTERNAL) Apply C{B{self} += B{other}}.
|
|
1039
1052
|
'''
|
|
1040
|
-
if
|
|
1041
|
-
self.
|
|
1053
|
+
if not self._ps: # new Fsum(x)
|
|
1054
|
+
self._fset(other, as_is=False, **up)
|
|
1055
|
+
elif _isFsumTuple(other):
|
|
1056
|
+
self._facc_scalar(other._ps, **up) # _Tuple
|
|
1042
1057
|
elif self._scalar(other, op):
|
|
1043
1058
|
self._facc_scalar_(other, **up)
|
|
1044
1059
|
return self
|
|
1045
1060
|
|
|
1046
|
-
fcopy = copy
|
|
1047
|
-
fdiv = __itruediv__
|
|
1048
|
-
fdivmod = __divmod__
|
|
1061
|
+
fcopy = copy # for backward compatibility
|
|
1062
|
+
fdiv = __itruediv__
|
|
1063
|
+
fdivmod = __divmod__
|
|
1049
1064
|
|
|
1050
1065
|
def _fdivmod2(self, other, op, **raiser_RESIDUAL):
|
|
1051
1066
|
'''(INTERNAL) Apply C{B{self} %= B{other}} and return a L{DivMod2Tuple}.
|
|
@@ -1053,10 +1068,9 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1053
1068
|
# result mostly follows CPython function U{float_divmod
|
|
1054
1069
|
# <https://GitHub.com/python/cpython/blob/main/Objects/floatobject.c>},
|
|
1055
1070
|
# but at least divmod(-3, 2) equals Cpython's result (-2, 1).
|
|
1056
|
-
q = self.
|
|
1057
|
-
q = q._ftruediv(other, op, **raiser_RESIDUAL).floor
|
|
1071
|
+
q = self._truediv(other, op, **raiser_RESIDUAL).floor
|
|
1058
1072
|
if q: # == float // other == floor(float / other)
|
|
1059
|
-
self -= Fsum(
|
|
1073
|
+
self -= Fsum(q) * other # NOT other * q!
|
|
1060
1074
|
|
|
1061
1075
|
s = signOf(other) # make signOf(self) == signOf(other)
|
|
1062
1076
|
if s and self.signOf() == -s: # PYCHOK no cover
|
|
@@ -1073,7 +1087,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1073
1087
|
if _isfinite(other):
|
|
1074
1088
|
return other
|
|
1075
1089
|
raise ValueError(_not_finite_) if op is None else \
|
|
1076
|
-
|
|
1090
|
+
self._Error(op, other, _ValueError, txt=_not_finite_)
|
|
1077
1091
|
|
|
1078
1092
|
def fint(self, name=NN, **raiser_RESIDUAL):
|
|
1079
1093
|
'''Return this instance' current running sum as C{integer}.
|
|
@@ -1089,7 +1103,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1089
1103
|
@raise ResidualError: Non-zero, significant residual or invalid
|
|
1090
1104
|
B{C{RESIDUAL}}.
|
|
1091
1105
|
|
|
1092
|
-
@see: Methods L{Fsum.int_float} and L{Fsum.is_integer}.
|
|
1106
|
+
@see: Methods L{Fsum.fint2}, L{Fsum.int_float} and L{Fsum.is_integer}.
|
|
1093
1107
|
'''
|
|
1094
1108
|
i, r = self._fint2
|
|
1095
1109
|
if r:
|
|
@@ -1118,7 +1132,8 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1118
1132
|
'''
|
|
1119
1133
|
s, r = self._fprs2
|
|
1120
1134
|
i = int(s)
|
|
1121
|
-
|
|
1135
|
+
n = _len(self._ps)
|
|
1136
|
+
r = self._ps_1sum(i) if r and n > 1 else _Float(s - i)
|
|
1122
1137
|
return i, (r or INT0) # Fsum2Tuple?
|
|
1123
1138
|
|
|
1124
1139
|
@deprecated_property_RO
|
|
@@ -1131,7 +1146,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1131
1146
|
'''Get this instance' C{floor} (C{int} in Python 3+, but
|
|
1132
1147
|
C{float} in Python 2-).
|
|
1133
1148
|
|
|
1134
|
-
@note:
|
|
1149
|
+
@note: This C{floor} takes the C{residual} into account.
|
|
1135
1150
|
|
|
1136
1151
|
@see: Method L{Fsum.int_float} and properties L{Fsum.ceil},
|
|
1137
1152
|
L{Fsum.imag} and L{Fsum.real}.
|
|
@@ -1140,9 +1155,10 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1140
1155
|
f = _floor(s) + _floor(r) + 1
|
|
1141
1156
|
while (f - s) > r: # f > (s + r)
|
|
1142
1157
|
f -= 1
|
|
1143
|
-
return f
|
|
1158
|
+
return f # _floor(self._n_d)
|
|
1144
1159
|
|
|
1145
|
-
#
|
|
1160
|
+
# ffloordiv = __ifloordiv__ # for naming consistency
|
|
1161
|
+
# floordiv = __floordiv__ # for naming consistency
|
|
1146
1162
|
|
|
1147
1163
|
def _floordiv(self, other, op, **raiser_RESIDUAL): # rather _ffloordiv?
|
|
1148
1164
|
'''Apply C{B{self} //= B{other}}.
|
|
@@ -1150,22 +1166,22 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1150
1166
|
q = self._ftruediv(other, op, **raiser_RESIDUAL) # == self
|
|
1151
1167
|
return self._fset(q.floor) # floor(q)
|
|
1152
1168
|
|
|
1153
|
-
fmul = __imul__
|
|
1169
|
+
fmul = __imul__
|
|
1154
1170
|
|
|
1155
1171
|
def _fmul(self, other, op):
|
|
1156
1172
|
'''(INTERNAL) Apply C{B{self} *= B{other}}.
|
|
1157
1173
|
'''
|
|
1158
1174
|
if _isFsumTuple(other):
|
|
1159
|
-
if
|
|
1175
|
+
if _len(self._ps) != 1:
|
|
1160
1176
|
f = self._mul_Fsum(other, op)
|
|
1161
|
-
elif
|
|
1177
|
+
elif _len(other._ps) != 1: # and _len(self._ps) == 1
|
|
1162
1178
|
f = other._mul_scalar(self._ps[0], op)
|
|
1163
|
-
else: #
|
|
1179
|
+
else: # _len(other._ps) == _len(self._ps) == 1
|
|
1164
1180
|
f = self._finite(self._ps[0] * other._ps[0])
|
|
1165
1181
|
else:
|
|
1166
1182
|
s = self._scalar(other, op)
|
|
1167
1183
|
f = self._mul_scalar(s, op)
|
|
1168
|
-
return self._fset(f) # n=
|
|
1184
|
+
return self._fset(f) # n=_len(self) + 1
|
|
1169
1185
|
|
|
1170
1186
|
def fover(self, over, **raiser_RESIDUAL):
|
|
1171
1187
|
'''Apply C{B{self} /= B{over}} and summate.
|
|
@@ -1182,9 +1198,9 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1182
1198
|
|
|
1183
1199
|
@see: Methods L{Fsum.fsum} and L{Fsum.__itruediv__}.
|
|
1184
1200
|
'''
|
|
1185
|
-
return
|
|
1201
|
+
return _Float(self.fdiv(over, **raiser_RESIDUAL)._fprs)
|
|
1186
1202
|
|
|
1187
|
-
fpow = __ipow__
|
|
1203
|
+
fpow = __ipow__
|
|
1188
1204
|
|
|
1189
1205
|
def _fpow(self, other, op, *mod, **raiser_RESIDUAL):
|
|
1190
1206
|
'''Apply C{B{self} **= B{other}}, optional B{C{mod}} or C{None}.
|
|
@@ -1202,7 +1218,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1202
1218
|
f = self._pow(other, other, op, **raiser_RESIDUAL)
|
|
1203
1219
|
else: # pow(self, other)
|
|
1204
1220
|
f = self._pow(other, other, op, **raiser_RESIDUAL)
|
|
1205
|
-
return self._fset(f,
|
|
1221
|
+
return self._fset(f, as_is=isint(f)) # n=max(_len(self), 1)
|
|
1206
1222
|
|
|
1207
1223
|
@Property_RO
|
|
1208
1224
|
def _fprs(self):
|
|
@@ -1212,47 +1228,49 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1212
1228
|
@note: The precision running C{fsum} after a C{//=} or
|
|
1213
1229
|
C{//} C{floor} division is C{int} in Python 3+.
|
|
1214
1230
|
'''
|
|
1215
|
-
|
|
1231
|
+
s, _ = self._fprs2
|
|
1232
|
+
return s # ._fprs2.fsum
|
|
1216
1233
|
|
|
1217
1234
|
@Property_RO
|
|
1218
1235
|
def _fprs2(self):
|
|
1219
1236
|
'''(INTERNAL) Get and cache this instance' precision
|
|
1220
1237
|
running sum and residual (L{Fsum2Tuple}).
|
|
1221
1238
|
'''
|
|
1222
|
-
ps =
|
|
1223
|
-
n =
|
|
1224
|
-
if n > 0: #
|
|
1239
|
+
ps = self._ps
|
|
1240
|
+
n = _len(ps) - 2
|
|
1241
|
+
if n > 0: # _len(ps) > 2
|
|
1225
1242
|
s = _psum(ps)
|
|
1226
|
-
n =
|
|
1243
|
+
n = _len(ps) - 2
|
|
1227
1244
|
if n > 0:
|
|
1228
|
-
r =
|
|
1245
|
+
r = self._ps_1sum(s)
|
|
1229
1246
|
return Fsum2Tuple(*_s_r(s, r))
|
|
1230
|
-
if n == 0: #
|
|
1247
|
+
if n == 0: # _len(ps) == 2
|
|
1231
1248
|
s, r = _s_r(*_2sum(*ps))
|
|
1232
1249
|
ps[:] = (r, s) if r else (s,)
|
|
1233
|
-
elif ps: #
|
|
1250
|
+
elif ps: # _len(ps) == 1
|
|
1234
1251
|
s, r = ps[0], INT0
|
|
1235
|
-
else: #
|
|
1252
|
+
else: # _len(ps) == 0
|
|
1236
1253
|
s, r = _0_0, INT0
|
|
1237
1254
|
ps[:] = s,
|
|
1238
1255
|
# assert self._ps is ps
|
|
1239
1256
|
return Fsum2Tuple(s, r)
|
|
1240
1257
|
|
|
1241
1258
|
def fset_(self, *xs):
|
|
1242
|
-
'''Replace this instance' value with
|
|
1259
|
+
'''Replace this instance' value with all positional items.
|
|
1243
1260
|
|
|
1244
1261
|
@arg xs: Optional, new values (each C{scalar} or
|
|
1245
1262
|
an L{Fsum} or L{Fsum2Tuple} instance),
|
|
1246
1263
|
all positional.
|
|
1247
1264
|
|
|
1248
|
-
@return: This instance (C{Fsum}).
|
|
1265
|
+
@return: This instance, replaced (C{Fsum}).
|
|
1249
1266
|
|
|
1250
1267
|
@see: Method L{Fsum.fadd} for further details.
|
|
1251
1268
|
'''
|
|
1252
|
-
f =
|
|
1269
|
+
f = xs[0] if len(xs) == 1 else (
|
|
1270
|
+
Fsum(*xs) if xs else _0_0)
|
|
1253
1271
|
return self._fset(f)
|
|
1254
1272
|
|
|
1255
|
-
def _fset(self, other,
|
|
1273
|
+
def _fset(self, other, as_is=True, n=0, up=True):
|
|
1256
1274
|
'''(INTERNAL) Overwrite this instance with an other or a C{scalar}.
|
|
1257
1275
|
'''
|
|
1258
1276
|
if other is self:
|
|
@@ -1261,21 +1279,22 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1261
1279
|
self._ps[:] = other._ps
|
|
1262
1280
|
self._n = n or other._n
|
|
1263
1281
|
# self._copy_RESIDUAL(other)
|
|
1264
|
-
# use or zap the C{Property_RO} values
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1282
|
+
if up: # use or zap the C{Property_RO} values
|
|
1283
|
+
Fsum._fint2._update_from(self, other)
|
|
1284
|
+
Fsum._fprs ._update_from(self, other)
|
|
1285
|
+
Fsum._fprs2._update_from(self, other)
|
|
1268
1286
|
elif isscalar(other):
|
|
1269
|
-
s = other if
|
|
1270
|
-
i = int(s) # see ._fint2
|
|
1271
|
-
t = i, ((s - i) or INT0)
|
|
1287
|
+
s = other if as_is else _Float(other)
|
|
1272
1288
|
self._ps[:] = s,
|
|
1273
1289
|
self._n = n or 1
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1290
|
+
if up:
|
|
1291
|
+
i = int(s) # see ._fint2
|
|
1292
|
+
t = i, ((s - i) or INT0)
|
|
1293
|
+
# Property_ROs _fint2, _fprs and _fprs2 can't be a Property:
|
|
1294
|
+
# Property's _fset zaps the value just set by the @setter
|
|
1295
|
+
self.__dict__.update(_fint2=t, _fprs=s, _fprs2=Fsum2Tuple(s, INT0))
|
|
1277
1296
|
else: # PYCHOK no cover
|
|
1278
|
-
raise self._Error(_fset_op_, other,
|
|
1297
|
+
raise self._Error(_fset_op_, other, _TypeError)
|
|
1279
1298
|
return self
|
|
1280
1299
|
|
|
1281
1300
|
def _fset_ps(self, other, n=0): # in .fmath
|
|
@@ -1290,18 +1309,18 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1290
1309
|
return self
|
|
1291
1310
|
|
|
1292
1311
|
def fsub(self, xs=()):
|
|
1293
|
-
'''Subtract
|
|
1312
|
+
'''Subtract an iterable's items from this instance.
|
|
1294
1313
|
|
|
1295
1314
|
@see: Method L{Fsum.fadd} for further details.
|
|
1296
1315
|
'''
|
|
1297
1316
|
return self._facc_neg(xs)
|
|
1298
1317
|
|
|
1299
1318
|
def fsub_(self, *xs):
|
|
1300
|
-
'''Subtract all positional
|
|
1319
|
+
'''Subtract all positional items from this instance.
|
|
1301
1320
|
|
|
1302
1321
|
@see: Method L{Fsum.fadd_} for further details.
|
|
1303
1322
|
'''
|
|
1304
|
-
return self._fsub(xs[0], _sub_op_) if
|
|
1323
|
+
return self._fsub(xs[0], _sub_op_) if _len(xs) == 1 else \
|
|
1305
1324
|
self._facc_neg(xs, origin=1)
|
|
1306
1325
|
|
|
1307
1326
|
def _fsub(self, other, op):
|
|
@@ -1309,7 +1328,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1309
1328
|
'''
|
|
1310
1329
|
if _isFsumTuple(other):
|
|
1311
1330
|
if other is self: # or other._fprs2 == self._fprs2:
|
|
1312
|
-
self._fset(_0_0, n=
|
|
1331
|
+
self._fset(_0_0, n=_len(self) * 2)
|
|
1313
1332
|
elif other._ps:
|
|
1314
1333
|
self._facc_scalar(other._ps_neg)
|
|
1315
1334
|
elif self._scalar(other, op):
|
|
@@ -1317,8 +1336,8 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1317
1336
|
return self
|
|
1318
1337
|
|
|
1319
1338
|
def fsum(self, xs=()):
|
|
1320
|
-
'''Add
|
|
1321
|
-
|
|
1339
|
+
'''Add an iterable's items, summate and return the
|
|
1340
|
+
current precision running sum.
|
|
1322
1341
|
|
|
1323
1342
|
@arg xs: Iterable of items to add (each item C{scalar}
|
|
1324
1343
|
or an L{Fsum} or L{Fsum2Tuple} instance).
|
|
@@ -1332,10 +1351,10 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1332
1351
|
return self._facc(xs)._fprs
|
|
1333
1352
|
|
|
1334
1353
|
def fsum_(self, *xs):
|
|
1335
|
-
'''Add any positional
|
|
1354
|
+
'''Add any positional items, summate and return the
|
|
1336
1355
|
current precision running sum.
|
|
1337
1356
|
|
|
1338
|
-
@arg xs:
|
|
1357
|
+
@arg xs: Items to add (each C{scalar} or an L{Fsum}
|
|
1339
1358
|
or L{Fsum2Tuple} instance), all positional.
|
|
1340
1359
|
|
|
1341
1360
|
@return: Precision running sum (C{float} or C{int}).
|
|
@@ -1345,17 +1364,15 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1345
1364
|
return self._facc_1(xs)._fprs
|
|
1346
1365
|
|
|
1347
1366
|
@property_RO
|
|
1348
|
-
def _Fsum(self):
|
|
1349
|
-
|
|
1350
|
-
'''
|
|
1351
|
-
return self
|
|
1367
|
+
def _Fsum(self): # like L{Fsum2Tuple._Fsum}, for C{_2floats}, .fstats
|
|
1368
|
+
return self # NOT @Property_RO, see .copy and ._copy_2
|
|
1352
1369
|
|
|
1353
1370
|
def Fsum_(self, *xs, **name):
|
|
1354
1371
|
'''Like method L{Fsum.fsum_} but returning a named L{Fsum}.
|
|
1355
1372
|
|
|
1356
1373
|
@kwarg name: Optional name (C{str}).
|
|
1357
1374
|
|
|
1358
|
-
@return:
|
|
1375
|
+
@return: Copy of this updated instance (L{Fsum}).
|
|
1359
1376
|
'''
|
|
1360
1377
|
return self._facc_1(xs)._copy_2(self.Fsum_, **name)
|
|
1361
1378
|
|
|
@@ -1364,12 +1381,12 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1364
1381
|
|
|
1365
1382
|
@kwarg name: Optional name (C{str}).
|
|
1366
1383
|
|
|
1367
|
-
@return:
|
|
1384
|
+
@return: Precision running sum (L{Fsum2Tuple}).
|
|
1368
1385
|
'''
|
|
1369
1386
|
return Fsum2Tuple(self._facc_1(xs)._fprs2, **name)
|
|
1370
1387
|
|
|
1371
1388
|
def fsum2(self, xs=(), name=NN):
|
|
1372
|
-
'''Add
|
|
1389
|
+
'''Add an iterable's items, summate and return the
|
|
1373
1390
|
current precision running sum I{and} the C{residual}.
|
|
1374
1391
|
|
|
1375
1392
|
@arg xs: Iterable of items to add (each item C{scalar}
|
|
@@ -1388,8 +1405,8 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1388
1405
|
return t.dup(name=name) if name else t
|
|
1389
1406
|
|
|
1390
1407
|
def fsum2_(self, *xs):
|
|
1391
|
-
'''Add any positional
|
|
1392
|
-
precision running sum
|
|
1408
|
+
'''Add any positional items, summate and return the current
|
|
1409
|
+
precision running sum and the I{differential}.
|
|
1393
1410
|
|
|
1394
1411
|
@arg xs: Values to add (each C{scalar} or an L{Fsum} or
|
|
1395
1412
|
L{Fsum2Tuple} instance), all positional.
|
|
@@ -1435,7 +1452,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1435
1452
|
n = _1_0
|
|
1436
1453
|
if _isFsumTuple(other):
|
|
1437
1454
|
if other is self or self == other:
|
|
1438
|
-
return self._fset(n) # n=
|
|
1455
|
+
return self._fset(n) # n=_len(self)
|
|
1439
1456
|
d, r = other._fprs2
|
|
1440
1457
|
if r:
|
|
1441
1458
|
R = self._raiser(r, d, **raiser_RESIDUAL)
|
|
@@ -1449,13 +1466,13 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1449
1466
|
except Exception as X:
|
|
1450
1467
|
raise self._ErrorX(X, op, other)
|
|
1451
1468
|
f = self._mul_scalar(s, _mul_op_) # handles 0, INF, NAN
|
|
1452
|
-
return self._fset(f) #
|
|
1469
|
+
return self._fset(f) # as_is=False
|
|
1453
1470
|
|
|
1454
1471
|
@property_RO
|
|
1455
1472
|
def imag(self):
|
|
1456
1473
|
'''Get the C{imaginary} part of this instance (C{0.0}, always).
|
|
1457
1474
|
|
|
1458
|
-
@see:
|
|
1475
|
+
@see: Property L{Fsum.real}.
|
|
1459
1476
|
'''
|
|
1460
1477
|
return _0_0
|
|
1461
1478
|
|
|
@@ -1484,11 +1501,12 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1484
1501
|
if R:
|
|
1485
1502
|
t = _stresidual(_non_zero_, r, **R)
|
|
1486
1503
|
raise ResidualError(int_float=s, txt=t)
|
|
1487
|
-
s =
|
|
1504
|
+
s = _Float(s) # redundant
|
|
1488
1505
|
return s
|
|
1489
1506
|
|
|
1490
1507
|
def is_exact(self):
|
|
1491
|
-
'''Is this instance' running C{fsum} considered to be exact?
|
|
1508
|
+
'''Is this instance' running C{fsum} considered to be exact?
|
|
1509
|
+
(C{bool}), C{True} only if the C{residual is }L{INT0}.
|
|
1492
1510
|
'''
|
|
1493
1511
|
return self.residual is INT0
|
|
1494
1512
|
|
|
@@ -1515,13 +1533,15 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1515
1533
|
return 2 if _psum is f else bool(f)
|
|
1516
1534
|
|
|
1517
1535
|
def is_scalar(self, **raiser_RESIDUAL):
|
|
1518
|
-
'''Is this instance' running sum C{scalar}
|
|
1519
|
-
|
|
1520
|
-
threshold? (C{bool}).
|
|
1536
|
+
'''Is this instance' running sum C{scalar} without residual or with
|
|
1537
|
+
a residual I{ratio} not exceeding the RESIDUAL threshold?
|
|
1521
1538
|
|
|
1522
|
-
@kwarg raiser_RESIDUAL: Use C{B{raiser}=False} (C{bool}) to
|
|
1523
|
-
|
|
1524
|
-
|
|
1539
|
+
@kwarg raiser_RESIDUAL: Use C{B{raiser}=False} (C{bool}) to ignore
|
|
1540
|
+
L{ResidualError}s and C{B{RESIDUAL}=scalar} to override
|
|
1541
|
+
the L{RESIDUAL<Fsum.RESIDUAL>} threshold.
|
|
1542
|
+
|
|
1543
|
+
@return: C{True} if this instance' non-zero residual C{ratio} exceeds
|
|
1544
|
+
the L{RESIDUAL<Fsum.RESIDUAL>} threshold (C{bool}).
|
|
1525
1545
|
|
|
1526
1546
|
@raise ResidualError: Non-zero, significant residual or invalid
|
|
1527
1547
|
B{C{RESIDUAL}}.
|
|
@@ -1537,23 +1557,28 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1537
1557
|
'''
|
|
1538
1558
|
# assert _isFsumTuple(other)
|
|
1539
1559
|
if self._ps and other._ps:
|
|
1540
|
-
f = self._ps_mul(op, *other._ps) # NO .as_iscalar
|
|
1560
|
+
f = self._ps_mul(op, *other._ps) # NO .as_iscalar!
|
|
1541
1561
|
else:
|
|
1542
1562
|
f = _0_0
|
|
1543
1563
|
return f
|
|
1544
1564
|
|
|
1545
1565
|
def _mul_scalar(self, factor, op): # in .fmath.Fhorner
|
|
1546
|
-
'''(INTERNAL) Return C{B{self} * scalar B{factor}} as L{Fsum}, C{0} or C{self}.
|
|
1566
|
+
'''(INTERNAL) Return C{B{self} * scalar B{factor}} as L{Fsum}, C{0.0} or C{self}.
|
|
1547
1567
|
'''
|
|
1548
1568
|
# assert isscalar(factor)
|
|
1549
1569
|
if self._ps and self._finite(factor, op):
|
|
1550
|
-
f = self if factor == _1_0
|
|
1570
|
+
f = self if factor == _1_0 else (
|
|
1551
1571
|
self._neg if factor == _N_1_0 else
|
|
1552
1572
|
self._ps_mul(op, factor).as_iscalar)
|
|
1553
1573
|
else:
|
|
1554
1574
|
f = _0_0
|
|
1555
1575
|
return f
|
|
1556
1576
|
|
|
1577
|
+
# @property_RO
|
|
1578
|
+
# def _n_d(self):
|
|
1579
|
+
# n, d = self.as_integer_ratio()
|
|
1580
|
+
# return n / d
|
|
1581
|
+
|
|
1557
1582
|
@property_RO
|
|
1558
1583
|
def _neg(self):
|
|
1559
1584
|
'''(INTERNAL) Return C{Fsum(-self)} or scalar C{NEG0}.
|
|
@@ -1564,7 +1589,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1564
1589
|
def partials(self):
|
|
1565
1590
|
'''Get this instance' current, partial sums (C{tuple} of C{float}s).
|
|
1566
1591
|
'''
|
|
1567
|
-
return
|
|
1592
|
+
return _Tuple(self._ps)
|
|
1568
1593
|
|
|
1569
1594
|
def pow(self, x, *mod, **raiser_RESIDUAL):
|
|
1570
1595
|
'''Return C{B{self}**B{x}} as L{Fsum}.
|
|
@@ -1652,7 +1677,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1652
1677
|
'''
|
|
1653
1678
|
# assert isint(x) and x >= 0
|
|
1654
1679
|
ps = self._ps
|
|
1655
|
-
if
|
|
1680
|
+
if _len(ps) > 1:
|
|
1656
1681
|
_mul_Fsum = Fsum._mul_Fsum
|
|
1657
1682
|
if x > 4:
|
|
1658
1683
|
p = self
|
|
@@ -1663,11 +1688,11 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1663
1688
|
if (m & 1):
|
|
1664
1689
|
f = _mul_Fsum(f, p, op) # f *= p
|
|
1665
1690
|
m >>= 1 # //= 2
|
|
1666
|
-
elif x > 1: # self**2, 3 or 4
|
|
1691
|
+
elif x > 1: # self**2, 3, or 4
|
|
1667
1692
|
f = _mul_Fsum(self, self, op)
|
|
1668
1693
|
if x > 2: # self**3 or 4
|
|
1669
1694
|
p = self if x < 4 else f
|
|
1670
|
-
f = _mul_Fsum(f, p, op)
|
|
1695
|
+
f = _mul_Fsum(f, p, op)
|
|
1671
1696
|
else: # self**1 or self**0 == 1 or _1_0
|
|
1672
1697
|
f = self._pow_0_1(x, other)
|
|
1673
1698
|
elif ps: # self._ps[0]**x
|
|
@@ -1684,8 +1709,8 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1684
1709
|
if r:
|
|
1685
1710
|
# assert s != 0
|
|
1686
1711
|
if isint(x, both=True): # self**int
|
|
1687
|
-
x =
|
|
1688
|
-
y =
|
|
1712
|
+
x = int(x)
|
|
1713
|
+
y = _abs(x)
|
|
1689
1714
|
if y > 1:
|
|
1690
1715
|
f = self._pow_int(y, other, op, **raiser_RESIDUAL)
|
|
1691
1716
|
if x > 0: # i.e. > 1
|
|
@@ -1709,18 +1734,18 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1709
1734
|
if R:
|
|
1710
1735
|
raise self._ResidualError(op, other, r, **R)
|
|
1711
1736
|
n, d = self.as_integer_ratio()
|
|
1712
|
-
if
|
|
1737
|
+
if _abs(n) > _abs(d):
|
|
1713
1738
|
n, d, x = d, n, (-x)
|
|
1714
1739
|
s = n / d
|
|
1715
1740
|
# assert isscalar(s) and isscalar(x)
|
|
1716
1741
|
return self._pow_2_3(s, x, other, op, **raiser_RESIDUAL)
|
|
1717
1742
|
|
|
1718
1743
|
def _ps_acc(self, ps, xs, up=True, **unused):
|
|
1719
|
-
'''(INTERNAL) Accumulate
|
|
1744
|
+
'''(INTERNAL) Accumulate C{xs} scalars into list C{ps}.
|
|
1720
1745
|
'''
|
|
1721
1746
|
n = 0
|
|
1722
1747
|
_2s = _2sum
|
|
1723
|
-
for x in (
|
|
1748
|
+
for x in (_Tuple(xs) if xs is ps else xs):
|
|
1724
1749
|
# assert isscalar(x) and _isfinite(x)
|
|
1725
1750
|
if x:
|
|
1726
1751
|
i = 0
|
|
@@ -1733,17 +1758,17 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1733
1758
|
n += 1
|
|
1734
1759
|
if n:
|
|
1735
1760
|
self._n += n
|
|
1736
|
-
# Fsum._ps_max = max(Fsum._ps_max,
|
|
1761
|
+
# Fsum._ps_max = max(Fsum._ps_max, _len(ps))
|
|
1737
1762
|
if up:
|
|
1738
1763
|
self._update()
|
|
1739
1764
|
return ps
|
|
1740
1765
|
|
|
1741
1766
|
def _ps_mul(self, op, *factors):
|
|
1742
|
-
'''(INTERNAL) Multiply this instance' C{partials} with
|
|
1743
|
-
|
|
1767
|
+
'''(INTERNAL) Multiply this instance' C{partials} with
|
|
1768
|
+
each scalar C{factor} and accumulate into an C{Fsum}.
|
|
1744
1769
|
'''
|
|
1745
1770
|
def _pfs(ps, fs):
|
|
1746
|
-
if
|
|
1771
|
+
if _len(ps) < _len(fs):
|
|
1747
1772
|
ps, fs = fs, ps
|
|
1748
1773
|
_fin = _isfinite
|
|
1749
1774
|
for f in fs:
|
|
@@ -1751,7 +1776,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1751
1776
|
p *= f
|
|
1752
1777
|
yield p if _fin(p) else self._finite(p, op)
|
|
1753
1778
|
|
|
1754
|
-
return
|
|
1779
|
+
return Fsum()._facc_scalar(_pfs(self._ps, factors), up=False)
|
|
1755
1780
|
|
|
1756
1781
|
@property_RO
|
|
1757
1782
|
def _ps_neg(self):
|
|
@@ -1760,15 +1785,18 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1760
1785
|
for p in self._ps:
|
|
1761
1786
|
yield -p
|
|
1762
1787
|
|
|
1763
|
-
def
|
|
1764
|
-
'''(INTERNAL)
|
|
1788
|
+
def _ps_1sum(self, *less):
|
|
1789
|
+
'''(INTERNAL) Return the partials sum, 1-primed C{less} some scalars.
|
|
1765
1790
|
'''
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1791
|
+
def _1pls(ps, ls):
|
|
1792
|
+
yield _1_0
|
|
1793
|
+
for p in ps:
|
|
1794
|
+
yield p
|
|
1795
|
+
for p in ls:
|
|
1796
|
+
yield -p
|
|
1797
|
+
yield _N_1_0
|
|
1798
|
+
|
|
1799
|
+
return _fsum(_1pls(self._ps, less))
|
|
1772
1800
|
|
|
1773
1801
|
def _raiser(self, r, s, raiser=True, **RESIDUAL):
|
|
1774
1802
|
'''(INTERNAL) Does ratio C{r / s} exceed the RESIDUAL threshold
|
|
@@ -1785,6 +1813,8 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1785
1813
|
return dict(ratio=q, R=t)
|
|
1786
1814
|
return {}
|
|
1787
1815
|
|
|
1816
|
+
rdiv = __rtruediv__
|
|
1817
|
+
|
|
1788
1818
|
@property_RO
|
|
1789
1819
|
def real(self):
|
|
1790
1820
|
'''Get the C{real} part of this instance (C{float}).
|
|
@@ -1793,7 +1823,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1793
1823
|
and properties L{Fsum.ceil}, L{Fsum.floor},
|
|
1794
1824
|
L{Fsum.imag} and L{Fsum.residual}.
|
|
1795
1825
|
'''
|
|
1796
|
-
return
|
|
1826
|
+
return _Float(self._fprs)
|
|
1797
1827
|
|
|
1798
1828
|
@property_RO
|
|
1799
1829
|
def residual(self):
|
|
@@ -1871,7 +1901,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1871
1901
|
'''
|
|
1872
1902
|
if isscalar(other):
|
|
1873
1903
|
return other
|
|
1874
|
-
raise self.
|
|
1904
|
+
raise self._Error(op, other, _TypeError, **txt) # _invalid_
|
|
1875
1905
|
|
|
1876
1906
|
def signOf(self, res=True):
|
|
1877
1907
|
'''Determine the sign of this instance.
|
|
@@ -1885,45 +1915,38 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1885
1915
|
r = (-r) if res else 0
|
|
1886
1916
|
return _signOf(s, r)
|
|
1887
1917
|
|
|
1888
|
-
def toRepr(self, **
|
|
1918
|
+
def toRepr(self, **lenc_prec_sep_fmt): # PYCHOK signature
|
|
1889
1919
|
'''Return this C{Fsum} instance as representation.
|
|
1890
1920
|
|
|
1891
|
-
@kwarg
|
|
1892
|
-
method L{
|
|
1893
|
-
(C{bool}) to in-/exclude the current C{[len]}
|
|
1894
|
-
of this L{Fsum} enclosed in I{[brackets]}.
|
|
1921
|
+
@kwarg lenc_prec_sep_fmt: Optional keyword arguments
|
|
1922
|
+
for method L{Fsum.toStr}.
|
|
1895
1923
|
|
|
1896
1924
|
@return: This instance (C{repr}).
|
|
1897
1925
|
'''
|
|
1898
|
-
return
|
|
1926
|
+
return Fmt.repr_at(self, self.toStr(**lenc_prec_sep_fmt))
|
|
1899
1927
|
|
|
1900
|
-
def toStr(self, **
|
|
1928
|
+
def toStr(self, lenc=True, **prec_sep_fmt): # PYCHOK signature
|
|
1901
1929
|
'''Return this C{Fsum} instance as string.
|
|
1902
1930
|
|
|
1903
|
-
@kwarg
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1931
|
+
@kwarg lenc: If C{True} include the current C{[len]} of this
|
|
1932
|
+
L{Fsum} enclosed in I{[brackets]} (C{bool}).
|
|
1933
|
+
@kwarg prec_sep_fmt: Optional keyword arguments for method
|
|
1934
|
+
L{Fsum2Tuple.toStr}.
|
|
1907
1935
|
|
|
1908
1936
|
@return: This instance (C{str}).
|
|
1909
1937
|
'''
|
|
1910
|
-
return self._toT(self._fprs2.toStr, **prec_sep_fmt_lenc)
|
|
1911
|
-
|
|
1912
|
-
def _toT(self, toT, fmt=Fmt.g, lenc=True, **kwds):
|
|
1913
|
-
'''(INTERNAL) Helper for C{toRepr} and C{toStr}.
|
|
1914
|
-
'''
|
|
1915
1938
|
p = self.classname
|
|
1916
1939
|
if lenc:
|
|
1917
|
-
p = Fmt.SQUARE(p,
|
|
1918
|
-
n = self.name
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
return NN(p, _SPACE_, n, toT(fmt=fmt, **kwds))
|
|
1940
|
+
p = Fmt.SQUARE(p, _len(self))
|
|
1941
|
+
n = _enquote(self.name, white=_UNDER_)
|
|
1942
|
+
t = self._fprs2.toStr(**prec_sep_fmt)
|
|
1943
|
+
return NN(p, _SPACE_, n, t)
|
|
1922
1944
|
|
|
1923
|
-
def
|
|
1924
|
-
'''(INTERNAL) Return
|
|
1945
|
+
def _truediv(self, other, op, **raiser_RESIDUAL):
|
|
1946
|
+
'''(INTERNAL) Return C{B{self} / B{other}} as an L{Fsum}.
|
|
1925
1947
|
'''
|
|
1926
|
-
|
|
1948
|
+
f = self._copy_2(self.__truediv__)
|
|
1949
|
+
return f._ftruediv(other, op, **raiser_RESIDUAL)
|
|
1927
1950
|
|
|
1928
1951
|
def _update(self, updated=True): # see ._fset
|
|
1929
1952
|
'''(INTERNAL) Zap all cached C{Property_RO} values.
|
|
@@ -1937,16 +1960,6 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1937
1960
|
# Fsum._fprs2._update(self)
|
|
1938
1961
|
return self # for .fset_
|
|
1939
1962
|
|
|
1940
|
-
def _ValueError(self, op, other, **txt): # PYCHOK no cover
|
|
1941
|
-
'''(INTERNAL) Return a C{ValueError}.
|
|
1942
|
-
'''
|
|
1943
|
-
return self._Error(op, other, _ValueError, **txt)
|
|
1944
|
-
|
|
1945
|
-
def _ZeroDivisionError(self, op, other, **txt): # PYCHOK no cover
|
|
1946
|
-
'''(INTERNAL) Return a C{ZeroDivisionError}.
|
|
1947
|
-
'''
|
|
1948
|
-
return self._Error(op, other, _ZeroDivisionError, **txt)
|
|
1949
|
-
|
|
1950
1963
|
_ROs = _allPropertiesOf_n(3, Fsum, Property_RO) # PYCHOK see Fsum._update
|
|
1951
1964
|
|
|
1952
1965
|
|
|
@@ -1968,7 +1981,7 @@ class DivMod2Tuple(_NamedTuple):
|
|
|
1968
1981
|
_Units_ = (_Float_Int, Fsum)
|
|
1969
1982
|
|
|
1970
1983
|
|
|
1971
|
-
class Fsum2Tuple(_NamedTuple):
|
|
1984
|
+
class Fsum2Tuple(_NamedTuple): # in .fstats
|
|
1972
1985
|
'''2-Tuple C{(fsum, residual)} with the precision running C{fsum}
|
|
1973
1986
|
and the C{residual}, the sum of the remaining partials. Each
|
|
1974
1987
|
item is C{float} or C{int}.
|
|
@@ -1979,6 +1992,44 @@ class Fsum2Tuple(_NamedTuple):
|
|
|
1979
1992
|
_Names_ = ( Fsum.fsum.__name__, Fsum.residual.name)
|
|
1980
1993
|
_Units_ = (_Float_Int, _Float_Int)
|
|
1981
1994
|
|
|
1995
|
+
def __abs__(self): # in .fmath
|
|
1996
|
+
return self._Fsum.__abs__()
|
|
1997
|
+
|
|
1998
|
+
def __bool__(self): # PYCHOK Python 3+
|
|
1999
|
+
return bool(self._Fsum)
|
|
2000
|
+
|
|
2001
|
+
def __eq__(self, other):
|
|
2002
|
+
return self._other_op(other, self.__eq__)
|
|
2003
|
+
|
|
2004
|
+
def __float__(self):
|
|
2005
|
+
return self._Fsum.__float__()
|
|
2006
|
+
|
|
2007
|
+
def __ge__(self, other):
|
|
2008
|
+
return self._other_op(other, self.__ge__)
|
|
2009
|
+
|
|
2010
|
+
def __gt__(self, other):
|
|
2011
|
+
return self._other_op(other, self.__gt__)
|
|
2012
|
+
|
|
2013
|
+
def __le__(self, other):
|
|
2014
|
+
return self._other_op(other, self.__le__)
|
|
2015
|
+
|
|
2016
|
+
def __lt__(self, other):
|
|
2017
|
+
return self._other_op(other, self.__lt__)
|
|
2018
|
+
|
|
2019
|
+
def __int__(self):
|
|
2020
|
+
return self._Fsum.__int__()
|
|
2021
|
+
|
|
2022
|
+
def __ne__(self, other):
|
|
2023
|
+
return self._other_op(other, self.__ne__)
|
|
2024
|
+
|
|
2025
|
+
def __neg__(self):
|
|
2026
|
+
return self._Fsum.__neg__()
|
|
2027
|
+
|
|
2028
|
+
__nonzero__ = __bool__ # Python 2-
|
|
2029
|
+
|
|
2030
|
+
def __pos__(self):
|
|
2031
|
+
return self._Fsum.__pos__()
|
|
2032
|
+
|
|
1982
2033
|
def as_integer_ratio(self):
|
|
1983
2034
|
'''Return this instance as the ratio of 2 integers.
|
|
1984
2035
|
|
|
@@ -1988,32 +2039,45 @@ class Fsum2Tuple(_NamedTuple):
|
|
|
1988
2039
|
|
|
1989
2040
|
@property_RO
|
|
1990
2041
|
def _fint2(self):
|
|
1991
|
-
return self._Fsum.
|
|
2042
|
+
return self._Fsum._fint2
|
|
1992
2043
|
|
|
1993
2044
|
@property_RO
|
|
1994
2045
|
def _fprs2(self):
|
|
1995
2046
|
return self._Fsum._fprs2
|
|
1996
2047
|
|
|
1997
2048
|
@Property_RO
|
|
1998
|
-
def _Fsum(self):
|
|
1999
|
-
|
|
2049
|
+
def _Fsum(self): # this C{Fsum2Tuple} as L{Fsum}, in .fstats
|
|
2050
|
+
s, r = _s_r(*self)
|
|
2051
|
+
ps = (r, s) if r else (s,)
|
|
2052
|
+
return _Psum(ps, name=self.name)
|
|
2053
|
+
|
|
2054
|
+
def Fsum_(self, *xs, **name_RESIDUAL):
|
|
2055
|
+
'''Return this C{Fsum2Tuple} as an L{Fsum} plus some C{xs}.
|
|
2056
|
+
'''
|
|
2057
|
+
f = _Psum(self._Fsum._ps, **name_RESIDUAL)
|
|
2058
|
+
return f._facc_1(xs, up=False) if xs else f
|
|
2000
2059
|
|
|
2001
2060
|
def is_exact(self):
|
|
2002
2061
|
'''Is this L{Fsum2Tuple} considered to be exact? (C{bool}).
|
|
2003
2062
|
'''
|
|
2004
|
-
|
|
2005
|
-
return False if r else True
|
|
2063
|
+
return self._Fsum.is_exact()
|
|
2006
2064
|
|
|
2007
2065
|
def is_integer(self):
|
|
2008
2066
|
'''Is this L{Fsum2Tuple} C{integer}? (C{bool}).
|
|
2009
2067
|
'''
|
|
2010
|
-
|
|
2011
|
-
|
|
2068
|
+
return self._Fsum.is_integer()
|
|
2069
|
+
|
|
2070
|
+
def _mul_scalar(self, other, op): # for Fsum._fmul
|
|
2071
|
+
return self._Fsum._mul_scalar(other, op)
|
|
2012
2072
|
|
|
2013
2073
|
@property_RO
|
|
2014
2074
|
def _n(self):
|
|
2015
2075
|
return self._Fsum._n
|
|
2016
2076
|
|
|
2077
|
+
def _other_op(self, other, which):
|
|
2078
|
+
C, s = (_Tuple, self) if _isAn(other, _Tuple) else (Fsum, self._Fsum)
|
|
2079
|
+
return getattr(C, which.__name__)(s, other)
|
|
2080
|
+
|
|
2017
2081
|
@property_RO
|
|
2018
2082
|
def _ps(self):
|
|
2019
2083
|
return self._Fsum._ps
|
|
@@ -2023,11 +2087,20 @@ class Fsum2Tuple(_NamedTuple):
|
|
|
2023
2087
|
return self._Fsum._ps_neg
|
|
2024
2088
|
|
|
2025
2089
|
def signOf(self, **res):
|
|
2026
|
-
'''Like L{Fsum.signOf}.
|
|
2090
|
+
'''Like method L{Fsum.signOf}.
|
|
2027
2091
|
'''
|
|
2028
2092
|
return self._Fsum.signOf(**res)
|
|
2029
2093
|
|
|
2030
|
-
|
|
2094
|
+
def toStr(self, fmt=Fmt.g, **prec_sep): # PYCHOK signature
|
|
2095
|
+
'''Return this L{Fsum2Tuple} as string (C{str}).
|
|
2096
|
+
|
|
2097
|
+
@kwarg fmt: Optional C{float} format (C{letter}).
|
|
2098
|
+
@kwarg prec_sep: Optional keyword arguments for function
|
|
2099
|
+
L{fstr<streprs.fstr>}.
|
|
2100
|
+
'''
|
|
2101
|
+
return Fmt.PAREN(fstr(self, fmt=fmt, strepr=str, force=False, **prec_sep))
|
|
2102
|
+
|
|
2103
|
+
_Fsum_Fsum2Tuple_types = Fsum, Fsum2Tuple # PYCHOK lines
|
|
2031
2104
|
|
|
2032
2105
|
|
|
2033
2106
|
class ResidualError(_ValueError):
|
|
@@ -2064,10 +2137,10 @@ except ImportError:
|
|
|
2064
2137
|
def fsum(xs, floats=False):
|
|
2065
2138
|
'''Precision floating point summation based on/like Python's C{math.fsum}.
|
|
2066
2139
|
|
|
2067
|
-
@arg xs: Iterable of items to add (each C{scalar} or an L{Fsum} or
|
|
2068
|
-
|
|
2069
|
-
@kwarg floats: Use C{B{floats}=True} iff I{all} B{C{xs}} items are
|
|
2070
|
-
|
|
2140
|
+
@arg xs: Iterable of items to add (each C{scalar} or an L{Fsum} or L{Fsum2Tuple}
|
|
2141
|
+
instance).
|
|
2142
|
+
@kwarg floats: Use C{B{floats}=True} iff I{all} B{C{xs}} items are I{known to
|
|
2143
|
+
be scalar} (C{bool}).
|
|
2071
2144
|
|
|
2072
2145
|
@return: Precision C{fsum} (C{float}).
|
|
2073
2146
|
|
|
@@ -2086,12 +2159,12 @@ def fsum(xs, floats=False):
|
|
|
2086
2159
|
|
|
2087
2160
|
|
|
2088
2161
|
def fsum_(*xs, **floats):
|
|
2089
|
-
'''Precision floating point summation of all positional
|
|
2162
|
+
'''Precision floating point summation of all positional items.
|
|
2090
2163
|
|
|
2091
|
-
@arg xs: Items to add (each C{scalar} or an L{Fsum} or L{Fsum2Tuple}
|
|
2092
|
-
|
|
2093
|
-
@kwarg floats: Use C{B{floats}=True} iff I{all} B{C{xs}} items are
|
|
2094
|
-
|
|
2164
|
+
@arg xs: Items to add (each C{scalar} or an L{Fsum} or L{Fsum2Tuple} instance),
|
|
2165
|
+
all positional.
|
|
2166
|
+
@kwarg floats: Use C{B{floats}=True} iff I{all} B{C{xs}} items are I{known to
|
|
2167
|
+
be scalar} (C{bool}).
|
|
2095
2168
|
|
|
2096
2169
|
@see: Function L{fsum<fsums.fsum>} for further details.
|
|
2097
2170
|
'''
|
|
@@ -2110,10 +2183,10 @@ def fsumf_(*xs):
|
|
|
2110
2183
|
def fsum1(xs, floats=False):
|
|
2111
2184
|
'''Precision floating point summation, 1-primed.
|
|
2112
2185
|
|
|
2113
|
-
@arg xs: Iterable of items to add (each C{scalar} or an L{Fsum} or
|
|
2114
|
-
|
|
2115
|
-
@kwarg floats: Use C{B{floats}=True} iff I{all} B{C{xs}} items are
|
|
2116
|
-
|
|
2186
|
+
@arg xs: Iterable of items to add (each C{scalar} or an L{Fsum} or L{Fsum2Tuple}
|
|
2187
|
+
instance).
|
|
2188
|
+
@kwarg floats: Use C{B{floats}=True} iff I{all} B{C{xs}} items are I{known to
|
|
2189
|
+
be scalar} (C{bool}).
|
|
2117
2190
|
|
|
2118
2191
|
@see: Function L{fsum<fsums.fsum>} for further details.
|
|
2119
2192
|
'''
|
|
@@ -2121,12 +2194,12 @@ def fsum1(xs, floats=False):
|
|
|
2121
2194
|
|
|
2122
2195
|
|
|
2123
2196
|
def fsum1_(*xs, **floats):
|
|
2124
|
-
'''Precision floating point summation, 1-primed of all positional
|
|
2197
|
+
'''Precision floating point summation, 1-primed of all positional items.
|
|
2125
2198
|
|
|
2126
|
-
@arg xs: Items to add (each C{scalar} or an L{Fsum} or L{Fsum2Tuple}
|
|
2127
|
-
|
|
2128
|
-
@kwarg floats: Use C{B{floats}=True} iff I{all} B{C{xs}} items are
|
|
2129
|
-
|
|
2199
|
+
@arg xs: Items to add (each C{scalar} or an L{Fsum} or L{Fsum2Tuple} instance),
|
|
2200
|
+
all positional.
|
|
2201
|
+
@kwarg floats: Use C{B{floats}=True} iff I{all} B{C{xs}} items are I{known to
|
|
2202
|
+
be scalar} (C{bool}).
|
|
2130
2203
|
|
|
2131
2204
|
@see: Function L{fsum_<fsums.fsum_>} for further details.
|
|
2132
2205
|
'''
|
|
@@ -2135,7 +2208,7 @@ def fsum1_(*xs, **floats):
|
|
|
2135
2208
|
|
|
2136
2209
|
|
|
2137
2210
|
def fsum1f_(*xs):
|
|
2138
|
-
'''Precision floating point summation iff I{all} C{B{xs}} are I{known to be scalar}.
|
|
2211
|
+
'''Precision floating point summation iff I{all} C{B{xs}} items are I{known to be scalar}.
|
|
2139
2212
|
|
|
2140
2213
|
@see: Function L{fsum_<fsums.fsum_>} for further details.
|
|
2141
2214
|
'''
|
|
@@ -2159,7 +2232,7 @@ if __name__ == '__main__':
|
|
|
2159
2232
|
F = Fsum()
|
|
2160
2233
|
if F.is_math_fsum():
|
|
2161
2234
|
for t in frandoms(n, seeded=True):
|
|
2162
|
-
assert
|
|
2235
|
+
assert _Float(F.fset_(*t)) == _fsum(t)
|
|
2163
2236
|
printf(_DOT_, end=NN)
|
|
2164
2237
|
printf(NN)
|
|
2165
2238
|
|