simple-squiggle

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

diag.js (5741B)


      1 "use strict";
      2 
      3 Object.defineProperty(exports, "__esModule", {
      4   value: true
      5 });
      6 exports.createDiag = void 0;
      7 
      8 var _is = require("../../utils/is.js");
      9 
     10 var _array = require("../../utils/array.js");
     11 
     12 var _number = require("../../utils/number.js");
     13 
     14 var _factory = require("../../utils/factory.js");
     15 
     16 var name = 'diag';
     17 var dependencies = ['typed', 'matrix', 'DenseMatrix', 'SparseMatrix'];
     18 var createDiag = /* #__PURE__ */(0, _factory.factory)(name, dependencies, function (_ref) {
     19   var typed = _ref.typed,
     20       matrix = _ref.matrix,
     21       DenseMatrix = _ref.DenseMatrix,
     22       SparseMatrix = _ref.SparseMatrix;
     23 
     24   /**
     25    * Create a diagonal matrix or retrieve the diagonal of a matrix
     26    *
     27    * When `x` is a vector, a matrix with vector `x` on the diagonal will be returned.
     28    * When `x` is a two dimensional matrix, the matrixes `k`th diagonal will be returned as vector.
     29    * When k is positive, the values are placed on the super diagonal.
     30    * When k is negative, the values are placed on the sub diagonal.
     31    *
     32    * Syntax:
     33    *
     34    *     math.diag(X)
     35    *     math.diag(X, format)
     36    *     math.diag(X, k)
     37    *     math.diag(X, k, format)
     38    *
     39    * Examples:
     40    *
     41    *     // create a diagonal matrix
     42    *     math.diag([1, 2, 3])      // returns [[1, 0, 0], [0, 2, 0], [0, 0, 3]]
     43    *     math.diag([1, 2, 3], 1)   // returns [[0, 1, 0, 0], [0, 0, 2, 0], [0, 0, 0, 3]]
     44    *     math.diag([1, 2, 3], -1)  // returns [[0, 0, 0], [1, 0, 0], [0, 2, 0], [0, 0, 3]]
     45    *
     46    *    // retrieve the diagonal from a matrix
     47    *    const a = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
     48    *    math.diag(a)   // returns [1, 5, 9]
     49    *
     50    * See also:
     51    *
     52    *     ones, zeros, identity
     53    *
     54    * @param {Matrix | Array} x          A two dimensional matrix or a vector
     55    * @param {number | BigNumber} [k=0]  The diagonal where the vector will be filled
     56    *                                    in or retrieved.
     57    * @param {string} [format='dense']   The matrix storage format.
     58    *
     59    * @returns {Matrix | Array} Diagonal matrix from input vector, or diagonal from input matrix.
     60    */
     61   return typed(name, {
     62     // FIXME: simplify this huge amount of signatures as soon as typed-function supports optional arguments
     63     Array: function Array(x) {
     64       return _diag(x, 0, (0, _array.arraySize)(x), null);
     65     },
     66     'Array, number': function ArrayNumber(x, k) {
     67       return _diag(x, k, (0, _array.arraySize)(x), null);
     68     },
     69     'Array, BigNumber': function ArrayBigNumber(x, k) {
     70       return _diag(x, k.toNumber(), (0, _array.arraySize)(x), null);
     71     },
     72     'Array, string': function ArrayString(x, format) {
     73       return _diag(x, 0, (0, _array.arraySize)(x), format);
     74     },
     75     'Array, number, string': function ArrayNumberString(x, k, format) {
     76       return _diag(x, k, (0, _array.arraySize)(x), format);
     77     },
     78     'Array, BigNumber, string': function ArrayBigNumberString(x, k, format) {
     79       return _diag(x, k.toNumber(), (0, _array.arraySize)(x), format);
     80     },
     81     Matrix: function Matrix(x) {
     82       return _diag(x, 0, x.size(), x.storage());
     83     },
     84     'Matrix, number': function MatrixNumber(x, k) {
     85       return _diag(x, k, x.size(), x.storage());
     86     },
     87     'Matrix, BigNumber': function MatrixBigNumber(x, k) {
     88       return _diag(x, k.toNumber(), x.size(), x.storage());
     89     },
     90     'Matrix, string': function MatrixString(x, format) {
     91       return _diag(x, 0, x.size(), format);
     92     },
     93     'Matrix, number, string': function MatrixNumberString(x, k, format) {
     94       return _diag(x, k, x.size(), format);
     95     },
     96     'Matrix, BigNumber, string': function MatrixBigNumberString(x, k, format) {
     97       return _diag(x, k.toNumber(), x.size(), format);
     98     }
     99   });
    100   /**
    101    * Creeate diagonal matrix from a vector or vice versa
    102    * @param {Array | Matrix} x
    103    * @param {number} k
    104    * @param {string} format Storage format for matrix. If null,
    105    *                          an Array is returned
    106    * @returns {Array | Matrix}
    107    * @private
    108    */
    109 
    110   function _diag(x, k, size, format) {
    111     if (!(0, _number.isInteger)(k)) {
    112       throw new TypeError('Second parameter in function diag must be an integer');
    113     }
    114 
    115     var kSuper = k > 0 ? k : 0;
    116     var kSub = k < 0 ? -k : 0; // check dimensions
    117 
    118     switch (size.length) {
    119       case 1:
    120         return _createDiagonalMatrix(x, k, format, size[0], kSub, kSuper);
    121 
    122       case 2:
    123         return _getDiagonal(x, k, format, size, kSub, kSuper);
    124     }
    125 
    126     throw new RangeError('Matrix for function diag must be 2 dimensional');
    127   }
    128 
    129   function _createDiagonalMatrix(x, k, format, l, kSub, kSuper) {
    130     // matrix size
    131     var ms = [l + kSub, l + kSuper];
    132 
    133     if (format && format !== 'sparse' && format !== 'dense') {
    134       throw new TypeError("Unknown matrix type ".concat(format, "\""));
    135     } // create diagonal matrix
    136 
    137 
    138     var m = format === 'sparse' ? SparseMatrix.diagonal(ms, x, k) : DenseMatrix.diagonal(ms, x, k); // check we need to return a matrix
    139 
    140     return format !== null ? m : m.valueOf();
    141   }
    142 
    143   function _getDiagonal(x, k, format, s, kSub, kSuper) {
    144     // check x is a Matrix
    145     if ((0, _is.isMatrix)(x)) {
    146       // get diagonal matrix
    147       var dm = x.diagonal(k); // check we need to return a matrix
    148 
    149       if (format !== null) {
    150         // check we need to change matrix format
    151         if (format !== dm.storage()) {
    152           return matrix(dm, format);
    153         }
    154 
    155         return dm;
    156       }
    157 
    158       return dm.valueOf();
    159     } // vector size
    160 
    161 
    162     var n = Math.min(s[0] - kSub, s[1] - kSuper); // diagonal values
    163 
    164     var vector = []; // loop diagonal
    165 
    166     for (var i = 0; i < n; i++) {
    167       vector[i] = x[i + kSub][i + kSuper];
    168     } // check we need to return a matrix
    169 
    170 
    171     return format !== null ? matrix(vector) : vector;
    172   }
    173 });
    174 exports.createDiag = createDiag;