1/* 2 * QuickJS Javascript Calculator 3 * 4 * Copyright (c) 2017-2020 Fabrice Bellard 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * of this software and associated documentation files (the "Software"), to deal 8 * in the Software without restriction, including without limitation the rights 9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 * copies of the Software, and to permit persons to whom the Software is 11 * furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in 14 * all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 * THE SOFTWARE. 23 */ 24"use strict"; 25"use math"; 26 27var Integer, Float, Fraction, Complex, Mod, Polynomial, PolyMod, RationalFunction, Series, Matrix; 28 29(function(global) { 30 global.Integer = global.BigInt; 31 global.Float = global.BigFloat; 32 global.algebraicMode = true; 33 34 /* add non enumerable properties */ 35 function add_props(obj, props) { 36 var i, val, prop, tab, desc; 37 tab = Reflect.ownKeys(props); 38 for(i = 0; i < tab.length; i++) { 39 prop = tab[i]; 40 desc = Object.getOwnPropertyDescriptor(props, prop); 41 desc.enumerable = false; 42 if ("value" in desc) { 43 if (typeof desc.value !== "function") { 44 desc.writable = false; 45 desc.configurable = false; 46 } 47 } else { 48 /* getter/setter */ 49 desc.configurable = false; 50 } 51 Object.defineProperty(obj, prop, desc); 52 } 53 } 54 55 /* same as proto[Symbol.operatorSet] = Operators.create(..op_list) 56 but allow shortcuts: left: [], right: [] or both 57 */ 58 function operators_set(proto, ...op_list) 59 { 60 var new_op_list, i, a, j, b, k, obj, tab; 61 var fields = [ "left", "right" ]; 62 new_op_list = []; 63 for(i = 0; i < op_list.length; i++) { 64 a = op_list[i]; 65 if (a.left || a.right) { 66 tab = [ a.left, a.right ]; 67 delete a.left; 68 delete a.right; 69 for(k = 0; k < 2; k++) { 70 obj = tab[k]; 71 if (obj) { 72 if (!Array.isArray(obj)) { 73 obj = [ obj ]; 74 } 75 for(j = 0; j < obj.length; j++) { 76 b = {}; 77 Object.assign(b, a); 78 b[fields[k]] = obj[j]; 79 new_op_list.push(b); 80 } 81 } 82 } 83 } else { 84 new_op_list.push(a); 85 } 86 } 87 proto[Symbol.operatorSet] = 88 Operators.create.call(null, ...new_op_list); 89 } 90 91 /* Integer */ 92 93 function generic_pow(a, b) { 94 var r, is_neg, i; 95 if (!Integer.isInteger(b)) { 96 return exp(log(a) * b); 97 } 98 if (Array.isArray(a) && !(a instanceof Polynomial || 99 a instanceof Series)) { 100 r = idn(Matrix.check_square(a)); 101 } else { 102 r = 1; 103 } 104 if (b == 0) 105 return r; 106 is_neg = false; 107 if (b < 0) { 108 is_neg = true; 109 b = -b; 110 } 111 r = a; 112 for(i = Integer.floorLog2(b) - 1; i >= 0; i--) { 113 r *= r; 114 if ((b >> i) & 1) 115 r *= a; 116 } 117 if (is_neg) { 118 if (typeof r.inverse != "function") 119 throw "negative powers are not supported for this type"; 120 r = r.inverse(); 121 } 122 return r; 123 } 124 125 var small_primes = [ 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499 ]; 126 127 function miller_rabin_test(n, t) { 128 var d, r, s, i, j, a; 129 d = n - 1; 130 s = 0; 131 while ((d & 1) == 0) { 132 d >>= 1; 133 s++; 134 } 135 if (small_primes.length < t) 136 t = small_primes.length; 137 loop: for(j = 0; j < t; j++) { 138 a = small_primes[j]; 139 r = Integer.pmod(a, d, n); 140 if (r == 1 || r == (n - 1)) 141 continue; 142 for(i = 1; i < s; i++) { 143 r = (r * r) % n; 144 if (r == 1) 145 return false; 146 if (r == (n - 1)) 147 continue loop; 148 } 149 return false; /* n is composite */ 150 } 151 return true; /* n is probably prime with probability (1-0.5^t) */ 152 } 153 154 function fact_rec(a, b) { /* assumes a <= b */ 155 var i, r; 156 if ((b - a) <= 5) { 157 r = a; 158 for(i = a + 1; i <= b; i++) 159 r *= i; 160 return r; 161 } else { 162 /* to avoid a quadratic running time it is better to 163 multiply numbers of similar size */ 164 i = (a + b) >> 1; 165 return fact_rec(a, i) * fact_rec(i + 1, b); 166 } 167 } 168 169 /* math mode specific quirk to overload the integer division and power */ 170 Operators.updateBigIntOperators( 171 { 172 "/"(a, b) { 173 if (algebraicMode) { 174 return Fraction.toFraction(a, b); 175 } else { 176 return Float(a) / Float(b); 177 } 178 }, 179 "**"(a, b) { 180 if (algebraicMode) { 181 return generic_pow(a, b); 182 } else { 183 return Float(a) ** Float(b); 184 } 185 } 186 }); 187 188 add_props(Integer, { 189 isInteger(a) { 190 /* integers are represented either as bigint or as number */ 191 return typeof a === "bigint" || 192 (typeof a === "number" && Number.isSafeInteger(a)); 193 }, 194 gcd(a, b) { 195 var r; 196 while (b != 0) { 197 r = a % b; 198 a = b; 199 b = r; 200 } 201 return a; 202 }, 203 fact(n) { 204 return n <= 0 ? 1 : fact_rec(1, n); 205 }, 206 /* binomial coefficient */ 207 comb(n, k) { 208 if (k < 0 || k > n) 209 return 0; 210 if (k > n - k) 211 k = n - k; 212 if (k == 0) 213 return 1; 214 return Integer.tdiv(fact_rec(n - k + 1, n), fact_rec(1, k)); 215 }, 216 /* inverse of x modulo y */ 217 invmod(x, y) { 218 var q, u, v, a, c, t; 219 u = x; 220 v = y; 221 c = 1; 222 a = 0; 223 while (u != 0) { 224 t = Integer.fdivrem(v, u); 225 q = t[0]; 226 v = u; 227 u = t[1]; 228 t = c; 229 c = a - q * c; 230 a = t; 231 } 232 /* v = gcd(x, y) */ 233 if (v != 1) 234 throw RangeError("not invertible"); 235 return a % y; 236 }, 237 /* return a ^ b modulo m */ 238 pmod(a, b, m) { 239 var r; 240 if (b == 0) 241 return 1; 242 if (b < 0) { 243 a = Integer.invmod(a, m); 244 b = -b; 245 } 246 r = 1; 247 for(;;) { 248 if (b & 1) { 249 r = (r * a) % m; 250 } 251 b >>= 1; 252 if (b == 0) 253 break; 254 a = (a * a) % m; 255 } 256 return r; 257 }, 258 259 /* return true if n is prime (or probably prime with 260 probability 1-0.5^t) */ 261 isPrime(n, t) { 262 var i, d, n1; 263 if (!Integer.isInteger(n)) 264 throw TypeError("invalid type"); 265 if (n <= 1) 266 return false; 267 n1 = small_primes.length; 268 /* XXX: need Integer.sqrt() */ 269 for(i = 0; i < n1; i++) { 270 d = small_primes[i]; 271 if (d == n) 272 return true; 273 if (d > n) 274 return false; 275 if ((n % d) == 0) 276 return false; 277 } 278 if (n < d * d) 279 return true; 280 if (typeof t == "undefined") 281 t = 64; 282 return miller_rabin_test(n, t); 283 }, 284 nextPrime(n) { 285 if (!Integer.isInteger(n)) 286 throw TypeError("invalid type"); 287 if (n < 1) 288 n = 1; 289 for(;;) { 290 n++; 291 if (Integer.isPrime(n)) 292 return n; 293 } 294 }, 295 factor(n) { 296 var r, d; 297 if (!Integer.isInteger(n)) 298 throw TypeError("invalid type"); 299 r = []; 300 if (abs(n) <= 1) { 301 r.push(n); 302 return r; 303 } 304 if (n < 0) { 305 r.push(-1); 306 n = -n; 307 } 308 309 while ((n % 2) == 0) { 310 n >>= 1; 311 r.push(2); 312 } 313 314 d = 3; 315 while (n != 1) { 316 if (Integer.isPrime(n)) { 317 r.push(n); 318 break; 319 } 320 /* we are sure there is at least one divisor, so one test */ 321 for(;;) { 322 if ((n % d) == 0) 323 break; 324 d += 2; 325 } 326 for(;;) { 327 r.push(d); 328 n = Integer.tdiv(n, d); 329 if ((n % d) != 0) 330 break; 331 } 332 } 333 return r; 334 }, 335 }); 336 337 add_props(Integer.prototype, { 338 inverse() { 339 return 1 / this; 340 }, 341 norm2() { 342 return this * this; 343 }, 344 abs() { 345 var v = this; 346 if (v < 0) 347 v = -v; 348 return v; 349 }, 350 conj() { 351 return this; 352 }, 353 arg() { 354 if (this >= 0) 355 return 0; 356 else 357 return Float.PI; 358 }, 359 exp() { 360 if (this == 0) 361 return 1; 362 else 363 return Float.exp(this); 364 }, 365 log() { 366 if (this == 1) 367 return 0; 368 else 369 return Float(this).log(); 370 }, 371 }); 372 373 /* Fraction */ 374 375 Fraction = function Fraction(a, b) 376 { 377 var d, r, obj; 378 379 if (new.target) 380 throw TypeError("not a constructor"); 381 if (a instanceof Fraction) 382 return a; 383 if (!Integer.isInteger(a)) 384 throw TypeError("integer expected"); 385 if (typeof b === "undefined") { 386 b = 1; 387 } else { 388 if (!Integer.isInteger(b)) 389 throw TypeError("integer expected"); 390 if (b == 0) 391 throw RangeError("division by zero"); 392 d = Integer.gcd(a, b); 393 if (d != 1) { 394 a = Integer.tdiv(a, d); 395 b = Integer.tdiv(b, d); 396 } 397 398 /* the fractions are normalized with den > 0 */ 399 if (b < 0) { 400 a = -a; 401 b = -b; 402 } 403 } 404 obj = Object.create(Fraction.prototype); 405 obj.num = a; 406 obj.den = b; 407 return obj; 408 } 409 410 function fraction_add(a, b) { 411 a = Fraction(a); 412 b = Fraction(b); 413 return Fraction.toFraction(a.num * b.den + a.den * b.num, a.den * b.den); 414 } 415 function fraction_sub(a, b) { 416 a = Fraction(a); 417 b = Fraction(b); 418 return Fraction.toFraction(a.num * b.den - a.den * b.num, a.den * b.den); 419 } 420 function fraction_mul(a, b) { 421 a = Fraction(a); 422 b = Fraction(b); 423 return Fraction.toFraction(a.num * b.num, a.den * b.den); 424 } 425 function fraction_div(a, b) { 426 a = Fraction(a); 427 b = Fraction(b); 428 return Fraction.toFraction(a.num * b.den, a.den * b.num); 429 } 430 function fraction_mod(a, b) { 431 var a1 = Fraction(a); 432 var b1 = Fraction(b); 433 return a - Integer.ediv(a1.num * b1.den, a1.den * b1.num) * b; 434 } 435 function fraction_eq(a, b) { 436 a = Fraction(a); 437 b = Fraction(b); 438 /* we assume the fractions are normalized */ 439 return (a.num == b.num && a.den == b.den); 440 } 441 function fraction_lt(a, b) { 442 a = Fraction(a); 443 b = Fraction(b); 444 return (a.num * b.den < b.num * a.den); 445 } 446 447 /* operators are needed for fractions */ 448 function float_add(a, b) { 449 return Float(a) + Float(b); 450 } 451 function float_sub(a, b) { 452 return Float(a) - Float(b); 453 } 454 function float_mul(a, b) { 455 return Float(a) * Float(b); 456 } 457 function float_div(a, b) { 458 return Float(a) / Float(b); 459 } 460 function float_mod(a, b) { 461 return Float(a) % Float(b); 462 } 463 function float_pow(a, b) { 464 return Float(a) ** Float(b); 465 } 466 function float_eq(a, b) { 467 /* XXX: may be better to use infinite precision for the comparison */ 468 return Float(a) === Float(b); 469 } 470 function float_lt(a, b) { 471 a = Float(a); 472 b = Float(b); 473 /* XXX: may be better to use infinite precision for the comparison */ 474 if (Float.isNaN(a) || Float.isNaN(b)) 475 return undefined; 476 else 477 return a < b; 478 } 479 480 operators_set(Fraction.prototype, 481 { 482 "+": fraction_add, 483 "-": fraction_sub, 484 "*": fraction_mul, 485 "/": fraction_div, 486 "%": fraction_mod, 487 "**": generic_pow, 488 "==": fraction_eq, 489 "<": fraction_lt, 490 "pos"(a) { 491 return a; 492 }, 493 "neg"(a) { 494 return Fraction(-a.num, a.den); 495 }, 496 }, 497 { 498 left: [Number, BigInt], 499 right: [Number, BigInt], 500 "+": fraction_add, 501 "-": fraction_sub, 502 "*": fraction_mul, 503 "/": fraction_div, 504 "%": fraction_mod, 505 "**": generic_pow, 506 "==": fraction_eq, 507 "<": fraction_lt, 508 }, 509 { 510 left: Float, 511 right: Float, 512 "+": float_add, 513 "-": float_sub, 514 "*": float_mul, 515 "/": float_div, 516 "%": float_mod, 517 "**": float_pow, 518 "==": float_eq, 519 "<": float_lt, 520 }); 521 522 add_props(Fraction, { 523 /* (internal use) simplify 'a' to an integer when possible */ 524 toFraction(a, b) { 525 var r = Fraction(a, b); 526 if (algebraicMode && r.den == 1) 527 return r.num; 528 else 529 return r; 530 }, 531 }); 532 533 add_props(Fraction.prototype, { 534 [Symbol.toPrimitive](hint) { 535 if (hint === "string") { 536 return this.toString(); 537 } else { 538 return Float(this.num) / this.den; 539 } 540 }, 541 inverse() { 542 return Fraction(this.den, this.num); 543 }, 544 toString() { 545 return this.num + "/" + this.den; 546 }, 547 norm2() { 548 return this * this; 549 }, 550 abs() { 551 if (this.num < 0) 552 return -this; 553 else 554 return this; 555 }, 556 conj() { 557 return this; 558 }, 559 arg() { 560 if (this.num >= 0) 561 return 0; 562 else 563 return Float.PI; 564 }, 565 exp() { 566 return Float.exp(Float(this)); 567 }, 568 log() { 569 return Float(this).log(); 570 }, 571 }); 572 573 /* Number (Float64) */ 574 575 add_props(Number.prototype, { 576 inverse() { 577 return 1 / this; 578 }, 579 norm2() { 580 return this * this; 581 }, 582 abs() { 583 return Math.abs(this); 584 }, 585 conj() { 586 return this; 587 }, 588 arg() { 589 if (this >= 0) 590 return 0; 591 else 592 return Float.PI; 593 }, 594 exp() { 595 return Float.exp(this); 596 }, 597 log() { 598 if (this < 0) { 599 return Complex(this).log(); 600 } else { 601 return Float.log(this); 602 } 603 }, 604 }); 605 606 /* Float */ 607 608 var const_tab = []; 609 610 /* we cache the constants for small precisions */ 611 function get_const(n) { 612 var t, c, p; 613 t = const_tab[n]; 614 p = BigFloatEnv.prec; 615 if (t && t.prec == p) { 616 return t.val; 617 } else { 618 switch(n) { 619 case 0: c = Float.exp(1); break; 620 case 1: c = Float.log(10); break; 621// case 2: c = Float.log(2); break; 622 case 3: c = 1/Float.log(2); break; 623 case 4: c = 1/Float.log(10); break; 624// case 5: c = Float.atan(1) * 4; break; 625 case 6: c = Float.sqrt(0.5); break; 626 case 7: c = Float.sqrt(2); break; 627 } 628 if (p <= 1024) { 629 const_tab[n] = { prec: p, val: c }; 630 } 631 return c; 632 } 633 } 634 635 add_props(Float, { 636 isFloat(a) { 637 return typeof a === "number" || typeof a === "bigfloat"; 638 }, 639 bestappr(u, b) { 640 var num1, num0, den1, den0, u, num, den, n; 641 642 if (typeof b === "undefined") 643 throw TypeError("second argument expected"); 644 num1 = 1; 645 num0 = 0; 646 den1 = 0; 647 den0 = 1; 648 for(;;) { 649 n = Integer(Float.floor(u)); 650 num = n * num1 + num0; 651 den = n * den1 + den0; 652 if (den > b) 653 break; 654 u = 1.0 / (u - n); 655 num0 = num1; 656 num1 = num; 657 den0 = den1; 658 den1 = den; 659 } 660 return Fraction(num1, den1); 661 }, 662 /* similar constants as Math.x */ 663 get E() { return get_const(0); }, 664 get LN10() { return get_const(1); }, 665// get LN2() { return get_const(2); }, 666 get LOG2E() { return get_const(3); }, 667 get LOG10E() { return get_const(4); }, 668// get PI() { return get_const(5); }, 669 get SQRT1_2() { return get_const(6); }, 670 get SQRT2() { return get_const(7); }, 671 }); 672 673 add_props(Float.prototype, { 674 inverse() { 675 return 1.0 / this; 676 }, 677 norm2() { 678 return this * this; 679 }, 680 abs() { 681 return Float.abs(this); 682 }, 683 conj() { 684 return this; 685 }, 686 arg() { 687 if (this >= 0) 688 return 0; 689 else 690 return Float.PI; 691 }, 692 exp() { 693 return Float.exp(this); 694 }, 695 log() { 696 if (this < 0) { 697 return Complex(this).log(); 698 } else { 699 return Float.log(this); 700 } 701 }, 702 }); 703 704 /* Complex */ 705 706 Complex = function Complex(re, im) 707 { 708 var obj; 709 if (new.target) 710 throw TypeError("not a constructor"); 711 if (re instanceof Complex) 712 return re; 713 if (typeof im === "undefined") { 714 im = 0; 715 } 716 obj = Object.create(Complex.prototype); 717 obj.re = re; 718 obj.im = im; 719 return obj; 720 } 721 722 723 function complex_add(a, b) { 724 a = Complex(a); 725 b = Complex(b); 726 return Complex.toComplex(a.re + b.re, a.im + b.im); 727 } 728 function complex_sub(a, b) { 729 a = Complex(a); 730 b = Complex(b); 731 return Complex.toComplex(a.re - b.re, a.im - b.im); 732 } 733 function complex_mul(a, b) { 734 a = Complex(a); 735 b = Complex(b); 736 return Complex.toComplex(a.re * b.re - a.im * b.im, 737 a.re * b.im + a.im * b.re); 738 } 739 function complex_div(a, b) { 740 a = Complex(a); 741 b = Complex(b); 742 return a * b.inverse(); 743 } 744 function complex_eq(a, b) { 745 a = Complex(a); 746 b = Complex(b); 747 return a.re == b.re && a.im == b.im; 748 } 749 750 operators_set(Complex.prototype, 751 { 752 "+": complex_add, 753 "-": complex_sub, 754 "*": complex_mul, 755 "/": complex_div, 756 "**": generic_pow, 757 "==": complex_eq, 758 "pos"(a) { 759 return a; 760 }, 761 "neg"(a) { 762 return Complex(-a.re, -a.im); 763 } 764 }, 765 { 766 left: [Number, BigInt, Float, Fraction], 767 right: [Number, BigInt, Float, Fraction], 768 "+": complex_add, 769 "-": complex_sub, 770 "*": complex_mul, 771 "/": complex_div, 772 "**": generic_pow, 773 "==": complex_eq, 774 }); 775 776 add_props(Complex, { 777 /* simplify to real number when possible */ 778 toComplex(re, im) { 779 if (algebraicMode && im == 0) 780 return re; 781 else 782 return Complex(re, im); 783 }, 784 }); 785 786 add_props(Complex.prototype, { 787 inverse() { 788 var c = this.norm2(); 789 return Complex(this.re / c, -this.im / c); 790 }, 791 toString() { 792 var v, s = "", a = this; 793 if (a.re != 0) 794 s += a.re.toString(); 795 if (a.im == 1) { 796 if (s != "") 797 s += "+"; 798 s += "I"; 799 } else if (a.im == -1) { 800 s += "-I"; 801 } else { 802 v = a.im.toString(); 803 if (v[0] != "-" && s != "") 804 s += "+"; 805 s += v + "*I"; 806 } 807 return s; 808 }, 809 norm2() { 810 return this.re * this.re + this.im * this.im; 811 }, 812 abs() { 813 return Float.sqrt(norm2(this)); 814 }, 815 conj() { 816 return Complex(this.re, -this.im); 817 }, 818 arg() { 819 return Float.atan2(this.im, this.re); 820 }, 821 exp() { 822 var arg = this.im, r = this.re.exp(); 823 return Complex(r * cos(arg), r * sin(arg)); 824 }, 825 log() { 826 return Complex(abs(this).log(), atan2(this.im, this.re)); 827 }, 828 }); 829 830 /* Mod */ 831 832 Mod = function Mod(a, m) { 833 var obj, t; 834 if (new.target) 835 throw TypeError("not a constructor"); 836 obj = Object.create(Mod.prototype); 837 if (Integer.isInteger(m)) { 838 if (m <= 0) 839 throw RangeError("the modulo cannot be <= 0"); 840 if (Integer.isInteger(a)) { 841 a %= m; 842 } else if (a instanceof Fraction) { 843 return Mod(a.num, m) / a.den; 844 } else { 845 throw TypeError("invalid types"); 846 } 847 } else { 848 throw TypeError("invalid types"); 849 } 850 obj.res = a; 851 obj.mod = m; 852 return obj; 853 }; 854 855 function mod_add(a, b) { 856 if (!(a instanceof Mod)) { 857 return Mod(a + b.res, b.mod); 858 } else if (!(b instanceof Mod)) { 859 return Mod(a.res + b, a.mod); 860 } else { 861 if (a.mod != b.mod) 862 throw TypeError("different modulo for binary operator"); 863 return Mod(a.res + b.res, a.mod); 864 } 865 } 866 function mod_sub(a, b) { 867 if (!(a instanceof Mod)) { 868 return Mod(a - b.res, b.mod); 869 } else if (!(b instanceof Mod)) { 870 return Mod(a.res - b, a.mod); 871 } else { 872 if (a.mod != b.mod) 873 throw TypeError("different modulo for binary operator"); 874 return Mod(a.res - b.res, a.mod); 875 } 876 } 877 function mod_mul(a, b) { 878 if (!(a instanceof Mod)) { 879 return Mod(a * b.res, b.mod); 880 } else if (!(b instanceof Mod)) { 881 return Mod(a.res * b, a.mod); 882 } else { 883 if (a.mod != b.mod) 884 throw TypeError("different modulo for binary operator"); 885 return Mod(a.res * b.res, a.mod); 886 } 887 } 888 function mod_div(a, b) { 889 if (!(b instanceof Mod)) 890 b = Mod(b, a.mod); 891 return mod_mul(a, b.inverse()); 892 } 893 function mod_eq(a, b) { 894 return (a.mod == b.mod && a.res == b.res); 895 } 896 897 operators_set(Mod.prototype, 898 { 899 "+": mod_add, 900 "-": mod_sub, 901 "*": mod_mul, 902 "/": mod_div, 903 "**": generic_pow, 904 "==": mod_eq, 905 "pos"(a) { 906 return a; 907 }, 908 "neg"(a) { 909 return Mod(-a.res, a.mod); 910 } 911 }, 912 { 913 left: [Number, BigInt, Float, Fraction], 914 right: [Number, BigInt, Float, Fraction], 915 "+": mod_add, 916 "-": mod_sub, 917 "*": mod_mul, 918 "/": mod_div, 919 "**": generic_pow, 920 }); 921 922 add_props(Mod.prototype, { 923 inverse() { 924 var a = this, m = a.mod; 925 if (Integer.isInteger(m)) { 926 return Mod(Integer.invmod(a.res, m), m); 927 } else { 928 throw TypeError("unsupported type"); 929 } 930 }, 931 toString() { 932 return "Mod(" + this.res + "," + this.mod + ")"; 933 }, 934 }); 935 936 /* Polynomial */ 937 938 function polynomial_is_scalar(a) 939 { 940 if (typeof a === "number" || 941 typeof a === "bigint" || 942 typeof a === "bigfloat") 943 return true; 944 if (a instanceof Fraction || 945 a instanceof Complex || 946 a instanceof Mod) 947 return true; 948 return false; 949 } 950 951 Polynomial = function Polynomial(a) 952 { 953 if (new.target) 954 throw TypeError("not a constructor"); 955 if (a instanceof Polynomial) { 956 return a; 957 } else if (Array.isArray(a)) { 958 if (a.length == 0) 959 a = [ 0 ]; 960 Object.setPrototypeOf(a, Polynomial.prototype); 961 return a.trim(); 962 } else if (polynomial_is_scalar(a)) { 963 a = [a]; 964 Object.setPrototypeOf(a, Polynomial.prototype); 965 return a; 966 } else { 967 throw TypeError("invalid type"); 968 } 969 } 970 971 function number_need_paren(c) 972 { 973 return !(Integer.isInteger(c) || 974 Float.isFloat(c) || 975 c instanceof Fraction || 976 (c instanceof Complex && c.re == 0)); 977 } 978 979 /* string for c*X^i */ 980 function monomial_toString(c, i) 981 { 982 var str1; 983 if (i == 0) { 984 str1 = c.toString(); 985 } else { 986 if (c == 1) { 987 str1 = ""; 988 } else if (c == -1) { 989 str1 = "-"; 990 } else { 991 if (number_need_paren(c)) { 992 str1 = "(" + c + ")"; 993 } else { 994 str1 = String(c); 995 } 996 str1 += "*"; 997 } 998 str1 += "X"; 999 if (i != 1) { 1000 str1 += "^" + i; 1001 } 1002 } 1003 return str1; 1004 } 1005 1006 /* find one complex root of 'p' starting from z at precision eps using 1007 at most max_it iterations. Return null if could not find root. */ 1008 function poly_root_laguerre1(p, z, max_it) 1009 { 1010 var p1, p2, i, z0, z1, z2, d, t0, t1, d1, d2, e, el, zl; 1011 1012 d = p.deg(); 1013 if (d == 1) { 1014 /* monomial case */ 1015 return -p[0] / p[1]; 1016 } 1017 /* trivial zero */ 1018 if (p[0] == 0) 1019 return 0.0; 1020 1021 p1 = p.deriv(); 1022 p2 = p1.deriv(); 1023 el = 0.0; 1024 zl = 0.0; 1025 for(i = 0; i < max_it; i++) { 1026 z0 = p.apply(z); 1027 if (z0 == 0) 1028 return z; /* simple exit case */ 1029 1030 /* Ward stopping criteria */ 1031 e = abs(z - zl); 1032// print("e", i, e); 1033 if (i >= 2 && e >= el) { 1034 if (abs(zl) < 1e-4) { 1035 if (e < 1e-7) 1036 return zl; 1037 } else { 1038 if (e < abs(zl) * 1e-3) 1039 return zl; 1040 } 1041 } 1042 el = e; 1043 zl = z; 1044 1045 z1 = p1.apply(z); 1046 z2 = p2.apply(z); 1047 t0 = (d - 1) * z1; 1048 t0 = t0 * t0; 1049 t1 = d * (d - 1) * z0 * z2; 1050 t0 = sqrt(t0 - t1); 1051 d1 = z1 + t0; 1052 d2 = z1 - t0; 1053 if (norm2(d2) > norm2(d1)) 1054 d1 = d2; 1055 if (d1 == 0) 1056 return null; 1057 z = z - d * z0 / d1; 1058 } 1059 return null; 1060 } 1061 1062 function poly_roots(p) 1063 { 1064 var d, i, roots, j, z, eps; 1065 var start_points = [ 0.1, -1.4, 1.7 ]; 1066 1067 if (!(p instanceof Polynomial)) 1068 throw TypeError("polynomial expected"); 1069 d = p.deg(); 1070 if (d <= 0) 1071 return []; 1072 eps = 2.0 ^ (-BigFloatEnv.prec); 1073 roots = []; 1074 for(i = 0; i < d; i++) { 1075 /* XXX: should select another start point if error */ 1076 for(j = 0; j < 3; j++) { 1077 z = poly_root_laguerre1(p, start_points[j], 100); 1078 if (z !== null) 1079 break; 1080 } 1081 if (j == 3) 1082 throw RangeError("error in root finding algorithm"); 1083 roots[i] = z; 1084 p = Polynomial.divrem(p, X - z)[0]; 1085 } 1086 return roots; 1087 } 1088 1089 add_props(Polynomial.prototype, { 1090 trim() { 1091 var a = this, i; 1092 i = a.length; 1093 while (i > 1 && a[i - 1] == 0) 1094 i--; 1095 a.length = i; 1096 return a; 1097 }, 1098 conj() { 1099 var r, i, n, a; 1100 a = this; 1101 n = a.length; 1102 r = []; 1103 for(i = 0; i < n; i++) 1104 r[i] = a[i].conj(); 1105 return Polynomial(r); 1106 }, 1107 inverse() { 1108 return RationalFunction(Polynomial([1]), this); 1109 }, 1110 toString() { 1111 var i, str, str1, c, a = this; 1112 if (a.length == 1) { 1113 return a[0].toString(); 1114 } 1115 str=""; 1116 for(i = a.length - 1; i >= 0; i--) { 1117 c = a[i]; 1118 if (c == 0 || 1119 (c instanceof Mod) && c.res == 0) 1120 continue; 1121 str1 = monomial_toString(c, i); 1122 if (str1[0] != "-") { 1123 if (str != "") 1124 str += "+"; 1125 } 1126 str += str1; 1127 } 1128 return str; 1129 }, 1130 deg() { 1131 if (this.length == 1 && this[0] == 0) 1132 return -Infinity; 1133 else 1134 return this.length - 1; 1135 }, 1136 apply(b) { 1137 var i, n, r, a = this; 1138 n = a.length - 1; 1139 r = a[n]; 1140 while (n > 0) { 1141 n--; 1142 r = r * b + a[n]; 1143 } 1144 return r; 1145 }, 1146 deriv() { 1147 var a = this, n, r, i; 1148 n = a.length; 1149 if (n == 1) { 1150 return Polynomial(0); 1151 } else { 1152 r = []; 1153 for(i = 1; i < n; i++) { 1154 r[i - 1] = i * a[i]; 1155 } 1156 return Polynomial(r); 1157 } 1158 }, 1159 integ() { 1160 var a = this, n, r, i; 1161 n = a.length; 1162 r = [0]; 1163 for(i = 0; i < n; i++) { 1164 r[i + 1] = a[i] / (i + 1); 1165 } 1166 return Polynomial(r); 1167 }, 1168 norm2() { 1169 var a = this, n, r, i; 1170 n = a.length; 1171 r = 0; 1172 for(i = 0; i < n; i++) { 1173 r += a[i].norm2(); 1174 } 1175 return r; 1176 }, 1177 }); 1178 1179 1180 function polynomial_add(a, b) { 1181 var tmp, r, i, n1, n2; 1182 a = Polynomial(a); 1183 b = Polynomial(b); 1184 if (a.length < b.length) { 1185 tmp = a; 1186 a = b; 1187 b = tmp; 1188 } 1189 n1 = b.length; 1190 n2 = a.length; 1191 r = []; 1192 for(i = 0; i < n1; i++) 1193 r[i] = a[i] + b[i]; 1194 for(i = n1; i < n2; i++) 1195 r[i] = a[i]; 1196 return Polynomial(r); 1197 } 1198 function polynomial_sub(a, b) { 1199 return polynomial_add(a, -b); 1200 } 1201 function polynomial_mul(a, b) { 1202 var i, j, n1, n2, n, r; 1203 a = Polynomial(a); 1204 b = Polynomial(b); 1205 n1 = a.length; 1206 n2 = b.length; 1207 n = n1 + n2 - 1; 1208 r = []; 1209 for(i = 0; i < n; i++) 1210 r[i] = 0; 1211 for(i = 0; i < n1; i++) { 1212 for(j = 0; j < n2; j++) { 1213 r[i + j] += a[i] * b[j]; 1214 } 1215 } 1216 return Polynomial(r); 1217 } 1218 function polynomial_div_scalar(a, b) { 1219 return a * (1 / b); 1220 } 1221 function polynomial_div(a, b) 1222 { 1223 return RationalFunction(Polynomial(a), 1224 Polynomial(b)); 1225 } 1226 function polynomial_mod(a, b) { 1227 return Polynomial.divrem(a, b)[1]; 1228 } 1229 function polynomial_eq(a, b) { 1230 var n, i; 1231 n = a.length; 1232 if (n != b.length) 1233 return false; 1234 for(i = 0; i < n; i++) { 1235 if (a[i] != b[i]) 1236 return false; 1237 } 1238 return true; 1239 } 1240 1241 operators_set(Polynomial.prototype, 1242 { 1243 "+": polynomial_add, 1244 "-": polynomial_sub, 1245 "*": polynomial_mul, 1246 "/": polynomial_div, 1247 "**": generic_pow, 1248 "==": polynomial_eq, 1249 "pos"(a) { 1250 return a; 1251 }, 1252 "neg"(a) { 1253 var r, i, n, a; 1254 n = a.length; 1255 r = []; 1256 for(i = 0; i < n; i++) 1257 r[i] = -a[i]; 1258 return Polynomial(r); 1259 }, 1260 }, 1261 { 1262 left: [Number, BigInt, Float, Fraction, Complex, Mod], 1263 "+": polynomial_add, 1264 "-": polynomial_sub, 1265 "*": polynomial_mul, 1266 "/": polynomial_div, 1267 "**": generic_pow, /* XXX: only for integer */ 1268 }, 1269 { 1270 right: [Number, BigInt, Float, Fraction, Complex, Mod], 1271 "+": polynomial_add, 1272 "-": polynomial_sub, 1273 "*": polynomial_mul, 1274 "/": polynomial_div_scalar, 1275 "**": generic_pow, /* XXX: only for integer */ 1276 }); 1277 1278 add_props(Polynomial, { 1279 divrem(a, b) { 1280 var n1, n2, i, j, q, r, n, c; 1281 if (b.deg() < 0) 1282 throw RangeError("division by zero"); 1283 n1 = a.length; 1284 n2 = b.length; 1285 if (n1 < n2) 1286 return [Polynomial([0]), a]; 1287 r = Array.prototype.dup.call(a); 1288 q = []; 1289 n2--; 1290 n = n1 - n2; 1291 for(i = 0; i < n; i++) 1292 q[i] = 0; 1293 for(i = n - 1; i >= 0; i--) { 1294 c = r[i + n2]; 1295 if (c != 0) { 1296 c = c / b[n2]; 1297 r[i + n2] = 0; 1298 for(j = 0; j < n2; j++) { 1299 r[i + j] -= b[j] * c; 1300 } 1301 q[i] = c; 1302 } 1303 } 1304 return [Polynomial(q), Polynomial(r)]; 1305 }, 1306 gcd(a, b) { 1307 var t; 1308 while (b.deg() >= 0) { 1309 t = Polynomial.divrem(a, b); 1310 a = b; 1311 b = t[1]; 1312 } 1313 /* convert to monic form */ 1314 return a / a[a.length - 1]; 1315 }, 1316 invmod(x, y) { 1317 var q, u, v, a, c, t; 1318 u = x; 1319 v = y; 1320 c = Polynomial([1]); 1321 a = Polynomial([0]); 1322 while (u.deg() >= 0) { 1323 t = Polynomial.divrem(v, u); 1324 q = t[0]; 1325 v = u; 1326 u = t[1]; 1327 t = c; 1328 c = a - q * c; 1329 a = t; 1330 } 1331 /* v = gcd(x, y) */ 1332 if (v.deg() > 0) 1333 throw RangeError("not invertible"); 1334 return Polynomial.divrem(a, y)[1]; 1335 }, 1336 roots(p) { 1337 return poly_roots(p); 1338 } 1339 }); 1340 1341 /* Polynomial Modulo Q */ 1342 1343 PolyMod = function PolyMod(a, m) { 1344 var obj, t; 1345 if (new.target) 1346 throw TypeError("not a constructor"); 1347 obj = Object.create(PolyMod.prototype); 1348 if (m instanceof Polynomial) { 1349 if (m.deg() <= 0) 1350 throw RangeError("the modulo cannot have a degree <= 0"); 1351 if (a instanceof RationalFunction) { 1352 return PolyMod(a.num, m) / a.den; 1353 } else { 1354 a = Polynomial(a); 1355 t = Polynomial.divrem(a, m); 1356 a = t[1]; 1357 } 1358 } else { 1359 throw TypeError("invalid types"); 1360 } 1361 obj.res = a; 1362 obj.mod = m; 1363 return obj; 1364 }; 1365 1366 function polymod_add(a, b) { 1367 if (!(a instanceof PolyMod)) { 1368 return PolyMod(a + b.res, b.mod); 1369 } else if (!(b instanceof PolyMod)) { 1370 return PolyMod(a.res + b, a.mod); 1371 } else { 1372 if (a.mod != b.mod) 1373 throw TypeError("different modulo for binary operator"); 1374 return PolyMod(a.res + b.res, a.mod); 1375 } 1376 } 1377 function polymod_sub(a, b) { 1378 return polymod_add(a, -b); 1379 } 1380 function polymod_mul(a, b) { 1381 if (!(a instanceof PolyMod)) { 1382 return PolyMod(a * b.res, b.mod); 1383 } else if (!(b instanceof PolyMod)) { 1384 return PolyMod(a.res * b, a.mod); 1385 } else { 1386 if (a.mod != b.mod) 1387 throw TypeError("different modulo for binary operator"); 1388 return PolyMod(a.res * b.res, a.mod); 1389 } 1390 } 1391 function polymod_div(a, b) { 1392 if (!(b instanceof PolyMod)) 1393 b = PolyMod(b, a.mod); 1394 return polymod_mul(a, b.inverse()); 1395 } 1396 function polymod_eq(a, b) { 1397 return (a.mod == b.mod && a.res == b.res); 1398 } 1399 1400 operators_set(PolyMod.prototype, 1401 { 1402 "+": polymod_add, 1403 "-": polymod_sub, 1404 "*": polymod_mul, 1405 "/": polymod_div, 1406 "**": generic_pow, 1407 "==": polymod_eq, 1408 "pos"(a) { 1409 return a; 1410 }, 1411 "neg"(a) { 1412 return PolyMod(-a.res, a.mod); 1413 }, 1414 }, 1415 { 1416 left: [Number, BigInt, Float, Fraction, Complex, Mod, Polynomial], 1417 right: [Number, BigInt, Float, Fraction, Complex, Mod, Polynomial], 1418 "+": polymod_add, 1419 "-": polymod_sub, 1420 "*": polymod_mul, 1421 "/": polymod_div, 1422 "**": generic_pow, /* XXX: only for integer */ 1423 }); 1424 1425 add_props(PolyMod.prototype, { 1426 inverse() { 1427 var a = this, m = a.mod; 1428 if (m instanceof Polynomial) { 1429 return PolyMod(Polynomial.invmod(a.res, m), m); 1430 } else { 1431 throw TypeError("unsupported type"); 1432 } 1433 }, 1434 toString() { 1435 return "PolyMod(" + this.res + "," + this.mod + ")"; 1436 }, 1437 }); 1438 1439 /* Rational function */ 1440 1441 RationalFunction = function RationalFunction(a, b) 1442 { 1443 var t, r, d, obj; 1444 if (new.target) 1445 throw TypeError("not a constructor"); 1446 if (!(a instanceof Polynomial) || 1447 !(b instanceof Polynomial)) 1448 throw TypeError("polynomial expected"); 1449 t = Polynomial.divrem(a, b); 1450 r = t[1]; 1451 if (r.deg() < 0) 1452 return t[0]; /* no need for a fraction */ 1453 d = Polynomial.gcd(b, r); 1454 if (d.deg() > 0) { 1455 a = Polynomial.divrem(a, d)[0]; 1456 b = Polynomial.divrem(b, d)[0]; 1457 } 1458 obj = Object.create(RationalFunction.prototype); 1459 obj.num = a; 1460 obj.den = b; 1461 return obj; 1462 } 1463 1464 add_props(RationalFunction.prototype, { 1465 inverse() { 1466 return RationalFunction(this.den, this.num); 1467 }, 1468 conj() { 1469 return RationalFunction(this.num.conj(), this.den.conj()); 1470 }, 1471 toString() { 1472 var str; 1473 if (this.num.deg() <= 0 && 1474 !number_need_paren(this.num[0])) 1475 str = this.num.toString(); 1476 else 1477 str = "(" + this.num.toString() + ")"; 1478 str += "/(" + this.den.toString() + ")" 1479 return str; 1480 }, 1481 apply(b) { 1482 return this.num.apply(b) / this.den.apply(b); 1483 }, 1484 deriv() { 1485 var n = this.num, d = this.den; 1486 return RationalFunction(n.deriv() * d - n * d.deriv(), d * d); 1487 }, 1488 }); 1489 1490 function ratfunc_add(a, b) { 1491 a = RationalFunction.toRationalFunction(a); 1492 b = RationalFunction.toRationalFunction(b); 1493 return RationalFunction(a.num * b.den + a.den * b.num, a.den * b.den); 1494 } 1495 function ratfunc_sub(a, b) { 1496 a = RationalFunction.toRationalFunction(a); 1497 b = RationalFunction.toRationalFunction(b); 1498 return RationalFunction(a.num * b.den - a.den * b.num, a.den * b.den); 1499 } 1500 function ratfunc_mul(a, b) { 1501 a = RationalFunction.toRationalFunction(a); 1502 b = RationalFunction.toRationalFunction(b); 1503 return RationalFunction(a.num * b.num, a.den * b.den); 1504 } 1505 function ratfunc_div(a, b) { 1506 a = RationalFunction.toRationalFunction(a); 1507 b = RationalFunction.toRationalFunction(b); 1508 return RationalFunction(a.num * b.den, a.den * b.num); 1509 } 1510 function ratfunc_eq(a, b) { 1511 a = RationalFunction.toRationalFunction(a); 1512 b = RationalFunction.toRationalFunction(b); 1513 /* we assume the fractions are normalized */ 1514 return (a.num == b.num && a.den == b.den); 1515 } 1516 1517 operators_set(RationalFunction.prototype, 1518 { 1519 "+": ratfunc_add, 1520 "-": ratfunc_sub, 1521 "*": ratfunc_mul, 1522 "/": ratfunc_div, 1523 "**": generic_pow, 1524 "==": ratfunc_eq, 1525 "pos"(a) { 1526 return a; 1527 }, 1528 "neg"(a) { 1529 return RationalFunction(-this.num, this.den); 1530 }, 1531 }, 1532 { 1533 left: [Number, BigInt, Float, Fraction, Complex, Mod, Polynomial], 1534 right: [Number, BigInt, Float, Fraction, Complex, Mod, Polynomial], 1535 "+": ratfunc_add, 1536 "-": ratfunc_sub, 1537 "*": ratfunc_mul, 1538 "/": ratfunc_div, 1539 "**": generic_pow, /* should only be used with integers */ 1540 }); 1541 1542 add_props(RationalFunction, { 1543 /* This function always return a RationalFunction object even 1544 if it could simplified to a polynomial, so it is not 1545 equivalent to RationalFunction(a) */ 1546 toRationalFunction(a) { 1547 var obj; 1548 if (a instanceof RationalFunction) { 1549 return a; 1550 } else { 1551 obj = Object.create(RationalFunction.prototype); 1552 obj.num = Polynomial(a); 1553 obj.den = Polynomial(1); 1554 return obj; 1555 } 1556 }, 1557 }); 1558 1559 /* Power series */ 1560 1561 /* 'a' is an array */ 1562 function get_emin(a) { 1563 var i, n; 1564 n = a.length; 1565 for(i = 0; i < n; i++) { 1566 if (a[i] != 0) 1567 return i; 1568 } 1569 return n; 1570 }; 1571 1572 function series_is_scalar_or_polynomial(a) 1573 { 1574 return polynomial_is_scalar(a) || 1575 (a instanceof Polynomial); 1576 } 1577 1578 /* n is the maximum number of terms if 'a' is not a serie */ 1579 Series = function Series(a, n) { 1580 var emin, r, i; 1581 1582 if (a instanceof Series) { 1583 return a; 1584 } else if (series_is_scalar_or_polynomial(a)) { 1585 if (n <= 0) { 1586 /* XXX: should still use the polynomial degree */ 1587 return Series.zero(0, 0); 1588 } else { 1589 a = Polynomial(a); 1590 emin = get_emin(a); 1591 r = Series.zero(n, emin); 1592 n = Math.min(a.length - emin, n); 1593 for(i = 0; i < n; i++) 1594 r[i] = a[i + emin]; 1595 return r; 1596 } 1597 } else if (a instanceof RationalFunction) { 1598 return Series(a.num, n) / a.den; 1599 } else { 1600 throw TypeError("invalid type"); 1601 } 1602 }; 1603 1604 function series_add(v1, v2) { 1605 var tmp, d, emin, n, r, i, j, v2_emin, c1, c2; 1606 if (!(v1 instanceof Series)) { 1607 tmp = v1; 1608 v1 = v2; 1609 v2 = tmp; 1610 } 1611 d = v1.emin + v1.length; 1612 if (series_is_scalar_or_polynomial(v2)) { 1613 v2 = Polynomial(v2); 1614 if (d <= 0) 1615 return v1; 1616 v2_emin = 0; 1617 } else if (v2 instanceof RationalFunction) { 1618 /* compute the emin of the rational fonction */ 1619 i = get_emin(v2.num) - get_emin(v2.den); 1620 if (d <= i) 1621 return v1; 1622 /* compute the serie with the required terms */ 1623 v2 = Series(v2, d - i); 1624 v2_emin = v2.emin; 1625 } else { 1626 v2_emin = v2.emin; 1627 d = Math.min(d, v2_emin + v2.length); 1628 } 1629 emin = Math.min(v1.emin, v2_emin); 1630 n = d - emin; 1631 r = Series.zero(n, emin); 1632 /* XXX: slow */ 1633 for(i = emin; i < d; i++) { 1634 j = i - v1.emin; 1635 if (j >= 0 && j < v1.length) 1636 c1 = v1[j]; 1637 else 1638 c1 = 0; 1639 j = i - v2_emin; 1640 if (j >= 0 && j < v2.length) 1641 c2 = v2[j]; 1642 else 1643 c2 = 0; 1644 r[i - emin] = c1 + c2; 1645 } 1646 return r.trim(); 1647 } 1648 function series_sub(a, b) { 1649 return series_add(a, -b); 1650 } 1651 function series_mul(v1, v2) { 1652 var n, i, j, r, n, emin, n1, n2, k; 1653 if (!(v1 instanceof Series)) 1654 v1 = Series(v1, v2.length); 1655 else if (!(v2 instanceof Series)) 1656 v2 = Series(v2, v1.length); 1657 emin = v1.emin + v2.emin; 1658 n = Math.min(v1.length, v2.length); 1659 n1 = v1.length; 1660 n2 = v2.length; 1661 r = Series.zero(n, emin); 1662 for(i = 0; i < n1; i++) { 1663 k = Math.min(n2, n - i); 1664 for(j = 0; j < k; j++) { 1665 r[i + j] += v1[i] * v2[j]; 1666 } 1667 } 1668 return r.trim(); 1669 } 1670 function series_div(v1, v2) { 1671 if (!(v2 instanceof Series)) 1672 v2 = Series(v2, v1.length); 1673 return series_mul(v1, v2.inverse()); 1674 } 1675 function series_pow(a, b) { 1676 if (Integer.isInteger(b)) { 1677 return generic_pow(a, b); 1678 } else { 1679 if (!(a instanceof Series)) 1680 a = Series(a, b.length); 1681 return exp(log(a) * b); 1682 } 1683 } 1684 function series_eq(a, b) { 1685 var n, i; 1686 if (a.emin != b.emin) 1687 return false; 1688 n = a.length; 1689 if (n != b.length) 1690 return false; 1691 for(i = 0; i < n; i++) { 1692 if (a[i] != b[i]) 1693 return false; 1694 } 1695 return true; 1696 } 1697 1698 operators_set(Series.prototype, 1699 { 1700 "+": series_add, 1701 "-": series_sub, 1702 "*": series_mul, 1703 "/": series_div, 1704 "**": series_pow, 1705 "==": series_eq, 1706 "pos"(a) { 1707 return a; 1708 }, 1709 "neg"(a) { 1710 var obj, n, i; 1711 n = a.length; 1712 obj = Series.zero(a.length, a.emin); 1713 for(i = 0; i < n; i++) { 1714 obj[i] = -a[i]; 1715 } 1716 return obj; 1717 }, 1718 }, 1719 { 1720 left: [Number, BigInt, Float, Fraction, Complex, Mod, Polynomial], 1721 right: [Number, BigInt, Float, Fraction, Complex, Mod, Polynomial], 1722 "+": series_add, 1723 "-": series_sub, 1724 "*": series_mul, 1725 "/": series_div, 1726 "**": series_pow, 1727 }); 1728 1729 add_props(Series.prototype, { 1730 conj() { 1731 var obj, n, i; 1732 n = this.length; 1733 obj = Series.zero(this.length, this.emin); 1734 for(i = 0; i < n; i++) { 1735 obj[i] = this[i].conj(); 1736 } 1737 return obj; 1738 }, 1739 inverse() { 1740 var r, n, i, j, sum, v1 = this; 1741 n = v1.length; 1742 if (n == 0) 1743 throw RangeError("division by zero"); 1744 r = Series.zero(n, -v1.emin); 1745 r[0] = 1 / v1[0]; 1746 for(i = 1; i < n; i++) { 1747 sum = 0; 1748 for(j = 1; j <= i; j++) { 1749 sum += v1[j] * r[i - j]; 1750 } 1751 r[i] = -sum * r[0]; 1752 } 1753 return r; 1754 }, 1755 /* remove leading zero terms */ 1756 trim() { 1757 var i, j, n, r, v1 = this; 1758 n = v1.length; 1759 i = 0; 1760 while (i < n && v1[i] == 0) 1761 i++; 1762 if (i == 0) 1763 return v1; 1764 for(j = i; j < n; j++) 1765 v1[j - i] = v1[j]; 1766 v1.length = n - i; 1767 v1.__proto__.emin += i; 1768 return v1; 1769 }, 1770 toString() { 1771 var i, j, str, str1, c, a = this, emin, n; 1772 str=""; 1773 emin = this.emin; 1774 n = this.length; 1775 for(j = 0; j < n; j++) { 1776 i = j + emin; 1777 c = a[j]; 1778 if (c != 0) { 1779 str1 = monomial_toString(c, i); 1780 if (str1[0] != "-") { 1781 if (str != "") 1782 str += "+"; 1783 } 1784 str += str1; 1785 } 1786 } 1787 if (str != "") 1788 str += "+"; 1789 str += "O(" + monomial_toString(1, n + emin) + ")"; 1790 return str; 1791 }, 1792 apply(b) { 1793 var i, n, r, a = this; 1794 n = a.length; 1795 if (n == 0) 1796 return 0; 1797 r = a[--n]; 1798 while (n > 0) { 1799 n--; 1800 r = r * b + a[n]; 1801 } 1802 if (a.emin != 0) 1803 r *= b ^ a.emin; 1804 return r; 1805 }, 1806 deriv() { 1807 var a = this, n = a.length, emin = a.emin, r, i, j; 1808 if (n == 0 && emin == 0) { 1809 return Series.zero(0, 0); 1810 } else { 1811 r = Series.zero(n, emin - 1); 1812 for(i = 0; i < n; i++) { 1813 j = emin + i; 1814 if (j == 0) 1815 r[i] = 0; 1816 else 1817 r[i] = j * a[i]; 1818 } 1819 return r.trim(); 1820 } 1821 }, 1822 integ() { 1823 var a = this, n = a.length, emin = a.emin, i, j, r; 1824 r = Series.zero(n, emin + 1); 1825 for(i = 0; i < n; i++) { 1826 j = emin + i; 1827 if (j == -1) { 1828 if (a[i] != 0) 1829 throw RangError("cannot represent integ(1/X)"); 1830 } else { 1831 r[i] = a[i] / (j + 1); 1832 } 1833 } 1834 return r.trim(); 1835 }, 1836 exp() { 1837 var c, i, r, n, a = this; 1838 if (a.emin < 0) 1839 throw RangeError("negative exponent in exp"); 1840 n = a.emin + a.length; 1841 if (a.emin > 0 || a[0] == 0) { 1842 c = 1; 1843 } else { 1844 c = global.exp(a[0]); 1845 a -= a[0]; 1846 } 1847 r = Series.zero(n, 0); 1848 for(i = 0; i < n; i++) { 1849 r[i] = c / fact(i); 1850 } 1851 return r.apply(a); 1852 }, 1853 log() { 1854 var a = this, r; 1855 if (a.emin != 0) 1856 throw Range("log argument must have a non zero constant term"); 1857 r = integ(deriv(a) / a); 1858 /* add the constant term */ 1859 r += global.log(a[0]); 1860 return r; 1861 }, 1862 }); 1863 1864 add_props(Series, { 1865 /* new series of length n and first exponent emin */ 1866 zero(n, emin) { 1867 var r, i, obj; 1868 1869 r = []; 1870 for(i = 0; i < n; i++) 1871 r[i] = 0; 1872 /* we return an array and store emin in its prototype */ 1873 obj = Object.create(Series.prototype); 1874 obj.emin = emin; 1875 Object.setPrototypeOf(r, obj); 1876 return r; 1877 }, 1878 O(a) { 1879 function ErrorO() { 1880 return TypeError("invalid O() argument"); 1881 } 1882 var n; 1883 if (series_is_scalar_or_polynomial(a)) { 1884 a = Polynomial(a); 1885 n = a.deg(); 1886 if (n < 0) 1887 throw ErrorO(); 1888 } else if (a instanceof RationalFunction) { 1889 if (a.num.deg() != 0) 1890 throw ErrorO(); 1891 n = a.den.deg(); 1892 if (n < 0) 1893 throw ErrorO(); 1894 n = -n; 1895 } else 1896 throw ErrorO(); 1897 return Series.zero(0, n); 1898 }, 1899 }); 1900 1901 /* Array (Matrix) */ 1902 1903 Matrix = function Matrix(h, w) { 1904 var i, j, r, rl; 1905 if (typeof w === "undefined") 1906 w = h; 1907 r = []; 1908 for(i = 0; i < h; i++) { 1909 rl = []; 1910 for(j = 0; j < w; j++) 1911 rl[j] = 0; 1912 r[i] = rl; 1913 } 1914 return r; 1915 }; 1916 1917 add_props(Matrix, { 1918 idn(n) { 1919 var r, i; 1920 r = Matrix(n, n); 1921 for(i = 0; i < n; i++) 1922 r[i][i] = 1; 1923 return r; 1924 }, 1925 diag(a) { 1926 var r, i, n; 1927 n = a.length; 1928 r = Matrix(n, n); 1929 for(i = 0; i < n; i++) 1930 r[i][i] = a[i]; 1931 return r; 1932 }, 1933 hilbert(n) { 1934 var i, j, r; 1935 r = Matrix(n); 1936 for(i = 0; i < n; i++) { 1937 for(j = 0; j < n; j++) { 1938 r[i][j] = 1 / (1 + i + j); 1939 } 1940 } 1941 return r; 1942 }, 1943 trans(a) { 1944 var h, w, r, i, j; 1945 if (!Array.isArray(a)) 1946 throw TypeError("matrix expected"); 1947 h = a.length; 1948 if (!Array.isArray(a[0])) { 1949 w = 1; 1950 r = Matrix(w, h); 1951 for(i = 0; i < h; i++) { 1952 r[0][i] = a[i]; 1953 } 1954 } else { 1955 w = a[0].length; 1956 r = Matrix(w, h); 1957 for(i = 0; i < h; i++) { 1958 for(j = 0; j < w; j++) { 1959 r[j][i] = a[i][j]; 1960 } 1961 } 1962 } 1963 return r; 1964 }, 1965 check_square(a) { 1966 var a, n; 1967 if (!Array.isArray(a)) 1968 throw TypeError("array expected"); 1969 n = a.length; 1970 if (!Array.isArray(a[0]) || n != a[0].length) 1971 throw TypeError("square matrix expected"); 1972 return n; 1973 }, 1974 trace(a) { 1975 var n, r, i; 1976 n = Matrix.check_square(a); 1977 r = a[0][0]; 1978 for(i = 1; i < n; i++) { 1979 r += a[i][i]; 1980 } 1981 return r; 1982 }, 1983 charpoly(a) { 1984 var n, p, c, i, j, coef; 1985 n = Matrix.check_square(a); 1986 p = []; 1987 for(i = 0; i < n + 1; i++) 1988 p[i] = 0; 1989 p[n] = 1; 1990 c = Matrix.idn(n); 1991 for(i = 0; i < n; i++) { 1992 c = c * a; 1993 coef = -trace(c) / (i + 1); 1994 p[n - i - 1] = coef; 1995 for(j = 0; j < n; j++) 1996 c[j][j] += coef; 1997 } 1998 return Polynomial(p); 1999 }, 2000 eigenvals(a) { 2001 return Polynomial.roots(Matrix.charpoly(a)); 2002 }, 2003 det(a) { 2004 var n, i, j, k, s, src, v, c; 2005 2006 n = Matrix.check_square(a); 2007 s = 1; 2008 src = a.dup(); 2009 for(i=0;i<n;i++) { 2010 for(j = i; j < n; j++) { 2011 if (src[j][i] != 0) 2012 break; 2013 } 2014 if (j == n) 2015 return 0; 2016 if (j != i) { 2017 for(k = 0;k < n; k++) { 2018 v = src[j][k]; 2019 src[j][k] = src[i][k]; 2020 src[i][k] = v; 2021 } 2022 s = -s; 2023 } 2024 c = src[i][i].inverse(); 2025 for(j = i + 1; j < n; j++) { 2026 v = c * src[j][i]; 2027 for(k = 0;k < n; k++) { 2028 src[j][k] -= src[i][k] * v; 2029 } 2030 } 2031 } 2032 c = s; 2033 for(i=0;i<n;i++) 2034 c *= src[i][i]; 2035 return c; 2036 }, 2037 inverse(a) { 2038 var n, dst, src, i, j, k, n2, r, c, v; 2039 n = Matrix.check_square(a); 2040 src = a.dup(); 2041 dst = Matrix.idn(n); 2042 for(i=0;i<n;i++) { 2043 for(j = i; j < n; j++) { 2044 if (src[j][i] != 0) 2045 break; 2046 } 2047 if (j == n) 2048 throw RangeError("matrix is not invertible"); 2049 if (j != i) { 2050 /* swap lines in src and dst */ 2051 v = src[j]; 2052 src[j] = src[i]; 2053 src[i] = v; 2054 v = dst[j]; 2055 dst[j] = dst[i]; 2056 dst[i] = v; 2057 } 2058 2059 c = src[i][i].inverse(); 2060 for(k = 0; k < n; k++) { 2061 src[i][k] *= c; 2062 dst[i][k] *= c; 2063 } 2064 2065 for(j = 0; j < n; j++) { 2066 if (j != i) { 2067 c = src[j][i]; 2068 for(k = i; k < n; k++) { 2069 src[j][k] -= src[i][k] * c; 2070 } 2071 for(k = 0; k < n; k++) { 2072 dst[j][k] -= dst[i][k] * c; 2073 } 2074 } 2075 } 2076 } 2077 return dst; 2078 }, 2079 rank(a) { 2080 var src, i, j, k, w, h, l, c; 2081 2082 if (!Array.isArray(a) || 2083 !Array.isArray(a[0])) 2084 throw TypeError("matrix expected"); 2085 h = a.length; 2086 w = a[0].length; 2087 src = a.dup(); 2088 l = 0; 2089 for(i=0;i<w;i++) { 2090 for(j = l; j < h; j++) { 2091 if (src[j][i] != 0) 2092 break; 2093 } 2094 if (j == h) 2095 continue; 2096 if (j != l) { 2097 /* swap lines */ 2098 for(k = 0; k < w; k++) { 2099 v = src[j][k]; 2100 src[j][k] = src[l][k]; 2101 src[l][k] = v; 2102 } 2103 } 2104 2105 c = src[l][i].inverse(); 2106 for(k = 0; k < w; k++) { 2107 src[l][k] *= c; 2108 } 2109 2110 for(j = l + 1; j < h; j++) { 2111 c = src[j][i]; 2112 for(k = i; k < w; k++) { 2113 src[j][k] -= src[l][k] * c; 2114 } 2115 } 2116 l++; 2117 } 2118 return l; 2119 }, 2120 ker(a) { 2121 var src, i, j, k, w, h, l, m, r, im_cols, ker_dim, c; 2122 2123 if (!Array.isArray(a) || 2124 !Array.isArray(a[0])) 2125 throw TypeError("matrix expected"); 2126 h = a.length; 2127 w = a[0].length; 2128 src = a.dup(); 2129 im_cols = []; 2130 l = 0; 2131 for(i=0;i<w;i++) { 2132 im_cols[i] = false; 2133 for(j = l; j < h; j++) { 2134 if (src[j][i] != 0) 2135 break; 2136 } 2137 if (j == h) 2138 continue; 2139 im_cols[i] = true; 2140 if (j != l) { 2141 /* swap lines */ 2142 for(k = 0; k < w; k++) { 2143 v = src[j][k]; 2144 src[j][k] = src[l][k]; 2145 src[l][k] = v; 2146 } 2147 } 2148 2149 c = src[l][i].inverse(); 2150 for(k = 0; k < w; k++) { 2151 src[l][k] *= c; 2152 } 2153 2154 for(j = 0; j < h; j++) { 2155 if (j != l) { 2156 c = src[j][i]; 2157 for(k = i; k < w; k++) { 2158 src[j][k] -= src[l][k] * c; 2159 } 2160 } 2161 } 2162 l++; 2163 // log_str("m=" + cval_toString(v1) + "\n"); 2164 } 2165 // log_str("im cols="+im_cols+"\n"); 2166 2167 /* build the kernel vectors */ 2168 ker_dim = w - l; 2169 r = Matrix(w, ker_dim); 2170 k = 0; 2171 for(i = 0; i < w; i++) { 2172 if (!im_cols[i]) { 2173 /* select this column from the matrix */ 2174 l = 0; 2175 m = 0; 2176 for(j = 0; j < w; j++) { 2177 if (im_cols[j]) { 2178 r[j][k] = -src[m][i]; 2179 m++; 2180 } else { 2181 if (l == k) { 2182 r[j][k] = 1; 2183 } else { 2184 r[j][k] = 0; 2185 } 2186 l++; 2187 } 2188 } 2189 k++; 2190 } 2191 } 2192 return r; 2193 }, 2194 dp(a, b) { 2195 var i, n, r; 2196 n = a.length; 2197 if (n != b.length) 2198 throw TypeError("incompatible array length"); 2199 /* XXX: could do complex product */ 2200 r = 0; 2201 for(i = 0; i < n; i++) { 2202 r += a[i] * b[i]; 2203 } 2204 return r; 2205 }, 2206 /* cross product */ 2207 cp(v1, v2) { 2208 var r; 2209 if (v1.length != 3 || v2.length != 3) 2210 throw TypeError("vectors must have 3 elements"); 2211 r = []; 2212 r[0] = v1[1] * v2[2] - v1[2] * v2[1]; 2213 r[1] = v1[2] * v2[0] - v1[0] * v2[2]; 2214 r[2] = v1[0] * v2[1] - v1[1] * v2[0]; 2215 return r; 2216 }, 2217 }); 2218 2219 function array_add(a, b) { 2220 var r, i, n; 2221 n = a.length; 2222 if (n != b.length) 2223 throw TypeError("incompatible array size"); 2224 r = []; 2225 for(i = 0; i < n; i++) 2226 r[i] = a[i] + b[i]; 2227 return r; 2228 } 2229 function array_sub(a, b) { 2230 var r, i, n; 2231 n = a.length; 2232 if (n != b.length) 2233 throw TypeError("incompatible array size"); 2234 r = []; 2235 for(i = 0; i < n; i++) 2236 r[i] = a[i] - b[i]; 2237 return r; 2238 } 2239 function array_scalar_mul(a, b) { 2240 var r, i, n; 2241 n = a.length; 2242 r = []; 2243 for(i = 0; i < n; i++) 2244 r[i] = a[i] * b; 2245 return r; 2246 } 2247 function array_mul(a, b) { 2248 var h, w, l, i, j, k, r, rl, sum, a_mat, b_mat; 2249 h = a.length; 2250 a_mat = Array.isArray(a[0]); 2251 if (a_mat) { 2252 l = a[0].length; 2253 } else { 2254 l = 1; 2255 } 2256 if (l != b.length) 2257 throw RangeError("incompatible matrix size"); 2258 b_mat = Array.isArray(b[0]); 2259 if (b_mat) 2260 w = b[0].length; 2261 else 2262 w = 1; 2263 r = []; 2264 if (a_mat && b_mat) { 2265 for(i = 0; i < h; i++) { 2266 rl = []; 2267 for(j = 0; j < w; j++) { 2268 sum = 0; 2269 for(k = 0; k < l; k++) { 2270 sum += a[i][k] * b[k][j]; 2271 } 2272 rl[j] = sum; 2273 } 2274 r[i] = rl; 2275 } 2276 } else if (a_mat && !b_mat) { 2277 for(i = 0; i < h; i++) { 2278 sum = 0; 2279 for(k = 0; k < l; k++) { 2280 sum += a[i][k] * b[k]; 2281 } 2282 r[i] = sum; 2283 } 2284 } else if (!a_mat && b_mat) { 2285 for(i = 0; i < h; i++) { 2286 rl = []; 2287 for(j = 0; j < w; j++) { 2288 rl[j] = a[i] * b[0][j]; 2289 } 2290 r[i] = rl; 2291 } 2292 } else { 2293 for(i = 0; i < h; i++) { 2294 r[i] = a[i] * b[0]; 2295 } 2296 } 2297 return r; 2298 } 2299 function array_div(a, b) { 2300 return array_mul(a, b.inverse()); 2301 } 2302 function array_scalar_div(a, b) { 2303 return a * b.inverse(); 2304 } 2305 function array_eq(a, b) { 2306 var n, i; 2307 n = a.length; 2308 if (n != b.length) 2309 return false; 2310 for(i = 0; i < n; i++) { 2311 if (a[i] != b[i]) 2312 return false; 2313 } 2314 return true; 2315 } 2316 2317 operators_set(Array.prototype, 2318 { 2319 "+": array_add, 2320 "-": array_sub, 2321 "*": array_mul, 2322 "/": array_div, 2323 "==": array_eq, 2324 "pos"(a) { 2325 return a; 2326 }, 2327 "neg"(a) { 2328 var i, n, r; 2329 n = a.length; 2330 r = []; 2331 for(i = 0; i < n; i++) 2332 r[i] = -a[i]; 2333 return r; 2334 } 2335 }, 2336 { 2337 right: [Number, BigInt, Float, Fraction, Complex, Mod, 2338 Polynomial, PolyMod, RationalFunction, Series], 2339 "*": array_scalar_mul, 2340 "/": array_scalar_div, 2341 "**": generic_pow, /* XXX: only for integer */ 2342 }, 2343 { 2344 left: [Number, BigInt, Float, Fraction, Complex, Mod, 2345 Polynomial, PolyMod, RationalFunction, Series], 2346 "*"(a, b) { return array_scalar_mul(b, a); }, 2347 "/"(a, b) { return array_scalar_div(b, a); }, 2348 }); 2349 2350 add_props(Array.prototype, { 2351 conj() { 2352 var i, n, r; 2353 n = this.length; 2354 r = []; 2355 for(i = 0; i < n; i++) 2356 r[i] = this[i].conj(); 2357 return r; 2358 }, 2359 dup() { 2360 var r, i, n, el, a = this; 2361 r = []; 2362 n = a.length; 2363 for(i = 0; i < n; i++) { 2364 el = a[i]; 2365 if (Array.isArray(el)) 2366 el = el.dup(); 2367 r[i] = el; 2368 } 2369 return r; 2370 }, 2371 inverse() { 2372 return Matrix.inverse(this); 2373 }, 2374 norm2: Polynomial.prototype.norm2, 2375 }); 2376 2377})(this); 2378 2379/* global definitions */ 2380var I = Complex(0, 1); 2381var X = Polynomial([0, 1]); 2382var O = Series.O; 2383 2384Object.defineProperty(this, "PI", { get: function () { return Float.PI } }); 2385 2386/* put frequently used functions in the global context */ 2387var gcd = Integer.gcd; 2388var fact = Integer.fact; 2389var comb = Integer.comb; 2390var pmod = Integer.pmod; 2391var invmod = Integer.invmod; 2392var factor = Integer.factor; 2393var isprime = Integer.isPrime; 2394var nextprime = Integer.nextPrime; 2395 2396function deriv(a) 2397{ 2398 return a.deriv(); 2399} 2400 2401function integ(a) 2402{ 2403 return a.integ(); 2404} 2405 2406function norm2(a) 2407{ 2408 return a.norm2(); 2409} 2410 2411function abs(a) 2412{ 2413 return a.abs(); 2414} 2415 2416function conj(a) 2417{ 2418 return a.conj(); 2419} 2420 2421function arg(a) 2422{ 2423 return a.arg(); 2424} 2425 2426function inverse(a) 2427{ 2428 return a.inverse(); 2429} 2430 2431function trunc(a) 2432{ 2433 if (Integer.isInteger(a)) { 2434 return a; 2435 } else if (a instanceof Fraction) { 2436 return Integer.tdiv(a.num, a.den); 2437 } else if (a instanceof Polynomial) { 2438 return a; 2439 } else if (a instanceof RationalFunction) { 2440 return Polynomial.divrem(a.num, a.den)[0]; 2441 } else { 2442 return Float.ceil(a); 2443 } 2444} 2445 2446function floor(a) 2447{ 2448 if (Integer.isInteger(a)) { 2449 return a; 2450 } else if (a instanceof Fraction) { 2451 return Integer.fdiv(a.num, a.den); 2452 } else { 2453 return Float.floor(a); 2454 } 2455} 2456 2457function ceil(a) 2458{ 2459 if (Integer.isInteger(a)) { 2460 return a; 2461 } else if (a instanceof Fraction) { 2462 return Integer.cdiv(a.num, a.den); 2463 } else { 2464 return Float.ceil(a); 2465 } 2466} 2467 2468function sqrt(a) 2469{ 2470 var t, u, re, im; 2471 if (a instanceof Series) { 2472 return a ^ (1/2); 2473 } else if (a instanceof Complex) { 2474 t = abs(a); 2475 u = a.re; 2476 re = sqrt((t + u) / 2); 2477 im = sqrt((t - u) / 2); 2478 if (a.im < 0) 2479 im = -im; 2480 return Complex.toComplex(re, im); 2481 } else { 2482 a = Float(a); 2483 if (a < 0) { 2484 return Complex(0, Float.sqrt(-a)); 2485 } else { 2486 return Float.sqrt(a); 2487 } 2488 } 2489} 2490 2491function exp(a) 2492{ 2493 return a.exp(); 2494} 2495 2496function log(a) 2497{ 2498 return a.log(); 2499} 2500 2501function log2(a) 2502{ 2503 return log(a) * Float.LOG2E; 2504} 2505 2506function log10(a) 2507{ 2508 return log(a) * Float.LOG10E; 2509} 2510 2511function todb(a) 2512{ 2513 return log10(a) * 10; 2514} 2515 2516function fromdb(a) 2517{ 2518 return 10 ^ (a / 10); 2519} 2520 2521function sin(a) 2522{ 2523 var t; 2524 if (a instanceof Complex || a instanceof Series) { 2525 t = exp(a * I); 2526 return (t - 1/t) / (2 * I); 2527 } else { 2528 return Float.sin(Float(a)); 2529 } 2530} 2531 2532function cos(a) 2533{ 2534 var t; 2535 if (a instanceof Complex || a instanceof Series) { 2536 t = exp(a * I); 2537 return (t + 1/t) / 2; 2538 } else { 2539 return Float.cos(Float(a)); 2540 } 2541} 2542 2543function tan(a) 2544{ 2545 if (a instanceof Complex || a instanceof Series) { 2546 return sin(a) / cos(a); 2547 } else { 2548 return Float.tan(Float(a)); 2549 } 2550} 2551 2552function asin(a) 2553{ 2554 return Float.asin(Float(a)); 2555} 2556 2557function acos(a) 2558{ 2559 return Float.acos(Float(a)); 2560} 2561 2562function atan(a) 2563{ 2564 return Float.atan(Float(a)); 2565} 2566 2567function atan2(a, b) 2568{ 2569 return Float.atan2(Float(a), Float(b)); 2570} 2571 2572function sinc(a) 2573{ 2574 if (a == 0) { 2575 return 1; 2576 } else { 2577 a *= Float.PI; 2578 return sin(a) / a; 2579 } 2580} 2581 2582function todeg(a) 2583{ 2584 return a * 180 / Float.PI; 2585} 2586 2587function fromdeg(a) 2588{ 2589 return a * Float.PI / 180; 2590} 2591 2592function sinh(a) 2593{ 2594 var e = Float.exp(Float(a)); 2595 return (e - 1/e) * 0.5; 2596} 2597 2598function cosh(a) 2599{ 2600 var e = Float.exp(Float(a)); 2601 return (e + 1/e) * 0.5; 2602} 2603 2604function tanh(a) 2605{ 2606 var e = Float.exp(Float(a) * 2); 2607 return (e - 1) / (e + 1); 2608} 2609 2610function asinh(a) 2611{ 2612 var x = Float(a); 2613 return log(sqrt(x * x + 1) + x); 2614} 2615 2616function acosh(a) 2617{ 2618 var x = Float(a); 2619 return log(sqrt(x * x - 1) + x); 2620} 2621 2622function atanh(a) 2623{ 2624 var x = Float(a); 2625 return 0.5 * log((1 + x) / (1 - x)); 2626} 2627 2628var idn = Matrix.idn; 2629var diag = Matrix.diag; 2630var trans = Matrix.trans; 2631var trace = Matrix.trace; 2632var charpoly = Matrix.charpoly; 2633var eigenvals = Matrix.eigenvals; 2634var det = Matrix.det; 2635var rank = Matrix.rank; 2636var ker = Matrix.ker; 2637var cp = Matrix.cp; 2638var dp = Matrix.dp; 2639 2640var polroots = Polynomial.roots; 2641var bestappr = Float.bestappr; 2642