UNPKG

@rayyamhk/matrix

Version:

A professional, comprehensive and high-performance library for you to manipulate matrices.

113 lines (86 loc) 2.53 kB
"use strict"; var Matrix = require('../..'); var isNumber = require('../../util/isNumber'); var _require = require('../../Error'), INVALID_ARRAY = _require.INVALID_ARRAY, EXPECTED_ARRAY_OF_NUMBERS_OR_MATRICES = _require.EXPECTED_ARRAY_OF_NUMBERS_OR_MATRICES, INVALID_SQUARE_MATRIX = _require.INVALID_SQUARE_MATRIX; /** * Generates diagonal Matrix if the argument is an array of numbers, * generates block diagonal Matrix if the argument is an array of Matrices. * @memberof Matrix * @static * @param {(number[]|Matrix[])} values - Array of numbers or Matrices * @returns {Matrix} Block diagonal Matrix */ function diag(values) { if (!Array.isArray(values)) { throw new Error(INVALID_ARRAY); } var argsNum = values.length; var variant; for (var i = 0; i < argsNum; i++) { var entry = values[i]; if (!isNumber(entry) && !(entry instanceof Matrix)) { throw new Error(EXPECTED_ARRAY_OF_NUMBERS_OR_MATRICES); } if (isNumber(entry)) { if (!variant) { variant = 'number'; continue; } if (variant !== 'number') { throw new Error(EXPECTED_ARRAY_OF_NUMBERS_OR_MATRICES); } } else { if (!entry.isSquare()) { throw new Error(INVALID_SQUARE_MATRIX); } if (!variant) { variant = 'square'; continue; } if (variant !== 'square') { throw new Error(EXPECTED_ARRAY_OF_NUMBERS_OR_MATRICES); } } } // HERE: variant should be either 'number' or 'square' if (variant === 'number') { return Matrix.generate(argsNum, argsNum, function (i, j) { if (i === j) { return values[i]; } return 0; }); } // Guaranteed that [values] is a list of square matrices var size = 0; var temp = new Array(argsNum); for (var _i = 0; _i < argsNum; _i++) { var _len = values[_i].size()[0]; size += _len; temp[_i] = _len; } var idx = 0; var start = 0; var len = temp[idx]; return Matrix.generate(size, size, function (i, j) { if (i - start === len && j - start === len) { start += len; idx++; } var ith = i - start; // ith < 0 if below main diagonal var jth = j - start; // jth < 0 if above main diagonal // skip 0x0 matrices len = temp[idx]; while (len === 0) { idx++; len = temp[idx]; } if (ith < len && ith >= 0 && jth < len && jth >= 0) { return values[idx]._matrix[ith][jth]; } return 0; }); } ; module.exports = diag;