From ede98fd2a9616cb386d5c64bac4025d6699bdfad Mon Sep 17 00:00:00 2001 From: nakul-krishnakumar Date: Mon, 3 Aug 2026 11:12:05 +0530 Subject: [PATCH] feat: add `ml/base/sgd/params/struct-factory` --- type: pre_commit_static_analysis_report description: Results of running static analysis checks when committing changes. report: - task: lint_filenames status: passed - task: lint_editorconfig status: passed - task: lint_markdown_pkg_readmes status: passed - task: lint_markdown_docs status: na - task: lint_markdown status: na - task: lint_package_json status: passed - task: lint_repl_help status: passed - task: lint_javascript_src status: passed - task: lint_javascript_cli status: na - task: lint_javascript_examples status: passed - task: lint_javascript_tests status: passed - task: lint_javascript_benchmarks status: passed - task: lint_python status: na - task: lint_r status: na - task: lint_c_src status: na - task: lint_c_examples status: na - task: lint_c_benchmarks status: na - task: lint_c_tests_fixtures status: na - task: lint_shell status: na - task: lint_typescript_declarations status: passed - task: lint_typescript_tests status: passed - task: lint_license_headers status: passed --- --- .../base/sgd/params/struct-factory/README.md | 168 ++++++++++++++ .../struct-factory/benchmark/benchmark.js | 54 +++++ .../sgd/params/struct-factory/docs/repl.txt | 24 ++ .../struct-factory/docs/types/index.d.ts | 189 ++++++++++++++++ .../params/struct-factory/docs/types/test.ts | 54 +++++ .../params/struct-factory/examples/index.js | 61 +++++ .../sgd/params/struct-factory/lib/index.js | 43 ++++ .../sgd/params/struct-factory/lib/main.js | 118 ++++++++++ .../sgd/params/struct-factory/package.json | 68 ++++++ .../sgd/params/struct-factory/test/test.js | 209 ++++++++++++++++++ 10 files changed, 988 insertions(+) create mode 100644 lib/node_modules/@stdlib/ml/base/sgd/params/struct-factory/README.md create mode 100644 lib/node_modules/@stdlib/ml/base/sgd/params/struct-factory/benchmark/benchmark.js create mode 100644 lib/node_modules/@stdlib/ml/base/sgd/params/struct-factory/docs/repl.txt create mode 100644 lib/node_modules/@stdlib/ml/base/sgd/params/struct-factory/docs/types/index.d.ts create mode 100644 lib/node_modules/@stdlib/ml/base/sgd/params/struct-factory/docs/types/test.ts create mode 100644 lib/node_modules/@stdlib/ml/base/sgd/params/struct-factory/examples/index.js create mode 100644 lib/node_modules/@stdlib/ml/base/sgd/params/struct-factory/lib/index.js create mode 100644 lib/node_modules/@stdlib/ml/base/sgd/params/struct-factory/lib/main.js create mode 100644 lib/node_modules/@stdlib/ml/base/sgd/params/struct-factory/package.json create mode 100644 lib/node_modules/@stdlib/ml/base/sgd/params/struct-factory/test/test.js diff --git a/lib/node_modules/@stdlib/ml/base/sgd/params/struct-factory/README.md b/lib/node_modules/@stdlib/ml/base/sgd/params/struct-factory/README.md new file mode 100644 index 000000000000..e47068d50640 --- /dev/null +++ b/lib/node_modules/@stdlib/ml/base/sgd/params/struct-factory/README.md @@ -0,0 +1,168 @@ + + +# structFactory + +> Create a new [`struct`][@stdlib/dstructs/struct] constructor tailored to a specified floating-point data type. + + + +
+ +
+ + + + + +
+ +## Usage + +```javascript +var structFactory = require( '@stdlib/ml/base/sgd/params/struct-factory' ); +``` + +#### structFactory( dtype ) + +Returns a new [`struct`][@stdlib/dstructs/struct] constructor tailored to a specified floating-point data type. + +```javascript +var Struct = structFactory( 'float64' ); +// returns + +var s = new Struct(); +// returns +``` + +The function supports the following parameters: + +- **dtype**: floating-point data type for storing floating-point parameters. Must be either `'float64'` or `'float32'`. + +A returned [`struct`][@stdlib/dstructs/struct] constructor supports the following fields: + +- **penalty**: regularization function to be used. +- **penaltyParams**: parameters specific to the regularization function being used. +- **learningRate**: learning rate scheduler to be used. +- **learningRateParams**: parameters specific to the learning rate scheduler being used. +- **lossFunction**: loss function to be used. +- **lossFunctionParams**: parameters specific to the loss function being used. +- **fitIntercept**: boolean indicating whether to include an intercept. +- **intercept**: initial intercept value. +- **maxIter**: maximum number of iterations to run. + +
+ + + + + +
+ +## Notes + +- A [`struct`][@stdlib/dstructs/struct] provides a fixed-width composite data structure for storing SGD trainer parameters and provides an ABI-stable data layout for JavaScript-C interoperation. +- Each parameter list is a fixed-length array which is large enough to accommodate the option requiring the most parameters (`penaltyParams`: `3`, `learningRateParams`: `2`, `lossFunctionParams`: `1`). Accordingly, one must provide a list having the expected length, with any unused elements set to zero. As struct instances are zero-filled upon initialization, one may omit a list when the corresponding option requires no parameters. + +
+ + + + + +
+ +## Examples + + + +```javascript +var resolveLREnum = require( '@stdlib/ml/base/sgd-classification/learning-rate-resolve-enum' ); +var resolveLossFunctionEnum = require( '@stdlib/ml/base/sgd-classification/loss-function-resolve-enum' ); +var resolvePenaltyEnum = require( '@stdlib/ml/base/sgd-classification/penalty-resolve-enum' ); +var Float64Array = require( '@stdlib/array/float64' ); +var Float32Array = require( '@stdlib/array/float32' ); +var structFactory = require( '@stdlib/ml/base/sgd/params/struct-factory' ); + +// Note: hinge loss requires no parameters, and thus we may omit the respective parameter list. +var Struct = structFactory( 'float64' ); +var params = new Struct({ + 'penalty': resolvePenaltyEnum( 'l2' ), + 'penaltyParams': new Float64Array( [ 2.5, 0.0, 0.0 ] ), + 'learningRate': resolveLREnum( 'constant' ), + 'learningRateParams': new Float64Array( [ 0.01, 0.0 ] ), + 'lossFunction': resolveLossFunctionEnum( 'hinge' ), + 'fitIntercept': true, + 'intercept': 0.0, + 'maxIter': 500 +}); + +var str = params.toString({ + 'format': 'linear' +}); +console.log( str ); + +Struct = structFactory( 'float32' ); +params = new Struct({ + 'penalty': resolvePenaltyEnum( 'l2' ), + 'penaltyParams': new Float32Array( [ 2.5, 0.0, 0.0 ] ), + 'learningRate': resolveLREnum( 'constant' ), + 'learningRateParams': new Float32Array( [ 0.01, 0.0 ] ), + 'lossFunction': resolveLossFunctionEnum( 'hinge' ), + 'fitIntercept': true, + 'intercept': 0.0, + 'maxIter': 500 +}); + +str = params.toString({ + 'format': 'linear' +}); +console.log( str ); +``` + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + diff --git a/lib/node_modules/@stdlib/ml/base/sgd/params/struct-factory/benchmark/benchmark.js b/lib/node_modules/@stdlib/ml/base/sgd/params/struct-factory/benchmark/benchmark.js new file mode 100644 index 000000000000..f4c4a1b9ec96 --- /dev/null +++ b/lib/node_modules/@stdlib/ml/base/sgd/params/struct-factory/benchmark/benchmark.js @@ -0,0 +1,54 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2025 The Stdlib Authors. +* +* 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. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var isFunction = require( '@stdlib/assert/is-function' ); +var pkg = require( './../package.json' ).name; +var factory = require( './../lib' ); + + +// MAIN // + +bench( pkg, function benchmark( b ) { + var values; + var v; + var i; + + values = [ + 'float64', + 'float32' + ]; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = factory( values[ i%values.length ] ); + if ( typeof v !== 'function' ) { + b.fail( 'should return a function' ); + } + } + b.toc(); + if ( !isFunction( v ) ) { + b.fail( 'should return a function' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/lib/node_modules/@stdlib/ml/base/sgd/params/struct-factory/docs/repl.txt b/lib/node_modules/@stdlib/ml/base/sgd/params/struct-factory/docs/repl.txt new file mode 100644 index 000000000000..44d00f06a186 --- /dev/null +++ b/lib/node_modules/@stdlib/ml/base/sgd/params/struct-factory/docs/repl.txt @@ -0,0 +1,24 @@ + +{{alias}}( dtype ) + Returns a new struct constructor tailored to a specified floating-point data + type. + + Parameters + ---------- + dtype: string + Floating-point data type for storing floating-point parameters. + + Returns + ------- + fcn: Function + Struct constructor. + + Examples + -------- + > var S = {{alias}}( 'float64' ); + > var r = new S(); + > r.toString() + + + See Also + -------- diff --git a/lib/node_modules/@stdlib/ml/base/sgd/params/struct-factory/docs/types/index.d.ts b/lib/node_modules/@stdlib/ml/base/sgd/params/struct-factory/docs/types/index.d.ts new file mode 100644 index 000000000000..ca37ce059007 --- /dev/null +++ b/lib/node_modules/@stdlib/ml/base/sgd/params/struct-factory/docs/types/index.d.ts @@ -0,0 +1,189 @@ +/* +* @license Apache-2.0 +* +* Copyright (c) 2025 The Stdlib Authors. +* +* 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. +*/ + +// TypeScript Version: 4.1 + +/** +* Interface describing SGD trainer function parameters. +*/ +interface Params { + /** + * Regularization function to be used. + */ + penalty?: number; + + /** + * Parameters specific to the regularization function being used. + */ + penaltyParams?: T; + + /** + * Learning rate scheduler to be used. + */ + learningRate?: number; + + /** + * Parameters specific to the learning rate scheduler being used. + */ + learningRateParams?: T; + + /** + * Loss function to be used. + */ + lossFunction?: number; + + /** + * Parameters specific to the loss function being used. + */ + lossFunctionParams?: T; + + /** + * Boolean indicating whether to include intercept. + */ + fitIntercept?: boolean; + + /** + * Initial intercept value. + */ + intercept?: number; + + /** + * Maximum number of iterations to run. + */ + maxIter?: number; +} + +/** +* Interface describing a struct data structure. +*/ +declare class Struct { + /** + * Struct constructor. + * + * @param arg - buffer or data object + * @param byteOffset - byte offset + * @param byteLength - maximum byte length + * @returns struct + */ + constructor( arg?: ArrayBuffer | Params, byteOffset?: number, byteLength?: number ); + + /** + * Regularization function to be used. + */ + penalty: number; + + /** + * Parameters specific to the regularization function being used. + */ + penaltyParams: T; + + /** + * Learning rate scheduler to be used. + */ + learningRate: number; + + /** + * Parameters specific to the learning rate scheduler being used. + */ + learningRateParams: T; + + /** + * Loss function to be used. + */ + lossFunction: number; + + /** + * Parameters specific to the loss function being used. + */ + lossFunctionParams: T; + + /** + * Boolean indicating whether to include intercept. + */ + fitIntercept: boolean; + + /** + * Initial intercept value. + */ + intercept: number; + + /** + * Maximum number of iterations to run. + */ + maxIter: number; +} + +/** +* Interface defining a struct constructor which is both "newable" and "callable". +*/ +interface StructConstructor { + /** + * Struct constructor. + * + * @param arg - buffer or data object + * @param byteOffset - byte offset + * @param byteLength - maximum byte length + * @returns struct + */ + new( arg?: ArrayBuffer | Params, byteOffset?: number, byteLength?: number ): Struct; + + /** + * Struct constructor. + * + * @param arg - buffer or data object + * @param byteOffset - byte offset + * @param byteLength - maximum byte length + * @returns struct + */ + ( arg?: ArrayBuffer | Params, byteOffset?: number, byteLength?: number ): Struct; +} + +/** +* Returns a new struct constructor tailored to a specified floating-point data type. +* +* @param dtype - floating-point data type for storing floating-point results +* @returns struct constructor +* +* @example +* var Struct = structFactory( 'float64' ); +* // returns +* +* var s = new Struct(); +* // returns +*/ +declare function structFactory( dtype: 'float64' ): StructConstructor; + +/** +* Returns a new struct constructor tailored to a specified floating-point data type. +* +* @param dtype - floating-point data type for storing floating-point results +* @returns struct constructor +* +* @example +* var Struct = structFactory( 'float32' ); +* // returns +* +* var s = new Struct(); +* // returns +*/ +declare function structFactory( dtype: 'float32' ): StructConstructor; + + +// EXPORTS // + +export = structFactory; diff --git a/lib/node_modules/@stdlib/ml/base/sgd/params/struct-factory/docs/types/test.ts b/lib/node_modules/@stdlib/ml/base/sgd/params/struct-factory/docs/types/test.ts new file mode 100644 index 000000000000..d468857951a5 --- /dev/null +++ b/lib/node_modules/@stdlib/ml/base/sgd/params/struct-factory/docs/types/test.ts @@ -0,0 +1,54 @@ +/* +* @license Apache-2.0 +* +* Copyright (c) 2025 The Stdlib Authors. +* +* 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. +*/ + +import structFactory = require( './index' ); + + +// TESTS // + +// The function returns a function... +{ + structFactory( 'float64' ); // $ExpectType StructConstructor + structFactory( 'float32' ); // $ExpectType StructConstructor +} + +// The compiler throws an error if not provided a supported data type... +{ + structFactory( 10 ); // $ExpectError + structFactory( true ); // $ExpectError + structFactory( false ); // $ExpectError + structFactory( null ); // $ExpectError + structFactory( undefined ); // $ExpectError + structFactory( [] ); // $ExpectError + structFactory( {} ); // $ExpectError + structFactory( ( x: number ): number => x ); // $ExpectError +} + +// The function returns a function which returns a struct object... +{ + const Struct = structFactory( 'float64' ); + + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const s1 = new Struct( new ArrayBuffer( 92 ) ); // $ExpectType Struct + + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const s2 = new Struct( new ArrayBuffer( 100 ), 8 ); // $ExpectType Struct + + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const s3 = new Struct( new ArrayBuffer( 100 ), 8, 92 ); // $ExpectType Struct +} diff --git a/lib/node_modules/@stdlib/ml/base/sgd/params/struct-factory/examples/index.js b/lib/node_modules/@stdlib/ml/base/sgd/params/struct-factory/examples/index.js new file mode 100644 index 000000000000..2e005dff188e --- /dev/null +++ b/lib/node_modules/@stdlib/ml/base/sgd/params/struct-factory/examples/index.js @@ -0,0 +1,61 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2025 The Stdlib Authors. +* +* 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. +*/ + +'use strict'; + +var resolveLREnum = require( '@stdlib/ml/base/sgd-classification/learning-rate-resolve-enum' ); +var resolveLossFunctionEnum = require( '@stdlib/ml/base/sgd-classification/loss-function-resolve-enum' ); +var resolvePenaltyEnum = require( '@stdlib/ml/base/sgd-classification/penalty-resolve-enum' ); +var Float64Array = require( '@stdlib/array/float64' ); +var Float32Array = require( '@stdlib/array/float32' ); +var structFactory = require( './../lib' ); + +// Note: each parameter list has a fixed length, and thus one must provide a list having the expected length, with any unused elements set to zero. Alternatively, for an option requiring no parameters (e.g., hinge loss), one may omit the respective list, as struct instances are zero-filled upon initialization. +var Struct = structFactory( 'float64' ); +var results = new Struct({ + 'penalty': resolvePenaltyEnum( 'l2' ), + 'penaltyParams': new Float64Array( [ 2.5, 0.0, 0.0 ] ), + 'learningRate': resolveLREnum( 'constant' ), + 'learningRateParams': new Float64Array( [ 0.01, 0.0 ] ), + 'lossFunction': resolveLossFunctionEnum( 'hinge' ), + 'fitIntercept': true, + 'intercept': 0.0, + 'maxIter': 500 +}); + +var str = results.toString({ + 'format': 'linear' +}); +console.log( str ); + +Struct = structFactory( 'float32' ); +results = new Struct({ + 'penalty': resolvePenaltyEnum( 'l2' ), + 'penaltyParams': new Float32Array( [ 2.5, 0.0, 0.0 ] ), + 'learningRate': resolveLREnum( 'constant' ), + 'learningRateParams': new Float32Array( [ 0.01, 0.0 ] ), + 'lossFunction': resolveLossFunctionEnum( 'hinge' ), + 'fitIntercept': true, + 'intercept': 0.0, + 'maxIter': 500 +}); + +str = results.toString({ + 'format': 'linear' +}); +console.log( str ); diff --git a/lib/node_modules/@stdlib/ml/base/sgd/params/struct-factory/lib/index.js b/lib/node_modules/@stdlib/ml/base/sgd/params/struct-factory/lib/index.js new file mode 100644 index 000000000000..f20f31a562a1 --- /dev/null +++ b/lib/node_modules/@stdlib/ml/base/sgd/params/struct-factory/lib/index.js @@ -0,0 +1,43 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2025 The Stdlib Authors. +* +* 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. +*/ + +'use strict'; + +/** +* Create a new struct constructor tailored to a specified floating-point data type. +* +* @module @stdlib/ml/base/sgd/params/struct-factory +* +* @example +* var structFactory = require( '@stdlib/ml/base/sgd/params/struct-factory' ); +* +* var Struct = structFactory( 'float64' ); +* // returns +* +* var s = new Struct(); +* // returns +*/ + +// MODULES // + +var main = require( './main.js' ); + + +// EXPORTS // + +module.exports = main; diff --git a/lib/node_modules/@stdlib/ml/base/sgd/params/struct-factory/lib/main.js b/lib/node_modules/@stdlib/ml/base/sgd/params/struct-factory/lib/main.js new file mode 100644 index 000000000000..2c76866897fd --- /dev/null +++ b/lib/node_modules/@stdlib/ml/base/sgd/params/struct-factory/lib/main.js @@ -0,0 +1,118 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2025 The Stdlib Authors. +* +* 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. +*/ + +'use strict'; + +// MODULES // + +var struct = require( '@stdlib/dstructs/struct' ); + + +// VARIABLES // + +var PENALTY_PARAMS_LENGTH = 3; +var LEARNING_RATE_PARAMS_LENGTH = 2; +var LOSS_FUNCTION_PARAMS_LENGTH = 1; + + +// MAIN // + +/** +* Returns a new struct constructor tailored to a specified floating-point data type. +* +* ## Notes +* +* - Each parameter list is a fixed-length array which is zero-filled upon initialization. Consumers should only read as many elements as are applicable to the corresponding penalty, learning rate scheduler, or loss function, with any remaining elements being unused. +* +* @param {string} dtype - floating-point data type +* @returns {Function} struct constructor +* +* @example +* var Struct = factory( 'float64' ); +* // returns +* +* var s = new Struct(); +* // returns +*/ +function factory( dtype ) { + var schema = [ + { + 'name': 'penalty', + 'description': 'regularization function to be used', + 'type': 'int8', + 'castingMode': 'none' + }, + { + 'name': 'penaltyParams', + 'description': 'parameters specific to the regularization function being used', + 'type': dtype, + 'length': PENALTY_PARAMS_LENGTH, + 'castingMode': 'mostly-safe' + }, + { + 'name': 'learningRate', + 'description': 'learning rate scheduler to be used', + 'type': 'int8', + 'castingMode': 'none' + }, + { + 'name': 'learningRateParams', + 'description': 'parameters specific to the learning rate scheduler being used', + 'type': dtype, + 'length': LEARNING_RATE_PARAMS_LENGTH, + 'castingMode': 'mostly-safe' + }, + { + 'name': 'lossFunction', + 'description': 'loss function to be used', + 'type': 'int8', + 'castingMode': 'none' + }, + { + 'name': 'lossFunctionParams', + 'description': 'parameters specific to the loss function being used', + 'type': dtype, + 'length': LOSS_FUNCTION_PARAMS_LENGTH, + 'castingMode': 'mostly-safe' + }, + { + 'name': 'fitIntercept', + 'description': 'boolean indicating whether to include intercept', + 'type': 'bool', + 'castingMode': 'none' + }, + { + 'name': 'intercept', + 'description': 'initial intercept value', + 'type': dtype, + 'castingMode': 'mostly-safe' + }, + { + 'name': 'maxIter', + 'description': 'maximum number of iterations to run', + 'type': 'int32', + 'castingMode': 'mostly-safe' + } + ]; + return struct( schema ); +} + + +// EXPORTS // + +module.exports = factory; diff --git a/lib/node_modules/@stdlib/ml/base/sgd/params/struct-factory/package.json b/lib/node_modules/@stdlib/ml/base/sgd/params/struct-factory/package.json new file mode 100644 index 000000000000..089cf5b84b66 --- /dev/null +++ b/lib/node_modules/@stdlib/ml/base/sgd/params/struct-factory/package.json @@ -0,0 +1,68 @@ +{ + "name": "@stdlib/ml/base/sgd/params/struct-factory", + "version": "0.0.0", + "description": "Create a new struct constructor tailored to a specified floating-point data type.", + "license": "Apache-2.0", + "author": { + "name": "The Stdlib Authors", + "url": "https://github.com/stdlib-js/stdlib/graphs/contributors" + }, + "contributors": [ + { + "name": "The Stdlib Authors", + "url": "https://github.com/stdlib-js/stdlib/graphs/contributors" + } + ], + "main": "./lib", + "directories": { + "benchmark": "./benchmark", + "doc": "./docs", + "example": "./examples", + "lib": "./lib", + "test": "./test" + }, + "types": "./docs/types", + "scripts": {}, + "homepage": "https://github.com/stdlib-js/stdlib", + "repository": { + "type": "git", + "url": "git://github.com/stdlib-js/stdlib.git" + }, + "bugs": { + "url": "https://github.com/stdlib-js/stdlib/issues" + }, + "dependencies": {}, + "devDependencies": {}, + "engines": { + "node": ">=0.10.0", + "npm": ">2.7.0" + }, + "os": [ + "aix", + "darwin", + "freebsd", + "linux", + "macos", + "openbsd", + "sunos", + "win32", + "windows" + ], + "keywords": [ + "stdlib", + "ml", + "machine", + "learning", + "sgd", + "stochastic gradient descent", + "trainer", + "utilities", + "utility", + "utils", + "util", + "struct", + "params", + "parameters" + ], + "__stdlib__": {} +} diff --git a/lib/node_modules/@stdlib/ml/base/sgd/params/struct-factory/test/test.js b/lib/node_modules/@stdlib/ml/base/sgd/params/struct-factory/test/test.js new file mode 100644 index 000000000000..c8d1a915b65d --- /dev/null +++ b/lib/node_modules/@stdlib/ml/base/sgd/params/struct-factory/test/test.js @@ -0,0 +1,209 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2025 The Stdlib Authors. +* +* 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. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var isSameFloat64Array = require( '@stdlib/assert/is-same-float64array' ); +var isSameFloat32Array = require( '@stdlib/assert/is-same-float32array' ); +var Float64Array = require( '@stdlib/array/float64' ); +var Float32Array = require( '@stdlib/array/float32' ); +var resolveLREnum = require( '@stdlib/ml/base/sgd-classification/learning-rate-resolve-enum' ); +var resolveLossFunctionEnum = require( '@stdlib/ml/base/sgd-classification/loss-function-resolve-enum' ); +var resolvePenaltyEnum = require( '@stdlib/ml/base/sgd-classification/penalty-resolve-enum' ); +var f32 = require( '@stdlib/number/float64/base/to-float32' ); +var structFactory = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof structFactory, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function throws an error if provided a first argument which is not a supported data type', function test( t ) { + var values; + var i; + + values = [ + '5', + 5, + NaN, + true, + false, + null, + void 0, + [], + {}, + function noop() {} + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), TypeError, 'throws an error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + structFactory( value ); + }; + } +}); + +tape( 'the function returns a constructor for creating a fixed-width parameters object (dtype=float64)', function test( t ) { + var expected; + var actual; + var Struct; + + Struct = structFactory( 'float64' ); + t.strictEqual( typeof Struct, 'function', 'returns expected value' ); + + actual = new Struct({ + 'penalty': resolvePenaltyEnum( 'l2' ), + 'penaltyParams': new Float64Array( [ 2.5, 0.0, 0.0 ] ), + 'learningRate': resolveLREnum( 'constant' ), + 'learningRateParams': new Float64Array( [ 0.01, 0.0 ] ), + 'lossFunction': resolveLossFunctionEnum( 'hinge' ), + 'lossFunctionParams': new Float64Array( [ 0.0 ] ), + 'fitIntercept': true, + 'intercept': 0.5, + 'maxIter': 500 + }); + + expected = { + 'penalty': resolvePenaltyEnum( 'l2' ), + 'penaltyParams': new Float64Array( [ 2.5, 0.0, 0.0 ] ), + 'learningRate': resolveLREnum( 'constant' ), + 'learningRateParams': new Float64Array( [ 0.01, 0.0 ] ), + 'lossFunction': resolveLossFunctionEnum( 'hinge' ), + 'lossFunctionParams': new Float64Array( [ 0.0 ] ), + 'fitIntercept': true, + 'intercept': 0.5, + 'maxIter': 500 + }; + + t.strictEqual( actual instanceof Struct, true, 'returns expected value' ); + t.strictEqual( actual.penalty, expected.penalty, 'returns expected value' ); + t.strictEqual( actual.learningRate, expected.learningRate, 'returns expected value' ); + t.strictEqual( actual.lossFunction, expected.lossFunction, 'returns expected value' ); + t.strictEqual( actual.fitIntercept, expected.fitIntercept, 'returns expected value' ); + t.strictEqual( actual.intercept, expected.intercept, 'returns expected value' ); + t.strictEqual( actual.maxIter, expected.maxIter, 'returns expected value' ); + t.strictEqual( isSameFloat64Array( actual.penaltyParams, expected.penaltyParams ), true, 'returns expected value' ); + t.strictEqual( isSameFloat64Array( actual.learningRateParams, expected.learningRateParams ), true, 'returns expected value' ); + t.strictEqual( isSameFloat64Array( actual.lossFunctionParams, expected.lossFunctionParams ), true, 'returns expected value' ); + t.end(); +}); + +tape( 'the function returns a constructor for creating a fixed-width parameters object (dtype=float32)', function test( t ) { + var expected; + var actual; + var Struct; + + Struct = structFactory( 'float32' ); + t.strictEqual( typeof Struct, 'function', 'returns expected value' ); + + actual = new Struct({ + 'penalty': resolvePenaltyEnum( 'l2' ), + 'penaltyParams': new Float32Array( [ 2.5, 0.0, 0.0 ] ), + 'learningRate': resolveLREnum( 'constant' ), + 'learningRateParams': new Float32Array( [ 0.01, 0.0 ] ), + 'lossFunction': resolveLossFunctionEnum( 'hinge' ), + 'lossFunctionParams': new Float32Array( [ 0.0 ] ), + 'fitIntercept': true, + 'intercept': f32( 0.5 ), + 'maxIter': 500 + }); + + expected = { + 'penalty': resolvePenaltyEnum( 'l2' ), + 'penaltyParams': new Float32Array( [ 2.5, 0.0, 0.0 ] ), + 'learningRate': resolveLREnum( 'constant' ), + 'learningRateParams': new Float32Array( [ 0.01, 0.0 ] ), + 'lossFunction': resolveLossFunctionEnum( 'hinge' ), + 'lossFunctionParams': new Float32Array( [ 0.0 ] ), + 'fitIntercept': true, + 'intercept': f32( 0.5 ), + 'maxIter': 500 + }; + + t.strictEqual( actual instanceof Struct, true, 'returns expected value' ); + t.strictEqual( actual.penalty, expected.penalty, 'returns expected value' ); + t.strictEqual( actual.learningRate, expected.learningRate, 'returns expected value' ); + t.strictEqual( actual.lossFunction, expected.lossFunction, 'returns expected value' ); + t.strictEqual( actual.fitIntercept, expected.fitIntercept, 'returns expected value' ); + t.strictEqual( actual.intercept, expected.intercept, 'returns expected value' ); + t.strictEqual( actual.maxIter, expected.maxIter, 'returns expected value' ); + t.strictEqual( isSameFloat32Array( actual.penaltyParams, expected.penaltyParams ), true, 'returns expected value' ); + t.strictEqual( isSameFloat32Array( actual.learningRateParams, expected.learningRateParams ), true, 'returns expected value' ); + t.strictEqual( isSameFloat32Array( actual.lossFunctionParams, expected.lossFunctionParams ), true, 'returns expected value' ); + t.end(); +}); + +tape( 'the function returns a constructor which zero-fills parameter lists which are not provided', function test( t ) { + var expected; + var actual; + var Struct; + + Struct = structFactory( 'float64' ); + + actual = new Struct({ + 'lossFunction': resolveLossFunctionEnum( 'hinge' ) + }); + + expected = { + 'penaltyParams': new Float64Array( [ 0.0, 0.0, 0.0 ] ), + 'learningRateParams': new Float64Array( [ 0.0, 0.0 ] ), + 'lossFunctionParams': new Float64Array( [ 0.0 ] ) + }; + + t.strictEqual( isSameFloat64Array( actual.penaltyParams, expected.penaltyParams ), true, 'returns expected value' ); + t.strictEqual( isSameFloat64Array( actual.learningRateParams, expected.learningRateParams ), true, 'returns expected value' ); + t.strictEqual( isSameFloat64Array( actual.lossFunctionParams, expected.lossFunctionParams ), true, 'returns expected value' ); + t.end(); +}); + +tape( 'the function returns a constructor which throws an error if provided a parameter list having an unexpected length', function test( t ) { + var Struct; + var values; + var i; + + Struct = structFactory( 'float64' ); + + values = [ + new Float64Array( [] ), + new Float64Array( [ 2.5 ] ), + new Float64Array( [ 2.5, 0.0 ] ), + new Float64Array( [ 2.5, 0.0, 0.0, 0.0 ] ) + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), RangeError, 'throws an error when provided an array having length ' + values[ i ].length ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + return new Struct({ + 'penaltyParams': value + }); + }; + } +});