pygeodesy 24.5.2__py2.py3-none-any.whl → 24.5.6__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/fsums.py CHANGED
@@ -27,36 +27,39 @@ from pygeodesy.basics import isbool, iscomplex, isint, isscalar, itemsorted, \
27
27
  signOf, _signOf
28
28
  from pygeodesy.constants import INT0, _isfinite, NEG0, _pos_self, \
29
29
  _0_0, _1_0, _N_1_0, Float, Int
30
- from pygeodesy.errors import _AssertionError, _OverflowError, _TypeError, \
31
- _ValueError, _xError, _xError2, _xkwds_get, \
32
- _ZeroDivisionError
30
+ from pygeodesy.errors import _OverflowError, _TypeError, _ValueError, \
31
+ _xError, _xError2, _xkwds_get
33
32
  from pygeodesy.interns import NN, _arg_, _COMMASPACE_, _DASH_, _DOT_, \
34
- _EQUAL_, _from_, _LANGLE_, _NOTEQUAL_, \
33
+ _enquote, _EQUAL_, _from_, _LANGLE_, _NOTEQUAL_, \
35
34
  _not_finite_, _PERCENT_, _PLUS_, _RANGLE_, \
36
35
  _SLASH_, _SPACE_, _STAR_, _UNDER_
37
36
  from pygeodesy.lazily import _ALL_LAZY, _getenv, _sys_version_info2
38
- from pygeodesy.named import _Named, _NamedTuple, _NotImplemented, Fmt, unstr
37
+ from pygeodesy.named import _Named, _NamedTuple, _NotImplemented
39
38
  from pygeodesy.props import _allPropertiesOf_n, deprecated_property_RO, \
40
39
  Property_RO, property_RO
41
- # from pygeodesy.streprs import Fmt, unstr # from .named
40
+ from pygeodesy.streprs import Fmt, fstr, unstr
42
41
  # from pygeodesy.units import Float, Int # from .constants
43
42
 
44
43
  from math import ceil as _ceil, fabs, floor as _floor # PYCHOK used! .ltp
45
44
 
46
45
  __all__ = _ALL_LAZY.fsums
47
- __version__ = '24.05.02'
46
+ __version__ = '24.05.06'
48
47
 
48
+ _abs = abs
49
49
  _add_op_ = _PLUS_ # in .auxilats.auxAngle
50
50
  _eq_op_ = _EQUAL_ * 2 # _DEQUAL_
51
51
  _div_ = 'div'
52
+ _Float = float # in .fstats
52
53
  _floordiv_op_ = _SLASH_ * 2 # _DSLASH_
53
54
  _fset_op_ = _EQUAL_
54
55
  _ge_op_ = _RANGLE_ + _EQUAL_
55
56
  _gt_op_ = _RANGLE_
56
57
  _iadd_op_ = _add_op_ + _EQUAL_ # in .auxilats.auxAngle, .fstats
57
58
  _integer_ = 'integer'
58
- _isinstance = isinstance
59
+ _isAn = isinstance # in .fstats
59
60
  _le_op_ = _LANGLE_ + _EQUAL_
61
+ _len = len
62
+ _List = list
60
63
  _lt_op_ = _LANGLE_
61
64
  _mod_ = 'mod'
62
65
  _mod_op_ = _PERCENT_
@@ -68,6 +71,7 @@ _significant_ = 'significant'
68
71
  _sub_op_ = _DASH_ # in .auxilats.auxAngle
69
72
  _threshold_ = 'threshold'
70
73
  _truediv_op_ = _SLASH_
74
+ _Tuple = tuple
71
75
  _divmod_op_ = _floordiv_op_ + _mod_op_
72
76
  _isub_op_ = _sub_op_ + _fset_op_ # in .auxilats.auxAngle
73
77
 
@@ -79,7 +83,7 @@ def _2delta(*ab):
79
83
  a, b = _2sum(*ab)
80
84
  except _OverflowError:
81
85
  a, b = ab
82
- return float(a if fabs(a) > fabs(b) else b)
86
+ return _Float(a if fabs(a) > fabs(b) else b)
83
87
 
84
88
 
85
89
  def _2error(unused):
@@ -93,7 +97,7 @@ def _2float(index=None, **name_value): # in .fmath, .fstats
93
97
  '''
94
98
  n, v = name_value.popitem() # _xkwds_item2(name_value)
95
99
  try:
96
- v = float(v)
100
+ v = _Float(v)
97
101
  return v if _isfinite(v) else _2error(v)
98
102
  except Exception as X:
99
103
  raise _xError(X, Fmt.INDEX(n, index), v)
@@ -103,14 +107,14 @@ def _X_ps(X): # for _2floats only
103
107
  return X._ps
104
108
 
105
109
 
106
- def _2floats(xs, origin=0, _X=_X_ps, _x=float):
110
+ def _2floats(xs, origin=0, _X=_X_ps, _x=_Float):
107
111
  '''(INTERNAL) Yield each B{C{xs}} as a C{float}.
108
112
  '''
109
113
  try:
110
114
  i, x = origin, None
111
115
  _fin = _isfinite
112
116
  _FsT = _Fsum_Fsum2Tuple_types
113
- _is = _isinstance
117
+ _is = _isAn
114
118
  for x in xs:
115
119
  if _is(x, _FsT):
116
120
  for p in _X(x._Fsum):
@@ -147,16 +151,16 @@ def _2halfeven(s, r, p):
147
151
  return s
148
152
 
149
153
 
150
- def _isFsum(x):
154
+ def _isFsum(x): # in .fmath
151
155
  '''(INTERNAL) Is C{x} an C{Fsum} instance?
152
156
  '''
153
- return _isinstance(x, Fsum)
157
+ return _isAn(x, Fsum)
154
158
 
155
159
 
156
- def _isFsumTuple(x):
160
+ def _isFsumTuple(x): # in .fmath
157
161
  '''(INTERNAL) Is C{x} an C{Fsum} or C{Fsum2Tuple} instance?
158
162
  '''
159
- return _isinstance(x, _Fsum_Fsum2Tuple_types)
163
+ return _isAn(x, _Fsum_Fsum2Tuple_types)
160
164
 
161
165
 
162
166
  def _1_Over(x, op, **raiser_RESIDUAL): # vs _1_over
@@ -167,7 +171,7 @@ def _1_Over(x, op, **raiser_RESIDUAL): # vs _1_over
167
171
 
168
172
  def _1primed(xs): # in .fmath
169
173
  '''(INTERNAL) 1-Primed summation of iterable C{xs}
170
- items, all I{known} to be C{finite float}.
174
+ items, all I{known} to be C{scalar}.
171
175
  '''
172
176
  yield _1_0
173
177
  for x in xs:
@@ -178,8 +182,8 @@ def _1primed(xs): # in .fmath
178
182
  def _psum(ps): # PYCHOK used!
179
183
  '''(INTERNAL) Partials summation, updating C{ps}.
180
184
  '''
181
- # assert _isinstance(ps, list)
182
- i = len(ps) - 1
185
+ # assert _isAn(ps, _List)
186
+ i = _len(ps) - 1
183
187
  s = _0_0 if i < 0 else ps[i]
184
188
  _2s = _2sum
185
189
  while i > 0:
@@ -196,20 +200,20 @@ def _psum(ps): # PYCHOK used!
196
200
  return s
197
201
 
198
202
 
199
- def _Psum(ps, **name):
203
+ def _Psum(ps, **name_RESIDUAL):
200
204
  '''(INTERNAL) Return an C{Fsum} from I{ordered} partials C{ps}.
201
205
  '''
202
- F = Fsum(**name) if name else Fsum()
206
+ f = Fsum(**name_RESIDUAL) if name_RESIDUAL else Fsum()
203
207
  if ps:
204
- F._ps[:] = ps
205
- F._n = len(F._ps)
206
- return F
208
+ f._ps[:] = ps
209
+ f._n = _len(f._ps)
210
+ return f
207
211
 
208
212
 
209
- def _Psum_(*ps, **name):
213
+ def _Psum_(*ps, **name_RESIDUAL):
210
214
  '''(INTERNAL) Return an C{Fsum} from 1 or 2 known scalar(s) C{ps}.
211
215
  '''
212
- return _Psum(ps, **name)
216
+ return _Psum(ps, **name_RESIDUAL)
213
217
 
214
218
 
215
219
  def _2scalar2(other):
@@ -245,7 +249,7 @@ def _strcomplex(s, *args):
245
249
  '''(INTERNAL) C{Complex} 2- or 3-arg C{pow} error as C{str}.
246
250
  '''
247
251
  c = _strcomplex.__name__[4:]
248
- n = _DASH_(len(args), _arg_)
252
+ n = _DASH_(_len(args), _arg_)
249
253
  t = unstr(pow, *args)
250
254
  return _SPACE_(c, s, _from_, n, t)
251
255
 
@@ -278,7 +282,7 @@ def _threshold(threshold):
278
282
  '''(INTERNAL) Get the L{ResidualError}s threshold.
279
283
  '''
280
284
  try:
281
- t = float(threshold) or _0_0
285
+ t = _Float(threshold) or _0_0
282
286
  return t if _isfinite(t) else _2error(t) # PYCHOK None
283
287
  except Exception as x:
284
288
  raise ResidualError(threshold=threshold, cause=x)
@@ -305,10 +309,10 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
305
309
  file I{Modules/mathmodule.c} and the issue log U{Full precision summation
306
310
  <https://Bugs.Python.org/issue2819>}.
307
311
  '''
308
- _math_fsum = None
312
+ _math_fsum = None
309
313
  _n = 0
310
314
  # _ps = [] # partial sums
311
- # _ps_max = 0 # max(Fsum._ps_max, len(Fsum._ps))
315
+ # _ps_max = 0 # max(Fsum._ps_max, _len(Fsum._ps))
312
316
  _RESIDUAL = _threshold(_getenv('PYGEODESY_FSUM_RESIDUAL', _0_0))
313
317
 
314
318
  def __init__(self, *xs, **name_RESIDUAL):
@@ -323,12 +327,12 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
323
327
  '''
324
328
  if name_RESIDUAL:
325
329
 
326
- def _n_r(name=NN, RESIDUAL=None):
330
+ def _n_R(name=NN, RESIDUAL=None):
327
331
  return name, RESIDUAL
328
332
 
329
- n, r = _n_r(**name_RESIDUAL)
330
- if r is not None:
331
- self.RESIDUAL(r)
333
+ n, R = _n_R(**name_RESIDUAL)
334
+ if R is not None:
335
+ self.RESIDUAL(R)
332
336
  if n:
333
337
  self.name = n
334
338
 
@@ -349,12 +353,12 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
349
353
 
350
354
  @return: The sum (L{Fsum}).
351
355
 
352
- @see: Method L{Fsum.__iadd__}.
356
+ @see: Methods L{Fsum.fadd_} and L{Fsum.fadd}.
353
357
  '''
354
358
  f = self._copy_2(self.__add__)
355
359
  return f._fadd(other, _add_op_)
356
360
 
357
- def __bool__(self): # PYCHOK not special in Python 2-
361
+ def __bool__(self): # PYCHOK Python 3+
358
362
  '''Return C{True} if this instance is I{exactly} non-zero.
359
363
  '''
360
364
  s, r = self._fprs2
@@ -392,7 +396,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
392
396
  @raise ResidualError: Non-zero, significant residual or invalid
393
397
  B{C{RESIDUAL}}.
394
398
 
395
- @see: Method L{Fsum.__itruediv__}.
399
+ @see: Method L{Fsum.fdiv}.
396
400
  '''
397
401
  f = self._copy_2(self.__divmod__)
398
402
  return f._fdivmod2(other, _divmod_op_, **raiser_RESIDUAL)
@@ -407,7 +411,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
407
411
 
408
412
  @see: Methods L{Fsum.fsum} and L{Fsum.int_float}.
409
413
  '''
410
- return float(self._fprs)
414
+ return _Float(self._fprs)
411
415
 
412
416
  def __floor__(self): # PYCHOK not special in Python 2-
413
417
  '''Return this instance' C{math.floor} as C{int} or C{float}.
@@ -459,7 +463,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
459
463
  @raise TypeError: Invalid B{C{other}}, not
460
464
  C{scalar} nor L{Fsum}.
461
465
 
462
- @see: Methods L{Fsum.fadd} and L{Fsum.fadd_}.
466
+ @see: Methods L{Fsum.fadd_} and L{Fsum.fadd}.
463
467
  '''
464
468
  return self._fadd(other, _iadd_op_)
465
469
 
@@ -516,9 +520,8 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
516
520
  def __int__(self):
517
521
  '''Return this instance as an C{int}.
518
522
 
519
- @see: Methods L{Fsum.int_float}, L{Fsum.__ceil__}
520
- and L{Fsum.__floor__} and properties
521
- L{Fsum.ceil} and L{Fsum.floor}.
523
+ @see: Method L{Fsum.int_float} and properties L{Fsum.ceil}
524
+ and L{Fsum.floor}.
522
525
  '''
523
526
  i, _ = self._fint2
524
527
  return i
@@ -575,7 +578,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
575
578
 
576
579
  @raise TypeError: Invalid B{C{other}} type.
577
580
 
578
- @see: Method L{Fsum.fadd}.
581
+ @see: Methods L{Fsum.fsub_} and L{Fsum.fsub}.
579
582
  '''
580
583
  return self._fsub(other, _isub_op_)
581
584
 
@@ -725,7 +728,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
725
728
  '''
726
729
  f = self._copy_2(self.__round__)
727
730
  # <https://docs.Python.org/3.12/reference/datamodel.html?#object.__round__>
728
- return f._fset(round(float(self), *ndigits)) # can be C{int}
731
+ return f._fset(round(_Float(self), *ndigits)) # can be C{int}
729
732
 
730
733
  def __rpow__(self, other, *mod):
731
734
  '''Return C{B{other}**B{self}} as an L{Fsum}.
@@ -783,8 +786,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
783
786
 
784
787
  @see: Method L{Fsum.__itruediv__}.
785
788
  '''
786
- f = self._copy_2(self.__truediv__)
787
- return f._ftruediv(other, _truediv_op_, **raiser_RESIDUAL)
789
+ return self._truediv(other, _truediv_op_, **raiser_RESIDUAL)
788
790
 
789
791
  __trunc__ = __int__
790
792
 
@@ -799,14 +801,15 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
799
801
  def as_integer_ratio(self):
800
802
  '''Return this instance as the ratio of 2 integers.
801
803
 
802
- @return: 2-Tuple C{(numerator, denominator)} both
803
- C{int} and with positive C{denominator}.
804
+ @return: 2-Tuple C{(numerator, denominator)} both C{int}
805
+ with C{numerator} signed and C{denominator}
806
+ non-zero, positive.
804
807
 
805
- @see: Standard C{float.as_integer_ratio} in Python 3+.
808
+ @see: Standard C{float.as_integer_ratio} in Python 2.7+.
806
809
  '''
807
810
  n, r = self._fint2
808
811
  if r:
809
- i, d = float(r).as_integer_ratio()
812
+ i, d = _Float(r).as_integer_ratio()
810
813
  n *= d
811
814
  n += i
812
815
  else: # PYCHOK no cover
@@ -815,17 +818,18 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
815
818
 
816
819
  @property_RO
817
820
  def as_iscalar(self):
818
- '''Get this instance I{as-is} (L{Fsum}) or as C{scalar} iff scalar.
821
+ '''Get this instance I{as-is} (L{Fsum} or C{scalar}), the
822
+ latter only if the C{residual} equals C{zero}.
819
823
  '''
820
824
  s, r = self._fprs2
821
825
  return self if r else s
822
826
 
823
827
  @property_RO
824
828
  def ceil(self):
825
- '''Get this instance' C{ceil} value (C{int} in Python 3+,
826
- but C{float} in Python 2-).
829
+ '''Get this instance' C{ceil} value (C{int} in Python 3+, but
830
+ C{float} in Python 2-).
827
831
 
828
- @note: The C{ceil} takes the C{residual} into account.
832
+ @note: This C{ceil} takes the C{residual} into account.
829
833
 
830
834
  @see: Method L{Fsum.int_float} and properties L{Fsum.floor},
831
835
  L{Fsum.imag} and L{Fsum.real}.
@@ -842,11 +846,11 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
842
846
  '''(INTERNAL) Return C{scalar(self - B{other})} for 0-comparison.
843
847
  '''
844
848
  if _isFsumTuple(other):
845
- s = _fsum(self._ps_1primed(*other._ps))
849
+ s = self._ps_1sum(*other._ps)
846
850
  elif self._scalar(other, op):
847
- s = _fsum(self._ps_1primed(other))
851
+ s = self._ps_1sum(other)
848
852
  else:
849
- s = self.signOf() # res=True
853
+ s = self.signOf() # res=True
850
854
  return s
851
855
 
852
856
  def copy(self, deep=False, name=NN):
@@ -856,9 +860,10 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
856
860
  '''
857
861
  f = _Named.copy(self, deep=deep, name=name)
858
862
  if f._ps is self._ps:
859
- f._ps = list(self._ps) # separate list
863
+ f._ps = _List(self._ps) # separate list
860
864
  if not deep:
861
865
  f._n = 1
866
+ # assert f._Fsum is f
862
867
  return f
863
868
 
864
869
  def _copy_2(self, which, name=NN):
@@ -867,8 +872,9 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
867
872
  n = name or which.__name__
868
873
  # NOT .classof due to .Fdot(a, *b) args, etc.
869
874
  f = _Named.copy(self, deep=False, name=n)
875
+ f._ps = _List(self._ps) # separate list
870
876
  # assert f._n == self._n
871
- f._ps = list(self._ps) # separate list
877
+ # assert f._Fsum is f
872
878
  return f
873
879
 
874
880
  def _copy_2r(self, other, which):
@@ -903,7 +909,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
903
909
  '''(INTERNAL) Format the caught exception C{X}.
904
910
  '''
905
911
  E, t = _xError2(X)
906
- u = unstr(self.named3, *xs[:3], _ELLIPSIS=len(xs) > 3, **kwds)
912
+ u = unstr(self.named3, *xs[:3], _ELLIPSIS=_len(xs) > 3, **kwds)
907
913
  return E(u, txt=t, cause=X)
908
914
 
909
915
  def _facc(self, xs, up=True, **origin_X_x):
@@ -912,14 +918,14 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
912
918
  if xs:
913
919
  _xs = _2floats(xs, **origin_X_x) # PYCHOK yield
914
920
  ps = self._ps
915
- ps[:] = self._ps_acc(list(ps), _xs, up=up)
921
+ ps[:] = self._ps_acc(_List(ps), _xs, up=up)
916
922
  return self
917
923
 
918
924
  def _facc_1(self, xs, **up):
919
925
  '''(INTERNAL) Accumulate 0, 1 or more C{scalars} or L{Fsum}s,
920
926
  all positional C{xs} in the caller of this method.
921
927
  '''
922
- return self._fadd(xs[0], _add_op_, **up) if len(xs) == 1 else \
928
+ return self._fadd(xs[0], _add_op_, **up) if _len(xs) == 1 else \
923
929
  self._facc(xs, origin=1, **up)
924
930
 
925
931
  def _facc_neg(self, xs, **up_origin):
@@ -929,7 +935,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
929
935
  return X._ps_neg
930
936
 
931
937
  def _n(x):
932
- return -float(x)
938
+ return -_Float(x)
933
939
 
934
940
  return self._facc(xs, _X=_N, _x=_n, **up_origin)
935
941
 
@@ -955,15 +961,16 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
955
961
  _Pow, p, s, r = _Pow4(power)
956
962
  if p: # and xs:
957
963
  op = which.__name__
958
- _isF = _isFsum
964
+ _Fs = Fsum
965
+ _is = _isAn
959
966
  _pow = self._pow_2_3
960
967
 
961
968
  def _P(X):
962
969
  f = _Pow(X, p, power, op, **raiser_RESIDUAL)
963
- return f._ps if _isF(f) else (f,)
970
+ return f._ps if _is(f, _Fs) else (f,)
964
971
 
965
972
  def _p(x):
966
- x = float(x)
973
+ x = _Float(x)
967
974
  f = _pow(x, s, power, op, **raiser_RESIDUAL)
968
975
  if f and r:
969
976
  f *= _pow(x, r, power, op, **raiser_RESIDUAL)
@@ -971,7 +978,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
971
978
 
972
979
  f = self._facc(xs, origin=1, _X=_P, _x=_p)
973
980
  else:
974
- f = self._facc_scalar_(float(len(xs))) # x**0 == 1
981
+ f = self._facc_scalar_(_Float(_len(xs))) # x**0 == 1
975
982
  return f
976
983
 
977
984
  def _facc_scalar(self, xs, **up):
@@ -993,7 +1000,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
993
1000
  # and re-accumulating the final C{partial}.
994
1001
  # '''
995
1002
  # ps = self._ps
996
- # while len(ps) > 1:
1003
+ # while _len(ps) > 1:
997
1004
  # p = ps.pop()
998
1005
  # if p:
999
1006
  # n = self._n
@@ -1003,7 +1010,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
1003
1010
  # return self._update() if up else self
1004
1011
 
1005
1012
  def fadd(self, xs=()):
1006
- '''Add all items from an iterable to this instance.
1013
+ '''Add an iterable's items to this instance.
1007
1014
 
1008
1015
  @arg xs: Iterable of items to add (each C{scalar}
1009
1016
  or an L{Fsum} or L{Fsum2Tuple} instance).
@@ -1017,7 +1024,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
1017
1024
  @raise ValueError: Invalid or non-finite B{C{xs}} value.
1018
1025
  '''
1019
1026
  if _isFsumTuple(xs):
1020
- self._facc_scalar(xs._ps) # tuple(xs._ps)
1027
+ self._facc_scalar(xs._ps) # _Tuple(xs._ps)
1021
1028
  elif isscalar(xs): # for backward compatibility
1022
1029
  self._facc_scalar_(_2float(x=xs)) # PYCHOK no cover
1023
1030
  elif xs: # assert isiterable(xs)
@@ -1025,7 +1032,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
1025
1032
  return self
1026
1033
 
1027
1034
  def fadd_(self, *xs):
1028
- '''Add all positional arguments to this instance.
1035
+ '''Add all positional items to this instance.
1029
1036
 
1030
1037
  @arg xs: Values to add (each C{scalar} or an L{Fsum}
1031
1038
  or L{Fsum2Tuple} instance), all positional.
@@ -1037,15 +1044,17 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
1037
1044
  def _fadd(self, other, op, **up): # in .fmath.Fhorner
1038
1045
  '''(INTERNAL) Apply C{B{self} += B{other}}.
1039
1046
  '''
1040
- if _isFsumTuple(other):
1041
- self._facc_scalar(other._ps, **up) # tuple
1047
+ if not self._ps: # new Fsum(x)
1048
+ self._fset(other, as_is=False, **up)
1049
+ elif _isFsumTuple(other):
1050
+ self._facc_scalar(other._ps, **up) # _Tuple
1042
1051
  elif self._scalar(other, op):
1043
1052
  self._facc_scalar_(other, **up)
1044
1053
  return self
1045
1054
 
1046
- fcopy = copy # for backward compatibility
1047
- fdiv = __itruediv__ # for backward compatibility
1048
- fdivmod = __divmod__ # for backward compatibility
1055
+ fcopy = copy # for backward compatibility
1056
+ fdiv = __itruediv__
1057
+ fdivmod = __divmod__
1049
1058
 
1050
1059
  def _fdivmod2(self, other, op, **raiser_RESIDUAL):
1051
1060
  '''(INTERNAL) Apply C{B{self} %= B{other}} and return a L{DivMod2Tuple}.
@@ -1053,10 +1062,9 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
1053
1062
  # result mostly follows CPython function U{float_divmod
1054
1063
  # <https://GitHub.com/python/cpython/blob/main/Objects/floatobject.c>},
1055
1064
  # but at least divmod(-3, 2) equals Cpython's result (-2, 1).
1056
- q = self._copy_2(self._fdivmod2)
1057
- q = q._ftruediv(other, op, **raiser_RESIDUAL).floor
1065
+ q = self._truediv(other, op, **raiser_RESIDUAL).floor
1058
1066
  if q: # == float // other == floor(float / other)
1059
- self -= Fsum(other) * q # NO Fsum2Tuple.__mul__!
1067
+ self -= Fsum(q) * other # NOT other * q!
1060
1068
 
1061
1069
  s = signOf(other) # make signOf(self) == signOf(other)
1062
1070
  if s and self.signOf() == -s: # PYCHOK no cover
@@ -1073,7 +1081,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
1073
1081
  if _isfinite(other):
1074
1082
  return other
1075
1083
  raise ValueError(_not_finite_) if op is None else \
1076
- self._ValueError(op, other, txt=_not_finite_)
1084
+ self._Error(op, other, _ValueError, txt=_not_finite_)
1077
1085
 
1078
1086
  def fint(self, name=NN, **raiser_RESIDUAL):
1079
1087
  '''Return this instance' current running sum as C{integer}.
@@ -1089,7 +1097,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
1089
1097
  @raise ResidualError: Non-zero, significant residual or invalid
1090
1098
  B{C{RESIDUAL}}.
1091
1099
 
1092
- @see: Methods L{Fsum.int_float} and L{Fsum.is_integer}.
1100
+ @see: Methods L{Fsum.fint2}, L{Fsum.int_float} and L{Fsum.is_integer}.
1093
1101
  '''
1094
1102
  i, r = self._fint2
1095
1103
  if r:
@@ -1118,7 +1126,8 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
1118
1126
  '''
1119
1127
  s, r = self._fprs2
1120
1128
  i = int(s)
1121
- r = _fsum(self._ps_1primed(i)) if r else float(s - i)
1129
+ n = _len(self._ps)
1130
+ r = self._ps_1sum(i) if r and n > 1 else _Float(s - i)
1122
1131
  return i, (r or INT0) # Fsum2Tuple?
1123
1132
 
1124
1133
  @deprecated_property_RO
@@ -1131,7 +1140,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
1131
1140
  '''Get this instance' C{floor} (C{int} in Python 3+, but
1132
1141
  C{float} in Python 2-).
1133
1142
 
1134
- @note: The C{floor} takes the C{residual} into account.
1143
+ @note: This C{floor} takes the C{residual} into account.
1135
1144
 
1136
1145
  @see: Method L{Fsum.int_float} and properties L{Fsum.ceil},
1137
1146
  L{Fsum.imag} and L{Fsum.real}.
@@ -1142,7 +1151,8 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
1142
1151
  f -= 1
1143
1152
  return f
1144
1153
 
1145
- # floordiv = __floordiv__ # for naming consistency
1154
+ # ffloordiv = __ifloordiv__ # for naming consistency
1155
+ # floordiv = __floordiv__ # for naming consistency
1146
1156
 
1147
1157
  def _floordiv(self, other, op, **raiser_RESIDUAL): # rather _ffloordiv?
1148
1158
  '''Apply C{B{self} //= B{other}}.
@@ -1150,22 +1160,22 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
1150
1160
  q = self._ftruediv(other, op, **raiser_RESIDUAL) # == self
1151
1161
  return self._fset(q.floor) # floor(q)
1152
1162
 
1153
- fmul = __imul__ # for backward compatibility
1163
+ fmul = __imul__
1154
1164
 
1155
1165
  def _fmul(self, other, op):
1156
1166
  '''(INTERNAL) Apply C{B{self} *= B{other}}.
1157
1167
  '''
1158
1168
  if _isFsumTuple(other):
1159
- if len(self._ps) != 1:
1169
+ if _len(self._ps) != 1:
1160
1170
  f = self._mul_Fsum(other, op)
1161
- elif len(other._ps) != 1: # and len(self._ps) == 1
1171
+ elif _len(other._ps) != 1: # and _len(self._ps) == 1
1162
1172
  f = other._mul_scalar(self._ps[0], op)
1163
- else: # len(other._ps) == len(self._ps) == 1
1173
+ else: # _len(other._ps) == _len(self._ps) == 1
1164
1174
  f = self._finite(self._ps[0] * other._ps[0])
1165
1175
  else:
1166
1176
  s = self._scalar(other, op)
1167
1177
  f = self._mul_scalar(s, op)
1168
- return self._fset(f) # n=len(self) + 1
1178
+ return self._fset(f) # n=_len(self) + 1
1169
1179
 
1170
1180
  def fover(self, over, **raiser_RESIDUAL):
1171
1181
  '''Apply C{B{self} /= B{over}} and summate.
@@ -1182,9 +1192,9 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
1182
1192
 
1183
1193
  @see: Methods L{Fsum.fsum} and L{Fsum.__itruediv__}.
1184
1194
  '''
1185
- return float(self.fdiv(over, **raiser_RESIDUAL)._fprs)
1195
+ return _Float(self.fdiv(over, **raiser_RESIDUAL)._fprs)
1186
1196
 
1187
- fpow = __ipow__ # for backward compatibility
1197
+ fpow = __ipow__
1188
1198
 
1189
1199
  def _fpow(self, other, op, *mod, **raiser_RESIDUAL):
1190
1200
  '''Apply C{B{self} **= B{other}}, optional B{C{mod}} or C{None}.
@@ -1202,7 +1212,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
1202
1212
  f = self._pow(other, other, op, **raiser_RESIDUAL)
1203
1213
  else: # pow(self, other)
1204
1214
  f = self._pow(other, other, op, **raiser_RESIDUAL)
1205
- return self._fset(f, asis=isint(f)) # n=max(len(self), 1)
1215
+ return self._fset(f, as_is=isint(f)) # n=max(_len(self), 1)
1206
1216
 
1207
1217
  @Property_RO
1208
1218
  def _fprs(self):
@@ -1219,40 +1229,40 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
1219
1229
  '''(INTERNAL) Get and cache this instance' precision
1220
1230
  running sum and residual (L{Fsum2Tuple}).
1221
1231
  '''
1222
- ps = self._ps
1223
- n = len(ps) - 2
1224
- if n > 0: # len(ps) > 2
1232
+ ps = self._ps
1233
+ n = _len(ps) - 2
1234
+ if n > 0: # _len(ps) > 2
1225
1235
  s = _psum(ps)
1226
- n = len(ps) - 2
1236
+ n = _len(ps) - 2
1227
1237
  if n > 0:
1228
- r = _fsum(self._ps_1primed(s))
1238
+ r = self._ps_1sum(s)
1229
1239
  return Fsum2Tuple(*_s_r(s, r))
1230
- if n == 0: # len(ps) == 2
1240
+ if n == 0: # _len(ps) == 2
1231
1241
  s, r = _s_r(*_2sum(*ps))
1232
1242
  ps[:] = (r, s) if r else (s,)
1233
- elif ps: # len(ps) == 1
1243
+ elif ps: # _len(ps) == 1
1234
1244
  s, r = ps[0], INT0
1235
- else: # len(ps) == 0
1245
+ else: # _len(ps) == 0
1236
1246
  s, r = _0_0, INT0
1237
1247
  ps[:] = s,
1238
1248
  # assert self._ps is ps
1239
1249
  return Fsum2Tuple(s, r)
1240
1250
 
1241
1251
  def fset_(self, *xs):
1242
- '''Replace this instance' value with C{xs}.
1252
+ '''Replace this instance' value with all positional items.
1243
1253
 
1244
1254
  @arg xs: Optional, new values (each C{scalar} or
1245
1255
  an L{Fsum} or L{Fsum2Tuple} instance),
1246
1256
  all positional.
1247
1257
 
1248
- @return: This instance (C{Fsum}).
1258
+ @return: This instance, replaced (C{Fsum}).
1249
1259
 
1250
1260
  @see: Method L{Fsum.fadd} for further details.
1251
1261
  '''
1252
1262
  f = Fsum(*xs) if xs else _0_0
1253
1263
  return self._fset(f)
1254
1264
 
1255
- def _fset(self, other, asis=True, n=0):
1265
+ def _fset(self, other, as_is=True, n=0, up=True):
1256
1266
  '''(INTERNAL) Overwrite this instance with an other or a C{scalar}.
1257
1267
  '''
1258
1268
  if other is self:
@@ -1261,21 +1271,22 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
1261
1271
  self._ps[:] = other._ps
1262
1272
  self._n = n or other._n
1263
1273
  # self._copy_RESIDUAL(other)
1264
- # use or zap the C{Property_RO} values
1265
- Fsum._fint2._update_from(self, other)
1266
- Fsum._fprs ._update_from(self, other)
1267
- Fsum._fprs2._update_from(self, other)
1274
+ if up: # use or zap the C{Property_RO} values
1275
+ Fsum._fint2._update_from(self, other)
1276
+ Fsum._fprs ._update_from(self, other)
1277
+ Fsum._fprs2._update_from(self, other)
1268
1278
  elif isscalar(other):
1269
- s = other if asis else float(other)
1270
- i = int(s) # see ._fint2
1271
- t = i, ((s - i) or INT0)
1279
+ s = other if as_is else _Float(other)
1272
1280
  self._ps[:] = s,
1273
1281
  self._n = n or 1
1274
- # Property_ROs _fint2, _fprs and _fprs2 can't be a Property:
1275
- # Property's _fset zaps the value just set by the @setter
1276
- self.__dict__.update(_fint2=t, _fprs=s, _fprs2=Fsum2Tuple(s, INT0))
1282
+ if up:
1283
+ i = int(s) # see ._fint2
1284
+ t = i, ((s - i) or INT0)
1285
+ # Property_ROs _fint2, _fprs and _fprs2 can't be a Property:
1286
+ # Property's _fset zaps the value just set by the @setter
1287
+ self.__dict__.update(_fint2=t, _fprs=s, _fprs2=Fsum2Tuple(s, INT0))
1277
1288
  else: # PYCHOK no cover
1278
- raise self._Error(_fset_op_, other, _AssertionError)
1289
+ raise self._Error(_fset_op_, other, _TypeError)
1279
1290
  return self
1280
1291
 
1281
1292
  def _fset_ps(self, other, n=0): # in .fmath
@@ -1290,18 +1301,18 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
1290
1301
  return self
1291
1302
 
1292
1303
  def fsub(self, xs=()):
1293
- '''Subtract all items of an iterable from this instance.
1304
+ '''Subtract an iterable's items from this instance.
1294
1305
 
1295
1306
  @see: Method L{Fsum.fadd} for further details.
1296
1307
  '''
1297
1308
  return self._facc_neg(xs)
1298
1309
 
1299
1310
  def fsub_(self, *xs):
1300
- '''Subtract all positional arguments from this instance.
1311
+ '''Subtract all positional items from this instance.
1301
1312
 
1302
1313
  @see: Method L{Fsum.fadd_} for further details.
1303
1314
  '''
1304
- return self._fsub(xs[0], _sub_op_) if len(xs) == 1 else \
1315
+ return self._fsub(xs[0], _sub_op_) if _len(xs) == 1 else \
1305
1316
  self._facc_neg(xs, origin=1)
1306
1317
 
1307
1318
  def _fsub(self, other, op):
@@ -1309,7 +1320,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
1309
1320
  '''
1310
1321
  if _isFsumTuple(other):
1311
1322
  if other is self: # or other._fprs2 == self._fprs2:
1312
- self._fset(_0_0, n=len(self) * 2)
1323
+ self._fset(_0_0, n=_len(self) * 2)
1313
1324
  elif other._ps:
1314
1325
  self._facc_scalar(other._ps_neg)
1315
1326
  elif self._scalar(other, op):
@@ -1317,8 +1328,8 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
1317
1328
  return self
1318
1329
 
1319
1330
  def fsum(self, xs=()):
1320
- '''Add more items from an iterable, summate and return
1321
- the current precision running sum.
1331
+ '''Add an iterable's items, summate and return the
1332
+ current precision running sum.
1322
1333
 
1323
1334
  @arg xs: Iterable of items to add (each item C{scalar}
1324
1335
  or an L{Fsum} or L{Fsum2Tuple} instance).
@@ -1332,10 +1343,10 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
1332
1343
  return self._facc(xs)._fprs
1333
1344
 
1334
1345
  def fsum_(self, *xs):
1335
- '''Add any positional arguments, summate and return the
1346
+ '''Add any positional items, summate and return the
1336
1347
  current precision running sum.
1337
1348
 
1338
- @arg xs: Values to add (each C{scalar} or an L{Fsum}
1349
+ @arg xs: Items to add (each C{scalar} or an L{Fsum}
1339
1350
  or L{Fsum2Tuple} instance), all positional.
1340
1351
 
1341
1352
  @return: Precision running sum (C{float} or C{int}).
@@ -1345,17 +1356,15 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
1345
1356
  return self._facc_1(xs)._fprs
1346
1357
 
1347
1358
  @property_RO
1348
- def _Fsum(self):
1349
- '''(INTERNAL) Like L{Fsum2Tuple._Fsum}, for C{_2floats}.
1350
- '''
1351
- return self
1359
+ def _Fsum(self): # like L{Fsum2Tuple._Fsum}, for C{_2floats}.
1360
+ return self # NOT @Property_RO, see .copy and ._copy_2
1352
1361
 
1353
1362
  def Fsum_(self, *xs, **name):
1354
1363
  '''Like method L{Fsum.fsum_} but returning a named L{Fsum}.
1355
1364
 
1356
1365
  @kwarg name: Optional name (C{str}).
1357
1366
 
1358
- @return: Current, precision running sum (L{Fsum}).
1367
+ @return: Copy of this updated instance (L{Fsum}).
1359
1368
  '''
1360
1369
  return self._facc_1(xs)._copy_2(self.Fsum_, **name)
1361
1370
 
@@ -1364,12 +1373,12 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
1364
1373
 
1365
1374
  @kwarg name: Optional name (C{str}).
1366
1375
 
1367
- @return: Current, precision running sum (L{Fsum2Tuple}).
1376
+ @return: Precision running sum (L{Fsum2Tuple}).
1368
1377
  '''
1369
1378
  return Fsum2Tuple(self._facc_1(xs)._fprs2, **name)
1370
1379
 
1371
1380
  def fsum2(self, xs=(), name=NN):
1372
- '''Add more items from an iterable, summate and return the
1381
+ '''Add an iterable's items, summate and return the
1373
1382
  current precision running sum I{and} the C{residual}.
1374
1383
 
1375
1384
  @arg xs: Iterable of items to add (each item C{scalar}
@@ -1388,8 +1397,8 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
1388
1397
  return t.dup(name=name) if name else t
1389
1398
 
1390
1399
  def fsum2_(self, *xs):
1391
- '''Add any positional arguments, summate and return the current
1392
- precision running sum I{and} the C{differential}.
1400
+ '''Add any positional items, summate and return the current
1401
+ precision running sum and the I{differential}.
1393
1402
 
1394
1403
  @arg xs: Values to add (each C{scalar} or an L{Fsum} or
1395
1404
  L{Fsum2Tuple} instance), all positional.
@@ -1435,7 +1444,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
1435
1444
  n = _1_0
1436
1445
  if _isFsumTuple(other):
1437
1446
  if other is self or self == other:
1438
- return self._fset(n) # n=len(self)
1447
+ return self._fset(n) # n=_len(self)
1439
1448
  d, r = other._fprs2
1440
1449
  if r:
1441
1450
  R = self._raiser(r, d, **raiser_RESIDUAL)
@@ -1449,13 +1458,13 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
1449
1458
  except Exception as X:
1450
1459
  raise self._ErrorX(X, op, other)
1451
1460
  f = self._mul_scalar(s, _mul_op_) # handles 0, INF, NAN
1452
- return self._fset(f) # asis=False
1461
+ return self._fset(f) # as_is=False
1453
1462
 
1454
1463
  @property_RO
1455
1464
  def imag(self):
1456
1465
  '''Get the C{imaginary} part of this instance (C{0.0}, always).
1457
1466
 
1458
- @see: Properties L{Fsum.ceil}, L{Fsum.floor} and L{Fsum.real}.
1467
+ @see: Property L{Fsum.real}.
1459
1468
  '''
1460
1469
  return _0_0
1461
1470
 
@@ -1484,11 +1493,12 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
1484
1493
  if R:
1485
1494
  t = _stresidual(_non_zero_, r, **R)
1486
1495
  raise ResidualError(int_float=s, txt=t)
1487
- s = float(s) # redundant
1496
+ s = _Float(s) # redundant
1488
1497
  return s
1489
1498
 
1490
1499
  def is_exact(self):
1491
- '''Is this instance' running C{fsum} considered to be exact? (C{bool}).
1500
+ '''Is this instance' running C{fsum} considered to be exact?
1501
+ (C{bool}), C{True} only if the C{residual is }L{INT0}.
1492
1502
  '''
1493
1503
  return self.residual is INT0
1494
1504
 
@@ -1515,13 +1525,15 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
1515
1525
  return 2 if _psum is f else bool(f)
1516
1526
 
1517
1527
  def is_scalar(self, **raiser_RESIDUAL):
1518
- '''Is this instance' running sum C{scalar} with an insignificant
1519
- residual and the residual I{ratio} not exceeding the RESIDUAL
1520
- threshold? (C{bool}).
1528
+ '''Is this instance' running sum C{scalar} without residual or with
1529
+ a residual I{ratio} not exceeding the RESIDUAL threshold?
1521
1530
 
1522
- @kwarg raiser_RESIDUAL: Use C{B{raiser}=False} (C{bool}) to
1523
- ignore L{ResidualError}s and C{B{RESIDUAL}=scalar}
1524
- to override the L{RESIDUAL<Fsum.RESIDUAL>}.
1531
+ @kwarg raiser_RESIDUAL: Use C{B{raiser}=False} (C{bool}) to ignore
1532
+ L{ResidualError}s and C{B{RESIDUAL}=scalar} to override
1533
+ the L{RESIDUAL<Fsum.RESIDUAL>} threshold.
1534
+
1535
+ @return: C{True} if this instance' non-zero residual C{ratio} exceeds
1536
+ the L{RESIDUAL<Fsum.RESIDUAL>} threshold (C{bool}).
1525
1537
 
1526
1538
  @raise ResidualError: Non-zero, significant residual or invalid
1527
1539
  B{C{RESIDUAL}}.
@@ -1537,13 +1549,13 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
1537
1549
  '''
1538
1550
  # assert _isFsumTuple(other)
1539
1551
  if self._ps and other._ps:
1540
- f = self._ps_mul(op, *other._ps) # NO .as_iscalar
1552
+ f = self._ps_mul(op, *other._ps) # NO .as_iscalar!
1541
1553
  else:
1542
1554
  f = _0_0
1543
1555
  return f
1544
1556
 
1545
1557
  def _mul_scalar(self, factor, op): # in .fmath.Fhorner
1546
- '''(INTERNAL) Return C{B{self} * scalar B{factor}} as L{Fsum}, C{0} or C{self}.
1558
+ '''(INTERNAL) Return C{B{self} * scalar B{factor}} as L{Fsum}, C{0.0} or C{self}.
1547
1559
  '''
1548
1560
  # assert isscalar(factor)
1549
1561
  if self._ps and self._finite(factor, op):
@@ -1564,7 +1576,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
1564
1576
  def partials(self):
1565
1577
  '''Get this instance' current, partial sums (C{tuple} of C{float}s).
1566
1578
  '''
1567
- return tuple(self._ps)
1579
+ return _Tuple(self._ps)
1568
1580
 
1569
1581
  def pow(self, x, *mod, **raiser_RESIDUAL):
1570
1582
  '''Return C{B{self}**B{x}} as L{Fsum}.
@@ -1652,7 +1664,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
1652
1664
  '''
1653
1665
  # assert isint(x) and x >= 0
1654
1666
  ps = self._ps
1655
- if len(ps) > 1:
1667
+ if _len(ps) > 1:
1656
1668
  _mul_Fsum = Fsum._mul_Fsum
1657
1669
  if x > 4:
1658
1670
  p = self
@@ -1663,11 +1675,11 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
1663
1675
  if (m & 1):
1664
1676
  f = _mul_Fsum(f, p, op) # f *= p
1665
1677
  m >>= 1 # //= 2
1666
- elif x > 1: # self**2, 3 or 4
1678
+ elif x > 1: # self**2, 3, or 4
1667
1679
  f = _mul_Fsum(self, self, op)
1668
1680
  if x > 2: # self**3 or 4
1669
1681
  p = self if x < 4 else f
1670
- f = _mul_Fsum(f, p, op).as_iscalar
1682
+ f = _mul_Fsum(f, p, op)
1671
1683
  else: # self**1 or self**0 == 1 or _1_0
1672
1684
  f = self._pow_0_1(x, other)
1673
1685
  elif ps: # self._ps[0]**x
@@ -1684,8 +1696,8 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
1684
1696
  if r:
1685
1697
  # assert s != 0
1686
1698
  if isint(x, both=True): # self**int
1687
- x = int(x)
1688
- y = abs(x)
1699
+ x = int(x)
1700
+ y = _abs(x)
1689
1701
  if y > 1:
1690
1702
  f = self._pow_int(y, other, op, **raiser_RESIDUAL)
1691
1703
  if x > 0: # i.e. > 1
@@ -1709,18 +1721,18 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
1709
1721
  if R:
1710
1722
  raise self._ResidualError(op, other, r, **R)
1711
1723
  n, d = self.as_integer_ratio()
1712
- if abs(n) > abs(d):
1724
+ if _abs(n) > _abs(d):
1713
1725
  n, d, x = d, n, (-x)
1714
1726
  s = n / d
1715
1727
  # assert isscalar(s) and isscalar(x)
1716
1728
  return self._pow_2_3(s, x, other, op, **raiser_RESIDUAL)
1717
1729
 
1718
1730
  def _ps_acc(self, ps, xs, up=True, **unused):
1719
- '''(INTERNAL) Accumulate all C{xs} scalars into list C{ps}.
1731
+ '''(INTERNAL) Accumulate C{xs} scalars into list C{ps}.
1720
1732
  '''
1721
1733
  n = 0
1722
1734
  _2s = _2sum
1723
- for x in (tuple(xs) if xs is ps else xs):
1735
+ for x in (_Tuple(xs) if xs is ps else xs):
1724
1736
  # assert isscalar(x) and _isfinite(x)
1725
1737
  if x:
1726
1738
  i = 0
@@ -1733,7 +1745,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
1733
1745
  n += 1
1734
1746
  if n:
1735
1747
  self._n += n
1736
- # Fsum._ps_max = max(Fsum._ps_max, len(ps))
1748
+ # Fsum._ps_max = max(Fsum._ps_max, _len(ps))
1737
1749
  if up:
1738
1750
  self._update()
1739
1751
  return ps
@@ -1743,7 +1755,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
1743
1755
  of the scalar B{C{factors}} and accumulate.
1744
1756
  '''
1745
1757
  def _pfs(ps, fs):
1746
- if len(ps) < len(fs):
1758
+ if _len(ps) < _len(fs):
1747
1759
  ps, fs = fs, ps
1748
1760
  _fin = _isfinite
1749
1761
  for f in fs:
@@ -1760,15 +1772,18 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
1760
1772
  for p in self._ps:
1761
1773
  yield -p
1762
1774
 
1763
- def _ps_1primed(self, *less):
1764
- '''(INTERNAL) Yield partials, 1-primed C{less} any scalars.
1775
+ def _ps_1sum(self, *less):
1776
+ '''(INTERNAL) Return the partials sum, 1-primed C{less} any scalars.
1765
1777
  '''
1766
- yield _1_0
1767
- for p in self._ps:
1768
- yield p
1769
- for p in less:
1770
- yield -p
1771
- yield _N_1_0
1778
+ def _1pls(ps, ls):
1779
+ yield _1_0
1780
+ for p in ps:
1781
+ yield p
1782
+ for p in ls:
1783
+ yield -p
1784
+ yield _N_1_0
1785
+
1786
+ return _fsum(_1pls(self._ps, less))
1772
1787
 
1773
1788
  def _raiser(self, r, s, raiser=True, **RESIDUAL):
1774
1789
  '''(INTERNAL) Does ratio C{r / s} exceed the RESIDUAL threshold
@@ -1793,7 +1808,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
1793
1808
  and properties L{Fsum.ceil}, L{Fsum.floor},
1794
1809
  L{Fsum.imag} and L{Fsum.residual}.
1795
1810
  '''
1796
- return float(self._fprs)
1811
+ return _Float(self._fprs)
1797
1812
 
1798
1813
  @property_RO
1799
1814
  def residual(self):
@@ -1871,7 +1886,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
1871
1886
  '''
1872
1887
  if isscalar(other):
1873
1888
  return other
1874
- raise self._TypeError(op, other, **txt) # _invalid_
1889
+ raise self._Error(op, other, _TypeError, **txt) # _invalid_
1875
1890
 
1876
1891
  def signOf(self, res=True):
1877
1892
  '''Determine the sign of this instance.
@@ -1885,45 +1900,38 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
1885
1900
  r = (-r) if res else 0
1886
1901
  return _signOf(s, r)
1887
1902
 
1888
- def toRepr(self, **prec_sep_fmt_lenc): # PYCHOK signature
1903
+ def toRepr(self, **lenc_prec_sep_fmt): # PYCHOK signature
1889
1904
  '''Return this C{Fsum} instance as representation.
1890
1905
 
1891
- @kwarg prec_sep_fmt_lenc: Optional keyword arguments for
1892
- method L{Fsum2Tuple.toRepr} plus C{B{lenc}=True}
1893
- (C{bool}) to in-/exclude the current C{[len]}
1894
- of this L{Fsum} enclosed in I{[brackets]}.
1906
+ @kwarg lenc_prec_sep_fmt: Optional keyword arguments
1907
+ for method L{Fsum.toStr}.
1895
1908
 
1896
1909
  @return: This instance (C{repr}).
1897
1910
  '''
1898
- return self._toT(self._fprs2.toRepr, **prec_sep_fmt_lenc)
1911
+ return Fmt.repr_at(self, self.toStr(**lenc_prec_sep_fmt))
1899
1912
 
1900
- def toStr(self, **prec_sep_fmt_lenc): # PYCHOK signature
1913
+ def toStr(self, lenc=True, **prec_sep_fmt): # PYCHOK signature
1901
1914
  '''Return this C{Fsum} instance as string.
1902
1915
 
1903
- @kwarg prec_sep_fmt_lenc: Optional keyword arguments for
1904
- method L{Fsum2Tuple.toStr} plus C{B{lenc}=True}
1905
- (C{bool}) to in-/exclude the current C{[len]}
1906
- of this L{Fsum} enclosed in I{[brackets]}.
1916
+ @kwarg lenc: If C{True} include the current C{[len]} of this
1917
+ L{Fsum} enclosed in I{[brackets]} (C{bool}).
1918
+ @kwarg prec_sep_fmt: Optional keyword arguments for method
1919
+ L{Fsum2Tuple.toStr}.
1907
1920
 
1908
1921
  @return: This instance (C{str}).
1909
1922
  '''
1910
- return self._toT(self._fprs2.toStr, **prec_sep_fmt_lenc)
1911
-
1912
- def _toT(self, toT, fmt=Fmt.g, lenc=True, **kwds):
1913
- '''(INTERNAL) Helper for C{toRepr} and C{toStr}.
1914
- '''
1915
1923
  p = self.classname
1916
1924
  if lenc:
1917
- p = Fmt.SQUARE(p, len(self))
1918
- n = self.name
1919
- if n:
1920
- n = _UNDER_(*n.split())
1921
- return NN(p, _SPACE_, n, toT(fmt=fmt, **kwds))
1925
+ p = Fmt.SQUARE(p, _len(self))
1926
+ n = _enquote(self.name, white=_UNDER_)
1927
+ t = self._fprs2.toStr(**prec_sep_fmt)
1928
+ return NN(p, _SPACE_, n, t)
1922
1929
 
1923
- def _TypeError(self, op, other, **txt): # PYCHOK no cover
1924
- '''(INTERNAL) Return a C{TypeError}.
1930
+ def _truediv(self, other, op, **raiser_RESIDUAL):
1931
+ '''(INTERNAL) Return C{B{self} / B{other}} as an L{Fsum}.
1925
1932
  '''
1926
- return self._Error(op, other, _TypeError, **txt)
1933
+ f = self._copy_2(self.__truediv__)
1934
+ return f._ftruediv(other, op, **raiser_RESIDUAL)
1927
1935
 
1928
1936
  def _update(self, updated=True): # see ._fset
1929
1937
  '''(INTERNAL) Zap all cached C{Property_RO} values.
@@ -1937,16 +1945,6 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
1937
1945
  # Fsum._fprs2._update(self)
1938
1946
  return self # for .fset_
1939
1947
 
1940
- def _ValueError(self, op, other, **txt): # PYCHOK no cover
1941
- '''(INTERNAL) Return a C{ValueError}.
1942
- '''
1943
- return self._Error(op, other, _ValueError, **txt)
1944
-
1945
- def _ZeroDivisionError(self, op, other, **txt): # PYCHOK no cover
1946
- '''(INTERNAL) Return a C{ZeroDivisionError}.
1947
- '''
1948
- return self._Error(op, other, _ZeroDivisionError, **txt)
1949
-
1950
1948
  _ROs = _allPropertiesOf_n(3, Fsum, Property_RO) # PYCHOK see Fsum._update
1951
1949
 
1952
1950
 
@@ -1979,6 +1977,44 @@ class Fsum2Tuple(_NamedTuple):
1979
1977
  _Names_ = ( Fsum.fsum.__name__, Fsum.residual.name)
1980
1978
  _Units_ = (_Float_Int, _Float_Int)
1981
1979
 
1980
+ def __abs__(self): # in .fmath
1981
+ return self._Fsum.__abs__()
1982
+
1983
+ def __bool__(self): # PYCHOK Python 3+
1984
+ return bool(self._Fsum)
1985
+
1986
+ def __eq__(self, other):
1987
+ return self._other_op(other, self.__eq__)
1988
+
1989
+ def __float__(self):
1990
+ return self._Fsum.__float__()
1991
+
1992
+ def __ge__(self, other):
1993
+ return self._other_op(other, self.__ge__)
1994
+
1995
+ def __gt__(self, other):
1996
+ return self._other_op(other, self.__gt__)
1997
+
1998
+ def __le__(self, other):
1999
+ return self._other_op(other, self.__le__)
2000
+
2001
+ def __lt__(self, other):
2002
+ return self._other_op(other, self.__lt__)
2003
+
2004
+ def __int__(self):
2005
+ return self._Fsum.__int__()
2006
+
2007
+ def __ne__(self, other):
2008
+ return self._other_op(other, self.__ne__)
2009
+
2010
+ def __neg__(self):
2011
+ return self._Fsum.__neg__()
2012
+
2013
+ __nonzero__ = __bool__ # Python 2-
2014
+
2015
+ def __pos__(self):
2016
+ return self._Fsum.__pos__()
2017
+
1982
2018
  def as_integer_ratio(self):
1983
2019
  '''Return this instance as the ratio of 2 integers.
1984
2020
 
@@ -1988,32 +2024,45 @@ class Fsum2Tuple(_NamedTuple):
1988
2024
 
1989
2025
  @property_RO
1990
2026
  def _fint2(self):
1991
- return self._Fsum.fint2
2027
+ return self._Fsum._fint2
1992
2028
 
1993
2029
  @property_RO
1994
2030
  def _fprs2(self):
1995
2031
  return self._Fsum._fprs2
1996
2032
 
1997
2033
  @Property_RO
1998
- def _Fsum(self):
1999
- return Fsum(*self)
2034
+ def _Fsum(self): # this C{Fsum2Tuple} as L{Fsum}
2035
+ s, r = _s_r(*self)
2036
+ ps = (r, s) if r else (s,)
2037
+ return _Psum(ps, name=self.name)
2038
+
2039
+ def Fsum_(self, *xs, **name_RESIDUAL):
2040
+ '''Return this C{Fsum2Tuple} as an L{Fsum} plus some C{xs}.
2041
+ '''
2042
+ f = _Psum(self._Fsum._ps, **name_RESIDUAL)
2043
+ return f._facc_1(xs, up=False) if xs else f
2000
2044
 
2001
2045
  def is_exact(self):
2002
2046
  '''Is this L{Fsum2Tuple} considered to be exact? (C{bool}).
2003
2047
  '''
2004
- _, r = _s_r(*self)
2005
- return False if r else True
2048
+ return self._Fsum.is_exact()
2006
2049
 
2007
2050
  def is_integer(self):
2008
2051
  '''Is this L{Fsum2Tuple} C{integer}? (C{bool}).
2009
2052
  '''
2010
- s, r = _s_r(*self)
2011
- return False if r else isint(s, both=True)
2053
+ return self._Fsum.is_integer()
2054
+
2055
+ def _mul_scalar(self, other, op): # for Fsum._fmul
2056
+ return self._Fsum._mul_scalar(other, op)
2012
2057
 
2013
2058
  @property_RO
2014
2059
  def _n(self):
2015
2060
  return self._Fsum._n
2016
2061
 
2062
+ def _other_op(self, other, which):
2063
+ C, s = (_Tuple, self) if _isAn(other, _Tuple) else (Fsum, self._Fsum)
2064
+ return getattr(C, which.__name__)(s, other)
2065
+
2017
2066
  @property_RO
2018
2067
  def _ps(self):
2019
2068
  return self._Fsum._ps
@@ -2023,11 +2072,20 @@ class Fsum2Tuple(_NamedTuple):
2023
2072
  return self._Fsum._ps_neg
2024
2073
 
2025
2074
  def signOf(self, **res):
2026
- '''Like L{Fsum.signOf}.
2075
+ '''Like method L{Fsum.signOf}.
2027
2076
  '''
2028
2077
  return self._Fsum.signOf(**res)
2029
2078
 
2030
- _Fsum_Fsum2Tuple_types = Fsum, Fsum2Tuple # PYCHOK line
2079
+ def toStr(self, fmt=Fmt.g, **prec_sep): # PYCHOK signature
2080
+ '''Return this L{Fsum2Tuple} as string (C{str}).
2081
+
2082
+ @kwarg fmt: Optional C{float} format (C{letter}).
2083
+ @kwarg prec_sep: Optional keyword arguments for function
2084
+ L{fstr<streprs.fstr>}.
2085
+ '''
2086
+ return Fmt.PAREN(fstr(self, fmt=fmt, strepr=str, force=False, **prec_sep))
2087
+
2088
+ _Fsum_Fsum2Tuple_types = Fsum, Fsum2Tuple # PYCHOK in .fstats
2031
2089
 
2032
2090
 
2033
2091
  class ResidualError(_ValueError):
@@ -2064,10 +2122,10 @@ except ImportError:
2064
2122
  def fsum(xs, floats=False):
2065
2123
  '''Precision floating point summation based on/like Python's C{math.fsum}.
2066
2124
 
2067
- @arg xs: Iterable of items to add (each C{scalar} or an L{Fsum} or
2068
- L{Fsum2Tuple} instance).
2069
- @kwarg floats: Use C{B{floats}=True} iff I{all} B{C{xs}} items are
2070
- I{known to be scalar} (C{bool}).
2125
+ @arg xs: Iterable of items to add (each C{scalar} or an L{Fsum} or L{Fsum2Tuple}
2126
+ instance).
2127
+ @kwarg floats: Use C{B{floats}=True} iff I{all} B{C{xs}} items are I{known to
2128
+ be scalar} (C{bool}).
2071
2129
 
2072
2130
  @return: Precision C{fsum} (C{float}).
2073
2131
 
@@ -2086,12 +2144,12 @@ def fsum(xs, floats=False):
2086
2144
 
2087
2145
 
2088
2146
  def fsum_(*xs, **floats):
2089
- '''Precision floating point summation of all positional arguments.
2147
+ '''Precision floating point summation of all positional items.
2090
2148
 
2091
- @arg xs: Items to add (each C{scalar} or an L{Fsum} or L{Fsum2Tuple}
2092
- instance), all positional.
2093
- @kwarg floats: Use C{B{floats}=True} iff I{all} B{C{xs}} items are
2094
- I{known to be scalar} (C{bool}).
2149
+ @arg xs: Items to add (each C{scalar} or an L{Fsum} or L{Fsum2Tuple} instance),
2150
+ all positional.
2151
+ @kwarg floats: Use C{B{floats}=True} iff I{all} B{C{xs}} items are I{known to
2152
+ be scalar} (C{bool}).
2095
2153
 
2096
2154
  @see: Function L{fsum<fsums.fsum>} for further details.
2097
2155
  '''
@@ -2110,10 +2168,10 @@ def fsumf_(*xs):
2110
2168
  def fsum1(xs, floats=False):
2111
2169
  '''Precision floating point summation, 1-primed.
2112
2170
 
2113
- @arg xs: Iterable of items to add (each C{scalar} or an L{Fsum} or
2114
- L{Fsum2Tuple} instance).
2115
- @kwarg floats: Use C{B{floats}=True} iff I{all} B{C{xs}} items are
2116
- I{known to be scalar} (C{bool}).
2171
+ @arg xs: Iterable of items to add (each C{scalar} or an L{Fsum} or L{Fsum2Tuple}
2172
+ instance).
2173
+ @kwarg floats: Use C{B{floats}=True} iff I{all} B{C{xs}} items are I{known to
2174
+ be scalar} (C{bool}).
2117
2175
 
2118
2176
  @see: Function L{fsum<fsums.fsum>} for further details.
2119
2177
  '''
@@ -2121,12 +2179,12 @@ def fsum1(xs, floats=False):
2121
2179
 
2122
2180
 
2123
2181
  def fsum1_(*xs, **floats):
2124
- '''Precision floating point summation, 1-primed of all positional arguments.
2182
+ '''Precision floating point summation, 1-primed of all positional items.
2125
2183
 
2126
- @arg xs: Items to add (each C{scalar} or an L{Fsum} or L{Fsum2Tuple}
2127
- instance), all positional.
2128
- @kwarg floats: Use C{B{floats}=True} iff I{all} B{C{xs}} items are
2129
- I{known to be scalar} (C{bool}).
2184
+ @arg xs: Items to add (each C{scalar} or an L{Fsum} or L{Fsum2Tuple} instance),
2185
+ all positional.
2186
+ @kwarg floats: Use C{B{floats}=True} iff I{all} B{C{xs}} items are I{known to
2187
+ be scalar} (C{bool}).
2130
2188
 
2131
2189
  @see: Function L{fsum_<fsums.fsum_>} for further details.
2132
2190
  '''
@@ -2135,7 +2193,7 @@ def fsum1_(*xs, **floats):
2135
2193
 
2136
2194
 
2137
2195
  def fsum1f_(*xs):
2138
- '''Precision floating point summation iff I{all} C{B{xs}} are I{known to be scalar}.
2196
+ '''Precision floating point summation iff I{all} C{B{xs}} items are I{known to be scalar}.
2139
2197
 
2140
2198
  @see: Function L{fsum_<fsums.fsum_>} for further details.
2141
2199
  '''
@@ -2159,7 +2217,7 @@ if __name__ == '__main__':
2159
2217
  F = Fsum()
2160
2218
  if F.is_math_fsum():
2161
2219
  for t in frandoms(n, seeded=True):
2162
- assert float(F.fset_(*t)) == _fsum(t)
2220
+ assert _Float(F.fset_(*t)) == _fsum(t)
2163
2221
  printf(_DOT_, end=NN)
2164
2222
  printf(NN)
2165
2223