"use strict";
|
/**
|
* @license
|
* Copyright 2018 Google Inc. 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 tensor_util_env_1 = require("../tensor_util_env");
|
var util = require("../util");
|
var operation_1 = require("./operation");
|
var tensor_ops_1 = require("./tensor_ops");
|
/**
|
* Computes `-1 * x` element-wise.
|
*
|
* ```js
|
* const x = tf.tensor2d([1, 2, -2, 0], [2, 2]);
|
*
|
* x.neg().print(); // or tf.neg(x)
|
* ```
|
*
|
* @param x The input tensor.
|
*/
|
/** @doc {heading: 'Operations', subheading: 'Basic math'} */
|
function neg_(x) {
|
var $x = tensor_util_env_1.convertToTensor(x, 'x', 'neg');
|
var grad = function (dy) {
|
return { x: function () { return dy.neg(); } };
|
};
|
var attrs = {};
|
var inputsToSave = [$x];
|
return engine_1.ENGINE.runKernelFunc(function (backend) { return backend.neg($x); }, { x: $x }, grad, 'Neg', attrs, inputsToSave);
|
}
|
/**
|
* Computes ceiling of input `tf.Tensor` element-wise: `ceil(x)`
|
*
|
* ```js
|
* const x = tf.tensor1d([.6, 1.1, -3.3]);
|
*
|
* x.ceil().print(); // or tf.ceil(x)
|
* ```
|
* @param x The input Tensor.
|
*/
|
/** @doc {heading: 'Operations', subheading: 'Basic math'} */
|
function ceil_(x) {
|
var $x = tensor_util_env_1.convertToTensor(x, 'x', 'ceil');
|
// TODO(manrajgrover): Return null for gradients when backprop supports it.
|
var grad = function (dy) {
|
return { $x: function () { return tensor_ops_1.zerosLike(dy); } };
|
};
|
return engine_1.ENGINE.runKernelFunc(function (backend) { return backend.ceil($x); }, { $x: $x }, grad);
|
}
|
/**
|
* Computes floor of input `tf.Tensor` element-wise: `floor(x)`.
|
*
|
* ```js
|
* const x = tf.tensor1d([.6, 1.1, -3.3]);
|
*
|
* x.floor().print(); // or tf.floor(x)
|
* ```
|
* @param x The input tensor.
|
*/
|
/** @doc {heading: 'Operations', subheading: 'Basic math'} */
|
function floor_(x) {
|
var $x = tensor_util_env_1.convertToTensor(x, 'x', 'floor');
|
// TODO(nsthorat): Let gradients be null for cases where we want to stop
|
// backpropgation.
|
var grad = function (dy) {
|
return { $x: function () { return tensor_ops_1.zerosLike(dy); } };
|
};
|
return engine_1.ENGINE.runKernelFunc(function (backend) { return backend.floor($x); }, { $x: $x }, grad);
|
}
|
/**
|
* Returns an element-wise indication of the sign of a number.
|
*
|
* ```js
|
* const x = tf.tensor1d([.6, 1.1, -3.3, NaN, 0]);
|
*
|
* x.sign().print(); // or tf.sign(x)
|
* ```
|
* @param x The input Tensor.
|
*/
|
/** @doc {heading: 'Operations', subheading: 'Basic math'} */
|
function sign_(x) {
|
var $x = tensor_util_env_1.convertToTensor(x, 'x', 'sign');
|
var grad = function (dy) {
|
return { $x: function () { return tensor_ops_1.zerosLike(dy); } };
|
};
|
return engine_1.ENGINE.runKernelFunc(function (backend) { return backend.sign($x); }, { $x: $x }, grad);
|
}
|
/**
|
* RReturns which elements of x are NaN.
|
*
|
* ```js
|
* const x = tf.tensor1d([NaN, Infinity, -Infinity, 0, 1]);
|
*
|
* x.isNaN().print(); // or tf.isNaN(x)
|
* ```
|
* @param x The input Tensor.
|
*/
|
/** @doc {heading: 'Operations', subheading: 'Basic math'} */
|
function isNaN_(x) {
|
var $x = tensor_util_env_1.convertToTensor(x, 'x', 'isNaN');
|
// TODO(nsthorat): Let gradients be null for cases where we want to stop
|
// backpropgation.
|
var grad = function (dy) {
|
return { $x: function () { return tensor_ops_1.zerosLike(dy); } };
|
};
|
return engine_1.ENGINE.runKernelFunc(function (backend) { return backend.isNaN($x); }, { $x: $x }, grad);
|
}
|
/**
|
* Returns which elements of x are Infinity or -Infinity.
|
*
|
* ```js
|
* const x = tf.tensor1d([NaN, Infinity, -Infinity, 0, 1]);
|
*
|
* x.isInf().print(); // or tf.isNaN(x)
|
* ```
|
* @param x The input Tensor.
|
*/
|
/** @doc {heading: 'Operations', subheading: 'Basic math'} */
|
function isInf_(x) {
|
var $x = tensor_util_env_1.convertToTensor(x, 'x', 'isInf');
|
// TODO(nsthorat): Let gradients be null for cases where we want to stop
|
// backpropgation.
|
var grad = function (dy) {
|
return { $x: function () { return tensor_ops_1.zerosLike(dy); } };
|
};
|
return engine_1.ENGINE.runKernelFunc(function (backend) { return backend.isInf($x); }, { $x: $x }, grad);
|
}
|
/**
|
* Returns which elements of x are finite.
|
*
|
* ```js
|
* const x = tf.tensor1d([NaN, Infinity, -Infinity, 0, 1]);
|
*
|
* x.isFinite().print(); // or tf.isNaN(x)
|
* ```
|
* @param x The input Tensor.
|
*/
|
/** @doc {heading: 'Operations', subheading: 'Basic math'} */
|
function isFinite_(x) {
|
var $x = tensor_util_env_1.convertToTensor(x, 'x', 'isFinite');
|
// TODO(nsthorat): Let gradients be null for cases where we want to stop
|
// backpropgation.
|
var grad = function (dy) {
|
return { $x: function () { return tensor_ops_1.zerosLike(dy); } };
|
};
|
return engine_1.ENGINE.runKernelFunc(function (backend) { return backend.isFinite($x); }, { $x: $x }, grad);
|
}
|
/**
|
* Computes round of input `tf.Tensor` element-wise: `round(x)`.
|
* It implements banker's rounding.
|
*
|
* ```js
|
* const x = tf.tensor1d([.6, 1.1, -3.3]);
|
*
|
* x.round().print(); // or tf.round(x)
|
* ```
|
* @param x The input tensor.
|
*/
|
/** @doc {heading: 'Operations', subheading: 'Basic math'} */
|
function round_(x) {
|
var $x = tensor_util_env_1.convertToTensor(x, 'x', 'round');
|
// TODO(nsthorat): Let gradients be null for cases where we want to stop
|
// backpropgation.
|
var grad = function (dy) {
|
return { $x: function () { return tensor_ops_1.zerosLike(dy); } };
|
};
|
return engine_1.ENGINE.runKernelFunc(function (backend) { return backend.round($x); }, { $x: $x }, grad);
|
}
|
/**
|
* Computes exponential of the input `tf.Tensor` element-wise. `e ^ x`
|
*
|
* ```js
|
* const x = tf.tensor1d([1, 2, -3]);
|
*
|
* x.exp().print(); // or tf.exp(x)
|
* ```
|
* @param x The input tensor.
|
*/
|
/** @doc {heading: 'Operations', subheading: 'Basic math'} */
|
function exp_(x) {
|
var $x = tensor_util_env_1.convertToTensor(x, 'x', 'exp');
|
var bck = function (dy, saved) {
|
return { x: function () { return dy.mulStrict(saved[0]); } };
|
};
|
var attrs = {};
|
var inputsToSave = [];
|
var outputsToSave = [true];
|
return engine_1.ENGINE.runKernelFunc(function (backend, save) {
|
var y = backend.exp($x);
|
save([y]);
|
return y;
|
}, { x: $x }, bck, 'Exp', attrs, inputsToSave, outputsToSave);
|
}
|
/**
|
* Computes exponential of the input `tf.Tensor` minus one element-wise.
|
* `e ^ x - 1`
|
*
|
* ```js
|
* const x = tf.tensor1d([1, 2, -3]);
|
*
|
* x.expm1().print(); // or tf.expm1(x)
|
* ```
|
* @param x The input tensor.
|
*/
|
/** @doc {heading: 'Operations', subheading: 'Basic math'} */
|
function expm1_(x) {
|
var $x = tensor_util_env_1.convertToTensor(x, 'x', 'expm1');
|
var grad = function (dy, saved) {
|
var $x = saved[0];
|
return { $x: function () { return dy.mul($x.exp()); } };
|
};
|
return engine_1.ENGINE.runKernelFunc(function (backend, save) {
|
var res = backend.expm1($x);
|
save([$x]);
|
return res;
|
}, { $x: $x }, grad);
|
}
|
/**
|
* Computes natural logarithm of the input `tf.Tensor` element-wise: `ln(x)`
|
*
|
* ```js
|
* const x = tf.tensor1d([1, 2, Math.E]);
|
*
|
* x.log().print(); // or tf.log(x)
|
* ```
|
* @param x The input tensor.
|
*/
|
/** @doc {heading: 'Operations', subheading: 'Basic math'} */
|
function log_(x) {
|
var $x = tensor_util_env_1.convertToTensor(x, 'x', 'log');
|
var grad = function (dy, saved) {
|
var $x = saved[0];
|
return { x: function () { return dy.div($x.toFloat()); } };
|
};
|
var attrs = {};
|
var inputsToSave = [$x];
|
return engine_1.ENGINE.runKernelFunc(function (backend, save) {
|
var res = backend.log($x);
|
save([$x]);
|
return res;
|
}, { x: $x }, grad, 'Log', attrs, inputsToSave);
|
}
|
/**
|
* Computes natural logarithm of the input `tf.Tensor` plus one
|
* element-wise: `ln(1 + x)`
|
*
|
* ```js
|
* const x = tf.tensor1d([1, 2, Math.E - 1]);
|
*
|
* x.log1p().print(); // or tf.log1p(x)
|
* ```
|
* @param x The input tensor.
|
*/
|
/** @doc {heading: 'Operations', subheading: 'Basic math'} */
|
function log1p_(x) {
|
var $x = tensor_util_env_1.convertToTensor(x, 'x', 'log1p');
|
var grad = function (dy, saved) {
|
var $x = saved[0];
|
return { $x: function () { return dy.div($x.add(1)); } };
|
};
|
return engine_1.ENGINE.runKernelFunc(function (backend, save) {
|
var res = backend.log1p($x);
|
save([$x]);
|
return res;
|
}, { $x: $x }, grad);
|
}
|
/**
|
* Computes square root of the input `tf.Tensor` element-wise: `y = sqrt(x)`
|
*
|
* ```js
|
* const x = tf.tensor1d([1, 2, 4, -1]);
|
*
|
* x.sqrt().print(); // or tf.sqrt(x)
|
* ```
|
* @param x The input tensor.
|
*/
|
/** @doc {heading: 'Operations', subheading: 'Basic math'} */
|
function sqrt_(x) {
|
var $x = tensor_util_env_1.convertToTensor(x, 'x', 'sqrt');
|
var grad = function (dy, saved) {
|
var $x = saved[0];
|
return { $x: function () { return dy.div($x.toFloat().sqrt().mul(2)); } };
|
};
|
return engine_1.ENGINE.runKernelFunc(function (backend, save) {
|
var res = backend.sqrt($x);
|
save([$x]);
|
return res;
|
}, { $x: $x }, grad);
|
}
|
/**
|
* Computes reciprocal of square root of the input `tf.Tensor` element-wise:
|
* `y = 1 / sqrt(x)`
|
*
|
* ```js
|
* const x = tf.tensor1d([1, 2, 4, -1]);
|
*
|
* x.rsqrt().print(); // or tf.rsqrt(x)
|
* ```
|
* @param x The input tensor.
|
*/
|
/** @doc {heading: 'Operations', subheading: 'Basic math'} */
|
function rsqrt_(x) {
|
var $x = tensor_util_env_1.convertToTensor(x, 'x', 'rsqrt');
|
var grad = function (dy, saved) {
|
var $x = saved[0];
|
return { x: function () { return dy.div($x.pow(1.5).mul(2)).neg(); } };
|
};
|
var inputsToSave = [$x];
|
return engine_1.ENGINE.runKernelFunc(function (backend, save) {
|
var res = backend.rsqrt($x);
|
save([$x]);
|
return res;
|
}, { x: $x }, grad, 'Rsqrt', {} /* attrs */, inputsToSave);
|
}
|
/**
|
* Computes reciprocal of x element-wise: `1 / x`
|
*
|
* ```js
|
* const x = tf.tensor1d([0, 1, 2]);
|
*
|
* x.reciprocal().print(); // or tf.reciprocal(x)
|
* ```
|
* @param x The input tensor.
|
*/
|
/** @doc {heading: 'Operations', subheading: 'Basic math'} */
|
function reciprocal_(x) {
|
var $x = tensor_util_env_1.convertToTensor(x, 'x', 'reciprocal');
|
var grad = function (dy, saved) {
|
var $x = saved[0];
|
return { $x: function () { return dy.div($x.square().neg()); } };
|
};
|
return engine_1.ENGINE.runKernelFunc(function (backend, save) {
|
var res = backend.reciprocal($x);
|
save([$x]);
|
return res;
|
}, { $x: $x }, grad);
|
}
|
/**
|
* Computes absolute value element-wise: `abs(x)`
|
*
|
* ```js
|
* const x = tf.tensor1d([-1, 2, -3, 4]);
|
*
|
* x.abs().print(); // or tf.abs(x)
|
* ```
|
* @param x The input `tf.Tensor`.
|
*/
|
/** @doc {heading: 'Operations', subheading: 'Basic math'} */
|
function abs_(x) {
|
var $x = tensor_util_env_1.convertToTensor(x, 'x', 'abs');
|
if ($x.dtype === 'complex64') {
|
return engine_1.ENGINE.runKernelFunc(function (backend) { return backend.complexAbs($x); }, { $x: $x });
|
}
|
var grad = function (dy, saved) {
|
var $x = saved[0];
|
return { x: function () { return dy.mul($x.toFloat().step(-1)); } };
|
};
|
return engine_1.ENGINE.runKernelFunc(function (backend, save) {
|
var res = backend.abs($x);
|
save([$x]);
|
return res;
|
}, { x: $x }, grad, 'Abs');
|
}
|
/**
|
* Clips values element-wise. `max(min(x, clipValueMax), clipValueMin)`
|
*
|
* ```js
|
* const x = tf.tensor1d([-1, 2, -3, 4]);
|
*
|
* x.clipByValue(-2, 3).print(); // or tf.clipByValue(x, -2, 3)
|
* ```
|
* @param x The input tensor.
|
* @param clipValueMin Lower-bound of range to be clipped to.
|
* @param clipValueMax Upper-bound of range to be clipped to.
|
*/
|
/** @doc {heading: 'Operations', subheading: 'Basic math'} */
|
function clipByValue_(x, clipValueMin, clipValueMax) {
|
var $x = tensor_util_env_1.convertToTensor(x, 'x', 'clipByValue');
|
util.assert((clipValueMin <= clipValueMax), function () { return "Error in clip: min (" + clipValueMin + ") must be " +
|
("less than or equal to max (" + clipValueMax + ")."); });
|
var grad = function (dy, saved) {
|
var $x = saved[0];
|
return {
|
x: function () { return dy.where($x.greaterEqual(clipValueMin)
|
.logicalAnd($x.lessEqual(clipValueMax)), tensor_ops_1.zerosLike(dy)); },
|
};
|
};
|
var inputsToSave = [$x];
|
var attr = { min: clipValueMin, max: clipValueMax };
|
return engine_1.ENGINE.runKernelFunc(function (backend, save) {
|
var res = backend.clip($x, clipValueMin, clipValueMax);
|
save([$x]);
|
return res;
|
}, { x: $x }, grad, 'ClipByValue', attr, inputsToSave);
|
}
|
/**
|
* Computes sigmoid element-wise, `1 / (1 + exp(-x))`
|
*
|
* ```js
|
* const x = tf.tensor1d([0, -1, 2, -3]);
|
*
|
* x.sigmoid().print(); // or tf.sigmoid(x)
|
* ```
|
* @param x The input tensor.
|
*/
|
/** @doc {heading: 'Operations', subheading: 'Basic math'} */
|
function sigmoid_(x) {
|
var $x = tensor_util_env_1.convertToTensor(x, 'x', 'sigmoid');
|
var grad = function (dy, saved) {
|
var y = saved[0];
|
return { x: function () { return dy.mul(y.mul(tensor_ops_1.scalar(1).sub(y))); } };
|
};
|
return engine_1.ENGINE.runKernelFunc(function (backend, save) {
|
var y = backend.sigmoid($x);
|
save([y]);
|
return y;
|
}, { x: $x }, grad, 'Sigmoid');
|
}
|
/**
|
* Computes log sigmoid of the input `tf.Tensor` element-wise:
|
* `logSigmoid(x)`. For numerical stability, we use `-tf.softplus(-x)`.
|
*
|
* ```js
|
* const x = tf.tensor1d([0, 1, -1, .7]);
|
*
|
* x.logSigmoid().print(); // or tf.logSigmoid(x)
|
* ```
|
* @param x The input tensor.
|
*/
|
/** @doc {heading: 'Operations', subheading: 'Basic math'} */
|
function logSigmoid_(x) {
|
var $x = tensor_util_env_1.convertToTensor(x, 'x', 'logSigmoid');
|
var grad = function (dy, saved) {
|
var $x = saved[0];
|
return { $x: function () { return dy.mul($x.neg().sigmoid()); } };
|
};
|
return engine_1.ENGINE.runKernelFunc(function (backend, save) {
|
var res = backend.softplus($x.neg()).neg();
|
save([$x]);
|
return res;
|
}, { $x: $x }, grad);
|
}
|
/**
|
* Computes softplus of the input `tf.Tensor` element-wise: `log(exp(x) + 1)`
|
*
|
* ```js
|
* const x = tf.tensor1d([0, 1, -1, .7]);
|
*
|
* x.softplus().print(); // or tf.softplus(x)
|
* ```
|
* @param x The input tensor.
|
*/
|
/** @doc {heading: 'Operations', subheading: 'Basic math'} */
|
function softplus_(x) {
|
var $x = tensor_util_env_1.convertToTensor(x, 'x', 'softplus');
|
var grad = function (dy, saved) {
|
var $x = saved[0];
|
return { $x: function () { return dy.mul($x.sigmoid()); } };
|
};
|
return engine_1.ENGINE.runKernelFunc(function (backend, save) {
|
var res = backend.softplus($x);
|
save([$x]);
|
return res;
|
}, { $x: $x }, grad);
|
}
|
/**
|
* Computes sin of the input Tensor element-wise: `sin(x)`
|
*
|
* ```js
|
* const x = tf.tensor1d([0, Math.PI / 2, Math.PI * 3 / 4]);
|
*
|
* x.sin().print(); // or tf.sin(x)
|
* ```
|
* @param x The input tensor.
|
*/
|
/** @doc {heading: 'Operations', subheading: 'Basic math'} */
|
function sin_(x) {
|
var $x = tensor_util_env_1.convertToTensor(x, 'x', 'sin');
|
var grad = function (dy, saved) {
|
var $x = saved[0];
|
return { x: function () { return $x.toFloat().cos().mul(dy); } };
|
};
|
var inputsToSave = [$x];
|
return engine_1.ENGINE.runKernelFunc(function (backend, save) {
|
var res = backend.sin($x);
|
save([$x]);
|
return res;
|
}, { x: $x }, grad, 'Sin', {} /* attrs */, inputsToSave);
|
}
|
/**
|
* Computes cos of the input `tf.Tensor` element-wise: `cos(x)`
|
*
|
* ```js
|
* const x = tf.tensor1d([0, Math.PI / 2, Math.PI * 3 / 4]);
|
*
|
* x.cos().print(); // or tf.cos(x)
|
* ```
|
* @param x The input tensor.
|
*/
|
/** @doc {heading: 'Operations', subheading: 'Basic math'} */
|
function cos_(x) {
|
var $x = tensor_util_env_1.convertToTensor(x, 'x', 'cos');
|
var grad = function (dy, saved) {
|
var $x = saved[0];
|
return { x: function () { return $x.toFloat().sin().neg().mul(dy); } };
|
};
|
var inputsToSave = [$x];
|
return engine_1.ENGINE.runKernelFunc(function (backend, save) {
|
var res = backend.cos($x);
|
save([$x]);
|
return res;
|
}, { x: $x }, grad, 'Cos', {} /* attrs */, inputsToSave);
|
}
|
/**
|
* Computes tan of the input `tf.Tensor` element-wise, `tan(x)`
|
*
|
* ```js
|
* const x = tf.tensor1d([0, Math.PI / 2, Math.PI * 3 / 4]);
|
*
|
* x.tan().print(); // or tf.tan(x)
|
* ```
|
* @param x The input tensor.
|
*/
|
/** @doc {heading: 'Operations', subheading: 'Basic math'} */
|
function tan_(x) {
|
var $x = tensor_util_env_1.convertToTensor(x, 'x', 'tan');
|
var grad = function (dy, saved) {
|
var $x = saved[0];
|
return { $x: function () { return dy.div($x.cos().square()); } };
|
};
|
return engine_1.ENGINE.runKernelFunc(function (backend, save) {
|
var res = backend.tan($x);
|
save([$x]);
|
return res;
|
}, { $x: $x }, grad);
|
}
|
/**
|
* Computes asin of the input `tf.Tensor` element-wise: `asin(x)`
|
*
|
* ```js
|
* const x = tf.tensor1d([0, 1, -1, .7]);
|
*
|
* x.asin().print(); // or tf.asin(x)
|
* ```
|
* @param x The input tensor.
|
*/
|
/** @doc {heading: 'Operations', subheading: 'Basic math'} */
|
function asin_(x) {
|
var $x = tensor_util_env_1.convertToTensor(x, 'x', 'asin');
|
var grad = function (dy, saved) {
|
var $x = saved[0];
|
return {
|
$x: function () { return dy.divStrict(tensor_ops_1.scalar(1).sub($x.toFloat().square()).sqrt()); }
|
};
|
};
|
return engine_1.ENGINE.runKernelFunc(function (backend, save) {
|
var res = backend.asin($x);
|
save([$x]);
|
return res;
|
}, { $x: $x }, grad);
|
}
|
/**
|
* Computes acos of the input `tf.Tensor` element-wise: `acos(x)`
|
*
|
* ```js
|
* const x = tf.tensor1d([0, 1, -1, .7]);
|
*
|
* x.acos().print(); // or tf.acos(x)
|
* ```
|
* @param x The input tensor.
|
*/
|
/** @doc {heading: 'Operations', subheading: 'Basic math'} */
|
function acos_(x) {
|
var $x = tensor_util_env_1.convertToTensor(x, 'x', 'acos');
|
var grad = function (dy, saved) {
|
var $x = saved[0];
|
return {
|
$x: function () {
|
return dy.divStrict(tensor_ops_1.scalar(1).sub($x.toFloat().square()).sqrt()).neg();
|
}
|
};
|
};
|
return engine_1.ENGINE.runKernelFunc(function (backend, save) {
|
var res = backend.acos($x);
|
save([$x]);
|
return res;
|
}, { $x: $x }, grad);
|
}
|
/**
|
* Computes atan of the input `tf.Tensor` element-wise: `atan(x)`
|
*
|
* ```js
|
* const x = tf.tensor1d([0, 1, -1, .7]);
|
*
|
* x.atan().print(); // or tf.atan(x)
|
* ```
|
* @param x The input tensor.
|
*/
|
/** @doc {heading: 'Operations', subheading: 'Basic math'} */
|
function atan_(x) {
|
var $x = tensor_util_env_1.convertToTensor(x, 'x', 'atan');
|
var grad = function (dy, saved) {
|
var $x = saved[0];
|
return { $x: function () { return dy.div($x.toFloat().square().add(1)); } };
|
};
|
return engine_1.ENGINE.runKernelFunc(function (backend, save) {
|
var res = backend.atan($x);
|
save([$x]);
|
return res;
|
}, { $x: $x }, grad);
|
}
|
/**
|
* Computes hyperbolic sin of the input `tf.Tensor` element-wise: `sinh(x)`
|
*
|
* ```js
|
* const x = tf.tensor1d([0, 1, -1, .7]);
|
*
|
* x.sinh().print(); // or tf.sinh(x)
|
* ```
|
* @param x The input tensor.
|
*/
|
/** @doc {heading: 'Operations', subheading: 'Basic math'} */
|
function sinh_(x) {
|
var $x = tensor_util_env_1.convertToTensor(x, 'x', 'sinh');
|
var grad = function (dy, saved) {
|
var $x = saved[0];
|
return { $x: function () { return $x.toFloat().cosh().mulStrict(dy); } };
|
};
|
return engine_1.ENGINE.runKernelFunc(function (backend, save) {
|
var res = backend.sinh($x);
|
save([$x]);
|
return res;
|
}, { $x: $x }, grad);
|
}
|
/**
|
* Computes hyperbolic cos of the input `tf.Tensor` element-wise: `cosh(x)`
|
*
|
* ```js
|
* const x = tf.tensor1d([0, 1, -1, .7]);
|
*
|
* x.cosh().print(); // or tf.cosh(x)
|
* ```
|
* @param x The input tensor.
|
*/
|
/** @doc {heading: 'Operations', subheading: 'Basic math'} */
|
function cosh_(x) {
|
var $x = tensor_util_env_1.convertToTensor(x, 'x', 'cosh');
|
var grad = function (dy, saved) {
|
var $x = saved[0];
|
return { $x: function () { return $x.toFloat().sinh().mulStrict(dy); } };
|
};
|
return engine_1.ENGINE.runKernelFunc(function (backend, save) {
|
var res = backend.cosh($x);
|
save([$x]);
|
return res;
|
}, { $x: $x }, grad);
|
}
|
/**
|
* Computes hyperbolic tangent of the input `tf.Tensor` element-wise: `tanh(x)`
|
*
|
* ```js
|
* const x = tf.tensor1d([0, 1, -1, 70]);
|
*
|
* x.tanh().print(); // or tf.tanh(x)
|
* ```
|
* @param x The input tensor.
|
*/
|
/** @doc {heading: 'Operations', subheading: 'Basic math'} */
|
function tanh_(x) {
|
var $x = tensor_util_env_1.convertToTensor(x, 'x', 'tanh');
|
var grad = function (dy, saved) {
|
var y = saved[0];
|
return { x: function () { return tensor_ops_1.scalar(1).sub(y.square()).mulStrict(dy); } };
|
};
|
var outputsToSave = [true];
|
return engine_1.ENGINE.runKernelFunc(function (backend, save) {
|
var y = backend.tanh($x);
|
save([y]);
|
return y;
|
}, { x: $x }, grad, 'Tanh', {} /* attrs */, null /* inputsToSave */, outputsToSave);
|
}
|
/**
|
* Computes inverse hyperbolic sin of the input `tf.Tensor` element-wise:
|
* `asinh(x)`
|
*
|
* ```js
|
* const x = tf.tensor1d([0, 1, -1, .7]);
|
*
|
* x.asinh().print(); // or tf.asinh(x)
|
* ```
|
* @param x The input tensor.
|
*/
|
/** @doc {heading: 'Operations', subheading: 'Basic math'} */
|
function asinh_(x) {
|
var $x = tensor_util_env_1.convertToTensor(x, 'x', 'asinh');
|
var grad = function (dy, saved) {
|
var $x = saved[0];
|
return {
|
$x: function () { return dy.divStrict(tensor_ops_1.scalar(1).add($x.toFloat().square()).sqrt()); }
|
};
|
};
|
return engine_1.ENGINE.runKernelFunc(function (backend, save) {
|
var res = backend.asinh($x);
|
save([$x]);
|
return res;
|
}, { $x: $x }, grad);
|
}
|
/**
|
* Computes the inverse hyperbolic cos of the input `tf.Tensor` element-wise:
|
* `acosh(x)`
|
*
|
* ```js
|
* const x = tf.tensor1d([10, 1, 3, 5.7]);
|
*
|
* x.acosh().print(); // or tf.acosh(x)
|
* ```
|
* @param x The input tensor.
|
*/
|
/** @doc {heading: 'Operations', subheading: 'Basic math'} */
|
function acosh_(x) {
|
var $x = tensor_util_env_1.convertToTensor(x, 'x', 'acosh');
|
var grad = function (dy, saved) {
|
var $x = saved[0];
|
return { $x: function () { return dy.divStrict($x.toFloat().square().sub(1).sqrt()); } };
|
};
|
return engine_1.ENGINE.runKernelFunc(function (backend, save) {
|
var res = backend.acosh($x);
|
save([$x]);
|
return res;
|
}, { $x: $x }, grad);
|
}
|
/**
|
* Computes inverse hyperbolic tan of the input `tf.Tensor` element-wise:
|
* `atanh(x)`
|
*
|
* ```js
|
* const x = tf.tensor1d([0, .1, -.1, .7]);
|
*
|
* x.atanh().print(); // or tf.atanh(x)
|
* ```
|
* @param x The input tensor.
|
*/
|
/** @doc {heading: 'Operations', subheading: 'Basic math'} */
|
function atanh_(x) {
|
var $x = tensor_util_env_1.convertToTensor(x, 'x', 'atanh');
|
var grad = function (dy, saved) {
|
var $x = saved[0];
|
return { $x: function () { return dy.div(tensor_ops_1.scalar(1).sub($x.toFloat().square())); } };
|
};
|
return engine_1.ENGINE.runKernelFunc(function (backend, save) {
|
var res = backend.atanh($x);
|
save([$x]);
|
return res;
|
}, { $x: $x }, grad);
|
}
|
/**
|
* Computes gause error function of the input `tf.Tensor` element-wise:
|
* `erf(x)`
|
*
|
* ```js
|
* const x = tf.tensor1d([0, .1, -.1, .7]);
|
*
|
* x.erf().print(); // or tf.erf(x);
|
* ```
|
* @param x The input tensor.
|
*/
|
/** @doc {heading: 'Operations', subheading: 'Basic math'} */
|
function erf_(x) {
|
var $x = tensor_util_env_1.convertToTensor(x, 'x', 'erf');
|
util.assert($x.dtype === 'int32' || $x.dtype === 'float32', function () { return 'Input dtype must be `int32` or `float32`.'; });
|
if ($x.dtype === 'int32') {
|
$x = $x.toFloat();
|
}
|
var grad = function (dy, saved) {
|
var $x = saved[0];
|
return {
|
$x: function () { return dy.mul($x.square().neg().exp().mul(2 / Math.sqrt(Math.PI))); }
|
};
|
};
|
return engine_1.ENGINE.runKernelFunc(function (backend, save) {
|
var res = backend.erf($x);
|
save([$x]);
|
return res;
|
}, { $x: $x }, grad);
|
}
|
/**
|
* Computes step of the input `tf.Tensor` element-wise: `x > 0 ? 1 : alpha * x`
|
*
|
* ```js
|
* const x = tf.tensor1d([0, 2, -1, -3]);
|
*
|
* x.step(.5).print(); // or tf.step(x, .5)
|
* ```
|
* @param x The input tensor.
|
* @param alpha The gradient when input is negative.
|
*/
|
/** @doc {heading: 'Operations', subheading: 'Basic math'} */
|
function step_(x, alpha) {
|
if (alpha === void 0) { alpha = 0.0; }
|
var $x = tensor_util_env_1.convertToTensor(x, 'x', 'step');
|
// TODO(manrajgrover): Return null for gradients when backprop supports
|
// it.
|
var grad = function (dy) {
|
return { $x: function () { return tensor_ops_1.zerosLike(dy); } };
|
};
|
return engine_1.ENGINE.runKernelFunc(function (backend) { return backend.step($x, alpha); }, { $x: $x }, grad);
|
}
|
exports.abs = operation_1.op({ abs_: abs_ });
|
exports.acos = operation_1.op({ acos_: acos_ });
|
exports.acosh = operation_1.op({ acosh_: acosh_ });
|
exports.asin = operation_1.op({ asin_: asin_ });
|
exports.asinh = operation_1.op({ asinh_: asinh_ });
|
exports.atan = operation_1.op({ atan_: atan_ });
|
exports.atanh = operation_1.op({ atanh_: atanh_ });
|
exports.ceil = operation_1.op({ ceil_: ceil_ });
|
exports.clipByValue = operation_1.op({ clipByValue_: clipByValue_ });
|
exports.cos = operation_1.op({ cos_: cos_ });
|
exports.cosh = operation_1.op({ cosh_: cosh_ });
|
exports.erf = operation_1.op({ erf_: erf_ });
|
exports.exp = operation_1.op({ exp_: exp_ });
|
exports.expm1 = operation_1.op({ expm1_: expm1_ });
|
exports.floor = operation_1.op({ floor_: floor_ });
|
exports.log = operation_1.op({ log_: log_ });
|
exports.log1p = operation_1.op({ log1p_: log1p_ });
|
exports.logSigmoid = operation_1.op({ logSigmoid_: logSigmoid_ });
|
exports.neg = operation_1.op({ neg_: neg_ });
|
exports.reciprocal = operation_1.op({ reciprocal_: reciprocal_ });
|
exports.round = operation_1.op({ round_: round_ });
|
exports.rsqrt = operation_1.op({ rsqrt_: rsqrt_ });
|
exports.sigmoid = operation_1.op({ sigmoid_: sigmoid_ });
|
exports.sign = operation_1.op({ sign_: sign_ });
|
exports.isNaN = operation_1.op({ isNaN_: isNaN_ });
|
exports.isInf = operation_1.op({ isInf_: isInf_ });
|
exports.isFinite = operation_1.op({ isFinite_: isFinite_ });
|
exports.sin = operation_1.op({ sin_: sin_ });
|
exports.sinh = operation_1.op({ sinh_: sinh_ });
|
exports.softplus = operation_1.op({ softplus_: softplus_ });
|
exports.sqrt = operation_1.op({ sqrt_: sqrt_ });
|
exports.step = operation_1.op({ step_: step_ });
|
exports.tan = operation_1.op({ tan_: tan_ });
|
exports.tanh = operation_1.op({ tanh_: tanh_ });
|
//# sourceMappingURL=unary_ops.js.map
|