simple-squiggle

A restricted subset of Squiggle
Log | Files | Refs | README

nthRoots.js (3610B)


      1 "use strict";
      2 
      3 Object.defineProperty(exports, "__esModule", {
      4   value: true
      5 });
      6 exports.createNthRoots = void 0;
      7 
      8 var _factory = require("../../utils/factory.js");
      9 
     10 var name = 'nthRoots';
     11 var dependencies = ['config', 'typed', 'divideScalar', 'Complex'];
     12 var createNthRoots = /* #__PURE__ */(0, _factory.factory)(name, dependencies, function (_ref) {
     13   var typed = _ref.typed,
     14       config = _ref.config,
     15       divideScalar = _ref.divideScalar,
     16       Complex = _ref.Complex;
     17 
     18   /**
     19    * Each function here returns a real multiple of i as a Complex value.
     20    * @param  {number} val
     21    * @return {Complex} val, i*val, -val or -i*val for index 0, 1, 2, 3
     22    */
     23   // This is used to fix float artifacts for zero-valued components.
     24   var _calculateExactResult = [function realPos(val) {
     25     return new Complex(val, 0);
     26   }, function imagPos(val) {
     27     return new Complex(0, val);
     28   }, function realNeg(val) {
     29     return new Complex(-val, 0);
     30   }, function imagNeg(val) {
     31     return new Complex(0, -val);
     32   }];
     33   /**
     34    * Calculate the nth root of a Complex Number a using De Movire's Theorem.
     35    * @param  {Complex} a
     36    * @param  {number} root
     37    * @return {Array} array of n Complex Roots
     38    */
     39 
     40   function _nthComplexRoots(a, root) {
     41     if (root < 0) throw new Error('Root must be greater than zero');
     42     if (root === 0) throw new Error('Root must be non-zero');
     43     if (root % 1 !== 0) throw new Error('Root must be an integer');
     44     if (a === 0 || a.abs() === 0) return [new Complex(0, 0)];
     45     var aIsNumeric = typeof a === 'number';
     46     var offset; // determine the offset (argument of a)/(pi/2)
     47 
     48     if (aIsNumeric || a.re === 0 || a.im === 0) {
     49       if (aIsNumeric) {
     50         offset = 2 * +(a < 0); // numeric value on the real axis
     51       } else if (a.im === 0) {
     52         offset = 2 * +(a.re < 0); // complex value on the real axis
     53       } else {
     54         offset = 2 * +(a.im < 0) + 1; // complex value on the imaginary axis
     55       }
     56     }
     57 
     58     var arg = a.arg();
     59     var abs = a.abs();
     60     var roots = [];
     61     var r = Math.pow(abs, 1 / root);
     62 
     63     for (var k = 0; k < root; k++) {
     64       var halfPiFactor = (offset + 4 * k) / root;
     65       /**
     66        * If (offset + 4*k)/root is an integral multiple of pi/2
     67        * then we can produce a more exact result.
     68        */
     69 
     70       if (halfPiFactor === Math.round(halfPiFactor)) {
     71         roots.push(_calculateExactResult[halfPiFactor % 4](r));
     72         continue;
     73       }
     74 
     75       roots.push(new Complex({
     76         r: r,
     77         phi: (arg + 2 * Math.PI * k) / root
     78       }));
     79     }
     80 
     81     return roots;
     82   }
     83   /**
     84    * Calculate the nth roots of a value.
     85    * An nth root of a positive real number A,
     86    * is a positive real solution of the equation "x^root = A".
     87    * This function returns an array of complex values.
     88    *
     89    * Syntax:
     90    *
     91    *    math.nthRoots(x)
     92    *    math.nthRoots(x, root)
     93    *
     94    * Examples:
     95    *
     96    *    math.nthRoots(1)
     97    *    // returns [
     98    *    //   {re: 1, im: 0},
     99    *    //   {re: -1, im: 0}
    100    *    // ]
    101    *    nthRoots(1, 3)
    102    *    // returns [
    103    *    //   { re: 1, im: 0 },
    104    *    //   { re: -0.4999999999999998, im: 0.8660254037844387 },
    105    *    //   { re: -0.5000000000000004, im: -0.8660254037844385 }
    106    *    ]
    107    *
    108    * See also:
    109    *
    110    *    nthRoot, pow, sqrt
    111    *
    112    * @param {number | BigNumber | Fraction | Complex} x Number to be rounded
    113    * @return {number | BigNumber | Fraction | Complex}            Rounded value
    114    */
    115 
    116 
    117   return typed(name, {
    118     Complex: function Complex(x) {
    119       return _nthComplexRoots(x, 2);
    120     },
    121     'Complex, number': _nthComplexRoots
    122   });
    123 });
    124 exports.createNthRoots = createNthRoots;