not-so-float 1.2.1 → 2.1.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,20 @@ var Union = class {
227
173
  contains(value) {
228
174
  return this.intervals.some((i) => i.contains(value));
229
175
  }
176
+ subset(other) {
177
+ return this.intervals.every(
178
+ (thisInterval) => other.intervals.some((otherInterval) => thisInterval.subset(otherInterval))
179
+ );
180
+ }
181
+ superset(other) {
182
+ return other.intervals.every(
183
+ (otherInterval) => this.intervals.some((thisInterval) => thisInterval.superset(otherInterval))
184
+ );
185
+ }
186
+ hull() {
187
+ if (this.isEmpty()) return EMPTY;
188
+ return single(this.lower(), this.upper());
189
+ }
230
190
  forEach(callback) {
231
191
  this.intervals.forEach(callback);
232
192
  }
@@ -310,10 +270,17 @@ function makeBinaryOpEither(op) {
310
270
  return op(toUnion(A), toUnion(B));
311
271
  };
312
272
  }
273
+ function single(a, b) {
274
+ if (typeof b === "undefined") {
275
+ b = a;
276
+ }
277
+ return union([interval(a, b)]);
278
+ }
313
279
  function bounded(x) {
314
- return new Union([new Interval(prev(x), next(x))]);
280
+ return single(prev(x), next(x));
315
281
  }
316
282
  var EMPTY = new Union([]);
283
+ var FULL = new Union([new Interval(-Infinity, Infinity)]);
317
284
 
318
285
  // src/compare.ts
319
286
  function ioverlap(a, b) {
@@ -471,6 +438,8 @@ function leftDiv(a, b) {
471
438
  if (b === -Infinity) {
472
439
  return Math.sign(-a) * 0;
473
440
  }
441
+ if (b === 1) return a;
442
+ if (b === -1) return -a;
474
443
  return prev(a / b);
475
444
  }
476
445
  function rightDiv(a, b) {
@@ -480,6 +449,8 @@ function rightDiv(a, b) {
480
449
  if (b === -Infinity) {
481
450
  return Math.sign(-a) * 0;
482
451
  }
452
+ if (b === 1) return a;
453
+ if (b === -1) return -a;
483
454
  return next(a / b);
484
455
  }
485
456
  function intervalType(x) {
@@ -499,7 +470,7 @@ function idiv(x, y) {
499
470
  return EMPTY;
500
471
  }
501
472
  if (xType === 5 /* Z */) {
502
- return union([inter(0, 0)]);
473
+ return single(0);
503
474
  }
504
475
  const [a, b] = [x.lo, x.hi];
505
476
  const [c, d] = [y.lo, y.hi];
@@ -521,7 +492,7 @@ function idiv(x, y) {
521
492
  } else if (xType === 1 /* P0 */) {
522
493
  return union([new Interval(0, Infinity)]);
523
494
  } else if (xType === 2 /* M */) {
524
- return union([FULL]);
495
+ return FULL;
525
496
  } else if (xType === 3 /* N0 */) {
526
497
  return union([new Interval(-Infinity, -0)]);
527
498
  } else {
@@ -539,7 +510,7 @@ function idiv(x, y) {
539
510
  new Interval(leftDiv(b, c), Infinity)
540
511
  ]);
541
512
  } else {
542
- return union([FULL]);
513
+ return FULL;
543
514
  }
544
515
  } else if (yType === 3 /* N0 */) {
545
516
  if (xType === 0 /* P1 */) {
@@ -547,7 +518,7 @@ function idiv(x, y) {
547
518
  } else if (xType === 1 /* P0 */) {
548
519
  return union([new Interval(-Infinity, -0)]);
549
520
  } else if (xType === 2 /* M */) {
550
- return union([FULL]);
521
+ return FULL;
551
522
  } else if (xType === 3 /* N0 */) {
552
523
  return union([new Interval(0, Infinity)]);
553
524
  } else {
@@ -575,6 +546,7 @@ function uneg(U) {
575
546
  typeCheckIsUnion(U);
576
547
  return new Union(U.intervals.slice().reverse().map(ineg));
577
548
  }
549
+ var neg = makeUnaryOpEither(uneg);
578
550
  var add = makeBinaryOpEither(uadd);
579
551
  var sub = makeBinaryOpEither(usub);
580
552
  var mul = makeBinaryOpEither(umul);
@@ -664,9 +636,7 @@ function ipowInt(X, n) {
664
636
  } else if (X.hi < 0) {
665
637
  return new Union([new Interval(leftPowInt(X.hi, n), rightPowInt(X.lo, n))]);
666
638
  } else {
667
- return new Union([
668
- new Interval(0, rightPowInt(Math.max(Math.abs(X.hi), Math.abs(X.lo)), n))
669
- ]);
639
+ return new Union([new Interval(0, rightPowInt(Math.max(X.hi, -X.lo), n))]);
670
640
  }
671
641
  }
672
642
  function upowInt(U, n) {
@@ -709,14 +679,84 @@ function usqinv(U) {
709
679
  return union(uneg(x).intervals.concat(x.intervals));
710
680
  }
711
681
  var sqinv = makeUnaryOpEither(usqinv);
682
+ function upowIntInv(U, n) {
683
+ if (n === 0) {
684
+ if (U.contains(1)) return FULL;
685
+ else return EMPTY;
686
+ }
687
+ if (n === 1) {
688
+ return U;
689
+ }
690
+ if (n > 0 && n % 2 === 0) {
691
+ return upowEvenInv(U, n);
692
+ }
693
+ if (n > 0 && n % 2 !== 0) {
694
+ return upowOddInv(U, n);
695
+ }
696
+ if (U.lower() === 0 && U.upper() === 0) {
697
+ return EMPTY;
698
+ }
699
+ const one = new Union([new Interval(1, 1)]);
700
+ return div(one, upowIntInv(U, -n));
701
+ }
702
+ function powIntInv(A, n) {
703
+ typeCheckIsIntervalOrUnion(A);
704
+ return upowIntInv(toUnion(A), n);
705
+ }
706
+ function leftPowOddInv(y, n) {
707
+ if (y === 0) return 0;
708
+ if (y === 1) return 1;
709
+ if (y === -1) return -1;
710
+ else if (y > 0) return prev(Math.pow(y, prev(1 / n)));
711
+ else return prev(-Math.pow(-y, next(1 / n)));
712
+ }
713
+ function rightPowOddInv(y, n) {
714
+ if (y === 0) return 0;
715
+ if (y === 1) return 1;
716
+ if (y === -1) return -1;
717
+ else if (y > 0) return next(Math.pow(y, next(1 / n)));
718
+ else return next(-Math.pow(-y, prev(1 / n)));
719
+ }
720
+ function ipowOddInv(X, n) {
721
+ typeCheckIsInterval(X);
722
+ return new Interval(leftPowOddInv(X.lo, n), rightPowOddInv(X.hi, n));
723
+ }
724
+ function upowOddInv(U, n) {
725
+ typeCheckIsUnion(U);
726
+ return new Union(U.intervals.map((X) => ipowOddInv(X, n)));
727
+ }
728
+ function leftPowEvenInv(y, n) {
729
+ if (y === 0) return 0;
730
+ if (y === 1) return 1;
731
+ return prev(Math.pow(y, prev(1 / n)));
732
+ }
733
+ function rightPowEvenInv(y, n) {
734
+ if (y === 0) return 0;
735
+ if (y === 1) return 1;
736
+ return next(Math.pow(y, next(1 / n)));
737
+ }
738
+ function ipowEvenInv(Y, n) {
739
+ if (Y.hi < 0) {
740
+ return EMPTY;
741
+ } else if (Y.hi === 0) {
742
+ return new Union([new Interval(0, 0)]);
743
+ } else {
744
+ const principal = new Interval(
745
+ leftPowEvenInv(Math.max(0, Y.lo), n),
746
+ rightPowEvenInv(Y.hi, n)
747
+ );
748
+ return new Union([ineg(principal), principal]);
749
+ }
750
+ }
751
+ function upowEvenInv(U, n) {
752
+ typeCheckIsUnion(U);
753
+ return union(U.intervals.map((X) => ipowEvenInv(X, n).intervals).flat());
754
+ }
712
755
 
713
756
  // src/trigonometry.ts
714
757
  var pi = Math.PI;
715
758
  var halfpi = Math.PI / 2;
716
759
  var tau = 2 * Math.PI;
717
- function wrapAngle(angle) {
718
- return (angle % tau + tau) % tau;
719
- }
720
760
  function piMultiples(X) {
721
761
  const lower = Math.ceil(X.lo / Math.PI);
722
762
  const upper = Math.floor(X.hi / Math.PI);
@@ -794,81 +834,28 @@ var tan = makeUnaryOpEither(utan);
794
834
  bounded,
795
835
  complement,
796
836
  cos,
797
- defaultNumbers,
798
837
  disjoint,
799
838
  div,
800
839
  exp,
801
- halfPiMultiples,
802
- iabs,
803
- iadd,
804
- icos,
805
- idisjoint,
806
- idiv,
807
- iexp,
808
- iintersection,
809
- ilog,
810
- imax,
811
- imin,
812
- imul,
813
- ineg,
814
- inter,
815
840
  intersection,
816
841
  interval,
817
- intervalType,
818
- ioverlap,
819
- ipow,
820
- ipowInt,
821
- isIntervalOrUnion,
822
- isin,
823
- isqrt,
824
- isub,
825
- iudisjoint,
826
- iuoverlap,
827
- leftMul,
828
842
  log,
829
- makeBinaryOpEither,
830
- makeBinaryOpUnion,
831
- makeUnaryOpEither,
832
- makeUnaryOpUnion,
833
843
  max,
834
844
  min,
835
845
  mul,
846
+ neg,
836
847
  next,
837
848
  overlap,
838
- piMultiples,
839
849
  pow,
840
850
  powInt,
851
+ powIntInv,
841
852
  prev,
842
- rightMul,
843
853
  sin,
854
+ single,
844
855
  sqinv,
845
856
  sqrt,
846
857
  sub,
847
858
  tan,
848
- toUnion,
849
- typeCheckIsInterval,
850
- typeCheckIsIntervalOrUnion,
851
- typeCheckIsUnion,
852
- uabs,
853
- uadd,
854
- ucomplement,
855
- ucos,
856
- udiv,
857
- uexp,
858
- uintersection,
859
- ulog,
860
- umax,
861
- umin,
862
- umul,
863
- uneg,
864
- union,
865
- upow,
866
- upowInt,
867
- usin,
868
- usqinv,
869
- usqrt,
870
- usub,
871
- utan,
872
- wrapAngle
859
+ union
873
860
  });
874
861
  //# sourceMappingURL=index.cjs.map