pygeodesy 24.4.12__py2.py3-none-any.whl → 24.4.24__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.4.12.dist-info → PyGeodesy-24.4.24.dist-info}/METADATA +2 -2
- {PyGeodesy-24.4.12.dist-info → PyGeodesy-24.4.24.dist-info}/RECORD +21 -21
- pygeodesy/__init__.py +1 -1
- pygeodesy/albers.py +12 -19
- pygeodesy/auxilats/auxLat.py +3 -3
- pygeodesy/constants.py +1 -2
- pygeodesy/deprecated/__init__.py +1 -1
- pygeodesy/deprecated/classes.py +14 -1
- pygeodesy/ellipsoids.py +3 -3
- pygeodesy/elliptic.py +10 -11
- pygeodesy/errors.py +27 -28
- pygeodesy/fmath.py +201 -156
- pygeodesy/fsums.py +354 -262
- pygeodesy/lazily.py +4 -4
- pygeodesy/ltp.py +11 -11
- pygeodesy/osgr.py +24 -24
- pygeodesy/resections.py +16 -24
- pygeodesy/triaxials.py +4 -4
- pygeodesy/vector2d.py +9 -8
- {PyGeodesy-24.4.12.dist-info → PyGeodesy-24.4.24.dist-info}/WHEEL +0 -0
- {PyGeodesy-24.4.12.dist-info → PyGeodesy-24.4.24.dist-info}/top_level.txt +0 -0
pygeodesy/fsums.py
CHANGED
|
@@ -27,14 +27,15 @@ from __future__ import division as _; del _ # PYCHOK semicolon
|
|
|
27
27
|
|
|
28
28
|
from pygeodesy.basics import iscomplex, isint, isscalar, itemsorted, \
|
|
29
29
|
signOf, _signOf
|
|
30
|
-
from pygeodesy.constants import INT0, _isfinite,
|
|
30
|
+
from pygeodesy.constants import INT0, _isfinite, NEG0, _pos_self, \
|
|
31
31
|
_0_0, _1_0, _N_1_0, Float, Int
|
|
32
|
-
from pygeodesy.errors import _OverflowError, _TypeError,
|
|
33
|
-
_xError2, _xkwds_get,
|
|
32
|
+
from pygeodesy.errors import _AssertionError, _OverflowError, _TypeError, \
|
|
33
|
+
_ValueError, _xError, _xError2, _xkwds_get, \
|
|
34
|
+
_ZeroDivisionError
|
|
34
35
|
from pygeodesy.interns import NN, _arg_, _COMMASPACE_, _DASH_, _DOT_, _EQUAL_, \
|
|
35
36
|
_exceeds_, _from_, _iadd_op_, _LANGLE_, _negative_, \
|
|
36
|
-
_NOTEQUAL_, _not_finite_,
|
|
37
|
-
|
|
37
|
+
_NOTEQUAL_, _not_finite_, _PERCENT_, _PLUS_, _R_, \
|
|
38
|
+
_RANGLE_, _SLASH_, _SPACE_, _STAR_, _UNDER_
|
|
38
39
|
from pygeodesy.lazily import _ALL_LAZY, _getenv, _sys_version_info2
|
|
39
40
|
from pygeodesy.named import _Named, _NamedTuple, _NotImplemented, Fmt, unstr
|
|
40
41
|
from pygeodesy.props import _allPropertiesOf_n, deprecated_property_RO, \
|
|
@@ -45,7 +46,7 @@ from pygeodesy.props import _allPropertiesOf_n, deprecated_property_RO, \
|
|
|
45
46
|
from math import ceil as _ceil, fabs, floor as _floor # PYCHOK used! .ltp
|
|
46
47
|
|
|
47
48
|
__all__ = _ALL_LAZY.fsums
|
|
48
|
-
__version__ = '24.04.
|
|
49
|
+
__version__ = '24.04.24'
|
|
49
50
|
|
|
50
51
|
_add_op_ = _PLUS_ # in .auxilats.auxAngle
|
|
51
52
|
_eq_op_ = _EQUAL_ * 2 # _DEQUAL_
|
|
@@ -72,7 +73,7 @@ _isub_op_ = _sub_op_ + _fset_op_ # in .auxilats.auxAngle, .fsums
|
|
|
72
73
|
|
|
73
74
|
|
|
74
75
|
def _2delta(*ab):
|
|
75
|
-
'''(INTERNAL) Helper for C{Fsum.
|
|
76
|
+
'''(INTERNAL) Helper for C{Fsum._fsum2}.
|
|
76
77
|
'''
|
|
77
78
|
try:
|
|
78
79
|
a, b = _2sum(*ab)
|
|
@@ -121,6 +122,18 @@ def _2floats(xs, origin=0, _X=_X_ps, _x=float):
|
|
|
121
122
|
raise _xError(X, Fmt.INDEX(xs=i), x)
|
|
122
123
|
|
|
123
124
|
|
|
125
|
+
def _Fsumf_(*xs): # floats=True, in .auxLat, ...
|
|
126
|
+
'''(INTERNAL) An C{Fsum} of I{known scalars}.
|
|
127
|
+
'''
|
|
128
|
+
return Fsum()._facc_scalar(xs, up=False)
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
def _Fsum1f_(*xs): # floats=True, in .albers, ...
|
|
132
|
+
'''(INTERNAL) An C{Fsum} of I{known scalars}, 1-primed.
|
|
133
|
+
'''
|
|
134
|
+
return Fsum()._facc_scalar(_1primed(xs), up=False)
|
|
135
|
+
|
|
136
|
+
|
|
124
137
|
def _2halfeven(s, r, p):
|
|
125
138
|
'''(INTERNAL) Round half-even.
|
|
126
139
|
'''
|
|
@@ -133,6 +146,12 @@ def _2halfeven(s, r, p):
|
|
|
133
146
|
return s
|
|
134
147
|
|
|
135
148
|
|
|
149
|
+
def _1_over(x, op=_truediv_op_, **raiser):
|
|
150
|
+
'''(INTERNAL) Return C{Fsum(1) /= B{x}}.
|
|
151
|
+
'''
|
|
152
|
+
return _Psum_(_1_0)._ftruediv(x, op, **raiser)
|
|
153
|
+
|
|
154
|
+
|
|
136
155
|
def _1primed(xs): # in .fmath
|
|
137
156
|
'''(INTERNAL) 1-Primed summation of iterable C{xs}
|
|
138
157
|
items, all I{known} to be C{finite float}.
|
|
@@ -144,9 +163,11 @@ def _1primed(xs): # in .fmath
|
|
|
144
163
|
|
|
145
164
|
|
|
146
165
|
def _2ps(s, r):
|
|
147
|
-
'''(INTERNAL) Return
|
|
166
|
+
'''(INTERNAL) Return an C{s} and C{r} pair, I{ps-ordered}.
|
|
148
167
|
'''
|
|
149
|
-
|
|
168
|
+
if fabs(s) < fabs(r):
|
|
169
|
+
s, r = r, s
|
|
170
|
+
return (r, s) if r else (s,) # PYCHOK types
|
|
150
171
|
|
|
151
172
|
|
|
152
173
|
def _psum(ps): # PYCHOK used!
|
|
@@ -173,20 +194,17 @@ def _psum(ps): # PYCHOK used!
|
|
|
173
194
|
def _Psum(ps, **name):
|
|
174
195
|
'''(INTERNAL) Return an C{Fsum} from I{ordered} partials C{ps}.
|
|
175
196
|
'''
|
|
176
|
-
|
|
197
|
+
F = Fsum(**name) if name else Fsum()
|
|
177
198
|
if ps:
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
return
|
|
199
|
+
F._ps[:] = ps
|
|
200
|
+
F._n = len(F._ps)
|
|
201
|
+
return F
|
|
181
202
|
|
|
182
203
|
|
|
183
|
-
def
|
|
184
|
-
'''(INTERNAL) Return an C{Fsum} from
|
|
204
|
+
def _Psum_(*ps, **name):
|
|
205
|
+
'''(INTERNAL) Return an C{Fsum} from 1 or 2 known scalar(s) C{ps}.
|
|
185
206
|
'''
|
|
186
|
-
|
|
187
|
-
f._ps[:] = p,
|
|
188
|
-
f._n = 1 # len(f._ps)
|
|
189
|
-
return f
|
|
207
|
+
return _Psum(ps, **name)
|
|
190
208
|
|
|
191
209
|
|
|
192
210
|
def _2scalar(other, _raiser=None, **mod):
|
|
@@ -233,13 +251,13 @@ def _2sum(a, b): # by .testFmath
|
|
|
233
251
|
'''(INTERNAL) Return C{a + b} as 2-tuple (sum, residual).
|
|
234
252
|
'''
|
|
235
253
|
s = a + b
|
|
236
|
-
if
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
254
|
+
if _isfinite(s):
|
|
255
|
+
if fabs(a) < fabs(b):
|
|
256
|
+
b, a = a, b
|
|
257
|
+
return s, (b - (s - a))
|
|
258
|
+
u = unstr(_2sum, a, b)
|
|
259
|
+
t = Fmt.PARENSPACED(_not_finite_, s)
|
|
260
|
+
raise _OverflowError(u, txt=t)
|
|
243
261
|
|
|
244
262
|
|
|
245
263
|
class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
@@ -255,9 +273,9 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
255
273
|
@note: Handling of exceptions and C{inf}, C{INF}, C{nan} and C{NAN} differs from
|
|
256
274
|
Python's C{math.fsum}.
|
|
257
275
|
|
|
258
|
-
@see: U{Hettinger<https://GitHub.com/ActiveState/code/
|
|
259
|
-
393090_Binary_floating_point_summatiaccurate_full/recipe-393090.py>},
|
|
260
|
-
<https://WikiPedia.org/wiki/Kahan_summation_algorithm>}, U{Klein
|
|
276
|
+
@see: U{Hettinger<https://GitHub.com/ActiveState/code/tree/master/recipes/Python/
|
|
277
|
+
393090_Binary_floating_point_summatiaccurate_full/recipe-393090.py>},
|
|
278
|
+
U{Kahan<https://WikiPedia.org/wiki/Kahan_summation_algorithm>}, U{Klein
|
|
261
279
|
<https://Link.Springer.com/article/10.1007/s00607-005-0139-x>}, Python 2.6+
|
|
262
280
|
file I{Modules/mathmodule.c} and the issue log U{Full precision summation
|
|
263
281
|
<https://Bugs.Python.org/issue2819>}.
|
|
@@ -266,7 +284,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
266
284
|
_n = 0
|
|
267
285
|
# _ps = [] # partial sums
|
|
268
286
|
# _ps_max = 0 # max(Fsum._ps_max, len(Fsum._ps))
|
|
269
|
-
_ratio = None
|
|
287
|
+
_ratio = None # see method _raiser
|
|
270
288
|
_recursive = bool(_getenv('PYGEODESY_FSUM_RECURSIVE', NN))
|
|
271
289
|
_RESIDUAL = max(float(_getenv('PYGEODESY_FSUM_RESIDUAL', _0_0)), _0_0)
|
|
272
290
|
|
|
@@ -289,12 +307,12 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
289
307
|
self.RESIDUAL(r) # ... ResidualError
|
|
290
308
|
self._ps = [] # [_0_0], see L{Fsum._fprs}
|
|
291
309
|
if xs:
|
|
292
|
-
self.
|
|
310
|
+
self._facc(xs, origin=1, up=False)
|
|
293
311
|
|
|
294
312
|
def __abs__(self):
|
|
295
313
|
'''Return this instance' absolute value as an L{Fsum}.
|
|
296
314
|
'''
|
|
297
|
-
s = _fsum(self.
|
|
315
|
+
s = _fsum(self._ps_1primed()) # == self._cmp_0(0, ...)
|
|
298
316
|
return (-self) if s < 0 else self._copy_2(self.__abs__)
|
|
299
317
|
|
|
300
318
|
def __add__(self, other):
|
|
@@ -324,8 +342,8 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
324
342
|
'''
|
|
325
343
|
return self.ceil
|
|
326
344
|
|
|
327
|
-
def __cmp__(self, other): #
|
|
328
|
-
'''Compare this with an other instance or C{scalar}
|
|
345
|
+
def __cmp__(self, other): # PYCHOK no cover
|
|
346
|
+
'''Compare this with an other instance or C{scalar}, Python 2-.
|
|
329
347
|
|
|
330
348
|
@return: -1, 0 or +1 (C{int}).
|
|
331
349
|
|
|
@@ -478,13 +496,15 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
478
496
|
# Luciano Ramalho, "Fluent Python", O'Reilly, 2nd Ed, 2022 p. 567
|
|
479
497
|
return _NotImplemented(self)
|
|
480
498
|
|
|
481
|
-
def __ipow__(self, other, *mod): # PYCHOK 2 vs 3 args
|
|
499
|
+
def __ipow__(self, other, *mod, **raiser): # PYCHOK 2 vs 3 args
|
|
482
500
|
'''Apply C{B{self} **= B{other}} to this instance.
|
|
483
501
|
|
|
484
502
|
@arg other: The exponent (L{Fsum} or C{scalar}).
|
|
485
503
|
@arg mod: Optional modulus (C{int} or C{None}) for the
|
|
486
504
|
3-argument C{pow(B{self}, B{other}, B{mod})}
|
|
487
505
|
version.
|
|
506
|
+
@kwarg raiser: Use C{B{raiser}=False} to ignore L{ResidualError}s
|
|
507
|
+
(C{bool}), see also method L{RESIDUAL}.
|
|
488
508
|
|
|
489
509
|
@return: This instance, updated (L{Fsum}).
|
|
490
510
|
|
|
@@ -513,7 +533,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
513
533
|
@see: CPython function U{float_pow<https://GitHub.com/
|
|
514
534
|
python/cpython/blob/main/Objects/floatobject.c>}.
|
|
515
535
|
'''
|
|
516
|
-
return self._fpow(other, _pow_op_ + _fset_op_, *mod)
|
|
536
|
+
return self._fpow(other, _pow_op_ + _fset_op_, *mod, **raiser)
|
|
517
537
|
|
|
518
538
|
def __isub__(self, other):
|
|
519
539
|
'''Apply C{B{self} -= B{other}} to this instance.
|
|
@@ -533,10 +553,12 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
533
553
|
'''
|
|
534
554
|
return iter(self.partials)
|
|
535
555
|
|
|
536
|
-
def __itruediv__(self, other):
|
|
556
|
+
def __itruediv__(self, other, **raiser):
|
|
537
557
|
'''Apply C{B{self} /= B{other}} to this instance.
|
|
538
558
|
|
|
539
559
|
@arg other: An L{Fsum} or C{scalar} divisor.
|
|
560
|
+
@kwarg raiser: Use C{B{raiser}=False} to ignore L{ResidualError}s
|
|
561
|
+
(C{bool}), see also method L{RESIDUAL}.
|
|
540
562
|
|
|
541
563
|
@return: This instance, updated (L{Fsum}).
|
|
542
564
|
|
|
@@ -553,7 +575,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
553
575
|
|
|
554
576
|
@see: Method L{Fsum.__ifloordiv__}.
|
|
555
577
|
'''
|
|
556
|
-
return self._ftruediv(other, _truediv_op_ + _fset_op_)
|
|
578
|
+
return self._ftruediv(other, _truediv_op_ + _fset_op_, **raiser)
|
|
557
579
|
|
|
558
580
|
def __le__(self, other):
|
|
559
581
|
'''Compare this with an other instance or C{scalar}.
|
|
@@ -670,8 +692,8 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
670
692
|
@arg ndigits: Optional number of digits (C{int}).
|
|
671
693
|
'''
|
|
672
694
|
# <https://docs.Python.org/3.12/reference/datamodel.html?#object.__round__>
|
|
673
|
-
return
|
|
674
|
-
|
|
695
|
+
return _Psum_(round(float(self), *ndigits), # can be C{int}
|
|
696
|
+
name=self.__round__.__name__)
|
|
675
697
|
|
|
676
698
|
def __rpow__(self, other, *mod):
|
|
677
699
|
'''Return C{B{other}**B{self}} as an L{Fsum}.
|
|
@@ -689,13 +711,13 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
689
711
|
f = self._copy_2r(other, self.__rsub__)
|
|
690
712
|
return f._fsub(self, _sub_op_)
|
|
691
713
|
|
|
692
|
-
def __rtruediv__(self, other):
|
|
714
|
+
def __rtruediv__(self, other, **raiser):
|
|
693
715
|
'''Return C{B{other} / B{self}} as an L{Fsum}.
|
|
694
716
|
|
|
695
717
|
@see: Method L{Fsum.__itruediv__}.
|
|
696
718
|
'''
|
|
697
719
|
f = self._copy_2r(other, self.__rtruediv__)
|
|
698
|
-
return f._ftruediv(self, _truediv_op_)
|
|
720
|
+
return f._ftruediv(self, _truediv_op_, **raiser)
|
|
699
721
|
|
|
700
722
|
def __str__(self):
|
|
701
723
|
'''Return the default C{str(self)}.
|
|
@@ -714,17 +736,19 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
714
736
|
f = self._copy_2(self.__sub__)
|
|
715
737
|
return f._fsub(other, _sub_op_)
|
|
716
738
|
|
|
717
|
-
def __truediv__(self, other):
|
|
739
|
+
def __truediv__(self, other, **raiser):
|
|
718
740
|
'''Return C{B{self} / B{other}} as an L{Fsum}.
|
|
719
741
|
|
|
720
742
|
@arg other: An L{Fsum} or C{scalar} divisor.
|
|
743
|
+
@kwarg raiser: Use C{B{raiser}=False} to ignore L{ResidualError}s
|
|
744
|
+
(C{bool}), see also method L{RESIDUAL}.
|
|
721
745
|
|
|
722
746
|
@return: The quotient (L{Fsum}).
|
|
723
747
|
|
|
724
748
|
@see: Method L{Fsum.__itruediv__}.
|
|
725
749
|
'''
|
|
726
750
|
f = self._copy_2(self.__truediv__)
|
|
727
|
-
return f._ftruediv(other, _truediv_op_)
|
|
751
|
+
return f._ftruediv(other, _truediv_op_, **raiser)
|
|
728
752
|
|
|
729
753
|
__trunc__ = __int__
|
|
730
754
|
|
|
@@ -753,6 +777,13 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
753
777
|
d = 1
|
|
754
778
|
return n, d
|
|
755
779
|
|
|
780
|
+
@property_RO
|
|
781
|
+
def as_iscalar(self):
|
|
782
|
+
'''Get this instance I{as-is} (L{Fsum}) or C{scalar} iff scalar.
|
|
783
|
+
'''
|
|
784
|
+
s, r = self._fprs2
|
|
785
|
+
return self if r else s
|
|
786
|
+
|
|
756
787
|
@property_RO
|
|
757
788
|
def ceil(self):
|
|
758
789
|
'''Get this instance' C{ceil} value (C{int} in Python 3+,
|
|
@@ -773,15 +804,12 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
773
804
|
'''(INTERNAL) Return C{scalar(self - B{other})} for 0-comparison.
|
|
774
805
|
'''
|
|
775
806
|
if isinstance(other, Fsum):
|
|
776
|
-
s = _fsum(self.
|
|
777
|
-
elif
|
|
778
|
-
|
|
779
|
-
s = _fsum(self._ps_1(other))
|
|
780
|
-
else:
|
|
781
|
-
s, r = self._fprs2
|
|
782
|
-
s = _signOf(s, -r)
|
|
807
|
+
s = _fsum(self._ps_1primed(*other._ps))
|
|
808
|
+
elif self._scalar(other, op):
|
|
809
|
+
s = _fsum(self._ps_1primed(other))
|
|
783
810
|
else:
|
|
784
|
-
|
|
811
|
+
s, r = self._fprs2
|
|
812
|
+
s = _signOf(s, -r)
|
|
785
813
|
return s
|
|
786
814
|
|
|
787
815
|
def copy(self, deep=False, name=NN):
|
|
@@ -790,8 +818,10 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
790
818
|
@return: The copy (L{Fsum}).
|
|
791
819
|
'''
|
|
792
820
|
f = _Named.copy(self, deep=deep, name=name)
|
|
793
|
-
f._ps
|
|
794
|
-
|
|
821
|
+
if f._ps is self._ps:
|
|
822
|
+
f._ps = list(self._ps) # separate list
|
|
823
|
+
if not deep:
|
|
824
|
+
f._n = 1
|
|
795
825
|
return f
|
|
796
826
|
|
|
797
827
|
def _copy_2(self, which, name=NN):
|
|
@@ -817,11 +847,13 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
817
847
|
# if R is not Fsum._RESIDUAL:
|
|
818
848
|
# self._RESIDUAL = R
|
|
819
849
|
|
|
820
|
-
def divmod(self, other):
|
|
850
|
+
def divmod(self, other, **raiser):
|
|
821
851
|
'''Return C{divmod(B{self}, B{other})} as 2-tuple C{(quotient,
|
|
822
852
|
remainder)}.
|
|
823
853
|
|
|
824
854
|
@arg other: An L{Fsum} or C{scalar} divisor.
|
|
855
|
+
@kwarg raiser: Use C{B{raiser}=False} to ignore L{ResidualError}s
|
|
856
|
+
(C{bool}), see also method L{RESIDUAL}.
|
|
825
857
|
|
|
826
858
|
@return: A L{DivMod2Tuple}C{(div, mod)}, with quotient C{div}
|
|
827
859
|
an C{int} in Python 3+ or C{float} in Python 2- and
|
|
@@ -830,12 +862,12 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
830
862
|
@see: Method L{Fsum.__itruediv__}.
|
|
831
863
|
'''
|
|
832
864
|
f = self._copy_2(self.divmod)
|
|
833
|
-
return f._fdivmod2(other, _divmod_op_)
|
|
865
|
+
return f._fdivmod2(other, _divmod_op_, **raiser)
|
|
834
866
|
|
|
835
867
|
def _Error(self, op, other, Error, **txt_cause):
|
|
836
868
|
'''(INTERNAL) Format an B{C{Error}} for C{{self} B{op} B{other}}.
|
|
837
869
|
'''
|
|
838
|
-
return Error(_SPACE_(self.
|
|
870
|
+
return Error(_SPACE_(self.as_iscalar, op, other), **txt_cause)
|
|
839
871
|
|
|
840
872
|
def _ErrorX(self, X, op, other, *mod):
|
|
841
873
|
'''(INTERNAL) Format the caught exception C{X}.
|
|
@@ -852,66 +884,91 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
852
884
|
n = unstr(self.named3, *xs[:3], _ELLIPSIS=len(xs) > 3, **kwds)
|
|
853
885
|
return E(n, txt=t, cause=X)
|
|
854
886
|
|
|
855
|
-
def _facc(self, xs, **
|
|
856
|
-
'''(INTERNAL) Accumulate
|
|
857
|
-
'''
|
|
858
|
-
self._ps_acc(self._ps, xs, **up)
|
|
859
|
-
return self
|
|
860
|
-
|
|
861
|
-
def _facc_(self, *xs, **up):
|
|
862
|
-
'''(INTERNAL) Accumulate all positional C{xs}, known to be scalar.
|
|
887
|
+
def _facc(self, xs, up=True, **origin_X_x):
|
|
888
|
+
'''(INTERNAL) Accumulate more C{scalars} or L{Fsum}s.
|
|
863
889
|
'''
|
|
864
890
|
if xs:
|
|
865
|
-
|
|
891
|
+
_xs = _2floats(xs, **origin_X_x) # PYCHOK yield
|
|
892
|
+
ps = self._ps
|
|
893
|
+
ps[:] = self._ps_acc(list(ps), _xs, up=up)
|
|
866
894
|
return self
|
|
867
895
|
|
|
868
|
-
def
|
|
869
|
-
'''(INTERNAL) Accumulate more C{scalars} or L{Fsum}s
|
|
896
|
+
def _facc_1(self, xs, **up):
|
|
897
|
+
'''(INTERNAL) Accumulate 0, 1 or more C{scalars} or L{Fsum}s,
|
|
898
|
+
all positional C{xs} in the caller of this method.
|
|
870
899
|
'''
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
900
|
+
# assert islistuple(xs)
|
|
901
|
+
return self._fadd(xs[0], _add_op_) if len(xs) == 1 else \
|
|
902
|
+
self._facc(xs, origin=1, **up)
|
|
874
903
|
|
|
875
|
-
def
|
|
904
|
+
def _facc_neg(self, xs, up=True, **origin):
|
|
876
905
|
'''(INTERNAL) Accumulate more C{scalars} or L{Fsum}s, negated.
|
|
877
906
|
'''
|
|
878
|
-
|
|
879
|
-
|
|
907
|
+
if xs:
|
|
908
|
+
def _neg(x):
|
|
909
|
+
return -x
|
|
880
910
|
|
|
881
|
-
|
|
882
|
-
|
|
911
|
+
_x = _2floats(xs, **origin) # PYCHOK yield
|
|
912
|
+
ps = self._ps
|
|
913
|
+
ps[:] = self._ps_acc(list(ps), map(_neg, _x), up=up)
|
|
883
914
|
return self
|
|
884
915
|
|
|
885
|
-
def _facc_power(self, power, xs, which): # in .fmath
|
|
916
|
+
def _facc_power(self, power, xs, which, **raiser): # in .fmath
|
|
886
917
|
'''(INTERNAL) Add each C{xs} as C{float(x**power)}.
|
|
887
918
|
'''
|
|
888
|
-
p
|
|
889
|
-
|
|
890
|
-
if p
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
919
|
+
def _Pow4(p):
|
|
920
|
+
r = 0
|
|
921
|
+
if isinstance(p, Fsum):
|
|
922
|
+
s, r = p._fprs2
|
|
923
|
+
if r == 0:
|
|
924
|
+
return _Pow4(s)
|
|
925
|
+
m = Fsum._pow
|
|
926
|
+
elif isint(p, both=True) and int(p) >= 0:
|
|
927
|
+
p = s = int(p)
|
|
928
|
+
m = Fsum._pow_int
|
|
929
|
+
else:
|
|
930
|
+
p = s = _2float(power=p)
|
|
931
|
+
m = Fsum._pow_scalar
|
|
932
|
+
return m, p, s, r
|
|
897
933
|
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
_Fs
|
|
934
|
+
_Pow, p, s, r = _Pow4(power)
|
|
935
|
+
if p: # and xs:
|
|
936
|
+
_pow = Fsum._pow_2_3
|
|
937
|
+
_Fs = Fsum
|
|
938
|
+
_Ps = _Psum_ # ()._fset_ps_
|
|
939
|
+
op = which.__name__
|
|
902
940
|
|
|
903
941
|
def _X(X):
|
|
904
|
-
f = _Pow(X, p, power, op)
|
|
942
|
+
f = _Pow(X, p, power, op, **raiser)
|
|
905
943
|
return f._ps if isinstance(f, _Fs) else (f,)
|
|
906
944
|
|
|
907
945
|
def _x(x):
|
|
908
|
-
|
|
946
|
+
x = float(x)
|
|
947
|
+
X = _Ps(x)
|
|
948
|
+
f = _pow(X, x, s, power, op, **raiser)
|
|
949
|
+
if r:
|
|
950
|
+
f *= _pow(X, x, r, power, op, **raiser)
|
|
951
|
+
return f
|
|
909
952
|
|
|
910
|
-
f = self.
|
|
953
|
+
f = self._facc(xs, origin=1, _X=_X, _x=_x)
|
|
911
954
|
else:
|
|
912
|
-
f = self.
|
|
955
|
+
f = self._facc_scalar_(float(len(xs))) # x**0 == 1
|
|
913
956
|
return f
|
|
914
957
|
|
|
958
|
+
def _facc_scalar(self, xs, **up):
|
|
959
|
+
'''(INTERNAL) Accumulate all C{xs}, known to be scalar.
|
|
960
|
+
'''
|
|
961
|
+
if xs:
|
|
962
|
+
self._ps_acc(self._ps, xs, **up)
|
|
963
|
+
return self
|
|
964
|
+
|
|
965
|
+
def _facc_scalar_(self, *xs, **up):
|
|
966
|
+
'''(INTERNAL) Accumulate all positional C{xs}, known to be scalar.
|
|
967
|
+
'''
|
|
968
|
+
if xs:
|
|
969
|
+
self._ps_acc(self._ps, xs, **up)
|
|
970
|
+
return self
|
|
971
|
+
|
|
915
972
|
# def _facc_up(self, up=True):
|
|
916
973
|
# '''(INTERNAL) Update the C{partials}, by removing
|
|
917
974
|
# and re-accumulating the final C{partial}.
|
|
@@ -920,7 +977,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
920
977
|
# p = self._ps.pop()
|
|
921
978
|
# if p:
|
|
922
979
|
# n = self._n
|
|
923
|
-
# self.
|
|
980
|
+
# self._facc_scalar_(p, up=False)
|
|
924
981
|
# self._n = n
|
|
925
982
|
# break
|
|
926
983
|
# return self._update() if up else self # ._fpsqz()
|
|
@@ -942,11 +999,11 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
942
999
|
@raise ValueError: Invalid or non-finite B{C{xs}} value.
|
|
943
1000
|
'''
|
|
944
1001
|
if isinstance(xs, Fsum):
|
|
945
|
-
self.
|
|
1002
|
+
self._facc_scalar(xs._ps) # tuple
|
|
946
1003
|
elif isscalar(xs): # for backward compatibility
|
|
947
|
-
self.
|
|
948
|
-
elif xs:
|
|
949
|
-
self.
|
|
1004
|
+
self._facc_scalar_(_2float(x=xs)) # PYCHOK no cover
|
|
1005
|
+
elif xs: # assert isiterable(xs)
|
|
1006
|
+
self._facc(xs)
|
|
950
1007
|
return self
|
|
951
1008
|
|
|
952
1009
|
def fadd_(self, *xs):
|
|
@@ -965,30 +1022,29 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
965
1022
|
|
|
966
1023
|
@raise ValueError: Invalid or non-finite B{C{xs}} value.
|
|
967
1024
|
'''
|
|
968
|
-
return self.
|
|
1025
|
+
return self._facc_1(xs)
|
|
969
1026
|
|
|
970
1027
|
def _fadd(self, other, op, **up): # in .fmath.Fhorner
|
|
971
1028
|
'''(INTERNAL) Apply C{B{self} += B{other}}.
|
|
972
1029
|
'''
|
|
973
1030
|
if isinstance(other, Fsum):
|
|
974
|
-
self.
|
|
975
|
-
elif
|
|
976
|
-
|
|
977
|
-
elif other:
|
|
978
|
-
self._facc_(other, **up)
|
|
1031
|
+
self._facc_scalar(other._ps, **up) # tuple
|
|
1032
|
+
elif self._scalar(other, op):
|
|
1033
|
+
self._facc_scalar_(other, **up)
|
|
979
1034
|
return self
|
|
980
1035
|
|
|
981
1036
|
fcopy = copy # for backward compatibility
|
|
982
1037
|
fdiv = __itruediv__ # for backward compatibility
|
|
983
1038
|
fdivmod = __divmod__ # for backward compatibility
|
|
984
1039
|
|
|
985
|
-
def _fdivmod2(self, other, op):
|
|
1040
|
+
def _fdivmod2(self, other, op, **raiser):
|
|
986
1041
|
'''(INTERNAL) Apply C{B{self} %= B{other}} and return a L{DivMod2Tuple}.
|
|
987
1042
|
'''
|
|
988
1043
|
# result mostly follows CPython function U{float_divmod
|
|
989
1044
|
# <https://GitHub.com/python/cpython/blob/main/Objects/floatobject.c>},
|
|
990
1045
|
# but at least divmod(-3, 2) equals Cpython's result (-2, 1).
|
|
991
|
-
|
|
1046
|
+
f = self._copy_2(self._fdivmod2)
|
|
1047
|
+
q = f._ftruediv(other, op, **raiser).floor
|
|
992
1048
|
if q: # == float // other == floor(float / other)
|
|
993
1049
|
self -= other * q
|
|
994
1050
|
|
|
@@ -1009,24 +1065,28 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1009
1065
|
raise ValueError(_not_finite_) if op is None else \
|
|
1010
1066
|
self._ValueError(op, other, txt=_not_finite_)
|
|
1011
1067
|
|
|
1012
|
-
def fint(self, raiser=True, **
|
|
1068
|
+
def fint(self, raiser=True, name=NN, **RESIDUAL):
|
|
1013
1069
|
'''Return this instance' current running sum as C{integer}.
|
|
1014
1070
|
|
|
1015
|
-
@kwarg raiser:
|
|
1016
|
-
|
|
1071
|
+
@kwarg raiser: Use C{B{raiser}=False} to ignore L{ResidualError}s
|
|
1072
|
+
(C{bool}), see also method L{RESIDUAL}.
|
|
1017
1073
|
@kwarg name: Optional name (C{str}), overriding C{"fint"}.
|
|
1074
|
+
@kwarg RESIDUAL: Optional threshold, overriding the current
|
|
1075
|
+
L{RESIDUAL<Fsum.RESIDUAL>} (C{scalar}).
|
|
1018
1076
|
|
|
1019
|
-
@return: The C{integer} (L{Fsum})
|
|
1077
|
+
@return: The C{integer} sum (L{Fsum}) if this instance
|
|
1078
|
+
C{is_integer} and the residual is zero or
|
|
1079
|
+
insignificant or if C{B{raiser}=False}.
|
|
1020
1080
|
|
|
1021
1081
|
@raise ResidualError: Non-zero I{integer} residual.
|
|
1022
1082
|
|
|
1023
1083
|
@see: Methods L{Fsum.int_float} and L{Fsum.is_integer}.
|
|
1024
1084
|
'''
|
|
1025
1085
|
i, r = self._fint2
|
|
1026
|
-
if r and raiser:
|
|
1086
|
+
if r and raiser and self._raiser2sum(r, i, **RESIDUAL):
|
|
1027
1087
|
t = _stresidual(_integer_, r)
|
|
1028
1088
|
raise ResidualError(_integer_, i, txt=t)
|
|
1029
|
-
f = self._copy_2(self.fint,
|
|
1089
|
+
f = self._copy_2(self.fint, name=name)
|
|
1030
1090
|
return f._fset(i)
|
|
1031
1091
|
|
|
1032
1092
|
def fint2(self, **name):
|
|
@@ -1047,7 +1107,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1047
1107
|
'''
|
|
1048
1108
|
s, r = self._fprs2
|
|
1049
1109
|
i = int(s)
|
|
1050
|
-
r = _fsum(self.
|
|
1110
|
+
r = _fsum(self._ps_1primed(i)) if r else float(s - i)
|
|
1051
1111
|
return i, (r or INT0) # Fsum2Tuple?
|
|
1052
1112
|
|
|
1053
1113
|
@deprecated_property_RO
|
|
@@ -1073,10 +1133,10 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1073
1133
|
|
|
1074
1134
|
# floordiv = __floordiv__ # for naming consistency
|
|
1075
1135
|
|
|
1076
|
-
def _floordiv(self, other, op): # rather _ffloordiv?
|
|
1136
|
+
def _floordiv(self, other, op, **raiser): # rather _ffloordiv?
|
|
1077
1137
|
'''Apply C{B{self} //= B{other}}.
|
|
1078
1138
|
'''
|
|
1079
|
-
q = self._ftruediv(other, op) # == self
|
|
1139
|
+
q = self._ftruediv(other, op, **raiser) # == self
|
|
1080
1140
|
return self._fset(q.floor) # floor(q)
|
|
1081
1141
|
|
|
1082
1142
|
fmul = __imul__ # for backward compatibility
|
|
@@ -1091,41 +1151,42 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1091
1151
|
f = other._mul_scalar(self._ps[0], op)
|
|
1092
1152
|
else: # len(other._ps) == len(self._ps) == 1
|
|
1093
1153
|
f = self._finite(self._ps[0] * other._ps[0])
|
|
1094
|
-
elif isscalar(other):
|
|
1095
|
-
f = self._mul_scalar(other, op) if other != _1_0 else self
|
|
1096
1154
|
else:
|
|
1097
|
-
|
|
1155
|
+
s = self._scalar(other, op)
|
|
1156
|
+
f = self._mul_scalar(s, op)
|
|
1098
1157
|
return self._fset(f) # n=len(self) + 1
|
|
1099
1158
|
|
|
1100
|
-
def fover(self, over):
|
|
1159
|
+
def fover(self, over, **raiser):
|
|
1101
1160
|
'''Apply C{B{self} /= B{over}} and summate.
|
|
1102
1161
|
|
|
1103
1162
|
@arg over: An L{Fsum} or C{scalar} denominator.
|
|
1163
|
+
@kwarg raiser: Use C{B{raiser}=False} to ignore L{ResidualError}s
|
|
1164
|
+
(C{bool}), see also method L{RESIDUAL}.
|
|
1104
1165
|
|
|
1105
1166
|
@return: Precision running sum (C{float}).
|
|
1106
1167
|
|
|
1107
1168
|
@see: Methods L{Fsum.fsum} and L{Fsum.__itruediv__}.
|
|
1108
1169
|
'''
|
|
1109
|
-
return float(self.fdiv(over)._fprs)
|
|
1170
|
+
return float(self.fdiv(over, **raiser)._fprs)
|
|
1110
1171
|
|
|
1111
1172
|
fpow = __ipow__ # for backward compatibility
|
|
1112
1173
|
|
|
1113
|
-
def _fpow(self, other, op, *mod):
|
|
1174
|
+
def _fpow(self, other, op, *mod, **raiser):
|
|
1114
1175
|
'''Apply C{B{self} **= B{other}}, optional B{C{mod}} or C{None}.
|
|
1115
1176
|
'''
|
|
1116
1177
|
if mod:
|
|
1117
1178
|
if mod[0] is not None: # == 3-arg C{pow}
|
|
1118
|
-
f = self._pow_2_3(self, other, other, op, *mod)
|
|
1179
|
+
f = self._pow_2_3(self, other, other, op, *mod, **raiser)
|
|
1119
1180
|
elif self.is_integer():
|
|
1120
1181
|
# return an exact C{int} for C{int}**C{int}
|
|
1121
1182
|
i, _ = self._fint2 # assert _ == 0
|
|
1122
1183
|
x = _2scalar(other) # C{int}, C{float} or other
|
|
1123
|
-
f = self._pow_2_3(i, x, other, op) if isscalar(x) else \
|
|
1124
|
-
|
|
1184
|
+
f = self._pow_2_3(i, x, other, op, **raiser) if isscalar(x) else \
|
|
1185
|
+
_Psum_(i)._pow( x, other, op, **raiser) # x is Fsum
|
|
1125
1186
|
else: # mod[0] is None, power(self, other)
|
|
1126
|
-
f = self.
|
|
1127
|
-
else: # pow(self, other)
|
|
1128
|
-
f = self.
|
|
1187
|
+
f = self._pow(other, other, op, **raiser)
|
|
1188
|
+
else: # pow(self, other)
|
|
1189
|
+
f = self._pow(other, other, op, **raiser)
|
|
1129
1190
|
return self._fset(f, asis=isint(f)) # n=max(len(self), 1)
|
|
1130
1191
|
|
|
1131
1192
|
@Property_RO
|
|
@@ -1149,7 +1210,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1149
1210
|
s = _psum(ps)
|
|
1150
1211
|
n = len(ps) - 2
|
|
1151
1212
|
if n > 0:
|
|
1152
|
-
r = _fsum(self.
|
|
1213
|
+
r = _fsum(self._ps_1primed(s)) or INT0
|
|
1153
1214
|
return Fsum2Tuple(s, r)
|
|
1154
1215
|
if n == 0: # len(ps) == 2
|
|
1155
1216
|
ps[:] = _2ps(*_2sum(*ps))
|
|
@@ -1187,7 +1248,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1187
1248
|
'''(INTERNAL) Overwrite this instance with an other or a C{scalar}.
|
|
1188
1249
|
'''
|
|
1189
1250
|
if other is self:
|
|
1190
|
-
pass # from ._fmul, ._ftruediv and .
|
|
1251
|
+
pass # from ._fmul, ._ftruediv and ._pow_0_1
|
|
1191
1252
|
elif isinstance(other, Fsum):
|
|
1192
1253
|
self._ps[:] = other._ps
|
|
1193
1254
|
self._n = n or other._n
|
|
@@ -1206,7 +1267,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1206
1267
|
# Property's _fset zaps the value just set by the @setter
|
|
1207
1268
|
self.__dict__.update(_fint2=t, _fprs=s, _fprs2=Fsum2Tuple(s, INT0))
|
|
1208
1269
|
else: # PYCHOK no cover
|
|
1209
|
-
raise self.
|
|
1270
|
+
raise self._Error(_fset_op_, other, _AssertionError)
|
|
1210
1271
|
return self
|
|
1211
1272
|
|
|
1212
1273
|
def _fset_ps(self, other, n=0): # in .fmath
|
|
@@ -1220,6 +1281,13 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1220
1281
|
self._n = n or 1
|
|
1221
1282
|
return self
|
|
1222
1283
|
|
|
1284
|
+
# def _fset_ps_(self, *xs):
|
|
1285
|
+
# '''(INTERNAL) Set partials to all known scalar C{xs}.
|
|
1286
|
+
# '''
|
|
1287
|
+
# self._ps[:] = xs
|
|
1288
|
+
# self.n = len(xs)
|
|
1289
|
+
# return self
|
|
1290
|
+
|
|
1223
1291
|
def fsub(self, xs=()):
|
|
1224
1292
|
'''Subtract an iterable of C{scalar} or L{Fsum} instances from
|
|
1225
1293
|
this instance.
|
|
@@ -1231,7 +1299,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1231
1299
|
|
|
1232
1300
|
@see: Method L{Fsum.fadd}.
|
|
1233
1301
|
'''
|
|
1234
|
-
return self.
|
|
1302
|
+
return self._facc_neg(xs)
|
|
1235
1303
|
|
|
1236
1304
|
def fsub_(self, *xs):
|
|
1237
1305
|
'''Subtract all positional C{scalar} or L{Fsum} instances from
|
|
@@ -1244,7 +1312,8 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1244
1312
|
|
|
1245
1313
|
@see: Method L{Fsum.fadd}.
|
|
1246
1314
|
'''
|
|
1247
|
-
return self.
|
|
1315
|
+
return self._fsub(xs[0], _sub_op_) if len(xs) == 1 else \
|
|
1316
|
+
self._facc_neg(xs, origin=1)
|
|
1248
1317
|
|
|
1249
1318
|
def _fsub(self, other, op):
|
|
1250
1319
|
'''(INTERNAL) Apply C{B{self} -= B{other}}.
|
|
@@ -1253,11 +1322,9 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1253
1322
|
if other is self: # or other._fprs2 == self._fprs2:
|
|
1254
1323
|
self._fset(_0_0) # n=len(self) * 2, self -= self
|
|
1255
1324
|
elif other._ps:
|
|
1256
|
-
self.
|
|
1257
|
-
elif
|
|
1258
|
-
|
|
1259
|
-
elif self._finite(other, op):
|
|
1260
|
-
self._facc_(-other)
|
|
1325
|
+
self._facc_scalar(other._ps_neg)
|
|
1326
|
+
elif self._scalar(other, op):
|
|
1327
|
+
self._facc_scalar_(-self._finite(other, op))
|
|
1261
1328
|
return self
|
|
1262
1329
|
|
|
1263
1330
|
def fsum(self, xs=()):
|
|
@@ -1272,8 +1339,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1272
1339
|
|
|
1273
1340
|
@note: Accumulation can continue after summation.
|
|
1274
1341
|
'''
|
|
1275
|
-
|
|
1276
|
-
return f._fprs
|
|
1342
|
+
return self._facc(xs)._fprs
|
|
1277
1343
|
|
|
1278
1344
|
def fsum_(self, *xs):
|
|
1279
1345
|
'''Add all positional C{scalar} or L{Fsum} instances and summate.
|
|
@@ -1285,15 +1351,14 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1285
1351
|
|
|
1286
1352
|
@see: Methods L{Fsum.fsum}, L{Fsum.Fsum_} and L{Fsum.fsumf_}.
|
|
1287
1353
|
'''
|
|
1288
|
-
|
|
1289
|
-
return f._fprs
|
|
1354
|
+
return self._facc_1(xs)._fprs
|
|
1290
1355
|
|
|
1291
1356
|
def Fsum_(self, *xs):
|
|
1292
1357
|
'''Like method L{Fsum.fsum_} but returning an L{Fsum}.
|
|
1293
1358
|
|
|
1294
1359
|
@return: Current, precision running sum (L{Fsum}).
|
|
1295
1360
|
'''
|
|
1296
|
-
return self.
|
|
1361
|
+
return self._facc_1(xs)._copy_2(self.Fsum_)
|
|
1297
1362
|
|
|
1298
1363
|
def fsum2(self, xs=(), name=NN):
|
|
1299
1364
|
'''Add more C{scalar} or L{Fsum} instances and return the
|
|
@@ -1311,11 +1376,8 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1311
1376
|
|
|
1312
1377
|
@see: Methods L{Fsum.fint2}, L{Fsum.fsum} and L{Fsum.fsum2_}
|
|
1313
1378
|
'''
|
|
1314
|
-
|
|
1315
|
-
t
|
|
1316
|
-
if name:
|
|
1317
|
-
t = t.dup(name=name)
|
|
1318
|
-
return t
|
|
1379
|
+
t = self._facc(xs)._fprs2
|
|
1380
|
+
return t.dup(name=name) if name else t
|
|
1319
1381
|
|
|
1320
1382
|
def fsum2_(self, *xs):
|
|
1321
1383
|
'''Add any positional C{scalar} or L{Fsum} instances and return
|
|
@@ -1330,62 +1392,58 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1330
1392
|
|
|
1331
1393
|
@see: Methods L{Fsum.fsum_} and L{Fsum.fsum}.
|
|
1332
1394
|
'''
|
|
1333
|
-
return self.
|
|
1395
|
+
return self._fsum2(xs, self._facc_1)
|
|
1396
|
+
|
|
1397
|
+
def _fsum2(self, xs, _f, **origin):
|
|
1398
|
+
'''(INTERNAL) Helper for L{Fsum.fsum2_} and L{Fsum.fsum2f_}.
|
|
1399
|
+
'''
|
|
1400
|
+
p, q = self._fprs2
|
|
1401
|
+
if xs:
|
|
1402
|
+
s, r = _f(xs, **origin)._fprs2
|
|
1403
|
+
return s, _2delta(s - p, r - q) # _fsum(_1primed((s, -p, r, -q))
|
|
1404
|
+
else:
|
|
1405
|
+
return p, _0_0
|
|
1334
1406
|
|
|
1335
1407
|
def fsumf_(self, *xs):
|
|
1336
|
-
'''Like method L{Fsum.fsum_} but only for
|
|
1408
|
+
'''Like method L{Fsum.fsum_} but only for C{B{xs}}, I{known to be scalar}.
|
|
1337
1409
|
'''
|
|
1338
|
-
|
|
1339
|
-
return f._fprs
|
|
1410
|
+
return self._facc_scalar(xs)._fprs
|
|
1340
1411
|
|
|
1341
1412
|
def Fsumf_(self, *xs):
|
|
1342
|
-
'''Like method L{Fsum.Fsum_} but only for
|
|
1413
|
+
'''Like method L{Fsum.Fsum_} but only for C{B{xs}}, I{known to be scalar}.
|
|
1343
1414
|
'''
|
|
1344
|
-
return self.
|
|
1415
|
+
return self._facc_scalar(xs)._copy_2(self.Fsumf_)
|
|
1345
1416
|
|
|
1346
1417
|
def fsum2f_(self, *xs):
|
|
1347
|
-
'''Like method L{Fsum.fsum2_} but only for
|
|
1348
|
-
'''
|
|
1349
|
-
return self._fsum2f_any(xs, self._facc)
|
|
1350
|
-
|
|
1351
|
-
def _fsum2f_any(self, xs, _facc, **origin):
|
|
1352
|
-
'''(INTERNAL) Helper for L{Fsum.fsum2_} and L{Fsum.fsum2f_}.
|
|
1418
|
+
'''Like method L{Fsum.fsum2_} but only for C{B{xs}}, I{known to be scalar}.
|
|
1353
1419
|
'''
|
|
1354
|
-
|
|
1355
|
-
if xs:
|
|
1356
|
-
s, r = _facc(xs, **origin)._fprs2
|
|
1357
|
-
return s, _2delta(s - p, r - q) # _fsum(_1primed((s, -p, r, -q))
|
|
1358
|
-
else:
|
|
1359
|
-
return p, _0_0
|
|
1420
|
+
return self._fsum2(xs, self._facc_scalar, origin=1)
|
|
1360
1421
|
|
|
1361
1422
|
# ftruediv = __itruediv__ # for naming consistency?
|
|
1362
1423
|
|
|
1363
|
-
def _ftruediv(self, other, op):
|
|
1424
|
+
def _ftruediv(self, other, op, **raiser):
|
|
1364
1425
|
'''(INTERNAL) Apply C{B{self} /= B{other}}.
|
|
1365
1426
|
'''
|
|
1366
1427
|
n = _1_0
|
|
1367
1428
|
if isinstance(other, Fsum):
|
|
1368
1429
|
if other is self or other == self:
|
|
1369
|
-
return self._fset(
|
|
1430
|
+
return self._fset(n) # n=len(self)
|
|
1370
1431
|
d, r = other._fprs2
|
|
1371
1432
|
if r:
|
|
1372
1433
|
if d:
|
|
1373
|
-
if self._raiser(r, d):
|
|
1434
|
+
if self._raiser(r, d, **raiser):
|
|
1374
1435
|
raise self._ResidualError(op, other, r)
|
|
1375
1436
|
d, n = other.as_integer_ratio()
|
|
1376
1437
|
else: # PYCHOK no cover
|
|
1377
1438
|
d = r
|
|
1378
|
-
|
|
1379
|
-
d = other
|
|
1380
|
-
else: # PYCHOK no cover
|
|
1381
|
-
raise self._TypeError(op, other) # txt=_invalid_
|
|
1439
|
+
else:
|
|
1440
|
+
d = self._scalar(other, op)
|
|
1382
1441
|
try:
|
|
1383
|
-
s =
|
|
1384
|
-
d if isnan(d) else self._finite(n / d))
|
|
1442
|
+
s = n / d
|
|
1385
1443
|
except Exception as X:
|
|
1386
1444
|
raise self._ErrorX(X, op, other)
|
|
1387
|
-
f = self._mul_scalar(s, _mul_op_) # handles 0,
|
|
1388
|
-
return self._fset(f
|
|
1445
|
+
f = self._mul_scalar(s, _mul_op_) # handles 0, INF, NAN
|
|
1446
|
+
return self._fset(f) # asis=False
|
|
1389
1447
|
|
|
1390
1448
|
@property_RO
|
|
1391
1449
|
def imag(self):
|
|
@@ -1395,24 +1453,26 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1395
1453
|
'''
|
|
1396
1454
|
return _0_0
|
|
1397
1455
|
|
|
1398
|
-
def int_float(self, raiser=False):
|
|
1456
|
+
def int_float(self, raiser=False, **RESIDUAL):
|
|
1399
1457
|
'''Return this instance' current running sum as C{int} or C{float}.
|
|
1400
1458
|
|
|
1401
1459
|
@kwarg raiser: If C{True} throw a L{ResidualError} if the
|
|
1402
|
-
residual
|
|
1460
|
+
residual exceeds the C{RESIDUAL} (C{bool}).
|
|
1461
|
+
@kwarg RESIDUAL: Optional threshold, overriding the current
|
|
1462
|
+
L{RESIDUAL<Fsum.RESIDUAL>} (C{scalar}).
|
|
1403
1463
|
|
|
1404
1464
|
@return: This C{integer} sum if this instance C{is_integer},
|
|
1405
|
-
otherwise return the C{float} sum if the residual
|
|
1406
|
-
|
|
1465
|
+
otherwise return the C{float} sum if the residual is
|
|
1466
|
+
zero or insignificant or if C{B{raiser}=False}.
|
|
1407
1467
|
|
|
1408
1468
|
@raise ResidualError: Non-zero residual and C{B{raiser}=True}.
|
|
1409
1469
|
|
|
1410
|
-
@see: Methods L{Fsum.fint} and L{Fsum.fint2}.
|
|
1470
|
+
@see: Methods L{Fsum.fint} and L{Fsum.fint2} and property L{Fsum.as_iscalar}.
|
|
1411
1471
|
'''
|
|
1412
1472
|
s, r = self._fint2
|
|
1413
1473
|
if r:
|
|
1414
1474
|
s, r = self._fprs2
|
|
1415
|
-
if r and raiser: # PYCHOK no cover
|
|
1475
|
+
if r and raiser and self._raiser2sum(r, s, **RESIDUAL): # PYCHOK no cover
|
|
1416
1476
|
t = _stresidual(_non_zero_, r)
|
|
1417
1477
|
raise ResidualError(int_float=s, txt=t)
|
|
1418
1478
|
s = float(s) # redundant
|
|
@@ -1426,7 +1486,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1426
1486
|
def is_integer(self):
|
|
1427
1487
|
'''Is this instance' running sum C{integer}? (C{bool}).
|
|
1428
1488
|
|
|
1429
|
-
@see: Methods L{Fsum.fint} and L{Fsum.
|
|
1489
|
+
@see: Methods L{Fsum.fint}, L{Fsum.fint2} and L{Fsum.is_scalar}.
|
|
1430
1490
|
'''
|
|
1431
1491
|
_, r = self._fint2
|
|
1432
1492
|
return False if r else True
|
|
@@ -1445,12 +1505,20 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1445
1505
|
f = Fsum._math_fsum
|
|
1446
1506
|
return 2 if _psum is f else bool(f)
|
|
1447
1507
|
|
|
1508
|
+
def is_scalar(self):
|
|
1509
|
+
'''Is this instance' running sum C{scalar}? (C{bool}).
|
|
1510
|
+
|
|
1511
|
+
@see: Method L{Fsum.is_integer} and property L{Fsum.as_iscalar}.
|
|
1512
|
+
'''
|
|
1513
|
+
s, r = t = self._fprs2
|
|
1514
|
+
return False if r and _2sum(s, r) != t else True
|
|
1515
|
+
|
|
1448
1516
|
def _mul_Fsum(self, other, op=_mul_op_): # in .fmath.Fhorner
|
|
1449
1517
|
'''(INTERNAL) Return C{B{self} * Fsum B{other}} as L{Fsum} or C{0}.
|
|
1450
1518
|
'''
|
|
1451
1519
|
# assert isinstance(other, Fsum)
|
|
1452
1520
|
if self._ps and other._ps:
|
|
1453
|
-
f = self._ps_mul(op, *other._ps) # NO .
|
|
1521
|
+
f = self._ps_mul(op, *other._ps) # NO .as_iscalar
|
|
1454
1522
|
else:
|
|
1455
1523
|
f = _0_0
|
|
1456
1524
|
return f
|
|
@@ -1462,7 +1530,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1462
1530
|
if self._ps and self._finite(factor, op):
|
|
1463
1531
|
f = self if factor == _1_0 else (
|
|
1464
1532
|
self._neg if factor == _N_1_0 else
|
|
1465
|
-
self._ps_mul(op, factor).
|
|
1533
|
+
self._ps_mul(op, factor).as_iscalar)
|
|
1466
1534
|
else:
|
|
1467
1535
|
f = _0_0
|
|
1468
1536
|
return f
|
|
@@ -1479,12 +1547,14 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1479
1547
|
'''
|
|
1480
1548
|
return tuple(self._ps)
|
|
1481
1549
|
|
|
1482
|
-
def pow(self, x, *mod):
|
|
1550
|
+
def pow(self, x, *mod, **raiser):
|
|
1483
1551
|
'''Return C{B{self}**B{x}} as L{Fsum}.
|
|
1484
1552
|
|
|
1485
1553
|
@arg x: The exponent (L{Fsum} or C{scalar}).
|
|
1486
1554
|
@arg mod: Optional modulus (C{int} or C{None}) for the 3-argument
|
|
1487
1555
|
C{pow(B{self}, B{other}, B{mod})} version.
|
|
1556
|
+
@kwarg raiser: Use C{B{raiser}=False} to ignore L{ResidualError}s
|
|
1557
|
+
(C{bool}), see also method L{RESIDUAL}.
|
|
1488
1558
|
|
|
1489
1559
|
@return: The C{pow(self, B{x})} or C{pow(self, B{x}, *B{mod})}
|
|
1490
1560
|
result (L{Fsum}).
|
|
@@ -1493,17 +1563,35 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1493
1563
|
C{integer} L{Fsum} provided this instance C{is_integer}
|
|
1494
1564
|
or set to C{integer} by an L{Fsum.fint} call.
|
|
1495
1565
|
|
|
1496
|
-
@see: Methods L{Fsum.__ipow__}, L{Fsum.fint}
|
|
1566
|
+
@see: Methods L{Fsum.__ipow__}, L{Fsum.fint}, L{Fsum.is_integer}
|
|
1567
|
+
and L{Fsum.root}.
|
|
1497
1568
|
'''
|
|
1498
1569
|
f = self._copy_2(self.pow)
|
|
1499
|
-
return f._fpow(x, _pow_op_, *mod) # f = pow(f, x, *mod)
|
|
1570
|
+
return f._fpow(x, _pow_op_, *mod, **raiser) # f = pow(f, x, *mod)
|
|
1571
|
+
|
|
1572
|
+
def _pow(self, other, unused, op, **raiser):
|
|
1573
|
+
'''Return C{B{self} ** B{other}}.
|
|
1574
|
+
'''
|
|
1575
|
+
if isinstance(other, Fsum):
|
|
1576
|
+
x, r = other._fprs2
|
|
1577
|
+
if r and self._raiser(r, x, **raiser):
|
|
1578
|
+
raise self._ResidualError(op, other, r)
|
|
1579
|
+
f = self._pow_scalar(x, other, op, **raiser)
|
|
1580
|
+
if r:
|
|
1581
|
+
f *= self._pow_scalar(r, other, op, **raiser)
|
|
1582
|
+
elif self._scalar(other, op):
|
|
1583
|
+
x = self._finite(other, op)
|
|
1584
|
+
f = self._pow_scalar(x, other, op, **raiser)
|
|
1585
|
+
else:
|
|
1586
|
+
f = self._pow_0_1(0, other)
|
|
1587
|
+
return f
|
|
1500
1588
|
|
|
1501
1589
|
def _pow_0_1(self, x, other):
|
|
1502
1590
|
'''(INTERNAL) Return B{C{self}**1} or C{B{self}**0 == 1.0}.
|
|
1503
1591
|
'''
|
|
1504
1592
|
return self if x else (1 if isint(other) and self.is_integer() else _1_0)
|
|
1505
1593
|
|
|
1506
|
-
def _pow_2_3(self, b, x, other, op, *mod):
|
|
1594
|
+
def _pow_2_3(self, b, x, other, op, *mod, **raiser):
|
|
1507
1595
|
'''(INTERNAL) 2-arg C{pow(B{b}, scalar B{x})} and 3-arg C{pow(B{b},
|
|
1508
1596
|
B{x}, int B{mod} or C{None})}, embellishing errors.
|
|
1509
1597
|
'''
|
|
@@ -1511,7 +1599,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1511
1599
|
if mod: # b, x, mod all C{int}, unless C{mod} is C{None}
|
|
1512
1600
|
m = mod[0]
|
|
1513
1601
|
b, r = b._fprs2 if m is None else b._fint2
|
|
1514
|
-
if r and self._raiser(r, b):
|
|
1602
|
+
if r and self._raiser(r, b, **raiser):
|
|
1515
1603
|
t = _non_zero_ if m is None else _integer_
|
|
1516
1604
|
raise ResidualError(_stresidual(t, r, mod=m), txt=None)
|
|
1517
1605
|
x = _2scalar(x, _raiser=self._raiser, mod=m)
|
|
@@ -1524,24 +1612,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1524
1612
|
except Exception as X:
|
|
1525
1613
|
raise self._ErrorX(X, op, other, *mod)
|
|
1526
1614
|
|
|
1527
|
-
def
|
|
1528
|
-
'''Return C{B{self} ** B{other}}.
|
|
1529
|
-
'''
|
|
1530
|
-
if isinstance(other, Fsum):
|
|
1531
|
-
x, r = other._fprs2
|
|
1532
|
-
if r and self._raiser(r, x):
|
|
1533
|
-
raise self._ResidualError(op, other, r)
|
|
1534
|
-
f = self._pow_scalar(x, other, op)
|
|
1535
|
-
if r:
|
|
1536
|
-
f *= self._pow_scalar(r, other, op)
|
|
1537
|
-
elif isscalar(other):
|
|
1538
|
-
x = self._finite(other, op)
|
|
1539
|
-
f = self._pow_scalar(x, other, op)
|
|
1540
|
-
else:
|
|
1541
|
-
raise self._TypeError(op, other) # txt=_invalid_
|
|
1542
|
-
return f
|
|
1543
|
-
|
|
1544
|
-
def _pow_int(self, x, other, op):
|
|
1615
|
+
def _pow_int(self, x, other, op, **raiser):
|
|
1545
1616
|
'''(INTERNAL) Return C{B{self} **= B{x}} for C{int B{x} >= 0}.
|
|
1546
1617
|
'''
|
|
1547
1618
|
# assert isint(x) and x >= 0
|
|
@@ -1550,7 +1621,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1550
1621
|
_mul_Fsum = Fsum._mul_Fsum
|
|
1551
1622
|
if x > 4:
|
|
1552
1623
|
p = self
|
|
1553
|
-
f = self if (x & 1) else
|
|
1624
|
+
f = self if (x & 1) else _Psum_(_1_0)
|
|
1554
1625
|
m = x >> 1 # // 2
|
|
1555
1626
|
while m:
|
|
1556
1627
|
p = _mul_Fsum(p, p, op) # p **= 2
|
|
@@ -1561,17 +1632,17 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1561
1632
|
f = _mul_Fsum(self, self, op)
|
|
1562
1633
|
if x > 2: # self**3 or 4
|
|
1563
1634
|
p = self if x < 4 else f
|
|
1564
|
-
f = _mul_Fsum(f, p, op).
|
|
1635
|
+
f = _mul_Fsum(f, p, op).as_iscalar
|
|
1565
1636
|
else: # self**1 or self**0 == 1 or _1_0
|
|
1566
1637
|
f = self._pow_0_1(x, other)
|
|
1567
1638
|
elif ps: # self._ps[0]**x
|
|
1568
|
-
f = self._pow_2_3(ps[0], x, other, op)
|
|
1639
|
+
f = self._pow_2_3(ps[0], x, other, op, **raiser)
|
|
1569
1640
|
else: # PYCHOK no cover
|
|
1570
1641
|
# 0**pos_int == 0, but 0**0 == 1
|
|
1571
1642
|
f = 0 if x else 1
|
|
1572
1643
|
return f
|
|
1573
1644
|
|
|
1574
|
-
def _pow_scalar(self, x, other, op):
|
|
1645
|
+
def _pow_scalar(self, x, other, op, **raiser):
|
|
1575
1646
|
'''(INTERNAL) Return C{self**B{x}} for C{scalar B{x}}.
|
|
1576
1647
|
'''
|
|
1577
1648
|
s, r = self._fprs2
|
|
@@ -1580,41 +1651,33 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1580
1651
|
y = abs(x)
|
|
1581
1652
|
if y > 1:
|
|
1582
1653
|
if r:
|
|
1583
|
-
f = self._pow_int(y, other, op)
|
|
1654
|
+
f = self._pow_int(y, other, op, **raiser)
|
|
1584
1655
|
if x > 0: # > 1
|
|
1585
1656
|
return f
|
|
1586
1657
|
# assert x < 0 # < -1
|
|
1587
1658
|
s, r = f._fprs2 if isinstance(f, Fsum) else (f, 0)
|
|
1588
1659
|
if r:
|
|
1589
|
-
return
|
|
1660
|
+
return _1_over(f, op, **raiser) # PYCHOK 2 args
|
|
1590
1661
|
# use **= -1 for the CPython float_pow
|
|
1591
1662
|
# error if s is zero, and not s = 1 / s
|
|
1592
1663
|
x = -1
|
|
1593
1664
|
elif x < 0: # == -1: self**(-1) == 1 / self
|
|
1594
1665
|
if r:
|
|
1595
|
-
return
|
|
1666
|
+
return _1_over(self, op, **raiser) # PYCHOK 2 args
|
|
1596
1667
|
else: # self**1 or self**0
|
|
1597
1668
|
return self._pow_0_1(x, other) # self, 1 or 1.0
|
|
1598
|
-
elif
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1669
|
+
elif r: # non-zero residual**fractional
|
|
1670
|
+
if s:
|
|
1671
|
+
n, d = self.as_integer_ratio()
|
|
1672
|
+
if abs(n) > abs(d):
|
|
1673
|
+
n, d, x = d, n, (-x)
|
|
1674
|
+
s = n / d
|
|
1675
|
+
else:
|
|
1676
|
+
s = r
|
|
1604
1677
|
# assert isscalar(s) and isscalar(x)
|
|
1605
|
-
return self._pow_2_3(s, x, other, op)
|
|
1678
|
+
return self._pow_2_3(s, x, other, op, **raiser)
|
|
1606
1679
|
|
|
1607
|
-
def
|
|
1608
|
-
'''(INTERNAL) Yield partials, 1-primed and subtract any C{less}.
|
|
1609
|
-
'''
|
|
1610
|
-
yield _1_0
|
|
1611
|
-
for p in self._ps:
|
|
1612
|
-
yield p
|
|
1613
|
-
for p in less:
|
|
1614
|
-
yield -p
|
|
1615
|
-
yield _N_1_0
|
|
1616
|
-
|
|
1617
|
-
def _ps_acc(self, ps, xs, up=True):
|
|
1680
|
+
def _ps_acc(self, ps, xs, up=True, **unused):
|
|
1618
1681
|
'''(INTERNAL) Accumulate all scalar C{xs} into C{ps}.
|
|
1619
1682
|
'''
|
|
1620
1683
|
n = 0
|
|
@@ -1639,7 +1702,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1639
1702
|
|
|
1640
1703
|
def _ps_mul(self, op, *factors):
|
|
1641
1704
|
'''(INTERNAL) Multiply this instance' C{partials} with
|
|
1642
|
-
each of the B{C{factors}}
|
|
1705
|
+
each of the scalar B{C{factors}} and accumulate.
|
|
1643
1706
|
'''
|
|
1644
1707
|
def _pfs(ps, fs):
|
|
1645
1708
|
if len(ps) < len(fs):
|
|
@@ -1659,11 +1722,32 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1659
1722
|
for p in self._ps:
|
|
1660
1723
|
yield -p
|
|
1661
1724
|
|
|
1662
|
-
def
|
|
1663
|
-
'''(INTERNAL)
|
|
1725
|
+
def _ps_1primed(self, *less):
|
|
1726
|
+
'''(INTERNAL) Yield partials, 1-primed and subtract any C{less} scalars.
|
|
1727
|
+
'''
|
|
1728
|
+
yield _1_0
|
|
1729
|
+
for p in self._ps:
|
|
1730
|
+
yield p
|
|
1731
|
+
for p in less:
|
|
1732
|
+
yield -p
|
|
1733
|
+
yield _N_1_0
|
|
1734
|
+
|
|
1735
|
+
def _raiser(self, r, s, raiser=True, **RESIDUAL):
|
|
1736
|
+
'''(INTERNAL) Does ratio C{r / s} exceed the RESIDUAL threshold?
|
|
1664
1737
|
'''
|
|
1665
|
-
self._ratio =
|
|
1666
|
-
|
|
1738
|
+
self._ratio = r = (r / s) if s else s # == 0.
|
|
1739
|
+
if r and raiser:
|
|
1740
|
+
R = self._RESIDUAL
|
|
1741
|
+
if RESIDUAL:
|
|
1742
|
+
R = _xkwds_get(RESIDUAL, RESIDUAL=R)
|
|
1743
|
+
return fabs(r) > R
|
|
1744
|
+
return False
|
|
1745
|
+
|
|
1746
|
+
def _raiser2sum(self, r, s, **raiser_RESIDUAL):
|
|
1747
|
+
'''(INTERNAL) Does ratio C{r / s} exceed the RESIDUAL threshold
|
|
1748
|
+
I{and} is the residual B{C{r}} significant vs sum B{C{s}}?
|
|
1749
|
+
'''
|
|
1750
|
+
return self._raiser(r, s, **raiser_RESIDUAL) and _2sum(s, r) != (s, r)
|
|
1667
1751
|
|
|
1668
1752
|
@property_RO
|
|
1669
1753
|
def real(self):
|
|
@@ -1697,7 +1781,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1697
1781
|
C{PYGEODESY_FSUM_RESIDUAL} or if omitted, keep the
|
|
1698
1782
|
current setting.
|
|
1699
1783
|
|
|
1700
|
-
@return: The previous C{RESIDUAL} setting (C{float}), default C{0}.
|
|
1784
|
+
@return: The previous C{RESIDUAL} setting (C{float}), default C{0.0}.
|
|
1701
1785
|
|
|
1702
1786
|
@raise ValueError: Negative B{C{threshold}}.
|
|
1703
1787
|
|
|
@@ -1724,12 +1808,27 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1724
1808
|
t = t.replace(_COMMASPACE_R_, _exceeds_R_)
|
|
1725
1809
|
return self._Error(op, other, ResidualError, txt=t)
|
|
1726
1810
|
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1811
|
+
def root(self, root, **raiser):
|
|
1812
|
+
'''Return C{B{self}**(1 / B{root})} as L{Fsum}.
|
|
1813
|
+
|
|
1814
|
+
@arg root: The order (C{scalar} or C{Fsum}), non-zero.
|
|
1815
|
+
@kwarg raiser: Use C{B{raiser}=False} to ignore L{ResidualError}s
|
|
1816
|
+
(C{bool}), see also method L{RESIDUAL}.
|
|
1817
|
+
|
|
1818
|
+
@return: The C{self ** (1 / B{root})} result (L{Fsum}).
|
|
1819
|
+
|
|
1820
|
+
@see: Method L{Fsum.pow}.
|
|
1730
1821
|
'''
|
|
1731
|
-
|
|
1732
|
-
|
|
1822
|
+
x = _1_over(root, **raiser)
|
|
1823
|
+
f = self._copy_2(self.root)
|
|
1824
|
+
return f._fpow(x, f.name, **raiser) # == pow(f, x)
|
|
1825
|
+
|
|
1826
|
+
def _scalar(self, other, op, **txt):
|
|
1827
|
+
'''(INTERNAL) Return scalar C{other}.
|
|
1828
|
+
'''
|
|
1829
|
+
if isscalar(other):
|
|
1830
|
+
return other
|
|
1831
|
+
raise self._TypeError(op, other, **txt) # _invalid_
|
|
1733
1832
|
|
|
1734
1833
|
def signOf(self, res=True):
|
|
1735
1834
|
'''Determine the sign of this instance.
|
|
@@ -1914,8 +2013,8 @@ def fsum_(*xs, **floats):
|
|
|
1914
2013
|
|
|
1915
2014
|
@arg xs: Values to be added (C{scalar} or L{Fsum} instances), all
|
|
1916
2015
|
positional.
|
|
1917
|
-
@kwarg floats: Use C{B{floats}=True} iff I{all} B{C{xs}} are known
|
|
1918
|
-
to be
|
|
2016
|
+
@kwarg floats: Use C{B{floats}=True} iff I{all} B{C{xs}} are I{known
|
|
2017
|
+
to be scalar} (C{bool}).
|
|
1919
2018
|
|
|
1920
2019
|
@return: Precision C{fsum} (C{float}).
|
|
1921
2020
|
|
|
@@ -1926,7 +2025,8 @@ def fsum_(*xs, **floats):
|
|
|
1926
2025
|
|
|
1927
2026
|
|
|
1928
2027
|
def fsumf_(*xs):
|
|
1929
|
-
'''Precision floating point summation L{fsum_}C{(*xs, floats=True)}
|
|
2028
|
+
'''Precision floating point summation, L{fsum_}C{(*B{xs}, floats=True)},
|
|
2029
|
+
but only for C{B{xs}} I{known to be scalar}.
|
|
1930
2030
|
'''
|
|
1931
2031
|
return _fsum(xs) if xs else _0_0
|
|
1932
2032
|
|
|
@@ -1951,8 +2051,8 @@ def fsum1_(*xs, **floats):
|
|
|
1951
2051
|
|
|
1952
2052
|
@arg xs: Values to be added (C{scalar} or L{Fsum} instances), all
|
|
1953
2053
|
positional.
|
|
1954
|
-
@kwarg floats: Use C{B{floats}=True} iff I{all} B{C{xs}} are known
|
|
1955
|
-
to be
|
|
2054
|
+
@kwarg floats: Use C{B{floats}=True} iff I{all} B{C{xs}} are I{known
|
|
2055
|
+
to be scalar} (C{bool}).
|
|
1956
2056
|
|
|
1957
2057
|
@return: Precision C{fsum} (C{float}).
|
|
1958
2058
|
|
|
@@ -1963,7 +2063,8 @@ def fsum1_(*xs, **floats):
|
|
|
1963
2063
|
|
|
1964
2064
|
|
|
1965
2065
|
def fsum1f_(*xs):
|
|
1966
|
-
'''Precision floating point summation, L{fsum1_}C{(*xs, floats=True)}
|
|
2066
|
+
'''Precision floating point summation, L{fsum1_}C{(*B{xs}, floats=True)},
|
|
2067
|
+
but only for C{B{xs}} I{known to be scalar}.
|
|
1967
2068
|
'''
|
|
1968
2069
|
return _fsum(_1primed(xs)) if xs else _0_0
|
|
1969
2070
|
|
|
@@ -1974,23 +2075,14 @@ if __name__ == '__main__':
|
|
|
1974
2075
|
|
|
1975
2076
|
def _test(n):
|
|
1976
2077
|
# copied from Hettinger, see L{Fsum} reference
|
|
1977
|
-
from pygeodesy import printf
|
|
1978
|
-
from random import gauss, random, shuffle
|
|
2078
|
+
from pygeodesy import frandoms, printf
|
|
1979
2079
|
|
|
1980
2080
|
printf(_fsum.__name__, end=_COMMASPACE_)
|
|
1981
2081
|
printf(_psum.__name__, end=_COMMASPACE_)
|
|
1982
2082
|
|
|
1983
2083
|
F = Fsum()
|
|
1984
2084
|
if F.is_math_fsum():
|
|
1985
|
-
|
|
1986
|
-
for _ in range(n):
|
|
1987
|
-
t = list(c)
|
|
1988
|
-
s = 0
|
|
1989
|
-
for _ in range(n * 8):
|
|
1990
|
-
v = gauss(0, random())**7 - s
|
|
1991
|
-
t.append(v)
|
|
1992
|
-
s += v
|
|
1993
|
-
shuffle(t)
|
|
2085
|
+
for t in frandoms(n, seeded=True):
|
|
1994
2086
|
assert float(F.fset_(*t)) == _fsum(t)
|
|
1995
2087
|
printf(_DOT_, end=NN)
|
|
1996
2088
|
printf(NN)
|