UNPKG

@tensorflow/tfjs-core

Version:

Hardware-accelerated JavaScript library for machine intelligence

1,369 lines (1,282 loc) 699 kB
/** * @license * Copyright 2018 Google LLC. All Rights Reserved. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ============================================================================= */ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('crypto')) : typeof define === 'function' && define.amd ? define(['exports', 'crypto'], factory) : (factory((global.tf = global.tf || {}),global.crypto)); }(this, (function (exports,crypto) { 'use strict'; crypto = crypto && crypto.hasOwnProperty('default') ? crypto['default'] : crypto; /*! ***************************************************************************** Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT. See the Apache Version 2.0 License for specific language governing permissions and limitations under the License. ***************************************************************************** */ /* global Reflect, Promise */ var extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; function __extends(d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); } function __decorate(decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; } function __awaiter(thisArg, _arguments, P, generator) { return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); } function __generator(thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [0, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } } function isMobile() { var a = navigator.userAgent || navigator.vendor || window.opera; return /(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i .test(a) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i .test(a.substr(0, 4)); } function doc(info) { return function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } }; } function assertArgumentIsTensor(x, argName, functionName) { assert(x instanceof Tensor, "Argument '" + argName + "' passed to '" + functionName + "' must be a Tensor, " + ("but got " + typeof x + ".")); } function assertArgumentsAreTensors(args, functionName) { var _loop_1 = function (argName) { var arg = args[argName]; if (Array.isArray(arg)) { arg.forEach(function (t, i) { assertArgumentIsTensor(t, argName + "[" + i + "]", functionName); }); } else { assertArgumentIsTensor(arg, argName, functionName); } }; for (var argName in args) { _loop_1(argName); } } function shuffle(array) { var counter = array.length; var temp = 0; var index = 0; while (counter > 0) { index = (Math.random() * counter) | 0; counter--; temp = array[counter]; array[counter] = array[index]; array[index] = temp; } } function clamp(min, x, max) { return Math.max(min, Math.min(x, max)); } function randUniform(a, b) { return Math.random() * (b - a) + a; } function distSquared(a, b) { var result = 0; for (var i = 0; i < a.length; i++) { var diff = Number(a[i]) - Number(b[i]); result += diff * diff; } return result; } function assert(expr, msg) { if (!expr) { throw new Error(msg); } } function assertShapesMatch(shapeA, shapeB, errorMessagePrefix) { if (errorMessagePrefix === void 0) { errorMessagePrefix = ''; } assert(arraysEqual(shapeA, shapeB), errorMessagePrefix + (" Shapes " + shapeA + " and " + shapeB + " must match")); } function assertTypesMatch(a, b) { assert(a.dtype === b.dtype, " The dtypes of the first(" + a.dtype + ") and" + (" second(" + b.dtype + ") input must match")); } function flatten(arr, ret) { if (ret === void 0) { ret = []; } if (Array.isArray(arr)) { for (var i = 0; i < arr.length; ++i) { flatten(arr[i], ret); } } else { ret.push(arr); } return ret; } function inferShape(val) { if (isTypedArray(val)) { return [val.length]; } if (!Array.isArray(val)) { return []; } var shape = []; while (val instanceof Array) { shape.push(val.length); val = val[0]; } return shape; } function sizeFromShape(shape) { if (shape.length === 0) { return 1; } var size = shape[0]; for (var i = 1; i < shape.length; i++) { size *= shape[i]; } return size; } function isScalarShape(shape) { return shape.length === 0; } function arraysEqual(n1, n2) { if (n1.length !== n2.length) { return false; } for (var i = 0; i < n1.length; i++) { if (n1[i] !== n2[i]) { return false; } } return true; } function isInt(a) { return a % 1 === 0; } function tanh(x) { if (Math.tanh != null) { return Math.tanh(x); } if (x === Infinity) { return 1; } else if (x === -Infinity) { return -1; } else { var e2x = Math.exp(2 * x); return (e2x - 1) / (e2x + 1); } } function sizeToSquarishShape(size) { for (var a = Math.floor(Math.sqrt(size)); a > 1; --a) { if (size % a === 0) { return [a, size / a]; } } return [1, size]; } function createShuffledIndices(n) { var shuffledIndices = new Uint32Array(n); for (var i = 0; i < n; ++i) { shuffledIndices[i] = i; } shuffle(shuffledIndices); return shuffledIndices; } function rightPad(a, size) { if (size <= a.length) { return a; } return a + ' '.repeat(size - a.length); } function repeatedTry(checkFn, delayFn, maxCounter) { if (delayFn === void 0) { delayFn = function (counter) { return 0; }; } return new Promise(function (resolve, reject) { var tryCount = 0; var tryFn = function () { if (checkFn()) { resolve(); return; } tryCount++; var nextBackoff = delayFn(tryCount); if (maxCounter != null && tryCount >= maxCounter) { reject(); return; } setTimeout(tryFn, nextBackoff); }; setTimeout(tryFn, 0); }); } function getQueryParams(queryString) { var params = {}; queryString.replace(/[?&]([^=?&]+)(?:=([^&]*))?/g, function (s) { var t = []; for (var _i = 1; _i < arguments.length; _i++) { t[_i - 1] = arguments[_i]; } decodeParam(params, t[0], t[1]); return t.join('='); }); return params; } function decodeParam(params, name, value) { params[decodeURIComponent(name)] = decodeURIComponent(value || ''); } function inferFromImplicitShape(shape, size) { var shapeProd = 1; var implicitIdx = -1; for (var i = 0; i < shape.length; ++i) { if (shape[i] > 0) { shapeProd *= shape[i]; } else if (shape[i] === -1) { if (implicitIdx !== -1) { throw Error("Shapes can only have 1 implicit size. " + ("Found - 1 at dim " + implicitIdx + " and dim " + i)); } implicitIdx = i; } else if (shape[i] <= 0) { throw Error("Shapes can not be <= 0. Found " + shape[i] + " at dim " + i); } } if (implicitIdx === -1) { if (size > 0 && size !== shapeProd) { throw Error("Size(" + size + ") must match the product of shape " + shape); } return shape; } if (size % shapeProd !== 0) { throw Error("The implicit shape can't be a fractional number. " + ("Got " + size + " / " + shapeProd)); } var newShape = shape.slice(); newShape[implicitIdx] = size / shapeProd; return newShape; } function squeezeShape(shape, axis) { var newShape = []; var keptDims = []; var j = 0; for (var i = 0; i < shape.length; ++i) { if (axis != null) { if (axis[j] === i && shape[i] > 1) { throw new Error("Can't squeeze axis " + i + " since its dim '" + shape[i] + "' is not 1"); } if ((axis[j] == null || axis[j] > i) && shape[i] === 1) { newShape.push(shape[i]); keptDims.push(i); } if (axis[j] <= i) { j++; } } if (shape[i] > 1) { newShape.push(shape[i]); keptDims.push(i); } } return { newShape: newShape, keptDims: keptDims }; } function getTypedArrayFromDType(dtype, size) { var values = null; if (dtype == null || dtype === 'float32') { values = new Float32Array(size); } else if (dtype === 'int32') { values = new Int32Array(size); } else if (dtype === 'bool') { values = new Uint8Array(size); } else { throw new Error("Unknown data type " + dtype); } return values; } function isTensorInList(tensor, tensorList) { for (var i = 0; i < tensorList.length; i++) { if (tensorList[i].id === tensor.id) { return true; } } return false; } function checkForNaN(vals, dtype, name) { if (dtype !== 'float32') { return; } for (var i = 0; i < vals.length; i++) { if (isNaN(vals[i])) { throw Error("The result of the '" + name + "' has NaNs."); } } } function flattenNameArrayMap(nameArrayMap, keys) { var xs = []; if (nameArrayMap instanceof Tensor) { xs.push(nameArrayMap); } else { var xMap = nameArrayMap; for (var i = 0; i < keys.length; i++) { xs.push(xMap[keys[i]]); } } return xs; } function unflattenToNameArrayMap(keys, flatArrays) { if (keys.length !== flatArrays.length) { throw new Error("Cannot unflatten Tensor[], keys and arrays are not of same length."); } var result = {}; for (var i = 0; i < keys.length; i++) { result[keys[i]] = flatArrays[i]; } return result; } function hasEncodingLoss(oldType, newType) { if (newType === 'float32') { return false; } if (newType === 'int32' && oldType !== 'float32') { return false; } if (newType === 'bool' && oldType === 'bool') { return false; } return true; } function copyTypedArray(array, dtype) { if (dtype == null || dtype === 'float32') { return new Float32Array(array); } else if (dtype === 'int32') { return new Int32Array(array); } else if (dtype === 'bool') { var bool = new Uint8Array(array.length); for (var i = 0; i < bool.length; ++i) { if (Math.round(array[i]) !== 0) { bool[i] = 1; } } return bool; } else { throw new Error("Unknown data type " + dtype); } } function isTypedArray(a) { return a instanceof Float32Array || a instanceof Int32Array || a instanceof Uint8Array; } function bytesPerElement(dtype) { if (dtype === 'float32' || dtype === 'int32') { return 4; } else if (dtype === 'bool') { return 1; } else { throw new Error("Unknown dtype " + dtype); } } function isFunction(f) { return !!(f && f.constructor && f.call && f.apply); } function extractTensorsFromContainer(result) { return extractTensorsFromAny(result); } function extractTensorsFromAny(result) { if (result == null) { return []; } if (result instanceof Tensor) { return [result]; } var list = []; var resultObj = result; if (!isIterable(resultObj)) { return []; } for (var k in resultObj) { var sublist = flatten(resultObj[k]).filter(function (x) { return x instanceof Tensor; }); list.push.apply(list, sublist); } return list; } function isIterable(obj) { return Array.isArray(obj) || typeof obj === 'object'; } var util = /*#__PURE__*/Object.freeze({ assertArgumentsAreTensors: assertArgumentsAreTensors, shuffle: shuffle, clamp: clamp, randUniform: randUniform, distSquared: distSquared, assert: assert, assertShapesMatch: assertShapesMatch, assertTypesMatch: assertTypesMatch, flatten: flatten, inferShape: inferShape, sizeFromShape: sizeFromShape, isScalarShape: isScalarShape, arraysEqual: arraysEqual, isInt: isInt, tanh: tanh, sizeToSquarishShape: sizeToSquarishShape, createShuffledIndices: createShuffledIndices, rightPad: rightPad, repeatedTry: repeatedTry, getQueryParams: getQueryParams, inferFromImplicitShape: inferFromImplicitShape, squeezeShape: squeezeShape, getTypedArrayFromDType: getTypedArrayFromDType, isTensorInList: isTensorInList, checkForNaN: checkForNaN, flattenNameArrayMap: flattenNameArrayMap, unflattenToNameArrayMap: unflattenToNameArrayMap, hasEncodingLoss: hasEncodingLoss, copyTypedArray: copyTypedArray, isTypedArray: isTypedArray, bytesPerElement: bytesPerElement, isFunction: isFunction, extractTensorsFromContainer: extractTensorsFromContainer, extractTensorsFromAny: extractTensorsFromAny }); var FORMAT_LIMIT_NUM_VALS = 20; var FORMAT_NUM_FIRST_LAST_VALS = 3; var FORMAT_NUM_SIG_DIGITS = 7; function tensorToString(t, verbose) { var vals = t.dataSync(); var padPerCol = computeMaxSizePerColumn(t); var valsLines = subTensorToString(vals, t.shape, t.strides, padPerCol); var lines = ['Tensor']; if (verbose) { lines.push(" dtype: " + t.dtype); lines.push(" rank: " + t.rank); lines.push(" shape: [" + t.shape + "]"); lines.push(" values:"); } lines.push(valsLines.map(function (l) { return ' ' + l; }).join('\n')); return lines.join('\n'); } function computeMaxSizePerColumn(t) { var vals = t.dataSync(); var n = t.size; var numCols = t.strides[t.strides.length - 1]; var padPerCol = new Array(numCols).fill(0); if (t.rank > 1) { for (var row = 0; row < n / numCols; row++) { var offset = row * numCols; for (var j = 0; j < numCols; j++) { padPerCol[j] = Math.max(padPerCol[j], valToString(vals[offset + j], 0).length); } } } return padPerCol; } function valToString(val, pad) { return rightPad(parseFloat(val.toFixed(FORMAT_NUM_SIG_DIGITS)).toString(), pad); } function subTensorToString(vals, shape, strides, padPerCol, isLast) { if (isLast === void 0) { isLast = true; } var size = shape[0]; var rank = shape.length; if (rank === 0) { return [vals[0].toString()]; } if (rank === 1) { if (size > FORMAT_LIMIT_NUM_VALS) { var firstVals = Array.from(vals.subarray(0, FORMAT_NUM_FIRST_LAST_VALS)); var lastVals = Array.from(vals.subarray(size - FORMAT_NUM_FIRST_LAST_VALS, size)); return [ '[' + firstVals.map(function (x, i) { return valToString(x, padPerCol[i]); }).join(', ') + ', ..., ' + lastVals .map(function (x, i) { return valToString(x, padPerCol[size - FORMAT_NUM_FIRST_LAST_VALS + i]); }) .join(', ') + ']' ]; } return [ '[' + Array.from(vals).map(function (x, i) { return valToString(x, padPerCol[i]); }).join(', ') + ']' ]; } var subshape = shape.slice(1); var substrides = strides.slice(1); var stride = strides[0]; var lines = []; if (size > FORMAT_LIMIT_NUM_VALS) { for (var i = 0; i < FORMAT_NUM_FIRST_LAST_VALS; i++) { var start = i * stride; var end = start + stride; lines.push.apply(lines, subTensorToString(vals.subarray(start, end), subshape, substrides, padPerCol, false)); } lines.push('...'); for (var i = size - FORMAT_NUM_FIRST_LAST_VALS; i < size; i++) { var start = i * stride; var end = start + stride; lines.push.apply(lines, subTensorToString(vals.subarray(start, end), subshape, substrides, padPerCol, i === size - 1)); } } else { for (var i = 0; i < size; i++) { var start = i * stride; var end = start + stride; lines.push.apply(lines, subTensorToString(vals.subarray(start, end), subshape, substrides, padPerCol, i === size - 1)); } } var sep = rank === 2 ? ',' : ''; lines[0] = '[' + lines[0] + sep; for (var i = 1; i < lines.length - 1; i++) { lines[i] = ' ' + lines[i] + sep; } var newLineSep = ',\n'; for (var i = 2; i < rank; i++) { newLineSep += '\n'; } lines[lines.length - 1] = ' ' + lines[lines.length - 1] + ']' + (isLast ? '' : newLineSep); return lines; } function axesAreInnerMostDims(axes, rank) { for (var i = 0; i < axes.length; ++i) { if (axes[axes.length - i - 1] !== rank - 1 - i) { return false; } } return true; } function combineLocations(outputLoc, reduceLoc, axes) { var rank = outputLoc.length + reduceLoc.length; var loc = []; var outIdx = 0; var reduceIdx = 0; for (var dim = 0; dim < rank; dim++) { if (axes.indexOf(dim) === -1) { loc.push(outputLoc[outIdx++]); } else { loc.push(reduceLoc[reduceIdx++]); } } return loc; } function computeOutAndReduceShapes(aShape, axes) { var outShape = []; var rank = aShape.length; for (var dim = 0; dim < rank; dim++) { if (axes.indexOf(dim) === -1) { outShape.push(aShape[dim]); } } var reduceShape = axes.map(function (dim) { return aShape[dim]; }); return [outShape, reduceShape]; } function expandShapeToKeepDim(shape, axes) { var reduceSubShape = axes.map(function (x) { return 1; }); return combineLocations(shape, reduceSubShape, axes); } function parseAxisParam(axis, shape) { var rank = shape.length; axis = axis == null ? shape.map(function (s, i) { return i; }) : [].concat(axis); assert(axis.every(function (ax) { return ax >= -rank && ax < rank; }), "All values in axis param must be in range [-" + rank + ", " + rank + ") but " + ("got axis " + axis)); assert(axis.every(function (ax) { return isInt(ax); }), "All values in axis param must be integers but " + ("got axis " + axis)); return axis.map(function (a) { return a < 0 ? rank + a : a; }); } function assertAxesAreInnerMostDims(msg, axes, rank) { assert(axesAreInnerMostDims(axes, rank), msg + " supports only inner-most axes for now. " + ("Got axes " + axes + " and rank-" + rank + " input.")); } function getAxesPermutation(axes, rank) { if (axesAreInnerMostDims(axes, rank)) { return null; } var result = []; for (var i = 0; i < rank; ++i) { if (axes.indexOf(i) === -1) { result.push(i); } } axes.forEach(function (axis) { return result.push(axis); }); return result; } function getUndoAxesPermutation(axes) { return axes.map(function (axis, i) { return [i, axis]; }) .sort(function (a, b) { return a[1] - b[1]; }) .map(function (x) { return x[0]; }); } function getInnerMostAxes(numAxes, rank) { var res = []; for (var i = rank - numAxes; i < rank; ++i) { res.push(i); } return res; } function assertParams(aShape, bShape, axis) { var aRank = aShape.length; var bRank = bShape.length; assert(aShape.length === bShape.length, "Error in concat" + aRank + "D: rank of x1 (" + aRank + ") and x2 (" + bRank + ") " + "must be the same."); assert(axis >= 0 && axis < aRank, "Error in concat" + aRank + "D: axis must be " + ("between 0 and " + (aRank - 1) + ".")); for (var i = 0; i < aRank; i++) { assert((i === axis) || (aShape[i] === bShape[i]), "Error in concat" + aRank + "D: Shape (" + aShape + ") does not match " + ("(" + bShape + ") along the non-concatenated axis " + i + ".")); } } function computeOutShape(x1Shape, x2Shape, axis) { assert(x1Shape.length === x2Shape.length, 'x1 and x2 should have the same rank.'); var outputShape = x1Shape.slice(); outputShape[axis] += x2Shape[axis]; return outputShape; } function computeGradientSliceShapes(aShape, bShape) { return { aBegin: [0, 0], aSize: aShape, bBegin: [0, aShape[1]], bSize: bShape }; } function operation(target, name, descriptor) { var fn = descriptor.value; descriptor.value = function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } return tidy(name, function () { return fn.apply(void 0, args); }); }; return descriptor; } var ConcatOps = (function () { function ConcatOps() { } ConcatOps.concat1d = function (tensors) { return ConcatOps.concat(tensors, 0); }; ConcatOps.concat2d = function (tensors, axis) { return ConcatOps.concat(tensors, axis); }; ConcatOps.concat3d = function (tensors, axis) { return ConcatOps.concat(tensors, axis); }; ConcatOps.concat4d = function (tensors, axis) { return ConcatOps.concat(tensors, axis); }; ConcatOps.concat = function (tensors, axis) { if (axis === void 0) { axis = 0; } assert(tensors.length >= 1, 'Pass at least one tensor to concat'); assertArgumentsAreTensors({ tensors: tensors }, 'concat'); var result = tensors[0]; if (tensors.length === 1) { return result; } var axes = parseAxisParam(axis, result.shape); for (var i = 1; i < tensors.length; ++i) { result = concat2Tensors(result, tensors[i], axes[0]); } return result; }; __decorate([ doc({ heading: 'Tensors', subheading: 'Slicing and Joining' }), operation ], ConcatOps, "concat", null); return ConcatOps; }()); function concat2Tensors(a, b, axis) { assertParams(a.shape, b.shape, axis); var outShape = computeOutShape(a.shape, b.shape, axis); var a2D = a.as2D(-1, sizeFromShape(a.shape.slice(axis))); var b2D = b.as2D(-1, sizeFromShape(b.shape.slice(axis))); var _a = computeGradientSliceShapes(a2D.shape, b2D.shape), aBegin = _a.aBegin, aSize = _a.aSize, bBegin = _a.bBegin, bSize = _a.bSize; var der = function (dy) { return { a: function () { return dy.slice(aBegin, aSize); }, b: function () { return dy.slice(bBegin, bSize); } }; }; var res = ENV.engine.runKernel(function (backend) { return backend.concat(a2D, b2D); }, { a: a2D, b: b2D }, der); return res.reshape(outShape); } var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; function createCommonjsModule(fn, module) { return module = { exports: {} }, fn(module, module.exports), module.exports; } var alea = createCommonjsModule(function (module) { // A port of an algorithm by Johannes Baagøe <baagoe@baagoe.com>, 2010 // http://baagoe.com/en/RandomMusings/javascript/ // https://github.com/nquinlan/better-random-numbers-for-javascript-mirror // Original work is under MIT license - // Copyright (C) 2010 by Johannes Baagøe <baagoe@baagoe.org> // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. (function(global, module, define) { function Alea(seed) { var me = this, mash = Mash(); me.next = function() { var t = 2091639 * me.s0 + me.c * 2.3283064365386963e-10; // 2^-32 me.s0 = me.s1; me.s1 = me.s2; return me.s2 = t - (me.c = t | 0); }; // Apply the seeding algorithm from Baagoe. me.c = 1; me.s0 = mash(' '); me.s1 = mash(' '); me.s2 = mash(' '); me.s0 -= mash(seed); if (me.s0 < 0) { me.s0 += 1; } me.s1 -= mash(seed); if (me.s1 < 0) { me.s1 += 1; } me.s2 -= mash(seed); if (me.s2 < 0) { me.s2 += 1; } mash = null; } function copy(f, t) { t.c = f.c; t.s0 = f.s0; t.s1 = f.s1; t.s2 = f.s2; return t; } function impl(seed, opts) { var xg = new Alea(seed), state = opts && opts.state, prng = xg.next; prng.int32 = function() { return (xg.next() * 0x100000000) | 0; }; prng.double = function() { return prng() + (prng() * 0x200000 | 0) * 1.1102230246251565e-16; // 2^-53 }; prng.quick = prng; if (state) { if (typeof(state) == 'object') copy(state, xg); prng.state = function() { return copy(xg, {}); }; } return prng; } function Mash() { var n = 0xefc8249d; var mash = function(data) { data = data.toString(); for (var i = 0; i < data.length; i++) { n += data.charCodeAt(i); var h = 0.02519603282416938 * n; n = h >>> 0; h -= n; h *= n; n = h >>> 0; h -= n; n += h * 0x100000000; // 2^32 } return (n >>> 0) * 2.3283064365386963e-10; // 2^-32 }; return mash; } if (module && module.exports) { module.exports = impl; } else if (define && define.amd) { define(function() { return impl; }); } else { this.alea = impl; } })( commonjsGlobal, module, // present in node.js (typeof undefined) == 'function' && undefined // present with an AMD loader ); }); var xor128 = createCommonjsModule(function (module) { // A Javascript implementaion of the "xor128" prng algorithm by // George Marsaglia. See http://www.jstatsoft.org/v08/i14/paper (function(global, module, define) { function XorGen(seed) { var me = this, strseed = ''; me.x = 0; me.y = 0; me.z = 0; me.w = 0; // Set up generator function. me.next = function() { var t = me.x ^ (me.x << 11); me.x = me.y; me.y = me.z; me.z = me.w; return me.w ^= (me.w >>> 19) ^ t ^ (t >>> 8); }; if (seed === (seed | 0)) { // Integer seed. me.x = seed; } else { // String seed. strseed += seed; } // Mix in string seed, then discard an initial batch of 64 values. for (var k = 0; k < strseed.length + 64; k++) { me.x ^= strseed.charCodeAt(k) | 0; me.next(); } } function copy(f, t) { t.x = f.x; t.y = f.y; t.z = f.z; t.w = f.w; return t; } function impl(seed, opts) { var xg = new XorGen(seed), state = opts && opts.state, prng = function() { return (xg.next() >>> 0) / 0x100000000; }; prng.double = function() { do { var top = xg.next() >>> 11, bot = (xg.next() >>> 0) / 0x100000000, result = (top + bot) / (1 << 21); } while (result === 0); return result; }; prng.int32 = xg.next; prng.quick = prng; if (state) { if (typeof(state) == 'object') copy(state, xg); prng.state = function() { return copy(xg, {}); }; } return prng; } if (module && module.exports) { module.exports = impl; } else if (define && define.amd) { define(function() { return impl; }); } else { this.xor128 = impl; } })( commonjsGlobal, module, // present in node.js (typeof undefined) == 'function' && undefined // present with an AMD loader ); }); var xorwow = createCommonjsModule(function (module) { // A Javascript implementaion of the "xorwow" prng algorithm by // George Marsaglia. See http://www.jstatsoft.org/v08/i14/paper (function(global, module, define) { function XorGen(seed) { var me = this, strseed = ''; // Set up generator function. me.next = function() { var t = (me.x ^ (me.x >>> 2)); me.x = me.y; me.y = me.z; me.z = me.w; me.w = me.v; return (me.d = (me.d + 362437 | 0)) + (me.v = (me.v ^ (me.v << 4)) ^ (t ^ (t << 1))) | 0; }; me.x = 0; me.y = 0; me.z = 0; me.w = 0; me.v = 0; if (seed === (seed | 0)) { // Integer seed. me.x = seed; } else { // String seed. strseed += seed; } // Mix in string seed, then discard an initial batch of 64 values. for (var k = 0; k < strseed.length + 64; k++) { me.x ^= strseed.charCodeAt(k) | 0; if (k == strseed.length) { me.d = me.x << 10 ^ me.x >>> 4; } me.next(); } } function copy(f, t) { t.x = f.x; t.y = f.y; t.z = f.z; t.w = f.w; t.v = f.v; t.d = f.d; return t; } function impl(seed, opts) { var xg = new XorGen(seed), state = opts && opts.state, prng = function() { return (xg.next() >>> 0) / 0x100000000; }; prng.double = function() { do { var top = xg.next() >>> 11, bot = (xg.next() >>> 0) / 0x100000000, result = (top + bot) / (1 << 21); } while (result === 0); return result; }; prng.int32 = xg.next; prng.quick = prng; if (state) { if (typeof(state) == 'object') copy(state, xg); prng.state = function() { return copy(xg, {}); }; } return prng; } if (module && module.exports) { module.exports = impl; } else if (define && define.amd) { define(function() { return impl; }); } else { this.xorwow = impl; } })( commonjsGlobal, module, // present in node.js (typeof undefined) == 'function' && undefined // present with an AMD loader ); }); var xorshift7 = createCommonjsModule(function (module) { // A Javascript implementaion of the "xorshift7" algorithm by // François Panneton and Pierre L'ecuyer: // "On the Xorgshift Random Number Generators" // http://saluc.engr.uconn.edu/refs/crypto/rng/panneton05onthexorshift.pdf (function(global, module, define) { function XorGen(seed) { var me = this; // Set up generator function. me.next = function() { // Update xor generator. var X = me.x, i = me.i, t, v; t = X[i]; t ^= (t >>> 7); v = t ^ (t << 24); t = X[(i + 1) & 7]; v ^= t ^ (t >>> 10); t = X[(i + 3) & 7]; v ^= t ^ (t >>> 3); t = X[(i + 4) & 7]; v ^= t ^ (t << 7); t = X[(i + 7) & 7]; t = t ^ (t << 13); v ^= t ^ (t << 9); X[i] = v; me.i = (i + 1) & 7; return v; }; function init(me, seed) { var j, w, X = []; if (seed === (seed | 0)) { // Seed state array using a 32-bit integer. w = X[0] = seed; } else { // Seed state using a string. seed = '' + seed; for (j = 0; j < seed.length; ++j) { X[j & 7] = (X[j & 7] << 15) ^ (seed.charCodeAt(j) + X[(j + 1) & 7] << 13); } } // Enforce an array length of 8, not all zeroes. while (X.length < 8) X.push(0); for (j = 0; j < 8 && X[j] === 0; ++j); if (j == 8) w = X[7] = -1; else w = X[j]; me.x = X; me.i = 0; // Discard an initial 256 values. for (j = 256; j > 0; --j) { me.next(); } } init(me, seed); } function copy(f, t) { t.x = f.x.slice(); t.i = f.i; return t; } function impl(seed, opts) { if (seed == null) seed = +(new Date); var xg = new XorGen(seed), state = opts && opts.state, prng = function() { return (xg.next() >>> 0) / 0x100000000; }; prng.double = function() { do { var top = xg.next() >>> 11, bot = (xg.next() >>> 0) / 0x100000000, result = (top + bot) / (1 << 21); } while (result === 0); return result; }; prng.int32 = xg.next; prng.quick = prng; if (state) { if (state.x) copy(state, xg); prng.state = function() { return copy(xg, {}); }; } return prng; } if (module && module.exports) { module.exports = impl; } else if (define && define.amd) { define(function() { return impl; }); } else { this.xorshift7 = impl; } })( commonjsGlobal, module, // present in node.js (typeof undefined) == 'function' && undefined // present with an AMD loader ); }); var xor4096 = createCommonjsModule(function (module) { // A Javascript implementaion of Richard Brent's Xorgens xor4096 algorithm. // // This fast non-cryptographic random number generator is designed for // use in Monte-Carlo algorithms. It combines a long-period xorshift // generator with a Weyl generator, and it passes all common batteries // of stasticial tests for randomness while consuming only a few nanoseconds // for each prng generated. For background on the generator, see Brent's // paper: "Some long-period random number generators using shifts and xors." // http://arxiv.org/pdf/1004.3115v1.pdf // // Usage: // // var xor4096 = require('xor4096'); // random = xor4096(1); // Seed with int32 or string. // assert.equal(random(), 0.1520436450538547); // (0, 1) range, 53 bits. // assert.equal(random.int32(), 1806534897); // signed int32, 32 bits. // // For nonzero numeric keys, this impelementation provides a sequence // identical to that by Brent's xorgens 3 implementaion in C. This // implementation also provides for initalizing the generator with // string seeds, or for saving and restoring the state of the generator. // // On Chrome, this prng benchmarks about 2.1 times slower than // Javascript's built-in Math.random(). (function(global, module, define) { function XorGen(seed) { var me = this; // Set up generator function. me.next = function() { var w = me.w, X = me.X, i = me.i, t, v; // Update Weyl generator. me.w = w = (w + 0x61c88647) | 0; // Update xor generator. v = X[(i + 34) & 127]; t = X[i = ((i + 1) & 127)]; v ^= v << 13; t ^= t << 17; v ^= v >>> 15; t ^= t >>> 12; // Update Xor generator array state. v = X[i] = v ^ t; me.i = i; // Result is the combination. return (v + (w ^ (w >>> 16))) | 0; }; function init(me, seed) { var t, v, i, j, w, X = [], limit = 128; if (seed === (seed | 0)) { // Numeric seeds initialize v, which is used to generates X. v = seed; seed = null; } else { // String seeds are mixed into v and X one character at a time. seed = seed + '\0'; v = 0; limit = Math.max(limit, seed.length); } // Initialize circular array and weyl value. for (i = 0, j = -32; j < limit; ++j) { // Put the unicode characters into the array, and shuffle them. if (seed) v ^= seed.charCodeAt((j + 32) % seed.length); // After 32 shuffles, take v as the starting w value. if (j === 0) w = v; v ^= v << 10; v ^= v >>> 15; v ^= v << 4; v ^= v >>> 13; if (j >= 0) { w = (w + 0x61c88647) | 0; // Weyl. t = (X[j & 127] ^= (v + w)); // Combine xor and weyl to init array. i = (0 == t) ? i + 1 : 0; // Count zeroes. } } // We have detected all zeroes; make the key nonzero. if (i >= 128) { X[(seed && seed.length || 0) & 127] = -1; } // Run the generator 512 times to further mix the state before using it. // Factoring this as a function slows the main generator, so it is just // unrolled here. The weyl generator is not advanced while warming up. i = 127; for (j = 4 * 128; j > 0; --j) { v = X[(i + 34) & 127]; t = X[i = ((i + 1) & 127)]; v ^= v << 13; t ^= t << 17; v ^= v >>> 15; t ^= t >>> 12; X[i] = v ^ t; } // Storing state as object members is faster than using closure variables. me.w = w; me.X = X; me.i = i; } init(me, seed); } function copy(f, t) { t.i = f.i; t.w = f.w; t.X = f.X.slice(); return t; } function impl(seed, opts) { if (seed == null) seed = +(new Date); var xg = new XorGen(seed), state = opts && opts.state, prng = function() { return (xg.next() >>> 0) / 0x100000000; }; prng.double = function() { do { var top = xg.next() >>> 11, bot = (xg.next() >>> 0) / 0x100000000, result = (top + bot) / (1 << 21); } while (result === 0); return result; }; prng.int32 = xg.next; prng.quick = prng; if (state) { if (state.X) copy(state, xg); prng.state = function() { return copy(xg, {}); }; } return prng; } if (module && module.exports) { module.exports = impl; } else if (define && define.amd) { define(function() { return impl; }); } else { this.xor4096 = impl; } })( commonjsGlobal, // window object or global module, // present in node.js (typeof undefined) == 'function' && undefined // present with an AMD loader ); }); var tychei = createCommonjsModule(function (module) { // A Javascript implementaion of the "Tyche-i" prng algorithm by // Samuel Neves and Filipe Araujo. // See https://eden.dei.uc.pt/~sneves/pubs/2011-snfa2.pdf (function(global, module, define) { function XorGen(seed) { var me = this, strseed = ''; // Set up generator function. me.next = function() { var b = me.b, c = me.c, d = me.d, a = me.a; b = (b << 25) ^ (b >>> 7) ^ c; c = (c - d) | 0; d = (d << 24) ^ (d >>> 8) ^ a; a = (a - b) | 0; me.b = b = (b << 20) ^ (b >>> 12) ^ c; me.c = c = (c - d) | 0; me.d = (d << 16) ^ (c >>> 16) ^ a; return me.a = (a - b) | 0; }; /* The following is non-inverted tyche, which has better internal * bit diffusion, but which is about 25% slower than tyche-i in JS. me.next = function() { var a = me.a, b = me.b, c = me.c, d = me.d; a = (me.a + me.b | 0) >>> 0; d = me.d ^ a; d = d << 16 ^ d >>> 16; c = me.c + d | 0; b = me.b ^ c; b = b << 12 ^ d >>> 20; me.a = a = a + b | 0; d = d ^ a; me.d = d = d << 8 ^ d >>> 24; me.c = c = c + d | 0; b = b ^ c; return me.b = (b << 7 ^ b >>> 25); } */ me.a = 0; me.b = 0; me.c = 2654435769 | 0; me.d = 1367130551; if (seed === Math.floor(seed)) { // Integer seed. me.a = (seed / 0x100000000) | 0; me.b = se