pygeodesy 24.4.12__py2.py3-none-any.whl → 24.4.18__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.18.dist-info}/METADATA +2 -2
- {PyGeodesy-24.4.12.dist-info → PyGeodesy-24.4.18.dist-info}/RECORD +20 -20
- pygeodesy/__init__.py +1 -1
- pygeodesy/albers.py +12 -19
- pygeodesy/auxilats/auxLat.py +3 -3
- 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 +64 -65
- pygeodesy/fsums.py +290 -215
- pygeodesy/lazily.py +3 -3
- 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.18.dist-info}/WHEEL +0 -0
- {PyGeodesy-24.4.12.dist-info → PyGeodesy-24.4.18.dist-info}/top_level.txt +0 -0
pygeodesy/fsums.py
CHANGED
|
@@ -27,14 +27,14 @@ 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
32
|
from pygeodesy.errors import _OverflowError, _TypeError, _ValueError, _xError, \
|
|
33
33
|
_xError2, _xkwds_get, _ZeroDivisionError
|
|
34
34
|
from pygeodesy.interns import NN, _arg_, _COMMASPACE_, _DASH_, _DOT_, _EQUAL_, \
|
|
35
35
|
_exceeds_, _from_, _iadd_op_, _LANGLE_, _negative_, \
|
|
36
|
-
_NOTEQUAL_, _not_finite_,
|
|
37
|
-
|
|
36
|
+
_NOTEQUAL_, _not_finite_, _PERCENT_, _PLUS_, _R_, \
|
|
37
|
+
_RANGLE_, _SLASH_, _SPACE_, _STAR_, _UNDER_
|
|
38
38
|
from pygeodesy.lazily import _ALL_LAZY, _getenv, _sys_version_info2
|
|
39
39
|
from pygeodesy.named import _Named, _NamedTuple, _NotImplemented, Fmt, unstr
|
|
40
40
|
from pygeodesy.props import _allPropertiesOf_n, deprecated_property_RO, \
|
|
@@ -45,7 +45,7 @@ from pygeodesy.props import _allPropertiesOf_n, deprecated_property_RO, \
|
|
|
45
45
|
from math import ceil as _ceil, fabs, floor as _floor # PYCHOK used! .ltp
|
|
46
46
|
|
|
47
47
|
__all__ = _ALL_LAZY.fsums
|
|
48
|
-
__version__ = '24.04.
|
|
48
|
+
__version__ = '24.04.18'
|
|
49
49
|
|
|
50
50
|
_add_op_ = _PLUS_ # in .auxilats.auxAngle
|
|
51
51
|
_eq_op_ = _EQUAL_ * 2 # _DEQUAL_
|
|
@@ -72,7 +72,7 @@ _isub_op_ = _sub_op_ + _fset_op_ # in .auxilats.auxAngle, .fsums
|
|
|
72
72
|
|
|
73
73
|
|
|
74
74
|
def _2delta(*ab):
|
|
75
|
-
'''(INTERNAL) Helper for C{Fsum.
|
|
75
|
+
'''(INTERNAL) Helper for C{Fsum._fsum2}.
|
|
76
76
|
'''
|
|
77
77
|
try:
|
|
78
78
|
a, b = _2sum(*ab)
|
|
@@ -121,6 +121,18 @@ def _2floats(xs, origin=0, _X=_X_ps, _x=float):
|
|
|
121
121
|
raise _xError(X, Fmt.INDEX(xs=i), x)
|
|
122
122
|
|
|
123
123
|
|
|
124
|
+
def _Fsumf_(*xs): # floats=True, in .auxLat, ...
|
|
125
|
+
'''(INTERNAL) An C{Fsum} of I{known scalars}.
|
|
126
|
+
'''
|
|
127
|
+
return Fsum()._facc_scalar(xs, up=False)
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def _Fsum1f_(*xs): # floats=True, in .albers, ...
|
|
131
|
+
'''(INTERNAL) An C{Fsum} of I{known scalars}, 1-primed.
|
|
132
|
+
'''
|
|
133
|
+
return Fsum()._facc_scalar(_1primed(xs), up=False)
|
|
134
|
+
|
|
135
|
+
|
|
124
136
|
def _2halfeven(s, r, p):
|
|
125
137
|
'''(INTERNAL) Round half-even.
|
|
126
138
|
'''
|
|
@@ -173,20 +185,20 @@ def _psum(ps): # PYCHOK used!
|
|
|
173
185
|
def _Psum(ps, **name):
|
|
174
186
|
'''(INTERNAL) Return an C{Fsum} from I{ordered} partials C{ps}.
|
|
175
187
|
'''
|
|
176
|
-
|
|
188
|
+
F = Fsum(**name) if name else Fsum()
|
|
177
189
|
if ps:
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
return
|
|
190
|
+
F._ps[:] = ps
|
|
191
|
+
F._n = len(F._ps)
|
|
192
|
+
return F
|
|
181
193
|
|
|
182
194
|
|
|
183
195
|
def _Psum_1(p=_1_0, **name):
|
|
184
196
|
'''(INTERNAL) Return an C{Fsum} from a single partial C{p}.
|
|
185
197
|
'''
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
return
|
|
198
|
+
F = Fsum(**name) if name else Fsum()
|
|
199
|
+
F._ps[:] = p,
|
|
200
|
+
F._n = 1 # len(F._ps)
|
|
201
|
+
return F
|
|
190
202
|
|
|
191
203
|
|
|
192
204
|
def _2scalar(other, _raiser=None, **mod):
|
|
@@ -233,13 +245,13 @@ def _2sum(a, b): # by .testFmath
|
|
|
233
245
|
'''(INTERNAL) Return C{a + b} as 2-tuple (sum, residual).
|
|
234
246
|
'''
|
|
235
247
|
s = a + b
|
|
236
|
-
if
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
248
|
+
if _isfinite(s):
|
|
249
|
+
if fabs(a) < fabs(b):
|
|
250
|
+
b, a = a, b
|
|
251
|
+
return s, (b - (s - a))
|
|
252
|
+
u = unstr(_2sum, a, b)
|
|
253
|
+
t = Fmt.PARENSPACED(_not_finite_, s)
|
|
254
|
+
raise _OverflowError(u, txt=t)
|
|
243
255
|
|
|
244
256
|
|
|
245
257
|
class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
@@ -266,7 +278,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
266
278
|
_n = 0
|
|
267
279
|
# _ps = [] # partial sums
|
|
268
280
|
# _ps_max = 0 # max(Fsum._ps_max, len(Fsum._ps))
|
|
269
|
-
_ratio = None
|
|
281
|
+
_ratio = None # see method _raiser
|
|
270
282
|
_recursive = bool(_getenv('PYGEODESY_FSUM_RECURSIVE', NN))
|
|
271
283
|
_RESIDUAL = max(float(_getenv('PYGEODESY_FSUM_RESIDUAL', _0_0)), _0_0)
|
|
272
284
|
|
|
@@ -289,12 +301,12 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
289
301
|
self.RESIDUAL(r) # ... ResidualError
|
|
290
302
|
self._ps = [] # [_0_0], see L{Fsum._fprs}
|
|
291
303
|
if xs:
|
|
292
|
-
self.
|
|
304
|
+
self._facc(xs, origin=1, up=False)
|
|
293
305
|
|
|
294
306
|
def __abs__(self):
|
|
295
307
|
'''Return this instance' absolute value as an L{Fsum}.
|
|
296
308
|
'''
|
|
297
|
-
s = _fsum(self.
|
|
309
|
+
s = _fsum(self._ps_1primed()) # == self._cmp_0(0, ...)
|
|
298
310
|
return (-self) if s < 0 else self._copy_2(self.__abs__)
|
|
299
311
|
|
|
300
312
|
def __add__(self, other):
|
|
@@ -478,13 +490,15 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
478
490
|
# Luciano Ramalho, "Fluent Python", O'Reilly, 2nd Ed, 2022 p. 567
|
|
479
491
|
return _NotImplemented(self)
|
|
480
492
|
|
|
481
|
-
def __ipow__(self, other, *mod): # PYCHOK 2 vs 3 args
|
|
493
|
+
def __ipow__(self, other, *mod, **raiser): # PYCHOK 2 vs 3 args
|
|
482
494
|
'''Apply C{B{self} **= B{other}} to this instance.
|
|
483
495
|
|
|
484
496
|
@arg other: The exponent (L{Fsum} or C{scalar}).
|
|
485
497
|
@arg mod: Optional modulus (C{int} or C{None}) for the
|
|
486
498
|
3-argument C{pow(B{self}, B{other}, B{mod})}
|
|
487
499
|
version.
|
|
500
|
+
@kwarg raiser: Use C{B{raiser}=False} to ignore L{ResidualError}s
|
|
501
|
+
(C{bool}), see also method L{RESIDUAL}.
|
|
488
502
|
|
|
489
503
|
@return: This instance, updated (L{Fsum}).
|
|
490
504
|
|
|
@@ -513,7 +527,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
513
527
|
@see: CPython function U{float_pow<https://GitHub.com/
|
|
514
528
|
python/cpython/blob/main/Objects/floatobject.c>}.
|
|
515
529
|
'''
|
|
516
|
-
return self._fpow(other, _pow_op_ + _fset_op_, *mod)
|
|
530
|
+
return self._fpow(other, _pow_op_ + _fset_op_, *mod, **raiser)
|
|
517
531
|
|
|
518
532
|
def __isub__(self, other):
|
|
519
533
|
'''Apply C{B{self} -= B{other}} to this instance.
|
|
@@ -533,10 +547,12 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
533
547
|
'''
|
|
534
548
|
return iter(self.partials)
|
|
535
549
|
|
|
536
|
-
def __itruediv__(self, other):
|
|
550
|
+
def __itruediv__(self, other, **raiser):
|
|
537
551
|
'''Apply C{B{self} /= B{other}} to this instance.
|
|
538
552
|
|
|
539
553
|
@arg other: An L{Fsum} or C{scalar} divisor.
|
|
554
|
+
@kwarg raiser: Use C{B{raiser}=False} to ignore L{ResidualError}s
|
|
555
|
+
(C{bool}), see also method L{RESIDUAL}.
|
|
540
556
|
|
|
541
557
|
@return: This instance, updated (L{Fsum}).
|
|
542
558
|
|
|
@@ -553,7 +569,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
553
569
|
|
|
554
570
|
@see: Method L{Fsum.__ifloordiv__}.
|
|
555
571
|
'''
|
|
556
|
-
return self._ftruediv(other, _truediv_op_ + _fset_op_)
|
|
572
|
+
return self._ftruediv(other, _truediv_op_ + _fset_op_, **raiser)
|
|
557
573
|
|
|
558
574
|
def __le__(self, other):
|
|
559
575
|
'''Compare this with an other instance or C{scalar}.
|
|
@@ -689,13 +705,13 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
689
705
|
f = self._copy_2r(other, self.__rsub__)
|
|
690
706
|
return f._fsub(self, _sub_op_)
|
|
691
707
|
|
|
692
|
-
def __rtruediv__(self, other):
|
|
708
|
+
def __rtruediv__(self, other, **raiser):
|
|
693
709
|
'''Return C{B{other} / B{self}} as an L{Fsum}.
|
|
694
710
|
|
|
695
711
|
@see: Method L{Fsum.__itruediv__}.
|
|
696
712
|
'''
|
|
697
713
|
f = self._copy_2r(other, self.__rtruediv__)
|
|
698
|
-
return f._ftruediv(self, _truediv_op_)
|
|
714
|
+
return f._ftruediv(self, _truediv_op_, **raiser)
|
|
699
715
|
|
|
700
716
|
def __str__(self):
|
|
701
717
|
'''Return the default C{str(self)}.
|
|
@@ -714,17 +730,19 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
714
730
|
f = self._copy_2(self.__sub__)
|
|
715
731
|
return f._fsub(other, _sub_op_)
|
|
716
732
|
|
|
717
|
-
def __truediv__(self, other):
|
|
733
|
+
def __truediv__(self, other, **raiser):
|
|
718
734
|
'''Return C{B{self} / B{other}} as an L{Fsum}.
|
|
719
735
|
|
|
720
736
|
@arg other: An L{Fsum} or C{scalar} divisor.
|
|
737
|
+
@kwarg raiser: Use C{B{raiser}=False} to ignore L{ResidualError}s
|
|
738
|
+
(C{bool}), see also method L{RESIDUAL}.
|
|
721
739
|
|
|
722
740
|
@return: The quotient (L{Fsum}).
|
|
723
741
|
|
|
724
742
|
@see: Method L{Fsum.__itruediv__}.
|
|
725
743
|
'''
|
|
726
744
|
f = self._copy_2(self.__truediv__)
|
|
727
|
-
return f._ftruediv(other, _truediv_op_)
|
|
745
|
+
return f._ftruediv(other, _truediv_op_, **raiser)
|
|
728
746
|
|
|
729
747
|
__trunc__ = __int__
|
|
730
748
|
|
|
@@ -773,15 +791,12 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
773
791
|
'''(INTERNAL) Return C{scalar(self - B{other})} for 0-comparison.
|
|
774
792
|
'''
|
|
775
793
|
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)
|
|
794
|
+
s = _fsum(self._ps_1primed(*other._ps))
|
|
795
|
+
elif self._scalar(other, op):
|
|
796
|
+
s = _fsum(self._ps_1primed(other))
|
|
783
797
|
else:
|
|
784
|
-
|
|
798
|
+
s, r = self._fprs2
|
|
799
|
+
s = _signOf(s, -r)
|
|
785
800
|
return s
|
|
786
801
|
|
|
787
802
|
def copy(self, deep=False, name=NN):
|
|
@@ -790,8 +805,10 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
790
805
|
@return: The copy (L{Fsum}).
|
|
791
806
|
'''
|
|
792
807
|
f = _Named.copy(self, deep=deep, name=name)
|
|
793
|
-
f._ps
|
|
794
|
-
|
|
808
|
+
if f._ps is self._ps:
|
|
809
|
+
f._ps = list(self._ps) # separate list
|
|
810
|
+
if not deep:
|
|
811
|
+
f._n = 1
|
|
795
812
|
return f
|
|
796
813
|
|
|
797
814
|
def _copy_2(self, which, name=NN):
|
|
@@ -817,11 +834,13 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
817
834
|
# if R is not Fsum._RESIDUAL:
|
|
818
835
|
# self._RESIDUAL = R
|
|
819
836
|
|
|
820
|
-
def divmod(self, other):
|
|
837
|
+
def divmod(self, other, **raiser):
|
|
821
838
|
'''Return C{divmod(B{self}, B{other})} as 2-tuple C{(quotient,
|
|
822
839
|
remainder)}.
|
|
823
840
|
|
|
824
841
|
@arg other: An L{Fsum} or C{scalar} divisor.
|
|
842
|
+
@kwarg raiser: Use C{B{raiser}=False} to ignore L{ResidualError}s
|
|
843
|
+
(C{bool}), see also method L{RESIDUAL}.
|
|
825
844
|
|
|
826
845
|
@return: A L{DivMod2Tuple}C{(div, mod)}, with quotient C{div}
|
|
827
846
|
an C{int} in Python 3+ or C{float} in Python 2- and
|
|
@@ -830,7 +849,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
830
849
|
@see: Method L{Fsum.__itruediv__}.
|
|
831
850
|
'''
|
|
832
851
|
f = self._copy_2(self.divmod)
|
|
833
|
-
return f._fdivmod2(other, _divmod_op_)
|
|
852
|
+
return f._fdivmod2(other, _divmod_op_, **raiser)
|
|
834
853
|
|
|
835
854
|
def _Error(self, op, other, Error, **txt_cause):
|
|
836
855
|
'''(INTERNAL) Format an B{C{Error}} for C{{self} B{op} B{other}}.
|
|
@@ -852,66 +871,91 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
852
871
|
n = unstr(self.named3, *xs[:3], _ELLIPSIS=len(xs) > 3, **kwds)
|
|
853
872
|
return E(n, txt=t, cause=X)
|
|
854
873
|
|
|
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.
|
|
874
|
+
def _facc(self, xs, up=True, **origin_X_x):
|
|
875
|
+
'''(INTERNAL) Accumulate more C{scalars} or L{Fsum}s.
|
|
863
876
|
'''
|
|
864
877
|
if xs:
|
|
865
|
-
|
|
878
|
+
_x = _2floats(xs, **origin_X_x) # PYCHOK yield
|
|
879
|
+
ps = self._ps
|
|
880
|
+
ps[:] = self._ps_acc(list(ps), _x, up=up)
|
|
866
881
|
return self
|
|
867
882
|
|
|
868
|
-
def
|
|
869
|
-
'''(INTERNAL) Accumulate more C{scalars} or L{Fsum}s
|
|
883
|
+
def _facc_1(self, xs, **up):
|
|
884
|
+
'''(INTERNAL) Accumulate 0, 1 or more C{scalars} or L{Fsum}s,
|
|
885
|
+
all positional C{xs} in the caller of this method.
|
|
870
886
|
'''
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
887
|
+
# assert islistuple(xs)
|
|
888
|
+
return self._fadd(xs[0], _add_op_) if len(xs) == 1 else \
|
|
889
|
+
self._facc(xs, origin=1, **up)
|
|
874
890
|
|
|
875
|
-
def
|
|
891
|
+
def _facc_neg(self, xs, up=True, **origin):
|
|
876
892
|
'''(INTERNAL) Accumulate more C{scalars} or L{Fsum}s, negated.
|
|
877
893
|
'''
|
|
878
|
-
|
|
879
|
-
|
|
894
|
+
if xs:
|
|
895
|
+
def _neg(x):
|
|
896
|
+
return -x
|
|
880
897
|
|
|
881
|
-
|
|
882
|
-
|
|
898
|
+
_x = _2floats(xs, **origin) # PYCHOK yield
|
|
899
|
+
ps = self._ps
|
|
900
|
+
ps[:] = self._ps_acc(list(ps), map(_neg, _x), up=up)
|
|
883
901
|
return self
|
|
884
902
|
|
|
885
|
-
def _facc_power(self, power, xs, which): # in .fmath
|
|
903
|
+
def _facc_power(self, power, xs, which, **raiser): # in .fmath
|
|
886
904
|
'''(INTERNAL) Add each C{xs} as C{float(x**power)}.
|
|
887
905
|
'''
|
|
888
|
-
p
|
|
889
|
-
|
|
890
|
-
if p
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
906
|
+
def _Pow4(p):
|
|
907
|
+
r = 0
|
|
908
|
+
if isinstance(p, Fsum):
|
|
909
|
+
s, r = p._fprs2
|
|
910
|
+
if r:
|
|
911
|
+
return _Pow4(s)
|
|
912
|
+
m = Fsum._pow
|
|
913
|
+
elif isint(p, both=True) and int(p) >= 0:
|
|
914
|
+
p = s = int(p)
|
|
915
|
+
m = Fsum._pow_int
|
|
916
|
+
else:
|
|
917
|
+
p = s = _2float(power=p)
|
|
918
|
+
m = Fsum._pow_scalar
|
|
919
|
+
return m, p, s, r
|
|
897
920
|
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
_Fs
|
|
921
|
+
_Pow, p, s, r = _Pow4(power)
|
|
922
|
+
if p: # and xs:
|
|
923
|
+
_pow = Fsum._pow_2_3
|
|
924
|
+
_Fs = Fsum
|
|
925
|
+
_Ps = _Psum_1()._fset_ps_
|
|
926
|
+
op = which.__name__
|
|
902
927
|
|
|
903
928
|
def _X(X):
|
|
904
|
-
f = _Pow(X, p, power, op)
|
|
929
|
+
f = _Pow(X, p, power, op, **raiser)
|
|
905
930
|
return f._ps if isinstance(f, _Fs) else (f,)
|
|
906
931
|
|
|
907
932
|
def _x(x):
|
|
908
|
-
|
|
933
|
+
x = float(x)
|
|
934
|
+
X = _Ps(x)
|
|
935
|
+
f = _pow(X, x, s, power, op, **raiser)
|
|
936
|
+
if r:
|
|
937
|
+
f *= _pow(X, x, r, power, op, **raiser)
|
|
938
|
+
return f
|
|
909
939
|
|
|
910
|
-
f = self.
|
|
940
|
+
f = self._facc(xs, origin=1, _X=_X, _x=_x)
|
|
911
941
|
else:
|
|
912
|
-
f = self.
|
|
942
|
+
f = self._facc_scalar_(float(len(xs))) # x**0 == 1
|
|
913
943
|
return f
|
|
914
944
|
|
|
945
|
+
def _facc_scalar(self, xs, **up):
|
|
946
|
+
'''(INTERNAL) Accumulate all C{xs}, known to be scalar.
|
|
947
|
+
'''
|
|
948
|
+
if xs:
|
|
949
|
+
self._ps_acc(self._ps, xs, **up)
|
|
950
|
+
return self
|
|
951
|
+
|
|
952
|
+
def _facc_scalar_(self, *xs, **up):
|
|
953
|
+
'''(INTERNAL) Accumulate all positional C{xs}, known to be scalar.
|
|
954
|
+
'''
|
|
955
|
+
if xs:
|
|
956
|
+
self._ps_acc(self._ps, xs, **up)
|
|
957
|
+
return self
|
|
958
|
+
|
|
915
959
|
# def _facc_up(self, up=True):
|
|
916
960
|
# '''(INTERNAL) Update the C{partials}, by removing
|
|
917
961
|
# and re-accumulating the final C{partial}.
|
|
@@ -920,7 +964,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
920
964
|
# p = self._ps.pop()
|
|
921
965
|
# if p:
|
|
922
966
|
# n = self._n
|
|
923
|
-
# self.
|
|
967
|
+
# self._facc_scalar_(p, up=False)
|
|
924
968
|
# self._n = n
|
|
925
969
|
# break
|
|
926
970
|
# return self._update() if up else self # ._fpsqz()
|
|
@@ -942,11 +986,11 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
942
986
|
@raise ValueError: Invalid or non-finite B{C{xs}} value.
|
|
943
987
|
'''
|
|
944
988
|
if isinstance(xs, Fsum):
|
|
945
|
-
self.
|
|
989
|
+
self._facc_scalar(xs._ps) # tuple
|
|
946
990
|
elif isscalar(xs): # for backward compatibility
|
|
947
|
-
self.
|
|
948
|
-
elif xs:
|
|
949
|
-
self.
|
|
991
|
+
self._facc_scalar_(_2float(x=xs)) # PYCHOK no cover
|
|
992
|
+
elif xs: # assert isiterable(xs)
|
|
993
|
+
self._facc(xs)
|
|
950
994
|
return self
|
|
951
995
|
|
|
952
996
|
def fadd_(self, *xs):
|
|
@@ -965,30 +1009,29 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
965
1009
|
|
|
966
1010
|
@raise ValueError: Invalid or non-finite B{C{xs}} value.
|
|
967
1011
|
'''
|
|
968
|
-
return self.
|
|
1012
|
+
return self._facc_1(xs)
|
|
969
1013
|
|
|
970
1014
|
def _fadd(self, other, op, **up): # in .fmath.Fhorner
|
|
971
1015
|
'''(INTERNAL) Apply C{B{self} += B{other}}.
|
|
972
1016
|
'''
|
|
973
1017
|
if isinstance(other, Fsum):
|
|
974
|
-
self.
|
|
975
|
-
elif
|
|
976
|
-
|
|
977
|
-
elif other:
|
|
978
|
-
self._facc_(other, **up)
|
|
1018
|
+
self._facc_scalar(other._ps, **up) # tuple
|
|
1019
|
+
elif self._scalar(other, op):
|
|
1020
|
+
self._facc_scalar_(other, **up)
|
|
979
1021
|
return self
|
|
980
1022
|
|
|
981
1023
|
fcopy = copy # for backward compatibility
|
|
982
1024
|
fdiv = __itruediv__ # for backward compatibility
|
|
983
1025
|
fdivmod = __divmod__ # for backward compatibility
|
|
984
1026
|
|
|
985
|
-
def _fdivmod2(self, other, op):
|
|
1027
|
+
def _fdivmod2(self, other, op, **raiser):
|
|
986
1028
|
'''(INTERNAL) Apply C{B{self} %= B{other}} and return a L{DivMod2Tuple}.
|
|
987
1029
|
'''
|
|
988
1030
|
# result mostly follows CPython function U{float_divmod
|
|
989
1031
|
# <https://GitHub.com/python/cpython/blob/main/Objects/floatobject.c>},
|
|
990
1032
|
# but at least divmod(-3, 2) equals Cpython's result (-2, 1).
|
|
991
|
-
|
|
1033
|
+
f = self._copy_2(self._fdivmod2)
|
|
1034
|
+
q = f._ftruediv(other, op, **raiser).floor
|
|
992
1035
|
if q: # == float // other == floor(float / other)
|
|
993
1036
|
self -= other * q
|
|
994
1037
|
|
|
@@ -1012,8 +1055,8 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1012
1055
|
def fint(self, raiser=True, **name):
|
|
1013
1056
|
'''Return this instance' current running sum as C{integer}.
|
|
1014
1057
|
|
|
1015
|
-
@kwarg raiser:
|
|
1016
|
-
|
|
1058
|
+
@kwarg raiser: Use C{B{raiser}=False} to ignore L{ResidualError}s
|
|
1059
|
+
(C{bool}), see also method L{RESIDUAL}.
|
|
1017
1060
|
@kwarg name: Optional name (C{str}), overriding C{"fint"}.
|
|
1018
1061
|
|
|
1019
1062
|
@return: The C{integer} (L{Fsum}).
|
|
@@ -1047,7 +1090,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1047
1090
|
'''
|
|
1048
1091
|
s, r = self._fprs2
|
|
1049
1092
|
i = int(s)
|
|
1050
|
-
r = _fsum(self.
|
|
1093
|
+
r = _fsum(self._ps_1primed(i)) if r else float(s - i)
|
|
1051
1094
|
return i, (r or INT0) # Fsum2Tuple?
|
|
1052
1095
|
|
|
1053
1096
|
@deprecated_property_RO
|
|
@@ -1073,10 +1116,10 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1073
1116
|
|
|
1074
1117
|
# floordiv = __floordiv__ # for naming consistency
|
|
1075
1118
|
|
|
1076
|
-
def _floordiv(self, other, op): # rather _ffloordiv?
|
|
1119
|
+
def _floordiv(self, other, op, **raiser): # rather _ffloordiv?
|
|
1077
1120
|
'''Apply C{B{self} //= B{other}}.
|
|
1078
1121
|
'''
|
|
1079
|
-
q = self._ftruediv(other, op) # == self
|
|
1122
|
+
q = self._ftruediv(other, op, **raiser) # == self
|
|
1080
1123
|
return self._fset(q.floor) # floor(q)
|
|
1081
1124
|
|
|
1082
1125
|
fmul = __imul__ # for backward compatibility
|
|
@@ -1091,41 +1134,42 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1091
1134
|
f = other._mul_scalar(self._ps[0], op)
|
|
1092
1135
|
else: # len(other._ps) == len(self._ps) == 1
|
|
1093
1136
|
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
1137
|
else:
|
|
1097
|
-
|
|
1138
|
+
s = self._scalar(other, op)
|
|
1139
|
+
f = self._mul_scalar(s, op)
|
|
1098
1140
|
return self._fset(f) # n=len(self) + 1
|
|
1099
1141
|
|
|
1100
|
-
def fover(self, over):
|
|
1142
|
+
def fover(self, over, **raiser):
|
|
1101
1143
|
'''Apply C{B{self} /= B{over}} and summate.
|
|
1102
1144
|
|
|
1103
1145
|
@arg over: An L{Fsum} or C{scalar} denominator.
|
|
1146
|
+
@kwarg raiser: Use C{B{raiser}=False} to ignore L{ResidualError}s
|
|
1147
|
+
(C{bool}), see also method L{RESIDUAL}.
|
|
1104
1148
|
|
|
1105
1149
|
@return: Precision running sum (C{float}).
|
|
1106
1150
|
|
|
1107
1151
|
@see: Methods L{Fsum.fsum} and L{Fsum.__itruediv__}.
|
|
1108
1152
|
'''
|
|
1109
|
-
return float(self.fdiv(over)._fprs)
|
|
1153
|
+
return float(self.fdiv(over, **raiser)._fprs)
|
|
1110
1154
|
|
|
1111
1155
|
fpow = __ipow__ # for backward compatibility
|
|
1112
1156
|
|
|
1113
|
-
def _fpow(self, other, op, *mod):
|
|
1157
|
+
def _fpow(self, other, op, *mod, **raiser):
|
|
1114
1158
|
'''Apply C{B{self} **= B{other}}, optional B{C{mod}} or C{None}.
|
|
1115
1159
|
'''
|
|
1116
1160
|
if mod:
|
|
1117
1161
|
if mod[0] is not None: # == 3-arg C{pow}
|
|
1118
|
-
f = self._pow_2_3(self, other, other, op, *mod)
|
|
1162
|
+
f = self._pow_2_3(self, other, other, op, *mod, **raiser)
|
|
1119
1163
|
elif self.is_integer():
|
|
1120
1164
|
# return an exact C{int} for C{int}**C{int}
|
|
1121
1165
|
i, _ = self._fint2 # assert _ == 0
|
|
1122
1166
|
x = _2scalar(other) # C{int}, C{float} or other
|
|
1123
|
-
f = self._pow_2_3(i, x, other, op) if isscalar(x) else \
|
|
1124
|
-
_Psum_1(i).
|
|
1167
|
+
f = self._pow_2_3(i, x, other, op, **raiser) if isscalar(x) else \
|
|
1168
|
+
_Psum_1(i)._pow( x, other, op, **raiser) # x is Fsum
|
|
1125
1169
|
else: # mod[0] is None, power(self, other)
|
|
1126
|
-
f = self.
|
|
1127
|
-
else: # pow(self, other)
|
|
1128
|
-
f = self.
|
|
1170
|
+
f = self._pow(other, other, op, **raiser)
|
|
1171
|
+
else: # pow(self, other)
|
|
1172
|
+
f = self._pow(other, other, op, **raiser)
|
|
1129
1173
|
return self._fset(f, asis=isint(f)) # n=max(len(self), 1)
|
|
1130
1174
|
|
|
1131
1175
|
@Property_RO
|
|
@@ -1149,7 +1193,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1149
1193
|
s = _psum(ps)
|
|
1150
1194
|
n = len(ps) - 2
|
|
1151
1195
|
if n > 0:
|
|
1152
|
-
r = _fsum(self.
|
|
1196
|
+
r = _fsum(self._ps_1primed(s)) or INT0
|
|
1153
1197
|
return Fsum2Tuple(s, r)
|
|
1154
1198
|
if n == 0: # len(ps) == 2
|
|
1155
1199
|
ps[:] = _2ps(*_2sum(*ps))
|
|
@@ -1187,7 +1231,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1187
1231
|
'''(INTERNAL) Overwrite this instance with an other or a C{scalar}.
|
|
1188
1232
|
'''
|
|
1189
1233
|
if other is self:
|
|
1190
|
-
pass # from ._fmul, ._ftruediv and .
|
|
1234
|
+
pass # from ._fmul, ._ftruediv and ._pow_0_1
|
|
1191
1235
|
elif isinstance(other, Fsum):
|
|
1192
1236
|
self._ps[:] = other._ps
|
|
1193
1237
|
self._n = n or other._n
|
|
@@ -1206,7 +1250,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1206
1250
|
# Property's _fset zaps the value just set by the @setter
|
|
1207
1251
|
self.__dict__.update(_fint2=t, _fprs=s, _fprs2=Fsum2Tuple(s, INT0))
|
|
1208
1252
|
else: # PYCHOK no cover
|
|
1209
|
-
raise self._TypeError(_fset_op_, other) #
|
|
1253
|
+
raise self._TypeError(_fset_op_, other) # AssertionError
|
|
1210
1254
|
return self
|
|
1211
1255
|
|
|
1212
1256
|
def _fset_ps(self, other, n=0): # in .fmath
|
|
@@ -1220,6 +1264,13 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1220
1264
|
self._n = n or 1
|
|
1221
1265
|
return self
|
|
1222
1266
|
|
|
1267
|
+
def _fset_ps_(self, *xs):
|
|
1268
|
+
'''(INTERNAL) Set partials to all known scalar C{xs}.
|
|
1269
|
+
'''
|
|
1270
|
+
self._ps[:] = xs
|
|
1271
|
+
self.n = len(xs)
|
|
1272
|
+
return self
|
|
1273
|
+
|
|
1223
1274
|
def fsub(self, xs=()):
|
|
1224
1275
|
'''Subtract an iterable of C{scalar} or L{Fsum} instances from
|
|
1225
1276
|
this instance.
|
|
@@ -1231,7 +1282,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1231
1282
|
|
|
1232
1283
|
@see: Method L{Fsum.fadd}.
|
|
1233
1284
|
'''
|
|
1234
|
-
return self.
|
|
1285
|
+
return self._facc_neg(xs)
|
|
1235
1286
|
|
|
1236
1287
|
def fsub_(self, *xs):
|
|
1237
1288
|
'''Subtract all positional C{scalar} or L{Fsum} instances from
|
|
@@ -1244,7 +1295,8 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1244
1295
|
|
|
1245
1296
|
@see: Method L{Fsum.fadd}.
|
|
1246
1297
|
'''
|
|
1247
|
-
return self.
|
|
1298
|
+
return self._fsub(xs[0], _sub_op_) if len(xs) == 1 else \
|
|
1299
|
+
self._facc_neg(xs, origin=1)
|
|
1248
1300
|
|
|
1249
1301
|
def _fsub(self, other, op):
|
|
1250
1302
|
'''(INTERNAL) Apply C{B{self} -= B{other}}.
|
|
@@ -1253,11 +1305,9 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1253
1305
|
if other is self: # or other._fprs2 == self._fprs2:
|
|
1254
1306
|
self._fset(_0_0) # n=len(self) * 2, self -= self
|
|
1255
1307
|
elif other._ps:
|
|
1256
|
-
self.
|
|
1257
|
-
elif
|
|
1258
|
-
|
|
1259
|
-
elif self._finite(other, op):
|
|
1260
|
-
self._facc_(-other)
|
|
1308
|
+
self._facc_scalar(other._ps_neg)
|
|
1309
|
+
elif self._scalar(other, op):
|
|
1310
|
+
self._facc_scalar_(-self._finite(other, op))
|
|
1261
1311
|
return self
|
|
1262
1312
|
|
|
1263
1313
|
def fsum(self, xs=()):
|
|
@@ -1272,8 +1322,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1272
1322
|
|
|
1273
1323
|
@note: Accumulation can continue after summation.
|
|
1274
1324
|
'''
|
|
1275
|
-
|
|
1276
|
-
return f._fprs
|
|
1325
|
+
return self._facc(xs)._fprs
|
|
1277
1326
|
|
|
1278
1327
|
def fsum_(self, *xs):
|
|
1279
1328
|
'''Add all positional C{scalar} or L{Fsum} instances and summate.
|
|
@@ -1285,15 +1334,14 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1285
1334
|
|
|
1286
1335
|
@see: Methods L{Fsum.fsum}, L{Fsum.Fsum_} and L{Fsum.fsumf_}.
|
|
1287
1336
|
'''
|
|
1288
|
-
|
|
1289
|
-
return f._fprs
|
|
1337
|
+
return self._facc_1(xs)._fprs
|
|
1290
1338
|
|
|
1291
1339
|
def Fsum_(self, *xs):
|
|
1292
1340
|
'''Like method L{Fsum.fsum_} but returning an L{Fsum}.
|
|
1293
1341
|
|
|
1294
1342
|
@return: Current, precision running sum (L{Fsum}).
|
|
1295
1343
|
'''
|
|
1296
|
-
return self.
|
|
1344
|
+
return self._facc_1(xs)._copy_2(self.Fsum_)
|
|
1297
1345
|
|
|
1298
1346
|
def fsum2(self, xs=(), name=NN):
|
|
1299
1347
|
'''Add more C{scalar} or L{Fsum} instances and return the
|
|
@@ -1311,11 +1359,8 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1311
1359
|
|
|
1312
1360
|
@see: Methods L{Fsum.fint2}, L{Fsum.fsum} and L{Fsum.fsum2_}
|
|
1313
1361
|
'''
|
|
1314
|
-
|
|
1315
|
-
t
|
|
1316
|
-
if name:
|
|
1317
|
-
t = t.dup(name=name)
|
|
1318
|
-
return t
|
|
1362
|
+
t = self._facc(xs)._fprs2
|
|
1363
|
+
return t.dup(name=name) if name else t
|
|
1319
1364
|
|
|
1320
1365
|
def fsum2_(self, *xs):
|
|
1321
1366
|
'''Add any positional C{scalar} or L{Fsum} instances and return
|
|
@@ -1330,62 +1375,58 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1330
1375
|
|
|
1331
1376
|
@see: Methods L{Fsum.fsum_} and L{Fsum.fsum}.
|
|
1332
1377
|
'''
|
|
1333
|
-
return self.
|
|
1378
|
+
return self._fsum2(xs, self._facc_1)
|
|
1379
|
+
|
|
1380
|
+
def _fsum2(self, xs, _f, **origin):
|
|
1381
|
+
'''(INTERNAL) Helper for L{Fsum.fsum2_} and L{Fsum.fsum2f_}.
|
|
1382
|
+
'''
|
|
1383
|
+
p, q = self._fprs2
|
|
1384
|
+
if xs:
|
|
1385
|
+
s, r = _f(xs, **origin)._fprs2
|
|
1386
|
+
return s, _2delta(s - p, r - q) # _fsum(_1primed((s, -p, r, -q))
|
|
1387
|
+
else:
|
|
1388
|
+
return p, _0_0
|
|
1334
1389
|
|
|
1335
1390
|
def fsumf_(self, *xs):
|
|
1336
|
-
'''Like method L{Fsum.fsum_} but only for
|
|
1391
|
+
'''Like method L{Fsum.fsum_} but only for C{B{xs}}, I{known to be scalar}.
|
|
1337
1392
|
'''
|
|
1338
|
-
|
|
1339
|
-
return f._fprs
|
|
1393
|
+
return self._facc_scalar(xs)._fprs
|
|
1340
1394
|
|
|
1341
1395
|
def Fsumf_(self, *xs):
|
|
1342
|
-
'''Like method L{Fsum.Fsum_} but only for
|
|
1396
|
+
'''Like method L{Fsum.Fsum_} but only for C{B{xs}}, I{known to be scalar}.
|
|
1343
1397
|
'''
|
|
1344
|
-
return self.
|
|
1398
|
+
return self._facc_scalar(xs)._copy_2(self.Fsumf_)
|
|
1345
1399
|
|
|
1346
1400
|
def fsum2f_(self, *xs):
|
|
1347
|
-
'''Like method L{Fsum.fsum2_} but only for
|
|
1401
|
+
'''Like method L{Fsum.fsum2_} but only for C{B{xs}}, I{known to be scalar}.
|
|
1348
1402
|
'''
|
|
1349
|
-
return self.
|
|
1350
|
-
|
|
1351
|
-
def _fsum2f_any(self, xs, _facc, **origin):
|
|
1352
|
-
'''(INTERNAL) Helper for L{Fsum.fsum2_} and L{Fsum.fsum2f_}.
|
|
1353
|
-
'''
|
|
1354
|
-
p, q = self._fprs2
|
|
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
|
|
1403
|
+
return self._fsum2(xs, self._facc_scalar, origin=1)
|
|
1360
1404
|
|
|
1361
1405
|
# ftruediv = __itruediv__ # for naming consistency?
|
|
1362
1406
|
|
|
1363
|
-
def _ftruediv(self, other, op):
|
|
1407
|
+
def _ftruediv(self, other, op, **raiser):
|
|
1364
1408
|
'''(INTERNAL) Apply C{B{self} /= B{other}}.
|
|
1365
1409
|
'''
|
|
1366
1410
|
n = _1_0
|
|
1367
1411
|
if isinstance(other, Fsum):
|
|
1368
1412
|
if other is self or other == self:
|
|
1369
|
-
return self._fset(
|
|
1413
|
+
return self._fset(n) # n=len(self)
|
|
1370
1414
|
d, r = other._fprs2
|
|
1371
1415
|
if r:
|
|
1372
1416
|
if d:
|
|
1373
|
-
if self._raiser(r, d):
|
|
1417
|
+
if self._raiser(r, d, **raiser):
|
|
1374
1418
|
raise self._ResidualError(op, other, r)
|
|
1375
1419
|
d, n = other.as_integer_ratio()
|
|
1376
1420
|
else: # PYCHOK no cover
|
|
1377
1421
|
d = r
|
|
1378
|
-
|
|
1379
|
-
d = other
|
|
1380
|
-
else: # PYCHOK no cover
|
|
1381
|
-
raise self._TypeError(op, other) # txt=_invalid_
|
|
1422
|
+
else:
|
|
1423
|
+
d = self._scalar(other, op)
|
|
1382
1424
|
try:
|
|
1383
|
-
s =
|
|
1384
|
-
d if isnan(d) else self._finite(n / d))
|
|
1425
|
+
s = n / d
|
|
1385
1426
|
except Exception as X:
|
|
1386
1427
|
raise self._ErrorX(X, op, other)
|
|
1387
|
-
f = self._mul_scalar(s, _mul_op_) # handles 0,
|
|
1388
|
-
return self._fset(f
|
|
1428
|
+
f = self._mul_scalar(s, _mul_op_) # handles 0, INF, NAN
|
|
1429
|
+
return self._fset(f) # asis=False
|
|
1389
1430
|
|
|
1390
1431
|
@property_RO
|
|
1391
1432
|
def imag(self):
|
|
@@ -1399,7 +1440,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1399
1440
|
'''Return this instance' current running sum as C{int} or C{float}.
|
|
1400
1441
|
|
|
1401
1442
|
@kwarg raiser: If C{True} throw a L{ResidualError} if the
|
|
1402
|
-
residual is non-zero.
|
|
1443
|
+
residual is non-zero (C{bool}).
|
|
1403
1444
|
|
|
1404
1445
|
@return: This C{integer} sum if this instance C{is_integer},
|
|
1405
1446
|
otherwise return the C{float} sum if the residual
|
|
@@ -1479,12 +1520,14 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1479
1520
|
'''
|
|
1480
1521
|
return tuple(self._ps)
|
|
1481
1522
|
|
|
1482
|
-
def pow(self, x, *mod):
|
|
1523
|
+
def pow(self, x, *mod, **raiser):
|
|
1483
1524
|
'''Return C{B{self}**B{x}} as L{Fsum}.
|
|
1484
1525
|
|
|
1485
1526
|
@arg x: The exponent (L{Fsum} or C{scalar}).
|
|
1486
1527
|
@arg mod: Optional modulus (C{int} or C{None}) for the 3-argument
|
|
1487
1528
|
C{pow(B{self}, B{other}, B{mod})} version.
|
|
1529
|
+
@kwarg raiser: Use C{B{raiser}=False} to ignore L{ResidualError}s
|
|
1530
|
+
(C{bool}), see also method L{RESIDUAL}.
|
|
1488
1531
|
|
|
1489
1532
|
@return: The C{pow(self, B{x})} or C{pow(self, B{x}, *B{mod})}
|
|
1490
1533
|
result (L{Fsum}).
|
|
@@ -1493,17 +1536,35 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1493
1536
|
C{integer} L{Fsum} provided this instance C{is_integer}
|
|
1494
1537
|
or set to C{integer} by an L{Fsum.fint} call.
|
|
1495
1538
|
|
|
1496
|
-
@see: Methods L{Fsum.__ipow__}, L{Fsum.fint}
|
|
1539
|
+
@see: Methods L{Fsum.__ipow__}, L{Fsum.fint}, L{Fsum.is_integer}
|
|
1540
|
+
and L{Fsum.root}.
|
|
1497
1541
|
'''
|
|
1498
1542
|
f = self._copy_2(self.pow)
|
|
1499
|
-
return f._fpow(x, _pow_op_, *mod) # f = pow(f, x, *mod)
|
|
1543
|
+
return f._fpow(x, _pow_op_, *mod, **raiser) # f = pow(f, x, *mod)
|
|
1544
|
+
|
|
1545
|
+
def _pow(self, other, unused, op, **raiser):
|
|
1546
|
+
'''Return C{B{self} ** B{other}}.
|
|
1547
|
+
'''
|
|
1548
|
+
if isinstance(other, Fsum):
|
|
1549
|
+
x, r = other._fprs2
|
|
1550
|
+
if r and self._raiser(r, x, **raiser):
|
|
1551
|
+
raise self._ResidualError(op, other, r)
|
|
1552
|
+
f = self._pow_scalar(x, other, op, **raiser)
|
|
1553
|
+
if r:
|
|
1554
|
+
f *= self._pow_scalar(r, other, op, **raiser)
|
|
1555
|
+
elif self._scalar(other, op):
|
|
1556
|
+
x = self._finite(other, op)
|
|
1557
|
+
f = self._pow_scalar(x, other, op, **raiser)
|
|
1558
|
+
else:
|
|
1559
|
+
f = self._pow_0_1(0, other)
|
|
1560
|
+
return f
|
|
1500
1561
|
|
|
1501
1562
|
def _pow_0_1(self, x, other):
|
|
1502
1563
|
'''(INTERNAL) Return B{C{self}**1} or C{B{self}**0 == 1.0}.
|
|
1503
1564
|
'''
|
|
1504
1565
|
return self if x else (1 if isint(other) and self.is_integer() else _1_0)
|
|
1505
1566
|
|
|
1506
|
-
def _pow_2_3(self, b, x, other, op, *mod):
|
|
1567
|
+
def _pow_2_3(self, b, x, other, op, *mod, **raiser):
|
|
1507
1568
|
'''(INTERNAL) 2-arg C{pow(B{b}, scalar B{x})} and 3-arg C{pow(B{b},
|
|
1508
1569
|
B{x}, int B{mod} or C{None})}, embellishing errors.
|
|
1509
1570
|
'''
|
|
@@ -1511,7 +1572,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1511
1572
|
if mod: # b, x, mod all C{int}, unless C{mod} is C{None}
|
|
1512
1573
|
m = mod[0]
|
|
1513
1574
|
b, r = b._fprs2 if m is None else b._fint2
|
|
1514
|
-
if r and self._raiser(r, b):
|
|
1575
|
+
if r and self._raiser(r, b, **raiser):
|
|
1515
1576
|
t = _non_zero_ if m is None else _integer_
|
|
1516
1577
|
raise ResidualError(_stresidual(t, r, mod=m), txt=None)
|
|
1517
1578
|
x = _2scalar(x, _raiser=self._raiser, mod=m)
|
|
@@ -1524,24 +1585,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1524
1585
|
except Exception as X:
|
|
1525
1586
|
raise self._ErrorX(X, op, other, *mod)
|
|
1526
1587
|
|
|
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):
|
|
1588
|
+
def _pow_int(self, x, other, op, **raiser):
|
|
1545
1589
|
'''(INTERNAL) Return C{B{self} **= B{x}} for C{int B{x} >= 0}.
|
|
1546
1590
|
'''
|
|
1547
1591
|
# assert isint(x) and x >= 0
|
|
@@ -1565,13 +1609,13 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1565
1609
|
else: # self**1 or self**0 == 1 or _1_0
|
|
1566
1610
|
f = self._pow_0_1(x, other)
|
|
1567
1611
|
elif ps: # self._ps[0]**x
|
|
1568
|
-
f = self._pow_2_3(ps[0], x, other, op)
|
|
1612
|
+
f = self._pow_2_3(ps[0], x, other, op, **raiser)
|
|
1569
1613
|
else: # PYCHOK no cover
|
|
1570
1614
|
# 0**pos_int == 0, but 0**0 == 1
|
|
1571
1615
|
f = 0 if x else 1
|
|
1572
1616
|
return f
|
|
1573
1617
|
|
|
1574
|
-
def _pow_scalar(self, x, other, op):
|
|
1618
|
+
def _pow_scalar(self, x, other, op, **raiser):
|
|
1575
1619
|
'''(INTERNAL) Return C{self**B{x}} for C{scalar B{x}}.
|
|
1576
1620
|
'''
|
|
1577
1621
|
s, r = self._fprs2
|
|
@@ -1580,41 +1624,29 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1580
1624
|
y = abs(x)
|
|
1581
1625
|
if y > 1:
|
|
1582
1626
|
if r:
|
|
1583
|
-
f = self._pow_int(y, other, op)
|
|
1627
|
+
f = self._pow_int(y, other, op, **raiser)
|
|
1584
1628
|
if x > 0: # > 1
|
|
1585
1629
|
return f
|
|
1586
1630
|
# assert x < 0 # < -1
|
|
1587
1631
|
s, r = f._fprs2 if isinstance(f, Fsum) else (f, 0)
|
|
1588
1632
|
if r:
|
|
1589
|
-
return _Psum_1()._ftruediv(f, op)
|
|
1633
|
+
return _Psum_1()._ftruediv(f, op, **raiser)
|
|
1590
1634
|
# use **= -1 for the CPython float_pow
|
|
1591
1635
|
# error if s is zero, and not s = 1 / s
|
|
1592
1636
|
x = -1
|
|
1593
1637
|
elif x < 0: # == -1: self**(-1) == 1 / self
|
|
1594
1638
|
if r:
|
|
1595
|
-
return _Psum_1()._ftruediv(self, op)
|
|
1639
|
+
return _Psum_1()._ftruediv(self, op, **raiser)
|
|
1596
1640
|
else: # self**1 or self**0
|
|
1597
1641
|
return self._pow_0_1(x, other) # self, 1 or 1.0
|
|
1598
|
-
elif
|
|
1599
|
-
raise self._TypeError(op, other, txt=_not_scalar_)
|
|
1600
|
-
elif r and self._raiser(r, s): # non-zero residual**fractional
|
|
1642
|
+
elif r and self._raiser(r, s, **raiser): # non-zero residual**fractional
|
|
1601
1643
|
# raise self._ResidualError(op, other, r, fractional_power=x)
|
|
1602
1644
|
t = _stresidual(_non_zero_, r, fractional_power=x)
|
|
1603
1645
|
raise self._Error(op, other, ResidualError, txt=t)
|
|
1604
1646
|
# assert isscalar(s) and isscalar(x)
|
|
1605
|
-
return self._pow_2_3(s, x, other, op)
|
|
1647
|
+
return self._pow_2_3(s, x, other, op, **raiser)
|
|
1606
1648
|
|
|
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):
|
|
1649
|
+
def _ps_acc(self, ps, xs, up=True, **unused):
|
|
1618
1650
|
'''(INTERNAL) Accumulate all scalar C{xs} into C{ps}.
|
|
1619
1651
|
'''
|
|
1620
1652
|
n = 0
|
|
@@ -1639,7 +1671,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1639
1671
|
|
|
1640
1672
|
def _ps_mul(self, op, *factors):
|
|
1641
1673
|
'''(INTERNAL) Multiply this instance' C{partials} with
|
|
1642
|
-
each of the B{C{factors}}
|
|
1674
|
+
each of the scalar B{C{factors}} and accumulate.
|
|
1643
1675
|
'''
|
|
1644
1676
|
def _pfs(ps, fs):
|
|
1645
1677
|
if len(ps) < len(fs):
|
|
@@ -1659,11 +1691,21 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1659
1691
|
for p in self._ps:
|
|
1660
1692
|
yield -p
|
|
1661
1693
|
|
|
1662
|
-
def
|
|
1663
|
-
'''(INTERNAL)
|
|
1694
|
+
def _ps_1primed(self, *less):
|
|
1695
|
+
'''(INTERNAL) Yield partials, 1-primed and subtract any C{less} scalars.
|
|
1664
1696
|
'''
|
|
1665
|
-
|
|
1666
|
-
|
|
1697
|
+
yield _1_0
|
|
1698
|
+
for p in self._ps:
|
|
1699
|
+
yield p
|
|
1700
|
+
for p in less:
|
|
1701
|
+
yield -p
|
|
1702
|
+
yield _N_1_0
|
|
1703
|
+
|
|
1704
|
+
def _raiser(self, r, s, raiser=True):
|
|
1705
|
+
'''(INTERNAL) Does ratio C{r / s} exceed the RESIDUAL threshold?
|
|
1706
|
+
'''
|
|
1707
|
+
self._ratio = t = fabs(r / s) if s else 0 # _0_0
|
|
1708
|
+
return raiser and (t > self._RESIDUAL)
|
|
1667
1709
|
|
|
1668
1710
|
@property_RO
|
|
1669
1711
|
def real(self):
|
|
@@ -1697,7 +1739,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1697
1739
|
C{PYGEODESY_FSUM_RESIDUAL} or if omitted, keep the
|
|
1698
1740
|
current setting.
|
|
1699
1741
|
|
|
1700
|
-
@return: The previous C{RESIDUAL} setting (C{float}), default C{0}.
|
|
1742
|
+
@return: The previous C{RESIDUAL} setting (C{float}), default C{0.}.
|
|
1701
1743
|
|
|
1702
1744
|
@raise ValueError: Negative B{C{threshold}}.
|
|
1703
1745
|
|
|
@@ -1724,6 +1766,37 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1724
1766
|
t = t.replace(_COMMASPACE_R_, _exceeds_R_)
|
|
1725
1767
|
return self._Error(op, other, ResidualError, txt=t)
|
|
1726
1768
|
|
|
1769
|
+
def root(self, root, **raiser):
|
|
1770
|
+
'''Return C{B{self}**(1 / B{root})} as L{Fsum}.
|
|
1771
|
+
|
|
1772
|
+
@arg root: The order (C{scalar} or C{Fsum}), non-zero.
|
|
1773
|
+
@kwarg raiser: Use C{B{raiser}=False} to ignore L{ResidualError}s
|
|
1774
|
+
(C{bool}), see also method L{RESIDUAL}.
|
|
1775
|
+
|
|
1776
|
+
@return: The C{self ** (1 / B{root})} result (L{Fsum}).
|
|
1777
|
+
|
|
1778
|
+
@see: Method L{Fsum.pow}.
|
|
1779
|
+
'''
|
|
1780
|
+
_root_ = self.root.__name__
|
|
1781
|
+
if isinstance(root, Fsum):
|
|
1782
|
+
x = root.__rtruediv__(_1_0, **raiser)
|
|
1783
|
+
else:
|
|
1784
|
+
try:
|
|
1785
|
+
x = _1_0 / _2float(root=root)
|
|
1786
|
+
except Exception as X:
|
|
1787
|
+
E, t = _xError2(X)
|
|
1788
|
+
n = _SPACE_(_1_0, _truediv_op_, _root_)
|
|
1789
|
+
raise E(n, root, txt=t, cause=X)
|
|
1790
|
+
f = self._copy_2(self.root)
|
|
1791
|
+
return f._fpow(x, _root_, **raiser) # == pow(f, x)
|
|
1792
|
+
|
|
1793
|
+
def _scalar(self, other, op, **txt):
|
|
1794
|
+
'''(INTERNAL) Return scalar C{other}.
|
|
1795
|
+
'''
|
|
1796
|
+
if isscalar(other):
|
|
1797
|
+
return other
|
|
1798
|
+
raise self._TypeError(op, other, **txt) # _invalid_
|
|
1799
|
+
|
|
1727
1800
|
@property_RO
|
|
1728
1801
|
def _2scalar(self):
|
|
1729
1802
|
'''(INTERNAL) Get this instance as C{scalar} or C{as-is}.
|
|
@@ -1914,8 +1987,8 @@ def fsum_(*xs, **floats):
|
|
|
1914
1987
|
|
|
1915
1988
|
@arg xs: Values to be added (C{scalar} or L{Fsum} instances), all
|
|
1916
1989
|
positional.
|
|
1917
|
-
@kwarg floats: Use C{B{floats}=True} iff I{all} B{C{xs}} are known
|
|
1918
|
-
to be
|
|
1990
|
+
@kwarg floats: Use C{B{floats}=True} iff I{all} B{C{xs}} are I{known
|
|
1991
|
+
to be scalar} (C{bool}).
|
|
1919
1992
|
|
|
1920
1993
|
@return: Precision C{fsum} (C{float}).
|
|
1921
1994
|
|
|
@@ -1926,7 +1999,8 @@ def fsum_(*xs, **floats):
|
|
|
1926
1999
|
|
|
1927
2000
|
|
|
1928
2001
|
def fsumf_(*xs):
|
|
1929
|
-
'''Precision floating point summation L{fsum_}C{(*xs, floats=True)}
|
|
2002
|
+
'''Precision floating point summation, L{fsum_}C{(*B{xs}, floats=True)},
|
|
2003
|
+
but only for C{B{xs}} I{known to be scalar}.
|
|
1930
2004
|
'''
|
|
1931
2005
|
return _fsum(xs) if xs else _0_0
|
|
1932
2006
|
|
|
@@ -1951,8 +2025,8 @@ def fsum1_(*xs, **floats):
|
|
|
1951
2025
|
|
|
1952
2026
|
@arg xs: Values to be added (C{scalar} or L{Fsum} instances), all
|
|
1953
2027
|
positional.
|
|
1954
|
-
@kwarg floats: Use C{B{floats}=True} iff I{all} B{C{xs}} are known
|
|
1955
|
-
to be
|
|
2028
|
+
@kwarg floats: Use C{B{floats}=True} iff I{all} B{C{xs}} are I{known
|
|
2029
|
+
to be scalar} (C{bool}).
|
|
1956
2030
|
|
|
1957
2031
|
@return: Precision C{fsum} (C{float}).
|
|
1958
2032
|
|
|
@@ -1963,7 +2037,8 @@ def fsum1_(*xs, **floats):
|
|
|
1963
2037
|
|
|
1964
2038
|
|
|
1965
2039
|
def fsum1f_(*xs):
|
|
1966
|
-
'''Precision floating point summation, L{fsum1_}C{(*xs, floats=True)}
|
|
2040
|
+
'''Precision floating point summation, L{fsum1_}C{(*B{xs}, floats=True)},
|
|
2041
|
+
but only for C{B{xs}} I{known to be scalar}.
|
|
1967
2042
|
'''
|
|
1968
2043
|
return _fsum(_1primed(xs)) if xs else _0_0
|
|
1969
2044
|
|