{"id":13837426,"url":"https://github.com/streamcode9/node-discrete-spsa","last_synced_at":"2025-07-08T17:35:55.534Z","repository":{"id":57212861,"uuid":"58771211","full_name":"streamcode9/node-discrete-spsa","owner":"streamcode9","description":"Discrete Simultaneous Perturbation Stochastic Aproximation algorithm in Javascript","archived":false,"fork":false,"pushed_at":"2024-11-04T15:01:16.000Z","size":62,"stargazers_count":5,"open_issues_count":14,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-05-23T09:34:28.929Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/streamcode9.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2016-05-13T20:45:36.000Z","updated_at":"2024-08-28T12:38:32.000Z","dependencies_parsed_at":"2025-05-04T22:31:32.368Z","dependency_job_id":"ccba7699-e903-440c-b0d3-8c38db4c0457","html_url":"https://github.com/streamcode9/node-discrete-spsa","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/streamcode9/node-discrete-spsa","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/streamcode9%2Fnode-discrete-spsa","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/streamcode9%2Fnode-discrete-spsa/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/streamcode9%2Fnode-discrete-spsa/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/streamcode9%2Fnode-discrete-spsa/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/streamcode9","download_url":"https://codeload.github.com/streamcode9/node-discrete-spsa/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/streamcode9%2Fnode-discrete-spsa/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":264315088,"owners_count":23589705,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-04T15:01:08.780Z","updated_at":"2025-07-08T17:35:55.488Z","avatar_url":"https://github.com/streamcode9.png","language":"TypeScript","funding_links":[],"categories":["TypeScript"],"sub_categories":[],"readme":"# discrete-spsa \n\n[![NPM][npm-badge]][npm-link]\n\n[![Build Status]][travis-link] \n[![Dependency Status][dm-badge]][dm-link]\n[![devDependency Status][dm-dev-badge]][dm-dev-link] \n[![Status: experimental][experimental-badge]][stability-link]  \n\n[![Code Climate](https://codeclimate.com/github/streamcode9/node-discrete-spsa/badges/gpa.svg)](https://codeclimate.com/github/streamcode9/node-discrete-spsa) [![Test Coverage](https://codeclimate.com/github/streamcode9/node-discrete-spsa/badges/coverage.svg)](https://codeclimate.com/github/streamcode9/node-discrete-spsa/coverage) [![Issue Count](https://codeclimate.com/github/streamcode9/node-discrete-spsa/badges/issue_count.svg)](https://codeclimate.com/github/streamcode9/node-discrete-spsa)\n\nAn implementation of the Discrete Simultaneous Perturbation Stochastic Aproximation algorithm.\n\nSee Stacy D. Hill, \"Discrete Stochastic Approximation with Application to Resource Allocation\", 2005 \n([pdf])\n\nThe algorithm is suitable for optimization tasks in feedback control and \nsimulation-based optimization. It iteratively improves an array of interdependent\nparameters based on subsequent benchmarks. The algorithm requires only 2 benchmark\nruns per iteration regardless the number of parameters, so it is suitable for optimization\nproblems with large number of parameters which are simultaneously improved from run to run. \nAnother advantage is that the algorithm works well with unreliable benchmarks. No averaging\nor measures to guarantee statistical significance of benchmarks is required.\n\nCommon examples of problems this algorithm is suitable for are finding buffer sizes and worker\ncounts in distributed systems, finding optimal memory and CPU frequency in overclocking scenarios\nand so on.\n\n## The Algorithm\n\nOn each iteration:\n\n- a random direction of perturbation is chosen\n- the benchmark is run twice with a positive and a negative perturbation of current guess in that direction\n- the stochastic gradient is calculated from the benchmark results\n- the next guess is calculated by multiplying the gradient by the learning rate parameter\n\nIn pseudo-code:\n\n```Javascript\n{ xs, step } = perturb(initialParameters, learningRate)\nys[0] = benchmark(xs[0])\nys[1] = benchmark(xs[1])\nimprovedParameters = step(ys)\n```\n\n- Choose values for each parameter and feed them to the algorithm\n- Run the benchmark twice with the parameters suggested by the algorithm and collect the results\n- Feed the results to the algorithm to get the improved parameters\n- Use the improved parameters in next iteration\n- Stop when benchmark results stop to improve\n\n## API Documentation\n\nThe `perturb()` function implements the algorithm. The rest of the library are wrappers to use it more easily.\n\n`perturb()` accepts `currentGuess[]` and `learningRate`, and returns `xs[]` and `step()` \n - `currentGuess`: an array numbers, current parameters\n - `learningRate`: a positive or negative number. Use positive numbers to minimize benchmark results. Use negative numbers to maximize bechmark results. Large absolute values mean large jump distance at each iteration. Use smaller values as you get closer to the optimum. \n - `xs` is a 2-element array. Run benchmark twice with the provided sets of parameters.\n - feed benchmark results as an array of 2 numbers to `step()` function, and obtain `improvedParameters`\n - if improved parameters are out of range, fix them: round them and clip to closest valid values. Many methods of rounding and chosing the closest valid values are possible.\n - run the next iteration\n \n`iterate()` and `iterateSync()` use `perturb()` to run steps 1-4 in synchronous and asynchronous manner respectively\n\n`optimize()` runs all the 6 steps in a loop. It accepts an object with 6 fields, all of them are mandatory:\n\n- `iterations`: number of iterations to perform\n- `initialGuess`: initial parameters vector\n- `learningRate`: the learning rate numeric parameter, see above\n- `fn`: the benchmark function. Accepts parameters, returns a promise of a number.\n- `fix`: accepts parameters vector, returns a fixed version\n\n## 0.2 roadmap\n\n- Field-test with real problems\n- Jupyter visualizations\n\n## 0.1 (current)\n\n- Synchronous `spsa.iterateSync()`\n- Asynchronous `spsa.iterate()` (utilizes Bluebird promises)\n- High-level `spsa.optimize()`, asynchronous only\n- Disk seek concurrency optimization demo in `examples/ncq.ts`\n- Network buffering optimization demo in `example/ping.ts` \n\n[pdf]: http://www.jhuapl.edu/SPSA/PDF-SPSA/Hill_TechDig05.pdf\n[Build Status]: https://travis-ci.org/streamcode9/node-discrete-spsa.svg?branch=master\n[travis-link]: https://travis-ci.org/streamcode9/node-discrete-spsa\n[dm-badge]: https://david-dm.org/streamcode9/node-discrete-spsa.svg\n[dm-dev-badge]: https://david-dm.org/streamcode9/node-discrete-spsa/dev-status.svg\n[dm-link]: https://david-dm.org/streamcode9/node-discrete-spsa\n[dm-dev-link]: https://david-dm.org/streamcode9/node-discrete-spsa?type=dev\n\n[npm-badge]: https://nodei.co/npm/discrete-spsa.png?downloads=true\u0026downloadRank=true\u0026stars=true\n[npm-link]: https://nodei.co/npm/discrete-spsa/\n[experimental-badge]: http://badges.github.io/stability-badges/dist/experimental.svg\n[stability-link]: http://github.com/badges/stability-badges\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstreamcode9%2Fnode-discrete-spsa","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstreamcode9%2Fnode-discrete-spsa","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstreamcode9%2Fnode-discrete-spsa/lists"}