"use strict";
|
/**
|
* @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.
|
* =============================================================================
|
*/
|
Object.defineProperty(exports, "__esModule", { value: true });
|
var engine_1 = require("../engine");
|
var environment_1 = require("../environment");
|
var tensor_util_env_1 = require("../tensor_util_env");
|
var util_1 = require("../util");
|
var complex_ops_1 = require("./complex_ops");
|
var operation_1 = require("./operation");
|
/**
|
* Creates a `tf.Tensor` with the provided values, shape and dtype.
|
*
|
* ```js
|
* // Pass an array of values to create a vector.
|
* tf.tensor([1, 2, 3, 4]).print();
|
* ```
|
*
|
* ```js
|
* // Pass a nested array of values to make a matrix or a higher
|
* // dimensional tensor.
|
* tf.tensor([[1, 2], [3, 4]]).print();
|
* ```
|
*
|
* ```js
|
* // Pass a flat array and specify a shape yourself.
|
* tf.tensor([1, 2, 3, 4], [2, 2]).print();
|
* ```
|
*
|
* @param values The values of the tensor. Can be nested array of numbers,
|
* or a flat array, or a `TypedArray`. If the values are strings,
|
* they will be encoded as utf-8 and kept as `Uint8Array[]`.
|
* @param shape The shape of the tensor. Optional. If not provided,
|
* it is inferred from `values`.
|
* @param dtype The data type.
|
*/
|
/** @doc {heading: 'Tensors', subheading: 'Creation'} */
|
function tensor(values, shape, dtype) {
|
var inferredShape = tensor_util_env_1.inferShape(values, dtype);
|
return makeTensor(values, shape, inferredShape, dtype);
|
}
|
exports.tensor = tensor;
|
/** This is shared code across all tensor creation methods. */
|
function makeTensor(values, shape, inferredShape, dtype) {
|
if (dtype == null) {
|
dtype = util_1.inferDtype(values);
|
}
|
if (dtype === 'complex64') {
|
throw new Error("Cannot construct a complex64 tensor directly. " +
|
"Please use tf.complex(real, imag).");
|
}
|
if (!util_1.isTypedArray(values) && !Array.isArray(values) &&
|
typeof values !== 'number' && typeof values !== 'boolean' &&
|
typeof values !== 'string') {
|
throw new Error('values passed to tensor(values) must be a number/boolean/string or ' +
|
'an array of numbers/booleans/strings, or a TypedArray');
|
}
|
if (shape != null) {
|
util_1.assertNonNegativeIntegerDimensions(shape);
|
var providedSize_1 = util_1.sizeFromShape(shape);
|
var inferredSize_1 = util_1.sizeFromShape(inferredShape);
|
util_1.assert(providedSize_1 === inferredSize_1, function () {
|
return "Based on the provided shape, [" + shape + "], the tensor should have " +
|
(providedSize_1 + " values but has " + inferredSize_1);
|
});
|
for (var i = 0; i < inferredShape.length; ++i) {
|
var inferred = inferredShape[i];
|
var flatDimsDontMatch = i === inferredShape.length - 1 ?
|
inferred !== util_1.sizeFromShape(shape.slice(i)) :
|
true;
|
util_1.assert(inferredShape[i] === shape[i] || !flatDimsDontMatch, function () { return "Error creating a new Tensor. Inferred shape " +
|
("(" + inferredShape + ") does not match the provided ") +
|
("shape (" + shape + "). "); });
|
}
|
}
|
if (!util_1.isTypedArray(values) && !Array.isArray(values)) {
|
values = [values];
|
}
|
shape = shape || inferredShape;
|
values = dtype !== 'string' ?
|
util_1.toTypedArray(values, dtype, environment_1.env().getBool('DEBUG')) :
|
util_1.flatten(values, [], true);
|
return engine_1.ENGINE.makeTensor(values, shape, dtype);
|
}
|
/**
|
* Creates rank-0 `tf.Tensor` (scalar) with the provided value and dtype.
|
*
|
* The same functionality can be achieved with `tf.tensor`, but in general
|
* we recommend using `tf.scalar` as it makes the code more readable.
|
*
|
* ```js
|
* tf.scalar(3.14).print();
|
* ```
|
*
|
* @param value The value of the scalar.
|
* @param dtype The data type.
|
*/
|
/** @doc {heading: 'Tensors', subheading: 'Creation'} */
|
function scalar(value, dtype) {
|
if (((util_1.isTypedArray(value) && dtype !== 'string') || Array.isArray(value)) &&
|
dtype !== 'complex64') {
|
throw new Error('Error creating a new Scalar: value must be a primitive ' +
|
'(number|boolean|string)');
|
}
|
if (dtype === 'string' && util_1.isTypedArray(value) &&
|
!(value instanceof Uint8Array)) {
|
throw new Error('When making a scalar from encoded string, ' +
|
'the value must be `Uint8Array`.');
|
}
|
var shape = [];
|
var inferredShape = [];
|
return makeTensor(value, shape, inferredShape, dtype);
|
}
|
exports.scalar = scalar;
|
/**
|
* Creates rank-1 `tf.Tensor` with the provided values, shape and dtype.
|
*
|
* The same functionality can be achieved with `tf.tensor`, but in general
|
* we recommend using `tf.tensor1d` as it makes the code more readable.
|
*
|
* ```js
|
* tf.tensor1d([1, 2, 3]).print();
|
* ```
|
*
|
* @param values The values of the tensor. Can be array of numbers,
|
* or a `TypedArray`.
|
* @param dtype The data type.
|
*/
|
/** @doc {heading: 'Tensors', subheading: 'Creation'} */
|
function tensor1d(values, dtype) {
|
util_1.assertNonNull(values);
|
var inferredShape = tensor_util_env_1.inferShape(values, dtype);
|
if (inferredShape.length !== 1) {
|
throw new Error('tensor1d() requires values to be a flat/TypedArray');
|
}
|
var shape = null;
|
return makeTensor(values, shape, inferredShape, dtype);
|
}
|
exports.tensor1d = tensor1d;
|
/**
|
* Creates rank-2 `tf.Tensor` with the provided values, shape and dtype.
|
*
|
* The same functionality can be achieved with `tf.tensor`, but in general
|
* we recommend using `tf.tensor2d` as it makes the code more readable.
|
*
|
* ```js
|
* // Pass a nested array.
|
* tf.tensor2d([[1, 2], [3, 4]]).print();
|
* ```
|
* ```js
|
* // Pass a flat array and specify a shape.
|
* tf.tensor2d([1, 2, 3, 4], [2, 2]).print();
|
* ```
|
*
|
* @param values The values of the tensor. Can be nested array of numbers,
|
* or a flat array, or a `TypedArray`.
|
* @param shape The shape of the tensor. If not provided, it is inferred from
|
* `values`.
|
* @param dtype The data type.
|
*/
|
/** @doc {heading: 'Tensors', subheading: 'Creation'} */
|
function tensor2d(values, shape, dtype) {
|
util_1.assertNonNull(values);
|
if (shape != null && shape.length !== 2) {
|
throw new Error('tensor2d() requires shape to have two numbers');
|
}
|
var inferredShape = tensor_util_env_1.inferShape(values, dtype);
|
if (inferredShape.length !== 2 && inferredShape.length !== 1) {
|
throw new Error('tensor2d() requires values to be number[][] or flat/TypedArray');
|
}
|
if (inferredShape.length === 1 && shape == null) {
|
throw new Error('tensor2d() requires shape to be provided when `values` ' +
|
'are a flat/TypedArray');
|
}
|
return makeTensor(values, shape, inferredShape, dtype);
|
}
|
exports.tensor2d = tensor2d;
|
/**
|
* Creates rank-3 `tf.Tensor` with the provided values, shape and dtype.
|
*
|
* The same functionality can be achieved with `tf.tensor`, but in general
|
* we recommend using `tf.tensor3d` as it makes the code more readable.
|
*
|
* ```js
|
* // Pass a nested array.
|
* tf.tensor3d([[[1], [2]], [[3], [4]]]).print();
|
* ```
|
* ```js
|
* // Pass a flat array and specify a shape.
|
* tf.tensor3d([1, 2, 3, 4], [2, 2, 1]).print();
|
* ```
|
*
|
* @param values The values of the tensor. Can be nested array of numbers,
|
* or a flat array, or a `TypedArray`.
|
* @param shape The shape of the tensor. If not provided, it is inferred from
|
* `values`.
|
* @param dtype The data type.
|
*/
|
/** @doc {heading: 'Tensors', subheading: 'Creation'} */
|
function tensor3d(values, shape, dtype) {
|
util_1.assertNonNull(values);
|
if (shape != null && shape.length !== 3) {
|
throw new Error('tensor3d() requires shape to have three numbers');
|
}
|
var inferredShape = tensor_util_env_1.inferShape(values, dtype);
|
if (inferredShape.length !== 3 && inferredShape.length !== 1) {
|
throw new Error('tensor3d() requires values to be number[][][] or flat/TypedArray');
|
}
|
if (inferredShape.length === 1 && shape == null) {
|
throw new Error('tensor3d() requires shape to be provided when `values` ' +
|
'are a flat array');
|
}
|
return makeTensor(values, shape, inferredShape, dtype);
|
}
|
exports.tensor3d = tensor3d;
|
/**
|
* Creates rank-4 `tf.Tensor` with the provided values, shape and dtype.
|
*
|
* The same functionality can be achieved with `tf.tensor`, but in general
|
* we recommend using `tf.tensor4d` as it makes the code more readable.
|
*
|
* ```js
|
* // Pass a nested array.
|
* tf.tensor4d([[[[1], [2]], [[3], [4]]]]).print();
|
* ```
|
* ```js
|
* // Pass a flat array and specify a shape.
|
* tf.tensor4d([1, 2, 3, 4], [1, 2, 2, 1]).print();
|
* ```
|
*
|
* @param values The values of the tensor. Can be nested array of numbers,
|
* or a flat array, or a `TypedArray`.
|
* @param shape The shape of the tensor. Optional. If not provided,
|
* it is inferred from `values`.
|
* @param dtype The data type.
|
*/
|
/** @doc {heading: 'Tensors', subheading: 'Creation'} */
|
function tensor4d(values, shape, dtype) {
|
util_1.assertNonNull(values);
|
if (shape != null && shape.length !== 4) {
|
throw new Error('tensor4d() requires shape to have four numbers');
|
}
|
var inferredShape = tensor_util_env_1.inferShape(values, dtype);
|
if (inferredShape.length !== 4 && inferredShape.length !== 1) {
|
throw new Error('tensor4d() requires values to be number[][][][] or flat/TypedArray');
|
}
|
if (inferredShape.length === 1 && shape == null) {
|
throw new Error('tensor4d() requires shape to be provided when `values` ' +
|
'are a flat array');
|
}
|
return makeTensor(values, shape, inferredShape, dtype);
|
}
|
exports.tensor4d = tensor4d;
|
/**
|
* Creates rank-5 `tf.Tensor` with the provided values, shape and dtype.
|
*
|
* The same functionality can be achieved with `tf.tensor`, but in general
|
* we recommend using `tf.tensor5d` as it makes the code more readable.
|
*
|
* ```js
|
* // Pass a nested array.
|
* tf.tensor5d([[[[[1], [2]], [[3], [4]]]]]).print();
|
* ```
|
* ```js
|
* // Pass a flat array and specify a shape.
|
* tf.tensor5d([1, 2, 3, 4, 5, 6, 7, 8], [1, 2, 2, 2, 1]).print();
|
* ```
|
*
|
* @param values The values of the tensor. Can be nested array of numbers,
|
* or a flat array, or a `TypedArray`.
|
* @param shape The shape of the tensor. Optional. If not provided,
|
* it is inferred from `values`.
|
* @param dtype The data type.
|
*/
|
/** @doc {heading: 'Tensors', subheading: 'Creation'} */
|
function tensor5d(values, shape, dtype) {
|
util_1.assertNonNull(values);
|
if (shape != null && shape.length !== 5) {
|
throw new Error('tensor5d() requires shape to have five numbers');
|
}
|
var inferredShape = tensor_util_env_1.inferShape(values, dtype);
|
if (inferredShape.length !== 5 && inferredShape.length !== 1) {
|
throw new Error('tensor5d() requires values to be ' +
|
'number[][][][][] or flat/TypedArray');
|
}
|
if (inferredShape.length === 1 && shape == null) {
|
throw new Error('tensor5d() requires shape to be provided when `values` ' +
|
'are a flat array');
|
}
|
return makeTensor(values, shape, inferredShape, dtype);
|
}
|
exports.tensor5d = tensor5d;
|
/**
|
* Creates rank-6 `tf.Tensor` with the provided values, shape and dtype.
|
*
|
* The same functionality can be achieved with `tf.tensor`, but in general
|
* we recommend using `tf.tensor6d` as it makes the code more readable.
|
*
|
* ```js
|
* // Pass a nested array.
|
* tf.tensor6d([[[[[[1],[2]],[[3],[4]]],[[[5],[6]],[[7],[8]]]]]]).print();
|
* ```
|
* ```js
|
* // Pass a flat array and specify a shape.
|
* tf.tensor6d([1, 2, 3, 4, 5, 6, 7, 8], [1, 1, 2, 2, 2, 1]).print();
|
* ```
|
*
|
* @param values The values of the tensor. Can be nested array of numbers,
|
* or a flat array, or a `TypedArray`.
|
* @param shape The shape of the tensor. Optional. If not provided,
|
* it is inferred from `values`.
|
* @param dtype The data type.
|
*/
|
/** @doc {heading: 'Tensors', subheading: 'Creation'} */
|
function tensor6d(values, shape, dtype) {
|
util_1.assertNonNull(values);
|
if (shape != null && shape.length !== 6) {
|
throw new Error('tensor6d() requires shape to have six numbers');
|
}
|
var inferredShape = tensor_util_env_1.inferShape(values, dtype);
|
if (inferredShape.length !== 6 && inferredShape.length !== 1) {
|
throw new Error('tensor6d() requires values to be number[][][][][][] or ' +
|
'flat/TypedArray');
|
}
|
if (inferredShape.length === 1 && shape == null) {
|
throw new Error('tensor6d() requires shape to be provided when `values` ' +
|
'are a flat array');
|
}
|
shape = shape ||
|
inferredShape;
|
return makeTensor(values, shape, inferredShape, dtype);
|
}
|
exports.tensor6d = tensor6d;
|
/**
|
* Creates a new variable with the provided initial value.
|
* ```js
|
* const x = tf.variable(tf.tensor([1, 2, 3]));
|
* x.assign(tf.tensor([4, 5, 6]));
|
*
|
* x.print();
|
* ```
|
*
|
* @param initialValue Initial value for the tensor.
|
* @param trainable If true, optimizers are allowed to update it.
|
* @param name Name of the variable. Defaults to a unique id.
|
* @param dtype If set, initialValue will be converted to the given type.
|
*/
|
/** @doc {heading: 'Tensors', subheading: 'Creation'} */
|
function variable(initialValue, trainable, name, dtype) {
|
if (trainable === void 0) { trainable = true; }
|
return engine_1.ENGINE.makeVariable(initialValue, trainable, name, dtype);
|
}
|
exports.variable = variable;
|
/**
|
* Creates a `tf.Tensor` with all elements set to 1.
|
*
|
* ```js
|
* tf.ones([2, 2]).print();
|
* ```
|
*
|
* @param shape An array of integers defining the output tensor shape.
|
* @param dtype The type of an element in the resulting tensor. Defaults to
|
* 'float'.
|
*/
|
/** @doc {heading: 'Tensors', subheading: 'Creation'} */
|
function ones(shape, dtype) {
|
if (dtype === void 0) { dtype = 'float32'; }
|
if (dtype === 'complex64') {
|
var real_1 = ones(shape, 'float32');
|
var imag_1 = zeros(shape, 'float32');
|
return complex_ops_1.complex(real_1, imag_1);
|
}
|
var values = util_1.makeOnesTypedArray(util_1.sizeFromShape(shape), dtype);
|
return engine_1.ENGINE.makeTensor(values, shape, dtype);
|
}
|
exports.ones = ones;
|
/**
|
* Creates a `tf.Tensor` with all elements set to 0.
|
*
|
* ```js
|
* tf.zeros([2, 2]).print();
|
* ```
|
*
|
* @param shape An array of integers defining the output tensor shape.
|
* @param dtype The type of an element in the resulting tensor. Can
|
* be 'float32', 'int32' or 'bool'. Defaults to 'float'.
|
*/
|
/** @doc {heading: 'Tensors', subheading: 'Creation'} */
|
function zeros(shape, dtype) {
|
if (dtype === void 0) { dtype = 'float32'; }
|
if (dtype === 'complex64') {
|
var real_2 = zeros(shape, 'float32');
|
var imag_2 = zeros(shape, 'float32');
|
return complex_ops_1.complex(real_2, imag_2);
|
}
|
var values = util_1.makeZerosTypedArray(util_1.sizeFromShape(shape), dtype);
|
return engine_1.ENGINE.makeTensor(values, shape, dtype);
|
}
|
exports.zeros = zeros;
|
/**
|
* Creates a `tf.Tensor` filled with a scalar value.
|
*
|
* ```js
|
* tf.fill([2, 2], 4).print();
|
* ```
|
*
|
* @param shape An array of integers defining the output tensor shape.
|
* @param value The scalar value to fill the tensor with.
|
* @param dtype The type of an element in the resulting tensor. Defaults to
|
* 'float'.
|
*/
|
/** @doc {heading: 'Tensors', subheading: 'Creation'} */
|
function fill(shape, value, dtype) {
|
return engine_1.ENGINE.runKernelFunc(function (backend) { return backend.fill(shape, value, dtype); }, {});
|
}
|
exports.fill = fill;
|
/**
|
* Creates a `tf.Tensor` with all elements set to 1 with the same shape as the
|
* given tensor.
|
*
|
* ```js
|
* const x = tf.tensor([1, 2]);
|
* tf.onesLike(x).print();
|
* ```
|
* @param x A tensor.
|
*/
|
/** @doc {heading: 'Tensors', subheading: 'Creation'} */
|
function onesLike_(x) {
|
var $x = tensor_util_env_1.convertToTensor(x, 'x', 'onesLike');
|
if ($x.dtype === 'complex64') {
|
var r = exports.onesLike(complex_ops_1.real($x));
|
var i = exports.zerosLike(complex_ops_1.imag($x));
|
return complex_ops_1.complex(r, i);
|
}
|
var der = function (dy, saved) { return ({ $x: function () { return exports.zerosLike(dy); } }); };
|
return engine_1.ENGINE.runKernelFunc(function (backend) { return backend.onesLike($x); }, { $x: $x }, der);
|
}
|
/**
|
* Creates a `tf.Tensor` with all elements set to 0 with the same shape as the
|
* given tensor.
|
*
|
* ```js
|
* const x = tf.tensor([1, 2]);
|
* tf.zerosLike(x).print();
|
* ```
|
*
|
* @param x The tensor of required shape.
|
*/
|
/** @doc {heading: 'Tensors', subheading: 'Creation'} */
|
function zerosLike_(x) {
|
var $x = tensor_util_env_1.convertToTensor(x, 'x', 'zerosLike');
|
var der = function (dy, saved) { return ({ $x: function () { return exports.zerosLike(dy); } }); };
|
return engine_1.ENGINE.runKernelFunc(function (backend) { return backend.zerosLike($x); }, { $x: $x }, der);
|
}
|
/**
|
* Return an evenly spaced sequence of numbers over the given interval.
|
*
|
* ```js
|
* tf.linspace(0, 9, 10).print();
|
* ```
|
* @param start The start value of the sequence.
|
* @param stop The end value of the sequence.
|
* @param num The number of values to generate.
|
*/
|
/** @doc {heading: 'Tensors', subheading: 'Creation'} */
|
function linspace(start, stop, num) {
|
if (num <= 0) {
|
throw new Error('The number of values should be positive.');
|
}
|
return engine_1.ENGINE.runKernelFunc(function (backend) { return backend.linspace(start, stop, num); }, {});
|
}
|
exports.linspace = linspace;
|
/**
|
* Creates a new `tf.Tensor1D` filled with the numbers in the range provided.
|
*
|
* The tensor is a is half-open interval meaning it includes start, but
|
* excludes stop. Decrementing ranges and negative step values are also
|
* supported.
|
*
|
* ```js
|
* tf.range(0, 9, 2).print();
|
* ```
|
*
|
* @param start An integer start value
|
* @param stop An integer stop value
|
* @param step An integer increment (will default to 1 or -1)
|
* @param dtype The data type of the output tensor. Defaults to 'float32'.
|
*/
|
/** @doc {heading: 'Tensors', subheading: 'Creation'} */
|
function range(start, stop, step, dtype) {
|
if (step === void 0) { step = 1; }
|
if (dtype === void 0) { dtype = 'float32'; }
|
if (step === 0) {
|
throw new Error('Cannot have a step of zero');
|
}
|
var sameStartStop = start === stop;
|
var increasingRangeNegativeStep = start < stop && step < 0;
|
var decreasingRangePositiveStep = stop < start && step > 1;
|
if (sameStartStop || increasingRangeNegativeStep ||
|
decreasingRangePositiveStep) {
|
return zeros([0], dtype);
|
}
|
var numElements = Math.abs(Math.ceil((stop - start) / step));
|
var values = util_1.makeZerosTypedArray(numElements, dtype);
|
if (stop < start && step === 1) {
|
// Auto adjust the step's sign if it hasn't been set
|
// (or was set to 1)
|
step = -1;
|
}
|
values[0] = start;
|
for (var i = 1; i < values.length; i++) {
|
values[i] = values[i - 1] + step;
|
}
|
return tensor1d(values, dtype);
|
}
|
exports.range = range;
|
exports.onesLike = operation_1.op({ onesLike_: onesLike_ });
|
exports.zerosLike = operation_1.op({ zerosLike_: zerosLike_ });
|
//# sourceMappingURL=tensor_ops.js.map
|