diff --git a/lib/util/matrix.js b/lib/util/matrix.js index a1f5e424..95f34b73 100644 --- a/lib/util/matrix.js +++ b/lib/util/matrix.js @@ -1316,33 +1316,43 @@ export default class Matrix { return r } + /** + * Returns a matrix reduced along all element with the callback function. + * @overload + * @param {function (T, T, number[], Matrix): T} cb Reducing function + * @param {undefined | null} [init] Initial value + * @returns {T} Reduced value + */ /** * Returns a matrix reduced along all element with the callback function. * @template U * @overload * @param {function (U, T, number[], Matrix): U} cb Reducing function - * @param {U} [init] Initial value + * @param {U} init Initial value * @returns {U} Reduced value */ /** * Returns a matrix reduced along the axis with the callback function. - * @template U + * @template {number | number[]} A + * @template {boolean} F * @overload - * @param {function (U, T, number[], Matrix): U} cb Reducing function - * @param {U} init Initial value - * @param {0 | 1} axis Axis to be reduced - * @param {boolean} [keepdims] Keep dimensions or not. If null, negative axis retuns number and other axis returns Matrix. - * @returns {Matrix} Reduced matrix + * @param {function (T, T, number[], Matrix): T} cb Reducing function + * @param {undefined | null} init Initial value + * @param {A} axis Axis to be reduced + * @param {F} [keepdims] Keep dimensions or not. If null, negative axis retuns number and other axis returns Matrix. + * @returns {Matrix | (A extends 0 | 1 ? never : F extends true ? never : T)} Reduced matrix */ /** * Returns a matrix reduced along the axis with the callback function. * @template U + * @template {number | number[]} A + * @template {boolean} F * @overload * @param {function (U, T, number[], Matrix): U} cb Reducing function * @param {U} init Initial value - * @param {number | number[]} axis Axis to be reduced. If negative, reduce along all elements. - * @param {boolean} [keepdims] Keep dimensions or not. If null, negative axis retuns number and other axis returns Matrix. - * @returns {Matrix | U} Reduced matrix or value + * @param {A} axis Axis to be reduced + * @param {F} [keepdims] Keep dimensions or not. If null, negative axis retuns number and other axis returns Matrix. + * @returns {Matrix | (A extends 0 | 1 ? never : F extends true ? never : U)} Reduced matrix */ /** * @template U diff --git a/lib/util/tensor.js b/lib/util/tensor.js index ea4f7228..85e4781d 100644 --- a/lib/util/tensor.js +++ b/lib/util/tensor.js @@ -9,13 +9,19 @@ const normal_random = function (m, s) { return [X * std + m, Y * std + m] } +/** + * @template {number} T + * @typedef {Array>} NestedArray + */ + /** * Tensor class + * @template {*} [T=number] - Element type */ export default class Tensor { /** * @param {number[]} size Sizes for each dimension - * @param {number | number[]} [value] Initial values + * @param {T | NestedArray} [value] Initial values */ constructor(size, value) { /** @private */ @@ -38,17 +44,17 @@ export default class Tensor { * Returns a tensor filled with 0. * @overload * @param {...number} size Sizes for each dimension - * @returns {Tensor} Tensor filled with 0 + * @returns {Tensor} Tensor filled with 0 */ /** * Returns a tensor filled with 0. * @overload * @param {number[]} size Sizes for each dimension - * @returns {Tensor} Tensor filled with 0 + * @returns {Tensor} Tensor filled with 0 */ /** * @param {...number | number[]} size Sizes for each dimension - * @returns {Tensor} Tensor filled with 0 + * @returns {Tensor} Tensor filled with 0 */ static zeros(...size) { return new Tensor(Array.isArray(size[0]) ? size[0] : size) @@ -58,17 +64,17 @@ export default class Tensor { * Returns a tensor filled with 1. * @overload * @param {...number} size Sizes for each dimension - * @returns {Tensor} Tensor filled with 1 + * @returns {Tensor} Tensor filled with 1 */ /** * Returns a tensor filled with 1. * @overload * @param {number[]} size Sizes for each dimension - * @returns {Tensor} Tensor filled with 1 + * @returns {Tensor} Tensor filled with 1 */ /** * @param {...number | number[]} size Sizes for each dimension - * @returns {Tensor} Tensor filled with 1 + * @returns {Tensor} Tensor filled with 1 */ static ones(...size) { return new Tensor(Array.isArray(size[0]) ? size[0] : size, 1) @@ -79,7 +85,7 @@ export default class Tensor { * @param {number[]} size Sizes for each dimension * @param {number} [min] Minimum value of the Tensor * @param {number} [max] Maximum value of the Tensor - * @returns {Tensor} Tensor initialized uniform random values + * @returns {Tensor} Tensor initialized uniform random values */ static random(size, min = 0, max = 1) { const mat = new Tensor(size) @@ -94,7 +100,7 @@ export default class Tensor { * @param {number[]} size Sizes for each dimension * @param {number} [myu] Mean value of the Tensor * @param {number} [sigma] Variance value of the Tensor - * @returns {Tensor} Tensor initialized normal random values + * @returns {Tensor} Tensor initialized normal random values */ static randn(size, myu = 0, sigma = 1) { const mat = new Tensor(size) @@ -110,8 +116,9 @@ export default class Tensor { /** * Returns a tensor from some value. - * @param {Tensor | Matrix | Array | number} arr Original values - * @returns {Tensor} Tensor from some value + * @template T + * @param {Tensor | Matrix | NestedArray | T} arr Original values + * @returns {Tensor} Tensor from some value */ static fromArray(arr) { if (arr instanceof Tensor) { @@ -158,7 +165,7 @@ export default class Tensor { /** * Elements in the tensor. - * @type {number[]} + * @type {T[]} */ get value() { return this._value @@ -166,7 +173,7 @@ export default class Tensor { /** * Iterate over the elements. - * @yields {number} + * @yields {T} */ *[Symbol.iterator]() { yield* this._value @@ -174,7 +181,7 @@ export default class Tensor { /** * Returns a nested array represented this tensor. - * @returns {Array} Nested array + * @returns {NestedArray} Nested array */ toArray() { const root = [] @@ -224,7 +231,7 @@ export default class Tensor { /** * Returns a Matrix if the dimension of this tensor is 2. - * @returns {Matrix} Matrix + * @returns {Matrix} Matrix * @throws {MatrixException} If the dimension of this tensor is not 2. */ toMatrix() { @@ -236,7 +243,7 @@ export default class Tensor { /** * Returns the only element. - * @returns {number} The only element + * @returns {T} The only element */ toScaler() { if (this._value.length !== 1) { @@ -267,7 +274,7 @@ export default class Tensor { /** * Returns a copy of this tensor. - * @returns {Tensor} Copied tensor + * @returns {Tensor} Copied tensor */ copy() { return new Tensor(this._size, this.value.slice(this._offset, this._offset + this._length)) @@ -300,17 +307,17 @@ export default class Tensor { * Returns value at the index position. * @overload * @param {...number} i Index values - * @returns {number} The value + * @returns {T} The value */ /** * Returns value at the index position. * @overload * @param {number[]} i Index values - * @returns {number} The value + * @returns {T} The value */ /** * @param {...number | number[]} i Index values - * @returns {number} The value + * @returns {T} The value */ at(...i) { if (Array.isArray(i[0])) { @@ -326,17 +333,17 @@ export default class Tensor { * Returns tensor at the index position. * @overload * @param {...number} i Index values - * @returns {Tensor} Sub tensor + * @returns {Tensor} Sub tensor */ /** * Returns tensor at the index position. * @overload * @param {number[]} i Index values - * @returns {Tensor} Sub tensor + * @returns {Tensor} Sub tensor */ /** * @param {...number | number[]} i Index values - * @returns {Tensor} Sub tensor + * @returns {Tensor} Sub tensor */ index(...i) { if (Array.isArray(i[0])) { @@ -364,7 +371,7 @@ export default class Tensor { /** * Set the value at the specific position. * @param {number | number[]} i Index values - * @param {number} value Set value + * @param {T} value Set value */ set(i, value) { if (!Array.isArray(i)) { @@ -377,7 +384,7 @@ export default class Tensor { * Returns the sub-tensor corresponding to position i in the first dimension of this. * @param {number | number[]} idx Select index value(s) * @param {number} [axis] Axis - * @returns {Tensor} Selected tensor + * @returns {Tensor} Selected tensor */ select(idx, axis = 0) { if (axis < 0 || this.dimension <= axis) { @@ -414,7 +421,7 @@ export default class Tensor { * @param {number} from Start index * @param {number} to End index * @param {number} [axis] Axis - * @returns {Tensor} Sliced tensor + * @returns {Tensor} Sliced tensor */ slice(from, to, axis = 0) { if (axis < 0 || this.dimension <= axis) { @@ -446,7 +453,7 @@ export default class Tensor { /** * Fill in all the elements with the value. - * @param {number} value Filled value + * @param {T} value Filled value */ fill(value) { this._value = Array(this.length).fill(value) @@ -454,7 +461,7 @@ export default class Tensor { /** * Iterate over all the elements and replace the value. - * @param {function (number, number[], Tensor): number} cb Mapping function + * @param {function (T, number[], Tensor): T} cb Mapping function */ map(cb) { for (let i = this.length - 1; i >= 0; i--) { @@ -464,7 +471,7 @@ export default class Tensor { /** * Iterate over all the elements. - * @param {function (number, number[], Tensor): void} cb Callback function + * @param {function (T, number[], Tensor): void} cb Callback function */ forEach(cb) { for (let i = 0; i < this.length; i++) { @@ -475,16 +482,16 @@ export default class Tensor { /** * Returns a tensor transposed along the axis. * @param {...number} axises Selected axises - * @returns {Tensor} Transposed tensor + * @returns {Tensor} Transposed tensor */ /** * Returns a tensor transposed along the axis. * @param {number[]} axises Selected axises - * @returns {Tensor} Transposed tensor + * @returns {Tensor} Transposed tensor */ /** * @param {...number | number[]} axises Selected axises - * @returns {Tensor} Transposed tensor + * @returns {Tensor} Transposed tensor */ transpose(...axises) { if (Array.isArray(axises[0])) { @@ -636,7 +643,7 @@ export default class Tensor { /** * Concatenate this and t. - * @param {Tensor} t Concatenate tensor + * @param {Tensor} t Concatenate tensor * @param {number} [axis] Axis to be concatenated */ concat(t, axis = 0) { @@ -668,25 +675,46 @@ export default class Tensor { /** * Returns a tensor reduced along all element with the callback function. * @overload - * @param {function (number, number, number[], Tensor): number} cb Reducing function - * @param {*} [init] Initial value - * @returns {number} Reduced tensor or value + * @param {function (T, T, number[], Tensor): T} cb Reducing function + * @param {undefined | null} [init] Initial value + * @returns {T} Reduced tensor or value + */ + /** + * Returns a tensor reduced along all element with the callback function. + * @template U + * @overload + * @param {function (U, T, number[], Tensor): U} cb Reducing function + * @param {U} init Initial value + * @returns {U} Reduced tensor or value */ /** * Returns a tensor reduced along the axis with the callback function. + * @template {boolean} F * @overload - * @param {function (number, number, number[], Tensor): number} cb Reducing function - * @param {*} init Initial value + * @param {function (T, T, number[], Tensor): T} cb Reducing function + * @param {undefined | null} init Initial value * @param {number | number[]} axis Axis to be reduced. If negative, reduce along all elements. - * @param {boolean} [keepdims] Keep dimensions or not. - * @returns {Tensor | number} Reduced tensor or value + * @param {F} [keepdims] Keep dimensions or not. + * @returns {Tensor | (F extends true ? never : T)} Reduced tensor or value + */ + /** + * Returns a tensor reduced along the axis with the callback function. + * @template U + * @template {boolean} F + * @overload + * @param {function (U, T, number[], Tensor): U} cb Reducing function + * @param {U} init Initial value + * @param {number | number[]} axis Axis to be reduced. If negative, reduce along all elements. + * @param {F} [keepdims] Keep dimensions or not. + * @returns {Tensor | (F extends true ? never : U)} Reduced tensor or value */ /** - * @param {function (number, number, number[], Tensor): number} cb Reducing function - * @param {*} [init] Initial value + * @template U + * @param {function (U, T, number[], Tensor): U} cb Reducing function + * @param {U} [init] Initial value * @param {number | number[]} [axis] Axis to be reduced. If negative, reduce along all elements. * @param {boolean} [keepdims] Keep dimensions or not. - * @returns {Tensor | number} Reduced tensor or value + * @returns {Tensor | U} Reduced tensor or value */ reduce(cb, init, axis = -1, keepdims = false) { if (typeof axis === 'number') { @@ -751,8 +779,9 @@ export default class Tensor { /** * Apply function for all elements with broadcasting. - * @param {Tensor | Matrix | number} o Applied value - * @param {function (number, number): number} fn Applied function + * @template U + * @param {Tensor | Matrix | U} o Applied value + * @param {function (T, U): T} fn Applied function */ broadcastOperate(o, fn) { if (o instanceof Tensor || o instanceof Matrix) { @@ -819,8 +848,8 @@ export default class Tensor { /** * Apply function to the position. * @param {number | number[]} i Index values - * @param {function (number): number} [fn] Applied function - * @returns {number} Old value + * @param {function (T): T} [fn] Applied function + * @returns {T} Old value */ operateAt(i, fn) { if (!Array.isArray(i)) { @@ -834,8 +863,8 @@ export default class Tensor { /** * Returns a tensor product value. - * @param {Matrix} o Right matrix - * @returns {Tensor} Producted tensor + * @param {Matrix} o Right matrix + * @returns {Tensor} Producted tensor */ dot(o) { if (this._size[this._size.length - 1] !== o.rows) {