UNPKG

mathjs

Version:

Math.js is an extensive math library for JavaScript and Node.js. It features a flexible expression parser and offers an integrated solution to work with numbers, big numbers, complex numbers, units, and matrices.

91 lines (80 loc) 2.5 kB
module.exports = function (math) { var util = require('../../util/index'), BigNumber = math.type.BigNumber, Matrix = require('../../type/Matrix'), object = util.object, isArray = util.array.isArray, isNumber = util.number.isNumber, isInteger = util.number.isInteger; /** * Create a diagonal matrix or retrieve the diagonal of a matrix * * diag(v) * diag(v, k) * diag(X) * diag(X, k) * * TODO: more documentation on diag * * @param {Matrix | Array} x * @param {Number | BigNumber} [k] * @return {Matrix | Array} matrix */ math.diag = function diag (x, k) { var data, vector, i, iMax; if (arguments.length != 1 && arguments.length != 2) { throw new math.error.ArgumentsError('diag', arguments.length, 1, 2); } if (k) { // convert BigNumber to a number if (k instanceof BigNumber) k = k.toNumber(); if (!isNumber(k) || !isInteger(k)) { throw new TypeError ('Second parameter in function diag must be an integer'); } } else { k = 0; } var kSuper = k > 0 ? k : 0; var kSub = k < 0 ? -k : 0; // check type of input var asArray; if (x instanceof Matrix) { asArray = false; } else if (isArray(x)) { // convert to matrix x = new Matrix(x); asArray = true; } else { throw new TypeError ('First parameter in function diag must be a Matrix or Array'); } var s = x.size(); switch (s.length) { case 1: // x is a vector. create diagonal matrix vector = x.valueOf(); var matrix = new Matrix(); var defaultValue = (vector[0] instanceof BigNumber) ? new BigNumber(0) : 0; matrix.resize([vector.length + kSub, vector.length + kSuper], defaultValue); data = matrix.valueOf(); iMax = vector.length; for (i = 0; i < iMax; i++) { data[i + kSub][i + kSuper] = object.clone(vector[i]); } return asArray ? matrix.valueOf() : matrix; case 2: // x is a matrix get diagonal from matrix vector = []; data = x.valueOf(); iMax = Math.min(s[0] - kSub, s[1] - kSuper); for (i = 0; i < iMax; i++) { vector[i] = object.clone(data[i + kSub][i + kSuper]); } return asArray ? vector : new Matrix(vector); default: throw new RangeError('Matrix for function diag must be 2 dimensional'); } }; };