not-so-float 1.2.0 → 2.0.0

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.
package/README.md CHANGED
@@ -15,9 +15,9 @@ Arithmetic** over IEEE 754 double precision floats (JS numbers).
15
15
  ```typescript
16
16
  import * as nsf from "not-so-float";
17
17
 
18
- const X = nsf.union([nsf.inter(-10, -1), nsf.inter(100, 120)]);
19
- const Y = nsf.union([nsf.inter(-10, 2)]);
20
- const Q = nsf.udiv(X, Y);
18
+ const X = nsf.union([nsf.interval(-10, -1), nsf.interval(100, 120)]);
19
+ const Y = nsf.union([nsf.interval(-10, 2)]);
20
+ const Q = nsf.div(X, Y);
21
21
 
22
22
  console.log(`(${X.toString()}) / ${Y.toString()} = ${Q.toString()}`);
23
23
  ```
@@ -112,16 +112,16 @@ interval represents:
112
112
  Where $a$ and $b$ are real IEEE 754 values (not infinite).
113
113
  The special case when both bounds are equal is called a _degenerate_ interval.
114
114
 
115
- To construct an interval, use the `nsf.inter()` function:
115
+ To construct an interval, use the `nsf.interval()` function:
116
116
 
117
117
  ```typescript
118
- nsf.inter(a: number, b: number) : Interval
118
+ nsf.interval(a: number, b: number) : Interval
119
119
  ```
120
120
 
121
121
  For example:
122
122
 
123
123
  ```typescript
124
- > I = nsf.inter(0, 6)
124
+ > I = nsf.interval(0, 6)
125
125
  Interval { lo: 0, hi: 6 }
126
126
  ```
127
127
 
@@ -133,6 +133,7 @@ class Interval {
133
133
  isFinite(): boolean;
134
134
  isDegenerate(): boolean;
135
135
  contains(value: number): boolean;
136
+ hull(): Union;
136
137
  superset(other: Interval): boolean;
137
138
  subset(other: Interval): boolean;
138
139
  toString(numbers?: (x: number) => string): string;
@@ -179,6 +180,17 @@ For example:
179
180
  [ Interval { lo: 1, hi: 2 }, Interval { lo: 4, hi: 6 } ]
180
181
  ```
181
182
 
183
+ You can also use the shorthand `nsf.single()` to construct a singleton, i.e. a union with a single interval:
184
+
185
+ ```typescript
186
+ const U = nsf.single(-0.1, 0.1);
187
+ ```
188
+
189
+ Constants are also provided:
190
+
191
+ - `FULL`: all real numbers
192
+ - `EMPTY`: the empty union
193
+
182
194
  ## Set theory
183
195
 
184
196
  Compare and compute intervals and unions with the following implementations of
@@ -244,5 +256,3 @@ function complement(A: Union | Interval): Union;
244
256
  ## Future improvements
245
257
 
246
258
  - Support multiple rounding modes
247
- - Add shortcut function for `nsf.union(nsf.inter([x]))`
248
- - Change FULL constant to Union
package/dist/index.cjs CHANGED
@@ -29,82 +29,29 @@ __export(index_exports, {
29
29
  bounded: () => bounded,
30
30
  complement: () => complement,
31
31
  cos: () => cos,
32
- defaultNumbers: () => defaultNumbers,
33
32
  disjoint: () => disjoint,
34
33
  div: () => div,
35
34
  exp: () => exp,
36
- halfPiMultiples: () => halfPiMultiples,
37
- iabs: () => iabs,
38
- iadd: () => iadd,
39
- icos: () => icos,
40
- idisjoint: () => idisjoint,
41
- idiv: () => idiv,
42
- iexp: () => iexp,
43
- iintersection: () => iintersection,
44
- ilog: () => ilog,
45
- imax: () => imax,
46
- imin: () => imin,
47
- imul: () => imul,
48
- ineg: () => ineg,
49
- inter: () => inter,
50
35
  intersection: () => intersection,
51
36
  interval: () => interval,
52
- intervalType: () => intervalType,
53
- ioverlap: () => ioverlap,
54
- ipow: () => ipow,
55
- ipowInt: () => ipowInt,
56
- isIntervalOrUnion: () => isIntervalOrUnion,
57
- isin: () => isin,
58
- isqrt: () => isqrt,
59
- isub: () => isub,
60
- iudisjoint: () => iudisjoint,
61
- iuoverlap: () => iuoverlap,
62
- leftMul: () => leftMul,
63
37
  log: () => log,
64
- makeBinaryOpEither: () => makeBinaryOpEither,
65
- makeBinaryOpUnion: () => makeBinaryOpUnion,
66
- makeUnaryOpEither: () => makeUnaryOpEither,
67
- makeUnaryOpUnion: () => makeUnaryOpUnion,
68
38
  max: () => max,
69
39
  min: () => min,
70
40
  mul: () => mul,
41
+ neg: () => neg,
71
42
  next: () => next,
72
43
  overlap: () => overlap,
73
- piMultiples: () => piMultiples,
74
44
  pow: () => pow,
75
45
  powInt: () => powInt,
46
+ powIntInv: () => powIntInv,
76
47
  prev: () => prev,
77
- rightMul: () => rightMul,
78
48
  sin: () => sin,
49
+ single: () => single,
79
50
  sqinv: () => sqinv,
80
51
  sqrt: () => sqrt,
81
52
  sub: () => sub,
82
53
  tan: () => tan,
83
- toUnion: () => toUnion,
84
- typeCheckIsInterval: () => typeCheckIsInterval,
85
- typeCheckIsIntervalOrUnion: () => typeCheckIsIntervalOrUnion,
86
- typeCheckIsUnion: () => typeCheckIsUnion,
87
- uabs: () => uabs,
88
- uadd: () => uadd,
89
- ucomplement: () => ucomplement,
90
- ucos: () => ucos,
91
- udiv: () => udiv,
92
- uexp: () => uexp,
93
- uintersection: () => uintersection,
94
- ulog: () => ulog,
95
- umax: () => umax,
96
- umin: () => umin,
97
- umul: () => umul,
98
- uneg: () => uneg,
99
- union: () => union,
100
- upow: () => upow,
101
- upowInt: () => upowInt,
102
- usin: () => usin,
103
- usqinv: () => usqinv,
104
- usqrt: () => usqrt,
105
- usub: () => usub,
106
- utan: () => utan,
107
- wrapAngle: () => wrapAngle
54
+ union: () => union
108
55
  });
109
56
  module.exports = __toCommonJS(index_exports);
110
57
 
@@ -196,14 +143,13 @@ function interval(a, b) {
196
143
  }
197
144
  return new Interval(a, b);
198
145
  }
199
- var inter = interval;
200
- var FULL = new Interval(-Infinity, Infinity);
201
146
  function typeCheckIsInterval(x) {
202
147
  if (!(x instanceof Interval)) {
203
148
  throw TypeError(`Argument must be an interval (got type ${typeof x})`);
204
149
  }
205
150
  return true;
206
151
  }
152
+ var IFULL = new Interval(-Infinity, Infinity);
207
153
 
208
154
  // src/union.ts
209
155
  var Union = class {
@@ -227,6 +173,10 @@ var Union = class {
227
173
  contains(value) {
228
174
  return this.intervals.some((i) => i.contains(value));
229
175
  }
176
+ hull() {
177
+ if (this.isEmpty()) return EMPTY;
178
+ return single(this.lower(), this.upper());
179
+ }
230
180
  forEach(callback) {
231
181
  this.intervals.forEach(callback);
232
182
  }
@@ -310,10 +260,17 @@ function makeBinaryOpEither(op) {
310
260
  return op(toUnion(A), toUnion(B));
311
261
  };
312
262
  }
263
+ function single(a, b) {
264
+ if (typeof b === "undefined") {
265
+ b = a;
266
+ }
267
+ return union([interval(a, b)]);
268
+ }
313
269
  function bounded(x) {
314
- return new Union([new Interval(prev(x), next(x))]);
270
+ return single(prev(x), next(x));
315
271
  }
316
272
  var EMPTY = new Union([]);
273
+ var FULL = new Union([new Interval(-Infinity, Infinity)]);
317
274
 
318
275
  // src/compare.ts
319
276
  function ioverlap(a, b) {
@@ -471,6 +428,8 @@ function leftDiv(a, b) {
471
428
  if (b === -Infinity) {
472
429
  return Math.sign(-a) * 0;
473
430
  }
431
+ if (b === 1) return a;
432
+ if (b === -1) return -a;
474
433
  return prev(a / b);
475
434
  }
476
435
  function rightDiv(a, b) {
@@ -480,6 +439,8 @@ function rightDiv(a, b) {
480
439
  if (b === -Infinity) {
481
440
  return Math.sign(-a) * 0;
482
441
  }
442
+ if (b === 1) return a;
443
+ if (b === -1) return -a;
483
444
  return next(a / b);
484
445
  }
485
446
  function intervalType(x) {
@@ -499,7 +460,7 @@ function idiv(x, y) {
499
460
  return EMPTY;
500
461
  }
501
462
  if (xType === 5 /* Z */) {
502
- return union([inter(0, 0)]);
463
+ return single(0);
503
464
  }
504
465
  const [a, b] = [x.lo, x.hi];
505
466
  const [c, d] = [y.lo, y.hi];
@@ -521,7 +482,7 @@ function idiv(x, y) {
521
482
  } else if (xType === 1 /* P0 */) {
522
483
  return union([new Interval(0, Infinity)]);
523
484
  } else if (xType === 2 /* M */) {
524
- return union([FULL]);
485
+ return FULL;
525
486
  } else if (xType === 3 /* N0 */) {
526
487
  return union([new Interval(-Infinity, -0)]);
527
488
  } else {
@@ -539,7 +500,7 @@ function idiv(x, y) {
539
500
  new Interval(leftDiv(b, c), Infinity)
540
501
  ]);
541
502
  } else {
542
- return union([FULL]);
503
+ return FULL;
543
504
  }
544
505
  } else if (yType === 3 /* N0 */) {
545
506
  if (xType === 0 /* P1 */) {
@@ -547,7 +508,7 @@ function idiv(x, y) {
547
508
  } else if (xType === 1 /* P0 */) {
548
509
  return union([new Interval(-Infinity, -0)]);
549
510
  } else if (xType === 2 /* M */) {
550
- return union([FULL]);
511
+ return FULL;
551
512
  } else if (xType === 3 /* N0 */) {
552
513
  return union([new Interval(0, Infinity)]);
553
514
  } else {
@@ -575,6 +536,7 @@ function uneg(U) {
575
536
  typeCheckIsUnion(U);
576
537
  return new Union(U.intervals.slice().reverse().map(ineg));
577
538
  }
539
+ var neg = makeUnaryOpEither(uneg);
578
540
  var add = makeBinaryOpEither(uadd);
579
541
  var sub = makeBinaryOpEither(usub);
580
542
  var mul = makeBinaryOpEither(umul);
@@ -658,13 +620,13 @@ function ipowInt(X, n) {
658
620
  throw Error(`ipowint: exponent must be an integer, got ${n}`);
659
621
  }
660
622
  if (n < 0) return idiv(new Interval(1, 1), ipowInt(X, -n).intervals[0]);
661
- if (n === 0) return new Union([X]);
623
+ if (n === 0) return new Union([new Interval(1, 1)]);
662
624
  if (X.lo > 0 || n % 2 !== 0) {
663
625
  return new Union([new Interval(leftPowInt(X.lo, n), rightPowInt(X.hi, n))]);
664
626
  } else if (X.hi < 0) {
665
627
  return new Union([new Interval(leftPowInt(X.hi, n), rightPowInt(X.lo, n))]);
666
628
  } else {
667
- return new Union([new Interval(0, rightPowInt(Math.abs(X.lo), n))]);
629
+ return new Union([new Interval(0, rightPowInt(Math.max(X.hi, -X.lo), n))]);
668
630
  }
669
631
  }
670
632
  function upowInt(U, n) {
@@ -707,14 +669,84 @@ function usqinv(U) {
707
669
  return union(uneg(x).intervals.concat(x.intervals));
708
670
  }
709
671
  var sqinv = makeUnaryOpEither(usqinv);
672
+ function upowIntInv(U, n) {
673
+ if (n === 0) {
674
+ if (U.contains(1)) return FULL;
675
+ else return EMPTY;
676
+ }
677
+ if (n === 1) {
678
+ return U;
679
+ }
680
+ if (n > 0 && n % 2 === 0) {
681
+ return upowEvenInv(U, n);
682
+ }
683
+ if (n > 0 && n % 2 !== 0) {
684
+ return upowOddInv(U, n);
685
+ }
686
+ if (U.lower() === 0 && U.upper() === 0) {
687
+ return EMPTY;
688
+ }
689
+ const one = new Union([new Interval(1, 1)]);
690
+ return div(one, upowIntInv(U, -n));
691
+ }
692
+ function powIntInv(A, n) {
693
+ typeCheckIsIntervalOrUnion(A);
694
+ return upowIntInv(toUnion(A), n);
695
+ }
696
+ function leftPowOddInv(y, n) {
697
+ if (y === 0) return 0;
698
+ if (y === 1) return 1;
699
+ if (y === -1) return -1;
700
+ else if (y > 0) return prev(Math.pow(y, prev(1 / n)));
701
+ else return prev(-Math.pow(-y, next(1 / n)));
702
+ }
703
+ function rightPowOddInv(y, n) {
704
+ if (y === 0) return 0;
705
+ if (y === 1) return 1;
706
+ if (y === -1) return -1;
707
+ else if (y > 0) return next(Math.pow(y, next(1 / n)));
708
+ else return next(-Math.pow(-y, prev(1 / n)));
709
+ }
710
+ function ipowOddInv(X, n) {
711
+ typeCheckIsInterval(X);
712
+ return new Interval(leftPowOddInv(X.lo, n), rightPowOddInv(X.hi, n));
713
+ }
714
+ function upowOddInv(U, n) {
715
+ typeCheckIsUnion(U);
716
+ return new Union(U.intervals.map((X) => ipowOddInv(X, n)));
717
+ }
718
+ function leftPowEvenInv(y, n) {
719
+ if (y === 0) return 0;
720
+ if (y === 1) return 1;
721
+ return prev(Math.pow(y, prev(1 / n)));
722
+ }
723
+ function rightPowEvenInv(y, n) {
724
+ if (y === 0) return 0;
725
+ if (y === 1) return 1;
726
+ return next(Math.pow(y, next(1 / n)));
727
+ }
728
+ function ipowEvenInv(Y, n) {
729
+ if (Y.hi < 0) {
730
+ return EMPTY;
731
+ } else if (Y.hi === 0) {
732
+ return new Union([new Interval(0, 0)]);
733
+ } else {
734
+ const principal = new Interval(
735
+ leftPowEvenInv(Math.max(0, Y.lo), n),
736
+ rightPowEvenInv(Y.hi, n)
737
+ );
738
+ return new Union([ineg(principal), principal]);
739
+ }
740
+ }
741
+ function upowEvenInv(U, n) {
742
+ typeCheckIsUnion(U);
743
+ return union(U.intervals.map((X) => ipowEvenInv(X, n).intervals).flat());
744
+ }
710
745
 
711
746
  // src/trigonometry.ts
712
747
  var pi = Math.PI;
713
748
  var halfpi = Math.PI / 2;
714
749
  var tau = 2 * Math.PI;
715
- function wrapAngle(angle) {
716
- return (angle % tau + tau) % tau;
717
- }
718
750
  function piMultiples(X) {
719
751
  const lower = Math.ceil(X.lo / Math.PI);
720
752
  const upper = Math.floor(X.hi / Math.PI);
@@ -792,81 +824,28 @@ var tan = makeUnaryOpEither(utan);
792
824
  bounded,
793
825
  complement,
794
826
  cos,
795
- defaultNumbers,
796
827
  disjoint,
797
828
  div,
798
829
  exp,
799
- halfPiMultiples,
800
- iabs,
801
- iadd,
802
- icos,
803
- idisjoint,
804
- idiv,
805
- iexp,
806
- iintersection,
807
- ilog,
808
- imax,
809
- imin,
810
- imul,
811
- ineg,
812
- inter,
813
830
  intersection,
814
831
  interval,
815
- intervalType,
816
- ioverlap,
817
- ipow,
818
- ipowInt,
819
- isIntervalOrUnion,
820
- isin,
821
- isqrt,
822
- isub,
823
- iudisjoint,
824
- iuoverlap,
825
- leftMul,
826
832
  log,
827
- makeBinaryOpEither,
828
- makeBinaryOpUnion,
829
- makeUnaryOpEither,
830
- makeUnaryOpUnion,
831
833
  max,
832
834
  min,
833
835
  mul,
836
+ neg,
834
837
  next,
835
838
  overlap,
836
- piMultiples,
837
839
  pow,
838
840
  powInt,
841
+ powIntInv,
839
842
  prev,
840
- rightMul,
841
843
  sin,
844
+ single,
842
845
  sqinv,
843
846
  sqrt,
844
847
  sub,
845
848
  tan,
846
- toUnion,
847
- typeCheckIsInterval,
848
- typeCheckIsIntervalOrUnion,
849
- typeCheckIsUnion,
850
- uabs,
851
- uadd,
852
- ucomplement,
853
- ucos,
854
- udiv,
855
- uexp,
856
- uintersection,
857
- ulog,
858
- umax,
859
- umin,
860
- umul,
861
- uneg,
862
- union,
863
- upow,
864
- upowInt,
865
- usin,
866
- usqinv,
867
- usqrt,
868
- usub,
869
- utan,
870
- wrapAngle
849
+ union
871
850
  });
872
851
  //# sourceMappingURL=index.cjs.map